From 4231c33ad7c7765fd3851c5c7168f8c7d367deef Mon Sep 17 00:00:00 2001 From: whiteshark0 Date: Tue, 16 Oct 2007 23:19:11 +0000 Subject: nearly finished Cores loading procs Add PluginLoader Unit to implent new PluginLoader Reordered Delphi .dpr uses clausel git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@519 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UCore.pas | 216 +++++++++++++++++++++++++++++++++--- Game/Code/Classes/UCoreModule.pas | 21 ++-- Game/Code/Classes/uPluginLoader.pas | 7 ++ Game/Code/UltraStar.dpr | 72 ++++++++---- Modis/SDK/Hooks.txt | 1 + Modis/SDK/Services.txt | 8 +- Modis/SDK/UPluginDefs.pas | 9 ++ 7 files changed, 288 insertions(+), 46 deletions(-) create mode 100644 Game/Code/Classes/uPluginLoader.pas diff --git a/Game/Code/Classes/UCore.pas b/Game/Code/Classes/UCore.pas index 990ee7ab..de44fb3b 100644 --- a/Game/Code/Classes/UCore.pas +++ b/Game/Code/Classes/UCore.pas @@ -26,13 +26,18 @@ type //Some Hook Handles. See Plugin SDKs Hooks.txt for Infos hLoadingFinished: THandle; hMainLoop: THandle; + hTranslate: THandle; hLoadTextures: THandle; hExitQuery: THandle; hExit: THandle; hDebug: THandle; hError: THandle; - sReportError: THandle; - sReportDebug: THandle; + sReportError: THandle; + sReportDebug: THandle; + sShowMessage: THandle; + sRetranslate: THandle; + sReloadTextures: THandle; + sGetModuleInfo: THandle; Modules: Array [0..High(CORE_MODULES_TO_LOAD)] of TModuleListItem; @@ -69,6 +74,10 @@ type 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 + + //--------------- //Main Methods to control the Core: //--------------- @@ -81,17 +90,21 @@ type // Hook and Service Procs: //-------------- Function ShowMessage(wParam, lParam: DWord): integer; //Shows a Message (lParam: PChar Text, wParam: Symbol) - {Function ShowMessage(wParam, lParam: DWord): integer; //Shows a Message (lParam: PChar Text, wParam: Symbol) - Function ShowMessage(wParam, lParam: DWord): integer; //Shows a Message (lParam: PChar Text, wParam: Symbol)} + Function ReportError(wParam, lParam: DWord): integer; //Shows a Message (wParam: Pchar(Message), lParam: PChar(Reportername)) + Function ReportDebug(wParam, lParam: DWord): integer; //Shows a Message (wParam: Pchar(Message), lParam: PChar(Reportername)) + Function Retranslate(wParam, lParam: DWord): integer; //Calls Translate hook + Function ReloadTextures(wParam, lParam: DWord): integer; //Calls LoadTextures hook + Function GetModuleInfo(wParam, lParam: DWord): integer; //If lParam = nil then get length of Moduleinfo Array. If lparam <> nil then write array of TModuleInfo to address at lparam end; var Core: TCore; implementation +uses SysUtils, {$IFDEF win32} -uses Windows; -{$ENDIF} +Windows +{$ENDIF}; //------------- // Create - Creates Class + Hook and Service Manager @@ -102,6 +115,9 @@ begin Version := cVersion; CurExecuted := 0; + LastErrorReporter := ''; + LastErrorString := ''; + Hooks := THookManager.Create(50); Services := TServiceManager.Create; end; @@ -128,9 +144,88 @@ begin Except noError := False; end; + + if (noError) then + begin //Init + Try + noError := Init; + Except + noError := False; + end; + + If noError then + begin + //Call Translate Hook + noError := (Hooks.CallEventChain(hTranslate, 0, 0) = 0); + + If noError then + begin //Calls LoadTextures Hook + noError := (Hooks.CallEventChain(hLoadTextures, 0, 0) = 0); + + if noError then + begin //Calls Loading Finished Hook + noError := (Hooks.CallEventChain(hLoadingFinished, 0, 0) = 0); + + If noError then + begin + //Start MainLoop + While noError do + begin + noError := MainLoop; + // to-do : Call Display Draw here + end; + end + else + begin + If (LastErrorString <> '') then + Self.ShowMessage(CORE_SM_ERROR, Integer(PChar('Error calling LoadingFinished Hook: ' + LastErrorString))) + else + Self.ShowMessage(CORE_SM_ERROR, Integer(PChar('Error calling LoadingFinished Hook'))); + end; + end + else + begin + If (LastErrorString <> '') then + Self.ShowMessage(CORE_SM_ERROR, Integer(PChar('Error loading textures: ' + LastErrorString))) + else + Self.ShowMessage(CORE_SM_ERROR, Integer(PChar('Error loading textures'))); + end; + end + else + begin + If (LastErrorString <> '') then + Self.ShowMessage(CORE_SM_ERROR, Integer(PChar('Error translating: ' + LastErrorString))) + else + Self.ShowMessage(CORE_SM_ERROR, Integer(PChar('Error translating'))); + end; + + end + else + begin + If (LastErrorString <> '') then + Self.ShowMessage(CORE_SM_ERROR, Integer(PChar('Error initing Modules: ' + LastErrorString))) + else + Self.ShowMessage(CORE_SM_ERROR, Integer(PChar('Error initing Modules'))); + end; + end + else + begin + If (LastErrorString <> '') then + Self.ShowMessage(CORE_SM_ERROR, Integer(PChar('Error loading Modules: ' + LastErrorString))) + else + Self.ShowMessage(CORE_SM_ERROR, Integer(PChar('Error loading Modules'))); + end; end else - Self.ShowMessage(CORE_SM_ERROR, Integer(PChar(''))); + begin + If (LastErrorString <> '') then + Self.ShowMessage(CORE_SM_ERROR, Integer(PChar('Error Getting Modules: ' + LastErrorString))) + else + Self.ShowMessage(CORE_SM_ERROR, Integer(PChar('Error Getting Modules'))); + end; + + //DeInit + DeInit; end; //------------- @@ -138,7 +233,7 @@ end; //------------- Function TCore.MainLoop: Boolean; begin - Result := True; + Result := False; end; @@ -149,11 +244,17 @@ Function TCore.GetModules: Boolean; var I: Integer; begin - For I := 0 to high(Modules) do - begin - Modules[I].NeedsDeInit := False; - Modules[I].Module := CORE_MODULES_TO_LOAD[I].Create; - Modules[I].Module.Info(@Modules[I].Info); + Result := False; + try + For I := 0 to high(Modules) do + begin + Modules[I].NeedsDeInit := False; + Modules[I].Module := CORE_MODULES_TO_LOAD[I].Create; + Modules[I].Module.Info(@Modules[I].Info); + end; + Result := True; + except + ReportError(Integer(PChar('Can''t get module #' + InttoStr(I) + ' "' + Modules[I].Info.Name + '"')), Integer(PChar('Core'))); end; end; @@ -169,7 +270,13 @@ begin I := 0; While ((Result = True) AND (I <= High(CORE_MODULES_TO_LOAD))) do begin - Result := Modules[I].Module.Load; + try + Result := Modules[I].Module.Load; + except + Result := False; + ReportError(Integer(PChar('Error loading module #' + InttoStr(I) + ' "' + Modules[I].Info.Name + '"')), Integer(PChar('Core'))); + end; + Inc(I); end; end; @@ -186,7 +293,14 @@ begin I := 0; While ((Result = True) AND (I <= High(CORE_MODULES_TO_LOAD))) do begin - Result := Modules[I].Module.Init; + try + Result := Modules[I].Module.Init; + except + Result := False; + ReportError(Integer(PChar('Error initing module #' + InttoStr(I) + ' "' + Modules[I].Info.Name + '"')), Integer(PChar('Core'))); + end; + + Modules[I].NeedsDeInit := Result; Inc(I); end; end; @@ -227,13 +341,19 @@ Function TCore.LoadCore: Boolean; begin hLoadingFinished := Hooks.AddEvent('Core/LoadingFinished'); hMainLoop := Hooks.AddEvent('Core/MainLoop'); + hTranslate := Hooks.AddEvent('Core/Translate'); hLoadTextures := Hooks.AddEvent('Core/LoadTextures'); hExitQuery := Hooks.AddEvent('Core/ExitQuery'); hExit := Hooks.AddEvent('Core/Exit'); hDebug := Hooks.AddEvent('Core/NewDebugInfo'); hError := Hooks.AddEvent('Core/NewError'); - sReportError := Services.AddService('Core/ReportError'); - sReportDebug := Services.AddService('Core/ReportDebug'); + + sReportError := Services.AddService('Core/ReportError', nil, Self.ReportError); + sReportDebug := Services.AddService('Core/ReportDebug', nil, Self.ReportDebug); + sShowMessage := Services.AddService('Core/ShowMessage', nil, Self.ShowMessage); + sRetranslate := Services.AddService('Core/Retranslate', nil, Self.Retranslate); + sReloadTextures := Services.AddService('Core/ReloadTextures', nil, Self.ReloadTextures); + sGetModuleInfo := Services.AddService('Core/GetModuleInfo', nil, Self.GetModuleInfo); end; //------------- @@ -255,7 +375,7 @@ begin end; //------------- -//Shows a MessageDialog (lParam: PChar Text, wParam: Symbol) +// Shows a MessageDialog (lParam: PChar Text, wParam: Symbol) //------------- Function TCore.ShowMessage(wParam, lParam: DWord): integer; var Params: Cardinal; @@ -280,4 +400,64 @@ begin // to-do : write ShowMessage for other OSes end; +//------------- +// Calls NewError HookChain (wParam: Pchar(Message), lParam: PChar(Reportername)) +//------------- +Function TCore.ReportError(wParam, lParam: DWord): integer; +begin + Hooks.CallEventChain(hError, wParam, lParam); + + //Update LastErrorReporter and LastErrorString + LastErrorReporter := String(PChar(Ptr(lParam))); + LastErrorString := String(PChar(Ptr(wParam))); +end; + +//------------- +// Calls NewDebugInfo HookChain (wParam: Pchar(Message), lParam: PChar(Reportername)) +//------------- +Function TCore.ReportDebug(wParam, lParam: DWord): integer; +begin + Hooks.CallEventChain(hDebug, wParam, lParam); +end; + +//------------- +// Calls Translate hook +//------------- +Function TCore.Retranslate(wParam, lParam: DWord): integer; +begin + Hooks.CallEventChain(hTranslate, 0, 1); +end; + +//------------- +// Calls LoadTextures hook +//------------- +Function TCore.ReloadTextures(wParam, lParam: DWord): integer; +begin + Hooks.CallEventChain(hLoadTextures, 0, 1); +end; + +//------------- +// 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, lParam: DWord): integer; +begin + if (ptr(lParam) = nil) then + begin + Result := Length(Modules); + end + else + begin + Try + For Result := 0 to High(Modules) do + begin + AModuleInfo(ptr(lParam))[Result].Name := Modules[Result].Info.Name; + AModuleInfo(ptr(lParam))[Result].Version := Modules[Result].Info.Version; + AModuleInfo(ptr(lParam))[Result].Description := Modules[Result].Info.Description; + end; + Except + Result := -1; + end; + end; +end; + end. \ No newline at end of file diff --git a/Game/Code/Classes/UCoreModule.pas b/Game/Code/Classes/UCoreModule.pas index 4d36f925..6fca5d37 100644 --- a/Game/Code/Classes/UCoreModule.pas +++ b/Game/Code/Classes/UCoreModule.pas @@ -6,19 +6,13 @@ interface Dummy Class that has Methods that will be called from Core In the Best case every Piece of this Software is a Module *********************} +uses UPluginDefs; {$IFDEF FPC} {$MODE Delphi} {$ENDIF} type - PModuleInfo = ^TModuleInfo; - TModuleInfo = record - Name: String; - Version: LongWord; - Description: String; - end; - TCoreModule = class public //Function that gives some Infos about the Module to the Core @@ -44,6 +38,10 @@ type //Deinit is in backwards Initing Order //If False is Returned this will cause a Forced Exit Procedure DeInit; virtual; + + //Is Called if this Module will be unloaded and has been created + //Should be used to Free Memory + Procedure Free; virtual; end; cCoreModule = class of TCoreModule; @@ -102,4 +100,13 @@ begin //Dummy ftw!! end; +//------------- +//Is Called if this Module will be unloaded and has been created +//Should be used to Free Memory +//------------- +Procedure TCoreModule.Free; +begin + //Dummy ftw!! +end; + end. \ No newline at end of file diff --git a/Game/Code/Classes/uPluginLoader.pas b/Game/Code/Classes/uPluginLoader.pas new file mode 100644 index 00000000..929fd84e --- /dev/null +++ b/Game/Code/Classes/uPluginLoader.pas @@ -0,0 +1,7 @@ +unit uPluginLoader; + +interface + +implementation + +end. diff --git a/Game/Code/UltraStar.dpr b/Game/Code/UltraStar.dpr index 9cdbca50..1e418a49 100644 --- a/Game/Code/UltraStar.dpr +++ b/Game/Code/UltraStar.dpr @@ -4,16 +4,22 @@ program UltraStar; {$I switches.inc} uses + //------------------------------ + //Includes - 3rd Party Libraries + //------------------------------ SDL in 'lib\JEDI-SDLv1.0\SDL\Pas\SDL.pas', moduleloader in 'lib\JEDI-SDLv1.0\SDL\Pas\moduleloader.pas', sdlutils in 'lib\JEDI-SDLv1.0\SDL\Pas\sdlutils.pas', sdl_image in 'lib\JEDI-SDLv1.0\SDL_Image\Pas\sdl_image.pas', OpenGL12 in 'lib\JEDI-SDLv1.0\OpenGL\Pas\OpenGL12.pas', sdl_ttf in 'lib\JEDI-SDLv1.0\SDL_ttf\Pas\sdl_ttf.pas', + bass in 'lib\bass\delphi\bass.pas', + PNGImage in 'lib\PNGImage\PNGImage.pas', PNGzLib in 'lib\PNGImage\PNGzLib.pas', pnglang in 'lib\PNGImage\pnglang.pas', + midiout in 'lib\midi\midiout.pas', midiin in 'lib\midi\midiin.pas', CIRCBUF in 'lib\midi\CIRCBUF.PAS', @@ -22,14 +28,20 @@ uses MidiCons in 'lib\midi\MidiCons.PAS', MidiFile in 'lib\midi\MidiFile.PAS', Delphmcb in 'lib\midi\Delphmcb.PAS', + avcodec in 'lib\ffmpeg\avcodec.pas', avformat in 'lib\ffmpeg\avformat.pas', avutil in 'lib\ffmpeg\avutil.pas', rational in 'lib\ffmpeg\rational.pas', opt in 'lib\ffmpeg\opt.pas', avio in 'lib\ffmpeg\avio.pas', + SQLiteTable3 in 'lib\SQLite\SQLiteTable3.pas', SQLite3 in 'lib\SQLite\SQLite3.pas', + + //------------------------------ + //Includes - Menu System + //------------------------------ UDisplay in 'Menu\UDisplay.pas', UMenu in 'Menu\UMenu.pas', UMenuStatic in 'Menu\UMenuStatic.pas', @@ -40,19 +52,15 @@ uses UMenuSelectSlide in 'Menu\UMenuSelectSlide.pas', UDrawTexture in 'Menu\UDrawTexture.pas', UMenuButtonCollection in 'Menu\UMenuButtonCollection.pas', + + //------------------------------ + //Includes - Classes + //------------------------------ UCommon in 'Classes\UCommon.pas', UGraphic in 'Classes\UGraphic.pas', UTexture in 'Classes\UTexture.pas', - - UMusic in 'Classes\UMusic.pas', - UMedia_dummy in 'Classes\UMedia_dummy.pas', - - // UAudio_FFMpeg in 'Classes\UAudio_FFMpeg.pas', - UAudio_Bass in 'Classes\UAudio_Bass.pas', - UVideo in 'Classes\UVideo.pas', - - - + UMusic in 'Classes\UMusic.pas', + UAudio_Bass in 'Classes\UAudio_Bass.pas', ULanguage in 'Classes\ULanguage.pas', UMain in 'Classes\UMain.pas', UDraw in 'Classes\UDraw.pas', @@ -75,19 +83,31 @@ uses UFiles in 'Classes\UFiles.pas', UGraphicClasses in 'Classes\UGraphicClasses.pas', UDLLManager in 'Classes\UDLLManager.pas', - UParty in 'Classes\UParty.pas', UPlaylist in 'Classes\UPlaylist.pas', UCommandLine in 'Classes\UCommandLine.pas', UTextClasses in 'Classes\UTextClasses.pas', USingScores in 'Classes\USingScores.pas', USingNotes in 'Classes\USingNotes.pas', - UModules in 'Classes\UModules.pas', - UHooks in 'Classes\UHooks.pas', - UServices in 'Classes\UServices.pas', - UCore in 'Classes\UCore.pas', - UCoreModule in 'Classes\UCoreModule.pas', - UPluginInterface in 'Classes\UPluginInterface.pas', + UModules in 'Classes\UModules.pas', //List of Modules to Load + UHooks in 'Classes\UHooks.pas', //Hook Managing + UServices in 'Classes\UServices.pas',//Service Managing + UCore in 'Classes\UCore.pas', //Core, Maybe remove this + UCoreModule in 'Classes\UCoreModule.pas', //^ + UPluginInterface in 'Classes\UPluginInterface.pas', //Interface offered by Core to Plugins + uPluginLoader in 'Classes\uPluginLoader.pas', //New Plugin Loader Module + + UParty in 'Classes\UParty.pas', // to - do : rewrite Party Manager as Module, reomplent ability to offer party Mody by Plugin + + //------------------------------ + //Includes - Video Support + //------------------------------ + UMedia_dummy in 'Classes\UMedia_dummy.pas', + UVideo in 'Classes\UVideo.pas', + + //------------------------------ + //Includes - Screens + //------------------------------ UScreenLoading in 'Screens\UScreenLoading.pas', UScreenWelcome in 'Screens\UScreenWelcome.pas', UScreenMain in 'Screens\UScreenMain.pas', @@ -116,14 +136,23 @@ uses UScreenStatDetail in 'Screens\UScreenStatDetail.pas', UScreenCredits in 'Screens\UScreenCredits.pas', UScreenPopup in 'Screens\UScreenPopup.pas', + + //------------------------------ + //Includes - Screens PartyMode + //------------------------------ UScreenSingModi in 'Screens\UScreenSingModi.pas', UScreenPartyNewRound in 'Screens\UScreenPartyNewRound.pas', UScreenPartyScore in 'Screens\UScreenPartyScore.pas', UScreenPartyPlayer in 'Screens\UScreenPartyPlayer.pas', UScreenPartyOptions in 'Screens\UScreenPartyOptions.pas', UScreenPartyWin in 'Screens\UScreenPartyWin.pas', - ModiSDK in '..\..\Modis\SDK\ModiSDK.pas', - UPluginDefs in '..\..\Modis\SDK\UPluginDefs.pas', + + //------------------------------ + //Includes - Modi SDK + //------------------------------ + ModiSDK in '..\..\Modis\SDK\ModiSDK.pas', //Old SDK, will be deleted soon + UPluginDefs in '..\..\Modis\SDK\UPluginDefs.pas', //New SDK, not only Modis + Windows, SysUtils; @@ -346,6 +375,11 @@ begin Log.BenchmarkEnd(0); Log.LogBenchmark('Loading Time', 0); + Log.LogError('Creating Core'); + Core := TCore.Create('Ultrastar Deluxe Beta', MakeVersion(1,1,0, chr(0))); + + Log.LogError('Running Core'); + Core.Run; //------------------------------ //Start- Mainloop diff --git a/Modis/SDK/Hooks.txt b/Modis/SDK/Hooks.txt index 32237694..f63773e0 100644 --- a/Modis/SDK/Hooks.txt +++ b/Modis/SDK/Hooks.txt @@ -7,6 +7,7 @@ Core: -------------------- Core/LoadingFinished <- Hook is called after all Modules and Plugins are loaded completely, before MainLoop Core/MainLoop <- Hook is called once in MainLoop before Drawing +Core/Translate <- Hook is called when Strings should be translated. If this is Retranslating lParam is Non Zero Core/LoadTextures <- Hook is called when Textures should be Loaded. This will be called in Ogl Thread. If Textures are Reloaded (e.g. on Display ReInit) LParam is non Zero. Core/ExitQuery <- Hook is called if someone querys an exit. (e.g. X is pressed). Not called on ForcedExit. If Chain is breaked the exit will be aborted. Core/Exit <- Hook is called before Module a. Plugin unload. diff --git a/Modis/SDK/Services.txt b/Modis/SDK/Services.txt index ae8f4097..7ed4be0e 100644 --- a/Modis/SDK/Services.txt +++ b/Modis/SDK/Services.txt @@ -1,4 +1,4 @@ -Ultrastar Deluxe Hook List +Ultrastar Deluxe Service List ----------------------------------- Here you can find the Services the Core offers to you: @@ -6,4 +6,8 @@ Here you can find the Services the Core offers to you: Core: -------------------- Core/ReportError <- Calls the 'Core/NewError' Chain. wParam: Pchar(Message), lParam: PChar(Reportername) -Core/ReportDebug <- Calls the 'Core/NewDebugInfo' Chain. wParam: Pchar(Message), lParam: PChar(Reportername) \ No newline at end of file +Core/ReportDebug <- Calls the 'Core/NewDebugInfo' Chain. wParam: Pchar(Message), lParam: PChar(Reportername) +Core/ShowMessage <- Shows a Message Dialog. (lParam: PChar Text, wParam: Symbol) +Core/Retranslate <- Calls Translate Hook +Core/ReloadTextures <- Calls LoadTextures Hook +Core/GetModuleInfo <- If lParam = nil then get length of Moduleinfo Array. If lparam <> nil then write array of TModuleInfo to address at lparam \ No newline at end of file diff --git a/Modis/SDK/UPluginDefs.pas b/Modis/SDK/UPluginDefs.pas index 5a16d807..8b964cc2 100644 --- a/Modis/SDK/UPluginDefs.pas +++ b/Modis/SDK/UPluginDefs.pas @@ -100,6 +100,15 @@ type ServiceExists: Function (ServiceName: PChar): Integer; stdcall; end; + //TModuleInfo: Info about Modules + PModuleInfo = ^TModuleInfo; + TModuleInfo = record + Name: String; + Version: LongWord; + Description: String; + end; + AModuleInfo = array of TModuleInfo; + //---------------- // Some Default Constants //---------------- -- cgit v1.2.3