Update contrib.
2 * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
14 * Description: Global definitions
18 #ifndef __M3G_DEFS_H__
19 #define __M3G_DEFS_H__
24 * \brief Global definitions for the Nokia M3G API implementation
27 /* Include public API */
28 #include "M3G/m3g_core.h"
30 #if defined(__cplusplus)
34 /* Try to recognize debug builds */
35 #if defined(_DEBUG) || defined(DEBUG)
40 /*----------------------------------------------------------------------
41 * Platform dependent definitions
42 *--------------------------------------------------------------------*/
44 /* Define constants for use in m3g_config.h */
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
62 /* Include the platform configuration file; the possible configuration
63 * options are documented and their default values set below */
65 #include "m3g_config.h"
69 * \def M3G_TARGET_GENERIC
70 * \brief Enables a generic C build
75 * \brief Enables building for ISA
79 * \def M3G_TARGET_SYMBIAN
80 * \brief Enables building for Symbian
84 * \def M3G_TARGET_WIN32
85 * \brief Enables building for Win32
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
94 # error Build target undefined! Supply one of the M3G_TARGET_* definitions.
99 * \def M3G_USE_NGL_API
100 * \brief Enable the legacy "NGL" OpenGL context management interface
102 #if defined(M3G_USE_NGL_API)
103 # define M3G_NGL_CONTEXT_API
104 # define M3G_NGL_TEXTURE_API
107 #if defined(M3G_TARGET_ISA)
108 # if !defined(M3G_NGL_CONTEXT_API)
109 # error ISA builds must define M3G_USE_NGL_API
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
121 * \brief Alignment, in bytes, mandated for internal data structures
123 * This must meet or exceed the alignment requirement of the
124 * underlying hardware. The default is 4 bytes.
126 #if !defined(M3G_ALIGNMENT)
127 # define M3G_ALIGNMENT 4
132 * \def M3G_MAX_GL_CONTEXTS
133 * \brief Maximum number of GL contexts to cache at once
135 * \note This only applies to builds using the EGL API.
137 #if !defined(M3G_MAX_GL_CONTEXTS)
138 # define M3G_MAX_GL_CONTEXTS 3
143 * \def M3G_MAX_GL_SURFACES
144 * \brief Maximum number of GL surfaces to cache at once
146 * \note This only applies to builds using the EGL API.
148 #if !defined(M3G_MAX_GL_SURFACES)
149 # define M3G_MAX_GL_SURFACES 4
154 * \def M3G_MAX_LIGHTS
155 * \brief Maximum number of lights in use simultaneously
157 * This is a rendering quality / performance trade-off; less lights
158 * will be (slightly) faster, but reduce the quality of lighting.
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
165 #if !defined(M3G_MAX_LIGHTS)
166 # define M3G_MAX_LIGHTS 8
171 * \def M3G_MAX_TEXTURE_DIMENSION
172 * \brief Maximum supported texture dimension
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
179 #if !defined(M3G_MAX_TEXTURE_DIMENSION)
180 # define M3G_MAX_TEXTURE_DIMENSION 256
185 * \def M3G_MAX_VERTEX_TRANSFORMS
186 * \brief Maximum number of transforms per vertex
188 * \note The value set here must not exceed the limits of the
189 * underlying OpenGL implementation; this is not automatically
192 #if !defined(M3G_MAX_VERTEX_TRANSFORMS)
193 # define M3G_MAX_VERTEX_TRANSFORMS 4
198 * \def M3G_MAX_VIEWPORT_DIMENSION
199 * \brief Maximum supported viewport dimension
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
206 #if !defined(M3G_MAX_VIEWPORT_DIMENSION)
207 # define M3G_MAX_VIEWPORT_DIMENSION 1024
212 * \def M3G_MAX_VIEWPORT_WIDTH
213 * \brief Maximum supported viewport width
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
220 #if !defined(M3G_MAX_VIEWPORT_WIDTH)
221 # define M3G_MAX_VIEWPORT_WIDTH 1024
226 * \def M3G_MAX_VIEWPORT_HEIGHT
227 * \brief Maximum supported viewport height
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
234 #if !defined(M3G_MAX_VIEWPORT_HEIGHT)
235 # define M3G_MAX_VIEWPORT_HEIGHT 1024
240 * \def M3G_NATIVE_LOADER
241 * \brief Include a native loader implementation
243 * This is always enabled in current builds.
245 #undef M3G_NATIVE_LOADER
246 #define M3G_NATIVE_LOADER
250 * \def M3G_NUM_TEXTURE_UNITS
251 * \brief Number of texture units to support
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
258 #if !defined(M3G_NUM_TEXTURE_UNITS)
259 # define M3G_NUM_TEXTURE_UNITS 2
264 * \def M3G_SUPPORT_ANTIALIASING
265 * \brief Enable or disable support for antialiasing
267 * \note This is currently only supported for Symbian.
269 #if !defined(M3G_SUPPORT_ANTIALIASING)
270 # if defined(M3G_NGL_CONTEXT_API)
271 # define M3G_SUPPORT_ANTIALIASING M3G_FALSE
273 # define M3G_SUPPORT_ANTIALIASING M3G_TRUE
279 * \def M3G_SUPPORT_DITHERING
280 * \brief Enable or disable support for dithering
282 #if !defined(M3G_SUPPORT_DITHERING)
283 # define M3G_SUPPORT_DITHERING M3G_FALSE
288 * \def M3G_SUPPORT_LOCAL_CAMERA_LIGHTING
289 * \brief Enable or disable support for local camera lighting
291 #if !defined(M3G_SUPPORT_LOCAL_CAMERA_LIGHTING)
292 # define M3G_SUPPORT_LOCAL_CAMERA_LIGHTING M3G_FALSE
297 * \def M3G_SUPPORT_MIPMAPPING
298 * \brief Enable or disable support for mipmapping
300 #if !defined(M3G_SUPPORT_MIPMAPPING)
301 # define M3G_SUPPORT_MIPMAPPING M3G_TRUE
306 * \def M3G_SUPPORT_PERSPECTIVE_CORRECTION
307 * \brief Enable or disable support for perspective correct texturing
309 #if !defined(M3G_SUPPORT_PERSPECTIVE_CORRECTION)
310 # define M3G_SUPPORT_PERSPECTIVE_CORRECTION M3G_TRUE
315 * \def M3G_SUPPORT_TRUE_COLOR
316 * \brief Enable or disable support for "true color" rendering
318 #if !defined(M3G_SUPPORT_TRUE_COLOR)
319 # define M3G_SUPPORT_TRUE_COLOR M3G_FALSE
324 * \def M3G_USE_16BIT_TEXTURES
325 * \brief Use 16-bit RGB textures internally to save memory
327 * This may reduce in some loss of performance, so it is defined
328 * M3G_FALSE by default.
330 #if !defined(M3G_USE_16BIT_TEXTURES)
331 # define M3G_USE_16BIT_TEXTURES M3G_FALSE
338 * \brief Controls the amount of log output
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:
346 * M3G_LOG_FATAL_ERRORS fatal internal errors (equals 0)
347 * M3G_LOG_USER_ERRORS user errors (the same as reported
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
361 * \note The amount of log output may be limited in non-debug builds.
366 * \def M3G_PROFILE_LOG_INTERVAL
367 * \brief Profile logging interval
369 * Number of frames to wait between outputting (and resetting!) the
370 * profiling counters. Zero (default) disables profile logging.
372 #if !defined(M3G_PROFILE_LOG_INTERVAL)
373 # define M3G_PROFILE_LOG_INTERVAL 0
376 /*----------------------------------------------------------------------
378 *--------------------------------------------------------------------*/
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
387 /*----------------------------------------------------------------------
388 * Compiler dependent definitions
389 *--------------------------------------------------------------------*/
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 */
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
415 # error Could not identify the compiler. Please refer to m3g_defs.h for more information.
419 /* Try to recognize thumb/arm */
420 #if defined(M3G_BUILD_ADS)
421 # if defined(__thumb)
422 # define M3G_BUILD_THUMB
424 # define M3G_BUILD_ARM
428 /* Set up compiler-dependent definitions */
433 * \internal \brief Macro used to denote Splint constraints */
434 #define M3G_SPLINT(def)
438 * \internal \def M3G_INLINE
439 * \brief Platform-independent inline function specifier
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 */
448 #elif defined (M3G_BUILD_ADS)
449 # define M3G_INLINE __inline
451 #elif defined(M3G_BUILD_BORLAND)
452 # define M3G_INLINE __inline
454 #elif defined(M3G_BUILD_CW)
457 #elif defined(M3G_BUILD_GCC)
458 # define M3G_INLINE inline
460 #elif defined(M3G_BUILD_RVCT)
461 # define M3G_INLINE __inline
463 #elif defined(M3G_BUILD_SPLINT)
467 # define M3G_SPLINT(def) def
470 /*# define M3G_DEBUG*/
472 #else /* generic fallback */
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) */
481 #if defined(M3G_STRICT_STDC)
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
493 /*----------------------------------------------------------------------
494 * Internal configuration and performance tuning parameters
495 *--------------------------------------------------------------------*/
497 #define M3G_RENDERQUEUE_BUCKET_BITS 8
498 #define M3G_ENABLE_VF_CULLING
499 #define M3G_GL_FORCE_PBUFFER_SIZE
501 /*----------------------------------------------------------------------
503 *--------------------------------------------------------------------*/
505 #if defined(M3G_NO_STDLIB)
507 typedef M3Guint M3Gsize;
510 typedef size_t M3Gsize;
513 /*----------------------------------------------------------------------
514 * Run time and compile time assertions
515 *--------------------------------------------------------------------*/
518 * \internal \def M3G_ASSERT(a)
519 * \brief Run-time assertion
521 #if defined(M3G_DEBUG_ASSERTS)
523 extern void m3gAssertFailed(const char *filename, int line);
524 #define M3G_ASSERT(cond) \
526 if (!(cond)) m3gAssertFailed(__FILE__, __LINE__); \
529 M3G_SPLINT(extern /*@noreturnwhenfalse@*/ void M3G_ASSERT(/*@sef@*//*@null@*/ M3Gbool /*@alt const void*@*/ cond)/*@*/;)
534 # define M3G_ASSERT(cond)
536 M3G_SPLINT(extern /*@noreturnwhenfalse@*/ void M3G_ASSERT(/*@sef@*//*@null@*//*@unused@*/ M3Gbool /*@alt const void*@*/ cond)/*@*/;)
538 #endif /* M3G_DEBUG */
542 * \brief Compile-time assertion
545 #define M3G_CT_ASSERT(a) struct __M3G_UNIQUE_NAME { unsigned bf : (a) ? 1 : -1; }
547 #define __M3G_UNIQUE_NAME __M3G_MAKE_UNIQUE_NAME(__LINE__, 0)
549 #define __M3G_MAKE_UNIQUE_NAME(line, num) __M3G_MAKE_UNIQUE_NAME2(line, num)
551 #define __M3G_MAKE_UNIQUE_NAME2(line, num) m3gCTassert ## num ## line
554 #define M3G_CT_ASSERT1(a) struct __M3G_UNIQUE_NAME1 { unsigned bf : (a) ? 1 : -1; }
556 #define __M3G_UNIQUE_NAME1 M3G_MAKE_UNIQUE_NAME(__LINE__, 1)
559 #define M3G_CT_ASSERT2(a) struct __M3G_UNIQUE_NAME2 { unsigned bf : (a) ? 1 : -1; }
561 #define __M3G_UNIQUE_NAME2 __M3G_MAKE_UNIQUE_NAME(__LINE__, 2)
563 #if defined(M3G_DEBUG_RANGE_CHECKING)
564 #define M3G_ASSERT_RANGE(val, min, max) M3G_ASSERT(m3gInRange((val), (min), (max)))
567 #define M3G_ASSERT_RANGE(val, min, max)
571 /*----------------------------------------------------------------------
572 * Verify any global definitions, expected type sizes etc.
573 *--------------------------------------------------------------------*/
575 #if !defined(M3G_INLINE)
576 # error M3G_INLINE not defined in platform definitions!
579 #if !defined(M3G_ALIGNMENT)
580 # error M3G_ALIGNMENT not defined in platform definitions!
583 #if ((M3G_ALIGNMENT & (M3G_ALIGNMENT-1)) != 0)
584 # error M3G_ALIGNMENT is not a power of two!
587 #if defined(M3G_TARGET_ISA) && !defined(M3G_USE_NGL_API)
588 # error ISA targets currently supported with M3G_USE_NGL_API only!
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!
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);
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*));
612 * Globally disable some redundant Lint messages
615 /*lint -e701 Signed shifts left should never be a problem */
616 /*lint -e702 Signed shifts right are run-time verified (m3g_interface.c) */
618 /*----------------------------------------------------------------------
620 *--------------------------------------------------------------------*/
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))
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)
647 /*----------------------------------------------------------------------
649 *--------------------------------------------------------------------*/
653 * \brief Range checking inline function
655 * \param a Value to check
656 * \param min Lower bound, inclusive
657 * \param max Upper bound, inclusive
659 static M3G_INLINE M3Gbool m3gInRange(M3Gint a, M3Gint min, M3Gint max)
661 return ((M3Guint)(a - min) <= (M3Guint)(max - min));
666 * \brief Range checking for floats
668 static M3G_INLINE M3Gbool m3gInRangef(M3Gfloat a, M3Gfloat min, M3Gfloat max)
670 return (a >= min && a <= max);
675 * \brief Clamping function for floats
677 * \param a Value to clamp
678 * \param min Minimum value
679 * \param max Maximum value
681 static M3G_INLINE M3Gfloat m3gClampFloat(M3Gfloat a, M3Gfloat min, M3Gfloat max)
683 return (a <= min) ? min : (a >= max) ? max : a;
688 * \brief Clamping function for floats
690 * \param a Value to clamp
692 static M3G_INLINE M3Gfloat m3gClampFloatPositive(M3Gfloat a)
694 return (a <= 0) ? 0 : a;
700 static M3G_INLINE M3Gint m3gClampInt(M3Gint a, M3Gint min, M3Gint max)
702 return (a <= min) ? min : (a >= max) ? max : a;
709 static M3G_INLINE M3Gbool m3gIsPowerOfTwo(M3Guint a)
711 return ((a & (a-1)) == 0u);
716 * \brief Returns the smallest power of two greater than or equal to a
719 * \note Only works with positive numbers of 2^30 or less
721 static M3G_INLINE M3Gint m3gNextPowerOfTwo(M3Gint x)
724 M3G_ASSERT(m3gInRange(x, 0, 1 << 30));
733 * \brief Indicate (intentionally) unreferenced parameters
735 * This is used on virtual functions, where not every implementation
736 * uses all the arguments.
739 #define M3G_UNREF(a) ((void)(a)) /*@*/
743 * \brief Clamp a value to signed 8-bit range
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);)
750 * \brief Clamp a value to signed 16-bit range
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);)
757 * \brief Clamp a value to unsigned 8-bit range
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);)
764 * \brief Clamp a value to unsigned 16-bit range
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);)
771 * \brief Offset any pointer by a given number of bytes
773 #define M3G_OFFSET_PTR(ptr, bytes) (void*)(((M3Gbyte*)(ptr)) + bytes)
775 /* Min & max macros and inline functions
777 * The inline function may be better optimized when one or both of the
778 * arguments are expressions */
780 #define M3G_MIN(a, b) ((a) <= (b) ? (a) : (b))
781 #define M3G_MAX(a, b) ((a) >= (b) ? (a) : (b))
783 static M3G_INLINE M3Gint m3gMaxInt(M3Gint a, M3Gint b)
785 return M3G_MAX(a, b);
788 static M3G_INLINE M3Gint m3gMinInt(M3Gint a, M3Gint b)
790 return M3G_MIN(a, b);
797 #define M3G_RGB_MASK 0x00FFFFFFu
803 #define M3G_ALPHA_MASK 0xFF000000u
805 /*----------------------------------------------------------------------
806 * Data alignment macros
807 *--------------------------------------------------------------------*/
811 * \brief Align a pointer or size value to an N-byte boundary
813 * @param value Value to align.
814 * @param size Alignment size; must be a power of two
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);)
821 * \brief Returns a truth value for whether a pointer is aligned or not
823 #define M3G_IS_ALIGNED(ptr) ((((unsigned)(ptr)) & (M3G_ALIGNMENT-1)) == 0)
827 * \brief Assert proper alignment of a pointer
829 * Currently, we assume alignment to 4-byte boundaries.
831 #define M3G_ASSERT_ALIGNMENT(ptr) M3G_ASSERT(M3G_IS_ALIGNED(ptr))
835 * \brief Asserts that a pointer is both non-null and aligned
837 #define M3G_ASSERT_PTR(ptr) M3G_ASSERT((ptr) != NULL && M3G_IS_ALIGNED(ptr))
838 #define M3G_VALIDATE_PTR(ptr) M3G_ASSERT_PTR(ptr)
840 /*----------------------------------------------------------------------
841 * Easier names for math classes...
842 *--------------------------------------------------------------------*/
844 typedef M3GMatrix Matrix;
845 typedef M3GQuat Quat;
846 typedef M3GVec3 Vec3;
847 typedef M3GVec4 Vec4;
848 typedef M3GRectangle Rect;
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 */
853 M3G_CT_ASSERT(sizeof(M3GVec4) == 4 * sizeof(M3Gfloat));
854 M3G_CT_ASSERT(sizeof(M3GQuat) == 4 * sizeof(M3Gfloat));
856 #if defined(__cplusplus)
860 #endif /*__M3G_DEFS_H__*/