Index: d3d_disp.cpp
===================================================================
--- d3d_disp.cpp	(revision 13282)
+++ d3d_disp.cpp	(working copy)
@@ -1,6 +1,6 @@
 /*         ______   ___    ___
- *        /\  _  \ /\_ \  /\_ \ 
- *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___ 
+ *        /\  _  \ /\_ \  /\_ \
+ *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
  *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
  *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
  *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
@@ -44,11 +44,24 @@
 
 extern "C" {
 
+static const char* _al_d3d_module_name = "d3d9.dll";
+
 ALLEGRO_DEBUG_CHANNEL("d3d")
 
-
 static ALLEGRO_DISPLAY_INTERFACE *vt = 0;
 
+static HMODULE _al_d3d_module = 0;
+
+typedef LPDIRECT3D9 (WINAPI *DIRECT3DCREATE9PROC)(UINT);
+
+static DIRECT3DCREATE9PROC _al_d3d_create = (DIRECT3DCREATE9PROC)NULL;
+
+#ifdef ALLEGRO_CFG_D3D9EX
+typedef HRESULT (WINAPI *DIRECT3DCREATE9EXPROC)(UINT, LPDIRECT3D9EX*);
+
+static DIRECT3DCREATE9EXPROC _al_d3d_create_ex = (DIRECT3DCREATE9EXPROC)NULL;
+#endif
+
 static LPDIRECT3D9 _al_d3d = 0;
 
 static D3DPRESENT_PARAMETERS d3d_pp;
@@ -59,13 +72,6 @@
 static HWND fullscreen_focus_window;
 static bool ffw_set = false;
 
-#ifdef ALLEGRO_CFG_D3D9EX
-// Stuff dynamically loaded from dlls
-typedef HRESULT (WINAPI *_dyn_create_type)(UINT, IDirect3D9Ex **);
-static _dyn_create_type _dyn_create;
-#endif
-
-
 static bool d3d_can_wait_for_vsync;
 
 static bool render_to_texture_supported = true;
@@ -183,8 +189,8 @@
    { 8, 8, 8, 0, 16, 8, 0,  0, 0, 0, 0, 0, 0, 0, 32, 24, 8, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 11, D3DFMT_D24S8 },
    { 8, 8, 8, 0, 16, 8, 0,  0, 0, 0, 0, 0, 0, 0, 32, 24, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 11, D3DFMT_D24X8 },
    { 8, 8, 8, 0, 16, 8, 0,  0, 0, 0, 0, 0, 0, 0, 32, 24, 4, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 11, D3DFMT_D24X4S4 },
-   
-   
+
+
    { 5, 6, 5, 0, 11, 5, 0,  0, 0, 0, 0, 0, 0, 0, 16,  0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 0 },
    { 5, 6, 5, 0, 11, 5, 0,  0, 0, 0, 0, 0, 0, 0, 16, 15, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, D3DFMT_D15S1 },
    { 5, 6, 5, 0, 11, 5, 0,  0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, D3DFMT_D16 },
@@ -426,7 +432,7 @@
       ALLEGRO_ERROR("SetSamplerState failed\n");
    if (disp->device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP) != D3D_OK)
       ALLEGRO_ERROR("SetSamplerState failed\n");
-      
+
    /* Set up filtering */
    if (disp->device->SetSamplerState(0, D3DSAMP_MINFILTER, d3d_min_filter) != D3D_OK)
       ALLEGRO_ERROR("SetSamplerState failed\n");
@@ -839,31 +845,48 @@
    D3DDISPLAYMODE d3d_dm;
    OSVERSIONINFO info;
 
+   _al_d3d_module = LoadLibraryA(_al_d3d_module_name);
+   if (_al_d3d_module == NULL) {
+      ALLEGRO_ERROR("Failed to open '%s' library\n", _al_d3d_module_name);
+      return false;
+   }
+
    info.dwOSVersionInfoSize = sizeof(info);
    GetVersionEx(&info);
    is_vista = info.dwMajorVersion >= 6;
 
 #ifdef ALLEGRO_CFG_D3D9EX
    if (is_vista) {
-      _dyn_create = (_dyn_create_type)GetProcAddress(GetModuleHandle(TEXT("d3d9.dll")), "Direct3DCreate9Ex");
-      if (_dyn_create != NULL) {
-         if (_dyn_create(D3D_SDK_VERSION, (LPDIRECT3D9EX *)&_al_d3d) != D3D_OK) {
+      _al_d3d_create_ex = (DIRECT3DCREATE9EXPROC)GetProcAddress(_al_d3d_module, "Direct3DCreate9Ex");
+      if (_al_d3d_create_ex != NULL) {
+         if (_al_d3d_create_ex(D3D_SDK_VERSION, (LPDIRECT3D9EX *)&_al_d3d) != D3D_OK) {
             ALLEGRO_ERROR("Direct3DCreate9Ex failed\n");
+            FreeLibrary(_al_d3d_module);
             return false;
          }
       }
       else {
-         ALLEGRO_INFO("Direct3DCreate9Ex not in d3d9.dll\n");
+         ALLEGRO_INFO("Direct3DCreate9Ex not in %s\n", _al_d3d_module_name);
          is_vista = false;
       }
    }
 
    if (!is_vista) {
 #endif
-      if ((_al_d3d = Direct3DCreate9(D3D9b_SDK_VERSION)) == NULL) {
-         ALLEGRO_ERROR("Direct3DCreate9 failed.\n");
+      _al_d3d_create = (DIRECT3DCREATE9PROC)GetProcAddress(_al_d3d_module, "Direct3DCreate9");
+      if (_al_d3d_create != NULL) {
+         if ((_al_d3d = _al_d3d_create(D3D9b_SDK_VERSION)) == NULL) {
+            ALLEGRO_ERROR("Direct3DCreate9 failed.\n");
+            FreeLibrary(_al_d3d_module);
+            return false;
+         }
+      }
+      else {
+         ALLEGRO_ERROR("Direct3DCreate9 not in %s\n", _al_d3d_module_name);
+         FreeLibrary(_al_d3d_module);
          return false;
       }
+
 #ifdef ALLEGRO_CFG_D3D9EX
    }
 #endif
@@ -1331,7 +1354,7 @@
    d3d_display->device->BeginScene();
 
    d3d_reset_state(d3d_display);
-   
+
    al_unlock_mutex(_al_d3d_lost_device_mutex);
 
    return 1;
@@ -1470,7 +1493,7 @@
    D3DCAPS9 caps;
    int new_format;
    bool convert_to_faux;
-   
+
    d3d_display = params->display;
    win_display = &d3d_display->win_display;
    al_display = &win_display->display;
@@ -1787,9 +1810,9 @@
    static bool cfg_read = false;
    ALLEGRO_SYSTEM *sys;
    const char *s;
-   
+
    params.display = d3d_display;
-  
+
    ALLEGRO_EXTRA_DISPLAY_SETTINGS *ref =  _al_get_new_display_settings();
    d3d_generate_display_format_list();
 
@@ -1913,8 +1936,8 @@
    /* Setup the mouse */
    if (al_display->flags & ALLEGRO_FULLSCREEN && al_is_mouse_installed()) {
       RAWINPUTDEVICE rid[1];
-      rid[0].usUsagePage = 0x01; 
-      rid[0].usUsage = 0x02; 
+      rid[0].usUsagePage = 0x01;
+      rid[0].usUsage = 0x02;
       rid[0].dwFlags = RIDEV_NOLEGACY;
       rid[0].hwndTarget = 0;
       if (RegisterRawInputDevices(rid, 1, sizeof(rid[0])) == FALSE) {
@@ -2083,7 +2106,7 @@
       ALLEGRO_ERROR("d3d_draw_pixel: DrawPrimitive failed.\n");
       return;
    }
-   
+
    if (dest->parent) {
       new_trans.m[3][0] = al_display->cur_transform.m[3][0] - 0.5;
       new_trans.m[3][1] = al_display->cur_transform.m[3][1] - 0.5;
@@ -2195,7 +2218,7 @@
    if (rect.left == 0 && rect.top == 0 && rect.right == disp->win_display.display.w && rect.left == disp->win_display.display.h) {
       disp->device->SetRenderState(D3DRS_SCISSORTESTENABLE, false);
       return;
-   }   
+   }
 
    disp->device->SetRenderState(D3DRS_SCISSORTESTENABLE, true);
    disp->device->SetScissorRect(&rect);
@@ -2580,25 +2603,28 @@
 
    _al_d3d_bmp_destroy();
 
+   FreeLibrary(_al_d3d_module);
+   _al_d3d_module = NULL;
+
    _AL_FREE(vt);
    vt = NULL;
 }
 
-static void* d3d_prepare_vertex_cache(ALLEGRO_DISPLAY* disp, 
+static void* d3d_prepare_vertex_cache(ALLEGRO_DISPLAY* disp,
                                       int num_new_vertices)
 {
    disp->num_cache_vertices += num_new_vertices;
-   if(!disp->vertex_cache) {  
+   if(!disp->vertex_cache) {
       disp->vertex_cache = _AL_MALLOC(num_new_vertices * sizeof(D3D_TL_VERTEX));
-      
+
       disp->vertex_cache_size = num_new_vertices;
    } else if (disp->num_cache_vertices > disp->vertex_cache_size) {
-      disp->vertex_cache = _AL_REALLOC(disp->vertex_cache, 
+      disp->vertex_cache = _AL_REALLOC(disp->vertex_cache,
                               2 * disp->num_cache_vertices * sizeof(D3D_TL_VERTEX));
-                              
+
       disp->vertex_cache_size = 2 * disp->num_cache_vertices;
    }
-   return (D3D_TL_VERTEX*)disp->vertex_cache + 
+   return (D3D_TL_VERTEX*)disp->vertex_cache +
          (disp->num_cache_vertices - num_new_vertices);
 }
 
@@ -2610,9 +2636,9 @@
       return;
    if(disp->num_cache_vertices == 0)
       return;
-      
+
    ALLEGRO_DISPLAY_D3D* d3d_disp = (ALLEGRO_DISPLAY_D3D*)disp;
-   
+
    /* For sub-bitmaps */
    if (dest->parent) {
       memcpy(new_trans.m[0], disp->cur_transform.m[0], 16 * sizeof(float));
@@ -2628,19 +2654,19 @@
    }
 
    d3d_disp->device->SetFVF(D3DFVF_TL_VERTEX);
-   
+
    if (d3d_disp->device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, disp->num_cache_vertices / 3,
       (D3D_TL_VERTEX*)disp->vertex_cache, sizeof(D3D_TL_VERTEX)) != D3D_OK) {
       ALLEGRO_ERROR("d3d_flush_vertex_cache: DrawPrimitive failed.\n");
       return;
    }
-   
+
    if (dest->parent) {
       new_trans.m[3][0] = disp->cur_transform.m[3][0] - 0.5;
       new_trans.m[3][1] = disp->cur_transform.m[3][1] - 0.5;
       d3d_disp->device->SetTransform(D3DTS_VIEW, &new_trans);
    }
-   
+
    disp->num_cache_vertices = 0;
    d3d_disp->device->SetTexture(0, NULL);
 }
@@ -2652,7 +2678,7 @@
    memcpy(matrix.m[0], disp->cur_transform.m[0], 16 * sizeof(float));
    matrix.m[3][0] -= 0.5;
    matrix.m[3][1] -= 0.5;
-   
+
    d3d_disp->device->SetTransform(D3DTS_VIEW, &matrix);
 }
 
@@ -2698,10 +2724,10 @@
    vt->toggle_display_flag = _al_win_toggle_display_flag;
    vt->set_window_title = _al_win_set_window_title;
    vt->shutdown = d3d_shutdown;
-   
+
    vt->flush_vertex_cache = d3d_flush_vertex_cache;
    vt->prepare_vertex_cache = d3d_prepare_vertex_cache;
-   
+
    vt->update_transformation = d3d_update_transformation;
 
    return vt;
@@ -2729,7 +2755,7 @@
       if (allegro_formats[j] == -1)
          return 0;
    }
-   
+
    for (; allegro_formats[j] != -1; j++) {
       int adapter = al_get_current_video_adapter();
       if (adapter == -1)
