2016-03-12 01:20:51 +01:00
|
|
|
/* Copyright (c) 2002-2012 Croteam Ltd.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of version 2 of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation
|
|
|
|
|
|
|
|
|
|
|
|
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, write to the Free Software Foundation, Inc.,
|
|
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
|
2016-03-11 14:57:17 +01:00
|
|
|
|
2016-03-29 03:03:54 +02:00
|
|
|
#include "Engine/StdH.h"
|
2016-03-11 14:57:17 +01:00
|
|
|
|
|
|
|
#include <Engine/Base/Memory.h>
|
|
|
|
#include <Engine/Base/Translation.h>
|
|
|
|
|
|
|
|
#include <Engine/Base/ErrorReporting.h>
|
2016-03-29 03:03:54 +02:00
|
|
|
|
|
|
|
/* rcg10282005 "new.h" is deprecated in newer C++ standards... --ryan. */
|
|
|
|
#ifdef _MSC_VER
|
2016-03-11 14:57:17 +01:00
|
|
|
#include <new.h>
|
2016-03-29 03:03:54 +02:00
|
|
|
#else
|
|
|
|
#include <new>
|
|
|
|
#endif
|
2016-03-11 14:57:17 +01:00
|
|
|
|
2016-03-29 03:03:54 +02:00
|
|
|
FLOAT _bCheckAllAllocations = FALSE;
|
2016-03-11 14:57:17 +01:00
|
|
|
|
2016-03-29 03:03:54 +02:00
|
|
|
#ifdef PLATFORM_WIN32
|
2016-03-11 14:57:17 +01:00
|
|
|
/*
|
|
|
|
* Declarations for setting up the 'new_handler'.
|
|
|
|
*/
|
|
|
|
_CRTIMP int __cdecl _query_new_mode( void );
|
|
|
|
_CRTIMP int __cdecl _set_new_mode( int );
|
|
|
|
|
|
|
|
#ifndef _PNH_DEFINED
|
|
|
|
typedef int (__cdecl * _PNH)( size_t );
|
|
|
|
#define _PNH_DEFINED
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*_CRTIMP _PNH __cdecl _query_new_handler( void );
|
|
|
|
_CRTIMP _PNH __cdecl _set_new_handler( _PNH );*/
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
// include this for debug version of operator new
|
|
|
|
#pragma comment (lib, "msvcrtd.lib")
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// include user32 library (because of message box)
|
|
|
|
#pragma comment (lib, "user32.lib")
|
2016-03-29 03:03:54 +02:00
|
|
|
#endif
|
|
|
|
|
2016-03-11 14:57:17 +01:00
|
|
|
|
|
|
|
// if not enough memory
|
2016-03-29 03:03:54 +02:00
|
|
|
#ifdef _MSC_VER
|
2016-03-11 14:57:17 +01:00
|
|
|
int NewHandler(size_t size)
|
|
|
|
{
|
|
|
|
// terminate program
|
|
|
|
FatalError(TRANS("Not enough memory (%d bytes needed)!"), size);
|
|
|
|
return 0;
|
|
|
|
}
|
2016-03-29 03:03:54 +02:00
|
|
|
#else
|
|
|
|
void NewHandler(void)
|
|
|
|
{
|
|
|
|
// terminate program
|
|
|
|
FatalError(TRANS("Not enough memory!"));
|
|
|
|
}
|
|
|
|
#endif
|
2016-03-11 14:57:17 +01:00
|
|
|
|
|
|
|
/* Static class used for initializing memory handlers. */
|
|
|
|
static class CMemHandlerInit {
|
|
|
|
public:
|
|
|
|
// constructor
|
|
|
|
CMemHandlerInit(void);
|
|
|
|
} MemHandlerInit;
|
|
|
|
|
|
|
|
CMemHandlerInit::CMemHandlerInit(void)
|
|
|
|
{
|
|
|
|
// set our not-enough-memory handler
|
|
|
|
_set_new_handler(NewHandler);
|
|
|
|
// make malloc use that handler
|
2016-03-29 03:03:54 +02:00
|
|
|
#ifdef _MSC_VER
|
2016-03-11 14:57:17 +01:00
|
|
|
_set_new_mode(1);
|
2016-03-29 03:03:54 +02:00
|
|
|
#endif
|
2016-03-11 14:57:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#undef AllocMemory
|
|
|
|
|
|
|
|
void *AllocMemory( SLONG memsize )
|
|
|
|
{
|
|
|
|
void *pmem;
|
|
|
|
ASSERTMSG(memsize>0, "AllocMemory: Block size is less or equal zero.");
|
|
|
|
if (_bCheckAllAllocations) {
|
|
|
|
_CrtCheckMemory();
|
|
|
|
}
|
|
|
|
pmem = malloc( memsize);
|
|
|
|
// memory handler asures no null results here?!
|
|
|
|
if (pmem==NULL) {
|
|
|
|
_CrtCheckMemory();
|
|
|
|
FatalError(TRANS("Not enough memory (%d bytes needed)!"), memsize);
|
|
|
|
}
|
|
|
|
return pmem;
|
|
|
|
}
|
|
|
|
|
2016-03-29 03:03:54 +02:00
|
|
|
#ifdef _MSC_VER
|
2016-03-11 14:57:17 +01:00
|
|
|
#ifndef NDEBUG
|
|
|
|
void *_debug_AllocMemory( SLONG memsize, int iType, const char *strFile, int iLine)
|
|
|
|
{
|
|
|
|
void *pmem;
|
|
|
|
ASSERTMSG(memsize>0, "AllocMemory: Block size is less or equal zero.");
|
|
|
|
|
|
|
|
if (_bCheckAllAllocations) {
|
|
|
|
_CrtCheckMemory();
|
|
|
|
}
|
|
|
|
pmem = _malloc_dbg( memsize, iType, strFile, iLine);
|
|
|
|
// memory handler asures no null results here?!
|
|
|
|
if (pmem==NULL) {
|
|
|
|
_CrtCheckMemory();
|
|
|
|
FatalError(TRANS("Not enough memory (%d bytes needed)!"), memsize);
|
|
|
|
}
|
|
|
|
return pmem;
|
|
|
|
}
|
|
|
|
#endif
|
2016-03-29 03:03:54 +02:00
|
|
|
#endif
|
2016-03-11 14:57:17 +01:00
|
|
|
|
|
|
|
void *AllocMemoryAligned( SLONG memsize, SLONG slAlignPow2)
|
|
|
|
{
|
|
|
|
ULONG ulMem = (ULONG)AllocMemory(memsize+slAlignPow2*2);
|
|
|
|
ULONG ulMemAligned = ((ulMem+slAlignPow2-1) & ~(slAlignPow2-1)) + slAlignPow2;
|
|
|
|
((ULONG *)ulMemAligned)[-1] = ulMem;
|
|
|
|
return (void*)ulMemAligned;
|
|
|
|
}
|
|
|
|
void FreeMemoryAligned( void *memory)
|
|
|
|
{
|
|
|
|
FreeMemory((void*) ( ( (ULONG*)memory )[-1] ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void FreeMemory( void *memory )
|
|
|
|
{
|
|
|
|
ASSERTMSG(memory!=NULL, "FreeMemory: NULL pointer input.");
|
|
|
|
free( (char *)memory);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ResizeMemory( void **ppv, SLONG slSize )
|
|
|
|
{
|
|
|
|
if (_bCheckAllAllocations) {
|
|
|
|
_CrtCheckMemory();
|
|
|
|
}
|
|
|
|
void *pv = realloc(*ppv, slSize);
|
|
|
|
// memory handler asures no null results here?!
|
|
|
|
if (pv==NULL) {
|
|
|
|
_CrtCheckMemory();
|
|
|
|
FatalError(TRANS("Not enough memory (%d bytes needed)!"), slSize);
|
|
|
|
}
|
|
|
|
*ppv = pv;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GrowMemory( void **ppv, SLONG newSize )
|
|
|
|
{
|
|
|
|
ResizeMemory(ppv, newSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ShrinkMemory( void **ppv, SLONG newSize )
|
|
|
|
{
|
|
|
|
ResizeMemory(ppv, newSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate a copy of a string. - fatal error if not enough memory.
|
|
|
|
*/
|
|
|
|
char *StringDuplicate(const char *strOriginal) {
|
|
|
|
// get the size
|
|
|
|
SLONG slSize = strlen(strOriginal)+1;
|
|
|
|
// allocate that much memory
|
|
|
|
char *strCopy = (char *)AllocMemory(slSize);
|
|
|
|
// copy it there
|
|
|
|
memcpy(strCopy, strOriginal, slSize);
|
|
|
|
// result is the pointer to the copied string
|
|
|
|
return strCopy;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// return position where we encounter zero byte or iBytes
|
|
|
|
INDEX FindZero( UBYTE *pubMemory, INDEX iBytes)
|
|
|
|
{
|
|
|
|
for( INDEX i=0; i<iBytes; i++) if( pubMemory[i]==0) return i;
|
|
|
|
return iBytes;
|
|
|
|
}
|