From a48be5b4dd13db5cbc2cce4932508e61ff354340 Mon Sep 17 00:00:00 2001 From: mogguh Date: Wed, 21 Mar 2007 21:35:49 +0000 Subject: Golden notes are implemented from now on. So "golden notes" twinkle, and perfect sung notes twinkle too. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@12 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UDraw.pas | 22 +-- Game/Code/Classes/UGraphicClasses.pas | 266 ++++++++++++++++++++++++++++++++++ Game/Code/Screens/UScreenSing.pas | 8 +- Game/Code/UltraStar.dpr | 7 + 4 files changed, 293 insertions(+), 10 deletions(-) (limited to 'Game/Code') diff --git a/Game/Code/Classes/UDraw.pas b/Game/Code/Classes/UDraw.pas index e9433790..4e4691ad 100644 --- a/Game/Code/Classes/UDraw.pas +++ b/Game/Code/Classes/UDraw.pas @@ -1,7 +1,7 @@ unit UDraw; interface -uses UThemes, ModiSDK; +uses UThemes, ModiSDK, UGraphicClasses; procedure SingDraw; procedure SingModiDraw (PlayerInfo: TPlayerInfo); @@ -200,6 +200,8 @@ var Pet: integer; TempR: real; R,G,B: real; + + GoldenStarPos : real; begin glColor3f(1, 1, 1); glEnable(GL_TEXTURE_2D); @@ -214,11 +216,9 @@ begin // Golden Note Patch case Wartosc of 1: glColor4f(1, 1, 1, 0.85); - 2: glColor4f(1, 1, 0.3, 0.85); + 2: glColor4f(1, 1, 1, 0.85); // no stars, paint yellow -> glColor4f(1, 1, 0.3, 0.85); end; // case - - // lewa czesc - left part Rec.Left := (Start-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left + 0.5 + 10*ScreenX; Rec.Right := Rec.Left + NotesW; @@ -232,6 +232,11 @@ begin glTexCoord2f(7/8, 0); glVertex2f(Rec.Right, Rec.Top); glEnd; + //We keep the postion of the top left corner b4 it's overwritten + GoldenStarPos := Rec.Left; + //done + + // srodkowa czesc - middle part Rec.Left := Rec.Right; Rec.Right := (Start+Dlugosc-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left - NotesW - 0.5 + 10*ScreenX; @@ -256,12 +261,11 @@ begin glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); glEnd; - // Golden Star Patch - //case Wartosc of - // 2: SingGoldenStar(Rec.Left, Rec.Top, 1, StarfrG); - //end; // case - + if Wartosc = 2 then + begin + GoldenRec.SaveGoldenStarsRec(GoldenStarPos, Rec.Top, Rec.Right, Rec.Bottom); + end; end; // if not FreeStyle end; // with diff --git a/Game/Code/Classes/UGraphicClasses.pas b/Game/Code/Classes/UGraphicClasses.pas index abb59e4b..d66bd142 100644 --- a/Game/Code/Classes/UGraphicClasses.pas +++ b/Game/Code/Classes/UGraphicClasses.pas @@ -2,6 +2,272 @@ unit UGraphicClasses; interface +type + TParticle = Class + X, Y : Real; //Position + Frame : Byte; //act. Frame + Tex : Cardinal; //Tex num from Textur Manager + Live : Byte; //How many Cycles before Kill + RecIndex : Integer; //To which rectangle belongs this particle + + Constructor Create(cX,cY: Real; cTex: Cardinal; cLive: Byte; cFrame : integer; RecArrayIndex : Integer); + procedure Draw; + end; + + RectanglePositions = Record + xTop, yTop, xBottom, yBottom : Real; + TotalStarCount : Integer; + CurrentStarCount : Integer; + end; + + PerfectNotePositions = Record + xPos, yPos : Real; + end; + + TEffectManager = Class + Particle : array of TParticle; + LastTime : Cardinal; + RecArray : Array of RectanglePositions; + PerfNoteArray : Array of PerfectNotePositions; + + constructor Create; + procedure Draw; + function Spawn(X, Y: Real; Tex: Cardinal; Live: Byte; StartFrame : Integer; RecArrayIndex : Integer): Cardinal; + procedure SpawnRec(); + procedure Kill(index: Cardinal); + procedure KillAll(); + procedure SaveGoldenStarsRec(Xtop, Ytop, Xbottom, Ybottom: Real); + procedure SpawnNotePerfect(xPos,yPos : real); + procedure SavePerfectNotePos(Xtop, Ytop: Real); + end; + +var GoldenRec : TEffectManager; + implementation +uses sysutils, Windows,OpenGl12, UThemes, USkins, UGraphic, UDrawTexture, UTexture, math, dialogs; + +//TParticle +Constructor TParticle.Create(cX,cY: Real; cTex: Cardinal; cLive: Byte; cFrame : integer; RecArrayIndex : Integer); +begin + X := cX; + Y := cY; + Tex := cTex; + Live := cLive; + Frame:= cFrame; + RecIndex := RecArrayIndex; +end; + + +procedure TParticle.Draw; +var + W, H: real; + Alpha : real; +begin + W := 20; + H := 20; + + Alpha := (-cos((Frame+1)*2*pi/16)+1); //Fade Eyecandy + + glColor4f(0.99, 1, 0.6, Alpha); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, Tex_Note_Star.TexNum); + + begin + glBegin(GL_QUADS); + glTexCoord2f((1/16) * Frame, 0); glVertex2f(X-W, Y-H); + glTexCoord2f((1/16) * Frame + (1/16), 0); glVertex2f(X-W, Y+H); + glTexCoord2f((1/16) * Frame + (1/16), 1); glVertex2f(X+W, Y+H); + glTexCoord2f((1/16) * Frame, 1); glVertex2f(X+W, Y-H); + glEnd; + end; + glcolor4f(1,1,1,1); +end; + + + +constructor TEffectManager.Create; +begin + LastTime := GetTickCount; +end; + + +procedure TEffectManager.Draw; +var + I: Integer; + CurrentTime: Cardinal; +const + DelayBetweenFrames : Integer = 100; +begin + + CurrentTime := GetTickCount; + //Manage particle life + if (CurrentTime > (LastTime + DelayBetweenFrames)) then + begin + LastTime := CurrentTime; + for I := 0 to high(Particle) do + begin + Particle[I].Frame := (Particle[I].Frame + 1 ) mod 16; + //Live = 0 => Live forever + if (Particle[I].Live > 0) then + begin + Dec(Particle[I].Live); + end; + end; + end; + I := 0; + //Kill dead particles + while (I <= High(Particle)) do + begin + if (Particle[I].Live <= 0) then + begin + kill(I); + end + else + begin + inc(I); + end; + end; + + //Draw + for I := 0 to high(Particle) do + begin + Particle[I].Draw; + end; +end; + + +function TEffectManager.Spawn(X, Y: Real; Tex: Cardinal; Live: Byte; StartFrame : Integer; RecArrayIndex : Integer): Cardinal; +begin + Result := Length(Particle); + SetLength(Particle, (Result + 1)); + Particle[Result] := TParticle.Create(X, Y, Tex, Live, StartFrame, RecArrayIndex); +end; + + +procedure TEffectManager.SpawnRec(); +Var + Xkatze, Ykatze : Real; + RandomFrame : Integer; + P : Integer; // P as seen on TV as Positionman +begin +//Spawn a random amount of stars within the given coordinates +//RandomRange(0,14) <- this one starts at a random frame, 16 is our last frame - would be senseless to start a particle with 16, cause it would be dead at the next frame +for P:= 0 to high(RecArray) do + begin + while (RecArray[P].TotalStarCount > RecArray[P].CurrentStarCount) do + begin + Xkatze := RandomRange(Ceil(RecArray[P].xTop), Ceil(RecArray[P].xBottom)); + Ykatze := RandomRange(Ceil(RecArray[P].yTop), Ceil(RecArray[P].yBottom)); + RandomFrame := RandomRange(0,14); + Spawn(Xkatze, Ykatze, Tex_Note_Star.TexNum, 16 - RandomFrame, RandomFrame, P); + inc(RecArray[P].CurrentStarCount); + end; + end; + draw; +end; + + +procedure TEffectManager.SpawnNotePerfect(xPos,yPos : real); +Var + Xkatze, Ykatze : Real; + RandomFrame : Integer; + P : Integer; // P as seen on TV as Positionman +begin +//Spawn a random amount of stars within the given coordinates +//RandomRange(0,14) <- this one starts at a random frame, 16 is our last frame - would be senseless to start a particle with 16, cause it would be dead at the next frame +for P:= 0 to 2 do + begin + Xkatze := RandomRange(ceil(xPos) - 5 , ceil(xPos) + 10); + Ykatze := RandomRange(ceil(yPos) - 5 , ceil(yPos) + 10); + RandomFrame := RandomRange(0,14); + Spawn(Xkatze, Ykatze, Tex_Note_Star.TexNum, 16 - RandomFrame, RandomFrame, -1); + end; + draw; +end; + + +procedure TEffectManager.Kill(Index: Cardinal); +var + LastParticleIndex : Cardinal; +begin +// We put the last element of the array on the place where our element_to_delete resides and then we shorten the array - cool, hu? :P + +LastParticleIndex := high(Particle); +if not(LastParticleIndex = -1) then + begin + Try + Finally + if not(Particle[Index].RecIndex = -1) then + dec(RecArray[Particle[Index].RecIndex].CurrentStarCount); + Particle[Index].Destroy; + Particle[Index] := Particle[LastParticleIndex]; + SetLength(Particle, LastParticleIndex); + end; + end; +end; + +procedure TEffectManager.KillAll(); +begin +//It's the kill all kennies rotuine + while Length(Particle) > 0 do + Kill(0); + SetLength(RecArray,0); + SetLength(PerfNoteArray,0); +end; + +procedure TEffectManager.SaveGoldenStarsRec(Xtop, Ytop, Xbottom, Ybottom: Real); +var + P : Integer; // P like used in Positions + NewIndex : Integer; +begin + For P := 0 to high(RecArray) do // Do we already have that "new" position? + begin + if ((ceil(RecArray[P].xTop) = ceil(Xtop)) and (ceil(RecArray[P].yTop) = ceil(Ytop))) then + exit; // it's already in the array, so we don't have to create a new one + end; + +// we got a new position, add the new positions to our array + NewIndex := Length(RecArray); + SetLength(RecArray, NewIndex + 1); + RecArray[NewIndex].xTop := Xtop; + RecArray[NewIndex].yTop := Ytop; + RecArray[NewIndex].xBottom := Xbottom; + RecArray[NewIndex].yBottom := Ybottom; + RecArray[NewIndex].TotalStarCount := ceil(Xbottom - Xtop) div 12 + 3; + RecArray[NewIndex].CurrentStarCount := 0; +end; + +procedure TEffectManager.SavePerfectNotePos(Xtop, Ytop: Real); +var + P : Integer; // P like used in Positions + NewIndex : Integer; + + RandomFrame : Integer; + Xkatze, Ykatze : Integer; +begin + For P := 0 to high(PerfNoteArray) do // Do we already have that "new" position? + begin + if ((ceil(PerfNoteArray[P].xPos) = ceil(Xtop)) and (ceil(PerfNoteArray[P].yPos) = ceil(Ytop))) then + exit; // it's already in the array, so we don't have to create a new one + end; + +// we got a new position, add the new positions to our array + NewIndex := Length(PerfNoteArray); + SetLength(PerfNoteArray, NewIndex + 1); + PerfNoteArray[NewIndex].xPos := Xtop; + PerfNoteArray[NewIndex].yPos := Ytop; + + for P:= 0 to 2 do + begin + Xkatze := RandomRange(ceil(Xtop) - 5 , ceil(Xtop) + 10); + Ykatze := RandomRange(ceil(Ytop) - 5 , ceil(Ytop) + 10); + RandomFrame := RandomRange(0,14); + Spawn(Xkatze, Ykatze, Tex_Note_Star.TexNum, 16 - RandomFrame, RandomFrame, -1); + end; + +end; end. + diff --git a/Game/Code/Screens/UScreenSing.pas b/Game/Code/Screens/UScreenSing.pas index 2a97482d..3dd1119a 100644 --- a/Game/Code/Screens/UScreenSing.pas +++ b/Game/Code/Screens/UScreenSing.pas @@ -3,7 +3,7 @@ unit UScreenSing; interface uses UMenu, UMusic, SDL, SysUtils, UPliki, UTime, USongs, UIni, ULog, USmpeg, UTexture, ULyrics, - TextGL, OpenGL12, BASS, UThemes, ULCD; + TextGL, OpenGL12, BASS, UThemes, ULCD, UGraphicClasses; type TScreenSing = class(TMenu) @@ -973,6 +973,9 @@ begin // draw custom items SingDraw; // always draw +//GoldenNoteStarsTwinkle Mod + GoldenRec.SpawnRec; +//GoldenNoteStarsTwinkle Mod // back stereo Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10*ScreenX; @@ -1116,6 +1119,9 @@ Player[I].ScoreLast := Player[I].Score + Player[I].ScoreGolden; end; //PhrasenBonus - Line Bonus Mod End// } +//GoldenStarsTwinkle Mod + GoldenRec.KillAll; +//GoldenStarsTwinkle Mod End end; end. diff --git a/Game/Code/UltraStar.dpr b/Game/Code/UltraStar.dpr index 5c598eda..b0d49610 100644 --- a/Game/Code/UltraStar.dpr +++ b/Game/Code/UltraStar.dpr @@ -258,6 +258,13 @@ begin Log.BenchmarkEnd(1); Log.LogBenchmark('Loading Score DB System', 1); + //GoldenStarsTwinkleMod + Log.BenchmarkStart(1); + Log.LogStatus('GoldenStars', 'Initialization'); + GoldenRec := TEffectManager.Create; + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading GoldenStars', 1); + // Joypad if Ini.Joypad = 1 then begin Log.BenchmarkStart(1); -- cgit v1.2.3