As RenderWare Graphics starts up we need to inform RenderWare Graphics that every atomic that gets created must increase in size by enough bytes to store a character pointer. This is why plugins must register with RenderWare Graphics. First of all we will write a plugin API call to initialize the plugin.
RpAName.c and RpAName.h and add them to the project. RpAName.h:
/* Function prototypes */ #ifndef RPANAME_H #define RPANAME_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern RwInt32 RpAtomicNameInitialize(void);
#ifdef __cplusplus } #endif /* __cplusplus */ #endif /* RPANAME_H */
RpAName.c. This code tells RenderWare Graphics that each atomic must grow in size by the size of a character pointer. The code also registers two callbacks, one used to initialize the plugin data, and one to destroy the data.
#include <rwcore.h> #include <rpworld.h> #include "RpAName.h" /****************************************************************************/ /* Local defines */
/* note that this is a hack and should be a registered plugin ID */ #define rwID_EXAMPLE 0xff /****************************************************************************/ /* Local variables */ static RwInt32 rpExtensionOffset = -1; /****************************************************************************/ /* Local functions for the atomic name plugin */
/* Atomic Name Application Programming Interface */ /*********************************************************************************/ RwInt32 RpAtomicNameInitialize(void) { rpExtensionOffset = RpAtomicRegisterPlugin(sizeof(char *), MAKECHUNKID(rwVENDORID_CRITERIONTK, rwID_EXAMPLE), rpConstructor, rpDestructor, NULL);
/* return the offset */ return (rpExtensionOffset); }
RpAName.c stores the offset from the beginning of an atomic to the extension data in the variable rpExtensionOffset. This value is needed by the plugin.
Next we must implement the construction and destruction callbacks. To begin with, we will implement basic stub functions that simply call RwDebugSendMessage() to inform us that the functions have been called.
rpConstructor() and rpDestructor(). Both functions take three arguments, a void pointer, and two RwInt32's - offset and size. Make calls to RwDebugSendMessage() to report that the functions have been called. You might need to check the API reference for the arguments you need to pass to this function.
/* Local functions for the atomic name plugin */ static void * rpConstructor(void *atom, RwInt32 offset __RWUNUSED__, RwInt32 size __RWUNUSED__) {
RwDebugSendMessage(rwDEBUGMESSAGE, "rpConstructor", "Atomic constructor called.");
/* success */ return (atom); }
RwDebugSendMessage(rwDEBUGMESSAGE, "rpDestructor", "Atomic destructor called.");
/* success */ return (atom); }
RpAName.h header file to main.c, and in the AttachPlugins() function, make a call to RpAtomicNameInitialize() to register the atomic extension.
rpConstructor() function is called.
Now we should initialize the extension data when the constructor is called, and destroy any extension data when the destructor is called. In our application when an atomic is created it will have no name. This will be denoted by the normal convention of the character pointer being NULL. Later on we will create space for the name by using RwMalloc(), so the destructor will call RwFree(). Note that the constructor and destructor get passed a void *. If we add the value of rpExtensionOffset to the address of the void * pointer we get a pointer to our extension data. If is helpful to define a macro to convert the void * into a pointer to our data.
RpAName.c. This converts a pointer to an atomic to our extension data.
/* Local defines */ /* Given an atomic, return a pointer to the extension */ #define RPEXTFROMATOMIC(a)\ ((char **)(((RwUInt8 *)(a)) + rpExtensionOffset)) /* note that this is a hack and should be a registered plugin ID */ #define rwID_EXAMPLE 0xff
static void * rpConstructor(void *atom, RwInt32 offset __RWUNUSED__, RwInt32 size __RWUNUSED__) { if (rpExtensionOffset > 0) { char **extData = RPEXTFROMATOMIC(atom); /* atomics have no name to start with */ *extData = NULL; } /* success */ return (atom);
}
static void * rpDestructor(void *atom, RwInt32 offset __RWUNUSED__, RwInt32 size __RWUNUSED__) { if (rpExtensionOffset > 0) { char **extData = RPEXTFROMATOMIC(atom); if (*extData) { RwFree(*extData); } } /* success */ return (atom);
}
© 1993-2004 Criterion Software Limited. All rights reserved. Built Thu Feb 12 13:46:58 2004.
Send Feedback