From 6db1465f89985e8675db3fdac1aa7d662dda3722 Mon Sep 17 00:00:00 2001 From: s_alexander Date: Sat, 19 Apr 2008 15:23:35 +0000 Subject: tried to make songloading working with the old loader and keep all changes that were made since starting to work on a new one *hope that worked* you may delete your existing cover.cache (the cover cache is still NOT working) git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1024 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UCovers.pas | 693 ++++---------- Game/Code/Classes/UDataBase.pas | 398 ++------- Game/Code/Classes/UGraphic.pas | 4 +- Game/Code/Classes/UMain.pas | 2 +- Game/Code/Classes/UPlaylist.pas | 18 +- Game/Code/Classes/USong.pas | 666 +++++--------- Game/Code/Classes/USong_TextFile.pas | 86 -- Game/Code/Classes/USong_Txt.pas | 436 --------- Game/Code/Classes/USongs.pas | 76 +- Game/Code/Classes/UTexture.pas | 173 +++- Game/Code/Screens/UScreenEditSub.pas | 14 +- Game/Code/Screens/UScreenPartyOptions.pas | 18 +- Game/Code/Screens/UScreenSing.pas | 48 +- Game/Code/Screens/UScreenSingModi.pas | 1389 ++++++++++++++--------------- Game/Code/Screens/UScreenSong.pas | 196 ++-- Game/Code/Screens/UScreenTop5.pas | 14 +- Game/Code/UltraStar.dpr | 2 - 17 files changed, 1477 insertions(+), 2756 deletions(-) delete mode 100644 Game/Code/Classes/USong_TextFile.pas delete mode 100644 Game/Code/Classes/USong_Txt.pas (limited to 'Game/Code') diff --git a/Game/Code/Classes/UCovers.pas b/Game/Code/Classes/UCovers.pas index 7a192e66..0e9ad689 100644 --- a/Game/Code/Classes/UCovers.pas +++ b/Game/Code/Classes/UCovers.pas @@ -1,23 +1,5 @@ unit UCovers; -{******************** - UCover - Contains Class managing Covers.Cache File - File Structure: - TCC_FileHeader - - TextureData - * Array of TCC_TextureData - - Indexes - * TCC_FileIndex Header Block - * TCC_FileIndex - * String containing Filename of Last IndexEntry. Ending with #0 - . - . - * TCC_FileIndex Footer Block -*********************} - interface {$IFDEF FPC} @@ -36,15 +18,8 @@ uses OpenGL12, {$IFNDEF FPC} Graphics, {$ENDIF} - UThemes; - -const - cCC_CoverW = 128; - cCC_CoverH = 128; - cCC_CoverSize = cCC_CoverW * cCC_CoverH * 3; - cCC_HeaderText = 'USDxCo' + #0 + #1; - cCC_HeaderVersion = 1000; - cCC_IndexIndicator= 'I' + 'N' + 'D' + #0; + UThemes, + UTexture; type TCover = record @@ -52,478 +27,223 @@ type W: word; H: word; Size: integer; - Position: integer; //position of picture in the cache file + Position: integer; // position of picture in the cache file // Data: array of byte; end; - //------------------------------------------------------------------- - //Covers.Cache File Parts - - TCC_Hash = Array [1..32] of Char; - TCC_FileHeader = record - FileTyp: Array [1..8] of Char; //Some String to detect if this is the file we want to open - Version: DWord; //Version of Covers.Cache File - Hash: TCC_Hash; //Some Randomly Created Alphanumeric String to Identify w/ SongDB - CoverW: Word; //Width of all Covers in Cache - CoverH: Word; //Height of all Covers in Cache - DataStart: Cardinal; //Start Position in Bytes of Data Part - DataLength: Cardinal; //Start Position in Bytes of Data Part - IndexStart: Cardinal; //Start of Index Block in Bytes - end; - - PCC_TextureData = ^TCC_TextureData; - TCC_TextureData = Array [0..cCC_CoverSize - 1] of Byte; - - TCC_FileIndexHeader = record - Indicator: Array [1..4] of Char; //Contains INDE - HighestID: Integer; //Highest ID of a Cover - end; - - TCC_FileIndex = record - LastUpdated: Integer; //Time of LastFilechange - DataStart: Cardinal; //Position of TextureData of this Cover in Bytes. - //0 if this is empty slot(Deleted Cover)(Id not available) - //1 if the Texture Data is not already loaded to Cache - //High(Cardinal) if this is IndexFooter - //Filename: String; - end; - - TCC_IndexListItem = record - Filename: String; - TexID: Integer; - FileIndex: TCC_FileIndex; - end; - TCC_IndexList = Array of TCC_IndexListItem; - TCovers = class - private - Filename: String; - - Header: TCC_FileHeader; - HighestID: Integer; - Count: Cardinal; - - Index: TCC_IndexList; - - IndexNeedRewrite: Boolean; //Index in CacheFile is overwritten by other Data - CacheReadOnly: Boolean; //Cache File is read only - - Function WriteHeader(const ReWriteCache: Boolean = false):Boolean; - Function ReadHeader: Boolean; - Function ReadIndex: Boolean; - Function WriteIndex(const ReWriteCache: Boolean = false): Boolean; - Function AddTexData(Data: PCC_TextureData): Cardinal; - public - W: word; - H: word; - Size: integer; - Data: array of byte; - Cover: array of TCover; - - property Hash: TCC_Hash read Header.Hash; - - constructor Create(const Filename: String); - procedure Load(const Filename: String); - Function AddCover(FileName: string): Integer; //Returns ID, Checks Cover for Change, Updates Cover if required - function CoverExists(FileName: string): Integer; //Returns ID by FilePath - procedure PrepareData(FileName: string); - Procedure LoadTextures; - Function ReWriteCache: Boolean; //Deletes old cover.cache file and writes new one - - Function GetTexbyID(ID: Cardinal): Integer; + Cover: array of TCover; + W: word; + H: word; + Size: integer; + Data: array of byte; + WritetoFile: Boolean; + + constructor Create; + procedure Load; + procedure Save; + procedure AddCover(Name: string); + function CoverExists(Name: string): boolean; + function CoverNumber(Name: string): integer; + procedure PrepareData(Name: string); end; var Covers: TCovers; - // to - do : new Song management + implementation uses UMain, // UFiles, ULog, - UTexture, DateUtils; -constructor TCovers.Create(const Filename: String); +constructor TCovers.Create; begin - HighestID := -1; - SetLength(Index, HighestID + 2); - //Load(Filename); + W := 128; + H := 128; + Size := W*H*3; + Load; + WritetoFile := True; end; -//---------------------------------------------- -// Some File handling helpers - -//-------- -// Reads and Checks Header. Returns True if Header is correct -//-------- -Function TCovers.ReadHeader: Boolean; +procedure TCovers.Load; var - F: File of TCC_FileHeader; + F: File; + C: integer; // cover number + W: word; + H: word; + Bits: byte; + NLen: word; + Name: string; +// Data: array of byte; begin - try - //Read Header - AssignFile(F, Filename); - - try - Reset(F); - Read(F, Header); - finally - CloseFile(F); - end; - - //Check Header - If (Header.FileTyp = cCC_HeaderText) AND - (Header.Version = cCC_HeaderVersion) then - begin - Result := True; - IndexNeedRewrite := True; - end - Else - Result := False; - - - except - Result := False; - end; -end; - -//-------- -// Writes Header(Resets File). Returns True if Writing succeed -//-------- -Function TCovers.WriteHeader(const ReWriteCache: Boolean):Boolean; -var - F: File of TCC_FileHeader; -begin - try - Result := True; - //Read Header - AssignFile(F, Filename); - try - If (not FileExists(Filename)) OR (ReWriteCache) then - ReWrite(F) - else - Reset(F); - - Write(F, Header); - finally - CloseFile(F); - end; - except - Result := False; - end; -end; - -//-------- -// Reads and Checks Index. Returns True if Index is correct -//-------- -Function TCovers.ReadIndex: Boolean; -var - F: File of Byte; - IndexHeader: TCC_FileIndexHeader; - I: Integer; - - Procedure mReadLn(var S: String); - var - Len: Integer; + if FileExists(GamePath + 'covers.cache') then begin - S := ''; + AssignFile(F, GamePath + 'covers.cache'); + Reset(F, 1); - BlockRead(F, Len, 4); //Read Len of Filename String + WritetoFile := not FileIsReadOnly(GamePath + 'covers.cache'); - //Read Filename String - SetLength(S, Len); - BlockRead(F, S[1], Len); - end; -begin - try - //Read Header - AssignFile(F, Filename); - try - Reset(F); - Seek(F, Header.IndexStart); - - BlockRead(F, IndexHeader, SizeOf(TCC_FileIndexHeader)); - - If (IndexHeader.Indicator = cCC_IndexIndicator) then - begin - Log.LogError('TCovers: loading Cover Index Header. HighestID: ' + InttoStr(IndexHeader.HighestID)); - HighestID := IndexHeader.HighestID; - SetLength(Index, HighestID + 2); - - Count := 0; - Result := True; - If (HighestID >= 0) then - begin - //Read File Infos until (Eof or Footer) - I := 0; - //While (Not Eof(F)) AND ((I <= 0) OR (Index[I-1].FileIndex.DataStart <> High(Cardinal))) do - Repeat - Log.LogError('TCovers: loading Cover Index. Position #' + InttoStr(I)); - If (I > HighestID + 1) then - begin //Header IndexCOunt was wrong, running out of array - Log.LogError('TCovers: Wrong HighestID in Index Header. Running out of Array at Postion #' + InttoStr(I)); - Inc(HighestID); - IndexNeedReWrite := True; - SetLength(Index, HighestID + 2); - end; - - BlockRead(F, Index[I].FileIndex, SizeOf(TCC_FileIndex)); - Index[I].TexID := -1; - - If (Index[I].FileIndex.DataStart = High(Cardinal)) then - begin //Found Footer - Log.LogError('TCovers: Found footer at Position #' + InttoStr(I)); - Break; - end; - - If (Not Eof(F)) then - begin - //Read Filename - mReadLn(Index[I].Filename); - - Log.LogError('TCovers: Cover loaded: ' + Index[I].Filename); - If (Index[I].FileIndex.DataStart <> 0) AND (Index[I].FileIndex.DataStart <> 1) then - Inc(Count); - end; - - Inc(I); - Until Eof(F); - - If (Index[HighestID + 1].FileIndex.DataStart = High(Cardinal)) then - begin //No Footer found - IndexNeedReWrite := True; - end; - end; - - end; - - finally - CloseFile(F); - end; - except - Result := False; - end; -end; + SetLength(Cover, 0); -//-------- -// Writes Index. Returns True if Writing succeed -//-------- -Function TCovers.WriteIndex(const ReWriteCache: Boolean): Boolean; -var - F: File of Byte; - IndexHeader: TCC_FileIndexHeader; - I: Integer; + while not EOF(F) do + begin + SetLength(Cover, Length(Cover)+1); - Procedure mWriteLn(var S: String); - var Len: Integer; - begin - //Write Length of String - Len := Length(S); - BlockWrite(F, Len, 4); + BlockRead(F, W, 2); + Cover[High(Cover)].W := W; - //Write String - BlockWrite(F, S[1], Len); - end; -begin - Result := WriteHeader(ReWriteCache); + BlockRead(F, H, 2); + Cover[High(Cover)].H := H; - If (Result) then - begin - try - //Read Header - AssignFile(F, Filename); - try - Reset(F); + BlockRead(F, Bits, 1); - Seek(F, Header.IndexStart); - //Write Header - IndexHeader.Indicator := cCC_IndexIndicator; - IndexHeader.HighestID := HighestID; + Cover[High(Cover)].Size := W * H * (Bits div 8); - BlockWrite(F, IndexHeader, SizeOf(TCC_FileIndexHeader)); + // test + // W := 128; + // H := 128; + // Bits := 24; + // Seek(F, FilePos(F) + 3); - Count := 0; - Result := True; + BlockRead(F, NLen, 2); + SetLength(Name, NLen); - //Prepare Footer - Index[HighestID + 1].FileIndex.DataStart := High(Cardinal); + BlockRead(F, Name[1], NLen); + Cover[High(Cover)].Name := Name; - // Write Fileinfo - For I := 0 to HighestID+1 do - begin - BlockWrite(F, Index[I].FileIndex, SizeOf(TCC_FileIndex)); - If (I <= HighestID) then - mWriteLn(Index[I].Filename); - end; + Cover[High(Cover)].Position := FilePos(F); + Seek(F, FilePos(F) + W*H*(Bits div 8)); - IndexNeedRewrite := False; + // SetLength(Cover[High(Cover)].Data, W*H*(Bits div 8)); + // BlockRead(F, Cover[High(Cover)].Data[0], W*H*(Bits div 8)); - finally - CloseFile(F); - end; - except - Result := False; - end; - end; + end; // While + + CloseFile(F); + end; // fileexists end; -//-------- -// Writes some Texture Data to the End of TextureData Block -//-------- -Function TCovers.AddTexData(Data: PCC_TextureData): Cardinal; +procedure TCovers.Save; var - F: File of Byte; + F: File; + C: integer; // cover number + W: word; + H: word; + NLen: word; + Bits: byte; begin - try - AssignFile(F, Filename); - try - Reset(F); - Seek(F, Header.DataStart + Header.DataLength); - - BlockWrite(F, Data^, SizeOf(TCC_TextureData)); - - Result := Header.DataStart + Header.DataLength; - Inc(Header.DataLength, SizeOf(TCC_TextureData)); - - Header.IndexStart := Header.DataStart + Header.DataLength + 1; - IndexNeedReWrite := True; - finally - CloseFile(F); - end; - except - Result := 0; +{ AssignFile(F, GamePath + 'covers.cache'); + Rewrite(F, 1); + + Bits := 24; + for C := 0 to High(Cover) do begin + W := Cover[C].W; + H := Cover[C].H; + + BlockWrite(F, W, 2); + BlockWrite(F, H, 2); + BlockWrite(F, Bits, 1); + + NLen := Length(Cover[C].Name); + BlockWrite(F, NLen, 2); + BlockWrite(F, Cover[C].Name[1], NLen); + BlockWrite(F, Cover[C].Data[0], W*H*(Bits div 8)); end; + + CloseFile(F);} end; -procedure TCovers.Load(const Filename: String); +procedure TCovers.AddCover(Name: string); var - Succeed: Boolean; + B: integer; + F: File; + C: integer; // cover number + NLen: word; + Bits: byte; begin - Log.LogError('TCovers: Load cache from file: ''' + Filename + ''''); - - Self.Filename := Filename; - Succeed := False; - If (FileExists(Filename)) then + if not CoverExists(Name) then begin - CacheReadOnly := FileisReadOnly(Filename); - If (ReadHeader) then - begin //Header successful read - If (ReadIndex) then + SetLength(Cover, Length(Cover)+1); + Cover[High(Cover)].Name := Name; + + Cover[High(Cover)].W := W; + Cover[High(Cover)].H := H; + Cover[High(Cover)].Size := Size; + + // do not copy data. write them directly to file +// SetLength(Cover[High(Cover)].Data, Size); +// for B := 0 to Size-1 do +// Cover[High(Cover)].Data[B] := CacheMipmap[B]; + + if WritetoFile then + begin + AssignFile(F, GamePath + 'covers.cache'); + + if FileExists(GamePath + 'covers.cache') then begin - Succeed := True; + Reset(F, 1); + Seek(F, FileSize(F)); + end + else + begin + Rewrite(F, 1); end; - end; - end; - If not Succeed and not CacheReadOnly then - If not (ReWriteCache) then - begin - CacheReadOnly := True; - Log.LogError('TCovers: Cache readonly!'); - end; -end; + Bits := 24; -Function TCovers.AddCover(FileName: string): Integer; -var I: Integer; -begin - Result := CoverExists(Filename); - If (Result = -1) then - begin //Add Cover(Does not exist) - Log.LogError('TCovers: Adding cover: ''' + Filename + ''''); - If (Count <= HighestID) then - begin //There is an empty slot, Search It - Log.LogError('TCovers: Searching for Empty Slot'); - For I := 0 to HighestID do - If (Index[I].FileIndex.DataStart = 0) then - begin //Found that Slot - Result := I; - Break; - end; - end; + BlockWrite(F, W, 2); + BlockWrite(F, H, 2); + BlockWrite(F, Bits, 1); - If (Result = -1) then - begin //Attach it to the End - Log.LogError('TCovers: Attach Cover to the end'); - Inc(HighestID); - SetLength(Index, HighestID + 2); - Result := HighestID; - end; + NLen := Length(Name); + BlockWrite(F, NLen, 2); + BlockWrite(F, Name[1], NLen); - Index[Result].Filename := Filename; - Index[Result].TexID := -1; - Index[Result].FileIndex.DataStart := 1; - Log.LogError('TCovers: Cover Added, ID: ' + InttoStr(Result)); - end - else - begin //Check if File has Changed - If (Index[Result].FileIndex.LastUpdated < 0) then - begin + Cover[High(Cover)].Position := FilePos(F); + BlockWrite(F, CacheMipmap[0], W*H*(Bits div 8)); + CloseFile(F); end; - end; + end + else + Cover[High(Cover)].Position := 0; end; -Function TCovers.CoverExists(FileName: string): integer; +function TCovers.CoverExists(Name: string): boolean; var - I: integer; + C: integer; // cover begin - Result := -1; - {$IFDEF MSWINDOWS} - Filename := Uppercase(Filename); - {$ENDIF} - - For I := 0 to HighestID do + Result := false; + C := 0; + + while (C <= High(Cover)) and (Result = false) do begin - If (Index[I].FileIndex.DataStart <> 0) AND - {$IFDEF MSWINDOWS} - (Uppercase(Index[I].Filename) = Filename) - {$ELSE} - (Index[I].Filename = Filename) - {$ENDIF} then - begin - Result := I; - Exit; - end; + if Cover[C].Name = Name then + Result := true; + + Inc(C); end; end; -//-------- -// Deletes old cover.cache file and writes new one -//-------- -Function TCovers.ReWriteCache: Boolean; - - Function MakeHash: TCC_Hash; - const AlphaNumeric: Array[0..35] of Char = ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); - var I: Integer; - begin - For I := Low(Result) to High(Result) do - Result[I] := AlphaNumeric[Random(Length(AlphaNumeric))]; - end; +function TCovers.CoverNumber(Name: string): integer; +var + C: integer; begin - If not CacheReadOnly then + Result := -1; + C := 0; + + while (C <= High(Cover)) and (Result = -1) do begin - Log.LogError('TCovers: Rewriting Cache'); - - Header.FileTyp := cCC_HeaderText; - Header.Version := cCC_HeaderVersion; - Header.Hash := MakeHash; - Header.CoverW := cCC_CoverW; - Header.CoverH := cCC_CoverH; - Header.DataStart := SizeOf(TCC_FileHeader) + 4; //Total of 64 Bytes (4 Bytes Space) - Header.DataLength := 0; - Header.IndexStart := Header.DataStart + Header.DataLength + 4; - - HighestID := -1; - SetLength(Index, HighestID + 2); - - Result := WriteIndex(True); - end - else - Result := False; + if Cover[C].Name = Name then + Result := C; + + Inc(C); + end; end; -procedure TCovers.PrepareData(FileName: string); +procedure TCovers.PrepareData(Name: string); var F: File; C: integer; @@ -533,113 +253,12 @@ begin AssignFile(F, GamePath + 'covers.cache'); Reset(F, 1); - C := CoverExists(FileName); + C := CoverNumber(Name); SetLength(Data, Cover[C].Size); - if Length(Data) < 6 then - Log.LogStatus('Length(Data) < 6', 'TCovers.PrepareData'); Seek(F, Cover[C].Position); BlockRead(F, Data[0], Cover[C].Size); CloseFile(F); end; end; -Procedure TCovers.LoadTextures; -var - I: Integer; - TexData: PCC_TextureData; - CachedData: TCC_TextureData; - F: File of Byte; - - Function LoadCover: Integer; - begin - Result := -1; - - If (Index[I].FileIndex.DataStart = 1) then - begin //This Texture is new and has to be loaded - TexData := Texture.GetCoverThumbnail(Index[I].Filename); - If (TexData <> nil) then - begin - If not (CacheReadonly) then - begin //Save this Tex to Cache - Index[I].FileIndex.DataStart := AddTexData(TexData); - If (Index[I].FileIndex.DataStart = 0) then - begin - CacheReadOnly := True; //Failed to write Data - Log.LogError('Failed to Write TextureData to Cache'); - end; - end; - - //Create Texture - glGenTextures(1, @Result); - - glBindTexture(GL_TEXTURE_2D, Result); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - //glTexImage2D(GL_TEXTURE_2D, 0, 3, cCC_CoverW, cCC_CoverH, 0, GL_RGB, GL_UNSIGNED_BYTE, Data); - glTexImage2D(GL_TEXTURE_2D, 0, 3, cCC_CoverW, cCC_CoverH, 0, GL_RGB, GL_UNSIGNED_BYTE, TexData); - end - else - Log.LogError('Couldn''t get Thumbnail Data'); - end - Else If (Index[I].FileIndex.DataStart > 1) then - begin //This texture is already in Cache, Load it from there - try - Log.LogError('TCovers: Loading Cover #' + InttoStr(I) + ' from Cache at Position: ' + InttoStr(Index[I].FileIndex.DataStart)); - Assign(F, Filename); - try - Reset(F); - Seek(F, Index[I].FileIndex.DataStart); - BlockRead(F, CachedData, SizeOf(TCC_TextureData)); - finally - CloseFile(F); - end; - - - //Create Texture - glGenTextures(1, @Result); - - if (Result > 0) then - begin - - glBindTexture(GL_TEXTURE_2D, Result); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - //glTexImage2D(GL_TEXTURE_2D, 0, 3, cCC_CoverW, cCC_CoverH, 0, GL_RGB, GL_UNSIGNED_BYTE, Data); - glTexImage2D(GL_TEXTURE_2D, 0, 3, cCC_CoverW, cCC_CoverH, 0, GL_RGB, GL_UNSIGNED_BYTE, @CachedData[0]); - end - else - Log.LogError('TCovers: Error Generating Texture'); - except - Log.LogError('TCovers: Error during loading'); - end; - end; - end; -begin - Texture.SetCoverSize(cCC_CoverW, cCC_CoverH); - Log.LogError('TCovers: LoadingTextures'); - - For I := 0 to HighestID do - begin //Load all the Covers - If (Index[I].FileIndex.DataStart > 0) then - Index[I].TexID := LoadCover; //No empty SLot -> Load the Texture - - Log.LogError('TCovers: Texture for ID#' + InttoStr(I) + ': ' + InttoStr(Index[I].TexID)); - end; - - If IndexNeedRewrite then - WriteIndex; -end; - -Function TCovers.GetTexbyID(ID: Cardinal): Integer; -begin - If (ID <= HighestID) then - Result := Index[ID].TexID - else - Result := -1; -end; - end. diff --git a/Game/Code/Classes/UDataBase.pas b/Game/Code/Classes/UDataBase.pas index ee0ca94b..dcf32315 100644 --- a/Game/Code/Classes/UDataBase.pas +++ b/Game/Code/Classes/UDataBase.pas @@ -35,106 +35,28 @@ type TimesSungtot: Word); end; AStatResult = Array of TStatResult; - - PDBSongInfo = ^TDBSongInfo; - TDBSongInfo = record - FileName: String; - FolderID: Integer; - FullPath: String; - LastChanged: Integer; //TimeStamp - - //Required Information - Artist: widestring; - Title: widestring; - - Mp3: widestring; - - //Some Files - Cover: widestring; //Path to Cover - CoverID: Integer; //ID of Cover in Covers Cache - Video: widestring; - VideoGAP: real; - - - //Additional Information - Start: real; // in seconds - - //Sorting - Genre: widestring; - Edition: widestring; - Language: widestring; - Year: widestring; - Creator: widestring; - TimesPlayed:Word; - end; - - TSongListInfo = record //SongInfo used by Songscreen - ID: Integer; - Title: widestring; - Artist: widestring; - - Mp3: widestring; - Video: widestring; - CoverID: Integer; //Cover ID in CoversCache - end; - ASongList = Array of TSongListInfo; - - TSongListFilter = record - Field: Byte; //FieldID //See constants below - isSearch: Boolean; //Search Mask(true) or exact Match(False) - Filter: String; - end; - ASongListFilter = Array of TSongListFilter; - + TDataBaseSystem = class private ScoreDB: TSqliteDatabase; sFilename: string; - UpdateFromVer1: Boolean; - + public property Filename: String read sFilename; - + Destructor Free; Procedure Init(const Filename: string); - Function ReadScore(const Song: Integer; const Difficulty: Byte): AScore; - procedure AddScore(Song: Integer; Level: integer; Name: string; Score: integer); - procedure WriteScore(Song: Integer); - - Function GetIDbyPath(const Path: String): Integer; - Function GetIDbyFileName(const Filename: String; FolderID: Integer): Integer; - Function GetSongData(ID: Integer; const Info: PDBSongInfo): Boolean; - Function SetSongData(ID: Integer; const Info: PDBSongInfo): Boolean; - Function AddSong(ID: Integer; const Info: PDBSongInfo): Boolean; - Function GetLastChangedbyID(const Song: Integer): Integer; - Function GetLastChangedbyFileName(const Filename: String; FolderID: Integer): Integer; - - Function GetFolderIDbyPath(Path: String): Integer; - Function GetFolderIDbyName(const Name: String; ParentFolder: Integer): Integer; - - Function GetSongList(var List: ASongList; const Filter: ASongListFilter): Integer; + procedure ReadScore(var Song: TSong); + procedure AddScore(var Song: TSong; Level: integer; Name: string; Score: integer); + procedure WriteScore(var Song: TSong); Function GetStats(var Stats: AStatResult; const Typ, Count: Byte; const Page: Cardinal; const Reversed: Boolean): Boolean; Function GetTotalEntrys(const Typ: Byte): Cardinal; end; -const - //Filter FieldIDs - SLF_Edition = 0; - SLF_Genre = 1; - SLF_Language = 2; - SLF_Folder = 3; - SLF_Title = 4; - SLF_Artist = 5; - SLF_Year = 6; - SLF_Creator = 7; - SLF_Video = 8; //Songs w/ Video are returned - SLF_NoVideo = 9; //Songs w/o Video are returned - Max_FilterFieldID = SLF_NoVideo; - var DataBase: TDataBaseSystem; @@ -148,9 +70,6 @@ uses const cUS_Scores = 'us_scores'; cUS_Songs = 'us_songs'; - cUS_Info = 'us_info'; - cUS_Directories = 'us_directories'; - cDB_Version = '2.0.0'; //-------------------- //Create - Opens Database and Create Tables if not Exist @@ -161,79 +80,26 @@ begin debugWriteln( 'TDataBaseSystem.Init ('+Filename+') @ '+ floattostr( now() ) ); //Open Database - ScoreDB := TSqliteDatabase.Create( Filename ); - sFilename := Filename; - UpdateFromVer1 := False; + ScoreDB := TSqliteDatabase.Create( Filename ); + sFilename := Filename; try - //Check for Database Version - if not ScoreDB.TableExists( cUS_Info ) then - begin - If (ScoreDB.TableExists( cUS_Scores ) And ScoreDB.TableExists( cUS_Songs )) And (Not ScoreDB.TableExists( cUS_Directories )) then - begin //Update from a Ver. 1.0 - 1.0.1a Database - UpdateFromVer1 := True; //This table should be Updated from before Database ver 2.0 - ScoreDb.ExecSQL('ALTER TABLE `' + cUS_Songs + '` RENAME TO ''' + cUS_Songs + '_old'''); //Rename old Song Table, to achieve old SongIDs - debugWriteln( 'TDataBaseSystem.Init - Switched to "Update from DB Version 1" Mode' ); - end; - - //Create Info Table - ScoreDB.ExecSQL('CREATE TABLE `' + cUS_Info + '` ( `Ident` varchar(32) PRIMARY KEY, `Value` varchar(64) NOT NULL default '''');'); - - //Write Database Version to Table - ScoreDB.ExecSQL('INSERT INTO `' + cUS_Info + '` VALUES (''version'', ''' + cDB_Version + ''');'); - - debugWriteln( 'TDataBaseSystem.Init - CREATED US_Info' ); - end; - //Look for Tables => When not exist Create them - - if not ScoreDB.TableExists( cUS_Directories ) then - begin - ScoreDB.execsql('CREATE TABLE `' + cUS_Directories + '` ( `ID` integer NOT NULL PRIMARY KEY AUTOINCREMENT, `Name` varchar(255) NOT NULL default '''', `FullPath` text NOT NULL, `LastChange` int(10) NOT NULL default ''0'');'); - - //Add Root Directory - ScoreDB.ExecSQL('INSERT INTO `us_directories` VALUES (1, ''root'', '''', ''0'');'); - - debugWriteln( 'TDataBaseSystem.Init - CREATED US_Directories' ); - end; - if not ScoreDB.TableExists( cUS_Scores ) then begin - ScoreDB.execsql('CREATE TABLE `'+cUS_Scores+'` (`SongID` INT( 10 ) NOT NULL , `Difficulty` INT( 1 ) NOT NULL , `Player` VARCHAR( 150 ) NOT NULL , `Score` INT( 5 ) NOT NULL );'); - + ScoreDB.execsql('CREATE TABLE `'+cUS_Scores+'` (`SongID` INT( 11 ) NOT NULL , `Difficulty` INT( 1 ) NOT NULL , `Player` VARCHAR( 150 ) NOT NULL , `Score` INT( 5 ) NOT NULL );'); debugWriteln( 'TDataBaseSystem.Init - CREATED US_Scores' ); end; if not ScoreDB.TableExists( cUS_Songs ) then begin - // Old 1.0 Style: ScoreDB.execsql('CREATE TABLE `'+cUS_Songs+'` (`ID` INTEGER PRIMARY KEY, `Artist` VARCHAR( 255 ) NOT NULL , `Title` VARCHAR( 255 ) NOT NULL , `TimesPlayed` int(5) NOT NULL );'); - //New: Dataabse 2.0 Style - ScoreDb.ExecSQL('CREATE TABLE `' + cUS_Songs + '` ( ' + - '`ID` integer PRIMARY KEY AUTOINCREMENT, ' + - '`Filename` varchar(255) NOT NULL default '''', ' + - '`FolderID` int(10) NOT NULL default ''0'', ' + - '`FullPath` text NOT NULL, ' + - '`LastChanged` int(10) NOT NULL default ''0'', ' + - '`Artist` varchar(255) NOT NULL default '''', ' + - '`Title` varchar(255) NOT NULL default '''', ' + - '`Mp3` text NOT NULL, ' + - '`Cover` text NOT NULL, ' + - '`CoverID` int(10) NOT NULL default ''0'', ' + - '`Video` text NOT NULL, ' + - '`VideoGap` float NOT NULL default ''0'', ' + - '`Start` float NOT NULL default ''0'', ' + - '`Genre` varchar(255) NOT NULL default '''', ' + - '`Edition` varchar(255) NOT NULL default '''', ' + - '`Language` varchar(255) NOT NULL default '''', ' + - '`Year` varchar(255) NOT NULL default '''', ' + - '`Creator` varchar(255) NOT NULL default '''', ' + - '`TimesPlayed` int(5) NOT NULL default ''0'');'); - - //Delete Score Table to avoid wrong IDS - ScoreDb.ExecSQL('DELETE FROM `' + cUS_Scores + '`'); - + ScoreDB.execsql('CREATE TABLE `'+cUS_Songs+'` (`ID` INTEGER PRIMARY KEY, `Artist` VARCHAR( 255 ) NOT NULL , `Title` VARCHAR( 255 ) NOT NULL , `TimesPlayed` int(5) NOT NULL );'); debugWriteln( 'TDataBaseSystem.Init - CREATED US_Songs' ); end; + + //Not possible because of String Limitation to 255 Chars //Need to rewrite Wrapper + {if not ScoreDB.TableExists('US_SongCache') then + ScoreDB.ExecSQL('CREATE TABLE `US_SongCache` (`Path` VARCHAR( 255 ) NOT NULL , `Filename` VARCHAR( 255 ) NOT NULL , `Title` VARCHAR( 255 ) NOT NULL , `Artist` VARCHAR( 255 ) NOT NULL , `Folder` VARCHAR( 255 ) NOT NULL , `Genre` VARCHAR( 255 ) NOT NULL , `Edition` VARCHAR( 255 ) NOT NULL , `Language` VARCHAR( 255 ) NOT NULL , `Creator` VARCHAR( 255 ) NOT NULL , `Cover` VARCHAR( 255 ) NOT NULL , `Background` VARCHAR( 255 ) NOT NULL , `Video` VARCHAR( 255 ) NOT NULL , `VideoGap` FLOAT NOT NULL , `Gap` FLOAT NOT NULL , `Start` FLOAT NOT NULL , `Finish` INT( 11 ) NOT NULL , `BPM` INT( 5 ) NOT NULL , `Relative` BOOLEAN NOT NULL , `NotesGap` INT( 11 ) NOT NULL);');} finally @@ -257,102 +123,109 @@ end; //-------------------- //ReadScore - Read Scores into SongArray //-------------------- -Function TDataBaseSystem.ReadScore(const Song: Integer; const Difficulty: Byte): AScore; +procedure TDataBaseSystem.ReadScore(var Song: TSong); var TableData: TSqliteTable; - I: Integer; + Difficulty: Integer; begin - if (assigned( ScoreDB )) AND (Difficulty < 2) then - begin + if not assigned( ScoreDB ) then + exit; + - //ScoreDB := TSqliteDatabase.Create(sFilename); + //ScoreDB := TSqliteDatabase.Create(sFilename); + try try - try - //Search Song in DB - TableData := ScoreDB.GetTable('SELECT `Player`, `Score` FROM `'+cUS_Scores+'` WHERE (`SongID` = ''' + InttoStr(Song) + ''') AND (`Difficulty` = ''' + InttoStr(Difficulty) + ''') ORDER BY `Score` DESC LIMIT 5'); - - - I := 0; - while not TableData.Eof do //Go through all Entrys - begin //Add one Entry to Array - Result[I].Name := - TableData.FieldAsString(TableData.FieldIndex['Player']); - Result[I].Score := - StrtoInt(TableData.FieldAsString(TableData.FieldIndex['Score'])); - - TableData.Next; - Inc(I); - end; // While not TableData.EOF - - If (I < 5) then - Result[1].Score := 0; //Place ending Zero - - except - Result[0].Name := 'Error Reading ScoreDB'; - Result[0].Score := -1; - Result[1].Score := 0; + //Search Song in DB + TableData := ScoreDB.GetTable('SELECT `Difficulty`, `Player`, `Score` FROM `'+cUS_Scores+'` WHERE `SongID` = (SELECT `ID` FROM `us_songs` WHERE `Artist` = "' + Song.Artist + '" AND `Title` = "' + Song.Title + '" LIMIT 1) ORDER BY `Score` DESC LIMIT 15'); + + //Empty Old Scores + SetLength (Song.Score[0], 0); + SetLength (Song.Score[1], 0); + SetLength (Song.Score[2], 0); + + while not TableData.Eof do //Go through all Entrys + begin //Add one Entry to Array + Difficulty := StrToIntDef(TableData.FieldAsString(TableData.FieldIndex['Difficulty']), -1); + if (Difficulty >= 0) AND (Difficulty <= 2) then + begin + SetLength(Song.Score[Difficulty], Length(Song.Score[Difficulty]) + 1); + + Song.Score[Difficulty, high(Song.Score[Difficulty])].Name := + TableData.FieldAsString(TableData.FieldIndex['Player']); + Song.Score[Difficulty, high(Song.Score[Difficulty])].Score := + StrtoInt(TableData.FieldAsString(TableData.FieldIndex['Score'])); end; + TableData.Next; + + end; // While not TableData.EOF - finally - //ScoreDb.Free; + except + for Difficulty := 0 to 2 do + begin + SetLength(Song.Score[Difficulty], 1); + Song.Score[Difficulty, 1].Name := 'Error Reading ScoreDB'; + end; end; + + finally + //ScoreDb.Free; end; end; //-------------------- //AddScore - Add one new Score to DB //-------------------- -procedure TDataBaseSystem.AddScore(Song: Integer; Level: integer; Name: string; Score: integer); +procedure TDataBaseSystem.AddScore(var Song: TSong; Level: integer; Name: string; Score: integer); var ID: Integer; TableData: TSqliteTable; begin - if assigned( ScoreDB ) then + if not assigned( ScoreDB ) then + exit; + + //ScoreDB := TSqliteDatabase.Create(sFilename); + try + //Prevent 0 Scores from being added + if (Score > 0) then begin - //ScoreDB := TSqliteDatabase.Create(sFilename); - try - //Prevent 0 Scores from being added - if (Score > 0) then - begin - {ID := ScoreDB.GetTableValue('SELECT `ID` FROM `'+cUS_Songs+'` WHERE `Artist` = "' + Song.Artist + '" AND `Title` = "' + Song.Title + '"'); - if ID = 0 then //Song doesn't exist -> Create - begin - ScoreDB.ExecSQL ('INSERT INTO `'+cUS_Songs+'` ( `ID` , `Artist` , `Title` , `TimesPlayed` ) VALUES (NULL , "' + Song.Artist + '", "' + Song.Title + '", "0");'); - ID := ScoreDB.GetTableValue('SELECT `ID` FROM `US_Songs` WHERE `Artist` = "' + Song.Artist + '" AND `Title` = "' + Song.Title + '"'); - if ID = 0 then //Could not Create Table - exit; - end; } - //Create new Entry - ScoreDB.ExecSQL('INSERT INTO `'+cUS_Scores+'` ( `SongID` , `Difficulty` , `Player` , `Score` ) VALUES ("' + InttoStr(Song) + '", "' + InttoStr(Level) + '", "' + Name + '", "' + InttoStr(Score) + '");'); - - //Delete Last Position when there are more than 5 Entrys - if ScoreDB.GetTableValue('SELECT COUNT(`SongID`) FROM `'+cUS_Scores+'` WHERE `SongID` = "' + InttoStr(ID) + '" AND `Difficulty` = "' + InttoStr(Level) +'"') > 5 then - begin - TableData := ScoreDB.GetTable('SELECT `Player`, `Score` FROM `'+cUS_Scores+'` WHERE SongID = "' + InttoStr(ID) + '" AND `Difficulty` = "' + InttoStr(Level) +'" ORDER BY `Score` ASC LIMIT 1'); - ScoreDB.ExecSQL('DELETE FROM `US_Scores` WHERE SongID = "' + InttoStr(ID) + '" AND `Difficulty` = "' + InttoStr(Level) +'" AND `Player` = "' + TableData.FieldAsString(TableData.FieldIndex['Player']) + '" AND `Score` = "' + TableData.FieldAsString(TableData.FieldIndex['Score']) + '"'); - end; + ID := ScoreDB.GetTableValue('SELECT `ID` FROM `'+cUS_Songs+'` WHERE `Artist` = "' + Song.Artist + '" AND `Title` = "' + Song.Title + '"'); + if ID = 0 then //Song doesn't exist -> Create + begin + ScoreDB.ExecSQL ('INSERT INTO `'+cUS_Songs+'` ( `ID` , `Artist` , `Title` , `TimesPlayed` ) VALUES (NULL , "' + Song.Artist + '", "' + Song.Title + '", "0");'); + ID := ScoreDB.GetTableValue('SELECT `ID` FROM `US_Songs` WHERE `Artist` = "' + Song.Artist + '" AND `Title` = "' + Song.Title + '"'); + if ID = 0 then //Could not Create Table + exit; + end; + //Create new Entry + ScoreDB.ExecSQL('INSERT INTO `'+cUS_Scores+'` ( `SongID` , `Difficulty` , `Player` , `Score` ) VALUES ("' + InttoStr(ID) + '", "' + InttoStr(Level) + '", "' + Name + '", "' + InttoStr(Score) + '");'); - end; - finally - //ScoreDB.Free; + //Delete Last Position when there are more than 5 Entrys + if ScoreDB.GetTableValue('SELECT COUNT(`SongID`) FROM `'+cUS_Scores+'` WHERE `SongID` = "' + InttoStr(ID) + '" AND `Difficulty` = "' + InttoStr(Level) +'"') > 5 then + begin + TableData := ScoreDB.GetTable('SELECT `Player`, `Score` FROM `'+cUS_Scores+'` WHERE SongID = "' + InttoStr(ID) + '" AND `Difficulty` = "' + InttoStr(Level) +'" ORDER BY `Score` ASC LIMIT 1'); + ScoreDB.ExecSQL('DELETE FROM `US_Scores` WHERE SongID = "' + InttoStr(ID) + '" AND `Difficulty` = "' + InttoStr(Level) +'" AND `Player` = "' + TableData.FieldAsString(TableData.FieldIndex['Player']) + '" AND `Score` = "' + TableData.FieldAsString(TableData.FieldIndex['Score']) + '"'); end; + + end; + finally + //ScoreDB.Free; end; end; //-------------------- //WriteScore - Not needed with new System; But used for Increment Played Count //-------------------- -procedure TDataBaseSystem.WriteScore(Song: Integer); +procedure TDataBaseSystem.WriteScore(var Song: TSong); begin if not assigned( ScoreDB ) then - begin - try - //Increase TimesPlayed - ScoreDB.ExecSQL ('UPDATE `'+cUS_Songs+'` SET `TimesPlayed` = `TimesPlayed` + ''1'' WHERE `ID` = ''' + InttoStr(Song) + ''';'); - except + exit; + + try + //Increase TimesPlayed + ScoreDB.ExecSQL ('UPDATE `'+cUS_Songs+'` SET `TimesPlayed` = `TimesPlayed` + "1" WHERE `Title` = "' + Song.Title + '" AND `Artist` = "' + Song.Artist + '";'); + except - end; end; end; @@ -496,103 +369,4 @@ begin end; -Function TDataBaseSystem.GetIDbyPath(const Path: String): Integer; -begin - -end; - -Function TDataBaseSystem.GetIDbyFileName(const Filename: String; FolderID: Integer): Integer; -begin - try - Result := ScoreDB.GetTableValue('SELECT `ID` FROM `' + cUS_Songs + '` WHERE (`Filename` = ''' + Filename + ''') AND (`FolderID` = ''' + InttoStr(FolderID) + ''')'); - except - Result := 0; - end; -end; - -Function TDataBaseSystem.GetSongData(ID: Integer; const Info: PDBSongInfo): Boolean; -var - TableData: TSqliteTable; -begin - Result := True; - try - TableData := ScoreDB.GetTable('SELECT Filename`, `FolderID`, `FullPath`, `LastChanged`, `Artist`, `Title`, `Mp3`, `Cover`, `CoverID`, `Video`, `VideoGap`, `Start`, `Genre`, `Edition`, `Language`, `Year`, `Creator`, `TimesPlayed` FROM `' + cUS_Songs + '` WHERE `ID` = ''' + InttoStr(ID) + ''' '); - If (TableData.RowCount > 0) then //All Fieldnames are listed to ensure Field order - begin // - Info^.FileName := TableData.Fields[0]; - Info^.FolderID := StrToIntDef(TableData.Fields[1], -1); - Info^.FullPath := TableData.Fields[2]; - Info^.LastChanged := StrToIntDef(TableData.Fields[3], 0); - Info^.Artist := TableData.Fields[4]; - Info^.Title := TableData.Fields[5]; - Info^.Mp3 := TableData.Fields[6]; - Info^.Cover := TableData.Fields[7]; - Info^.CoverID := StrToIntDef(TableData.Fields[8], -1); - Info^.Video := TableData.Fields[9]; - Info^.VideoGAP := StrToFloatDef(TableData.Fields[10], 0); - Info^.Start := StrToFloatDef(TableData.Fields[11], 0); - Info^.Genre := TableData.Fields[12]; - Info^.Edition := TableData.Fields[13]; - Info^.Language := TableData.Fields[14]; - Info^.Year := TableData.Fields[15]; - Info^.Creator := TableData.Fields[16]; - Info^.TimesPlayed := StrToIntDef(TableData.Fields[17], 0); - end; - except - Result := False; - end; -end; - -Function TDataBaseSystem.AddSong(ID: Integer; const Info: PDBSongInfo): Boolean; -var - OldID: Integer; -begin - Result := True; - try - ScoreDB.ExecSQL('INSERT INTO `us_songs` ( `ID` , `Filename` , `FolderID` , `FullPath` , `LastChanged` , `Artist` , `Title` , `Mp3` , `Cover` , `CoverID` , `Video` , `VideoGap` , `Start` , `Genre` , `Edition` , `Language` , `Year` , `Creator` , `TimesPlayed` ) ' + - 'VALUES ( '''', '''+ Info^.FileName +''', '''+ InttoStr(Info^.FolderID) +''', '''+ Info^.FullPath +''', '''+ InttoStr(Info^.LastChanged) +''', '''+ Info^.Artist +''', '''+ Info^.Title +''', '''+ Info^.Mp3 +''', '''+ Info^.Cover +''', '''+ InttoStr(Info^.CoverID) +''', '''+ Info^.Video + ''', '''+ FloattoStr(Info^.VideoGAP) + ''', '''+ FloattoStr(Info^.Start) +''', '''+ Info^.Genre +''', '''+ Info^.Edition +''', '''+ Info^.Language +''', '''+ Info^.Year +''', '''+ Info^.Creator +''', ''0'');'); - - //Version 1.0 to 2.0 Update - If UpdateFromVer1 then - begin //Search for Song w/ same Artist and Title in Old DB - OldID := ScoreDB.GetTableValue('SELECT `ID` FROM `US_Songs` WHERE `Artist` = "' + Info^.Artist + '" AND `Title` = "' + Info^.Title + '"'); - end; - except - Result := False; - end; -end; - -Function TDataBaseSystem.SetSongData(ID: Integer; const Info: PDBSongInfo): Boolean; -begin - -end; - -Function TDataBaseSystem.GetLastChangedbyID(const Song: Integer): Integer; -begin - -end; - -Function TDataBaseSystem.GetLastChangedbyFileName(const Filename: String; FolderID: Integer): Integer; -begin - -end; - - -Function TDataBaseSystem.GetFolderIDbyPath(Path: String): Integer; -begin - -end; - -Function TDataBaseSystem.GetFolderIDbyName(const Name: String; ParentFolder: Integer): Integer; -begin - -end; - - -Function TDataBaseSystem.GetSongList(var List: ASongList; const Filter: ASongListFilter): Integer; -begin - -end; - - end. diff --git a/Game/Code/Classes/UGraphic.pas b/Game/Code/Classes/UGraphic.pas index 90772ca8..afb986e1 100644 --- a/Game/Code/Classes/UGraphic.pas +++ b/Game/Code/Classes/UGraphic.pas @@ -253,7 +253,6 @@ uses UMain, UIni, UDisplay, UCommandLine, - UCovers, {$IFNDEF FPC} Graphics, {$ENDIF} @@ -539,8 +538,7 @@ begin // the mainthread have to know somehow what opengl function have to be called with which parameters like // texturetype, textureobjekt, textur-buffer-adress, ... - //Load Covers from Cache and new added/ Updated Covers - Covers.LoadTextures; + // wait for loading thread to finish // funktioniert so auch noch nicht - currently dos not work this way diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas index 22aa4ad6..f5e1250f 100644 --- a/Game/Code/Classes/UMain.pas +++ b/Game/Code/Classes/UMain.pas @@ -234,7 +234,7 @@ begin // Covers Cache Log.BenchmarkStart(1); Log.LogStatus('Creating Covers Cache', 'Initialization'); - Covers := TCovers.Create('covers.cache'); + Covers := TCovers.Create; Log.LogBenchmark('Loading Covers Cache Array', 1); Log.BenchmarkStart(1); diff --git a/Game/Code/Classes/UPlaylist.pas b/Game/Code/Classes/UPlaylist.pas index c05460cf..4f181d73 100644 --- a/Game/Code/Classes/UPlaylist.pas +++ b/Game/Code/Classes/UPlaylist.pas @@ -267,13 +267,13 @@ begin exit; //Hide all Songs - {For I := 0 to high(CatSongs.Song) do - CatSongs.Song[I].Visible := False;} + For I := 0 to high(CatSongs.Song) do + CatSongs.Song[I].Visible := False; //Show Songs in PL For I := 0 to high(PlayLists[Index].Items) do begin - //CatSongs.Song[PlayLists[Index].Items[I].SongID].Visible := True; + CatSongs.Song[PlayLists[Index].Items[I].SongID].Visible := True; end; //Set CatSongsMode + Playlist Mode @@ -335,8 +335,8 @@ Procedure TPlayListManager.DelPlaylist(const Index: Cardinal); var I: Integer; Filename: String; -begin // to - do : new Song management - {If Int(Index) > High(Playlists) then +begin + If Int(Index) > High(Playlists) then Exit; Filename := PlaylistPath + Playlists[Index].Filename; @@ -368,7 +368,7 @@ begin // to - do : new Song management ScreenSong.Interaction := 0; ScreenSong.FixSelected; ScreenSong.ChangeMusic; - end; } + end; end; //---------- @@ -385,8 +385,8 @@ begin P := iPlaylist else exit; - // to - do : new Song management - {if (Int(SongID) <= High(CatSongs.Song)) AND (NOT CatSongs.Song[SongID].Main) then + + if (Int(SongID) <= High(CatSongs.Song)) AND (NOT CatSongs.Song[SongID].Main) then begin Len := Length(Playlists[P].Items); SetLength(Playlists[P].Items, Len + 1); @@ -401,7 +401,7 @@ begin //Correct Display when Editing current Playlist if (CatSongs.CatNumShow = -3) and (P = CurPlaylist) then SetPlaylist(P); - end; } + end; end; //---------- diff --git a/Game/Code/Classes/USong.pas b/Game/Code/Classes/USong.pas index d878132a..66169ef0 100644 --- a/Game/Code/Classes/USong.pas +++ b/Game/Code/Classes/USong.pas @@ -42,7 +42,13 @@ type StartBeat: real; end; - {TSong = class + TScore = record + Name: widestring; + Score: integer; + Length: string; + end; + + TSong = class FileLineNo : integer; //Line which is readed at Last, for error reporting procedure ParseNote(LineNumber: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string); @@ -105,88 +111,6 @@ type function Analyse(): boolean; function AnalyseXML(): boolean; procedure clear(); - end; } - - TScore = record - Name: widestring; - Score: integer; - Length: string; - end; - - AScore = Array[0..4] of TScore; - - {******************* - New TSong Class. - Containing some Methods for DB communication - but none for Song laoding, saving, these should be - implemented by child classes - *******************} - TSong = class - protected - SongID: Integer; //ID of this Song in the Song Database - FolderID: Integer; //ID of the Folder containing this Song - FileName: String; //Filename of this Song w/o Path - FilePath: String; //Path of this Song - - Procedure ResetAttributes; virtual; //Reset all Attributes of this object - Procedure ReadHeader; virtual; abstract; //Reads Fileheader (Implemented by Child only) - Procedure ReadFile; virtual; abstract; //Reads complete File (Header + Notes) (Implemented by Child only) - Procedure WriteFile; virtual; abstract; //Writes complete File (Header + Notes) (Implemented by Child only) - Procedure ReadFromDB; virtual; //Reads all available Information from DB - Function CheckDB: Integer; virtual; //Checks DB for Song. Result > 0 SongExists (ID Returned) - Function UpdateDB: Integer; virtual; //Writes all Header Information set in this Song Object to DB. Returns ID (Required when Updated first Time) - - // procedures to manage the lyrics - Procedure ResetLyrics; - Procedure AddLyricLine(const PlayerID: Integer; const StartBeat: Integer; const RelativeBeat: Integer = -1); - Procedure AddNote(const PlayerID: Integer; const NoteType: Char; const NoteStart, NoteLength, NoteTone: Integer; const NoteText: WideString); - Function SolmizatLyrics(const NoteTone: Integer; const NoteText: WideString): WideString; - Procedure AddBPM(const StartBeat: Integer; const NewBeat: Extended); - public - //Required Information - Title: widestring; - Artist: widestring; - - Mp3: widestring; //Full Path to MP3 - - Creator: widestring; - - Resolution: integer; - BPM: array of TBPM; - GAP: real; // in miliseconds - - Base : array[0..1] of integer; - Mult : integer; - MultBPM : integer; - - //Some Files - Cover: widestring; //Full Path to Cover - CoverID: Integer; //ID of Cover in Covers Cache - Background: widestring; //Full Path to BG - Video: widestring; //Full Path to Video - VideoGAP: real; - - - //Additional Information - NotesGAP: integer; - Start: real; // in seconds - Finish: integer; // in miliseconds - Relative: boolean; - - //Sorting - Genre: widestring; - Edition: widestring; - Language: widestring; - - - constructor Create(const Path: String = ''; const FolderID: Integer = 0); - Procedure LoadbyFile(const Path: String); - Procedure LoadbyID(const ID: Integer); - Procedure SavetoFile(const Filename: String = ''); - - Function Score(const Difficulty: Byte): AScore; - - Procedure Clear; end; implementation @@ -194,288 +118,10 @@ implementation uses TextGL, UIni, - UMusic; //needed for Lines - -var - RelativPosition: array [0..1] of Integer; - -constructor TSong.Create(const Path: String = ''; const FolderID: Integer = 0); -begin - If (Length(Path) > 0) AND (FolderID > 0) then - begin //Read Song Infos from File or DB - FilePath := ExtractFilePath(Path); - FileName := ExtractFileName(Path); - Self.FolderID := FolderID; - SongID := CheckDB; - - If (SongID = 0) then //Check if File has changed - begin - ResetAttributes; - ReadHeader; - SongID := UpdateDB; - //Get CoverID from Covers by Covers.AddCover(Coverscache checks if the Cover requires update - end; - end - else - begin - ResetAttributes; - end; -end; - -Procedure TSong.LoadbyFile(const Path: String); -begin - //Call all Functions to Load From File - //Set Song and Folder ID and Update DB if required - //Get CoverID from Covers by Covers.AddCover(Coverscache checks if the Cover requires update -end; - -Procedure TSong.LoadbyID(const ID: Integer); -begin - //Call all Functions to Load Song by ID - //Read all Information from file - //Get CoverID from Covers by Covers.AddCover(Coverscache checks if the Cover requires update -end; - -Procedure TSong.SavetoFile(const Filename: String = ''); -begin - //Save HeaderInformation and Notes to File. If File = '' use File that was read from -end; - -Function TSong.Score(const Difficulty: Byte): AScore; -begin - //Return Score of Difficulty(0..2) Easy to Difficult -end; - -Procedure TSong.Clear; -begin - ResetAttributes; -end; - -//-------- -// Reset all Attributes of this object -//-------- -Procedure TSong.ResetAttributes; -begin - SongID := 0; - FolderID := 0; - FileName := ''; - FilePath := ''; - - Title := ''; - Artist := ''; - Mp3 := ''; - SetLength(BPM, 0); - - Creator := ''; - Resolution := 0; - GAP := 0; - - Base[0] := 100; - Base[1] := 100; - - Mult := 1; - MultBPM := 4; - - Cover := ''; - CoverID := 0; - Background := ''; - Video := ''; - VideoGAP := 0; - - NotesGAP := 0; - Start := 0; - Finish := 0; - Relative := False; - - Genre := ''; - Edition := ''; - Language := ''; -end; - -//-------- -// Reads all available Information from DB -//-------- -Procedure TSong.ReadFromDB; -begin - // to- do -end; - - -//-------- -// Checks DB for Song. Result > 0 SongExists (ID Returned) -//-------- -Function TSong.CheckDB: Integer; -begin - // to- do -end; - - -//-------- -// Writes all Header Information set in this Song Object to DB. Returns ID (Required when Updated first Time) -//-------- -Function TSong.UpdateDB: Integer; -begin - // to- do -end; - -Procedure TSong.ResetLyrics; -var - i: Integer; -begin - for i := 0 to High(Lines) do - begin - SetLength(Lines[i].Line, 0); - Lines[i].High := -1; - end; - - for i := 0 to High(RelativPosition) do - begin - RelativPosition[i] := 0; - end; -end; - -Procedure TSong.AddLyricLine(const PlayerID: Integer; const StartBeat: Integer; const RelativeBeat: Integer = -1); -var - NewLineIdx: Integer; -begin - NewLineIdx := High(Lines[PlayerID].Line) + 1; - - with Lines[PlayerID] do - begin - // recent added line is not the last of the song - if (NewLineIdx > 0) then - Lines[PlayerID].Line[NewLineIdx - 1].LastLine := False; - - // if last line, has no notes, ignore the new line (except for the RelativeBeat) - if (NewLineIdx < 1) OR (Lines[PlayerID].Line[NewLineIdx - 1].HighNote > -1) then - begin - // create lyric line and update references - SetLength(Line, NewLineIdx); - High := NewLineIdx; - Number := Number + 1; - with Line[High] do - begin - // default values - TotalNotes := 0; - HighNote := -1; - LastLine := True; - BaseNote := 100; - - // set start beat count of this new line - Start := (RelativPosition[PlayerID] + StartBeat) * Mult; - end; - end; - - if Relative then - begin - if RelativeBeat >= 0 then - // if this is a relativ song, we have to update the relativ offset - RelativPosition[PlayerID] := (RelativPosition[PlayerID] + RelativeBeat) * Mult - else - RelativPosition[PlayerID] := (RelativPosition[PlayerID] + StartBeat) * Mult; - end; - end; -end; - -Procedure TSong.AddNote(const PlayerID: Integer; const NoteType: Char; const NoteStart, NoteLength, NoteTone: Integer; const NoteText: WideString); -begin - if (High(Lines[PlayerID].Line) < 0) then - AddLyricLine(PlayerID, NoteStart, 0); - - with Lines[PlayerID].Line[Lines[PlayerID].High] do begin - // array of Notes expand to have space for new Note - HighNote := HighNote + 1; - TotalNotes := TotalNotes + 1; - SetLength(Note, HighNote + 1); - - with Note[HighNote] do - begin - Start := (RelativPosition[PlayerID] + NoteStart) * Mult; - Length := NoteLength * Mult; - Tone := NoteTone; - Text := SolmizatLyrics(NoteTone, NoteText); - Lyric := Lyric + Text; - - // identify lowest note of line - if Tone < BaseNote then - BaseNote := Tone; - end; - - case NoteType of - 'F': Note[HighNote].NoteType := ntFreestyle; - ':': Note[HighNote].NoteType := ntNormal; - '*': Note[HighNote].NoteType := ntGolden; - end; - - // calculate total score value - if (Note[HighNote].NoteType = ntNormal) then - begin - // normal notes - Lines[PlayerID].ScoreValue := Lines[PlayerID].ScoreValue + Note[HighNote].Length; - TotalNotes := TotalNotes + Note[HighNote].Length; - end - else if (Note[HighNote].NoteType = ntGolden) then - begin - // golden notes - Lines[PlayerID].ScoreValue := Lines[PlayerID].ScoreValue + (Note[HighNote].Length * 2); - TotalNotes := TotalNotes + (Note[HighNote].Length * 2); - end; - - // finish of the line - End_ := Note[HighNote].Start + Note[HighNote].Length; - end; // with -end; + UMusic, //needed for Lines + UMain; //needed for Player -Function TSong.SolmizatLyrics(const NoteTone: Integer; const NoteText: WideString): WideString; -begin - Result := NoteText; - - case Ini.Solmization of - 1: // european - case (NoteTone mod 12) of - 0..1: Result := 'do '; - 2..3: Result := 're '; - 4: Result := 'mi '; - 5..6: Result := 'fa '; - 7..8: Result := 'sol '; - 9..10: Result := 'la '; - 11: Result := 'si '; - end; - - 2: // japanese - case (NoteTone mod 12) of - 0..1: Result := 'do '; - 2..3: Result := 're '; - 4: Result := 'mi '; - 5..6: Result := 'fa '; - 7..8: Result := 'so '; - 9..10: Result := 'la '; - 11: Result := 'shi '; - end; - - 3: // american - case (NoteTone mod 12) of - 0..1: Result := 'do '; - 2..3: Result := 're '; - 4: Result := 'mi '; - 5..6: Result := 'fa '; - 7..8: Result := 'sol '; - 9..10: Result := 'la '; - 11: Result := 'ti '; - end; - end; // case Ini.Solmization -end; - -Procedure TSong.AddBPM(const StartBeat: Integer; const NewBeat: Extended); -begin - SetLength(BPM, Length(BPM) + 1); - BPM[High(BPM)].StartBeat := StartBeat; - BPM[High(BPM)].StartBeat := BPM[High(BPM)].StartBeat + RelativPosition[0]; - - BPM[High(BPM)].BPM := NewBeat * Mult * MultBPM; -end; - -{constructor TSong.create( const aFileName : WideString ); +constructor TSong.create( const aFileName : WideString ); begin Mult := 1; @@ -512,8 +158,7 @@ begin end; end; -} -(* + //Load TXT Song function TSong.LoadSong(): boolean; @@ -540,7 +185,7 @@ begin MultBPM := 4; // multiply beat-count of note by 4 Mult := 1; // accuracy of measurement of note Base[0] := 100; // high number - Lines[0].NoteType := 0; + Lines[0].ScoreValue := 0; self.Relative := false; Rel[0] := 0; CP := 0; @@ -589,7 +234,6 @@ begin Lines[Count].Current := 0; Lines[Count].Resolution := self.Resolution; Lines[Count].NotesGAP := self.NotesGAP; - Lines[Count].Line[0].IlNut := 0; Lines[Count].Line[0].HighNote := -1; Lines[Count].Line[0].LastLine := False; end; @@ -660,7 +304,11 @@ begin Lines[CP].Line[Lines[CP].High].TotalNotes := 0; for I := low(Lines[CP].Line[Lines[CP].High].Note) to high(Lines[CP].Line[Lines[CP].High].Note) do begin - Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[I].Length * Lines[CP].Line[Lines[CP].High].Note[I].NoteType; + if (Lines[CP].Line[Lines[CP].High].Note[I].NoteType = ntGolden) then + Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[I].Length; + + if (Lines[CP].Line[Lines[CP].High].Note[I].NoteType <> ntFreestyle) then + Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[I].Length; end; //Total Notes Patch End end else begin @@ -671,14 +319,17 @@ begin Lines[Count].Line[Lines[Count].High].TotalNotes := 0; for I := low(Lines[Count].Line[Lines[Count].High].Note) to high(Lines[Count].Line[Lines[Count].High].Note) do begin - Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[I].Length * Lines[Count].Line[Lines[Count].High].Note[I].NoteType; + if (Lines[Count].Line[Lines[Count].High].Note[I].NoteType = ntGolden) then + Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[I].Length; + if (Lines[Count].Line[Lines[Count].High].Note[I].NoteType <> ntFreestyle) then + Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[I].Length; end; //Total Notes Patch End end; end; Read(SongFile, TempC); Inc(FileLineNo); - end; // while} { + end; // while} for Count := 0 to High(Lines) do begin Lines[Count].Line[High(Lines[Count].Line)].LastLine := True; @@ -728,7 +379,7 @@ begin MultBPM := 4; // multiply beat-count of note by 4 Mult := 1; // accuracy of measurement of note Base[0] := 100; // high number - Lines[0].NoteType := 0; + Lines[0].ScoreValue := 0; self.Relative := false; Rel[0] := 0; CP := 0; @@ -739,7 +390,7 @@ begin Parser := TParser.Create; - Parser.Settings.DashReplacement := '~'; + Parser.Settings.DashReplacement := '~'; for Count := 0 to High(Lines) do begin @@ -749,7 +400,6 @@ begin Lines[Count].Current := 0; Lines[Count].Resolution := self.Resolution; Lines[Count].NotesGAP := self.NotesGAP; - Lines[Count].Line[0].IlNut := 0; Lines[Count].Line[0].HighNote := -1; Lines[Count].Line[0].LastLine := False; end; @@ -757,38 +407,38 @@ begin //Try to Parse the Song If Parser.ParseSong(Path + PathDelim + FileName) then - begin -// Writeln('XML Inputfile Parsed succesful'); - //Start write parsed information to Song - //Notes Part - For I := 0 to High(Parser.SongInfo.Sentences) do - begin - //Add Notes - For J := 0 to High(Parser.SongInfo.Sentences[I].Notes) do - begin - Case Parser.SongInfo.Sentences[I].Notes[J].NoteTyp of - NT_Normal: NoteType := ':'; - NT_Golden: NoteType := '*'; - NT_Freestyle: NoteType := 'F'; - end; - - Param1:=Parser.SongInfo.Sentences[I].Notes[J].Start; //Note Start - Param2:=Parser.SongInfo.Sentences[I].Notes[J].Duration; //Note Duration - Param3:=Parser.SongInfo.Sentences[I].Notes[J].Tone; //Note Tone - ParamS:=' ' + Parser.SongInfo.Sentences[I].Notes[J].Lyric; //Note Lyric - - - if not Both then + begin +// Writeln('XML Inputfile Parsed succesful'); + //Start write parsed information to Song + //Notes Part + For I := 0 to High(Parser.SongInfo.Sentences) do + begin + //Add Notes + For J := 0 to High(Parser.SongInfo.Sentences[I].Notes) do + begin + Case Parser.SongInfo.Sentences[I].Notes[J].NoteTyp of + NT_Normal: NoteType := ':'; + NT_Golden: NoteType := '*'; + NT_Freestyle: NoteType := 'F'; + end; + + Param1:=Parser.SongInfo.Sentences[I].Notes[J].Start; //Note Start + Param2:=Parser.SongInfo.Sentences[I].Notes[J].Duration; //Note Duration + Param3:=Parser.SongInfo.Sentences[I].Notes[J].Tone; //Note Tone + ParamS:=' ' + Parser.SongInfo.Sentences[I].Notes[J].Lyric; //Note Lyric + + + if not Both then // P1 ParseNote(0, NoteType, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS) else begin // P1 + P2 ParseNote(0, NoteType, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS); ParseNote(1, NoteType, (Param1+Rel[1]) * Mult, Param2 * Mult, Param3, ParamS); - end; - - - if not Both then + end; + + + if not Both then begin Lines[CP].Line[Lines[CP].High].BaseNote := Base[CP]; Lines[CP].Line[Lines[CP].High].LyricWidth := glTextWidth(PChar(Lines[CP].Line[Lines[CP].High].Lyric)); @@ -796,7 +446,11 @@ If Parser.ParseSong(Path + PathDelim + FileName) then Lines[CP].Line[Lines[CP].High].TotalNotes := 0; for X := low(Lines[CP].Line[Lines[CP].High].Note) to high(Lines[CP].Line[Lines[CP].High].Note) do begin - Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[X].Length * Lines[CP].Line[Lines[CP].High].Note[X].NoteType; + if (Lines[CP].Line[Lines[CP].High].Note[I].NoteType = ntGolden) then + Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[X].Length; + + if (Lines[CP].Line[Lines[CP].High].Note[I].NoteType <> ntFreestyle) then + Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[X].Length; end; //Total Notes Patch End end else begin @@ -807,35 +461,39 @@ If Parser.ParseSong(Path + PathDelim + FileName) then Lines[Count].Line[Lines[Count].High].TotalNotes := 0; for X := low(Lines[Count].Line[Lines[Count].High].Note) to high(Lines[Count].Line[Lines[Count].High].Note) do begin - Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[X].Length * Lines[Count].Line[Lines[Count].High].Note[X].NoteType; - end; + if (Lines[Count].Line[Lines[Count].High].Note[I].NoteType = ntGolden) then + Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[X].Length; + if (Lines[Count].Line[Lines[Count].High].Note[I].NoteType <> ntFreestyle) then + Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[X].Length; + + end; //Total Notes Patch End end; end; - - - - end; //J Forloop - - //Add Sentence break - If (I < High(Parser.SongInfo.Sentences)) then - begin - - SentenceEnd := Parser.SongInfo.Sentences[I].Notes[High(Parser.SongInfo.Sentences[I].Notes)].Start + Parser.SongInfo.Sentences[I].Notes[High(Parser.SongInfo.Sentences[I].Notes)].Duration; - Rest := Parser.SongInfo.Sentences[I+1].Notes[0].Start - SentenceEnd; - - //Calculate Time - Case Rest of - 0, 1: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start; - 2: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start - 1; - 3: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start - 2; - else - If (Rest >= 4) then - Time := SentenceEnd + 2 - Else //Sentence overlapping :/ - Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start; - end; - // new sentence + + + + end; //J Forloop + + //Add Sentence break + If (I < High(Parser.SongInfo.Sentences)) then + begin + + SentenceEnd := Parser.SongInfo.Sentences[I].Notes[High(Parser.SongInfo.Sentences[I].Notes)].Start + Parser.SongInfo.Sentences[I].Notes[High(Parser.SongInfo.Sentences[I].Notes)].Duration; + Rest := Parser.SongInfo.Sentences[I+1].Notes[0].Start - SentenceEnd; + + //Calculate Time + Case Rest of + 0, 1: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start; + 2: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start - 1; + 3: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start - 2; + else + If (Rest >= 4) then + Time := SentenceEnd + 2 + Else //Sentence overlapping :/ + Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start; + end; + // new sentence if not Both then // P1 NewSentence(0, (Time + Rel[0]) * Mult, Param2) @@ -843,19 +501,19 @@ If Parser.ParseSong(Path + PathDelim + FileName) then // P1 + P2 NewSentence(0, (Time + Rel[0]) * Mult, Param2); NewSentence(1, (Time + Rel[1]) * Mult, Param2); - end; - - end; - end; + end; + + end; + end; //End write parsed information to Song Parser.Free; - end - else - begin - Log.LogError('Could not parse Inputfile: ' + Path + PathDelim + FileName); - exit; - end; - + end + else + begin + Log.LogError('Could not parse Inputfile: ' + Path + PathDelim + FileName); + exit; + end; + for Count := 0 to High(Lines) do begin Lines[Count].Line[High(Lines[Count].Line)].LastLine := True; end; @@ -1022,10 +680,10 @@ begin //Required Attributes //----------- - {$IFDEF UTF8_FILENAMES} { + {$IFDEF UTF8_FILENAMES} if ((Identifier = 'MP3') or (Identifier = 'BACKGROUND') or (Identifier = 'COVER') or (Identifier = 'VIDEO')) then Value := Utf8Encode(Value); - {$ENDIF} { + {$ENDIF} //Title if (Identifier = 'TITLE') then @@ -1169,6 +827,126 @@ begin end; +procedure TSong.ParseNote(LineNumber: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string); +//var +// Space: boolean; // Auto Removed, Unused Variable +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 Lines[LineNumber].Line[Lines[LineNumber].High] do begin + SetLength(Note, Length(Note) + 1); + HighNote := High(Note); + + Note[HighNote].Start := StartP; + if HighNote = 0 then begin + if Lines[LineNumber].Number = 1 then + Start := -100; +// Start := Note[HighNote].Start; + end; + + Note[HighNote].Length := DurationP; + + // back to the normal system with normal, golden and now freestyle notes + case TypeP of + 'F': Note[HighNote].NoteType := ntFreestyle; + ':': Note[HighNote].NoteType := ntNormal; + '*': Note[HighNote].NoteType := ntGolden; + end; + + if (Note[HighNote].NoteType = ntGolden) then + Lines[LineNumber].ScoreValue := Lines[LineNumber].ScoreValue + Note[HighNote].Length; + + if (Note[HighNote].NoteType <> ntFreestyle) then + Lines[LineNumber].ScoreValue := Lines[LineNumber].ScoreValue + Note[HighNote].Length; + + Note[HighNote].Tone := NoteP; + if Note[HighNote].Tone < Base[LineNumber] then Base[LineNumber] := Note[HighNote].Tone; + + Note[HighNote].Text := Copy(LyricS, 2, 100); + Lyric := Lyric + Note[HighNote].Text; + + End_ := Note[HighNote].Start + Note[HighNote].Length; + end; // with +end; + +procedure TSong.NewSentence(LineNumberP: integer; Param1, Param2: integer); +var +I: Integer; +begin + + // stara czesc //Alter Satz //Update Old Part + Lines[LineNumberP].Line[Lines[LineNumberP].High].BaseNote := Base[LineNumberP]; + Lines[LineNumberP].Line[Lines[LineNumberP].High].LyricWidth := glTextWidth(PChar(Lines[LineNumberP].Line[Lines[LineNumberP].High].Lyric)); + + //Total Notes Patch + Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes := 0; + for I := low(Lines[LineNumberP].Line[Lines[LineNumberP].High].Note) to high(Lines[LineNumberP].Line[Lines[LineNumberP].High].Note) do + begin + if (Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].NoteType = ntGolden) then + Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes := Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes + Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].Length; + + if (Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].NoteType <> ntFreestyle) then + Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes := Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes + Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].Length; + end; + //Total Notes Patch End + + + // nowa czesc //Neuer Satz //Update New Part + SetLength(Lines[LineNumberP].Line, Lines[LineNumberP].Number + 1); + Lines[LineNumberP].High := Lines[LineNumberP].High + 1; + Lines[LineNumberP].Number := Lines[LineNumberP].Number + 1; + Lines[LineNumberP].Line[Lines[LineNumberP].High].HighNote := -1; + + if self.Relative then + begin + Lines[LineNumberP].Line[Lines[LineNumberP].High].Start := Param1; + Rel[LineNumberP] := Rel[LineNumberP] + Param2; + end + else + Lines[LineNumberP].Line[Lines[LineNumberP].High].Start := Param1; + + Lines[LineNumberP].Line[Lines[LineNumberP].High].LastLine := False; + + Base[LineNumberP] := 100; // high number +end; + procedure TSong.clear(); begin //Main Information @@ -1182,11 +960,11 @@ begin //Required Information Mp3 := ''; - {$IFDEF FPC} { + {$IFDEF FPC} setlength( BPM, 0 ); - {$ELSE} { + {$ELSE} BPM := nil; - {$ENDIF} { + {$ENDIF} GAP := 0; Start := 0; @@ -1242,6 +1020,6 @@ begin //Read Header Result := self.ReadXMLHeader( FileName ); -end; *) +end; end. diff --git a/Game/Code/Classes/USong_TextFile.pas b/Game/Code/Classes/USong_TextFile.pas deleted file mode 100644 index a3e605de..00000000 --- a/Game/Code/Classes/USong_TextFile.pas +++ /dev/null @@ -1,86 +0,0 @@ -unit USong_TextFile; - -interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -{$I switches.inc} - -uses - Classes, - SysUtils, - USong; - -type - {******************* - Child of the new TSong class. - implements filehandling to load a song from a text file - *******************} - TSong_TextFile = class(TSong) - protected - SongFile: TextFile; - - Function OpenSongFile: Boolean; - Function IsDataAvailable: Boolean; - Function GetNextLine(): String; - Procedure CloseSongFile; - end; - -implementation - -uses - ULog; - -//-------- -// Open the SongFile -//-------- -Function TSong_TextFile.OpenSongFile: Boolean; -begin - Result := False; - - if not FileExists(FilePath + FileName) then - Log.LogError('File does not exsist', FilePath + FileName) - else - begin - try - AssignFile(SongFile, FilePath + FileName); - Reset(SongFile); - Result := True; - except - Log.LogError('Faild to open file', FilePath + FileName) - end; - end; -end; - -//-------- -// More data in songfile available? -//-------- -Function TSong_TextFile.IsDataAvailable: Boolean; -begin - Result := not eof(SongFile); -end; - -//-------- -// Returns the next line from the SongFile -//-------- -Function TSong_TextFile.GetNextLine(): String; -begin - ReadLn(SongFile, Result); - Result := Trim(Result); -end; - -//-------- -// Close the SongFile -//-------- -Procedure TSong_TextFile.CloseSongFile; -begin - try - CloseFile(SongFile); - except - Log.LogError('Error closing file', FilePath + FileName); - end; -end; - -end. \ No newline at end of file diff --git a/Game/Code/Classes/USong_Txt.pas b/Game/Code/Classes/USong_Txt.pas deleted file mode 100644 index a0259baf..00000000 --- a/Game/Code/Classes/USong_Txt.pas +++ /dev/null @@ -1,436 +0,0 @@ -unit USong_Txt; - -interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -{$I switches.inc} - - -uses - Classes, - SysUtils, - USong_TextFile; - -type - {******************* - Child of the new TSong class. - implements methods to load a song form a txt file (ultrastar file format) - *******************} - TSong_Txt = class(TSong_TextFile) - public - Procedure ReadHeader; override; //Reads Fileheader (Implemented by Child only) - Procedure ReadFile; override; //Reads complete File (Header + Notes) (Implemented by Child only) - Procedure WriteFile; override; //Writes complete File (Header + Notes) (Implemented by Child only) - end; - -implementation - -uses - UMusic, - UMain, - UPlatform, - ULog; - -type - TTags = (ArtistTag, TitleTag, Mp3Tag, BPMTag); - -//-------- -// Reads Fileheader -//-------- -Procedure TSong_Txt.ReadHeader; -var - started: Boolean; - line, key, value: String; - FloatValue: Real; - FoundTags: Set of TTags; - - // splits a headerline in key an value - // returns true on success and false if this is not a valid headerline - Function SplitHeaderLine(const Line: String; var Key, Value: String): Boolean; - var - idx: Integer; - begin - Result := False; - - idx := Pos(':', Line); - if idx > 0 then - begin - Key := Uppercase(Trim(Copy(Line, 2, idx - 2))); //Uppercase is for Case Insensitive Checks - Value := Trim(Copy(Line, idx + 1,Length(Line) - idx)); - - if (Length(Key) > 0) AND (Length(Value) > 0) then - Result := True - end; - end; - - function song_StrToFloat(const aValue : String): Extended; - var - lValue: String; - begin - lValue := aValue; - - if (Pos(',', lValue) <> 0) then - lValue[Pos(',', lValue)] := '.'; - - Result := StrToFloatDef(lValue, 0); - end; - -begin - if not OpenSongFile then - exit; - - started := False; - FoundTags := []; - - while isDataAvailable do - begin - line := GetNextLine(); - - // break if header has finished - if started AND ((Length(line) > 0) AND (not (line[1] = '#'))) then - break; - - // skip invalid lines at beginning - if (not started) AND (line[1] = '#') then - started := True; - - // parse line - if started then - begin - if (Length(line) > 0) AND not SplitHeaderLine(line, key, value) then - begin - Log.LogError('Invalide line in Header of file: ' + FilePath + FileName); - Log.LogError('Line: ' + line); - break; - end; - - {$IFDEF UTF8_FILENAMES} - if ((Key = 'MP3') or (Key = 'BACKGROUND') or (Key = 'COVER') or (Key = 'VIDEO')) then - Value := Utf8Encode(Value); - {$ENDIF} - - //Title - if (Key = 'TITLE') then - begin - Title := Value; - FoundTags := FoundTags + [TitleTag]; - continue; - end; - - //Artist - if (Key = 'ARTIST') then - begin - Artist := Value; - FoundTags := FoundTags + [ArtistTag]; - continue; - end; - - //MP3 File //Test if Exists - if (Key = 'MP3') then - begin - if FileExists(FilePath + Value) then - begin - Mp3 := FilePath + Value; - FoundTags := FoundTags + [Mp3Tag]; - end - else - Log.LogError('Can''t find MP3 File: ' + FilePath + Value + ' in Song: ' + FilePath + FileName); - continue; - end; - - //Beats per Minute - if (Key = 'BPM') then - begin - FloatValue := song_StrtoFloat( Value ) * Mult * MultBPM; - - if FloatValue <> 0 then - begin - SetLength(BPM, 1); - BPM[0].StartBeat := 0; - BPM[0].BPM := floatValue; - FoundTags := FoundTags + [BPMTag]; - end; - - continue; - end; - - //--------- - //Additional Header Information - //--------- - - // Gap - if (Key = 'GAP') then - begin - GAP := song_StrtoFloat( Value ); - - continue; - end; - - //Cover Picture - if (Key = 'COVER') then - begin - if FileExists(FilePath + Value) then - Cover := FilePath + Value - else - Log.LogError('Can''t find Cover File: ' + FilePath + Value + ' in Song: ' + FilePath + FileName); - - continue; - end; - - //Background Picture - if (Key = 'BACKGROUND') then - begin - if FileExists(FilePath + Value) then - Background := FilePath + Value - else - Log.LogError('Can''t find Background File: ' + FilePath + Value + ' in Song: ' + FilePath + FileName); - - continue; - end; - - // Video File - if (Key = 'VIDEO') then - begin - if FileExists(FilePath + Value) then - Video := FilePath + Value - else - Log.LogError('Can''t find Video File: ' + FilePath + Value + ' in Song: ' + FilePath + FileName); - - continue; - end; - - // Video Gap - if (Key = 'VIDEOGAP') then - begin - VideoGAP := song_StrtoFloat(Value); - continue; - end; - - //Genre Sorting - if (Key = 'GENRE') then - begin - Genre := Value; - continue; - end; - - //Edition Sorting - if (Key = 'EDITION') then - begin - Edition := Value; - continue; - end; - - //Creator Tag - if (Key = 'CREATOR') then - begin - Creator := Value; - continue; - end; - - //Language Sorting - if (Key = 'LANGUAGE') then - begin - Language := Value; - continue; - end; - - // Song Start - if (Key = 'START') then - begin - Start := song_StrtoFloat( Value ); - continue; - end; - - // Song Ending - if (Key = 'END') then - begin - TryStrtoInt(Value, Finish); - continue; - end; - - // Resolution - if (Key = 'RESOLUTION') then - begin - TryStrtoInt(Value, Resolution); - continue; - end; - - // Notes Gap - if (Key = 'NOTESGAP') then - begin - TryStrtoInt(Value, NotesGAP); - continue; - end; - - // Relative Notes - if (Key = 'RELATIVE') AND (uppercase(Value) = 'YES') then - begin - Relative := True; - continue; - end; - - end; // if started - end; // while - - if Cover = '' then - begin - Cover := platform.FindSongFile(FilePath, '*[CO].jpg'); - end; - - // check if all required infos are given - if not (BPMTag in FoundTags) then - Log.LogError('BPM Tag missing: ' + FilePath + FileName); - - if not (MP3Tag in FoundTags) then - Log.LogError('MP3 Tag missing or invalid file: ' + FilePath + FileName); - - if not (ArtistTag in FoundTags) then - Log.LogError('Artist Tag missing: ' + FilePath + FileName); - - if not (TitleTag in FoundTags) then - Log.LogError('Title Tag missing: ' + FilePath + FileName); - - CloseSongFile(); -end; - -//-------- -// Reads complete File (Header + Notes) -//-------- -Procedure TSong_Txt.ReadFile; -var - Line: String; - NotesRead: Boolean; - Values: TStringList; - - Procedure ParseDelimited(const StringList: TStringList; const Value: String; const Delimiter: String; const MaxParts: Integer); - var - idx: Integer; - Source: String; - Delta: Integer; - begin - Delta := Length(Delimiter); - Source := Value; - StringList.BeginUpdate; - StringList.Clear; - try - while ((Pos(Delimiter, Source) > 0) OR ((MaxParts > 0) AND (StringList.count+1 >= MaxParts))) do - begin - idx := Pos(Delimiter, Source); - StringList.Add(Copy(Source,0,idx-1)); - Source := Copy(Source,idx+Delta, MaxInt); - end; - - if (Length(Source) > 0) then - StringList.Add(Source); - finally - StringList.EndUpdate; - end; - end; - -begin - // read Header - Self.ReadHeader; - - OpenSongFile(); - - ResetLyrics; - NotesRead := False; - - while isDataAvailable do - begin - line := GetNextLine(); - - // end of song - if (line[1] = 'E') then - break; - - // skip invalid lines - if (line[1] <> ':') OR (line[1] <> 'F') OR (line[1] <> '*') OR (line[1] <> '-') OR (line[1] <> 'B') then - continue; - - // aktuelle Zeile in einzelne Werte aufteilen - Values := TStringList.Create; - try - ParseDelimited(Values, line, ' ', 5); - - try - if (line[1] = '-') then - if (not NotesRead) then - // skip newline if no notes before - continue - else - begin - // new lyric line - // param count: 1 (relative: 2) - - if (Values.Count > 2) then - // relativ offset - begin - // P1 - AddLyricLine(0, StrToInt(Values[1]), StrToInt(Values[2])); - - // P2 - if Length(Player) = 2 Then - AddLyricLine(1, StrToInt(Values[1]), StrToInt(Values[2])) - end - else - begin - AddLyricLine(0, StrToInt(Values[1])); - - // P2 - if Length(Player) = 2 then - AddLyricLine(1, StrToInt(Values[1])) - end; - end; - - // new BPM set - if (line[1] = 'B') then - begin - // param count: 2 - AddBPM(StrToInt(Values[1]), StrToFloat(Values[2])); - end; - - if (line[1] = ':') OR (line[1] = '*') OR (line[1] = 'F') then - begin - // param count: 4 - if (Values.Count < 5) then - Log.LogError('Error parsing line: ' + line, 'Not enough arguments.') - else - begin - // Check for ZeroNote - if StrToInt(Values[2]) = 0 then - Log.LogError('Found ZeroNote: "' + line + '" -> Note ignored!') - else - begin - // P1 - AddNote(0, line[1], StrToInt(Values[1]), StrToInt(Values[2]), StrToInt(Values[3]), Values[4]); - - // P2 - if Length(Player) = 2 then - AddNote(1, line[1], StrToInt(Values[1]), StrToInt(Values[2]), StrToInt(Values[3]), Values[4]); - end; - end; - end; - except - on E : Exception do - Log.LogError('Error parsing line: ' + line, E.ClassName + ': ' + E.Message); - end; - finally - Values.Free(); - end; - end; - - CloseSongFile(); -end; - -//-------- -// Writes complete File (Header + Notes) -//-------- -Procedure TSong_Txt.WriteFile; -begin -end; - -end. \ No newline at end of file diff --git a/Game/Code/Classes/USongs.pas b/Game/Code/Classes/USongs.pas index 5ae37d5d..df748e74 100644 --- a/Game/Code/Classes/USongs.pas +++ b/Game/Code/Classes/USongs.pas @@ -224,7 +224,7 @@ begin CatCovers.Load; if assigned( Covers ) then - Covers.Load('covers.cache'); + Covers.Load; if assigned(ScreenSong) then begin @@ -259,8 +259,8 @@ var Files : TDirectoryEntryArray; lSong : TSong; begin - // to - do : new Song management - {Files := Platform.DirectoryFindFiles( Dir, '.txt', true); + + Files := Platform.DirectoryFindFiles( Dir, '.txt', true); for i := 0 to Length(Files)-1 do begin @@ -282,7 +282,7 @@ begin end; end; SetLength( Files, 0); - } + end; procedure TSongs.BrowseXMLFiles(Dir: widestring); @@ -292,7 +292,7 @@ var lSong : TSong; begin - {Files := Platform.DirectoryFindFiles( Dir, '.xml', true); + Files := Platform.DirectoryFindFiles( Dir, '.xml', true); for i := 0 to Length(Files)-1 do begin @@ -313,7 +313,7 @@ begin end; end; - SetLength( Files, 0); } + SetLength( Files, 0); end; @@ -323,7 +323,7 @@ var S2: integer; TempSong: TSong; begin - {case Order of + case Order of sEdition: // by edition begin for S2 := 0 to SongList.Count -1 do @@ -422,7 +422,7 @@ begin end; end; - end; // case } + end; // case end; function TSongs.FindSongFile(Dir, Mask: widestring): widestring; @@ -449,7 +449,7 @@ begin CatNumShow := -1; // Songs.Sort(0); // by title -(*case Ini.Sorting of +case Ini.Sorting of sEdition: begin Songs.Sort(sArtist); Songs.Sort(sEdition); @@ -514,7 +514,7 @@ begin {// cover-patch if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg' - else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';//}{ + else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';//} CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS); @@ -541,7 +541,7 @@ begin {// cover-patch if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg' - else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}{ + else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';} CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS); //CatNumber Patch @@ -567,7 +567,7 @@ begin {// cover-patch if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg' - else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}{ + else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';} CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS); //CatNumber Patch @@ -597,7 +597,7 @@ begin {// cover-patch if FileExists(CoversPath + 'Title' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Title' + Letter + '.jpg' - else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}{ + else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';} CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter); //CatNumber Patch @@ -625,7 +625,7 @@ begin {// cover-patch if FileExists(CoversPath + 'Artist' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Artist' + Letter + '.jpg' - else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}{ + else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';} CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter); //CatNumber Patch @@ -651,7 +651,7 @@ begin {// cover-patch if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg' - else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}{ + else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';} CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS); //CatNumber Patch @@ -680,7 +680,7 @@ begin {// cover-patch if FileExists(CoversPath + 'Title' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Title' + Letter + '.jpg' - else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}{ + else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';} CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter); //CatNumber Patch @@ -710,7 +710,7 @@ begin {// cover-patch if FileExists(CoversPath + 'Artist' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Artist' + Letter + '.jpg' - else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}{ + else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';} CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter); //CatNumber Patch @@ -719,7 +719,7 @@ begin Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy CatNumber := 0; end; - + CatSongs.Song[CatLen].Visible := true; end; end; @@ -744,45 +744,45 @@ begin if (ini.Tabs_at_startup = 1) And (high(Song) >=1) then Song[CatLen - CatNumber].CatNumber := CatNumber;//Set CatNumber of Categroy //CatCount Patch -CatCount := Order; *) +CatCount := Order; end; procedure TCatSongs.ShowCategory(Index: integer); var S: integer; // song -begin // to - do : new Song management - { CatNumShow := Index; +begin + CatNumShow := Index; for S := 0 to high(CatSongs.Song) do begin if (CatSongs.Song[S].OrderNum = Index) AND (Not CatSongs.Song[S].Main) then CatSongs.Song[S].Visible := true else CatSongs.Song[S].Visible := false; - end; } + end; end; procedure TCatSongs.HideCategory(Index: integer); // hides all songs in category var S: integer; // song -begin // to - do : new Song management - {for S := 0 to high(CatSongs.Song) do begin +begin + for S := 0 to high(CatSongs.Song) do begin if not CatSongs.Song[S].Main then CatSongs.Song[S].Visible := false // hides all at now - end; } + end; end; procedure TCatSongs.ClickCategoryButton(Index: integer); var Num, S: integer; begin - { Num := CatSongs.Song[Index].OrderNum; + Num := CatSongs.Song[Index].OrderNum; if Num <> CatNumShow then begin ShowCategory(Num); end else begin ShowCategoryList; - end; } + end; end; //Hide Categorys when in Category Hack @@ -790,7 +790,7 @@ procedure TCatSongs.ShowCategoryList; var Num, S: integer; begin - {//Hide All Songs Show All Cats + //Hide All Songs Show All Cats for S := 0 to high(CatSongs.Song) do begin if CatSongs.Song[S].Main then CatSongs.Song[S].Visible := true @@ -798,7 +798,7 @@ begin CatSongs.Song[S].Visible := false end; CatSongs.Selected := CatNumShow; //Show last shown Category - CatNumShow := -1; } + CatNumShow := -1; end; //Hide Categorys when in Category Hack End @@ -808,7 +808,7 @@ var I: Integer; begin Result := -1; - I := SearchFrom + 1; { + I := SearchFrom + 1; while not CatSongs.Song[I].Visible do begin Inc (I); @@ -816,7 +816,7 @@ var I := low(CatSongs.Song); if (I = SearchFrom) then //Make One Round and no song found->quit break; - end; } + end; end; //Wrong song selected when tabs on bug End @@ -825,8 +825,8 @@ var S: integer; // song begin Result := 0; - {for S := 0 to high(CatSongs.Song) do - if CatSongs.Song[S].Visible = true then Inc(Result); } + for S := 0 to high(CatSongs.Song) do + if CatSongs.Song[S].Visible = true then Inc(Result); end; function TCatSongs.VisibleIndex(Index: integer): integer; @@ -834,8 +834,8 @@ var S: integer; // song begin Result := 0; - {for S := 0 to Index-1 do - if CatSongs.Song[S].Visible = true then Inc(Result); } + for S := 0 to Index-1 do + if CatSongs.Song[S].Visible = true then Inc(Result); end; function TCatSongs.SetFilter(FilterStr: String; const fType: Byte): Cardinal; @@ -847,7 +847,7 @@ begin {fType: 0: All 1: Title 2: Artist} - {FilterStr := Trim(FilterStr); + FilterStr := Trim(FilterStr); if FilterStr<>'' then begin Result := 0; //Create Search Array @@ -893,9 +893,9 @@ begin for i:=0 to High(Song) do begin Song[i].Visible:=(Ini.Tabs=1)=Song[i].Main; CatNumShow := -1; - end; } + end; Result := 0; - {end; } + end; end; diff --git a/Game/Code/Classes/UTexture.pas b/Game/Code/Classes/UTexture.pas index 3fac0524..a56c0096 100644 --- a/Game/Code/Classes/UTexture.pas +++ b/Game/Code/Classes/UTexture.pas @@ -101,7 +101,6 @@ type function GetTexture(const Name: string; Typ: TTextureType; FromCache: boolean = true): TTexture; overload; function GetTexture(const Name: string; Typ: TTextureType; Col: LongWord; FromCache: boolean = true): TTexture; overload; function FindTexture(const Name: string; Typ: TTextureType; Col: Cardinal): integer; - function LoadTexture(FromRegistry: boolean; const Identifier: string; Typ: TTextureType; Col: LongWord): TTexture; overload; function LoadTexture(const Identifier: string; Typ: TTextureType; Col: LongWord): TTexture; overload; function LoadTexture(const Identifier: string): TTexture; overload; @@ -112,8 +111,7 @@ type Function GetCoverThumbnail(const Name: string): Pointer; Procedure SetCoverSize(W, H: Integer); - - + Constructor Create; Destructor Destroy; override; end; @@ -126,16 +124,61 @@ var Mipmapping: Boolean; + CacheMipmap: array[0..256*256*3-1] of byte; // 3KB + CacheMipmapSurface: PSDL_Surface; + + implementation uses ULog, DateUtils, + UCovers, UThemes, {$IFDEF DARWIN} MacResources, {$ENDIF} - StrUtils; + StrUtils, + dialogs; +const + fmt_rgba: TSDL_Pixelformat = ( + palette: nil; + BitsPerPixel: 32; + BytesPerPixel: 4; + Rloss: 0; + Gloss: 0; + Bloss: 0; + Aloss: 0; + Rshift: 0; + Gshift: 8; + Bshift: 16; + Ashift: 24; + Rmask: $000000ff; + Gmask: $0000ff00; + Bmask: $00ff0000; + Amask: $ff000000; + ColorKey: 0; + Alpha: 255 + ); + fmt_rgb: TSDL_Pixelformat = ( + palette: nil; + BitsPerPixel: 24; + BytesPerPixel: 3; + Rloss: 0; + Gloss: 0; + Bloss: 0; + Aloss: 0; + Rshift: 0; + Gshift: 8; + Bshift: 16; + Ashift: 0; + Rmask: $000000ff; + Gmask: $0000ff00; + Bmask: $00ff0000; + Amask: $00000000; + ColorKey: 0; + Alpha: 255 + ); Constructor TTextureUnit.Create; begin @@ -308,6 +351,7 @@ begin Result:=SDL_ScaleSurfaceRect(TempSurface, 0,0,TempSurface^.W,TempSurface^.H, W,H); + SDL_FreeSurface(TempSurface); end; procedure TTextureUnit.ScaleTexture(var TexSurface: PSDL_Surface; W,H: Cardinal); @@ -355,38 +399,85 @@ procedure TTextureUnit.ColorizeTexture(TexSurface: PSDL_Surface; Col: Cardinal); hue := hue + 6.0; Result := hue; end; - procedure ColorizePixel(Pix: PByteArray; hue: Double); - var - clr: array[0..2] of Double; // [0: R, 1: G, 2: B] - hsv: array[0..2] of Double; // [0: H(ue), 1: S(aturation), 2: V(alue)] + +var + DestinationHue: Double; + PixelIndex: Cardinal; + Pixel: PByte; + PixelColors: PByteArray; +// clr: array[0..2] of Double; // [0: R, 1: G, 2: B] + clr2: array[0..2] of Uint32; +// hsv: array[0..2] of Double; // [0: H(ue), 1: S(aturation), 2: V(alue)] + hsv2: array[0..2] of UInt32;//LongInt; + dhue: UInt32;//LongInt; h_int: Cardinal; - delta, f, p, q, t: Double; - max: Double; - begin - clr[0] := Pix[0]/255; - clr[1] := Pix[1]/255; - clr[2] := Pix[2]/255; +// delta, f, p, q, t: Double; + delta2,f2,p2,q2,t2: Longint;//LongInt; +// max: Double; + max2: Uint32; +begin + DestinationHue := col2hue(Col); + + dhue:=Trunc(DestinationHue*1024); + + Pixel := TexSurface^.Pixels; + for PixelIndex := 0 to (TexSurface^.W * TexSurface^.H)-1 do + begin + PixelColors:=PByteArray(Pixel); + // inlined colorize per pixel + + // uses fixed point math + // get color values + clr2[0]:=PixelColors[0] shl 10; + clr2[1]:=PixelColors[1] shl 10; + clr2[2]:=PixelColors[2] shl 10; //calculate luminance and saturation from rgb + + max2:=clr2[0]; + if clr2[1]>max2 then max2:=clr2[1]; + if clr2[2]>max2 then max2:=clr2[2]; + delta2:=clr2[0]; + if clr2[1] RGB (H from color, S ans V from pixel) - // transformation according to Gonzalez and Woods - { This part does not really improve speed, maybe even slows down - if ((hsv[1] = 0.0) or (hsv[2] = 0.0)) then - begin - clr[0]:=hsv[2]; clr[1]:=hsv[2]; clr[2]:=hsv[2]; // (v,v,v) - end - else - } - begin +// ColorizePixel(PByteArray(Pixel), DestinationHue); h_int := trunc(hsv[0]); // h_int = |_h_| f := hsv[0]-h_int; // f = h-h_int p := hsv[2]*(1.0-hsv[1]); // p = v*(1-s) @@ -400,24 +491,12 @@ procedure TTextureUnit.ColorizeTexture(TexSurface: PSDL_Surface; Col: Cardinal); 4: begin clr[0]:=t; clr[1]:=p; clr[2]:=hsv[2]; end; // (t,p,v) 5: begin clr[0]:=hsv[2]; clr[1]:=p; clr[2]:=q; end; // (v,p,q) end; - end; // and store new rgb back into the image - Pix[0] := trunc(255*clr[0]); - Pix[1] := trunc(255*clr[1]); - Pix[2] := trunc(255*clr[2]); - end; - -var - DestinationHue: Double; - PixelIndex: Cardinal; - Pixel: PByte; -begin - DestinationHue := col2hue(Col); - Pixel := TexSurface^.Pixels; - for PixelIndex := 0 to (TexSurface^.W * TexSurface^.H)-1 do - begin - ColorizePixel(PByteArray(Pixel), DestinationHue); + PixelColors[0] := trunc(255*clr[0]); + PixelColors[1] := trunc(255*clr[1]); + PixelColors[2] := trunc(255*clr[2]); +*) Inc(Pixel, TexSurface^.format.BytesPerPixel); end; end; @@ -466,7 +545,7 @@ begin // adjust texture size (scale down, if necessary) newWidth := TexSurface.W; newHeight := TexSurface.H; - + if (newWidth > Limit) then newWidth := Limit; @@ -634,8 +713,8 @@ begin Log.BenchmarkEnd(4); if Log.BenchmarkTimeLength[4] >= 1 then - Log.LogBenchmark('**********> Texture Load Time Warning - ' + Identifier + '/' + TextureTypeToStr(Typ), 4); - + Log.LogBenchmark('**********> Texture Load Time Warning - ' + Identifier + '/' + TextureTypeToStr(Typ), 4) + else Log.LogBenchmark('**********> Texture Load Time ' + ExtractFileName(Identifier) + '/' + TextureTypeToStr(Typ), 4); {$ifdef blindydebug} Log.LogStatus('',' JB-8'); {$endif} @@ -696,10 +775,10 @@ begin Result := TextureDatabase.Texture[T].Texture; end; - {if FromCache and (Covers.CoverExists(Name) >= 0) then + if FromCache and Covers.CoverExists(Name) then begin // use cache texture - C := Covers.CoverExists(Name); + C := Covers.CoverNumber(Name); if TextureDatabase.Texture[T].TextureCache.TexNum = -1 then begin @@ -710,7 +789,7 @@ begin // use texture Result := TextureDatabase.Texture[T].TextureCache; - end;} + end; end; //-------- diff --git a/Game/Code/Screens/UScreenEditSub.pas b/Game/Code/Screens/UScreenEditSub.pas index 8ca1c3f3..8d4a3335 100644 --- a/Game/Code/Screens/UScreenEditSub.pas +++ b/Game/Code/Screens/UScreenEditSub.pas @@ -128,11 +128,10 @@ begin 'S': begin // Save Song - // to - do : new Song management - {if SDL_ModState = KMOD_LSHIFT then + if SDL_ModState = KMOD_LSHIFT then SaveSong(CurrentSong, Lines[0], CurrentSong.Path + CurrentSong.FileName, true) else - SaveSong(CurrentSong, Lines[0], CurrentSong.Path + CurrentSong.FileName, false);} + SaveSong(CurrentSong, Lines[0], CurrentSong.Path + CurrentSong.FileName, false); {if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL + KMOD_LALT then // Save Song @@ -1143,14 +1142,14 @@ begin ResetSingTemp; - {try // to - do : new Song management + try //Check if File is XML if copy(CurrentSong.FileName,length(CurrentSong.FileName)-3,4) = '.xml' then Error := not CurrentSong.LoadXMLSong() else Error := not CurrentSong.LoadSong(); - except } + except Error := True; - //end; + end; if Error then begin @@ -1173,8 +1172,7 @@ begin Lines[0].Current := 0; CurrentNote := 0; Lines[0].Line[0].Note[0].Color := 1; - // to - do : new Song management - AudioPlayback.Open({CurrentSong.Path + }CurrentSong.Mp3); + AudioPlayback.Open(CurrentSong.Path + CurrentSong.Mp3); //Set Down Music Volume for Better hearability of Midi Sounds //Music.SetVolume(40); diff --git a/Game/Code/Screens/UScreenPartyOptions.pas b/Game/Code/Screens/UScreenPartyOptions.pas index 52e1671f..bd05e653 100644 --- a/Game/Code/Screens/UScreenPartyOptions.pas +++ b/Game/Code/Screens/UScreenPartyOptions.pas @@ -98,12 +98,12 @@ begin PartySession.Teams.Teaminfo[0].NumPlayers := NumPlayer1+1; PartySession.Teams.Teaminfo[1].NumPlayers := NumPlayer2+1; PartySession.Teams.Teaminfo[2].NumPlayers := NumPlayer3+1;} - // to - do : new Song management + //Save Playlist PlaylistMan.Mode := TSingMode( Playlist ); PlaylistMan.CurPlayList := High(Cardinal); //If Category Selected Search Category ID - {if Playlist = 1 then + if Playlist = 1 then begin J := -1; For I := 0 to high(CatSongs.Song) do @@ -123,7 +123,7 @@ begin Exit; end else - PlaylistMan.CurPlayList := Playlist2;} + PlaylistMan.CurPlayList := Playlist2; //Start Party // to-do : Party @@ -216,7 +216,7 @@ end; procedure TScreenPartyOptions.SetPlaylist2; var I: Integer; -begin // to - do : new Song management +begin Case Playlist of 0: begin @@ -226,14 +226,14 @@ begin // to - do : new Song management 1: begin SetLength(IPlaylist2, 0); - {For I := 0 to high(CatSongs.Song) do + For I := 0 to high(CatSongs.Song) do begin If (CatSongs.Song[I].Main) then begin SetLength(IPlaylist2, Length(IPlaylist2) + 1); IPlaylist2[high(IPlaylist2)] := CatSongs.Song[I].Artist; end; - end; } + end; If (Length(IPlaylist2) = 0) then begin @@ -243,16 +243,16 @@ begin // to - do : new Song management end; 2: begin - {if (Length(PlaylistMan.Playlists) > 0) then + if (Length(PlaylistMan.Playlists) > 0) then begin SetLength(IPlaylist2, Length(PlaylistMan.Playlists)); PlaylistMan.GetNames(IPlaylist2); end else - begin} + begin SetLength(IPlaylist2, 1); IPlaylist2[0] := 'No Playlists found'; - //end; + end; end; end; diff --git a/Game/Code/Screens/UScreenSing.pas b/Game/Code/Screens/UScreenSing.pas index ccf75441..f6b5a3c2 100644 --- a/Game/Code/Screens/UScreenSing.pas +++ b/Game/Code/Screens/UScreenSing.pas @@ -222,9 +222,9 @@ begin // pause Music AudioPlayback.Pause; - // pause Video // to - do : new Song management - {if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then - fCurrentVideoPlaybackEngine.Pause;} + // pause Video + if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then + fCurrentVideoPlaybackEngine.Pause; end else //disable Pause @@ -239,9 +239,9 @@ begin // Play Music AudioPlayback.Play; - // Video // to - do : new Song management - {if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then - fCurrentVideoPlaybackEngine.Pause; } + // Video + if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then + fCurrentVideoPlaybackEngine.Pause; Paused := false; end; @@ -461,14 +461,14 @@ begin CurrentSong := CatSongs.Song[CatSongs.Selected]; // FIXME: bad style, put the try-except into LoadSong() and not here - {try // to - do : new Song management + try //Check if File is XML if copy(CurrentSong.FileName,length(CurrentSong.FileName)-3,4) = '.xml' then success := CurrentSong.LoadXMLSong() else success := CurrentSong.LoadSong(); - except } + except success := false; - //end; + end; if (not success) then begin @@ -479,7 +479,7 @@ begin ScreenSong.SelectRandomSong(); ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG')); // FIXME: do we need this? - //CurrentSong.Path := CatSongs.Song[CatSongs.Selected].Path; + CurrentSong.Path := CatSongs.Song[CatSongs.Selected].Path; Exit; end; @@ -492,8 +492,8 @@ begin fCurrentVideoPlaybackEngine.Close; fCurrentVideoPlaybackEngine := VideoPlayback; - // set movie // to - do : new Song management - {CurrentSong.VideoLoaded := false; + // set movie + CurrentSong.VideoLoaded := false; fShowVisualization := false; if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then begin @@ -504,14 +504,14 @@ begin fCurrentVideoPlaybackEngine.position := CurrentSong.VideoGAP + CurrentSong.Start; CurrentSong.VideoLoaded := true; - end; } + end; // set background - if (CurrentSong.Background <> '') { and (CurrentSong.VideoLoaded = false)} then + if (CurrentSong.Background <> '') and (CurrentSong.VideoLoaded = false) then try - Tex_Background := Texture.LoadTexture({CurrentSong.Path + }CurrentSong.Background); + Tex_Background := Texture.LoadTexture(CurrentSong.Path + CurrentSong.Background); except - log.LogError('Background could not be loaded: ' + {CurrentSong.Path + }CurrentSong.Background); + log.LogError('Background could not be loaded: ' + CurrentSong.Path + CurrentSong.Background); Tex_Background.TexNum := -1; end else @@ -914,8 +914,8 @@ end; procedure TScreenSing.onShowFinish; begin // play movie (II) - // to - do : new Song management - {if CurrentSong.VideoLoaded then + + if CurrentSong.VideoLoaded then begin try fCurrentVideoPlaybackEngine.GetFrame(LineState.CurrentTime); @@ -939,7 +939,7 @@ begin end; end; end; - end; } + end; // play music (II) @@ -1184,8 +1184,8 @@ begin SingDrawBackground; // update and draw movie - if ShowFinish and // to - do : new Song management - ( {CurrentSong.VideoLoaded or }fShowVisualization ) then + if ShowFinish and + ( CurrentSong.VideoLoaded or fShowVisualization ) then // if ShowFinish then begin // try @@ -1303,13 +1303,13 @@ begin Log.BenchmarkEnd(0); Log.LogBenchmark('Creating files', 0); end; - // to - do : new Song management - {if CurrentSong.VideoLoaded then + + if CurrentSong.VideoLoaded then begin // CloseSmpeg; fCurrentVideoPlaybackEngine.Close; CurrentSong.VideoLoaded := false; // to prevent drawing closed video - end; } + end; SetFontItalic (False); end; diff --git a/Game/Code/Screens/UScreenSingModi.pas b/Game/Code/Screens/UScreenSingModi.pas index e1441684..480b9e11 100644 --- a/Game/Code/Screens/UScreenSingModi.pas +++ b/Game/Code/Screens/UScreenSingModi.pas @@ -1,700 +1,699 @@ -unit UScreenSingModi; - -interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -{$I switches.inc} - - -uses UMenu, - UMusic, - SDL, - SysUtils, - UFiles, - UTime, - USongs, - UIni, - ULog, - UTexture, - ULyrics, - TextGL, - OpenGL12, - - UThemes, - //ULCD, //TODO: maybe LCD Support as Plugin? - UScreenSing, - ModiSDK; - -type - TScreenSingModi = class(TScreenSing) - protected - //paused: boolean; //Pause Mod - //PauseTime: Real; - //NumEmptySentences: integer; - public - //TextTime: integer; - - //StaticP1: integer; - //StaticP1ScoreBG: integer; - //TextP1: integer; - //TextP1Score: integer; - - //StaticP2R: integer; - //StaticP2RScoreBG: integer; - //TextP2R: integer; - //TextP2RScore: integer; - - //StaticP2M: integer; - //StaticP2MScoreBG: integer; - //TextP2M: integer; - //TextP2MScore: integer; - - //StaticP3R: integer; - //StaticP3RScoreBG: integer; - //TextP3R: integer; - //TextP3RScore: integer; - - //Tex_Background: TTexture; - //FadeOut: boolean; - //LyricMain: TLyric; - //LyricSub: TLyric; - Winner: Byte; //Who Wins - PlayerInfo: TPlayerInfo; - TeamInfo: TTeamInfo; - - constructor Create; override; - procedure onShow; override; - //procedure onShowFinish; override; - function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override; - function Draw: boolean; override; - procedure Finish; override; - //procedure UpdateLCD; //TODO: maybe LCD Support as Plugin? - //procedure Pause; //Pause Mod(Toggles Pause) - end; - -type +unit UScreenSingModi; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + + +uses UMenu, + UMusic, + SDL, + SysUtils, + UFiles, + UTime, + USongs, + UIni, + ULog, + UTexture, + ULyrics, + TextGL, + OpenGL12, + + UThemes, + //ULCD, //TODO: maybe LCD Support as Plugin? + UScreenSing, + ModiSDK; + +type + TScreenSingModi = class(TScreenSing) + protected + //paused: boolean; //Pause Mod + //PauseTime: Real; + //NumEmptySentences: integer; + public + //TextTime: integer; + + //StaticP1: integer; + //StaticP1ScoreBG: integer; + //TextP1: integer; + //TextP1Score: integer; + + //StaticP2R: integer; + //StaticP2RScoreBG: integer; + //TextP2R: integer; + //TextP2RScore: integer; + + //StaticP2M: integer; + //StaticP2MScoreBG: integer; + //TextP2M: integer; + //TextP2MScore: integer; + + //StaticP3R: integer; + //StaticP3RScoreBG: integer; + //TextP3R: integer; + //TextP3RScore: integer; + + //Tex_Background: TTexture; + //FadeOut: boolean; + //LyricMain: TLyric; + //LyricSub: TLyric; + Winner: Byte; //Who Wins + PlayerInfo: TPlayerInfo; + TeamInfo: TTeamInfo; + + constructor Create; override; + procedure onShow; override; + //procedure onShowFinish; override; + function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override; + function Draw: boolean; override; + procedure Finish; override; + //procedure UpdateLCD; //TODO: maybe LCD Support as Plugin? + //procedure Pause; //Pause Mod(Toggles Pause) + end; + +type TCustomSoundEntry = record Filename : String; Stream : TAudioPlaybackStream; end; -var - //Custom Sounds - CustomSounds: array of TCustomSoundEntry; - -//Procedured for Plugin -function LoadTex (const Name: PChar; Typ: TTextureType): TsmallTexture; stdcall; -//function Translate (const Name: PChar): PChar; stdcall; -procedure Print (const Style, Size: Byte; const X, Y: Real; const Text: PChar); stdcall; //Procedure to Print Text -function LoadSound (const Name: PChar): Cardinal; stdcall; //Procedure that loads a Custom Sound -procedure PlaySound (const Index: Cardinal); stdcall; //Plays a Custom Sound - -//Utilys -function ToSentences(Const Lines: TLines): TSentences; - -implementation -uses UGraphic, UDraw, UMain, Classes, URecord, ULanguage, math, UDLLManager, USkins, UGraphicClasses; - -// Method for input parsing. If False is returned, GetNextWindow -// should be checked to know the next window to load; -function TScreenSingModi.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; -begin - Result := true; - If (PressedDown) Then - begin // Key Down - case PressedKey of - - SDLK_ESCAPE, - SDLK_BACKSPACE : - begin - Finish; - AudioPlayback.PlaySound(SoundLib.Back); - FadeTo(@ScreenPartyScore); - end; - - else - Result := inherited ParseInput(PressedKey, CharCode, PressedDown); - end; - end; -end; - -constructor TScreenSingModi.Create; -begin - inherited Create; - -end; - -function ToSentences(Const Lines: TLines): TSentences; -var - I, J: Integer; -begin - Result.Current := Lines.Current; - Result.High := Lines.High; - Result.Number := Lines.Number; - Result.Resolution := Lines.Resolution; - Result.NotesGAP := Lines.NotesGAP; - Result.TotalLength := Lines.ScoreValue; - - SetLength(Result.Sentence, Length(Lines.Line)); - for I := low(Result.Sentence) to high(Result.Sentence) do - begin - Result.Sentence[I].Start := Lines.Line[I].Start; - Result.Sentence[I].StartNote := Lines.Line[I].Note[0].Start; - Result.Sentence[I].Lyric := Lines.Line[I].Lyric; - Result.Sentence[I].LyricWidth := Lines.Line[I].LyricWidth; - Result.Sentence[I].End_ := Lines.Line[I].End_; - Result.Sentence[I].BaseNote := Lines.Line[I].BaseNote; - Result.Sentence[I].HighNote := Lines.Line[I].HighNote; - Result.Sentence[I].TotalNotes := Lines.Line[I].TotalNotes; - - SetLength(Result.Sentence[I].Note, Length(Lines.Line[I].Note)); - for J := low(Result.Sentence[I].Note) to high(Result.Sentence[I].Note) do - begin - Result.Sentence[I].Note[J].Color := Lines.Line[I].Note[J].Color; - Result.Sentence[I].Note[J].Start := Lines.Line[I].Note[J].Start; - Result.Sentence[I].Note[J].Length := Lines.Line[I].Note[J].Length; - Result.Sentence[I].Note[J].Tone := Lines.Line[I].Note[J].Tone; - //Result.Sentence[I].Note[J].Text := Lines.Line[I].Note[J].Tekst; - Result.Sentence[I].Note[J].FreeStyle := (Lines.Line[I].Note[J].NoteType = ntFreestyle); - Result.Sentence[I].Note[J].Typ := Ord(Lines.Line[I].Note[J].NoteType); - end; - end; -end; - -procedure TScreenSingModi.onShow; -var - I: Integer; -begin - inherited; - - PlayersPlay := TeamInfo.NumTeams; - - if DLLMan.Selected.LoadSong then //Start with Song - begin - inherited; - end - else //Start Without Song - begin - AudioInput.CaptureStart; - end; - -//Set Playerinfo - PlayerInfo.NumPlayers := PlayersPlay; - for I := 0 to PlayerInfo.NumPlayers-1 do - begin - PlayerInfo.Playerinfo[I].Name := PChar(Ini.Name[I]); - PlayerInfo.Playerinfo[I].Score := 0; - PlayerInfo.Playerinfo[I].Bar := 50; - PlayerInfo.Playerinfo[I].Enabled := True; - end; - - for I := PlayerInfo.NumPlayers to high(PlayerInfo.Playerinfo) do - begin - PlayerInfo.Playerinfo[I].Score:= 0; - PlayerInfo.Playerinfo[I].Bar := 0; - PlayerInfo.Playerinfo[I].Enabled := False; - end; - - {Case PlayersPlay of - 1: begin - PlayerInfo.Playerinfo[0].PosX := Static[StaticP1ScoreBG].Texture.X; - PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ScoreBG].Texture.Y + Static[StaticP1ScoreBG].Texture.H; - end; - 2,4: begin - PlayerInfo.Playerinfo[0].PosX := Static[StaticP1TwoPScoreBG].Texture.X; - PlayerInfo.Playerinfo[0].PosY := Static[StaticP1TwoPScoreBG].Texture.Y + Static[StaticP1TwoPScoreBG].Texture.H; - PlayerInfo.Playerinfo[2].PosX := Static[StaticP1TwoPScoreBG].Texture.X; - PlayerInfo.Playerinfo[2].PosY := Static[StaticP1TwoPScoreBG].Texture.Y + Static[StaticP1TwoPScoreBG].Texture.H; - PlayerInfo.Playerinfo[1].PosX := Static[StaticP2RScoreBG].Texture.X; - PlayerInfo.Playerinfo[1].PosY := Static[StaticP2RScoreBG].Texture.Y + Static[StaticP2RScoreBG].Texture.H; - PlayerInfo.Playerinfo[3].PosX := Static[StaticP2RScoreBG].Texture.X; - PlayerInfo.Playerinfo[3].PosY := Static[StaticP2RScoreBG].Texture.Y + Static[StaticP2RScoreBG].Texture.H; - end; - 3,6: begin - PlayerInfo.Playerinfo[0].PosX := Static[StaticP1ThreePScoreBG].Texture.X; - PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ThreePScoreBG].Texture.Y + Static[StaticP1ThreePScoreBG].Texture.H; - PlayerInfo.Playerinfo[3].PosX := Static[StaticP1ThreePScoreBG].Texture.X; - PlayerInfo.Playerinfo[3].PosY := Static[StaticP1ThreePScoreBG].Texture.Y + Static[StaticP1ThreePScoreBG].Texture.H; - PlayerInfo.Playerinfo[1].PosX := Static[StaticP2MScoreBG].Texture.X; - PlayerInfo.Playerinfo[1].PosY := Static[StaticP2MScoreBG].Texture.Y + Static[StaticP2MScoreBG].Texture.H; - PlayerInfo.Playerinfo[4].PosX := Static[StaticP2MScoreBG].Texture.X; - PlayerInfo.Playerinfo[4].PosY := Static[StaticP2MScoreBG].Texture.Y + Static[StaticP2MScoreBG].Texture.H; - PlayerInfo.Playerinfo[2].PosX := Static[StaticP3RScoreBG].Texture.X; - PlayerInfo.Playerinfo[2].PosY := Static[StaticP3RScoreBG].Texture.Y + Static[StaticP3RScoreBG].Texture.H; - PlayerInfo.Playerinfo[5].PosX := Static[StaticP3RScoreBG].Texture.X; - PlayerInfo.Playerinfo[5].PosY := Static[StaticP3RScoreBG].Texture.Y + Static[StaticP3RScoreBG].Texture.H; - end; - end; } - - // play music (I) - //Music.CaptureStart; - //Music.MoveTo(AktSong.Start); - - //Init Plugin - if not DLLMan.PluginInit(TeamInfo, PlayerInfo, ToSentences(Lines[0]), LoadTex, Print, LoadSound, PlaySound) then - begin - //Fehler - Log.LogError('Could not Init Plugin'); - Halt; - end; - - // Set Background (Little Workaround, maybe change sometime) - if (DLLMan.Selected.LoadBack) AND (DLLMan.Selected.LoadSong) then - ScreenSing.Tex_Background := Tex_Background; - - Winner := 0; - - //Set Score Visibility - {if PlayersPlay = 1 then begin - Text[TextP1Score].Visible := DLLMan.Selected.ShowScore; - Static[StaticP1ScoreBG].Visible := DLLMan.Selected.ShowScore; - end; - - if (PlayersPlay = 2) OR (PlayersPlay = 4) then begin - Text[TextP1TwoPScore].Visible := DLLMan.Selected.ShowScore; - Static[StaticP1TwoPScoreBG].Visible := DLLMan.Selected.ShowScore; - - Text[TextP2RScore].Visible := DLLMan.Selected.ShowScore; - Static[StaticP2RScoreBG].Visible := DLLMan.Selected.ShowScore; - end; - - if (PlayersPlay = 3) OR (PlayersPlay = 6) then begin - Text[TextP1ThreePScore].Visible := DLLMan.Selected.ShowScore; - Static[StaticP1ThreePScoreBG].Visible := DLLMan.Selected.ShowScore; - - Text[TextP2MScore].Visible := DLLMan.Selected.ShowScore; - Static[StaticP2MScoreBG].Visible := DLLMan.Selected.ShowScore; - - Text[TextP3RScore].Visible := DLLMan.Selected.ShowScore; - Static[StaticP3RScoreBG].Visible := DLLMan.Selected.ShowScore; - end; } -end; - -function TScreenSingModi.Draw: boolean; -var - Min: integer; - Sec: integer; - Tekst: string; - S, I: integer; - T: integer; -begin - Result := false; - - //Set Playerinfo - PlayerInfo.NumPlayers := PlayersPlay; - for I := 0 to PlayerInfo.NumPlayers-1 do - begin - PlayerInfo.Playerinfo[I].Name := PChar(Player[I].Name); - if PlayerInfo.Playerinfo[I].Enabled then - begin - if (Player[I].ScoreTotalI<=10000) then - PlayerInfo.Playerinfo[I].Score:= Player[I].ScoreTotalI; - PlayerInfo.Playerinfo[I].Bar := Round(Scores.Players[I].RBPos * 100); - end; - end; - - //Show Score - if DLLMan.Selected.ShowScore then - begin - {//ScoreBG Mod - // set player colors - if PlayersPlay = 4 then begin - if ScreenAct = 1 then begin - LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG, - Static[StaticP1TwoP].Texture.ColB, 'P1Dark'); - LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG, - Static[StaticP2R].Texture.ColB, 'P2Dark'); - - - - LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG, - Static[StaticP1TwoPScoreBG].Texture.ColB, 'P1Dark'); - LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG, - Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark'); - - - - end; - if ScreenAct = 2 then begin - LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG, - Static[StaticP1TwoP].Texture.ColB, 'P3Dark'); - LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG, - Static[StaticP2R].Texture.ColB, 'P4Dark'); - - - - LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG, - Static[StaticP1TwoPScoreBG].Texture.ColB, 'P3Dark'); - LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG, - Static[StaticP2RScoreBG].Texture.ColB, 'P4Dark'); - - - - end; - end; - - if PlayersPlay = 6 then begin - if ScreenAct = 1 then begin - LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG, - Static[StaticP1ThreeP].Texture.ColB, 'P1Dark'); - LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG, - Static[StaticP2R].Texture.ColB, 'P2Dark'); - LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG, - Static[StaticP3R].Texture.ColB, 'P3Dark'); - - - - LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG, - Static[StaticP1ThreePScoreBG].Texture.ColB, 'P1Dark'); - LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG, - Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark'); - LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG, - Static[StaticP3RScoreBG].Texture.ColB, 'P3Dark'); - - - - end; - if ScreenAct = 2 then begin - LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG, - Static[StaticP1ThreeP].Texture.ColB, 'P4Dark'); - LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG, - Static[StaticP2R].Texture.ColB, 'P5Dark'); - LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG, - Static[StaticP3R].Texture.ColB, 'P6Dark'); - - - - - LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG, - Static[StaticP1ThreePScoreBG].Texture.ColB, 'P4Dark'); - LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG, - Static[StaticP2RScoreBG].Texture.ColB, 'P5Dark'); - LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG, - Static[StaticP3RScoreBG].Texture.ColB, 'P6Dark'); - - - - - end; - end; - //end ScoreBG Mod } - - // set player names (for 2 screens and only Singstar skin) - if ScreenAct = 1 then begin - Text[TextP1].Text := 'P1'; - Text[TextP1TwoP].Text := 'P1'; // added for ps3 skin - Text[TextP1ThreeP].Text := 'P1'; // added for ps3 skin - Text[TextP2R].Text := 'P2'; - Text[TextP2M].Text := 'P2'; - Text[TextP3R].Text := 'P3'; - end; - - if ScreenAct = 2 then begin - case PlayersPlay of - 4: begin - Text[TextP1TwoP].Text := 'P3'; - Text[TextP2R].Text := 'P4'; - end; - 6: begin - Text[TextP1ThreeP].Text := 'P4'; - Text[TextP2M].Text := 'P5'; - Text[TextP3R].Text := 'P6'; - end; - end; // case - end; // if - - - // stereo <- and where iss P2M? or P3? - Static[StaticP1].Texture.X := Static[StaticP1].Texture.X + 10*ScreenX; - Text[TextP1].X := Text[TextP1].X + 10*ScreenX; - - {Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X + 10*ScreenX; - Text[TextP1Score].X := Text[TextP1Score].X + 10*ScreenX;} - - Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X + 10*ScreenX; - Text[TextP2R].X := Text[TextP2R].X + 10*ScreenX; - - {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X + 10*ScreenX; - Text[TextP2RScore].X := Text[TextP2RScore].X + 10*ScreenX;} - - // .. and scores - {if PlayersPlay = 1 then begin - Tekst := IntToStr(Player[0].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP1Score].Text := Tekst; - end; - - if PlayersPlay = 2 then begin - Tekst := IntToStr(Player[0].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP1TwoPScore].Text := Tekst; - - Tekst := IntToStr(Player[1].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP2RScore].Text := Tekst; - end; - - if PlayersPlay = 3 then begin - Tekst := IntToStr(Player[0].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP1ThreePScore].Text := Tekst; - - Tekst := IntToStr(Player[1].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP2MScore].Text := Tekst; - - Tekst := IntToStr(Player[2].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP3RScore].Text := Tekst; - end; - - if PlayersPlay = 4 then begin - if ScreenAct = 1 then begin - Tekst := IntToStr(Player[0].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP1TwoPScore].Text := Tekst; - - Tekst := IntToStr(Player[1].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP2RScore].Text := Tekst; - end; - if ScreenAct = 2 then begin - Tekst := IntToStr(Player[2].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP1TwoPScore].Text := Tekst; - - Tekst := IntToStr(Player[3].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP2RScore].Text := Tekst; - end; - end; - - if PlayersPlay = 6 then begin - if ScreenAct = 1 then begin - Tekst := IntToStr(Player[0].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP1ThreePScore].Text := Tekst; - - Tekst := IntToStr(Player[1].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP2MScore].Text := Tekst; - - Tekst := IntToStr(Player[2].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP3RScore].Text := Tekst; - end; - if ScreenAct = 2 then begin - Tekst := IntToStr(Player[3].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP1ThreePScore].Text := Tekst; - - Tekst := IntToStr(Player[4].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP2MScore].Text := Tekst; - - Tekst := IntToStr(Player[5].ScoreTotalI); - while Length(Tekst) < 5 do Tekst := '0' + Tekst; - Text[TextP3RScore].Text := Tekst; - end; - end; } - - end; //ShowScore - - for S := 1 to 1 do - Static[S].Texture.X := Static[S].Texture.X + 10*ScreenX; - - for T := 0 to 1 do - Text[T].X := Text[T].X + 10*ScreenX; - - if DLLMan.Selected.LoadSong then - begin - // update static menu with time ... - Min := Round(LineState.CurrentTime) div 60; - Sec := Round(LineState.CurrentTime) mod 60; - Text[TextTimeText].Text := ''; - if Min < 10 then Text[TextTimeText].Text := '0'; - Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Min) + ':'; - if Sec < 10 then Text[TextTimeText].Text := Text[TextTimeText].Text + '0'; - Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Sec); - end; - - // draw static menu (BG) - DrawBG; - - //Draw Background - if (DllMan.Selected.LoadSong) AND (DllMan.Selected.LoadBack) then - SingDrawBackground; - - // 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 CurrentSong.VideoLoaded AND DllMan.Selected.LoadVideo then begin - UpdateSmpeg; // this only draws - end;} - - // draw static menu (FG) - DrawFG; - - if ShowFinish then begin - if DllMan.Selected.LoadSong then - begin - if (not AudioPlayback.Finished) and ((CurrentSong.Finish = 0) or (LineState.CurrentTime*1000 <= CurrentSong.Finish)) then begin - //Pause Mod: - if not Paused then - Sing(Self); // analyze song - end else begin - if not FadeOut then begin - Finish; - FadeOut := true; - FadeTo(@ScreenPartyScore); - end; - end; - end; - end; - - // draw custom items - SingModiDraw(PlayerInfo); // always draw - - //GoldenNoteStarsTwinkle Mod - GoldenRec.SpawnRec; - //GoldenNoteStarsTwinkle Mod - - //Update PlayerInfo - for I := 0 to PlayerInfo.NumPlayers-1 do - begin - if PlayerInfo.Playerinfo[I].Enabled then - begin - //PlayerInfo.Playerinfo[I].Bar := Player[I].ScorePercent; - PlayerInfo.Playerinfo[I].Score := Player[I].ScoreTotalI; - end; - end; - - if ((ShowFinish) AND (NOT Paused)) then - begin - if not DLLMan.PluginDraw(Playerinfo, Lines[0].Current) then - begin - if not FadeOut then begin - Finish; - FadeOut := true; - FadeTo(@ScreenPartyScore); - end; - end; - end; - - //Change PlayerInfo/Changeables - for I := 0 to PlayerInfo.NumPlayers-1 do - begin - if (Player[I].ScoreTotalI <> PlayerInfo.Playerinfo[I].Score) then - begin - //Player[I].ScoreTotal := Player[I].ScoreTotal + (PlayerInfo.Playerinfo[I].Score - Player[I].ScoreTotalI); - Player[I].ScoreTotalI := PlayerInfo.Playerinfo[I].Score; - end; - {if (PlayerInfo.Playerinfo[I].Bar <> Player[I].ScorePercent) then - Player[I].ScorePercentTarget := PlayerInfo.Playerinfo[I].Bar; } - end; - - // back stereo - Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10*ScreenX; - Text[TextP1].X := Text[TextP1].X - 10*ScreenX; - - {Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X - 10*ScreenX; - Text[TextP1Score].X := Text[TextP1Score].X - 10*ScreenX;} - - - Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X - 10*ScreenX; - Text[TextP2R].X := Text[TextP2R].X - 10*ScreenX; - - {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X - 10*ScreenX; - Text[TextP2RScore].X := Text[TextP2RScore].X - 10*ScreenX;} - - - for S := 1 to 1 do - Static[S].Texture.X := Static[S].Texture.X - 10*ScreenX; - - for T := 0 to 1 do - Text[T].X := Text[T].X - 10*ScreenX; - - Result := true; -end; - -procedure TScreenSingModi.Finish; -begin -inherited Finish; - -Winner := DllMan.PluginFinish(PlayerInfo); - -//Log.LogError('Winner: ' + InttoStr(Winner)); - -//DLLMan.UnLoadPlugin; -end; - -function LoadTex (const Name: PChar; Typ: TTextureType): TsmallTexture; stdcall; -var - Texname, EXT: String; - Tex: TTexture; -begin - //Get texture Name - TexName := Skin.GetTextureFileName(String(Name)); - //Get File Typ - Ext := ExtractFileExt(TexName); - if (uppercase(Ext) = '.JPG') then - Ext := 'JPG' - else - Ext := 'BMP'; - - Tex := Texture.LoadTexture(TexName, UTexture.TTextureType(Typ), 0); - - Result.TexNum := Tex.TexNum; - Result.W := Tex.W; - Result.H := Tex.H; -end; -{ -function Translate (const Name: PChar): PChar; stdcall; -begin - Result := PChar(Language.Translate(String(Name))); -end; } - -procedure Print (const Style, Size: Byte; const X, Y: Real; const Text: PChar); stdcall; //Procedure to Print Text -begin - SetFontItalic ((Style and 128) = 128); - SetFontStyle(Style and 7); - SetFontSize(Size); - SetFontPos (X, Y); - glPrint (PChar(Language.Translate(String(Text)))); -end; - -function LoadSound (const Name: PChar): Cardinal; stdcall; //Procedure that loads a Custom Sound -var - S: TAudioPlaybackStream; - I: Integer; - F: String; -begin - //Search for Sound in already loaded Sounds - F := UpperCase(SoundPath + FileName); - For I := 0 to High(CustomSounds) do - begin - if (UpperCase(CustomSounds[I].Filename) = F) then - begin - Result := I; - Exit; - end; - end; - - S := AudioPlayback.OpenSound(SoundPath + String(Name)); - if (S <> nil) then - Result := High(CustomSounds) - else - Result := 0; -end; - -procedure PlaySound (const Index: Cardinal); stdcall; //Plays a Custom Sound -begin - if (Index <= High(CustomSounds)) then - AudioPlayback.PlaySound(CustomSounds[Index].Stream); -end; - -end. - +var + //Custom Sounds + CustomSounds: array of TCustomSoundEntry; + +//Procedured for Plugin +function LoadTex (const Name: PChar; Typ: TTextureType): TsmallTexture; stdcall; +//function Translate (const Name: PChar): PChar; stdcall; +procedure Print (const Style, Size: Byte; const X, Y: Real; const Text: PChar); stdcall; //Procedure to Print Text +function LoadSound (const Name: PChar): Cardinal; stdcall; //Procedure that loads a Custom Sound +procedure PlaySound (const Index: Cardinal); stdcall; //Plays a Custom Sound + +//Utilys +function ToSentences(Const Lines: TLines): TSentences; + +implementation +uses UGraphic, UDraw, UMain, Classes, URecord, ULanguage, math, UDLLManager, USkins, UGraphicClasses; + +// Method for input parsing. If False is returned, GetNextWindow +// should be checked to know the next window to load; +function TScreenSingModi.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; +begin + Result := true; + If (PressedDown) Then + begin // Key Down + case PressedKey of + + SDLK_ESCAPE, + SDLK_BACKSPACE : + begin + Finish; + AudioPlayback.PlaySound(SoundLib.Back); + FadeTo(@ScreenPartyScore); + end; + + else + Result := inherited ParseInput(PressedKey, CharCode, PressedDown); + end; + end; +end; + +constructor TScreenSingModi.Create; +begin + inherited Create; + +end; + +function ToSentences(Const Lines: TLines): TSentences; +var + I, J: Integer; +begin + Result.Current := Lines.Current; + Result.High := Lines.High; + Result.Number := Lines.Number; + Result.Resolution := Lines.Resolution; + Result.NotesGAP := Lines.NotesGAP; + Result.TotalLength := Lines.ScoreValue; + + SetLength(Result.Sentence, Length(Lines.Line)); + for I := low(Result.Sentence) to high(Result.Sentence) do + begin + Result.Sentence[I].Start := Lines.Line[I].Start; + Result.Sentence[I].StartNote := Lines.Line[I].Note[0].Start; + Result.Sentence[I].Lyric := Lines.Line[I].Lyric; + Result.Sentence[I].LyricWidth := Lines.Line[I].LyricWidth; + Result.Sentence[I].End_ := Lines.Line[I].End_; + Result.Sentence[I].BaseNote := Lines.Line[I].BaseNote; + Result.Sentence[I].HighNote := Lines.Line[I].HighNote; + Result.Sentence[I].TotalNotes := Lines.Line[I].TotalNotes; + + SetLength(Result.Sentence[I].Note, Length(Lines.Line[I].Note)); + for J := low(Result.Sentence[I].Note) to high(Result.Sentence[I].Note) do + begin + Result.Sentence[I].Note[J].Color := Lines.Line[I].Note[J].Color; + Result.Sentence[I].Note[J].Start := Lines.Line[I].Note[J].Start; + Result.Sentence[I].Note[J].Length := Lines.Line[I].Note[J].Length; + Result.Sentence[I].Note[J].Tone := Lines.Line[I].Note[J].Tone; + //Result.Sentence[I].Note[J].Text := Lines.Line[I].Note[J].Tekst; + Result.Sentence[I].Note[J].FreeStyle := (Lines.Line[I].Note[J].NoteType = ntFreestyle); + end; + end; +end; + +procedure TScreenSingModi.onShow; +var + I: Integer; +begin + inherited; + + PlayersPlay := TeamInfo.NumTeams; + + if DLLMan.Selected.LoadSong then //Start with Song + begin + inherited; + end + else //Start Without Song + begin + AudioInput.CaptureStart; + end; + +//Set Playerinfo + PlayerInfo.NumPlayers := PlayersPlay; + for I := 0 to PlayerInfo.NumPlayers-1 do + begin + PlayerInfo.Playerinfo[I].Name := PChar(Ini.Name[I]); + PlayerInfo.Playerinfo[I].Score := 0; + PlayerInfo.Playerinfo[I].Bar := 50; + PlayerInfo.Playerinfo[I].Enabled := True; + end; + + for I := PlayerInfo.NumPlayers to high(PlayerInfo.Playerinfo) do + begin + PlayerInfo.Playerinfo[I].Score:= 0; + PlayerInfo.Playerinfo[I].Bar := 0; + PlayerInfo.Playerinfo[I].Enabled := False; + end; + + {Case PlayersPlay of + 1: begin + PlayerInfo.Playerinfo[0].PosX := Static[StaticP1ScoreBG].Texture.X; + PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ScoreBG].Texture.Y + Static[StaticP1ScoreBG].Texture.H; + end; + 2,4: begin + PlayerInfo.Playerinfo[0].PosX := Static[StaticP1TwoPScoreBG].Texture.X; + PlayerInfo.Playerinfo[0].PosY := Static[StaticP1TwoPScoreBG].Texture.Y + Static[StaticP1TwoPScoreBG].Texture.H; + PlayerInfo.Playerinfo[2].PosX := Static[StaticP1TwoPScoreBG].Texture.X; + PlayerInfo.Playerinfo[2].PosY := Static[StaticP1TwoPScoreBG].Texture.Y + Static[StaticP1TwoPScoreBG].Texture.H; + PlayerInfo.Playerinfo[1].PosX := Static[StaticP2RScoreBG].Texture.X; + PlayerInfo.Playerinfo[1].PosY := Static[StaticP2RScoreBG].Texture.Y + Static[StaticP2RScoreBG].Texture.H; + PlayerInfo.Playerinfo[3].PosX := Static[StaticP2RScoreBG].Texture.X; + PlayerInfo.Playerinfo[3].PosY := Static[StaticP2RScoreBG].Texture.Y + Static[StaticP2RScoreBG].Texture.H; + end; + 3,6: begin + PlayerInfo.Playerinfo[0].PosX := Static[StaticP1ThreePScoreBG].Texture.X; + PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ThreePScoreBG].Texture.Y + Static[StaticP1ThreePScoreBG].Texture.H; + PlayerInfo.Playerinfo[3].PosX := Static[StaticP1ThreePScoreBG].Texture.X; + PlayerInfo.Playerinfo[3].PosY := Static[StaticP1ThreePScoreBG].Texture.Y + Static[StaticP1ThreePScoreBG].Texture.H; + PlayerInfo.Playerinfo[1].PosX := Static[StaticP2MScoreBG].Texture.X; + PlayerInfo.Playerinfo[1].PosY := Static[StaticP2MScoreBG].Texture.Y + Static[StaticP2MScoreBG].Texture.H; + PlayerInfo.Playerinfo[4].PosX := Static[StaticP2MScoreBG].Texture.X; + PlayerInfo.Playerinfo[4].PosY := Static[StaticP2MScoreBG].Texture.Y + Static[StaticP2MScoreBG].Texture.H; + PlayerInfo.Playerinfo[2].PosX := Static[StaticP3RScoreBG].Texture.X; + PlayerInfo.Playerinfo[2].PosY := Static[StaticP3RScoreBG].Texture.Y + Static[StaticP3RScoreBG].Texture.H; + PlayerInfo.Playerinfo[5].PosX := Static[StaticP3RScoreBG].Texture.X; + PlayerInfo.Playerinfo[5].PosY := Static[StaticP3RScoreBG].Texture.Y + Static[StaticP3RScoreBG].Texture.H; + end; + end; } + + // play music (I) + //Music.CaptureStart; + //Music.MoveTo(AktSong.Start); + + //Init Plugin + if not DLLMan.PluginInit(TeamInfo, PlayerInfo, ToSentences(Lines[0]), LoadTex, Print, LoadSound, PlaySound) then + begin + //Fehler + Log.LogError('Could not Init Plugin'); + Halt; + end; + + // Set Background (Little Workaround, maybe change sometime) + if (DLLMan.Selected.LoadBack) AND (DLLMan.Selected.LoadSong) then + ScreenSing.Tex_Background := Tex_Background; + + Winner := 0; + + //Set Score Visibility + {if PlayersPlay = 1 then begin + Text[TextP1Score].Visible := DLLMan.Selected.ShowScore; + Static[StaticP1ScoreBG].Visible := DLLMan.Selected.ShowScore; + end; + + if (PlayersPlay = 2) OR (PlayersPlay = 4) then begin + Text[TextP1TwoPScore].Visible := DLLMan.Selected.ShowScore; + Static[StaticP1TwoPScoreBG].Visible := DLLMan.Selected.ShowScore; + + Text[TextP2RScore].Visible := DLLMan.Selected.ShowScore; + Static[StaticP2RScoreBG].Visible := DLLMan.Selected.ShowScore; + end; + + if (PlayersPlay = 3) OR (PlayersPlay = 6) then begin + Text[TextP1ThreePScore].Visible := DLLMan.Selected.ShowScore; + Static[StaticP1ThreePScoreBG].Visible := DLLMan.Selected.ShowScore; + + Text[TextP2MScore].Visible := DLLMan.Selected.ShowScore; + Static[StaticP2MScoreBG].Visible := DLLMan.Selected.ShowScore; + + Text[TextP3RScore].Visible := DLLMan.Selected.ShowScore; + Static[StaticP3RScoreBG].Visible := DLLMan.Selected.ShowScore; + end; } +end; + +function TScreenSingModi.Draw: boolean; +var + Min: integer; + Sec: integer; + Tekst: string; + S, I: integer; + T: integer; +begin + Result := false; + + //Set Playerinfo + PlayerInfo.NumPlayers := PlayersPlay; + for I := 0 to PlayerInfo.NumPlayers-1 do + begin + PlayerInfo.Playerinfo[I].Name := PChar(Player[I].Name); + if PlayerInfo.Playerinfo[I].Enabled then + begin + if (Player[I].ScoreTotalI<=10000) then + PlayerInfo.Playerinfo[I].Score:= Player[I].ScoreTotalI; + PlayerInfo.Playerinfo[I].Bar := Round(Scores.Players[I].RBPos * 100); + end; + end; + + //Show Score + if DLLMan.Selected.ShowScore then + begin + {//ScoreBG Mod + // set player colors + if PlayersPlay = 4 then begin + if ScreenAct = 1 then begin + LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG, + Static[StaticP1TwoP].Texture.ColB, 'P1Dark'); + LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG, + Static[StaticP2R].Texture.ColB, 'P2Dark'); + + + + LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG, + Static[StaticP1TwoPScoreBG].Texture.ColB, 'P1Dark'); + LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG, + Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark'); + + + + end; + if ScreenAct = 2 then begin + LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG, + Static[StaticP1TwoP].Texture.ColB, 'P3Dark'); + LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG, + Static[StaticP2R].Texture.ColB, 'P4Dark'); + + + + LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG, + Static[StaticP1TwoPScoreBG].Texture.ColB, 'P3Dark'); + LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG, + Static[StaticP2RScoreBG].Texture.ColB, 'P4Dark'); + + + + end; + end; + + if PlayersPlay = 6 then begin + if ScreenAct = 1 then begin + LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG, + Static[StaticP1ThreeP].Texture.ColB, 'P1Dark'); + LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG, + Static[StaticP2R].Texture.ColB, 'P2Dark'); + LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG, + Static[StaticP3R].Texture.ColB, 'P3Dark'); + + + + LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG, + Static[StaticP1ThreePScoreBG].Texture.ColB, 'P1Dark'); + LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG, + Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark'); + LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG, + Static[StaticP3RScoreBG].Texture.ColB, 'P3Dark'); + + + + end; + if ScreenAct = 2 then begin + LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG, + Static[StaticP1ThreeP].Texture.ColB, 'P4Dark'); + LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG, + Static[StaticP2R].Texture.ColB, 'P5Dark'); + LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG, + Static[StaticP3R].Texture.ColB, 'P6Dark'); + + + + + LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG, + Static[StaticP1ThreePScoreBG].Texture.ColB, 'P4Dark'); + LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG, + Static[StaticP2RScoreBG].Texture.ColB, 'P5Dark'); + LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG, + Static[StaticP3RScoreBG].Texture.ColB, 'P6Dark'); + + + + + end; + end; + //end ScoreBG Mod } + + // set player names (for 2 screens and only Singstar skin) + if ScreenAct = 1 then begin + Text[TextP1].Text := 'P1'; + Text[TextP1TwoP].Text := 'P1'; // added for ps3 skin + Text[TextP1ThreeP].Text := 'P1'; // added for ps3 skin + Text[TextP2R].Text := 'P2'; + Text[TextP2M].Text := 'P2'; + Text[TextP3R].Text := 'P3'; + end; + + if ScreenAct = 2 then begin + case PlayersPlay of + 4: begin + Text[TextP1TwoP].Text := 'P3'; + Text[TextP2R].Text := 'P4'; + end; + 6: begin + Text[TextP1ThreeP].Text := 'P4'; + Text[TextP2M].Text := 'P5'; + Text[TextP3R].Text := 'P6'; + end; + end; // case + end; // if + + + // stereo <- and where iss P2M? or P3? + Static[StaticP1].Texture.X := Static[StaticP1].Texture.X + 10*ScreenX; + Text[TextP1].X := Text[TextP1].X + 10*ScreenX; + + {Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X + 10*ScreenX; + Text[TextP1Score].X := Text[TextP1Score].X + 10*ScreenX;} + + Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X + 10*ScreenX; + Text[TextP2R].X := Text[TextP2R].X + 10*ScreenX; + + {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X + 10*ScreenX; + Text[TextP2RScore].X := Text[TextP2RScore].X + 10*ScreenX;} + + // .. and scores + {if PlayersPlay = 1 then begin + Tekst := IntToStr(Player[0].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP1Score].Text := Tekst; + end; + + if PlayersPlay = 2 then begin + Tekst := IntToStr(Player[0].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP1TwoPScore].Text := Tekst; + + Tekst := IntToStr(Player[1].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP2RScore].Text := Tekst; + end; + + if PlayersPlay = 3 then begin + Tekst := IntToStr(Player[0].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP1ThreePScore].Text := Tekst; + + Tekst := IntToStr(Player[1].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP2MScore].Text := Tekst; + + Tekst := IntToStr(Player[2].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP3RScore].Text := Tekst; + end; + + if PlayersPlay = 4 then begin + if ScreenAct = 1 then begin + Tekst := IntToStr(Player[0].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP1TwoPScore].Text := Tekst; + + Tekst := IntToStr(Player[1].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP2RScore].Text := Tekst; + end; + if ScreenAct = 2 then begin + Tekst := IntToStr(Player[2].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP1TwoPScore].Text := Tekst; + + Tekst := IntToStr(Player[3].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP2RScore].Text := Tekst; + end; + end; + + if PlayersPlay = 6 then begin + if ScreenAct = 1 then begin + Tekst := IntToStr(Player[0].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP1ThreePScore].Text := Tekst; + + Tekst := IntToStr(Player[1].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP2MScore].Text := Tekst; + + Tekst := IntToStr(Player[2].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP3RScore].Text := Tekst; + end; + if ScreenAct = 2 then begin + Tekst := IntToStr(Player[3].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP1ThreePScore].Text := Tekst; + + Tekst := IntToStr(Player[4].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP2MScore].Text := Tekst; + + Tekst := IntToStr(Player[5].ScoreTotalI); + while Length(Tekst) < 5 do Tekst := '0' + Tekst; + Text[TextP3RScore].Text := Tekst; + end; + end; } + + end; //ShowScore + + for S := 1 to 1 do + Static[S].Texture.X := Static[S].Texture.X + 10*ScreenX; + + for T := 0 to 1 do + Text[T].X := Text[T].X + 10*ScreenX; + + if DLLMan.Selected.LoadSong then + begin + // update static menu with time ... + Min := Round(LineState.CurrentTime) div 60; + Sec := Round(LineState.CurrentTime) mod 60; + Text[TextTimeText].Text := ''; + if Min < 10 then Text[TextTimeText].Text := '0'; + Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Min) + ':'; + if Sec < 10 then Text[TextTimeText].Text := Text[TextTimeText].Text + '0'; + Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Sec); + end; + + // draw static menu (BG) + DrawBG; + + //Draw Background + if (DllMan.Selected.LoadSong) AND (DllMan.Selected.LoadBack) then + SingDrawBackground; + + // 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 CurrentSong.VideoLoaded AND DllMan.Selected.LoadVideo then begin + UpdateSmpeg; // this only draws + end;} + + // draw static menu (FG) + DrawFG; + + if ShowFinish then begin + if DllMan.Selected.LoadSong then + begin + if (not AudioPlayback.Finished) and ((CurrentSong.Finish = 0) or (LineState.CurrentTime*1000 <= CurrentSong.Finish)) then begin + //Pause Mod: + if not Paused then + Sing(Self); // analyze song + end else begin + if not FadeOut then begin + Finish; + FadeOut := true; + FadeTo(@ScreenPartyScore); + end; + end; + end; + end; + + // draw custom items + SingModiDraw(PlayerInfo); // always draw + + //GoldenNoteStarsTwinkle Mod + GoldenRec.SpawnRec; + //GoldenNoteStarsTwinkle Mod + + //Update PlayerInfo + for I := 0 to PlayerInfo.NumPlayers-1 do + begin + if PlayerInfo.Playerinfo[I].Enabled then + begin + //PlayerInfo.Playerinfo[I].Bar := Player[I].ScorePercent; + PlayerInfo.Playerinfo[I].Score := Player[I].ScoreTotalI; + end; + end; + + if ((ShowFinish) AND (NOT Paused)) then + begin + if not DLLMan.PluginDraw(Playerinfo, Lines[0].Current) then + begin + if not FadeOut then begin + Finish; + FadeOut := true; + FadeTo(@ScreenPartyScore); + end; + end; + end; + + //Change PlayerInfo/Changeables + for I := 0 to PlayerInfo.NumPlayers-1 do + begin + if (Player[I].ScoreTotalI <> PlayerInfo.Playerinfo[I].Score) then + begin + //Player[I].ScoreTotal := Player[I].ScoreTotal + (PlayerInfo.Playerinfo[I].Score - Player[I].ScoreTotalI); + Player[I].ScoreTotalI := PlayerInfo.Playerinfo[I].Score; + end; + {if (PlayerInfo.Playerinfo[I].Bar <> Player[I].ScorePercent) then + Player[I].ScorePercentTarget := PlayerInfo.Playerinfo[I].Bar; } + end; + + // back stereo + Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10*ScreenX; + Text[TextP1].X := Text[TextP1].X - 10*ScreenX; + + {Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X - 10*ScreenX; + Text[TextP1Score].X := Text[TextP1Score].X - 10*ScreenX;} + + + Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X - 10*ScreenX; + Text[TextP2R].X := Text[TextP2R].X - 10*ScreenX; + + {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X - 10*ScreenX; + Text[TextP2RScore].X := Text[TextP2RScore].X - 10*ScreenX;} + + + for S := 1 to 1 do + Static[S].Texture.X := Static[S].Texture.X - 10*ScreenX; + + for T := 0 to 1 do + Text[T].X := Text[T].X - 10*ScreenX; + + Result := true; +end; + +procedure TScreenSingModi.Finish; +begin +inherited Finish; + +Winner := DllMan.PluginFinish(PlayerInfo); + +//Log.LogError('Winner: ' + InttoStr(Winner)); + +//DLLMan.UnLoadPlugin; +end; + +function LoadTex (const Name: PChar; Typ: TTextureType): TsmallTexture; stdcall; +var + Texname, EXT: String; + Tex: TTexture; +begin + //Get texture Name + TexName := Skin.GetTextureFileName(String(Name)); + //Get File Typ + Ext := ExtractFileExt(TexName); + if (uppercase(Ext) = '.JPG') then + Ext := 'JPG' + else + Ext := 'BMP'; + + Tex := Texture.LoadTexture(false, PChar(TexName), UTEXTURE.TTextureType(Typ), 0); + + Result.TexNum := Tex.TexNum; + Result.W := Tex.W; + Result.H := Tex.H; +end; +{ +function Translate (const Name: PChar): PChar; stdcall; +begin + Result := PChar(Language.Translate(String(Name))); +end; } + +procedure Print (const Style, Size: Byte; const X, Y: Real; const Text: PChar); stdcall; //Procedure to Print Text +begin + SetFontItalic ((Style and 128) = 128); + SetFontStyle(Style and 7); + SetFontSize(Size); + SetFontPos (X, Y); + glPrint (PChar(Language.Translate(String(Text)))); +end; + +function LoadSound (const Name: PChar): Cardinal; stdcall; //Procedure that loads a Custom Sound +var + S: TAudioPlaybackStream; + I: Integer; + F: String; +begin + //Search for Sound in already loaded Sounds + F := UpperCase(SoundPath + FileName); + For I := 0 to High(CustomSounds) do + begin + if (UpperCase(CustomSounds[I].Filename) = F) then + begin + Result := I; + Exit; + end; + end; + + S := AudioPlayback.OpenSound(SoundPath + String(Name)); + if (S <> nil) then + Result := High(CustomSounds) + else + Result := 0; +end; + +procedure PlaySound (const Index: Cardinal); stdcall; //Plays a Custom Sound +begin + if (Index <= High(CustomSounds)) then + AudioPlayback.PlaySound(CustomSounds[Index].Stream); +end; + +end. + diff --git a/Game/Code/Screens/UScreenSong.pas b/Game/Code/Screens/UScreenSong.pas index 27c137f7..609d46b1 100644 --- a/Game/Code/Screens/UScreenSong.pas +++ b/Game/Code/Screens/UScreenSong.pas @@ -144,7 +144,7 @@ uses UGraphic, procedure TScreenSong.FixSelected; var I, I2: Integer; begin - {if CatSongs.VisibleSongs > 0 then + if CatSongs.VisibleSongs > 0 then begin I2:= 0; for I := low(CatSongs.Song) to High(Catsongs.Song) do @@ -158,13 +158,13 @@ var I, I2: Integer; SongCurrent := I2; SongTarget := I2; - end; } + end; end; procedure TScreenSong.FixSelected2; var I, I2: Integer; - begin // to - do : new Song management - { if CatSongs.VisibleSongs > 0 then + begin + if CatSongs.VisibleSongs > 0 then begin I2:= 0; for I := low(CatSongs.Song) to High(Catsongs.Song) do @@ -177,7 +177,7 @@ var I, I2: Integer; end; SongTarget := I2; - end;} + end; end; //Show Wrong Song when Tabs on Fix End @@ -262,7 +262,7 @@ begin begin For I := 1 to high(CatSongs.Song) do begin - {if (CatSongs.Song[(I + Interaction) mod I2].Visible) AND + if (CatSongs.Song[(I + Interaction) mod I2].Visible) AND (Length(CatSongs.Song[(I + Interaction) mod I2].Title)>0) AND (WideUpperCase(CatSongs.Song[(I + Interaction) mod I2].Title)[1] = Letter) then begin @@ -275,15 +275,15 @@ begin //UpdateLCD; //TODO: maybe LCD Support as Plugin? //Break and Exit Exit; - end; } + end; end; end //Jump to Artist else if (SDL_ModState = KMOD_LALT) then begin For I := 1 to high(CatSongs.Song) do - begin // to - do : new Song management - {if (CatSongs.Song[(I + Interaction) mod I2].Visible) AND + begin + if (CatSongs.Song[(I + Interaction) mod I2].Visible) AND (Length(CatSongs.Song[(I + Interaction) mod I2].Artist)>0) AND (WideUpperCase(CatSongs.Song[(I + Interaction) mod I2].Artist)[1] = Letter) then begin @@ -297,7 +297,7 @@ begin //Break and Exit Exit; - end; } + end; end; end; end; @@ -316,8 +316,8 @@ begin 'M': //Show SongMenu begin if (Songs.SongList.Count > 0) then begin - if (Mode = smNormal) then begin // to - do : new Song management - {if not CatSongs.Song[Interaction].Main then begin // clicked on Song + if (Mode = smNormal) then begin + if not CatSongs.Song[Interaction].Main then begin // clicked on Song if CatSongs.CatNumShow = -3 then ScreenSongMenu.MenuShow(SM_Playlist) else @@ -326,7 +326,7 @@ begin else begin ScreenSongMenu.MenuShow(SM_Playlist_Load); - end;} + end; end //Party Mode -> Show Party Menu else ScreenSongMenu.MenuShow(SM_Party_Main); end; @@ -362,16 +362,16 @@ begin if (SDL_ModState = KMOD_LSHIFT) AND (Ini.Tabs_at_startup = 1) then //Random Category begin - I2 := 0; //Count Cats // to - do : new Song management - {for I:= low(CatSongs.Song) to high (CatSongs.Song) do - if CatSongs.Song[I].Main then Inc(I2);} + I2 := 0; //Count Cats + for I:= low(CatSongs.Song) to high (CatSongs.Song) do + if CatSongs.Song[I].Main then Inc(I2); I2 := Random (I2)+1; //Zufall //Find Cat: for I:= low(CatSongs.Song) to high (CatSongs.Song) do begin - {if CatSongs.Song[I].Main then + if CatSongs.Song[I].Main then Dec(I2); if (I2<=0) then begin @@ -385,23 +385,23 @@ begin SelectNext; FixSelected; break; - end; } - end; // to - do : new Song management + end; + end; end else if (SDL_ModState = KMOD_LCTRL) AND (Ini.Tabs_at_startup = 1) then //random in All Categorys begin - {repeat + repeat I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1; - until CatSongs.Song[I2].Main = false; } + until CatSongs.Song[I2].Main = false; //Search Cat - {for I := I2 downto low(CatSongs.Song) do + for I := I2 downto low(CatSongs.Song) do begin if CatSongs.Song[I].Main then break; - end; } + end; //In I is now the categorie in I2 the song //Choose Cat @@ -446,12 +446,12 @@ begin begin //Find Category I := Interaction; - {while not catsongs.Song[I].Main do + while not catsongs.Song[I].Main do begin Dec (I); if (I < low(catsongs.Song)) then break; - end; } + end; if (I<= 1) then Interaction := high(catsongs.Song) else @@ -514,8 +514,8 @@ begin begin {$IFDEF UseSerialPort} // PortWriteB($378, 0); - {$ENDIF} // to - do : new Song management - {if CatSongs.Song[Interaction].Main then + {$ENDIF} + if CatSongs.Song[Interaction].Main then begin // clicked on Category Button //Show Cat in Top Left Mod @@ -530,7 +530,7 @@ begin // SetScroll4; //Show Wrong Song when Tabs on Fix -{ SelectNext; + SelectNext; FixSelected; //Play Music: @@ -560,7 +560,7 @@ begin else ScreenSong.StartSong; end; - end; } + end; end; end; @@ -577,12 +577,12 @@ begin I := Interaction; if I <= 0 then I := 1; - {while not catsongs.Song[I].Main do + while not catsongs.Song[I].Main do begin Inc (I); if (I > high(catsongs.Song)) then I := low(catsongs.Song); - end; } + end; Interaction := I; @@ -618,14 +618,14 @@ begin I2 := 0; if I <= 0 then I := 1; - {while not catsongs.Song[I].Main or (I2 = 0) do + while not catsongs.Song[I].Main or (I2 = 0) do begin if catsongs.Song[I].Main then Inc(I2); Dec (I); if (I < low(catsongs.Song)) then I := high(catsongs.Song); - end; } + end; Interaction := I; @@ -790,7 +790,7 @@ var Pet: integer; Label CreateSongButtons; begin - {if (length(CatSongs.Song) > 0) then + if (length(CatSongs.Song) > 0) then begin //Set Length of Button Array one Time Instead of one time for every Song SetButtonLength(Length(CatSongs.Song)); @@ -803,30 +803,30 @@ begin // new Texture.Limit := 512;// 256 0.4.2 value, 512 in 0.5.0 - if not FileExists({CatSongs.Song[Pet].Path + }{CatSongs.Song[Pet].Cover) then + if not FileExists(CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover) then CatSongs.Song[Pet].Cover := ''; // 0.5.0: if cover not found then show 'no cover' - // to - do : new Song management + if CatSongs.Song[Pet].Cover = '' then AddButton(300 + Pet*250, 140, 200, 200, Skin.GetTextureFileName('SongCover'), TEXTURE_TYPE_PLAIN, Theme.Song.Cover.Reflections) else begin // cache texture if there is a need to this - if not Covers.CoverExists({CatSongs.Song[Pet].Path + }{CatSongs.Song[Pet].Cover) then + if not Covers.CoverExists(CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover) then begin Texture.CreateCacheMipmap := true; - Texture.GetTexture({CatSongs.Song[Pet].Path + }{CatSongs.Song[Pet].Cover, TEXTURE_TYPE_PLAIN, true); // preloads textures and creates cache mipmap + Texture.GetTexture(CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover, TEXTURE_TYPE_PLAIN, true); // preloads textures and creates cache mipmap Texture.CreateCacheMipmap := false; // puts this texture to the cache file - Covers.AddCover({CatSongs.Song[Pet].Path + }{CatSongs.Song[Pet].Cover); + Covers.AddCover(CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover); // unload full size texture - Texture.UnloadTexture({CatSongs.Song[Pet].Path + }{CatSongs.Song[Pet].Cover, TEXTURE_TYPE_PLAIN, false); + Texture.UnloadTexture(CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover, TEXTURE_TYPE_PLAIN, false); // we should also add mipmap texture by calling createtexture and use mipmap cache as data source end; // and now load it from cache file (small place for the optimization by eliminating reading it from file, but not here) - AddButton(300 + Pet*250, 140, 200, 200,{ CatSongs.Song[Pet].Path + }{CatSongs.Song[Pet].Cover, TEXTURE_TYPE_PLAIN, Theme.Song.Cover.Reflections); + AddButton(300 + Pet*250, 140, 200, 200, CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover, TEXTURE_TYPE_PLAIN, Theme.Song.Cover.Reflections); end; Texture.Limit := 1024*1024; I := -1; @@ -848,7 +848,7 @@ begin try AddButton(300 + Pet*250, 140, 200, 200, '', TEXTURE_TYPE_PLAIN, Theme.Song.Cover.Reflections); except - ShowMessage('"No Cover" image is damaged. Ultrastar will exit now.'); + ShowMessage('"No Cover" image is damaged. Ultrastar will exit now.'); Halt; end; I := Pet + 1; @@ -858,7 +858,7 @@ begin if (I <> -1) then GoTo CreateSongButtons; - end; } + end; end; procedure TScreenSong.SetScroll; @@ -886,7 +886,7 @@ begin //Set Texts: Text[TextArtist].Text := CatSongs.Song[Interaction].Artist; Text[TextTitle].Text := CatSongs.Song[Interaction].Title; - {if (Ini.Tabs_at_startup = 1) And (CatSongs.CatNumShow = -1) then + if (Ini.Tabs_at_startup = 1) And (CatSongs.CatNumShow = -1) then begin Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].OrderNum) + '/' + IntToStr(CatSongs.CatCount); Text[TextTitle].Text := '(' + IntToStr(CatSongs.Song[Interaction].CatNumber) + ' ' + Language.Translate('SING_SONGS_IN_CAT') + ')'; @@ -898,15 +898,15 @@ begin else if (Ini.Tabs_at_startup = 1) then Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].CatNumber) + '/' + IntToStr(CatSongs.Song[Interaction - CatSongs.Song[Interaction].CatNumber].CatNumber) else - Text[TextNumber].Text := IntToStr(Interaction+1) + '/' + IntToStr(Length(CatSongs.Song));} + Text[TextNumber].Text := IntToStr(Interaction+1) + '/' + IntToStr(Length(CatSongs.Song)); end else begin Text[TextNumber].Text := '0/0'; Text[TextArtist].Text := ''; Text[TextTitle].Text := ''; - {for B := 0 to High(Button) do - Button[B].Visible := False; } + for B := 0 to High(Button) do + Button[B].Visible := False; end; end; @@ -934,12 +934,12 @@ begin Placed := 0; VisCount := 0; - {for B := 0 to High(Button) do - if CatSongs.Song[B].Visible then Inc(VisCount);} + for B := 0 to High(Button) do + if CatSongs.Song[B].Visible then Inc(VisCount); VisInt := 0; - {for B := 0 to Interaction-1 do - if CatSongs.Song[B].Visible then Inc(VisInt); } + for B := 0 to Interaction-1 do + if CatSongs.Song[B].Visible then Inc(VisInt); if VisCount <= 6 then begin @@ -964,11 +964,11 @@ begin end; - // to - do : new Song management + // hide all buttons for B := 0 to High(Button) do begin Button[B].Visible := false; - //Button[B].Selectable := CatSongs.Song[B].Visible; + Button[B].Selectable := CatSongs.Song[B].Visible; end; { for B := Src to Dst do begin @@ -979,7 +979,7 @@ begin end;} - {if Typ = 0 then begin + if Typ = 0 then begin for B := 0 to High(Button) do begin if CatSongs.Song[B].Visible then begin Button[B].Visible := true; @@ -987,9 +987,9 @@ begin Inc(Placed); end; end; - end; } + end; - {if Typ = 1 then begin + if Typ = 1 then begin B := 0; while (Count > 0) do begin if CatSongs.Song[B].Visible then begin @@ -1000,9 +1000,9 @@ begin end; Inc(B); end; - end; } + end; - {if Typ = 2 then begin + if Typ = 2 then begin B := High(Button); while (Count > 0) do begin if CatSongs.Song[B].Visible then begin @@ -1044,7 +1044,7 @@ begin end; if Length(Button) > 0 then - Static[1].Texture.Y := Button[Interaction].Y - 5; // selection texture } + Static[1].Texture.Y := Button[Interaction].Y - 5; // selection texture end; procedure TScreenSong.SetScroll2; @@ -1053,7 +1053,7 @@ var // Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu // Auto Removed, Unused Variable // Wsp2: real; // Auto Removed, Unused Variable begin - {// liniowe + // liniowe for B := 0 to High(Button) do Button[B].X := 300 + (B - Interaction) * 260; @@ -1080,7 +1080,7 @@ var // Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu // Auto Removed, Unused Variable // Wsp2: real; // Auto Removed, Unused Variable begin - {SongTarget := Interaction; + SongTarget := Interaction; // liniowe for B := 0 to High(Button) do @@ -1116,7 +1116,7 @@ var Z, Z2: real; VS: integer; begin - {VS := CatSongs.VisibleSongs; // 0.5.0 (I): cached, very important + VS := CatSongs.VisibleSongs; // 0.5.0 (I): cached, very important // kolowe for B := 0 to High(Button) do begin @@ -1124,7 +1124,7 @@ begin if Button[B].Visible then begin // 0.5.0 optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / VS {CatSongs.VisibleSongs};// 0.5.0 (II): takes another 16ms -{ + Z := (1 + cos(Wsp)) / 2; Z2 := (1 + 2*Z) / 3; @@ -1134,11 +1134,11 @@ begin Button[B].W := Theme.Song.Cover.H * Z2; -// Button[B].Y := {50 +}{ 140 + 50 - 50 * Z2; -{ Button[B].Y := Theme.Song.Cover.Y + (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7 ; +// Button[B].Y := {50 +} 140 + 50 - 50 * Z2; + Button[B].Y := Theme.Song.Cover.Y + (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7 ; Button[B].H := Button[B].W; end; - end;} + end; end; (* @@ -1234,7 +1234,7 @@ var X: Real; helper: real; begin - {VS := CatSongs.VisibleSongs; // cache Visible Songs + VS := CatSongs.VisibleSongs; // cache Visible Songs {Vars Theme.Song.CoverW: Radius des Kreises Theme.Song.CoverX: X Pos Linke Kante des gewählten Covers @@ -1242,7 +1242,7 @@ begin Theme.Song.CoverH: Höhe der Cover (CatSongs.VisibleIndex(B) - SongCurrent)/VS = Distance to middle Cover in % - }{ + } //Change Pos of all Buttons for B := low(Button) to high(Button) do @@ -1256,7 +1256,7 @@ begin else if (Pos > VS/2) then Pos := Pos - VS; - if (Abs(Pos) < 2.5) then {fixed Positions} { + if (Abs(Pos) < 2.5) then {fixed Positions} begin Angle := Pi * (Pos / 5); // Button[B].Visible := False; @@ -1281,7 +1281,7 @@ begin end else - begin {Behind the Front Covers} { + begin {Behind the Front Covers} // limit-bg-covers hack if (abs(abs(Pos)-VS/2)>10) then Button[B].Visible:=False; @@ -1322,7 +1322,7 @@ begin // Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Button[B].H) * 0.7); end; - end; } + end; end; procedure TScreenSong.SetScroll6; // rotate (slotmachine style) @@ -1336,7 +1336,7 @@ var Wsp: real; Z, Z2: real; begin - {VS := CatSongs.VisibleSongs; // cache Visible Songs + VS := CatSongs.VisibleSongs; // cache Visible Songs if VS <=5 then begin // kolowe for B := 0 to High(Button) do @@ -1345,7 +1345,7 @@ begin if Button[B].Visible then begin // 0.5.0 optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / VS {CatSongs.VisibleSongs};// 0.5.0 (II): takes another 16ms - { + Z := (1 + cos(Wsp)) / 2; Z2 := (1 + 2*Z) / 3; @@ -1355,9 +1355,9 @@ begin Button[B].W := Theme.Song.Cover.H * Z2; -// Button[B].Y := {50 +}{ 140 + 50 - 50 * Z2; +// Button[B].Y := {50 +} 140 + 50 - 50 * Z2; Button[B].X := Theme.Song.Cover.X + (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7 ; - Button[B].H := Button[B].W; { + Button[B].H := Button[B].W; end; end; end @@ -1375,7 +1375,7 @@ begin else if (Pos > VS/2) then Pos := Pos - VS; - if (Abs(Pos) < 2.5) then {fixed Positions} { + if (Abs(Pos) < 2.5) then {fixed Positions} begin Angle := Pi * (Pos / 5); // Button[B].Visible := False; @@ -1398,7 +1398,7 @@ begin Button[B].Y := Theme.Song.Cover.Y + Theme.Song.Cover.W * X - Diff; end else - begin {Behind the Front Covers} { + begin {Behind the Front Covers} // limit-bg-covers hack if (abs(VS/2-abs(Pos))>10) then Button[B].Visible:=False; @@ -1427,7 +1427,7 @@ begin end; end; end; - end; } + end; end; @@ -1453,8 +1453,8 @@ begin if Length(CatSongs.Song) > 0 then begin //Load Music only when Song Preview is activated if ( Ini.PreviewVolume <> 0 ) then - begin // to - do : new Song management - if(AudioPlayback.Open({CatSongs.Song[Interaction].Path + }CatSongs.Song[Interaction].Mp3)) then + begin + if(AudioPlayback.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3)) then begin AudioPlayback.SetLoop(false); AudioPlayback.Position := AudioPlayback.Length / 4; @@ -1508,8 +1508,8 @@ begin AudioPlayback.SetMusicVolume(100); //If Preview is deactivated: Load MUsicfile now - If (Ini.PreviewVolume = 0) then // to - do : new Song management - AudioPlayback.Open({Song[Interaction].Path + } CatSongs.Song[Interaction].Mp3); + If (Ini.PreviewVolume = 0) then + AudioPlayback.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3); //When hide then Stop Music (For Party Mode Popup on Exit) if (Display.NextScreen <> @ScreenSing) and (Display.NextScreen <> @ScreenSingModi) and (AudioPlayback <> nil) then @@ -1565,9 +1565,9 @@ begin Button[Interaction].Texture2 := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false); Button[Interaction].Texture2.Alpha := 1; end; - // to - do : new Song management + //Song Fade - if (CatSongs.VisibleSongs > 0) AND (Ini.PreviewVolume <> 0) {AND (Not CatSongs.Song[Interaction].Main)} AND (Ini.PreviewFading <> 0) then + if (CatSongs.VisibleSongs > 0) AND (Ini.PreviewVolume <> 0) AND (Not CatSongs.Song[Interaction].Main) AND (Ini.PreviewFading <> 0) then begin //Start Song Fade after a little Time, to prevent Song to be Played on Scrolling if (CoverTime < 0.2) and (CoverTime + TimeSkip >= 0.2) then @@ -1636,9 +1636,9 @@ begin Skip := 1; // this 1 could be changed by CatSongs.FindNextVisible - {while (not CatSongs.Song[(Interaction + Skip) mod Length(Interactions)].Visible) do Inc(Skip); + while (not CatSongs.Song[(Interaction + Skip) mod Length(Interactions)].Visible) do Inc(Skip); - }SongTarget := SongTarget + 1;//Skip; + SongTarget := SongTarget + 1;//Skip; Interaction := (Interaction + Skip) mod Length(Interactions); @@ -1667,8 +1667,8 @@ begin Skip := 1; - {while (not CatSongs.Song[(Interaction - Skip + Length(Interactions)) mod Length(Interactions)].Visible) do Inc(Skip); - }SongTarget := SongTarget - 1;//Skip; + while (not CatSongs.Song[(Interaction - Skip + Length(Interactions)) mod Length(Interactions)].Visible) do Inc(Skip); + SongTarget := SongTarget - 1;//Skip; Interaction := (Interaction - Skip + Length(Interactions)) mod Length(Interactions); @@ -1699,7 +1699,7 @@ begin //When Music Preview is avtivated -> then Change Music if (Ini.PreviewVolume <> 0) then begin - {if (NOT CatSongs.Song[Interaction].Main) AND(CatSongs.VisibleSongs > 0) then + if (NOT CatSongs.Song[Interaction].Main) AND(CatSongs.VisibleSongs > 0) then begin AudioPlayback.Close; if AudioPlayback.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3) then begin @@ -1712,7 +1712,7 @@ begin end; end else - AudioPlayback.Stop; } + AudioPlayback.Stop; end; end; @@ -1852,17 +1852,17 @@ begin begin //When Tabs are activated then use Tab Method if (Ini.Tabs_at_startup = 1) then - begin // to - do : new Song management - {repeat + begin + repeat I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1; - until CatSongs.Song[I2].Main = false;} + until CatSongs.Song[I2].Main = false; //Search Cat - {for I := I2 downto low(CatSongs.Song) do + for I := I2 downto low(CatSongs.Song) do begin if CatSongs.Song[I].Main then break; - end; } + end; //In I ist jetzt die Kategorie in I2 der Song //I is the CatNum, I2 is the No of the Song within this Cat @@ -2040,14 +2040,14 @@ begin end; procedure TScreenSong.OpenEditor; -begin // to - do : new Song management - {if (Songs.SongList.Count > 0) and (not CatSongs.Song[Interaction].Main) AND (Mode = smNormal) then +begin + if (Songs.SongList.Count > 0) and (not CatSongs.Song[Interaction].Main) AND (Mode = smNormal) then begin AudioPlayback.Stop; AudioPlayback.PlaySound(SoundLib.Start); CurrentSong := CatSongs.Song[Interaction]; FadeTo(@ScreenEditSub); - end; } + end; end; //Team No of Team (0-5) diff --git a/Game/Code/Screens/UScreenTop5.pas b/Game/Code/Screens/UScreenTop5.pas index 2a673880..7ad46d49 100644 --- a/Game/Code/Screens/UScreenTop5.pas +++ b/Game/Code/Screens/UScreenTop5.pas @@ -101,26 +101,26 @@ begin //ReadScore(CurrentSong); PMax := Ini.Players; - if Ini.Players = 4 then Ini.Players := 5; // to - do : new Song management - {for I := 0 to PMax do + if Ini.Players = 4 then Ini.Players := 5; + for I := 0 to PMax do DataBase.AddScore(CurrentSong, Ini.Difficulty, Ini.Name[I], Round(Player[I].ScoreTotalI)); DataBase.WriteScore(CurrentSong); - DataBase.ReadScore(CurrentSong); } + DataBase.ReadScore(CurrentSong); Text[TextArtistTitle].Text := CurrentSong.Artist + ' - ' + CurrentSong.Title; - for I := 1 to Length(CurrentSong.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 := CurrentSong.Score(Ini.Difficulty)[I-1].Name; - Text[TextScore[I]].Text := IntToStr(CurrentSong.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(CurrentSong.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 08513eb7..5ba06b79 100644 --- a/Game/Code/UltraStar.dpr +++ b/Game/Code/UltraStar.dpr @@ -109,8 +109,6 @@ uses UTime in 'Classes\UTime.pas', TextGL in 'Classes\TextGL.pas', USong in 'Classes\USong.pas', - USong_TextFile in 'Classes\USong_TextFile.pas', - USong_Txt in 'Classes\USong_Txt.pas', UXMLSong in 'Classes\UXMLSong.pas', USongs in 'Classes\USongs.pas', UIni in 'Classes\UIni.pas', -- cgit v1.2.3