commit
e47eaa1425
|
@ -203,15 +203,11 @@ CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUF
|
||||||
{
|
{
|
||||||
// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
|
// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
FILE *test = fopen(filename, "r");
|
char *real = casepath(filename);
|
||||||
if (!test) {
|
if (real) {
|
||||||
char *r = (char*)alloca(strlen(filename) + 4);
|
strcpy(m_aFilename, real);
|
||||||
if (casepath(filename, r))
|
free(real);
|
||||||
{
|
|
||||||
strcpy(m_aFilename, r);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
fclose(test);
|
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -189,10 +189,11 @@ GetGTA3ImgSize(void)
|
||||||
realpath(gImgNames[0], path);
|
realpath(gImgNames[0], path);
|
||||||
if (stat(path, &statbuf) == -1) {
|
if (stat(path, &statbuf) == -1) {
|
||||||
// Try case-insensitivity
|
// Try case-insensitivity
|
||||||
char *r = (char*)alloca(strlen(gImgNames[0]) + 4);
|
char* real = casepath(gImgNames[0], false);
|
||||||
if (casepath(gImgNames[0], r))
|
if (real)
|
||||||
{
|
{
|
||||||
realpath(r, path);
|
realpath(real, path);
|
||||||
|
free(real);
|
||||||
if (stat(path, &statbuf) != -1)
|
if (stat(path, &statbuf) != -1)
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
|
@ -210,7 +211,6 @@ CdStreamShutdown(void)
|
||||||
{
|
{
|
||||||
// Destroying semaphores and free(gpReadInfo) will be done at threads
|
// Destroying semaphores and free(gpReadInfo) will be done at threads
|
||||||
#ifndef ONE_THREAD_PER_CHANNEL
|
#ifndef ONE_THREAD_PER_CHANNEL
|
||||||
free(gChannelRequestQ.items);
|
|
||||||
gCdStreamThreadStatus = 2;
|
gCdStreamThreadStatus = 2;
|
||||||
sem_post(&gCdStreamSema);
|
sem_post(&gCdStreamSema);
|
||||||
#endif
|
#endif
|
||||||
|
@ -442,6 +442,7 @@ void *CdStreamThread(void *param)
|
||||||
sem_destroy(&gpReadInfo[i].pDoneSemaphore);
|
sem_destroy(&gpReadInfo[i].pDoneSemaphore);
|
||||||
}
|
}
|
||||||
sem_destroy(&gCdStreamSema);
|
sem_destroy(&gCdStreamSema);
|
||||||
|
free(gChannelRequestQ.items);
|
||||||
#else
|
#else
|
||||||
sem_destroy(&gpReadInfo[channel].pStartSemaphore);
|
sem_destroy(&gpReadInfo[channel].pStartSemaphore);
|
||||||
sem_destroy(&gpReadInfo[channel].pDoneSemaphore);
|
sem_destroy(&gpReadInfo[channel].pDoneSemaphore);
|
||||||
|
@ -460,10 +461,11 @@ CdStreamAddImage(char const *path)
|
||||||
|
|
||||||
// Fix case sensitivity and backslashes.
|
// Fix case sensitivity and backslashes.
|
||||||
if (gImgFiles[gNumImages] == -1) {
|
if (gImgFiles[gNumImages] == -1) {
|
||||||
char *r = (char*)alloca(strlen(path) + 4);
|
char* real = casepath(path, false);
|
||||||
if (casepath(path, r))
|
if (real)
|
||||||
{
|
{
|
||||||
gImgFiles[gNumImages] = open(r, _gdwCdStreamFlags);
|
gImgFiles[gNumImages] = open(real, _gdwCdStreamFlags);
|
||||||
|
free(real);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#endif
|
#endif
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "crossplatform.h"
|
||||||
|
|
||||||
#include "FileMgr.h"
|
#include "FileMgr.h"
|
||||||
|
|
||||||
|
@ -31,19 +32,16 @@ static myFILE myfiles[NUMFILES];
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "crossplatform.h"
|
|
||||||
#define _getcwd getcwd
|
#define _getcwd getcwd
|
||||||
|
|
||||||
// Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen)
|
// Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen)
|
||||||
void mychdir(char const *path)
|
void mychdir(char const *path)
|
||||||
{
|
{
|
||||||
char *r = (char*)alloca(strlen(path) + 4);
|
char* r = casepath(path, false);
|
||||||
if (casepath(path, r))
|
if (r) {
|
||||||
{
|
|
||||||
chdir(r);
|
chdir(r);
|
||||||
}
|
free(r);
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,30 +71,7 @@ found:
|
||||||
*p++ = 'b';
|
*p++ = 'b';
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
#if !defined(_WIN32)
|
myfiles[fd].file = fcaseopen(filename, realmode);
|
||||||
char *newPath = strdup(filename);
|
|
||||||
// Normally casepath() fixes backslashes, but if the mode is sth other than r/rb it will create new file with backslashes on linux, so fix backslashes here
|
|
||||||
char *nextBs;
|
|
||||||
while(nextBs = strstr(newPath, "\\")){
|
|
||||||
*nextBs = '/';
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
const char *newPath = filename;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
myfiles[fd].file = fopen(newPath, realmode);
|
|
||||||
// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
|
|
||||||
#if !defined(_WIN32)
|
|
||||||
if (!myfiles[fd].file) {
|
|
||||||
char *r = (char*)alloca(strlen(newPath) + 4);
|
|
||||||
if (casepath(newPath, r))
|
|
||||||
{
|
|
||||||
myfiles[fd].file = fopen(r, realmode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(newPath);
|
|
||||||
#endif
|
|
||||||
if(myfiles[fd].file == nil)
|
if(myfiles[fd].file == nil)
|
||||||
return 0;
|
return 0;
|
||||||
return fd;
|
return fd;
|
||||||
|
|
|
@ -375,23 +375,19 @@ RwStream *RwStreamOpen(RwStreamType type, RwStreamAccessType accessType, const v
|
||||||
file = rwNewT(StreamFile, 1, 0);
|
file = rwNewT(StreamFile, 1, 0);
|
||||||
memcpy(file, &fakefile, sizeof(StreamFile));
|
memcpy(file, &fakefile, sizeof(StreamFile));
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
// Be case-insensitive and fix backslashes (from https://github.com/OneSadCookie/fcaseopen/)
|
char *r = casepath((char*)pData);
|
||||||
FILE* first = fopen((char*)pData, "r");
|
if (r) {
|
||||||
char *r;
|
if (file->open((char*)r, mode)) {
|
||||||
if (!first) {
|
free(r);
|
||||||
r = (char*)alloca(strlen((char*)pData) + 4);
|
return file;
|
||||||
// Use default path(and pass error handling to librw) if we can't find any match
|
}
|
||||||
if (!casepath((char*)pData, r))
|
free(r);
|
||||||
r = (char*)pData;
|
|
||||||
} else
|
} else
|
||||||
fclose(first);
|
|
||||||
|
|
||||||
if(file->open((char*)r, mode))
|
|
||||||
return file;
|
|
||||||
#else
|
|
||||||
if(file->open((char*)pData, mode))
|
|
||||||
return file;
|
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
if (file->open((char*)pData, mode))
|
||||||
|
return file;
|
||||||
|
}
|
||||||
rwFree(file);
|
rwFree(file);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
@ -859,15 +855,14 @@ RwImage *
|
||||||
RtBMPImageWrite(RwImage *image, const RwChar *imageName)
|
RtBMPImageWrite(RwImage *image, const RwChar *imageName)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
char *r = nil;
|
char *r = casepath(imageName);
|
||||||
FILE *valid = fopen((char *)imageName, "r");
|
if (r) {
|
||||||
if(!valid) {
|
rw::writeBMP(image, r);
|
||||||
char *r = (char *)alloca(strlen((char *)imageName) + 4);
|
free(r);
|
||||||
// Use default path(and pass error handling to librw) if we can't find any match
|
} else {
|
||||||
if(!casepath((char *)imageName, r)) r = (char *)imageName;
|
rw::writeBMP(image, imageName);
|
||||||
} else
|
}
|
||||||
fclose(valid);
|
|
||||||
rw::writeBMP(image, r);
|
|
||||||
#else
|
#else
|
||||||
rw::writeBMP(image, imageName);
|
rw::writeBMP(image, imageName);
|
||||||
#endif
|
#endif
|
||||||
|
@ -877,15 +872,16 @@ RwImage *
|
||||||
RtBMPImageRead(const RwChar *imageName)
|
RtBMPImageRead(const RwChar *imageName)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
char *r = nil;
|
RwImage *image;
|
||||||
FILE *valid = fopen((char *)imageName, "r");
|
char *r = casepath(imageName);
|
||||||
if(!valid) {
|
if (r) {
|
||||||
r = (char *)alloca(strlen((char *)imageName) + 4);
|
image = rw::readBMP(r);
|
||||||
// Use default path(and pass error handling to librw) if we can't find any match
|
free(r);
|
||||||
if(!casepath((char *)imageName, r)) r = (char *)imageName;
|
} else {
|
||||||
} else
|
image = rw::readBMP(imageName);
|
||||||
fclose(valid);
|
}
|
||||||
return rw::readBMP(r);
|
return image;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
return rw::readBMP(imageName);
|
return rw::readBMP(imageName);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -87,7 +87,7 @@ void FileTimeToSystemTime(time_t* writeTime, SYSTEMTIME* out) {
|
||||||
// Funcs/features from Windows that we need on other platforms
|
// Funcs/features from Windows that we need on other platforms
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
char *strupr(char *s) {
|
char *strupr(char *s) {
|
||||||
char* tmp = s;
|
char* tmp = s;
|
||||||
|
|
||||||
for (;*tmp;++tmp) {
|
for (;*tmp;++tmp) {
|
||||||
*tmp = toupper((unsigned char) *tmp);
|
*tmp = toupper((unsigned char) *tmp);
|
||||||
|
@ -96,7 +96,7 @@ char *strupr(char *s) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
char *strlwr(char *s) {
|
char *strlwr(char *s) {
|
||||||
char* tmp = s;
|
char* tmp = s;
|
||||||
|
|
||||||
for (;*tmp;++tmp) {
|
for (;*tmp;++tmp) {
|
||||||
*tmp = tolower((unsigned char) *tmp);
|
*tmp = tolower((unsigned char) *tmp);
|
||||||
|
@ -116,86 +116,117 @@ char *trim(char *s) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen)
|
FILE* _fcaseopen(char const* filename, char const* mode)
|
||||||
// r must have strlen(path) + 2 bytes
|
|
||||||
int casepath(char const *path, char *r)
|
|
||||||
{
|
{
|
||||||
|
FILE* result;
|
||||||
|
char* real = casepath(filename);
|
||||||
|
if (!real)
|
||||||
|
result = fopen(filename, mode);
|
||||||
|
else {
|
||||||
|
result = fopen(real, mode);
|
||||||
|
free(real);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen)
|
||||||
|
// Returned string should freed manually (if exists)
|
||||||
|
char* casepath(char const* path, bool checkPathFirst)
|
||||||
|
{
|
||||||
|
if (checkPathFirst && access(path, F_OK) != -1) {
|
||||||
|
// File path is correct
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
size_t l = strlen(path);
|
size_t l = strlen(path);
|
||||||
char *p = (char*)alloca(l + 1);
|
char* p = (char*)alloca(l + 1);
|
||||||
|
char* out = (char*)malloc(l + 3); // for extra ./
|
||||||
strcpy(p, path);
|
strcpy(p, path);
|
||||||
|
|
||||||
// my addon: change \'s with /
|
// my addon: linux doesn't handle filenames with spaces at the end nicely
|
||||||
char *nextBs;
|
p = trim(p);
|
||||||
while(nextBs = strstr(p, "\\")){
|
|
||||||
*nextBs = '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
// my addon: linux doesn't handle filenames with spaces at the end nicely
|
|
||||||
p = trim(p);
|
|
||||||
|
|
||||||
size_t rl = 0;
|
size_t rl = 0;
|
||||||
|
|
||||||
DIR *d;
|
DIR* d;
|
||||||
if (p[0] == '/')
|
if (p[0] == '/' || p[0] == '\\')
|
||||||
{
|
{
|
||||||
d = opendir("/");
|
d = opendir("/");
|
||||||
p = p + 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d = opendir(".");
|
d = opendir(".");
|
||||||
r[0] = '.';
|
out[0] = '.';
|
||||||
r[1] = 0;
|
out[1] = 0;
|
||||||
rl = 1;
|
rl = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int last = 0;
|
bool cantProceed = false; // just convert slashes in what's left in string, not case sensitivity
|
||||||
char *c = strsep(&p, "/");
|
bool mayBeTrailingSlash = false;
|
||||||
while (c)
|
char* c;
|
||||||
|
while (c = strsep(&p, "/\\"))
|
||||||
{
|
{
|
||||||
if (!d)
|
// May be trailing slash(allow), slash at the start(avoid), or multiple slashes(avoid)
|
||||||
|
if (*c == '\0')
|
||||||
{
|
{
|
||||||
return 0;
|
mayBeTrailingSlash = true;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
mayBeTrailingSlash = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last)
|
out[rl] = '/';
|
||||||
{
|
|
||||||
closedir(d);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r[rl] = '/';
|
|
||||||
rl += 1;
|
rl += 1;
|
||||||
r[rl] = 0;
|
out[rl] = 0;
|
||||||
|
|
||||||
struct dirent *e = readdir(d);
|
if (cantProceed)
|
||||||
while (e)
|
{
|
||||||
|
strcpy(out + rl, c);
|
||||||
|
rl += strlen(c);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dirent* e;
|
||||||
|
while (e = readdir(d))
|
||||||
{
|
{
|
||||||
if (strcasecmp(c, e->d_name) == 0)
|
if (strcasecmp(c, e->d_name) == 0)
|
||||||
{
|
{
|
||||||
strcpy(r + rl, e->d_name);
|
strcpy(out + rl, e->d_name);
|
||||||
rl += strlen(e->d_name);
|
int reportedLen = (int)strlen(e->d_name);
|
||||||
|
rl += reportedLen;
|
||||||
|
assert(reportedLen == strlen(c) && "casepath: This is not good at all");
|
||||||
|
|
||||||
closedir(d);
|
closedir(d);
|
||||||
d = opendir(r);
|
d = opendir(out);
|
||||||
|
|
||||||
|
// Either it wasn't a folder, or permission error, I/O error etc.
|
||||||
|
if (!d) {
|
||||||
|
cantProceed = true;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
e = readdir(d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!e)
|
if (!e)
|
||||||
{
|
{
|
||||||
strcpy(r + rl, c);
|
printf("casepath couldn't find dir/file \"%s\", full path was %s\n", c, path);
|
||||||
|
// No match, add original name and continue converting further slashes.
|
||||||
|
strcpy(out + rl, c);
|
||||||
rl += strlen(c);
|
rl += strlen(c);
|
||||||
last = 1;
|
cantProceed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = strsep(&p, "/");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d) closedir(d);
|
if (d) closedir(d);
|
||||||
return 1;
|
if (mayBeTrailingSlash) {
|
||||||
|
out[rl] = '/'; rl += 1;
|
||||||
|
out[rl] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rl > l + 2) {
|
||||||
|
printf("\n\ncasepath: Corrected path length is longer then original+2:\n\tOriginal: %s (%d chars)\n\tCorrected: %s (%d chars)\n\n", path, l, out, rl);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,7 +23,7 @@ enum eWinVersion
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
#endif
|
#endif
|
||||||
extern DWORD _dwOperatingSystemVersion;
|
extern DWORD _dwOperatingSystemVersion;
|
||||||
|
#define fcaseopen fopen
|
||||||
#else
|
#else
|
||||||
char *strupr(char *str);
|
char *strupr(char *str);
|
||||||
char *strlwr(char *str);
|
char *strlwr(char *str);
|
||||||
|
@ -43,7 +43,9 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern long _dwOperatingSystemVersion;
|
extern long _dwOperatingSystemVersion;
|
||||||
int casepath(char const *path, char *r);
|
char *casepath(char const *path, bool checkPathFirst = true);
|
||||||
|
FILE *_fcaseopen(char const *filename, char const *mode);
|
||||||
|
#define fcaseopen _fcaseopen
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RW_GL3
|
#ifdef RW_GL3
|
||||||
|
|
Loading…
Reference in New Issue