2005-06-21 18:44:12 +02:00
|
|
|
#ifndef SYSDEP_H_INCLUDED
|
|
|
|
#define SYSDEP_H_INCLUDED
|
2004-03-03 00:56:51 +01:00
|
|
|
|
2004-07-13 00:05:49 +02:00
|
|
|
#include "config.h"
|
|
|
|
|
2005-11-07 03:45:25 +01:00
|
|
|
// some functions among the sysdep API are implemented as macros
|
|
|
|
// that redirect to the platform-dependent version. this is done where
|
|
|
|
// the cost of a trampoline function would be too great; VC7 does not
|
|
|
|
// always inline them.
|
|
|
|
// we therefore need to include those headers.
|
2005-08-09 18:23:19 +02:00
|
|
|
#if OS_WIN
|
2005-06-22 05:23:22 +02:00
|
|
|
# include "win/win.h"
|
2005-08-09 18:23:19 +02:00
|
|
|
#elif OS_UNIX
|
2005-06-22 05:23:22 +02:00
|
|
|
# include "unix/unix.h"
|
2004-04-09 14:39:55 +02:00
|
|
|
#endif
|
2005-11-07 03:45:25 +01:00
|
|
|
#if CPU_IA32
|
|
|
|
#include "ia32.h"
|
|
|
|
#endif
|
2004-03-03 00:56:51 +01:00
|
|
|
|
2005-12-12 20:19:30 +01:00
|
|
|
|
2005-10-29 04:32:36 +02:00
|
|
|
// pass "omit frame pointer" setting on to the compiler
|
|
|
|
#if MSC_VERSION
|
|
|
|
# if CONFIG_OMIT_FP
|
|
|
|
# pragma optimize("y", on)
|
|
|
|
# else
|
|
|
|
# pragma optimize("y", off)
|
|
|
|
# endif
|
|
|
|
#elif GCC_VERSION
|
|
|
|
// TODO
|
|
|
|
#endif
|
|
|
|
|
2005-08-09 18:23:19 +02:00
|
|
|
// compiling without exceptions (usually for performance reasons);
|
|
|
|
// tell STL not to generate any.
|
|
|
|
#if CONFIG_DISABLE_EXCEPTIONS
|
|
|
|
# if OS_WIN
|
|
|
|
# define _HAS_EXCEPTIONS 0
|
|
|
|
# else
|
|
|
|
# define STL_NO_EXCEPTIONS
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2005-01-27 16:50:11 +01:00
|
|
|
|
2005-12-07 04:38:39 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// C99 / SUSv3 emulation where needed
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2005-01-27 16:50:11 +01:00
|
|
|
// vsnprintf2: handles positional parameters and %lld.
|
|
|
|
// already available on *nix, emulated on Win32.
|
2005-08-09 18:23:19 +02:00
|
|
|
#if OS_WIN
|
2005-01-27 16:50:11 +01:00
|
|
|
extern int vsnprintf2(char* buffer, size_t count, const char* format, va_list argptr);
|
2004-08-09 17:44:35 +02:00
|
|
|
#else
|
2004-08-09 18:31:34 +02:00
|
|
|
#define vsnprintf2 vsnprintf
|
2004-08-09 17:44:35 +02:00
|
|
|
#endif
|
|
|
|
|
2005-12-07 04:38:39 +01:00
|
|
|
#if !HAVE_C99
|
|
|
|
extern float fminf(float a, float b);
|
|
|
|
extern float fmaxf(float a, float b);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if !MSC_VERSION
|
|
|
|
#define stricmp strcasecmp
|
|
|
|
#define strnicmp strncasecmp
|
|
|
|
#endif
|
|
|
|
|
2005-07-09 22:20:57 +02:00
|
|
|
// alloca: allocate on stack, automatically free, return 0 if out of mem.
|
|
|
|
// already available on *nix, emulated on Win32.
|
2005-08-09 18:23:19 +02:00
|
|
|
#if OS_WIN
|
2005-07-09 22:20:57 +02:00
|
|
|
#undef alloca // from malloc.h
|
|
|
|
extern void* alloca(size_t size);
|
|
|
|
#endif
|
|
|
|
|
2005-11-07 03:45:25 +01:00
|
|
|
// rint: round float to nearest integral value.
|
2005-10-19 22:26:53 +02:00
|
|
|
// provided by C99, otherwise:
|
|
|
|
#if !HAVE_C99
|
2005-11-07 03:45:25 +01:00
|
|
|
// .. fast IA-32 version
|
2005-10-19 22:26:53 +02:00
|
|
|
# if CPU_IA32
|
|
|
|
# define rintf ia32_rintf
|
|
|
|
# define rint ia32_rint
|
2005-11-07 03:45:25 +01:00
|
|
|
// .. portable C emulation
|
|
|
|
# else
|
|
|
|
extern float rintf(float f);
|
|
|
|
extern double rint(double d);
|
2005-10-19 22:26:53 +02:00
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2005-08-09 18:23:19 +02:00
|
|
|
// finite: return 0 iff the given double is infinite or NaN.
|
|
|
|
#if OS_WIN
|
|
|
|
# define finite _finite
|
|
|
|
#else
|
|
|
|
# define finite __finite
|
|
|
|
#endif
|
|
|
|
|
2005-10-19 05:06:54 +02:00
|
|
|
// C99 restrict
|
2005-10-12 19:19:07 +02:00
|
|
|
// .. for some reason, g++-3.3 claims to support C99 (according to
|
|
|
|
// __STDC_VERSION__) but doesn't have the restrict keyword.
|
|
|
|
// use the extension __restrict__ instead.
|
2005-10-12 18:27:23 +02:00
|
|
|
#if GCC_VERSION
|
2005-10-12 19:19:07 +02:00
|
|
|
# define restrict __restrict__
|
|
|
|
// .. already available; need do nothing
|
|
|
|
#elif HAVE_C99
|
|
|
|
// .. unsupported; remove it from code
|
2005-10-12 18:27:23 +02:00
|
|
|
#else
|
2005-10-12 06:22:44 +02:00
|
|
|
# define restrict
|
|
|
|
#endif
|
|
|
|
|
2005-10-19 05:06:54 +02:00
|
|
|
// C99 __func__
|
|
|
|
// .. already available; need do nothing
|
|
|
|
#if HAVE_C99
|
|
|
|
// .. VC supports something similar
|
|
|
|
#elif MSC_VERSION
|
|
|
|
# define __func__ __FUNCTION__
|
|
|
|
// .. unsupported; remove it from code
|
|
|
|
#else
|
2005-10-19 08:29:55 +02:00
|
|
|
# define __func__ "(unknown)"
|
2005-10-19 05:06:54 +02:00
|
|
|
#endif
|
2005-10-12 06:22:44 +02:00
|
|
|
|
2005-12-17 23:00:54 +01:00
|
|
|
#include "debug.h"
|
2005-08-09 18:23:19 +02:00
|
|
|
|
2005-12-07 04:38:39 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// sysdep API
|
|
|
|
//-----------------------------------------------------------------------------
|
2005-10-19 22:26:53 +02:00
|
|
|
|
2005-08-09 18:23:19 +02:00
|
|
|
//
|
|
|
|
// output
|
|
|
|
//
|
2004-03-03 00:56:51 +01:00
|
|
|
|
2005-12-10 08:04:31 +01:00
|
|
|
// raise a message box with the given text or (depending on platform)
|
|
|
|
// otherwise inform the user.
|
2005-12-12 20:19:30 +01:00
|
|
|
// called from debug_display_msgw.
|
2005-12-07 04:38:39 +01:00
|
|
|
extern void sys_display_msg(const char* caption, const char* msg);
|
|
|
|
extern void sys_display_msgw(const wchar_t* caption, const wchar_t* msg);
|
2005-12-12 20:19:30 +01:00
|
|
|
|
|
|
|
// show the error dialog. flags: see DisplayErrorFlags.
|
|
|
|
// called from debug_display_error.
|
2005-12-07 04:38:39 +01:00
|
|
|
extern ErrorReaction sys_display_error(const wchar_t* text, int flags);
|
2004-03-03 00:56:51 +01:00
|
|
|
|
2004-03-03 01:37:41 +01:00
|
|
|
|
2005-08-09 18:23:19 +02:00
|
|
|
//
|
|
|
|
// clipboard
|
|
|
|
//
|
|
|
|
|
2005-12-07 04:38:39 +01:00
|
|
|
// "copy" text into the clipboard. replaces previous contents.
|
2005-12-11 23:23:55 +01:00
|
|
|
extern LibError sys_clipboard_set(const wchar_t* text);
|
2005-12-07 04:38:39 +01:00
|
|
|
|
|
|
|
// allow "pasting" from clipboard. returns the current contents if they
|
|
|
|
// can be represented as text, otherwise 0.
|
|
|
|
// when it is no longer needed, the returned pointer must be freed via
|
|
|
|
// sys_clipboard_free. (NB: not necessary if zero, but doesn't hurt)
|
|
|
|
extern wchar_t* sys_clipboard_get(void);
|
|
|
|
|
|
|
|
// frees memory used by <copy>, which must have been returned by
|
|
|
|
// sys_clipboard_get. see note above.
|
2005-12-11 23:23:55 +01:00
|
|
|
extern LibError sys_clipboard_free(wchar_t* copy);
|
2004-07-13 23:17:26 +02:00
|
|
|
|
|
|
|
|
2005-08-09 18:23:19 +02:00
|
|
|
//
|
|
|
|
// mouse cursor
|
|
|
|
//
|
|
|
|
|
2005-08-10 02:27:56 +02:00
|
|
|
// note: these do not warn on error; that is left to the caller.
|
|
|
|
|
2005-12-07 04:38:39 +01:00
|
|
|
// creates a cursor from the given image.
|
|
|
|
// w, h specify image dimensions [pixels]. limit is implementation-
|
|
|
|
// dependent; 32x32 is typical and safe.
|
|
|
|
// bgra_img is the cursor image (BGRA format, bottom-up).
|
|
|
|
// it is no longer needed and can be freed after this call returns.
|
2005-09-29 07:00:20 +02:00
|
|
|
// hotspot (hx,hy) is the offset from its upper-left corner to the
|
2005-12-07 04:38:39 +01:00
|
|
|
// position where mouse clicks are registered.
|
|
|
|
// return: negative error code, or 0 on success. cursor is filled with
|
|
|
|
// a pointer and undefined on failure. it must be sys_cursor_free-ed
|
|
|
|
// when no longer needed.
|
2005-12-11 23:23:55 +01:00
|
|
|
extern LibError sys_cursor_create(uint w, uint h, void* bgra_img,
|
2005-09-29 07:00:20 +02:00
|
|
|
uint hx, uint hy, void** cursor);
|
2005-08-09 18:23:19 +02:00
|
|
|
|
|
|
|
// replaces the current system cursor with the one indicated. need only be
|
|
|
|
// called once per cursor; pass 0 to restore the default.
|
2005-12-11 23:23:55 +01:00
|
|
|
extern LibError sys_cursor_set(void* cursor);
|
2005-08-09 18:23:19 +02:00
|
|
|
|
|
|
|
// destroys the indicated cursor and frees its resources. if it is
|
|
|
|
// currently the system cursor, the default cursor is restored first.
|
2005-12-11 23:23:55 +01:00
|
|
|
extern LibError sys_cursor_free(void* cursor);
|
2005-08-09 18:23:19 +02:00
|
|
|
|
|
|
|
|
2005-12-07 04:38:39 +01:00
|
|
|
//
|
|
|
|
// misc
|
|
|
|
//
|
2005-09-14 18:58:10 +02:00
|
|
|
|
2005-12-07 04:38:39 +01:00
|
|
|
// OS-specific backend for error_description_r.
|
|
|
|
// NB: it is expected to be rare that OS return/error codes are actually
|
|
|
|
// seen by user code, but we still translate them for completeness.
|
2005-12-11 23:23:55 +01:00
|
|
|
extern LibError sys_error_description_r(int err, char* buf, size_t max_chars);
|
2005-11-19 19:12:16 +01:00
|
|
|
|
2005-12-07 04:38:39 +01:00
|
|
|
// determine filename of the module to whom the given address belongs.
|
|
|
|
// useful for handling exceptions in other modules.
|
|
|
|
// <path> receives full path to module; it must hold at least MAX_PATH chars.
|
|
|
|
// on error, it is set to L"".
|
|
|
|
// return path for convenience.
|
|
|
|
wchar_t* sys_get_module_filename(void* addr, wchar_t* path);
|
|
|
|
|
|
|
|
// store full path to the current executable.
|
|
|
|
// returns 0 or a negative error code.
|
|
|
|
// useful for determining installation directory, e.g. for VFS.
|
2005-12-11 23:23:55 +01:00
|
|
|
extern LibError sys_get_executable_name(char* n_path, size_t buf_size);
|
2005-12-07 04:38:39 +01:00
|
|
|
|
|
|
|
// have the user specify a directory via OS dialog.
|
|
|
|
// stores its full path in the given buffer, which must hold at least
|
|
|
|
// PATH_MAX chars.
|
|
|
|
// returns 0 on success or a negative error code.
|
2005-12-11 23:23:55 +01:00
|
|
|
extern LibError sys_pick_directory(char* n_path, size_t buf_size);
|
2005-12-07 04:38:39 +01:00
|
|
|
|
|
|
|
// execute the specified function once on each CPU.
|
|
|
|
// this includes logical HT units and proceeds serially (function
|
|
|
|
// is never re-entered) in order of increasing OS CPU ID.
|
|
|
|
// note: implemented by switching thread affinity masks and forcing
|
|
|
|
// a reschedule, which is apparently not possible with POSIX.
|
|
|
|
// return 0 on success or a negative error code on failure
|
|
|
|
// (e.g. if OS is preventing us from running on some CPUs).
|
2005-09-14 18:58:10 +02:00
|
|
|
// called from ia32.cpp get_cpu_count
|
2005-12-11 23:23:55 +01:00
|
|
|
extern LibError sys_on_each_cpu(void (*cb)());
|
2005-09-14 18:58:10 +02:00
|
|
|
|
|
|
|
|
2005-12-07 04:38:39 +01:00
|
|
|
// drop-in replacement for libc memcpy(). only requires CPU support for
|
|
|
|
// MMX (by now universal). highly optimized for Athlon and Pentium III
|
|
|
|
// microarchitectures; significantly outperforms VC7.1 memcpy and memcpy_amd.
|
|
|
|
// for details, see accompanying article.
|
|
|
|
#ifdef CPU_IA32
|
|
|
|
# define memcpy2 ia32_memcpy
|
|
|
|
extern void* ia32_memcpy(void* dst, const void* src, size_t nbytes);
|
|
|
|
#else
|
|
|
|
# define memcpy2 memcpy
|
2004-06-03 03:43:33 +02:00
|
|
|
#endif
|
|
|
|
|
2005-12-07 04:38:39 +01:00
|
|
|
// i32_from_float et al: convert float to int. much faster than _ftol2,
|
|
|
|
// which would normally be used by (int) casts.
|
|
|
|
// .. fast IA-32 version: only used in some cases; see macro definition.
|
|
|
|
#if USE_IA32_FLOAT_TO_INT
|
|
|
|
# define i32_from_float ia32_i32_from_float
|
|
|
|
# define i32_from_double ia32_i32_from_double
|
|
|
|
# define i64_from_double ia32_i64_from_double
|
|
|
|
// .. portable C emulation
|
|
|
|
#else
|
|
|
|
extern i32 i32_from_float(float);
|
|
|
|
extern i32 i32_from_double(double);
|
|
|
|
extern i64 i64_from_double(double);
|
2004-06-09 15:43:25 +02:00
|
|
|
#endif
|
2004-06-03 03:43:33 +02:00
|
|
|
|
2004-08-18 04:13:53 +02:00
|
|
|
|
2004-03-03 00:56:51 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-08-18 04:13:53 +02:00
|
|
|
|
2005-12-07 04:38:39 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
2005-05-01 21:09:13 +02:00
|
|
|
// STL_HASH_MAP, STL_HASH_MULTIMAP, STL_HASH_SET
|
2005-12-07 04:38:39 +01:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// these containers are useful but not part of C++98. most STL vendors
|
|
|
|
// provide them in some form; we hide their differences behind macros.
|
|
|
|
|
2005-08-09 18:23:19 +02:00
|
|
|
#if GCC_VERSION
|
2004-08-18 04:13:53 +02:00
|
|
|
# include <ext/hash_map>
|
2005-05-01 21:09:13 +02:00
|
|
|
# include <ext/hash_set> // Probably?
|
|
|
|
|
2004-08-18 04:13:53 +02:00
|
|
|
# define STL_HASH_MAP __gnu_cxx::hash_map
|
|
|
|
# define STL_HASH_MULTIMAP __gnu_cxx::hash_multimap
|
2005-05-01 21:09:13 +02:00
|
|
|
# define STL_HASH_SET __gnu_cxx::hash_set
|
2005-07-03 22:47:24 +02:00
|
|
|
# define STL_HASH_MULTISET __gnu_cxx::hash_multiset
|
|
|
|
# define STL_SLIST __gnu_cxx::slist
|
2004-11-07 22:30:47 +01:00
|
|
|
|
2005-11-06 00:03:55 +01:00
|
|
|
template<typename T>
|
|
|
|
size_t STL_HASH_VALUE(T v)
|
|
|
|
{
|
|
|
|
return __gnu_cxx::hash<T>()(v);
|
|
|
|
}
|
|
|
|
|
2004-11-07 22:30:47 +01:00
|
|
|
// Hack: GCC Doesn't have a hash instance for std::string included (and it looks
|
|
|
|
// like they won't add it - marked resolved/wontfix in the gcc bugzilla)
|
|
|
|
namespace __gnu_cxx
|
|
|
|
{
|
|
|
|
template<> struct hash<std::string>
|
|
|
|
{
|
2006-02-13 01:59:59 +01:00
|
|
|
size_t operator()(const std::string& __x) const
|
2004-11-07 22:30:47 +01:00
|
|
|
{
|
|
|
|
return __stl_hash_string(__x.c_str());
|
2005-11-05 05:59:54 +01:00
|
|
|
}
|
2004-11-07 22:30:47 +01:00
|
|
|
};
|
2006-02-13 01:59:59 +01:00
|
|
|
|
|
|
|
template<> struct hash<const void*>
|
|
|
|
{
|
2006-02-19 00:21:05 +01:00
|
|
|
// Nemesi hash function (see: http://mail-index.netbsd.org/tech-kern/2001/11/30/0001.html)
|
|
|
|
// treating the pointer as an array of bytes that is hashed.
|
2006-02-13 01:59:59 +01:00
|
|
|
size_t operator()(const void* __x) const
|
|
|
|
{
|
2006-02-19 00:21:05 +01:00
|
|
|
union {
|
|
|
|
const void* ptr;
|
|
|
|
unsigned char bytes[sizeof(void*)];
|
|
|
|
} val;
|
|
|
|
size_t h = 5381;
|
2006-02-13 01:59:59 +01:00
|
|
|
|
2006-02-19 00:21:05 +01:00
|
|
|
val.ptr = __x;
|
2006-02-13 01:59:59 +01:00
|
|
|
|
2006-02-19 00:21:05 +01:00
|
|
|
for(uint i = 0; i < sizeof(val); ++i)
|
|
|
|
h = 257*h + val.bytes[i];
|
|
|
|
|
|
|
|
return 257*h;
|
2006-02-13 01:59:59 +01:00
|
|
|
}
|
|
|
|
};
|
2004-11-07 22:30:47 +01:00
|
|
|
}
|
|
|
|
|
2004-08-18 04:13:53 +02:00
|
|
|
#else // !__GNUC__
|
2005-12-07 04:38:39 +01:00
|
|
|
|
2004-08-18 04:13:53 +02:00
|
|
|
# include <hash_map>
|
2005-05-01 21:09:13 +02:00
|
|
|
# include <hash_set>
|
2004-08-18 04:13:53 +02:00
|
|
|
// VC7 or above
|
2005-08-09 18:23:19 +02:00
|
|
|
# if MSC_VERSION >= 1300
|
2004-08-18 04:13:53 +02:00
|
|
|
# define STL_HASH_MAP stdext::hash_map
|
|
|
|
# define STL_HASH_MULTIMAP stdext::hash_multimap
|
2005-05-01 21:09:13 +02:00
|
|
|
# define STL_HASH_SET stdext::hash_set
|
2005-07-03 22:47:24 +02:00
|
|
|
# define STL_HASH_MULTISET stdext::hash_multiset
|
2005-11-05 05:59:54 +01:00
|
|
|
# define STL_HASH_VALUE stdext::hash_value
|
2004-08-18 04:13:53 +02:00
|
|
|
// VC6 and anything else (most likely name)
|
2005-08-09 18:23:19 +02:00
|
|
|
# else
|
2004-08-18 04:13:53 +02:00
|
|
|
# define STL_HASH_MAP std::hash_map
|
|
|
|
# define STL_HASH_MULTIMAP std::hash_multimap
|
2005-05-01 21:09:13 +02:00
|
|
|
# define STL_HASH_SET std::hash_set
|
2005-07-03 22:47:24 +02:00
|
|
|
# define STL_HASH_MULTISET std::hash_multiset
|
2005-11-05 05:59:54 +01:00
|
|
|
# define STL_HASH_VALUE std::hash_value
|
2005-08-09 18:23:19 +02:00
|
|
|
# endif // MSC_VERSION >= 1300
|
2004-08-18 04:13:53 +02:00
|
|
|
|
2005-12-07 04:38:39 +01:00
|
|
|
#endif // !__GNUC__
|
2004-08-18 04:13:53 +02:00
|
|
|
|
2005-06-21 18:44:12 +02:00
|
|
|
#endif // #ifndef SYSDEP_H_INCLUDED
|