]> git.jsancho.org Git - lugaru.git/blob - Source/MacCompatibility.cpp
Handle case mismatch in filenames.
[lugaru.git] / Source / MacCompatibility.cpp
1 #if !PLATFORM_MACOSX
2
3 /**> HEADER FILES <**/
4 #include "MacCompatibility.h"
5
6 #ifdef WIN32
7 #include <windows.h>
8 #endif
9
10 #include <errno.h>
11 #include <time.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15
16 #if PLATFORM_UNIX
17 #include <unistd.h>
18 #include <sys/time.h>
19 #include <assert.h>
20 typedef long long __int64;
21 typedef __int64 LARGE_INTEGER;
22 static int QueryPerformanceFrequency(LARGE_INTEGER *liptr)
23 {
24     assert(sizeof (__int64) == 8);
25     assert(sizeof (LARGE_INTEGER) == 8);
26     *liptr = 1000;
27     return(1);
28 }
29
30 static int QueryPerformanceCounter(LARGE_INTEGER *liptr)
31 {
32     struct timeval tv;
33     gettimeofday(&tv, NULL);
34     *liptr = ( (((LARGE_INTEGER) tv.tv_sec) * 1000) +
35                (((LARGE_INTEGER) tv.tv_usec) / 1000) );
36     return(1);
37 }
38 #endif
39
40 class AppTime
41 {
42 public:
43         AppTime()
44         {
45                 counterRate = 1;
46                 baseCounter = 0;
47                 QueryPerformanceFrequency( (LARGE_INTEGER*)&counterRate);
48                 QueryPerformanceCounter( (LARGE_INTEGER*)&baseCounter);
49         }
50         __int64 counterRate;            // LARGE_INTEGER type has no math functions so use int64
51         __int64 baseCounter;
52 };
53 static AppTime g_appTime;
54
55
56 void CopyCStringToPascal( const char* src, unsigned char dst[256])
57 {
58         int len = strlen( src);
59         dst[ 0] = len;
60         memcpy( dst + 1, src, len);
61 }
62
63
64 void CopyPascalStringToC( const unsigned char* src, char* dst)
65 {
66         int len = src[ 0];
67         memcpy( dst, src + 1, len);
68         dst[ len] = 0;
69 }
70
71
72 AbsoluteTime UpTime()
73 {
74         __int64 counter;
75         QueryPerformanceCounter( (LARGE_INTEGER*)&counter);
76
77         counter -= g_appTime.baseCounter;
78
79         AbsoluteTime time;
80         time.lo = (unsigned long)counter;
81         time.hi = (unsigned long)(counter >> 32);
82         return time;
83 }
84
85
86 Duration AbsoluteDeltaToDuration( AbsoluteTime& a, AbsoluteTime& b)
87 {
88         __int64 value = a.hi;
89         value <<= 32;
90         value |= a.lo;
91         __int64 value2 = b.hi;
92         value2 <<= 32;
93         value2 |= b.lo;
94         value -= value2;
95
96         if (value <= 0)
97                 return durationImmediate;
98
99         __int64 frac = value % g_appTime.counterRate;
100         value /= g_appTime.counterRate;
101
102         Duration time;
103
104         if (value == 0)
105         {
106                 frac *= -1000000;
107                 frac /= g_appTime.counterRate;
108                 time = (Duration)frac;
109         }
110         else
111         {
112                 frac *= 1000;
113                 frac /= g_appTime.counterRate;
114                 value *= 1000;
115                 value += frac;
116                 time = (Duration)value;
117         }
118
119         return time;
120 }
121
122
123 #if PLATFORM_UNIX
124 #include <sys/types.h>
125 #include <dirent.h>
126
127 // public domain code from PhysicsFS: http://icculus.org/physfs/
128 static int locateOneElement(char *buf)
129 {
130     char *ptr;
131     char **rc;
132     char **i;
133     DIR *dirp;
134
135     //if (PHYSFS_exists(buf))
136     if (access(buf, F_OK) == 0)
137         return(1);  /* quick rejection: exists in current case. */
138
139     ptr = strrchr(buf, '/');  /* find entry at end of path. */
140     if (ptr == NULL)
141     {
142         dirp = opendir(".");
143         ptr = buf;
144     } /* if */
145     else
146     {
147         *ptr = '\0';
148         dirp = opendir(buf);
149         *ptr = '/';
150         ptr++;  /* point past dirsep to entry itself. */
151     } /* else */
152
153     struct dirent *dent;
154     while ((dent = readdir(dirp)) != NULL)
155     {
156         if (stricmp(dent->d_name, ptr) == 0)
157         {
158             strcpy(ptr, dent->d_name); /* found a match. Overwrite with this case. */
159             closedir(dirp);
160             return(1);
161         } /* if */
162     } /* for */
163
164     /* no match at all... */
165     closedir(dirp);
166     return(0);
167 } /* locateOneElement */
168
169
170 static inline int PHYSFSEXT_locateCorrectCase(char *buf)
171 {
172     int rc;
173     char *ptr;
174     char *prevptr;
175
176     ptr = prevptr = buf;
177     if (*ptr == '\0')
178         return(0);  /* Uh...I guess that's success. */
179
180     while (ptr = strchr(ptr + 1, '/'))
181     {
182         *ptr = '\0';  /* block this path section off */
183         rc = locateOneElement(buf);
184         *ptr = '/'; /* restore path separator */
185         if (!rc)
186             return(-2);  /* missing element in path. */
187     } /* while */
188
189     /* check final element... */
190     return(locateOneElement(buf) ? 0 : -1);
191 } /* PHYSFSEXT_locateCorrectCase */
192 #endif
193
194
195 static char g_filename[ 256];
196 char* ConvertFileName( const char* orgfilename)
197 {
198         // translate filename into proper path name
199         if (orgfilename[ 0] == ':')
200                 orgfilename++;
201         strcpy( g_filename, orgfilename);
202
203         for (int n = 0; g_filename[ n]; n++)
204         {
205                 if (g_filename[ n] == ':')
206                         g_filename[ n] = '/';
207         }
208
209     #if PLATFORM_UNIX
210     PHYSFSEXT_locateCorrectCase(g_filename);
211     #endif
212
213         return g_filename;
214 }
215
216 #endif
217
218