+#ifdef WIN32
+# ifndef DONT_USE_SETDLLDIRECTORY
+# define _WIN32_WINNT 0x0502
+# endif
+#endif
+
#include "quakedef.h"
#define SUPPORTDLL
===============================================================================
*/
+static qboolean Sys_LoadLibraryFunctions(dllhandle_t dllhandle, const dllfunction_t *fcts, qboolean complain, qboolean has_next)
+{
+ const dllfunction_t *func;
+ if(dllhandle)
+ {
+ for (func = fcts; func && func->name != NULL; func++)
+ if (!(*func->funcvariable = (void *) Sys_GetProcAddress (dllhandle, func->name)))
+ {
+ if(complain)
+ {
+ Con_DPrintf (" - missing function \"%s\" - broken library!", func->name);
+ if(has_next)
+ Con_DPrintf("\nContinuing with");
+ }
+ goto notfound;
+ }
+ return true;
+
+ notfound:
+ for (func = fcts; func && func->name != NULL; func++)
+ *func->funcvariable = NULL;
+ }
+ return false;
+}
+
qboolean Sys_LoadLibrary (const char** dllnames, dllhandle_t* handle, const dllfunction_t *fcts)
{
#ifdef SUPPORTDLL
#ifndef WIN32
#ifdef PREFER_PRELOAD
dllhandle = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
- if(dllhandle)
+ if(Sys_LoadLibraryFunctions(dllhandle, fcts, false, false))
{
- for (func = fcts; func && func->name != NULL; func++)
- if (!(*func->funcvariable = (void *) Sys_GetProcAddress (dllhandle, func->name)))
- {
- dlclose(dllhandle);
- goto notfound;
- }
Con_DPrintf ("All of %s's functions were already linked in! Not loading dynamically...\n", dllnames[0]);
*handle = dllhandle;
return true;
}
+ else
+ Sys_UnloadLibrary(&dllhandle);
notfound:
#endif
#endif
{
Con_DPrintf (" \"%s\"", dllnames[i]);
#ifdef WIN32
+# ifndef DONT_USE_SETDLLDIRECTORY
+# ifdef _WIN64
+ SetDllDirectory("bin64");
+# else
+ SetDllDirectory("bin32");
+# endif
+# endif
dllhandle = LoadLibrary (dllnames[i]);
+ // no need to unset this - we want ALL dlls to be loaded from there, anyway
#else
dllhandle = dlopen (dllnames[i], RTLD_LAZY | RTLD_GLOBAL);
#endif
- if (dllhandle)
+ if (Sys_LoadLibraryFunctions(dllhandle, fcts, true, (dllnames[i+1] != NULL) || (strrchr(com_argv[0], '/'))))
break;
+ else
+ Sys_UnloadLibrary (&dllhandle);
}
// see if the names can be loaded relative to the executable path
#else
dllhandle = dlopen (temp, RTLD_LAZY | RTLD_GLOBAL);
#endif
- if (dllhandle)
+ if (Sys_LoadLibraryFunctions(dllhandle, fcts, true, dllnames[i+1] != NULL))
break;
+ else
+ Sys_UnloadLibrary (&dllhandle);
}
}
Con_DPrintf(" - loaded.\n");
- // Get the function adresses
- for (func = fcts; func && func->name != NULL; func++)
- if (!(*func->funcvariable = (void *) Sys_GetProcAddress (dllhandle, func->name)))
- {
- Con_DPrintf ("Missing function \"%s\" - broken library!\n", func->name);
- Sys_UnloadLibrary (&dllhandle);
- return false;
- }
-
*handle = dllhandle;
return true;
#else
# define HAVE_GETTIMEOFDAY 1
#endif
-#ifdef FD_SET
-# define HAVE_SELECT 1
+#ifndef WIN32
+// on Win32, select() cannot be used with all three FD list args being NULL according to MSDN
+// (so much for POSIX...)
+# ifdef FD_SET
+# define HAVE_SELECT 1
+# endif
#endif
#ifndef WIN32
return;
com_selffd = FS_SysOpenFD(Sys_FindExecutableName(), "rb", false);
}
+
+// for x86 cpus only... (x64 has SSE2_PRESENT)
+#if defined(SSE_POSSIBLE) && !defined(SSE2_PRESENT)
+// code from SDL, shortened as we can expect CPUID to work
+static int CPUID_Features(void)
+{
+ int features = 0;
+# if defined(__GNUC__) && defined(__i386__)
+ __asm__ (
+" movl %%ebx,%%edi\n"
+" xorl %%eax,%%eax \n"
+" incl %%eax \n"
+" cpuid # Get family/model/stepping/features\n"
+" movl %%edx,%0 \n"
+" movl %%edi,%%ebx\n"
+ : "=m" (features)
+ :
+ : "%eax", "%ecx", "%edx", "%edi"
+ );
+# elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
+ __asm {
+ xor eax, eax
+ inc eax
+ cpuid ; Get family/model/stepping/features
+ mov features, edx
+ }
+# else
+# error SSE_POSSIBLE set but no CPUID implementation
+# endif
+ return features;
+}
+
+qboolean Sys_HaveSSE(void)
+{
+ // COMMANDLINEOPTION: SSE: -nosse disables SSE support and detection
+ if(COM_CheckParm("-nosse"))
+ return false;
+ // COMMANDLINEOPTION: SSE: -forcesse enables SSE support and disables detection
+ if(COM_CheckParm("-forcesse") || COM_CheckParm("-forcesse2"))
+ return true;
+ if(CPUID_Features() & (1 << 25))
+ return true;
+ return false;
+}
+
+qboolean Sys_HaveSSE2(void)
+{
+ // COMMANDLINEOPTION: SSE2: -nosse2 disables SSE2 support and detection
+ if(COM_CheckParm("-nosse") || COM_CheckParm("-nosse2"))
+ return false;
+ // COMMANDLINEOPTION: SSE2: -forcesse2 enables SSE2 support and disables detection
+ if(COM_CheckParm("-forcesse2"))
+ return true;
+ if((CPUID_Features() & (3 << 25)) == (3 << 25)) // SSE is 1<<25, SSE2 is 1<<26
+ return true;
+ return false;
+}
+#endif