]> git.jsancho.org Git - lugaru.git/blobdiff - Source/MacCompatibility.cpp
AI: Prevent division by 0 when enemy has no velocity
[lugaru.git] / Source / MacCompatibility.cpp
index e82b1b758e276f99e4b18e8c2c56da1623ee5292..4ed303322a9f854cd1348c969978719d1cad4d61 100644 (file)
 /*
 Copyright (C) 2003, 2010 - Wolfire Games
+Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
 
 This file is part of Lugaru.
 
-Lugaru 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 2
-of the License, or (at your option) any later version.
+Lugaru 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 2 of the License, or
+(at your option) any later version.
 
-This program is distributed in the hope that it will be useful,
+Lugaru 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.
+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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#if !PLATFORM_MACOSX
+#include "MacCompatibility.hpp"
 
-/**> HEADER FILES <**/
-#include "MacCompatibility.h"
+#include <cerrno>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
 
 #ifdef WIN32
 #include <windows.h>
 #endif
 
-#include <errno.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
 #if PLATFORM_UNIX
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/stat.h>
 #include <assert.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
+
 typedef long long __int64;
 typedef __int64 LARGE_INTEGER;
-static int QueryPerformanceFrequency(LARGE_INTEGER *liptr)
+static int QueryPerformanceFrequency(LARGE_INTEGERliptr)
 {
-    assert(sizeof (__int64) == 8);
-    assert(sizeof (LARGE_INTEGER) == 8);
+    assert(sizeof(__int64) == 8);
+    assert(sizeof(LARGE_INTEGER) == 8);
     *liptr = 1000;
-    return(1);
+    return (1);
 }
 
-static int QueryPerformanceCounter(LARGE_INTEGER *liptr)
+static int QueryPerformanceCounter(LARGE_INTEGERliptr)
 {
     struct timeval tv;
     gettimeofday(&tv, NULL);
-    *liptr = ( (((LARGE_INTEGER) tv.tv_sec) * 1000) +
-               (((LARGE_INTEGER) tv.tv_usec) / 1000) );
-    return(1);
+    *liptr = ((((LARGE_INTEGER)tv.tv_sec) * 1000) +
+              (((LARGE_INTEGER)tv.tv_usec) / 1000));
+    return (1);
 }
 #endif
 
 class AppTime
 {
-public:
-       AppTime()
-       {
-               counterRate = 1;
-               baseCounter = 0;
-               QueryPerformanceFrequency( (LARGE_INTEGER*)&counterRate);
-               QueryPerformanceCounter( (LARGE_INTEGER*)&baseCounter);
-       }
-       __int64 counterRate;            // LARGE_INTEGER type has no math functions so use int64
-       __int64 baseCounter;
+  public:
+    AppTime()
+    {
+        counterRate = 1;
+        baseCounter = 0;
+        QueryPerformanceFrequency((LARGE_INTEGER*)&counterRate);
+        QueryPerformanceCounter((LARGE_INTEGER*)&baseCounter);
+    }
+    __int64 counterRate; // LARGE_INTEGER type has no math functions so use int64
+    __int64 baseCounter;
 };
 static AppTime g_appTime;
 
-
-void CopyCStringToPascal( const char* src, unsigned char dst[256])
-{
-       int len = strlen( src);
-       dst[ 0] = len;
-       memcpy( dst + 1, src, len);
-}
-
-
-void CopyPascalStringToC( const unsigned char* src, char* dst)
-{
-       int len = src[ 0];
-       memcpy( dst, src + 1, len);
-       dst[ len] = 0;
-}
-
-
 AbsoluteTime UpTime()
 {
-       __int64 counter;
-       QueryPerformanceCounter( (LARGE_INTEGER*)&counter);
+    __int64 counter;
+    QueryPerformanceCounter((LARGE_INTEGER*)&counter);
 
-       counter -= g_appTime.baseCounter;
+    counter -= g_appTime.baseCounter;
 
-       AbsoluteTime time;
-       time.lo = (unsigned long)counter;
-       time.hi = (unsigned long)(counter >> 32);
-       return time;
+    AbsoluteTime time;
+    time.lo = (unsigned long)counter;
+    time.hi = (unsigned long)(counter >> 32);
+    return time;
 }
 
-
-Duration AbsoluteDeltaToDuration( AbsoluteTime& a, AbsoluteTime& b)
+Duration AbsoluteDeltaToDuration(AbsoluteTime& a, AbsoluteTime& b)
 {
-       __int64 value = a.hi;
-       value <<= 32;
-       value |= a.lo;
-       __int64 value2 = b.hi;
-       value2 <<= 32;
-       value2 |= b.lo;
-       value -= value2;
-
-       if (value <= 0)
-               return durationImmediate;
-
-       __int64 frac = value % g_appTime.counterRate;
-       value /= g_appTime.counterRate;
-
-       Duration time;
-
-       if (value == 0)
-       {
-               frac *= -1000000;
-               frac /= g_appTime.counterRate;
-               time = (Duration)frac;
-       }
-       else
-       {
-               frac *= 1000;
-               frac /= g_appTime.counterRate;
-               value *= 1000;
-               value += frac;
-               time = (Duration)value;
-       }
-
-       return time;
-}
-
-
-#if PLATFORM_UNIX
-#include <sys/types.h>
-#include <pwd.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <dirent.h>
-
-// some but not all of this is code from PhysicsFS: http://icculus.org/physfs/
-//  the zlib license on physfs allows this cut-and-pasting.
-static int locateOneElement(char *buf)
-{
-    char *ptr;
-    char **rc;
-    char **i;
-    DIR *dirp;
-
-    //if (PHYSFS_exists(buf))
-    if (access(buf, F_OK) == 0)
-        return(1);  /* quick rejection: exists in current case. */
-
-    ptr = strrchr(buf, '/');  /* find entry at end of path. */
-    if (ptr == NULL)
-    {
-        dirp = opendir(".");
-        ptr = buf;
-    } /* if */
-    else
-    {
-        *ptr = '\0';
-        dirp = opendir(buf);
-        *ptr = '/';
-        ptr++;  /* point past dirsep to entry itself. */
-    } /* else */
-
-    struct dirent *dent;
-    while ((dent = readdir(dirp)) != NULL)
-    {
-        if (strcasecmp(dent->d_name, ptr) == 0)
-        {
-            strcpy(ptr, dent->d_name); /* found a match. Overwrite with this case. */
-            closedir(dirp);
-            return(1);
-        } /* if */
-    } /* for */
-
-    /* no match at all... */
-    closedir(dirp);
-    return(0);
-} /* locateOneElement */
-
-
-static inline const char *getUserDirByUID(void)
-{
-    struct passwd *pw = getpwuid(getuid());
-    if (pw != NULL)
-        return(pw->pw_dir);
-    return(NULL);
-} /* getUserDirByUID */
-
-
-static inline const char *getPrefPath(void)
-{
-    static char *prefpath = NULL;
-    if (prefpath == NULL)
-    {
-        const char *homedir = getenv("HOME");
-        if (homedir == NULL)
-            homedir = getUserDirByUID();
-        if (homedir == NULL)
-            homedir = ".";  // oh well.
-
-#if (defined(__APPLE__) && defined(__MACH__))
-        const char *PREFPATHNAME = "Library/Application Support/Lugaru";
-#else
-        const char *PREFPATHNAME = ".lugaru";
-#endif
-        size_t len = strlen(homedir) + strlen(PREFPATHNAME) + 2;
-        prefpath = new char[len];
-        snprintf(prefpath, len, "%s/%s", homedir, PREFPATHNAME);
+    __int64 value = a.hi;
+    value <<= 32;
+    value |= a.lo;
+    __int64 value2 = b.hi;
+    value2 <<= 32;
+    value2 |= b.lo;
+    value -= value2;
+
+    if (value <= 0) {
+        return durationImmediate;
     }
-    return(prefpath);
-}
-
-static int locateCorrectCase(char *buf, bool makedirs)
-{
-    int rc;
-    char *ptr;
-    char *prevptr;
-
-    ptr = prevptr = buf;
-    while (ptr = strchr(ptr + 1, '/'))
-    {
-        *ptr = '\0';  /* block this path section off */
-        rc = locateOneElement(buf);
-        if (!rc)
-        {
-            if (makedirs)  /* normal if we're writing; build dirs! */
-                mkdir(buf, S_IRWXU);
-            else
-            {
-                *ptr = '/'; /* restore path separator */
-                return(-2);  /* missing element in path. */
-            } /* else */
-        } /* if */
-        *ptr = '/'; /* restore path separator */
-    } /* while */
-
-    /* check final element... */
-    return(locateOneElement(buf) ? 0 : -1);
-}
-
 
-static int locateCorrectFile(char *buf, const char *mode)
-{
-    if (*buf == '\0')
-        return(0);  /* Uh...I guess that's failure. */
-
-    assert((mode[0] == 'w') || (mode[0] == 'r'));
-
-    bool iswriting = (mode[0] == 'w');
-    const char *prefpath = getPrefPath();
-    size_t len = strlen(buf) + strlen(prefpath) + 2;
-    char *prefpathfile = (char *) alloca(len);
-    snprintf(prefpathfile, len, "%s/%s", prefpath, buf);
-
-    int rc = locateCorrectCase(prefpathfile, iswriting);  /* favor prefpath. */
-    if ( (rc == 0) || ((rc == -1) && (iswriting)) ) // found or create?
-        strcpy(buf, prefpathfile);
-    else if ((rc < 0) && (!iswriting))  /* not writing? Try game dir... */
-        rc = locateCorrectCase(buf, iswriting);
-
-    return(rc);
-} /* locateCorrectFile */
-#endif
-
-
-static char g_filename[4096];
-char* ConvertFileName( const char* orgfilename, const char *mode)
-{
-    if (orgfilename == g_filename) // recursion?
-        return g_filename;
-
-       // translate filename into proper path name
-       if (orgfilename[ 0] == ':')
-               orgfilename++;
-       strcpy( g_filename, orgfilename);
-
-       for (int n = 0; g_filename[ n]; n++)
-       {
-               if (g_filename[ n] == ':')
-                       g_filename[ n] = '/';
-
-               else if (g_filename[ n] == '\\')
-                       g_filename[ n] = '/';
-       }
-
-    #if PLATFORM_UNIX
-    locateCorrectFile(g_filename, mode);
-    #endif
+    __int64 frac = value % g_appTime.counterRate;
+    value /= g_appTime.counterRate;
+
+    Duration time;
+
+    if (value == 0) {
+        frac *= -1000000;
+        frac /= g_appTime.counterRate;
+        time = (Duration)frac;
+    } else {
+        frac *= 1000;
+        frac /= g_appTime.counterRate;
+        value *= 1000;
+        value += frac;
+        time = (Duration)value;
+    }
 
-       return g_filename;
+    return time;
 }
-
-#endif
-
-