1
1
forked from 0ad/0ad
fpclassify fix
EntityManager: rename getExtant -> GetExtantAsHandles, fix its
implementation+call site to avoid dynamic alloc/auto ptr, rename extant
-> IsExtant
vsnprintf2 -> sys_vsnprintf. remove printf.h (function is declared in
sysdep header)
use SUS/posix-ish strcasecmp instead of defining that to the
windows-only stricmp
add cppdoc for ia32/cpu

This was SVN commit r5011.
This commit is contained in:
janwas 2007-04-30 19:58:04 +00:00
parent 22ede31161
commit 5a427440d0
35 changed files with 215 additions and 129 deletions

View File

@ -1022,7 +1022,7 @@ void CGUI::ReportParseError(const char *str, ...)
memset(buffer,0,sizeof(buffer));
va_start(argp, str);
vsnprintf2(buffer, sizeof(buffer), str, argp);
sys_vsnprintf(buffer, sizeof(buffer), str, argp);
va_end(argp);
// Print header

View File

@ -8,7 +8,7 @@
* =========================================================================
*/
/*b
/*
* Copyright (c) 2003-2005 Jan Wassenberg
*
* Redistribution and/or modification are also permitted under the

View File

@ -2,7 +2,7 @@
#include "posix.h"
#if CPU_IA32
# include "lib/sysdep/ia32/ia32.h"
# include "lib/sysdep/ia32/ia32_asm.h"
#endif
@ -48,17 +48,26 @@ float fmaxf(float a, float b)
uint fpclassifyd(double d)
{
#if CPU_IA32
return ia32_asm_fpclassifyd(d);
#else
// really sucky stub implementation; doesn't attempt to cover all cases.
if(d != d)
return FP_NAN;
else
return FP_NORMAL;
#endif
}
uint fpclassifyf(float f)
{
return fpclassify((double)f);
#if CPU_IA32
return ia32_asm_fpclassifyf(f);
#else
const double d = (double)f;
return fpclassifyd(d);
#endif
}
#endif // #if !HAVE_C99_MATH

View File

@ -75,6 +75,10 @@ need only be renamed (e.g. _open, _stat).
#include "posix_utsname.h"
// note: the following need only be #defined (instead of defining a
// trampoline function) because the redefined functions are already
// declared by standard headers.
// provide C99 *snprintf functions if compiler doesn't already
// (MinGW does, VC7.1 doesn't).
#if MSC_VERSION
@ -84,6 +88,12 @@ need only be renamed (e.g. _open, _stat).
# define vswprintf _vsnwprintf
#endif
// VC doesn't define str[n]casecmp
#if MSC_VERSION
#define strcasecmp stricmp
#define strncasecmp strnicmp
#endif
#if !HAVE_STRDUP
extern char* strdup(const char* str);

View File

@ -50,7 +50,7 @@ static inline bool file_type_is_uncompressible(const char* fn)
for(uint i = 0; i < ARRAY_SIZE(uncompressible_exts); i++)
{
if(!stricmp(ext+1, uncompressible_exts[i]))
if(!strcasecmp(ext+1, uncompressible_exts[i]))
return true;
}

View File

@ -661,11 +661,11 @@ static bool can_ignore_reload(const char* V_path, PathList pending_reloads, uint
return true;
// .. compiled XML files the engine writes out by the hundreds;
// skipping them is a big performance gain.
if(!stricmp(ext, "xmb"))
if(!strcasecmp(ext, "xmb"))
return true;
// .. temp files, usually created when an editor saves a file
// (delete, create temp, rename temp); no need to reload those.
if(!stricmp(ext, "tmp"))
if(!strcasecmp(ext, "tmp"))
return true;
// .. more than one notification for a file; only reload once.
// note: this doesn't suffer from the 'reloaded too early'

View File

@ -552,7 +552,7 @@ public:
// remove if not same extension
const char* ext = path_extension(ent.name);
if(stricmp(archive_ext, ext) != 0)
if(strcasecmp(archive_ext, ext) != 0)
return true;
// keep

View File

@ -174,7 +174,7 @@ public:
// possibly OS are case-sensitive) and wastes memory here.
// what we'll do is warn and treat as separate filename
// (least surprise).
// if(!stricmp(k1, k2))
// if(!strcasecmp(k1, k2))
// debug_warn("filenames differ only in case: bug?");
#endif
return false;

View File

@ -53,9 +53,9 @@ static const char* shader_type_to_string(GLenum type, char* buf, size_t buflen)
// or 0 if the shader type is not known.
static GLenum string_to_shader_type(const char* name)
{
if (!stricmp(name, "VERTEX_SHADER"))
if (!strcasecmp(name, "VERTEX_SHADER"))
return GL_VERTEX_SHADER_ARB;
if (!stricmp(name, "FRAGMENT_SHADER"))
if (!strcasecmp(name, "FRAGMENT_SHADER"))
return GL_FRAGMENT_SHADER_ARB;
return 0;
}

View File

@ -72,7 +72,7 @@ static bool bmp_is_hdr(const u8* file)
static bool bmp_is_ext(const char* ext)
{
return !stricmp(ext, "bmp");
return !strcasecmp(ext, "bmp");
}

View File

@ -605,7 +605,7 @@ static bool dds_is_hdr(const u8* file)
static bool dds_is_ext(const char* ext)
{
return !stricmp(ext, "dds");
return !strcasecmp(ext, "dds");
}

View File

@ -579,7 +579,7 @@ static bool jpg_is_hdr(const u8* file)
static bool jpg_is_ext(const char* ext)
{
return !stricmp(ext, "jpg") || !stricmp(ext, "jpeg");
return !strcasecmp(ext, "jpg") || !strcasecmp(ext, "jpeg");
}

View File

@ -204,7 +204,7 @@ static bool png_is_hdr(const u8* file)
static bool png_is_ext(const char* ext)
{
return !stricmp(ext, "png");
return !strcasecmp(ext, "png");
}

View File

@ -91,7 +91,7 @@ static bool tga_is_hdr(const u8* file)
static bool tga_is_ext(const char* ext)
{
return !stricmp(ext, "tga");
return !strcasecmp(ext, "tga");
}

View File

@ -1092,7 +1092,7 @@ static LibError SndData_reload(SndData * sd, const char * fn, Handle hsd)
const char * ext = path_extension(fn);
// .. OGG (data will be passed directly to OpenAL)
if(!stricmp(ext, "ogg"))
if(!strcasecmp(ext, "ogg"))
{
#ifdef OGG_HACK
#else
@ -1626,7 +1626,7 @@ static LibError VSrc_reload(VSrc * vs, const char * fn, Handle hvs)
// declare here so that it doesn't go out of scope below.
const char * ext = path_extension(fn);
if(!stricmp(ext, "txt"))
if(!strcasecmp(ext, "txt"))
{
FileIOBuf buf; size_t size;
RETURN_ERR(vfs_load(fn, buf, size));

View File

@ -81,6 +81,10 @@ extern bool cpu_CAS(uintptr_t* location, uintptr_t expected, uintptr_t new_value
// similar mishaps, the implementation verifies <location> is a valid pointer.
#define CAS(l,o,n) cpu_CAS((uintptr_t*)l, (uintptr_t)o, (uintptr_t)n)
/**
* add a signed value to a variable without the possibility of interference
* from other threads/CPUs.
**/
extern void cpu_atomic_add(intptr_t* location, intptr_t increment);
// enforce strong memory ordering.

View File

@ -9,7 +9,7 @@
*/
/*
* Copyright (c) 2003-2005 Jan Wassenberg
* Copyright (c) 2003-2007 Jan Wassenberg
*
* Redistribution and/or modification are also permitted under the
* terms of the GNU General Public License as published by the
@ -20,8 +20,8 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef IA32_H
#define IA32_H
#ifndef INCLUDED_IA32
#define INCLUDED_IA32
#if !CPU_IA32
#error "including ia32.h without CPU_IA32=1"
@ -30,19 +30,19 @@
#include "ia32_asm.h"
#include "ia32_memcpy.h"
// call before any of the following functions
/**
* must be called exactly once before any of the following functions.
**/
extern void ia32_init();
// fpclassify return values
/// fpclassify return values
#define IA32_FP_NAN 0x0100
#define IA32_FP_NORMAL 0x0400
#define IA32_FP_INFINITE (IA32_FP_NAN | IA32_FP_NORMAL)
#define IA32_FP_ZERO 0x4000
#define IA32_FP_SUBNORMAL (IA32_FP_NORMAL | IA32_FP_ZERO)
// FPU control word
// FPU control word (for ia32_asm_control87)
// .. Precision Control:
#define IA32_MCW_PC 0x0300
#define IA32_PC_24 0x0000
@ -61,24 +61,9 @@ extern void ia32_init();
#define IA32_EM_UNDERFLOW BIT(4)
#define IA32_EM_INEXACT BIT(5)
extern void ia32_mfence();
extern void ia32_serialize();
extern u64 ia32_rdtsc_safe(void);
#if CONFIG_RETURN64_EDX_EAX
# define ia32_rdtsc ia32_asm_rdtsc_edx_eax
#else
# define ia32_rdtsc ia32_rdtsc_safe
#endif
extern void ia32_debug_break(void);
// order in which registers are stored in CPUID regs array
// (do not change! brand string relies on this ordering)
/**
* order in which ia32_asm_cpuid stores register values
**/
enum IA32Regs
{
EAX,
@ -87,8 +72,10 @@ enum IA32Regs
EDX
};
// CPU capability flags (128 bits)
// do not change the order!
/**
* bit indices of CPU capability flags (128 bits).
* values are defined by IA-32 CPUID feature flags - do not change!
**/
enum IA32Cap
{
// standard (ecx) - currently only defined by Intel
@ -113,25 +100,89 @@ enum IA32Cap
IA32_CAP_AMD_3DNOW = 96+31
};
// indicate if the CPU supports the indicated cap.
/**
* @return whether the CPU supports the indicated IA32Cap / feature flag.
**/
extern bool ia32_cap(IA32Cap cap);
// checks if there is an IA-32 CALL instruction right before ret_addr.
// returns INFO::OK if so and ERR::FAIL if not.
// also attempts to determine the call target. if that is possible
// (directly addressed relative or indirect jumps), it is stored in
// target, which is otherwise 0.
//
// this is useful for walking the stack manually.
/**
* check if there is an IA-32 CALL instruction right before ret_addr.
* @return INFO::OK if so and ERR::FAIL if not.
*
* also attempts to determine the call target. if that is possible
* (directly addressed relative or indirect jumps), it is stored in
* target, which is otherwise 0.
*
* this function is used for walking the call stack.
**/
extern LibError ia32_get_call_target(void* ret_addr, void** target);
/// safe but slow inline-asm version
extern u64 ia32_rdtsc_safe(void);
/**
* @return the current value of the TimeStampCounter (a counter of
* CPU cycles since power-on, which is useful for high-resolution timing
* but potentially differs between multiple CPUs)
**/
extern u64 ia32_rdtsc(); // only for CppDoc's benefit
#if CONFIG_RETURN64_EDX_EAX
# define ia32_rdtsc ia32_asm_rdtsc_edx_eax
#else
# define ia32_rdtsc ia32_rdtsc_safe
#endif
/**
* trigger a breakpoint inside this function when it is called.
**/
extern void ia32_debug_break(void);
// CPU detection
/**
* @return string identifying the CPU (usually a cleaned-up version of the
* brand string)
**/
extern const char* ia32_identifierString();
/**
* @return whether CPU frequency throttling is possible or
* may potentially happen (if so, using RDTSC is unsafe).
**/
extern int ia32_isThrottlingPossible();
/**
* @return the cached result of a precise measurement of the
* CPU frequency.
**/
extern double ia32_clockFrequency();
/**
* @return number of *enabled* CPU packages / sockets.
**/
extern uint ia32_numPackages();
/**
* @return number of *enabled* CPU cores per package.
* (2 on dual-core systems)
**/
extern uint ia32_coresPerPackage();
/**
* @return number of *enabled* hyperthreading units per core.
* (2 on P4 EE)
**/
extern uint ia32_logicalPerCore();
#endif // #ifndef IA32_H
// implementations of the cpu.h interface
/// see cpu_mfence
extern void ia32_mfence();
// see cpu_serialize
extern void ia32_serialize();
#endif // #ifndef INCLUDED_IA32

View File

@ -192,9 +192,9 @@ sym(ia32_asm_control87):
; possible IA-32 FPU control word flags after FXAM: NAN|NORMAL|ZERO
FP_CLASSIFY_MASK equ 0x4500
; extern "C" uint __cdecl ia32_asm_fpclassify(double d);
global sym(ia32_asm_fpclassify)
sym(ia32_asm_fpclassify):
; extern "C" uint __cdecl ia32_asm_fpclassifyd(double d);
global sym(ia32_asm_fpclassifyd)
sym(ia32_asm_fpclassifyd):
fld qword [esp+4]
fxam
fnstsw ax

View File

@ -5,37 +5,66 @@
extern "C" {
#endif
/**
* prepare ia32_asm_cpuid for use (detects which CPUID functions are
* available). called by ia32_init.
**/
extern void ia32_asm_cpuid_init();
// try to call the specified CPUID sub-function. returns true on success or
// false on failure (i.e. CPUID or the specific function not supported).
// returns eax, ebx, ecx, edx registers in above order.
/**
* try to call the specified CPUID sub-function.
* (note: ECX is set to 0 beforehand as required by sub-function 4)
* fills register array according to IA32Regs.
* @return true on success or false if the sub-function isn't supported.
**/
extern bool ia32_asm_cpuid(u32 func, u32* regs);
extern void ia32_asm_atomic_add(intptr_t* location, intptr_t increment);
extern bool ia32_asm_CAS(uintptr_t* location, uintptr_t expected, uintptr_t new_value);
/**
* for all 1-bits in mask, update the corresponding FPU control word bits
* with the bit values in new_val.
* @return 0 to indicate success.
**/
extern uint ia32_asm_control87(uint new_val, uint mask);
extern uint ia32_asm_fpclassify(double d);
/**
* @return the current value of the TimeStampCounter in edx:eax
* (interpretable as a u64 when using the standard Win32 calling convention)
**/
extern u64 ia32_asm_rdtsc_edx_eax(void);
/**
* write the current execution state (e.g. all register values) into
* (Win32::CONTEXT*)pcontext (defined as void* to avoid dependency).
**/
extern void ia32_asm_get_current_context(void* pcontext);
// implementations of the cpu.h interface
/// see cpu_atomic_add
extern void ia32_asm_atomic_add(intptr_t* location, intptr_t increment);
/// see cpu_CAS
extern bool ia32_asm_CAS(uintptr_t* location, uintptr_t expected, uintptr_t new_value);
/// see cpu_i32_from_float
extern i32 ia32_asm_i32_from_float(float f);
extern i32 ia32_asm_i32_from_double(double d);
extern i64 ia32_asm_i64_from_double(double d);
// backends for POSIX/SUS functions
/// see fpclassify
extern uint ia32_asm_fpclassifyd(double d);
extern uint ia32_asm_fpclassifyf(float f);
/// see rintf
extern float ia32_asm_rintf(float);
extern double ia32_asm_rint(double);
extern float ia32_asm_fminf(float, float);
extern float ia32_asm_fmaxf(float, float);
extern i32 ia32_asm_i32_from_float(float f);
extern i32 ia32_asm_i32_from_double(double d);
extern i64 ia32_asm_i64_from_double(double d);
extern u64 ia32_asm_rdtsc_edx_eax(void);
// write the current execution state (e.g. all register values) into
// (Win32::CONTEXT*)pcontext (defined as void* to avoid dependency).
extern void ia32_asm_get_current_context(void* pcontext);
#ifdef __cplusplus
}

View File

@ -26,31 +26,9 @@
#include "lib/config.h"
#include "lib/debug.h" // ErrorReaction
#include <cstdarg> // needed for vsnprintf2
#include <cstdarg> // needed for sys_vsnprintf
//-----------------------------------------------------------------------------
// C99 / SUSv3 emulation where needed
//-----------------------------------------------------------------------------
// vsnprintf2: doesn't quite follow the standard for vsnprintf, but works
// better across compilers:
// - handles positional parameters and %lld
// - always null-terminates the buffer
// - returns -1 on overflow (if the output string (including null) does not fit in the buffer)
extern int vsnprintf2(char* buffer, size_t count, const char* format, va_list argptr);
#if !MSC_VERSION
#define stricmp strcasecmp
#define strnicmp strncasecmp
#endif
//-----------------------------------------------------------------------------
// sysdep API
//-----------------------------------------------------------------------------
//
// output
//
@ -120,6 +98,14 @@ extern LibError sys_cursor_free(void* cursor);
// misc
//
// sys_vsnprintf: doesn't quite follow the standard for vsnprintf, but works
// better across compilers:
// - handles positional parameters and %lld
// - always null-terminates the buffer
// - returns -1 on overflow (if the output string (including null) does not fit in the buffer)
extern int sys_vsnprintf(char* buffer, size_t count, const char* format, va_list argptr);
/**
* allocate on stack, automatically free when current function returns.
**/

View File

@ -6,7 +6,7 @@
class TestPrintf : public CxxTest::TestSuite
{
// Split some bits into separate functions, so we can get
// a legitimate va_list to pass to vsnprintf2:
// a legitimate va_list to pass to sys_vsnprintf:
void _test_truncate(int buffer_size, char* expected_output, int expected_return, /* char* input_string */...)
{
@ -15,7 +15,7 @@ class TestPrintf : public CxxTest::TestSuite
va_list ap;
va_start(ap, expected_return);
int ret = vsnprintf2(buf, buffer_size, "%s", ap);
int ret = sys_vsnprintf(buf, buffer_size, "%s", ap);
TS_ASSERT_STR_EQUALS(buf, expected_output);
TS_ASSERT_EQUALS(ret, expected_return);
@ -33,7 +33,7 @@ class TestPrintf : public CxxTest::TestSuite
va_list ap;
va_start(ap, format);
vsnprintf2(buf, sizeof(buf), format, ap);
sys_vsnprintf(buf, sizeof(buf), format, ap);
TS_ASSERT_STR_EQUALS(buf, expected_output);
va_end(ap);

View File

@ -5,7 +5,7 @@
// See declaration in sysdep.h for explanation of need
int vsnprintf2(char* buffer, size_t count, const char* format, va_list argptr)
int sys_vsnprintf(char* buffer, size_t count, const char* format, va_list argptr)
{
int ret = vsnprintf(buffer, count, format, argptr);

View File

@ -623,7 +623,7 @@ static FARPROC WINAPI notify_hook(unsigned dliNotify, PDelayLoadInfo pdli)
return 0;
for(DllLoadNotify* n = notify_list; n; n = n->next)
if(strnicmp(pdli->szDll, n->dll_name, strlen(n->dll_name)) == 0)
if(strncasecmp(pdli->szDll, n->dll_name, strlen(n->dll_name)) == 0)
n->func();
return 0;

View File

@ -1,2 +0,0 @@
// Acts like vsnprintf, but handles positional parameters and %lld
int vsnprintf2(char* buffer, size_t count, const char* format, va_list argptr);

View File

@ -175,7 +175,7 @@ int type_size(TCHAR type, int length)
return 0;
}
int vsnprintf2(TCHAR* buffer, size_t count, const TCHAR* format, va_list argptr)
int sys_vsnprintf(TCHAR* buffer, size_t count, const TCHAR* format, va_list argptr)
{
/*

View File

@ -90,7 +90,7 @@ static LibError add_if_oal_dll(const DirEnt* ent, PathPackage* pp, StringSet* dl
// skip if not an OpenAL DLL.
const size_t len = strlen(fn);
const bool oal = len >= 7 && !stricmp(fn+len-7, "oal.dll");
const bool oal = len >= 7 && !strcasecmp(fn+len-7, "oal.dll");
const bool openal = strstr(fn, "OpenAL") != 0;
if(!oal && !openal)
return INFO::OK;

View File

@ -170,7 +170,7 @@ void CLogger::Log(ELogMethod method, const char* category, const char *fmt, ...)
char buffer[512];
va_start(argp, fmt);
if (vsnprintf2(buffer, sizeof(buffer), fmt, argp) == -1)
if (sys_vsnprintf(buffer, sizeof(buffer), fmt, argp) == -1)
{
// Buffer too small - ensure the string is nicely terminated
strcpy(buffer+sizeof(buffer)-4, "..."); // safe
@ -187,7 +187,7 @@ void CLogger::LogOnce(ELogMethod method, const char* category, const char *fmt,
char buffer[512];
va_start(argp, fmt);
if (vsnprintf2(buffer, sizeof(buffer), fmt, argp) == -1)
if (sys_vsnprintf(buffer, sizeof(buffer), fmt, argp) == -1)
{
// Buffer too small - ensure the string is nicely terminated
strcpy(buffer+sizeof(buffer)-4, "..."); // safe

View File

@ -46,7 +46,7 @@ void CFileUnpacker::Read(const char* filename,const char magicstr[4])
// that the buffer will be kept in memory longer (avoids warning).
uint flags = 0;
const char* ext = path_extension(filename);
if(!stricmp(ext, "pmp"))
if(!strcasecmp(ext, "pmp"))
flags |= FILE_LONG_LIVED;
// load the whole thing into memory

View File

@ -176,7 +176,7 @@ void WriteScreenshot(const char* extension)
int flags = TEX_BOTTOM_UP;
// we want writing BMP to be as fast as possible,
// so read data from OpenGL in BMP format to obviate conversion.
if(!stricmp(extension, "bmp"))
if(!strcasecmp(extension, "bmp"))
{
fmt = GL_BGR;
flags |= TEX_BGR;
@ -221,7 +221,7 @@ void WriteBigScreenshot(const char* extension, int tiles)
int flags = TEX_BOTTOM_UP;
// we want writing BMP to be as fast as possible,
// so read data from OpenGL in BMP format to obviate conversion.
if(!stricmp(extension, "bmp"))
if(!strcasecmp(extension, "bmp"))
{
fmt = GL_BGR;
flags |= TEX_BGR;

View File

@ -89,7 +89,7 @@ int XMBFile::getElementID(const char* Name) const
{
// See if this could be the right string, checking its
// length and then its contents
if (*(int*)Pos == len && strnicmp(Pos+4, Name, len) == 0)
if (*(int*)Pos == len && strncasecmp(Pos+4, Name, len) == 0)
return i;
// If not, jump to the next string
Pos += 4 + *(int*)Pos;
@ -109,7 +109,7 @@ int XMBFile::getAttributeID(const char* Name) const
{
// See if this could be the right string, checking its
// length and then its contents
if (*(int*)Pos == len && strnicmp(Pos+4, Name, len) == 0)
if (*(int*)Pos == len && strncasecmp(Pos+4, Name, len) == 0)
return i;
// If not, jump to the next string
Pos += 4 + *(int*)Pos;

View File

@ -1508,11 +1508,11 @@ JSFunctionSpec ScriptFunctionTable[] =
JSBool GetEntitySet( JSContext* UNUSED(cx), JSObject* UNUSED(obj), jsval UNUSED(argv), jsval* vp )
{
std::auto_ptr<std::vector<HEntity> > extant (g_EntityManager.getExtant());
std::vector<HEntity> extant;
g_EntityManager.GetExtantAsHandles(extant);
*vp = OBJECT_TO_JSVAL(EntityCollection::Create(extant));
*vp = OBJECT_TO_JSVAL( EntityCollection::Create( *extant ) );
return( JS_TRUE );
return JS_TRUE;
}

View File

@ -31,7 +31,7 @@ HEntity::HEntity()
HEntity::~HEntity()
{
if( CEntityManager::extant() )
if( CEntityManager::IsExtant() )
decRef();
}

View File

@ -184,13 +184,12 @@ std::vector<HEntity>* CEntityManager::matches( EntityPredicate predicate, void*
return( matchlist );
}
std::vector<HEntity>* CEntityManager::getExtant()
void CEntityManager::GetExtantAsHandles( std::vector<HEntity>& results )
{
std::vector<HEntity>* activelist = new std::vector<HEntity>;
results.clear();
for( int i = 0; i < MAX_HANDLES; i++ )
if( isEntityRefd(i) )
activelist->push_back( HEntity( i ) );
return( activelist );
results.push_back( HEntity( i ) );
}
void CEntityManager::GetExtant( std::vector<CEntity*>& results )

View File

@ -11,7 +11,7 @@
// Perform updates on all world entities by g_EntityManager.updateAll( timestep )
// Dispatch an identical message to all world entities by g_EntityManager.dispatchAll( message_pointer )
// Get an STL vector container of all entities with a certain property with g_EntityManager.matches( predicate )
// or just get all entities with g_EntityManager.getExtant().
// or just get all entities with g_EntityManager.GetExtant().
//
// Those last two functions - caller has responsibility for deleting the collection when you're done with it.
@ -113,9 +113,9 @@ public:
{ return( !operand( target, userdata ) ); }
std::vector<HEntity>* matches( EntityPredicate predicate, void* userdata = NULL );
std::vector<HEntity>* getExtant();
void GetExtant( std::vector<CEntity*>& results ); // TODO: Switch most/all uses of getExtant() to this.
static inline bool extant() // True if the singleton is actively maintaining handles. When false, system is shutting down, handles are quietly dumped.
void GetExtantAsHandles( std::vector<HEntity>& results );
void GetExtant( std::vector<CEntity*>& results );
static inline bool IsExtant() // True if the singleton is actively maintaining handles. When false, system is shutting down, handles are quietly dumped.
{
return( m_extant );
}

View File

@ -35,7 +35,7 @@ CModelDef::~CModelDef()
SPropPoint* CModelDef::FindPropPoint(const char* name) const
{
for (uint i=0;i<m_NumPropPoints;i++) {
if (stricmp(name,m_PropPoints[i].m_Name)==0) {
if (strcasecmp(name,m_PropPoints[i].m_Name)==0) {
return &m_PropPoints[i];
}
}