From 278ff525686374c51d542e608ee612da8cdaec6d Mon Sep 17 00:00:00 2001 From: tobigun Date: Sat, 7 Jun 2008 18:43:58 +0000 Subject: just some cleanup - replaced many German and Polish comments - replaced many cryptic var-names - IlNut replaced with LengthNote - renamed the global var "Filename" to "ConversionFilename" to prevent unintended use of it - more readable code (hopefully), especially NewNote and OnSentenceEnd - added some comments on elementary classes/records and their fields git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1137 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/TextGL.pas | 106 +++--- Game/Code/Classes/UDraw.pas | 367 ++++++++++--------- Game/Code/Classes/UFiles.pas | 2 +- Game/Code/Classes/UIni.pas | 15 + Game/Code/Classes/UMain.pas | 518 +++++++++++++++------------ Game/Code/Classes/UMusic.pas | 51 ++- Game/Code/Classes/UParty.pas | 6 +- Game/Code/Classes/USingScores.pas | 18 +- Game/Code/Screens/UScreenEditConvert.pas | 8 +- Game/Code/Screens/UScreenEditHeader.pas | 2 +- Game/Code/Screens/UScreenOpen.pas | 8 +- Game/Code/Screens/UScreenScore.pas | 40 +-- Game/Code/Screens/UScreenSing.pas | 345 +++++++++--------- Game/Code/Screens/UScreenSingModi.pas | 43 ++- Game/Code/Screens/UScreenSong.pas | 593 ++++++++++++++++--------------- Game/Code/Screens/UScreenTop5.pas | 2 +- 16 files changed, 1117 insertions(+), 1007 deletions(-) (limited to 'Game/Code') diff --git a/Game/Code/Classes/TextGL.pas b/Game/Code/Classes/TextGL.pas index b21a5237..1396ae1b 100644 --- a/Game/Code/Classes/TextGL.pas +++ b/Game/Code/Classes/TextGL.pas @@ -20,23 +20,24 @@ uses SDL_ttf, ULog; -procedure BuildFont; // Build Our Bitmap Font -procedure KillFont; // Delete The Font -function glTextWidth(text: pchar): real; // Returns Text Width +procedure BuildFont; // build our bitmap font +procedure KillFont; // delete the font +function glTextWidth(text: pchar): real; // returns text width procedure glPrintDone(text: pchar; Done: real; ColR, ColG, ColB: real); procedure glPrintLetter(letter: char); procedure glPrintLetterCut(letter: char; Start, Finish: real); -procedure glPrint(text: pchar); // Custom GL "Print" Routine +procedure glPrint(text: pchar); // custom GL "Print" routine procedure glPrintCut(text: pchar); -procedure SetFontPos(X, Y: real); // Sets X And Y +procedure SetFontPos(X, Y: real); // sets X and Y procedure SetFontSize(Size: real); -procedure SetFontStyle(Style: integer); // sets active font style (normal, bold, etc) -procedure SetFontItalic(Enable: boolean); // sets italic type letter (works for all fonts) +procedure SetFontStyle(Style: integer); // sets active font style (normal, bold, etc) +procedure SetFontItalic(Enable: boolean); // sets italic type letter (works for all fonts) procedure SetFontAspectW(Aspect: real); procedure SetFontReflection(Enable:boolean;Spacing: real); // Enables/Disables text reflection + // Start of SDL_ttf function NextPowerOfTwo(Value: integer): integer; -//Checks if the ttf exists, if yes then a SDL_ttf is returned +// Checks if the ttf exists, if yes then a SDL_ttf is returned function LoadFont(FileName: PAnsiChar; PointSize: integer):PTTF_Font; // Does the renderstuff, color is in $ffeecc style @@ -69,7 +70,7 @@ type var - base: GLuint; // Base Display List For The Font Set + base: GLuint; // base display list for the font set Fonts: array of TFont; ActFont: integer; PColR: real; // temps for glPrintDone @@ -79,6 +80,7 @@ var // Colours for the reflection TempColor: array[0..3] of GLfloat; PTempColor: PGLfloat; + implementation uses @@ -87,26 +89,26 @@ uses SysUtils, UGraphic; -procedure BuildFont; // Build Our Bitmap Font - - procedure loadfont(aID : integer; const aType, aResourceName: string); - var - stream: TStream; +procedure LoadBitmapFontInfo(aID : integer; const aType, aResourceName: string); +var + stream: TStream; +begin + stream := GetResourceStream(aResourceName, aType); + if (not assigned(stream)) then begin - stream := GetResourceStream(aResourceName, aType); - if (not assigned(stream)) then - begin - Log.LogError('Unknown font['+ inttostr(aID) +': '+aType+']', 'loadfont'); - Exit; - end; - try - stream.Read(Fonts[ aID ].Width, 256); - except - Log.LogError('Error while reading font['+ inttostr(aID) +': '+aType+']', 'loadfont'); - end; - stream.Free; + Log.LogError('Unknown font['+ inttostr(aID) +': '+aType+']', 'loadfont'); + Exit; end; + try + stream.Read(Fonts[ aID ].Width, 256); + except + Log.LogError('Error while reading font['+ inttostr(aID) +': '+aType+']', 'loadfont'); + end; + stream.Free; +end; +// Builds bitmap fonts +procedure BuildFont; var Count: integer; begin @@ -150,16 +152,11 @@ begin Fonts[4].Done := -1; Fonts[4].Outline := 5;} - - - loadfont( 0, 'FNT', 'Font' ); - loadfont( 1, 'FNT', 'FontB' ); - loadfont( 2, 'FNT', 'FontO' ); - loadfont( 3, 'FNT', 'FontO2' ); - -{ Reg := TResourceStream.Create(HInstance, 'FontO', 'FNT'); - Reg.Read(Fonts[4].Width, 256); - Reg.Free;} + // load font info + LoadBitmapFontInfo( 0, 'FNT', 'Font' ); + LoadBitmapFontInfo( 1, 'FNT', 'FontB' ); + LoadBitmapFontInfo( 2, 'FNT', 'FontO' ); + LoadBitmapFontInfo( 3, 'FNT', 'FontO2' ); for Count := 0 to 255 do Fonts[1].Width[Count] := Fonts[1].Width[Count] div 2; @@ -175,9 +172,11 @@ begin end; -procedure KillFont; // Delete The Font +// Deletes the font +procedure KillFont; begin -// glDeleteLists(base, 256); // Delete All 96 Characters + // delete all characters + //glDeleteLists(base, 256); end; function glTextWidth(text: pchar): real; @@ -185,13 +184,10 @@ var Letter: char; i: integer; begin -// Log.LogStatus(Text, 'glTextWidth'); Result := 0; - for i := 0 to Length(text) -1 do // Patched by AlexanderS : bug with wrong sliced text lines + for i := 0 to Length(text) -1 do begin Letter := Text[i]; - // Bugfix: does not work with FPC, probably because a part of text is assigned to itself - //text := pchar(Copy(text, 2, Length(text)-1)); Result := Result + Fonts[ActFont].Width[Ord(Letter)] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW; end; end; @@ -316,7 +312,7 @@ begin FWidth := Fonts[ActFont].Width[Ord(Letter)]; W := FWidth * (H/30) * Fonts[ActFont].AspectW; -// H := 30; + //H := 30; OutTemp := Fonts[ActFont].Outline * (H/30) * Fonts[ActFont].AspectW; // set texture positions @@ -356,14 +352,14 @@ begin end; -procedure glPrint(text: pchar); // Custom GL "Print" Routine +// Custom GL "Print" Routine +procedure glPrint(text: pchar); var -// Letter : char; + //Letter : char; iPos : integer; - begin if (Text = '') then // If There's No Text - Exit; // Do Nothing + Exit; // Do Nothing (* while (length(text) > 0) do @@ -377,9 +373,9 @@ begin end; // while *) -//Save the actual color and alpha (for reflection) + //Save the actual color and alpha (for reflection) PTempColor:= @TempColor; -//I've read that glGetFloat is quite slow, but it seems that there is no alternative + //I've read that glGetFloat is quite slow, but it seems that there is no alternative glGetFloatv(GL_CURRENT_COLOR, PTempColor); // This code is better, because doing a Copy of for every @@ -393,9 +389,9 @@ begin end; -function NextPowerOfTwo(Value: integer): integer; // tyty to Asphyre // FIXME: check if the non-asm version is fast enough and use it by default if so +function NextPowerOfTwo(Value: integer): integer; begin Result:= 1; {$IF Defined(CPUX86_64)} @@ -465,14 +461,14 @@ begin clrbg.unused := 0; sText := RenderText(font, 'katzeeeeeee', $fe198e); -// sText := TTF_RenderText_Blended( font, 'huuuuuuuuuund', clrFG); + //sText := TTF_RenderText_Blended( font, 'huuuuuuuuuund', clrFG); -// Convert the rendered text to a known format + // Convert the rendered text to a known format w := nextpoweroftwo(sText.w); h := nextpoweroftwo(sText.h); intermediary := SDL_CreateRGBSurface(0, w, h, 32, - $000000ff, $0000ff00, $00ff0000, $ff000000); + $000000ff, $0000ff00, $00ff0000, $ff000000); SDL_SetAlpha(intermediary, 0, 255); SDL_SetAlpha(sText, 0, 255); @@ -518,8 +514,8 @@ var PDoingNow: real; S: string; begin - if (Text = '') then // If There's No Text - Exit; // Do Nothing + if (Text = '') then // If There's No Text + Exit; // Do Nothing PTotWidth := glTextWidth(Text); PToDo := Fonts[ActFont].Done; diff --git a/Game/Code/Classes/UDraw.pas b/Game/Code/Classes/UDraw.pas index 53508baf..d82fef33 100644 --- a/Game/Code/Classes/UDraw.pas +++ b/Game/Code/Classes/UDraw.pas @@ -19,8 +19,8 @@ procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer); procedure SingDrawNoteLines(Left, Top, Right: real; Space: integer); procedure SingDrawBeatDelimeters(Left, Top, Right: real; NrLines: integer); procedure SingDrawLine(Left, Top, Right: real; NrLines: integer; Space: integer); -procedure SingDrawPlayerLine(X, Y, W: real; NrGracza: integer; Space: integer); -procedure SingDrawPlayerBGLine(Left, Top, Right: real; NrLines, NrGracza: integer; Space: integer); +procedure SingDrawPlayerLine(X, Y, W: real; PlayerIndex: integer; Space: integer); +procedure SingDrawPlayerBGLine(Left, Top, Right: real; NrLines, PlayerIndex: integer; Space: integer); // TimeBar procedure SingDrawTimeBar(); @@ -338,129 +338,122 @@ end; // draw sung notes -procedure SingDrawPlayerLine(X, Y, W: real; NrGracza: integer; Space: integer); +procedure SingDrawPlayerLine(X, Y, W: real; PlayerIndex: integer; Space: integer); var - TempR: real; - Rec: TRecR; - N: integer; - R: real; - G: real; - B: real; - A: real; - NotesH2: real; - begin -// Log.LogStatus('Player notes', 'SingDraw'); + TempR: real; + Rec: TRecR; + N: integer; + R, G, B, A: real; + NotesH2: real; +begin + //Log.LogStatus('Player notes', 'SingDraw'); -// if NrGracza = 0 then LoadColor(R, G, B, 'P1Light') -// else LoadColor(R, G, B, 'P2Light'); + //if NrGracza = 0 then LoadColor(R, G, B, 'P1Light') + //else LoadColor(R, G, B, 'P2Light'); -// R := 71/255; -// G := 175/255; -// B := 247/255; + //R := 71/255; + //G := 175/255; + //B := 247/255; glColor3f(1, 1, 1); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -//// if Player[NrGracza].IlNut > 0 then + //if Player[NrGracza].LengthNote > 0 then + begin + TempR := W / (Lines[0].Line[Lines[0].Current].End_ - Lines[0].Line[Lines[0].Current].Note[0].Start); + for N := 0 to Player[PlayerIndex].HighNote do begin - TempR := W / (Lines[0].Line[Lines[0].Current].End_ - Lines[0].Line[Lines[0].Current].Note[0].Start); - for N := 0 to Player[NrGracza].HighNote do + with Player[PlayerIndex].Note[N] do + begin + // Left part of note + Rec.Left := X + (Start-Lines[0].Line[Lines[0].Current].Note[0].Start) * TempR + 0.5 + 10*ScreenX; + Rec.Right := Rec.Left + NotesW; + + // Draw it in half size, if not hit + if Hit then + begin + NotesH2 := NotesH + end + else + begin + NotesH2 := int(NotesH * 0.65); + end; + + Rec.Top := Y - (Tone-Lines[0].Line[Lines[0].Current].BaseNote)*Space/2 - NotesH2; + Rec.Bottom := Rec.Top + 2 *NotesH2; + + // draw the left part + glColor3f(1, 1, 1); + glBindTexture(GL_TEXTURE_2D, Tex_Left[PlayerIndex+1].TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + + // Middle part of the note + Rec.Left := Rec.Right; + Rec.Right := X + (Start+Length-Lines[0].Line[Lines[0].Current].Note[0].Start) * TempR - NotesW - 0.5 + 10*ScreenX; + + // (nowe) - dunno + if (Start+Length-1 = LineState.CurrentBeatD) then + Rec.Right := Rec.Right - (1-Frac(LineState.MidBeatD)) * TempR; + // the left note is more right than the right note itself, sounds weird - so we fix that xD + if Rec.Right <= Rec.Left then + Rec.Right := Rec.Left; + + // draw the middle part + glBindTexture(GL_TEXTURE_2D, Tex_Mid[PlayerIndex+1].TexNum); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(round((Rec.Right-Rec.Left)/32), 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(round((Rec.Right-Rec.Left)/32), 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + glColor3f(1, 1, 1); + + // the right part of the note + Rec.Left := Rec.Right; + Rec.Right := Rec.Right + NotesW; + + glBindTexture(GL_TEXTURE_2D, Tex_Right[PlayerIndex+1].TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + + // Perfect note is stored + if Perfect and (Ini.EffectSing=1) then + begin + A := 1 - 2*(LineState.CurrentTime - GetTimeFromBeat(Start+Length)); + if not (Start+Length-1 = LineState.CurrentBeatD) then begin - with Player[NrGracza].Note[N] do - begin - // Left part of note - Rec.Left := X + (Start-Lines[0].Line[Lines[0].Current].Note[0].Start) * TempR + 0.5 + 10*ScreenX; - Rec.Right := Rec.Left + NotesW; - - // Draw it in half size, if not hit - if Hit then - begin - NotesH2 := NotesH - end - else - begin - NotesH2 := int(NotesH * 0.65); - end; - - Rec.Top := Y - (Tone-Lines[0].Line[Lines[0].Current].BaseNote)*Space/2 - NotesH2; - Rec.Bottom := Rec.Top + 2 *NotesH2; - - // draw the left part - glColor3f(1, 1, 1); - glBindTexture(GL_TEXTURE_2D, Tex_Left[NrGracza+1].TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - - // Middle part of the note - Rec.Left := Rec.Right; - Rec.Right := X + (Start+Length-Lines[0].Line[Lines[0].Current].Note[0].Start) * TempR - NotesW - 0.5 + 10*ScreenX; - - // (nowe) - dunno - if (Start+Length-1 = LineState.CurrentBeatD) then - Rec.Right := Rec.Right - (1-Frac(LineState.MidBeatD)) * TempR; - // the left note is more right than the right note itself, sounds weird - so we fix that xD - if Rec.Right <= Rec.Left then Rec.Right := Rec.Left; - - // draw the middle part - glBindTexture(GL_TEXTURE_2D, Tex_Mid[NrGracza+1].TexNum); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(round((Rec.Right-Rec.Left)/32), 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(round((Rec.Right-Rec.Left)/32), 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - glColor3f(1, 1, 1); - - // the right part of the note - Rec.Left := Rec.Right; - Rec.Right := Rec.Right + NotesW; - - glBindTexture(GL_TEXTURE_2D, Tex_Right[NrGracza+1].TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - - // Perfect note is stored - if Perfect and (Ini.EffectSing=1) then - begin - A := 1 - 2*(LineState.CurrentTime - GetTimeFromBeat(Start+Length)); - if not (Start+Length-1 = LineState.CurrentBeatD) then - - //Star animation counter - //inc(Starfr); - //Starfr := Starfr mod 128; - GoldenRec.SavePerfectNotePos(Rec.Left, Rec.Top); - end; - end; // with - end; // for - // eigentlich brauchen wir hier einen vergleich, um festzustellen, ob wir mit - // singen schon weiter wären, als bei Rec.Right, _auch, wenn nicht gesungen wird_ - // English Translation: - // actually we need a compare here, to determine if the singing process is ahead Rec.Right - // even if there is no singing - - - // passing on NrGracza... hope this is really something like the player-number, not only - // some kind of weird index into a colour-table - - if (Ini.EffectSing=1) then - GoldenRec.GoldenNoteTwinkle(Rec.Top,Rec.Bottom,Rec.Right, NrGracza); + //Star animation counter + //inc(Starfr); + //Starfr := Starfr mod 128; + GoldenRec.SavePerfectNotePos(Rec.Left, Rec.Top); + end; + end; + end; // with + end; // for + + // actually we need a comparison here, to determine if the singing process + // is ahead Rec.Right even if there is no singing + + if (Ini.EffectSing = 1) then + GoldenRec.GoldenNoteTwinkle(Rec.Top,Rec.Bottom,Rec.Right, PlayerIndex); end; // if end; //draw Note glow -procedure SingDrawPlayerBGLine(Left, Top, Right: real; NrLines, NrGracza: integer; Space: integer); +procedure SingDrawPlayerBGLine(Left, Top, Right: real; NrLines, PlayerIndex: integer; Space: integer); var Rec: TRecR; Count: integer; @@ -472,87 +465,89 @@ var lTmpA , lTmpB : real; begin - if (Player[NrGracza].ScoreTotalI >= 0) then begin - glColor4f(1, 1, 1, sqrt((1+sin( AudioPlayback.Position * 3))/4)/ 2 + 0.5 ); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - - lTmpA := (Right-Left); - lTmpB := (Lines[NrLines].Line[Lines[NrLines].Current].End_ - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start); - - - if ( lTmpA > 0 ) AND - ( lTmpB > 0 ) THEN - begin - TempR := lTmpA / lTmpB; - end - else + if (Player[PlayerIndex].ScoreTotalInt >= 0) then begin - TempR := 0; - end; - - with Lines[NrLines].Line[Lines[NrLines].Current] do begin - for Count := 0 to HighNote do begin - with Note[Count] do begin - if NoteType <> ntFreestyle then begin - // begin: 14, 20 - // easy: 6, 11 - W := NotesW * 2 + 2; - H := NotesH * 1.5 + 3.5; - - X2 := (Start-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left + 0.5 + 10*ScreenX + 4; // wciecie - X1 := X2-W; - - X3 := (Start+Length-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left - 0.5 + 10*ScreenX - 4; // wciecie - X4 := X3+W; - - // left - Rec.Left := X1; - Rec.Right := X2; - Rec.Top := Top - (Tone-BaseNote)*Space/2 - H; - Rec.Bottom := Rec.Top + 2 * H; - - glBindTexture(GL_TEXTURE_2D, Tex_BG_Left[NrGracza+1].TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - - - // srodkowa czesc - Rec.Left := X2; - Rec.Right := X3; + glColor4f(1, 1, 1, sqrt((1+sin( AudioPlayback.Position * 3))/4)/ 2 + 0.5 ); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBindTexture(GL_TEXTURE_2D, Tex_BG_Mid[NrGracza+1].TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; + lTmpA := (Right-Left); + lTmpB := (Lines[NrLines].Line[Lines[NrLines].Current].End_ - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start); - // prawa czesc - Rec.Left := X3; - Rec.Right := X4; + if ( lTmpA > 0 ) and + ( lTmpB > 0 ) then + begin + TempR := lTmpA / lTmpB; + end + else + begin + TempR := 0; + end; - glBindTexture(GL_TEXTURE_2D, Tex_BG_Right[NrGracza+1].TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - end; // if not FreeStyle - end; // with - end; // for - end; // with 1 + with Lines[NrLines].Line[Lines[NrLines].Current] do + begin + for Count := 0 to HighNote do + begin + with Note[Count] do + begin + if NoteType <> ntFreestyle then + begin + // begin: 14, 20 + // easy: 6, 11 + W := NotesW * 2 + 2; + H := NotesH * 1.5 + 3.5; + + X2 := (Start-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left + 0.5 + 10*ScreenX + 4; // wciecie + X1 := X2-W; + + X3 := (Start+Length-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left - 0.5 + 10*ScreenX - 4; // wciecie + X4 := X3+W; + + // left + Rec.Left := X1; + Rec.Right := X2; + Rec.Top := Top - (Tone-BaseNote)*Space/2 - H; + Rec.Bottom := Rec.Top + 2 * H; + + glBindTexture(GL_TEXTURE_2D, Tex_BG_Left[PlayerIndex+1].TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + + // srodkowa czesc + Rec.Left := X2; + Rec.Right := X3; + + glBindTexture(GL_TEXTURE_2D, Tex_BG_Mid[PlayerIndex+1].TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + + // prawa czesc + Rec.Left := X3; + Rec.Right := X4; + + glBindTexture(GL_TEXTURE_2D, Tex_BG_Right[PlayerIndex+1].TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + end; // if not FreeStyle + end; // with + end; // for + end; // with - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); end; end; diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index 6b506574..af434b94 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -47,7 +47,7 @@ begin Lines[Count].Line[0].Lyric := ''; Lines[Count].Line[0].LyricWidth := 0; Player[Count].Score := 0; - Player[Count].IlNut := 0; + Player[Count].LengthNote := 0; Player[Count].HighNote := -1; end; diff --git a/Game/Code/Classes/UIni.pas b/Game/Code/Classes/UIni.pas index 0f31649c..5e651be0 100644 --- a/Game/Code/Classes/UIni.pas +++ b/Game/Code/Classes/UIni.pas @@ -15,6 +15,21 @@ uses SysUtils; type + // TInputDeviceConfig stores the configuration for an input device. + // Configurations will be stored in the InputDeviceConfig array. + // Note that not all devices listed in InputDeviceConfig are active devices. + // Some might be unplugged and hence unavailable. + // Available devices are held in TAudioInputProcessor.DeviceList. Each + // TAudioInputDevice listed there has a CfgIndex field which is the index to + // its configuration in the InputDeviceConfig array. + // Name: + // the name of the input device + // Input: + // the index of the input source to use for recording + // ChannelToPlayerMap: + // mapping of recording channels to players, e.g. ChannelToPlayerMap[0] = 2 + // maps the channel 0 (left) to player 2. A player index of 0 means that + // the channel is not assigned to a player. PInputDeviceConfig = ^TInputDeviceConfig; TInputDeviceConfig = record Name: string; diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas index 3e1a4ea1..f83830bb 100644 --- a/Game/Code/Classes/UMain.pas +++ b/Game/Code/Classes/UMain.pas @@ -25,6 +25,17 @@ uses UThemes; type + PPLayerNote = ^TPlayerNote; + TPlayerNote = record + Start: integer; + Length: integer; + Detect: real; // accurate place, detected in the note + Tone: real; + Perfect: boolean; // true if the note matches the original one, lit the star + Hit: boolean; // true if the note Hits the Line + end; + + PPLayer = ^TPlayer; TPlayer = record Name: string; @@ -37,10 +48,10 @@ type ScoreLine: real; ScoreGolden: real; - ScoreI: integer; - ScoreLineI: integer; - ScoreGoldenI: integer; - ScoreTotalI: integer; + ScoreInt: integer; + ScoreLineInt: integer; + ScoreGoldenInt: integer; + ScoreTotalInt: integer; // LineBonus Mod ScoreLast: Real;//Last Line Score @@ -50,18 +61,9 @@ type //Meter: real; - HighNote: integer; - IlNut: integer; - Note: array of record - Start: integer; - Length: integer; - Detekt: real; // accurate place, detected in the note - Tone: real; - Perfect: boolean; // true if the note matches the original one, lit the star - - // Half size Notes Patch - Hit: boolean; // true if the note Hits the Line - end; + HighNote: integer; // index of last note (= High(Note)?) + LengthNote: integer; // number of notes (= Length(Note)?). + Note: array of TPlayerNote; end; @@ -85,10 +87,10 @@ var UserCoversPath: string = ''; UserPlaylistPath: string = ''; - OGL: Boolean; Done: Boolean; Event: TSDL_event; - FileName: string; + // FIXME: ConversionFileName should not be global + ConversionFileName: string; Restart: boolean; // player and music info @@ -97,18 +99,22 @@ var CurrentSong : TSong; +const + MAX_SONG_SCORE = 10000; // max. achievable points per song + MAX_SONG_LINE_BONUS = 1000; // max. achievable line bonus per song + procedure InitializePaths; Procedure Main; procedure MainLoop; procedure CheckEvents; -procedure Sing(Sender: TScreenSing); -procedure NewSentence(Sender: TScreenSing); -procedure NewBeat(Sender: TScreenSing); // executed when on then new beat -procedure NewBeatC(Sender: TScreenSing); // executed when on then new beat for click -procedure NewBeatD(Sender: TScreenSing); // executed when on then new beat for detection +procedure Sing(Screen: TScreenSing); +procedure NewSentence(Screen: TScreenSing); +procedure NewBeat(Screen: TScreenSing); // executed when on then new beat +procedure NewBeatClick(Screen: TScreenSing); // executed when on then new beat for click +procedure NewBeatDetect(Screen: TScreenSing); // executed when on then new beat for detection //procedure NewHalf; // executed when in the half between beats -procedure NewNote(Sender: TScreenSing); // detect note +procedure NewNote(Screen: TScreenSing); // detect note function GetMidBeat(Time: real): real; function GetTimeFromBeat(Beat: integer): real; procedure ClearScores(PlayerNum: integer); @@ -206,7 +212,7 @@ begin Ini := TIni.Create; Ini.Load; - //Load Languagefile + // Load Languagefile if (Params.Language <> -1) then Language.ChangeLanguage(ILanguage[Params.Language]) else @@ -477,30 +483,29 @@ begin glViewPort(0, 0, ScreenW, ScreenH); end - // ScreenShot hack. If Print is pressed-> Make screenshot and Save to Screenshots Path + // if print is pressed -> make screenshot and save to screenshot path else if (Event.key.keysym.sym = SDLK_SYSREQ) or (Event.key.keysym.sym = SDLK_PRINT) then Display.SaveScreenShot - // popup hack... if there is a visible popup then let it handle input instead of underlying screen + // if there is a visible popup then let it handle input instead of underlying screen // shoud be done in a way to be sure the topmost popup has preference (maybe error, then check) else if (ScreenPopupError <> nil) and (ScreenPopupError.Visible) then done := not ScreenPopupError.ParseInput(Event.key.keysym.sym, WideChar(Event.key.keysym.unicode), True) else if (ScreenPopupCheck <> nil) and (ScreenPopupCheck.Visible) then done := not ScreenPopupCheck.ParseInput(Event.key.keysym.sym, WideChar(Event.key.keysym.unicode), True) - // end of popup hack else begin - // check for Screen want to Exit + // check if screen wants to exit done := not Display.CurrentScreen^.ParseInput(Event.key.keysym.sym, WideChar(Event.key.keysym.unicode), True); - // If Screen wants to Exit + // if screen wants to exit if done then begin - // If Question Option is enabled then Show Exit Popup + // if question option is enabled then show exit popup if (Ini.AskbeforeDel = 1) then begin Display.CurrentScreen^.CheckFadeTo(nil,'MSG_QUIT_USDX'); end - else // When asking for exit is disabled then simply exit + else // if ask-for-exit is disabled then simply exit begin Display.Fade := 0; Display.NextScreenWithCheck := nil; @@ -510,18 +515,16 @@ begin end; end; - { SDL_JOYAXISMOTION: begin // not implemented end; - } SDL_JOYBUTTONDOWN: begin // not implemented end; - end; // Case - end; // While + end; // case + end; // while end; function GetTimeForBeats(BPM, Beats: real): real; @@ -570,17 +573,18 @@ function GetMidBeat(Time: real): real; var CurBeat: real; CurBPM: integer; -// TopBeat: real; -// TempBeat: real; -// TempTime: real; + //TopBeat: real; + //TempBeat: real; + //TempTime: real; begin Result := 0; if Length(CurrentSong.BPM) = 1 then Result := Time * CurrentSong.BPM[0].BPM / 60; - (* 2 BPMs *) -{ if Length(CurrentSong.BPM) > 1 then begin - (* new system *) + // 2 BPMs + { + if Length(CurrentSong.BPM) > 1 then begin + // new system CurBeat := 0; TopBeat := GetBeats(CurrentSong.BPM[0].BPM, Time); if TopBeat > CurrentSong.BPM[1].StartBeat then begin @@ -593,12 +597,13 @@ begin end else begin - (* pierwszy przedzial *) + // first part Result := TopBeat; end; - end;} + end; + } - (* more BPMs *) + // more BPMs if Length(CurrentSong.BPM) > 1 then begin CurBeat := 0; @@ -621,7 +626,7 @@ begin if Length(CurrentSong.BPM) = 1 then Result := CurrentSong.GAP / 1000 + Beat * 60 / CurrentSong.BPM[0].BPM; - (* more BPMs *) + // more BPMs if Length(CurrentSong.BPM) > 1 then begin Result := CurrentSong.GAP / 1000; @@ -657,7 +662,7 @@ begin end; // if} end; -procedure Sing(Sender: TScreenSing); +procedure Sing(Screen: TScreenSing); var Count: integer; CountGr: integer; @@ -666,19 +671,22 @@ var N: integer; begin LineState.OldBeat := LineState.CurrentBeat; - LineState.MidBeat := GetMidBeat(LineState.CurrentTime - (CurrentSong.Gap{ + 90 I've forgotten for what it is}) / 1000); // new system with variable BPM in function + // new system with variable BPM in function + LineState.MidBeat := GetMidBeat(LineState.CurrentTime - + (CurrentSong.Gap {+ 90 I've forgotten for what it is}) / 1000); LineState.CurrentBeat := Floor(LineState.MidBeat); -// LineState.OldHalf := LineState.AktHalf; -// LineState.MidHalf := LineState.MidBeat + 0.5; -// LineState.AktHalf := Floor(LineState.MidHalf); + //LineState.OldHalf := LineState.AktHalf; + //LineState.MidHalf := LineState.MidBeat + 0.5; + //LineState.AktHalf := Floor(LineState.MidHalf); LineState.OldBeatC := LineState.CurrentBeatC; LineState.MidBeatC := GetMidBeat(LineState.CurrentTime - (CurrentSong.Gap) / 1000); LineState.CurrentBeatC := Floor(LineState.MidBeatC); LineState.OldBeatD := LineState.CurrentBeatD; - LineState.MidBeatD := -0.5+GetMidBeat(LineState.CurrentTime - (CurrentSong.Gap + 120 + 20) / 1000); // MidBeat with addition GAP + // MidBeat with additional GAP + LineState.MidBeatD := -0.5+GetMidBeat(LineState.CurrentTime - (CurrentSong.Gap + 120 + 20) / 1000); LineState.CurrentBeatD := Floor(LineState.MidBeatD); LineState.FracBeatD := Frac(LineState.MidBeatD); @@ -686,40 +694,40 @@ begin for CountGr := 0 to 0 do //High(Gracz) begin; CP := CountGr; - // ustawianie starej parts + // old parts LineState.OldLine := Lines[CP].Current; - // wybieranie aktualnej parts + // choose current parts for Count := 0 to Lines[CP].High do begin if LineState.CurrentBeat >= Lines[CP].Line[Count].Start then Lines[CP].Current := Count; end; - // czysczenie nut gracza, gdy to jest nowa plansza - // (optymizacja raz na halfbeat jest zla) + // clean player note if there is a new line + // (optimization on halfbeat time) if Lines[CP].Current <> LineState.OldLine then - NewSentence(Sender); + NewSentence(Screen); end; // for CountGr - // wykonuje operacje raz na beat + // execute operations on beat if (LineState.CurrentBeat >= 0) and (LineState.OldBeat <> LineState.CurrentBeat) then - NewBeat(Sender); + NewBeat(Screen); // make some operations on clicks if {(LineState.CurrentBeatC >= 0) and }(LineState.OldBeatC <> LineState.CurrentBeatC) then - NewBeatC(Sender); + NewBeatClick(Screen); // make some operations when detecting new voice pitch if (LineState.CurrentBeatD >= 0) and (LineState.OldBeatD <> LineState.CurrentBeatD) then - NewBeatD(Sender); + NewBeatDetect(Screen); - // wykonuje operacje w polowie beatu + // execute operations on beat field // if (LineState.AktHalf >= 1) and (LineState.OldHalf <> LineState.AktHalf) then // NewHalf; - // plynnie przesuwa text + // remove moving text Done := 1; for N := 0 to Lines[0].Line[Lines[0].Current].HighNote do begin @@ -732,40 +740,41 @@ begin N := Lines[0].Line[Lines[0].Current].HighNote; - // wylacza ostatnia nute po przejsciu + // if last note is used {// todo: Lyrics if (Ini.LyricsEffect = 1) and (Done = 1) and (LineState.MidBeat > Lines[0].Line[Lines[0].Current].Note[N].Start + Lines[0].Line[Lines[0].Current].Note[N].Length) - then Sender.LyricMain.Selected := -1; + then Screen.LyricMain.Selected := -1; if Done > 1 then Done := 1; - Sender.LyricMain.Done := Done; } + Screen.LyricMain.Done := Done; + } // use Done with LCD -{ with ScreenSing do begin + { + with ScreenSing do begin if LyricMain.Selected >= 0 then begin LCD.MoveCursor(1, LyricMain.SelectedLetter + Round((LyricMain.SelectedLength-1) * Done)); LCD.ShowCursor; end; - end;} - - + end; + } end; -procedure NewSentence(Sender: TScreenSing); +procedure NewSentence(Screen: TScreenSing); var -G: Integer; + i: Integer; begin - // czyszczenie nut graczy - for G := 0 to High(Player) do + // clean note of player + for i := 0 to High(Player) do begin - Player[G].IlNut := 0; - Player[G].HighNote := -1; - SetLength(Player[G].Note, 0); + Player[i].LengthNote := 0; + Player[i].HighNote := -1; + SetLength(Player[i].Note, 0); end; - // Add Words to Lyrics - with Sender do + // add words to lyrics + with Screen do begin {LyricMain.AddCzesc(Lines[0].Current); if Lines[0].Current < Lines[0].High then @@ -776,19 +785,19 @@ begin Lyrics.AddLine(@Lines[0].Line[Lyrics.LineCounter]); end; - //Sender.UpdateLCD; + //Screen.UpdateLCD; - //On Sentence Change... - Sender.onSentenceChange(Lines[0].Current); + // on sentence change... + Screen.onSentenceChange(Lines[0].Current); end; -procedure NewBeat(Sender: TScreenSing); +procedure NewBeat(Screen: TScreenSing); var Count: integer; -// TempBeat: integer; + //TempBeat: integer; begin - // ustawia zaznaczenie tekstu -// SingScreen.LyricMain.Selected := -1; + // add a text mark + //SingScreen.LyricMain.Selected := -1; for Count := 0 to Lines[0].Line[Lines[0].Current].HighNote do if (Lines[0].Line[Lines[0].Current].Note[Count].Start = LineState.CurrentBeat) then begin @@ -796,45 +805,48 @@ begin //Todo: Lyrics //Sender.LyricMain.Selected := Count; -// LCD.MoveCursor(1, ScreenSing.LyricMain.SelectedLetter); -// LCD.ShowCursor; + //LCD.MoveCursor(1, ScreenSing.LyricMain.SelectedLetter); + //LCD.ShowCursor; //LCD.MoveCursorBR(Sender.LyricMain.SelectedLetter); //LCD.ShowCursor; end; end; -procedure NewBeatC; +procedure NewBeatClick; var Count: integer; -// LPT_1: integer; -// LPT_2: integer; + //LPT_1: integer; + //LPT_2: integer; begin -// LPT_1 := 1; -// LPT_2 := 1; + //LPT_1 := 1; + //LPT_2 := 1; // beat click - if (Ini.BeatClick = 1) and ((LineState.CurrentBeatC + Lines[0].Resolution + Lines[0].NotesGAP) mod Lines[0].Resolution = 0) then + if ((Ini.BeatClick = 1) and + ((LineState.CurrentBeatC + Lines[0].Resolution + Lines[0].NotesGAP) mod Lines[0].Resolution = 0)) then + begin AudioPlayback.PlaySound(SoundLib.Click); + end; + { // debug system on LPT if ((LineState.CurrentBeatC + Lines[0].Resolution + Lines[0].NotesGAP) mod Lines[0].Resolution = 0) then begin - //LPT_1 := 0; -// Light.LightOne(0, 150); + LPT_1 := 0; + Light.LightOne(0, 150); - (* Light.LightOne(1, 200); // beat light if ParamStr(1) = '-doublelights' then Light.LightOne(0, 200); // beat light - *) -{ if ((LineState.CurrentBeatC + Lines[0].Resolution + Lines[0].NotesGAP) mod (Lines[0].Resolution * 2) = 0) then + if ((LineState.CurrentBeatC + Lines[0].Resolution + Lines[0].NotesGAP) mod (Lines[0].Resolution * 2) = 0) then Light.LightOne(0, 150) else - Light.LightOne(1, 150)} + Light.LightOne(1, 150) end; + } for Count := 0 to Lines[0].Line[Lines[0].Current].HighNote do begin @@ -844,113 +856,127 @@ begin if Ini.ClickAssist = 1 then AudioPlayback.PlaySound(SoundLib.Click); + { //LPT_2 := 0; - (* if ParamStr(1) <> '-doublelights' then Light.LightOne(0, 150); //125 - *) + } // drum machine (* TempBeat := LineState.CurrentBeat;// + 2; if (TempBeat mod 8 = 0) then Music.PlayDrum; if (TempBeat mod 8 = 4) then Music.PlayClap; -// if (TempBeat mod 4 = 2) then Music.PlayHihat; + //if (TempBeat mod 4 = 2) then Music.PlayHihat; if (TempBeat mod 4 <> 0) then Music.PlayHihat; *) end; end; {$IFDEF UseSerialPort} - // PortWriteB($378, LPT_1 + LPT_2 * 2); // 0 zapala + // PortWriteB($378, LPT_1 + LPT_2 * 2); // 0 light {$ENDIF} end; -procedure NewBeatD(Sender: TScreenSing); +procedure NewBeatDetect(Screen: TScreenSing); begin - NewNote(Sender); + NewNote(Screen); end; -procedure NewNote(Sender: TScreenSing); +procedure NewNote(Screen: TScreenSing); var - CP: integer; // current player - S: integer; // sentence - SMin: integer; - SMax: integer; - SDet: integer; // temporary: sentence of detected note - Count: integer; - Mozna: boolean; - New: boolean; - Range: integer; - NoteHit:boolean; - MaxPoints: integer; // maximal points without line bonus + LineFragmentIndex: integer; + CurrentLineFragment: PLineFragment; + PlayerIndex: integer; + CurrentSound: TCaptureBuffer; + CurrentPlayer: PPlayer; + LastPlayerNote: PPLayerNote; + Line: PLine; + SentenceIndex: integer; + SentenceMin: integer; + SentenceMax: integer; + SentenceDetected: integer; // sentence of detected note + NoteAvailable: boolean; + NewNote: boolean; + Range: integer; + NoteHit: boolean; + MaxSongPoints: integer; // max. points for the song (without line bonus) + MaxLinePoints: Real; // max. points for the current line begin - // Log.LogStatus('Beat ' + IntToStr(LineState.CurrentBeat) + ' HalfBeat ' + IntToStr(LineState.AktHalf), 'NewBeat'); - - // On linux we get an AV @ NEWNOTE, line 600 of Classes/UMain.pas - if not assigned( AudioInputProcessor.Sound ) then - exit; - - // analizuje dla obu graczy ten sam sygnal (Sound.OneSrcForBoth) - // albo juz lepiej nie - for CP := 0 to PlayersPlay-1 do - begin - // analyze buffer - AudioInputProcessor.Sound[CP].AnalyzeBuffer; + //Log.LogStatus('Beat ' + IntToStr(LineState.CurrentBeat) + ' HalfBeat ' + IntToStr(LineState.AktHalf), 'NewBeat'); - // adds some noise - //LineState.Tone := LineState.Tone + Round(Random(3)) - 1; + // TODO: add duet mode support + // use Lines[LineSetIndex] with LineSetIndex depending on the current player - // count min and max sentence range for checking (detection is delayed to the notes we see on the screen) - SMin := Lines[0].Current-1; - if SMin < 0 then - SMin := 0; - SMax := Lines[0].Current; + // count min and max sentence range for checking (detection is delayed to the notes we see on the screen) + SentenceMin := Lines[0].Current-1; + if (SentenceMin < 0) then + SentenceMin := 0; + SentenceMax := Lines[0].Current; - // check if we can add new note - Mozna := false; - SDet:=SMin; - for S := SMin to SMax do + // check for an active note at the current time defined in the lyrics + NoteAvailable := false; + SentenceDetected := SentenceMin; + for SentenceIndex := SentenceMin to SentenceMax do + begin + Line := @Lines[0].Line[SentenceIndex]; + for LineFragmentIndex := 0 to Line.HighNote do begin - for Count := 0 to Lines[0].Line[S].HighNote do + CurrentLineFragment := @Line.Note[LineFragmentIndex]; + // check if line is active + if ((CurrentLineFragment.Start <= LineState.CurrentBeatD) and + (CurrentLineFragment.Start + CurrentLineFragment.Length-1 >= LineState.CurrentBeatD)) and + (CurrentLineFragment.NoteType <> ntFreestyle) and // but ignore FreeStyle notes + (CurrentLineFragment.Length > 0) then // and make sure the note lengths is at least 1 begin - if ((Lines[0].Line[S].Note[Count].Start <= LineState.CurrentBeatD) - and (Lines[0].Line[S].Note[Count].Start + Lines[0].Line[S].Note[Count].Length - 1 >= LineState.CurrentBeatD)) - and (Lines[0].Line[S].Note[Count].NoteType <> ntFreestyle) // but don't allow when it's FreeStyle note - and (Lines[0].Line[S].Note[Count].Length > 0) then // and make sure the note lengths is at least 1 - begin - SDet := S; - Mozna := true; - Break; - end; + SentenceDetected := SentenceIndex; + NoteAvailable := true; + Break; end; end; + // TODO: break here, if NoteAvailable is true? We would then use the first instead + // of the last note matching the current beat if notes overlap. But notes + // should not overlap at all. + //if (NoteAvailable) then + // Break; + end; - S := SDet; + // analyze player signals + for PlayerIndex := 0 to PlayersPlay-1 do + begin + CurrentPlayer := @Player[PlayerIndex]; + CurrentSound := AudioInputProcessor.Sound[PlayerIndex]; + LastPlayerNote := @CurrentPlayer.Note[CurrentPlayer.HighNote]; - //Czas.SzczytJest := true; - //Czas.Tone := 27; + // analyze buffer + CurrentSound.AnalyzeBuffer; + + // add some noise + // TODO: do we need this? + //LineState.Tone := LineState.Tone + Round(Random(3)) - 1; - // gdy moze, to dodaje nute - When Mozna, it adds note (?) - if (AudioInputProcessor.Sound[CP].ToneValid) and (Mozna) then + // add note if possible + if (CurrentSound.ToneValid and NoteAvailable) then begin - // operowanie na ostatniej nucie - for Count := 0 to Lines[0].Line[S].HighNote do + Line := @Lines[0].Line[SentenceDetected]; + + // process until last note + for LineFragmentIndex := 0 to Line.HighNote do begin - if (Lines[0].Line[S].Note[Count].Start <= LineState.OldBeatD+1) and - (Lines[0].Line[S].Note[Count].Start + - Lines[0].Line[S].Note[Count].Length > LineState.OldBeatD+1) then + CurrentLineFragment := @Line.Note[LineFragmentIndex]; + if (CurrentLineFragment.Start <= LineState.OldBeatD+1) and + (CurrentLineFragment.Start + CurrentLineFragment.Length > LineState.OldBeatD+1) then begin - // to robi, tylko dla pary nut (oryginalnej i gracza) + // compare notes (from song-file and from player) - // przesuwanie tonu w odpowiednia game - while (AudioInputProcessor.Sound[CP].Tone - Lines[0].Line[S].Note[Count].Tone > 6) do - AudioInputProcessor.Sound[CP].Tone := AudioInputProcessor.Sound[CP].Tone - 12; + // move players tone to proper octave + while (CurrentSound.Tone - CurrentLineFragment.Tone > 6) do + CurrentSound.Tone := CurrentSound.Tone - 12; - while (AudioInputProcessor.Sound[CP].Tone - Lines[0].Line[S].Note[Count].Tone < -6) do - AudioInputProcessor.Sound[CP].Tone := AudioInputProcessor.Sound[CP].Tone + 12; + while (CurrentSound.Tone - CurrentLineFragment.Tone < -6) do + CurrentSound.Tone := CurrentSound.Tone + 12; - // Half size Notes Patch + // half size notes patch NoteHit := false; //if Ini.Difficulty = 0 then Range := 2; @@ -958,96 +984,115 @@ begin //if Ini.Difficulty = 2 then Range := 0; Range := 2 - Ini.Difficulty; - if abs(Lines[0].Line[S].Note[Count].Tone - AudioInputProcessor.Sound[CP].Tone) <= Range then + // check if the player hit the correct tone within the tolerated range + if (Abs(CurrentLineFragment.Tone - CurrentSound.Tone) <= Range) then begin - AudioInputProcessor.Sound[CP].Tone := Lines[0].Line[S].Note[Count].Tone; + // adjust the players tone to the correct one + // TODO: do we need to do this? + CurrentSound.Tone := CurrentLineFragment.Tone; - // Half size Notes Patch + // half size notes patch NoteHit := true; - - MaxPoints := 10000; - if (Ini.LineBonus <> 0) then - MaxPoints := 9000; - - case Lines[0].Line[S].Note[Count].NoteType of - ntNormal: Player[CP].Score := Player[CP].Score + MaxPoints / Lines[0].ScoreValue; - ntGolden: Player[CP].ScoreGolden := Player[CP].ScoreGolden + MaxPoints / Lines[0].ScoreValue; + + if (Ini.LineBonus > 0) then + MaxSongPoints := MAX_SONG_SCORE - MAX_SONG_LINE_BONUS + else + MaxSongPoints := MAX_SONG_SCORE; + + // Note: ScoreValue is the sum of all note values of the song + MaxLinePoints := MaxSongPoints / Lines[0].ScoreValue; + + // FIXME: is this correct? Why do we add the points for a whole line + // if just one note is correct? + case CurrentLineFragment.NoteType of + ntNormal: CurrentPlayer.Score := CurrentPlayer.Score + MaxLinePoints; + ntGolden: CurrentPlayer.ScoreGolden := CurrentPlayer.ScoreGolden + MaxLinePoints; end; - Player[CP].ScoreI := Floor(Player[CP].Score / 10) * 10; - Player[CP].ScoreGoldenI := Floor(Player[CP].ScoreGolden / 10) * 10; + CurrentPlayer.ScoreInt := Floor(CurrentPlayer.Score / 10) * 10; + CurrentPlayer.ScoreGoldenInt := Floor(CurrentPlayer.ScoreGolden / 10) * 10; - Player[CP].ScoreTotalI := Player[CP].ScoreI + Player[CP].ScoreGoldenI + Player[CP].ScoreLineI; + CurrentPlayer.ScoreTotalInt := CurrentPlayer.ScoreInt + + CurrentPlayer.ScoreGoldenInt + + CurrentPlayer.ScoreLineInt; end; - end; // operowanie + end; // operation end; // for - // sprawdzanie czy to nowa nuta, czy przedluzenie - if S = SMax then + // check if we have to add a new note or extend the note's length + if (SentenceDetected = SentenceMax) then begin - New := true; + // we will add a new note + NewNote := true; // if last has the same tone - if (Player[CP].IlNut > 0 ) and - (Player[CP].Note[Player[CP].HighNote].Tone = AudioInputProcessor.Sound[CP].Tone) and - (Player[CP].Note[Player[CP].HighNote].Start + Player[CP].Note[Player[CP].HighNote].Length = LineState.CurrentBeatD) then + if ((CurrentPlayer.LengthNote > 0) and + (LastPlayerNote.Tone = CurrentSound.Tone) and + ((LastPlayerNote.Start + LastPlayerNote.Length) = LineState.CurrentBeatD)) then begin - New := false; + NewNote := false; end; - // if is not as new note to control "beacie" (TODO: translate polish "beacie") - for Count := 0 to Lines[0].Line[S].HighNote do + // if is not as new note to control + for LineFragmentIndex := 0 to Line.HighNote do begin - if (Lines[0].Line[S].Note[Count].Start = LineState.CurrentBeatD) then - New := true; + if (Line.Note[LineFragmentIndex].Start = LineState.CurrentBeatD) then + NewNote := true; end; - // dodawanie nowej nuty - if New then + // add new note + if NewNote then begin - // New Note - Player[CP].IlNut := Player[CP].IlNut + 1; - Player[CP].HighNote := Player[CP].HighNote + 1; - SetLength(Player[CP].Note, Player[CP].IlNut); - Player[CP].Note[Player[CP].HighNote].Start := LineState.CurrentBeatD; - Player[CP].Note[Player[CP].HighNote].Length := 1; - Player[CP].Note[Player[CP].HighNote].Tone := AudioInputProcessor.Sound[CP].Tone; // Ton || TonDokl - Player[CP].Note[Player[CP].HighNote].Detekt := LineState.MidBeat; - - // Half Note Patch - Player[CP].Note[Player[CP].HighNote].Hit := NoteHit; - - //Log.LogStatus('New Note ' + IntToStr(Gracz.Note[Gracz.HighNote].Start), 'NewBeat'); + // new note + Inc(CurrentPlayer.LengthNote); + Inc(CurrentPlayer.HighNote); + SetLength(CurrentPlayer.Note, CurrentPlayer.LengthNote); + + // update player's last note + LastPlayerNote := @CurrentPlayer.Note[CurrentPlayer.HighNote]; + with LastPlayerNote^ do + begin + Start := LineState.CurrentBeatD; + Length := 1; + Tone := CurrentSound.Tone; // Tone || ToneAbs + Detect := LineState.MidBeat; + Hit := NoteHit; // half note patch + end; end else begin - // przedluzenie nuty - Player[CP].Note[Player[CP].HighNote].Length := Player[CP].Note[Player[CP].HighNote].Length + 1; + // extend note length + Inc(LastPlayerNote.Length); end; // check for perfect note and then lit the star (on Draw) - for Count := 0 to Lines[0].Line[S].HighNote do + for LineFragmentIndex := 0 to Line.HighNote do begin - if (Lines[0].Line[S].Note[Count].Start = Player[CP].Note[Player[CP].HighNote].Start) and - (Lines[0].Line[S].Note[Count].Length = Player[CP].Note[Player[CP].HighNote].Length) and - (Lines[0].Line[S].Note[Count].Tone = Player[CP].Note[Player[CP].HighNote].Tone) then + CurrentLineFragment := @Line.Note[LineFragmentIndex]; + if (CurrentLineFragment.Start = LastPlayerNote.Start) and + (CurrentLineFragment.Length = LastPlayerNote.Length) and + (CurrentLineFragment.Tone = LastPlayerNote.Tone) then begin - Player[CP].Note[Player[CP].HighNote].Perfect := true; + LastPlayerNote.Perfect := true; end; end; - end; // if S = SMax + end; // if SentenceDetected = SentenceMax + + end; // if Detected + end; // for PlayerIndex - end; // if moze - end; // for CP - // Log.LogStatus('EndBeat', 'NewBeat'); + //Log.LogStatus('EndBeat', 'NewBeat'); - //On Sentence End -> For LineBonus + SingBar - if (sDet >= low(Lines[0].Line)) and (sDet <= high(Lines[0].Line)) then + // on sentence end -> for LineBonus and display of SingBar (rating pop-up) + if (SentenceDetected >= Low(Lines[0].Line)) and + (SentenceDetected <= High(Lines[0].Line)) then begin - if assigned( Sender ) and - ((Lines[0].Line[SDet].Note[Lines[0].Line[SDet].HighNote].Start + Lines[0].Line[SDet].Note[Lines[0].Line[SDet].HighNote].Length - 1) = LineState.CurrentBeatD) then + Line := @Lines[0].Line[SentenceDetected]; + CurrentLineFragment := @Line.Note[Line.HighNote]; + if ((CurrentLineFragment.Start + CurrentLineFragment.Length - 1) = LineState.CurrentBeatD) then begin - Sender.onSentenceEnd(sDet); + if assigned(Screen) then + Screen.OnSentenceEnd(SentenceDetected); end; end; @@ -1055,22 +1100,25 @@ end; procedure ClearScores(PlayerNum: integer); begin - Player[PlayerNum].Score := 0; - Player[PlayerNum].ScoreI := 0; - Player[PlayerNum].ScoreLine := 0; - Player[PlayerNum].ScoreLineI := 0; - Player[PlayerNum].ScoreGolden := 0; - Player[PlayerNum].ScoreGoldenI := 0; - Player[PlayerNum].ScoreTotalI := 0; + with Player[PlayerNum] do + begin + Score := 0; + ScoreInt := 0; + ScoreLine := 0; + ScoreLineInt := 0; + ScoreGolden := 0; + ScoreGoldenInt := 0; + ScoreTotalInt := 0; + end; end; //-------------------- -// Function sets all Absolute Paths e.g. Song Path and makes sure the Directorys exist +// Function sets all absolute paths e.g. song path and makes sure the directorys exist //-------------------- procedure InitializePaths; - // Initialize a Path Variable - // After Setting Paths, make sure that Paths exist + // Initialize a path variable + // After setting paths, make sure that paths exist function initialize_path( out aPathVar : string; const aLocation : string ): boolean; var lWriteable: Boolean; diff --git a/Game/Code/Classes/UMusic.pas b/Game/Code/Classes/UMusic.pas index bad0aa86..35c67ae1 100644 --- a/Game/Code/Classes/UMusic.pas +++ b/Game/Code/Classes/UMusic.pas @@ -15,6 +15,25 @@ uses type TNoteType = (ntFreestyle, ntNormal, ntGolden); + (** + * TLineFragment represents a fragment of a lyrics line. + * This is a text-fragment (e.g. a syllable) assigned to a note pitch, + * represented by a bar in the sing-screen. + *) + PLineFragment = ^TLineFragment; + TLineFragment = record + Color: integer; + Start: integer; // beat the fragment starts at + Length: integer; // length in beats + Tone: integer; // full range tone + Text: string; // text assigned to this fragment (a syllable, word, etc.) + NoteType: TNoteType; // note-type: golden-note/freestyle etc. + end; + + (** + * TLine represents one lyrics line and consists of multiple + * notes. + *) PLine = ^TLine; TLine = record Start: integer; @@ -22,31 +41,31 @@ type LyricWidth: real; End_: integer; BaseNote: integer; - HighNote: integer; - TotalNotes: integer; + HighNote: integer; // index of last note in line (= High(Note)?) + TotalNotes: integer; // value of all notes in the line LastLine: boolean; - Note: array of record - Color: integer; - Start: integer; - Length: integer; - Tone: integer; // full range tone - Text: string; - NoteType: TNoteType; - end; + Note: array of TLineFragment; end; - ALine = array of TLine; // (TODO: rename to TLineArray) + (** + * TLines stores sets of lyric lines and information on them. + * Normally just one set is defined but in duet mode it might for example + * contain two sets. + *) TLines = record - Current: integer; // for drawing of current line - High: integer; + Current: integer; // for drawing of current line + High: integer; // (= High(Line)?) Number: integer; Resolution: integer; NotesGAP: integer; ScoreValue: integer; - Line: ALine; + Line: array of TLine; end; - TLineState = class // all that concerns the current frames + (** + * TLineState contains all information that concerns the current frames + *) + TLineState = class private Timer: TRelativeTimer; // keeps track of the current time public @@ -56,12 +75,14 @@ type // now we use this for super synchronization! // only used when analyzing voice + // TODO: change ...D to ...Detect(ed) OldBeatD: integer; // previous discovered beat CurrentBeatD: integer; MidBeatD: real; // like CurrentBeatD FracBeatD: real; // fractional part of MidBeatD // we use this for audible clicks + // TODO: Change ...C to ...Click OldBeatC: integer; // previous discovered beat CurrentBeatC: integer; MidBeatC: real; // like CurrentBeatC diff --git a/Game/Code/Classes/UParty.pas b/Game/Code/Classes/UParty.pas index 9fdcf7a6..5b9d2400 100644 --- a/Game/Code/Classes/UParty.pas +++ b/Game/Code/Classes/UParty.pas @@ -450,12 +450,12 @@ begin begin // to-do : recode Percentage stuff //PlayerInfo.Playerinfo[I].Percentage := PlayerInfo.Playerinfo[I].Score div 9999; - if (Player[I].ScoreTotalI > MaxScore) then + if (Player[I].ScoreTotalInt > MaxScore) then begin - MaxScore := Player[I].ScoreTotalI; + MaxScore := Player[I].ScoreTotalInt; Rounds[CurRound].Winner := 1 shl I; end - else if (Player[I].ScoreTotalI = MaxScore) AND (Player[I].ScoreTotalI <> 0) then + else if (Player[I].ScoreTotalInt = MaxScore) AND (Player[I].ScoreTotalInt <> 0) then begin Rounds[CurRound].Winner := Rounds[CurRound].Winner or (1 shl I); end; diff --git a/Game/Code/Classes/USingScores.pas b/Game/Code/Classes/USingScores.pas index dd326356..645f0f6e 100644 --- a/Game/Code/Classes/USingScores.pas +++ b/Game/Code/Classes/USingScores.pas @@ -22,7 +22,7 @@ uses UThemes, // but not testet yet // ////////////////////////////////////////////////////////////// -//Some Constances containing Options that could change by time +//Some constants containing options that could change by time const MaxPlayers = 6; //Maximum of Players that could be added MaxPositions = 6; //Maximum of Score Positions that could be added @@ -853,14 +853,16 @@ var Diff: Real; begin //Only Draw if Player has a Position - If Players[Index].Position <> high(byte) then + if Players[Index].Position <> high(byte) then begin //Only Draw if Player is on Cur Screen - If ((Players[Index].Position AND 128) = 0) = (ScreenAct = 1) AND (Players[index].RBVisible AND Players[index].Visible) then + if (((Players[Index].Position and 128) = 0) = (ScreenAct = 1) and + Players[index].RBVisible and + Players[index].Visible) then begin Position := @Positions[Players[Index].Position and 127]; - If (Enabled AND Players[Index].Enabled) then + if (Enabled AND Players[Index].Enabled) then begin //Move Position if Enabled Diff := Players[Index].RBTarget - Players[Index].RBPos; @@ -871,25 +873,25 @@ begin end; //Get Colors for RatingBar - If Players[index].RBPos <=0.22 then + if (Players[index].RBPos <= 0.22) then begin R := 1; G := 0; B := 0; end - Else If Players[index].RBPos <=0.42 then + else if (Players[index].RBPos <= 0.42) then begin R := 1; G := Players[index].RBPos*5; B := 0; end - Else If Players[index].RBPos <=0.57 then + else if (Players[index].RBPos <= 0.57) then begin R := 1; G := 1; B := 0; end - Else If Players[index].RBPos <=0.77 then + else if (Players[index].RBPos <= 0.77) then begin R := 1-(Players[index].RBPos-0.57)*5; G := 1; diff --git a/Game/Code/Screens/UScreenEditConvert.pas b/Game/Code/Screens/UScreenEditConvert.pas index 7527dc68..a57e89fb 100644 --- a/Game/Code/Screens/UScreenEditConvert.pas +++ b/Game/Code/Screens/UScreenEditConvert.pas @@ -165,7 +165,7 @@ begin if Interaction = 3 then begin if SelectedNumber > 0 then begin Extract; - SaveSong(Song, Lines, ChangeFileExt(FileName, '.txt'), false); + SaveSong(Song, Lines, ChangeFileExt(ConversionFileName, '.txt'), false); end; end; @@ -396,7 +396,7 @@ begin MidiOut.Open; // MidiOut.SetVolume(100, 100); // temporary} - FileName := GamePath + 'file.mid'; + ConversionFileName := GamePath + 'file.mid'; {$IFDEF UseMIDIPort} MidiFile := TMidiFile.Create(nil); {$ENDIF} @@ -426,9 +426,9 @@ begin MidiOut.Open; - if FileExists(FileName) then + if FileExists(ConversionFileName) then begin - MidiFile.Filename := FileName; + MidiFile.Filename := ConversionFileName; MidiFile.ReadFile; diff --git a/Game/Code/Screens/UScreenEditHeader.pas b/Game/Code/Screens/UScreenEditHeader.pas index 9c6ebc8b..2bba36cd 100644 --- a/Game/Code/Screens/UScreenEditHeader.pas +++ b/Game/Code/Screens/UScreenEditHeader.pas @@ -275,7 +275,7 @@ begin end; // if PlaySentence Text[TextSentence].Text := IntToStr(Czesci[0].Akt + 1) + ' / ' + IntToStr(Czesci[0].Ilosc); - Text[TextNote].Text := IntToStr(AktNuta + 1) + ' / ' + IntToStr(Czesci[0].Czesc[Czesci[0].Akt].IlNut); + Text[TextNote].Text := IntToStr(AktNuta + 1) + ' / ' + IntToStr(Czesci[0].Czesc[Czesci[0].Akt].LengthNote); // Song info Text[TextBPM].Text := FloatToStr(CurrentSong.BPM[0].BPM / 4); diff --git a/Game/Code/Screens/UScreenOpen.pas b/Game/Code/Screens/UScreenOpen.pas index e409812c..7dbe8743 100644 --- a/Game/Code/Screens/UScreenOpen.pas +++ b/Game/Code/Screens/UScreenOpen.pas @@ -61,7 +61,7 @@ begin SDLK_ESCAPE : begin //Empty Filename and go to last Screen - FileName := ''; + ConversionFileName := ''; AudioPlayback.PlaySound(SoundLib.Back); FadeTo(BackScreen); end; @@ -70,14 +70,14 @@ begin begin if (Interaction = 2) then begin //Update Filename and go to last Screen - FileName := Text[TextN].Text; + ConversionFileName := Text[TextN].Text; AudioPlayback.PlaySound(SoundLib.Back); FadeTo(BackScreen); end else if (Interaction = 1) then begin //Empty Filename and go to last Screen - FileName := ''; + ConversionFileName := ''; AudioPlayback.PlaySound(SoundLib.Back); FadeTo(BackScreen); end; @@ -127,7 +127,7 @@ begin // file name AddBox(20, 540, 500, 40); - TextN := AddText(50, 548, 0, 8, 0, 0, 0, FileName); + TextN := AddText(50, 548, 0, 8, 0, 0, 0, ConversionFileName); AddInteraction(iText, TextN); // buttons diff --git a/Game/Code/Screens/UScreenScore.pas b/Game/Code/Screens/UScreenScore.pas index 606d8366..b47c43f1 100644 --- a/Game/Code/Screens/UScreenScore.pas +++ b/Game/Code/Screens/UScreenScore.pas @@ -367,15 +367,15 @@ begin inherited Draw; {* - player[0].ScoreI := 7000; - player[0].ScoreLineI := 2000; - player[0].ScoreGoldenI := 1000; - player[0].ScoreTotalI := 10000; - - player[1].ScoreI := 2500; - player[1].ScoreLineI := 1100; - player[1].ScoreGoldenI := 900; - player[1].ScoreTotalI := 4500; + player[0].ScoreInt := 7000; + player[0].ScoreLineInt := 2000; + player[0].ScoreGoldenInt := 1000; + player[0].ScoreTotalInt := 10000; + + player[1].ScoreInt := 2500; + player[1].ScoreLineInt := 1100; + player[1].ScoreGoldenInt := 900; + player[1].ScoreTotalInt := 4500; *} // Let's start to arise the bars CurrentTime := SDL_GetTicks(); @@ -486,7 +486,7 @@ begin ThemeIndex := PlayerNumber + ArrayStartModifier; - case (Player[PlayerNumber-1].ScoreTotalI) of + case (Player[PlayerNumber-1].ScoreTotalInt) of 0..2009: begin Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_TONE_DEAF'); @@ -633,25 +633,25 @@ begin // EaseOut_Step is the actual step in the raising process, like the 20iest step of EaseOut_MaxSteps if (BarType = 'Note') then begin - Score := Player[PlayerNumber - 1].ScoreI; + Score := Player[PlayerNumber - 1].ScoreInt; RaiseStep := BarScore_EaseOut_Step; BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y + MaxHeight; end; if (BarType = 'Line') then begin - Score := Player[PlayerNumber - 1].ScoreLineI; + Score := Player[PlayerNumber - 1].ScoreLineInt; RaiseStep := BarPhrase_EaseOut_Step; BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y - aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight + MaxHeight; end; if (BarType = 'Golden') then begin - Score := Player[PlayerNumber - 1].ScoreGoldenI; + Score := Player[PlayerNumber - 1].ScoreGoldenInt; RaiseStep := BarGolden_EaseOut_Step; BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y - aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight - aPlayerScoreScreenDatas[PlayerNumber].BarLine_ActualHeight + MaxHeight; end; // the height dependend of the score - Height2Reach := (Score / 10000) * MaxHeight; + Height2Reach := (Score / MAX_SONG_SCORE) * MaxHeight; if (aPlayerScoreScreenDatas[PlayerNumber].Bar_Actual_Height < Height2Reach) then begin @@ -751,19 +751,19 @@ begin begin EaseOut_Step := BarScore_EaseOut_Step; ActualScoreValue := TextScore_ActualValue[PlayerNumber]; - ScoreReached := Player[PlayerNumber-1].ScoreI; + ScoreReached := Player[PlayerNumber-1].ScoreInt; end; if (ScoreType = 'Line') then begin EaseOut_Step := BarPhrase_EaseOut_Step; ActualScoreValue := TextPhrase_ActualValue[PlayerNumber]; - ScoreReached := Player[PlayerNumber-1].ScoreLineI; + ScoreReached := Player[PlayerNumber-1].ScoreLineInt; end; if (ScoreType = 'Golden') then begin EaseOut_Step := BarGolden_EaseOut_Step; ActualScoreValue := TextGolden_ActualValue[PlayerNumber]; - ScoreReached := Player[PlayerNumber-1].ScoreGoldenI; + ScoreReached := Player[PlayerNumber-1].ScoreGoldenInt; end; // EaseOut_Step is the actual step in the raising process, like the 20iest step of EaseOut_MaxSteps @@ -815,17 +815,17 @@ begin //fixed: line bonus and golden notes don't show up, // another bug: total score was shown without added golden-, linebonus - S := IntToStr(Player[P].ScoreTotalI); + S := IntToStr(Player[P].ScoreTotalInt); while (Length(S)<5) do S := '0' + S; Text[TextTotalScore[Item]].Text := S; - S := IntToStr(Player[P].ScoreLineI); + S := IntToStr(Player[P].ScoreLineInt); while (Length(S)<4) do S := '0' + S; Text[TextLineBonusScore[Item]].Text := S; - S := IntToStr(Player[P].ScoreGoldenI); + S := IntToStr(Player[P].ScoreGoldenInt); while (Length(S)<4) do S := '0' + S; Text[TextGoldenNotesScore[Item]].Text := S; diff --git a/Game/Code/Screens/UScreenSing.pas b/Game/Code/Screens/UScreenSing.pas index c97bc691..ad07a081 100644 --- a/Game/Code/Screens/UScreenSing.pas +++ b/Game/Code/Screens/UScreenSing.pas @@ -35,10 +35,9 @@ type public //TextTime: integer; - //TimeBar mod - StaticTimeProgress: integer; - TextTimeText: integer; - //eoa TimeBar mod + // TimeBar fields + StaticTimeProgress: integer; + TextTimeText: integer; StaticP1: integer; TextP1: integer; @@ -90,8 +89,8 @@ type Tex_Background: TTexture; FadeOut: boolean; -// LyricMain: TLyric; -// LyricSub: TLyric; + //LyricMain: TLyric; + //LyricSub: TLyric; Lyrics: TLyricEngine; //Score Manager: @@ -111,8 +110,8 @@ type //procedure UpdateLCD; //TODO: maybe LCD Support as Plugin? procedure Pause; //Pause Mod(Toggles Pause) - procedure onSentenceEnd(S: Cardinal); //OnSentenceEnd for LineBonus + Singbar - procedure onSentenceChange(S: Cardinal); //OnSentenceChange (for Golden Notes) + procedure OnSentenceEnd(SentenceIndex: Cardinal); //OnSentenceEnd for LineBonus + Singbar + procedure OnSentenceChange(SentenceIndex: Cardinal); //OnSentenceChange (for Golden Notes) end; implementation @@ -349,15 +348,17 @@ begin inherited; Log.LogStatus('Begin', 'onShow'); - FadeOut := false; // 0.5.0: early 0.5.0 problems were by this line commented + FadeOut := false; // reset video playback engine, to play Video Clip... fCurrentVideoPlaybackEngine := VideoPlayback; - //SetUp Score Manager - Scores.ClearPlayers; //Clear Old Player Values - Color.R := 0; Color.G := 0; Color.B := 0; //Dummy atm - For P := 0 to PlayersPlay -1 do //Add new Ones + // setup score manager + Scores.ClearPlayers; // clear old player values + Color.R := 0; Color.G := 0; Color.B := 0; // dummy atm + + // add new players + for P := 0 to PlayersPlay-1 do begin Scores.AddPlayer(Tex_ScoreBG[P], Color); end; @@ -368,7 +369,7 @@ begin // prepare players SetLength(Player, PlayersPlay); -// Player[0].ScoreTotalI := 0; + //Player[0].ScoreTotalInt := 0; case PlayersPlay of 1: begin @@ -462,20 +463,20 @@ begin // FIXME: bad style, put the try-except into LoadSong() and not here try - //Check if File is XML - if copy(CurrentSong.FileName,length(CurrentSong.FileName)-3,4) = '.xml' - then success := CurrentSong.LoadXMLSong() - else success := CurrentSong.LoadSong(); + // Check if file is XML + if copy(CurrentSong.FileName,length(CurrentSong.FileName)-3,4) = '.xml' + then success := CurrentSong.LoadXMLSong() + else success := CurrentSong.LoadSong(); except success := false; end; if (not success) then begin - //Error Loading Song -> Go back to Song Screen and Show some Error Message + // error loading song -> go back to song screen and show some error message FadeTo(@ScreenSong); - //Select New Song in Party Mode - if ScreenSong.Mode = smPartyMode then + // select new song in party mode + if ScreenSong.Mode = smPartyMode then ScreenSong.SelectRandomSong(); ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG')); // FIXME: do we need this? @@ -485,7 +486,7 @@ begin - // reset video playback engine, to play Video Clip... + // reset video playback engine, to play video clip... Visualization.Init(); @@ -497,12 +498,9 @@ begin fShowVisualization := false; if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then begin - // todo: VideoGap and Start time verwursten - + // TODO: use VideoGap and start time fCurrentVideoPlaybackEngine.Open( CurrentSong.Path + CurrentSong.Video ); - - fCurrentVideoPlaybackEngine.position := CurrentSong.VideoGAP + CurrentSong.Start; - + fCurrentVideoPlaybackEngine.Position := CurrentSong.VideoGAP + CurrentSong.Start; CurrentSong.VideoLoaded := true; end; @@ -657,21 +655,19 @@ begin end; end; // case - // Add Lines to Lyrics - While (not Lyrics.LineinQueue) AND (Lyrics.LineCounter <= High(Lines[0].Line)) do + // Add lines to lyrics + while (not Lyrics.LineinQueue) and (Lyrics.LineCounter <= High(Lines[0].Line)) do Lyrics.AddLine(@Lines[0].Line[Lyrics.LineCounter]); //UpdateLCD; //TODO: maybe LCD Support as Plugin? - //Deactivate Pause + // Deactivate pause Paused := False; - //Kill all Stars not Killed yet - //GoldenStarsTwinkle Mod - GoldenRec.SentenceChange; - //GoldenStarsTwinkle Mod End + // Kill all stars not killed yet (GoldenStarsTwinkle Mod) + GoldenRec.SentenceChange; - {//Set Position of Line Bonus - PhrasenBonus + {//Set Position of Line Bonus - Line Bonus start if (Ini.LineBonus = 1) then //Show Line Bonus at Scores begin Case PlayersPlay of @@ -904,10 +900,10 @@ begin end; end; } - //Set Position of Line Bonus - PhrasenBonus End - //Set Num of Empty Sentences for Phrasen Bonus + // set Position of Line Bonus - Line Bonus end + // set number of empty sentences for Line Bonus NumEmptySentences := 0; - for P := low(Lines[0].Line) to high(Lines[0].Line) do + for P := Low(Lines[0].Line) to High(Lines[0].Line) do if Lines[0].Line[P].TotalNotes = 0 then Inc(NumEmptySentences); Log.LogStatus('End', 'onShow'); @@ -922,24 +918,17 @@ begin try fCurrentVideoPlaybackEngine.GetFrame(LineState.CurrentTime); fCurrentVideoPlaybackEngine.DrawGL(ScreenAct); -// PlaySmpeg; - except - - on E : Exception do - begin - //If an Error occurs Reading Video: prevent Video from being Drawn again and Close Video + except on E : Exception do + begin + //If an error occurs reading video: prevent video from being drawn again and close video CurrentSong.VideoLoaded := False; Log.LogError('Error drawing Video, Video has been disabled for this Song/Session.'); Log.LogError('Error Message : '+ E.message ); Log.LogError(' In : '+ E.ClassName +' (TScreenSing.onShowFinish)' ); Log.LogError('Corrupted File: ' + CurrentSong.Video); - try -// CloseSmpeg; - fCurrentVideoPlaybackEngine.Close; - except - end; - end; + fCurrentVideoPlaybackEngine.Close; + end; end; end; @@ -960,12 +949,12 @@ var S: integer; T: integer; begin - - - - //ScoreBG Mod | den wirren Scheiss hier brauch mer nimmer, wir haben colorized png's - no need for wirrness also - // set player colors - macht nichts weiter als die farben des statics zu wechseln, was zu unschönen effekten bei colorized png führt -{ if PlayersPlay = 4 then begin + // ScoreBG Mod + // TODO: remove this commented out section as we do not need it anymore. + // We use colorized png's now. Set player colors does nothing than changing + // the colors of the statics which will lead to ugly effects on colorized pngs + { + if PlayersPlay = 4 then begin if ScreenAct = 1 then begin LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG, Static[StaticP1TwoP].Texture.ColB, 'P1Dark'); @@ -1038,7 +1027,8 @@ begin if ScreenAct = 2 then begin case PlayersPlay of -{ 1: begin + { + 1: begin Text[TextP1].Text := 'P2'; end; 2: begin @@ -1049,8 +1039,8 @@ begin Text[TextP1].Text := 'P4'; Text[TextP2M].Text := 'P5'; Text[TextP3R].Text := 'P6'; - end;} - + end; + } 4: begin Text[TextP1TwoP].Text := 'P3'; Text[TextP2R].Text := 'P4'; @@ -1063,11 +1053,15 @@ begin end; // case end; // if - // stereo -// weird stuff, maybe this is for "dual screen?", but where is player three then? | okay, i commented the stuff out the other day - nothing was missing on screen w/ 6 players - so do we even need this stuff? -// okay this stuff appears again some lines beneath this one, I commented it out for testing what it does - seems like it's doing nothing -// but I might be wrong, so what is this stuff here doing? O.o + //// + // dual screen, part 1 + //////////////////////// + + // Note: ScreenX is the offset of the current screen in dual-screen mode so we + // will move the statics and texts to the correct screen here. + // FIXME: clean up this weird stuff. Commenting this stuff out, nothing + // was missing on screen w/ 6 players - so do we even need this stuff? Static[StaticP1].Texture.X := Static[StaticP1].Texture.X + 10*ScreenX; Text[TextP1].X := Text[TextP1].X + 10*ScreenX; @@ -1082,7 +1076,8 @@ begin {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X + 10*ScreenX; Text[TextP2RScore].X := Text[TextP2RScore].X + 10*ScreenX;} -// end of weird stuff + + // end of weird stuff Static[1].Texture.X := Static[1].Texture.X + 10*ScreenX; @@ -1180,31 +1175,28 @@ begin end; } // draw static menu (BG) - //DrawBG; // there is no menu and the animated background brakes the video playback because the timecode is in a different format - //Draw Background + // Note: there is no menu and the animated background brakes the video playback + //DrawBG; + + // Draw Background SingDrawBackground; + // update and draw movie - - if ShowFinish and - ( CurrentSong.VideoLoaded or fShowVisualization ) then -// if ShowFinish then + if (ShowFinish and + (CurrentSong.VideoLoaded or fShowVisualization)) then begin -// try -// UpdateSmpeg; // this only draws - // todo: find a way to determine, when a new frame is needed - // toto: same for the need to skip frames - + //try + // TODO: find a way to determine, when a new frame is needed + // TODO: same for the need to skip frames if assigned( fCurrentVideoPlaybackEngine ) then begin fCurrentVideoPlaybackEngine.GetFrame(LineState.CurrentTime); fCurrentVideoPlaybackEngine.DrawGL(ScreenAct); end; - -(* + (* except on E : Exception do begin - //If an Error occurs drawing: prevent Video from being Drawn again and Close Video CurrentSong.VideoLoaded := False; log.LogError('Error drawing Video, Video has been disabled for this Song/Session.'); @@ -1212,53 +1204,54 @@ begin Log.LogError(' In : '+ E.ClassName +' (TScreenSing.Draw)' ); Log.LogError('Corrupted File: ' + CurrentSong.Video); - try -// CloseSmpeg; - fCurrentVideoPlaybackEngine.Close; - except - - end; + fCurrentVideoPlaybackEngine.Close; end; end; -*) - + *) end; // draw static menu (FG) DrawFG; // check for music finish -// Log.LogError('Check for music finish: ' + BoolToStr(Music.Finished) + ' ' + FloatToStr(LineState.CurrentTime*1000) + ' ' + IntToStr(CurrentSong.Finish)); - if ShowFinish 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 -// Log.LogError('End'); - if not FadeOut then begin -// Log.LogError('End2'); - Finish; - FadeOut := true; - FadeTo(@ScreenScore); + //Log.LogError('Check for music finish: ' + BoolToStr(Music.Finished) + ' ' + FloatToStr(LineState.CurrentTime*1000) + ' ' + IntToStr(CurrentSong.Finish)); + if ShowFinish then + begin + if (not AudioPlayback.Finished) and + ((CurrentSong.Finish = 0) or (LineState.CurrentTime*1000 <= CurrentSong.Finish)) then + begin + // analyze song if not paused + if (not Paused) then + Sing(Self); + end + else + begin + if (not FadeOut) then + begin + Finish; + FadeOut := true; + FadeTo(@ScreenScore); + end; end; end; - end; - // draw custom items - SingDraw; // always draw + // always draw custom items + SingDraw; -//GoldenNoteStarsTwinkle Mod + //GoldenNoteStarsTwinkle GoldenRec.SpawnRec; -//GoldenNoteStarsTwinkle Mod //Draw Scores Scores.Draw; - // back stereo + //// + // dual screen, part 2 + //////////////////////// + + // Note: ScreenX is the offset of the current screen in dual-screen mode so we + // will move the statics and texts to the correct screen here. + // FIXME: clean up this weird stuff -// weird stuff, maybe this is for "dual screen?", but where is player three then? -// okay this stuff appears again some lines above this one, I commented it out for testing what it does - seems like it's doing nothing -// but I might be wrong, so what is this stuff here doing? O.o Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10*ScreenX; Text[TextP1].X := Text[TextP1].X - 10*ScreenX; @@ -1271,22 +1264,23 @@ begin {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X - 10*ScreenX; Text[TextP2RScore].X := Text[TextP2RScore].X - 10*ScreenX;} -//weird end + + //end of weird Static[1].Texture.X := Static[1].Texture.X - 10*ScreenX; for T := 0 to 1 do Text[T].X := Text[T].X - 10*ScreenX; - //Draw Pausepopup - //I use this workaround that the Static is drawen over the Lyrics, Lines, Scores and Effects - //maybe someone could find a better solution + // Draw Pausepopup + // FIXME: this is a workaround that the Static is drawn over the Lyrics, Lines, Scores and Effects + // maybe someone could find a better solution if Paused then - begin - Static[StaticPausePopup].Visible := true; - Static[StaticPausePopup].Draw; - Static[StaticPausePopup].Visible := false; - end; + begin + Static[StaticPausePopup].Visible := true; + Static[StaticPausePopup].Draw; + Static[StaticPausePopup].Visible := false; + end; end; @@ -1295,7 +1289,7 @@ begin AudioInput.CaptureStop; AudioPlayback.Stop; - if Ini.SavePlayback = 1 then begin + if (Ini.SavePlayback = 1) then begin Log.BenchmarkStart(0); Log.LogVoice(0); Log.LogVoice(1); @@ -1306,7 +1300,6 @@ begin if CurrentSong.VideoLoaded then begin -// CloseSmpeg; fCurrentVideoPlaybackEngine.Close; CurrentSong.VideoLoaded := false; // to prevent drawing closed video end; @@ -1333,77 +1326,93 @@ begin end; *) -procedure TScreenSing.onSentenceEnd(S: Cardinal); +procedure TScreenSing.OnSentenceEnd(SentenceIndex: Cardinal); var -I: Integer; -A: Real; -B: integer; //Max Points for Notes + PlayerIndex: Integer; + CurrentPlayer: PPLayer; + CurrentScore: Real; + Line: PLine; + LinePerfection: Real; // perfection of singing performance on the current line + Rating: integer; + LineScore: Real; + LineBonus: Real; + MaxSongScore: integer; // max. points for the song (without line bonus) + MaxLineScore: Real; // max. points for the current line +const + // TODO: move this to a better place + MAX_LINE_RATING = 8; // max. rating for singing performance begin + Line := @Lines[0].Line[SentenceIndex]; - //Check for Empty Sentence - if (Lines[0].Line[S].TotalNotes<=0) then - exit; + // check for empty sentence + if (Line.TotalNotes <= 0) then + Exit; - //Set Max Note Points - if (Ini.LineBonus > 0) then - B := 9000 + // set max song score + if (Ini.LineBonus = 0) then + MaxSongScore := MAX_SONG_SCORE else - B := 10000; + MaxSongScore := MAX_SONG_SCORE - MAX_SONG_LINE_BONUS; - for I := 0 to High(Player) do begin - A := Player[I].Score + Player[I].ScoreGolden - Player[I].ScoreLast + 2; + // Note: ScoreValue is the sum of all note values of the song + MaxLineScore := MaxSongScore * (Line.TotalNotes / Lines[0].ScoreValue); + for PlayerIndex := 0 to High(Player) do + begin + CurrentPlayer := @Player[PlayerIndex]; + CurrentScore := CurrentPlayer.Score + CurrentPlayer.ScoreGolden; - //PhrasenBonus - Line Bonus Mod + // Line Bonus - //Generate Steps 0 to 8 - A := Floor(A / (B * Lines[0].Line[S].TotalNotes / Lines[0].ScoreValue) * 8); + // points for this line + LineScore := CurrentScore - CurrentPlayer.ScoreLast; - If (Ini.LineBonus > 0) then - begin - //PhrasenBonus give Points - Player[I].ScoreLine := Player[I].ScoreLine + (1000 / (Length(Lines[0].Line) - NumEmptySentences) * A / 8); - Player[I].ScoreLineI := Round(Player[I].ScoreLine / 10) * 10; - //Update Total Score - Player[I].ScoreTotalI := Player[I].ScoreI + Player[I].ScoreGoldenI + Player[I].ScoreLineI; - - //Spawn PopUp - If (A >= 8) then - A := 8 - else IF A < 0 then - A := 0; - - Scores.SpawnPopUp(I, Floor(A), Player[I].ScoreTotalI); - end; - //PhrasenBonus - Line Bonus Mod End// } + // determine LinePerfection + // Note: the "+2" extra points are a little bonus so the player does not + // have to be that perfect to reach the bonus steps. + LinePerfection := (LineScore + 2) / MaxLineScore; - //PerfectLineTwinkle Mod (effect) Pt.1 - If (Ini.EffectSing=1) then + // clamp LinePerfection to range [0..1] + if (LinePerfection < 0) then + LinePerfection := 0 + else if (LinePerfection > 1) then + LinePerfection := 1; + + // add line-bonus if enabled + if (Ini.LineBonus > 0) then begin - if A >= 8 then Player[I].LastSentencePerfect := True - else Player[I].LastSentencePerfect := False; + // line-bonus points (same for each line, no matter how long the line is) + LineBonus := MAX_SONG_LINE_BONUS / + (Length(Lines[0].Line) - NumEmptySentences); + // apply line-bonus + CurrentPlayer.ScoreLine := CurrentPlayer.ScoreLine + + LineBonus * LinePerfection; + CurrentPlayer.ScoreLineInt := Round(CurrentPlayer.ScoreLine / 10) * 10; + // update total score + CurrentPlayer.ScoreTotalInt := CurrentPlayer.ScoreInt + + CurrentPlayer.ScoreGoldenInt + + CurrentPlayer.ScoreLineInt; + + // spawn rating pop-up + Rating := Round(LinePerfection * MAX_LINE_RATING); + Scores.SpawnPopUp(PlayerIndex, Rating, CurrentPlayer.ScoreTotalInt); end; - //PerfectLineTwinkle Mod end - //Refresh LastScore - Player[I].ScoreLast := Player[I].Score + Player[I].ScoreGolden; + // PerfectLineTwinkle (effect), Part 1 + If (Ini.EffectSing = 1) then + CurrentPlayer.LastSentencePerfect := (LinePerfection >= 1); + // refresh last score + CurrentPlayer.ScoreLast := CurrentScore; end; - //PerfectLineTwinkle Mod (effect) Pt.2 - if Ini.EffectSing=1 then + // PerfectLineTwinkle (effect), Part 2 + if (Ini.EffectSing = 1) then GoldenRec.SpawnPerfectLineTwinkle; - //PerfectLineTwinkle Mod end - - - // if we are shoing a visualization... change to a new preset after each sentence.. - // Maybe we should make this less often or something... just a - if fShowVisualization then - fCurrentVideoPlaybackEngine.Position := now; // move to a random position end; //Called on Sentence Change S= New Current Sentence -procedure TScreenSing.onSentenceChange(S: Cardinal); +procedure TScreenSing.OnSentenceChange(SentenceIndex: Cardinal); begin //GoldenStarsTwinkle Mod GoldenRec.SentenceChange; diff --git a/Game/Code/Screens/UScreenSingModi.pas b/Game/Code/Screens/UScreenSingModi.pas index 4af999f1..f010ec31 100644 --- a/Game/Code/Screens/UScreenSingModi.pas +++ b/Game/Code/Screens/UScreenSingModi.pas @@ -289,8 +289,8 @@ 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; + if (Player[I].ScoreTotalInt <= MAX_SONG_SCORE) then + PlayerInfo.Playerinfo[I].Score:= Player[I].ScoreTotalInt; PlayerInfo.Playerinfo[I].Bar := Round(Scores.Players[I].RBPos * 100); end; end; @@ -567,7 +567,7 @@ begin if PlayerInfo.Playerinfo[I].Enabled then begin //PlayerInfo.Playerinfo[I].Bar := Player[I].ScorePercent; - PlayerInfo.Playerinfo[I].Score := Player[I].ScoreTotalI; + PlayerInfo.Playerinfo[I].Score := Player[I].ScoreTotalInt; end; end; @@ -586,10 +586,10 @@ begin //Change PlayerInfo/Changeables for I := 0 to PlayerInfo.NumPlayers-1 do begin - if (Player[I].ScoreTotalI <> PlayerInfo.Playerinfo[I].Score) then + if (Player[I].ScoreTotalInt <> 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; + Player[I].ScoreTotalInt := PlayerInfo.Playerinfo[I].Score; end; {if (PlayerInfo.Playerinfo[I].Bar <> Player[I].ScorePercent) then Player[I].ScorePercentTarget := PlayerInfo.Playerinfo[I].Bar; } @@ -656,7 +656,7 @@ 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 +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); @@ -665,31 +665,36 @@ begin glPrint (PChar(Language.Translate(String(Text)))); end; -function LoadSound (const Name: PChar): Cardinal; stdcall; //Procedure that loads a Custom Sound +function LoadSound(const Name: PChar): Cardinal; stdcall; //Procedure that loads a Custom Sound var - S: TAudioPlaybackStream; - I: Integer; - F: String; + Stream: TAudioPlaybackStream; + i: Integer; + Filename: String; begin //Search for Sound in already loaded Sounds - F := UpperCase(SoundPath + FileName); - For I := 0 to High(CustomSounds) do + Filename := UpperCase(SoundPath + Name); + for i := 0 to High(CustomSounds) do begin - if (UpperCase(CustomSounds[I].Filename) = F) then + if (UpperCase(CustomSounds[i].Filename) = Filename) then begin - Result := I; + Result := i; Exit; end; end; - S := AudioPlayback.OpenSound(SoundPath + String(Name)); - if (S <> nil) then - Result := High(CustomSounds) - else + Stream := AudioPlayback.OpenSound(SoundPath + String(Name)); + if (Stream = nil) then + begin Result := 0; + Exit; + end; + + SetLength(CustomSounds, Length(CustomSounds)+1); + CustomSounds[High(CustomSounds)].Stream := Stream; + Result := High(CustomSounds); end; -procedure PlaySound (const Index: Cardinal); stdcall; //Plays a Custom Sound +procedure PlaySound(const Index: Cardinal); stdcall; //Plays a Custom Sound begin if (Index <= High(CustomSounds)) then AudioPlayback.PlaySound(CustomSounds[Index].Stream); diff --git a/Game/Code/Screens/UScreenSong.pas b/Game/Code/Screens/UScreenSong.pas index 06314bcd..b790bc36 100644 --- a/Game/Code/Screens/UScreenSong.pas +++ b/Game/Code/Screens/UScreenSong.pas @@ -83,10 +83,10 @@ type StaticTeam3Joker4: Cardinal; StaticTeam3Joker5: Cardinal; - StaticParty: Array of Cardinal; - TextParty: Array of Cardinal; - StaticNonParty: Array of Cardinal; - TextNonParty: Array of Cardinal; + StaticParty: array of Cardinal; + TextParty: array of Cardinal; + StaticNonParty: array of Cardinal; + TextNonParty: array of Cardinal; constructor Create; override; @@ -131,96 +131,95 @@ type end; implementation -uses UGraphic, - UMain, - UCovers, - math, - gl, - USkins, - UDLLManager, - UParty, - UPlaylist, - UScreenSongMenu; + +uses + UGraphic, + UMain, + UCovers, + math, + gl, + USkins, + UDLLManager, + UParty, + UPlaylist, + UScreenSongMenu; // ***** Public methods ****** // //Show Wrong Song when Tabs on Fix procedure TScreenSong.FixSelected; var I, I2: Integer; +begin + if CatSongs.VisibleSongs > 0 then begin - if CatSongs.VisibleSongs > 0 then + I2:= 0; + for I := low(CatSongs.Song) to High(Catsongs.Song) do begin - I2:= 0; - for I := low(CatSongs.Song) to High(Catsongs.Song) do - begin - if CatSongs.Song[I].Visible then - inc(I2); - - if I = Interaction - 1 then - break; - end; + if CatSongs.Song[I].Visible then + inc(I2); - SongCurrent := I2; - SongTarget := I2; + if I = Interaction - 1 then + break; end; + + SongCurrent := I2; + SongTarget := I2; end; +end; procedure TScreenSong.FixSelected2; var I, I2: Integer; +begin + if CatSongs.VisibleSongs > 0 then begin - if CatSongs.VisibleSongs > 0 then + I2:= 0; + for I := low(CatSongs.Song) to High(Catsongs.Song) do begin - I2:= 0; - for I := low(CatSongs.Song) to High(Catsongs.Song) do - begin - if CatSongs.Song[I].Visible then - inc(I2); + if CatSongs.Song[I].Visible then + inc(I2); - if I = Interaction - 1 then - break; - end; - - SongTarget := I2; + if I = Interaction - 1 then + break; end; - end; -//Show Wrong Song when Tabs on Fix End - procedure TScreenSong.ShowCatTLCustom(Caption: String);// Show Custom Text in Top left - begin - Text[TextCat].Text := Caption; - Text[TextCat].Visible := true; - Static[StaticCat].Visible := False; + SongTarget := I2; end; +end; +//Show Wrong Song when Tabs on Fix End - //Show Cat in Top Left Mod - procedure TScreenSong.ShowCatTL(Cat: Integer); - begin - //Change - Text[TextCat].Text := CatSongs.Song[Cat].Artist; - //showmessage(CatSongs.Song[Cat].Path + CatSongs.Song[Cat].Cover); - //Static[StaticCat].Texture := Texture.GetTexture(Button[Cat].Texture.Name, TEXTURE_TYPE_PLAIN, true); +procedure TScreenSong.ShowCatTLCustom(Caption: String);// Show Custom Text in Top left +begin + Text[TextCat].Text := Caption; + Text[TextCat].Visible := true; + Static[StaticCat].Visible := False; +end; - Static[StaticCat].Texture := Texture.GetTexture(Button[Cat].Texture.Name, TEXTURE_TYPE_PLAIN, true); - //Texture.GetTexture(Button[Cat].Texture.Name, TEXTURE_TYPE_PLAIN, false); - //Button[Cat]. - //Cover +//Show Cat in Top Left Mod +procedure TScreenSong.ShowCatTL(Cat: Integer); +begin + //Change + Text[TextCat].Text := CatSongs.Song[Cat].Artist; + //showmessage(CatSongs.Song[Cat].Path + CatSongs.Song[Cat].Cover); + //Static[StaticCat].Texture := Texture.GetTexture(Button[Cat].Texture.Name, TEXTURE_TYPE_PLAIN, true); + Static[StaticCat].Texture := Texture.GetTexture(Button[Cat].Texture.Name, TEXTURE_TYPE_PLAIN, true); + //Texture.GetTexture(Button[Cat].Texture.Name, TEXTURE_TYPE_PLAIN, false); - //Show - Text[TextCat].Visible := true; - Static[StaticCat].Visible := True; - end; + //Show + Text[TextCat].Visible := true; + Static[StaticCat].Visible := True; +end; - procedure TScreenSong.HideCatTL; - begin - //Hide - //Text[TextCat].Visible := false; - Static[StaticCat].Visible := false; - //New -> Show Text specified in Theme - Text[TextCat].Visible := True; - Text[TextCat].Text := Theme.Song.TextCat.Text; - end; - //Show Cat in Top Left Mod End +procedure TScreenSong.HideCatTL; +begin + //Hide + //Text[TextCat].Visible := false; + Static[StaticCat].Visible := false; + //New -> Show Text specified in Theme + Text[TextCat].Visible := True; + Text[TextCat].Text := Theme.Song.TextCat.Text; +end; +//Show Cat in Top Left Mod End // Method for input parsing. If False is returned, GetNextWindow @@ -229,7 +228,6 @@ function TScreenSong.ParseInput(PressedKey: Cardinal; CharCode: WideChar; Presse var I: integer; I2: integer; -// HS: integer; // Auto Removed, Unused Variable SDL_ModState: Word; Letter: WideChar; begin @@ -247,14 +245,14 @@ begin Exit; end; - If (PressedDown) Then + if (PressedDown) then begin // Key Down SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT); //Jump to Artist/Titel - if ((SDL_ModState and KMOD_LALT <> 0) AND (Mode = smNormal)) then + if ((SDL_ModState and KMOD_LALT <> 0) and (Mode = smNormal)) then begin if (WideCharUpperCase(CharCode)[1] in ([WideChar('A')..WideChar('Z')]) ) then begin @@ -264,10 +262,10 @@ begin //Jump To Titel if (SDL_ModState = (KMOD_LALT or KMOD_LSHIFT)) then begin - For I := 1 to high(CatSongs.Song) do + for I := 1 to high(CatSongs.Song) do begin - if (CatSongs.Song[(I + Interaction) mod I2].Visible) AND - (Length(CatSongs.Song[(I + Interaction) mod I2].Title)>0) AND + if (CatSongs.Song[(I + Interaction) mod I2].Visible) and + (Length(CatSongs.Song[(I + Interaction) mod I2].Title)>0) and (WideStringUpperCase(CatSongs.Song[(I + Interaction) mod I2].Title)[1] = Letter) then begin SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2)); @@ -283,12 +281,12 @@ begin end; end //Jump to Artist - else if (SDL_ModState = KMOD_LALT) then + else if (SDL_ModState = KMOD_LALT) then begin - For I := 1 to high(CatSongs.Song) do + for I := 1 to high(CatSongs.Song) do begin - if (CatSongs.Song[(I + Interaction) mod I2].Visible) AND - (Length(CatSongs.Song[(I + Interaction) mod I2].Artist)>0) AND + if (CatSongs.Song[(I + Interaction) mod I2].Visible) and + (Length(CatSongs.Song[(I + Interaction) mod I2].Artist)>0) and (WideStringUpperCase(CatSongs.Song[(I + Interaction) mod I2].Artist)[1] = Letter) then begin SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2)); @@ -319,9 +317,12 @@ begin 'M': //Show SongMenu begin - if (Songs.SongList.Count > 0) then begin - if (Mode = smNormal) then begin - if not CatSongs.Song[Interaction].Main then begin // clicked on Song + if (Songs.SongList.Count > 0) then + begin + if (Mode = smNormal) then + begin + if (not CatSongs.Song[Interaction].Main) then // clicked on Song + begin if CatSongs.CatNumShow = -3 then ScreenSongMenu.MenuShow(SM_Playlist) else @@ -332,14 +333,18 @@ begin ScreenSongMenu.MenuShow(SM_Playlist_Load); end; end //Party Mode -> Show Party Menu - else ScreenSongMenu.MenuShow(SM_Party_Main); + else + begin + ScreenSongMenu.MenuShow(SM_Party_Main); + end; end; Exit; end; 'P': //Show Playlist Menu begin - if (Songs.SongList.Count > 0) AND (Mode = smNormal) then begin + if (Songs.SongList.Count > 0) and (Mode = smNormal) then + begin ScreenSongMenu.MenuShow(SM_Playlist_Load); end; Exit; @@ -347,7 +352,7 @@ begin 'J': //Show Jumpto Menu begin - if (Songs.SongList.Count > 0) AND (Mode = smNormal) then + if (Songs.SongList.Count > 0) and (Mode = smNormal) then begin ScreenSongJumpto.Visible := True; end; @@ -362,67 +367,68 @@ begin 'R': begin - if (Songs.SongList.Count > 0) AND (Mode = smNormal) then begin - - if (SDL_ModState = KMOD_LSHIFT) AND (Ini.Tabs_at_startup = 1) then //Random Category + if (Songs.SongList.Count > 0) and (Mode = smNormal) then + begin + if (SDL_ModState = KMOD_LSHIFT) and (Ini.Tabs_at_startup = 1) then //Random Category begin - I2 := 0; //Count Cats - 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 + begin + if CatSongs.Song[I].Main then + Inc(I2); + end; - I2 := Random (I2)+1; //Zufall + I2 := Random (I2)+1; //Zufall - //Find Cat: - for I:= low(CatSongs.Song) to high (CatSongs.Song) do - begin - if CatSongs.Song[I].Main then - Dec(I2); - if (I2<=0) then + //Find Cat: + for I:= low(CatSongs.Song) to high (CatSongs.Song) do begin - //Show Cat in Top Left Mod - ShowCatTL (I); + if CatSongs.Song[I].Main then + Dec(I2); + if (I2<=0) then + begin + //Show Cat in Top Left Mod + ShowCatTL (I); - Interaction := I; + Interaction := I; - CatSongs.ShowCategoryList; - CatSongs.ClickCategoryButton(I); - SelectNext; - FixSelected; - break; + CatSongs.ShowCategoryList; + CatSongs.ClickCategoryButton(I); + SelectNext; + FixSelected; + break; end; end; - - end - else if (SDL_ModState = KMOD_LCTRL) AND (Ini.Tabs_at_startup = 1) then //random in All Categorys + else if (SDL_ModState = KMOD_LCTRL) and (Ini.Tabs_at_startup = 1) then //random in All Categorys begin - repeat - I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1; - until CatSongs.Song[I2].Main = false; + repeat + I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1; + until CatSongs.Song[I2].Main = false; - //Search Cat - for I := I2 downto low(CatSongs.Song) do + //Search Cat + for I := I2 downto low(CatSongs.Song) do begin if CatSongs.Song[I].Main then break; end; - //In I is now the categorie in I2 the song + + //In I is now the categorie in I2 the song - //Choose Cat - CatSongs.ShowCategoryList; + //Choose Cat + CatSongs.ShowCategoryList; - //Show Cat in Top Left Mod + //Show Cat in Top Left Mod ShowCatTL (I); - CatSongs.ClickCategoryButton(I); - SelectNext; - - //Fix: Not Existing Song selected: - //if (I+1=I2) then Inc(I2); + CatSongs.ClickCategoryButton(I); + SelectNext; - //Choose Song - SkipTo(I2-I); + //Fix: Not Existing Song selected: + //if (I+1=I2) then Inc(I2); + //Choose Song + SkipTo(I2-I); end else //Random in one Category begin @@ -443,74 +449,74 @@ begin SDLK_ESCAPE, SDLK_BACKSPACE : begin - if (Mode = smNormal) then - begin - //On Escape goto Cat-List Hack - if (Ini.Tabs_at_startup = 1) AND (CatSongs.CatNumShow <> -1) then - begin - //Find Category - I := Interaction; - while not catsongs.Song[I].Main do + if (Mode = smNormal) then + begin + //On Escape goto Cat-List Hack + if (Ini.Tabs_at_startup = 1) and (CatSongs.CatNumShow <> -1) then begin - Dec (I); - if (I < low(catsongs.Song)) then - break; - end; - if (I<= 1) then - Interaction := high(catsongs.Song) - else - Interaction := I - 1; - - //Stop Music - AudioPlayback.Stop; - - CatSongs.ShowCategoryList; - - //Show Cat in Top Left Mod - HideCatTL; + //Find Category + I := Interaction; + while not catsongs.Song[I].Main do + begin + Dec (I); + if (I < low(catsongs.Song)) then + break; + end; + if (I<= 1) then + Interaction := high(catsongs.Song) + else + Interaction := I - 1; + //Stop Music + AudioPlayback.Stop; - //Show Wrong Song when Tabs on Fix - SelectNext; - FixSelected; - //SelectPrev; - //CatSongs.Song[0].Visible := False; - end - else - begin - //On Escape goto Cat-List Hack End - //Tabs off and in Search or Playlist -> Go back to Song view - if (CatSongs.CatNumShow < -1) then - begin - //Atm: Set Empty Filter - CatSongs.SetFilter('', 0); + CatSongs.ShowCategoryList; //Show Cat in Top Left Mod HideCatTL; - Interaction := 0; + //Show Wrong Song when Tabs on Fix SelectNext; FixSelected; - - ChangeMusic; - end + //SelectPrev; + //CatSongs.Song[0].Visible := False; + end else begin - AudioPlayback.Stop; - AudioPlayback.PlaySound(SoundLib.Back); + //On Escape goto Cat-List Hack End + //Tabs off and in Search or Playlist -> Go back to Song view + if (CatSongs.CatNumShow < -1) then + begin + //Atm: Set Empty Filter + CatSongs.SetFilter('', 0); - FadeTo(@ScreenMain); - end; + //Show Cat in Top Left Mod + HideCatTL; + Interaction := 0; + //Show Wrong Song when Tabs on Fix + SelectNext; + FixSelected; + + ChangeMusic; + end + else + begin + AudioPlayback.Stop; + AudioPlayback.PlaySound(SoundLib.Back); + + FadeTo(@ScreenMain); + end; + + end; + end + //When in party Mode then Ask before Close + else if (Mode = smPartyMode) then + begin + AudioPlayback.PlaySound(SoundLib.Back); + CheckFadeTo(@ScreenMain,'MSG_END_PARTY'); end; - end - //When in party Mode then Ask before Close - else if (Mode = smPartyMode) then - begin - AudioPlayback.PlaySound(SoundLib.Back); - CheckFadeTo(@ScreenMain,'MSG_END_PARTY'); - end; end; SDLK_RETURN: begin @@ -521,7 +527,6 @@ begin {$ENDIF} if CatSongs.Song[Interaction].Main then begin // clicked on Category Button - //Show Cat in Top Left Mod ShowCatTL (Interaction); @@ -531,15 +536,14 @@ begin SongCurrent := SongCurrent - I + I2; SongTarget := SongTarget - I + I2; } - // SetScroll4; - - //Show Wrong Song when Tabs on Fix - SelectNext; - FixSelected; + // SetScroll4; - //Play Music: - ChangeMusic; + //Show Wrong Song when Tabs on Fix + SelectNext; + FixSelected; + //Play Music: + ChangeMusic; end else begin // clicked on song @@ -550,7 +554,7 @@ begin 0: StartSong; 1: SelectPlayers; 2:begin - If (CatSongs.CatNumShow = -3) then + if (CatSongs.CatNumShow = -3) then ScreenSongMenu.MenuShow(SM_Playlist) else ScreenSongMenu.MenuShow(SM_Main); @@ -651,12 +655,12 @@ begin SDLK_RIGHT: begin - if (Songs.SongList.Count > 0) AND (Mode = smNormal) then + if (Songs.SongList.Count > 0) and (Mode = smNormal) then begin AudioPlayback.PlaySound(SoundLib.Change); SelectNext; -// InteractNext; -// SongTarget := Interaction; + //InteractNext; + //SongTarget := Interaction; ChangeMusic; SetScroll4; //UpdateLCD; //TODO: maybe LCD Support as Plugin? @@ -666,7 +670,8 @@ begin SDLK_LEFT: begin - if (Songs.SongList.Count > 0)AND (Mode = smNormal) then begin + if (Songs.SongList.Count > 0)and (Mode = smNormal) then + begin AudioPlayback.PlaySound(SoundLib.Change); SelectPrev; ChangeMusic; @@ -678,7 +683,7 @@ begin SDLK_1: begin //Joker // to-do : Party - {if (Mode = smPartyMode) AND (PartySession.Teams.NumTeams >= 1) AND (PartySession.Teams.Teaminfo[0].Joker > 0) then + {if (Mode = smPartyMode) and (PartySession.Teams.NumTeams >= 1) and (PartySession.Teams.Teaminfo[0].Joker > 0) then begin //Use Joker Dec(PartySession.Teams.Teaminfo[0].Joker); @@ -689,7 +694,7 @@ begin SDLK_2: begin //Joker - {if (Mode = smPartyMode) AND (PartySession.Teams.NumTeams >= 2) AND (PartySession.Teams.Teaminfo[1].Joker > 0) then + {if (Mode = smPartyMode) and (PartySession.Teams.NumTeams >= 2) and (PartySession.Teams.Teaminfo[1].Joker > 0) then begin //Use Joker Dec(PartySession.Teams.Teaminfo[1].Joker); @@ -700,7 +705,7 @@ begin SDLK_3: begin //Joker - {if (Mode = smPartyMode) AND (PartySession.Teams.NumTeams >= 3) AND (PartySession.Teams.Teaminfo[2].Joker > 0) then + {if (Mode = smPartyMode) and (PartySession.Teams.NumTeams >= 3) and (PartySession.Teams.Teaminfo[2].Joker > 0) then begin //Use Joker Dec(PartySession.Teams.Teaminfo[2].Joker); @@ -714,9 +719,7 @@ end; constructor TScreenSong.Create; var -// Pet: integer; - I: integer; -//Label CreateSongButtons; + i: integer; begin inherited Create; @@ -754,23 +757,23 @@ begin //Load Party or NonParty specific Statics and Texts SetLength(StaticParty, Length(Theme.Song.StaticParty)); - for I := 0 to High(Theme.Song.StaticParty) do - StaticParty[I] := AddStatic(Theme.Song.StaticParty[I]); + for i := 0 to High(Theme.Song.StaticParty) do + StaticParty[i] := AddStatic(Theme.Song.StaticParty[i]); SetLength(TextParty, Length(Theme.Song.TextParty)); - for I := 0 to High(Theme.Song.TextParty) do - TextParty[I] := AddText(Theme.Song.TextParty[I]); + for i := 0 to High(Theme.Song.TextParty) do + TextParty[i] := AddText(Theme.Song.TextParty[i]); SetLength(StaticNonParty, Length(Theme.Song.StaticNonParty)); - for I := 0 to High(Theme.Song.StaticNonParty) do - StaticNonParty[I] := AddStatic(Theme.Song.StaticNonParty[I]); + for i := 0 to High(Theme.Song.StaticNonParty) do + StaticNonParty[i] := AddStatic(Theme.Song.StaticNonParty[i]); SetLength(TextNonParty, Length(Theme.Song.TextNonParty)); - for I := 0 to High(Theme.Song.TextNonParty) do - TextNonParty[I] := AddText(Theme.Song.TextNonParty[I]); + for i := 0 to High(Theme.Song.TextNonParty) do + TextNonParty[i] := AddText(Theme.Song.TextNonParty[i]); // Song List -// Songs.LoadSongList; // moved to the UltraStar unit + //Songs.LoadSongList; // moved to the UltraStar unit CatSongs.Refresh; GenerateThumbnails(); @@ -919,10 +922,10 @@ end; procedure TScreenSong.SetScroll1; var B: integer; // button -// BMin: integer; // button min // Auto Removed, Unused Variable -// BMax: integer; // button max // Auto Removed, Unused Variable + //BMin: integer; // button min // Auto Removed, Unused Variable + //BMax: integer; // button max // Auto Removed, Unused Variable Src: integer; -// Dst: integer; + //Dst: integer; Count: integer; // Dst is not used. Count is used. Ready: boolean; @@ -931,8 +934,8 @@ var Typ: integer; // 0 when all songs fits the screen Placed: integer; // number of placed visible buttons begin -// Src := 0; -// Dst := -1; + //Src := 0; + //Dst := -1; Count := 1; Typ := 0; Ready := false; @@ -976,12 +979,14 @@ begin Button[B].Selectable := CatSongs.Song[B].Visible; end; -{ for B := Src to Dst do begin -// Button[B].Visible := true; + { + for B := Src to Dst do begin + //Button[B].Visible := true; Button[B].Visible := CatSongs.Song[B].Visible; Button[B].Selectable := Button[B].Visible; Button[B].Y := 140 + (B-Src) * 60; - end;} + end; + } if Typ = 0 then begin @@ -1055,8 +1060,8 @@ end; procedure TScreenSong.SetScroll2; var B: integer; -// Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu // Auto Removed, Unused Variable -// Wsp2: real; // Auto Removed, Unused Variable + //Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu + //Wsp2: real; begin // liniowe for B := 0 to High(Button) do @@ -1071,19 +1076,21 @@ begin end; // kolowe -{ for B := 0 to High(Button) do begin + { + for B := 0 to High(Button) do begin Wsp := (B - Interaction); // 0 dla srodka, -1 dla lewego, +1 dla prawego itd. Wsp2 := Wsp / Length(Button); Button[B].X := 300 + 10000 * sin(2*pi*Wsp2); -// Button[B].Y := 140 + 50 * ; - end;} + //Button[B].Y := 140 + 50 * ; + end; + } end; procedure TScreenSong.SetScroll3; // with slide var B: integer; -// Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu // Auto Removed, Unused Variable -// Wsp2: real; // Auto Removed, Unused Variable + //Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu + //Wsp2: real; begin SongTarget := Interaction; @@ -1097,21 +1104,25 @@ begin Button[B].Visible := True; end; -{ if Length(Button) >= 3 then begin + { + if Length(Button) >= 3 then begin if Interaction = 0 then Button[High(Button)].X := 300 - 260; if Interaction = High(Button) then Button[0].X := 300 + 260; - end;} + end; + } // kolowe -{ for B := 0 to High(Button) do begin + { + for B := 0 to High(Button) do begin Wsp := (B - Interaction); // 0 dla srodka, -1 dla lewego, +1 dla prawego itd. Wsp2 := Wsp / Length(Button); Button[B].X := 300 + 10000 * sin(2*pi*Wsp2); -// Button[B].Y := 140 + 50 * ; - end;} + //Button[B].Y := 140 + 50 * ; + end; + } end; procedure TScreenSong.SetScroll4; // rotate @@ -1139,7 +1150,7 @@ 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].Y := Theme.Song.Cover.Y + (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7 ; Button[B].H := Button[B].W; end; @@ -1174,7 +1185,7 @@ begin for B := 0 to High(Button) do begin Button[B].Visible := CatSongs.Song[B].Visible; // nowe 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 - if ((ModReal(CatSongs.VisibleIndex(B) - SongCurrent, VS)>-3) AND (ModReal(CatSongs.VisibleIndex(B) - SongCurrent, VS)<3)) then + if ((ModReal(CatSongs.VisibleIndex(B) - SongCurrent, VS)>-3) and (ModReal(CatSongs.VisibleIndex(B) - SongCurrent, VS)<3)) then begin if CatSongs.VisibleIndex(B)> SongCurrent then Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / Z2 @@ -1198,13 +1209,13 @@ begin Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX; Button[B].Z := Z-0.00001; -// Button[B].Y := {50 + 140 + 50 - 50 * Z2; - // Button[B].Y := (Theme.Song.CoverY + 40 + 50 - 50 * Z2); + //Button[B].Y := {50 + 140 + 50 - 50 * Z2; + //Button[B].Y := (Theme.Song.CoverY + 40 + 50 - 50 * Z2); Button[B].Y := (Theme.Song.CoverY + Theme.Song.CoverW - Button[B].W); Button[B].H := Button[B].W; Button[B].Visible := True; end - {else if (((CatSongs.VisibleIndex(B) - SongCurrent)>-3) AND ((CatSongs.VisibleIndex(B) - SongCurrent)<3)) OR ((round (CatSongs.VisibleIndex(B) - SongCurrent) mod VS > -3) AND ((CatSongs.VisibleIndex(B) - SongCurrent)<3)) then + {else if (((CatSongs.VisibleIndex(B) - SongCurrent)>-3) and ((CatSongs.VisibleIndex(B) - SongCurrent)<3)) OR ((round (CatSongs.VisibleIndex(B) - SongCurrent) mod VS > -3) and ((CatSongs.VisibleIndex(B) - SongCurrent)<3)) then begin Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / 12 ;// 0.5.0 (II): takes another 16ms @@ -1240,7 +1251,8 @@ var helper: real; begin VS := CatSongs.VisibleSongs; // cache Visible Songs - {Vars + { + //Vars Theme.Song.CoverW: Radius des Kreises Theme.Song.CoverX: X Pos Linke Kante des gewählten Covers Theme.Song.CoverX: Y Pos Obere Kante des gewählten Covers @@ -1264,11 +1276,11 @@ begin if (Abs(Pos) < 2.5) then {fixed Positions} begin Angle := Pi * (Pos / 5); -// Button[B].Visible := False; + //Button[B].Visible := False; Button[B].H := Abs(Theme.Song.Cover.H * cos(Angle*0.8));//Power(Z2, 3); -// Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H; + //Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H; Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H; Button[B].Z := 0.95 - Abs(Pos) * 0.01; @@ -1314,7 +1326,7 @@ begin Button[B].Y := Theme.Song.Cover.Y - (Button[B].H - Theme.Song.Cover.H)*0.75; -// Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H; + //Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H; Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H; Diff := (Button[B].H - Theme.Song.Cover.H)/2; @@ -1324,7 +1336,7 @@ begin end; //Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Button[B].H)/1.5); //Cover at down border of the change field -// Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Button[B].H) * 0.7); + //Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Button[B].H) * 0.7); end; end; @@ -1360,7 +1372,7 @@ 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; end; @@ -1383,7 +1395,7 @@ begin if (Abs(Pos) < 2.5) then {fixed Positions} begin Angle := Pi * (Pos / 5); -// Button[B].Visible := False; + //Button[B].Visible := False; Button[B].H := Abs(Theme.Song.Cover.H * cos(Angle*0.8));//Power(Z2, 3); @@ -1415,7 +1427,7 @@ begin else Pos := (Pos + VS/2)/VS; - Angle := pi * Pos*2; + Angle := Pi * Pos*2; Button[B].Z := (0.4 - Abs(Pos/4)) -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers @@ -1446,16 +1458,16 @@ begin if Ini.Players = 4 then PlayersPlay := 6; //Cat Mod etc - if (Ini.Tabs_at_startup = 1) AND (CatSongs.CatNumShow = -1) then - begin - CatSongs.ShowCategoryList; - FixSelected; - //Show Cat in Top Left Mod - HideCatTL; - end; - + if (Ini.Tabs_at_startup = 1) and (CatSongs.CatNumShow = -1) then + begin + CatSongs.ShowCategoryList; + FixSelected; + //Show Cat in Top Left Mod + HideCatTL; + end; - if Length(CatSongs.Song) > 0 then 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 @@ -1479,7 +1491,6 @@ begin //Party Mode else if (Mode = smPartyMode) then begin - SelectRandomSong; //Show Menu directly in PartyMode //But only if selected in Options @@ -1487,8 +1498,6 @@ begin begin ScreenSongMenu.MenuShow(SM_Party_Main); end; - - end; SetJoker; @@ -1541,18 +1550,22 @@ begin SongCurrent := SongCurrent + dx*dt; -{ if SongCurrent > Catsongs.VisibleSongs then begin + { + if SongCurrent > Catsongs.VisibleSongs then begin SongCurrent := SongCurrent - Catsongs.VisibleSongs; SongTarget := SongTarget - Catsongs.VisibleSongs; - end;} + end; + } + + //Log.BenchmarkStart(5); -// Log.BenchmarkStart(5); SetScroll; -// Log.BenchmarkEnd(5); -// Log.LogBenchmark('SetScroll4', 5); + + //Log.BenchmarkEnd(5); + //Log.LogBenchmark('SetScroll4', 5); //Fading Functions, Only if Covertime is under 5 Seconds - If (CoverTime < 5) then + if (CoverTime < 5) then begin // cover fade if (CoverTime < 1) and (CoverTime + TimeSkip >= 1) then @@ -1623,7 +1636,6 @@ end; procedure TScreenSong.SelectNext; var Skip: integer; -// I: integer; // Auto Removed, Unused Variable VS: Integer; begin VS := CatSongs.VisibleSongs; @@ -1635,7 +1647,8 @@ 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; @@ -1648,14 +1661,14 @@ begin end; end; - // Interaction -> Button, ktorego okladke przeczytamy - // Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false); // 0.5.0: show uncached texture + + // Interaction -> Button, ktorego okladke przeczytamy + //Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false); // 0.5.0: show uncached texture end; procedure TScreenSong.SelectPrev; var Skip: integer; -// I: integer; // Auto Removed, Unused Variable VS: Integer; begin VS := CatSongs.VisibleSongs; @@ -1739,15 +1752,14 @@ end; procedure TScreenSong.SkipTo(Target: Cardinal); var -// Skip: integer; // Auto Removed, Unused Variable - I: integer; + i: integer; begin UnLoadDetailedCover; Interaction := High(CatSongs.Song); SongTarget := 0; - for I := 1 to Target+1 do + for i := 1 to Target+1 do SelectNext; FixSelected2; @@ -1762,7 +1774,6 @@ var CurTime: Cardinal; PosX, PosY: Integer; Pos: Real; -// lTmp : double; // Auto Removed, Unused Variable begin // Nothing to do if no music is played or an equalizer bar consists of no block if (AudioPlayback.Finished or (Theme.Song.Equalizer.Length <= 0)) then @@ -1864,11 +1875,11 @@ begin end; end; -Procedure TScreenSong.SelectRandomSong; +procedure TScreenSong.SelectRandomSong; var I, I2: Integer; begin - Case PlaylistMan.Mode of + case PlaylistMan.Mode of smNormal: //All Songs Just Select Random Song begin //When Tabs are activated then use Tab Method @@ -1931,11 +1942,11 @@ end; procedure TScreenSong.SetJoker; begin -// {//If Party Mode + // If Party Mode // to-do : Party if Mode = smPartyMode then //Show Joker that are available begin -(* + (* if (PartySession.Teams.NumTeams >= 1) then begin Static[StaticTeam1Joker1].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 1); @@ -1986,7 +1997,7 @@ begin Static[StaticTeam3Joker4].Visible := False; Static[StaticTeam3Joker5].Visible := False; end; -*) + *) end else begin //Hide all @@ -2018,19 +2029,19 @@ begin //Set Visibility of Party Statics and Text Visible := (Mode = smPartyMode); - For I := 0 to high(StaticParty) do + for I := 0 to high(StaticParty) do Static[StaticParty[I]].Visible := Visible; - For I := 0 to high(TextParty) do + for I := 0 to high(TextParty) do Text[TextParty[I]].Visible := Visible; //Set Visibility of Non Party Statics and Text Visible := not Visible; - For I := 0 to high(StaticNonParty) do + for I := 0 to high(StaticNonParty) do Static[StaticNonParty[I]].Visible := Visible; - For I := 0 to high(TextNonParty) do + for I := 0 to high(TextNonParty) do Text[TextNonParty[I]].Visible := Visible; end; @@ -2062,7 +2073,9 @@ end; procedure TScreenSong.OpenEditor; begin - if (Songs.SongList.Count > 0) and (not CatSongs.Song[Interaction].Main) AND (Mode = smNormal) then + if (Songs.SongList.Count > 0) and + (not CatSongs.Song[Interaction].Main) and + (Mode = smNormal) then begin AudioPlayback.Stop; AudioPlayback.PlaySound(SoundLib.Start); @@ -2074,21 +2087,26 @@ end; //Team No of Team (0-5) procedure TScreenSong.DoJoker (Team: Byte); begin - {if (Mode = smPartyMode) AND (PartySession.Teams.NumTeams >= Team + 1) AND (PartySession.Teams.Teaminfo[Team].Joker > 0) then + { + if (Mode = smPartyMode) and + (PartySession.Teams.NumTeams >= Team + 1) and + (PartySession.Teams.Teaminfo[Team].Joker > 0) then begin //Use Joker Dec(PartySession.Teams.Teaminfo[Team].Joker); SelectRandomSong; SetJoker; - end; } + end; + } end; //Detailed Cover Unloading. Unloads the Detailed, uncached Cover of the cur. Song procedure TScreenSong.UnLoadDetailedCover; begin CoverTime := 0; - - Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, true); // 0.5.0: show cached texture + + // show cached texture + Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, true); Button[Interaction].Texture2.Alpha := 0; if Button[Interaction].Texture.Name <> Skin.GetTextureFileName('SongCover') then @@ -2096,13 +2114,14 @@ begin end; procedure TScreenSong.Refresh; -begin { -CatSongs.Refresh; -CatSongs.ShowCategoryList; -Interaction := 0; -SelectNext; -FixSelected; } - +begin + { + CatSongs.Refresh; + CatSongs.ShowCategoryList; + Interaction := 0; + SelectNext; + FixSelected; + } end; end. diff --git a/Game/Code/Screens/UScreenTop5.pas b/Game/Code/Screens/UScreenTop5.pas index 7ad46d49..18c90f5e 100644 --- a/Game/Code/Screens/UScreenTop5.pas +++ b/Game/Code/Screens/UScreenTop5.pas @@ -103,7 +103,7 @@ begin PMax := Ini.Players; 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.AddScore(CurrentSong, Ini.Difficulty, Ini.Name[I], Round(Player[I].ScoreTotalInt)); DataBase.WriteScore(CurrentSong); DataBase.ReadScore(CurrentSong); -- cgit v1.2.3