unit USingScores;
interface
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
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
Log.LogError('Spawn PopUp: Score: ' + InttoStr(Score));
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 !
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( '' );
lTempA := ( aPlayers[Cur.Player].RBTarget + (Cur.ScoreDiff - Cur.ScoreGiven) );
lTempB := ( Cur.ScoreDiff * (Cur.Rating / 20 - 0.26) );
writeln( 'USINGSCORES-lTempA : ' + floattostr( lTempA ) );
writeln( 'USINGSCORES-lTempB : ' + floattostr( lTempB ) );
writeln( '----------------------------------------------------------' );
if ( lTempA > 0 ) AND
( lTempB > 0 ) THEN
begin
writeln( 'USINGSCORES-lTempA / lTempB :' + floattostr( lTempA / lTempB ) );
aPlayers[Cur.Player].RBTarget := lTempA / lTempB;
end;
writeln( '----------------------------------------------------------' );
writeln( '' );
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.