The native DLL interface is nothing but a plug-in solution for Podball based on regular Win32 dynamic link libraries (DLLs).
The DLL must export the following functions:
void __stdcall GetInfo(podball::MODULEINFO *pModuleInfo) void* __stdcall Init(const podball::GAMEINFO *pGameInfo) void __stdcall Play(podball::WORLDSTRUCT *pWorld, void *pUser) void __stdcall Dispose(void *pUser)
Input: None.
Output: MODULEINFO containing information about the module.
This function is called from the host to get information about the module. It can be called at any time, so the function should not rely on any particular initialization.
Input: GAMEINFO.
Output (return value): A pointer to the private memory for a particular match and team.
Init is called exactly once per team and for every new match the module participates in. Note: The same module may need to manage both teams of a same match or even teams in different matches if the game engine hosts different matches at the same time. The function will be called once for each team the module manages in a match. So the DLL must make sure to allocate a new and different chunk of memory each time this function is called. The returned pointer will be used in the subsequent calls to the Play function (below) for the team that module controls. The function is given a GAMESTRUCT as its first argument, which contains all constant game information. The module should save this information in the allocated memory space for later use in the Play function.
Input: WORLDSTRUCT, pUser.
Output: WORLDSTRUCT.
Play is called every ENGINE_CTRL_STEP engine ticks for every team that is controlled by a module of this type. It is given a WORLDSTRUCT as its first argument which contains all the information about the dynamic world state (positions, velocities etc.). Note that teams and vectors are always given as if the own team is team[0] and playing from left-to-right (in the direction of increasing x-coordinates). The pointer returned from the Init function (for this match and team) is passed as a second argument. This allows the module to retrieve and store state information associated to this match and team. The output of the function are the different actions to be performed by the pods of this team (team[0]) and they are directly to be written into the WORLDSTRUCT: pWorld->team[0].pod[i].action, pWorld->team[0].pod[i].a for every pod of the team.
Input: pUser.
Output: None.
Dispose is called exactly once for each team and match, after a match has ended. It allows the module to release the memory that has been allocated in Init.
The source tree contains a well-documented Visual C++ 2008 Express demo project for a native DLL module: source:trunk/src/dummy .
Note: Since the DLL plug-in mechanism is language independent, modules using this interface may be coded in any language that supports compilation to a Win32 DLL. In this case, particular care must be taken so that the memory-layout of the different structs in source:trunk/src/podball2/podtypes.h is the same for the chosen language.
As of v2.7.0 (2018-03-18 ) there's a new Dll API function to initialize the module: InitEx (see description below).
The old Init function is still supported, but if the module exports the newer InitEx function, then only the newer InitEx function will be called.
The function prototype is:
void* __stdcall InitEx(const podball::INITINFO *pInitInfo)
Output (return value): A pointer to the private memory for a particular match and team.
Init is called exactly once per team and for every new match the module participates in. Note: The same module may need to manage both teams of a same match or even teams in different matches if the game engine hosts different matches at the same time. The function will be called once for each team the module manages in a match. So the DLL must make sure to allocate a new and different chunk of memory each time this function is called. The returned pointer will be used in the subsequent calls to the Play function (below) for the team that module controls.
The INITINFO structure is defined as follows:
(For details see podball.h)
// function prototypes of drawing interface functions typedef void(__stdcall *TDrawCirclePtr)(void* handle, const VECTOR center, FLOAT radius); typedef void(__stdcall *TDrawLinePtr)(void* handle, const VECTOR from, const VECTOR to); typedef void(__stdcall *TDrawCrossPtr)(void* handle, const VECTOR center, FLOAT radius); struct DRAWINGCALLBACKS { TDrawCirclePtr drawCircle; TDrawLinePtr drawLine; TDrawCrossPtr drawCross; }; struct INITINFO { UINT version; // version of INITINFO structure. void* handle; // handle to the module to be used in callbacks. const GAMEINFO* pGameInfo; UINT debug; // Debug mode active? const CHAR* sConfig; //zero-terminated config string from match.info. const DRAWINGCALLBACKS* pDrawingCallbacks; //additional items may follow in future versions. };