os/graphics/m3g/m3gcore11/inc/m3g_defs.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: Global definitions
    15 *
    16 */
    17 
    18 #ifndef __M3G_DEFS_H__
    19 #define __M3G_DEFS_H__
    20 
    21 /*!
    22  * \internal
    23  * \file
    24  * \brief Global definitions for the Nokia M3G API implementation
    25  */
    26 
    27 /* Include public API */
    28 #include "M3G/m3g_core.h"
    29 
    30 #if defined(__cplusplus)
    31 extern "C" {
    32 #endif
    33 
    34 /* Try to recognize debug builds */
    35 #if defined(_DEBUG) || defined(DEBUG)
    36 #undef M3G_DEBUG
    37 #define M3G_DEBUG
    38 #endif
    39 
    40 /*----------------------------------------------------------------------
    41  * Platform dependent definitions
    42  *--------------------------------------------------------------------*/
    43 
    44 /* Define constants for use in m3g_config.h */
    45     
    46 #define M3G_LOG_FATAL_ERRORS    0x0001
    47 #define M3G_LOG_USER_ERRORS     0x0002
    48 #define M3G_LOG_WARNINGS        0x0003
    49 #define M3G_LOG_PROFILE         0x0004
    50 #define M3G_LOG_INTERFACE       0x0010
    51 #define M3G_LOG_OBJECTS         0x0020
    52 #define M3G_LOG_STAGES          0x0040
    53 #define M3G_LOG_REFCOUNT        0x0080
    54 #define M3G_LOG_MEMORY_USAGE    0x0100
    55 #define M3G_LOG_MEMORY_BLOCKS   0x0200
    56 #define M3G_LOG_MEMORY_MAPPING  0x0400
    57 #define M3G_LOG_MEMORY_ALL      0x0F00
    58 #define M3G_LOG_RENDERING       0x1000
    59 #define M3G_LOG_IMAGES          0x2000
    60 #define M3G_LOG_ALL             0xFFFF
    61     
    62 /* Include the platform configuration file; the possible configuration
    63  * options are documented and their default values set below */
    64     
    65 #include "m3g_config.h"
    66 
    67 /*!
    68  * \internal
    69  * \def M3G_TARGET_GENERIC
    70  * \brief Enables a generic C build
    71  */   
    72 /*!
    73  * \internal
    74  * \def M3G_TARGET_ISA
    75  * \brief Enables building for ISA
    76  */   
    77 /*!
    78  * \internal
    79  * \def M3G_TARGET_SYMBIAN
    80  * \brief Enables building for Symbian
    81  */
    82 /*!
    83  * \internal
    84  * \def M3G_TARGET_WIN32
    85  * \brief Enables building for Win32
    86  */      
    87 #if defined(M3G_TARGET_GENERIC)
    88 #elif defined(M3G_TARGET_ISA)
    89 #elif defined(M3G_TARGET_SYMBIAN)
    90 #elif defined(M3G_TARGET_WIN32)
    91 #elif defined(S_SPLINT_S) /* auto-recognize Splint as a special case */
    92 #   define M3G_TARGET_GENERIC
    93 #else
    94 #   error Build target undefined! Supply one of the M3G_TARGET_* definitions.
    95 #endif
    96     
    97 /*!
    98  * \internal
    99  * \def M3G_USE_NGL_API
   100  * \brief Enable the legacy "NGL" OpenGL context management interface
   101  */
   102 #if defined(M3G_USE_NGL_API)
   103 #   define M3G_NGL_CONTEXT_API
   104 #   define M3G_NGL_TEXTURE_API
   105 #endif
   106     
   107 #if defined(M3G_TARGET_ISA)
   108 #   if !defined(M3G_NGL_CONTEXT_API)
   109 #       error ISA builds must define M3G_USE_NGL_API
   110 #   endif
   111 #endif   
   112 #if defined(M3G_TARGET_SYMBIAN)
   113 #   if defined(M3G_NGL_TEXTURE_API) || defined(M3G_NGL_CONTEXT_API)
   114 #       error Legacy NGL API not supported in Symbian builds
   115 #   endif
   116 #endif
   117     
   118 /*!
   119  * \internal
   120  * \def M3G_ALIGNMENT
   121  * \brief Alignment, in bytes, mandated for internal data structures
   122  *
   123  * This must meet or exceed the alignment requirement of the
   124  * underlying hardware. The default is 4 bytes.
   125  */
   126 #if !defined(M3G_ALIGNMENT)
   127 #   define M3G_ALIGNMENT        4
   128 #endif
   129 
   130 /*!
   131  * \internal
   132  * \def M3G_MAX_GL_CONTEXTS
   133  * \brief Maximum number of GL contexts to cache at once
   134  *
   135  * \note This only applies to builds using the EGL API.
   136  */
   137 #if !defined(M3G_MAX_GL_CONTEXTS)
   138 #   define M3G_MAX_GL_CONTEXTS  3
   139 #endif
   140 
   141 /*!
   142  * \internal
   143  * \def M3G_MAX_GL_SURFACES
   144  * \brief Maximum number of GL surfaces to cache at once
   145  *
   146  * \note This only applies to builds using the EGL API.
   147  */
   148 #if !defined(M3G_MAX_GL_SURFACES)
   149 #   define M3G_MAX_GL_SURFACES  4
   150 #endif
   151 
   152 /*!
   153  * \internal
   154  * \def M3G_MAX_LIGHTS
   155  * \brief Maximum number of lights in use simultaneously
   156  *
   157  * This is a rendering quality / performance trade-off; less lights
   158  * will be (slightly) faster, but reduce the quality of lighting.
   159  * 
   160  * \note The value set here must not exceed the limits of the
   161  * underlying OpenGL implementation; this is not automatically
   162  * verified, but the default should be safe for all compliant OpenGL
   163  * ES implementation
   164  */
   165 #if !defined(M3G_MAX_LIGHTS)
   166 #   define M3G_MAX_LIGHTS       8
   167 #endif
   168 
   169 /*!
   170  * \internal
   171  * \def M3G_MAX_TEXTURE_DIMENSION
   172  * \brief Maximum supported texture dimension
   173  *
   174  * \note The value set here must not exceed the limits of the
   175  * underlying OpenGL implementation; this is not automatically
   176  * verified, but the default should be safe for all compliant OpenGL
   177  * ES implementation
   178  */
   179 #if !defined(M3G_MAX_TEXTURE_DIMENSION)
   180 #   define M3G_MAX_TEXTURE_DIMENSION    256
   181 #endif
   182     
   183 /*!
   184  * \internal
   185  * \def M3G_MAX_VERTEX_TRANSFORMS
   186  * \brief Maximum number of transforms per vertex
   187  *
   188  * \note The value set here must not exceed the limits of the
   189  * underlying OpenGL implementation; this is not automatically
   190  * verified
   191  */
   192 #if !defined(M3G_MAX_VERTEX_TRANSFORMS)
   193 #   define M3G_MAX_VERTEX_TRANSFORMS    4
   194 #endif
   195 
   196 /*!
   197  * \internal
   198  * \def M3G_MAX_VIEWPORT_DIMENSION
   199  * \brief Maximum supported viewport dimension
   200  *
   201  * \note The value set here must not exceed the limits of the
   202  * underlying OpenGL implementation; this is not automatically
   203  * verified, but the default should be safe for all compliant OpenGL
   204  * ES implementation
   205  */
   206 #if !defined(M3G_MAX_VIEWPORT_DIMENSION)
   207 #   define M3G_MAX_VIEWPORT_DIMENSION   1024
   208 #endif
   209 
   210 /*!
   211  * \internal
   212  * \def M3G_MAX_VIEWPORT_WIDTH
   213  * \brief Maximum supported viewport width
   214  *
   215  * \note The value set here must not exceed the limits of the
   216  * underlying OpenGL implementation; this is not automatically
   217  * verified, but the default should be safe for all compliant OpenGL
   218  * ES implementation
   219  */
   220 #if !defined(M3G_MAX_VIEWPORT_WIDTH)
   221 #   define M3G_MAX_VIEWPORT_WIDTH       1024
   222 #endif
   223 
   224 /*!
   225  * \internal
   226  * \def M3G_MAX_VIEWPORT_HEIGHT
   227  * \brief Maximum supported viewport height
   228  *
   229  * \note The value set here must not exceed the limits of the
   230  * underlying OpenGL implementation; this is not automatically
   231  * verified, but the default should be safe for all compliant OpenGL
   232  * ES implementation
   233  */
   234 #if !defined(M3G_MAX_VIEWPORT_HEIGHT)
   235 #   define M3G_MAX_VIEWPORT_HEIGHT      1024
   236 #endif
   237 
   238 /*!
   239  * \internal
   240  * \def M3G_NATIVE_LOADER
   241  * \brief Include a native loader implementation
   242  *
   243  * This is always enabled in current builds.
   244  */
   245 #undef M3G_NATIVE_LOADER
   246 #define M3G_NATIVE_LOADER
   247     
   248 /*!
   249  * \internal
   250  * \def M3G_NUM_TEXTURE_UNITS
   251  * \brief Number of texture units to support
   252  *
   253  * \note The value set here must not exceed the limits of the
   254  * underlying OpenGL implementation; this is not automatically
   255  * verified, but the default should be safe for all compliant OpenGL
   256  * ES implementation
   257  */
   258 #if !defined(M3G_NUM_TEXTURE_UNITS)
   259 #   define M3G_NUM_TEXTURE_UNITS        2
   260 #endif
   261 
   262 /*!
   263  * \internal
   264  * \def M3G_SUPPORT_ANTIALIASING
   265  * \brief Enable or disable support for antialiasing
   266  *
   267  * \note This is currently only supported for Symbian.
   268  */
   269 #if !defined(M3G_SUPPORT_ANTIALIASING)
   270 #   if defined(M3G_NGL_CONTEXT_API)
   271 #       define M3G_SUPPORT_ANTIALIASING         M3G_FALSE
   272 #   else
   273 #       define M3G_SUPPORT_ANTIALIASING         M3G_TRUE
   274 #   endif
   275 #endif
   276 
   277 /*!
   278  * \internal
   279  * \def M3G_SUPPORT_DITHERING
   280  * \brief Enable or disable support for dithering
   281  */
   282 #if !defined(M3G_SUPPORT_DITHERING)
   283 #   define M3G_SUPPORT_DITHERING                M3G_FALSE
   284 #endif
   285 
   286 /*!
   287  * \internal
   288  * \def M3G_SUPPORT_LOCAL_CAMERA_LIGHTING
   289  * \brief Enable or disable support for local camera lighting
   290  */
   291 #if !defined(M3G_SUPPORT_LOCAL_CAMERA_LIGHTING)
   292 #   define M3G_SUPPORT_LOCAL_CAMERA_LIGHTING    M3G_FALSE
   293 #endif
   294 
   295 /*!
   296  * \internal
   297  * \def M3G_SUPPORT_MIPMAPPING
   298  * \brief Enable or disable support for mipmapping
   299  */
   300 #if !defined(M3G_SUPPORT_MIPMAPPING)
   301 #   define M3G_SUPPORT_MIPMAPPING               M3G_TRUE
   302 #endif
   303 
   304 /*!
   305  * \internal
   306  * \def M3G_SUPPORT_PERSPECTIVE_CORRECTION
   307  * \brief Enable or disable support for perspective correct texturing
   308  */
   309 #if !defined(M3G_SUPPORT_PERSPECTIVE_CORRECTION)
   310 #   define M3G_SUPPORT_PERSPECTIVE_CORRECTION   M3G_TRUE
   311 #endif
   312 
   313 /*!
   314  * \internal
   315  * \def M3G_SUPPORT_TRUE_COLOR
   316  * \brief Enable or disable support for "true color" rendering
   317  */
   318 #if !defined(M3G_SUPPORT_TRUE_COLOR)
   319 #   define M3G_SUPPORT_TRUE_COLOR               M3G_FALSE
   320 #endif
   321 
   322 /*!
   323  * \internal
   324  * \def M3G_USE_16BIT_TEXTURES
   325  * \brief Use 16-bit RGB textures internally to save memory
   326  *
   327  * This may reduce in some loss of performance, so it is defined
   328  * M3G_FALSE by default.
   329  */
   330 #if !defined(M3G_USE_16BIT_TEXTURES)
   331 #   define M3G_USE_16BIT_TEXTURES               M3G_FALSE
   332 #endif
   333     
   334 /*!
   335  * \internal
   336  * \def M3G_LOGLEVEL
   337  * 
   338  * \brief Controls the amount of log output
   339  *
   340  * Log output can be enabled by defining M3G_LOGLEVEL in m3g_config.h.
   341  * It must be set to a bitmask indicating which categories of log
   342  * messages to output.  Fatal internal errors are always output when
   343  * M3G_LOGLEVEL is defined; other kinds of messages can be included by
   344  * setting it to any combination of the following in m3g_config.h:
   345  *
   346  *  M3G_LOG_FATAL_ERRORS    fatal internal errors (equals 0)
   347  *  M3G_LOG_USER_ERRORS     user errors (the same as reported
   348  *                          via m3gGetError)
   349  *  M3G_LOG_WARNINGS        performance warnings
   350  *  M3G_LOG_PROFILE         profiling counters
   351  *  M3G_LOG_INTERFACE       interface construction/destruction events
   352  *  M3G_LOG_OBJECTS         object construction/destruction events
   353  *  M3G_LOG_STAGES          log processing stages (animate, render, etc.)
   354  *  M3G_LOG_REFCOUNT        reference count operations
   355  *  M3G_LOG_MEMORY_USAGE    memory usage counters
   356  *  M3G_LOG_MEMORY_BLOCKS   memory block allocs/deallocs
   357  *  M3G_LOG_MEMORY_ALL      output everything memory-related
   358  *  M3G_LOG_RENDERING       log rendering details
   359  *  M3G_LOG_IMAGES          log image memory usage details
   360  *
   361  * \note The amount of log output may be limited in non-debug builds.
   362  */
   363 
   364 /*!
   365  * \internal
   366  * \def M3G_PROFILE_LOG_INTERVAL
   367  * \brief Profile logging interval
   368  * 
   369  * Number of frames to wait between outputting (and resetting!) the
   370  * profiling counters.  Zero (default) disables profile logging.
   371  */
   372 #if !defined(M3G_PROFILE_LOG_INTERVAL)
   373 #   define M3G_PROFILE_LOG_INTERVAL     0
   374 #endif
   375     
   376 /*----------------------------------------------------------------------
   377  * Debug build setup
   378  *--------------------------------------------------------------------*/
   379 
   380 /* General settings enabled in debug builds */
   381 #if defined(M3G_DEBUG)
   382 #   define M3G_DEBUG_ASSERTS
   383 #   define M3G_DEBUG_RANGE_CHECKING
   384 #   define M3G_DEBUG_HEAP_TRACKING
   385 #endif
   386 
   387 /*----------------------------------------------------------------------
   388  * Compiler dependent definitions
   389  *--------------------------------------------------------------------*/
   390 
   391 /* Try to recognize the compiler */
   392 #if !defined(M3G_NO_COMPILER_DETECTION)
   393 #   if (defined (_MSC_VER) || defined(__VC32__))&& !defined(__MWERKS__) /* Microsoft Visual C++ */
   394 #       undef M3G_BUILD_MSVC
   395 #       define M3G_BUILD_MSVC
   396 #   elif defined(__ARMCC_VERSION)   /* ARM Developer Suite */
   397 #       undef M3G_BUILD_ADS
   398 #       define M3G_BUILD_ADS
   399 #   elif defined(__BORLANDC__)      /* Borland C++ */
   400 #       undef M3G_BUILD_BORLAND
   401 #       define M3G_BUILD_BORLAND
   402 #   elif defined(__MWERKS__) || defined(__CW32__) /* CodeWarrior */
   403 #       undef M3G_BUILD_CW
   404 #       define M3G_BUILD_CW
   405 #   elif defined(__GNUC__) || defined(__GCC32__) /* GNU C */
   406 #       undef M3G_BUILD_GCC
   407 #       define M3G_BUILD_GCC
   408 #   elif defined(__ARMCC__)         /* RVCT */
   409 #       undef M3G_BUILD_RVCT
   410 #       define M3G_BUILD_RVCT
   411 #   elif defined(S_SPLINT_S)        /* Splint */
   412 #       undef M3G_BUILD_SPLINT
   413 #       define M3G_BUILD_SPLINT
   414 #   else
   415 #       error Could not identify the compiler. Please refer to m3g_defs.h for more information.
   416 #   endif
   417 #endif
   418 
   419 /* Try to recognize thumb/arm */
   420 #if defined(M3G_BUILD_ADS)
   421 #   if defined(__thumb)
   422 #       define M3G_BUILD_THUMB
   423 #   else
   424 #       define M3G_BUILD_ARM
   425 #   endif
   426 #endif
   427 
   428 /* Set up compiler-dependent definitions */
   429 
   430 /*@-macroparams@*/
   431 /*@notfunction@*/
   432 /*!
   433  * \internal \brief Macro used to denote Splint constraints */
   434 #define M3G_SPLINT(def)
   435 /*@+macroparams@*/
   436 
   437 /*!
   438  * \internal \def M3G_INLINE
   439  * \brief Platform-independent inline function specifier
   440  */
   441 
   442 #if defined(M3G_BUILD_MSVC)
   443 #   define M3G_INLINE  __inline
   444 #   pragma warning (disable:4127) /* 4127: conditional expression is constant */
   445 #   pragma warning (disable:4514) /* 4514: unreferenced inline function has been removed */
   446 #   pragma warning (disable:4710) /* 4710: function not inlined */
   447 
   448 #elif defined (M3G_BUILD_ADS)
   449 #   define M3G_INLINE __inline
   450 
   451 #elif defined(M3G_BUILD_BORLAND)
   452 #   define M3G_INLINE  __inline
   453 
   454 #elif defined(M3G_BUILD_CW)
   455 #   define M3G_INLINE
   456     
   457 #elif defined(M3G_BUILD_GCC)
   458 #   define M3G_INLINE inline
   459 
   460 #elif defined(M3G_BUILD_RVCT)
   461 #   define M3G_INLINE __inline
   462     
   463 #elif defined(M3G_BUILD_SPLINT)
   464 #   define M3G_INLINE
   465 #   undef M3G_SPLINT
   466 /*@notfunction@*/
   467 #   define M3G_SPLINT(def) def
   468 
   469 #   undef M3G_DEBUG
   470 /*#   define M3G_DEBUG*/
   471 
   472 #else           /* generic fallback */
   473 #   define M3G_INLINE
   474 
   475 #endif
   476 
   477 /* Optionally cancel non-portable definitions. This is mainly to
   478  * facilitate portability checking with GCC, which defines __STDC__
   479  * even in non-ANSI mode) */
   480 
   481 #if defined(M3G_STRICT_STDC)
   482 #   undef M3G_INLINE
   483 #   define M3G_INLINE
   484 #endif
   485 
   486 /*----------------------------------------------------------------------
   487  * Identify GL version
   488  *--------------------------------------------------------------------*/
   489 #if defined(GL_VERSION_ES_CM_1_1) || defined(GL_OES_VERSION_1_1)
   490 #   define M3G_GL_ES_1_1
   491 #endif
   492 
   493 /*----------------------------------------------------------------------
   494  * Internal configuration and performance tuning parameters
   495  *--------------------------------------------------------------------*/
   496 
   497 #define M3G_RENDERQUEUE_BUCKET_BITS 8
   498 #define M3G_ENABLE_VF_CULLING
   499 #define M3G_GL_FORCE_PBUFFER_SIZE
   500     
   501 /*----------------------------------------------------------------------
   502  * Standard C library
   503  *--------------------------------------------------------------------*/
   504 
   505 #if defined(M3G_NO_STDLIB)
   506 #   define NULL 0
   507 typedef M3Guint M3Gsize;
   508 #else
   509 #   include <stdlib.h>
   510 typedef size_t M3Gsize;
   511 #endif
   512 
   513 /*----------------------------------------------------------------------
   514  * Run time and compile time assertions
   515  *--------------------------------------------------------------------*/
   516 
   517 /*!
   518  * \internal \def M3G_ASSERT(a)
   519  * \brief Run-time assertion
   520  */
   521 #if defined(M3G_DEBUG_ASSERTS)
   522 
   523 extern void m3gAssertFailed(const char *filename, int line);
   524 #define M3G_ASSERT(cond)                                        \
   525     do {                                                        \
   526         if (!(cond)) m3gAssertFailed(__FILE__, __LINE__);       \
   527     } while (M3G_FALSE)
   528 
   529 M3G_SPLINT(extern /*@noreturnwhenfalse@*/ void M3G_ASSERT(/*@sef@*//*@null@*/ M3Gbool /*@alt const void*@*/ cond)/*@*/;)
   530 
   531 #else
   532 
   533 /*@-macroparams@*/
   534 #   define M3G_ASSERT(cond)
   535 /*@+macroparams@*/
   536 M3G_SPLINT(extern /*@noreturnwhenfalse@*/ void M3G_ASSERT(/*@sef@*//*@null@*//*@unused@*/ M3Gbool /*@alt const void*@*/ cond)/*@*/;)
   537     
   538 #endif /* M3G_DEBUG */
   539 
   540 /*!
   541  * \internal
   542  * \brief Compile-time assertion
   543  */
   544 /*@notfunction@*/
   545 #define M3G_CT_ASSERT(a)    struct __M3G_UNIQUE_NAME { unsigned bf : (a) ? 1 : -1; }
   546 /*@notfunction@*/
   547 #define __M3G_UNIQUE_NAME           __M3G_MAKE_UNIQUE_NAME(__LINE__, 0)
   548 /*@notfunction@*/
   549 #define __M3G_MAKE_UNIQUE_NAME(line, num)   __M3G_MAKE_UNIQUE_NAME2(line, num)
   550 /*@notfunction@*/
   551 #define __M3G_MAKE_UNIQUE_NAME2(line, num)  m3gCTassert ## num ## line
   552 
   553 /*@notfunction@*/
   554 #define M3G_CT_ASSERT1(a)   struct __M3G_UNIQUE_NAME1 { unsigned bf : (a) ? 1 : -1; }
   555 /*@notfunction@*/
   556 #define __M3G_UNIQUE_NAME1  M3G_MAKE_UNIQUE_NAME(__LINE__, 1)
   557 
   558 /*@notfunction@*/
   559 #define M3G_CT_ASSERT2(a)   struct __M3G_UNIQUE_NAME2 { unsigned bf : (a) ? 1 : -1; }
   560 /*@notfunction@*/
   561 #define __M3G_UNIQUE_NAME2  __M3G_MAKE_UNIQUE_NAME(__LINE__, 2)
   562 
   563 #if defined(M3G_DEBUG_RANGE_CHECKING)
   564 #define M3G_ASSERT_RANGE(val, min, max) M3G_ASSERT(m3gInRange((val), (min), (max)))
   565 #else
   566 /*@-macroparams@*/
   567 #define M3G_ASSERT_RANGE(val, min, max)
   568 /*@+macroparams@*/
   569 #endif
   570 
   571 /*----------------------------------------------------------------------
   572  * Verify any global definitions, expected type sizes etc.
   573  *--------------------------------------------------------------------*/
   574 
   575 #if !defined(M3G_INLINE)
   576 #   error M3G_INLINE not defined in platform definitions!
   577 #endif
   578 
   579 #if !defined(M3G_ALIGNMENT)
   580 #   error M3G_ALIGNMENT not defined in platform definitions!
   581 #endif
   582 
   583 #if ((M3G_ALIGNMENT & (M3G_ALIGNMENT-1)) != 0)
   584 #   error M3G_ALIGNMENT is not a power of two!
   585 #endif
   586 
   587 #if defined(M3G_TARGET_ISA) && !defined(M3G_USE_NGL_API)
   588 #   error ISA targets currently supported with M3G_USE_NGL_API only!
   589 #endif
   590 
   591 #if (defined(M3G_NGL_CONTEXT_API) && !defined(M3G_NGL_TEXTURE_API)) \
   592         || (defined(M3G_NGL_TEXTURE_API) && !defined(M3G_NGL_CONTEXT_API))
   593 #   if !defined(M3G_DEBUG)
   594 #       error Nonstandard NGL configurations only allowed in debug builds!
   595 #   endif
   596 #endif
   597 
   598 /* Verify our expected type sizes */
   599 M3G_CT_ASSERT(sizeof(M3Gbyte)   == 1);
   600 M3G_CT_ASSERT(sizeof(M3Gubyte)  == 1);
   601 M3G_CT_ASSERT(sizeof(M3Gshort)  == 2);
   602 M3G_CT_ASSERT(sizeof(M3Gushort) == 2);
   603 M3G_CT_ASSERT(sizeof(M3Gint)    == 4);
   604 M3G_CT_ASSERT(sizeof(M3Guint)   == 4);
   605 M3G_CT_ASSERT(sizeof(M3Gfloat)   == 4);
   606 
   607 /* Unsigned is used extensively as a wrapper for object pointers, so
   608  * check that we can fit a pointer in there */
   609 M3G_CT_ASSERT(sizeof(M3Guint) >= sizeof(void*));
   610 
   611 /*
   612  * Globally disable some redundant Lint messages
   613  */
   614 
   615 /*lint -e701 Signed shifts left should never be a problem */
   616 /*lint -e702 Signed shifts right are run-time verified (m3g_interface.c) */
   617 
   618 /*----------------------------------------------------------------------
   619  * Event logging
   620  *--------------------------------------------------------------------*/
   621 
   622 #if !defined(M3G_LOGLEVEL)    
   623 #   define M3G_LOG(level, msg)              ((void)(level), (void)(msg))
   624 #   define M3G_LOG1(level, msg, a)          ((void)(level), (void)(msg), (void)(a))
   625 #   define M3G_LOG2(level, msg, a, b)       ((void)(level), (void)(msg), (void)(a), (void)(b))
   626 #   define M3G_LOG3(level, msg, a, b, c)    ((void)(level), (void)(msg), (void)(a), (void)(b), (void)(c))
   627 #   define M3G_LOG4(level, msg, a, b, c, d) ((void)(level), (void)(msg), (void)(a), (void)(b), (void)(c), (void)(d))
   628 #   define M3G_LOG5(level, msg, a, b, c, d, e) ((void)(level), (void)(msg), (void)(a), (void)(b), (void)(c), (void)(d), (void)(e))
   629 #else
   630     void m3gBeginLog(void);
   631     void m3gLogMessage(const char *format, ...);
   632     void m3gEndLog(void);
   633 #   define M3G_LOG(level, msg) \
   634     do { if ((level) & (M3G_LOGLEVEL)) m3gLogMessage((msg)); } while (M3G_FALSE)
   635 #   define M3G_LOG1(level, msg, a) \
   636     do { if ((level) & (M3G_LOGLEVEL)) m3gLogMessage((msg), (a)); } while (M3G_FALSE)
   637 #   define M3G_LOG2(level, msg, a, b) \
   638     do { if ((level) & (M3G_LOGLEVEL)) m3gLogMessage((msg), (a), (b)); } while (M3G_FALSE)
   639 #   define M3G_LOG3(level, msg, a, b, c) \
   640     do { if ((level) & (M3G_LOGLEVEL)) m3gLogMessage((msg), (a), (b), (c)); } while (M3G_FALSE)
   641 #   define M3G_LOG4(level, msg, a, b, c, d) \
   642     do { if ((level) & (M3G_LOGLEVEL)) m3gLogMessage((msg), (a), (b), (c), (d)); } while (M3G_FALSE)
   643 #   define M3G_LOG5(level, msg, a, b, c, d, e) \
   644     do { if ((level) & (M3G_LOGLEVEL)) m3gLogMessage((msg), (a), (b), (c), (d), (e)); } while (M3G_FALSE)
   645 #endif
   646     
   647 /*----------------------------------------------------------------------
   648  * Useful stuff
   649  *--------------------------------------------------------------------*/
   650 
   651 /*!
   652  * \internal
   653  * \brief Range checking inline function
   654  *
   655  * \param a     Value to check
   656  * \param min   Lower bound, inclusive
   657  * \param max   Upper bound, inclusive
   658  */
   659 static M3G_INLINE M3Gbool m3gInRange(M3Gint a, M3Gint min, M3Gint max)
   660 {
   661     return ((M3Guint)(a - min) <= (M3Guint)(max - min));
   662 }
   663 
   664 /*!
   665  * \internal
   666  * \brief Range checking for floats
   667  */
   668 static M3G_INLINE M3Gbool m3gInRangef(M3Gfloat a, M3Gfloat min, M3Gfloat max)
   669 {
   670     return (a >= min && a <= max);
   671 }
   672     
   673 /*!
   674  * \internal
   675  * \brief Clamping function for floats
   676  *
   677  * \param a     Value to clamp
   678  * \param min   Minimum value
   679  * \param max   Maximum value
   680  */
   681 static M3G_INLINE M3Gfloat m3gClampFloat(M3Gfloat a, M3Gfloat min, M3Gfloat max)
   682 {
   683     return (a <= min) ? min : (a >= max) ? max : a;
   684 }
   685 
   686 /*!
   687  * \internal
   688  * \brief Clamping function for floats
   689  *
   690  * \param a     Value to clamp
   691  */
   692 static M3G_INLINE M3Gfloat m3gClampFloatPositive(M3Gfloat a)
   693 {
   694     return (a <= 0) ? 0 : a;
   695 }
   696 
   697 /*!
   698  * \internal
   699  */
   700 static M3G_INLINE M3Gint m3gClampInt(M3Gint a, M3Gint min, M3Gint max)
   701 {
   702     return (a <= min) ? min : (a >= max) ? max : a;
   703 }
   704 
   705 /*!
   706  * \internal
   707  *
   708  */
   709 static M3G_INLINE M3Gbool m3gIsPowerOfTwo(M3Guint a)
   710 {
   711     return ((a & (a-1)) == 0u);
   712 }
   713 
   714 /*!
   715  * \internal
   716  * \brief Returns the smallest power of two greater than or equal to a
   717  * given integer
   718  *
   719  * \note Only works with positive numbers of 2^30 or less
   720  */
   721 static M3G_INLINE M3Gint m3gNextPowerOfTwo(M3Gint x)
   722 {
   723     M3Gint y = 1;
   724     M3G_ASSERT(m3gInRange(x, 0, 1 << 30));
   725     while (y < x) {
   726         y <<= 1;
   727     }
   728     return y;
   729 }
   730 
   731 /*!
   732  * \internal
   733  * \brief Indicate (intentionally) unreferenced parameters
   734  *
   735  * This is used on virtual functions, where not every implementation
   736  * uses all the arguments.
   737  */
   738 /*@notfunction@*/
   739 #define M3G_UNREF(a)    ((void)(a)) /*@*/
   740 
   741 /*!
   742  * \internal
   743  * \brief Clamp a value to signed 8-bit range
   744  */
   745 #define M3G_CLAMP_BYTE(a) ((M3Gbyte)  ((a) <   -128 ?   -128 : ((a) >   127 ?   127 : (a))))
   746 M3G_SPLINT(extern M3Gbyte M3G_CLAMP_BYTE(/*@sef@*/ int a);)
   747 
   748 /*!
   749  * \internal
   750  * \brief Clamp a value to signed 16-bit range
   751  */
   752 #define M3G_CLAMP_SHORT(a) ((M3Gshort) ((a) < -32768 ? -32768 : ((a) > 32767 ? 32767 : (a))))
   753 M3G_SPLINT(extern M3Gshort M3G_CLAMP_SHORT(/*@sef@*/ int a);)
   754 
   755 /*!
   756  * \internal
   757  * \brief Clamp a value to unsigned 8-bit range
   758  */
   759 #define M3G_CLAMP_UBYTE(a) ((M3Gubyte) ((a) < 0 ? 0 : ((a) >   255 ?   255 : (a))))
   760 M3G_SPLINT(extern M3Gubyte M3G_CLAMP_UBYTE(/*@sef@*/ int a);)
   761 
   762 /*!
   763  * \internal
   764  * \brief Clamp a value to unsigned 16-bit range
   765  */
   766 #define M3G_CLAMP_USHORT(a) ((M3Gushort)((a) < 0 ? 0 : ((a) > 65535 ? 65535 : (a))))
   767 M3G_SPLINT(extern M3Gushort M3G_CLAMP_USHORT(/*@sef@*/ int a);)
   768 
   769 /*!
   770  * \internal
   771  * \brief Offset any pointer by a given number of bytes
   772  */
   773 #define M3G_OFFSET_PTR(ptr, bytes) (void*)(((M3Gbyte*)(ptr)) + bytes)
   774 
   775 /* Min & max macros and inline functions
   776  *
   777  * The inline function may be better optimized when one or both of the
   778  * arguments are expressions */
   779     
   780 #define M3G_MIN(a, b) ((a) <= (b) ? (a) : (b))
   781 #define M3G_MAX(a, b) ((a) >= (b) ? (a) : (b))
   782 
   783 static M3G_INLINE M3Gint m3gMaxInt(M3Gint a, M3Gint b)
   784 {
   785     return M3G_MAX(a, b);
   786 }
   787 
   788 static M3G_INLINE M3Gint m3gMinInt(M3Gint a, M3Gint b)
   789 {
   790     return M3G_MIN(a, b);
   791 }
   792 
   793 /*!
   794  * \internal
   795  * \brief RGB mask
   796  */
   797 #define M3G_RGB_MASK    0x00FFFFFFu
   798 
   799 /*!
   800  * \internal
   801  * \brief Alpha mask
   802  */
   803 #define M3G_ALPHA_MASK  0xFF000000u
   804 
   805 /*----------------------------------------------------------------------
   806  * Data alignment macros
   807  *--------------------------------------------------------------------*/
   808 
   809 /*!
   810  * \internal
   811  * \brief Align a pointer or size value to an N-byte boundary
   812  *
   813  * @param value Value to align.
   814  * @param size  Alignment size; must be a power of two
   815  */
   816 #define M3G_ALIGN_TO(value, size) ((((unsigned) (value)) + ((size) - 1)) & ~((size) - 1))
   817 M3G_SPLINT(extern int M3G_ALIGN_TO(int /*@alt size_t@*/ value, /*@sef@*/ int size);)
   818 
   819 /*!
   820  * \internal
   821  * \brief Returns a truth value for whether a pointer is aligned or not
   822  */
   823 #define M3G_IS_ALIGNED(ptr) ((((unsigned)(ptr)) & (M3G_ALIGNMENT-1)) == 0)
   824 
   825 /*!
   826  * \internal
   827  * \brief Assert proper alignment of a pointer
   828  *
   829  * Currently, we assume alignment to 4-byte boundaries.
   830  */
   831 #define M3G_ASSERT_ALIGNMENT(ptr) M3G_ASSERT(M3G_IS_ALIGNED(ptr))
   832 
   833 /*!
   834  * \internal
   835  * \brief Asserts that a pointer is both non-null and aligned
   836  */
   837 #define M3G_ASSERT_PTR(ptr) M3G_ASSERT((ptr) != NULL && M3G_IS_ALIGNED(ptr))
   838 #define M3G_VALIDATE_PTR(ptr) M3G_ASSERT_PTR(ptr)
   839     
   840 /*----------------------------------------------------------------------
   841  * Easier names for math classes...
   842  *--------------------------------------------------------------------*/
   843 
   844 typedef M3GMatrix       Matrix;
   845 typedef M3GQuat         Quat;
   846 typedef M3GVec3         Vec3;
   847 typedef M3GVec4         Vec4;
   848 typedef M3GRectangle    Rect;
   849 
   850 /* We rely on the layout of a Vec4 or a Quat matching an array of 4
   851  * floats in a number of places, so check that */
   852 
   853 M3G_CT_ASSERT(sizeof(M3GVec4) == 4 * sizeof(M3Gfloat));
   854 M3G_CT_ASSERT(sizeof(M3GQuat) == 4 * sizeof(M3Gfloat));
   855 
   856 #if defined(__cplusplus)
   857 } /* extern "C" */
   858 #endif
   859 
   860 #endif /*__M3G_DEFS_H__*/