1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
|
{* 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/UMain.pas $
* $Id: UMain.pas 1485 2008-10-28 20:16:05Z tobigun $
*}
{*
some defines that are used by usdx and plugins
*}
unit UPluginDefines;
interface
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
{$I switches.inc}
const
US_VERSION_SHMAJOR = 20;
US_VERSION_SHMINOR = 10;
US_VERSION_SHFIX = 0;
SDK_Version = 1 shl US_VERSION_SHMAJOR; //< identifies the used SDK version (1.0.0.0)
type
{ this type is used for all version ints in this SDK
the versions are structured as follows
0 ... 11| 12 ... 21| 22 ... 31
major | minor | bugfix, etc.
e.g. 1 . 0 . 0 = 1 shl 20 }
TUS_Version = LongInt;
{ this type is used for all plugin handles in this SDK }
TUS_Handle = LongInt;
PInterface = ^IInterface;
const
US_HANDLE_CORE = 137; //< handle of core, also first defined handle
US_HANDLE_UNDEFINED = 0; //< undefined handle, used to indicate errors
US_VERSION_UNDEFINED = 0; //< defines an unset version, used by core,
// should not be used by Plugins
{ this type is used for all id strings in this SDK }
const
MaxLength_TUS_Identifier = 32; //max length of identifier strings, has to be multiply of 4
type
TUS_Identifier = String[MaxLength_TUS_Identifier];
{ this record is used to offer some information about this plugin to the core }
TUS_PluginInfo = packed record
Name : Array [1..32] of Char; //name of the plugin
Author : Array [1..32] of Char; //plugins author
PluginDesc : Array [1..64] of Char; //some further explentation
Version : TUS_Version;
end;
PUS_PluginInfo = ^TUS_PluginInfo;
{ this function reads the plugins information from a TUS_PluginInfo record,
and saves it. Can be called once per plugin.
Version is the SDK_Version used by the plugin
BufferLength is the size of buffer in bytes }
TUS_Func_Identify = function (Handle: TUS_Handle; Version: TUS_Version; Buffer: PUS_PluginInfo; BufferLength: LongInt): LongInt;
{$IFDEF MSWINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
{ this plugin is used for selfshutdown by the plugin on an error
case.
Reason should be used to describe the reason for the shutdown
OnChangeStatus(psDeInited) is called when old status was psInited }
TUS_Func_Error = function (Handle: TUS_Handle; Reason: PWideChar): LongInt;
{$IFDEF MSWINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
{ this function writes the plugins filename including its path ,
to buffer. A call with Buffer=nil or Len<=0 returns the actual
length of the path.
BufferLength is the size of buffer in bytes
Filename is used to identify duplicate load of one plugin
so it should even set when plugin is not loaded from file}
TUS_Func_GetFilename = function (Handle: TUS_Handle; Buffer: PWideChar; BufferLength: LongInt): LongInt;
{$IFDEF MSWINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
{ this function writes an interface, identified by 'ID', to the
buffer.
Version is the version of the interface that is used
BufferLength is the size of buffer in bytes}
TUS_Func_GetInterface = function (IID: TGUID; Buffer: PInterface): LongInt;
{$IFDEF MSWINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
{ this function reads an interface, identified by 'ID', from the
buffer, to offer it to calls of GetInterface.
version is the version of the interface
BufferLength is the size of buffer in bytes }
TUS_Func_SetInterface = function (IID: TGUID; Buffer: PInterface): LongInt;
{$IFDEF MSWINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
{ this function writes a record or some other data,
identified by 'ID', to the buffer.
Version is the version of the data that is used
BufferLength is the size of buffer in bytes}
TUS_Func_GetData = function (ID: TUS_Identifier; Version: TUS_Version; Buffer: Pointer; BufferLength: LongInt): LongInt;
{$IFDEF MSWINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
{ this function reads a record or some other data,
identified by 'ID', from the buffer, to offer it
to calls of GetData.
version is the version of the record
BufferLength is the size of buffer in bytes }
TUS_Func_SetData = function (ID: TUS_Identifier; Version: TUS_Version; Buffer: Pointer; BufferLength: LongInt): LongInt;
{$IFDEF MSWINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
{ a record w/ some useful methods for plugins }
TUS_PluginInterface = packed record
Version : TUS_Version; //SDK_Version
Handle : LongInt; //the plugins handle
Identify : TUS_Func_Identify;
Error : TUS_Func_Error;
GetFilename : TUS_Func_GetFilename;
GetInterface: TUS_Func_GetInterface;
SetInterface: TUS_Func_SetInterface;
GetData : TUS_Func_GetData;
SetData : TUS_Func_SetData;
end;
PUS_PluginInterface = ^TUS_PluginInterface;
{ this function writes the PluginInterface to the buffer }
TUS_Func_InitInterface = function (Handle: TUS_Handle; Version: TUS_Version; Buffer: PUS_PluginInterface; BufferSize: LongInt): LongInt;
{$IFDEF MSWINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
{ this function is called by core, in the WaitingInit status
it offers the plugin the possibility to load its plugininterface
and to check it's sdk version against the cores.
It has to be implemented by plugins loaded as library }
TUS_Plugin_Proc_Init = procedure (Handle: TUS_Handle; CoreVersion: TUS_Version; InitInterface: TUS_Func_InitInterface);
{$IFDEF MSWINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
TUS_PluginStatus = (psNone, psWaitingInit, psInited, psDeInited, psError);
{ this function is called everytime tbe plugins status changes
status is the new status.
it has to be implemented by plugins loaded as library }
TUS_Plugin_OnChangeStatus = procedure (Handle: TUS_Handle; Status: TUS_PluginStatus);
{$IFDEF MSWINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
{ this interface represents a loaded plugin, it eitber has to
be implemented by the pluginloader, e.g. for libs or by the
plugin itself in the case of integrated plugins }
IUS_Plugin = Interface
['{23F7B722-D979-4402-9953-C6B229A6E888}']
function GetLoader: LongInt; //< Returns id of this plugins loader
function GetStatus: TUS_PluginStatus; //< Returns current pluginstatus
procedure SetStatus(status: TUS_PluginStatus); //< set current pluginstatus, calls OnChangeStatus,
// status may not be updated in case of an error
function GetInfo: TUS_PluginInfo; //< Returns TUS_Plugininfo record for this plugin
function Identify(Info: TUS_PluginInfo): boolean; //< Sets TUS_Plugininfo record for this plugin, can only be called once
function GetHandle: TUS_Handle; //< Returns plugins handle
function GetUniqueID: TUS_Handle; //< This ID is unique for the given plugin it may be a hash of the plugins code or s/t like that. used to identify plugins laoded twice
function GetFilename: WideString; //< Returns plugins filename
Procedure Init;
Procedure DeInit;
Procedure SetError(Reason: WideString);
Function GetErrorReason: WideString;
end;
{ this function will be called when a hookable event is spawn
data is a pointer to a struct that can contain any data
defined by the event creator. if there is no data this should
be nil.
breakable is true if the hook chain can be interupted by
returning US_HOOK_BREAK or US_HOOK_UNHOOKME_BREAK
by returning US_HOOK_UNHOOKME the callback will immediately
be removed from the chain
UserID is the value that the UserID had when hook was called.
can be used to store user defined data, e.g. to use one hook procedure for different hooks }
TUS_Func_OnEvent = function(data: pointer; breakable: boolean; UserID: LongInt): integer;
TUS_cFunc_OnEvent = function(data: pointer; breakable: boolean; UserID: LongInt): integer of object;
{ this interface represents an event that can be hooked by
e.g. the core or other}
IUS_HookableEvent = Interface
// this GID has to be changed if we change this interface
['{FFC6F09D-EC0B-41E2-87F6-70EC6F055C0E}']
function GetIdentifier: TUS_Identifier;
function GetHash: LongInt;
//adds the callback to the top of the events hook chain
//proc is the callback function
//parent is the plugins handle, or US_HANDLE_CORE if called by core
//returns hook-handle on succes or US_HANDLE_UNDEFINED on failure
function Hook(proc: TUS_Func_OnEvent; Parent: TUS_Handle; UserID: LongInt): TUS_Handle;
function cHook(proc: TUS_cFunc_OnEvent; Parent: TUS_Handle; UserID: LongInt): TUS_Handle;
//removes a callback from the chain using the handle returned
//by the hook function
//returns an US_ERROR code
function UnHook(Handle: TUS_Handle): byte;
//removes all callbacks of a specified parent (plugin)
procedure UnHookbyParent(Parent: TUS_Handle);
end;
const
{ some errorcodes that are returned by functions using this SDK }
US_ERROR_None = 0; //< indicates success ;)
US_ERROR_VersionMismatch = 1; //< returned when the version the plugin wants to use is not supported
US_ERROR_SizeMismatch = 2; //< returned when the wanted data does not fit the buffersize
US_ERROR_WrongHandle = 3; //< returned when the given handle is not
US_ERROR_WrongID = 4; //< returned when the given id does not exist
US_ERROR_NameExists = 5; //< returned when the given name already exists
US_ERROR_Unknown = 255; //< returned when an unknown error occured
{ return values for hook function }
US_HOOK_BREAK = High(integer); //this will break the hook chain
US_HOOK_UNHOOKME = High(integer) - 2; //this will remove the callback from the hooks chain
US_HOOK_UNHOOKME_BREAK = High(integer) - 1; //this will do both explained above
US_LOADER_UNDEFINED = 0;
US_LOADER_LIBRARY = 100;
US_LOADER_INCLUDED = 200;
{ this function converts an errorcode to its textual expression }
function USErrortoString(Code: LongInt): String;
{ this function converts a TUS_PluginStatus to its textual expression }
function USPluginStatustoString(Status: TUS_PluginStatus): String;
{ this funtion creates a hash for an TUS_Identifier
the hash is not guaranteed to be unique, it is just
for a fast search of an identifier }
function CalculateUSHash(Identifier: TUS_Identifier): LongInt;
implementation
{ this function converts an errorcode to its textual expression }
Function USErrortoString(Code: LongInt): String;
begin
Case Code of
US_Error_None: Result := 'success, no error occured';
US_Error_VersionMismatch: Result := 'version mismatch';
US_Error_SizeMismatch: Result := 'size mismatch';
US_Error_WrongHandle: Result := 'handle does not exist';
US_Error_WrongID: Result := 'id does not exist';
US_Error_NameExists: Result := 'another item with this name does already exist';
Else Result := 'unknown error';
end;
end;
function USPluginStatustoString(Status: TUS_PluginStatus): String;
begin
Case Status of
psNone: Result := 'none';
psWaitingInit: Result := 'waiting init';
psInited: Result := 'inited';
psDeinited: Result := 'deinited';
psError: Result := 'error';
Else Result := 'unknown';
end;
end;
{ this funtion creates a hash for an TUS_Identifier
the hash is not guaranteed to be unique, it is just
for a fast search of an identifier }
function CalculateUSHash(Identifier: TUS_Identifier): LongInt;
var
L: Integer;
I: Integer;
const
StartHash = -1337456101;
begin
// fill the unused chars of the identifier w/ zeros
L := Length(Identifier);
if (L < MaxLength_TUS_Identifier) then
FillChar(Identifier[L+1], MaxLength_TUS_Identifier - L, 0);
// calculate the hash
// this is done by just adding respectively 4 bytes of the string
// to the hash (longint)
Result := StartHash;
for I := 1 to (MaxLength_TUS_Identifier div 4) do
Result := Result + LongInt(Identifier[I*4]);
end;
end.
|