sl@0: /* sl@0: * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: Global definitions sl@0: * sl@0: */ sl@0: sl@0: #ifndef __M3G_DEFS_H__ sl@0: #define __M3G_DEFS_H__ sl@0: sl@0: /*! sl@0: * \internal sl@0: * \file sl@0: * \brief Global definitions for the Nokia M3G API implementation sl@0: */ sl@0: sl@0: /* Include public API */ sl@0: #include "M3G/m3g_core.h" sl@0: sl@0: #if defined(__cplusplus) sl@0: extern "C" { sl@0: #endif sl@0: sl@0: /* Try to recognize debug builds */ sl@0: #if defined(_DEBUG) || defined(DEBUG) sl@0: #undef M3G_DEBUG sl@0: #define M3G_DEBUG sl@0: #endif sl@0: sl@0: /*---------------------------------------------------------------------- sl@0: * Platform dependent definitions sl@0: *--------------------------------------------------------------------*/ sl@0: sl@0: /* Define constants for use in m3g_config.h */ sl@0: sl@0: #define M3G_LOG_FATAL_ERRORS 0x0001 sl@0: #define M3G_LOG_USER_ERRORS 0x0002 sl@0: #define M3G_LOG_WARNINGS 0x0003 sl@0: #define M3G_LOG_PROFILE 0x0004 sl@0: #define M3G_LOG_INTERFACE 0x0010 sl@0: #define M3G_LOG_OBJECTS 0x0020 sl@0: #define M3G_LOG_STAGES 0x0040 sl@0: #define M3G_LOG_REFCOUNT 0x0080 sl@0: #define M3G_LOG_MEMORY_USAGE 0x0100 sl@0: #define M3G_LOG_MEMORY_BLOCKS 0x0200 sl@0: #define M3G_LOG_MEMORY_MAPPING 0x0400 sl@0: #define M3G_LOG_MEMORY_ALL 0x0F00 sl@0: #define M3G_LOG_RENDERING 0x1000 sl@0: #define M3G_LOG_IMAGES 0x2000 sl@0: #define M3G_LOG_ALL 0xFFFF sl@0: sl@0: /* Include the platform configuration file; the possible configuration sl@0: * options are documented and their default values set below */ sl@0: sl@0: #include "m3g_config.h" sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_TARGET_GENERIC sl@0: * \brief Enables a generic C build sl@0: */ sl@0: /*! sl@0: * \internal sl@0: * \def M3G_TARGET_ISA sl@0: * \brief Enables building for ISA sl@0: */ sl@0: /*! sl@0: * \internal sl@0: * \def M3G_TARGET_SYMBIAN sl@0: * \brief Enables building for Symbian sl@0: */ sl@0: /*! sl@0: * \internal sl@0: * \def M3G_TARGET_WIN32 sl@0: * \brief Enables building for Win32 sl@0: */ sl@0: #if defined(M3G_TARGET_GENERIC) sl@0: #elif defined(M3G_TARGET_ISA) sl@0: #elif defined(M3G_TARGET_SYMBIAN) sl@0: #elif defined(M3G_TARGET_WIN32) sl@0: #elif defined(S_SPLINT_S) /* auto-recognize Splint as a special case */ sl@0: # define M3G_TARGET_GENERIC sl@0: #else sl@0: # error Build target undefined! Supply one of the M3G_TARGET_* definitions. sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_USE_NGL_API sl@0: * \brief Enable the legacy "NGL" OpenGL context management interface sl@0: */ sl@0: #if defined(M3G_USE_NGL_API) sl@0: # define M3G_NGL_CONTEXT_API sl@0: # define M3G_NGL_TEXTURE_API sl@0: #endif sl@0: sl@0: #if defined(M3G_TARGET_ISA) sl@0: # if !defined(M3G_NGL_CONTEXT_API) sl@0: # error ISA builds must define M3G_USE_NGL_API sl@0: # endif sl@0: #endif sl@0: #if defined(M3G_TARGET_SYMBIAN) sl@0: # if defined(M3G_NGL_TEXTURE_API) || defined(M3G_NGL_CONTEXT_API) sl@0: # error Legacy NGL API not supported in Symbian builds sl@0: # endif sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_ALIGNMENT sl@0: * \brief Alignment, in bytes, mandated for internal data structures sl@0: * sl@0: * This must meet or exceed the alignment requirement of the sl@0: * underlying hardware. The default is 4 bytes. sl@0: */ sl@0: #if !defined(M3G_ALIGNMENT) sl@0: # define M3G_ALIGNMENT 4 sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_MAX_GL_CONTEXTS sl@0: * \brief Maximum number of GL contexts to cache at once sl@0: * sl@0: * \note This only applies to builds using the EGL API. sl@0: */ sl@0: #if !defined(M3G_MAX_GL_CONTEXTS) sl@0: # define M3G_MAX_GL_CONTEXTS 3 sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_MAX_GL_SURFACES sl@0: * \brief Maximum number of GL surfaces to cache at once sl@0: * sl@0: * \note This only applies to builds using the EGL API. sl@0: */ sl@0: #if !defined(M3G_MAX_GL_SURFACES) sl@0: # define M3G_MAX_GL_SURFACES 4 sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_MAX_LIGHTS sl@0: * \brief Maximum number of lights in use simultaneously sl@0: * sl@0: * This is a rendering quality / performance trade-off; less lights sl@0: * will be (slightly) faster, but reduce the quality of lighting. sl@0: * sl@0: * \note The value set here must not exceed the limits of the sl@0: * underlying OpenGL implementation; this is not automatically sl@0: * verified, but the default should be safe for all compliant OpenGL sl@0: * ES implementation sl@0: */ sl@0: #if !defined(M3G_MAX_LIGHTS) sl@0: # define M3G_MAX_LIGHTS 8 sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_MAX_TEXTURE_DIMENSION sl@0: * \brief Maximum supported texture dimension sl@0: * sl@0: * \note The value set here must not exceed the limits of the sl@0: * underlying OpenGL implementation; this is not automatically sl@0: * verified, but the default should be safe for all compliant OpenGL sl@0: * ES implementation sl@0: */ sl@0: #if !defined(M3G_MAX_TEXTURE_DIMENSION) sl@0: # define M3G_MAX_TEXTURE_DIMENSION 256 sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_MAX_VERTEX_TRANSFORMS sl@0: * \brief Maximum number of transforms per vertex sl@0: * sl@0: * \note The value set here must not exceed the limits of the sl@0: * underlying OpenGL implementation; this is not automatically sl@0: * verified sl@0: */ sl@0: #if !defined(M3G_MAX_VERTEX_TRANSFORMS) sl@0: # define M3G_MAX_VERTEX_TRANSFORMS 4 sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_MAX_VIEWPORT_DIMENSION sl@0: * \brief Maximum supported viewport dimension sl@0: * sl@0: * \note The value set here must not exceed the limits of the sl@0: * underlying OpenGL implementation; this is not automatically sl@0: * verified, but the default should be safe for all compliant OpenGL sl@0: * ES implementation sl@0: */ sl@0: #if !defined(M3G_MAX_VIEWPORT_DIMENSION) sl@0: # define M3G_MAX_VIEWPORT_DIMENSION 1024 sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_MAX_VIEWPORT_WIDTH sl@0: * \brief Maximum supported viewport width sl@0: * sl@0: * \note The value set here must not exceed the limits of the sl@0: * underlying OpenGL implementation; this is not automatically sl@0: * verified, but the default should be safe for all compliant OpenGL sl@0: * ES implementation sl@0: */ sl@0: #if !defined(M3G_MAX_VIEWPORT_WIDTH) sl@0: # define M3G_MAX_VIEWPORT_WIDTH 1024 sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_MAX_VIEWPORT_HEIGHT sl@0: * \brief Maximum supported viewport height sl@0: * sl@0: * \note The value set here must not exceed the limits of the sl@0: * underlying OpenGL implementation; this is not automatically sl@0: * verified, but the default should be safe for all compliant OpenGL sl@0: * ES implementation sl@0: */ sl@0: #if !defined(M3G_MAX_VIEWPORT_HEIGHT) sl@0: # define M3G_MAX_VIEWPORT_HEIGHT 1024 sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_NATIVE_LOADER sl@0: * \brief Include a native loader implementation sl@0: * sl@0: * This is always enabled in current builds. sl@0: */ sl@0: #undef M3G_NATIVE_LOADER sl@0: #define M3G_NATIVE_LOADER sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_NUM_TEXTURE_UNITS sl@0: * \brief Number of texture units to support sl@0: * sl@0: * \note The value set here must not exceed the limits of the sl@0: * underlying OpenGL implementation; this is not automatically sl@0: * verified, but the default should be safe for all compliant OpenGL sl@0: * ES implementation sl@0: */ sl@0: #if !defined(M3G_NUM_TEXTURE_UNITS) sl@0: # define M3G_NUM_TEXTURE_UNITS 2 sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_SUPPORT_ANTIALIASING sl@0: * \brief Enable or disable support for antialiasing sl@0: * sl@0: * \note This is currently only supported for Symbian. sl@0: */ sl@0: #if !defined(M3G_SUPPORT_ANTIALIASING) sl@0: # if defined(M3G_NGL_CONTEXT_API) sl@0: # define M3G_SUPPORT_ANTIALIASING M3G_FALSE sl@0: # else sl@0: # define M3G_SUPPORT_ANTIALIASING M3G_TRUE sl@0: # endif sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_SUPPORT_DITHERING sl@0: * \brief Enable or disable support for dithering sl@0: */ sl@0: #if !defined(M3G_SUPPORT_DITHERING) sl@0: # define M3G_SUPPORT_DITHERING M3G_FALSE sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_SUPPORT_LOCAL_CAMERA_LIGHTING sl@0: * \brief Enable or disable support for local camera lighting sl@0: */ sl@0: #if !defined(M3G_SUPPORT_LOCAL_CAMERA_LIGHTING) sl@0: # define M3G_SUPPORT_LOCAL_CAMERA_LIGHTING M3G_FALSE sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_SUPPORT_MIPMAPPING sl@0: * \brief Enable or disable support for mipmapping sl@0: */ sl@0: #if !defined(M3G_SUPPORT_MIPMAPPING) sl@0: # define M3G_SUPPORT_MIPMAPPING M3G_TRUE sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_SUPPORT_PERSPECTIVE_CORRECTION sl@0: * \brief Enable or disable support for perspective correct texturing sl@0: */ sl@0: #if !defined(M3G_SUPPORT_PERSPECTIVE_CORRECTION) sl@0: # define M3G_SUPPORT_PERSPECTIVE_CORRECTION M3G_TRUE sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_SUPPORT_TRUE_COLOR sl@0: * \brief Enable or disable support for "true color" rendering sl@0: */ sl@0: #if !defined(M3G_SUPPORT_TRUE_COLOR) sl@0: # define M3G_SUPPORT_TRUE_COLOR M3G_FALSE sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_USE_16BIT_TEXTURES sl@0: * \brief Use 16-bit RGB textures internally to save memory sl@0: * sl@0: * This may reduce in some loss of performance, so it is defined sl@0: * M3G_FALSE by default. sl@0: */ sl@0: #if !defined(M3G_USE_16BIT_TEXTURES) sl@0: # define M3G_USE_16BIT_TEXTURES M3G_FALSE sl@0: #endif sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_LOGLEVEL sl@0: * sl@0: * \brief Controls the amount of log output sl@0: * sl@0: * Log output can be enabled by defining M3G_LOGLEVEL in m3g_config.h. sl@0: * It must be set to a bitmask indicating which categories of log sl@0: * messages to output. Fatal internal errors are always output when sl@0: * M3G_LOGLEVEL is defined; other kinds of messages can be included by sl@0: * setting it to any combination of the following in m3g_config.h: sl@0: * sl@0: * M3G_LOG_FATAL_ERRORS fatal internal errors (equals 0) sl@0: * M3G_LOG_USER_ERRORS user errors (the same as reported sl@0: * via m3gGetError) sl@0: * M3G_LOG_WARNINGS performance warnings sl@0: * M3G_LOG_PROFILE profiling counters sl@0: * M3G_LOG_INTERFACE interface construction/destruction events sl@0: * M3G_LOG_OBJECTS object construction/destruction events sl@0: * M3G_LOG_STAGES log processing stages (animate, render, etc.) sl@0: * M3G_LOG_REFCOUNT reference count operations sl@0: * M3G_LOG_MEMORY_USAGE memory usage counters sl@0: * M3G_LOG_MEMORY_BLOCKS memory block allocs/deallocs sl@0: * M3G_LOG_MEMORY_ALL output everything memory-related sl@0: * M3G_LOG_RENDERING log rendering details sl@0: * M3G_LOG_IMAGES log image memory usage details sl@0: * sl@0: * \note The amount of log output may be limited in non-debug builds. sl@0: */ sl@0: sl@0: /*! sl@0: * \internal sl@0: * \def M3G_PROFILE_LOG_INTERVAL sl@0: * \brief Profile logging interval sl@0: * sl@0: * Number of frames to wait between outputting (and resetting!) the sl@0: * profiling counters. Zero (default) disables profile logging. sl@0: */ sl@0: #if !defined(M3G_PROFILE_LOG_INTERVAL) sl@0: # define M3G_PROFILE_LOG_INTERVAL 0 sl@0: #endif sl@0: sl@0: /*---------------------------------------------------------------------- sl@0: * Debug build setup sl@0: *--------------------------------------------------------------------*/ sl@0: sl@0: /* General settings enabled in debug builds */ sl@0: #if defined(M3G_DEBUG) sl@0: # define M3G_DEBUG_ASSERTS sl@0: # define M3G_DEBUG_RANGE_CHECKING sl@0: # define M3G_DEBUG_HEAP_TRACKING sl@0: #endif sl@0: sl@0: /*---------------------------------------------------------------------- sl@0: * Compiler dependent definitions sl@0: *--------------------------------------------------------------------*/ sl@0: sl@0: /* Try to recognize the compiler */ sl@0: #if !defined(M3G_NO_COMPILER_DETECTION) sl@0: # if (defined (_MSC_VER) || defined(__VC32__))&& !defined(__MWERKS__) /* Microsoft Visual C++ */ sl@0: # undef M3G_BUILD_MSVC sl@0: # define M3G_BUILD_MSVC sl@0: # elif defined(__ARMCC_VERSION) /* ARM Developer Suite */ sl@0: # undef M3G_BUILD_ADS sl@0: # define M3G_BUILD_ADS sl@0: # elif defined(__BORLANDC__) /* Borland C++ */ sl@0: # undef M3G_BUILD_BORLAND sl@0: # define M3G_BUILD_BORLAND sl@0: # elif defined(__MWERKS__) || defined(__CW32__) /* CodeWarrior */ sl@0: # undef M3G_BUILD_CW sl@0: # define M3G_BUILD_CW sl@0: # elif defined(__GNUC__) || defined(__GCC32__) /* GNU C */ sl@0: # undef M3G_BUILD_GCC sl@0: # define M3G_BUILD_GCC sl@0: # elif defined(__ARMCC__) /* RVCT */ sl@0: # undef M3G_BUILD_RVCT sl@0: # define M3G_BUILD_RVCT sl@0: # elif defined(S_SPLINT_S) /* Splint */ sl@0: # undef M3G_BUILD_SPLINT sl@0: # define M3G_BUILD_SPLINT sl@0: # else sl@0: # error Could not identify the compiler. Please refer to m3g_defs.h for more information. sl@0: # endif sl@0: #endif sl@0: sl@0: /* Try to recognize thumb/arm */ sl@0: #if defined(M3G_BUILD_ADS) sl@0: # if defined(__thumb) sl@0: # define M3G_BUILD_THUMB sl@0: # else sl@0: # define M3G_BUILD_ARM sl@0: # endif sl@0: #endif sl@0: sl@0: /* Set up compiler-dependent definitions */ sl@0: sl@0: /*@-macroparams@*/ sl@0: /*@notfunction@*/ sl@0: /*! sl@0: * \internal \brief Macro used to denote Splint constraints */ sl@0: #define M3G_SPLINT(def) sl@0: /*@+macroparams@*/ sl@0: sl@0: /*! sl@0: * \internal \def M3G_INLINE sl@0: * \brief Platform-independent inline function specifier sl@0: */ sl@0: sl@0: #if defined(M3G_BUILD_MSVC) sl@0: # define M3G_INLINE __inline sl@0: # pragma warning (disable:4127) /* 4127: conditional expression is constant */ sl@0: # pragma warning (disable:4514) /* 4514: unreferenced inline function has been removed */ sl@0: # pragma warning (disable:4710) /* 4710: function not inlined */ sl@0: sl@0: #elif defined (M3G_BUILD_ADS) sl@0: # define M3G_INLINE __inline sl@0: sl@0: #elif defined(M3G_BUILD_BORLAND) sl@0: # define M3G_INLINE __inline sl@0: sl@0: #elif defined(M3G_BUILD_CW) sl@0: # define M3G_INLINE sl@0: sl@0: #elif defined(M3G_BUILD_GCC) sl@0: # define M3G_INLINE inline sl@0: sl@0: #elif defined(M3G_BUILD_RVCT) sl@0: # define M3G_INLINE __inline sl@0: sl@0: #elif defined(M3G_BUILD_SPLINT) sl@0: # define M3G_INLINE sl@0: # undef M3G_SPLINT sl@0: /*@notfunction@*/ sl@0: # define M3G_SPLINT(def) def sl@0: sl@0: # undef M3G_DEBUG sl@0: /*# define M3G_DEBUG*/ sl@0: sl@0: #else /* generic fallback */ sl@0: # define M3G_INLINE sl@0: sl@0: #endif sl@0: sl@0: /* Optionally cancel non-portable definitions. This is mainly to sl@0: * facilitate portability checking with GCC, which defines __STDC__ sl@0: * even in non-ANSI mode) */ sl@0: sl@0: #if defined(M3G_STRICT_STDC) sl@0: # undef M3G_INLINE sl@0: # define M3G_INLINE sl@0: #endif sl@0: sl@0: /*---------------------------------------------------------------------- sl@0: * Identify GL version sl@0: *--------------------------------------------------------------------*/ sl@0: #if defined(GL_VERSION_ES_CM_1_1) || defined(GL_OES_VERSION_1_1) sl@0: # define M3G_GL_ES_1_1 sl@0: #endif sl@0: sl@0: /*---------------------------------------------------------------------- sl@0: * Internal configuration and performance tuning parameters sl@0: *--------------------------------------------------------------------*/ sl@0: sl@0: #define M3G_RENDERQUEUE_BUCKET_BITS 8 sl@0: #define M3G_ENABLE_VF_CULLING sl@0: #define M3G_GL_FORCE_PBUFFER_SIZE sl@0: sl@0: /*---------------------------------------------------------------------- sl@0: * Standard C library sl@0: *--------------------------------------------------------------------*/ sl@0: sl@0: #if defined(M3G_NO_STDLIB) sl@0: # define NULL 0 sl@0: typedef M3Guint M3Gsize; sl@0: #else sl@0: # include <stdlib.h> sl@0: typedef size_t M3Gsize; sl@0: #endif sl@0: sl@0: /*---------------------------------------------------------------------- sl@0: * Run time and compile time assertions sl@0: *--------------------------------------------------------------------*/ sl@0: sl@0: /*! sl@0: * \internal \def M3G_ASSERT(a) sl@0: * \brief Run-time assertion sl@0: */ sl@0: #if defined(M3G_DEBUG_ASSERTS) sl@0: sl@0: extern void m3gAssertFailed(const char *filename, int line); sl@0: #define M3G_ASSERT(cond) \ sl@0: do { \ sl@0: if (!(cond)) m3gAssertFailed(__FILE__, __LINE__); \ sl@0: } while (M3G_FALSE) sl@0: sl@0: M3G_SPLINT(extern /*@noreturnwhenfalse@*/ void M3G_ASSERT(/*@sef@*//*@null@*/ M3Gbool /*@alt const void*@*/ cond)/*@*/;) sl@0: sl@0: #else sl@0: sl@0: /*@-macroparams@*/ sl@0: # define M3G_ASSERT(cond) sl@0: /*@+macroparams@*/ sl@0: M3G_SPLINT(extern /*@noreturnwhenfalse@*/ void M3G_ASSERT(/*@sef@*//*@null@*//*@unused@*/ M3Gbool /*@alt const void*@*/ cond)/*@*/;) sl@0: sl@0: #endif /* M3G_DEBUG */ sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Compile-time assertion sl@0: */ sl@0: /*@notfunction@*/ sl@0: #define M3G_CT_ASSERT(a) struct __M3G_UNIQUE_NAME { unsigned bf : (a) ? 1 : -1; } sl@0: /*@notfunction@*/ sl@0: #define __M3G_UNIQUE_NAME __M3G_MAKE_UNIQUE_NAME(__LINE__, 0) sl@0: /*@notfunction@*/ sl@0: #define __M3G_MAKE_UNIQUE_NAME(line, num) __M3G_MAKE_UNIQUE_NAME2(line, num) sl@0: /*@notfunction@*/ sl@0: #define __M3G_MAKE_UNIQUE_NAME2(line, num) m3gCTassert ## num ## line sl@0: sl@0: /*@notfunction@*/ sl@0: #define M3G_CT_ASSERT1(a) struct __M3G_UNIQUE_NAME1 { unsigned bf : (a) ? 1 : -1; } sl@0: /*@notfunction@*/ sl@0: #define __M3G_UNIQUE_NAME1 M3G_MAKE_UNIQUE_NAME(__LINE__, 1) sl@0: sl@0: /*@notfunction@*/ sl@0: #define M3G_CT_ASSERT2(a) struct __M3G_UNIQUE_NAME2 { unsigned bf : (a) ? 1 : -1; } sl@0: /*@notfunction@*/ sl@0: #define __M3G_UNIQUE_NAME2 __M3G_MAKE_UNIQUE_NAME(__LINE__, 2) sl@0: sl@0: #if defined(M3G_DEBUG_RANGE_CHECKING) sl@0: #define M3G_ASSERT_RANGE(val, min, max) M3G_ASSERT(m3gInRange((val), (min), (max))) sl@0: #else sl@0: /*@-macroparams@*/ sl@0: #define M3G_ASSERT_RANGE(val, min, max) sl@0: /*@+macroparams@*/ sl@0: #endif sl@0: sl@0: /*---------------------------------------------------------------------- sl@0: * Verify any global definitions, expected type sizes etc. sl@0: *--------------------------------------------------------------------*/ sl@0: sl@0: #if !defined(M3G_INLINE) sl@0: # error M3G_INLINE not defined in platform definitions! sl@0: #endif sl@0: sl@0: #if !defined(M3G_ALIGNMENT) sl@0: # error M3G_ALIGNMENT not defined in platform definitions! sl@0: #endif sl@0: sl@0: #if ((M3G_ALIGNMENT & (M3G_ALIGNMENT-1)) != 0) sl@0: # error M3G_ALIGNMENT is not a power of two! sl@0: #endif sl@0: sl@0: #if defined(M3G_TARGET_ISA) && !defined(M3G_USE_NGL_API) sl@0: # error ISA targets currently supported with M3G_USE_NGL_API only! sl@0: #endif sl@0: sl@0: #if (defined(M3G_NGL_CONTEXT_API) && !defined(M3G_NGL_TEXTURE_API)) \ sl@0: || (defined(M3G_NGL_TEXTURE_API) && !defined(M3G_NGL_CONTEXT_API)) sl@0: # if !defined(M3G_DEBUG) sl@0: # error Nonstandard NGL configurations only allowed in debug builds! sl@0: # endif sl@0: #endif sl@0: sl@0: /* Verify our expected type sizes */ sl@0: M3G_CT_ASSERT(sizeof(M3Gbyte) == 1); sl@0: M3G_CT_ASSERT(sizeof(M3Gubyte) == 1); sl@0: M3G_CT_ASSERT(sizeof(M3Gshort) == 2); sl@0: M3G_CT_ASSERT(sizeof(M3Gushort) == 2); sl@0: M3G_CT_ASSERT(sizeof(M3Gint) == 4); sl@0: M3G_CT_ASSERT(sizeof(M3Guint) == 4); sl@0: M3G_CT_ASSERT(sizeof(M3Gfloat) == 4); sl@0: sl@0: /* Unsigned is used extensively as a wrapper for object pointers, so sl@0: * check that we can fit a pointer in there */ sl@0: M3G_CT_ASSERT(sizeof(M3Guint) >= sizeof(void*)); sl@0: sl@0: /* sl@0: * Globally disable some redundant Lint messages sl@0: */ sl@0: sl@0: /*lint -e701 Signed shifts left should never be a problem */ sl@0: /*lint -e702 Signed shifts right are run-time verified (m3g_interface.c) */ sl@0: sl@0: /*---------------------------------------------------------------------- sl@0: * Event logging sl@0: *--------------------------------------------------------------------*/ sl@0: sl@0: #if !defined(M3G_LOGLEVEL) sl@0: # define M3G_LOG(level, msg) ((void)(level), (void)(msg)) sl@0: # define M3G_LOG1(level, msg, a) ((void)(level), (void)(msg), (void)(a)) sl@0: # define M3G_LOG2(level, msg, a, b) ((void)(level), (void)(msg), (void)(a), (void)(b)) sl@0: # define M3G_LOG3(level, msg, a, b, c) ((void)(level), (void)(msg), (void)(a), (void)(b), (void)(c)) sl@0: # define M3G_LOG4(level, msg, a, b, c, d) ((void)(level), (void)(msg), (void)(a), (void)(b), (void)(c), (void)(d)) sl@0: # define M3G_LOG5(level, msg, a, b, c, d, e) ((void)(level), (void)(msg), (void)(a), (void)(b), (void)(c), (void)(d), (void)(e)) sl@0: #else sl@0: void m3gBeginLog(void); sl@0: void m3gLogMessage(const char *format, ...); sl@0: void m3gEndLog(void); sl@0: # define M3G_LOG(level, msg) \ sl@0: do { if ((level) & (M3G_LOGLEVEL)) m3gLogMessage((msg)); } while (M3G_FALSE) sl@0: # define M3G_LOG1(level, msg, a) \ sl@0: do { if ((level) & (M3G_LOGLEVEL)) m3gLogMessage((msg), (a)); } while (M3G_FALSE) sl@0: # define M3G_LOG2(level, msg, a, b) \ sl@0: do { if ((level) & (M3G_LOGLEVEL)) m3gLogMessage((msg), (a), (b)); } while (M3G_FALSE) sl@0: # define M3G_LOG3(level, msg, a, b, c) \ sl@0: do { if ((level) & (M3G_LOGLEVEL)) m3gLogMessage((msg), (a), (b), (c)); } while (M3G_FALSE) sl@0: # define M3G_LOG4(level, msg, a, b, c, d) \ sl@0: do { if ((level) & (M3G_LOGLEVEL)) m3gLogMessage((msg), (a), (b), (c), (d)); } while (M3G_FALSE) sl@0: # define M3G_LOG5(level, msg, a, b, c, d, e) \ sl@0: do { if ((level) & (M3G_LOGLEVEL)) m3gLogMessage((msg), (a), (b), (c), (d), (e)); } while (M3G_FALSE) sl@0: #endif sl@0: sl@0: /*---------------------------------------------------------------------- sl@0: * Useful stuff sl@0: *--------------------------------------------------------------------*/ sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Range checking inline function sl@0: * sl@0: * \param a Value to check sl@0: * \param min Lower bound, inclusive sl@0: * \param max Upper bound, inclusive sl@0: */ sl@0: static M3G_INLINE M3Gbool m3gInRange(M3Gint a, M3Gint min, M3Gint max) sl@0: { sl@0: return ((M3Guint)(a - min) <= (M3Guint)(max - min)); sl@0: } sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Range checking for floats sl@0: */ sl@0: static M3G_INLINE M3Gbool m3gInRangef(M3Gfloat a, M3Gfloat min, M3Gfloat max) sl@0: { sl@0: return (a >= min && a <= max); sl@0: } sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Clamping function for floats sl@0: * sl@0: * \param a Value to clamp sl@0: * \param min Minimum value sl@0: * \param max Maximum value sl@0: */ sl@0: static M3G_INLINE M3Gfloat m3gClampFloat(M3Gfloat a, M3Gfloat min, M3Gfloat max) sl@0: { sl@0: return (a <= min) ? min : (a >= max) ? max : a; sl@0: } sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Clamping function for floats sl@0: * sl@0: * \param a Value to clamp sl@0: */ sl@0: static M3G_INLINE M3Gfloat m3gClampFloatPositive(M3Gfloat a) sl@0: { sl@0: return (a <= 0) ? 0 : a; sl@0: } sl@0: sl@0: /*! sl@0: * \internal sl@0: */ sl@0: static M3G_INLINE M3Gint m3gClampInt(M3Gint a, M3Gint min, M3Gint max) sl@0: { sl@0: return (a <= min) ? min : (a >= max) ? max : a; sl@0: } sl@0: sl@0: /*! sl@0: * \internal sl@0: * sl@0: */ sl@0: static M3G_INLINE M3Gbool m3gIsPowerOfTwo(M3Guint a) sl@0: { sl@0: return ((a & (a-1)) == 0u); sl@0: } sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Returns the smallest power of two greater than or equal to a sl@0: * given integer sl@0: * sl@0: * \note Only works with positive numbers of 2^30 or less sl@0: */ sl@0: static M3G_INLINE M3Gint m3gNextPowerOfTwo(M3Gint x) sl@0: { sl@0: M3Gint y = 1; sl@0: M3G_ASSERT(m3gInRange(x, 0, 1 << 30)); sl@0: while (y < x) { sl@0: y <<= 1; sl@0: } sl@0: return y; sl@0: } sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Indicate (intentionally) unreferenced parameters sl@0: * sl@0: * This is used on virtual functions, where not every implementation sl@0: * uses all the arguments. sl@0: */ sl@0: /*@notfunction@*/ sl@0: #define M3G_UNREF(a) ((void)(a)) /*@*/ sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Clamp a value to signed 8-bit range sl@0: */ sl@0: #define M3G_CLAMP_BYTE(a) ((M3Gbyte) ((a) < -128 ? -128 : ((a) > 127 ? 127 : (a)))) sl@0: M3G_SPLINT(extern M3Gbyte M3G_CLAMP_BYTE(/*@sef@*/ int a);) sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Clamp a value to signed 16-bit range sl@0: */ sl@0: #define M3G_CLAMP_SHORT(a) ((M3Gshort) ((a) < -32768 ? -32768 : ((a) > 32767 ? 32767 : (a)))) sl@0: M3G_SPLINT(extern M3Gshort M3G_CLAMP_SHORT(/*@sef@*/ int a);) sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Clamp a value to unsigned 8-bit range sl@0: */ sl@0: #define M3G_CLAMP_UBYTE(a) ((M3Gubyte) ((a) < 0 ? 0 : ((a) > 255 ? 255 : (a)))) sl@0: M3G_SPLINT(extern M3Gubyte M3G_CLAMP_UBYTE(/*@sef@*/ int a);) sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Clamp a value to unsigned 16-bit range sl@0: */ sl@0: #define M3G_CLAMP_USHORT(a) ((M3Gushort)((a) < 0 ? 0 : ((a) > 65535 ? 65535 : (a)))) sl@0: M3G_SPLINT(extern M3Gushort M3G_CLAMP_USHORT(/*@sef@*/ int a);) sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Offset any pointer by a given number of bytes sl@0: */ sl@0: #define M3G_OFFSET_PTR(ptr, bytes) (void*)(((M3Gbyte*)(ptr)) + bytes) sl@0: sl@0: /* Min & max macros and inline functions sl@0: * sl@0: * The inline function may be better optimized when one or both of the sl@0: * arguments are expressions */ sl@0: sl@0: #define M3G_MIN(a, b) ((a) <= (b) ? (a) : (b)) sl@0: #define M3G_MAX(a, b) ((a) >= (b) ? (a) : (b)) sl@0: sl@0: static M3G_INLINE M3Gint m3gMaxInt(M3Gint a, M3Gint b) sl@0: { sl@0: return M3G_MAX(a, b); sl@0: } sl@0: sl@0: static M3G_INLINE M3Gint m3gMinInt(M3Gint a, M3Gint b) sl@0: { sl@0: return M3G_MIN(a, b); sl@0: } sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief RGB mask sl@0: */ sl@0: #define M3G_RGB_MASK 0x00FFFFFFu sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Alpha mask sl@0: */ sl@0: #define M3G_ALPHA_MASK 0xFF000000u sl@0: sl@0: /*---------------------------------------------------------------------- sl@0: * Data alignment macros sl@0: *--------------------------------------------------------------------*/ sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Align a pointer or size value to an N-byte boundary sl@0: * sl@0: * @param value Value to align. sl@0: * @param size Alignment size; must be a power of two sl@0: */ sl@0: #define M3G_ALIGN_TO(value, size) ((((unsigned) (value)) + ((size) - 1)) & ~((size) - 1)) sl@0: M3G_SPLINT(extern int M3G_ALIGN_TO(int /*@alt size_t@*/ value, /*@sef@*/ int size);) sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Returns a truth value for whether a pointer is aligned or not sl@0: */ sl@0: #define M3G_IS_ALIGNED(ptr) ((((unsigned)(ptr)) & (M3G_ALIGNMENT-1)) == 0) sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Assert proper alignment of a pointer sl@0: * sl@0: * Currently, we assume alignment to 4-byte boundaries. sl@0: */ sl@0: #define M3G_ASSERT_ALIGNMENT(ptr) M3G_ASSERT(M3G_IS_ALIGNED(ptr)) sl@0: sl@0: /*! sl@0: * \internal sl@0: * \brief Asserts that a pointer is both non-null and aligned sl@0: */ sl@0: #define M3G_ASSERT_PTR(ptr) M3G_ASSERT((ptr) != NULL && M3G_IS_ALIGNED(ptr)) sl@0: #define M3G_VALIDATE_PTR(ptr) M3G_ASSERT_PTR(ptr) sl@0: sl@0: /*---------------------------------------------------------------------- sl@0: * Easier names for math classes... sl@0: *--------------------------------------------------------------------*/ sl@0: sl@0: typedef M3GMatrix Matrix; sl@0: typedef M3GQuat Quat; sl@0: typedef M3GVec3 Vec3; sl@0: typedef M3GVec4 Vec4; sl@0: typedef M3GRectangle Rect; sl@0: sl@0: /* We rely on the layout of a Vec4 or a Quat matching an array of 4 sl@0: * floats in a number of places, so check that */ sl@0: sl@0: M3G_CT_ASSERT(sizeof(M3GVec4) == 4 * sizeof(M3Gfloat)); sl@0: M3G_CT_ASSERT(sizeof(M3GQuat) == 4 * sizeof(M3Gfloat)); sl@0: sl@0: #if defined(__cplusplus) sl@0: } /* extern "C" */ sl@0: #endif sl@0: sl@0: #endif /*__M3G_DEFS_H__*/