{* 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$ * $Id$ *} unit UDLLManager; interface {$IFDEF FPC} {$MODE Delphi} {$ENDIF} {$I switches.inc} uses ModiSDK, UFiles; type TDLLMan = class private hLib: THandle; P_Init: fModi_Init; P_Draw: fModi_Draw; P_Finish: fModi_Finish; P_RData: pModi_RData; public Plugins: array of TPluginInfo; PluginPaths: array of string; Selected: ^TPluginInfo; constructor Create; procedure GetPluginList; procedure ClearPluginInfo(No: cardinal); function LoadPluginInfo(Filename: string; No: cardinal): boolean; function LoadPlugin(No: cardinal): boolean; procedure UnLoadPlugin; function PluginInit (const TeamInfo: TTeamInfo; var Playerinfo: TPlayerinfo; const Sentences: TSentences; const LoadTex: fModi_LoadTex; const Print: fModi_Print; LoadSound: fModi_LoadSound; PlaySound: pModi_PlaySound) : boolean; function PluginDraw (var Playerinfo: TPlayerinfo; const CurSentence: cardinal): boolean; function PluginFinish (var Playerinfo: TPlayerinfo): byte; procedure PluginRData (handle: HSTREAM; buffer: Pointer; len: dword; user: dword); end; var DLLMan: TDLLMan; const {$IF Defined(MSWINDOWS)} DLLExt = '.dll'; {$ELSEIF Defined(DARWIN)} DLLExt = '.dylib'; {$ELSEIF Defined(UNIX)} DLLExt = '.so'; {$IFEND} implementation uses {$IFDEF MSWINDOWS} windows, {$ELSE} dynlibs, {$ENDIF} UPath, ULog, SysUtils; constructor TDLLMan.Create; begin inherited; SetLength(Plugins, 0); SetLength(PluginPaths, Length(Plugins)); GetPluginList; end; procedure TDLLMan.GetPluginList; var SearchRecord: TSearchRec; begin if FindFirst(PluginPath + '*' + DLLExt, faAnyFile, SearchRecord) = 0 then begin repeat SetLength(Plugins, Length(Plugins)+1); SetLength(PluginPaths, Length(Plugins)); if LoadPluginInfo(SearchRecord.Name, High(Plugins)) then // loaded succesful begin PluginPaths[High(PluginPaths)] := SearchRecord.Name; end else // error loading begin SetLength(Plugins, Length(Plugins)-1); SetLength(PluginPaths, Length(Plugins)); end; until FindNext(SearchRecord) <> 0; FindClose(SearchRecord); end; end; procedure TDLLMan.ClearPluginInfo(No: cardinal); begin // set to party modi plugin Plugins[No].Typ := 8; Plugins[No].Name := 'unknown'; Plugins[No].NumPlayers := 0; Plugins[No].Creator := 'Nobody'; Plugins[No].PluginDesc := 'NO_PLUGIN_DESC'; Plugins[No].LoadSong := true; Plugins[No].ShowScore := true; Plugins[No].ShowBars := true; Plugins[No].ShowNotes := true; Plugins[No].LoadVideo := true; Plugins[No].LoadBack := true; Plugins[No].TeamModeOnly := true; Plugins[No].GetSoundData := true; Plugins[No].Dummy := true; Plugins[No].BGShowFull := true; Plugins[No].BGShowFull_O := true; Plugins[No].ShowRateBar := true; Plugins[No].ShowRateBar_O := true; Plugins[No].EnLineBonus := true; Plugins[No].EnLineBonus_O := true; end; function TDLLMan.LoadPluginInfo(Filename: string; No: cardinal): boolean; var hLibg: THandle; Info: pModi_PluginInfo; // I: integer; begin Result := true; // clear plugin info ClearPluginInfo(No); { // workaround plugins loaded 2 times for i := low(pluginpaths) to high(pluginpaths) do if (pluginpaths[i] = filename) then exit; } // load libary hLibg := LoadLibrary(PChar(PluginPath + Filename)); // if loaded if (hLibg <> 0) then begin // load info procedure @Info := GetProcAddress(hLibg, PChar('PluginInfo')); // if loaded if (@Info <> nil) then begin // load plugininfo Info(Plugins[No]); Result := true; end else Log.LogError('Could not load plugin "' + Filename + '": Info procedure not found'); FreeLibrary (hLibg); end else Log.LogError('Could not load plugin "' + Filename + '": Libary not loaded'); end; function TDLLMan.LoadPlugin(No: cardinal): boolean; begin Result := true; // load libary hLib := LoadLibrary(PChar(PluginPath + PluginPaths[No])); // if loaded if (hLib <> 0) then begin // load info procedure @P_Init := GetProcAddress (hLib, 'Init'); @P_Draw := GetProcAddress (hLib, 'Draw'); @P_Finish := GetProcAddress (hLib, 'Finish'); // if loaded if (@P_Init <> nil) and (@P_Draw <> nil) and (@P_Finish <> nil) then begin Selected := @Plugins[No]; Result := true; end else begin Log.LogError('Could not load plugin "' + PluginPaths[No] + '": Procedures not found'); end; end else Log.LogError('Could not load plugin "' + PluginPaths[No] + '": Libary not loaded'); end; procedure TDLLMan.UnLoadPlugin; begin if (hLib <> 0) then FreeLibrary (hLib); // Selected := nil; @P_Init := nil; @P_Draw := nil; @P_Finish := nil; @P_RData := nil; end; function TDLLMan.PluginInit (const TeamInfo: TTeamInfo; var Playerinfo: TPlayerinfo; const Sentences: TSentences; const LoadTex: fModi_LoadTex; const Print: fModi_Print; LoadSound: fModi_LoadSound; PlaySound: pModi_PlaySound) : boolean; var Methods: TMethodRec; begin Methods.LoadTex := LoadTex; Methods.Print := Print; Methods.LoadSound := LoadSound; Methods.PlaySound := PlaySound; if (@P_Init <> nil) then Result := P_Init (TeamInfo, PlayerInfo, Sentences, Methods) else Result := true end; function TDLLMan.PluginDraw (var Playerinfo: TPlayerinfo; const CurSentence: cardinal): boolean; begin if (@P_Draw <> nil) then Result := P_Draw (PlayerInfo, CurSentence) else Result := true end; function TDLLMan.PluginFinish (var Playerinfo: TPlayerinfo): byte; begin if (@P_Finish <> nil) then Result := P_Finish (PlayerInfo) else Result := 0; end; procedure TDLLMan.PluginRData (handle: HStream; buffer: Pointer; len: dword; user: dword); begin if (@P_RData <> nil) then P_RData (handle, buffer, len, user); end; end.