diff options
author | jaybinks <jaybinks@b956fd51-792f-4845-bead-9b4dfca2ff2c> | 2007-11-01 23:22:01 +0000 |
---|---|---|
committer | jaybinks <jaybinks@b956fd51-792f-4845-bead-9b4dfca2ff2c> | 2007-11-01 23:22:01 +0000 |
commit | 99955c78f63d1cb0d8bec666bc33953590a74c8a (patch) | |
tree | 6fab123cf62264bb4997496c06d6d5230bad7248 /Game/Code/Classes/USingScores.pas | |
parent | 4df428bedccc51a542f46f3737a5848265d6dc27 (diff) | |
download | usdx-99955c78f63d1cb0d8bec666bc33953590a74c8a.tar.gz usdx-99955c78f63d1cb0d8bec666bc33953590a74c8a.tar.xz usdx-99955c78f63d1cb0d8bec666bc33953590a74c8a.zip |
fixed failed builds
build:USDX-LAZLIN-75
build:USDX-LAZLIN-76
for some reason we can not use {$MODE Delphi} in an
included file.
( Probably because of the way the compier scopes this switch to each pas file )
ive had to revert this part of eddies changes.
git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@548 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to 'Game/Code/Classes/USingScores.pas')
-rw-r--r-- | Game/Code/Classes/USingScores.pas | 1976 |
1 files changed, 990 insertions, 986 deletions
diff --git a/Game/Code/Classes/USingScores.pas b/Game/Code/Classes/USingScores.pas index d5256dc9..c7213180 100644 --- a/Game/Code/Classes/USingScores.pas +++ b/Game/Code/Classes/USingScores.pas @@ -1,986 +1,990 @@ -unit USingScores;
-
-interface
-
-{$I switches.inc}
-
-uses UThemes,
- OpenGl12,
- UTexture;
-
-//////////////////////////////////////////////////////////////
-// ATTENTION: //
-// Enabled Flag does not Work atm. This should cause Popups //
-// Not to Move and Scores to stay until Renenabling. //
-// To use e.g. in Pause Mode //
-// Also InVisible Flag causes Attributes not to change. //
-// This should be fixed after next Draw when Visible = True,//
-// but not testet yet //
-//////////////////////////////////////////////////////////////
-
-//Some Constances 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
-
-type
- //-----------
- // TScorePlayer - Record Containing Information about a Players Score
- //-----------
- TScorePlayer = record
- Position: Byte; //Index of the Position where the Player should be Drawn
- Enabled: Boolean; //Is the Score Display Enabled
- Visible: Boolean; //Is the Score Display Visible
- Score: Word; //Current Score of the Player
- ScoreDisplayed: Word; //Score cur. Displayed(for counting up)
- ScoreBG: TTexture;//Texture of the Players Scores BG
- Color: TRGB; //Teh Players Color
- RBPos: Real; //Cur. Percentille of the Rating Bar
- RBTarget: Real; //Target Position of Rating Bar
- RBVisible:Boolean; //Is Rating bar Drawn
- end;
- aScorePlayer = array[0..MaxPlayers-1] of TScorePlayer;
-
- //-----------
- // TScorePosition - Record Containing Information about a Score Position, that can be used
- //-----------
- PScorePosition = ^TScorePosition;
- TScorePosition = record
- //The Position is Used for Which Playercount
- PlayerCount: Byte;
- // 1 - One Player per Screen
- // 2 - 2 Players per Screen
- // 4 - 3 Players per Screen
- // 6 would be 2 and 3 Players per Screen
-
- BGX: Real; //X Position of the Score BG
- BGY: Real; //Y Position of the Score BG
- BGW: Real; //Width of the Score BG
- BGH: Real; //Height of the Score BG
-
- RBX: Real; //X Position of the Rating Bar
- RBY: Real; //Y Position of the Rating Bar
- RBW: Real; //Width of the Rating Bar
- RBH: Real; //Height of the Rating Bar
-
- TextX: Real; //X Position of the Score Text
- TextY: Real; //Y Position of the Score Text
- TextFont: Byte; //Font of the Score Text
- TextSize: Byte; //Size of the Score Text
-
- PUW: Real; //Width of the LineBonus Popup
- PUH: Real; //Height of the LineBonus Popup
- PUFont: Byte; //Font for the PopUps
- PUFontSize: Byte; //FontSize for the PopUps
- PUStartX: Real; //X Start Position of the LineBonus Popup
- PUStartY: Real; //Y Start Position of the LineBonus Popup
- PUTargetX: Real; //X Target Position of the LineBonus Popup
- PUTargetY: Real; //Y Target Position of the LineBonus Popup
- end;
- aScorePosition = array[0..MaxPositions-1] of TScorePosition;
-
- //-----------
- // TScorePopUp - Record Containing Information about a LineBonus Popup
- // List, Next Item is Saved in Next attribute
- //-----------
- PScorePopUp = ^TScorePopUp;
- TScorePopUp = record
- Player: Byte; //Index of the PopUps Player
- TimeStamp: Cardinal; //Timestamp of Popups Spawn
- Rating: Byte; //0 to 8, Type of Rating (Cool, bad, etc.)
- ScoreGiven:Word; //Score that has already been given to the Player
- ScoreDiff: Word; //Difference Between Cur Score at Spawn and Old Score
- Next: PScorePopUp; //Next Item in List
- end;
- aScorePopUp = array of TScorePopUp;
-
- //-----------
- // TSingScores - Class containing Scores Positions and Drawing Scores, Rating Bar + Popups
- //-----------
- TSingScores = class
- private
- Positions: aScorePosition;
- aPlayers: aScorePlayer;
- oPositionCount: Byte;
- oPlayerCount: Byte;
-
- //Saves the First and Last Popup of the List
- FirstPopUp: PScorePopUp;
- LastPopUp: PScorePopUp;
-
- //Procedure Draws a Popup by Pointer
- Procedure DrawPopUp(const PopUp: PScorePopUp);
-
- //Procedure Draws a Score by Playerindex
- Procedure DrawScore(const Index: Integer);
-
- //Procedure Draws the RatingBar by Playerindex
- Procedure DrawRatingBar(const Index: Integer);
-
- //Procedure Removes a PopUp w/o destroying the List
- Procedure KillPopUp(const last, cur: PScorePopUp);
- public
- Settings: record //Record containing some Displaying Options
- Phase1Time: Real; //time for Phase 1 to complete (in msecs)
- //The Plop Up of the PopUp
- Phase2Time: Real; //time for Phase 2 to complete (in msecs)
- //The Moving (mainly Upwards) of the Popup
- Phase3Time: Real; //time for Phase 3 to complete (in msecs)
- //The Fade out and Score adding
-
- PopUpTex: Array [0..8] of TTexture; //Textures for every Popup Rating
-
- RatingBar_BG_Tex: TTexture; //Rating Bar Texs
- RatingBar_FG_Tex: TTexture;
- RatingBar_Bar_Tex: TTexture;
-
- end;
-
- Visible: Boolean; //Visibility of all Scores
- Enabled: Boolean; //Scores are changed, PopUps are Moved etc.
- RBVisible: Boolean; //Visibility of all Rating Bars
-
- //Propertys for Reading Position and Playercount
- Property PositionCount: Byte read oPositionCount;
- Property PlayerCount: Byte read oPlayerCount;
- Property Players: aScorePlayer read aPlayers;
-
- //Constructor just sets some standard Settings
- Constructor Create;
-
- //Procedure Adds a Position to Array and Increases Position Count
- Procedure AddPosition(const pPosition: PScorePosition);
-
- //Procedure Adds a Player to Array and Increases Player Count
- Procedure AddPlayer(const ScoreBG: TTexture; const Color: TRGB; const Score: Word = 0; const Enabled: Boolean = True; const Visible: Boolean = True);
-
- //Change a Players Visibility, Enable
- Procedure ChangePlayerVisibility(const Index: Byte; const pVisible: Boolean);
- Procedure ChangePlayerEnabled(const Index: Byte; const pEnabled: Boolean);
-
- //Procedure Deletes all Player Information
- Procedure ClearPlayers;
-
- //Procedure Deletes Positions and Playerinformation
- Procedure Clear;
-
- //Procedure Loads some Settings and the Positions from Theme
- Procedure LoadfromTheme;
-
- //Procedure has to be called after Positions and Players have been added, before first call of Draw
- //It gives every Player a Score Position
- Procedure Init;
-
- //Spawns a new Line Bonus PopUp for the Player
- Procedure SpawnPopUp(const PlayerIndex: Byte; const Rating: Byte; const Score: Word);
-
- //Removes all PopUps from Mem
- Procedure KillAllPopUps;
-
- //Procedure Draws Scores and Linebonus PopUps
- Procedure Draw;
- end;
-
-
-implementation
-
-uses SDL,
- SysUtils,
- ULog,
- UGraphic,
- TextGL;
-
-//-----------
-//Constructor just sets some standard Settings
-//-----------
-Constructor TSingScores.Create;
-begin
- //Clear PopupList Pointers
- FirstPopUp := nil;
- LastPopUp := nil;
-
- //Clear Variables
- Visible := True;
- Enabled := True;
- RBVisible := True;
-
- //Clear Position Index
- oPositionCount := 0;
- oPlayerCount := 0;
-
- Settings.Phase1Time := 1000;
- Settings.Phase2Time := 2000;
- Settings.Phase3Time := 2000;
-
- Settings.PopUpTex[0].TexNum := High(gluInt);
- Settings.PopUpTex[1].TexNum := High(gluInt);
- Settings.PopUpTex[2].TexNum := High(gluInt);
- Settings.PopUpTex[3].TexNum := High(gluInt);
- Settings.PopUpTex[4].TexNum := High(gluInt);
- Settings.PopUpTex[5].TexNum := High(gluInt);
- Settings.PopUpTex[6].TexNum := High(gluInt);
- Settings.PopUpTex[7].TexNum := High(gluInt);
- Settings.PopUpTex[8].TexNum := High(gluInt);
-
- Settings.RatingBar_BG_Tex.TexNum := High(gluInt);
- Settings.RatingBar_FG_Tex.TexNum := High(gluInt);
- Settings.RatingBar_Bar_Tex.TexNum := High(gluInt);
-end;
-
-//-----------
-//Procedure Adds a Position to Array and Increases Position Count
-//-----------
-Procedure TSingScores.AddPosition(const pPosition: PScorePosition);
-begin
- if (PositionCount < MaxPositions) then
- begin
- Positions[PositionCount] := pPosition^;
-
- Inc(oPositionCount);
- end;
-end;
-
-//-----------
-//Procedure Adds a Player to Array and Increases Player Count
-//-----------
-Procedure TSingScores.AddPlayer(const ScoreBG: TTexture; const Color: TRGB; const Score: Word; const Enabled: Boolean; const Visible: Boolean);
-begin
- if (PlayerCount < MaxPlayers) then
- begin
- aPlayers[PlayerCount].Position := High(byte);
- aPlayers[PlayerCount].Enabled := Enabled;
- aPlayers[PlayerCount].Visible := Visible;
- aPlayers[PlayerCount].Score := Score;
- aPlayers[PlayerCount].ScoreDisplayed := Score;
- aPlayers[PlayerCount].ScoreBG := ScoreBG;
- aPlayers[PlayerCount].Color := Color;
- aPlayers[PlayerCount].RBPos := 0.5;
- aPlayers[PlayerCount].RBTarget := 0.5;
- aPlayers[PlayerCount].RBVisible := True;
-
- Inc(oPlayerCount);
- end;
-end;
-
-//-----------
-//Change a Players Visibility
-//-----------
-Procedure TSingScores.ChangePlayerVisibility(const Index: Byte; const pVisible: Boolean);
-begin
- if (Index < MaxPlayers) then
- aPlayers[Index].Visible := pVisible;
-end;
-
-//-----------
-//Change Player Enabled
-//-----------
-Procedure TSingScores.ChangePlayerEnabled(const Index: Byte; const pEnabled: Boolean);
-begin
- if (Index < MaxPlayers) then
- aPlayers[Index].Enabled := pEnabled;
-end;
-
-//-----------
-//Procedure Deletes all Player Information
-//-----------
-Procedure TSingScores.ClearPlayers;
-begin
- KillAllPopUps;
- oPlayerCount := 0;
-end;
-
-//-----------
-//Procedure Deletes Positions and Playerinformation
-//-----------
-Procedure TSingScores.Clear;
-begin
- KillAllPopUps;
- oPlayerCount := 0;
- oPositionCount := 0;
-end;
-
-//-----------
-//Procedure Loads some Settings and the Positions from Theme
-//-----------
-Procedure TSingScores.LoadfromTheme;
-var I: Integer;
- Procedure AddbyStatics(const PC: Byte; const ScoreStatic, SingBarStatic: TThemeStatic; ScoreText: TThemeText);
- var nPosition: TScorePosition;
- begin
- nPosition.PlayerCount := PC; //Only for one Player Playing
-
- nPosition.BGX := ScoreStatic.X;
- nPosition.BGY := ScoreStatic.Y;
- nPosition.BGW := ScoreStatic.W;
- nPosition.BGH := ScoreStatic.H;
-
- nPosition.TextX := ScoreText.X;
- nPosition.TextY := ScoreText.Y;
- nPosition.TextFont := ScoreText.Font;
- nPosition.TextSize := ScoreText.Size;
-
- nPosition.RBX := SingBarStatic.X;
- nPosition.RBY := SingBarStatic.Y;
- nPosition.RBW := SingBarStatic.W;
- nPosition.RBH := SingBarStatic.H;
-
- nPosition.PUW := nPosition.BGW;
- nPosition.PUH := nPosition.BGH;
-
- nPosition.PUFont := 2;
- nPosition.PUFontSize := 6;
-
- nPosition.PUStartX := nPosition.BGX;
- nPosition.PUStartY := nPosition.TextY + 65;
-
- nPosition.PUTargetX := nPosition.BGX;
- nPosition.PUTargetY := nPosition.TextY;
-
- AddPosition(@nPosition);
- end;
-begin
- Clear;
-
- //Set Textures
- //Popup Tex
- For I := 0 to 8 do
- Settings.PopUpTex[I] := Tex_SingLineBonusBack[I];
-
- //Rating Bar Tex
- Settings.RatingBar_BG_Tex := Tex_SingBar_Back;
- Settings.RatingBar_FG_Tex := Tex_SingBar_Front;
- Settings.RatingBar_Bar_Tex := Tex_SingBar_Bar;
-
- //Load Positions from Theme
-
- // Player1:
- AddByStatics(1, Theme.Sing.StaticP1ScoreBG, Theme.Sing.StaticP1SingBar, Theme.Sing.TextP1Score);
- AddByStatics(2, Theme.Sing.StaticP1TwoPScoreBG, Theme.Sing.StaticP1TwoPSingBar, Theme.Sing.TextP1TwoPScore);
- AddByStatics(4, Theme.Sing.StaticP1ThreePScoreBG, Theme.Sing.StaticP1ThreePSingBar, Theme.Sing.TextP1ThreePScore);
-
- // Player2:
- AddByStatics(2, Theme.Sing.StaticP2RScoreBG, Theme.Sing.StaticP2RSingBar, Theme.Sing.TextP2RScore);
- AddByStatics(4, Theme.Sing.StaticP2MScoreBG, Theme.Sing.StaticP2MSingBar, Theme.Sing.TextP2MScore);
-
- // Player3:
- AddByStatics(4, Theme.Sing.StaticP3RScoreBG, Theme.Sing.StaticP3RScoreBG, Theme.Sing.TextP3RScore);
-end;
-
-//-----------
-//Spawns a new Line Bonus PopUp for the Player
-//-----------
-Procedure TSingScores.SpawnPopUp(const PlayerIndex: Byte; const Rating: Byte; const Score: Word);
-var Cur: PScorePopUp;
-begin
- if (PlayerIndex < PlayerCount) then
- begin
- //Get Memory and Add Data
- GetMem(Cur, SizeOf(TScorePopUp));
-
- Cur.Player := PlayerIndex;
- Cur.TimeStamp := SDL_GetTicks;
- Cur.Rating := Rating;
- Cur.ScoreGiven:= 0;
- If (Players[PlayerIndex].Score < Score) then
- begin
- Cur.ScoreDiff := Score - Players[PlayerIndex].Score;
- aPlayers[PlayerIndex].Score := Score;
- end
- else
- Cur.ScoreDiff := 0;
- Cur.Next := nil;
-
- //Log.LogError('TSingScores.SpawnPopUp| Player: ' + InttoStr(PlayerIndex) + ', Score: ' + InttoStr(Score) + ', ScoreDiff: ' + InttoStr(Cur.ScoreDiff));
-
- //Add it to the Chain
- if (FirstPopUp = nil) then
- //the first PopUp in the List
- FirstPopUp := Cur
- else
- //second or earlier popup
- LastPopUp.Next := Cur;
-
- //Set new Popup to Last PopUp in the List
- LastPopUp := Cur;
- end
- else
- Log.LogError('TSingScores: Try to add PopUp for not existing player');
-end;
-
-//-----------
-// Removes a PopUp w/o destroying the List
-//-----------
-Procedure TSingScores.KillPopUp(const last, cur: PScorePopUp);
-var
- lTempA ,
- lTempB : real;
-begin
- //Give Player the Last Points that missing till now
- aPlayers[Cur.Player].ScoreDisplayed := aPlayers[Cur.Player].ScoreDisplayed + Cur.ScoreDiff - Cur.ScoreGiven;
-
- //Change Bars Position
-
- // TODO : JB_Lazarus - Exception=Invalid floating point operation
- // AT THIS LINE !
-
- {$IFDEF LAZARUS}
-(*
- writeln( 'USINGSCORES-aPlayers[Cur.Player].RBTarget : ' + floattostr( aPlayers[Cur.Player].RBTarget ) );
- writeln( 'USINGSCORES-(Cur.ScoreDiff - Cur.ScoreGiven) : ' + floattostr( (Cur.ScoreDiff - Cur.ScoreGiven) ) );
- writeln( 'USINGSCORES-Cur.ScoreDiff : ' + floattostr( Cur.ScoreDiff ) );
- writeln( 'USINGSCORES-(Cur.Rating / 20 - 0.26) : ' + floattostr( (Cur.Rating / 20 - 0.26) ) );
- writeln( '' );
-*)
- {$ENDIF}
-
- lTempA := ( aPlayers[Cur.Player].RBTarget + (Cur.ScoreDiff - Cur.ScoreGiven) );
- lTempB := ( Cur.ScoreDiff * (Cur.Rating / 20 - 0.26) );
-
- {$IFDEF LAZARUS}
-(*
- writeln( 'USINGSCORES-lTempA : ' + floattostr( lTempA ) );
- writeln( 'USINGSCORES-lTempB : ' + floattostr( lTempB ) );
- writeln( '----------------------------------------------------------' );
-*)
- {$ENDIF}
-
- if ( lTempA > 0 ) AND
- ( lTempB > 0 ) THEN
- begin
- aPlayers[Cur.Player].RBTarget := lTempA / lTempB;
- end;
-
- If (aPlayers[Cur.Player].RBTarget > 1) then
- aPlayers[Cur.Player].RBTarget := 1
- else
- If (aPlayers[Cur.Player].RBTarget < 0) then
- aPlayers[Cur.Player].RBTarget := 0;
-
- //If this is the First PopUp => Make Next PopUp the First
- If (Cur = FirstPopUp) then
- FirstPopUp := Cur.Next
- //Else => Remove Curent Popup from Chain
- else
- Last.Next := Cur.Next;
-
- //If this is the Last PopUp, Make PopUp before the Last
- If (Cur = LastPopUp) then
- LastPopUp := Last;
-
- //Free the Memory
- FreeMem(Cur, SizeOf(TScorePopUp));
-end;
-
-//-----------
-//Removes all PopUps from Mem
-//-----------
-Procedure TSingScores.KillAllPopUps;
-var
- Cur: PScorePopUp;
- Last: PScorePopUp;
-begin
- Cur := FirstPopUp;
-
- //Remove all PopUps:
- While (Cur <> nil) do
- begin
- Last := Cur;
- Cur := Cur.Next;
- FreeMem(Last, SizeOf(TScorePopUp));
- end;
-
- FirstPopUp := nil;
- LastPopUp := nil;
-end;
-
-//-----------
-//Init - has to be called after Positions and Players have been added, before first call of Draw
-//It gives every Player a Score Position
-//-----------
-Procedure TSingScores.Init;
-var
- PlC: Array [0..1] of Byte; //Playercount First Screen and Second Screen
- I, J: Integer;
- MaxPlayersperScreen: Byte;
- CurPlayer: Byte;
-
- Function GetPositionCountbyPlayerCount(bPlayerCount: Byte): Byte;
- var I: Integer;
- begin
- Result := 0;
- bPlayerCount := 1 shl (bPlayerCount - 1);
-
- For I := 0 to PositionCount-1 do
- begin
- If ((Positions[I].PlayerCount AND bPlayerCount) <> 0) then
- Inc(Result);
- end;
- end;
-
- Function GetPositionbyPlayernum(bPlayerCount, bPlayer: Byte): Byte;
- var I: Integer;
- begin
- bPlayerCount := 1 shl (bPlayerCount - 1);
- Result := High(Byte);
-
- For I := 0 to PositionCount-1 do
- begin
- If ((Positions[I].PlayerCount AND bPlayerCount) <> 0) then
- begin
- If (bPlayer = 0) then
- begin
- Result := I;
- Break;
- end
- else
- Dec(bPlayer);
- end;
- end;
- end;
-
-begin
-
- For I := 1 to 6 do
- begin
- //If there are enough Positions -> Write to MaxPlayers
- If (GetPositionCountbyPlayerCount(I) = I) then
- MaxPlayersperScreen := I
- else
- Break;
- end;
-
-
- //Split Players to both Screen or Display on One Screen
- if (Screens = 2) and (MaxPlayersperScreen < PlayerCount) then
- begin
- PlC[0] := PlayerCount div 2 + PlayerCount mod 2;
- PlC[1] := PlayerCount div 2;
- end
- else
- begin
- PlC[0] := PlayerCount;
- PlC[1] := 0;
- end;
-
-
- //Check if there are enough Positions for all Players
- For I := 0 to Screens - 1 do
- begin
- if (PlC[I] > MaxPlayersperScreen) then
- begin
- PlC[I] := MaxPlayersperScreen;
- Log.LogError('More Players than available Positions, TSingScores');
- end;
- end;
-
- CurPlayer := 0;
- //Give every Player a Position
- For I := 0 to Screens - 1 do
- For J := 0 to PlC[I]-1 do
- begin
- aPlayers[CurPlayer].Position := GetPositionbyPlayernum(PlC[I], J) OR (I shl 7);
- //Log.LogError('Player ' + InttoStr(CurPlayer) + ' gets Position: ' + InttoStr(aPlayers[CurPlayer].Position));
- Inc(CurPlayer);
- end;
-end;
-
-//-----------
-//Procedure Draws Scores and Linebonus PopUps
-//-----------
-Procedure TSingScores.Draw;
-var
- I: Integer;
- CurTime: Cardinal;
- CurPopUp, LastPopUp: PScorePopUp;
-begin
- CurTime := SDL_GetTicks;
-
- If Visible then
- begin
- //Draw Popups
- LastPopUp := nil;
- CurPopUp := FirstPopUp;
-
- While (CurPopUp <> nil) do
- begin
- if (CurTime - CurPopUp.TimeStamp > Settings.Phase1Time + Settings.Phase2Time + Settings.Phase3Time) then
- begin
- KillPopUp(LastPopUp, CurPopUp);
- if (LastPopUp = nil) then
- CurPopUp := FirstPopUp
- else
- CurPopUp := LastPopUp.Next;
- end
- else
- begin
- DrawPopUp(CurPopUp);
- LastPopUp := CurPopUp;
- CurPopUp := LastPopUp.Next;
- end;
- end;
-
-
- IF (RBVisible) then
- //Draw Players w/ Rating Bar
- For I := 0 to PlayerCount-1 do
- begin
- DrawScore(I);
- DrawRatingBar(I);
- end
- else
- //Draw Players w/o Rating Bar
- For I := 0 to PlayerCount-1 do
- begin
- DrawScore(I);
- end;
-
- end; //eo Visible
-end;
-
-//-----------
-//Procedure Draws a Popup by Pointer
-//-----------
-Procedure TSingScores.DrawPopUp(const PopUp: PScorePopUp);
-var
- Progress: Real;
- CurTime: Cardinal;
- X, Y, W, H, Alpha: Real;
- FontSize: Byte;
- TimeDiff: Cardinal;
- PIndex: Byte;
- TextLen: Real;
- ScoretoAdd: Word;
- PosDiff: Real;
-begin
- if (PopUp <> nil) then
- begin
- //Only Draw if Player has a Position
- PIndex := Players[PopUp.Player].Position;
- If PIndex <> high(byte) then
- begin
- //Only Draw if Player is on Cur Screen
- If ((Players[PopUp.Player].Position AND 128) = 0) = (ScreenAct = 1) then
- begin
- CurTime := SDL_GetTicks;
- If Not (Enabled AND Players[PopUp.Player].Enabled) then
- //Increase Timestamp with TIem where there is no Movement ...
- begin
- //Inc(PopUp.TimeStamp, LastRender);
- end;
- TimeDiff := CurTime - PopUp.TimeStamp;
-
- //Get Position of PopUp
- PIndex := PIndex AND 127;
-
-
- //Check for Phase ...
- If (TimeDiff <= Settings.Phase1Time) then
- begin
- //Phase 1 - The Ploping up
- Progress := TimeDiff / Settings.Phase1Time;
-
-
- W := Positions[PIndex].PUW * Sin(Progress/2*Pi);
- H := Positions[PIndex].PUH * Sin(Progress/2*Pi);
-
- X := Positions[PIndex].PUStartX + (Positions[PIndex].PUW - W)/2;
- Y := Positions[PIndex].PUStartY + (Positions[PIndex].PUH - H)/2;
-
- FontSize := Round(Progress * Positions[PIndex].PUFontSize);
- Alpha := 1;
- end
-
- Else If (TimeDiff <= Settings.Phase2Time + Settings.Phase1Time) then
- begin
- //Phase 2 - The Moving
- Progress := (TimeDiff - Settings.Phase1Time) / Settings.Phase2Time;
-
- W := Positions[PIndex].PUW;
- H := Positions[PIndex].PUH;
-
- PosDiff := Positions[PIndex].PUTargetX - Positions[PIndex].PUStartX;
- If PosDiff > 0 then
- PosDiff := PosDiff + W;
- X := Positions[PIndex].PUStartX + PosDiff * sqr(Progress);
-
- PosDiff := Positions[PIndex].PUTargetY - Positions[PIndex].PUStartY;
- If PosDiff < 0 then
- PosDiff := PosDiff + Positions[PIndex].BGH;
- Y := Positions[PIndex].PUStartY + PosDiff * sqr(Progress);
-
- FontSize := Positions[PIndex].PUFontSize;
- Alpha := 1 - 0.3 * Progress;
- end
-
- else
- begin
- //Phase 3 - The Fading out + Score adding
- Progress := (TimeDiff - Settings.Phase1Time - Settings.Phase2Time) / Settings.Phase3Time;
-
- If (PopUp.Rating > 0) then
- begin
- //Add Scores if Player Enabled
- If (Enabled AND Players[PopUp.Player].Enabled) then
- begin
- ScoreToAdd := Round(PopUp.ScoreDiff * Progress) - PopUp.ScoreGiven;
- Inc(PopUp.ScoreGiven, ScoreToAdd);
- aPlayers[PopUp.Player].ScoreDisplayed := Players[PopUp.Player].ScoreDisplayed + ScoreToAdd;
-
- //Change Bars Position
- aPlayers[PopUp.Player].RBTarget := aPlayers[PopUp.Player].RBTarget + ScoreToAdd/PopUp.ScoreDiff * (PopUp.Rating / 20 - 0.26);
- If (aPlayers[PopUp.Player].RBTarget > 1) then
- aPlayers[PopUp.Player].RBTarget := 1
- else If (aPlayers[PopUp.Player].RBTarget < 0) then
- aPlayers[PopUp.Player].RBTarget := 0;
- end;
-
- //Set Positions etc.
- Alpha := 0.7 - 0.7 * Progress;
-
- W := Positions[PIndex].PUW;
- H := Positions[PIndex].PUH;
-
- PosDiff := Positions[PIndex].PUTargetX - Positions[PIndex].PUStartX;
- If (PosDiff > 0) then
- PosDiff := W
- else
- PosDiff := 0;
- X := Positions[PIndex].PUTargetX + PosDiff * Progress;
-
- PosDiff := Positions[PIndex].PUTargetY - Positions[PIndex].PUStartY;
- If (PosDiff < 0) then
- PosDiff := -Positions[PIndex].BGH
- else
- PosDiff := 0;
- Y := Positions[PIndex].PUTargetY - PosDiff * (1-Progress);
-
- FontSize := Positions[PIndex].PUFontSize;
- end
- else
- begin
- //Here the Effect that Should be shown if a PopUp without Score is Drawn
- //And or Spawn with the GraphicObjects etc.
- //Some Work for Blindy to do :P
-
- //ATM: Just Let it Slide in the Scores just like the Normal PopUp
- Alpha := 0;
- end;
- end;
-
- //Draw PopUp
-
- if (Alpha > 0) AND (Players[PopUp.Player].Visible) then
- begin
- //Draw BG:
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glColor4f(1,1,1, Alpha);
- glBindTexture(GL_TEXTURE_2D, Settings.PopUpTex[PopUp.Rating].TexNum);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(X, Y);
- glTexCoord2f(0, Settings.PopUpTex[PopUp.Rating].TexH); glVertex2f(X, Y + H);
- glTexCoord2f(Settings.PopUpTex[PopUp.Rating].TexW, Settings.PopUpTex[PopUp.Rating].TexH); glVertex2f(X + W, Y + H);
- glTexCoord2f(Settings.PopUpTex[PopUp.Rating].TexW, 0); glVertex2f(X + W, Y);
- glEnd;
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- //Set FontStyle and Size
- SetFontStyle(Positions[PIndex].PUFont);
- SetFontItalic(False);
- SetFontSize(FontSize);
-
- //Draw Text
- TextLen := glTextWidth(PChar(Theme.Sing.LineBonusText[PopUp.Rating]));
-
- //Color and Pos
- SetFontPos (X + (W - TextLen) / 2, Y + 12);
- glColor4f(1, 1, 1, Alpha);
-
- //Draw
- glPrint(PChar(Theme.Sing.LineBonusText[PopUp.Rating]));
- end; //eo Alpha check
- end; //eo Right Screen
- end; //eo Player has Position
- end
- else
- Log.LogError('TSingScores: Try to Draw a not existing PopUp');
-end;
-
-//-----------
-//Procedure Draws a Score by Playerindex
-//-----------
-Procedure TSingScores.DrawScore(const Index: Integer);
-var
- Position: PScorePosition;
- ScoreStr: String;
-begin
- //Only Draw if Player has a Position
- 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].Visible then
- begin
- Position := @Positions[Players[Index].Position and 127];
-
- //Draw ScoreBG
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glColor4f(1,1,1, 1);
- glBindTexture(GL_TEXTURE_2D, Players[Index].ScoreBG.TexNum);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Position.BGX, Position.BGY);
- glTexCoord2f(0, Players[Index].ScoreBG.TexH); glVertex2f(Position.BGX, Position.BGY + Position.BGH);
- glTexCoord2f(Players[Index].ScoreBG.TexW, Players[Index].ScoreBG.TexH); glVertex2f(Position.BGX + Position.BGW, Position.BGY + Position.BGH);
- glTexCoord2f(Players[Index].ScoreBG.TexW, 0); glVertex2f(Position.BGX + Position.BGW, Position.BGY);
- glEnd;
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- //Draw Score Text
- SetFontStyle(Position.TextFont);
- SetFontItalic(False);
- SetFontSize(Position.TextSize);
- SetFontPos(Position.TextX, Position.TextY);
-
- ScoreStr := InttoStr(Players[Index].ScoreDisplayed div 10) + '0';
- While (Length(ScoreStr) < 5) do
- ScoreStr := '0' + ScoreStr;
-
- glPrint(PChar(ScoreStr));
-
- end; //eo Right Screen
- end; //eo Player has Position
-end;
-
-
-Procedure TSingScores.DrawRatingBar(const Index: Integer);
-var
- Position: PScorePosition;
- R,G,B, Size: Real;
- Diff: Real;
-begin
- //Only Draw if Player has a Position
- 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
- begin
- Position := @Positions[Players[Index].Position and 127];
-
- If (Enabled AND Players[Index].Enabled) then
- begin
- //Move Position if Enabled
- Diff := Players[Index].RBTarget - Players[Index].RBPos;
- If(Abs(Diff) < 0.02) then
- aPlayers[Index].RBPos := aPlayers[Index].RBTarget
- else
- aPlayers[Index].RBPos := aPlayers[Index].RBPos + Diff*0.1;
- end;
-
- //Get Colors for RatingBar
- If Players[index].RBPos <=0.22 then
- begin
- R := 1;
- G := 0;
- B := 0;
- end
- 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
- begin
- R := 1;
- G := 1;
- B := 0;
- end
- Else If Players[index].RBPos <=0.77 then
- begin
- R := 1-(Players[index].RBPos-0.57)*5;
- G := 1;
- B := 0;
- end
- else
- begin
- R := 0;
- G := 1;
- B := 0;
- end;
-
- //Enable all glFuncs Needed
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- //Draw RatingBar BG
- glColor4f(1, 1, 1, 0.8);
- glBindTexture(GL_TEXTURE_2D, Settings.RatingBar_BG_Tex.TexNum);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0);
- glVertex2f(Position.RBX, Position.RBY);
-
- glTexCoord2f(0, Settings.RatingBar_BG_Tex.TexH);
- glVertex2f(Position.RBX, Position.RBY+Position.RBH);
-
- glTexCoord2f(Settings.RatingBar_BG_Tex.TexW, Settings.RatingBar_BG_Tex.TexH);
- glVertex2f(Position.RBX+Position.RBW, Position.RBY+Position.RBH);
-
- glTexCoord2f(Settings.RatingBar_BG_Tex.TexW, 0);
- glVertex2f(Position.RBX+Position.RBW, Position.RBY);
- glEnd;
-
- //Draw Rating bar itself
- Size := Position.RBX + Position.RBW * Players[Index].RBPos;
- glColor4f(R, G, B, 1);
- glBindTexture(GL_TEXTURE_2D, Settings.RatingBar_Bar_Tex.TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0);
- glVertex2f(Position.RBX, Position.RBY);
-
- glTexCoord2f(0, Settings.RatingBar_Bar_Tex.TexH);
- glVertex2f(Position.RBX, Position.RBY + Position.RBH);
-
- glTexCoord2f(Settings.RatingBar_Bar_Tex.TexW, Settings.RatingBar_Bar_Tex.TexH);
- glVertex2f(Size, Position.RBY + Position.RBH);
-
- glTexCoord2f(Settings.RatingBar_Bar_Tex.TexW, 0);
- glVertex2f(Size, Position.RBY);
- glEnd;
-
- //Draw Ratingbar FG (Teh thing with the 3 lines to get better readability)
- glColor4f(1, 1, 1, 0.6);
- glBindTexture(GL_TEXTURE_2D, Settings.RatingBar_FG_Tex.TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0);
- glVertex2f(Position.RBX, Position.RBY);
-
- glTexCoord2f(0, Settings.RatingBar_FG_Tex.TexH);
- glVertex2f(Position.RBX, Position.RBY + Position.RBH);
-
- glTexCoord2f(Settings.RatingBar_FG_Tex.TexW, Settings.RatingBar_FG_Tex.TexH);
- glVertex2f(Position.RBX + Position.RBW, Position.RBY + Position.RBH);
-
- glTexCoord2f(Settings.RatingBar_FG_Tex.TexW, 0);
- glVertex2f(Position.RBX + Position.RBW, Position.RBY);
- glEnd;
-
- //Disable all Enabled glFuncs
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- end; //eo Right Screen
- end; //eo Player has Position
-end;
-
-end.
+unit USingScores; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses UThemes, + OpenGl12, + UTexture; + +////////////////////////////////////////////////////////////// +// ATTENTION: // +// Enabled Flag does not Work atm. This should cause Popups // +// Not to Move and Scores to stay until Renenabling. // +// To use e.g. in Pause Mode // +// Also InVisible Flag causes Attributes not to change. // +// This should be fixed after next Draw when Visible = True,// +// but not testet yet // +////////////////////////////////////////////////////////////// + +//Some Constances 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 + +type + //----------- + // TScorePlayer - Record Containing Information about a Players Score + //----------- + TScorePlayer = record + Position: Byte; //Index of the Position where the Player should be Drawn + Enabled: Boolean; //Is the Score Display Enabled + Visible: Boolean; //Is the Score Display Visible + Score: Word; //Current Score of the Player + ScoreDisplayed: Word; //Score cur. Displayed(for counting up) + ScoreBG: TTexture;//Texture of the Players Scores BG + Color: TRGB; //Teh Players Color + RBPos: Real; //Cur. Percentille of the Rating Bar + RBTarget: Real; //Target Position of Rating Bar + RBVisible:Boolean; //Is Rating bar Drawn + end; + aScorePlayer = array[0..MaxPlayers-1] of TScorePlayer; + + //----------- + // TScorePosition - Record Containing Information about a Score Position, that can be used + //----------- + PScorePosition = ^TScorePosition; + TScorePosition = record + //The Position is Used for Which Playercount + PlayerCount: Byte; + // 1 - One Player per Screen + // 2 - 2 Players per Screen + // 4 - 3 Players per Screen + // 6 would be 2 and 3 Players per Screen + + BGX: Real; //X Position of the Score BG + BGY: Real; //Y Position of the Score BG + BGW: Real; //Width of the Score BG + BGH: Real; //Height of the Score BG + + RBX: Real; //X Position of the Rating Bar + RBY: Real; //Y Position of the Rating Bar + RBW: Real; //Width of the Rating Bar + RBH: Real; //Height of the Rating Bar + + TextX: Real; //X Position of the Score Text + TextY: Real; //Y Position of the Score Text + TextFont: Byte; //Font of the Score Text + TextSize: Byte; //Size of the Score Text + + PUW: Real; //Width of the LineBonus Popup + PUH: Real; //Height of the LineBonus Popup + PUFont: Byte; //Font for the PopUps + PUFontSize: Byte; //FontSize for the PopUps + PUStartX: Real; //X Start Position of the LineBonus Popup + PUStartY: Real; //Y Start Position of the LineBonus Popup + PUTargetX: Real; //X Target Position of the LineBonus Popup + PUTargetY: Real; //Y Target Position of the LineBonus Popup + end; + aScorePosition = array[0..MaxPositions-1] of TScorePosition; + + //----------- + // TScorePopUp - Record Containing Information about a LineBonus Popup + // List, Next Item is Saved in Next attribute + //----------- + PScorePopUp = ^TScorePopUp; + TScorePopUp = record + Player: Byte; //Index of the PopUps Player + TimeStamp: Cardinal; //Timestamp of Popups Spawn + Rating: Byte; //0 to 8, Type of Rating (Cool, bad, etc.) + ScoreGiven:Word; //Score that has already been given to the Player + ScoreDiff: Word; //Difference Between Cur Score at Spawn and Old Score + Next: PScorePopUp; //Next Item in List + end; + aScorePopUp = array of TScorePopUp; + + //----------- + // TSingScores - Class containing Scores Positions and Drawing Scores, Rating Bar + Popups + //----------- + TSingScores = class + private + Positions: aScorePosition; + aPlayers: aScorePlayer; + oPositionCount: Byte; + oPlayerCount: Byte; + + //Saves the First and Last Popup of the List + FirstPopUp: PScorePopUp; + LastPopUp: PScorePopUp; + + //Procedure Draws a Popup by Pointer + Procedure DrawPopUp(const PopUp: PScorePopUp); + + //Procedure Draws a Score by Playerindex + Procedure DrawScore(const Index: Integer); + + //Procedure Draws the RatingBar by Playerindex + Procedure DrawRatingBar(const Index: Integer); + + //Procedure Removes a PopUp w/o destroying the List + Procedure KillPopUp(const last, cur: PScorePopUp); + public + Settings: record //Record containing some Displaying Options + Phase1Time: Real; //time for Phase 1 to complete (in msecs) + //The Plop Up of the PopUp + Phase2Time: Real; //time for Phase 2 to complete (in msecs) + //The Moving (mainly Upwards) of the Popup + Phase3Time: Real; //time for Phase 3 to complete (in msecs) + //The Fade out and Score adding + + PopUpTex: Array [0..8] of TTexture; //Textures for every Popup Rating + + RatingBar_BG_Tex: TTexture; //Rating Bar Texs + RatingBar_FG_Tex: TTexture; + RatingBar_Bar_Tex: TTexture; + + end; + + Visible: Boolean; //Visibility of all Scores + Enabled: Boolean; //Scores are changed, PopUps are Moved etc. + RBVisible: Boolean; //Visibility of all Rating Bars + + //Propertys for Reading Position and Playercount + Property PositionCount: Byte read oPositionCount; + Property PlayerCount: Byte read oPlayerCount; + Property Players: aScorePlayer read aPlayers; + + //Constructor just sets some standard Settings + Constructor Create; + + //Procedure Adds a Position to Array and Increases Position Count + Procedure AddPosition(const pPosition: PScorePosition); + + //Procedure Adds a Player to Array and Increases Player Count + Procedure AddPlayer(const ScoreBG: TTexture; const Color: TRGB; const Score: Word = 0; const Enabled: Boolean = True; const Visible: Boolean = True); + + //Change a Players Visibility, Enable + Procedure ChangePlayerVisibility(const Index: Byte; const pVisible: Boolean); + Procedure ChangePlayerEnabled(const Index: Byte; const pEnabled: Boolean); + + //Procedure Deletes all Player Information + Procedure ClearPlayers; + + //Procedure Deletes Positions and Playerinformation + Procedure Clear; + + //Procedure Loads some Settings and the Positions from Theme + Procedure LoadfromTheme; + + //Procedure has to be called after Positions and Players have been added, before first call of Draw + //It gives every Player a Score Position + Procedure Init; + + //Spawns a new Line Bonus PopUp for the Player + Procedure SpawnPopUp(const PlayerIndex: Byte; const Rating: Byte; const Score: Word); + + //Removes all PopUps from Mem + Procedure KillAllPopUps; + + //Procedure Draws Scores and Linebonus PopUps + Procedure Draw; + end; + + +implementation + +uses SDL, + SysUtils, + ULog, + UGraphic, + TextGL; + +//----------- +//Constructor just sets some standard Settings +//----------- +Constructor TSingScores.Create; +begin + //Clear PopupList Pointers + FirstPopUp := nil; + LastPopUp := nil; + + //Clear Variables + Visible := True; + Enabled := True; + RBVisible := True; + + //Clear Position Index + oPositionCount := 0; + oPlayerCount := 0; + + Settings.Phase1Time := 1000; + Settings.Phase2Time := 2000; + Settings.Phase3Time := 2000; + + Settings.PopUpTex[0].TexNum := High(gluInt); + Settings.PopUpTex[1].TexNum := High(gluInt); + Settings.PopUpTex[2].TexNum := High(gluInt); + Settings.PopUpTex[3].TexNum := High(gluInt); + Settings.PopUpTex[4].TexNum := High(gluInt); + Settings.PopUpTex[5].TexNum := High(gluInt); + Settings.PopUpTex[6].TexNum := High(gluInt); + Settings.PopUpTex[7].TexNum := High(gluInt); + Settings.PopUpTex[8].TexNum := High(gluInt); + + Settings.RatingBar_BG_Tex.TexNum := High(gluInt); + Settings.RatingBar_FG_Tex.TexNum := High(gluInt); + Settings.RatingBar_Bar_Tex.TexNum := High(gluInt); +end; + +//----------- +//Procedure Adds a Position to Array and Increases Position Count +//----------- +Procedure TSingScores.AddPosition(const pPosition: PScorePosition); +begin + if (PositionCount < MaxPositions) then + begin + Positions[PositionCount] := pPosition^; + + Inc(oPositionCount); + end; +end; + +//----------- +//Procedure Adds a Player to Array and Increases Player Count +//----------- +Procedure TSingScores.AddPlayer(const ScoreBG: TTexture; const Color: TRGB; const Score: Word; const Enabled: Boolean; const Visible: Boolean); +begin + if (PlayerCount < MaxPlayers) then + begin + aPlayers[PlayerCount].Position := High(byte); + aPlayers[PlayerCount].Enabled := Enabled; + aPlayers[PlayerCount].Visible := Visible; + aPlayers[PlayerCount].Score := Score; + aPlayers[PlayerCount].ScoreDisplayed := Score; + aPlayers[PlayerCount].ScoreBG := ScoreBG; + aPlayers[PlayerCount].Color := Color; + aPlayers[PlayerCount].RBPos := 0.5; + aPlayers[PlayerCount].RBTarget := 0.5; + aPlayers[PlayerCount].RBVisible := True; + + Inc(oPlayerCount); + end; +end; + +//----------- +//Change a Players Visibility +//----------- +Procedure TSingScores.ChangePlayerVisibility(const Index: Byte; const pVisible: Boolean); +begin + if (Index < MaxPlayers) then + aPlayers[Index].Visible := pVisible; +end; + +//----------- +//Change Player Enabled +//----------- +Procedure TSingScores.ChangePlayerEnabled(const Index: Byte; const pEnabled: Boolean); +begin + if (Index < MaxPlayers) then + aPlayers[Index].Enabled := pEnabled; +end; + +//----------- +//Procedure Deletes all Player Information +//----------- +Procedure TSingScores.ClearPlayers; +begin + KillAllPopUps; + oPlayerCount := 0; +end; + +//----------- +//Procedure Deletes Positions and Playerinformation +//----------- +Procedure TSingScores.Clear; +begin + KillAllPopUps; + oPlayerCount := 0; + oPositionCount := 0; +end; + +//----------- +//Procedure Loads some Settings and the Positions from Theme +//----------- +Procedure TSingScores.LoadfromTheme; +var I: Integer; + Procedure AddbyStatics(const PC: Byte; const ScoreStatic, SingBarStatic: TThemeStatic; ScoreText: TThemeText); + var nPosition: TScorePosition; + begin + nPosition.PlayerCount := PC; //Only for one Player Playing + + nPosition.BGX := ScoreStatic.X; + nPosition.BGY := ScoreStatic.Y; + nPosition.BGW := ScoreStatic.W; + nPosition.BGH := ScoreStatic.H; + + nPosition.TextX := ScoreText.X; + nPosition.TextY := ScoreText.Y; + nPosition.TextFont := ScoreText.Font; + nPosition.TextSize := ScoreText.Size; + + nPosition.RBX := SingBarStatic.X; + nPosition.RBY := SingBarStatic.Y; + nPosition.RBW := SingBarStatic.W; + nPosition.RBH := SingBarStatic.H; + + nPosition.PUW := nPosition.BGW; + nPosition.PUH := nPosition.BGH; + + nPosition.PUFont := 2; + nPosition.PUFontSize := 6; + + nPosition.PUStartX := nPosition.BGX; + nPosition.PUStartY := nPosition.TextY + 65; + + nPosition.PUTargetX := nPosition.BGX; + nPosition.PUTargetY := nPosition.TextY; + + AddPosition(@nPosition); + end; +begin + Clear; + + //Set Textures + //Popup Tex + For I := 0 to 8 do + Settings.PopUpTex[I] := Tex_SingLineBonusBack[I]; + + //Rating Bar Tex + Settings.RatingBar_BG_Tex := Tex_SingBar_Back; + Settings.RatingBar_FG_Tex := Tex_SingBar_Front; + Settings.RatingBar_Bar_Tex := Tex_SingBar_Bar; + + //Load Positions from Theme + + // Player1: + AddByStatics(1, Theme.Sing.StaticP1ScoreBG, Theme.Sing.StaticP1SingBar, Theme.Sing.TextP1Score); + AddByStatics(2, Theme.Sing.StaticP1TwoPScoreBG, Theme.Sing.StaticP1TwoPSingBar, Theme.Sing.TextP1TwoPScore); + AddByStatics(4, Theme.Sing.StaticP1ThreePScoreBG, Theme.Sing.StaticP1ThreePSingBar, Theme.Sing.TextP1ThreePScore); + + // Player2: + AddByStatics(2, Theme.Sing.StaticP2RScoreBG, Theme.Sing.StaticP2RSingBar, Theme.Sing.TextP2RScore); + AddByStatics(4, Theme.Sing.StaticP2MScoreBG, Theme.Sing.StaticP2MSingBar, Theme.Sing.TextP2MScore); + + // Player3: + AddByStatics(4, Theme.Sing.StaticP3RScoreBG, Theme.Sing.StaticP3RScoreBG, Theme.Sing.TextP3RScore); +end; + +//----------- +//Spawns a new Line Bonus PopUp for the Player +//----------- +Procedure TSingScores.SpawnPopUp(const PlayerIndex: Byte; const Rating: Byte; const Score: Word); +var Cur: PScorePopUp; +begin + if (PlayerIndex < PlayerCount) then + begin + //Get Memory and Add Data + GetMem(Cur, SizeOf(TScorePopUp)); + + Cur.Player := PlayerIndex; + Cur.TimeStamp := SDL_GetTicks; + Cur.Rating := Rating; + Cur.ScoreGiven:= 0; + If (Players[PlayerIndex].Score < Score) then + begin + Cur.ScoreDiff := Score - Players[PlayerIndex].Score; + aPlayers[PlayerIndex].Score := Score; + end + else + Cur.ScoreDiff := 0; + Cur.Next := nil; + + //Log.LogError('TSingScores.SpawnPopUp| Player: ' + InttoStr(PlayerIndex) + ', Score: ' + InttoStr(Score) + ', ScoreDiff: ' + InttoStr(Cur.ScoreDiff)); + + //Add it to the Chain + if (FirstPopUp = nil) then + //the first PopUp in the List + FirstPopUp := Cur + else + //second or earlier popup + LastPopUp.Next := Cur; + + //Set new Popup to Last PopUp in the List + LastPopUp := Cur; + end + else + Log.LogError('TSingScores: Try to add PopUp for not existing player'); +end; + +//----------- +// Removes a PopUp w/o destroying the List +//----------- +Procedure TSingScores.KillPopUp(const last, cur: PScorePopUp); +var + lTempA , + lTempB : real; +begin + //Give Player the Last Points that missing till now + aPlayers[Cur.Player].ScoreDisplayed := aPlayers[Cur.Player].ScoreDisplayed + Cur.ScoreDiff - Cur.ScoreGiven; + + //Change Bars Position + + // TODO : JB_Lazarus - Exception=Invalid floating point operation + // AT THIS LINE ! + + {$IFDEF LAZARUS} +(* + writeln( 'USINGSCORES-aPlayers[Cur.Player].RBTarget : ' + floattostr( aPlayers[Cur.Player].RBTarget ) ); + writeln( 'USINGSCORES-(Cur.ScoreDiff - Cur.ScoreGiven) : ' + floattostr( (Cur.ScoreDiff - Cur.ScoreGiven) ) ); + writeln( 'USINGSCORES-Cur.ScoreDiff : ' + floattostr( Cur.ScoreDiff ) ); + writeln( 'USINGSCORES-(Cur.Rating / 20 - 0.26) : ' + floattostr( (Cur.Rating / 20 - 0.26) ) ); + writeln( '' ); +*) + {$ENDIF} + + lTempA := ( aPlayers[Cur.Player].RBTarget + (Cur.ScoreDiff - Cur.ScoreGiven) ); + lTempB := ( Cur.ScoreDiff * (Cur.Rating / 20 - 0.26) ); + + {$IFDEF LAZARUS} +(* + writeln( 'USINGSCORES-lTempA : ' + floattostr( lTempA ) ); + writeln( 'USINGSCORES-lTempB : ' + floattostr( lTempB ) ); + writeln( '----------------------------------------------------------' ); +*) + {$ENDIF} + + if ( lTempA > 0 ) AND + ( lTempB > 0 ) THEN + begin + aPlayers[Cur.Player].RBTarget := lTempA / lTempB; + end; + + If (aPlayers[Cur.Player].RBTarget > 1) then + aPlayers[Cur.Player].RBTarget := 1 + else + If (aPlayers[Cur.Player].RBTarget < 0) then + aPlayers[Cur.Player].RBTarget := 0; + + //If this is the First PopUp => Make Next PopUp the First + If (Cur = FirstPopUp) then + FirstPopUp := Cur.Next + //Else => Remove Curent Popup from Chain + else + Last.Next := Cur.Next; + + //If this is the Last PopUp, Make PopUp before the Last + If (Cur = LastPopUp) then + LastPopUp := Last; + + //Free the Memory + FreeMem(Cur, SizeOf(TScorePopUp)); +end; + +//----------- +//Removes all PopUps from Mem +//----------- +Procedure TSingScores.KillAllPopUps; +var + Cur: PScorePopUp; + Last: PScorePopUp; +begin + Cur := FirstPopUp; + + //Remove all PopUps: + While (Cur <> nil) do + begin + Last := Cur; + Cur := Cur.Next; + FreeMem(Last, SizeOf(TScorePopUp)); + end; + + FirstPopUp := nil; + LastPopUp := nil; +end; + +//----------- +//Init - has to be called after Positions and Players have been added, before first call of Draw +//It gives every Player a Score Position +//----------- +Procedure TSingScores.Init; +var + PlC: Array [0..1] of Byte; //Playercount First Screen and Second Screen + I, J: Integer; + MaxPlayersperScreen: Byte; + CurPlayer: Byte; + + Function GetPositionCountbyPlayerCount(bPlayerCount: Byte): Byte; + var I: Integer; + begin + Result := 0; + bPlayerCount := 1 shl (bPlayerCount - 1); + + For I := 0 to PositionCount-1 do + begin + If ((Positions[I].PlayerCount AND bPlayerCount) <> 0) then + Inc(Result); + end; + end; + + Function GetPositionbyPlayernum(bPlayerCount, bPlayer: Byte): Byte; + var I: Integer; + begin + bPlayerCount := 1 shl (bPlayerCount - 1); + Result := High(Byte); + + For I := 0 to PositionCount-1 do + begin + If ((Positions[I].PlayerCount AND bPlayerCount) <> 0) then + begin + If (bPlayer = 0) then + begin + Result := I; + Break; + end + else + Dec(bPlayer); + end; + end; + end; + +begin + + For I := 1 to 6 do + begin + //If there are enough Positions -> Write to MaxPlayers + If (GetPositionCountbyPlayerCount(I) = I) then + MaxPlayersperScreen := I + else + Break; + end; + + + //Split Players to both Screen or Display on One Screen + if (Screens = 2) and (MaxPlayersperScreen < PlayerCount) then + begin + PlC[0] := PlayerCount div 2 + PlayerCount mod 2; + PlC[1] := PlayerCount div 2; + end + else + begin + PlC[0] := PlayerCount; + PlC[1] := 0; + end; + + + //Check if there are enough Positions for all Players + For I := 0 to Screens - 1 do + begin + if (PlC[I] > MaxPlayersperScreen) then + begin + PlC[I] := MaxPlayersperScreen; + Log.LogError('More Players than available Positions, TSingScores'); + end; + end; + + CurPlayer := 0; + //Give every Player a Position + For I := 0 to Screens - 1 do + For J := 0 to PlC[I]-1 do + begin + aPlayers[CurPlayer].Position := GetPositionbyPlayernum(PlC[I], J) OR (I shl 7); + //Log.LogError('Player ' + InttoStr(CurPlayer) + ' gets Position: ' + InttoStr(aPlayers[CurPlayer].Position)); + Inc(CurPlayer); + end; +end; + +//----------- +//Procedure Draws Scores and Linebonus PopUps +//----------- +Procedure TSingScores.Draw; +var + I: Integer; + CurTime: Cardinal; + CurPopUp, LastPopUp: PScorePopUp; +begin + CurTime := SDL_GetTicks; + + If Visible then + begin + //Draw Popups + LastPopUp := nil; + CurPopUp := FirstPopUp; + + While (CurPopUp <> nil) do + begin + if (CurTime - CurPopUp.TimeStamp > Settings.Phase1Time + Settings.Phase2Time + Settings.Phase3Time) then + begin + KillPopUp(LastPopUp, CurPopUp); + if (LastPopUp = nil) then + CurPopUp := FirstPopUp + else + CurPopUp := LastPopUp.Next; + end + else + begin + DrawPopUp(CurPopUp); + LastPopUp := CurPopUp; + CurPopUp := LastPopUp.Next; + end; + end; + + + IF (RBVisible) then + //Draw Players w/ Rating Bar + For I := 0 to PlayerCount-1 do + begin + DrawScore(I); + DrawRatingBar(I); + end + else + //Draw Players w/o Rating Bar + For I := 0 to PlayerCount-1 do + begin + DrawScore(I); + end; + + end; //eo Visible +end; + +//----------- +//Procedure Draws a Popup by Pointer +//----------- +Procedure TSingScores.DrawPopUp(const PopUp: PScorePopUp); +var + Progress: Real; + CurTime: Cardinal; + X, Y, W, H, Alpha: Real; + FontSize: Byte; + TimeDiff: Cardinal; + PIndex: Byte; + TextLen: Real; + ScoretoAdd: Word; + PosDiff: Real; +begin + if (PopUp <> nil) then + begin + //Only Draw if Player has a Position + PIndex := Players[PopUp.Player].Position; + If PIndex <> high(byte) then + begin + //Only Draw if Player is on Cur Screen + If ((Players[PopUp.Player].Position AND 128) = 0) = (ScreenAct = 1) then + begin + CurTime := SDL_GetTicks; + If Not (Enabled AND Players[PopUp.Player].Enabled) then + //Increase Timestamp with TIem where there is no Movement ... + begin + //Inc(PopUp.TimeStamp, LastRender); + end; + TimeDiff := CurTime - PopUp.TimeStamp; + + //Get Position of PopUp + PIndex := PIndex AND 127; + + + //Check for Phase ... + If (TimeDiff <= Settings.Phase1Time) then + begin + //Phase 1 - The Ploping up + Progress := TimeDiff / Settings.Phase1Time; + + + W := Positions[PIndex].PUW * Sin(Progress/2*Pi); + H := Positions[PIndex].PUH * Sin(Progress/2*Pi); + + X := Positions[PIndex].PUStartX + (Positions[PIndex].PUW - W)/2; + Y := Positions[PIndex].PUStartY + (Positions[PIndex].PUH - H)/2; + + FontSize := Round(Progress * Positions[PIndex].PUFontSize); + Alpha := 1; + end + + Else If (TimeDiff <= Settings.Phase2Time + Settings.Phase1Time) then + begin + //Phase 2 - The Moving + Progress := (TimeDiff - Settings.Phase1Time) / Settings.Phase2Time; + + W := Positions[PIndex].PUW; + H := Positions[PIndex].PUH; + + PosDiff := Positions[PIndex].PUTargetX - Positions[PIndex].PUStartX; + If PosDiff > 0 then + PosDiff := PosDiff + W; + X := Positions[PIndex].PUStartX + PosDiff * sqr(Progress); + + PosDiff := Positions[PIndex].PUTargetY - Positions[PIndex].PUStartY; + If PosDiff < 0 then + PosDiff := PosDiff + Positions[PIndex].BGH; + Y := Positions[PIndex].PUStartY + PosDiff * sqr(Progress); + + FontSize := Positions[PIndex].PUFontSize; + Alpha := 1 - 0.3 * Progress; + end + + else + begin + //Phase 3 - The Fading out + Score adding + Progress := (TimeDiff - Settings.Phase1Time - Settings.Phase2Time) / Settings.Phase3Time; + + If (PopUp.Rating > 0) then + begin + //Add Scores if Player Enabled + If (Enabled AND Players[PopUp.Player].Enabled) then + begin + ScoreToAdd := Round(PopUp.ScoreDiff * Progress) - PopUp.ScoreGiven; + Inc(PopUp.ScoreGiven, ScoreToAdd); + aPlayers[PopUp.Player].ScoreDisplayed := Players[PopUp.Player].ScoreDisplayed + ScoreToAdd; + + //Change Bars Position + aPlayers[PopUp.Player].RBTarget := aPlayers[PopUp.Player].RBTarget + ScoreToAdd/PopUp.ScoreDiff * (PopUp.Rating / 20 - 0.26); + If (aPlayers[PopUp.Player].RBTarget > 1) then + aPlayers[PopUp.Player].RBTarget := 1 + else If (aPlayers[PopUp.Player].RBTarget < 0) then + aPlayers[PopUp.Player].RBTarget := 0; + end; + + //Set Positions etc. + Alpha := 0.7 - 0.7 * Progress; + + W := Positions[PIndex].PUW; + H := Positions[PIndex].PUH; + + PosDiff := Positions[PIndex].PUTargetX - Positions[PIndex].PUStartX; + If (PosDiff > 0) then + PosDiff := W + else + PosDiff := 0; + X := Positions[PIndex].PUTargetX + PosDiff * Progress; + + PosDiff := Positions[PIndex].PUTargetY - Positions[PIndex].PUStartY; + If (PosDiff < 0) then + PosDiff := -Positions[PIndex].BGH + else + PosDiff := 0; + Y := Positions[PIndex].PUTargetY - PosDiff * (1-Progress); + + FontSize := Positions[PIndex].PUFontSize; + end + else + begin + //Here the Effect that Should be shown if a PopUp without Score is Drawn + //And or Spawn with the GraphicObjects etc. + //Some Work for Blindy to do :P + + //ATM: Just Let it Slide in the Scores just like the Normal PopUp + Alpha := 0; + end; + end; + + //Draw PopUp + + if (Alpha > 0) AND (Players[PopUp.Player].Visible) then + begin + //Draw BG: + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glColor4f(1,1,1, Alpha); + glBindTexture(GL_TEXTURE_2D, Settings.PopUpTex[PopUp.Rating].TexNum); + + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(X, Y); + glTexCoord2f(0, Settings.PopUpTex[PopUp.Rating].TexH); glVertex2f(X, Y + H); + glTexCoord2f(Settings.PopUpTex[PopUp.Rating].TexW, Settings.PopUpTex[PopUp.Rating].TexH); glVertex2f(X + W, Y + H); + glTexCoord2f(Settings.PopUpTex[PopUp.Rating].TexW, 0); glVertex2f(X + W, Y); + glEnd; + + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + + //Set FontStyle and Size + SetFontStyle(Positions[PIndex].PUFont); + SetFontItalic(False); + SetFontSize(FontSize); + + //Draw Text + TextLen := glTextWidth(PChar(Theme.Sing.LineBonusText[PopUp.Rating])); + + //Color and Pos + SetFontPos (X + (W - TextLen) / 2, Y + 12); + glColor4f(1, 1, 1, Alpha); + + //Draw + glPrint(PChar(Theme.Sing.LineBonusText[PopUp.Rating])); + end; //eo Alpha check + end; //eo Right Screen + end; //eo Player has Position + end + else + Log.LogError('TSingScores: Try to Draw a not existing PopUp'); +end; + +//----------- +//Procedure Draws a Score by Playerindex +//----------- +Procedure TSingScores.DrawScore(const Index: Integer); +var + Position: PScorePosition; + ScoreStr: String; +begin + //Only Draw if Player has a Position + 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].Visible then + begin + Position := @Positions[Players[Index].Position and 127]; + + //Draw ScoreBG + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glColor4f(1,1,1, 1); + glBindTexture(GL_TEXTURE_2D, Players[Index].ScoreBG.TexNum); + + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Position.BGX, Position.BGY); + glTexCoord2f(0, Players[Index].ScoreBG.TexH); glVertex2f(Position.BGX, Position.BGY + Position.BGH); + glTexCoord2f(Players[Index].ScoreBG.TexW, Players[Index].ScoreBG.TexH); glVertex2f(Position.BGX + Position.BGW, Position.BGY + Position.BGH); + glTexCoord2f(Players[Index].ScoreBG.TexW, 0); glVertex2f(Position.BGX + Position.BGW, Position.BGY); + glEnd; + + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + + //Draw Score Text + SetFontStyle(Position.TextFont); + SetFontItalic(False); + SetFontSize(Position.TextSize); + SetFontPos(Position.TextX, Position.TextY); + + ScoreStr := InttoStr(Players[Index].ScoreDisplayed div 10) + '0'; + While (Length(ScoreStr) < 5) do + ScoreStr := '0' + ScoreStr; + + glPrint(PChar(ScoreStr)); + + end; //eo Right Screen + end; //eo Player has Position +end; + + +Procedure TSingScores.DrawRatingBar(const Index: Integer); +var + Position: PScorePosition; + R,G,B, Size: Real; + Diff: Real; +begin + //Only Draw if Player has a Position + 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 + begin + Position := @Positions[Players[Index].Position and 127]; + + If (Enabled AND Players[Index].Enabled) then + begin + //Move Position if Enabled + Diff := Players[Index].RBTarget - Players[Index].RBPos; + If(Abs(Diff) < 0.02) then + aPlayers[Index].RBPos := aPlayers[Index].RBTarget + else + aPlayers[Index].RBPos := aPlayers[Index].RBPos + Diff*0.1; + end; + + //Get Colors for RatingBar + If Players[index].RBPos <=0.22 then + begin + R := 1; + G := 0; + B := 0; + end + 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 + begin + R := 1; + G := 1; + B := 0; + end + Else If Players[index].RBPos <=0.77 then + begin + R := 1-(Players[index].RBPos-0.57)*5; + G := 1; + B := 0; + end + else + begin + R := 0; + G := 1; + B := 0; + end; + + //Enable all glFuncs Needed + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + //Draw RatingBar BG + glColor4f(1, 1, 1, 0.8); + glBindTexture(GL_TEXTURE_2D, Settings.RatingBar_BG_Tex.TexNum); + + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2f(Position.RBX, Position.RBY); + + glTexCoord2f(0, Settings.RatingBar_BG_Tex.TexH); + glVertex2f(Position.RBX, Position.RBY+Position.RBH); + + glTexCoord2f(Settings.RatingBar_BG_Tex.TexW, Settings.RatingBar_BG_Tex.TexH); + glVertex2f(Position.RBX+Position.RBW, Position.RBY+Position.RBH); + + glTexCoord2f(Settings.RatingBar_BG_Tex.TexW, 0); + glVertex2f(Position.RBX+Position.RBW, Position.RBY); + glEnd; + + //Draw Rating bar itself + Size := Position.RBX + Position.RBW * Players[Index].RBPos; + glColor4f(R, G, B, 1); + glBindTexture(GL_TEXTURE_2D, Settings.RatingBar_Bar_Tex.TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2f(Position.RBX, Position.RBY); + + glTexCoord2f(0, Settings.RatingBar_Bar_Tex.TexH); + glVertex2f(Position.RBX, Position.RBY + Position.RBH); + + glTexCoord2f(Settings.RatingBar_Bar_Tex.TexW, Settings.RatingBar_Bar_Tex.TexH); + glVertex2f(Size, Position.RBY + Position.RBH); + + glTexCoord2f(Settings.RatingBar_Bar_Tex.TexW, 0); + glVertex2f(Size, Position.RBY); + glEnd; + + //Draw Ratingbar FG (Teh thing with the 3 lines to get better readability) + glColor4f(1, 1, 1, 0.6); + glBindTexture(GL_TEXTURE_2D, Settings.RatingBar_FG_Tex.TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2f(Position.RBX, Position.RBY); + + glTexCoord2f(0, Settings.RatingBar_FG_Tex.TexH); + glVertex2f(Position.RBX, Position.RBY + Position.RBH); + + glTexCoord2f(Settings.RatingBar_FG_Tex.TexW, Settings.RatingBar_FG_Tex.TexH); + glVertex2f(Position.RBX + Position.RBW, Position.RBY + Position.RBH); + + glTexCoord2f(Settings.RatingBar_FG_Tex.TexW, 0); + glVertex2f(Position.RBX + Position.RBW, Position.RBY); + glEnd; + + //Disable all Enabled glFuncs + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + end; //eo Right Screen + end; //eo Player has Position +end; + +end. |