Declaration of GiveFnptrsToDll() and Server_GetBlendingInterface()

update : Pierre has fixed bugs in HPB bot template 4, and is aware of bugs in RACC template 2

version 1.0, 31.08.2004

Newest version of this document can be found on http://neuron.tuke.sk/~wagner or http://kxbot.sourceforge.net

This is part of Guide : Exporting functions in Half-life mods

Copyright (C) 2004 Jozef Wagner, http://neuron.tuke.sk/~wagner

Valid XHTML 1.1! Valid CSS! Dogma W4

Disclaimer :

This document is for experienced Half-life bot/mod coders.

Seems like bot coders have problem determining how to export various functions in their bot. This document should help them understand how things should be.

If you are not interested in details, read at least sections with red text

Table of Contents :

Acronyms

1. How GiveFnptrsToDll() is declared ?

2. How is EXPORT, DLLEXPORT and WINAPI defined ?

3. Is bot using .def file ?

4. How is Server_GetBlendingInterface declared ?

References

Acronyms :

Most of the bots/mods can be downloaded from www.bots-united.com

SDK - Half-Life 1 SDK, version 2.3. Alfred Reinolds patch applied

HPB4 - Botmans bot, version 4

HPBT3 - Botmans bot template, version 3

HPBT4 - Botmans bot template, version 4

JOE - Joebot, version 1.6.5.3

META - Metamod, version 1.17.2

POD26 - Podbot, version 2.6

RACCP - RACC Preview

RACC1 - RACC Template, version 1

RACC2 - RACC Template, version 2

REAL - RealBot, CVS snapshot, August 2004

WHIST - Whistlers bot framework, first version

VC6 - Visual C++ 6.0 headers

VC7 - Visual C++ 7.0 headers (Visual Studio .NET 2003)

HPBF3 - Botmans forum archive, 2003

HPBF4 - Botmans forum archive, 2004

BUF4 - Bots united forum, August 2004

1. How GiveFnptrsToDll() is declared ?

SDK :

defined in dlls\h_export.cpp :

#ifdef _WIN32
void DLLEXPORT  GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)
#else
extern "C" void GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)
#endif

HPB4 :

defined in h_export.cpp :

void WINAPI GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)

HPBT3 :

defined in dlls\h_export.cpp :

#ifndef __linux__
#ifdef __BORLANDC__
extern "C" DLLEXPORT void EXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)
#else
void       DLLEXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)
#endif
#else
extern "C" DLLEXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)
#endif

ERROR : Under linux, GiveFnptrsToDll will not be returning void (?will return int?). This differs from the SDKs definition. Also definition under Borland looks very strange.

HPBT4 :

defined in dlls\h_export.cpp : (same as HPBT3)

#ifndef __linux__
#ifdef __BORLANDC__
extern "C" DLLEXPORT void EXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals)
#else
void       DLLEXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals )
#endif
#else
extern "C" DLLEXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals )
#endif

ERROR : Under linux, GiveFnptrsToDll will not be returning void (?will return int?). This differs from the SDKs definition. Also definition under Borland looks very strange.

JOE :

defined in dlls\h_export.cpp :

#ifdef _WIN32
#if defined(__BORLANDC__) || defined(__MINGW32__)
extern "C" DLLEXPORT void EXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)
#else
void DLLEXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)
#endif
#else
extern "C" DLLEXPORT void GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)
#endif

ERROR : DLLEXPORT must be after the the void. However it does not matter, because the DLLEXPORT is empty definition under the linux.

META :

C_DLLEXPORT declared in metamod\osdep.h :

#define C_DLLEXPORT extern "C" DLLEXPORT

declared in metamod\h_export.h :

C_DLLEXPORT void WINAPI GiveFnptrsToDll(enginefuncs_t *pengfuncsFromEngine,globalvars_t *pGlobals);

defined in metamod\h_export.cpp :

void WINAPI GiveFnptrsToDll(enginefuncs_t *pengfuncsFromEngine,globalvars_t *pGlobals)

WARNING : DLLEXPORT *IS NOT* the same as in the SDKs dlls\cbase.h definition. See below for more information

WARNING : The definition is different than the declaration. However, there is no need to specify an extern "C" __declspec(dllexport) in both definition and declaration

POD26 :

defined in dlls\h_export.cpp :

#ifndef __linux__
void       DLLEXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)
#else
extern "C" DLLEXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)
#endif

ERROR : Under linux, GiveFnptrsToDll will not be returning void (?will return int?). This differs from the SDKs definition

RACCP :

declared in common\bot_common.h :

void DLLEXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals);

defined in *\dll.cpp :

void DLLEXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)

RACC1 :

declared in common\engine_specific.h :

#ifdef _WIN32
   #define DLL_GIVEFNPTRSTODLL void
#else
   #define DLL_GIVEFNPTRSTODLL extern "C"
#endif // _WIN32

declared in common\racc.h :

DLL_GIVEFNPTRSTODLL DLLEXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals);

defined in cstrike\dll.cpp :

DLL_GIVEFNPTRSTODLL DLLEXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)

ERROR : Under linux, GiveFnptrsToDll will not be returning void (?will return int?). This differs from the SDKs definition

RACC2 :

declared in common\racc.h :

void DLLEXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals);

defined in *\dll.cpp :

void DLLEXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)

REAL :

defined in dll.cpp :

C_DLLEXPORT void WINAPI GiveFnptrsToDll(enginefuncs_t * pengfuncsFromEngine,globalvars_t * pGlobals)

NOTE : C_DLLEXPORT definition is taken from META

WHIST :

declared in main.h :

#define C_DLLEXPORT extern "C" DLLEXPORT
C_DLLEXPORT void WINAPI GiveFnptrsToDll(enginefuncs_t *pengfuncsFromEngine,globalvars_t *pGlobals);

defined in h_export.cpp :

void WINAPI GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals )

This bot copied declaration from META

WARNING : DLLEXPORT *IS NOT* the same as in SDKs dlls\cbase.h definition. See below for more information

WARNING : The definition is different than the declaration. However, there is no need to specify an extern "C" __declspec(dllexport) in both definition and declaration

Notes :

DLLEXPORT is defined differently in various bots

GiveFnptrsToDll is declared/definied differently in various bots. Only difference is usage of extern "C" and void as a return type

I've read many posts in HPBF4 regarding missing void type ("h_export.cpp: ISO C++ forbids declaration of `GiveFnptrsToDll' with no type"). This can be simply fixed by adding void return type to declaration of GiveFnptrsToDll() where it is missing.

Of course, GiveFnptrsToDll should NOT be exported with LINK_ENTITY_TO_FUNC() macro. This applies also for GetNewDLLFunctions, GetEntityAPI, GetEntityAPI2 and Server_GetBlendingInterface

Solution :

Correct and simplest definition for MSVC and linux (not for Borland and MingW32) is

#ifdef _WIN32
extern "C" __declspec(dllexport) void __stdcall GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)
#elif defined __linux__
extern "C" void GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)
#endif

Note that this definition works both with/without the .def file (However to make it work without .def file, small piece of code must be attached. see below in the .def section)

Note : extern "C" is important in MSVC if you want to export the GiveFnptrsToDll without .def. Read more about it in my solution to the 3rd problem

2. How is EXPORT, DLLEXPORT and WINAPI defined ?

SDK :

DLLEXPORT is defined in engine\eiface.h :

#ifdef _WIN32
#define DLLEXPORT __stdcall
#else
#define DLLEXPORT /* */
#endif

NOTE : DLLEXPORT is defined differently in the other SDK files, but dlls\h_export.cpp is using definition mentioned above

EXPORT is defined in dlls\cbase.h :

#ifdef _WIN32
#define EXPORT	_declspec( dllexport )
#else
#define EXPORT	/* */
#endif

HPB4 :

WINAPI is defined in VC6 and VC7, see below

HPBT3 :

Using DLLEXPORT definition from SDK, file engine\eiface.h

EXPORT is defined in dlls\cbase.h :

#ifndef __linux__
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define EXPORT	_declspec( dllexport )
#else
#define EXPORT	__declspec( dllexport )
#endif
#else
#define EXPORT
#endif

Note that this EXPORT slightly differs from the SDKs dlls\cbase.h definition

HPBT4 :

Using DLLEXPORT definition from SDK, file engine\eiface.h

Using EXPORT definition from SDK, file dlls\cbase.h

JOE :

Using the DLLEXPORT definition from the SDK, file engine\eiface.h

EXPORT is defined in dlls\cbase.h : (same as in HPBT3)

#ifndef __linux__
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define EXPORT	_declspec( dllexport )
#else
#define EXPORT	__declspec( dllexport )
#endif
#else
#define EXPORT
#endif

Note that this EXPORT slightly differs from the SDKs dlls\cbase.h definition

META :

WINAPI is defined in VC6 and VC7, see below

DLLEXPORT is defined in metamod\osdep.h :

#ifdef _WIN32
	#define DLLEXPORT	__declspec(dllexport)
#elif defined(linux)
	#define DLLEXPORT	/* */
#endif /* linux */

Note that this DLLEXPORT *IS NOT* the same as in SDKs dlls\cbase.h definition

POD26 :

Using DLLEXPORT definition from the SDK, file engine\eiface.h

RACCP :

Using DLLEXPORT definition from the SDK, file engine\eiface.h. File is moved to directory \common

RACC1 :

Using DLLEXPORT definition from the SDK, file engine\eiface.h. File is moved to directory \common

RACC2 :

DLLEXPORT definition is not present. Assuming that it is using the declaration from SDK, but care should be taken not to include DLLEXPORT from META

REAL :

WINAPI is defined in the VC6 and VC7, see below

WHIST :

WINAPI is defined in the VC6 and VC7, see below

This bot copied definition of the C_DLLEXPORT and DLLEXPORT from META

VC6 :

WINAPI is defined in include\windef.h :

#ifdef _MAC
#define WINAPI CDECL
#elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#define WINAPI __stdcall
#else
#define WINAPI
#endif

NOTE : CDECL is defined as __cdecl

NOTE : WINAPI is defined as FAR PASCAL in some other files. For WIN16, FAR and PASCAL is defined as __far and __pascal, respectively. But in WIN32, FAR is defined as empty and PASCAL is defined as __stdcall, so everything is OK

VC7 :

WINAPI is defined in include\windef.h :

#ifdef _MAC
#define WINAPI CDECL
#elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#define WINAPI __stdcall
#else
#define WINAPI
#endif

WINAPI is defined in platformsdk\include\MAPINls.h :

#if !defined(WINAPI)
	#if defined(_WIN32) && (_MSC_VER >= 800)
		#define WINAPI	__stdcall
	#elif defined(WIN16)
		#define WINAPI	_far _pascal
	#else
		#define WINAPI	_far _pascal
	#endif
#endif

NOTE : CDECL is defined as __cdecl

NOTE : WINAPI is defined as FAR PASCAL in some other files. For WIN16, FAR and PASCAL is defined as __far and __pascal, respectively. But in WIN32, FAR is defined as empty and PASCAL is defined as __stdcall, so everything is OK

Notes :

Solution :

Do not use DLLEXPORT, EXPORT and WINAPI. Many programs is defining it differently and it may cause trouble. Use construction like I mentioned above for GiveFnptrsToDll(), and use this construction for other functions :

#ifdef _WIN32
#define MYEXPORT extern "C" __declspec(dllexport)
#elif defined __linux__
#define MYEXPORT extern "C" 
#endif
...
MYEXPORT int MyFunction(enginefuncs_t* pengfuncsFromEngine,globalvars_t *pGlobals)

NOTE : It is something like the META used, but it does not collide with "oh so useful" DLLEXPORT

3. Is bot using .def file ?

SDK :

dlls\mp.def :

LIBRARY mp
EXPORTS
	GiveFnptrsToDll	@1
SECTIONS
	.data READ WRITE

In dlls\mp.dsp, def is included to project : /def:".\mp.def"

HPB4 :

.def file is present and same as in SDK

HPBT3 :

.def file is present and same as in SDK

NOTE : This bot has different .def file for the borland compiler, but this is beyond the scope of this document

HPBT4 :

.def file is present and same as in SDK

NOTE : This bot has different .def file for the borland compiler, but this is beyond the scope of this document

JOE :

.def file is present and same as in SDK

NOTE : This bot has different .def file for the borland compiler, but this is beyond the scope of this document

META :

.def file is present and same as in SDK

POD26 :

.def file is present and same as in SDK

RACCP :

.def file is present and same as in SDK

RACC1 :

.def file is present and same as in SDK

RACC2 :

.def file is present and same as in SDK

REAL :

.def file is not present, but this CVS snapshot I have is not suited for the MSVC, so everything is OK. I assume that in the "MSVC version", .def file is present

WHIST :

.def file is present and same as in SDK

Solution :

Do not use .def files

Reasons : Because of 1 function, you have to have your code separated into 3 files :

Also there are many posts in HPBF4 and BUF4 from people who cannot sucessfully run their mod, and only problem is correct including of .def file.

Solution : use this code in the file where GiveFnptrsToDll() is defined (h_export.dll, best location is right before GiveFnptrsToDll()) :

#if defined _WIN32
#pragma comment(linker, "/EXPORT:GiveFnptrsToDll=_GiveFnptrsToDll@8,@1")
#pragma comment(linker, "/SECTION:.data,RW")
#endif // _WIN32

NOTE : You must also use extern "C" in definition of GiveFnptrsToDll() for above code to work, just like I stated in my solution to the first problem

4. How is Server_GetBlendingInterface declared ?

SDK :

Server_GetBlendingInterface is NOT defined in SDK

HPB4 :

Not defined

HPBT3 :

Not defined

HPBT4 :

Defined in dlls\h_export.cpp :

#ifdef __BORLANDC__
extern "C" DLLEXPORT int EXPORT Server_GetBlendingInterface( int version, struct sv_blending_interface_s **ppinterface, struct engine_studio_api_s *pstudio, float (*rotationmatrix)[3][4], float (*bonetransform)[MAXSTUDIOBONES][3][4] )
#else
int DLLEXPORT Server_GetBlendingInterface( int version, struct sv_blending_interface_s **ppinterface, struct engine_studio_api_s *pstudio, float (*rotationmatrix)[3][4], float (*bonetransform)[MAXSTUDIOBONES][3][4] )
#endif
{
   static SERVER_GETBLENDINGINTERFACE other_Server_GetBlendingInterface = NULL;
   static bool missing = FALSE;
   // if the blending interface has been formerly reported as missing, give up
   if (missing)
      return (FALSE);
   // do we NOT know if the blending interface is provided ? if so, look for its address
   if (other_Server_GetBlendingInterface == NULL)
      other_Server_GetBlendingInterface = (SERVER_GETBLENDINGINTERFACE) GetProcAddress (h_Library, "Server_GetBlendingInterface");
   // have we NOT found it ?
   if (!other_Server_GetBlendingInterface) {
      missing = TRUE; // then mark it as missing, no use to look for it again in the future
      return (FALSE); // and give up
   }
   // else call the function that provides the blending interface on request
   return ((other_Server_GetBlendingInterface) (version, ppinterface, pstudio, rotationmatrix, bonetransform));
}

***ERROR*** : This function is not exported under MSVC. DLLEXPORT macro is wrong and there is no declarator telling that this function should be exported. If this function will be exported by some miracle or .def file, it will crash whole Half-life for sure, because of wrong __stdcall calling convention. Calling convention for this function is __cdecl, which is default

JOE :

Defined in dlls\dll.cpp :

#ifdef __BORLANDC__
//extern "C" DLLEXPORT int EXPORT Server_GetBlendingInterface(int version, struct sv_blending_interface_s **ppinterface,struct engine_studio_api_s *pstudio,float (*rotationmatrix)[3][4], float (*bonetransform)[MAXSTUDIOBONES][3][4])
int EXPORT Server_GetBlendingInterface(int version, struct sv_blending_interface_s **ppinterface,struct engine_studio_api_s *pstudio,float (*rotationmatrix)[3][4], float (*bonetransform)[MAXSTUDIOBONES][3][4])
#else
//int DLLEXPORT Server_GetBlendingInterface(int version, struct sv_blending_interface_s **ppinterface,struct engine_studio_api_s *pstudio,float (*rotationmatrix)[3][4], float (*bonetransform)[MAXSTUDIOBONES][3][4])
extern "C" EXPORT int Server_GetBlendingInterface(int version, struct sv_blending_interface_s **ppinterface,struct engine_studio_api_s *pstudio,float (*rotationmatrix)[3][4], float (*bonetransform)[MAXSTUDIOBONES][3][4])
#endif
{
	if (other_Server_GetBlendingInterface == NULL)
		return FALSE;
	// call blending interface function
	return ((*other_Server_GetBlendingInterface)(version, ppinterface, pstudio, rotationmatrix, bonetransform));
}
#endif /* not USE_METAMOD */

NOTE that in this case, bot author corrected error mentioned above

META :

Defined in metamod\studioapi.cpp :

C_DLLEXPORT int Server_GetBlendingInterface(int version,struct sv_blending_interface_s **ppinterface,struct engine_studio_api_s *pstudio,float (*rotationmatrix)[3][4],float (*bonetransform)[MAXSTUDIOBONES][3][4])
{
	static GETBLENDAPI_FN getblend=NULL;
	static int missing=0;
	// Note that we're not checking if
	// (version==SV_BLENDING_INTERFACE_VERSION) because at this point, we
	// don't really care, as we're not looking at or using the contents of
	// the function tables; we're only passing them through to the gamedll,
	// which presumably will check for version match, since it's the one
	// that cares and actually uses the function tables.
	// Return(0) if the gamedll does not provide this routine, and the
	// Engine will use its own builtin blending.  The Engine will report
	// "Couldn't get server .dll studio model blending interface.  Version
	// mismatch?", but this will only show in "developer" (-dev) mode.
	META_DEBUG(6, ("called: Server_GetBlendingInterface; version=%d", version));
	if(missing) {
		META_DEBUG(6, ("Skipping Server_GetBlendingInterface; was previously found missing"));
		return(0);
	}
	if(!getblend) {
		META_DEBUG(6, ("Looking up Server_GetBlendingInterface"));
		getblend = (GETBLENDAPI_FN) DLSYM(GameDLL.handle, 
				"Server_GetBlendingInterface");
	}
	if(!getblend) {
		META_DEBUG(6, ("Couldn't find Server_GetBlendingInterface in game DLL '%s': %s", GameDLL.name, DLERROR()));
		missing=1;
		return(0);
	}
	META_DEBUG(6, ("Calling Server_GetBlendingInterface"));
	return((getblend)(version, ppinterface, pstudio, rotationmatrix, 
			bonetransform));
}

POD26 :

Not defined

RACCP :

Not defined

RACC1 :

Not defined

RACC2 :

Defined in *\dll.cpp :

int DLLEXPORT Server_GetBlendingInterface (int version, struct sv_blending_interface_s **ppinterface, struct engine_studio_api_s *pstudio, float (*rotationmatrix)[3][4], float (*bonetransform)[MAXSTUDIOBONES][3][4])
{
   // this function synchronizes the studio model animation blending interface (i.e, what parts
   // of the body move, which bones, which hitboxes and how) between the server and the game DLL.
   // some MODs can be using a different hitbox scheme than the standard one.
   static SERVER_GETBLENDINGINTERFACE other_Server_GetBlendingInterface = NULL;
   static bool missing = FALSE;
   // if the blending interface has been formerly reported as missing, give up
   if (missing)
      return (FALSE);
   // do we NOT know if the blending interface is provided ? if so, look for its address
   if (other_Server_GetBlendingInterface == NULL)
      other_Server_GetBlendingInterface = (SERVER_GETBLENDINGINTERFACE) GetProcAddress (h_Library, "Server_GetBlendingInterface");
   // have we NOT found it ?
   if (!other_Server_GetBlendingInterface) {
      missing = TRUE; // then mark it as missing, no use to look for it again in the future
      return (FALSE); // and give up
   }
   // else call the function that provides the blending interface on request
   return ((other_Server_GetBlendingInterface) (version, ppinterface, pstudio, rotationmatrix, bonetransform));
}

***ERROR*** : This function is not exported under MSVC. DLLEXPORT macro is wrong and there is no declarator telling that this function should be exported. If this function will be exported by some miracle or .def file, it will crash whole Half-life for sure, because of wrong __stdcall calling convention. Calling convention for this function is __cdecl, which is default

REAL :

Not defined

WHIST :

Defined in h_export.cpp :

C_DLLEXPORT int Server_GetBlendingInterface(int version,struct sv_blending_interface_s **ppinterface,struct engine_studio_api_s *pstudio,float (*rotationmatrix)[3][4],float (*bonetransform)[MAXSTUDIOBONES][3][4])
{
   // do we NOT know if the blending interface is provided?
   if (!other_Server_GetBlendingInterface)
      return FALSE; // give up

   // else call the function that provides the blending interface on request
   if (!((*other_Server_GetBlendingInterface)(version, ppinterface, pstudio, rotationmatrix, bonetransform)))
      return FALSE;

   return TRUE;
}

It is also declared in main.h with same function prototype as in definition

Notes :

http://www.mail-archive.com/hlcoders@list.valvesoftware.com/msg01224.html

http://www.mail-archive.com/hlcoders@list.valvesoftware.com/msg02724.html

HPBT4 and RACC2 should be fixed !

Of course, Server_GetBlendingInterface should NOT be exported with LINK_ENTITY_TO_FUNC() macro. This applies also for GiveFnptrsToDll, GetNewDLLFunctions, GetEntityAPI and GetEntityAPI2

Solution :

Function is exported normally with __cdecl (default) calling convention, without name-decoration

You don't have to specify __cdecl, because it is default calling convention in MSVC

Correct declaration (for MSVC and linux) is :

#ifdef _WIN32
extern "C" __declspec(dllexport) int Server_GetBlendingInterface( int version, struct sv_blending_interface_s **ppinterface, struct engine_studio_api_s *pstudio, float (*rotationmatrix)[3][4], float (*bonetransform)[MAXSTUDIOBONES][3][4] )
#else
extern "C" int Server_GetBlendingInterface( int version, struct sv_blending_interface_s **ppinterface, struct engine_studio_api_s *pstudio, float (*rotationmatrix)[3][4], float (*bonetransform)[MAXSTUDIOBONES][3][4] )
#endif

References

SDK :

HPB4, HPBT3, HPBT4 :

JOE :

META :

POD26 :

RACCP, RACC1, RACC2 :

REAL :

WHIST :

Visual C++ 6.0, Visual C++ 7.0 (Visual Studio .NET 2003) :

End of document