aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Lua/src/base/USingScores.pas103
-rw-r--r--Lua/src/base/USong.pas28
-rw-r--r--Lua/src/screens/UScreenSing.pas4
3 files changed, 125 insertions, 10 deletions
diff --git a/Lua/src/base/USingScores.pas b/Lua/src/base/USingScores.pas
index be0d4a58..56301539 100644
--- a/Lua/src/base/USingScores.pas
+++ b/Lua/src/base/USingScores.pas
@@ -138,9 +138,18 @@ type
FirstPopUp: PScorePopUp;
LastPopUp: PScorePopUp;
+ // only defined during draw, time passed between
+ // current and previous call of draw
+ TimePassed: Cardinal;
+
// draws a popup by pointer
procedure DrawPopUp(const PopUp: PScorePopUp);
+ // raises players score if RaiseScore was called
+ // has to be called after DrawPopUp and before
+ // DrawScore
+ procedure DoRaiseScore(const Index: integer);
+
// draws a score by playerindex
procedure DrawScore(const Index: integer);
@@ -149,6 +158,10 @@ type
// removes a popup w/o destroying the list
procedure KillPopUp(const last, cur: PScorePopUp);
+
+ // calculate the amount of points for a player that is
+ // still in popups and therfore not displayed
+ function GetPopUpPoints(const Index: integer): integer;
public
Settings: record // Record containing some Displaying Options
Phase1Time: real; // time for phase 1 to complete (in msecs)
@@ -202,6 +215,12 @@ type
// it gives every player a score position
procedure Init;
+ // raises the score of a specified player to the specified score
+ procedure RaiseScore(Player: byte; Score: integer);
+
+ // sets the score of a specified player to the specified score
+ procedure SetScore(Player: byte; Score: integer);
+
// spawns a new line bonus popup for the player
procedure SpawnPopUp(const PlayerIndex: byte; const Rating: integer; const Score: integer);
@@ -216,6 +235,7 @@ implementation
uses
SysUtils,
+ Math,
SDL,
TextGL,
ULog,
@@ -319,6 +339,7 @@ procedure TSingScores.ClearPlayers;
begin
KillAllPopUps;
oPlayerCount := 0;
+ TimePassed := 0;
end;
{**
@@ -329,6 +350,7 @@ begin
KillAllPopUps;
oPlayerCount := 0;
oPositionCount := 0;
+ TimePassed := 0;
end;
{**
@@ -401,6 +423,30 @@ begin
end;
{**
+ * raises the score of a specified player to the specified score
+ *}
+procedure TSingScores.RaiseScore(Player: byte; Score: integer);
+begin
+ if (Player <= PlayerCount - 1) then
+ aPlayers[Player].Score := Score;
+end;
+
+{**
+ * sets the score of a specified player to the specified score
+ *}
+procedure TSingScores.SetScore(Player: byte; Score: integer);
+ var
+ Diff: Integer;
+begin
+ if (Player <= PlayerCount - 1) then
+ begin
+ Diff := Score - Players[Player].Score;
+ aPlayers[Player].Score := Score;
+ Inc(aPlayers[Player].ScoreDisplayed, Diff);
+ end;
+end;
+
+{**
* spawns a new line bonus popup for the player
*}
procedure TSingScores.SpawnPopUp(const PlayerIndex: byte; const Rating: integer; const Score: integer);
@@ -516,6 +562,32 @@ begin
end;
{**
+ * calculate the amount of points for a player that is
+ * still in popups and therfore not displayed
+ *}
+function TSingScores.GetPopUpPoints(const Index: integer): integer;
+ var
+ CurPopUp: PScorePopUp;
+begin
+ Result := 0;
+
+ // only check points if there is a difference between actual
+ // and displayed points
+ if (Players[Index].Score > Players[Index].ScoreDisplayed) then
+ begin
+ CurPopUp := FirstPopUp;
+ while (CurPopUp <> nil) do
+ begin
+ if (CurPopUp.Player = Index) then
+ begin // add points left "in" popup to result
+ Inc(Result, CurPopUp.ScoreDiff - CurPopUp.ScoreGiven);
+ end;
+ CurPopUp := CurPopUp.Next;
+ end;
+ end;
+end;
+
+{**
* has to be called after positions and players have been added, before first call of draw
* it gives each player a score position
*}
@@ -617,6 +689,8 @@ var
CurPopUp, LastPopUp: PScorePopUp;
begin
CurTime := SDL_GetTicks;
+ if (TimePassed <> 0) then
+ TimePassed := CurTime - TimePassed;
if Visible then
begin
@@ -647,6 +721,7 @@ begin
// draw players w/ rating bar
for I := 0 to PlayerCount-1 do
begin
+ DoRaiseScore(I);
DrawScore(I);
DrawRatingBar(I);
end
@@ -654,10 +729,38 @@ begin
// draw players w/o rating bar
for I := 0 to PlayerCount-1 do
begin
+ DoRaiseScore(I);
DrawScore(I);
end;
end; // eo visible
+
+ TimePassed := CurTime;
+end;
+
+{**
+ * raises players score if RaiseScore was called
+ * has to be called after DrawPopUp and before
+ * DrawScore
+ *}
+procedure TSingScores.DoRaiseScore(const Index: integer);
+ var
+ S: integer;
+ Diff: integer;
+ const
+ RaisePerSecond = 500;
+begin
+ S := (Players[Index].Score - Players[Index].ScoreDisplayed) + GetPopUpPoints(Index);
+
+ if (S <> 0) then
+ begin
+ if (S > 0) then
+ Diff := Min(Round(RoundTo((RaisePerSecond * TimePassed) / 1000, 1)), S)
+ else
+ Diff := Max(Round(RoundTo((RaisePerSecond * TimePassed) / 1000, 1)), S);
+
+ Inc(aPlayers[Index].ScoreDisplayed, Diff);
+ end;
end;
{**
diff --git a/Lua/src/base/USong.pas b/Lua/src/base/USong.pas
index c465f198..fccf2757 100644
--- a/Lua/src/base/USong.pas
+++ b/Lua/src/base/USong.pas
@@ -96,7 +96,7 @@ type
function ParseLyricStringParam(const Line: RawByteString; var LinePos: integer): RawByteString;
function ParseLyricIntParam(const Line: RawByteString; var LinePos: integer): integer;
- function ParseLyricFloatParam(const Line: RawByteString; var LinePos: integer): real;
+ function ParseLyricFloatParam(const Line: RawByteString; var LinePos: integer): extended;
function ParseLyricCharParam(const Line: RawByteString; var LinePos: integer): AnsiChar;
function ParseLyricText(const Line: RawByteString; var LinePos: integer): RawByteString;
@@ -346,24 +346,26 @@ var
begin
OldLinePos := LinePos;
Str := ParseLyricStringParam(Line, LinePos);
- try
- Result := StrToInt(Str);
- except // on EConvertError
+
+ if not TryStrToInt(Str, Result) then
+ begin // on convert error
+ Result := 0;
LinePos := OldLinePos;
raise EUSDXParseException.Create('Integer expected');
end;
end;
-function TSong.ParseLyricFloatParam(const Line: RawByteString; var LinePos: integer): real;
+function TSong.ParseLyricFloatParam(const Line: RawByteString; var LinePos: integer): extended;
var
Str: RawByteString;
OldLinePos: integer;
begin
OldLinePos := LinePos;
Str := ParseLyricStringParam(Line, LinePos);
- try
- Result := StrToFloat(Str);
- except // on EConvertError
+
+ if not TryStrToFloat(Str, Result) then
+ begin // on convert error
+ Result := 0;
LinePos := OldLinePos;
raise EUSDXParseException.Create('Float expected');
end;
@@ -378,6 +380,14 @@ begin
Str := ParseLyricStringParam(Line, LinePos);
if (Length(Str) <> 1) then
begin
+ { to-do : decide what to do here
+ usdx < 1.1 does not nead a whitespace after a char param
+ so we may just write a warning to error.log and use the
+ first non whitespace character instead of raising an
+ exception that causes the song not to load. So the more
+ error resistant code is:
+ LinePos := OldLinePos + 1;
+ // raise EUSDXParseException.Create('Character expected'); }
LinePos := OldLinePos;
raise EUSDXParseException.Create('Character expected');
end;
@@ -483,7 +493,7 @@ begin
while true do
begin
- LinePos := 0;
+ LinePos := 1;
Param0 := ParseLyricCharParam(CurLine, LinePos);
if (Param0 = 'E') then
diff --git a/Lua/src/screens/UScreenSing.pas b/Lua/src/screens/UScreenSing.pas
index f907051c..18496517 100644
--- a/Lua/src/screens/UScreenSing.pas
+++ b/Lua/src/screens/UScreenSing.pas
@@ -1004,7 +1004,9 @@ begin
// spawn rating pop-up
Rating := Round(LinePerfection * MAX_LINE_RATING);
Scores.SpawnPopUp(PlayerIndex, Rating, CurrentPlayer.ScoreTotalInt);
- end;
+ end
+ else
+ Scores.RaiseScore(PlayerIndex, CurrentPlayer.ScoreTotalInt);
// PerfectLineTwinkle (effect), part 1
if (Ini.EffectSing = 1) then