├── D3D9Hook.h ├── D3D9Hook.c ├── D3D9Object.h └── D3D9Object.c /D3D9Hook.h: -------------------------------------------------------------------------------- 1 | // --- Author : Moreau Cyril - Spl3en 2 | #pragma once 3 | 4 | // ---------- Includes ------------ 5 | #include "Utils/Utils.h" 6 | #include "dx/d3d9.h" 7 | #include "dx/d3dx9.h" 8 | 9 | // ---------- Defines ------------- 10 | 11 | 12 | // ------ Structure declaration ------- 13 | typedef struct _D3D9Hook 14 | { 15 | DWORD *vftable; 16 | 17 | } D3D9Hook; 18 | 19 | typedef enum 20 | { 21 | D3D9INDEX_QueryInterface, // 0 22 | D3D9INDEX_AddRef, // 1 23 | D3D9INDEX_Release, // 2 24 | D3D9INDEX_TestCooperativeLevel, // 3 25 | D3D9INDEX_GetAvailableTextureMem, // 4 26 | D3D9INDEX_EvictManagedResources, // 5 27 | D3D9INDEX_GetDirect3D, // 6 28 | D3D9INDEX_GetDeviceCaps, // 7 29 | D3D9INDEX_GetDisplayMode, // 8 30 | D3D9INDEX_GetCreationParameters, // 9 31 | D3D9INDEX_SetCursorProperties, // 10 32 | D3D9INDEX_SetCursorPosition, // 11 33 | D3D9INDEX_ShowCursor, // 12 34 | D3D9INDEX_CreateAdditionalSwapChain, // 13 35 | D3D9INDEX_GetSwapChain, // 14 36 | D3D9INDEX_GetNumberOfSwapChains, // 15 37 | D3D9INDEX_Reset, // 16 38 | D3D9INDEX_Present, // 17 39 | D3D9INDEX_GetBackBuffer, // 18 40 | D3D9INDEX_GetRasterStatus, // 19 41 | D3D9INDEX_SetDialogBoxMode, // 20 42 | D3D9INDEX_SetGammaRamp, // 21 43 | D3D9INDEX_GetGammaRamp, // 22 44 | D3D9INDEX_CreateTexture, // 23 45 | D3D9INDEX_CreateVolumeTexture, // 24 46 | D3D9INDEX_CreateCubeTexture, // 25 47 | D3D9INDEX_CreateVertexBuffer, // 26 48 | D3D9INDEX_CreateIndexBuffer, // 27 49 | D3D9INDEX_CreateRenderTarget, // 28 50 | D3D9INDEX_CreateDepthStencilSurface, // 29 51 | D3D9INDEX_UpdateSurface, // 30 52 | D3D9INDEX_UpdateTexture, // 31 53 | D3D9INDEX_GetRenderTargetData, // 32 54 | D3D9INDEX_GetFrontBufferData, // 33 55 | D3D9INDEX_StretchRect, // 34 56 | D3D9INDEX_ColorFill, // 35 57 | D3D9INDEX_CreateOffscreenPlainSurface, // 36 58 | D3D9INDEX_SetRenderTarget, // 37 59 | D3D9INDEX_GetRenderTarget, // 38 60 | D3D9INDEX_SetDepthStencilSurface, // 39 61 | D3D9INDEX_GetDepthStencilSurface, // 40 62 | D3D9INDEX_BeginScene, // 41 63 | D3D9INDEX_EndScene, // 42 64 | D3D9INDEX_Clear, // 43 65 | D3D9INDEX_SetTransform, // 44 66 | D3D9INDEX_GetTransform, // 45 67 | D3D9INDEX_MultiplyTransform, // 46 68 | D3D9INDEX_SetViewport, // 47 69 | D3D9INDEX_GetViewport, // 48 70 | D3D9INDEX_SetMaterial, // 49 71 | D3D9INDEX_GetMaterial, // 50 72 | D3D9INDEX_SetLight, // 51 73 | D3D9INDEX_GetLight, // 52 74 | D3D9INDEX_LightEnable, // 53 75 | D3D9INDEX_GetLightEnable, // 54 76 | D3D9INDEX_SetClipPlane, // 55 77 | D3D9INDEX_GetClipPlane, // 56 78 | D3D9INDEX_SetRenderState, // 57 79 | D3D9INDEX_GetRenderState, // 58 80 | D3D9INDEX_CreateStateBlock, // 59 81 | D3D9INDEX_BeginStateBlock, // 60 82 | D3D9INDEX_EndStateBlock, // 61 83 | D3D9INDEX_SetClipStatus, // 62 84 | D3D9INDEX_GetClipStatus, // 63 85 | D3D9INDEX_GetTexture, // 64 86 | D3D9INDEX_SetTexture, // 65 87 | D3D9INDEX_GetTextureStageState, // 66 88 | D3D9INDEX_SetTextureStageState, // 67 89 | D3D9INDEX_GetSamplerState, // 68 90 | D3D9INDEX_SetSamplerState, // 69 91 | D3D9INDEX_ValidateDevice, // 70 92 | D3D9INDEX_SetPaletteEntries, // 71 93 | D3D9INDEX_GetPaletteEntries, // 72 94 | D3D9INDEX_SetCurrentTexturePalette, // 73 95 | D3D9INDEX_GetCurrentTexturePalette, // 74 96 | D3D9INDEX_SetScissorRect, // 75 97 | D3D9INDEX_GetScissorRect, // 76 98 | D3D9INDEX_SetSoftwareVertexProcessing, // 77 99 | D3D9INDEX_GetSoftwareVertexProcessing, // 78 100 | D3D9INDEX_SetNPatchMode, // 79 101 | D3D9INDEX_GetNPatchMode, // 80 102 | D3D9INDEX_DrawPrimitive, // 81 103 | D3D9INDEX_DrawIndexedPrimitive, // 82 104 | D3D9INDEX_DrawPrimitiveUP, // 83 105 | D3D9INDEX_DrawIndexedPrimitiveUP, // 84 106 | D3D9INDEX_ProcessVertices, // 85 107 | D3D9INDEX_CreateVertexDeclaration, // 86 108 | D3D9INDEX_SetVertexDeclaration, // 87 109 | D3D9INDEX_GetVertexDeclaration, // 88 110 | D3D9INDEX_SetFVF, // 89 111 | D3D9INDEX_GetFVF, // 90 112 | D3D9INDEX_CreateVertexShader, // 91 113 | D3D9INDEX_SetVertexShader, // 92 114 | D3D9INDEX_GetVertexShader, // 93 115 | D3D9INDEX_SetVertexShaderConstantF, // 94 116 | D3D9INDEX_GetVertexShaderConstantF, // 95 117 | D3D9INDEX_SetVertexShaderConstantI, // 96 118 | D3D9INDEX_GetVertexShaderConstantI, // 97 119 | D3D9INDEX_SetVertexShaderConstantB, // 98 120 | D3D9INDEX_GetVertexShaderConstantB, // 99 121 | D3D9INDEX_SetStreamSource, // 100 122 | D3D9INDEX_GetStreamSource, // 101 123 | D3D9INDEX_SetStreamSourceFreq, // 102 124 | D3D9INDEX_GetStreamSourceFreq, // 103 125 | D3D9INDEX_SetIndices, // 104 126 | D3D9INDEX_GetIndices, // 105 127 | D3D9INDEX_CreatePixelShader, // 106 128 | D3D9INDEX_SetPixelShader, // 107 129 | D3D9INDEX_GetPixelShader, // 108 130 | D3D9INDEX_SetPixelShaderConstantF, // 109 131 | D3D9INDEX_GetPixelShaderConstantF, // 110 132 | D3D9INDEX_SetPixelShaderConstantI, // 111 133 | D3D9INDEX_GetPixelShaderConstantI, // 112 134 | D3D9INDEX_SetPixelShaderConstantB, // 113 135 | D3D9INDEX_GetPixelShaderConstantB, // 114 136 | D3D9INDEX_DrawRectPatch, // 115 137 | D3D9INDEX_DrawTriPatch, // 116 138 | D3D9INDEX_DeletePatch, // 117 139 | D3D9INDEX_CreateQuery, // 118 140 | 141 | D3D9INDEX_Undefined, // Unknown index 142 | D3D9INDEX_VFTABLE_SIZE // Always at the end 143 | 144 | } D3D9VirtualFunctionTableIndex; 145 | 146 | 147 | // --------- Allocators --------- 148 | 149 | /* 150 | * Description : Allocate a new D3D9Hook structure. 151 | * DWORD baseAddress : Base address of the in-memory D3D9 module 152 | * DWORD sizeOfModule : The size of the module 153 | * Return : A pointer to an allocated D3D9Hook. 154 | */ 155 | D3D9Hook * 156 | D3D9Hook_new ( 157 | DWORD baseAddress, 158 | DWORD sizeOfModule 159 | ); 160 | 161 | // ----------- Functions ------------ 162 | 163 | /* 164 | * Description : Initialize an allocated D3D9Hook structure. 165 | * D3D9Hook *this : An allocated D3D9Hook to initialize. 166 | * DWORD baseAddress : Base address of the in-memory D3D9 module 167 | * DWORD sizeOfModule : The size of the module 168 | */ 169 | bool 170 | D3D9Hook_init ( 171 | D3D9Hook *this, 172 | DWORD baseAddress, 173 | DWORD sizeOfModule 174 | ); 175 | 176 | 177 | /* 178 | * Description : 179 | * D3D9Hook *this : An allocated D3D9Hook 180 | * D3D9VirtualFunctionTableIndex index : Index of the function to hook 181 | * ULONG_PTR hookFunction : Hook function 182 | * Return : DWORD address of the original function hooked, or 0 if error 183 | */ 184 | void * 185 | D3D9Hook_hook ( 186 | D3D9Hook *this, 187 | D3D9VirtualFunctionTableIndex index, 188 | ULONG_PTR hookFunction 189 | ); 190 | 191 | /* 192 | * Description : Unit tests checking if a D3D9Hook is coherent 193 | * D3D9Hook *this : The instance to test 194 | * Return : true on success, false on failure 195 | */ 196 | bool 197 | D3D9Hook_test ( 198 | D3D9Hook *this 199 | ); 200 | 201 | /* 202 | * Description : Convert a D3D9VirtualFunctionTableIndex to string 203 | * D3D9VirtualFunctionTableIndex index : The D3D9VirtualFunctionTableIndex to convert 204 | * Return : char * the string 205 | */ 206 | char * 207 | D3D9VirtualFunctionTableIndex_to_string ( 208 | D3D9VirtualFunctionTableIndex index 209 | ); 210 | 211 | /* 212 | * Description : Check if a D3D9VirtualFunctionTableIndex is valid 213 | * D3D9VirtualFunctionTableIndex index : An allocated D3D9VirtualFunctionTableIndex 214 | * Return : bool true on success, false otherwise 215 | */ 216 | bool 217 | D3D9VirtualFunctionTableIndex_is_valid ( 218 | D3D9VirtualFunctionTableIndex index 219 | ); 220 | 221 | // --------- Destructors ---------- 222 | 223 | /* 224 | * Description : Free an allocated D3D9Hook structure. 225 | * D3D9Hook *this : An allocated D3D9Hook to free. 226 | */ 227 | void 228 | D3D9Hook_free ( 229 | D3D9Hook *this 230 | ); 231 | 232 | 233 | -------------------------------------------------------------------------------- /D3D9Hook.c: -------------------------------------------------------------------------------- 1 | #include "D3D9Hook.h" 2 | #include "HookEngine/HookEngine.h" 3 | #include "Scanner/Scanner.h" 4 | #include 5 | 6 | // ---------- Debugging ------------- 7 | #define __DEBUG_OBJECT__ "D3D9Hook" 8 | #include "dbg/dbg.h" 9 | 10 | 11 | static EnumerationStringAssociation association [D3D9INDEX_VFTABLE_SIZE] = { 12 | 13 | [0 ... D3D9INDEX_VFTABLE_SIZE-1] = {D3D9INDEX_Undefined, "D3D9INDEX_Undefined"}, 14 | 15 | associate (D3D9INDEX_QueryInterface), 16 | associate (D3D9INDEX_AddRef), 17 | associate (D3D9INDEX_Release), 18 | associate (D3D9INDEX_TestCooperativeLevel), 19 | associate (D3D9INDEX_GetAvailableTextureMem), 20 | associate (D3D9INDEX_EvictManagedResources), 21 | associate (D3D9INDEX_GetDirect3D), 22 | associate (D3D9INDEX_GetDeviceCaps), 23 | associate (D3D9INDEX_GetDisplayMode), 24 | associate (D3D9INDEX_GetCreationParameters), 25 | associate (D3D9INDEX_SetCursorProperties), 26 | associate (D3D9INDEX_SetCursorPosition), 27 | associate (D3D9INDEX_ShowCursor), 28 | associate (D3D9INDEX_CreateAdditionalSwapChain), 29 | associate (D3D9INDEX_GetSwapChain), 30 | associate (D3D9INDEX_GetNumberOfSwapChains), 31 | associate (D3D9INDEX_Reset), 32 | associate (D3D9INDEX_Present), 33 | associate (D3D9INDEX_GetBackBuffer), 34 | associate (D3D9INDEX_GetRasterStatus), 35 | associate (D3D9INDEX_SetDialogBoxMode), 36 | associate (D3D9INDEX_SetGammaRamp), 37 | associate (D3D9INDEX_GetGammaRamp), 38 | associate (D3D9INDEX_CreateTexture), 39 | associate (D3D9INDEX_CreateVolumeTexture), 40 | associate (D3D9INDEX_CreateCubeTexture), 41 | associate (D3D9INDEX_CreateVertexBuffer), 42 | associate (D3D9INDEX_CreateIndexBuffer), 43 | associate (D3D9INDEX_CreateRenderTarget), 44 | associate (D3D9INDEX_CreateDepthStencilSurface), 45 | associate (D3D9INDEX_UpdateSurface), 46 | associate (D3D9INDEX_UpdateTexture), 47 | associate (D3D9INDEX_GetRenderTargetData), 48 | associate (D3D9INDEX_GetFrontBufferData), 49 | associate (D3D9INDEX_StretchRect), 50 | associate (D3D9INDEX_ColorFill), 51 | associate (D3D9INDEX_CreateOffscreenPlainSurface), 52 | associate (D3D9INDEX_SetRenderTarget), 53 | associate (D3D9INDEX_GetRenderTarget), 54 | associate (D3D9INDEX_SetDepthStencilSurface), 55 | associate (D3D9INDEX_GetDepthStencilSurface), 56 | associate (D3D9INDEX_BeginScene), 57 | associate (D3D9INDEX_EndScene), 58 | associate (D3D9INDEX_Clear), 59 | associate (D3D9INDEX_SetTransform), 60 | associate (D3D9INDEX_GetTransform), 61 | associate (D3D9INDEX_MultiplyTransform), 62 | associate (D3D9INDEX_SetViewport), 63 | associate (D3D9INDEX_GetViewport), 64 | associate (D3D9INDEX_SetMaterial), 65 | associate (D3D9INDEX_GetMaterial), 66 | associate (D3D9INDEX_SetLight), 67 | associate (D3D9INDEX_GetLight), 68 | associate (D3D9INDEX_LightEnable), 69 | associate (D3D9INDEX_GetLightEnable), 70 | associate (D3D9INDEX_SetClipPlane), 71 | associate (D3D9INDEX_GetClipPlane), 72 | associate (D3D9INDEX_SetRenderState), 73 | associate (D3D9INDEX_GetRenderState), 74 | associate (D3D9INDEX_CreateStateBlock), 75 | associate (D3D9INDEX_BeginStateBlock), 76 | associate (D3D9INDEX_EndStateBlock), 77 | associate (D3D9INDEX_SetClipStatus), 78 | associate (D3D9INDEX_GetClipStatus), 79 | associate (D3D9INDEX_GetTexture), 80 | associate (D3D9INDEX_SetTexture), 81 | associate (D3D9INDEX_GetTextureStageState), 82 | associate (D3D9INDEX_SetTextureStageState), 83 | associate (D3D9INDEX_GetSamplerState), 84 | associate (D3D9INDEX_SetSamplerState), 85 | associate (D3D9INDEX_ValidateDevice), 86 | associate (D3D9INDEX_SetPaletteEntries), 87 | associate (D3D9INDEX_GetPaletteEntries), 88 | associate (D3D9INDEX_SetCurrentTexturePalette), 89 | associate (D3D9INDEX_GetCurrentTexturePalette), 90 | associate (D3D9INDEX_SetScissorRect), 91 | associate (D3D9INDEX_GetScissorRect), 92 | associate (D3D9INDEX_SetSoftwareVertexProcessing), 93 | associate (D3D9INDEX_GetSoftwareVertexProcessing), 94 | associate (D3D9INDEX_SetNPatchMode), 95 | associate (D3D9INDEX_GetNPatchMode), 96 | associate (D3D9INDEX_DrawPrimitive), 97 | associate (D3D9INDEX_DrawIndexedPrimitive), 98 | associate (D3D9INDEX_DrawPrimitiveUP), 99 | associate (D3D9INDEX_DrawIndexedPrimitiveUP), 100 | associate (D3D9INDEX_ProcessVertices), 101 | associate (D3D9INDEX_CreateVertexDeclaration), 102 | associate (D3D9INDEX_SetVertexDeclaration), 103 | associate (D3D9INDEX_GetVertexDeclaration), 104 | associate (D3D9INDEX_SetFVF), 105 | associate (D3D9INDEX_GetFVF), 106 | associate (D3D9INDEX_CreateVertexShader), 107 | associate (D3D9INDEX_SetVertexShader), 108 | associate (D3D9INDEX_GetVertexShader), 109 | associate (D3D9INDEX_SetVertexShaderConstantF), 110 | associate (D3D9INDEX_GetVertexShaderConstantF), 111 | associate (D3D9INDEX_SetVertexShaderConstantI), 112 | associate (D3D9INDEX_GetVertexShaderConstantI), 113 | associate (D3D9INDEX_SetVertexShaderConstantB), 114 | associate (D3D9INDEX_GetVertexShaderConstantB), 115 | associate (D3D9INDEX_SetStreamSource), 116 | associate (D3D9INDEX_GetStreamSource), 117 | associate (D3D9INDEX_SetStreamSourceFreq), 118 | associate (D3D9INDEX_GetStreamSourceFreq), 119 | associate (D3D9INDEX_SetIndices), 120 | associate (D3D9INDEX_GetIndices), 121 | associate (D3D9INDEX_CreatePixelShader), 122 | associate (D3D9INDEX_SetPixelShader), 123 | associate (D3D9INDEX_GetPixelShader), 124 | associate (D3D9INDEX_SetPixelShaderConstantF), 125 | associate (D3D9INDEX_GetPixelShaderConstantF), 126 | associate (D3D9INDEX_SetPixelShaderConstantI), 127 | associate (D3D9INDEX_GetPixelShaderConstantI), 128 | associate (D3D9INDEX_SetPixelShaderConstantB), 129 | associate (D3D9INDEX_GetPixelShaderConstantB), 130 | associate (D3D9INDEX_DrawRectPatch), 131 | associate (D3D9INDEX_DrawTriPatch), 132 | associate (D3D9INDEX_DeletePatch), 133 | associate (D3D9INDEX_CreateQuery) 134 | }; 135 | 136 | 137 | /* 138 | * Description : Allocate a new D3D9Hook structure. 139 | * DWORD baseAddress : Base address of the module 140 | * DWORD hudChatInstance : The address of hudChat 141 | * Return : A pointer to an allocated D3D9Hook. 142 | */ 143 | D3D9Hook * 144 | D3D9Hook_new ( 145 | DWORD baseAddress, 146 | DWORD sizeOfModule 147 | ) { 148 | D3D9Hook *this; 149 | 150 | if ((this = calloc (1, sizeof(D3D9Hook))) == NULL) 151 | return NULL; 152 | 153 | if (!D3D9Hook_init (this, baseAddress, sizeOfModule)) { 154 | D3D9Hook_free (this); 155 | return NULL; 156 | } 157 | 158 | return this; 159 | } 160 | 161 | /* 162 | * Description : Initialize an allocated D3D9Hook structure. 163 | * D3D9Hook *this : An allocated D3D9Hook to initialize. 164 | * DWORD baseAddress : Base address of the module 165 | * DWORD hudChatInstance : The address of hudChat 166 | * Return : true on success, false on failure. 167 | */ 168 | bool 169 | D3D9Hook_init ( 170 | D3D9Hook *this, 171 | DWORD baseAddress, 172 | DWORD sizeOfModule 173 | ) { 174 | unsigned char pattern [] = { 175 | /* C706 084E8C5C mov [dword ds:esi], d3d9.5C8C4E08 176 | 8986 68300000 mov [dword ds:esi+3068], eax 177 | 8986 60300000 mov [dword ds:esi+3060], eax */ 178 | 0xC7, 0x06, '?', '?', '?', '?', 179 | 0x89, 0x86, '?', '?', '?', '?', 180 | 0x89, 0x86, '?', '?', '?', '?' 181 | }; 182 | 183 | // Get the d3d9 device vftable 184 | DWORD * pDeviceVftable = (DWORD *) mem_scanner ("pDeviceVftable", 185 | baseAddress, sizeOfModule, 186 | pattern, 187 | 188 | "xx????" 189 | "xx????" 190 | "xx????", 191 | 192 | "xx????" 193 | "xxxxxx" 194 | "xxxxxx" 195 | ); 196 | 197 | if (!pDeviceVftable) { 198 | dbg ("pDeviceVftable pattern not found."); 199 | return false; 200 | } 201 | 202 | dbg ("pDeviceVftable found : 0x%.08X", pDeviceVftable); 203 | this->vftable = pDeviceVftable; 204 | 205 | return true; 206 | } 207 | 208 | 209 | /* 210 | * Description : 211 | * D3D9Hook *this : An allocated D3D9Hook 212 | * D3D9VirtualFunctionTableIndex index : Index of the function to hook 213 | * ULONG_PTR hookFunction : Hook function 214 | * Return : DWORD address of the original function hooked, or 0 if error 215 | */ 216 | void * 217 | D3D9Hook_hook ( 218 | D3D9Hook *this, 219 | D3D9VirtualFunctionTableIndex index, 220 | ULONG_PTR hookFunction 221 | ) { 222 | if (!D3D9VirtualFunctionTableIndex_is_valid (index)) { 223 | dbg ("Invalid D3D9VirtualFunctionTableIndex : %d", index); 224 | return 0; 225 | } 226 | 227 | char * functionName = D3D9VirtualFunctionTableIndex_to_string (index); 228 | if (!HookEngine_hook (this->vftable [index], hookFunction)) { 229 | dbg ("Cannot hook %s.", functionName); 230 | return 0; 231 | } 232 | 233 | void * originalFunction = (void *) HookEngine_get_original_function (hookFunction); 234 | 235 | if (!originalFunction) { 236 | dbg ("Cannot get original function for 0x%.08X.", hookFunction); 237 | return 0; 238 | } 239 | 240 | dbg ("%s has been hooked. Original function address = 0x%.08X.", functionName, originalFunction); 241 | 242 | return originalFunction; 243 | } 244 | 245 | /* 246 | * Description : Free an allocated D3D9Hook structure. 247 | * D3D9Hook *this : An allocated D3D9Hook to free. 248 | */ 249 | void 250 | D3D9Hook_free ( 251 | D3D9Hook *this 252 | ) { 253 | if (this != NULL) { 254 | free (this); 255 | } 256 | } 257 | 258 | /* 259 | * Description : Check if a D3D9VirtualFunctionTableIndex is valid 260 | * D3D9VirtualFunctionTableIndex index : An allocated D3D9VirtualFunctionTableIndex 261 | * Return : bool true on success, false otherwise 262 | */ 263 | bool 264 | D3D9VirtualFunctionTableIndex_is_valid ( 265 | D3D9VirtualFunctionTableIndex index 266 | ) { 267 | return (index < D3D9INDEX_VFTABLE_SIZE 268 | && index >= 0); 269 | } 270 | 271 | 272 | /* 273 | * Description : Convert a D3D9VirtualFunctionTableIndex to string 274 | * D3D9VirtualFunctionTableIndex index : The D3D9VirtualFunctionTableIndex to convert 275 | * Return : char * the string 276 | */ 277 | char * 278 | D3D9VirtualFunctionTableIndex_to_string ( 279 | D3D9VirtualFunctionTableIndex index 280 | ) { 281 | if (!D3D9VirtualFunctionTableIndex_is_valid (index)) { 282 | return NULL; 283 | } 284 | 285 | return association [index].string; 286 | } 287 | 288 | 289 | /* 290 | * Description : Unit tests checking if a D3D9Hook is coherent 291 | * D3D9Hook *this : The instance to test 292 | * Return : true on success, false on failure 293 | */ 294 | bool 295 | D3D9Hook_test ( 296 | D3D9Hook *this 297 | ) { 298 | if (!this) { 299 | fail ("Instance is NULL"); 300 | return false; 301 | } 302 | 303 | return true; 304 | } 305 | -------------------------------------------------------------------------------- /D3D9Object.h: -------------------------------------------------------------------------------- 1 | // --- Author : Moreau Cyril - Spl3en 2 | #pragma once 3 | 4 | // ---------- Includes ------------ 5 | #include "Utils/Utils.h" 6 | #include "dx/d3d9.h" 7 | #include "dx/d3dx9.h" 8 | #include "BbQueue/BbQueue.h" 9 | #include "Win32Tools/Win32Tools.h" 10 | 11 | // ---------- Defines ------------- 12 | 13 | 14 | // ------ Structure declaration ------- 15 | 16 | 17 | 18 | 19 | // --------- Allocators --------- 20 | 21 | typedef enum { 22 | 23 | D3D9_OBJECT_RECTANGLE, 24 | D3D9_OBJECT_TEXT, 25 | D3D9_OBJECT_SPRITE 26 | 27 | } D3D9ObjectType; 28 | 29 | typedef enum { 30 | 31 | D3D9_OBJECT_SPRITE_NOT_READY, 32 | D3D9_OBJECT_SPRITE_READY, 33 | D3D9_OBJECT_SPRITE_ERROR 34 | 35 | } D3D9ObjectSpriteStatus; 36 | 37 | typedef struct 38 | { 39 | int w, h; 40 | byte r, g, b; 41 | 42 | } D3D9ObjectRect; 43 | 44 | typedef struct 45 | { 46 | ID3DXFont *font; 47 | byte r, g, b; 48 | int opacity; 49 | char *string; 50 | 51 | } D3D9ObjectText; 52 | 53 | typedef struct 54 | { 55 | int opacity; 56 | char * filePath; 57 | ID3DXSprite * sprite; 58 | IDirect3DTexture9 * texture; 59 | D3D9ObjectSpriteStatus status; 60 | int w, h; 61 | 62 | } D3D9ObjectSprite; 63 | 64 | typedef struct 65 | { 66 | int id; 67 | D3D9ObjectType type; 68 | int x, y; 69 | 70 | union { 71 | D3D9ObjectRect rect; 72 | D3D9ObjectText text; 73 | D3D9ObjectSprite sprite; 74 | }; 75 | 76 | HANDLE mutex; 77 | 78 | } D3D9Object; 79 | 80 | 81 | // ----------- Functions ------------ 82 | 83 | /// ===== D3D9ObjectFactory ===== 84 | 85 | /* 86 | * Description : Allocate a new D3D9Object 87 | * D3D9ObjectType type : Type of the object to create 88 | * Return : D3D9Object * an allocated D3D9Object 89 | */ 90 | D3D9Object * 91 | D3D9ObjectFactory_createD3D9Object ( 92 | D3D9ObjectType type 93 | ); 94 | 95 | /* 96 | * Description : Return an allocated D3D9Object from the factory list 97 | * unsigned int id : A D3D9ObjectFactory ID already allocated 98 | * Return : void 99 | */ 100 | D3D9Object * 101 | D3D9ObjectFactory_get ( 102 | unsigned int id 103 | ); 104 | 105 | /* 106 | * Description : Add an allocated D3D9Object to the factory draw list. 107 | Don't add it again if it already exists in the list. 108 | * unsigned int id : A D3D9ObjectFactory ID already allocated 109 | * Return : The D3D9Object hidden, or NULL if not found 110 | */ 111 | D3D9Object * 112 | D3D9ObjectFactory_show ( 113 | unsigned int id 114 | ); 115 | 116 | /* 117 | * Description : Add all allocated D3D9Object to the factory draw list. 118 | Don't add it again if it already exists in the list. 119 | * Return : void 120 | */ 121 | void 122 | D3D9ObjectFactory_show_all ( 123 | void 124 | ); 125 | 126 | /* 127 | * Description : Remove an allocated D3D9Object from the factory draw list, so it isn't displayed anymore 128 | * unsigned int id : A D3D9ObjectFactory ID already allocated 129 | * Return : The D3D9Object hidden, or NULL if not found 130 | */ 131 | D3D9Object * 132 | D3D9ObjectFactory_hide ( 133 | unsigned int id 134 | ); 135 | 136 | 137 | /* 138 | * Description : Remove all allocated D3D9Object from the factory draw list, so they aren't displayed anymore 139 | * Return : void 140 | */ 141 | void 142 | D3D9ObjectFactory_hide_all ( 143 | void 144 | ); 145 | 146 | /* 147 | * Description : Return a pointer to the objects list 148 | * Return : BbQueue * A list of D3D9Objects pointer 149 | */ 150 | BbQueue * 151 | D3D9ObjectFactory_get_objects ( 152 | void 153 | ); 154 | 155 | /* 156 | * Description : Remove all the allocated D3D9Object from the working factory lists 157 | * Return : void 158 | */ 159 | void 160 | D3D9ObjectFactory_delete_all ( 161 | void 162 | ); 163 | 164 | /* 165 | * Description : Remove all the allocated D3D9Object from all the factory lists 166 | * Return : void 167 | */ 168 | void 169 | D3D9ObjectFactory_clean_memory ( 170 | void 171 | ); 172 | 173 | /* 174 | * Description : Remove an allocated D3D9Object from all the factory lists 175 | * unsigned int id : A D3D9ObjectFactory ID already allocated 176 | * Return : void 177 | */ 178 | void 179 | D3D9ObjectFactory_delete ( 180 | unsigned int id 181 | ); 182 | 183 | /* 184 | * Description : Lock the mutex shared with all the d3d9objects 185 | * Return : void 186 | */ 187 | void 188 | D3D9ObjectFactory_lock ( 189 | void 190 | ); 191 | 192 | /* 193 | * Description : Release the mutex shared with all the d3d9objects 194 | * Return : void 195 | */ 196 | void 197 | D3D9ObjectFactory_release ( 198 | void 199 | ); 200 | 201 | /* 202 | * Description : Initialize D3D9ObjectSprite DirectX objects. 203 | * /!\ This function must be called only from the DirectX thread. 204 | * IDirect3DDevice9 * pDevice : An allocated IDirect3DDevice9 205 | * Return : void 206 | */ 207 | void 208 | D3D9ObjectSprite_init_directx ( 209 | IDirect3DDevice9 * pDevice 210 | ); 211 | 212 | /* 213 | * Description : Get the top level object that is hovered. If no object is hovered, return NULL 214 | * HWND hWindow : The window containing the directX context 215 | * Return : A pointer to the hovered object, or NULL 216 | */ 217 | D3D9Object * 218 | D3D9ObjectFactory_get_hovered_object ( 219 | HWND hWindow 220 | ); 221 | 222 | /// ===== D3D9Object ===== 223 | 224 | /* 225 | * Description : Move an allocated D3D9Object on the screen 226 | * D3D9Object *this : An allocated D3D9Object 227 | # int x, int y : The new position on the screen 228 | * Return : void 229 | */ 230 | void 231 | D3D9Object_move ( 232 | D3D9Object *this, 233 | int x, int y 234 | ); 235 | 236 | /* 237 | * Description : Initialize an allocated D3D9ObjectRect object. 238 | * int x, y : {x, y} position of the rectangle 239 | * int w, h : width and height 240 | * byte r, byte g, byte b : color of the rectangle 241 | * Return : void 242 | */ 243 | bool 244 | D3D9ObjectRect_init ( 245 | D3D9Object * this, 246 | int x, int y, 247 | int w, int h, 248 | byte r, byte g, byte b 249 | ); 250 | 251 | /* 252 | * Description : Set attributes of a D3D9ObjectRect 253 | * D3D9ObjectRect *this : An allocated D3D9ObjectRect 254 | * byte r, byte g, byte b : New color of the rectangle 255 | * int w, int h : Width and height of the rectangle 256 | * Return : void 257 | */ 258 | void 259 | D3D9ObjectRect_set ( 260 | D3D9ObjectRect *this, 261 | byte r, byte g, byte b, 262 | int w, int h 263 | ); 264 | 265 | 266 | /* 267 | * Description : Initialize an allocated D3D9ObjectText object. 268 | * D3D9Object * this : An allocated D3D9Object 269 | * IDirect3DDevice9 * pDevice : An allocated IDirect3DDevice9 270 | * int x, y : {x, y} position of the text 271 | * byte r, byte g, byte b : color of the text 272 | * float opacity : opacity of the text, value between 0.0 and 1.0 273 | * char * string : String of the text 274 | * int fontSize : the size of the font 275 | * char * fontFamily : The name of the family font. If NULL, "Arial" is used. 276 | * Return : void 277 | */ 278 | bool 279 | D3D9ObjectText_init ( 280 | D3D9Object * this, 281 | IDirect3DDevice9 * pDevice, 282 | int x, int y, 283 | byte r, byte g, byte b, 284 | float opacity, 285 | char *string, 286 | int fontSize, 287 | char *fontFamily 288 | ); 289 | 290 | /* 291 | * Description : Set new attribute to D3D9ObjectText 292 | * D3D9ObjectText *this : An allocated D3D9ObjectText 293 | * char *string : New string of the text 294 | * byte r, byte g, byte b : New color of the text 295 | * float opacity : opacity of the text 296 | * Return : void 297 | */ 298 | void 299 | D3D9ObjectText_set ( 300 | D3D9ObjectText *this, 301 | char *string, 302 | byte r, byte g, byte b, 303 | float opacity 304 | ); 305 | 306 | /* 307 | * Description : Initialize an allocated D3D9ObjectSprite object. 308 | * D3D9Object * this : An allocated D3D9Object 309 | * IDirect3DDevice9 * pDevice : An allocated IDirect3DDevice9 310 | * char * filePath : Absolute or relative path of the image (.bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, and .tga) 311 | * int x, y : {x, y} position of the text 312 | # float opacity : opacity of the image, value between 0.0 and 1.0 313 | * Return : bool True on success, false otherwise 314 | */ 315 | bool 316 | D3D9ObjectSprite_init ( 317 | D3D9Object * this, 318 | IDirect3DDevice9 * pDevice, 319 | char *filePath, 320 | int x, int y, 321 | float opacity 322 | ); 323 | 324 | /* 325 | * Description : Set new attribute to D3D9ObjectSprite 326 | * D3D9ObjectText *this : An allocated D3D9ObjectSprite 327 | * float opacity : opacity of the sprite 328 | * Return : void 329 | */ 330 | void 331 | D3D9ObjectSprite_set ( 332 | D3D9ObjectSprite *this, 333 | float opacity 334 | ); 335 | 336 | /// ===== Drawing utilities ===== 337 | 338 | 339 | /* 340 | * Description : Draw a rectangle at a given position / color on the screen 341 | * D3D9ObjectRect *rect : An allocated D3D9ObjectRect 342 | * int x, y : {x, y} position of the rectangle 343 | * IDirect3DDevice9 * pDevice : An allocated d3d9 device 344 | */ 345 | void 346 | D3D9ObjectRect_draw ( 347 | D3D9ObjectRect *rect, 348 | int x, int y, 349 | IDirect3DDevice9 * pDevice 350 | ); 351 | 352 | /* 353 | * Description : Draw text at a given position / color on the screen 354 | * D3D9ObjectText *text : An allocated D3D9ObjectText 355 | * int x, y : {x, y} position of the text 356 | * IDirect3DDevice9 * pDevice : An allocated d3d9 device 357 | */ 358 | void 359 | D3D9ObjectText_draw ( 360 | D3D9ObjectText *text, 361 | int x, int y, 362 | IDirect3DDevice9 * pDevice 363 | ); 364 | 365 | /* 366 | * Description : Draw a sprite at a given position on the screen 367 | * D3D9ObjectSprite *spriteObject : An allocated D3D9ObjectSprite. 368 | * int x, y : {x, y} position of the text 369 | * Return : void 370 | */ 371 | void 372 | D3D9ObjectSprite_draw ( 373 | D3D9ObjectSprite *spriteObject, 374 | int x, int y 375 | ); 376 | 377 | 378 | // --------- Destructors ---------- 379 | 380 | 381 | /* 382 | * Description : Free an allocated D3D9Object 383 | * D3D9Object *this : An allocated D3D9Object 384 | * Return : void 385 | */ 386 | void 387 | D3D9Object_free ( 388 | D3D9Object *this 389 | ); 390 | 391 | -------------------------------------------------------------------------------- /D3D9Object.c: -------------------------------------------------------------------------------- 1 | #include "D3D9Object.h" 2 | 3 | // ---------- Debugging ------------- 4 | #define __DEBUG_OBJECT__ "D3D9Object" 5 | #include "dbg/dbg.h" 6 | 7 | // Factory declaration and static initialization 8 | struct D3D9ObjectFactory { 9 | BbQueue drawObjects; 10 | BbQueue allObjects; 11 | BbQueue spriteToInstanciate; 12 | HANDLE mutex; 13 | int id; 14 | bool initialized; 15 | } d3d9ObjectFactory = { 16 | .drawObjects = bb_queue_local_decl (), 17 | .allObjects = bb_queue_local_decl (), 18 | .spriteToInstanciate = bb_queue_local_decl (), 19 | .mutex = NULL, 20 | .id = 0, 21 | .initialized = false 22 | }; 23 | 24 | // Private headers 25 | /* 26 | * Description : Add a D3D9Object into the collection of the factory 27 | * D3D9Object *this : An allocated D3D9Object 28 | * Return : void 29 | */ 30 | static void D3D9ObjectFactory_add (D3D9Object *this); 31 | 32 | 33 | /// ===== D3D9ObjectFactory ===== 34 | /* 35 | * Description : Allocate a new D3D9Object 36 | * D3D9ObjectType type : Type of the object to create 37 | * Return : D3D9Object * an allocated D3D9Object 38 | */ 39 | D3D9Object * 40 | D3D9ObjectFactory_createD3D9Object ( 41 | D3D9ObjectType type 42 | ) { 43 | D3D9Object *this = NULL; 44 | 45 | // Check if the factory has been initialized 46 | if (!d3d9ObjectFactory.initialized) { 47 | d3d9ObjectFactory.mutex = CreateMutex (NULL, false, NULL); 48 | d3d9ObjectFactory.initialized = true; 49 | } 50 | 51 | // Allocate a new instance of D3D9Object 52 | if ((this = calloc (1, sizeof(D3D9Object))) == NULL) 53 | return NULL; 54 | 55 | this->type = type; 56 | this->id = d3d9ObjectFactory.id++; 57 | this->mutex = d3d9ObjectFactory.mutex; 58 | 59 | return this; 60 | } 61 | 62 | /* 63 | * Description : Add a D3D9Object into the collection of the factory 64 | * D3D9Object *this : An allocated D3D9Object 65 | * Return : void 66 | */ 67 | static void 68 | D3D9ObjectFactory_add ( 69 | D3D9Object *this 70 | ) { 71 | if (!bb_queue_exists (&d3d9ObjectFactory.drawObjects, this)) 72 | bb_queue_add (&d3d9ObjectFactory.drawObjects, this); 73 | 74 | if (!bb_queue_exists (&d3d9ObjectFactory.allObjects, this)) 75 | bb_queue_add (&d3d9ObjectFactory.allObjects, this); 76 | } 77 | 78 | /* 79 | * Description : Return an allocated D3D9Object from the global factory list 80 | * unsigned int id : A D3D9ObjectFactory ID already allocated 81 | * Return : void 82 | */ 83 | D3D9Object * 84 | D3D9ObjectFactory_get ( 85 | unsigned int id 86 | ) { 87 | foreach_bbqueue_item (&d3d9ObjectFactory.allObjects, D3D9Object *object) 88 | { 89 | if (object->id == id) { 90 | return object; 91 | } 92 | } 93 | 94 | warn ("Object ID=%d not found in global list.", id); 95 | 96 | return NULL; 97 | } 98 | 99 | /* 100 | * Description : Return an allocated D3D9Object from the draw factory list 101 | * unsigned int id : A D3D9ObjectFactory ID already allocated 102 | * Return : void 103 | */ 104 | D3D9Object * 105 | D3D9ObjectFactory_get_draw ( 106 | unsigned int id 107 | ) { 108 | foreach_bbqueue_item (&d3d9ObjectFactory.drawObjects, D3D9Object *object) 109 | { 110 | if (object->id == id) { 111 | return object; 112 | } 113 | } 114 | 115 | warn ("Object ID=%d not found in draw list.", id); 116 | 117 | return NULL; 118 | } 119 | 120 | /* 121 | * Description : Add an allocated D3D9Object to the factory draw list. 122 | * unsigned int id : A D3D9ObjectFactory ID already allocated 123 | * Return : The D3D9Object hidden, or NULL if not found 124 | */ 125 | D3D9Object * 126 | D3D9ObjectFactory_show ( 127 | unsigned int id 128 | ) { 129 | D3D9ObjectFactory_lock (); 130 | 131 | D3D9Object *object; 132 | 133 | if (!(object = D3D9ObjectFactory_get (id))) { 134 | warn ("Cannot show object ID=%d.", id); 135 | return NULL; 136 | } 137 | 138 | // Put the object shown in the last position of the allObject list, so 139 | // it keeps a coherent order when hide_all / show_all is called. 140 | bb_queue_put_last (&d3d9ObjectFactory.allObjects, object); 141 | 142 | // If already exists, put it to the last position 143 | if (bb_queue_exists (&d3d9ObjectFactory.drawObjects, object)) { 144 | bb_queue_put_last (&d3d9ObjectFactory.drawObjects, object); 145 | } 146 | else { 147 | // Add the object in the draw list 148 | bb_queue_add (&d3d9ObjectFactory.drawObjects, object); 149 | } 150 | 151 | D3D9ObjectFactory_release (); 152 | 153 | return object; 154 | } 155 | 156 | /* 157 | * Description : Add all allocated D3D9Object to the factory draw list. 158 | Don't add it again if it already exists in the list. 159 | * Return : void 160 | */ 161 | void 162 | D3D9ObjectFactory_show_all ( 163 | void 164 | ) { 165 | D3D9ObjectFactory_lock (); 166 | 167 | foreach_bbqueue_item (&d3d9ObjectFactory.allObjects, D3D9Object *object) 168 | { 169 | if (!bb_queue_exists (&d3d9ObjectFactory.drawObjects, object)) 170 | bb_queue_add (&d3d9ObjectFactory.drawObjects, object); 171 | } 172 | 173 | D3D9ObjectFactory_release (); 174 | } 175 | 176 | /* 177 | * Description : Remove an allocated D3D9Object from the factory draw list, so it isn't displayed anymore 178 | * unsigned int id : A D3D9ObjectFactory ID already allocated 179 | * Return : The D3D9Object hidden, or NULL if not found 180 | */ 181 | D3D9Object * 182 | D3D9ObjectFactory_hide ( 183 | unsigned int id 184 | ) { 185 | D3D9ObjectFactory_lock (); 186 | 187 | D3D9Object *object; 188 | 189 | if (!(object = D3D9ObjectFactory_get_draw (id))) { 190 | warn ("Cannot hide object ID=%d.", id); 191 | return NULL; 192 | } 193 | 194 | // Remove from the draw list 195 | if (!(bb_queue_exists (&d3d9ObjectFactory.drawObjects, object))) { 196 | warn ("Object ID=%d doesn't exist in the draw list. Abort hide.", id); 197 | return NULL; 198 | } 199 | 200 | bb_queue_remv (&d3d9ObjectFactory.drawObjects, object); 201 | 202 | D3D9ObjectFactory_release (); 203 | 204 | return object; 205 | } 206 | 207 | 208 | /* 209 | * Description : Remove all allocated D3D9Object from the factory draw list, so they aren't displayed anymore 210 | * Return : void 211 | */ 212 | void 213 | D3D9ObjectFactory_hide_all ( 214 | void 215 | ) { 216 | D3D9ObjectFactory_lock (); 217 | 218 | // Remove all D3D9Objects from the drawObjects list 219 | while (bb_queue_get_length (&d3d9ObjectFactory.drawObjects)) { 220 | bb_queue_pop (&d3d9ObjectFactory.drawObjects); 221 | } 222 | 223 | D3D9ObjectFactory_release (); 224 | } 225 | 226 | /* 227 | * Description : Remove an allocated D3D9Object from all the factory lists 228 | * unsigned int id : A D3D9ObjectFactory ID already allocated 229 | * Return : void 230 | */ 231 | void 232 | D3D9ObjectFactory_delete ( 233 | unsigned int id 234 | ) { 235 | D3D9ObjectFactory_lock (); 236 | 237 | D3D9Object * object; 238 | 239 | if (!(object = D3D9ObjectFactory_get (id))) { 240 | warn ("Cannot find the object to delete."); 241 | return; 242 | } 243 | 244 | if (bb_queue_exists (&d3d9ObjectFactory.drawObjects, object)) { 245 | bb_queue_remv (&d3d9ObjectFactory.drawObjects, object); 246 | } 247 | 248 | bb_queue_remv (&d3d9ObjectFactory.allObjects, object); 249 | 250 | D3D9Object_free (object); 251 | 252 | D3D9ObjectFactory_release (); 253 | } 254 | 255 | 256 | /* 257 | * Description : Remove all the allocated D3D9Object from the working factory lists 258 | * Return : void 259 | */ 260 | void 261 | D3D9ObjectFactory_delete_all ( 262 | void 263 | ) { 264 | D3D9ObjectFactory_lock (); 265 | 266 | // Remove all D3D9Objects from the drawObjects list 267 | while (bb_queue_get_length (&d3d9ObjectFactory.drawObjects)) { 268 | bb_queue_pop (&d3d9ObjectFactory.drawObjects); 269 | } 270 | 271 | // Remove all D3D9Objects from the global list 272 | while (bb_queue_get_length (&d3d9ObjectFactory.allObjects)) { 273 | D3D9Object *object = bb_queue_pop (&d3d9ObjectFactory.allObjects); 274 | 275 | // Free the memory 276 | D3D9Object_free (object); 277 | } 278 | 279 | D3D9ObjectFactory_release (); 280 | } 281 | 282 | /* 283 | * Description : Return a pointer to the objects list 284 | * Return : BbQueue * A list of D3D9Objects pointer 285 | */ 286 | BbQueue * 287 | D3D9ObjectFactory_get_objects ( 288 | void 289 | ) { 290 | return &d3d9ObjectFactory.drawObjects; 291 | } 292 | 293 | 294 | /* 295 | * Description : Lock the mutex shared with all the d3d9objects 296 | * Return : void 297 | */ 298 | void 299 | D3D9ObjectFactory_lock ( 300 | void 301 | ) { 302 | WaitForSingleObject (d3d9ObjectFactory.mutex, INFINITE); 303 | } 304 | 305 | 306 | /* 307 | * Description : Release the mutex shared with all the d3d9objects 308 | * Return : void 309 | */ 310 | void 311 | D3D9ObjectFactory_release ( 312 | void 313 | ) { 314 | ReleaseMutex (d3d9ObjectFactory.mutex); 315 | } 316 | 317 | 318 | /* 319 | * Description : Get the top level object that is hovered. If no object is hovered, return NULL 320 | * HWND hWindow : The window containing the directX context 321 | * Return : A pointer to the hovered object, or NULL 322 | */ 323 | D3D9Object * 324 | D3D9ObjectFactory_get_hovered_object ( 325 | HWND hWindow 326 | ) { 327 | int mouseX, mouseY; 328 | get_mouse_pos_in_window (hWindow, &mouseX, &mouseY); 329 | 330 | foreach_bbqueue_item_reversed (&d3d9ObjectFactory.drawObjects, D3D9Object *object) 331 | { 332 | switch (object->type) 333 | { 334 | case D3D9_OBJECT_RECTANGLE: { 335 | D3D9ObjectRect *rect = &object->rect; 336 | if (in_bound (mouseX, mouseY, object->x, object->y, object->x + rect->w, object->y + rect->h)) { 337 | return object; 338 | } 339 | } break; 340 | 341 | case D3D9_OBJECT_SPRITE: { 342 | D3D9ObjectSprite *sprite = &object->sprite; 343 | if (in_bound (mouseX, mouseY, object->x, object->y, object->x + sprite->w, object->y + sprite->h)) { 344 | return object; 345 | } 346 | } break; 347 | 348 | default : 349 | continue; 350 | break; 351 | } 352 | } 353 | 354 | return NULL; 355 | } 356 | 357 | 358 | /// ===== D3D9Object ===== 359 | /* 360 | * Description : Move an allocated D3D9Object on the screen 361 | * D3D9Object *this : An allocated D3D9Object 362 | # int x, int y : The new position on the screen 363 | * Return : void 364 | */ 365 | void 366 | D3D9Object_move ( 367 | D3D9Object *this, 368 | int x, int y 369 | ) { 370 | this->x = x; 371 | this->y = y; 372 | } 373 | 374 | /* 375 | * Description : Initialize an allocated D3D9ObjectRect object. 376 | * int x, y : {x, y} position of the rectangle 377 | * int w, h : width and height of the rectangle 378 | * byte r, byte g, byte b : color of the rectangle 379 | * Return : void 380 | */ 381 | bool 382 | D3D9ObjectRect_init ( 383 | D3D9Object * this, 384 | int x, int y, 385 | int w, int h, 386 | byte r, byte g, byte b 387 | ) { 388 | D3D9ObjectFactory_lock (); 389 | 390 | D3D9ObjectRect * rect = &this->rect; 391 | 392 | // Fill the structure 393 | this->x = x; 394 | this->y = y; 395 | rect->w = w; 396 | rect->h = h; 397 | rect->r = r; 398 | rect->g = g; 399 | rect->b = b; 400 | 401 | dbg ("Rectangle has been created.", this->id, x, y, w, h, r, g, b); 402 | 403 | D3D9ObjectFactory_add (this); 404 | 405 | D3D9ObjectFactory_release (); 406 | return true; 407 | } 408 | 409 | /* 410 | * Description : Set attributes of a D3D9ObjectRect 411 | * D3D9ObjectRect *this : An allocated D3D9ObjectRect 412 | * byte r, byte g, byte b : New color of the rectangle 413 | * int w, int h : Width and height of the rectangle 414 | * Return : void 415 | */ 416 | void 417 | D3D9ObjectRect_set ( 418 | D3D9ObjectRect *this, 419 | byte r, byte g, byte b, 420 | int w, int h 421 | ) { 422 | this->r = r; 423 | this->g = g; 424 | this->b = b; 425 | this->w = w; 426 | this->h = h; 427 | } 428 | 429 | /* 430 | * Description : Initialize an allocated D3D9ObjectText object. 431 | * D3D9Object * this : An allocated D3D9Object 432 | * IDirect3DDevice9 * pDevice : An allocated IDirect3DDevice9 433 | * int x, y : {x, y} position of the text 434 | * byte r, byte g, byte b : color of the text 435 | * float opacity : opacity of the text, value between 0.0 and 1.0 436 | * char * string : String of the text 437 | * int fontSize : the size of the font 438 | * char * fontFamily : The name of the family font. If NULL, "Arial" is used. 439 | * Return : void 440 | */ 441 | bool 442 | D3D9ObjectText_init ( 443 | D3D9Object * this, 444 | IDirect3DDevice9 * pDevice, 445 | int x, int y, 446 | byte r, byte g, byte b, 447 | float opacity, 448 | char *string, 449 | int fontSize, 450 | char *fontFamily 451 | ) { 452 | D3D9ObjectFactory_lock (); 453 | 454 | D3D9ObjectText * text = &this->text; 455 | 456 | // Default parameters 457 | if (fontFamily == NULL) { 458 | fontFamily = "Arial"; 459 | } 460 | 461 | // Allocate the font 462 | if ((D3DXCreateFont ( 463 | pDevice, 464 | fontSize, 465 | 0, 466 | FW_BOLD, 467 | 1, 468 | 0, 469 | DEFAULT_CHARSET, 470 | OUT_DEFAULT_PRECIS, 471 | DEFAULT_QUALITY, 472 | DEFAULT_PITCH | FF_DONTCARE, 473 | fontFamily, 474 | &text->font 475 | )) != S_OK) { 476 | warn ("Cannot create the font ID=%d.", this->id); 477 | D3D9ObjectFactory_release (); 478 | return false; 479 | } 480 | 481 | // Fill the structure 482 | this->x = x; 483 | this->y = y; 484 | text->r = r; 485 | text->g = g; 486 | text->b = b; 487 | text->string = strdup (string); 488 | text->opacity = (opacity * 255 > 255) ? 255 : opacity * 255; 489 | 490 | dbg ("Text | x=%d | y=%d | rgb=%02X%02X%02X | opacity=%d> has been created.", this->id, string, x, y, r, g, b, text->opacity); 491 | 492 | D3D9ObjectFactory_add (this); 493 | 494 | D3D9ObjectFactory_release (); 495 | return true; 496 | } 497 | 498 | /* 499 | * Description : Set new attribute to D3D9ObjectText 500 | * D3D9ObjectText *this : An allocated D3D9ObjectText 501 | * char *string : New string of the text 502 | * byte r, byte g, byte b : New color of the text 503 | * float opacity : opacity of the text 504 | * Return : void 505 | */ 506 | void 507 | D3D9ObjectText_set ( 508 | D3D9ObjectText *this, 509 | char *string, 510 | byte r, byte g, byte b, 511 | float opacity 512 | ) { 513 | this->string = strdup (string); 514 | this->r = r; 515 | this->g = g; 516 | this->b = b; 517 | this->opacity = (opacity * 255 > 255) ? 255 : opacity * 255; 518 | } 519 | 520 | /* 521 | * Description : Initialize an allocated D3D9ObjectSprite object. 522 | * D3D9Object * this : An allocated D3D9Object 523 | * IDirect3DDevice9 * pDevice : An allocated IDirect3DDevice9 524 | * char * filePath : Absolute or relative path of the image (.bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, and .tga) 525 | * int x, y : {x, y} position of the sprite 526 | # float opacity : opacity of the image, value between 0.0 and 1.0 527 | * Return : bool True on success, false otherwise 528 | */ 529 | bool 530 | D3D9ObjectSprite_init ( 531 | D3D9Object * this, 532 | IDirect3DDevice9 * pDevice, 533 | char *filePath, 534 | int x, int y, 535 | float opacity 536 | ) { 537 | D3D9ObjectFactory_lock (); 538 | 539 | D3D9ObjectSprite * sprite = &this->sprite; 540 | 541 | // Fill the structure 542 | this->x = x; 543 | this->y = y; 544 | sprite->opacity = (opacity * 255 > 255) ? 255 : opacity * 255; 545 | sprite->filePath = strdup (filePath); 546 | 547 | dbg ("Sprite | x=%d | y=%d | opacity=%.2f> has been created.", this->id, filePath, x, y, opacity); 548 | 549 | // Only DirectX thread can call safely D3DXCreateTextureFromFile and D3DXCreateSprite. 550 | bb_queue_add (&d3d9ObjectFactory.spriteToInstanciate, this); 551 | 552 | D3D9ObjectFactory_release (); 553 | 554 | while (sprite->status == D3D9_OBJECT_SPRITE_NOT_READY) { 555 | // Active waiting until the DirectX thread initialize the directx objects 556 | Sleep (1); 557 | } 558 | 559 | if (sprite->status == D3D9_OBJECT_SPRITE_ERROR) { 560 | return false; 561 | } 562 | 563 | return true; 564 | } 565 | 566 | /* 567 | * Description : Set new attribute to D3D9ObjectSprite 568 | * D3D9ObjectText *this : An allocated D3D9ObjectSprite 569 | * float opacity : opacity of the sprite 570 | * Return : void 571 | */ 572 | void 573 | D3D9ObjectSprite_set ( 574 | D3D9ObjectSprite *this, 575 | float opacity 576 | ) { 577 | this->opacity = (opacity * 255 > 255) ? 255 : opacity * 255; 578 | } 579 | 580 | /* 581 | * Description : Initialize D3D9ObjectSprite DirectX objects. 582 | * /!\ This function must be called only from the DirectX thread. 583 | * IDirect3DDevice9 * pDevice : An allocated IDirect3DDevice9 584 | * Return : void 585 | */ 586 | void 587 | D3D9ObjectSprite_init_directx ( 588 | IDirect3DDevice9 * pDevice 589 | ) { 590 | while (bb_queue_get_length (&d3d9ObjectFactory.spriteToInstanciate)) 591 | { 592 | D3D9Object * this = bb_queue_pop (&d3d9ObjectFactory.spriteToInstanciate); 593 | D3D9ObjectSprite * sprite = &this->sprite; 594 | 595 | // Create the texture 596 | if ((D3DXCreateTextureFromFileEx ( 597 | pDevice, 598 | sprite->filePath, 599 | D3DX_DEFAULT, 600 | D3DX_DEFAULT, 601 | D3DX_DEFAULT, 602 | 0, 603 | D3DFMT_UNKNOWN, 604 | D3DPOOL_MANAGED, 605 | D3DX_DEFAULT, 606 | D3DX_DEFAULT, 607 | 0, 608 | NULL, 609 | NULL, 610 | &sprite->texture)) != D3D_OK) { 611 | warn ("Cannot create the texture <%s>.", sprite->filePath); 612 | sprite->status = D3D9_OBJECT_SPRITE_ERROR; 613 | continue; 614 | } 615 | 616 | D3DSURFACE_DESC surfaceDesc; 617 | sprite->texture->lpVtbl->GetLevelDesc (sprite->texture, 0, &surfaceDesc); 618 | sprite->w = surfaceDesc.Width; 619 | sprite->h = surfaceDesc.Height; 620 | 621 | // Create the sprite 622 | if ((D3DXCreateSprite (pDevice, &sprite->sprite)) != D3D_OK) { 623 | warn ("Cannot create the sprite."); 624 | sprite->status = D3D9_OBJECT_SPRITE_ERROR; 625 | continue; 626 | } 627 | 628 | D3D9ObjectFactory_add (this); 629 | 630 | sprite->status = D3D9_OBJECT_SPRITE_READY; 631 | } 632 | } 633 | 634 | 635 | /// ===== Drawing utilities ===== 636 | 637 | /* 638 | * Description : Draw a rectangle at a given position / color on the screen 639 | * D3D9ObjectRect *this : An allocated D3D9ObjectRect 640 | * int x, y : {x, y} position of the rectangle 641 | * IDirect3DDevice9 * pDevice : An allocated d3d9 device 642 | */ 643 | void 644 | D3D9ObjectRect_draw ( 645 | D3D9ObjectRect *this, 646 | int x, int y, 647 | IDirect3DDevice9 * pDevice 648 | ) { 649 | D3DRECT rectPosition = {x, y, x + this->w, y + this->h}; 650 | D3DCOLOR color = D3DCOLOR_RGBA (this->r, this->g, this->b, 255); 651 | 652 | pDevice->lpVtbl->Clear (pDevice, 1, &rectPosition, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, color, 0, 0); 653 | } 654 | 655 | /* 656 | * Description : Draw text at a given position / color on the screen 657 | * D3D9ObjectText *text : An allocated D3D9ObjectText 658 | * int x, y : {x, y} position of the text 659 | * IDirect3DDevice9 * pDevice : An allocated d3d9 device 660 | */ 661 | void 662 | D3D9ObjectText_draw ( 663 | D3D9ObjectText *this, 664 | int x, int y, 665 | IDirect3DDevice9 * pDevice 666 | ) { 667 | RECT rect; 668 | ID3DXFont *font = this->font; 669 | D3DCOLOR color = D3DCOLOR_RGBA (this->r, this->g, this->b, this->opacity); 670 | 671 | SetRect (&rect, x, y, x, y); 672 | font->lpVtbl->DrawText (font, NULL, this->string, -1, &rect, DT_NOCLIP | DT_LEFT, color); 673 | } 674 | 675 | /* 676 | * Description : Draw a sprite at a given position on the screen 677 | * D3D9ObjectSprite *spriteObject : An allocated D3D9ObjectSprite. 678 | * int x, y : {x, y} position of the sprite 679 | * Return : void 680 | */ 681 | void 682 | D3D9ObjectSprite_draw ( 683 | D3D9ObjectSprite *this, 684 | int x, int y 685 | ) { 686 | ID3DXSprite * sprite = this->sprite; 687 | IDirect3DTexture9 * texture = this->texture; 688 | D3DXVECTOR3 position3D = {x, y, 0.0}; 689 | D3DCOLOR color = D3DCOLOR_ARGB (this->opacity, 255, 255, 255); 690 | 691 | sprite->lpVtbl->Begin (sprite, D3DXSPRITE_ALPHABLEND); 692 | sprite->lpVtbl->Draw (sprite, texture, NULL, NULL, &position3D, color); 693 | sprite->lpVtbl->End (sprite); 694 | } 695 | 696 | /* 697 | * Description : Free an allocated D3D9Object 698 | * /!\ The factory MUST BE LOCKED when calling this function. 699 | * D3D9Object *this : An allocated D3D9Object 700 | * Return : void 701 | */ 702 | void 703 | D3D9Object_free ( 704 | D3D9Object *this 705 | ) { 706 | switch (this->type) 707 | { 708 | case D3D9_OBJECT_RECTANGLE: { 709 | // Nothing to do 710 | } break; 711 | 712 | case D3D9_OBJECT_TEXT: { 713 | ID3DXFont *font = this->text.font; 714 | if (font) 715 | font->lpVtbl->Release (font); 716 | } break; 717 | 718 | case D3D9_OBJECT_SPRITE: { 719 | ID3DXSprite * sprite = this->sprite.sprite; 720 | IDirect3DTexture9 * texture = this->sprite.texture; 721 | if (texture) 722 | texture->lpVtbl->Release (texture); 723 | if (sprite) 724 | sprite->lpVtbl->Release (sprite); 725 | free (this->sprite.filePath); 726 | } break; 727 | 728 | default : warn ("Cannot free completely an unknown type."); break; 729 | } 730 | 731 | free (this); 732 | } 733 | --------------------------------------------------------------------------------