aboutsummaryrefslogtreecommitdiffstats
path: root/unicode/src/base
diff options
context:
space:
mode:
Diffstat (limited to 'unicode/src/base')
-rw-r--r--unicode/src/base/TextGL.pas7
-rw-r--r--unicode/src/base/UCatCovers.pas3
-rw-r--r--unicode/src/base/UCore.pas190
-rw-r--r--unicode/src/base/UDraw.pas660
-rw-r--r--unicode/src/base/UEditorLyrics.pas129
-rw-r--r--unicode/src/base/UFiles.pas5
-rw-r--r--unicode/src/base/UGraphic.pas21
-rw-r--r--unicode/src/base/UGraphicClasses.pas14
-rw-r--r--unicode/src/base/UHooks.pas55
-rw-r--r--unicode/src/base/UImage.pas234
-rw-r--r--unicode/src/base/UIni.pas179
-rw-r--r--unicode/src/base/ULanguage.pas3
-rw-r--r--unicode/src/base/ULog.pas3
-rw-r--r--unicode/src/base/UMain.pas783
-rw-r--r--unicode/src/base/UMusic.pas36
-rw-r--r--unicode/src/base/UNote.pas593
-rw-r--r--unicode/src/base/UParty.pas445
-rw-r--r--unicode/src/base/UPath.pas188
-rw-r--r--unicode/src/base/UPlatformMacOSX.pas99
-rw-r--r--unicode/src/base/UPlaylist.pas3
-rw-r--r--unicode/src/base/UPluginLoader.pas140
-rw-r--r--unicode/src/base/URecord.pas135
-rw-r--r--unicode/src/base/URingBuffer.pas24
-rw-r--r--unicode/src/base/USkins.pas87
-rw-r--r--unicode/src/base/USong.pas307
-rw-r--r--unicode/src/base/USongs.pas18
-rw-r--r--unicode/src/base/UTexture.pas48
-rw-r--r--unicode/src/base/UThemes.pas29
28 files changed, 2371 insertions, 2067 deletions
diff --git a/unicode/src/base/TextGL.pas b/unicode/src/base/TextGL.pas
index 28c3c6b6..667a224f 100644
--- a/unicode/src/base/TextGL.pas
+++ b/unicode/src/base/TextGL.pas
@@ -68,11 +68,12 @@ procedure SetFontReflection(Enable:boolean;Spacing: real); // enables/disables t
implementation
uses
- UMain,
- UCommon,
UTextEncoding,
SysUtils,
- IniFiles;
+ IniFiles,
+ UCommon,
+ UMain,
+ UPath;
function FindFontFile(FontIni: TCustomIniFile; Font: string): string;
var
diff --git a/unicode/src/base/UCatCovers.pas b/unicode/src/base/UCatCovers.pas
index 4fc54199..6ef81b68 100644
--- a/unicode/src/base/UCatCovers.pas
+++ b/unicode/src/base/UCatCovers.pas
@@ -64,8 +64,9 @@ uses
SysUtils,
Classes,
// UFiles,
+ ULog,
UMain,
- ULog;
+ UPath;
constructor TCatCovers.Create;
begin
diff --git a/unicode/src/base/UCore.pas b/unicode/src/base/UCore.pas
index 901f2f96..a7f9e56e 100644
--- a/unicode/src/base/UCore.pas
+++ b/unicode/src/base/UCore.pas
@@ -42,20 +42,20 @@ uses
{*********************
TCore
- Class manages all CoreModules, teh StartUp, teh MainLoop and the shutdown process
- Also it does some Error Handling, and maybe sometime multithreaded Loading ;)
+ Class manages all CoreModules, the StartUp, the MainLoop and the shutdown process
+ Also, it does some error handling, and maybe sometime multithreaded loading ;)
*********************}
type
TModuleListItem = record
- Module: TCoreModule; //Instance of the Modules Class
- Info: TModuleInfo; //ModuleInfo returned by Modules Modulinfo Proc
- NeedsDeInit: Boolean; //True if Module was succesful inited
+ Module: TCoreModule; // Instance of the modules class
+ Info: TModuleInfo; // ModuleInfo returned by modules modulinfo proc
+ NeedsDeInit: boolean; // True if module was succesful inited
end;
TCore = class
private
- //Some Hook Handles. See Plugin SDKs Hooks.txt for Infos
+ // Some Hook Handles. See Plugin SDKs Hooks.txt for Infos
hLoadingFinished: THandle;
hMainLoop: THandle;
hTranslate: THandle;
@@ -72,71 +72,71 @@ type
sGetModuleInfo: THandle;
sGetApplicationHandle: THandle;
- Modules: Array [0..High(CORE_MODULES_TO_LOAD)] of TModuleListItem;
+ Modules: array [0..High(CORE_MODULES_TO_LOAD)] of TModuleListItem;
- //Cur + Last Executed Setting and Getting ;)
- iCurExecuted: Integer;
- iLastExecuted: Integer;
+ // Cur + Last Executed Setting and Getting ;)
+ iCurExecuted: integer;
+ iLastExecuted: integer;
- procedure SetCurExecuted(Value: Integer);
+ procedure SetCurExecuted(Value: integer);
- //Function Get all Modules and Creates them
- function GetModules: Boolean;
+ // Function Get all Modules and Creates them
+ function GetModules: boolean;
- //Loads Core and all Modules
- function Load: Boolean;
+ // Loads Core and all Modules
+ function Load: boolean;
- //Inits Core and all Modules
- function Init: Boolean;
+ // Inits Core and all Modules
+ function Init: boolean;
- //DeInits Core and all Modules
- function DeInit: Boolean;
+ // DeInits Core and all Modules
+ function DeInit: boolean;
- //Load the Core
- function LoadCore: Boolean;
+ // Load the Core
+ function LoadCore: boolean;
- //Init the Core
- function InitCore: Boolean;
+ // Init the Core
+ function InitCore: boolean;
- //DeInit the Core
- function DeInitCore: Boolean;
+ // DeInit the Core
+ function DeInitCore: boolean;
- //Called one Time per Frame
- function MainLoop: Boolean;
+ // Called one time per frame
+ function MainLoop: boolean;
public
- Hooks: THookManager; //Teh Hook Manager ;)
- Services: TServiceManager;//The Service Manager
+ Hooks: THookManager; // The Hook Manager ;)
+ Services: TServiceManager; // The Service Manager
- Name: String; //Name of this Application
- Version: LongWord; //Version of this ". For Info Look PluginDefs Functions
+ Name: string; // Name of this application
+ Version: LongWord; // Version of this ". For info look plugindefs functions
- LastErrorReporter:String; //Who Reported the Last Error String
- LastErrorString: String; //Last Error String reported
+ LastErrorReporter: string; // Who reported the last error string
+ LastErrorString: string; // Last error string reported
- property CurExecuted: Integer read iCurExecuted write SetCurExecuted; //ID of Plugin or Module curently Executed
- property LastExecuted: Integer read iLastExecuted;
+ property CurExecuted: integer read iCurExecuted write SetCurExecuted; //ID of plugin or module curently executed
+ property LastExecuted: integer read iLastExecuted;
//---------------
- //Main Methods to control the Core:
+ // Main methods to control the core:
//---------------
- constructor Create(const cName: String; const cVersion: LongWord);
+ constructor Create(const cName: string; const cVersion: LongWord);
- //Starts Loading and Init Process. Then Runs MainLoop. DeInits on Shutdown
+ // Starts loading and init process. Then runs MainLoop. DeInits on shutdown
procedure Run;
- //Method for other Classes to get Pointer to a specific Module
- function GetModulebyName(const Name: String): PCoreModule;
+ // Method for other classes to get pointer to a specific module
+ function GetModulebyName(const Name: string): PCoreModule;
//--------------
- // Hook and Service Procs:
+ // Hook and service procs:
//--------------
function ShowMessage(wParam: TwParam; lParam: TlParam): integer; //Shows a Message (lParam: PChar Text, wParam: Symbol)
function ReportError(wParam: TwParam; lParam: TlParam): integer; //Shows a Message (wParam: Pchar(Message), lParam: PChar(Reportername))
function ReportDebug(wParam: TwParam; lParam: TlParam): integer; //Shows a Message (wParam: Pchar(Message), lParam: PChar(Reportername))
function Retranslate(wParam: TwParam; lParam: TlParam): integer; //Calls Translate hook
function ReloadTextures(wParam: TwParam; lParam: TlParam): integer; //Calls LoadTextures hook
- function GetModuleInfo(wParam: TwParam; lParam: TlParam): integer; //If lParam = nil then get length of Moduleinfo Array. If lparam <> nil then write array of TModuleInfo to address at lparam
+ function GetModuleInfo(wParam: TwParam; lParam: TlParam): integer; //If lParam = nil then get length of Moduleinfo array. If lparam <> nil then write array of TModuleInfo to address at lparam
function GetApplicationHandle(wParam: TwParam; lParam: TlParam): integer; //Returns Application Handle
end;
@@ -154,7 +154,7 @@ uses
//-------------
// Create - Creates Class + Hook and Service Manager
//-------------
-constructor TCore.Create(const cName: String; const cVersion: LongWord);
+constructor TCore.Create(const cName: string; const cVersion: LongWord);
begin
inherited Create;
@@ -171,11 +171,11 @@ begin
end;
//-------------
-//Starts Loading and Init Process. Then Runs MainLoop. DeInits on Shutdown
+// Starts Loading and Init process. Then runs MainLoop. DeInits on shutdown
//-------------
procedure TCore.Run;
var
- Success: Boolean;
+ Success: boolean;
procedure HandleError(const ErrorMsg: string);
begin
@@ -184,16 +184,16 @@ var
else
Self.ShowMessage(CORE_SM_ERROR, PChar(ErrorMsg));
- //DeInit
+ // DeInit
DeInit;
end;
begin
- //Get Modules
+ // Get modules
try
Success := GetModules();
except
- Success := False;
+ Success := false;
end;
if (not Success) then
@@ -202,11 +202,11 @@ begin
Exit;
end;
- //Loading
+ // Loading
try
Success := Load();
except
- Success := False;
+ Success := false;
end;
if (not Success) then
@@ -215,11 +215,11 @@ begin
Exit;
end;
- //Init
+ // Init
try
Success := Init();
except
- Success := False;
+ Success := false;
end;
if (not Success) then
@@ -228,28 +228,28 @@ begin
Exit;
end;
- //Call Translate Hook
+ // Call Translate Hook
if (Hooks.CallEventChain(hTranslate, 0, nil) <> 0) then
begin
HandleError('Error translating');
Exit;
end;
- //Calls LoadTextures Hook
+ // Calls LoadTextures Hook
if (Hooks.CallEventChain(hLoadTextures, 0, nil) <> 0) then
begin
HandleError('Error loading textures');
Exit;
end;
- //Calls Loading Finished Hook
+ // Calls Loading Finished Hook
if (Hooks.CallEventChain(hLoadingFinished, 0, nil) <> 0) then
begin
HandleError('Error calling LoadingFinished Hook');
Exit;
end;
- //Start MainLoop
+ // Start MainLoop
while Success do
begin
Success := MainLoop();
@@ -258,41 +258,41 @@ begin
end;
//-------------
-//Called one Time per Frame
+// Called one time per frame
//-------------
-function TCore.MainLoop: Boolean;
+function TCore.MainLoop: boolean;
begin
- Result := False;
+ Result := false;
end;
//-------------
-//Function Get all Modules and Creates them
+// Function get all modules and creates them
//-------------
-function TCore.GetModules: Boolean;
+function TCore.GetModules: boolean;
var
- i: Integer;
+ i: integer;
begin
- Result := False;
+ Result := false;
for i := 0 to high(Modules) do
begin
try
- Modules[i].NeedsDeInit := False;
+ Modules[i].NeedsDeInit := false;
Modules[i].Module := CORE_MODULES_TO_LOAD[i].Create;
Modules[i].Module.Info(@Modules[i].Info);
except
- ReportError(Integer(PChar('Can''t get module #' + InttoStr(i) + ' "' + Modules[i].Info.Name + '"')), PChar('Core'));
+ ReportError(integer(PChar('Can''t get module #' + InttoStr(i) + ' "' + Modules[i].Info.Name + '"')), PChar('Core'));
Exit;
end;
end;
- Result := True;
+ Result := true;
end;
//-------------
-//Loads Core and all Modules
+// Loads core and all modules
//-------------
-function TCore.Load: Boolean;
+function TCore.Load: boolean;
var
- i: Integer;
+ i: integer;
begin
Result := LoadCore;
@@ -301,23 +301,23 @@ begin
try
Result := Modules[i].Module.Load;
except
- Result := False;
+ Result := false;
end;
if (not Result) then
begin
- ReportError(Integer(PChar('Error loading module #' + InttoStr(i) + ' "' + Modules[i].Info.Name + '"')), PChar('Core'));
+ ReportError(integer(PChar('Error loading module #' + InttoStr(i) + ' "' + Modules[i].Info.Name + '"')), PChar('Core'));
break;
end;
end;
end;
//-------------
-//Inits Core and all Modules
+// Inits core and all modules
//-------------
-function TCore.Init: Boolean;
+function TCore.Init: boolean;
var
- i: Integer;
+ i: integer;
begin
Result := InitCore;
@@ -326,12 +326,12 @@ begin
try
Result := Modules[i].Module.Init;
except
- Result := False;
+ Result := false;
end;
if (not Result) then
begin
- ReportError(Integer(PChar('Error initing module #' + InttoStr(i) + ' "' + Modules[i].Info.Name + '"')), PChar('Core'));
+ ReportError(integer(PChar('Error initing module #' + InttoStr(i) + ' "' + Modules[i].Info.Name + '"')), PChar('Core'));
break;
end;
@@ -340,7 +340,7 @@ begin
end;
//-------------
-//DeInits Core and all Modules
+// DeInits core and all modules
//-------------
function TCore.DeInit: boolean;
var
@@ -362,9 +362,9 @@ begin
end;
//-------------
-//Load the Core
+// Load the Core
//-------------
-function TCore.LoadCore: Boolean;
+function TCore.LoadCore: boolean;
begin
hLoadingFinished := Hooks.AddEvent('Core/LoadingFinished');
hMainLoop := Hooks.AddEvent('Core/MainLoop');
@@ -383,35 +383,35 @@ begin
sGetModuleInfo := Services.AddService('Core/GetModuleInfo', nil, Self.GetModuleInfo);
sGetApplicationHandle := Services.AddService('Core/GetApplicationHandle', nil, Self.GetApplicationHandle);
- //A little Test
+ // A little Test
Hooks.AddSubscriber('Core/NewError', HookTest);
result := true;
end;
//-------------
-//Init the Core
+// Init the Core
//-------------
-function TCore.InitCore: Boolean;
+function TCore.InitCore: boolean;
begin
//Don not init something atm.
result := true;
end;
//-------------
-//DeInit the Core
+// DeInit the Core
//-------------
-function TCore.DeInitCore: Boolean;
+function TCore.DeInitCore: boolean;
begin
- // TODO: write TService-/HookManager.Free and call it here
+ // TODO: write TService-/HookManager. Free and call it here
Result := true;
end;
//-------------
-//Method for other classes to get pointer to a specific module
+// Method for other classes to get pointer to a specific module
//-------------
-function TCore.GetModuleByName(const Name: String): PCoreModule;
-var i: Integer;
+function TCore.GetModuleByName(const Name: string): PCoreModule;
+var i: integer;
begin
Result := nil;
for i := 0 to High(Modules) do
@@ -444,7 +444,7 @@ begin
CORE_SM_INFO: Params := Params or MB_ICONINFORMATION;
end;
- //Show:
+ // Show:
Result := Messagebox(0, lParam, PChar(Name), Params);
end;
{$ENDIF}
@@ -458,8 +458,8 @@ end;
function TCore.ReportError(wParam: TwParam; lParam: TlParam): integer;
begin
//Update LastErrorReporter and LastErrorString
- LastErrorReporter := String(PChar(lParam));
- LastErrorString := String(PChar(Pointer(wParam)));
+ LastErrorReporter := string(PChar(lParam));
+ LastErrorString := string(PChar(Pointer(wParam)));
Hooks.CallEventChain(hError, wParam, lParam);
@@ -501,7 +501,7 @@ begin
end;
//-------------
-// If lParam = nil then get length of Moduleinfo Array. If lparam <> nil then write array of TModuleInfo to address at lparam
+// If lParam = nil then get length of Moduleinfo array. If lparam <> nil then write array of TModuleInfo to address at lparam
//-------------
function TCore.GetModuleInfo(wParam: TwParam; lParam: TlParam): integer;
var
@@ -538,12 +538,12 @@ end;
//-------------
// Called when setting CurExecuted
//-------------
-procedure TCore.SetCurExecuted(Value: Integer);
+procedure TCore.SetCurExecuted(Value: integer);
begin
- //Set Last Executed
+ // Set Last Executed
iLastExecuted := iCurExecuted;
- //Set Cur Executed
+ // Set Cur Executed
iCurExecuted := Value;
end;
diff --git a/unicode/src/base/UDraw.pas b/unicode/src/base/UDraw.pas
index d3f19019..8a66d271 100644
--- a/unicode/src/base/UDraw.pas
+++ b/unicode/src/base/UDraw.pas
@@ -55,7 +55,6 @@ procedure SingDrawTimeBar();
//Draw Editor NoteLines
procedure EditDrawLine(Left, Top, Right: real; NrLines: integer; Space: integer);
-
type
TRecR = record
Top: real;
@@ -67,7 +66,6 @@ type
WMid: real;
Height: real;
HMid: real;
-
Mid: real;
end;
@@ -75,51 +73,45 @@ var
NotesW: real;
NotesH: real;
Starfr: integer;
- StarfrG: integer;
+ StarfrG: integer;
//SingBar
- TickOld: cardinal;
- TickOld2:cardinal;
-
-const
- Przedz = 32;
+ TickOld: cardinal;
+ TickOld2: cardinal;
implementation
uses
+ SysUtils,
+ Math,
gl,
+ TextGL,
+ UDLLManager,
+ UDrawTexture,
UGraphic,
- SysUtils,
+ UIni,
+ ULog,
+ ULyrics,
+ UNote,
UMusic,
URecord,
- ULog,
UScreenSing,
UScreenSingModi,
- ULyrics,
- UMain,
- TextGL,
- UTexture,
- UDrawTexture,
- UIni,
- Math,
- UDLLManager;
+ UTexture;
procedure SingDrawBackground;
var
- Rec: TRecR;
- TexRec: TRecR;
+ Rec: TRecR;
+ TexRec: TRecR;
begin
- if (ScreenSing.Tex_Background.TexNum > 0) then begin
-
- glClearColor (1, 1, 1, 1);
- glColor4f (1, 1, 1, 1);
-
+ if (ScreenSing.Tex_Background.TexNum > 0) then
+ begin
if (Ini.MovieSize <= 1) then //HalfSize BG
begin
(* half screen + gradient *)
Rec.Top := 110; // 80
Rec.Bottom := Rec.Top + 20;
- Rec.Left := 0;
+ Rec.Left := 0;
Rec.Right := 800;
TexRec.Top := (Rec.Top / 600) * ScreenSing.Tex_Background.TexH;
@@ -185,16 +177,17 @@ end;
procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer);
var
SampleIndex: integer;
- Sound: TCaptureBuffer;
- MaxX, MaxY: real;
+ Sound: TCaptureBuffer;
+ MaxX, MaxY: real;
begin;
Sound := AudioInputProcessor.Sound[NrSound];
// Log.LogStatus('Oscilloscope', 'SingDraw');
glColor3f(Skin_OscR, Skin_OscG, Skin_OscB);
- {if (ParamStr(1) = '-black') or (ParamStr(1) = '-fsblack') then
- glColor3f(1, 1, 1); }
-
+{
+ if (ParamStr(1) = '-black') or (ParamStr(1) = '-fsblack') then
+ glColor3f(1, 1, 1);
+}
MaxX := W-1;
MaxY := (H-1) / 2;
@@ -211,16 +204,15 @@ begin;
Sound.UnlockAnalysisBuffer();
end;
-
-
procedure SingDrawNoteLines(Left, Top, Right: real; Space: integer);
var
- Count: integer;
+ Count: integer;
begin
glEnable(GL_BLEND);
glColor4f(Skin_P1_LinesR, Skin_P1_LinesG, Skin_P1_LinesB, 0.4);
glBegin(GL_LINES);
- for Count := 0 to 9 do begin
+ for Count := 0 to 9 do
+ begin
glVertex2f(Left, Top + Count * Space);
glVertex2f(Right, Top + Count * Space);
end;
@@ -230,13 +222,14 @@ end;
procedure SingDrawBeatDelimeters(Left, Top, Right: real; NrLines: integer);
var
- Count: integer;
- TempR: real;
+ Count: integer;
+ TempR: real;
begin
TempR := (Right-Left) / (Lines[NrLines].Line[Lines[NrLines].Current].End_ - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start);
glEnable(GL_BLEND);
glBegin(GL_LINES);
- for Count := Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start to Lines[NrLines].Line[Lines[NrLines].Current].End_ do begin
+ for Count := Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start to Lines[NrLines].Line[Lines[NrLines].Current].End_ do
+ begin
if (Count mod Lines[NrLines].Resolution) = Lines[NrLines].NotesGAP then
glColor4f(0, 0, 0, 1)
else
@@ -251,18 +244,17 @@ end;
// draw blank Notebars
procedure SingDrawLine(Left, Top, Right: real; NrLines: integer; Space: integer);
var
- Rec: TRecR;
- Count: integer;
- TempR: real;
+ Rec: TRecR;
+ Count: integer;
+ TempR: real;
- PlayerNumber: Integer;
+ PlayerNumber: integer;
- GoldenStarPos : real;
-
- lTmpA ,
- lTmpB : real;
+ GoldenStarPos: real;
+
+ lTmpA, lTmpB : real;
begin
-// We actually don't have a playernumber in this procedure, it should reside in NrLines - but it's always set to zero
+// We actually don't have a playernumber in this procedure, it should reside in NrLines - but it is always set to zero
// So we exploit this behavior a bit - we give NrLines the playernumber, keep it in playernumber - and then we set NrLines to zero
// This could also come quite in handy when we do the duet mode, cause just the notes for the player that has to sing should be drawn then
// BUT this is not implemented yet, all notes are drawn! :D
@@ -280,23 +272,19 @@ begin
lTmpA := (Right-Left);
lTmpB := (Lines[NrLines].Line[Lines[NrLines].Current].End_ - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start);
- if ( lTmpA > 0 ) AND
- ( lTmpB > 0 ) THEN
- begin
- TempR := lTmpA / lTmpB;
- end
+ if ( lTmpA > 0 ) and ( lTmpB > 0 ) then
+ TempR := lTmpA / lTmpB
else
- begin
TempR := 0;
- end;
-
-
- with Lines[NrLines].Line[Lines[NrLines].Current] do begin
- for Count := 0 to HighNote do begin
- with Note[Count] do begin
- if NoteType <> ntFreestyle then begin
-
+ with Lines[NrLines].Line[Lines[NrLines].Current] do
+ begin
+ for Count := 0 to HighNote do
+ begin
+ with Note[Count] do
+ begin
+ if NoteType <> ntFreestyle then
+ begin
if Ini.EffectSing = 0 then
// If Golden note Effect of then Change not Color
begin
@@ -307,9 +295,9 @@ begin
end //Else all Notes same Color
else
glColor4f(1, 1, 1, 1); // We set alpha to 1, cause we can control the transparency through the png itself
- // Czesci == teil, element == piece, element | koniec == end / ending
- // lewa czesc - left part
- Rec.Left := (Start-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left + 0.5 + 10*ScreenX;
+
+ // left part
+ Rec.Left := (Start-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left + 0.5 + 10*ScreenX;
Rec.Right := Rec.Left + NotesW;
Rec.Top := Top - (Tone-BaseNote)*Space/2 - NotesH;
Rec.Bottom := Rec.Top + 2 * NotesH;
@@ -326,8 +314,8 @@ begin
//done
// middle part
- Rec.Left := Rec.Right;
- Rec.Right := (Start+Length-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left - NotesW - 0.5 + 10*ScreenX; // Dlugosc == length
+ Rec.Left := Rec.Right;
+ Rec.Right := (Start+Length-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left - NotesW - 0.5 + 10*ScreenX;
glBindTexture(GL_TEXTURE_2D, Tex_plain_Mid[PlayerNumber].TexNum);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
@@ -340,7 +328,7 @@ begin
glEnd;
// right part
- Rec.Left := Rec.Right;
+ Rec.Left := Rec.Right;
Rec.Right := Rec.Right + NotesW;
glBindTexture(GL_TEXTURE_2D, Tex_plain_Right[PlayerNumber].TexNum);
@@ -352,7 +340,7 @@ begin
glEnd;
// Golden Star Patch
- if (NoteType = ntGolden) AND (Ini.EffectSing=1) then
+ if (NoteType = ntGolden) and (Ini.EffectSing=1) then
begin
GoldenRec.SaveGoldenStarsRec(GoldenStarPos, Rec.Top, Rec.Right, Rec.Bottom);
end;
@@ -366,22 +354,23 @@ begin
glDisable(GL_TEXTURE_2D);
end;
-
// draw sung notes
procedure SingDrawPlayerLine(X, Y, W: real; PlayerIndex: integer; Space: integer);
var
TempR: real;
Rec: TRecR;
N: integer;
- //R, G, B, A: real;
+// R, G, B, A: real;
NotesH2: real;
begin
//Log.LogStatus('Player notes', 'SingDraw');
-
- //if NrGracza = 0 then LoadColor(R, G, B, 'P1Light')
- //else LoadColor(R, G, B, 'P2Light');
-
- //R := 71/255;
+{
+ if NrGracza = 0 then
+ LoadColor(R, G, B, 'P1Light')
+ else
+ LoadColor(R, G, B, 'P2Light');
+}
+ //R := 71/255;
//G := 175/255;
//B := 247/255;
@@ -398,7 +387,7 @@ begin
with Player[PlayerIndex].Note[N] do
begin
// Left part of note
- Rec.Left := X + (Start-Lines[0].Line[Lines[0].Current].Note[0].Start) * TempR + 0.5 + 10*ScreenX;
+ Rec.Left := X + (Start-Lines[0].Line[Lines[0].Current].Note[0].Start) * TempR + 0.5 + 10*ScreenX;
Rec.Right := Rec.Left + NotesW;
// Draw it in half size, if not hit
@@ -412,7 +401,7 @@ begin
end;
Rec.Top := Y - (Tone-Lines[0].Line[Lines[0].Current].BaseNote)*Space/2 - NotesH2;
- Rec.Bottom := Rec.Top + 2 *NotesH2;
+ Rec.Bottom := Rec.Top + 2 * NotesH2;
// draw the left part
glColor3f(1, 1, 1);
@@ -425,10 +414,10 @@ begin
glEnd;
// Middle part of the note
- Rec.Left := Rec.Right;
+ Rec.Left := Rec.Right;
Rec.Right := X + (Start+Length-Lines[0].Line[Lines[0].Current].Note[0].Start) * TempR - NotesW - 0.5 + 10*ScreenX;
- // (nowe) - dunno
+ // new
if (Start+Length-1 = LyricsState.CurrentBeatD) then
Rec.Right := Rec.Right - (1-Frac(LyricsState.MidBeatD)) * TempR;
// the left note is more right than the right note itself, sounds weird - so we fix that xD
@@ -448,7 +437,7 @@ begin
glColor3f(1, 1, 1);
// the right part of the note
- Rec.Left := Rec.Right;
+ Rec.Left := Rec.Right;
Rec.Right := Rec.Right + NotesW;
glBindTexture(GL_TEXTURE_2D, Tex_Right[PlayerIndex+1].TexNum);
@@ -485,14 +474,12 @@ end;
//draw Note glow
procedure SingDrawPlayerBGLine(Left, Top, Right: real; NrLines, PlayerIndex: integer; Space: integer);
var
- Rec: TRecR;
- Count: integer;
- TempR: real;
+ Rec: TRecR;
+ Count: integer;
+ TempR: real;
X1, X2, X3, X4: real;
- W, H: real;
-
- lTmpA ,
- lTmpB : real;
+ W, H: real;
+ lTmpA, lTmpB: real;
begin
if (Player[PlayerIndex].ScoreTotalInt >= 0) then
begin
@@ -504,15 +491,10 @@ begin
lTmpA := (Right-Left);
lTmpB := (Lines[NrLines].Line[Lines[NrLines].Current].End_ - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start);
- if ( lTmpA > 0 ) and
- ( lTmpB > 0 ) then
- begin
- TempR := lTmpA / lTmpB;
- end
+ if ( lTmpA > 0 ) and ( lTmpB > 0 ) then
+ TempR := lTmpA / lTmpB
else
- begin
TempR := 0;
- end;
with Lines[NrLines].Line[Lines[NrLines].Current] do
begin
@@ -527,14 +509,14 @@ begin
W := NotesW * 2 + 2;
H := NotesH * 1.5 + 3.5;
- X2 := (Start-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left + 0.5 + 10*ScreenX + 4; // wciecie
+ X2 := (Start-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left + 0.5 + 10*ScreenX + 4;
X1 := X2-W;
- X3 := (Start+Length-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left - 0.5 + 10*ScreenX - 4; // wciecie
+ X3 := (Start+Length-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left - 0.5 + 10*ScreenX - 4;
X4 := X3+W;
// left
- Rec.Left := X1;
+ Rec.Left := X1;
Rec.Right := X2;
Rec.Top := Top - (Tone-BaseNote)*Space/2 - H;
Rec.Bottom := Rec.Top + 2 * H;
@@ -547,8 +529,8 @@ begin
glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
glEnd;
- // srodkowa czesc
- Rec.Left := X2;
+ // middle part
+ Rec.Left := X2;
Rec.Right := X3;
glBindTexture(GL_TEXTURE_2D, Tex_BG_Mid[PlayerIndex+1].TexNum);
@@ -559,8 +541,8 @@ begin
glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
glEnd;
- // prawa czesc
- Rec.Left := X3;
+ // right part
+ Rec.Left := X3;
Rec.Right := X4;
glBindTexture(GL_TEXTURE_2D, Tex_BG_Right[PlayerIndex+1].TexNum);
@@ -608,7 +590,7 @@ begin
// FIXME: accessing ScreenSing is not that generic
LyricEngine := ScreenSing.Lyrics;
-
+
// do not draw the lyrics helper if the current line does not contain any note
if (Length(CurLine.Note) > 0) then
begin
@@ -696,27 +678,25 @@ begin
// FIXME: accessing ScreenSing is not that generic
LyricEngine := ScreenSing.Lyrics;
- // background //BG Fullsize Mod
- //SingDrawBackground;
-
// draw time-bar
SingDrawTimeBar();
// draw note-lines
if (PlayersPlay = 1) and (Ini.NoteLines = 1) then
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
+ SingDrawNoteLines(NR.Left + 10*ScreenX, Skin_P2_NotesB - 105, NR.Right + 10*ScreenX, 15);
if ((PlayersPlay = 2) or (PlayersPlay = 4)) and (Ini.NoteLines = 1) then
begin
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P1_NotesB - 105, Nr.Right + 10*ScreenX, 15);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
+ SingDrawNoteLines(NR.Left + 10*ScreenX, Skin_P1_NotesB - 105, NR.Right + 10*ScreenX, 15);
+ SingDrawNoteLines(NR.Left + 10*ScreenX, Skin_P2_NotesB - 105, NR.Right + 10*ScreenX, 15);
end;
- if ((PlayersPlay = 3) or (PlayersPlay = 6)) and (Ini.NoteLines = 1) then begin
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 120, Nr.Right + 10*ScreenX, 12);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 245, Nr.Right + 10*ScreenX, 12);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 370, Nr.Right + 10*ScreenX, 12);
+ if ((PlayersPlay = 3) or (PlayersPlay = 6)) and (Ini.NoteLines = 1) then
+ begin
+ SingDrawNoteLines(NR.Left + 10*ScreenX, 120, NR.Right + 10*ScreenX, 12);
+ SingDrawNoteLines(NR.Left + 10*ScreenX, 245, NR.Right + 10*ScreenX, 12);
+ SingDrawNoteLines(NR.Left + 10*ScreenX, 370, NR.Right + 10*ScreenX, 12);
end;
// draw Lyrics
@@ -724,39 +704,48 @@ begin
SingDrawLyricHelper(NR.Left, NR.WMid);
// oscilloscope
- if Ini.Oscilloscope = 1 then begin
+ if Ini.Oscilloscope = 1 then
+ begin
if PlayersPlay = 1 then
SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
- if PlayersPlay = 2 then begin
+ if PlayersPlay = 2 then
+ begin
SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
end;
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
+ if PlayersPlay = 4 then
+ begin
+ if ScreenAct = 1 then
+ begin
SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
end;
- if ScreenAct = 2 then begin
+ if ScreenAct = 2 then
+ begin
SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2);
SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3);
end;
end;
- if PlayersPlay = 3 then begin
- SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0);
+ if PlayersPlay = 3 then
+ begin
+ SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0);
SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
end;
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
+ if PlayersPlay = 6 then
+ begin
+ if ScreenAct = 1 then
+ begin
SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0);
SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
end;
- if ScreenAct = 2 then begin
+ if ScreenAct = 2 then
+ begin
SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3);
SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4);
SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5);
@@ -785,104 +774,121 @@ begin
end;
// Draw the Notes
- if PlayersPlay = 1 then begin
+ if PlayersPlay = 1 then
+ begin
SingDrawPlayerBGLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 0, 15); // Background glow - colorized in playercolor
SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15); // Plain unsung notes - colorized in playercolor
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 15); // imho the sung notes
+ SingDrawPlayerLine(NR.Left + 20, Skin_P2_NotesB, NR.Width - 40, 0, 15); // imho the sung notes
end;
- if (PlayersPlay = 2) then begin
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
+ if PlayersPlay = 2 then
+ begin
+ SingDrawPlayerBGLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 0, 15);
+ SingDrawPlayerBGLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 1, 15);
SingDrawLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 1, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
+ SingDrawPlayerLine(NR.Left + 20, Skin_P1_NotesB, NR.Width - 40, 0, 15);
+ SingDrawPlayerLine(NR.Left + 20, Skin_P2_NotesB, NR.Width - 40, 1, 15);
end;
- if PlayersPlay = 3 then begin
+ if PlayersPlay = 3 then
+ begin
NotesW := NotesW * 0.8;
NotesH := NotesH * 0.8;
- SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
+ SingDrawPlayerBGLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 0, 12);
+ SingDrawPlayerBGLine(NR.Left + 20, 245+95, NR.Right - 20, 0, 1, 12);
+ SingDrawPlayerBGLine(NR.Left + 20, 370+95, NR.Right - 20, 0, 2, 12);
SingDrawLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
SingDrawLine(NR.Left + 20, 245+95, NR.Right - 20, 1, 12);
SingDrawLine(NR.Left + 20, 370+95, NR.Right - 20, 2, 12);
- SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
- SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
- SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
+ SingDrawPlayerLine(NR.Left + 20, 120+95, NR.Width - 40, 0, 12);
+ SingDrawPlayerLine(NR.Left + 20, 245+95, NR.Width - 40, 1, 12);
+ SingDrawPlayerLine(NR.Left + 20, 370+95, NR.Width - 40, 2, 12);
end;
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
+ if PlayersPlay = 4 then
+ begin
+ if ScreenAct = 1 then
+ begin
+ SingDrawPlayerBGLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 0, 15);
+ SingDrawPlayerBGLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 1, 15);
end;
- if ScreenAct = 2 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 2, 15);
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 3, 15);
+ if ScreenAct = 2 then
+ begin
+ SingDrawPlayerBGLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 2, 15);
+ SingDrawPlayerBGLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 3, 15);
end;
- if ScreenAct = 1 then begin
+ if ScreenAct = 1 then
+ begin
SingDrawLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 1, 15);
end;
- if ScreenAct = 2 then begin
+ if ScreenAct = 2 then
+ begin
SingDrawLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 2, 15);
SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 3, 15);
end;
- if ScreenAct = 1 then begin
- SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
+ if ScreenAct = 1 then
+ begin
+ SingDrawPlayerLine(NR.Left + 20, Skin_P1_NotesB, NR.Width - 40, 0, 15);
+ SingDrawPlayerLine(NR.Left + 20, Skin_P2_NotesB, NR.Width - 40, 1, 15);
end;
- if ScreenAct = 2 then begin
- SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 2, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 3, 15);
+ if ScreenAct = 2 then
+ begin
+ SingDrawPlayerLine(NR.Left + 20, Skin_P1_NotesB, NR.Width - 40, 2, 15);
+ SingDrawPlayerLine(NR.Left + 20, Skin_P2_NotesB, NR.Width - 40, 3, 15);
end;
end;
- if PlayersPlay = 6 then begin
+ if PlayersPlay = 6 then
+ begin
NotesW := NotesW * 0.8;
NotesH := NotesH * 0.8;
- if ScreenAct = 1 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
+ if ScreenAct = 1 then
+ begin
+ SingDrawPlayerBGLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 0, 12);
+ SingDrawPlayerBGLine(NR.Left + 20, 245+95, NR.Right - 20, 0, 1, 12);
+ SingDrawPlayerBGLine(NR.Left + 20, 370+95, NR.Right - 20, 0, 2, 12);
end;
- if ScreenAct = 2 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 3, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 4, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 5, 12);
+ if ScreenAct = 2 then
+ begin
+ SingDrawPlayerBGLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 3, 12);
+ SingDrawPlayerBGLine(NR.Left + 20, 245+95, NR.Right - 20, 0, 4, 12);
+ SingDrawPlayerBGLine(NR.Left + 20, 370+95, NR.Right - 20, 0, 5, 12);
end;
- if ScreenAct = 1 then begin
+ if ScreenAct = 1 then
+ begin
SingDrawLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
SingDrawLine(NR.Left + 20, 245+95, NR.Right - 20, 1, 12);
SingDrawLine(NR.Left + 20, 370+95, NR.Right - 20, 2, 12);
end;
- if ScreenAct = 2 then begin
+ if ScreenAct = 2 then
+ begin
SingDrawLine(NR.Left + 20, 120+95, NR.Right - 20, 3, 12);
SingDrawLine(NR.Left + 20, 245+95, NR.Right - 20, 4, 12);
SingDrawLine(NR.Left + 20, 370+95, NR.Right - 20, 5, 12);
end;
- if ScreenAct = 1 then begin
- SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
- SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
- SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
+ if ScreenAct = 1 then
+ begin
+ SingDrawPlayerLine(NR.Left + 20, 120+95, NR.Width - 40, 0, 12);
+ SingDrawPlayerLine(NR.Left + 20, 245+95, NR.Width - 40, 1, 12);
+ SingDrawPlayerLine(NR.Left + 20, 370+95, NR.Width - 40, 2, 12);
end;
- if ScreenAct = 2 then begin
- SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 3, 12);
- SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 4, 12);
- SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 5, 12);
+ if ScreenAct = 2 then
+ begin
+ SingDrawPlayerLine(NR.Left + 20, 120+95, NR.Width - 40, 3, 12);
+ SingDrawPlayerLine(NR.Left + 20, 245+95, NR.Width - 40, 4, 12);
+ SingDrawPlayerLine(NR.Left + 20, 370+95, NR.Width - 40, 5, 12);
end;
end;
glDisable(GL_BLEND);
@@ -892,12 +898,15 @@ end;
// q'n'd for using the game mode dll's
procedure SingModiDraw (PlayerInfo: TPlayerInfo);
var
- NR: TRecR;
+ NR: TRecR;
begin
// positions
- if Ini.SingWindow = 0 then begin
+ if Ini.SingWindow = 0 then
+ begin
NR.Left := 120;
- end else begin
+ end
+ else
+ begin
NR.Left := 20;
end;
@@ -912,16 +921,18 @@ begin
if DLLMan.Selected.ShowNotes then
begin
if PlayersPlay = 1 then
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
- if (PlayersPlay = 2) or (PlayersPlay = 4) then begin
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P1_NotesB - 105, Nr.Right + 10*ScreenX, 15);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
+ SingDrawNoteLines(NR.Left + 10*ScreenX, Skin_P2_NotesB - 105, NR.Right + 10*ScreenX, 15);
+ if (PlayersPlay = 2) or (PlayersPlay = 4) then
+ begin
+ SingDrawNoteLines(NR.Left + 10*ScreenX, Skin_P1_NotesB - 105, NR.Right + 10*ScreenX, 15);
+ SingDrawNoteLines(NR.Left + 10*ScreenX, Skin_P2_NotesB - 105, NR.Right + 10*ScreenX, 15);
end;
- if (PlayersPlay = 3) or (PlayersPlay = 6) then begin
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 120, Nr.Right + 10*ScreenX, 12);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 245, Nr.Right + 10*ScreenX, 12);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 370, Nr.Right + 10*ScreenX, 12);
+ if (PlayersPlay = 3) or (PlayersPlay = 6) then
+ begin
+ SingDrawNoteLines(NR.Left + 10*ScreenX, 120, NR.Right + 10*ScreenX, 12);
+ SingDrawNoteLines(NR.Left + 10*ScreenX, 245, NR.Right + 10*ScreenX, 12);
+ SingDrawNoteLines(NR.Left + 10*ScreenX, 370, NR.Right + 10*ScreenX, 12);
end;
end;
@@ -930,26 +941,31 @@ begin
// TODO: Lyrics helper
// oscilloscope | the thing that moves when you yell into your mic (imho)
- if (((Ini.Oscilloscope = 1) AND (DLLMan.Selected.ShowRateBar_O)) AND (NOT DLLMan.Selected.ShowRateBar)) then begin
+ if (((Ini.Oscilloscope = 1) and (DLLMan.Selected.ShowRateBar_O)) and (not DLLMan.Selected.ShowRateBar)) then
+ begin
if PlayersPlay = 1 then
if PlayerInfo.Playerinfo[0].Enabled then
SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
- if PlayersPlay = 2 then begin
+ if PlayersPlay = 2 then
+ begin
if PlayerInfo.Playerinfo[0].Enabled then
SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
if PlayerInfo.Playerinfo[1].Enabled then
SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
end;
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
+ if PlayersPlay = 4 then
+ begin
+ if ScreenAct = 1 then
+ begin
if PlayerInfo.Playerinfo[0].Enabled then
SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
if PlayerInfo.Playerinfo[1].Enabled then
SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
end;
- if ScreenAct = 2 then begin
+ if ScreenAct = 2 then
+ begin
if PlayerInfo.Playerinfo[2].Enabled then
SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2);
if PlayerInfo.Playerinfo[3].Enabled then
@@ -957,17 +973,20 @@ begin
end;
end;
- if PlayersPlay = 3 then begin
+ if PlayersPlay = 3 then
+ begin
if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0);
+ SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0);
if PlayerInfo.Playerinfo[1].Enabled then
SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
if PlayerInfo.Playerinfo[2].Enabled then
SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
end;
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
+ if PlayersPlay = 6 then
+ begin
+ if ScreenAct = 1 then
+ begin
if PlayerInfo.Playerinfo[0].Enabled then
SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0);
if PlayerInfo.Playerinfo[1].Enabled then
@@ -975,7 +994,8 @@ begin
if PlayerInfo.Playerinfo[2].Enabled then
SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
end;
- if ScreenAct = 2 then begin
+ if ScreenAct = 2 then
+ begin
if PlayerInfo.Playerinfo[3].Enabled then
SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3);
if PlayerInfo.Playerinfo[4].Enabled then
@@ -1006,107 +1026,120 @@ begin
end;
end;
- if (DLLMAn.Selected.ShowNotes And DLLMan.Selected.LoadSong) then
+ if (DLLMAn.Selected.ShowNotes and DLLMan.Selected.LoadSong) then
begin
- if (PlayersPlay = 1) And PlayerInfo.Playerinfo[0].Enabled then begin
+ if (PlayersPlay = 1) and PlayerInfo.Playerinfo[0].Enabled then
+ begin
SingDrawPlayerBGLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 0, 15);
SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 15);
+ SingDrawPlayerLine(NR.Left + 20, Skin_P2_NotesB, NR.Width - 40, 0, 15);
end;
- if (PlayersPlay = 2) then begin
+ if PlayersPlay = 2 then
+ begin
if PlayerInfo.Playerinfo[0].Enabled then
begin
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
+ SingDrawPlayerBGLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 0, 15);
SingDrawLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
+ SingDrawPlayerLine(NR.Left + 20, Skin_P1_NotesB, NR.Width - 40, 0, 15);
end;
if PlayerInfo.Playerinfo[1].Enabled then
begin
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
+ SingDrawPlayerBGLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 1, 15);
SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
+ SingDrawPlayerLine(NR.Left + 20, Skin_P2_NotesB, NR.Width - 40, 1, 15);
end;
end;
- if PlayersPlay = 3 then begin
+ if PlayersPlay = 3 then
+ begin
NotesW := NotesW * 0.8;
NotesH := NotesH * 0.8;
if PlayerInfo.Playerinfo[0].Enabled then
begin
- SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
+ SingDrawPlayerBGLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 0, 12);
SingDrawLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
- SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
+ SingDrawPlayerLine(NR.Left + 20, 120+95, NR.Width - 40, 0, 12);
end;
if PlayerInfo.Playerinfo[1].Enabled then
begin
- SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
+ SingDrawPlayerBGLine(NR.Left + 20, 245+95, NR.Right - 20, 0, 1, 12);
SingDrawLine(NR.Left + 20, 245+95, NR.Right - 20, 0, 12);
- SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
+ SingDrawPlayerLine(NR.Left + 20, 245+95, NR.Width - 40, 1, 12);
end;
if PlayerInfo.Playerinfo[2].Enabled then
begin
- SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
+ SingDrawPlayerBGLine(NR.Left + 20, 370+95, NR.Right - 20, 0, 2, 12);
SingDrawLine(NR.Left + 20, 370+95, NR.Right - 20, 0, 12);
- SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
+ SingDrawPlayerLine(NR.Left + 20, 370+95, NR.Width - 40, 2, 12);
end;
end;
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
+ if PlayersPlay = 4 then
+ begin
+ if ScreenAct = 1 then
+ begin
+ SingDrawPlayerBGLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 0, 15);
+ SingDrawPlayerBGLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 1, 15);
end;
- if ScreenAct = 2 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 2, 15);
- SingDrawPlayerBGLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 3, 15);
+ if ScreenAct = 2 then
+ begin
+ SingDrawPlayerBGLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 2, 15);
+ SingDrawPlayerBGLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 3, 15);
end;
SingDrawLine(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
SingDrawLine(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
- if ScreenAct = 1 then begin
- SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
+ if ScreenAct = 1 then
+ begin
+ SingDrawPlayerLine(NR.Left + 20, Skin_P1_NotesB, NR.Width - 40, 0, 15);
+ SingDrawPlayerLine(NR.Left + 20, Skin_P2_NotesB, NR.Width - 40, 1, 15);
end;
- if ScreenAct = 2 then begin
- SingDrawPlayerLine(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 2, 15);
- SingDrawPlayerLine(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 3, 15);
+ if ScreenAct = 2 then
+ begin
+ SingDrawPlayerLine(NR.Left + 20, Skin_P1_NotesB, NR.Width - 40, 2, 15);
+ SingDrawPlayerLine(NR.Left + 20, Skin_P2_NotesB, NR.Width - 40, 3, 15);
end;
end;
- if PlayersPlay = 6 then begin
+ if PlayersPlay = 6 then
+ begin
NotesW := NotesW * 0.8;
NotesH := NotesH * 0.8;
- if ScreenAct = 1 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
+ if ScreenAct = 1 then
+ begin
+ SingDrawPlayerBGLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 0, 12);
+ SingDrawPlayerBGLine(NR.Left + 20, 245+95, NR.Right - 20, 0, 1, 12);
+ SingDrawPlayerBGLine(NR.Left + 20, 370+95, NR.Right - 20, 0, 2, 12);
end;
- if ScreenAct = 2 then begin
- SingDrawPlayerBGLine(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 3, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 4, 12);
- SingDrawPlayerBGLine(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 5, 12);
+ if ScreenAct = 2 then
+ begin
+ SingDrawPlayerBGLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 3, 12);
+ SingDrawPlayerBGLine(NR.Left + 20, 245+95, NR.Right - 20, 0, 4, 12);
+ SingDrawPlayerBGLine(NR.Left + 20, 370+95, NR.Right - 20, 0, 5, 12);
end;
SingDrawLine(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
SingDrawLine(NR.Left + 20, 245+95, NR.Right - 20, 0, 12);
SingDrawLine(NR.Left + 20, 370+95, NR.Right - 20, 0, 12);
- if ScreenAct = 1 then begin
- SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
- SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
- SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
+ if ScreenAct = 1 then
+ begin
+ SingDrawPlayerLine(NR.Left + 20, 120+95, NR.Width - 40, 0, 12);
+ SingDrawPlayerLine(NR.Left + 20, 245+95, NR.Width - 40, 1, 12);
+ SingDrawPlayerLine(NR.Left + 20, 370+95, NR.Width - 40, 2, 12);
end;
- if ScreenAct = 2 then begin
- SingDrawPlayerLine(Nr.Left + 20, 120+95, Nr.Width - 40, 3, 12);
- SingDrawPlayerLine(Nr.Left + 20, 245+95, Nr.Width - 40, 4, 12);
- SingDrawPlayerLine(Nr.Left + 20, 370+95, Nr.Width - 40, 5, 12);
+ if ScreenAct = 2 then
+ begin
+ SingDrawPlayerLine(NR.Left + 20, 120+95, NR.Width - 40, 3, 12);
+ SingDrawPlayerLine(NR.Left + 20, 245+95, NR.Width - 40, 4, 12);
+ SingDrawPlayerLine(NR.Left + 20, 370+95, NR.Width - 40, 5, 12);
end;
end;
end;
@@ -1115,15 +1148,14 @@ begin
glDisable(GL_TEXTURE_2D);
end;
-
{//SingBar Mod
procedure SingDrawSingbar(X, Y, W, H: real; Percent: integer);
var
- R: Real;
- G: Real;
- B: Real;
- A: cardinal;
- I: Integer;
+ R: real;
+ G: real;
+ B: real;
+ A: cardinal;
+ I: integer;
begin;
@@ -1141,7 +1173,7 @@ begin;
glEnd;
//SingBar coloured Bar
- Case Percent of
+ case Percent of
0..22: begin
R := 1;
G := 0;
@@ -1167,7 +1199,7 @@ begin;
G := 1;
B := 0;
end;
- End; //Case
+ end; //case
glColor4f(R, G, B, 1);
glEnable(GL_TEXTURE_2D);
@@ -1198,99 +1230,103 @@ end;
//end Singbar Mod
//PhrasenBonus - Line Bonus Pop Up
-procedure SingDrawLineBonus( const X, Y: Single; Color: TRGB; Alpha: Single; Text: string; Age: Integer);
+procedure SingDrawLineBonus(const X, Y: Single; Color: TRGB; Alpha: Single; Text: string; Age: integer);
var
-Length, X2: Real; //Length of Text
-Size: Integer; //Size of Popup
-begin
-if Alpha <> 0 then
+ Length, X2: real; //Length of Text
+ Size: integer; //Size of Popup
begin
+ if Alpha <> 0 then
+ begin
//Set Font Propertys
-SetFontStyle(2); //Font: Outlined1
-if Age < 5 then SetFontSize((Age + 1) * 3) else SetFontSize(18);
-SetFontItalic(False);
+ SetFontStyle(2); //Font: Outlined1
+ if Age < 5 then
+ SetFontSize((Age + 1) * 3)
+ else
+ SetFontSize(18);
+ SetFontItalic(False);
//Check Font Size
-Length := glTextWidth (Text) + 3; //Little Space for a Better Look ^^
+ Length := glTextWidth (Text) + 3; //Little Space for a Better Look ^^
//Text
-SetFontPos (X + 50 - (Length / 2), Y + 12); //Position
+ SetFontPos (X + 50 - (Length / 2), Y + 12); //Position
+ if Age < 5 then
+ Size := Age * 10
+ else
+ Size := 50;
-if Age < 5 then Size := Age * 10 else Size := 50;
-
- //Draw Background
- //glColor4f(Color.R, Color.G, Color.B, Alpha); //Set Color
- glColor4f(1, 1, 1, Alpha);
-
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
+//Draw Background
+// glColor4f(Color.R, Color.G, Color.B, Alpha); //Set Color
+ glColor4f(1, 1, 1, Alpha);
- //New Method, Not Variable
- glBindTexture(GL_TEXTURE_2D, Tex_SingLineBonusBack[2].TexNum);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(X + 50 - Size, Y + 25 - (Size/2));
- glTexCoord2f(0, 1); glVertex2f(X + 50 - Size, Y + 25 + (Size/2));
- glTexCoord2f(1, 1); glVertex2f(X + 50 + Size, Y + 25 + (Size/2));
- glTexCoord2f(1, 0); glVertex2f(X + 50 + Size, Y + 25 - (Size/2));
- glEnd;
+//New Method, Not Variable
+ glBindTexture(GL_TEXTURE_2D, Tex_SingLineBonusBack[2].TexNum);
- glColor4f(1, 1, 1, Alpha); //Set Color
- //Draw Text
- glPrint (Text);
-end;
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(X + 50 - Size, Y + 25 - (Size/2));
+ glTexCoord2f(0, 1); glVertex2f(X + 50 - Size, Y + 25 + (Size/2));
+ glTexCoord2f(1, 1); glVertex2f(X + 50 + Size, Y + 25 + (Size/2));
+ glTexCoord2f(1, 0); glVertex2f(X + 50 + Size, Y + 25 - (Size/2));
+ glEnd;
+
+ glColor4f(1, 1, 1, Alpha); //Set Color
+//Draw Text
+ glPrint (Text);
+ end;
end;
//PhrasenBonus - Line Bonus Mod}
// Draw Note Bars for Editor
-//There are 11 Resons for a new Procdedure: (nice binary :D )
-// 1. It don't look good when you Draw the Golden Note Star Effect in the Editor
-// 2. You can see the Freestyle Notes in the Editor SemiTransparent
-// 3. Its easier and Faster then changing the old Procedure
+// There are 11 reasons for a new procedure: (nice binary :D )
+// 1. It does not look good when you draw the golden note star effect in the editor
+// 2. You can see the freestyle notes in the editor semitransparent
+// 3. It is easier and faster then changing the old procedure
procedure EditDrawLine(Left, Top, Right: real; NrLines: integer; Space: integer);
var
- Rec: TRecR;
- Count: integer;
- TempR: real;
+ Rec: TRecR;
+ Count: integer;
+ TempR: real;
begin
glColor3f(1, 1, 1);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
TempR := (Right-Left) / (Lines[NrLines].Line[Lines[NrLines].Current].End_ - Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start);
- with Lines[NrLines].Line[Lines[NrLines].Current] do begin
- for Count := 0 to HighNote do begin
- with Note[Count] do begin
-
- // Golden Note Patch
- case NoteType of
- ntFreestyle: glColor4f(1, 1, 1, 0.35);
- ntNormal: glColor4f(1, 1, 1, 0.85);
- ntGolden: Glcolor4f(1, 1, 0.3, 0.85);
- end; // case
-
+ with Lines[NrLines].Line[Lines[NrLines].Current] do
+ begin
+ for Count := 0 to HighNote do
+ begin
+ with Note[Count] do
+ begin
+ // Golden Note Patch
+ case NoteType of
+ ntFreestyle: glColor4f(1, 1, 1, 0.35);
+ ntNormal: glColor4f(1, 1, 1, 0.85);
+ ntGolden: Glcolor4f(1, 1, 0.3, 0.85);
+ end; // case
- // lewa czesc - left part
- Rec.Left := (Start-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left + 0.5 + 10*ScreenX;
- Rec.Right := Rec.Left + NotesW;
- Rec.Top := Top - (Tone-BaseNote)*Space/2 - NotesH;
- Rec.Bottom := Rec.Top + 2 * NotesH;
- glBindTexture(GL_TEXTURE_2D, Tex_Left[Color].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
+ // left part
+ Rec.Left := (Start-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left + 0.5 + 10*ScreenX;
+ Rec.Right := Rec.Left + NotesW;
+ Rec.Top := Top - (Tone-BaseNote)*Space/2 - NotesH;
+ Rec.Bottom := Rec.Top + 2 * NotesH;
+ glBindTexture(GL_TEXTURE_2D, Tex_Left[Color].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
- // srodkowa czesc - middle part
- Rec.Left := Rec.Right;
+ // middle part
+ Rec.Left := Rec.Right;
Rec.Right := (Start+Length-Lines[NrLines].Line[Lines[NrLines].Current].Note[0].Start) * TempR + Left - NotesW - 0.5 + 10*ScreenX;
glBindTexture(GL_TEXTURE_2D, Tex_Mid[Color].TexNum);
@@ -1301,8 +1337,8 @@ begin
glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
glEnd;
- // prawa czesc - right part
- Rec.Left := Rec.Right;
+ // right part
+ Rec.Left := Rec.Right;
Rec.Right := Rec.Right + NotesW;
glBindTexture(GL_TEXTURE_2D, Tex_Right[Color].TexNum);
@@ -1323,7 +1359,7 @@ end;
procedure SingDrawTimeBar();
var
- x,y: real;
+ x, y: real;
width, height: real;
LyricsProgress: real;
CurLyricsTime: real;
diff --git a/unicode/src/base/UEditorLyrics.pas b/unicode/src/base/UEditorLyrics.pas
index d06fc891..fe8c3ee5 100644
--- a/unicode/src/base/UEditorLyrics.pas
+++ b/unicode/src/base/UEditorLyrics.pas
@@ -40,48 +40,50 @@ uses
UTexture;
type
+ alignment = (left, center, right);
+
TWord = record
- X: real;
- Y: real;
- Size: real;
- Width: real;
- Text: string;
- ColR: real;
- ColG: real;
- ColB: real;
- FontStyle: integer;
- Italic: boolean;
- Selected: boolean;
+ X: real;
+ Y: real;
+ Size: real;
+ Width: real;
+ Text: string;
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ FontStyle: integer;
+ Italic: boolean;
+ Selected: boolean;
end;
TEditorLyrics = class
private
- AlignI: integer;
- XR: real;
- YR: real;
- SizeR: real;
- SelectedI: integer;
- FontStyleI: integer; // font number
- Word: array of TWord;
+ AlignI: alignment;
+ XR: real;
+ YR: real;
+ SizeR: real;
+ SelectedI: integer;
+ FontStyleI: integer; // font number
+ Word: array of TWord;
procedure SetX(Value: real);
procedure SetY(Value: real);
function GetClientX: real;
- procedure SetAlign(Value: integer);
+ procedure SetAlign(Value: alignment);
function GetSize: real;
procedure SetSize(Value: real);
procedure SetSelected(Value: integer);
- procedure SetFStyle(Value: integer);
+ procedure SetFontStyle(Value: integer);
procedure AddWord(Text: string);
procedure Refresh;
public
- ColR: real;
- ColG: real;
- ColB: real;
- ColSR: real;
- ColSG: real;
- ColSB: real;
- Italic: boolean;
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ ColSR: real;
+ ColSG: real;
+ ColSB: real;
+ Italic: boolean;
constructor Create;
destructor Destroy; override;
@@ -94,16 +96,20 @@ type
property X: real write SetX;
property Y: real write SetY;
property ClientX: real read GetClientX;
- property Align: integer write SetAlign;
+ property Align: alignment write SetAlign;
property Size: real read GetSize write SetSize;
property Selected: integer read SelectedI write SetSelected;
- property FontStyle: integer write SetFStyle;
+ property FontStyle: integer write SetFontStyle;
end;
implementation
uses
- TextGL, UGraphic, UDrawTexture, Math, USkins;
+ TextGL,
+ UGraphic,
+ UDrawTexture,
+ Math,
+ USkins;
constructor TEditorLyrics.Create;
begin
@@ -131,7 +137,7 @@ begin
Result := Word[0].X;
end;
-procedure TEditorLyrics.SetAlign(Value: integer);
+procedure TEditorLyrics.SetAlign(Value: alignment);
begin
AlignI := Value;
end;
@@ -148,7 +154,7 @@ end;
procedure TEditorLyrics.SetSelected(Value: integer);
begin
- if (SelectedI > -1) and (SelectedI <= High(Word)) then
+ if (-1 < SelectedI) and (SelectedI <= High(Word)) then
begin
Word[SelectedI].Selected := false;
Word[SelectedI].ColR := ColR;
@@ -157,7 +163,7 @@ begin
end;
SelectedI := Value;
- if (Value > -1) and (Value <= High(Word)) then
+ if (-1 < Value) and (Value <= High(Word)) then
begin
Word[Value].Selected := true;
Word[Value].ColR := ColSR;
@@ -168,22 +174,21 @@ begin
Refresh;
end;
-procedure TEditorLyrics.SetFStyle(Value: integer);
+procedure TEditorLyrics.SetFontStyle(Value: integer);
begin
FontStyleI := Value;
end;
procedure TEditorLyrics.AddWord(Text: string);
var
- WordNum: integer;
+ WordNum: integer;
begin
WordNum := Length(Word);
SetLength(Word, WordNum + 1);
- if WordNum = 0 then begin
- Word[WordNum].X := XR;
- end else begin
+ if WordNum = 0 then
+ Word[WordNum].X := XR
+ else
Word[WordNum].X := Word[WordNum - 1].X + Word[WordNum - 1].Width;
- end;
Word[WordNum].Y := YR;
Word[WordNum].Size := SizeR;
@@ -202,12 +207,13 @@ end;
procedure TEditorLyrics.AddLine(NrLine: integer);
var
- N: integer;
+ NoteIndex: integer;
begin
Clear;
- for N := 0 to Lines[0].Line[NrLine].HighNote do begin
- Italic := Lines[0].Line[NrLine].Note[N].NoteType = ntFreestyle;
- AddWord(Lines[0].Line[NrLine].Note[N].Text);
+ for NoteIndex := 0 to Lines[0].Line[NrLine].HighNote do
+ begin
+ Italic := Lines[0].Line[NrLine].Note[NoteIndex].NoteType = ntFreestyle;
+ AddWord(Lines[0].Line[NrLine].Note[NoteIndex].Text);
end;
Selected := -1;
end;
@@ -220,32 +226,33 @@ end;
procedure TEditorLyrics.Refresh;
var
- W: integer;
- TotWidth: real;
+ WordIndex: integer;
+ TotalWidth: real;
begin
- if AlignI = 1 then begin
- TotWidth := 0;
- for W := 0 to High(Word) do
- TotWidth := TotWidth + Word[W].Width;
-
- Word[0].X := XR - TotWidth / 2;
- for W := 1 to High(Word) do
- Word[W].X := Word[W - 1].X + Word[W - 1].Width;
+ if AlignI = center then
+ begin
+ TotalWidth := 0;
+ for WordIndex := 0 to High(Word) do
+ TotalWidth := TotalWidth + Word[WordIndex].Width;
+
+ Word[0].X := XR - TotalWidth / 2;
+ for WordIndex := 1 to High(Word) do
+ Word[WordIndex].X := Word[WordIndex - 1].X + Word[WordIndex - 1].Width;
end;
end;
procedure TEditorLyrics.Draw;
var
- W: integer;
+ WordIndex: integer;
begin
- for W := 0 to High(Word) do
+ for WordIndex := 0 to High(Word) do
begin
- SetFontStyle(Word[W].FontStyle);
- SetFontPos(Word[W].X+ 10*ScreenX, Word[W].Y);
- SetFontSize(Word[W].Size);
- SetFontItalic(Word[W].Italic);
- glColor3f(Word[W].ColR, Word[W].ColG, Word[W].ColB);
- glPrint(Word[W].Text);
+ SetFontStyle(Word[WordIndex].FontStyle);
+ SetFontPos(Word[WordIndex].X + 10*ScreenX, Word[WordIndex].Y);
+ SetFontSize(Word[WordIndex].Size);
+ SetFontItalic(Word[WordIndex].Italic);
+ glColor3f(Word[WordIndex].ColR, Word[WordIndex].ColG, Word[WordIndex].ColB);
+ glPrint(Word[WordIndex].Text);
end;
end;
diff --git a/unicode/src/base/UFiles.pas b/unicode/src/base/UFiles.pas
index 463801c7..ee6f660a 100644
--- a/unicode/src/base/UFiles.pas
+++ b/unicode/src/base/UFiles.pas
@@ -58,8 +58,8 @@ implementation
uses
TextGL,
UIni,
- UPlatform,
- UMain;
+ UNote,
+ UPlatform;
//--------------------
// Resets the temporary Sentence Arrays for each Player and some other Variables
@@ -73,7 +73,6 @@ begin
SetLength(Lines[Count].Line, 1);
SetLength(Lines[Count].Line[0].Note, 0);
Lines[Count].Line[0].Lyric := '';
- Lines[Count].Line[0].LyricWidth := 0;
Player[Count].Score := 0;
Player[Count].LengthNote := 0;
Player[Count].HighNote := -1;
diff --git a/unicode/src/base/UGraphic.pas b/unicode/src/base/UGraphic.pas
index b525c170..17175d02 100644
--- a/unicode/src/base/UGraphic.pas
+++ b/unicode/src/base/UGraphic.pas
@@ -280,11 +280,12 @@ function LoadingThreadFunction: integer;
implementation
uses
+ Classes,
UMain,
UIni,
UDisplay,
UCommandLine,
- Classes;
+ UPath;
procedure LoadFontTextures;
begin
@@ -294,17 +295,19 @@ end;
procedure LoadTextures;
-
var
- P: integer;
- R, G, B: real;
- Col: integer;
+ P: integer;
+ R, G, B: real;
+ Col: integer;
begin
Log.LogStatus('Loading Textures', 'LoadTextures');
-
- Tex_Left[0] := Texture.LoadTexture(Skin.GetTextureFileName('GrayLeft'), TEXTURE_TYPE_TRANSPARENT, 0); //brauch man die noch?
- Tex_Mid[0] := Texture.LoadTexture(Skin.GetTextureFileName('GrayMid'), TEXTURE_TYPE_PLAIN, 0); //brauch man die noch?
- Tex_Right[0] := Texture.LoadTexture(Skin.GetTextureFileName('GrayRight'), TEXTURE_TYPE_TRANSPARENT, 0); //brauch man die noch?
+
+ // FIXME: do we need this? (REMOVE otherwise)
+ Tex_Left[0] := Texture.LoadTexture(Skin.GetTextureFileName('GrayLeft'), TEXTURE_TYPE_TRANSPARENT, 0);
+ // FIXME: do we need this? (REMOVE otherwise)
+ Tex_Mid[0] := Texture.LoadTexture(Skin.GetTextureFileName('GrayMid'), TEXTURE_TYPE_PLAIN, 0);
+ // FIXME: do we need this? (REMOVE otherwise)
+ Tex_Right[0] := Texture.LoadTexture(Skin.GetTextureFileName('GrayRight'), TEXTURE_TYPE_TRANSPARENT, 0);
Log.LogStatus('Loading Textures - A', 'LoadTextures');
diff --git a/unicode/src/base/UGraphicClasses.pas b/unicode/src/base/UGraphicClasses.pas
index 3fbe262f..cdaa238e 100644
--- a/unicode/src/base/UGraphicClasses.pas
+++ b/unicode/src/base/UGraphicClasses.pas
@@ -124,16 +124,16 @@ var
implementation
uses
- sysutils,
+ SysUtils,
+ Math,
gl,
+ UCommon,
+ UDrawTexture,
+ UGraphic,
UIni,
- UMain,
- UThemes,
+ UNote,
USkins,
- UGraphic,
- UDrawTexture,
- UCommon,
- math;
+ UThemes;
//TParticle
constructor TParticle.Create(cX, cY : real;
diff --git a/unicode/src/base/UHooks.pas b/unicode/src/base/UHooks.pas
index ab830090..acf2bba7 100644
--- a/unicode/src/base/UHooks.pas
+++ b/unicode/src/base/UHooks.pas
@@ -46,23 +46,23 @@ type
//Record that saves info from Subscriber
PSubscriberInfo = ^TSubscriberInfo;
TSubscriberInfo = record
- Self: THandle; //ID of this Subscription (First word: ID of Subscription; 2nd word: ID of Hook)
- Next: PSubscriberInfo; //Pointer to next Item in HookChain
+ Self: THandle; // ID of this Subscription (First word: ID of Subscription; 2nd word: ID of Hook)
+ Next: PSubscriberInfo; // Pointer to next Item in HookChain
Owner: integer; //For Error Handling and Plugin Unloading.
- //Here is s/t tricky
- //To avoid writing of Wrapping Functions to Hook an Event with a Class
- //We save a Normal Proc or a Method of a Class
+ // Here is s/t tricky
+ // To avoid writing of Wrapping Functions to Hook an Event with a Class
+ // We save a Normal Proc or a Method of a Class
case isClass: boolean of
- False: (Proc: TUS_Hook); //Proc that will be called on Event
- True: (ProcOfClass: TUS_Hook_of_Object);
+ false: (Proc: TUS_Hook); //Proc that will be called on Event
+ true: (ProcOfClass: TUS_Hook_of_Object);
end;
TEventInfo = record
- Name: string[60]; //Name of Event
- FirstSubscriber: PSubscriberInfo; //First subscriber in chain
- LastSubscriber: PSubscriberInfo; //Last " (for easier subscriber adding
+ Name: string[60]; // Name of Event
+ FirstSubscriber: PSubscriberInfo; // First subscriber in chain
+ LastSubscriber: PSubscriberInfo; // Last " (for easier subscriber adding)
end;
THookManager = class
@@ -101,7 +101,8 @@ uses
// Create - Creates Class and Set Standard Values
//------------
constructor THookManager.Create(const SpacetoAllocate: word);
-var I: integer;
+var
+ I: integer;
begin
inherited Create();
@@ -121,7 +122,8 @@ end;
// AddEvent - Adds an Event and return the Events Handle or 0 on Failure
//------------
function THookManager.AddEvent (const EventName: Pchar): THandle;
-var I: integer;
+var
+ I: integer;
begin
Result := 0;
@@ -177,7 +179,6 @@ begin
hEvent := hEvent - 1; //Arrayindex is Handle - 1
Result := -1;
-
if (Length(Events) > hEvent) and (Events[hEvent].Name[1] <> chr(0)) then
begin //Event exists
//Free the Space for all Subscribers
@@ -212,8 +213,8 @@ end;
function THookManager.AddSubscriber (const EventName: Pchar; const Proc: TUS_Hook; const ProcOfClass: TUS_Hook_of_Object): THandle;
var
EventHandle: THandle;
- EventIndex: Cardinal;
- Cur: PSubscriberInfo;
+ EventIndex: integer;
+ Cur: PSubscriberInfo;
begin
Result := 0;
@@ -224,7 +225,7 @@ begin
if (EventHandle <> 0) then
begin
EventIndex := EventHandle - 1;
-
+
//Get Memory
GetMem(Cur, SizeOf(TSubscriberInfo));
@@ -236,12 +237,12 @@ begin
if (@Proc = nil) then
begin //Use the ProcofClass Method
- Cur.isClass := True;
+ Cur.isClass := true;
Cur.ProcOfClass := ProcofClass;
end
else //Use the normal Proc
begin
- Cur.isClass := False;
+ Cur.isClass := false;
Cur.Proc := Proc;
end;
@@ -306,8 +307,8 @@ end;
//------------
function THookManager.DelSubscriber (const hSubscriber: THandle): integer;
var
- EventIndex: Cardinal;
- Cur, Last: PSubscriberInfo;
+ EventIndex: integer;
+ Cur, Last: PSubscriberInfo;
begin
Result := -1;
EventIndex := ((hSubscriber and (High(THandle) xor High(word))) SHR 16) - 1;
@@ -344,16 +345,15 @@ begin
end;
end;
-
//------------
// CallEventChain - Calls the Chain of a specified EventHandle
// Returns: -1: Handle doesn't Exist, 0 Chain is called until the End
//------------
function THookManager.CallEventChain (const hEvent: THandle; const wParam: TwParam; lParam: TlParam): integer;
var
- EventIndex: Cardinal;
- Cur: PSubscriberInfo;
- CurExecutedBackup: integer; //backup of Core.CurExecuted Attribute
+ EventIndex: integer;
+ Cur: PSubscriberInfo;
+ CurExecutedBackup: integer; // backup of Core.CurExecuted Attribute
begin
Result := -1;
EventIndex := hEvent - 1;
@@ -393,7 +393,7 @@ end;
//------------
function THookManager.EventExists (const EventName: Pchar): integer;
var
- I: integer;
+ I: integer;
Name: string[60];
begin
Result := 0;
@@ -418,7 +418,7 @@ end;
//------------
procedure THookManager.DelbyOwner(const Owner: integer);
var
- I: integer;
+ I: integer;
Cur, Last: PSubscriberInfo;
begin
//Search for Owner in all Hooks Chains
@@ -426,7 +426,7 @@ begin
begin
if (Events[I].Name[1] <> chr(0)) then
begin
-
+
Last := nil;
Cur := Events[I].FirstSubscriber;
//Went Through Chain
@@ -451,7 +451,6 @@ begin
end;
end;
-
function HookTest(wParam: TwParam; lParam: TlParam): integer; stdcall;
begin
Result := 0; //Don't break the chain
diff --git a/unicode/src/base/UImage.pas b/unicode/src/base/UImage.pas
index 18b0035c..8dc38495 100644
--- a/unicode/src/base/UImage.pas
+++ b/unicode/src/base/UImage.pas
@@ -151,10 +151,9 @@ function LoadImage(const Filename: string): PSDL_Surface;
*******************************************************)
function PixelFormatEquals(fmt1, fmt2: PSDL_PixelFormat): boolean;
-procedure ScaleImage(var ImgSurface: PSDL_Surface; Width, Height: Cardinal);
-procedure FitImage(var ImgSurface: PSDL_Surface; Width, Height: Cardinal);
-procedure ColorizeImage(ImgSurface: PSDL_Surface; NewColor: Cardinal);
-
+procedure ScaleImage(var ImgSurface: PSDL_Surface; Width, Height: cardinal);
+procedure FitImage(var ImgSurface: PSDL_Surface; Width, Height: cardinal);
+procedure ColorizeImage(ImgSurface: PSDL_Surface; NewColor: cardinal);
implementation
@@ -185,7 +184,6 @@ uses
UCommon,
ULog;
-
function IsRGBSurface(pixelFmt: PSDL_PixelFormat): boolean;
begin
Result := (pixelFmt.BitsPerPixel = 24) and
@@ -266,7 +264,6 @@ begin
end;
end;
-
(*******************************************************
* Image saving
*******************************************************)
@@ -759,12 +756,10 @@ end;
{$ENDIF}
-
(*******************************************************
* Image loading
*******************************************************)
-
(*
* Loads an image from the given file
*)
@@ -793,12 +788,10 @@ begin
end;
end;
-
(*******************************************************
* Image manipulation
*******************************************************)
-
function PixelFormatEquals(fmt1, fmt2: PSDL_PixelFormat): boolean;
begin
if (fmt1^.BitsPerPixel = fmt2^.BitsPerPixel) and
@@ -814,7 +807,7 @@ begin
Result := false;
end;
-procedure ScaleImage(var ImgSurface: PSDL_Surface; Width, Height: Cardinal);
+procedure ScaleImage(var ImgSurface: PSDL_Surface; Width, Height: cardinal);
var
TempSurface: PSDL_Surface;
begin
@@ -825,10 +818,10 @@ begin
SDL_FreeSurface(TempSurface);
end;
-procedure FitImage(var ImgSurface: PSDL_Surface; Width, Height: Cardinal);
+procedure FitImage(var ImgSurface: PSDL_Surface; Width, Height: cardinal);
var
TempSurface: PSDL_Surface;
- ImgFmt: PSDL_PixelFormat;
+ ImgFmt: PSDL_PixelFormat;
begin
TempSurface := ImgSurface;
@@ -849,12 +842,12 @@ end;
(*
// Old slow floating point version of ColorizeTexture.
// For an easier understanding of the faster fixed point version below.
-procedure ColorizeTexture(TexSurface: PSDL_Surface; Col: Cardinal);
+procedure ColorizeTexture(TexSurface: PSDL_Surface; Col: cardinal);
var
- clr: array[0..2] of Double; // [0: R, 1: G, 2: B]
- hsv: array[0..2] of Double; // [0: H(ue), 1: S(aturation), 2: V(alue)]
- delta, f, p, q, t: Double;
- max: Double;
+ clr: array[0..2] of double; // [0: R, 1: G, 2: B]
+ hsv: array[0..2] of double; // [0: H(ue), 1: S(aturation), 2: V(alue)]
+ delta, f, p, q, t: double;
+ max: double;
begin
clr[0] := PixelColors[0]/255;
clr[1] := PixelColors[1]/255;
@@ -892,90 +885,175 @@ begin
end;
*)
-procedure ColorizeImage(ImgSurface: PSDL_Surface; NewColor: Cardinal);
+procedure ColorizeImage(ImgSurface: PSDL_Surface; NewColor: cardinal);
- //returns hue within range [0.0-6.0)
- function col2hue(Color:Cardinal): double;
+ // First, the rgb colors are converted to hsv, second hue is replaced by
+ // the NewColor, saturation and value remain unchanged, finally this
+ // hsv color is converted back to rgb space.
+ // For the conversion algorithms of colors from rgb to hsv space
+ // and back simply check the wikipedia.
+ // In order to speed up starting time of USDX the division of reals is
+ // replaced by division of longwords, shifted by 10 bits to keep
+ // digits.
+
+ function ColorToHue(const Color: longword): longword;
+ // returns hue within the range [0.0-6.0] but shl 10, ie. times 1024
var
- clr: array[0..2] of double;
- hue, max, delta: double;
+ Red, Green, Blue: longword;
+ Min, Max, Delta: longword;
+ Hue: double;
begin
- clr[0] := ((Color and $ff0000) shr 16)/255; // R
- clr[1] := ((Color and $ff00) shr 8)/255; // G
- clr[2] := (Color and $ff) /255; // B
- max := maxvalue(clr);
- delta := max - minvalue(clr);
+ // extract the colors
+ // division by 255 is omitted, since it is implicitly done
+ // when deviding by delta
+ Red := ((Color and $ff0000) shr 16); // R
+ Green := ((Color and $ff00) shr 8); // G
+ Blue := (Color and $ff) ; // B
+
+ Min := Red;
+ if Green < Min then Min := Green;
+ if Blue < Min then Min := Blue;
+
+ Max := Red;
+ if Green > Max then Max := Green;
+ if Blue > Max then Max := Blue;
+
// calc hue
- if (delta = 0.0) then hue := 0
- else if (clr[0] = max) then hue := (clr[1]-clr[2])/delta
- else if (clr[1] = max) then hue := 2.0+(clr[2]-clr[0])/delta
- else if (clr[2] = max) then hue := 4.0+(clr[0]-clr[1])/delta;
- if (hue < 0.0) then
- hue := hue + 6.0;
- Result := hue;
+ Delta := Max - Min;
+ if (Delta = 0) then
+ Result := 0
+ else
+ begin
+ // The division by Delta is done separately afterwards.
+ // Necessary because Delphi did not do the type conversion from
+ // longword to double as expected.
+ if (Max = Red ) then Hue := Green - Blue
+ else if (Max = Green) then Hue := 2.0*Delta + Blue - Red
+ else if (Max = Blue ) then Hue := 4.0*Delta + Red - Green;
+ Hue := Hue / Delta;
+ if (Hue < 0.0) then
+ Hue := Hue + 6.0;
+ Result := trunc(Hue*1024); // '*1024' is shl 10
+ end;
end;
var
- DestinationHue: Double;
- PixelIndex: Cardinal;
+ PixelIndex: longword;
Pixel: PByte;
PixelColors: PByteArray;
- clr: array[0..2] of UInt32; // [0: R, 1: G, 2: B]
- hsv: array[0..2] of UInt32; // [0: H(ue), 1: S(aturation), 2: V(alue)]
- dhue: UInt32;
- h_int: Cardinal;
- delta, f, p, q, t: Longint;
- max: Uint32;
+ Red, Green, Blue: longword;
+ Hue, Sat: longword;
+ Min, Max, Delta: longword;
+ HueInteger: longword;
+ f, p, q, t: longword;
begin
- DestinationHue := col2hue(NewColor);
-
- dhue := Trunc(DestinationHue*1024);
Pixel := ImgSurface^.Pixels;
+ // check of the size of a pixel in bytes.
+ // It should be always 4, but this
+ // additional safeguard will show,
+ // whether something went wrong up to here.
+
+ if ImgSurface^.format.BytesPerPixel <> 4 then
+ Log.LogError ('ColorizeImage: The pixel size should be 4, but it is '
+ + IntToStr(ImgSurface^.format.BytesPerPixel));
+
+ Hue := ColorToHue(NewColor); // Hue is shl 10
+ f := Hue and $3ff; // f is the dezimal part of hue
+ HueInteger := Hue shr 10;
+
for PixelIndex := 0 to (ImgSurface^.W * ImgSurface^.H)-1 do
begin
PixelColors := PByteArray(Pixel);
// inlined colorize per pixel
// uses fixed point math
+ // shl 10 is used for divisions
+
// get color values
- clr[0] := PixelColors[0] shl 10;
- clr[1] := PixelColors[1] shl 10;
- clr[2] := PixelColors[2] shl 10;
+
+ {$IFDEF FPC_BIG_ENDIAN}
+ Red := PixelColors[3];
+ Green := PixelColors[2];
+ Blue := PixelColors[1];
+ // PixelColors[0] is alpha and remains untouched
+ {$ELSE}
+ Red := PixelColors[0];
+ Green := PixelColors[1];
+ Blue := PixelColors[2];
+ // PixelColors[3] is alpha and remains untouched
+ {$ENDIF}
+
//calculate luminance and saturation from rgb
- max := clr[0];
- if clr[1] > max then max := clr[1];
- if clr[2] > max then max := clr[2];
- delta := clr[0];
- if clr[1] < delta then delta := clr[1];
- if clr[2] < delta then delta := clr[2];
- delta := max-delta;
- hsv[0] := dhue; // shl 8
- hsv[2] := max; // shl 8
- if (max = 0) then
- hsv[1] := 0
+ Max := Red;
+ if Green > Max then Max := Green;
+ if Blue > Max then Max := Blue ;
+
+ if (Max = 0) then // the color is black
+ begin
+ {$IFDEF FPC_BIG_ENDIAN}
+ PixelColors[3] := 0;
+ PixelColors[2] := 0;
+ PixelColors[1] := 0;
+ {$ELSE}
+ PixelColors[0] := 0;
+ PixelColors[1] := 0;
+ PixelColors[2] := 0;
+ {$ENDIF}
+ end
else
- hsv[1] := (delta shl 10) div max; // shl 8
- h_int := hsv[0] and $fffffC00;
- f := hsv[0]-h_int; //shl 10
- p := (hsv[2]*(1024-hsv[1])) shr 10;
- q := (hsv[2]*(1024-(hsv[1]*f) shr 10)) shr 10;
- t := (hsv[2]*(1024-(hsv[1]*(1024-f)) shr 10)) shr 10;
- h_int := h_int shr 10;
- case h_int of
- 0: begin clr[0] := hsv[2]; clr[1] := t; clr[2] := p; end; // (v,t,p)
- 1: begin clr[0] := q; clr[1] := hsv[2]; clr[2] := p; end; // (q,v,p)
- 2: begin clr[0] := p; clr[1] := hsv[2]; clr[2] := t; end; // (p,v,t)
- 3: begin clr[0] := p; clr[1] := q; clr[2] := hsv[2]; end; // (p,q,v)
- 4: begin clr[0] := t; clr[1] := p; clr[2] := hsv[2]; end; // (t,p,v)
- 5: begin clr[0] := hsv[2]; clr[1] := p; clr[2] := q; end; // (v,p,q)
- end;
+ begin
+ Min := Red;
+ if Green < Min then Min := Green;
+ if Blue < Min then Min := Blue ;
+
+ if (Min = 255) then // the color is white
+ begin
+ {$IFDEF FPC_BIG_ENDIAN}
+ PixelColors[3] := 255;
+ PixelColors[2] := 255;
+ PixelColors[1] := 255;
+ {$ELSE}
+ PixelColors[0] := 255;
+ PixelColors[1] := 255;
+ PixelColors[2] := 255;
+ {$ENDIF}
+ end
+ else // all colors except black and white
+ begin
+ Delta := Max - Min;
+ Sat := (Delta shl 10) div Max; // shl 10
+
+ // shr 10 corrects that sat and f are shl 10
+ // the resulting p, q and t are unshifted
+
+ p := (Max*(1024-Sat)) shr 10;
+ q := (Max*(1024-(Sat*f) shr 10)) shr 10;
+ t := (Max*(1024-(Sat*(1024-f)) shr 10)) shr 10;
+
+ case HueInteger of
+ 0: begin Red := Max; Green := t; Blue := p; end; // (v,t,p)
+ 1: begin Red := q; Green := Max; Blue := p; end; // (q,v,p)
+ 2: begin Red := p; Green := Max; Blue := t; end; // (p,v,t)
+ 3: begin Red := p; Green := q; Blue := Max; end; // (p,q,v)
+ 4: begin Red := t; Green := p; Blue := Max; end; // (t,p,v)
+ 5: begin Red := Max; Green := p; Blue := q; end; // (v,p,q)
+ end;
+
+ {$IFDEF FPC_BIG_ENDIAN}
+ PixelColors[3] := Red;
+ PixelColors[2] := Green;
+ PixelColors[1] := Blue
+ {$ELSE}
+ PixelColors[0] := Red;
+ PixelColors[1] := Green;
+ PixelColors[2] := Blue;
+ {$ENDIF}
- PixelColors[0] := clr[0] shr 10;
- PixelColors[1] := clr[1] shr 10;
- PixelColors[2] := clr[2] shr 10;
+ end;
+ end;
Inc(Pixel, ImgSurface^.format.BytesPerPixel);
end;
diff --git a/unicode/src/base/UIni.pas b/unicode/src/base/UIni.pas
index e90ae31c..241b34e8 100644
--- a/unicode/src/base/UIni.pas
+++ b/unicode/src/base/UIni.pas
@@ -74,7 +74,7 @@ type
function RemoveFileExt(FullName: string): string;
function ExtractKeyIndex(const Key, Prefix, Suffix: string): integer;
function GetMaxKeyIndex(Keys: TStringList; const Prefix, Suffix: string): integer;
- function GetArrayIndex(const SearchArray: array of string; Value: string; CaseInsensitiv: Boolean = False): integer;
+ function GetArrayIndex(const SearchArray: array of string; Value: string; CaseInsensitiv: boolean = false): integer;
function ReadArrayIndex(const SearchArray: array of string; IniFile: TCustomIniFile;
IniSection: string; IniProperty: string; Default: integer): integer;
@@ -99,7 +99,7 @@ type
Difficulty: integer;
Language: integer;
Tabs: integer;
- Tabs_at_startup:integer; //Tabs at Startup fix
+ TabsAtStartup: integer; //Tabs at Startup fix
Sorting: integer;
Debug: integer;
@@ -107,7 +107,7 @@ type
Screens: integer;
Resolution: integer;
Depth: integer;
- VisualizerOption:integer;
+ VisualizerOption: integer;
FullScreen: integer;
TextureSize: integer;
SingWindow: integer;
@@ -122,8 +122,8 @@ type
BeatClick: integer;
SavePlayback: integer;
ThresholdIndex: integer;
- AudioOutputBufferSizeIndex:integer;
- VoicePassthrough:integer;
+ AudioOutputBufferSizeIndex: integer;
+ VoicePassthrough: integer;
//Song Preview
PreviewVolume: integer;
@@ -139,8 +139,8 @@ type
Theme: integer;
SkinNo: integer;
Color: integer;
- BackgroundMusicOption:integer;
-
+ BackgroundMusicOption: integer;
+
// Record
InputDeviceConfig: array of TInputDeviceConfig;
@@ -166,22 +166,20 @@ type
end;
var
- Ini: TIni;
- IResolution: array of string;
- ILanguage: array of string;
- ITheme: array of string;
- ISkin: array of string;
-
-
+ Ini: TIni;
+ IResolution: array of string;
+ ILanguage: array of string;
+ ITheme: array of string;
+ ISkin: array of string;
const
- IPlayers: array[0..4] of string = ('1', '2', '3', '4', '6');
- IPlayersVals: array[0..4] of integer = ( 1 , 2 , 3 , 4 , 6 );
+ IPlayers: array[0..4] of string = ('1', '2', '3', '4', '6');
+ IPlayersVals: array[0..4] of integer = ( 1 , 2 , 3 , 4 , 6 );
- IDifficulty: array[0..2] of string = ('Easy', 'Medium', 'Hard');
- ITabs: array[0..1] of string = ('Off', 'On');
+ IDifficulty: array[0..2] of string = ('Easy', 'Medium', 'Hard');
+ ITabs: array[0..1] of string = ('Off', 'On');
- ISorting: array[0..7] of string = ('Edition', 'Genre', 'Language', 'Folder', 'Title', 'Artist', 'Title2', 'Artist2');
+ ISorting: array[0..7] of string = ('Edition', 'Genre', 'Language', 'Folder', 'Title', 'Artist', 'Title2', 'Artist2');
sEdition = 0;
sGenre = 1;
sLanguage = 2;
@@ -191,51 +189,49 @@ const
sTitle2 = 6;
sArtist2 = 7;
- IDebug: array[0..1] of string = ('Off', 'On');
+ IDebug: array[0..1] of string = ('Off', 'On');
- IScreens: array[0..1] of string = ('1', '2');
- IFullScreen: array[0..1] of string = ('Off', 'On');
- IDepth: array[0..1] of string = ('16 bit', '32 bit');
- IVisualizer: array[0..2] of string = ('Off', 'WhenNoVideo','On');
+ IScreens: array[0..1] of string = ('1', '2');
+ IFullScreen: array[0..1] of string = ('Off', 'On');
+ IDepth: array[0..1] of string = ('16 bit', '32 bit');
+ IVisualizer: array[0..2] of string = ('Off', 'WhenNoVideo','On');
- IBackgroundMusic: array[0..1] of string = ('Off', 'On');
+ IBackgroundMusic: array[0..1] of string = ('Off', 'On');
+ ITextureSize: array[0..2] of string = ('128', '256', '512');
+ ITextureSizeVals: array[0..2] of integer = ( 128, 256, 512);
- ITextureSize: array[0..2] of string = ('128', '256', '512');
- ITextureSizeVals: array[0..2] of integer = ( 128, 256, 512);
-
- ISingWindow: array[0..1] of string = ('Small', 'Big');
+ ISingWindow: array[0..1] of string = ('Small', 'Big');
//SingBar Mod
- IOscilloscope: array[0..2] of string = ('Off', 'Osci', 'Bar');
-//IOscilloscope: array[0..1] of string = ('Off', 'On');
+ IOscilloscope: array[0..2] of string = ('Off', 'Osci', 'Bar');
+//IOscilloscope: array[0..1] of string = ('Off', 'On');
- ISpectrum: array[0..1] of string = ('Off', 'On');
- ISpectrograph: array[0..1] of string = ('Off', 'On');
- IMovieSize: array[0..2] of string = ('Half', 'Full [Vid]', 'Full [BG+Vid]');
+ ISpectrum: array[0..1] of string = ('Off', 'On');
+ ISpectrograph: array[0..1] of string = ('Off', 'On');
+ IMovieSize: array[0..2] of string = ('Half', 'Full [Vid]', 'Full [BG+Vid]');
- IClickAssist: array[0..1] of string = ('Off', 'On');
- IBeatClick: array[0..1] of string = ('Off', 'On');
- ISavePlayback: array[0..1] of string = ('Off', 'On');
+ IClickAssist: array[0..1] of string = ('Off', 'On');
+ IBeatClick: array[0..1] of string = ('Off', 'On');
+ ISavePlayback: array[0..1] of string = ('Off', 'On');
- IThreshold: array[0..3] of string = ('5%', '10%', '15%', '20%');
- IThresholdVals: array[0..3] of single = (0.05, 0.10, 0.15, 0.20);
+ IThreshold: array[0..3] of string = ('5%', '10%', '15%', '20%');
+ IThresholdVals: array[0..3] of single = (0.05, 0.10, 0.15, 0.20);
- IVoicePassthrough: array[0..1] of string = ('Off', 'On');
+ IVoicePassthrough: array[0..1] of string = ('Off', 'On');
IAudioOutputBufferSize: array[0..9] of string = ('Auto', '256', '512', '1024', '2048', '4096', '8192', '16384', '32768', '65536');
IAudioOutputBufferSizeVals: array[0..9] of integer = ( 0, 256, 512 , 1024 , 2048 , 4096 , 8192 , 16384 , 32768 , 65536 );
- IAudioInputBufferSize: array[0..9] of string = ('Auto', '256', '512', '1024', '2048', '4096', '8192', '16384', '32768', '65536');
- IAudioInputBufferSizeVals: array[0..9] of integer = ( 0, 256, 512 , 1024 , 2048 , 4096 , 8192 , 16384 , 32768 , 65536 );
+ IAudioInputBufferSize: array[0..9] of string = ('Auto', '256', '512', '1024', '2048', '4096', '8192', '16384', '32768', '65536');
+ IAudioInputBufferSizeVals: array[0..9] of integer = ( 0, 256, 512 , 1024 , 2048 , 4096 , 8192 , 16384 , 32768 , 65536 );
//Song Preview
- IPreviewVolume: array[0..10] of string = ('Off', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%');
- IPreviewVolumeVals: array[0..10] of single = ( 0, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00 );
-
- IPreviewFading: array[0..5] of string = ('Off', '1 Sec', '2 Secs', '3 Secs', '4 Secs', '5 Secs');
- IPreviewFadingVals: array[0..5] of integer = ( 0, 1, 2, 3, 4, 5 );
+ IPreviewVolume: array[0..10] of string = ('Off', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%');
+ IPreviewVolumeVals: array[0..10] of single = ( 0, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00 );
+ IPreviewFading: array[0..5] of string = ('Off', '1 Sec', '2 Secs', '3 Secs', '4 Secs', '5 Secs');
+ IPreviewFadingVals: array[0..5] of integer = ( 0, 1, 2, 3, 4, 5 );
ILyricsFont: array[0..2] of string = ('Plain', 'OLine1', 'OLine2');
ILyricsEffect: array[0..4] of string = ('Simple', 'Zoom', 'Slide', 'Ball', 'Shift');
@@ -247,7 +243,7 @@ const
// Advanced
ILoadAnimation: array[0..1] of string = ('Off', 'On');
IEffectSing: array[0..1] of string = ('Off', 'On');
- IScreenFade: array[0..1] of string =('Off', 'On');
+ IScreenFade: array[0..1] of string = ('Off', 'On');
IAskbeforeDel: array[0..1] of string = ('Off', 'On');
IOnSongClick: array[0..2] of string = ('Sing', 'Select Players', 'Open Menu');
ILineBonus: array[0..2] of string = ('Off', 'At Score', 'At Notes');
@@ -270,6 +266,7 @@ uses
USkins,
URecord,
UCommandLine,
+ UPath,
UUnicodeUtils;
(**
@@ -288,17 +285,22 @@ function TIni.ExtractKeyIndex(const Key, Prefix, Suffix: string): integer;
var
Value: string;
Start: integer;
+ PrefixPos, SuffixPos: integer;
begin
Result := -1;
- if Pos(Prefix, Key) > -1 then
- begin
- Start := Pos(Prefix, Key) + Length(Prefix);
+ PrefixPos := Pos(Prefix, Key);
+ if (PrefixPos <= 0) then
+ Exit;
+ SuffixPos := Pos(Suffix, Key);
+ if (SuffixPos <= 0) then
+ Exit;
- // copy all between prefix and suffix
- Value := Copy(Key, Start, Pos(Suffix, Key)-1 - Start);
- Result := StrToIntDef(Value, -1);
- end;
+ Start := PrefixPos + Length(Prefix);
+
+ // copy all between prefix and suffix
+ Value := Copy(Key, Start, SuffixPos - Start);
+ Result := StrToIntDef(Value, -1);
end;
(**
@@ -308,7 +310,7 @@ end;
*)
function TIni.GetMaxKeyIndex(Keys: TStringList; const Prefix, Suffix: string): integer;
var
- i: integer;
+ i: integer;
KeyIndex: integer;
begin
Result := -1;
@@ -326,7 +328,7 @@ end;
* or -1 if Value is not in SearchArray.
*)
function TIni.GetArrayIndex(const SearchArray: array of string; Value: string;
- CaseInsensitiv: Boolean = False): integer;
+ CaseInsensitiv: boolean = false): integer;
var
i: integer;
begin
@@ -362,15 +364,14 @@ begin
end;
end;
-
procedure TIni.LoadInputDeviceCfg(IniFile: TMemIniFile);
var
- DeviceCfg: PInputDeviceConfig;
- DeviceIndex: integer;
+ DeviceCfg: PInputDeviceConfig;
+ DeviceIndex: integer;
ChannelCount: integer;
ChannelIndex: integer;
- RecordKeys: TStringList;
- i: integer;
+ RecordKeys: TStringList;
+ i: integer;
begin
RecordKeys := TStringList.Create();
@@ -419,15 +420,15 @@ begin
RecordKeys.Free();
// MicBoost
- //MicBoost := GetArrayIndex(IMicBoost, IniFile.ReadString('Record', 'MicBoost', 'Off'));
+ MicBoost := GetArrayIndex(IMicBoost, IniFile.ReadString('Record', 'MicBoost', 'Off'));
// Threshold
- // ThresholdIndex := GetArrayIndex(IThreshold, IniFile.ReadString('Record', 'Threshold', IThreshold[1]));
+ ThresholdIndex := GetArrayIndex(IThreshold, IniFile.ReadString('Record', 'Threshold', IThreshold[1]));
end;
procedure TIni.SaveInputDeviceCfg(IniFile: TIniFile);
var
- DeviceIndex: integer;
- ChannelIndex: integer;
+ DeviceIndex: integer;
+ ChannelIndex: integer;
begin
for DeviceIndex := 0 to High(InputDeviceConfig) do
begin
@@ -436,7 +437,7 @@ begin
InputDeviceConfig[DeviceIndex].Name);
IniFile.WriteInteger('Record', Format('Input[%d]', [DeviceIndex+1]),
InputDeviceConfig[DeviceIndex].Input);
-
+
// Channel-to-Player Mapping
for ChannelIndex := 0 to High(InputDeviceConfig[DeviceIndex].ChannelToPlayerMap) do
begin
@@ -447,15 +448,15 @@ begin
end;
// MicBoost
- //IniFile.WriteString('Record', 'MicBoost', IMicBoost[MicBoost]);
+ IniFile.WriteString('Record', 'MicBoost', IMicBoost[MicBoost]);
// Threshold
- //IniFile.WriteString('Record', 'Threshold', IThreshold[ThresholdIndex]);
+ IniFile.WriteString('Record', 'Threshold', IThreshold[ThresholdIndex]);
end;
procedure TIni.LoadPaths(IniFile: TCustomIniFile);
var
PathStrings: TStringList;
- I: integer;
+ I: integer;
begin
PathStrings := TStringList.Create;
IniFile.ReadSection('Directories', PathStrings);
@@ -513,7 +514,7 @@ begin
Theme := GetArrayIndex(ITheme, IniFile.ReadString('Themes', 'Theme', 'DELUXE'), true);
if (Theme = -1) then
- Theme := 0;
+ Theme := 0;
// Skin
Skin.onThemeChange;
@@ -535,25 +536,25 @@ procedure TIni.LoadScreenModes(IniFile: TCustomIniFile);
var
Modes: PPSDL_Rect;
- I: integer;
+ I: integer;
begin
// Screens
Screens := GetArrayIndex(IScreens, IniFile.ReadString('Graphics', 'Screens', IScreens[0]));
-
+
// FullScreen
FullScreen := GetArrayIndex(IFullScreen, IniFile.ReadString('Graphics', 'FullScreen', 'On'));
// Resolution
SetLength(IResolution, 0);
-
+
// Check if there are any modes available
// TODO: we should seperate windowed and fullscreen modes. Otherwise it is not
// possible to select a reasonable fullscreen mode when in windowed mode
if IFullScreen[FullScreen] = 'On' then
Modes := SDL_ListModes(nil, SDL_OPENGL or SDL_FULLSCREEN)
- else
+ else
Modes := SDL_ListModes(nil, SDL_OPENGL or SDL_RESIZABLE) ;
-
+
if (Modes = nil) then
begin
Log.LogStatus( 'No resolutions Found' , 'Video');
@@ -572,7 +573,7 @@ begin
IResolution[7] := '1440x900';
IResolution[8] := '1600x1200';
IResolution[9] := '1680x1050';
-
+
Resolution := GetArrayIndex(IResolution, IniFile.ReadString('Graphics', 'Resolution', '800x600'));
if Resolution = -1 then
begin
@@ -628,7 +629,7 @@ end;
procedure TIni.Load();
var
IniFile: TMemIniFile;
- I: integer;
+ I: integer;
begin
GamePath := Platform.GetGameUserPath;
@@ -655,24 +656,24 @@ begin
NameTeam[I] := IniFile.ReadString('NameTeam', 'T'+IntToStr(I+1), 'Team'+IntToStr(I+1));
for I := 0 to 11 do
NameTemplate[I] := IniFile.ReadString('NameTemplate', 'Name'+IntToStr(I+1), 'Template'+IntToStr(I+1));
-
+
// Players
Players := GetArrayIndex(IPlayers, IniFile.ReadString('Game', 'Players', IPlayers[0]));
-
+
// Difficulty
Difficulty := GetArrayIndex(IDifficulty, IniFile.ReadString('Game', 'Difficulty', 'Easy'));
-
+
// Language
Language := GetArrayIndex(ILanguage, IniFile.ReadString('Game', 'Language', 'English'));
//Language.ChangeLanguage(ILanguage[Language]);
-
+
// Tabs
Tabs := GetArrayIndex(ITabs, IniFile.ReadString('Game', 'Tabs', ITabs[0]));
- Tabs_at_startup := Tabs; //Tabs at Startup fix
-
+ TabsAtStartup := Tabs; //Tabs at Startup fix
+
// Song Sorting
Sorting := GetArrayIndex(ISorting, IniFile.ReadString('Game', 'Sorting', ISorting[0]));
-
+
// Debug
Debug := GetArrayIndex(IDebug, IniFile.ReadString('Game', 'Debug', IDebug[0]));
@@ -710,7 +711,7 @@ begin
//Preview Volume
PreviewVolume := GetArrayIndex(IPreviewVolume, IniFile.ReadString('Sound', 'PreviewVolume', IPreviewVolume[7]));
-
+
//Preview Fading
PreviewFading := GetArrayIndex(IPreviewFading, IniFile.ReadString('Sound', 'PreviewFading', IPreviewFading[1]));
@@ -778,13 +779,13 @@ begin
Joypad := GetArrayIndex(IJoypad, IniFile.ReadString('Controller', 'Joypad', IJoypad[0]));
LoadPaths(IniFile);
-
+
IniFile.Free;
end;
procedure TIni.Save;
var
- IniFile: TIniFile;
+ IniFile: TIniFile;
begin
if (FileExists(Filename) and FileIsReadOnly(Filename)) then
begin
@@ -859,7 +860,7 @@ begin
// Song Preview
IniFile.WriteString('Sound', 'PreviewVolume', IPreviewVolume[PreviewVolume]);
-
+
// PreviewFading
IniFile.WriteString('Sound', 'PreviewFading', IPreviewFading[PreviewFading]);
diff --git a/unicode/src/base/ULanguage.pas b/unicode/src/base/ULanguage.pas
index a89ded2d..f79f4165 100644
--- a/unicode/src/base/ULanguage.pas
+++ b/unicode/src/base/ULanguage.pas
@@ -78,7 +78,8 @@ uses
IniFiles,
Classes,
SysUtils,
- ULog;
+ ULog,
+ UPath;
{**
* LoadList, set default language, set standard implode glues
diff --git a/unicode/src/base/ULog.pas b/unicode/src/base/ULog.pas
index 582120bc..a872729a 100644
--- a/unicode/src/base/ULog.pas
+++ b/unicode/src/base/ULog.pas
@@ -132,7 +132,8 @@ uses
UMain,
UTime,
UCommon,
- UCommandLine;
+ UCommandLine,
+ UPath;
(*
* Write to console if in debug mode (Thread-safe).
diff --git a/unicode/src/base/UMain.pas b/unicode/src/base/UMain.pas
index ce25d16e..8d11b91d 100644
--- a/unicode/src/base/UMain.pas
+++ b/unicode/src/base/UMain.pas
@@ -35,109 +35,15 @@ interface
uses
SysUtils,
- Classes,
- SDL,
- UMusic,
- URecord,
- UTime,
- UDisplay,
- UIni,
- ULog,
- ULyrics,
- UScreenSing,
- USong,
- gl;
-
-type
- PPLayerNote = ^TPlayerNote;
- TPlayerNote = record
- Start: integer;
- Length: integer;
- Detect: real; // accurate place, detected in the note
- Tone: real;
- Perfect: boolean; // true if the note matches the original one, lit the star
- Hit: boolean; // true if the note Hits the Line
- end;
-
- PPLayer = ^TPlayer;
- TPlayer = record
- Name: string;
-
- // Index in Teaminfo record
- TeamID: Byte;
- PlayerID: Byte;
-
- // Scores
- Score: real;
- ScoreLine: real;
- ScoreGolden: real;
-
- ScoreInt: integer;
- ScoreLineInt: integer;
- ScoreGoldenInt: integer;
- ScoreTotalInt: integer;
-
- // LineBonus
- ScoreLast: Real;//Last Line Score
-
- // PerfectLineTwinkle (effect)
- LastSentencePerfect: Boolean;
-
- HighNote: integer; // index of last note (= High(Note)?)
- LengthNote: integer; // number of notes (= Length(Note)?).
- Note: array of TPlayerNote;
- end;
-
+ SDL;
var
- // Absolute Paths
- GamePath: string;
- SoundPath: string;
- SongPaths: TStringList;
- LogPath: string;
- ThemePath: string;
- SkinsPath: string;
- ScreenshotsPath: string;
- CoverPaths: TStringList;
- LanguagesPath: string;
- PluginPath: string;
- VisualsPath: string;
- FontPath: string;
- ResourcesPath: string;
- PlayListPath: string;
-
- Done: Boolean;
- // FIXME: ConversionFileName should not be global
- ConversionFileName: string;
- Restart: boolean;
-
- // player and music info
- Player: array of TPlayer;
- PlayersPlay: integer;
-
- CurrentSong : TSong;
-
-const
- MAX_SONG_SCORE = 10000; // max. achievable points per song
- MAX_SONG_LINE_BONUS = 1000; // max. achievable line bonus per song
-
-
-function FindPath(out PathResult: string; const RequestedPath: string; NeedsWritePermission: boolean): boolean;
-procedure InitializePaths;
-procedure AddSongPath(const Path: string);
+ Done: boolean;
+ Restart: boolean;
procedure Main;
procedure MainLoop;
procedure CheckEvents;
-procedure Sing(Screen: TScreenSing);
-procedure NewSentence(Screen: TScreenSing);
-procedure NewBeatClick(Screen: TScreenSing); // executed when on then new beat for click
-procedure NewBeatDetect(Screen: TScreenSing); // executed when on then new beat for detection
-procedure NewNote(Screen: TScreenSing); // detect note
-function GetMidBeat(Time: real): real;
-function GetTimeFromBeat(Beat: integer): real;
-procedure ClearScores(PlayerNum: integer);
-
type
TMainThreadExecProc = procedure(Data: Pointer);
@@ -155,48 +61,51 @@ const
*}
procedure MainThreadExec(Proc: TMainThreadExecProc; Data: Pointer);
-
implementation
uses
Math,
- StrUtils,
- USongs,
- UJoystick,
+ gl,
+{
+ SDL_ttf,
+ UParty,
+ UCore,
+}
+ UCatCovers,
UCommandLine,
- ULanguage,
- //SDL_ttf,
- USkins,
+ UCommon,
+ UConfig,
UCovers,
- UCatCovers,
UDataBase,
- UPlaylist,
+ UDisplay,
UDLLManager,
- UParty,
- UConfig,
- UCore,
- UCommon,
UGraphic,
UGraphicClasses,
- UPluginDefs,
+ UIni,
+ UJoystick,
+ ULanguage,
+ ULog,
+ UPath,
+ UPlaylist,
+ UMusic,
UPlatform,
- UThemes;
-
-
-
+ USkins,
+ USongs,
+ UThemes,
+ UTime;
procedure Main;
var
- WndTitle: string;
+ WindowTitle: string;
begin
{$IFNDEF Debug}
try
{$ENDIF}
- WndTitle := USDXVersionStr;
+ WindowTitle := USDXVersionStr;
Platform.Init;
- if Platform.TerminateIfAlreadyRunning(WndTitle) then
+ if Platform.TerminateIfAlreadyRunning(WindowTitle) then
Exit;
// fix floating-point exceptions (FPE)
@@ -210,11 +119,11 @@ begin
DecimalSeparator := '.';
//------------------------------
- //StartUp - Create Classes and Load Files
+ // StartUp - create classes and load files
//------------------------------
- // Initialize SDL
- // Without SDL_INIT_TIMER SDL_GetTicks() might return strange values
+ // initialize SDL
+ // without SDL_INIT_TIMER SDL_GetTicks() might return strange values
SDL_Init(SDL_INIT_VIDEO or SDL_INIT_TIMER);
SDL_EnableUnicode(1);
@@ -226,7 +135,7 @@ begin
// Log + Benchmark
Log := TLog.Create;
- Log.Title := WndTitle;
+ Log.Title := WindowTitle;
Log.FileOutputEnabled := not Params.NoLog;
Log.BenchmarkStart(0);
@@ -237,19 +146,19 @@ begin
Log.LogStatus('Load Language', 'Initialization');
Language := TLanguage.Create;
- // Add Const Values:
+ // add const values:
Language.AddConst('US_VERSION', USDXVersionStr);
Log.BenchmarkEnd(1);
Log.LogBenchmark('Loading Language', 1);
- {
+{
// SDL_ttf (Not used yet, maybe in version 1.5)
Log.BenchmarkStart(1);
Log.LogStatus('Initialize SDL_ttf', 'Initialization');
TTF_Init();
Log.BenchmarkEnd(1);
Log.LogBenchmark('Initializing SDL_ttf', 1);
- }
+}
// Skin
Log.BenchmarkStart(1);
@@ -264,7 +173,7 @@ begin
Ini := TIni.Create;
Ini.Load;
- //it's possible that this is the first run, create a .ini file if neccessary
+ // it is possible that this is the first run, create a .ini file if neccessary
Log.LogStatus('Write Ini', 'Initialization');
Ini.Save;
@@ -327,18 +236,19 @@ begin
Log.BenchmarkEnd(1);
Log.LogBenchmark('Loading PluginManager', 1);
- {// Party Mode Manager
+{
+ // Party Mode Manager
Log.BenchmarkStart(1);
Log.LogStatus('PartySession Manager', 'Initialization');
PartySession := TPartySession.Create; //Load PartySession
-
Log.BenchmarkEnd(1);
- Log.LogBenchmark('Loading PartySession Manager', 1); }
+ Log.LogBenchmark('Loading PartySession Manager', 1);
+}
// Graphics
Log.BenchmarkStart(1);
Log.LogStatus('Initialize 3D', 'Initialization');
- Initialize3D(WndTitle);
+ Initialize3D(WindowTitle);
Log.BenchmarkEnd(1);
Log.LogBenchmark('Initializing 3D', 1);
@@ -370,7 +280,7 @@ begin
Log.LogBenchmark('Loading Particle System', 1);
// Joypad
- if (Ini.Joypad = 1) OR (Params.Joypad) then
+ if (Ini.Joypad = 1) or (Params.Joypad) then
begin
Log.BenchmarkStart(1);
Log.LogStatus('Initialize Joystick', 'Initialization');
@@ -383,19 +293,21 @@ begin
Log.LogBenchmark('Loading Time', 0);
Log.LogStatus('Creating Core', 'Initialization');
- {Core := TCore.Create(
+{
+ Core := TCore.Create(
USDXShortVersionStr,
MakeVersion(USDX_VERSION_MAJOR,
USDX_VERSION_MINOR,
USDX_VERSION_RELEASE,
chr(0))
- ); }
+ );
+}
Log.LogStatus('Running Core', 'Initialization');
//Core.Run;
//------------------------------
- //Start- Mainloop
+ // Start Mainloop
//------------------------------
Log.LogStatus('Main Loop', 'Initialization');
MainLoop;
@@ -404,12 +316,12 @@ begin
finally
{$ENDIF}
//------------------------------
- //Finish Application
+ // Finish Application
//------------------------------
// TODO:
// call an uninitialize routine for every initialize step
- // or at least use the corresponding Free-Methods
+ // or at least use the corresponding Free methods
FinalizeMedia();
@@ -428,7 +340,7 @@ end;
procedure MainLoop;
var
- Delay: integer;
+ Delay: integer;
const
MAX_FPS = 100;
begin
@@ -445,7 +357,7 @@ begin
CheckEvents;
// display
- done := not Display.Draw;
+ Done := not Display.Draw;
SwapBuffers;
// delay
@@ -466,7 +378,7 @@ begin
end;
end;
-End;
+end;
procedure CheckEvents;
var
@@ -474,7 +386,7 @@ var
begin
if Assigned(Display.NextScreen) then
Exit;
-
+
while (SDL_PollEvent(@Event) <> 0) do
begin
case Event.type_ of
@@ -482,19 +394,19 @@ begin
begin
Display.Fade := 0;
Display.NextScreenWithCheck := nil;
- Display.CheckOK := True;
+ Display.CheckOK := true;
end;
SDL_MOUSEBUTTONDOWN:
begin
- {
+{
with Event.button do
begin
- if State = SDL_BUTTON_LEFT Then
+ if State = SDL_BUTTON_LEFT then
begin
//
end;
end;
- }
+}
end;
SDL_VIDEORESIZE:
begin
@@ -503,7 +415,7 @@ begin
// Note: do NOT call SDL_SetVideoMode on Windows and MacOSX here.
// This would create a new OpenGL render-context and all texture data
// would be invalidated.
- // On Linux the mode MUST be resetted, otherwise graphics will be corrupted.
+ // On Linux the mode MUST be reset, otherwise graphics will be corrupted.
{$IF Defined(Linux) or Defined(FreeBSD)}
if boolean( Ini.FullScreen ) then
SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN)
@@ -525,7 +437,7 @@ begin
// FIXME: SDL_SetVideoMode creates a new OpenGL RC so we have to
// reload all texture data (-> whitescreen bug).
- // Only Linux (and FreeBSD) is able to handle screen-switching this way.
+ // Only Linux and FreeBSD are able to handle screen-switching this way.
{$IF Defined(Linux) or Defined(FreeBSD)}
if boolean( Ini.FullScreen ) then
begin
@@ -547,16 +459,16 @@ begin
// if there is a visible popup then let it handle input instead of underlying screen
// shoud be done in a way to be sure the topmost popup has preference (maybe error, then check)
else if (ScreenPopupError <> nil) and (ScreenPopupError.Visible) then
- done := not ScreenPopupError.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True)
+ Done := not ScreenPopupError.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, true)
else if (ScreenPopupCheck <> nil) and (ScreenPopupCheck.Visible) then
- done := not ScreenPopupCheck.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True)
+ Done := not ScreenPopupCheck.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, true)
else
begin
// check if screen wants to exit
- done := not Display.CurrentScreen^.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True);
+ Done := not Display.CurrentScreen^.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, true);
// if screen wants to exit
- if done then
+ if Done then
begin
// if question option is enabled then show exit popup
if (Ini.AskbeforeDel = 1) then
@@ -567,7 +479,7 @@ begin
begin
Display.Fade := 0;
Display.NextScreenWithCheck := nil;
- Display.CheckOK := True;
+ Display.CheckOK := true;
end;
end;
@@ -604,573 +516,4 @@ begin
SDL_PushEvent(@Event);
end;
-function GetTimeForBeats(BPM, Beats: real): real;
-begin
- Result := 60 / BPM * Beats;
-end;
-
-function GetBeats(BPM, msTime: real): real;
-begin
- Result := BPM * msTime / 60;
-end;
-
-procedure GetMidBeatSub(BPMNum: integer; var Time: real; var CurBeat: real);
-var
- NewTime: real;
-begin
- if High(CurrentSong.BPM) = BPMNum then
- begin
- // last BPM
- CurBeat := CurrentSong.BPM[BPMNum].StartBeat + GetBeats(CurrentSong.BPM[BPMNum].BPM, Time);
- Time := 0;
- end
- else
- begin
- // not last BPM
- // count how much time is it for start of the new BPM and store it in NewTime
- NewTime := GetTimeForBeats(CurrentSong.BPM[BPMNum].BPM, CurrentSong.BPM[BPMNum+1].StartBeat - CurrentSong.BPM[BPMNum].StartBeat);
-
- // compare it to remaining time
- if (Time - NewTime) > 0 then
- begin
- // there is still remaining time
- CurBeat := CurrentSong.BPM[BPMNum].StartBeat;
- Time := Time - NewTime;
- end
- else
- begin
- // there is no remaining time
- CurBeat := CurrentSong.BPM[BPMNum].StartBeat + GetBeats(CurrentSong.BPM[BPMNum].BPM, Time);
- Time := 0;
- end; // if
- end; // if
-end;
-
-function GetMidBeat(Time: real): real;
-var
- CurBeat: real;
- CurBPM: integer;
-begin
- // static BPM
- if Length(CurrentSong.BPM) = 1 then
- begin
- Result := Time * CurrentSong.BPM[0].BPM / 60;
- end
- // variable BPM
- else if Length(CurrentSong.BPM) > 1 then
- begin
- CurBeat := 0;
- CurBPM := 0;
- while (Time > 0) do
- begin
- GetMidBeatSub(CurBPM, Time, CurBeat);
- Inc(CurBPM);
- end;
-
- Result := CurBeat;
- end
- // invalid BPM
- else
- begin
- Result := 0;
- end;
-end;
-
-function GetTimeFromBeat(Beat: integer): real;
-var
- CurBPM: integer;
-begin
- // static BPM
- if Length(CurrentSong.BPM) = 1 then
- begin
- Result := CurrentSong.GAP / 1000 + Beat * 60 / CurrentSong.BPM[0].BPM;
- end
- // variable BPM
- else if Length(CurrentSong.BPM) > 1 then
- begin
- Result := CurrentSong.GAP / 1000;
- CurBPM := 0;
- while (CurBPM <= High(CurrentSong.BPM)) and
- (Beat > CurrentSong.BPM[CurBPM].StartBeat) do
- begin
- if (CurBPM < High(CurrentSong.BPM)) and
- (Beat >= CurrentSong.BPM[CurBPM+1].StartBeat) then
- begin
- // full range
- Result := Result + (60 / CurrentSong.BPM[CurBPM].BPM) *
- (CurrentSong.BPM[CurBPM+1].StartBeat - CurrentSong.BPM[CurBPM].StartBeat);
- end;
-
- if (CurBPM = High(CurrentSong.BPM)) or
- (Beat < CurrentSong.BPM[CurBPM+1].StartBeat) then
- begin
- // in the middle
- Result := Result + (60 / CurrentSong.BPM[CurBPM].BPM) *
- (Beat - CurrentSong.BPM[CurBPM].StartBeat);
- end;
- Inc(CurBPM);
- end;
-
- {
- while (Time > 0) do
- begin
- GetMidBeatSub(CurBPM, Time, CurBeat);
- Inc(CurBPM);
- end;
- }
- end
- // invalid BPM
- else
- begin
- Result := 0;
- end;
-end;
-
-procedure Sing(Screen: TScreenSing);
-var
- Count: integer;
- CountGr: integer;
- CP: integer;
- N: integer;
-begin
- LyricsState.UpdateBeats();
-
- // sentences routines
- for CountGr := 0 to 0 do //High(Lines)
- begin;
- CP := CountGr;
- // old parts
- LyricsState.OldLine := Lines[CP].Current;
-
- // choose current parts
- for Count := 0 to Lines[CP].High do
- begin
- if LyricsState.CurrentBeat >= Lines[CP].Line[Count].Start then
- Lines[CP].Current := Count;
- end;
-
- // clean player note if there is a new line
- // (optimization on halfbeat time)
- if Lines[CP].Current <> LyricsState.OldLine then
- NewSentence(Screen);
-
- end; // for CountGr
-
- // make some operations on clicks
- if {(LyricsState.CurrentBeatC >= 0) and }(LyricsState.OldBeatC <> LyricsState.CurrentBeatC) then
- NewBeatClick(Screen);
-
- // make some operations when detecting new voice pitch
- if (LyricsState.CurrentBeatD >= 0) and (LyricsState.OldBeatD <> LyricsState.CurrentBeatD) then
- NewBeatDetect(Screen);
-end;
-
-procedure NewSentence(Screen: TScreenSing);
-var
- i: Integer;
-begin
- // clean note of player
- for i := 0 to High(Player) do
- begin
- Player[i].LengthNote := 0;
- Player[i].HighNote := -1;
- SetLength(Player[i].Note, 0);
- end;
-
- // on sentence change...
- Screen.onSentenceChange(Lines[0].Current);
-end;
-
-procedure NewBeatClick;
-var
- Count: integer;
-begin
- // beat click
- if ((Ini.BeatClick = 1) and
- ((LyricsState.CurrentBeatC + Lines[0].Resolution + Lines[0].NotesGAP) mod Lines[0].Resolution = 0)) then
- begin
- AudioPlayback.PlaySound(SoundLib.Click);
- end;
-
- for Count := 0 to Lines[0].Line[Lines[0].Current].HighNote do
- begin
- if (Lines[0].Line[Lines[0].Current].Note[Count].Start = LyricsState.CurrentBeatC) then
- begin
- // click assist
- if Ini.ClickAssist = 1 then
- AudioPlayback.PlaySound(SoundLib.Click);
-
- // drum machine
- (*
- TempBeat := LyricsState.CurrentBeat;// + 2;
- if (TempBeat mod 8 = 0) then Music.PlayDrum;
- if (TempBeat mod 8 = 4) then Music.PlayClap;
- //if (TempBeat mod 4 = 2) then Music.PlayHihat;
- if (TempBeat mod 4 <> 0) then Music.PlayHihat;
- *)
- end;
- end;
-end;
-
-procedure NewBeatDetect(Screen: TScreenSing);
-begin
- NewNote(Screen);
-end;
-
-procedure NewNote(Screen: TScreenSing);
-var
- LineFragmentIndex: integer;
- CurrentLineFragment: PLineFragment;
- PlayerIndex: integer;
- CurrentSound: TCaptureBuffer;
- CurrentPlayer: PPlayer;
- LastPlayerNote: PPlayerNote;
- Line: PLine;
- SentenceIndex: integer;
- SentenceMin: integer;
- SentenceMax: integer;
- SentenceDetected: integer; // sentence of detected note
- NoteAvailable: boolean;
- NewNote: boolean;
- Range: integer;
- NoteHit: boolean;
- MaxSongPoints: integer; // max. points for the song (without line bonus)
- MaxLinePoints: Real; // max. points for the current line
-begin
- // TODO: add duet mode support
- // use Lines[LineSetIndex] with LineSetIndex depending on the current player
-
- // count min and max sentence range for checking (detection is delayed to the notes we see on the screen)
- SentenceMin := Lines[0].Current-1;
- if (SentenceMin < 0) then
- SentenceMin := 0;
- SentenceMax := Lines[0].Current;
-
- // check for an active note at the current time defined in the lyrics
- NoteAvailable := false;
- SentenceDetected := SentenceMin;
- for SentenceIndex := SentenceMin to SentenceMax do
- begin
- Line := @Lines[0].Line[SentenceIndex];
- for LineFragmentIndex := 0 to Line.HighNote do
- begin
- CurrentLineFragment := @Line.Note[LineFragmentIndex];
- // check if line is active
- if ((CurrentLineFragment.Start <= LyricsState.CurrentBeatD) and
- (CurrentLineFragment.Start + CurrentLineFragment.Length-1 >= LyricsState.CurrentBeatD)) and
- (CurrentLineFragment.NoteType <> ntFreestyle) and // but ignore FreeStyle notes
- (CurrentLineFragment.Length > 0) then // and make sure the note lengths is at least 1
- begin
- SentenceDetected := SentenceIndex;
- NoteAvailable := true;
- Break;
- end;
- end;
- // TODO: break here, if NoteAvailable is true? We would then use the first instead
- // of the last note matching the current beat if notes overlap. But notes
- // should not overlap at all.
- //if (NoteAvailable) then
- // Break;
- end;
-
- // analyze player signals
- for PlayerIndex := 0 to PlayersPlay-1 do
- begin
- CurrentPlayer := @Player[PlayerIndex];
- CurrentSound := AudioInputProcessor.Sound[PlayerIndex];
-
- // At the beginning of the song there is no previous note
- if (Length(CurrentPlayer.Note) > 0) then
- LastPlayerNote := @CurrentPlayer.Note[CurrentPlayer.HighNote]
- else
- LastPlayerNote := nil;
-
- // analyze buffer
- CurrentSound.AnalyzeBuffer;
-
- // add some noise
- // TODO: do we need this?
- //LyricsState.Tone := LyricsState.Tone + Round(Random(3)) - 1;
-
- // add note if possible
- if (CurrentSound.ToneValid and NoteAvailable) then
- begin
- Line := @Lines[0].Line[SentenceDetected];
-
- // process until last note
- for LineFragmentIndex := 0 to Line.HighNote do
- begin
- CurrentLineFragment := @Line.Note[LineFragmentIndex];
- if (CurrentLineFragment.Start <= LyricsState.OldBeatD+1) and
- (CurrentLineFragment.Start + CurrentLineFragment.Length > LyricsState.OldBeatD+1) then
- begin
- // compare notes (from song-file and from player)
-
- // move players tone to proper octave
- while (CurrentSound.Tone - CurrentLineFragment.Tone > 6) do
- CurrentSound.Tone := CurrentSound.Tone - 12;
-
- while (CurrentSound.Tone - CurrentLineFragment.Tone < -6) do
- CurrentSound.Tone := CurrentSound.Tone + 12;
-
- // half size notes patch
- NoteHit := false;
-
- //if Ini.Difficulty = 0 then Range := 2;
- //if Ini.Difficulty = 1 then Range := 1;
- //if Ini.Difficulty = 2 then Range := 0;
- Range := 2 - Ini.Difficulty;
-
- // check if the player hit the correct tone within the tolerated range
- if (Abs(CurrentLineFragment.Tone - CurrentSound.Tone) <= Range) then
- begin
- // adjust the players tone to the correct one
- // TODO: do we need to do this?
- CurrentSound.Tone := CurrentLineFragment.Tone;
-
- // half size notes patch
- NoteHit := true;
-
- if (Ini.LineBonus > 0) then
- MaxSongPoints := MAX_SONG_SCORE - MAX_SONG_LINE_BONUS
- else
- MaxSongPoints := MAX_SONG_SCORE;
-
- // Note: ScoreValue is the sum of all note values of the song
- MaxLinePoints := MaxSongPoints / Lines[0].ScoreValue;
-
- // FIXME: is this correct? Why do we add the points for a whole line
- // if just one note is correct?
- case CurrentLineFragment.NoteType of
- ntNormal: CurrentPlayer.Score := CurrentPlayer.Score + MaxLinePoints;
- ntGolden: CurrentPlayer.ScoreGolden := CurrentPlayer.ScoreGolden + MaxLinePoints;
- end;
-
- CurrentPlayer.ScoreInt := Floor(CurrentPlayer.Score / 10) * 10;
- CurrentPlayer.ScoreGoldenInt := Floor(CurrentPlayer.ScoreGolden / 10) * 10;
-
- CurrentPlayer.ScoreTotalInt := CurrentPlayer.ScoreInt +
- CurrentPlayer.ScoreGoldenInt +
- CurrentPlayer.ScoreLineInt;
- end;
-
- end; // operation
- end; // for
-
- // check if we have to add a new note or extend the note's length
- if (SentenceDetected = SentenceMax) then
- begin
- // we will add a new note
- NewNote := true;
-
- // if previous note (if any) was the same, extend prrevious note
- if ((CurrentPlayer.LengthNote > 0) and
- (LastPlayerNote <> nil) and
- (LastPlayerNote.Tone = CurrentSound.Tone) and
- ((LastPlayerNote.Start + LastPlayerNote.Length) = LyricsState.CurrentBeatD)) then
- begin
- NewNote := false;
- end;
-
- // if is not as new note to control
- for LineFragmentIndex := 0 to Line.HighNote do
- begin
- if (Line.Note[LineFragmentIndex].Start = LyricsState.CurrentBeatD) then
- NewNote := true;
- end;
-
- // add new note
- if NewNote then
- begin
- // new note
- Inc(CurrentPlayer.LengthNote);
- Inc(CurrentPlayer.HighNote);
- SetLength(CurrentPlayer.Note, CurrentPlayer.LengthNote);
-
- // update player's last note
- LastPlayerNote := @CurrentPlayer.Note[CurrentPlayer.HighNote];
- with LastPlayerNote^ do
- begin
- Start := LyricsState.CurrentBeatD;
- Length := 1;
- Tone := CurrentSound.Tone; // Tone || ToneAbs
- Detect := LyricsState.MidBeat;
- Hit := NoteHit; // half note patch
- end;
- end
- else
- begin
- // extend note length
- if (LastPlayerNote <> nil) then
- Inc(LastPlayerNote.Length);
- end;
-
- // check for perfect note and then lit the star (on Draw)
- for LineFragmentIndex := 0 to Line.HighNote do
- begin
- CurrentLineFragment := @Line.Note[LineFragmentIndex];
- if (CurrentLineFragment.Start = LastPlayerNote.Start) and
- (CurrentLineFragment.Length = LastPlayerNote.Length) and
- (CurrentLineFragment.Tone = LastPlayerNote.Tone) then
- begin
- LastPlayerNote.Perfect := true;
- end;
- end;
- end; // if SentenceDetected = SentenceMax
-
- end; // if Detected
- end; // for PlayerIndex
-
- //Log.LogStatus('EndBeat', 'NewBeat');
-
- // on sentence end -> for LineBonus and display of SingBar (rating pop-up)
- if (SentenceDetected >= Low(Lines[0].Line)) and
- (SentenceDetected <= High(Lines[0].Line)) then
- begin
- Line := @Lines[0].Line[SentenceDetected];
- CurrentLineFragment := @Line.Note[Line.HighNote];
- if ((CurrentLineFragment.Start + CurrentLineFragment.Length - 1) = LyricsState.CurrentBeatD) then
- begin
- if assigned(Screen) then
- Screen.OnSentenceEnd(SentenceDetected);
- end;
- end;
-
-end;
-
-procedure ClearScores(PlayerNum: integer);
-begin
- with Player[PlayerNum] do
- begin
- Score := 0;
- ScoreLine := 0;
- ScoreGolden := 0;
-
- ScoreInt := 0;
- ScoreLineInt := 0;
- ScoreGoldenInt:= 0;
- ScoreTotalInt := 0;
-
- ScoreLast := 0;
-
- LastSentencePerfect := False;
- end;
-end;
-
-procedure AddSpecialPath(var PathList: TStringList; const Path: string);
-var
- I: integer;
- PathAbs, OldPathAbs: string;
-begin
- if (PathList = nil) then
- PathList := TStringList.Create;
-
- if (Path = '') or not ForceDirectories(Path) then
- Exit;
-
- PathAbs := IncludeTrailingPathDelimiter(ExpandFileName(Path));
-
- // check if path or a part of the path was already added
- for I := 0 to PathList.Count-1 do
- begin
- OldPathAbs := IncludeTrailingPathDelimiter(ExpandFileName(PathList[I]));
- // check if the new directory is a sub-directory of a previously added one.
- // This is also true, if both paths point to the same directories.
- if (AnsiStartsText(OldPathAbs, PathAbs)) then
- begin
- // ignore the new path
- Exit;
- end;
-
- // check if a previously added directory is a sub-directory of the new one.
- if (AnsiStartsText(PathAbs, OldPathAbs)) then
- begin
- // replace the old with the new one.
- PathList[I] := PathAbs;
- Exit;
- end;
- end;
-
- PathList.Add(PathAbs);
-end;
-
-procedure AddSongPath(const Path: string);
-begin
- AddSpecialPath(SongPaths, Path);
-end;
-
-procedure AddCoverPath(const Path: string);
-begin
- AddSpecialPath(CoverPaths, Path);
-end;
-
-(**
- * Initialize a path variable
- * After setting paths, make sure that paths exist
- *)
-function FindPath(out PathResult: string; const RequestedPath: string; NeedsWritePermission: boolean): boolean;
-begin
- Result := false;
-
- if (RequestedPath = '') then
- Exit;
-
- // Make sure the directory exists
- if (not ForceDirectories(RequestedPath)) then
- begin
- PathResult := '';
- Exit;
- end;
-
- PathResult := IncludeTrailingPathDelimiter(RequestedPath);
-
- if (NeedsWritePermission) and
- (FileIsReadOnly(RequestedPath)) then
- begin
- Exit;
- end;
-
- Result := true;
-end;
-
-(**
- * Function sets all absolute paths e.g. song path and makes sure the directorys exist
- *)
-procedure InitializePaths;
-begin
- // Log directory (must be writable)
- if (not FindPath(LogPath, Platform.GetLogPath, true)) then
- begin
- Log.FileOutputEnabled := false;
- Log.LogWarn('Log directory "'+ Platform.GetLogPath +'" not available', 'InitializePaths');
- end;
-
- FindPath(SoundPath, Platform.GetGameSharedPath + 'sounds', false);
- FindPath(ThemePath, Platform.GetGameSharedPath + 'themes', false);
- FindPath(SkinsPath, Platform.GetGameSharedPath + 'themes', false);
- FindPath(LanguagesPath, Platform.GetGameSharedPath + 'languages', false);
- FindPath(PluginPath, Platform.GetGameSharedPath + 'plugins', false);
- FindPath(VisualsPath, Platform.GetGameSharedPath + 'visuals', false);
- FindPath(FontPath, Platform.GetGameSharedPath + 'fonts', false);
- FindPath(ResourcesPath, Platform.GetGameSharedPath + 'resources', false);
-
- // Playlists are not shared as we need one directory to write too
- FindPath(PlaylistPath, Platform.GetGameUserPath + 'playlists', true);
-
- // Screenshot directory (must be writable)
- if (not FindPath(ScreenshotsPath, Platform.GetGameUserPath + 'screenshots', true)) then
- begin
- Log.LogWarn('Screenshot directory "'+ Platform.GetGameUserPath +'" not available', 'InitializePaths');
- end;
-
- // Add song paths
- AddSongPath(Params.SongPath);
- AddSongPath(Platform.GetGameSharedPath + 'songs');
- AddSongPath(Platform.GetGameUserPath + 'songs');
-
- // Add category cover paths
- AddCoverPath(Platform.GetGameSharedPath + 'covers');
- AddCoverPath(Platform.GetGameUserPath + 'covers');
-end;
-
end.
diff --git a/unicode/src/base/UMusic.pas b/unicode/src/base/UMusic.pas
index 70e8d63c..19c3b942 100644
--- a/unicode/src/base/UMusic.pas
+++ b/unicode/src/base/UMusic.pas
@@ -35,11 +35,21 @@ interface
uses
UTime,
+ SysUtils,
Classes;
type
TNoteType = (ntFreestyle, ntNormal, ntGolden);
+const
+ // ScoreFactor defines how a notehit of a specified notetype is
+ // measured in comparison to the other types
+ // 0 means this notetype is not rated at all
+ // 2 means a hit of this notetype will be rated w/ twice as much
+ // points as a hit of a notetype w/ ScoreFactor 1
+ ScoreFactor: array[TNoteType] of integer = (0, 1, 2);
+
+type
(**
* TLineFragment represents a fragment of a lyrics line.
* This is a text-fragment (e.g. a syllable) assigned to a note pitch,
@@ -63,7 +73,7 @@ type
TLine = record
Start: integer; // the start beat of this line (<> start beat of the first note of this line)
Lyric: UTF8String;
- LyricWidth: real; // @deprecated: width of the line in pixels.
+ //LyricWidth: real; // @deprecated: width of the line in pixels.
// Do not use this as the width is not correct.
// Use TLyricsEngine.GetUpperLine().Width instead.
End_: integer;
@@ -81,7 +91,7 @@ type
*)
TLines = record
Current: integer; // for drawing of current line
- High: integer; // (= High(Line)?)
+ High: integer; // = High(Line)!
Number: integer;
Resolution: integer;
NotesGAP: integer;
@@ -212,12 +222,12 @@ type
TSoundEffect = class
public
EngineData: Pointer; // can be used for engine-specific data
- procedure Callback(Buffer: PChar; BufSize: integer); virtual; abstract;
+ procedure Callback(Buffer: PByteArray; BufSize: integer); virtual; abstract;
end;
TVoiceRemoval = class(TSoundEffect)
public
- procedure Callback(Buffer: PChar; BufSize: integer); override;
+ procedure Callback(Buffer: PByteArray; BufSize: integer); override;
end;
type
@@ -262,7 +272,7 @@ type
function IsEOF(): boolean; virtual; abstract;
function IsError(): boolean; virtual; abstract;
public
- function ReadData(Buffer: PChar; BufferSize: integer): integer; virtual; abstract;
+ function ReadData(Buffer: PByteArray; BufferSize: integer): integer; virtual; abstract;
property EOF: boolean read IsEOF;
property Error: boolean read IsError;
@@ -292,7 +302,7 @@ type
function GetVolume(): single; virtual; abstract;
procedure SetVolume(Volume: single); virtual; abstract;
function Synchronize(BufferSize: integer; FormatInfo: TAudioFormatInfo): integer;
- procedure FillBufferWithFrame(Buffer: PChar; BufferSize: integer; Frame: PChar; FrameSize: integer);
+ procedure FillBufferWithFrame(Buffer: PByteArray; BufferSize: integer; Frame: PByteArray; FrameSize: integer);
public
(**
* Opens a SourceStream for playback.
@@ -335,7 +345,7 @@ type
function Open(ChannelMap: integer; FormatInfo: TAudioFormatInfo): boolean; virtual;
procedure Close(); override;
- procedure WriteData(Buffer: PChar; BufferSize: integer); virtual; abstract;
+ procedure WriteData(Buffer: PByteArray; BufferSize: integer); virtual; abstract;
function GetAudioFormatInfo(): TAudioFormatInfo; override;
function GetLength(): real; override;
@@ -468,7 +478,7 @@ type
* input-buffer bytes used.
* Returns the number of bytes written to the output-buffer or -1 if an error occured.
*)
- function Convert(InputBuffer: PChar; OutputBuffer: PChar; var InputSize: integer): integer; virtual; abstract;
+ function Convert(InputBuffer: PByteArray; OutputBuffer: PByteArray; var InputSize: integer): integer; virtual; abstract;
(**
* Destination/Source size ratio
@@ -561,13 +571,13 @@ procedure DumpMediaInterfaces();
implementation
uses
- sysutils,
math,
UIni,
- UMain,
+ UNote,
UCommandLine,
URecord,
- ULog;
+ ULog,
+ UPath;
var
DefaultVideoPlayback : IVideoPlayback;
@@ -942,7 +952,7 @@ end;
{ TVoiceRemoval }
-procedure TVoiceRemoval.Callback(Buffer: PChar; BufSize: integer);
+procedure TVoiceRemoval.Callback(Buffer: PByteArray; BufSize: integer);
var
FrameIndex, FrameSize: integer;
Value: integer;
@@ -1180,7 +1190,7 @@ end;
(*
* Fills a buffer with copies of the given frame or with 0 if frame.
*)
-procedure TAudioPlaybackStream.FillBufferWithFrame(Buffer: PChar; BufferSize: integer; Frame: PChar; FrameSize: integer);
+procedure TAudioPlaybackStream.FillBufferWithFrame(Buffer: PByteArray; BufferSize: integer; Frame: PByteArray; FrameSize: integer);
var
i: integer;
FrameCopyCount: integer;
diff --git a/unicode/src/base/UNote.pas b/unicode/src/base/UNote.pas
new file mode 100644
index 00000000..5e70bfe1
--- /dev/null
+++ b/unicode/src/base/UNote.pas
@@ -0,0 +1,593 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://ultrastardx.svn.sourceforge.net/svnroot/ultrastardx/trunk/src/base/UNote.pas $
+ * $Id: UNote.pas 1626 2009-03-07 19:53:00Z k-m_schindler $
+ *}
+
+unit UNote;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ SysUtils,
+ Classes,
+ SDL,
+ UMusic,
+ URecord,
+ UTime,
+ UDisplay,
+ UIni,
+ ULog,
+ ULyrics,
+ UScreenSing,
+ USong,
+ gl;
+
+type
+ PPLayerNote = ^TPlayerNote;
+ TPlayerNote = record
+ Start: integer;
+ Length: integer;
+ Detect: real; // accurate place, detected in the note
+ Tone: real;
+ Perfect: boolean; // true if the note matches the original one, light the star
+ Hit: boolean; // true if the note hits the line
+ end;
+
+ PPLayer = ^TPlayer;
+ TPlayer = record
+ Name: string;
+
+ // Index in Teaminfo record
+ TeamID: byte;
+ PlayerID: byte;
+
+ // Scores
+ Score: real;
+ ScoreLine: real;
+ ScoreGolden: real;
+
+ ScoreInt: integer;
+ ScoreLineInt: integer;
+ ScoreGoldenInt: integer;
+ ScoreTotalInt: integer;
+
+ // LineBonus
+ ScoreLast: real; // Last Line Score
+
+ // PerfectLineTwinkle (effect)
+ LastSentencePerfect: boolean;
+
+ HighNote: integer; // index of last note (= High(Note)?)
+ LengthNote: integer; // number of notes (= Length(Note)?).
+ Note: array of TPlayerNote;
+ end;
+
+var
+
+ // player and music info
+ Player: array of TPlayer;
+ PlayersPlay: integer;
+
+ CurrentSong: TSong;
+
+const
+ MAX_SONG_SCORE = 10000; // max. achievable points per song
+ MAX_SONG_LINE_BONUS = 1000; // max. achievable line bonus per song
+
+procedure Sing(Screen: TScreenSing);
+procedure NewSentence(Screen: TScreenSing);
+procedure NewBeatClick(Screen: TScreenSing); // executed when on then new beat for click
+procedure NewBeatDetect(Screen: TScreenSing); // executed when on then new beat for detection
+procedure NewNote(Screen: TScreenSing); // detect note
+function GetMidBeat(Time: real): real;
+function GetTimeFromBeat(Beat: integer): real;
+
+implementation
+
+uses
+ Math,
+ StrUtils,
+ USongs,
+ UJoystick,
+ UCommandLine,
+ ULanguage,
+ //SDL_ttf,
+ USkins,
+ UCovers,
+ UCatCovers,
+ UDataBase,
+ UPlaylist,
+ UDLLManager,
+ UParty,
+ UConfig,
+ UCore,
+ UCommon,
+ UGraphic,
+ UGraphicClasses,
+ UPath,
+ UPluginDefs,
+ UPlatform,
+ UThemes;
+
+function GetTimeForBeats(BPM, Beats: real): real;
+begin
+ Result := 60 / BPM * Beats;
+end;
+
+function GetBeats(BPM, msTime: real): real;
+begin
+ Result := BPM * msTime / 60;
+end;
+
+procedure GetMidBeatSub(BPMNum: integer; var Time: real; var CurBeat: real);
+var
+ NewTime: real;
+begin
+ if High(CurrentSong.BPM) = BPMNum then
+ begin
+ // last BPM
+ CurBeat := CurrentSong.BPM[BPMNum].StartBeat + GetBeats(CurrentSong.BPM[BPMNum].BPM, Time);
+ Time := 0;
+ end
+ else
+ begin
+ // not last BPM
+ // count how much time is it for start of the new BPM and store it in NewTime
+ NewTime := GetTimeForBeats(CurrentSong.BPM[BPMNum].BPM, CurrentSong.BPM[BPMNum+1].StartBeat - CurrentSong.BPM[BPMNum].StartBeat);
+
+ // compare it to remaining time
+ if (Time - NewTime) > 0 then
+ begin
+ // there is still remaining time
+ CurBeat := CurrentSong.BPM[BPMNum].StartBeat;
+ Time := Time - NewTime;
+ end
+ else
+ begin
+ // there is no remaining time
+ CurBeat := CurrentSong.BPM[BPMNum].StartBeat + GetBeats(CurrentSong.BPM[BPMNum].BPM, Time);
+ Time := 0;
+ end; // if
+ end; // if
+end;
+
+function GetMidBeat(Time: real): real;
+var
+ CurBeat: real;
+ CurBPM: integer;
+begin
+ // static BPM
+ if Length(CurrentSong.BPM) = 1 then
+ begin
+ Result := Time * CurrentSong.BPM[0].BPM / 60;
+ end
+ // variable BPM
+ else if Length(CurrentSong.BPM) > 1 then
+ begin
+ CurBeat := 0;
+ CurBPM := 0;
+ while (Time > 0) do
+ begin
+ GetMidBeatSub(CurBPM, Time, CurBeat);
+ Inc(CurBPM);
+ end;
+
+ Result := CurBeat;
+ end
+ // invalid BPM
+ else
+ begin
+ Result := 0;
+ end;
+end;
+
+function GetTimeFromBeat(Beat: integer): real;
+var
+ CurBPM: integer;
+begin
+ // static BPM
+ if Length(CurrentSong.BPM) = 1 then
+ begin
+ Result := CurrentSong.GAP / 1000 + Beat * 60 / CurrentSong.BPM[0].BPM;
+ end
+ // variable BPM
+ else if Length(CurrentSong.BPM) > 1 then
+ begin
+ Result := CurrentSong.GAP / 1000;
+ CurBPM := 0;
+ while (CurBPM <= High(CurrentSong.BPM)) and
+ (Beat > CurrentSong.BPM[CurBPM].StartBeat) do
+ begin
+ if (CurBPM < High(CurrentSong.BPM)) and
+ (Beat >= CurrentSong.BPM[CurBPM+1].StartBeat) then
+ begin
+ // full range
+ Result := Result + (60 / CurrentSong.BPM[CurBPM].BPM) *
+ (CurrentSong.BPM[CurBPM+1].StartBeat - CurrentSong.BPM[CurBPM].StartBeat);
+ end;
+
+ if (CurBPM = High(CurrentSong.BPM)) or
+ (Beat < CurrentSong.BPM[CurBPM+1].StartBeat) then
+ begin
+ // in the middle
+ Result := Result + (60 / CurrentSong.BPM[CurBPM].BPM) *
+ (Beat - CurrentSong.BPM[CurBPM].StartBeat);
+ end;
+ Inc(CurBPM);
+ end;
+
+ {
+ while (Time > 0) do
+ begin
+ GetMidBeatSub(CurBPM, Time, CurBeat);
+ Inc(CurBPM);
+ end;
+ }
+ end
+ // invalid BPM
+ else
+ begin
+ Result := 0;
+ end;
+end;
+
+procedure Sing(Screen: TScreenSing);
+var
+ Count: integer;
+ CountGr: integer;
+ CP: integer;
+begin
+ LyricsState.UpdateBeats();
+
+ // sentences routines
+ for CountGr := 0 to 0 do //High(Lines)
+ begin;
+ CP := CountGr;
+ // old parts
+ LyricsState.OldLine := Lines[CP].Current;
+
+ // choose current parts
+ for Count := 0 to Lines[CP].High do
+ begin
+ if LyricsState.CurrentBeat >= Lines[CP].Line[Count].Start then
+ Lines[CP].Current := Count;
+ end;
+
+ // clean player note if there is a new line
+ // (optimization on halfbeat time)
+ if Lines[CP].Current <> LyricsState.OldLine then
+ NewSentence(Screen);
+
+ end; // for CountGr
+
+ // make some operations on clicks
+ if {(LyricsState.CurrentBeatC >= 0) and }(LyricsState.OldBeatC <> LyricsState.CurrentBeatC) then
+ NewBeatClick(Screen);
+
+ // make some operations when detecting new voice pitch
+ if (LyricsState.CurrentBeatD >= 0) and (LyricsState.OldBeatD <> LyricsState.CurrentBeatD) then
+ NewBeatDetect(Screen);
+end;
+
+procedure NewSentence(Screen: TScreenSing);
+var
+ i: integer;
+begin
+ // clean note of player
+ for i := 0 to High(Player) do
+ begin
+ Player[i].LengthNote := 0;
+ Player[i].HighNote := -1;
+ SetLength(Player[i].Note, 0);
+ end;
+
+ // on sentence change...
+ Screen.onSentenceChange(Lines[0].Current);
+end;
+
+procedure NewBeatClick;
+var
+ Count: integer;
+begin
+ // beat click
+ if ((Ini.BeatClick = 1) and
+ ((LyricsState.CurrentBeatC + Lines[0].Resolution + Lines[0].NotesGAP) mod Lines[0].Resolution = 0)) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Click);
+ end;
+
+ for Count := 0 to Lines[0].Line[Lines[0].Current].HighNote do
+ begin
+ if (Lines[0].Line[Lines[0].Current].Note[Count].Start = LyricsState.CurrentBeatC) then
+ begin
+ // click assist
+ if Ini.ClickAssist = 1 then
+ AudioPlayback.PlaySound(SoundLib.Click);
+
+ // drum machine
+ (*
+ TempBeat := LyricsState.CurrentBeat; // + 2;
+ if (TempBeat mod 8 = 0) then Music.PlayDrum;
+ if (TempBeat mod 8 = 4) then Music.PlayClap;
+ //if (TempBeat mod 4 = 2) then Music.PlayHihat;
+ if (TempBeat mod 4 <> 0) then Music.PlayHihat;
+ *)
+ end;
+ end;
+end;
+
+procedure NewBeatDetect(Screen: TScreenSing);
+begin
+ NewNote(Screen);
+end;
+
+procedure NewNote(Screen: TScreenSing);
+var
+ LineFragmentIndex: integer;
+ CurrentLineFragment: PLineFragment;
+ PlayerIndex: integer;
+ CurrentSound: TCaptureBuffer;
+ CurrentPlayer: PPlayer;
+ LastPlayerNote: PPlayerNote;
+ Line: PLine;
+ SentenceIndex: integer;
+ SentenceMin: integer;
+ SentenceMax: integer;
+ SentenceDetected: integer; // sentence of detected note
+ NoteAvailable: boolean;
+ NewNote: boolean;
+ Range: integer;
+ NoteHit: boolean;
+ MaxSongPoints: integer; // max. points for the song (without line bonus)
+ CurNotePoints: real; // Points for the cur. Note (PointsperNote * ScoreFactor[CurNote])
+begin
+ // TODO: add duet mode support
+ // use Lines[LineSetIndex] with LineSetIndex depending on the current player
+
+ // count min and max sentence range for checking
+ // (detection is delayed to the notes we see on the screen)
+ SentenceMin := Lines[0].Current-1;
+ if (SentenceMin < 0) then
+ SentenceMin := 0;
+ SentenceMax := Lines[0].Current;
+
+ // check for an active note at the current time defined in the lyrics
+ NoteAvailable := false;
+ SentenceDetected := SentenceMin;
+ for SentenceIndex := SentenceMin to SentenceMax do
+ begin
+ Line := @Lines[0].Line[SentenceIndex];
+ for LineFragmentIndex := 0 to Line.HighNote do
+ begin
+ CurrentLineFragment := @Line.Note[LineFragmentIndex];
+ // check if line is active
+ if ((CurrentLineFragment.Start <= LyricsState.CurrentBeatD) and
+ (CurrentLineFragment.Start + CurrentLineFragment.Length-1 >= LyricsState.CurrentBeatD)) and
+ (CurrentLineFragment.NoteType <> ntFreestyle) and // but ignore FreeStyle notes
+ (CurrentLineFragment.Length > 0) then // and make sure the note length is at least 1
+ begin
+ SentenceDetected := SentenceIndex;
+ NoteAvailable := true;
+ Break;
+ end;
+ end;
+ // TODO: break here, if NoteAvailable is true? We would then use the first instead
+ // of the last note matching the current beat if notes overlap. But notes
+ // should not overlap at all.
+ // if (NoteAvailable) then
+ // Break;
+ end;
+
+ // analyze player signals
+ for PlayerIndex := 0 to PlayersPlay-1 do
+ begin
+ CurrentPlayer := @Player[PlayerIndex];
+ CurrentSound := AudioInputProcessor.Sound[PlayerIndex];
+
+ // at the beginning of the song there is no previous note
+ if (Length(CurrentPlayer.Note) > 0) then
+ LastPlayerNote := @CurrentPlayer.Note[CurrentPlayer.HighNote]
+ else
+ LastPlayerNote := nil;
+
+ // analyze buffer
+ CurrentSound.AnalyzeBuffer;
+
+ // add some noise
+ // TODO: do we need this?
+ //LyricsState.Tone := LyricsState.Tone + Round(Random(3)) - 1;
+
+ // add note if possible
+ if (CurrentSound.ToneValid and NoteAvailable) then
+ begin
+ Line := @Lines[0].Line[SentenceDetected];
+
+ // process until last note
+ for LineFragmentIndex := 0 to Line.HighNote do
+ begin
+ CurrentLineFragment := @Line.Note[LineFragmentIndex];
+ if (CurrentLineFragment.Start <= LyricsState.OldBeatD+1) and
+ (CurrentLineFragment.Start + CurrentLineFragment.Length > LyricsState.OldBeatD+1) then
+ begin
+ // compare notes (from song-file and from player)
+
+ // move players tone to proper octave
+ while (CurrentSound.Tone - CurrentLineFragment.Tone > 6) do
+ CurrentSound.Tone := CurrentSound.Tone - 12;
+
+ while (CurrentSound.Tone - CurrentLineFragment.Tone < -6) do
+ CurrentSound.Tone := CurrentSound.Tone + 12;
+
+ // half size notes patch
+ NoteHit := false;
+
+ // if Ini.Difficulty = 0 then Range := 2;
+ // if Ini.Difficulty = 1 then Range := 1;
+ // if Ini.Difficulty = 2 then Range := 0;
+ Range := 2 - Ini.Difficulty;
+
+ // check if the player hit the correct tone within the tolerated range
+ if (Abs(CurrentLineFragment.Tone - CurrentSound.Tone) <= Range) then
+ begin
+ // adjust the players tone to the correct one
+ // TODO: do we need to do this?
+ // Philipp: I think we do, at least when we draw the notes.
+ // Otherwise the notehit thing would be shifted to the
+ // correct unhit note. I think this will look kind of strange.
+ CurrentSound.Tone := CurrentLineFragment.Tone;
+
+ // half size notes patch
+ NoteHit := true;
+
+ if (Ini.LineBonus > 0) then
+ MaxSongPoints := MAX_SONG_SCORE - MAX_SONG_LINE_BONUS
+ else
+ MaxSongPoints := MAX_SONG_SCORE;
+
+ // Note: ScoreValue is the sum of all note values of the song
+ // (MaxSongPoints / ScoreValue) is the points that a player
+ // gets for a hit of one beat of a normal note
+ // CurNotePoints is the amount of points that is meassured
+ // for a hit of the note per full beat
+ CurNotePoints := (MaxSongPoints / Lines[0].ScoreValue) * ScoreFactor[CurrentLineFragment.NoteType];
+
+ case CurrentLineFragment.NoteType of
+ ntNormal: CurrentPlayer.Score := CurrentPlayer.Score + CurNotePoints;
+ ntGolden: CurrentPlayer.ScoreGolden := CurrentPlayer.ScoreGolden + CurNotePoints;
+ end;
+
+ // a problem if we use floor instead of round is that a score of
+ // 10000 points is only possible if the last digit of the total points
+ // for golden and normal notes is 0.
+ // if we use round, the max score is 10000 for most songs
+ // but a score of 10010 is possible if the last digit of the total
+ // points for golden and normal notes is 5
+ // the best solution is to use round for one of these scores
+ // and round the other score in the opposite direction
+ // so we assure that the highest possible score is 10000 in every case.
+ CurrentPlayer.ScoreInt := round(CurrentPlayer.Score / 10) * 10;
+
+ if (CurrentPlayer.ScoreInt < CurrentPlayer.Score) then
+ //normal score is floored so we have to ceil golden notes score
+ CurrentPlayer.ScoreGoldenInt := ceil(CurrentPlayer.ScoreGolden / 10) * 10
+ else
+ //normal score is ceiled so we have to floor golden notes score
+ CurrentPlayer.ScoreGoldenInt := floor(CurrentPlayer.ScoreGolden / 10) * 10;
+
+
+ CurrentPlayer.ScoreTotalInt := CurrentPlayer.ScoreInt +
+ CurrentPlayer.ScoreGoldenInt +
+ CurrentPlayer.ScoreLineInt;
+ end;
+
+ end; // operation
+ end; // for
+
+ // check if we have to add a new note or extend the note's length
+ if (SentenceDetected = SentenceMax) then
+ begin
+ // we will add a new note
+ NewNote := true;
+
+ // if previous note (if any) was the same, extend previous note
+ if ((CurrentPlayer.LengthNote > 0) and
+ (LastPlayerNote <> nil) and
+ (LastPlayerNote.Tone = CurrentSound.Tone) and
+ ((LastPlayerNote.Start + LastPlayerNote.Length) = LyricsState.CurrentBeatD)) then
+ begin
+ NewNote := false;
+ end;
+
+ // if is not as new note to control
+ for LineFragmentIndex := 0 to Line.HighNote do
+ begin
+ if (Line.Note[LineFragmentIndex].Start = LyricsState.CurrentBeatD) then
+ NewNote := true;
+ end;
+
+ // add new note
+ if NewNote then
+ begin
+ // new note
+ Inc(CurrentPlayer.LengthNote);
+ Inc(CurrentPlayer.HighNote);
+ SetLength(CurrentPlayer.Note, CurrentPlayer.LengthNote);
+
+ // update player's last note
+ LastPlayerNote := @CurrentPlayer.Note[CurrentPlayer.HighNote];
+ with LastPlayerNote^ do
+ begin
+ Start := LyricsState.CurrentBeatD;
+ Length := 1;
+ Tone := CurrentSound.Tone; // Tone || ToneAbs
+ Detect := LyricsState.MidBeat;
+ Hit := NoteHit; // half note patch
+ end;
+ end
+ else
+ begin
+ // extend note length
+ if (LastPlayerNote <> nil) then
+ Inc(LastPlayerNote.Length);
+ end;
+
+ // check for perfect note and then light the star (on Draw)
+ for LineFragmentIndex := 0 to Line.HighNote do
+ begin
+ CurrentLineFragment := @Line.Note[LineFragmentIndex];
+ if (CurrentLineFragment.Start = LastPlayerNote.Start) and
+ (CurrentLineFragment.Length = LastPlayerNote.Length) and
+ (CurrentLineFragment.Tone = LastPlayerNote.Tone) then
+ begin
+ LastPlayerNote.Perfect := true;
+ end;
+ end;
+ end; // if SentenceDetected = SentenceMax
+
+ end; // if Detected
+ end; // for PlayerIndex
+
+ //Log.LogStatus('EndBeat', 'NewBeat');
+
+ // on sentence end -> for LineBonus and display of SingBar (rating pop-up)
+ if (SentenceDetected >= Low(Lines[0].Line)) and
+ (SentenceDetected <= High(Lines[0].Line)) then
+ begin
+ Line := @Lines[0].Line[SentenceDetected];
+ CurrentLineFragment := @Line.Note[Line.HighNote];
+ if ((CurrentLineFragment.Start + CurrentLineFragment.Length - 1) = LyricsState.CurrentBeatD) then
+ begin
+ if assigned(Screen) then
+ Screen.OnSentenceEnd(SentenceDetected);
+ end;
+ end;
+
+end;
+
+end.
diff --git a/unicode/src/base/UParty.pas b/unicode/src/base/UParty.pas
index 36ab33fb..937aab78 100644
--- a/unicode/src/base/UParty.pas
+++ b/unicode/src/base/UParty.pas
@@ -39,76 +39,82 @@ uses
UPluginDefs;
type
- ARounds = Array [0..252] of Integer; //0..252 needed for
+ ARounds = array [0..252] of integer; //0..252 needed for
PARounds = ^ARounds;
TRoundInfo = record
- Modi: Cardinal;
- Winner: Byte;
+ Modi: cardinal;
+ Winner: byte;
end;
TeamOrderEntry = record
- Teamnum: Byte;
- Score: Byte;
+ Teamnum: byte;
+ Score: byte;
end;
- TeamOrderArray = Array[0..5] of Byte;
+ TeamOrderArray = array[0..5] of byte;
TUS_ModiInfoEx = record
- Info: TUS_ModiInfo;
- Owner: Integer;
- TimesPlayed: Byte; //Helper for setting Round Plugins
+ Info: TUS_ModiInfo;
+ Owner: integer;
+ TimesPlayed: byte; //Helper for setting round plugins
end;
TPartySession = class (TCoreModule)
private
- bPartyMode: Boolean; //Is this Party or Singleplayer
- CurRound: Byte;
+ bPartyMode: boolean; //Is this party or single player
+ CurRound: byte;
- Modis: Array of TUS_ModiInfoEx;
+ Modis: array of TUS_ModiInfoEx;
Teams: TTeamInfo;
- function IsWinner(Player, Winner: Byte): boolean;
+ function IsWinner(Player, Winner: byte): boolean;
procedure GenScores;
- function GetRandomPlugin(TeamMode: Boolean): Cardinal;
- function GetRandomPlayer(Team: Byte): Byte;
+ function GetRandomPlugin(TeamMode: boolean): cardinal;
+ function GetRandomPlayer(Team: byte): byte;
public
//Teams: TTeamInfo;
Rounds: array of TRoundInfo;
//TCoreModule methods to inherit
- Constructor Create; override;
- Procedure Info(const pInfo: PModuleInfo); override;
- Function Load: Boolean; override;
- Function Init: Boolean; override;
- Procedure DeInit; override;
- Destructor Destroy; override;
+ constructor Create; override;
+ procedure Info(const pInfo: PModuleInfo); override;
+ function Load: boolean; override;
+ function Init: boolean; override;
+ procedure DeInit; override;
+ destructor Destroy; override;
- //Register Modi Service
- Function RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer; //Registers a new Modi. wParam: Pointer to TUS_ModiInfo
+ //Register modus service
+ function RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer; //Registers a new modus. wParam: Pointer to TUS_ModiInfo
//Start new Party
- Function StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer; //Starts new Party Mode. Returns Non Zero on Success
- Function GetCurModi(wParam: TwParam; lParam: TlParam): integer; //Returns Pointer to Cur. Modis TUS_ModiInfo (to Use with Singscreen)
- Function StopParty(wParam: TwParam; lParam: TlParam): integer; //Stops Party Mode. Returns 1 If Partymode was enabled before.
- Function NextRound(wParam: TwParam; lParam: TlParam): integer; //Increases CurRound by 1; Returns num of Round or -1 if last Round is already played
+ function StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer; //Starts new party mode. Returns non zero on success
+ function GetCurModi(wParam: TwParam; lParam: TlParam): integer; //Returns pointer to cur. Modis TUS_ModiInfo (to Use with Singscreen)
+ function StopParty(wParam: TwParam; lParam: TlParam): integer; //Stops party mode. Returns 1 if party mode was enabled before.
+ function NextRound(wParam: TwParam; lParam: TlParam): integer; //Increases curround by 1; Returns num of round or -1 if last round is already played
- Function CallModiInit(wParam: TwParam; lParam: TlParam): integer; //Calls CurModis Init Proc. If an Error occurs, Returns Nonzero. In this Case a New Plugin was Selected. Please renew Loading
- Function CallModiDeInit(wParam: TwParam; lParam: TlParam): integer; //Calls DeInitProc and does the RoundEnding
+ function CallModiInit(wParam: TwParam; lParam: TlParam): integer; //Calls curmodis init proc. If an error occurs, returns nonzero. In this case a new plugin was selected. Please renew loading
+ function CallModiDeInit(wParam: TwParam; lParam: TlParam): integer; //Calls DeInitProc and ends the round
- Function GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Writes TTeamInfo Record to Pointer at lParam. Returns Zero on Success
- Function SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Read TTeamInfo Record from Pointer at lParam. Returns Zero on Success
+ function GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Writes TTeamInfo record to pointer at lParam. Returns zero on success
+ function SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Read TTeamInfo record from pointer at lParam. Returns zero on success
- Function GetTeamOrder(wParam: TwParam; lParam: TlParam): integer; //Returns Team Order. Structure: Bits 1..3: Team at Place1; Bits 4..6: Team at Place2 ...
- Function GetWinnerString(wParam: TwParam; lParam: TlParam): integer; //wParam is Roundnum. If (Pointer = nil) then Return Length of the String. Otherwise Write the String to Address at lParam
+ function GetTeamOrder(wParam: TwParam; lParam: TlParam): integer; //Returns team order. Structure: Bits 1..3: Team at place1; Bits 4..6: Team at place2 ...
+ function GetWinnerString(wParam: TwParam; lParam: TlParam): integer; //wParam is roundnum. If (Pointer = nil) then return length of the string. Otherwise write the string to address at lParam
end;
const
- StandardModi = 0; //Modi ID that will be played in non party Mode
+ StandardModus = 0; //Modus ID that will be played in non-party mode
implementation
-uses UCore, UGraphic, UMain, ULanguage, ULog, SysUtils;
+uses
+ UCore,
+ UGraphic,
+ ULanguage,
+ ULog,
+ UNote,
+ SysUtils;
{*********************
TPluginLoader
@@ -116,85 +122,84 @@ uses UCore, UGraphic, UMain, ULanguage, ULog, SysUtils;
*********************}
//-------------
-// Function that gives some Infos about the Module to the Core
+// function that gives some infos about the module to the core
//-------------
-Procedure TPartySession.Info(const pInfo: PModuleInfo);
+procedure TPartySession.Info(const pInfo: PModuleInfo);
begin
pInfo^.Name := 'TPartySession';
pInfo^.Version := MakeVersion(1,0,0,chr(0));
- pInfo^.Description := 'Manages Party Modi and Party Game';
+ pInfo^.Description := 'Manages party modi and party game';
end;
//-------------
-// Just the Constructor
+// Just the constructor
//-------------
-Constructor TPartySession.Create;
+constructor TPartySession.Create;
begin
inherited;
//UnSet PartyMode
- bPartyMode := False;
+ bPartyMode := false;
end;
//-------------
-//Is Called on Loading.
-//In this Method only Events and Services should be created
-//to offer them to other Modules or Plugins during the Init process
-//If False is Returned this will cause a Forced Exit
+//Is called on loading.
+//In this method only events and services should be created
+//to offer them to other modules or plugins during the init process
+//If false is returned this will cause a forced exit
//-------------
-Function TPartySession.Load: Boolean;
+function TPartySession.Load: boolean;
begin
- //Add Register Party Modi Service
- Result := True;
+ //Add register party modus service
+ Result := true;
Core.Services.AddService('Party/RegisterModi', nil, Self.RegisterModi);
Core.Services.AddService('Party/StartParty', nil, Self.StartParty);
Core.Services.AddService('Party/GetCurModi', nil, Self.GetCurModi);
end;
//-------------
-//Is Called on Init Process
-//In this Method you can Hook some Events and Create + Init
-//your Classes, Variables etc.
-//If False is Returned this will cause a Forced Exit
+//Is called on init process
+//In this method you can hook some events and create + init
+//your classes, variables etc.
+//If false is returned this will cause a forced exit
//-------------
-Function TPartySession.Init: Boolean;
+function TPartySession.Init: boolean;
begin
- //Just set Prvate Var to true.
+ //Just set private var to true.
Result := true;
end;
//-------------
-//Is Called if this Module has been Inited and there is a Exit.
-//Deinit is in backwards Initing Order
+//Is called if this module has been inited and there is an exit.
+//Deinit is in reverse initing order
//-------------
-Procedure TPartySession.DeInit;
+procedure TPartySession.DeInit;
begin
//Force DeInit
-
end;
//-------------
-//Is Called if this Module will be unloaded and has been created
-//Should be used to Free Memory
+//Is called if this module will be unloaded and has been created
+//Should be used to free memory
//-------------
-Destructor TPartySession.Destroy;
+destructor TPartySession.Destroy;
begin
- //Just save some Memory if it wasn't done now..
+ //Just save some memory if it wasn't done now..
SetLength(Modis, 0);
inherited;
end;
//-------------
-// Registers a new Modi. wParam: Pointer to TUS_ModiInfo
-// Service for Plugins
+// Registers a new modus. wParam: Pointer to TUS_ModiInfo
+// Service for plugins
//-------------
-Function TPartySession.RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer;
+function TPartySession.RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer;
var
- Len: Integer;
+ Len: integer;
Info: PUS_ModiInfo;
begin
Info := PModiInfo;
//Copy Info if cbSize is correct
- If (Info.cbSize = SizeOf(TUS_ModiInfo)) then
+ if (Info.cbSize = SizeOf(TUS_ModiInfo)) then
begin
Len := Length(Modis);
SetLength(Modis, Len + 1);
@@ -202,49 +207,49 @@ begin
Modis[Len].Info := Info^;
end
else
- Core.ReportError(Integer(PChar('Plugins try to Register Modi with wrong Pointer, or wrong TUS_ModiInfo Record.')), PChar('TPartySession'));
+ Core.ReportError(integer(PChar('Plugins try to register modus with wrong pointer, or wrong TUS_ModiInfo record.')), PChar('TPartySession'));
// FIXME: return a valid result
Result := 0;
end;
//----------
-// Returns a Number of a Random Plugin
+// Returns a number of a random plugin
//----------
-Function TPartySession.GetRandomPlugin(TeamMode: Boolean): Cardinal;
+function TPartySession.GetRandomPlugin(TeamMode: boolean): cardinal;
var
- LowestTP: Byte;
- NumPwithLTP: Word;
- I: Integer;
- R: Word;
+ LowestTP: byte;
+ NumPwithLTP: word;
+ I: integer;
+ R: word;
begin
- Result := StandardModi; //If there are no matching Modis, Play StandardModi
- LowestTP := high(Byte);
+ Result := StandardModus; //If there are no matching modi, play standard modus
+ LowestTP := high(byte);
NumPwithLTP := 0;
//Search for Plugins not often played yet
- For I := 0 to high(Modis) do
+ for I := 0 to high(Modis) do
begin
- if (Modis[I].TimesPlayed < lowestTP) And (((Modis[I].Info.LoadingSettings AND MLS_TeamOnly) <> 0) = TeamMode) then
+ if (Modis[I].TimesPlayed < lowestTP) and (((Modis[I].Info.LoadingSettings and MLS_TeamOnly) <> 0) = TeamMode) then
begin
lowestTP := Modis[I].TimesPlayed;
NumPwithLTP := 1;
end
- else if (Modis[I].TimesPlayed = lowestTP) And (((Modis[I].Info.LoadingSettings AND MLS_TeamOnly) <> 0) = TeamMode) then
+ else if (Modis[I].TimesPlayed = lowestTP) and (((Modis[I].Info.LoadingSettings and MLS_TeamOnly) <> 0) = TeamMode) then
begin
Inc(NumPwithLTP);
end;
end;
- //Create Random No
+ //Create random no
R := Random(NumPwithLTP);
- //Search for Random Plugin
- For I := 0 to high(Modis) do
+ //Search for random plugin
+ for I := 0 to high(Modis) do
begin
- if (Modis[I].TimesPlayed = lowestTP) And (((Modis[I].Info.LoadingSettings AND MLS_TeamOnly) <> 0) = TeamMode) then
+ if (Modis[I].TimesPlayed = lowestTP) and (((Modis[I].Info.LoadingSettings and MLS_TeamOnly) <> 0) = TeamMode) then
begin
- //Plugin Found
+ //Plugin found
if (R = 0) then
begin
Result := I;
@@ -258,79 +263,79 @@ begin
end;
//----------
-// Starts new Party Mode. Returns Non Zero on Success
+// Starts new party mode. Returns non zero on success
//----------
-Function TPartySession.StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer;
+function TPartySession.StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer;
var
- I: Integer;
+ I: integer;
aiRounds: PARounds;
- TeamMode: Boolean;
+ TeamMode: boolean;
begin
Result := 0;
- If (Teams.NumTeams >= 1) AND (NumRounds < High(Byte)-1) then
+ if (Teams.NumTeams >= 1) and (NumRounds < High(byte)-1) then
begin
bPartyMode := false;
aiRounds := PAofIRounds;
- Try
- //Is this Teammode(More then one Player per Team) ?
- TeamMode := True;
- For I := 0 to Teams.NumTeams-1 do
- TeamMode := TeamMode AND (Teams.Teaminfo[I].NumPlayers > 1);
+ try
+ //Is this team mode (More than one player per team) ?
+ TeamMode := true;
+ for I := 0 to Teams.NumTeams-1 do
+ TeamMode := TeamMode and (Teams.Teaminfo[I].NumPlayers > 1);
//Set Rounds
SetLength(Rounds, NumRounds);
- For I := 0 to High(Rounds) do
- begin //Set Plugins
- If (aiRounds[I] = -1) then
+ for I := 0 to High(Rounds) do
+ begin //Set plugins
+ if (aiRounds[I] = -1) then
Rounds[I].Modi := GetRandomPlugin(TeamMode)
- Else If (aiRounds[I] >= 0) AND (aiRounds[I] <= High(Modis)) AND (TeamMode OR ((Modis[aiRounds[I]].Info.LoadingSettings AND MLS_TeamOnly) = 0)) then
+ else if (aiRounds[I] >= 0) and (aiRounds[I] <= High(Modis)) and (TeamMode or ((Modis[aiRounds[I]].Info.LoadingSettings and MLS_TeamOnly) = 0)) then
Rounds[I].Modi := aiRounds[I]
- Else
- Rounds[I].Modi := StandardModi;
+ else
+ Rounds[I].Modi := StandardModus;
- Rounds[I].Winner := High(Byte); //Set Winner to Not Played
+ Rounds[I].Winner := High(byte); //Set winner to not played
end;
- CurRound := High(Byte); //Set CurRound to not defined
+ CurRound := High(byte); //Set CurRound to not defined
- //Return teh true and Set PartyMode
- bPartyMode := True;
+ //Return true and set party mode
+ bPartyMode := true;
Result := 1;
- Except
- Core.ReportError(Integer(PChar('Can''t start PartyMode.')), PChar('TPartySession'));
+ except
+ Core.ReportError(integer(PChar('Can''t start party mode.')), PChar('TPartySession'));
end;
end;
end;
//----------
-// Returns Pointer to Cur. ModiInfoEx (to Use with Singscreen)
+// Returns pointer to Cur. ModiInfoEx (to use with sing screen)
//----------
-Function TPartySession.GetCurModi(wParam: TwParam; lParam: TlParam): integer;
+function TPartySession.GetCurModi(wParam: TwParam; lParam: TlParam): integer;
begin
- If (bPartyMode) AND (CurRound <= High(Rounds)) then
+ if (bPartyMode) and (CurRound <= High(Rounds)) then
begin //If PartyMode is enabled:
//Return the Plugin of the Cur Round
- Result := Integer(@Modis[Rounds[CurRound].Modi]);
+ Result := integer(@Modis[Rounds[CurRound].Modi]);
end
else
- begin //Return StandardModi
- Result := Integer(@Modis[StandardModi]);
+ begin //Return standard modus
+ Result := integer(@Modis[StandardModus]);
end;
end;
//----------
-// Stops Party Mode. Returns 1 If Partymode was enabled before. And -1 if Change was not possible
+// Stops party mode. Returns 1 if party mode was enabled before and -1 if change was not possible
//----------
-Function TPartySession.StopParty(wParam: TwParam; lParam: TlParam): integer;
+function TPartySession.StopParty(wParam: TwParam; lParam: TlParam): integer;
begin
Result := -1;
- If (bPartyMode) then
+ if (bPartyMode) then
begin
- // to-do : Whitü: Check here if SingScreen is not Shown atm.
- bPartyMode := False;
+ // to-do : Whitü: Check here if sing screen is not shown atm.
+ bPartyMode := false;
Result := 1;
end
else
@@ -338,59 +343,60 @@ begin
end;
//----------
-//GetRandomPlayer - Gives back a Random Player to Play next Round
+//GetRandomPlayer - gives back a random player to play next round
//----------
-function TPartySession.GetRandomPlayer(Team: Byte): Byte;
+function TPartySession.GetRandomPlayer(Team: byte): byte;
var
- I, R: Integer;
- lowestTP: Byte;
- NumPwithLTP: Byte;
+ I, R: integer;
+ lowestTP: byte;
+ NumPwithLTP: byte;
begin
- LowestTP := high(Byte);
- NumPwithLTP := 0;
- Result := 0;
+ LowestTP := high(byte);
+ NumPwithLTP := 0;
+ Result := 0;
- //Search for Players that have not often played yet
- For I := 0 to Teams.Teaminfo[Team].NumPlayers-1 do
+ //Search for players that have not often played yet
+ for I := 0 to Teams.Teaminfo[Team].NumPlayers-1 do
+ begin
+ if (Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed < lowestTP) then
begin
- if (Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed < lowestTP) then
- begin
- lowestTP := Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed;
- NumPwithLTP := 1;
- end
- else if (Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed = lowestTP) then
- begin
- Inc(NumPwithLTP);
- end;
+ lowestTP := Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed;
+ NumPwithLTP := 1;
+ end
+ else if (Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed = lowestTP) then
+ begin
+ Inc(NumPwithLTP);
end;
+ end;
- //Create Random No
- R := Random(NumPwithLTP);
+ //Create random no
+ R := Random(NumPwithLTP);
- //Search for Random Player
- For I := 0 to Teams.Teaminfo[Team].NumPlayers-1 do
+ //Search for random player
+ for I := 0 to Teams.Teaminfo[Team].NumPlayers-1 do
+ begin
+ if Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed = lowestTP then
begin
- if Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed = lowestTP then
+ //Player found
+ if (R = 0) then
begin
- //Player Found
- if (R = 0) then
- begin
- Result := I;
- Break;
- end;
-
- Dec(R);
+ Result := I;
+ Break;
end;
+
+ Dec(R);
end;
+ end;
end;
//----------
-// NextRound - Increases CurRound by 1; Returns num of Round or -1 if last Round is already played
+// NextRound - Increases CurRound by 1; Returns num of round or -1 if last round is already played
//----------
-Function TPartySession.NextRound(wParam: TwParam; lParam: TlParam): integer;
-var I: Integer;
+function TPartySession.NextRound(wParam: TwParam; lParam: TlParam): integer;
+var
+ I: integer;
begin
- If ((CurRound < high(Rounds)) OR (CurRound = high(CurRound))) then
+ if ((CurRound < high(Rounds)) or (CurRound = high(CurRound))) then
begin //everythings OK! -> Start the Round, maaaaan
Inc(CurRound);
@@ -406,23 +412,23 @@ begin
end;
//----------
-//IsWinner - Returns True if the Players Bit is set in the Winner Byte
+//IsWinner - returns true if the players bit is set in the winner byte
//----------
-function TPartySession.IsWinner(Player, Winner: Byte): boolean;
+function TPartySession.IsWinner(Player, Winner: byte): boolean;
var
- Bit: Byte;
+ Bit: byte;
begin
Bit := 1 shl Player;
- Result := ((Winner AND Bit) = Bit);
+ Result := ((Winner and Bit) = Bit);
end;
//----------
-//GenScores - Inc Scores for Cur. Round
+//GenScores - inc scores for cur. round
//----------
procedure TPartySession.GenScores;
var
- I: Byte;
+ I: byte;
begin
for I := 0 to Teams.NumTeams-1 do
begin
@@ -432,86 +438,86 @@ begin
end;
//----------
-// CallModiInit - Calls CurModis Init Proc. If an Error occurs, Returns Nonzero. In this Case a New Plugin was Selected. Please renew Loading
+// CallModiInit - calls CurModis Init Proc. If an error occurs, returns nonzero. In this case a new plugin was selected. Please renew loading
//----------
-Function TPartySession.CallModiInit(wParam: TwParam; lParam: TlParam): integer;
+function TPartySession.CallModiInit(wParam: TwParam; lParam: TlParam): integer;
begin
- If (not bPartyMode) then
- begin //Set Rounds if not in PartyMode
+ if (not bPartyMode) then
+ begin //Set rounds if not in party mode
SetLength(Rounds, 1);
- Rounds[0].Modi := StandardModi;
- Rounds[0].Winner := High(Byte);
+ Rounds[0].Modi := StandardModus;
+ Rounds[0].Winner := High(byte);
CurRound := 0;
end;
- Try
+ try
//Core.
- Except
+ except
on E : Exception do
begin
- Core.ReportError(Integer(PChar('Error starting Modi: ' + Modis[Rounds[CurRound].Modi].Info.Name + ' ErrorStr: ' + E.Message)), PChar('TPartySession'));
- If (Rounds[CurRound].Modi = StandardModi) then
+ Core.ReportError(integer(PChar('Error starting modus: ' + Modis[Rounds[CurRound].Modi].Info.Name + ' ErrorStr: ' + E.Message)), PChar('TPartySession'));
+ if (Rounds[CurRound].Modi = StandardModus) then
begin
- Core.ReportError(Integer(PChar('Can''t start StandardModi, will exit now!')), PChar('TPartySession'));
+ Core.ReportError(integer(PChar('Can''t start standard modus, will exit now!')), PChar('TPartySession'));
Halt;
end
- Else //Select StandardModi
+ else //Select standard modus
begin
- Rounds[CurRound].Modi := StandardModi
+ Rounds[CurRound].Modi := StandardModus
end;
end;
- End;
+ end;
// FIXME: return a valid result
Result := 0;
end;
//----------
-// CallModiDeInit - Calls DeInitProc and does the RoundEnding
+// CallModiDeInit - calls DeInitProc and ends the round
//----------
-Function TPartySession.CallModiDeInit(wParam: TwParam; lParam: TlParam): integer;
+function TPartySession.CallModiDeInit(wParam: TwParam; lParam: TlParam): integer;
var
- I: Integer;
- MaxScore: Word;
+ I: integer;
+ MaxScore: word;
begin
- If (bPartyMode) then
+ if (bPartyMode) then
begin
//Get Winner Byte!
- if (@Modis[Rounds[CurRound].Modi].Info.ModiDeInit <> nil) then //get Winners from Plugin
+ if (@Modis[Rounds[CurRound].Modi].Info.ModiDeInit <> nil) then //get winners from plugin
Rounds[CurRound].Winner := Modis[Rounds[CurRound].Modi].Info.ModiDeInit(Modis[Rounds[CurRound].Modi].Info.ID)
else
- begin //Create winners by Score :/
+ begin //Create winners by score :/
Rounds[CurRound].Winner := 0;
MaxScore := 0;
for I := 0 to Teams.NumTeams-1 do
begin
- // to-do : recode Percentage stuff
+ // to-do : recode percentage stuff
//PlayerInfo.Playerinfo[I].Percentage := PlayerInfo.Playerinfo[I].Score div 9999;
if (Player[I].ScoreTotalInt > MaxScore) then
begin
MaxScore := Player[I].ScoreTotalInt;
Rounds[CurRound].Winner := 1 shl I;
end
- else if (Player[I].ScoreTotalInt = MaxScore) AND (Player[I].ScoreTotalInt <> 0) then
+ else if (Player[I].ScoreTotalInt = MaxScore) and (Player[I].ScoreTotalInt <> 0) then
begin
Rounds[CurRound].Winner := Rounds[CurRound].Winner or (1 shl I);
end;
end;
- //When nobody has Points -> Everybody loose
+ //When nobody has points -> everybody looses
if (MaxScore = 0) then
Rounds[CurRound].Winner := 0;
end;
- //Generate teh Scores
+ //Generate the scores
GenScores;
- //Inc Players TimesPlayed
- If ((Modis[Rounds[CurRound-1].Modi].Info.LoadingSettings AND MLS_IncTP) = MLS_IncTP) then
+ //Inc players TimesPlayed
+ if ((Modis[Rounds[CurRound-1].Modi].Info.LoadingSettings and MLS_IncTP) = MLS_IncTP) then
begin
- For I := 0 to Teams.NumTeams-1 do
+ for I := 0 to Teams.NumTeams-1 do
Inc(Teams.TeamInfo[I].Playerinfo[Teams.TeamInfo[I].CurPlayer].TimesPlayed);
end;
end
@@ -523,69 +529,70 @@ begin
end;
//----------
-// GetTeamInfo - Writes TTeamInfo Record to Pointer at lParam. Returns Zero on Success
+// GetTeamInfo - writes TTeamInfo record to pointer at lParam. Returns zero on success
//----------
-Function TPartySession.GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer;
-var Info: ^TTeamInfo;
+function TPartySession.GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer;
+var
+ Info: ^TTeamInfo;
begin
Result := -1;
Info := pTeamInfo;
- If (Info <> nil) then
+ if (Info <> nil) then
begin
- Try
+ try
// to - do : Check Delphi memory management in this case
//Not sure if i had to copy PChars to a new address or if delphi manages this o0
Info^ := Teams;
Result := 0;
- Except
+ except
Result := -2;
- End;
+ end;
end;
end;
//----------
-// SetTeamInfo - Read TTeamInfo Record from Pointer at lParam. Returns Zero on Success
+// SetTeamInfo - read TTeamInfo record from pointer at lParam. Returns zero on success
//----------
-Function TPartySession.SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer;
+function TPartySession.SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer;
var
TeamInfobackup: TTeamInfo;
Info: ^TTeamInfo;
begin
Result := -1;
Info := pTeamInfo;
- If (Info <> nil) then
+ if (Info <> nil) then
begin
- Try
+ try
TeamInfoBackup := Teams;
// to - do : Check Delphi memory management in this case
//Not sure if i had to copy PChars to a new address or if delphi manages this o0
Teams := Info^;
Result := 0;
- Except
+ except
Teams := TeamInfoBackup;
Result := -2;
- End;
+ end;
end;
end;
//----------
-// GetTeamOrder - Returns Team Order. Structure: Bits 1..3: Team at Place1; Bits 4..6: Team at Place2 ...
+// GetTeamOrder - returns team order. Structure: Bits 1..3: Team at place1; Bits 4..6: Team at place2 ...
//----------
-Function TPartySession.GetTeamOrder(wParam: TwParam; lParam: TlParam): integer;
+function TPartySession.GetTeamOrder(wParam: TwParam; lParam: TlParam): integer;
var
- I, J: Integer;
+ I, J: integer;
ATeams: array [0..5] of TeamOrderEntry;
TempTeam: TeamOrderEntry;
begin
- // to-do : PartyMode: Write this in another way, so that teams with the same scire get the same Placing
- //Fill Team Array
- For I := 0 to Teams.NumTeams-1 do
+ // to-do : PartyMode: Write this in another way, so that teams with the same score get the same place
+ //Fill Team array
+ for I := 0 to Teams.NumTeams-1 do
begin
ATeams[I].Teamnum := I;
ATeams[I].Score := Teams.Teaminfo[I].Score;
end;
- //Sort Teams
+ //Sort teams
for J := 0 to Teams.NumTeams-1 do
for I := 1 to Teams.NumTeams-1 do
if ATeams[I].Score > ATeams[I-1].Score then
@@ -597,17 +604,17 @@ begin
//Copy to Result
Result := 0;
- For I := 0 to Teams.NumTeams-1 do
+ for I := 0 to Teams.NumTeams-1 do
Result := Result or (ATeams[I].TeamNum Shl I*3);
end;
//----------
-// GetWinnerString - wParam is Roundnum. If (Pointer = nil) then Return Length of the String. Otherwise Write the String to Address at lParam
+// GetWinnerString - wParam is Roundnum. If (pointer = nil) then return length of the string. Otherwise write the string to address at lParam
//----------
-Function TPartySession.GetWinnerString(wParam: TwParam; lParam: TlParam): integer;
+function TPartySession.GetWinnerString(wParam: TwParam; lParam: TlParam): integer;
var
Winners: array of UTF8String;
- I: Integer;
+ I: integer;
ResultStr: String;
S: ^String;
begin
@@ -637,21 +644,21 @@ begin
end;
end;
- //Now Return what we have got
- If (lParam = nil) then
- begin //ReturnString Length
+ //Now return what we have got
+ if (lParam = nil) then
+ begin //Return string length
Result := Length(ResultStr);
end
- Else
- begin //Return String
- Try
+ else
+ begin //Return string
+ try
S := lParam;
S^ := ResultStr;
Result := 0;
- Except
+ except
Result := -1;
- End;
+ end;
end;
end;
diff --git a/unicode/src/base/UPath.pas b/unicode/src/base/UPath.pas
new file mode 100644
index 00000000..2316ac02
--- /dev/null
+++ b/unicode/src/base/UPath.pas
@@ -0,0 +1,188 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://ultrastardx.svn.sourceforge.net/svnroot/ultrastardx/trunk/src/base/UPath.pas $
+ * $Id: UPath.pas 1624 2009-03-06 23:45:10Z k-m_schindler $
+ *}
+
+unit UPath;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ SysUtils,
+ Classes;
+
+var
+ // Absolute Paths
+ GamePath: string;
+ SoundPath: string;
+ SongPaths: TStringList;
+ LogPath: string;
+ ThemePath: string;
+ SkinsPath: string;
+ ScreenshotsPath: string;
+ CoverPaths: TStringList;
+ LanguagesPath: string;
+ PluginPath: string;
+ VisualsPath: string;
+ FontPath: string;
+ ResourcesPath: string;
+ PlayListPath: string;
+
+function FindPath(out PathResult: string; const RequestedPath: string; NeedsWritePermission: boolean): boolean;
+procedure InitializePaths;
+procedure AddSongPath(const Path: string);
+
+implementation
+
+uses
+ StrUtils,
+ UPlatform,
+ UCommandLine,
+ ULog;
+
+procedure AddSpecialPath(var PathList: TStringList; const Path: string);
+var
+ Index: integer;
+ PathAbs, OldPathAbs: string;
+begin
+ if (PathList = nil) then
+ PathList := TStringList.Create;
+
+ if (Path = '') or not ForceDirectories(Path) then
+ Exit;
+
+ PathAbs := IncludeTrailingPathDelimiter(ExpandFileName(Path));
+
+ // check if path or a part of the path was already added
+ for Index := 0 to PathList.Count-1 do
+ begin
+ OldPathAbs := IncludeTrailingPathDelimiter(ExpandFileName(PathList[Index]));
+ // check if the new directory is a sub-directory of a previously added one.
+ // This is also true, if both paths point to the same directories.
+ if (AnsiStartsText(OldPathAbs, PathAbs)) then
+ begin
+ // ignore the new path
+ Exit;
+ end;
+
+ // check if a previously added directory is a sub-directory of the new one.
+ if (AnsiStartsText(PathAbs, OldPathAbs)) then
+ begin
+ // replace the old with the new one.
+ PathList[Index] := PathAbs;
+ Exit;
+ end;
+ end;
+
+ PathList.Add(PathAbs);
+end;
+
+procedure AddSongPath(const Path: string);
+begin
+ AddSpecialPath(SongPaths, Path);
+end;
+
+procedure AddCoverPath(const Path: string);
+begin
+ AddSpecialPath(CoverPaths, Path);
+end;
+
+(**
+ * Initialize a path variable
+ * After setting paths, make sure that paths exist
+ *)
+function FindPath(out PathResult: string;
+ const RequestedPath: string;
+ NeedsWritePermission: boolean)
+ : boolean;
+begin
+ Result := false;
+
+ if (RequestedPath = '') then
+ Exit;
+
+ // Make sure the directory exists
+ if (not ForceDirectories(RequestedPath)) then
+ begin
+ PathResult := '';
+ Exit;
+ end;
+
+ PathResult := IncludeTrailingPathDelimiter(RequestedPath);
+
+ if (NeedsWritePermission) and
+ (FileIsReadOnly(RequestedPath)) then
+ begin
+ Exit;
+ end;
+
+ Result := true;
+end;
+
+(**
+ * Function sets all absolute paths e.g. song path and makes sure the directorys exist
+ *)
+procedure InitializePaths;
+begin
+ // Log directory (must be writable)
+ if (not FindPath(LogPath, Platform.GetLogPath, true)) then
+ begin
+ Log.FileOutputEnabled := false;
+ Log.LogWarn('Log directory "'+ Platform.GetLogPath +'" not available', 'InitializePaths');
+ end;
+
+ FindPath(SoundPath, Platform.GetGameSharedPath + 'sounds', false);
+ FindPath(ThemePath, Platform.GetGameSharedPath + 'themes', false);
+ FindPath(SkinsPath, Platform.GetGameSharedPath + 'themes', false);
+ FindPath(LanguagesPath, Platform.GetGameSharedPath + 'languages', false);
+ FindPath(PluginPath, Platform.GetGameSharedPath + 'plugins', false);
+ FindPath(VisualsPath, Platform.GetGameSharedPath + 'visuals', false);
+ FindPath(FontPath, Platform.GetGameSharedPath + 'fonts', false);
+ FindPath(ResourcesPath, Platform.GetGameSharedPath + 'resources', false);
+
+ // Playlists are not shared as we need one directory to write too
+ FindPath(PlaylistPath, Platform.GetGameUserPath + 'playlists', true);
+
+ // Screenshot directory (must be writable)
+ if (not FindPath(ScreenshotsPath, Platform.GetGameUserPath + 'screenshots', true)) then
+ begin
+ Log.LogWarn('Screenshot directory "'+ Platform.GetGameUserPath +'" not available', 'InitializePaths');
+ end;
+
+ // Add song paths
+ AddSongPath(Params.SongPath);
+ AddSongPath(Platform.GetGameSharedPath + 'songs');
+ AddSongPath(Platform.GetGameUserPath + 'songs');
+
+ // Add category cover paths
+ AddCoverPath(Platform.GetGameSharedPath + 'covers');
+ AddCoverPath(Platform.GetGameUserPath + 'covers');
+end;
+
+end.
diff --git a/unicode/src/base/UPlatformMacOSX.pas b/unicode/src/base/UPlatformMacOSX.pas
index 1aa37cd4..96e4bc63 100644
--- a/unicode/src/base/UPlatformMacOSX.pas
+++ b/unicode/src/base/UPlatformMacOSX.pas
@@ -47,19 +47,21 @@ type
* (Note for non-Maccies: "folder" is the Mac name for directory.)
*
* Note on the resource folders:
- * 1. Installation of an application on the mac works as follows: Extract and copy an application
- * and if you don't like or need the application anymore you move the folder
- * to the trash - and you're done.
- * 2. The use folders in the user's home directory is against Apple's guidelines
- * and strange to an average user.
+ * 1. Installation of an application on the mac works as follows: Extract and
+ * copy an application and if you don't like or need the application
+ * anymore you move the folder to the trash - and you're done.
+ * 2. The use of folders in the user's home directory is against Apple's
+ * guidelines and strange to an average user.
* 3. Even worse is using /usr/local/... since all lowercase folders in / are
- * not visible to an average user in the Finder, at least not without some "tricks".
+ * not visible to an average user in the Finder, at least not without some
+ * "tricks".
*
- * The best way would be to store everything within the application bundle. However, this
- * requires USDX to offer the handling of the resources. Until this is implemented, the
- * second best solution is as follows:
+ * The best way would be to store everything within the application bundle.
+ * However, this requires USDX to offer the handling of the resources. Until
+ * this is implemented, the second best solution is as follows:
*
- * According to Aple guidelines handling of resources and folders should follow these lines:
+ * According to Aple guidelines handling of resources and folders should follow
+ * these lines:
*
* Acceptable places for files are folders named UltraStarDeluxe either in
* /Library/Application Support/
@@ -68,19 +70,19 @@ type
*
* So
* GetGameSharedPath could return
- * /Library/Application Support/UltraStarDeluxe/Resources/.
+ * /Library/Application Support/UltraStarDeluxe/.
* GetGameUserPath could return
- * ~/Library/Application Support/UltraStarDeluxe/Resources/.
+ * ~/Library/Application Support/UltraStarDeluxe/.
*
- * Right now, only $HOME/Library/Application Support/UltraStarDeluxe/Resources
+ * Right now, only $HOME/Library/Application Support/UltraStarDeluxe
* is used. So every user needs the complete set of files and folders.
* Future versions may also use shared resources in
- * /Library/Application Support/UltraStarDeluxe/Resources. However, this is not
- * treated yet in the code outside this unit.
+ * /Library/Application Support/UltraStarDeluxe. However, this is
+ * not treated yet in the code outside this unit.
*
* USDX checks, whether GetGameUserPath exists. If not, USDX creates it.
* The existence of needed files is then checked and if a file is missing
- * it is copied to there from within the Resources folder in the Application
+ * it is copied to there from within the folder Contents in the Application
* bundle, which contains the default files. USDX should not delete files or
* folders in Application Support/UltraStarDeluxe automatically or without
* user confirmation.
@@ -88,13 +90,14 @@ type
TPlatformMacOSX = class(TPlatform)
private
{**
- * GetBundlePath returns the path to the application bundle UltraStarDeluxe.app.
+ * GetBundlePath returns the path to the application bundle
+ * UltraStarDeluxe.app.
*}
function GetBundlePath: WideString;
{**
* GetApplicationSupportPath returns the path to
- * $HOME/Library/Application Support/UltraStarDeluxe/Resources.
+ * $HOME/Library/Application Support/UltraStarDeluxe.
*}
function GetApplicationSupportPath: WideString;
@@ -102,38 +105,38 @@ type
* see the description of @link(Init).
*}
procedure CreateUserFolders();
-
+
public
{**
- * Init simply calls @link(CreateUserFolders), which in turn scans the folder
- * UltraStarDeluxe.app/Contents/Resources for all files and folders.
- * $HOME/Library/Application Support/UltraStarDeluxe/Resources is then checked
- * for their presence and missing ones are copied.
+ * Init simply calls @link(CreateUserFolders), which in turn scans the
+ * folder UltraStarDeluxe.app/Contents for all files and
+ * folders. $HOME/Library/Application Support/UltraStarDeluxe
+ * is then checked for their presence and missing ones are copied.
*}
procedure Init; override;
{**
- * DirectoryFindFiles returns all entries of a folder with names and booleans
- * about their type, i.e. file or directory.
+ * DirectoryFindFiles returns all entries of a folder with names and
+ * booleans about their type, i.e. file or directory.
*}
function DirectoryFindFiles(Dir, Filter: WideString; ReturnAllSubDirs: boolean): TDirectoryEntryArray; override;
{**
* GetLogPath returns the path for log messages. Currently it is set to
- * $HOME/Library/Application Support/UltraStarDeluxe/Resources/Log.
+ * $HOME/Library/Application Support/UltraStarDeluxe/Log.
*}
function GetLogPath : WideString; override;
{**
- * GetGameSharedPath returns the path for shared resources. Currently it is set to
- * /Library/Application Support/UltraStarDeluxe/Resources.
+ * GetGameSharedPath returns the path for shared resources. Currently it
+ * is set to /Library/Application Support/UltraStarDeluxe.
* However it is not used.
*}
function GetGameSharedPath : WideString; override;
{**
- * GetGameUserPath returns the path for user resources. Currently it is set to
- * $HOME/Library/Application Support/UltraStarDeluxe/Resources.
+ * GetGameUserPath returns the path for user resources. Currently it is
+ * set to $HOME/Library/Application Support/UltraStarDeluxe.
* This is where a user can add songs, themes, ....
*}
function GetGameUserPath : WideString; override;
@@ -151,6 +154,9 @@ begin
end;
procedure TPlatformMacOSX.CreateUserFolders();
+const
+ // used to construct the @link(UserPathName)
+ PathName: string = '/Library/Application Support/UltraStarDeluxe';
var
RelativePath: string;
// BaseDir contains the path to the folder, where a search is performed.
@@ -169,22 +175,23 @@ var
// searched for additional files and folders.
DirectoryIsFinished: longint;
Counter: longint;
+ // These three are for creating directories, due to possible symlinks
+ CreatedDirectory: boolean;
+ FileAttrs: integer;
+ DirectoryPath: string;
- UserPathName: string;
-const
- // used to construct the @link(UserPathName)
- PathName: string = '/Library/Application Support/UltraStarDeluxe/Resources';
+ UserPathName: string;
begin
// Get the current folder and save it in OldBaseDir for returning to it, when
// finished.
GetDir(0, OldBaseDir);
- // UltraStarDeluxe.app/Contents/Resources contains all the default files and
+ // UltraStarDeluxe.app/Contents contains all the default files and
// folders.
- BaseDir := OldBaseDir + '/UltraStarDeluxe.app/Contents/Resources';
+ BaseDir := OldBaseDir + '/UltraStarDeluxe.app/Contents';
ChDir(BaseDir);
- // Right now, only $HOME/Library/Application Support/UltraStarDeluxe/Resources
+ // Right now, only $HOME/Library/Application Support/UltraStarDeluxe
// is used.
UserPathName := GetEnvironmentVariable('HOME') + PathName;
@@ -192,7 +199,7 @@ begin
DirectoryList := TStringList.Create();
FileList := TStringList.Create();
DirectoryList.Add('.');
-
+
// create the folder and file lists
repeat
@@ -203,7 +210,7 @@ begin
repeat
if DirectoryExists(SearchInfo.Name) then
begin
- if (SearchInfo.Name <> '.') and (SearchInfo.Name <> '..') then
+ if (SearchInfo.Name <> '.') and (SearchInfo.Name <> '..') then
DirectoryList.Add(RelativePath + '/' + SearchInfo.Name);
end
else
@@ -218,7 +225,12 @@ begin
ForceDirectories(UserPathName); // should not be necessary since (UserPathName+'/.') is created.
for Counter := 0 to DirectoryList.Count-1 do
begin
- if not ForceDirectories(UserPathName + '/' + DirectoryList[Counter]) then
+ DirectoryPath := UserPathName + '/' + DirectoryList[Counter];
+ CreatedDirectory := ForceDirectories(DirectoryPath);
+ FileAttrs := FileGetAttr(DirectoryPath);
+ // Don't know how to analyse the target of the link.
+ // Let's assume the symlink is pointing to an existing directory.
+ if (not CreatedDirectory) and (FileAttrs and faSymLink > 0) then
Log.LogError('Failed to create the folder "'+ UserPathName + '/' + DirectoryList[Counter] +'"',
'TPlatformMacOSX.CreateUserFolders');
end;
@@ -241,8 +253,7 @@ var
i, pos : integer;
begin
// Mac applications are packaged in folders.
- // We have to cut the last two folders
- // to get the application folder.
+ // Cutting the last two folders yields the application folder.
Result := GetExecutionDir();
for i := 1 to 2 do
@@ -257,7 +268,7 @@ end;
function TPlatformMacOSX.GetApplicationSupportPath: WideString;
const
- PathName : string = '/Library/Application Support/UltraStarDeluxe/Resources';
+ PathName : string = '/Library/Application Support/UltraStarDeluxe';
begin
Result := GetEnvironmentVariable('HOME') + PathName + '/';
end;
@@ -287,7 +298,7 @@ begin
i := 0;
Filter := LowerCase(Filter);
- TheDir := FPOpenDir(Dir);
+ TheDir := FPOpenDir(Dir);
if Assigned(TheDir) then
repeat
ADirent := FPReadDir(TheDir);
diff --git a/unicode/src/base/UPlaylist.pas b/unicode/src/base/UPlaylist.pas
index 47ade154..744f4ce8 100644
--- a/unicode/src/base/UPlaylist.pas
+++ b/unicode/src/base/UPlaylist.pas
@@ -34,7 +34,8 @@ interface
{$I switches.inc}
uses
- USong;
+ USong,
+ UPath;
type
TPlaylistItem = record
diff --git a/unicode/src/base/UPluginLoader.pas b/unicode/src/base/UPluginLoader.pas
index 5e581c23..8836cb78 100644
--- a/unicode/src/base/UPluginLoader.pas
+++ b/unicode/src/base/UPluginLoader.pas
@@ -41,14 +41,15 @@ interface
uses
UPluginDefs,
- UCoreModule;
+ UCoreModule,
+ UPath;
type
TPluginListItem = record
Info: TUS_PluginInfo;
- State: Byte; // State of this plugin: 0 - undefined; 1 - loaded; 2 - inited / running; 4 - unloaded; 254 - loading aborted by plugin; 255 - unloaded because of error
- Path: String; // path to this plugin
- NeedsDeInit: Boolean; // if this is inited correctly this should be true
+ State: byte; // State of this plugin: 0 - undefined; 1 - loaded; 2 - inited / running; 4 - unloaded; 254 - loading aborted by plugin; 255 - unloaded because of error
+ Path: string; // path to this plugin
+ NeedsDeInit: boolean; // if this is inited correctly this should be true
hLib: THandle; // handle of loaded libary
Procs: record // procs offered by plugin. Don't call this directly use wrappers of TPluginLoader
Load: Func_Load;
@@ -63,13 +64,13 @@ type
PPluginLoader = ^TPluginLoader;
TPluginLoader = class (TCoreModule)
private
- LoadingProcessFinished: Boolean;
+ LoadingProcessFinished: boolean;
sUnloadPlugin: THandle;
sLoadPlugin: THandle;
sGetPluginInfo: THandle;
sGetPluginState: THandle;
- procedure FreePlugin(Index: Cardinal);
+ procedure FreePlugin(Index: integer);
public
PluginInterface: TUS_PluginInterface;
Plugins: array of TPluginListItem;
@@ -77,19 +78,19 @@ type
// TCoreModule methods to inherit
constructor Create; override;
procedure Info(const pInfo: PModuleInfo); override;
- function Load: Boolean; override;
- function Init: Boolean; override;
+ function Load: boolean; override;
+ function Init: boolean; override;
procedure DeInit; override;
Destructor Destroy; override;
// New methods
- procedure BrowseDir(Path: String); // browses the path at _Path_ for plugins
- function PluginExists(Name: String): integer; // if plugin exists: Index of plugin, else -1
- procedure AddPlugin(Filename: String); // adds plugin to the array
+ procedure BrowseDir(Path: string); // browses the path at _Path_ for plugins
+ function PluginExists(Name: string): integer; // if plugin exists: Index of plugin, else -1
+ procedure AddPlugin(Filename: string); // adds plugin to the array
- function CallLoad(Index: Cardinal): integer;
- function CallInit(Index: Cardinal): integer;
- procedure CallDeInit(Index: Cardinal);
+ function CallLoad(Index: integer): integer;
+ function CallInit(Index: integer): integer;
+ procedure CallDeInit(Index: integer);
//Services offered
function LoadPlugin(wParam: TwParam; lParam: TlParam): integer; //wParam PChar(PluginName/PluginPath) | lParam (if wParam = nil) ID of the Plugin
@@ -110,10 +111,10 @@ type
public
// TCoreModule methods to inherit
constructor Create; override;
-
+
procedure Info(const pInfo: PModuleInfo); override;
- function Load: Boolean; override;
- function Init: Boolean; override;
+ function Load: boolean; override;
+ function Init: boolean; override;
procedure DeInit; override;
end;
@@ -176,7 +177,7 @@ begin
PluginInterface.ServiceExists := ServiceExists;
// UnSet private var
- LoadingProcessFinished := False;
+ LoadingProcessFinished := false;
end;
//-------------
@@ -185,15 +186,15 @@ end;
// to offer them to other modules or plugins during the init process
// if false is returned this will cause a forced exit
//-------------
-function TPluginLoader.Load: Boolean;
+function TPluginLoader.Load: boolean;
begin
- Result := True;
+ Result := true;
try
// Start searching for plugins
BrowseDir(PluginPath);
except
- Result := False;
+ Result := false;
Core.ReportError(integer(PChar('Error browsing and loading.')), PChar('TPluginLoader'));
end;
end;
@@ -204,11 +205,11 @@ end;
// your classes, variables etc.
// If false is returned this will cause a forced exit
//-------------
-function TPluginLoader.Init: Boolean;
+function TPluginLoader.Init: boolean;
begin
// Just set private var to true.
- LoadingProcessFinished := True;
- Result := True;
+ LoadingProcessFinished := true;
+ Result := true;
end;
//-------------
@@ -244,7 +245,7 @@ end;
//--------------
// Browses the path at _Path_ for plugins
//--------------
-procedure TPluginLoader.BrowseDir(Path: String);
+procedure TPluginLoader.BrowseDir(Path: string);
var
SR: TSearchRec;
begin
@@ -256,7 +257,7 @@ begin
until FindNext(SR) <> 0;
end;
FindClose(SR);
-
+
// Search for plugins at path
if FindFirst(Path + '*' + PluginFileExtension, 0, SR) = 0 then
begin
@@ -266,11 +267,11 @@ begin
end;
FindClose(SR);
end;
-
+
//--------------
// If plugin exists: Index of plugin, else -1
//--------------
-function TPluginLoader.PluginExists(Name: String): integer;
+function TPluginLoader.PluginExists(Name: string): integer;
var
I: integer;
begin
@@ -286,11 +287,11 @@ begin
end;
end;
end;
-
+
//--------------
// Adds plugin to the array
//--------------
-procedure TPluginLoader.AddPlugin(Filename: String);
+procedure TPluginLoader.AddPlugin(Filename: string);
var
hLib: THandle;
PInfo: Proc_PluginInfo;
@@ -332,7 +333,7 @@ begin
Plugins[PluginID].Info := Info;
Plugins[PluginID].State := 0;
Plugins[PluginID].Path := Filename;
- Plugins[PluginID].NeedsDeInit := False;
+ Plugins[PluginID].NeedsDeInit := false;
Plugins[PluginID].hLib := hLib;
// Try to get procs
@@ -340,7 +341,7 @@ begin
Plugins[PluginID].Procs.Init := GetProcAddress (hLib, PChar('USPlugin_Init'));
Plugins[PluginID].Procs.DeInit := GetProcAddress (hLib, PChar('USPlugin_DeInit'));
- if (@Plugins[PluginID].Procs.Load = nil) OR (@Plugins[PluginID].Procs.Init = nil) OR (@Plugins[PluginID].Procs.DeInit = nil) then
+ if (@Plugins[PluginID].Procs.Load = nil) or (@Plugins[PluginID].Procs.Init = nil) or (@Plugins[PluginID].Procs.DeInit = nil) then
begin
Plugins[PluginID].State := 255;
FreeLibrary(hLib);
@@ -354,11 +355,11 @@ begin
CallInit(PluginID);
end;
end
- else if (LoadingProcessFinished = False) then
+ else if (LoadingProcessFinished = false) then
begin
if (Plugins[PluginID].Info.Version < Info.Version) then
begin // Found newer version of this plugin
- Core.ReportDebug(integer(PChar('Found a newer version of plugin: ' + String(Info.Name))), PChar('TPluginLoader'));
+ Core.ReportDebug(integer(PChar('Found a newer version of plugin: ' + string(Info.Name))), PChar('TPluginLoader'));
// Unload old plugin
UnloadPlugin(PluginID, nil);
@@ -367,7 +368,7 @@ begin
Plugins[PluginID].Info := Info;
Plugins[PluginID].State := 0;
Plugins[PluginID].Path := Filename;
- Plugins[PluginID].NeedsDeInit := False;
+ Plugins[PluginID].NeedsDeInit := false;
Plugins[PluginID].hLib := hLib;
// Try to get procs
@@ -375,7 +376,7 @@ begin
Plugins[PluginID].Procs.Init := GetProcAddress (hLib, PChar('USPlugin_Init'));
Plugins[PluginID].Procs.DeInit := GetProcAddress (hLib, PChar('USPlugin_DeInit'));
- if (@Plugins[PluginID].Procs.Load = nil) OR (@Plugins[PluginID].Procs.Init = nil) OR (@Plugins[PluginID].Procs.DeInit = nil) then
+ if (@Plugins[PluginID].Procs.Load = nil) or (@Plugins[PluginID].Procs.Init = nil) or (@Plugins[PluginID].Procs.DeInit = nil) then
begin
FreeLibrary(hLib);
Plugins[PluginID].State := 255;
@@ -390,7 +391,7 @@ begin
else
begin
FreeLibrary(hLib);
- Core.ReportError(integer(PChar('Plugin with this name already exists: ' + String(Info.Name))), PChar('TPluginLoader'));
+ Core.ReportError(integer(PChar('Plugin with this name already exists: ' + string(Info.Name))), PChar('TPluginLoader'));
end;
end
else
@@ -413,7 +414,7 @@ end;
//--------------
// Calls load func of plugin with the given index
//--------------
-function TPluginLoader.CallLoad(Index: Cardinal): integer;
+function TPluginLoader.CallLoad(Index: integer): integer;
begin
Result := -2;
if(Index < Length(Plugins)) then
@@ -424,7 +425,7 @@ begin
Result := Plugins[Index].Procs.Load(@PluginInterface);
except
Result := -3;
- End;
+ end;
if (Result = 0) then
Plugins[Index].State := 1
@@ -432,7 +433,7 @@ begin
begin
FreePlugin(Index);
Plugins[Index].State := 255;
- Core.ReportError(integer(PChar('Error calling load function from plugin: ' + String(Plugins[Index].Info.Name))), PChar('TPluginLoader'));
+ Core.ReportError(integer(PChar('Error calling load function from plugin: ' + string(Plugins[Index].Info.Name))), PChar('TPluginLoader'));
end;
end;
end;
@@ -441,7 +442,7 @@ end;
//--------------
// Calls init func of plugin with the given index
//--------------
-function TPluginLoader.CallInit(Index: Cardinal): integer;
+function TPluginLoader.CallInit(Index: integer): integer;
begin
Result := -2;
if(Index < Length(Plugins)) then
@@ -452,18 +453,18 @@ begin
Result := Plugins[Index].Procs.Init(@PluginInterface);
except
Result := -3;
- End;
-
+ end;
+
if (Result = 0) then
begin
Plugins[Index].State := 2;
- Plugins[Index].NeedsDeInit := True;
+ Plugins[Index].NeedsDeInit := true;
end
else
begin
FreePlugin(Index);
Plugins[Index].State := 255;
- Core.ReportError(integer(PChar('Error calling init function from plugin: ' + String(Plugins[Index].Info.Name))), PChar('TPluginLoader'));
+ Core.ReportError(integer(PChar('Error calling init function from plugin: ' + string(Plugins[Index].Info.Name))), PChar('TPluginLoader'));
end;
end;
end;
@@ -472,7 +473,7 @@ end;
//--------------
// Calls deinit proc of plugin with the given index
//--------------
-procedure TPluginLoader.CallDeInit(Index: Cardinal);
+procedure TPluginLoader.CallDeInit(Index: integer);
begin
if(Index < Length(Plugins)) then
begin
@@ -483,7 +484,7 @@ begin
Plugins[Index].Procs.DeInit(@PluginInterface);
except
- End;
+ end;
// Don't forget to remove services and subscriptions by this plugin
Core.Hooks.DelbyOwner(-1 - Index);
@@ -496,7 +497,7 @@ end;
//--------------
// Frees all plugin sources (procs and handles) - helper for deiniting functions
//--------------
-procedure TPluginLoader.FreePlugin(Index: Cardinal);
+procedure TPluginLoader.FreePlugin(Index: integer);
begin
Plugins[Index].State := 4;
Plugins[Index].Procs.Load := nil;
@@ -507,15 +508,13 @@ begin
FreeLibrary(Plugins[Index].hLib);
end;
-
-
//--------------
// wParam PChar(PluginName/PluginPath) | wParam (if lParam = nil) ID of the plugin
//--------------
function TPluginLoader.LoadPlugin(wParam: TwParam; lParam: TlParam): integer;
var
Index: integer;
- sFile: String;
+ sFile: string;
begin
Result := -1;
sFile := '';
@@ -527,9 +526,9 @@ begin
else
begin //lParam is PChar
try
- sFile := String(PChar(lParam));
+ sFile := string(PChar(lParam));
Index := PluginExists(sFile);
- if (Index < 0) And FileExists(sFile) then
+ if (Index < 0) and FileExists(sFile) then
begin // Is filename
AddPlugin(sFile);
Result := Plugins[High(Plugins)].State;
@@ -539,7 +538,6 @@ begin
end;
end;
-
if (Index >= 0) and (Index < Length(Plugins)) then
begin
AddPlugin(Plugins[Index].Path);
@@ -553,7 +551,7 @@ end;
function TPluginLoader.UnloadPlugin(wParam: TwParam; lParam: TlParam): integer;
var
Index: integer;
- sName: String;
+ sName: string;
begin
Result := -1;
// lParam is ID
@@ -564,14 +562,13 @@ begin
else
begin // wParam is PChar
try
- sName := String(PChar(lParam));
+ sName := string(PChar(lParam));
Index := PluginExists(sName);
except
Index := -2;
end;
end;
-
if (Index >= 0) and (Index < Length(Plugins)) then
CallDeInit(Index)
end;
@@ -592,7 +589,7 @@ begin
PUS_PluginInfo(lParam)^ := Plugins[wParam].Info;
except
- End;
+ end;
end;
end
else if (lParam = nil) then
@@ -607,13 +604,13 @@ begin
Result := Length(Plugins);
except
Core.ReportError(integer(PChar('Could not write PluginInfo Array')), PChar('TPluginLoader'));
- End;
+ end;
end;
end;
//--------------
-// if wParam = -1 then (if lParam = nil then get length of plugin state array. if lparam <> nil then write array of Byte to address at lparam) else (return state of plugin with index(wParam))
+// if wParam = -1 then (if lParam = nil then get length of plugin state array. if lparam <> nil then write array of byte to address at lparam) else (return state of plugin with index(wParam))
//--------------
function TPluginLoader.GetPluginState(wParam: TwParam; lParam: TlParam): integer;
var I: integer;
@@ -634,15 +631,14 @@ begin
begin
try
for I := 0 to high(Plugins) do
- Byte(Pointer(integer(lParam) + I)^) := Plugins[I].State;
+ byte(Pointer(integer(lParam) + I)^) := Plugins[I].State;
Result := Length(Plugins);
except
Core.ReportError(integer(PChar('Could not write pluginstate array')), PChar('TPluginLoader'));
- End;
+ end;
end;
end;
-
{*********************
TtehPlugins
Implementation
@@ -673,7 +669,7 @@ end;
// to offer them to other modules or plugins during the init process
// if false is returned this will cause a forced exit
//-------------
-function TtehPlugins.Load: Boolean;
+function TtehPlugins.Load: boolean;
var
i: integer; // Counter
CurExecutedBackup: integer; //backup of Core.CurExecuted Attribute
@@ -703,11 +699,11 @@ begin
begin
PluginLoader.CallDeInit(i);
PluginLoader.Plugins[i].State := 254; // Plugin asks for unload
- Core.ReportDebug(integer(PChar('Plugin selfabort during loading process: ' + String(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
+ Core.ReportDebug(integer(PChar('Plugin selfabort during loading process: ' + string(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
end
else
begin
- Core.ReportDebug(integer(PChar('Plugin loaded succesfully: ' + String(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
+ Core.ReportDebug(integer(PChar('Plugin loaded succesfully: ' + string(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
end;
except
// Plugin could not be loaded.
@@ -721,7 +717,7 @@ begin
end;
end;
- // Reset CurExecuted
+ // Reset CurExecuted
Core.CurExecuted := CurExecutedBackup;
end;
end;
@@ -732,7 +728,7 @@ end;
// your classes, variables etc.
// if false is returned this will cause a forced exit
//-------------
-function TtehPlugins.Init: Boolean;
+function TtehPlugins.Init: boolean;
var
i: integer; // Counter
CurExecutedBackup: integer; // backup of Core.CurExecuted attribute
@@ -752,16 +748,16 @@ begin
begin
PluginLoader.CallDeInit(i);
PluginLoader.Plugins[i].State := 254; //Plugin asks for unload
- Core.ReportDebug(integer(PChar('Plugin selfabort during init process: ' + String(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
+ Core.ReportDebug(integer(PChar('Plugin selfabort during init process: ' + string(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
end
else
- Core.ReportDebug(integer(PChar('Plugin inited succesfully: ' + String(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
+ Core.ReportDebug(integer(PChar('Plugin inited succesfully: ' + string(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
except
// Plugin could not be loaded.
// => Show error message, then shut down plugin
PluginLoader.CallDeInit(i);
PluginLoader.Plugins[i].State := 255; //Plugin causes Error
- Core.ReportError(integer(PChar('Plugin causes error during init process: ' + String(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
+ Core.ReportError(integer(PChar('Plugin causes error during init process: ' + string(PluginLoader.Plugins[i].Info.Name))), PChar('TtehPlugins'));
end;
// Reset CurExecuted
@@ -781,7 +777,7 @@ begin
CurExecutedBackup := Core.CurExecuted;
// Start loop
-
+
for i := 0 to High(PluginLoader.Plugins) do
begin
try
diff --git a/unicode/src/base/URecord.pas b/unicode/src/base/URecord.pas
index 132bafd5..8f37262d 100644
--- a/unicode/src/base/URecord.pas
+++ b/unicode/src/base/URecord.pas
@@ -36,26 +36,26 @@ interface
uses
Classes,
Math,
- SysUtils,
sdl,
+ SysUtils,
UCommon,
UMusic,
UIni;
const
BaseToneFreq = 65.4064; // lowest (half-)tone to analyze (C2 = 65.4064 Hz)
- NumHalftones = 36; // C2-B4 (for Whitney and my high voice)
+ NumHalftones = 36; // C2-B4 (for Whitney and my high voice)
type
TCaptureBuffer = class
private
- VoiceStream: TAudioVoiceStream; // stream for voice passthrough
+ VoiceStream: TAudioVoiceStream; // stream for voice passthrough
AnalysisBufferLock: PSDL_Mutex;
function GetToneString: string; // converts a tone to its string represenatation;
- procedure BoostBuffer(Buffer: PChar; Size: Cardinal);
- procedure ProcessNewBuffer(Buffer: PChar; BufferSize: integer);
+ procedure BoostBuffer(Buffer: PByteArray; Size: cardinal);
+ procedure ProcessNewBuffer(Buffer: PByteArray; BufferSize: integer);
// we call it to analyze sound by checking Autocorrelation
procedure AnalyzeByAutocorrelation;
@@ -86,7 +86,7 @@ type
procedure LockAnalysisBuffer(); {$IFDEF HasInline}inline;{$ENDIF}
procedure UnlockAnalysisBuffer(); {$IFDEF HasInline}inline;{$ENDIF}
- function MaxSampleVolume: Single;
+ function MaxSampleVolume: single;
property ToneString: string READ GetToneString;
end;
@@ -95,17 +95,17 @@ const
type
TAudioInputSource = record
- Name: string;
+ Name: string;
end;
// soundcard input-devices information
TAudioInputDevice = class
public
- CfgIndex: integer; // index of this device in Ini.InputDeviceConfig
- Name: string; // soundcard name
- Source: array of TAudioInputSource; // soundcard input-sources
- SourceRestore: integer; // source-index that will be selected after capturing (-1: not detected)
- MicSource: integer; // source-index of mic (-1: none detected)
+ CfgIndex: integer; // index of this device in Ini.InputDeviceConfig
+ Name: string; // soundcard name
+ Source: array of TAudioInputSource; // soundcard input-sources
+ SourceRestore: integer; // source-index that will be selected after capturing (-1: not detected)
+ MicSource: integer; // source-index of mic (-1: none detected)
AudioFormat: TAudioFormatInfo; // capture format info (e.g. 44.1kHz SInt16 stereo)
CaptureChannel: array of TCaptureBuffer; // sound-buffer references used for mono or stereo channel's capture data
@@ -115,10 +115,10 @@ type
procedure LinkCaptureBuffer(ChannelIndex: integer; Sound: TCaptureBuffer);
// TODO: add Open/Close functions so Start/Stop becomes faster
- //function Open(): boolean; virtual; abstract;
- //function Close(): boolean; virtual; abstract;
- function Start(): boolean; virtual; abstract;
- function Stop(): boolean; virtual; abstract;
+ //function Open(): boolean; virtual; abstract;
+ //function Close(): boolean; virtual; abstract;
+ function Start(): boolean; virtual; abstract;
+ function Stop(): boolean; virtual; abstract;
function GetVolume(): single; virtual; abstract;
procedure SetVolume(Volume: single); virtual; abstract;
@@ -135,7 +135,7 @@ type
procedure UpdateInputDeviceConfig;
// handle microphone input
- procedure HandleMicrophoneData(Buffer: PChar; Size: Cardinal;
+ procedure HandleMicrophoneData(Buffer: PByteArray; Size: cardinal;
InputDevice: TAudioInputDevice);
end;
@@ -153,7 +153,6 @@ type
procedure CaptureStop;
end;
-
TSmallIntArray = array [0..(MaxInt div SizeOf(SmallInt))-1] of SmallInt;
PSmallIntArray = ^TSmallIntArray;
@@ -163,12 +162,11 @@ implementation
uses
ULog,
- UMain;
+ UNote;
var
singleton_AudioInputProcessor : TAudioInputProcessor = nil;
-
{ Global }
function AudioInputProcessor(): TAudioInputProcessor;
@@ -179,7 +177,6 @@ begin
result := singleton_AudioInputProcessor;
end;
-
{ TAudioInputDevice }
destructor TAudioInputDevice.Destroy;
@@ -268,11 +265,11 @@ begin
UnlockAnalysisBuffer();
end;
-procedure TCaptureBuffer.ProcessNewBuffer(Buffer: PChar; BufferSize: integer);
+procedure TCaptureBuffer.ProcessNewBuffer(Buffer: PByteArray; BufferSize: integer);
var
BufferOffset: integer;
- SampleCount: integer;
- i: integer;
+ SampleCount: integer;
+ i: integer;
begin
// apply software boost
BoostBuffer(Buffer, BufferSize);
@@ -299,7 +296,6 @@ begin
SampleCount := Length(AnalysisBuffer);
end;
-
LockAnalysisBuffer();
try
@@ -315,7 +311,6 @@ begin
UnlockAnalysisBuffer();
end;
-
// save capture-data to BufferLong if enabled
if (Ini.SavePlayback = 1) then
begin
@@ -329,10 +324,10 @@ end;
procedure TCaptureBuffer.AnalyzeBuffer;
var
- Volume: single;
- MaxVolume: single;
+ Volume: single;
+ MaxVolume: single;
SampleIndex: integer;
- Threshold: single;
+ Threshold: single;
begin
ToneValid := false;
ToneAbs := -1;
@@ -431,10 +426,10 @@ begin
Result := 1 - AccumDist / AnalysisBufferSize;
end;
-function TCaptureBuffer.MaxSampleVolume: Single;
+function TCaptureBuffer.MaxSampleVolume: single;
var
- lSampleIndex: Integer;
- lMaxVol : Longint;
+ lSampleIndex: integer;
+ lMaxVol: longint;
begin;
LockAnalysisBuffer();
try
@@ -464,13 +459,13 @@ begin
Result := '-';
end;
-procedure TCaptureBuffer.BoostBuffer(Buffer: PChar; Size: Cardinal);
+procedure TCaptureBuffer.BoostBuffer(Buffer: PByteArray; Size: cardinal);
var
- i: integer;
- Value: Longint;
- SampleCount: integer;
+ i: integer;
+ Value: longint;
+ SampleCount: integer;
SampleBuffer: PSmallIntArray; // buffer handled as array of samples
- Boost: byte;
+ Boost: byte;
begin
// TODO: set boost per device
case Ini.MicBoost of
@@ -504,7 +499,6 @@ begin
end;
end;
-
{ TAudioInputProcessor }
constructor TAudioInputProcessor.Create;
@@ -531,14 +525,14 @@ end;
// See: TIni.LoadInputDeviceCfg()
procedure TAudioInputProcessor.UpdateInputDeviceConfig;
var
- deviceIndex: integer;
- newDevice: boolean;
+ deviceIndex: integer;
+ newDevice: boolean;
deviceIniIndex: integer;
- deviceCfg: PInputDeviceConfig;
- device: TAudioInputDevice;
- channelCount: integer;
- channelIndex: integer;
- i: integer;
+ deviceCfg: PInputDeviceConfig;
+ device: TAudioInputDevice;
+ channelCount: integer;
+ channelIndex: integer;
+ i: integer;
begin
// Input devices - append detected soundcards
for deviceIndex := 0 to High(DeviceList) do
@@ -608,18 +602,18 @@ end;
* Length - number of bytes in Buffer
* Input - Soundcard-Input used for capture
*}
-procedure TAudioInputProcessor.HandleMicrophoneData(Buffer: PChar; Size: Cardinal; InputDevice: TAudioInputDevice);
+procedure TAudioInputProcessor.HandleMicrophoneData(Buffer: PByteArray; Size: cardinal; InputDevice: TAudioInputDevice);
var
- MultiChannelBuffer: PChar; // buffer handled as array of bytes (offset relative to channel)
- SingleChannelBuffer: PChar; // temporary buffer for new samples per channel
+ MultiChannelBuffer: PByteArray; // buffer handled as array of bytes (offset relative to channel)
+ SingleChannelBuffer: PByteArray; // temporary buffer for new samples per channel
SingleChannelBufferSize: integer;
- ChannelIndex: integer;
- CaptureChannel: TCaptureBuffer;
- AudioFormat: TAudioFormatInfo;
- SampleSize: integer;
- SampleCount: integer;
- SamplesPerChannel: integer;
- i: integer;
+ ChannelIndex: integer;
+ CaptureChannel: TCaptureBuffer;
+ AudioFormat: TAudioFormatInfo;
+ SampleSize: integer;
+ SampleCount: integer;
+ SamplesPerChannel: integer;
+ i: integer;
begin
AudioFormat := InputDevice.AudioFormat;
SampleSize := AudioSampleSize[AudioFormat.Format];
@@ -638,7 +632,7 @@ begin
begin
// set offset according to channel index
MultiChannelBuffer := @Buffer[ChannelIndex * SampleSize];
- // seperate channel-data from interleaved multi-channel (e.g. stereo) data
+ // separate channel-data from interleaved multi-channel (e.g. stereo) data
for i := 0 to SamplesPerChannel-1 do
begin
Move(MultiChannelBuffer[i*AudioFormat.FrameSize],
@@ -652,7 +646,6 @@ begin
FreeMem(SingleChannelBuffer);
end;
-
{ TAudioInputBase }
function TAudioInputBase.FinalizeRecord: boolean;
@@ -670,13 +663,13 @@ end;
*}
procedure TAudioInputBase.CaptureStart;
var
- S: integer;
- DeviceIndex: integer;
+ S: integer;
+ DeviceIndex: integer;
ChannelIndex: integer;
- Device: TAudioInputDevice;
- DeviceCfg: PInputDeviceConfig;
- DeviceUsed: boolean;
- Player: integer;
+ Device: TAudioInputDevice;
+ DeviceCfg: PInputDeviceConfig;
+ DeviceUsed: boolean;
+ Player: integer;
begin
if (Started) then
CaptureStop();
@@ -728,10 +721,10 @@ end;
*}
procedure TAudioInputBase.CaptureStop;
var
- DeviceIndex: integer;
+ DeviceIndex: integer;
ChannelIndex: integer;
- Device: TAudioInputDevice;
- DeviceCfg: PInputDeviceConfig;
+ Device: TAudioInputDevice;
+ DeviceCfg: PInputDeviceConfig;
begin
for DeviceIndex := 0 to High(AudioInputProcessor.DeviceList) do
begin
@@ -758,17 +751,18 @@ var
var
i: integer;
begin
- Result := False;
+ Result := false;
// search devices with same description
- For i := 0 to deviceIndex-1 do
+ for i := 0 to deviceIndex-1 do
begin
if (AudioInputProcessor.DeviceList[i].Name = name) then
begin
- Result := True;
+ Result := true;
Break;
end;
end;
end;
+
begin
count := 1;
result := name;
@@ -783,6 +777,3 @@ begin
end;
end.
-
-
-
diff --git a/unicode/src/base/URingBuffer.pas b/unicode/src/base/URingBuffer.pas
index 515d0efb..684c13ee 100644
--- a/unicode/src/base/URingBuffer.pas
+++ b/unicode/src/base/URingBuffer.pas
@@ -39,7 +39,7 @@ uses
type
TRingBuffer = class
private
- RingBuffer: PChar;
+ RingBuffer: PByteArray;
BufferCount: integer;
BufferSize: integer;
WritePos: integer;
@@ -47,8 +47,10 @@ type
public
constructor Create(Size: integer);
destructor Destroy; override;
- function Read(Buffer: PChar; Count: integer): integer;
- function Write(Buffer: PChar; Count: integer): integer;
+ function Read(Buffer: PByteArray; Count: integer): integer;
+ function Write(Buffer: PByteArray; Count: integer): integer;
+ function Size(): integer;
+ function Available(): integer;
procedure Flush();
end;
@@ -71,7 +73,7 @@ begin
FreeMem(RingBuffer);
end;
-function TRingBuffer.Read(Buffer: PChar; Count: integer): integer;
+function TRingBuffer.Read(Buffer: PByteArray; Count: integer): integer;
var
PartCount: integer;
begin
@@ -106,7 +108,7 @@ begin
Result := Count;
end;
-function TRingBuffer.Write(Buffer: PChar; Count: integer): integer;
+function TRingBuffer.Write(Buffer: PByteArray; Count: integer): integer;
var
PartCount: integer;
begin
@@ -143,6 +145,16 @@ begin
Result := Count;
end;
+function TRingBuffer.Available(): integer;
+begin
+ Result := BufferCount;
+end;
+
+function TRingBuffer.Size(): integer;
+begin
+ Result := BufferSize;
+end;
+
procedure TRingBuffer.Flush();
begin
ReadPos := 0;
@@ -150,4 +162,4 @@ begin
BufferCount := 0;
end;
-end. \ No newline at end of file
+end.
diff --git a/unicode/src/base/USkins.pas b/unicode/src/base/USkins.pas
index df736684..a4722d95 100644
--- a/unicode/src/base/USkins.pas
+++ b/unicode/src/base/USkins.pas
@@ -35,23 +35,23 @@ interface
type
TSkinTexture = record
- Name: string;
- FileName: string;
+ Name: string;
+ FileName: string;
end;
TSkinEntry = record
- Theme: string;
- Name: string;
- Path: string;
- FileName: string;
- Creator: string; // not used yet
+ Theme: string;
+ Name: string;
+ Path: string;
+ FileName: string;
+ Creator: string; // not used yet
end;
TSkin = class
- Skin: array of TSkinEntry;
- SkinTexture: array of TSkinTexture;
- SkinPath: string;
- Color: integer;
+ Skin: array of TSkinEntry;
+ SkinTexture: array of TSkinTexture;
+ SkinPath: string;
+ Color: integer;
constructor Create;
procedure LoadList;
procedure ParseDir(Dir: string);
@@ -63,30 +63,33 @@ type
end;
var
- Skin: TSkin;
+ Skin: TSkin;
implementation
-uses IniFiles,
- Classes,
- SysUtils,
- UMain,
- ULog,
- UIni;
+uses
+ IniFiles,
+ Classes,
+ SysUtils,
+ UIni,
+ ULog,
+ UMain,
+ UPath;
constructor TSkin.Create;
begin
inherited;
LoadList;
-// LoadSkin('Lisek');
+// LoadSkin('...');
// SkinColor := Color;
end;
procedure TSkin.LoadList;
var
- SR: TSearchRec;
+ SR: TSearchRec;
begin
- if FindFirst(SkinsPath+'*', faDirectory, SR) = 0 then begin
+ if FindFirst(SkinsPath+'*', faDirectory, SR) = 0 then
+ begin
repeat
if (SR.Name <> '.') and (SR.Name <> '..') then
ParseDir(SkinsPath + SR.Name + PathDelim);
@@ -97,9 +100,10 @@ end;
procedure TSkin.ParseDir(Dir: string);
var
- SR: TSearchRec;
+ SR: TSearchRec;
begin
- if FindFirst(Dir + '*.ini', faAnyFile, SR) = 0 then begin
+ if FindFirst(Dir + '*.ini', faAnyFile, SR) = 0 then
+ begin
repeat
if (SR.Name <> '.') and (SR.Name <> '..') then
@@ -111,8 +115,8 @@ end;
procedure TSkin.LoadHeader(FileName: string);
var
- SkinIni: TMemIniFile;
- S: integer;
+ SkinIni: TMemIniFile;
+ S: integer;
begin
SkinIni := TMemIniFile.Create(FileName);
@@ -130,10 +134,10 @@ end;
procedure TSkin.LoadSkin(Name: string);
var
- SkinIni: TMemIniFile;
- SL: TStringList;
- T: integer;
- S: integer;
+ SkinIni: TMemIniFile;
+ SL: TStringList;
+ T: integer;
+ S: integer;
begin
S := GetSkinNumber(Name);
SkinPath := Skin[S].Path;
@@ -156,39 +160,43 @@ end;
function TSkin.GetTextureFileName(TextureName: string): string;
var
- T: integer;
+ T: integer;
begin
Result := '';
for T := 0 to High(SkinTexture) do
begin
- if ( SkinTexture[T].Name = TextureName ) AND
+ if ( SkinTexture[T].Name = TextureName ) and
( SkinTexture[T].FileName <> '' ) then
begin
Result := SkinPath + SkinTexture[T].FileName;
end;
end;
- if ( TextureName <> '' ) AND
- ( Result <> '' ) THEN
+ if ( TextureName <> '' ) and
+ ( Result <> '' ) then
begin
//Log.LogError('', '-----------------------------------------');
//Log.LogError(TextureName+' - '+ Result, 'TSkin.GetTextureFileName');
end;
{ Result := SkinPath + 'Bar.jpg';
- if TextureName = 'Ball' then Result := SkinPath + 'Ball.bmp';
- if Copy(TextureName, 1, 4) = 'Gray' then Result := SkinPath + 'Ball.bmp';
- if Copy(TextureName, 1, 6) = 'NoteBG' then Result := SkinPath + 'Ball.bmp';}
+ if TextureName = 'Ball' then
+ Result := SkinPath + 'Ball.bmp';
+ if Copy(TextureName, 1, 4) = 'Gray' then
+ Result := SkinPath + 'Ball.bmp';
+ if Copy(TextureName, 1, 6) = 'NoteBG' then
+ Result := SkinPath + 'Ball.bmp';}
end;
function TSkin.GetSkinNumber(Name: string): integer;
var
- S: integer;
+ S: integer;
begin
Result := 0; // set default to the first available skin
for S := 0 to High(Skin) do
- if Skin[S].Name = Name then Result := S;
+ if Skin[S].Name = Name then
+ Result := S;
end;
procedure TSkin.onThemeChange;
@@ -200,7 +208,8 @@ begin
SetLength(ISkin, 0);
Name := Uppercase(ITheme[Ini.Theme]);
for S := 0 to High(Skin) do
- if Name = Uppercase(Skin[S].Theme) then begin
+ if Name = Uppercase(Skin[S].Theme) then
+ begin
SetLength(ISkin, Length(ISkin)+1);
ISkin[High(ISkin)] := Skin[S].Name;
end;
diff --git a/unicode/src/base/USong.pas b/unicode/src/base/USong.pas
index 69c6615d..a547a077 100644
--- a/unicode/src/base/USong.pas
+++ b/unicode/src/base/USong.pas
@@ -74,7 +74,7 @@ type
end;
TSong = class
- FileLineNo : integer; //Line which is readed at Last, for error reporting
+ FileLineNo : integer; // line, which is read last, for error reporting
function EncodeFilename(Filename: string): string;
function Solmizate(Note: integer; Type_: integer): string;
@@ -135,8 +135,8 @@ type
MultBPM : integer;
LastError: AnsiString;
- Function GetErrorLineNo: Integer;
- Property ErrorLineNo: Integer read GetErrorLineNo;
+ function GetErrorLineNo: integer;
+ property ErrorLineNo: integer read GetErrorLineNo;
constructor Create(); overload;
@@ -151,17 +151,54 @@ type
implementation
uses
+ StrUtils,
TextGL,
UIni,
+ UPath,
UMusic, //needed for Lines
- UMain; //needed for Player
+ UNote; //needed for Player
constructor TSong.Create();
begin
inherited;
end;
-constructor TSong.Create( const aFileName : WideString );
+constructor TSong.Create( const aFileName: WideString );
+ // This may be changed, when we rewrite song select code.
+ // it is some kind of dirty, but imho the best possible
+ // solution as we do atm not support nested categorys.
+ // it works like the folder sorting in 1.0.1a
+ // folder is set to the first folder under the songdir
+ // so songs ~/.ultrastardx/songs/punk is in the same
+ // category as songs in shared/ultrastardx/songs are.
+ // note: folder is just the name of a category it has
+ // nothing to do with the path used for file loading
+ function GetFolderCategory: WideString;
+ var
+ I: Integer;
+ P: Integer; //position of next path delimiter
+ begin
+ Result := 'Unknown'; //default folder category, if we can't locate the song dir
+
+ for I := 0 to SongPaths.Count-1 do
+ if (AnsiStartsText(SongPaths.Strings[I], aFilename)) then
+ begin
+ P := PosEx(PathDelim, aFilename, Length(SongPaths.Strings[I]) + 1);
+
+ If (P > 0) then
+ begin
+ // we have found the category name => get it
+ Result := copy(self.Path, Length(SongPaths.Strings[I]) + 1, P - Length(SongPaths.Strings[I]) - 1);
+ end
+ else
+ begin
+ // songs are in the "root" of the songdir => use songdir for the categorys name
+ Result := SongPaths.Strings[I];
+ end;
+
+ Exit;
+ end;
+ end;
begin
inherited Create();
@@ -174,7 +211,7 @@ begin
if fileexists( aFileName ) then
begin
self.Path := ExtractFilePath( aFileName );
- self.Folder := ExtractFilePath( aFileName );
+ self.Folder := GetFolderCategory;
self.FileName := ExtractFileName( aFileName );
(*
if ReadTXTHeader( aFileName ) then
@@ -229,9 +266,6 @@ begin
MultBPM := 4; // multiply beat-count of note by 4
Mult := 1; // accuracy of measurement of note
- Base[0] := 100; // high number
- Lines[0].ScoreValue := 0;
- self.Relative := false;
Rel[0] := 0;
CP := 0;
Both := false;
@@ -271,20 +305,24 @@ begin
SetLength(Lines, 2);
for Count := 0 to High(Lines) do
begin
- SetLength(Lines[Count].Line, 1);
Lines[Count].High := 0;
Lines[Count].Number := 1;
Lines[Count].Current := 0;
Lines[Count].Resolution := self.Resolution;
Lines[Count].NotesGAP := self.NotesGAP;
+ Lines[Count].ScoreValue := 0;
+
+ //Add first line and set some standard values to fields
+ //see procedure NewSentence for further explantation
+ //concerning most of these values
+ SetLength(Lines[Count].Line, 1);
Lines[Count].Line[0].HighNote := -1;
- Lines[Count].Line[0].LastLine := False;
+ Lines[Count].Line[0].LastLine := false;
+ Lines[Count].Line[0].BaseNote := High(Integer);
+ Lines[Count].Line[0].TotalNotes := 0;
end;
- //TempC := ':';
- //TempC := Text[1]; // read from backup variable, don't use default ':' value
-
- while (TempC <> 'E') AND (not EOF(SongFile)) do
+ while (TempC <> 'E') and (not EOF(SongFile)) do
begin
if (TempC = ':') or (TempC = '*') or (TempC = 'F') then
@@ -296,13 +334,16 @@ begin
Read(SongFile, ParamS);
//Check for ZeroNote
- if Param2 = 0 then Log.LogError('Found ZeroNote at "'+TempC+' '+IntToStr(Param1)+' '+IntToStr(Param2)+' '+IntToStr(Param3)+ParamS+'" -> Note ignored!') else
+ if Param2 = 0 then
+ Log.LogError('Found ZeroNote at "'+TempC+' '+IntToStr(Param1)+' '+IntToStr(Param2)+' '+IntToStr(Param3)+ParamS+'" -> Note ignored!')
+ else
begin
// add notes
if not Both then
// P1
ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS)
- else begin
+ else
+ begin
// P1 + P2
ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS);
ParseNote(1, TempC, (Param1+Rel[1]) * Mult, Param2 * Mult, Param3, ParamS);
@@ -310,24 +351,26 @@ begin
end; //Zeronote check
end // if
- Else if TempC = '-' then
+ else if TempC = '-' then
begin
// reads sentence
Read(SongFile, Param1);
- if self.Relative then Read(SongFile, Param2); // read one more data for relative system
+ if self.Relative then
+ Read(SongFile, Param2); // read one more data for relative system
// new sentence
if not Both then
// P1
NewSentence(0, (Param1 + Rel[0]) * Mult, Param2)
- else begin
+ else
+ begin
// P1 + P2
NewSentence(0, (Param1 + Rel[0]) * Mult, Param2);
NewSentence(1, (Param1 + Rel[1]) * Mult, Param2);
end;
end // if
- Else if TempC = 'B' then
+ else if TempC = 'B' then
begin
SetLength(self.BPM, Length(self.BPM) + 1);
Read(SongFile, self.BPM[High(self.BPM)].StartBeat);
@@ -338,42 +381,7 @@ begin
self.BPM[High(self.BPM)].BPM := self.BPM[High(self.BPM)].BPM * Mult * MultBPM;
end;
-
- if not Both then
- begin
- Lines[CP].Line[Lines[CP].High].BaseNote := Base[CP];
- Lines[CP].Line[Lines[CP].High].LyricWidth := glTextWidth(Lines[CP].Line[Lines[CP].High].Lyric);
- //Total Notes Patch
- Lines[CP].Line[Lines[CP].High].TotalNotes := 0;
- for I := low(Lines[CP].Line[Lines[CP].High].Note) to high(Lines[CP].Line[Lines[CP].High].Note) do
- begin
- if (Lines[CP].Line[Lines[CP].High].Note[I].NoteType = ntGolden) then
- Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[I].Length;
-
- if (Lines[CP].Line[Lines[CP].High].Note[I].NoteType <> ntFreestyle) then
- Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[I].Length;
- end;
- //Total Notes Patch End
- end
- else
- begin
- for Count := 0 to High(Lines) do
- begin
- Lines[Count].Line[Lines[Count].High].BaseNote := Base[Count];
- Lines[Count].Line[Lines[Count].High].LyricWidth := glTextWidth(Lines[Count].Line[Lines[Count].High].Lyric);
- //Total Notes Patch
- Lines[Count].Line[Lines[Count].High].TotalNotes := 0;
- for I := low(Lines[Count].Line[Lines[Count].High].Note) to high(Lines[Count].Line[Lines[Count].High].Note) do
- begin
- if (Lines[Count].Line[Lines[Count].High].Note[I].NoteType = ntGolden) then
- Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[I].Length;
- if (Lines[Count].Line[Lines[Count].High].Note[I].NoteType <> ntFreestyle) then
- Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[I].Length;
- end;
- //Total Notes Patch End
- end;
- end;
- ReadLn(SongFile); //Jump to next line in File, otherwise the next Read would catch the linebreak(e.g. #13 #10 on win32)
+ ReadLn(SongFile); //Jump to next line in File, otherwise the next Read would catch the linebreak(e.g. #13 #10 on win32)
Read(SongFile, TempC);
Inc(FileLineNo);
@@ -381,18 +389,18 @@ begin
CloseFile(SongFile);
- For I := 0 to High(Lines) do
+ for I := 0 to High(Lines) do
begin
- If ((Both) or (I = 0)) then
+ if ((Both) or (I = 0)) then
begin
- If (Length(Lines[I].Line) < 2) then
+ if (Length(Lines[I].Line) < 2) then
begin
LastError := 'ERROR_CORRUPT_SONG_NO_BREAKS';
Log.LogError('Error Loading File, Can''t find any Linebreaks: "' + fFileName + '"');
exit;
end;
- If (Lines[I].Line[Lines[I].High].HighNote < 0) then
+ if (Lines[I].Line[Lines[I].High].HighNote < 0) then
begin
SetLength(Lines[I].Line, Lines[I].Number - 1);
Lines[I].High := Lines[I].High - 1;
@@ -404,8 +412,8 @@ begin
for Count := 0 to High(Lines) do
begin
- If (High(Lines[Count].Line) >= 0) then
- Lines[Count].Line[High(Lines[Count].Line)].LastLine := True;
+ if (High(Lines[Count].Line) >= 0) then
+ Lines[Count].Line[High(Lines[Count].Line)].LastLine := true;
end;
except
try
@@ -452,7 +460,6 @@ begin
MultBPM := 4; // multiply beat-count of note by 4
Mult := 1; // accuracy of measurement of note
- Base[0] := 100; // high number
Lines[0].ScoreValue := 0;
self.Relative := false;
Rel[0] := 0;
@@ -467,14 +474,21 @@ begin
for Count := 0 to High(Lines) do
begin
- SetLength(Lines[Count].Line, 1);
Lines[Count].High := 0;
- Lines[Count].Number := 1;
- Lines[Count].Current := 0;
- Lines[Count].Resolution := self.Resolution;
- Lines[Count].NotesGAP := self.NotesGAP;
- Lines[Count].Line[0].HighNote := -1;
- Lines[Count].Line[0].LastLine := False;
+ Lines[Count].Number := 1;
+ Lines[Count].Current := 0;
+ Lines[Count].Resolution := self.Resolution;
+ Lines[Count].NotesGAP := self.NotesGAP;
+ Lines[Count].ScoreValue := 0;
+
+ //Add first line and set some standard values to fields
+ //see procedure NewSentence for further explantation
+ //concerning most of these values
+ SetLength(Lines[Count].Line, 1);
+ Lines[Count].Line[0].HighNote := -1;
+ Lines[Count].Line[0].LastLine := false;
+ Lines[Count].Line[0].BaseNote := High(Integer);
+ Lines[Count].Line[0].TotalNotes := 0;
end;
//Try to Parse the Song
@@ -482,7 +496,7 @@ begin
if Parser.ParseSong(Path + PathDelim + FileName) then
begin
//Writeln('XML Inputfile Parsed succesful');
-
+
//Start write parsed information to Song
//Notes Part
for I := 0 to High(Parser.SongInfo.Sentences) do
@@ -491,8 +505,8 @@ begin
for J := 0 to High(Parser.SongInfo.Sentences[I].Notes) do
begin
case Parser.SongInfo.Sentences[I].Notes[J].NoteTyp of
- NT_Normal: NoteType := ':';
- NT_Golden: NoteType := '*';
+ NT_Normal: NoteType := ':';
+ NT_Golden: NoteType := '*';
NT_Freestyle: NoteType := 'F';
end;
@@ -511,42 +525,6 @@ begin
ParseNote(1, NoteType, (Param1+Rel[1]) * Mult, Param2 * Mult, Param3, ParamS);
end;
- if not Both then
- begin
- Lines[CP].Line[Lines[CP].High].BaseNote := Base[CP];
- Lines[CP].Line[Lines[CP].High].LyricWidth := glTextWidth(Lines[CP].Line[Lines[CP].High].Lyric);
- //Total Notes Patch
- Lines[CP].Line[Lines[CP].High].TotalNotes := 0;
- for NoteIndex := 0 to high(Lines[CP].Line[Lines[CP].High].Note) do
- begin
- if (Lines[CP].Line[Lines[CP].High].Note[NoteIndex].NoteType = ntGolden) then
- Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[NoteIndex].Length;
-
- if (Lines[CP].Line[Lines[CP].High].Note[NoteIndex].NoteType <> ntFreestyle) then
- Lines[CP].Line[Lines[CP].High].TotalNotes := Lines[CP].Line[Lines[CP].High].TotalNotes + Lines[CP].Line[Lines[CP].High].Note[NoteIndex].Length;
- end;
- //Total Notes Patch End
- end
- else
- begin
- for Count := 0 to High(Lines) do
- begin
- Lines[Count].Line[Lines[Count].High].BaseNote := Base[Count];
- Lines[Count].Line[Lines[Count].High].LyricWidth := glTextWidth(Lines[Count].Line[Lines[Count].High].Lyric);
- //Total Notes Patch
- Lines[Count].Line[Lines[Count].High].TotalNotes := 0;
- for NoteIndex := 0 to high(Lines[Count].Line[Lines[Count].High].Note) do
- begin
- if (Lines[Count].Line[Lines[Count].High].Note[NoteIndex].NoteType = ntGolden) then
- Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[NoteIndex].Length;
- if (Lines[Count].Line[Lines[Count].High].Note[NoteIndex].NoteType <> ntFreestyle) then
- Lines[Count].Line[Lines[Count].High].TotalNotes := Lines[Count].Line[Lines[Count].High].TotalNotes + Lines[Count].Line[Lines[Count].High].Note[NoteIndex].Length;
-
- end;
- //Total Notes Patch End
- end;
- end; { end of for loop }
-
end; //J Forloop
//Add Sentence break
@@ -558,8 +536,8 @@ begin
//Calculate Time
case Rest of
0, 1: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start;
- 2: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start - 1;
- 3: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start - 2;
+ 2: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start - 1;
+ 3: Time := Parser.SongInfo.Sentences[I+1].Notes[0].Start - 2;
else
if (Rest >= 4) then
Time := SentenceEnd + 2
@@ -588,7 +566,7 @@ begin
for Count := 0 to High(Lines) do
begin
- Lines[Count].Line[High(Lines[Count].Line)].LastLine := True;
+ Lines[Count].Line[High(Lines[Count].Line)].LastLine := true;
end;
Result := true;
@@ -670,7 +648,8 @@ begin
//Language Sorting
self.Language := Parser.SongInfo.Header.Language;
- end else
+ end
+ else
Log.LogError('File Incomplete or not SingStar XML (A): ' + aFileName);
Parser.Free;
@@ -678,7 +657,7 @@ begin
//Check if all Required Values are given
if (Done <> 15) then
begin
- Result := False;
+ Result := false;
if (Done and 8) = 0 then //No BPM Flag
Log.LogError('BPM Tag Missing: ' + self.FileName)
else if (Done and 4) = 0 then //No MP3 Flag
@@ -700,7 +679,7 @@ function TSong.ReadTXTHeader(const aFileName : WideString): boolean;
* "International" StrToFloat variant. Uses either ',' or '.' as decimal
* separator.
*}
- function StrToFloatI18n(const Value: string): Extended;
+ function StrToFloatI18n(const Value: string): extended;
var
TempValue : string;
begin
@@ -727,7 +706,7 @@ begin
begin
Log.LogError('File Starts with Empty Line: ' + Path + PathDelim + aFileName,
'TSong.ReadTXTHeader');
- Result := False;
+ Result := false;
Exit;
end;
@@ -736,8 +715,7 @@ begin
Encoding := encUTF8;
//Read Lines while Line starts with # or its empty
- while (Length(Line) = 0) or
- (Line[1] = '#') do
+ while (Length(Line) = 0) or (Line[1] = '#') do
begin
//Increase Line Number
Inc (FileLineNo);
@@ -898,7 +876,7 @@ begin
else if (Identifier = 'RELATIVE') then
begin
if (UpperCase(Value) = 'YES') then
- self.Relative := True;
+ self.Relative := true;
end
// File encoding
@@ -912,7 +890,7 @@ begin
// check for end of file
if Eof(SongFile) then
begin
- Result := False;
+ Result := false;
Log.LogError('File Incomplete or not Ultrastar TxT (A): ' + aFileName);
Break;
end;
@@ -927,7 +905,7 @@ begin
//Check if all Required Values are given
if (Done <> 15) then
begin
- Result := False;
+ Result := false;
if (Done and 8) = 0 then //No BPM Flag
Log.LogError('BPM Tag Missing: ' + self.FileName)
else if (Done and 4) = 0 then //No MP3 Flag
@@ -942,11 +920,11 @@ begin
end;
-Function TSong.GetErrorLineNo: Integer;
+function TSong.GetErrorLineNo: integer;
begin
- If (LastError='ERROR_CORRUPT_SONG_ERROR_IN_LINE') then
+ if (LastError='ERROR_CORRUPT_SONG_ERROR_IN_LINE') then
Result := FileLineNo
- Else
+ else
Result := -1;
end;
@@ -1001,7 +979,7 @@ begin
begin
SetLength(Note, Length(Note) + 1);
HighNote := High(Note);
-
+
Note[HighNote].Start := StartP;
if HighNote = 0 then
begin
@@ -1019,18 +997,28 @@ begin
'*': Note[HighNote].NoteType := ntGolden;
end;
- if (Note[HighNote].NoteType = ntGolden) then
- Lines[LineNumber].ScoreValue := Lines[LineNumber].ScoreValue + Note[HighNote].Length;
-
- if (Note[HighNote].NoteType <> ntFreestyle) then
- Lines[LineNumber].ScoreValue := Lines[LineNumber].ScoreValue + Note[HighNote].Length;
+ //add this notes value ("notes length" * "notes scorefactor") to the current songs entire value
+ Inc(Lines[LineNumber].ScoreValue, Note[HighNote].Length * ScoreFactor[Note[HighNote].NoteType]);
+
+ //and to the current lines entire value
+ Inc(TotalNotes, Note[HighNote].Length * ScoreFactor[Note[HighNote].NoteType]);
+
Note[HighNote].Tone := NoteP;
- if Note[HighNote].Tone < Base[LineNumber] then Base[LineNumber] := Note[HighNote].Tone;
- Note[HighNote].Text := RecodeStringUTF8(
- Copy(LyricS, 2, Length(LyricS)-1),
- Encoding);
+ //if a note w/ a deeper pitch then the current basenote is found
+ //we replace the basenote w/ the current notes pitch
+ if Note[HighNote].Tone < BaseNote then
+ BaseNote := Note[HighNote].Tone;
+
+ //delete the space that seperates the notes pitch from its lyrics
+ //it is left in the LyricS string because Read("some ordinal type") will
+ //set the files pointer to the first whitespace character after the
+ //ordinal string. Trim is no solution because it would cut the spaces
+ //that seperate the words of the lyrics, too.
+ Delete(LyricS, 1, 1);
+
+ Note[HighNote].Text := RecodeStringUTF8(LyricS, Encoding);
Lyric := Lyric + Note[HighNote].Text;
End_ := Note[HighNote].Start + Note[HighNote].Length;
@@ -1042,37 +1030,30 @@ var
I: integer;
begin
- If (Lines[LineNumberP].Line[Lines[LineNumberP].High].HighNote <> -1) then
- begin //Update old Sentence if it has notes and create a new sentence
- // stara czesc //Alter Satz //Update Old Part
- Lines[LineNumberP].Line[Lines[LineNumberP].High].BaseNote := Base[LineNumberP];
- Lines[LineNumberP].Line[Lines[LineNumberP].High].LyricWidth := glTextWidth(Lines[LineNumberP].Line[Lines[LineNumberP].High].Lyric);
-
- //Total Notes Patch
- Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes := 0;
- for I := low(Lines[LineNumberP].Line[Lines[LineNumberP].High].Note) to high(Lines[LineNumberP].Line[Lines[LineNumberP].High].Note) do
- begin
- if (Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].NoteType = ntGolden) then
- Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes := Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes + Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].Length;
-
- if (Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].NoteType <> ntFreestyle) then
- Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes := Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes + Lines[LineNumberP].Line[Lines[LineNumberP].High].Note[I].Length;
- end;
- //Total Notes Patch End
-
-
- // nowa czesc //Neuer Satz //Update New Part
+ if (Lines[LineNumberP].Line[Lines[LineNumberP].High].HighNote <> -1) then
+ begin //create a new line
SetLength(Lines[LineNumberP].Line, Lines[LineNumberP].Number + 1);
- Lines[LineNumberP].High := Lines[LineNumberP].High + 1;
- Lines[LineNumberP].Number := Lines[LineNumberP].Number + 1;
+ Inc(Lines[LineNumberP].High);
+ Inc(Lines[LineNumberP].Number);
end
else
- begin //Use old Sentence if it has no notes
+ begin //use old line if it there were no notes added since last call of NewSentence
Log.LogError('Error loading Song, sentence w/o note found in line ' + InttoStr(FileLineNo) + ': ' + Filename);
end;
Lines[LineNumberP].Line[Lines[LineNumberP].High].HighNote := -1;
+ //set the current lines value to zero
+ //it will be incremented w/ the value of every added note
+ Lines[LineNumberP].Line[Lines[LineNumberP].High].TotalNotes := 0;
+
+ //basenote is the pitch of the deepest note, it is used for note drawing.
+ //if a note with a less value than the current sentences basenote is found,
+ //basenote will be set to this notes pitch. Therefore the initial value of
+ //this field has to be very high.
+ Lines[LineNumberP].Line[Lines[LineNumberP].High].BaseNote := High(Integer);
+
+
if self.Relative then
begin
Lines[LineNumberP].Line[Lines[LineNumberP].High].Start := Param1;
@@ -1081,9 +1062,7 @@ begin
else
Lines[LineNumberP].Line[Lines[LineNumberP].High].Start := Param1;
- Lines[LineNumberP].Line[Lines[LineNumberP].High].LastLine := False;
-
- Base[LineNumberP] := 100; // high number
+ Lines[LineNumberP].Line[Lines[LineNumberP].High].LastLine := false;
end;
procedure TSong.clear();
@@ -1122,13 +1101,13 @@ begin
Resolution := 4;
Creator := '';
+ Relative := false;
end;
-
function TSong.Analyse(): boolean;
begin
- Result := False;
+ Result := false;
//Reset LineNo
FileLineNo := 0;
@@ -1155,7 +1134,7 @@ end;
function TSong.AnalyseXML(): boolean;
begin
- Result := False;
+ Result := false;
//Reset LineNo
FileLineNo := 0;
diff --git a/unicode/src/base/USongs.pas b/unicode/src/base/USongs.pas
index ac67eed0..852ccfc4 100644
--- a/unicode/src/base/USongs.pas
+++ b/unicode/src/base/USongs.pas
@@ -158,11 +158,13 @@ implementation
uses
StrUtils,
- UGraphic,
UCovers,
UFiles,
+ UGraphic,
UMain,
UIni,
+ UPath,
+ UNote,
UUnicodeUtils;
constructor TSongs.Create();
@@ -282,7 +284,11 @@ var
lSong : TSong;
begin
- Files := Platform.DirectoryFindFiles( Dir, '.txt', true);
+ try
+ Files := Platform.DirectoryFindFiles( Dir, '.txt', true)
+ except
+ Log.LogError('Couldn''t deal with directory/file: ' + Dir + ' in TSongs.BrowseTXTFiles')
+ end;
for i := 0 to Length(Files)-1 do
begin
@@ -315,7 +321,11 @@ var
lSong : TSong;
begin
- Files := Platform.DirectoryFindFiles( Dir, '.xml', true);
+ try
+ Files := Platform.DirectoryFindFiles( Dir, '.xml', true)
+ except
+ Log.LogError('Couldn''t deal with directory/file: ' + Dir + ' in TSongs.BrowseXMLFiles')
+ end;
for i := 0 to Length(Files)-1 do
begin
@@ -670,7 +680,7 @@ begin
end;
// set CatNumber of last category
- if (Ini.Tabs_at_startup = 1) and (High(Song) >= 1) then
+ if (Ini.TabsAtStartup = 1) and (High(Song) >= 1) then
begin
// set number of songs in previous category
SongIndex := CatIndex - CatNumber;
diff --git a/unicode/src/base/UTexture.pas b/unicode/src/base/UTexture.pas
index 4f33b78a..962bd2b0 100644
--- a/unicode/src/base/UTexture.pas
+++ b/unicode/src/base/UTexture.pas
@@ -93,7 +93,7 @@ type
TTextureEntry = record
Name: string;
Typ: TTextureType;
- Color: Cardinal;
+ Color: cardinal;
// we use normal TTexture, it's easier to implement and if needed - we copy ready data
Texture: TTexture; // Full-size texture
@@ -104,8 +104,8 @@ type
private
Texture: array of TTextureEntry;
public
- procedure AddTexture(var Tex: TTexture; Typ: TTextureType; Color: Cardinal; Cache: boolean);
- function FindTexture(const Name: string; Typ: TTextureType; Color: Cardinal): integer;
+ procedure AddTexture(var Tex: TTexture; Typ: TTextureType; Color: cardinal; Cache: boolean);
+ function FindTexture(const Name: string; Typ: TTextureType; Color: cardinal): integer;
end;
TTextureUnit = class
@@ -115,7 +115,7 @@ type
Limit: integer;
procedure AddTexture(var Tex: TTexture; Typ: TTextureType; Cache: boolean = false); overload;
- procedure AddTexture(var Tex: TTexture; Typ: TTextureType; Color: Cardinal; Cache: boolean = false); overload;
+ procedure AddTexture(var Tex: TTexture; Typ: TTextureType; Color: cardinal; Cache: boolean = false); overload;
function GetTexture(const Name: string; Typ: TTextureType; FromCache: boolean = false): TTexture; overload;
function GetTexture(const Name: string; Typ: TTextureType; Col: LongWord; FromCache: boolean = false): TTexture; overload;
function LoadTexture(FromRegistry: boolean; const Identifier: string; Typ: TTextureType; Col: LongWord): TTexture; overload;
@@ -123,7 +123,7 @@ type
function LoadTexture(const Identifier: string): TTexture; overload;
function CreateTexture(Data: PChar; const Name: string; Width, Height: word; BitsPerPixel: byte): TTexture;
procedure UnloadTexture(const Name: string; Typ: TTextureType; FromCache: boolean); overload;
- procedure UnloadTexture(const Name: string; Typ: TTextureType; Col: Cardinal; FromCache: boolean); overload;
+ procedure UnloadTexture(const Name: string; Typ: TTextureType; Col: cardinal; FromCache: boolean); overload;
//procedure FlushTextureDatabase();
constructor Create;
@@ -164,10 +164,10 @@ begin
SDL_FreeSurface(TempSurface);
end;
end;
-
+
{ TTextureDatabase }
-procedure TTextureDatabase.AddTexture(var Tex: TTexture; Typ: TTextureType; Color: Cardinal; Cache: boolean);
+procedure TTextureDatabase.AddTexture(var Tex: TTexture; Typ: TTextureType; Color: cardinal; Cache: boolean);
var
TextureIndex: integer;
begin
@@ -188,7 +188,7 @@ begin
Texture[TextureIndex].Texture := Tex;
end;
-function TTextureDatabase.FindTexture(const Name: string; Typ: TTextureType; Color: Cardinal): integer;
+function TTextureDatabase.FindTexture(const Name: string; Typ: TTextureType; Color: cardinal): integer;
var
TextureIndex: integer;
CurrentTexture: PTextureEntry;
@@ -211,7 +211,6 @@ begin
end;
end;
-
{ TTextureUnit }
constructor TTextureUnit.Create;
@@ -226,13 +225,12 @@ begin
inherited Destroy;
end;
-
procedure TTextureUnit.AddTexture(var Tex: TTexture; Typ: TTextureType; Cache: boolean);
begin
TextureDatabase.AddTexture(Tex, Typ, 0, Cache);
end;
-procedure TTextureUnit.AddTexture(var Tex: TTexture; Typ: TTextureType; Color: Cardinal; Cache: boolean);
+procedure TTextureUnit.AddTexture(var Tex: TTexture; Typ: TTextureType; Color: cardinal; Cache: boolean);
begin
TextureDatabase.AddTexture(Tex, Typ, Color, Cache);
end;
@@ -251,8 +249,8 @@ end;
function TTextureUnit.LoadTexture(const Identifier: string; Typ: TTextureType; Col: LongWord): TTexture;
var
TexSurface: PSDL_Surface;
- newWidth, newHeight: Cardinal;
- oldWidth, oldHeight: Cardinal;
+ newWidth, newHeight: integer;
+ oldWidth, oldHeight: integer;
ActTex: GLuint;
begin
// zero texture data
@@ -431,8 +429,8 @@ begin
{$ELSE}
glTexImage2D(GL_TEXTURE_2D, 0, 3, Width, Height, 0, GL_RGB, GL_UNSIGNED_BYTE, Data);
{$ENDIF}
-
- {
+
+{
if Mipmapping then
begin
Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 3, W, H, GL_RGB, GL_UNSIGNED_BYTE, @Data[0]);
@@ -440,8 +438,8 @@ begin
if Error > 0 then
Log.LogError('gluBuild2DMipmaps() failed', 'TTextureUnit.CreateTexture');
end;
- }
-
+}
+
Result.X := 0;
Result.Y := 0;
Result.Z := 0;
@@ -474,14 +472,14 @@ begin
UnloadTexture(Name, Typ, 0, FromCache);
end;
-procedure TTextureUnit.UnloadTexture(const Name: string; Typ: TTextureType; Col: Cardinal; FromCache: boolean);
+procedure TTextureUnit.UnloadTexture(const Name: string; Typ: TTextureType; Col: cardinal; FromCache: boolean);
var
T: integer;
TexNum: GLuint;
begin
T := TextureDatabase.FindTexture(Name, Typ, Col);
- if not FromCache then
+ if not FromCache then
begin
TexNum := TextureDatabase.Texture[T].Texture.TexNum;
if TexNum > 0 then
@@ -529,20 +527,20 @@ end;
function ParseTextureType(const TypeStr: string; Default: TTextureType): TTextureType;
var
- TexType: TTextureType;
+ TextureType: TTextureType;
UpCaseStr: string;
begin
UpCaseStr := UpperCase(TypeStr);
- for TexType := Low(TextureTypeStr) to High(TextureTypeStr) do
+ for TextureType := Low(TextureTypeStr) to High(TextureTypeStr) do
begin
- if (UpCaseStr = UpperCase(TextureTypeStr[TexType])) then
+ if (UpCaseStr = UpperCase(TextureTypeStr[TextureType])) then
begin
- Result := TexType;
+ Result := TextureType;
Exit;
end;
end;
- Log.LogWarn('Unknown texture-type: "' + TypeStr + '"', 'ParseTextureType');
- Result := TEXTURE_TYPE_PLAIN;
+ Log.LogWarn('Unknown texture type: "' + TypeStr + '". Using default texture type "' + TextureTypeToStr(Default) + '"', 'ParseTextureType');
+ Result := Default;
end;
end.
diff --git a/unicode/src/base/UThemes.pas b/unicode/src/base/UThemes.pas
index 361ed87d..9bf858ed 100644
--- a/unicode/src/base/UThemes.pas
+++ b/unicode/src/base/UThemes.pas
@@ -484,6 +484,16 @@ type
ButtonExit: TThemeButton;
end;
+ TThemeEdit = class(TThemeBasic)
+ ButtonConvert: TThemeButton;
+ ButtonExit: TThemeButton;
+
+ TextDescription: TThemeText;
+ TextDescriptionLong: TThemeText;
+ Description: array[0..5] of string;
+ DescriptionLong: array[0..5] of string;
+ end;
+
//Error- and Check-Popup
TThemeError = class(TThemeBasic)
Button1: TThemeButton;
@@ -723,6 +733,8 @@ type
OptionsThemes: TThemeOptionsThemes;
OptionsRecord: TThemeOptionsRecord;
OptionsAdvanced: TThemeOptionsAdvanced;
+ //edit
+ Edit: TThemeEdit;
//error and check popup
ErrorPopup: TThemeError;
CheckPopup: TThemeCheck;
@@ -852,6 +864,8 @@ begin
OptionsRecord := TThemeOptionsRecord.Create;
OptionsAdvanced := TThemeOptionsAdvanced.Create;
+ Edit := TThemeEdit.Create;
+
ErrorPopup := TThemeError.Create;
CheckPopup := TThemeCheck.Create;
@@ -1246,6 +1260,18 @@ begin
ThemeLoadSelectSlide(OptionsAdvanced.SelectPartyPopup, 'OptionsAdvancedSelectPartyPopup');
ThemeLoadButton (OptionsAdvanced.ButtonExit, 'OptionsAdvancedButtonExit');
+ //Edit Menu
+ ThemeLoadBasic (Edit, 'Edit');
+
+ ThemeLoadButton(Edit.ButtonConvert, 'EditButtonConvert');
+ ThemeLoadButton(Edit.ButtonExit, 'EditButtonExit');
+
+ Edit.Description[0] := Language.Translate('SING_EDIT_BUTTON_DESCRIPTION_CONVERT');
+ Edit.Description[1] := Language.Translate('SING_EDIT_BUTTON_DESCRIPTION_EXIT');
+
+ ThemeLoadText(Edit.TextDescription, 'EditTextDescription');
+ Edit.TextDescription.Text := Edit.Description[0];
+
//error and check popup
ThemeLoadBasic (ErrorPopup, 'ErrorPopup');
ThemeLoadButton(ErrorPopup.Button1, 'ErrorPopupButton1');
@@ -2310,6 +2336,9 @@ begin
freeandnil(OptionsAdvanced);
OptionsAdvanced := TThemeOptionsAdvanced.Create;
+ freeandnil(Edit);
+ Edit := TThemeEdit.Create;
+
freeandnil(ErrorPopup);
ErrorPopup := TThemeError.Create;