2003-11-03 17:22:45 +01:00
|
|
|
// system detect
|
|
|
|
//
|
|
|
|
// Copyright (c) 2003 Jan Wassenberg
|
|
|
|
//
|
2004-03-03 01:44:06 +01:00
|
|
|
// This file is free software; you can redistribute it and/or
|
2003-11-03 17:22:45 +01:00
|
|
|
// modify it under the terms of the GNU General Public License as
|
|
|
|
// published by the Free Software Foundation; either version 2 of the
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
//
|
2004-03-03 01:44:06 +01:00
|
|
|
// This file is distributed in the hope that it will be useful, but
|
2003-11-03 17:22:45 +01:00
|
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// General Public License for more details.
|
|
|
|
//
|
|
|
|
// Contact info:
|
|
|
|
// Jan.Wassenberg@stud.uni-karlsruhe.de
|
|
|
|
// http://www.stud.uni-karlsruhe.de/~urkt/
|
|
|
|
|
|
|
|
// things missing in POSIX, SDL, and OpenGL :P
|
2004-03-03 01:44:06 +01:00
|
|
|
// large platform-specific routines (e.g. CPU or gfx card info)
|
|
|
|
// are split out of here.
|
2003-11-03 17:22:45 +01:00
|
|
|
|
2004-05-08 03:11:51 +02:00
|
|
|
#include "precompiled.h"
|
2003-11-03 17:22:45 +01:00
|
|
|
|
2004-03-03 01:44:06 +01:00
|
|
|
#include "lib.h"
|
2005-03-27 19:24:57 +02:00
|
|
|
#include "posix.h"
|
2003-11-03 17:22:45 +01:00
|
|
|
#include "detect.h"
|
2004-05-08 03:11:51 +02:00
|
|
|
#include "timer.h"
|
2005-06-16 23:46:33 +02:00
|
|
|
#include "sdl.h"
|
2004-05-26 01:16:21 +02:00
|
|
|
|
2005-08-09 18:23:19 +02:00
|
|
|
#if CPU_IA32
|
2005-09-13 01:37:52 +02:00
|
|
|
#include "sysdep/ia32.h"
|
2004-03-04 21:36:31 +01:00
|
|
|
#endif
|
2004-05-08 03:11:51 +02:00
|
|
|
|
2005-08-09 18:23:19 +02:00
|
|
|
#if OS_WIN
|
2004-05-26 01:16:21 +02:00
|
|
|
extern int win_get_gfx_info();
|
2004-03-03 01:44:06 +01:00
|
|
|
extern int win_get_cpu_info();
|
2004-11-19 23:40:00 +01:00
|
|
|
extern int win_get_snd_info();
|
2005-09-26 07:38:40 +02:00
|
|
|
#elif OS_UNIX
|
|
|
|
extern int unix_get_cpu_info();
|
2004-05-26 01:16:21 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
extern "C" int ogl_get_gfx_info();
|
2003-11-03 17:22:45 +01:00
|
|
|
|
2004-11-19 23:40:00 +01:00
|
|
|
|
2004-03-03 01:44:06 +01:00
|
|
|
//
|
|
|
|
// memory
|
|
|
|
//
|
2003-11-03 17:22:45 +01:00
|
|
|
|
|
|
|
size_t tot_mem = 0;
|
|
|
|
size_t avl_mem = 0;
|
|
|
|
|
2003-11-12 15:47:38 +01:00
|
|
|
size_t page_size = 0;
|
|
|
|
|
2003-11-03 17:22:45 +01:00
|
|
|
void get_mem_status()
|
|
|
|
{
|
2003-11-12 15:47:38 +01:00
|
|
|
#ifdef _SC_PAGESIZE
|
2004-03-03 01:44:06 +01:00
|
|
|
if(!page_size)
|
|
|
|
page_size = (size_t)sysconf(_SC_PAGESIZE);
|
2003-11-12 15:47:38 +01:00
|
|
|
#endif
|
|
|
|
|
2003-11-03 17:22:45 +01:00
|
|
|
// Sys V derived (GNU/Linux, Solaris)
|
2005-08-09 18:23:19 +02:00
|
|
|
#if defined(_SC_AVPHYS_PAGES)
|
2003-11-03 17:22:45 +01:00
|
|
|
|
|
|
|
tot_mem = sysconf(_SC_PHYS_PAGES ) * page_size;
|
|
|
|
avl_mem = sysconf(_SC_AVPHYS_PAGES) * page_size;
|
|
|
|
|
|
|
|
// BSD / Mac OS X
|
2005-08-09 18:23:19 +02:00
|
|
|
#elif defined(HW_PHYSMEM)
|
2003-11-03 17:22:45 +01:00
|
|
|
|
|
|
|
size_t len = sizeof(tot_mem);
|
|
|
|
int mib[2] = { CTL_HW, HW_PHYSMEM };
|
|
|
|
sysctl(mib, 2, &tot_mem, &len, 0, 0);
|
|
|
|
mib[1] = HW_USERMEM;
|
|
|
|
sysctl(mib, 2, &avl_mem, &len, 0, 0);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2004-11-19 23:40:00 +01:00
|
|
|
|
2004-03-03 01:44:06 +01:00
|
|
|
//
|
|
|
|
// graphics card
|
|
|
|
//
|
|
|
|
|
2004-11-19 23:40:00 +01:00
|
|
|
char gfx_card[GFX_CARD_LEN] = "";
|
|
|
|
char gfx_drv_ver[GFX_DRV_VER_LEN] = "";
|
2003-11-03 17:22:45 +01:00
|
|
|
|
2005-06-16 23:46:33 +02:00
|
|
|
int gfx_mem = -1; // [MiB]; approximate
|
|
|
|
|
2003-11-03 17:22:45 +01:00
|
|
|
|
|
|
|
// attempt to detect graphics card without OpenGL (in case ogl init fails,
|
|
|
|
// or we want more detailed info). gfx_card[] is unchanged on failure.
|
2004-03-04 21:36:31 +01:00
|
|
|
void get_gfx_info()
|
2003-11-03 17:22:45 +01:00
|
|
|
{
|
2005-10-12 06:22:44 +02:00
|
|
|
// TODO: add sizeof(FB)?
|
2005-06-16 23:46:33 +02:00
|
|
|
gfx_mem = (SDL_GetVideoInfo()->video_mem) / 1048576; // [MiB]
|
|
|
|
|
2005-10-12 06:22:44 +02:00
|
|
|
// try platform-specific version: they return more
|
2004-05-26 01:16:21 +02:00
|
|
|
// detailed information, and don't require OpenGL to be ready.
|
2005-08-09 18:23:19 +02:00
|
|
|
#if OS_WIN
|
2005-10-12 06:22:44 +02:00
|
|
|
if(win_get_gfx_info() < 0)
|
2003-11-03 17:22:45 +01:00
|
|
|
#endif
|
2005-10-12 06:22:44 +02:00
|
|
|
{
|
|
|
|
// the OpenGL version should always work, unless OpenGL isn't ready for use,
|
|
|
|
// or we were called between glBegin and glEnd.
|
|
|
|
ogl_get_gfx_info();
|
|
|
|
}
|
|
|
|
|
|
|
|
// remove crap from vendor names. (don't dare touch the model name -
|
|
|
|
// it's too risky, there are too many different strings)
|
|
|
|
#define SHORTEN(what, chars_to_keep)\
|
|
|
|
if(!strncmp(gfx_card, what, ARRAY_SIZE(what)-1))\
|
|
|
|
memmove(gfx_card+chars_to_keep, gfx_card+ARRAY_SIZE(what)-1, strlen(gfx_card)-(ARRAY_SIZE(what)-1)+1);
|
|
|
|
SHORTEN("ATI Technologies Inc.", 3);
|
|
|
|
SHORTEN("NVIDIA Corporation", 6);
|
|
|
|
SHORTEN("S3 Graphics", 2); // EnumDisplayDevices
|
|
|
|
SHORTEN("S3 Graphics, Incorporated", 2); // GL_VENDOR
|
|
|
|
#undef SHORTEN
|
2003-11-03 17:22:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// CPU
|
|
|
|
//
|
|
|
|
|
2005-04-19 19:07:05 +02:00
|
|
|
char cpu_type[CPU_TYPE_LEN] = ""; // processor brand string is <= 48 chars
|
2003-11-03 17:22:45 +01:00
|
|
|
double cpu_freq = 0.f;
|
|
|
|
|
|
|
|
// -1 if detect not yet called, or cannot be determined
|
|
|
|
int cpus = -1;
|
2005-09-14 18:58:10 +02:00
|
|
|
int cpu_ht_units = -1;
|
|
|
|
int cpu_cores = -1;
|
2004-03-03 01:44:06 +01:00
|
|
|
int cpu_speedstep = -1;
|
2003-11-03 17:22:45 +01:00
|
|
|
|
2005-10-03 05:41:42 +02:00
|
|
|
static void get_cpu_info()
|
2003-11-03 17:22:45 +01:00
|
|
|
{
|
2005-08-09 18:23:19 +02:00
|
|
|
#if OS_WIN
|
2004-03-03 01:44:06 +01:00
|
|
|
win_get_cpu_info();
|
2005-09-26 07:38:40 +02:00
|
|
|
#elif OS_UNIX
|
|
|
|
unix_get_cpu_info();
|
2004-03-03 01:44:06 +01:00
|
|
|
#endif
|
2003-11-03 17:22:45 +01:00
|
|
|
|
2005-08-09 18:23:19 +02:00
|
|
|
#if CPU_IA32
|
2004-03-03 01:44:06 +01:00
|
|
|
ia32_get_cpu_info();
|
2003-11-03 17:22:45 +01:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-10-03 05:41:42 +02:00
|
|
|
void cpu_init()
|
|
|
|
{
|
|
|
|
#if CPU_IA32
|
2005-10-19 05:06:54 +02:00
|
|
|
// must come before any uses of ia32.asm, e.g. by get_cpu_info
|
2005-10-03 05:41:42 +02:00
|
|
|
ia32_init();
|
|
|
|
|
|
|
|
// no longer set 24 bit (float) precision by default: for
|
|
|
|
// very long game uptimes (> 1 day; e.g. dedicated server),
|
|
|
|
// we need full precision when calculating the time.
|
|
|
|
// if there's a spot where we want to speed up divides|sqrts,
|
|
|
|
// we can temporarily change precision there.
|
2005-10-18 01:35:16 +02:00
|
|
|
//_control87(_PC_24, _MCW_PC);
|
|
|
|
|
2005-10-19 05:06:54 +02:00
|
|
|
// to help catch bugs, enable as many floating-point exceptions as
|
|
|
|
// possible. that means only zero-divide, because the JS engine is
|
|
|
|
// triggering the rest.
|
2005-10-19 05:22:13 +02:00
|
|
|
// note: passing a flag *disables* that exception.
|
|
|
|
_control87(_EM_INVALID|_EM_DENORMAL|_EM_OVERFLOW|_EM_UNDERFLOW|_EM_INEXACT, _MCW_EM);
|
2005-10-03 05:41:42 +02:00
|
|
|
|
2005-11-06 02:33:16 +01:00
|
|
|
// round toward zero (truncate). this is what ANSI C calls for;
|
|
|
|
// if we set it to this (default is round to nearest), the compiler can
|
|
|
|
// generate FISTP (much faster) instead of _ftol2 with the same results.
|
|
|
|
_control87(_RC_CHOP, _MCW_RC);
|
|
|
|
|
2005-10-19 05:06:54 +02:00
|
|
|
// If possible, hook up capability-sensitive assembler routines
|
|
|
|
ia32_hook_capabilities();
|
|
|
|
#endif
|
|
|
|
|
2005-10-03 05:41:42 +02:00
|
|
|
// detects CPU clock frequency and capabilities, which are prerequisites
|
|
|
|
// for using the TSC as a timer (desirable due to its high resolution).
|
|
|
|
// do this before lengthy init so we can time those accurately.
|
|
|
|
get_cpu_info();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-11-19 23:40:00 +01:00
|
|
|
//
|
|
|
|
// sound
|
|
|
|
//
|
2004-03-03 01:44:06 +01:00
|
|
|
|
2004-11-19 23:40:00 +01:00
|
|
|
char snd_card[SND_CARD_LEN];
|
|
|
|
char snd_drv_ver[SND_DRV_VER_LEN];
|
2004-03-03 01:44:06 +01:00
|
|
|
|
2004-11-24 00:56:10 +01:00
|
|
|
void get_snd_info()
|
2003-11-03 17:22:45 +01:00
|
|
|
{
|
2005-08-09 18:23:19 +02:00
|
|
|
#if OS_WIN
|
2004-11-19 23:40:00 +01:00
|
|
|
win_get_snd_info();
|
2004-11-24 00:56:10 +01:00
|
|
|
#else
|
|
|
|
// At least reset the values for unhandled platforms. Should perhaps do
|
|
|
|
// something like storing the OpenAL version or similar.
|
2005-06-28 06:06:25 +02:00
|
|
|
debug_assert(SND_CARD_LEN >= 8 && SND_DRV_VER_LEN >= 8); // protect strcpy
|
2005-03-01 21:13:00 +01:00
|
|
|
strcpy(snd_card, "Unknown"); // safe
|
|
|
|
strcpy(snd_drv_ver, "Unknown"); // safe
|
2004-11-19 23:40:00 +01:00
|
|
|
#endif
|
2003-11-03 17:22:45 +01:00
|
|
|
}
|