====== Simple plugin ====== All defines and exports from PlayClaw are provided in supplied file //plugins_shared.h// <sxh cpp; title: plugins_shared.h> #define PLAYCLAW_API __declspec(dllimport) #define PLUGIN_EXPORT extern "C" __declspec(dllexport) </sxh> One must-have export for any plugin is //PluginInit// method. <sxh cpp; title: plugin sample code> DWORD m_dwPluginID = -1; PLUGIN_EXPORT DWORD PluginInit(DWORD dwPluginID) { // store unique plugin id (we will need it for some functions) m_dwPluginID = dwPluginID; // additional init // ... // plugin must return special flags return PC_PLUGIN_FLAG_IS_ACTIVE | PC_PLUGIN_FLAG_IS_OVERLAY; } </sxh> Returned plugin flags: <sxh cpp; Title: plugins_shared.h> #define PC_PLUGIN_FLAG_IS_ACTIVE 0x0001 // indicates that plugin can work #define PC_PLUGIN_FLAG_IS_OVERLAY 0x0002 // this plugin can render overlay </sxh> Also you need to statically link to playclaw export library (provided with SDK sources). If your plugin has its own variables, you need to export two methods: <sxh cpp; title: plugin sample code> // here you can set default values for common or your own unique variables PLUGIN_EXPORT void PluginSetDefaultVars() { PC_SetPluginVar(dwPluginID, OVR_VAR_SIZE_X, 64); PC_SetPluginVar(dwPluginID, OVR_VAR_SIZE_Y, 64); PC_SetPluginVar(dwPluginID, "my_variable", 100500); } // Update variables (after profile loading for example) PLUGIN_EXPORT void PluginUpdateVars() { my_var = PC_GetPluginVarInt(m_dwPluginID, "my_variable"); } </sxh> PlayClaw calls PluginSetDefaultVars before profile loading to set defaults and then, after profile loading it calls PluginUpdateVars to inform plugin that it can "cache" variables in its own memory (for fast processing, etc). Also this PluginUpdateVars method can be called after any variables change. If you need to delete/close something on plugin shutdown, use this export: <sxh cpp; title: plugin sample code> PLUGIN_EXPORT void PluginShutdown() { // ... } </sxh> If you returned PC_PLUGIN_FLAG_IS_OVERLAY then overlay render procedure must be exported: <sxh cpp; title: plugin sample code> PLUGIN_EXPORT void PluginUpdateOverlay() { // ... } </sxh> You can use any renderer which you like. You can even "draw" overlay by your own "software-renderer" code because PlayClaw provides memory frame buffer for PluginUpdateOverlay export. To simplify render task we provide special helper class //PluginOverlayGdiPlusHelper// in //plugins_helper.h// file To use it you only need to declare pointer to helper, add a few lines in Init and Shutdown methods: <sxh cpp; title: helper> PluginOverlayGdiPlusHelper *pRenderHelper = 0; </sxh> <sxh cpp; title: for Init> // Initialize GDI+. pRenderHelper = new PluginOverlayGdiPlusHelper(dwPluginID); </sxh> <sxh cpp; title: for Shutdown> if (pRenderHelper) delete pRenderHelper; </sxh> Now overlay renderer export will be like this: <sxh cpp; title: rendering overlay> PLUGIN_EXPORT void PluginUpdateOverlay() { if (!pRenderHelper) return; // lock overlay image if (!pRenderHelper->BeginFrame()) return; Gdiplus::Graphics *pGraphics = pRenderHelper->GetGraphics(); // we like antialiased text pGraphics->SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias); // some font Gdiplus::Font font(L"System", 30, Gdiplus::FontStyleBold); // brush with red color if recording is enabled and black color is disabled Gdiplus::SolidBrush br3(PC_IsRecording() ? Gdiplus::Color(255, 255, 0, 0) : Gdiplus::Color(200, 0, 0, 0)); // get fps counter and turn it to string WCHAR s[128]; wsprintf(s, L"%d", PC_GetFPSCounter()); // clear back ground pGraphics->Clear(Gdiplus::Color(0, 0, 0, 0)); // draw fps string at some point pGraphics->DrawString(s, wcslen(s), &font, Gdiplus::PointF(50, 10), &br3); // fill overlay image pRenderHelper->EndFrame(); } </sxh> If you do not like GDI+ or our helper class, then you can create your own renderer. Only two [[plugin_sdk:imports:start|imports from PlayClaw]] are important for this.