/* ** Command & Conquer Generals(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : Command & Conquer * * * * $Archive:: /Commando/Code/wwlib/always.h $* * * * $Author:: Steve_t $* * * * $Modtime:: 8/28/01 3:21p $* * * * $Revision:: 13 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 #ifndef ALWAYS_H #define ALWAYS_H #include // Disable warning about exception handling not being enabled. It's used as part of STL - in a part of STL we don't use. #pragma warning(disable : 4530) /* ** Define for debug memory allocation to include __FILE__ and __LINE__ for every memory allocation. ** This helps find leaks. */ //#define STEVES_NEW_CATCHER #ifdef _DEBUG #ifdef _MSC_VER #ifdef STEVES_NEW_CATCHER #include #include #include #define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__) #define calloc(c, s) _calloc_dbg(c, s, _NORMAL_BLOCK, __FILE__, __LINE__) #define realloc(p, s) _realloc_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__) #define _expand(p, s) _expand_dbg(p, s, _NORMAL_BLOCK, __FILE__, __LINE__) #define free(p) _free_dbg(p, _NORMAL_BLOCK) #define _msize(p) _msize_dbg(p, _NORMAL_BLOCK) void* __cdecl operator new(unsigned int s); #endif //STEVES_NEW_CATCHER #endif //_MSC_VER #endif //_DEBUG #ifndef _OPERATOR_NEW_DEFINED_ #define _OPERATOR_NEW_DEFINED_ extern void * __cdecl operator new (size_t size); extern void __cdecl operator delete (void *p); extern void * __cdecl operator new[] (size_t size); extern void __cdecl operator delete[] (void *p); // additional overloads to account for VC/MFC funky versions extern void* __cdecl operator new (size_t nSize, const char *, int); extern void __cdecl operator delete (void *, const char *, int); extern void* __cdecl operator new[] (size_t nSize, const char *, int); extern void __cdecl operator delete[] (void *, const char *, int); // additional overloads for 'placement new' //inline void* __cdecl operator new (size_t s, void *p) { return p; } //inline void __cdecl operator delete (void *, void *p) { } inline void* __cdecl operator new[] (size_t s, void *p) { return p; } inline void __cdecl operator delete[] (void *, void *p) { } #endif #if (defined(_DEBUG) || defined(_INTERNAL)) #define MSGW3DNEW(MSG) new( MSG, 0 ) #define MSGW3DNEWARRAY(MSG) new( MSG, 0 ) #define W3DNEW new("W3D_" __FILE__, 0) #define W3DNEWARRAY new("W3A_" __FILE__, 0) #else #define MSGW3DNEW(MSG) new #define MSGW3DNEWARRAY(MSG) new #define W3DNEW new #define W3DNEWARRAY new #endif // ---------------------------------------------------------------------------- extern void* createW3DMemPool(const char *poolName, int allocationSize); extern void* allocateFromW3DMemPool(void* p, int allocationSize); extern void* allocateFromW3DMemPool(void* p, int allocationSize, const char* msg, int unused); extern void freeFromW3DMemPool(void* pool, void* p); // ---------------------------------------------------------------------------- #define W3DMPO_GLUE(ARGCLASS) \ private: \ static void* getClassMemoryPool() \ { \ /* \ Note that this static variable will be initialized exactly once: the first time \ control flows over this section of code. This allows us to neatly resolve the \ order-of-execution problem for static variables, ensuring this is not executed \ prior to the initialization of TheMemoryPoolFactory. \ */ \ static void* The##ARGCLASS##Pool = createW3DMemPool(#ARGCLASS, sizeof(ARGCLASS)); \ return The##ARGCLASS##Pool; \ } \ protected: \ virtual int glueEnforcer() const { return sizeof(this); } \ public: \ inline void* operator new(size_t s) { return allocateFromW3DMemPool(getClassMemoryPool(), s); } \ inline void operator delete(void *p) { freeFromW3DMemPool(getClassMemoryPool(), p); } \ inline void* operator new(size_t s, const char* msg, int unused) { return allocateFromW3DMemPool(getClassMemoryPool(), s, msg, unused); } \ inline void operator delete(void *p, const char* msg, int unused) { freeFromW3DMemPool(getClassMemoryPool(), p); } \ // ---------------------------------------------------------------------------- class W3DMPO { private: static void* getClassMemoryPool() { assert(0); // must replace this via W3DMPO_GLUE return 0; } protected: // we never call this; it is present to cause compile errors in descendent classes virtual int glueEnforcer() const = 0; public: virtual ~W3DMPO() { /* nothing */ } }; // ---------------------------------------------------------------------------- // Jani: Intel's C++ compiler issues too many warnings in WW libraries when using warning level 4 #if defined (__ICL) // Detect Intel compiler #pragma warning (3) #pragma warning ( disable: 981 ) // parameters defined in unspecified order #pragma warning ( disable: 279 ) // controlling expressaion is constant #pragma warning ( disable: 271 ) // trailing comma is nonstandard #pragma warning ( disable: 171 ) // invalid type conversion #pragma warning ( disable: 1 ) // last line of file ends without a newline #endif // Jani: MSVC doesn't necessarily inline code with inline keyword. Using __forceinline results better inlining // and also prints out a warning if inlining wasn't possible. __forceinline is MSVC specific. #if defined(_MSC_VER) #define WWINLINE __forceinline #else #define WWINLINE inline #endif /* ** Define the MIN and MAX macros. ** NOTE: Joe used to #include in the various compiler header files. This ** header defines 'min' and 'max' macros which conflict with the surrender code so ** I'm relpacing all occurances of 'min' and 'max with 'MIN' and 'MAX'. For code which ** is out of our domain (e.g. Max sdk) I'm declaring template functions for 'min' and 'max' */ #define NOMINMAX #ifndef MAX #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef MIN #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif #ifdef min #undef min #endif #ifdef max #undef max #endif template T min(T a,T b) { if (a T max(T a,T b) { if (a>b) { return a; } else { return b; } } /* ** This includes the minimum set of compiler defines and pragmas in order to bring the ** various compilers to a common behavior such that the C&C engine will compile without ** error or warning. */ #if defined(__BORLANDC__) #include "borlandc.h" #endif #if defined(_MSC_VER) #include "visualc.h" #endif #if defined(__WATCOMC__) #include "watcom.h" #endif #ifndef NULL #define NULL 0 #endif /********************************************************************** ** This macro serves as a general way to determine the number of elements ** within an array. */ #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) int(sizeof(x)/sizeof(x[0])) #endif #ifndef size_of #define size_of(typ,id) sizeof(((typ*)0)->id) #endif #endif