aboutsummaryrefslogtreecommitdiffstats
path: root/cmake/src/base/UMain.pas
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/src/base/UMain.pas')
-rw-r--r--cmake/src/base/UMain.pas302
1 files changed, 169 insertions, 133 deletions
diff --git a/cmake/src/base/UMain.pas b/cmake/src/base/UMain.pas
index 275510fc..0d479420 100644
--- a/cmake/src/base/UMain.pas
+++ b/cmake/src/base/UMain.pas
@@ -37,13 +37,9 @@ uses
SysUtils,
SDL;
-var
- Done: boolean;
- Restart: boolean;
-
procedure Main;
procedure MainLoop;
-procedure CheckEvents;
+function CheckEvents: boolean;
type
TMainThreadExecProc = procedure(Data: Pointer);
@@ -73,22 +69,30 @@ uses
UCovers,
UDataBase,
UDisplay,
- UDLLManager,
UGraphic,
UGraphicClasses,
UIni,
UJoystick,
ULanguage,
ULog,
- UPath,
+ UPathUtils,
UPlaylist,
UMusic,
+ URecord,
UBeatTimer,
UPlatform,
USkins,
USongs,
UThemes,
UParty,
+ ULuaCore,
+ UHookableEvent,
+ ULuaGl,
+ ULuaLog,
+ ULuaTexture,
+ ULuaTextGL,
+ ULuaParty,
+ ULuaScreenSing,
UTime;
procedure Main;
@@ -124,6 +128,10 @@ begin
SDL_Init(SDL_INIT_VIDEO or SDL_INIT_TIMER);
SDL_EnableUnicode(1);
+ // create luacore first so other classes can register their events
+ LuaCore := TLuaCore.Create;
+
+
USTime := TTime.Create;
VideoBGTimer := TRelativeTimer.Create;
@@ -148,15 +156,6 @@ begin
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);
Log.LogStatus('Loading Skin List', 'Initialization');
@@ -164,6 +163,12 @@ begin
Log.BenchmarkEnd(1);
Log.LogBenchmark('Loading Skin List', 1);
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Loading Theme List', 'Initialization');
+ Theme := TTheme.Create;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Theme List', 1);
+
// Ini + Paths
Log.BenchmarkStart(1);
Log.LogStatus('Load Ini', 'Initialization');
@@ -174,12 +179,6 @@ begin
Log.LogStatus('Write Ini', 'Initialization');
Ini.Save;
- // Load Languagefile
- if (Params.Language <> -1) then
- Language.ChangeLanguage(ILanguage[Params.Language])
- else
- Language.ChangeLanguage(ILanguage[Ini.Language]);
-
Log.BenchmarkEnd(1);
Log.LogBenchmark('Loading Ini', 1);
@@ -195,10 +194,10 @@ begin
// Theme
Log.BenchmarkStart(1);
- Log.LogStatus('Load Themes', 'Initialization');
- Theme := TTheme.Create(ThemePath + ITheme[Ini.Theme] + '.ini', Ini.Color);
+ Log.LogStatus('Load Theme', 'Initialization');
+ Theme.LoadTheme(Ini.Theme, Ini.Color);
Log.BenchmarkEnd(1);
- Log.LogBenchmark('Loading Themes', 1);
+ Log.LogBenchmark('Loading Theme', 1);
// Covers Cache
Log.BenchmarkStart(1);
@@ -226,20 +225,6 @@ begin
Log.BenchmarkEnd(1);
Log.LogBenchmark('Loading Songs', 1);
- // PluginManager
- Log.BenchmarkStart(1);
- Log.LogStatus('PluginManager', 'Initialization');
- DLLMan := TDLLMan.Create; // Load PluginList
- Log.BenchmarkEnd(1);
- Log.LogBenchmark('Loading PluginManager', 1);
-
- // 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);
-
// Graphics
Log.BenchmarkStart(1);
Log.LogStatus('Initialize 3D', 'Initialization');
@@ -252,10 +237,10 @@ begin
Log.LogStatus('DataBase System', 'Initialization');
DataBase := TDataBaseSystem.Create;
- if (Params.ScoreFile = '') then
- DataBase.Init (Platform.GetGameUserPath + 'Ultrastar.db')
+ if (Params.ScoreFile.IsUnset) then
+ DataBase.Init(Platform.GetGameUserPath.Append('Ultrastar.db'))
else
- DataBase.Init (Params.ScoreFile);
+ DataBase.Init(Params.ScoreFile);
Log.BenchmarkEnd(1);
Log.LogBenchmark('Loading DataBase System', 1);
@@ -284,22 +269,43 @@ begin
Log.LogBenchmark('Initializing Joystick', 1);
end;
+ // Lua
+ Log.BenchmarkStart(1);
+ Party := TPartyGame.Create;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Initializing Party Manager', 1);
+
+ Log.BenchmarkStart(1);
+ LuaCore.RegisterModule('Log', ULuaLog_Lib_f);
+ LuaCore.RegisterModule('Gl', ULuaGl_Lib_f);
+ LuaCore.RegisterModule('TextGl', ULuaTextGl_Lib_f);
+ LuaCore.RegisterModule('Party', ULuaParty_Lib_f);
+ LuaCore.RegisterModule('ScreenSing', ULuaScreenSing_Lib_f);
+
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Initializing LuaCore', 1);
+
+ Log.BenchmarkStart(1);
+ LuaCore.LoadPlugins;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Lua Plugins', 1);
+
+ LuaCore.DumpPlugins;
+
Log.BenchmarkEnd(0);
Log.LogBenchmark('Loading Time', 0);
- Log.LogStatus('Creating Core', 'Initialization');
-{
- Core := TCore.Create(
- USDXShortVersionStr,
- MakeVersion(USDX_VERSION_MAJOR,
- USDX_VERSION_MINOR,
- USDX_VERSION_RELEASE,
- chr(0))
- );
-}
+ { prepare software cursor }
+ Display.SetCursor;
+
+ {**
+ * Start background music
+ *}
+ SoundLib.StartBgMusic;
- Log.LogStatus('Running Core', 'Initialization');
- //Core.Run;
+ // check microphone settings, goto record options if they are corrupt
+ if (not AudioInputProcessor.ValidateSettings) then
+ Display.CurrentScreen^.FadeTo( @ScreenOptionsRecord );
//------------------------------
// Start Mainloop
@@ -318,62 +324,58 @@ begin
// call an uninitialize routine for every initialize step
// or at least use the corresponding Free methods
+ Log.LogStatus('Finalize Media', 'Finalization');
FinalizeMedia();
- //TTF_Quit();
+ Log.LogStatus('Uninitialize 3D', 'Finalization');
+ Finalize3D();
+
+ Log.LogStatus('Finalize SDL', 'Finalization');
SDL_Quit();
- if assigned(Log) then
- begin
- Log.LogStatus('Main Loop', 'Finished');
- Log.Free;
- end;
+ Log.LogStatus('Finalize Log', 'Finalization');
+ Log.Free;
{$IFNDEF Debug}
end;
{$ENDIF}
end;
procedure MainLoop;
-var
- Delay: integer;
const
MAX_FPS = 100;
+var
+ Delay: integer;
+ TicksCurrent: cardinal;
+ TicksBeforeFrame: cardinal;
+ Continue: boolean;
begin
SDL_EnableKeyRepeat(125, 125);
CountSkipTime(); // JB - for some reason this seems to be needed when we use the SDL Timer functions.
- while not Done do
+ while Continue do
begin
+ TicksBeforeFrame := SDL_GetTicks;
+
// joypad
if (Ini.Joypad = 1) or (Params.Joypad) then
Joy.Update;
// keyboard events
- CheckEvents;
+ Continue := CheckEvents;
// display
- Done := not Display.Draw;
+ Continue := Display.Draw;
SwapBuffers;
- // delay
- CountMidTime;
-
- Delay := Floor(1000 / MAX_FPS - 1000 * TimeMid);
- Log.LogError ('MainLoop', 'Delay: ' + intToStr(Delay));
+ // FPS limiter
+ TicksCurrent := SDL_GetTicks;
+ Delay := 1000 div MAX_FPS - (TicksCurrent - TicksBeforeFrame);
if Delay >= 1 then
SDL_Delay(Delay); // dynamic, maximum is 100 fps
- Log.LogError ('MainLoop', 'Delay: ok ' + intToStr(Delay));
CountSkipTime;
- // reinitialization of graphics
- if Restart then
- begin
- Reinitialize3D;
- Restart := false;
- end;
-
end;
end;
@@ -392,15 +394,13 @@ begin
end;
end;
-procedure CheckEvents;
+function CheckEvents: boolean;
var
Event: TSDL_event;
mouseDown: boolean;
mouseBtn: integer;
begin
- if Assigned(Display.NextScreen) then
- Exit;
-
+ Result := true;
while (SDL_PollEvent(@Event) <> 0) do
begin
case Event.type_ of
@@ -425,29 +425,39 @@ begin
begin
mouseDown := true;
mouseBtn := Event.button.button;
+
+ if (mouseBtn = SDL_BUTTON_LEFT) or (mouseBtn = SDL_BUTTON_RIGHT) then
+ Display.OnMouseButton(true);
end;
SDL_MOUSEBUTTONUP:
begin
mouseDown := false;
mouseBtn := Event.button.button;
+
+ if (mouseBtn = SDL_BUTTON_LEFT) or (mouseBtn = SDL_BUTTON_RIGHT) then
+ Display.OnMouseButton(false);
end;
end;
- Display.MoveCursor(Event.button.X * 800 / Screen.w,
- Event.button.Y * 600 / Screen.h,
- mouseDown and ((mouseBtn <> SDL_BUTTON_WHEELDOWN) or (mouseBtn <> SDL_BUTTON_WHEELUP)));
-
- if (ScreenPopupError <> nil) and (ScreenPopupError.Visible) then
- done := not ScreenPopupError.ParseMouse(mouseBtn, mouseDown, Event.button.x, Event.button.y)
- else if (ScreenPopupCheck <> nil) and (ScreenPopupCheck.Visible) then
- done := not ScreenPopupCheck.ParseMouse(mouseBtn, mouseDown, Event.button.x, Event.button.y)
- else
- begin
- done := not Display.CurrentScreen^.ParseMouse(mouseBtn, mouseDown, Event.button.x, Event.button.y);
-
- // if screen wants to exit
- if done then
- DoQuit;
+ Display.MoveCursor(Event.button.X * 800 * Screens / ScreenW,
+ Event.button.Y * 600 / ScreenH);
+
+ if not Assigned(Display.NextScreen) then
+ begin //drop input when changing screens
+ if (ScreenPopupError <> nil) and (ScreenPopupError.Visible) then
+ Result := ScreenPopupError.ParseMouse(mouseBtn, mouseDown, Event.button.x, Event.button.y)
+ else if (ScreenPopupInfo <> nil) and (ScreenPopupInfo.Visible) then
+ Result := ScreenPopupInfo.ParseMouse(mouseBtn, mouseDown, Event.button.x, Event.button.y)
+ else if (ScreenPopupCheck <> nil) and (ScreenPopupCheck.Visible) then
+ Result := ScreenPopupCheck.ParseMouse(mouseBtn, mouseDown, Event.button.x, Event.button.y)
+ else
+ begin
+ Result := Display.CurrentScreen^.ParseMouse(mouseBtn, mouseDown, Event.button.x, Event.button.y);
+
+ // if screen wants to exit
+ if not Result then
+ DoQuit;
+ end;
end;
end;
end;
@@ -459,6 +469,12 @@ begin
// This would create a new OpenGL render-context and all texture data
// would be invalidated.
// On Linux the mode MUST be reset, otherwise graphics will be corrupted.
+ // Update: It seems to work now without creating a new OpenGL context. At least
+ // with Win7 and SDL 1.2.14. Maybe it generally works now with SDL 1.2.14 and we
+ // can switch it on for windows.
+ // Important: Unless SDL_SetVideoMode() is called (it is not on Windows), Screen.w
+ // and Screen.h are not valid after a resize and still contain the old size. Use
+ // ScreenW and ScreenH instead.
{$IF Defined(Linux) or Defined(FreeBSD)}
if boolean( Ini.FullScreen ) then
SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN)
@@ -468,52 +484,72 @@ begin
end;
SDL_KEYDOWN:
begin
+ // translate CTRL-A (ASCII 1) - CTRL-Z (ASCII 26) to correct charcodes.
+ // keysyms (SDLK_A, ...) could be used instead but they ignore the
+ // current key mapping (if 'a' is pressed on a French keyboard the
+ // .unicode field will be 'a' and .sym SDLK_Q).
+ // IMPORTANT: if CTRL is pressed with a key different than 'A'-'Z' SDL
+ // will set .unicode to 0. There is no possibility to obtain a
+ // translated charcode. Use keysyms instead.
+ //if (Event.key.keysym.unicode in [1 .. 26]) then
+ // Event.key.keysym.unicode := Ord('A') + Event.key.keysym.unicode - 1;
+
// remap the "keypad enter" key to the "standard enter" key
if (Event.key.keysym.sym = SDLK_KP_ENTER) then
Event.key.keysym.sym := SDLK_RETURN;
- if (Event.key.keysym.sym = SDLK_F11) or
- ((Event.key.keysym.sym = SDLK_RETURN) and
- ((Event.key.keysym.modifier and KMOD_ALT) <> 0)) then // toggle full screen
- begin
- Ini.FullScreen := integer( not boolean( Ini.FullScreen ) );
-
- // FIXME: SDL_SetVideoMode creates a new OpenGL RC so we have to
- // reload all texture data (-> whitescreen bug).
- // Only Linux and FreeBSD are able to handle screen-switching this way.
- {$IF Defined(Linux) or Defined(FreeBSD)}
- if boolean( Ini.FullScreen ) then
+ if not Assigned(Display.NextScreen) then
+ begin //drop input when changing screens
+ { to-do : F11 was used for fullscreen toggle, too here
+ but we also use the key in screenname and some other
+ screens. It is droped although fullscreen toggle doesn't
+ even work on windows.
+ should we add (Event.key.keysym.sym = SDLK_F11) here
+ anyway? }
+ if ((Event.key.keysym.sym = SDLK_RETURN) and
+ ((Event.key.keysym.modifier and KMOD_ALT) <> 0)) then // toggle full screen
begin
- SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN);
+ Ini.FullScreen := integer( not boolean( Ini.FullScreen ) );
+
+ // FIXME: SDL_SetVideoMode creates a new OpenGL RC so we have to
+ // reload all texture data (-> whitescreen bug).
+ // Only Linux and FreeBSD are able to handle screen-switching this way.
+ {$IF Defined(Linux) or Defined(FreeBSD)}
+ if boolean( Ini.FullScreen ) then
+ begin
+ SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN);
+ end
+ else
+ begin
+ SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_RESIZABLE);
+ end;
+
+ Display.SetCursor;
+
+ glViewPort(0, 0, ScreenW, ScreenH);
+ {$IFEND}
end
+ // if print is pressed -> make screenshot and save to screenshot path
+ else if (Event.key.keysym.sym = SDLK_SYSREQ) or (Event.key.keysym.sym = SDLK_PRINT) then
+ Display.SaveScreenShot
+ // 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
+ Result := ScreenPopupError.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, true)
+ else if (ScreenPopupInfo <> nil) and (ScreenPopupInfo.Visible) then
+ Result := ScreenPopupInfo.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, true)
+ else if (ScreenPopupCheck <> nil) and (ScreenPopupCheck.Visible) then
+ Result := ScreenPopupCheck.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, true)
else
begin
- SDL_SetVideoMode(ScreenW, ScreenH, (Ini.Depth+1) * 16, SDL_OPENGL or SDL_RESIZABLE);
- end;
+ // check if screen wants to exit
+ Result := Display.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, true);
- Display.SetCursor;
-
- glViewPort(0, 0, ScreenW, ScreenH);
- {$IFEND}
- end
- // if print is pressed -> make screenshot and save to screenshot path
- else if (Event.key.keysym.sym = SDLK_SYSREQ) or (Event.key.keysym.sym = SDLK_PRINT) then
- Display.SaveScreenShot
- // 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, WideChar(Event.key.keysym.unicode), true)
- else if (ScreenPopupCheck <> nil) and (ScreenPopupCheck.Visible) then
- Done := not ScreenPopupCheck.ParseInput(Event.key.keysym.sym, WideChar(Event.key.keysym.unicode), true)
- else
- begin
- // check if screen wants to exit
- Done := not Display.CurrentScreen^.ParseInput(Event.key.keysym.sym, WideChar(Event.key.keysym.unicode), true);
-
- // if screen wants to exit
- if Done then
- DoQuit;
+ // if screen wants to exit
+ if not Result then
+ DoQuit;
+ end;
end;
end;
SDL_JOYAXISMOTION: