2 * Copyright (C) 2011 David Hoyt <dhoyt@hoytsoft.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 #include <glib/gprintf.h>
25 #include "directx9/dx9.h"
26 #include "directx10/dx10.h"
27 #include "directx11/dx11.h"
32 init_supported_apis (void)
34 /* Gather information we'll need about each version of DirectX. */
35 /* Insert in reverse order of desired priority due to the g_list_prepend() call in directx_determine_best_available_api(). */
36 INITIALIZE_SUPPORTED_DIRECTX_API (DIRECTX_9);
37 /* TODO: Add DirectX 10 support. */
38 /*INITIALIZE_SUPPORTED_DIRECTX_API(DIRECTX_10); */
39 /* TODO: Add DirectX 11 support. */
40 /*INITIALIZE_SUPPORTED_DIRECTX_API(DIRECTX_11); */
45 /* Function declarations */
46 static DirectXAPI *directx_determine_best_available_api (void);
49 #define DIRECTX_LOCK g_static_rec_mutex_lock (&dx_lock);
50 #define DIRECTX_UNLOCK g_static_rec_mutex_unlock (&dx_lock);
52 typedef struct _DirectXInfo DirectXInfo;
58 DirectXInitParams *init_params;
60 GList *supported_api_list;
61 gint32 supported_api_count;
65 static DirectXInfo dx;
66 static GStaticRecMutex dx_lock = G_STATIC_REC_MUTEX_INIT;
69 directx_initialize (DirectXInitParams * init_params)
71 DIRECTX_LOCK if (dx.initialized)
74 dx.init_params = NULL;
75 dx.init_params = init_params;
77 init_supported_apis ();
79 dx.best_api = directx_determine_best_available_api ();
80 dx.supported = (dx.best_api != NULL
81 && !DIRECTX_VERSION_IS_UNKNOWN (dx.best_api->version));
82 dx.initialized = TRUE;
85 DIRECTX_UNLOCK return TRUE;
89 directx_api_initialize (DirectXAPI * api)
94 DIRECTX_LOCK if (!directx_is_initialized ())
101 api->initialize (api);
103 /* Component initialization */
104 DIRECTX_COMPONENT_INIT (DIRECTX_D3D (api));
105 DIRECTX_COMPONENT_INIT (DIRECTX_DINPUT (api));
106 DIRECTX_COMPONENT_INIT (DIRECTX_DSOUND (api));
107 DIRECTX_COMPONENT_INIT (DIRECTX_DWRITE (api));
108 DIRECTX_COMPONENT_INIT (DIRECTX_D2D (api));
109 DIRECTX_COMPONENT_INIT (DIRECTX_DCOMPUTE (api));
112 api->initialized = TRUE;
115 DIRECTX_UNLOCK return TRUE;
117 DIRECTX_UNLOCK return FALSE;
121 directx_initialize_best_available_api (void)
123 return directx_api_initialize (directx_get_best_available_api ());
127 directx_is_initialized (void)
129 gboolean initialized = FALSE;
131 DIRECTX_LOCK initialized = dx.initialized;
132 DIRECTX_UNLOCK return initialized;
136 directx_api_is_initialized (const DirectXAPI * api)
141 gboolean initialized;
143 DIRECTX_LOCK initialized = api->initialized;
144 DIRECTX_UNLOCK return initialized;
149 directx_best_available_api_is_initialized (void)
151 return directx_api_is_initialized (directx_get_best_available_api ());
155 directx_is_supported (void)
161 directx_get_supported_apis (void)
163 return dx.supported_api_list;
167 directx_get_supported_api_count (void)
169 return dx.supported_api_count;
173 directx_get_best_available_api (void)
179 directx_log_debug (const gchar * file, const gchar * function, gint line,
180 const gchar * format, ...)
182 if (!dx.init_params || !dx.init_params->log_debug)
186 va_start (args, format);
187 dx.init_params->log_debug (file, function, line, format, args);
193 directx_log_warning (const gchar * file, const gchar * function, gint line,
194 const gchar * format, ...)
196 if (!dx.init_params || !dx.init_params->log_warning)
200 va_start (args, format);
201 dx.init_params->log_warning (file, function, line, format, args);
207 directx_log_error (const gchar * file, const gchar * function, gint line,
208 const gchar * format, ...)
210 if (!dx.init_params || !dx.init_params->log_error)
214 va_start (args, format);
215 dx.init_params->log_error (file, function, line, format, args);
220 /* This should only be called through use of the DIRECTX_API() macro. It should never be called directly. */
222 directx_add_supported_api (DirectXAPI * api)
229 /* Add to our GList containing all of our supported APIs. */
230 /* GLists are doubly-linked lists and calling prepend() prevents it from having to traverse the entire list just to add one item. */
231 dx.supported_api_list = g_list_prepend (dx.supported_api_list, api);
232 dx.supported_api_count++;
236 DIRECTX_UNLOCK return TRUE;
240 directx_determine_best_available_api (void)
242 if (!g_module_supported ())
248 DirectXAPI *dxlib = NULL;
251 /* Search supported APIs (DirectX9, DirectX10, etc.) looking for the first one that works. */
253 ("Searching supported DirectX APIs for the best (most recent) one available");
254 for (item = g_list_first (dx.supported_api_list); item; item = item->next) {
255 if ((dxlib = (DirectXAPI *) item->data) == NULL)
258 DIRECTX_DEBUG ("Determining support for %s", dxlib->description);
259 DIRECTX_DEBUG ("Searching for module \"%s\" with the symbol \"%s\"",
260 dxlib->module_test, dxlib->symbol_test);
262 /* Can we locate and open a Direct3D library (e.g. d3d9.dll or d3d10.dll)? */
264 g_module_open (dxlib->module_test,
265 G_MODULE_BIND_LAZY)) != NULL) {
266 /* Look for a symbol/function (e.g. "Direct3DCreate9") in the module and if it exists, we found one! */
268 if (g_module_symbol (lib, dxlib->symbol_test, &symbol)) {
269 g_module_close (lib);
270 DIRECTX_DEBUG ("Selected %s", dxlib->description);
273 /* Ensure we don't have a mem leak. */
274 g_module_close (lib);
280 DIRECTX_UNLOCK return dxlib;