1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-11-05 02:39:41 +01:00
VVVVVV/desktop_version/src/FileSystemUtils.cpp

668 lines
16 KiB
C++
Raw Normal View History

#include <iostream>
#include <iterator>
#include <physfs.h>
#include <SDL.h>
2020-01-01 21:29:24 +01:00
#include <stdio.h>
#include <string>
#include <tinyxml2.h>
#include <vector>
2020-01-01 21:29:24 +01:00
#include "Exit.h"
#include "Graphics.h"
#include "UtilityClass.h"
2020-06-12 22:20:18 +02:00
/* These are needed for PLATFORM_* crap */
2020-01-01 21:29:24 +01:00
#if defined(_WIN32)
#include <windows.h>
#include <shlobj.h>
2020-04-20 15:41:11 +02:00
#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__) || defined(__DragonFly__)
2020-01-01 21:29:24 +01:00
#include <unistd.h>
#include <dirent.h>
2020-06-12 22:20:18 +02:00
#include <limits.h>
#include <sys/stat.h>
2020-01-01 21:29:24 +01:00
#define MAX_PATH PATH_MAX
#endif
static char saveDir[MAX_PATH] = {'\0'};
static char levelDir[MAX_PATH] = {'\0'};
2020-01-01 21:29:24 +01:00
static void PLATFORM_getOSDirectory(char* output);
static void PLATFORM_migrateSaveData(char* output);
static void PLATFORM_copyFile(const char *oldLocation, const char *newLocation);
2020-01-01 21:29:24 +01:00
static void* bridged_malloc(PHYSFS_uint64 size)
{
return SDL_malloc(size);
}
static void* bridged_realloc(void* ptr, PHYSFS_uint64 size)
{
return SDL_realloc(ptr, size);
}
static const PHYSFS_Allocator allocator = {
NULL,
NULL,
bridged_malloc,
bridged_realloc,
SDL_free
};
int FILESYSTEM_init(char *argvZero, char* baseDir, char *assetsPath)
2020-01-01 21:29:24 +01:00
{
char output[MAX_PATH];
int mkdirResult;
const char* pathSep = PHYSFS_getDirSeparator();
2020-01-01 21:29:24 +01:00
PHYSFS_setAllocator(&allocator);
2020-01-01 21:29:24 +01:00
PHYSFS_init(argvZero);
PHYSFS_permitSymbolicLinks(1);
2020-01-01 21:29:24 +01:00
/* Determine the OS user directory */
if (baseDir && baseDir[0] != '\0')
{
/* We later append to this path and assume it ends in a slash */
bool trailing_pathsep = SDL_strcmp(baseDir + SDL_strlen(baseDir) - SDL_strlen(pathSep), pathSep) == 0;
SDL_snprintf(output, sizeof(output), "%s%s",
baseDir,
!trailing_pathsep ? pathSep : ""
);
}
else
{
PLATFORM_getOSDirectory(output);
}
2020-01-01 21:29:24 +01:00
/* Create base user directory, mount */
2020-06-12 22:20:18 +02:00
mkdirResult = PHYSFS_mkdir(output);
2020-01-01 21:29:24 +01:00
/* Mount our base user directory */
PHYSFS_mount(output, NULL, 0);
PHYSFS_setWriteDir(output);
2020-01-01 21:29:24 +01:00
printf("Base directory: %s\n", output);
/* Create the save/level folders */
mkdirResult |= PHYSFS_mkdir("saves");
mkdirResult |= PHYSFS_mkdir("levels");
/* Store full save directory */
SDL_snprintf(saveDir, sizeof(saveDir), "%s%s%s",
output,
"saves",
PHYSFS_getDirSeparator()
);
printf("Save directory: %s\n", saveDir);
/* Store full level directory */
SDL_snprintf(levelDir, sizeof(levelDir), "%s%s%s",
output,
"levels",
PHYSFS_getDirSeparator()
);
printf("Level directory: %s\n", levelDir);
2020-01-01 21:29:24 +01:00
/* We didn't exist until now, migrate files! */
2020-06-12 22:21:45 +02:00
if (mkdirResult == 0)
2020-01-01 21:29:24 +01:00
{
PLATFORM_migrateSaveData(output);
}
/* Mount the stock content last */
if (assetsPath)
{
SDL_strlcpy(output, assetsPath, sizeof(output));
}
else
{
SDL_snprintf(output, sizeof(output), "%s%s",
PHYSFS_getBaseDir(),
"data.zip"
);
}
2020-01-10 19:59:34 +01:00
if (!PHYSFS_mount(output, NULL, 1))
{
puts("Error: data.zip missing!");
puts("You do not have data.zip!");
puts("Grab it from your purchased copy of the game,");
puts("or get it from the free Make and Play Edition.");
2020-01-10 19:59:34 +01:00
SDL_ShowSimpleMessageBox(
SDL_MESSAGEBOX_ERROR,
"data.zip missing!",
"You do not have data.zip!"
"\n\nGrab it from your purchased copy of the game,"
2020-01-10 20:00:45 +01:00
"\nor get it from the free Make and Play Edition.",
2020-01-10 19:59:34 +01:00
NULL
);
return 0;
2020-01-10 19:59:34 +01:00
}
2020-01-17 18:43:42 +01:00
2020-06-24 01:08:08 +02:00
SDL_snprintf(output, sizeof(output), "%s%s", PHYSFS_getBaseDir(), "gamecontrollerdb.txt");
2020-01-17 18:43:42 +01:00
if (SDL_GameControllerAddMappingsFromFile(output) < 0)
{
printf("gamecontrollerdb.txt not found!\n");
}
return 1;
2020-01-01 21:29:24 +01:00
}
void FILESYSTEM_deinit(void)
2020-01-01 21:29:24 +01:00
{
if (PHYSFS_isInit())
{
PHYSFS_deinit();
}
2020-01-01 21:29:24 +01:00
}
char *FILESYSTEM_getUserSaveDirectory(void)
2020-01-01 21:29:24 +01:00
{
return saveDir;
}
char *FILESYSTEM_getUserLevelDirectory(void)
2020-01-01 21:29:24 +01:00
{
return levelDir;
}
static bool FILESYSTEM_exists(const char *fname)
{
return PHYSFS_exists(fname);
}
void FILESYSTEM_mount(const char *fname)
{
const char* real_dir = PHYSFS_getRealDir(fname);
const char* dir_separator;
char path[MAX_PATH];
if (real_dir == NULL)
{
printf(
"Could not mount %s: real directory doesn't exist\n",
fname
);
return;
}
dir_separator = PHYSFS_getDirSeparator();
SDL_snprintf(path, sizeof(path), "%s%s%s", real_dir, dir_separator, fname);
if (!PHYSFS_mount(path, NULL, 0))
{
printf("Error mounting: %s\n", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
}
else
{
graphics.assetdir = std::string(path);
}
}
bool FILESYSTEM_assetsmounted = false;
void FILESYSTEM_mountassets(const char* path)
{
const size_t path_size = SDL_strlen(path);
char filename[MAX_PATH];
char zip_data[MAX_PATH];
const char* zip_normal;
char dir[MAX_PATH];
/* path is going to look like "levels/LEVELNAME.vvvvvv".
* We want LEVELNAME, which entails starting from index 7
* (which is how long "levels/" is)
* and then grabbing path_size-14 characters
* (14 chars because "levels/" and ".vvvvvv" are both 7 chars).
* We also add 1 when calculating the amount of bytes to grab
* to account for the null terminator.
*/
SDL_strlcpy(
filename,
&path[7],
VVV_min((path_size - 14) + 1, sizeof(filename))
);
SDL_snprintf(
zip_data,
sizeof(zip_data),
"levels/%s.data.zip",
filename
);
zip_normal = PHYSFS_getRealDir(path);
SDL_snprintf(
dir,
sizeof(dir),
"levels/%s/",
filename
);
if (FILESYSTEM_exists(zip_data))
{
printf("Custom asset directory is .data.zip at %s\n", zip_data);
FILESYSTEM_mount(zip_data);
graphics.reloadresources();
FILESYSTEM_assetsmounted = true;
}
else if (zip_normal != NULL && endsWith(zip_normal, ".zip"))
{
PHYSFS_File* zip = PHYSFS_openRead(zip_normal);
printf("Custom asset directory is .zip at %s\n", zip_normal);
SDL_snprintf(
zip_data,
sizeof(zip_data),
"%s.data.zip",
zip_normal
);
if (zip == NULL)
{
printf(
"Error loading .zip: %s\n",
PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())
);
}
else if (PHYSFS_mountHandle(zip, zip_data, "/", 0) == 0)
{
printf(
"Error mounting .zip: %s\n",
PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())
);
}
else
{
graphics.assetdir = std::string(zip_data);
}
FILESYSTEM_assetsmounted = true;
graphics.reloadresources();
}
else if (FILESYSTEM_exists(dir))
{
printf("Custom asset directory exists at %s\n", dir);
FILESYSTEM_mount(dir);
graphics.reloadresources();
FILESYSTEM_assetsmounted = true;
}
else
{
puts("Custom asset directory does not exist");
FILESYSTEM_assetsmounted = false;
}
}
void FILESYSTEM_unmountassets(void)
{
if (graphics.assetdir != "")
{
printf("Unmounting %s\n", graphics.assetdir.c_str());
PHYSFS_unmount(graphics.assetdir.c_str());
graphics.assetdir = "";
graphics.reloadresources();
}
else
{
printf("Cannot unmount when no asset directory is mounted\n");
}
FILESYSTEM_assetsmounted = false;
}
void FILESYSTEM_freeMemory(unsigned char **mem);
void FILESYSTEM_loadFileToMemory(
const char *name,
unsigned char **mem,
size_t *len,
bool addnull
) {
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
if (SDL_strcmp(name, "levels/special/stdin.vvvvvv") == 0)
{
// this isn't *technically* necessary when piping directly from a file, but checking for that is annoying
static std::vector<char> STDIN_BUFFER;
static bool STDIN_LOADED = false;
if (!STDIN_LOADED)
{
std::istreambuf_iterator<char> begin(std::cin), end;
STDIN_BUFFER.assign(begin, end);
STDIN_BUFFER.push_back(0); // there's no observable change in behavior if addnull is always true, but not vice versa
STDIN_LOADED = true;
}
size_t length = STDIN_BUFFER.size() - 1;
if (len != NULL)
{
*len = length;
}
++length;
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
*mem = static_cast<unsigned char*>(SDL_malloc(length)); // STDIN_BUFFER.data() causes double-free
if (*mem == NULL)
{
VVV_exit(1);
}
std::copy(STDIN_BUFFER.begin(), STDIN_BUFFER.end(), reinterpret_cast<char*>(*mem));
return;
}
2020-01-01 21:29:24 +01:00
PHYSFS_File *handle = PHYSFS_openRead(name);
if (handle == NULL)
{
return;
}
PHYSFS_sint64 length = PHYSFS_fileLength(handle);
2020-01-01 21:29:24 +01:00
if (len != NULL)
{
*len = length;
}
if (addnull)
{
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
*mem = (unsigned char *) SDL_malloc(length + 1);
if (*mem == NULL)
{
VVV_exit(1);
}
(*mem)[length] = 0;
}
else
{
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
*mem = (unsigned char*) SDL_malloc(length);
if (*mem == NULL)
{
VVV_exit(1);
}
}
int success = PHYSFS_readBytes(handle, *mem, length);
if (success == -1)
{
FILESYSTEM_freeMemory(mem);
}
2020-01-01 21:29:24 +01:00
PHYSFS_close(handle);
}
void FILESYSTEM_freeMemory(unsigned char **mem)
{
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
SDL_free(*mem);
2020-01-01 21:29:24 +01:00
*mem = NULL;
}
bool FILESYSTEM_saveTiXml2Document(const char *name, tinyxml2::XMLDocument& doc)
{
/* XMLDocument.SaveFile doesn't account for Unicode paths, PHYSFS does */
tinyxml2::XMLPrinter printer;
doc.Print(&printer);
PHYSFS_File* handle = PHYSFS_openWrite(name);
if (handle == NULL)
{
return false;
}
PHYSFS_writeBytes(handle, printer.CStr(), printer.CStrSize() - 1); // subtract one because CStrSize includes terminating null
PHYSFS_close(handle);
return true;
}
bool FILESYSTEM_loadTiXml2Document(const char *name, tinyxml2::XMLDocument& doc)
{
/* XMLDocument.LoadFile doesn't account for Unicode paths, PHYSFS does */
unsigned char *mem = NULL;
FILESYSTEM_loadFileToMemory(name, &mem, NULL, true);
if (mem == NULL)
{
return false;
}
doc.Parse((const char*) mem);
FILESYSTEM_freeMemory(&mem);
return true;
}
Refactor level dir listing to not use STL data marshalling Note that level dir listing still uses plenty of STL (including the end product - the `LevelMetaData` struct - which, for the purposes of 2.3, is okay enough (2.4 should remove STL usage entirely)); it's just that the initial act of iterating over the levels directory no longer takes four or SIX(!!!) heap allocations (not counting reallocations and other heap allocations this patch does not remove), and no longer does any data marshalling. Like text splitting, and binary blob extra indice grabbing, the current approach that FILESYSTEM_getLevelDirFileNames() uses is a temporary std::vector of std::strings as a middleman to store all the filenames, and the game iterates over that std::vector to grab each level metadata. Except, it's even worse in this case, because PHYSFS_enumerateFiles() ALREADY does a heap allocation. Oh, and FILESYSTEM_getLevelDirFileNames() gets called two or three times. Yeah, let me explain: 1. FILESYSTEM_getLevelDirFileNames() calls PHYSFS_enumerateFiles(). 2. PHYSFS_enumerateFiles() allocates an array of pointers to arrays of chars on the heap. For each filename, it will: a. Allocate an array of chars for the filename. b. Reallocate the array of pointers to add the pointer to the above char array. (In this step, it also inserts the filename in alphabetically - without any further allocations, as far as I know - but this is a COMPLETELY unnecessary step, because we are going to sort the list of levels by ourselves via the metadata title in the end anyways.) 3. FILESYSTEM_getLevelDirFileNames() iterates over the PhysFS list, and allocates an std::vector on the heap to shove the list into. Then, for each filename, it will: a. Allocate an std::string, initialized to "levels/". b. Append the filename to the std::string above. This will most likely require a re-allocation. c. Duplicate the std::string - which requires allocating more memory again - to put it into the std::vector. (Compared to the PhysFS list above, the std::vector does less reallocations; it however will still end up reallocating a certain amount of times in the end.) 4. FILESYSTEM_getLevelDirFileNames() will free the PhysFS list. 5. Then to get the std::vector<std::string> back to the caller, we end up having to reallocate the std::vector again - reallocating every single std::string inside it, too - to give it back to the caller. And to top it all off, FILESYSTEM_getLevelDirFileNames() is guaranteed to either be called two times, or three times. This is because editorclass::getDirectoryData() will call editorclass::loadZips(), which will unconditionally call FILESYSTEM_getLevelDirFileNames(), then call it AGAIN if a zip was found. Then once the function returns, getDirectoryData() will still unconditionally call FILESYSTEM_getLevelDirFileNames(). This smells like someone bolting something on without regard for the whole picture of the system, but whatever; I can clean up their mess just fine. So, what do I do about this? Well, just like I did with text splitting and binary blob extras, make the final for-loop - the one that does the actual metadata parsing - more immediate. So how do I do that? Well, PhysFS has a function named PHYSFS_enumerate(). PHYSFS_enumerateFiles(), in fact, uses this function internally, and is basically just a wrapper with some allocation and alphabetization. PHYSFS_enumerate() takes in a pointer to a function, which it will call for every single entry that it iterates over. It also lets you pass in another arbitrary pointer that it leaves alone, which I use to pass through a function pointer that is the actual callback. So to clarify, there are two callbacks - one callback is passed through into another callback that gets passed through to PHYSFS_enumerate(). The callback that gets passed to PHYSFS_enumerate() is always the same, but the callback that gets passed through the callback can be different (if you look at the calling code, you can see that one caller passes through a normal level metadata callback; the other passes through a zip file callback). Furthermore, I've also cleaned it up so that if editorclass::loadZips() finds a zip file, it won't iterate over all the files in the levels directory a third time. Instead, the level directory only gets iterated over twice - once to check for zips, and another to load every level plus all zips; the second time is when all the heap allocations happen. And with that, level list loading now uses less STL templated stuff and much less heap allocations. Also, ed.directoryList basically has no reason to exist other than being a temporary std::vector, so I've removed it. This further decreases memory usage, depending on how many levels you have in your levels folder (I know that I usually have a lot and don't really ever clean it up, lol). Lastly, in the callback passed to PhysFS, `builtLocation` is actually no longer hardcoded to just the `levels` directory, since instead we now use the `origdir` variable that PhysFS passes us. So that's good, too.
2021-02-19 03:42:13 +01:00
static PHYSFS_EnumerateCallbackResult enumerateCallback(
void* data,
const char* origdir,
const char* filename
) {
void (*callback)(const char*) = (void (*)(const char*)) data;
char builtLocation[MAX_PATH];
SDL_snprintf(
builtLocation,
sizeof(builtLocation),
"%s/%s",
origdir,
filename
);
2020-01-01 21:29:24 +01:00
Refactor level dir listing to not use STL data marshalling Note that level dir listing still uses plenty of STL (including the end product - the `LevelMetaData` struct - which, for the purposes of 2.3, is okay enough (2.4 should remove STL usage entirely)); it's just that the initial act of iterating over the levels directory no longer takes four or SIX(!!!) heap allocations (not counting reallocations and other heap allocations this patch does not remove), and no longer does any data marshalling. Like text splitting, and binary blob extra indice grabbing, the current approach that FILESYSTEM_getLevelDirFileNames() uses is a temporary std::vector of std::strings as a middleman to store all the filenames, and the game iterates over that std::vector to grab each level metadata. Except, it's even worse in this case, because PHYSFS_enumerateFiles() ALREADY does a heap allocation. Oh, and FILESYSTEM_getLevelDirFileNames() gets called two or three times. Yeah, let me explain: 1. FILESYSTEM_getLevelDirFileNames() calls PHYSFS_enumerateFiles(). 2. PHYSFS_enumerateFiles() allocates an array of pointers to arrays of chars on the heap. For each filename, it will: a. Allocate an array of chars for the filename. b. Reallocate the array of pointers to add the pointer to the above char array. (In this step, it also inserts the filename in alphabetically - without any further allocations, as far as I know - but this is a COMPLETELY unnecessary step, because we are going to sort the list of levels by ourselves via the metadata title in the end anyways.) 3. FILESYSTEM_getLevelDirFileNames() iterates over the PhysFS list, and allocates an std::vector on the heap to shove the list into. Then, for each filename, it will: a. Allocate an std::string, initialized to "levels/". b. Append the filename to the std::string above. This will most likely require a re-allocation. c. Duplicate the std::string - which requires allocating more memory again - to put it into the std::vector. (Compared to the PhysFS list above, the std::vector does less reallocations; it however will still end up reallocating a certain amount of times in the end.) 4. FILESYSTEM_getLevelDirFileNames() will free the PhysFS list. 5. Then to get the std::vector<std::string> back to the caller, we end up having to reallocate the std::vector again - reallocating every single std::string inside it, too - to give it back to the caller. And to top it all off, FILESYSTEM_getLevelDirFileNames() is guaranteed to either be called two times, or three times. This is because editorclass::getDirectoryData() will call editorclass::loadZips(), which will unconditionally call FILESYSTEM_getLevelDirFileNames(), then call it AGAIN if a zip was found. Then once the function returns, getDirectoryData() will still unconditionally call FILESYSTEM_getLevelDirFileNames(). This smells like someone bolting something on without regard for the whole picture of the system, but whatever; I can clean up their mess just fine. So, what do I do about this? Well, just like I did with text splitting and binary blob extras, make the final for-loop - the one that does the actual metadata parsing - more immediate. So how do I do that? Well, PhysFS has a function named PHYSFS_enumerate(). PHYSFS_enumerateFiles(), in fact, uses this function internally, and is basically just a wrapper with some allocation and alphabetization. PHYSFS_enumerate() takes in a pointer to a function, which it will call for every single entry that it iterates over. It also lets you pass in another arbitrary pointer that it leaves alone, which I use to pass through a function pointer that is the actual callback. So to clarify, there are two callbacks - one callback is passed through into another callback that gets passed through to PHYSFS_enumerate(). The callback that gets passed to PHYSFS_enumerate() is always the same, but the callback that gets passed through the callback can be different (if you look at the calling code, you can see that one caller passes through a normal level metadata callback; the other passes through a zip file callback). Furthermore, I've also cleaned it up so that if editorclass::loadZips() finds a zip file, it won't iterate over all the files in the levels directory a third time. Instead, the level directory only gets iterated over twice - once to check for zips, and another to load every level plus all zips; the second time is when all the heap allocations happen. And with that, level list loading now uses less STL templated stuff and much less heap allocations. Also, ed.directoryList basically has no reason to exist other than being a temporary std::vector, so I've removed it. This further decreases memory usage, depending on how many levels you have in your levels folder (I know that I usually have a lot and don't really ever clean it up, lol). Lastly, in the callback passed to PhysFS, `builtLocation` is actually no longer hardcoded to just the `levels` directory, since instead we now use the `origdir` variable that PhysFS passes us. So that's good, too.
2021-02-19 03:42:13 +01:00
callback(builtLocation);
2020-01-01 21:29:24 +01:00
Refactor level dir listing to not use STL data marshalling Note that level dir listing still uses plenty of STL (including the end product - the `LevelMetaData` struct - which, for the purposes of 2.3, is okay enough (2.4 should remove STL usage entirely)); it's just that the initial act of iterating over the levels directory no longer takes four or SIX(!!!) heap allocations (not counting reallocations and other heap allocations this patch does not remove), and no longer does any data marshalling. Like text splitting, and binary blob extra indice grabbing, the current approach that FILESYSTEM_getLevelDirFileNames() uses is a temporary std::vector of std::strings as a middleman to store all the filenames, and the game iterates over that std::vector to grab each level metadata. Except, it's even worse in this case, because PHYSFS_enumerateFiles() ALREADY does a heap allocation. Oh, and FILESYSTEM_getLevelDirFileNames() gets called two or three times. Yeah, let me explain: 1. FILESYSTEM_getLevelDirFileNames() calls PHYSFS_enumerateFiles(). 2. PHYSFS_enumerateFiles() allocates an array of pointers to arrays of chars on the heap. For each filename, it will: a. Allocate an array of chars for the filename. b. Reallocate the array of pointers to add the pointer to the above char array. (In this step, it also inserts the filename in alphabetically - without any further allocations, as far as I know - but this is a COMPLETELY unnecessary step, because we are going to sort the list of levels by ourselves via the metadata title in the end anyways.) 3. FILESYSTEM_getLevelDirFileNames() iterates over the PhysFS list, and allocates an std::vector on the heap to shove the list into. Then, for each filename, it will: a. Allocate an std::string, initialized to "levels/". b. Append the filename to the std::string above. This will most likely require a re-allocation. c. Duplicate the std::string - which requires allocating more memory again - to put it into the std::vector. (Compared to the PhysFS list above, the std::vector does less reallocations; it however will still end up reallocating a certain amount of times in the end.) 4. FILESYSTEM_getLevelDirFileNames() will free the PhysFS list. 5. Then to get the std::vector<std::string> back to the caller, we end up having to reallocate the std::vector again - reallocating every single std::string inside it, too - to give it back to the caller. And to top it all off, FILESYSTEM_getLevelDirFileNames() is guaranteed to either be called two times, or three times. This is because editorclass::getDirectoryData() will call editorclass::loadZips(), which will unconditionally call FILESYSTEM_getLevelDirFileNames(), then call it AGAIN if a zip was found. Then once the function returns, getDirectoryData() will still unconditionally call FILESYSTEM_getLevelDirFileNames(). This smells like someone bolting something on without regard for the whole picture of the system, but whatever; I can clean up their mess just fine. So, what do I do about this? Well, just like I did with text splitting and binary blob extras, make the final for-loop - the one that does the actual metadata parsing - more immediate. So how do I do that? Well, PhysFS has a function named PHYSFS_enumerate(). PHYSFS_enumerateFiles(), in fact, uses this function internally, and is basically just a wrapper with some allocation and alphabetization. PHYSFS_enumerate() takes in a pointer to a function, which it will call for every single entry that it iterates over. It also lets you pass in another arbitrary pointer that it leaves alone, which I use to pass through a function pointer that is the actual callback. So to clarify, there are two callbacks - one callback is passed through into another callback that gets passed through to PHYSFS_enumerate(). The callback that gets passed to PHYSFS_enumerate() is always the same, but the callback that gets passed through the callback can be different (if you look at the calling code, you can see that one caller passes through a normal level metadata callback; the other passes through a zip file callback). Furthermore, I've also cleaned it up so that if editorclass::loadZips() finds a zip file, it won't iterate over all the files in the levels directory a third time. Instead, the level directory only gets iterated over twice - once to check for zips, and another to load every level plus all zips; the second time is when all the heap allocations happen. And with that, level list loading now uses less STL templated stuff and much less heap allocations. Also, ed.directoryList basically has no reason to exist other than being a temporary std::vector, so I've removed it. This further decreases memory usage, depending on how many levels you have in your levels folder (I know that I usually have a lot and don't really ever clean it up, lol). Lastly, in the callback passed to PhysFS, `builtLocation` is actually no longer hardcoded to just the `levels` directory, since instead we now use the `origdir` variable that PhysFS passes us. So that's good, too.
2021-02-19 03:42:13 +01:00
return PHYSFS_ENUM_OK;
}
2020-01-01 21:29:24 +01:00
Refactor level dir listing to not use STL data marshalling Note that level dir listing still uses plenty of STL (including the end product - the `LevelMetaData` struct - which, for the purposes of 2.3, is okay enough (2.4 should remove STL usage entirely)); it's just that the initial act of iterating over the levels directory no longer takes four or SIX(!!!) heap allocations (not counting reallocations and other heap allocations this patch does not remove), and no longer does any data marshalling. Like text splitting, and binary blob extra indice grabbing, the current approach that FILESYSTEM_getLevelDirFileNames() uses is a temporary std::vector of std::strings as a middleman to store all the filenames, and the game iterates over that std::vector to grab each level metadata. Except, it's even worse in this case, because PHYSFS_enumerateFiles() ALREADY does a heap allocation. Oh, and FILESYSTEM_getLevelDirFileNames() gets called two or three times. Yeah, let me explain: 1. FILESYSTEM_getLevelDirFileNames() calls PHYSFS_enumerateFiles(). 2. PHYSFS_enumerateFiles() allocates an array of pointers to arrays of chars on the heap. For each filename, it will: a. Allocate an array of chars for the filename. b. Reallocate the array of pointers to add the pointer to the above char array. (In this step, it also inserts the filename in alphabetically - without any further allocations, as far as I know - but this is a COMPLETELY unnecessary step, because we are going to sort the list of levels by ourselves via the metadata title in the end anyways.) 3. FILESYSTEM_getLevelDirFileNames() iterates over the PhysFS list, and allocates an std::vector on the heap to shove the list into. Then, for each filename, it will: a. Allocate an std::string, initialized to "levels/". b. Append the filename to the std::string above. This will most likely require a re-allocation. c. Duplicate the std::string - which requires allocating more memory again - to put it into the std::vector. (Compared to the PhysFS list above, the std::vector does less reallocations; it however will still end up reallocating a certain amount of times in the end.) 4. FILESYSTEM_getLevelDirFileNames() will free the PhysFS list. 5. Then to get the std::vector<std::string> back to the caller, we end up having to reallocate the std::vector again - reallocating every single std::string inside it, too - to give it back to the caller. And to top it all off, FILESYSTEM_getLevelDirFileNames() is guaranteed to either be called two times, or three times. This is because editorclass::getDirectoryData() will call editorclass::loadZips(), which will unconditionally call FILESYSTEM_getLevelDirFileNames(), then call it AGAIN if a zip was found. Then once the function returns, getDirectoryData() will still unconditionally call FILESYSTEM_getLevelDirFileNames(). This smells like someone bolting something on without regard for the whole picture of the system, but whatever; I can clean up their mess just fine. So, what do I do about this? Well, just like I did with text splitting and binary blob extras, make the final for-loop - the one that does the actual metadata parsing - more immediate. So how do I do that? Well, PhysFS has a function named PHYSFS_enumerate(). PHYSFS_enumerateFiles(), in fact, uses this function internally, and is basically just a wrapper with some allocation and alphabetization. PHYSFS_enumerate() takes in a pointer to a function, which it will call for every single entry that it iterates over. It also lets you pass in another arbitrary pointer that it leaves alone, which I use to pass through a function pointer that is the actual callback. So to clarify, there are two callbacks - one callback is passed through into another callback that gets passed through to PHYSFS_enumerate(). The callback that gets passed to PHYSFS_enumerate() is always the same, but the callback that gets passed through the callback can be different (if you look at the calling code, you can see that one caller passes through a normal level metadata callback; the other passes through a zip file callback). Furthermore, I've also cleaned it up so that if editorclass::loadZips() finds a zip file, it won't iterate over all the files in the levels directory a third time. Instead, the level directory only gets iterated over twice - once to check for zips, and another to load every level plus all zips; the second time is when all the heap allocations happen. And with that, level list loading now uses less STL templated stuff and much less heap allocations. Also, ed.directoryList basically has no reason to exist other than being a temporary std::vector, so I've removed it. This further decreases memory usage, depending on how many levels you have in your levels folder (I know that I usually have a lot and don't really ever clean it up, lol). Lastly, in the callback passed to PhysFS, `builtLocation` is actually no longer hardcoded to just the `levels` directory, since instead we now use the `origdir` variable that PhysFS passes us. So that's good, too.
2021-02-19 03:42:13 +01:00
void FILESYSTEM_enumerateLevelDirFileNames(
void (*callback)(const char* filename)
) {
int success = PHYSFS_enumerate("levels", enumerateCallback, (void*) callback);
if (success == 0)
{
printf(
"Could not get list of levels: %s\n",
PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())
);
}
2020-01-01 21:29:24 +01:00
}
static void PLATFORM_getOSDirectory(char* output)
2020-01-01 21:29:24 +01:00
{
#ifdef _WIN32
/* This block is here for compatibility, do not touch it! */
WCHAR utf16_path[MAX_PATH];
SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, utf16_path);
WideCharToMultiByte(CP_UTF8, 0, utf16_path, -1, output, MAX_PATH, NULL, NULL);
2020-08-09 19:10:21 +02:00
SDL_strlcat(output, "\\VVVVVV\\", MAX_PATH);
2020-01-01 21:29:24 +01:00
#else
SDL_strlcpy(output, PHYSFS_getPrefDir("distractionware", "VVVVVV"), MAX_PATH);
2020-01-01 21:29:24 +01:00
#endif
}
static void PLATFORM_migrateSaveData(char* output)
2020-01-01 21:29:24 +01:00
{
char oldLocation[MAX_PATH];
char newLocation[MAX_PATH];
char oldDirectory[MAX_PATH];
2020-04-20 15:41:11 +02:00
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__) || defined(__DragonFly__)
2020-01-01 21:29:24 +01:00
DIR *dir = NULL;
struct dirent *de = NULL;
DIR *subDir = NULL;
struct dirent *subDe = NULL;
char subDirLocation[MAX_PATH];
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
const char *homeDir = SDL_getenv("HOME");
2020-01-01 21:29:24 +01:00
if (homeDir == NULL)
{
/* Uhh, I don't want to get near this. -flibit */
return;
}
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
const char oldPath[] =
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__) || defined(__DragonFly__)
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
"/.vvvvvv/";
#elif defined(__APPLE__)
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
"/Documents/VVVVVV/";
#endif
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
SDL_snprintf(oldDirectory, sizeof(oldDirectory), "%s%s", homeDir, oldPath);
2020-01-01 21:29:24 +01:00
dir = opendir(oldDirectory);
if (!dir)
{
printf("Could not find directory %s\n", oldDirectory);
return;
}
printf("Migrating old savedata to new location...\n");
for (de = readdir(dir); de != NULL; de = readdir(dir))
{
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
if ( SDL_strcmp(de->d_name, "..") == 0 ||
SDL_strcmp(de->d_name, ".") == 0 )
2020-01-01 21:29:24 +01:00
{
continue;
}
#define COPY_SAVEFILE(name) \
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
else if (SDL_strcmp(de->d_name, name) == 0) \
2020-01-01 21:29:24 +01:00
{ \
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
SDL_snprintf(oldLocation, sizeof(oldLocation), "%s%s", oldDirectory, name); \
SDL_snprintf(newLocation, sizeof(newLocation), "%ssaves/%s", output, name); \
2020-01-01 21:29:24 +01:00
PLATFORM_copyFile(oldLocation, newLocation); \
}
COPY_SAVEFILE("unlock.vvv")
COPY_SAVEFILE("tsave.vvv")
COPY_SAVEFILE("qsave.vvv")
#undef COPY_SAVEFILE
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
else if (SDL_strstr(de->d_name, ".vvvvvv.vvv") != NULL)
2020-01-01 21:29:24 +01:00
{
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
SDL_snprintf(oldLocation, sizeof(oldLocation), "%s%s", oldDirectory, de->d_name);
SDL_snprintf(newLocation, sizeof(newLocation), "%ssaves/%s", output, de->d_name);
2020-01-01 21:29:24 +01:00
PLATFORM_copyFile(oldLocation, newLocation);
}
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
else if (SDL_strstr(de->d_name, ".vvvvvv") != NULL)
2020-01-01 21:29:24 +01:00
{
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
SDL_snprintf(oldLocation, sizeof(oldLocation), "%s%s", oldDirectory, de->d_name);
SDL_snprintf(newLocation, sizeof(newLocation), "%slevels/%s", output, de->d_name);
2020-01-01 21:29:24 +01:00
PLATFORM_copyFile(oldLocation, newLocation);
}
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
else if (SDL_strcmp(de->d_name, "Saves") == 0)
2020-01-01 21:29:24 +01:00
{
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
SDL_snprintf(subDirLocation, sizeof(subDirLocation), "%sSaves/", oldDirectory);
2020-01-01 21:29:24 +01:00
subDir = opendir(subDirLocation);
if (!subDir)
{
printf("Could not open Saves/ subdir!\n");
continue;
}
for (
subDe = readdir(subDir);
subDe != NULL;
subDe = readdir(subDir)
) {
#define COPY_SAVEFILE(name) \
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
(SDL_strcmp(subDe->d_name, name) == 0) \
2020-01-01 21:29:24 +01:00
{ \
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
SDL_snprintf(oldLocation, sizeof(oldLocation), "%s%s", subDirLocation, name); \
SDL_snprintf(newLocation, sizeof(newLocation), "%ssaves/%s", output, name); \
2020-01-01 21:29:24 +01:00
PLATFORM_copyFile(oldLocation, newLocation); \
}
if COPY_SAVEFILE("unlock.vvv")
else if COPY_SAVEFILE("tsave.vvv")
else if COPY_SAVEFILE("qsave.vvv")
#undef COPY_SAVEFILE
}
}
}
#elif defined(_WIN32)
WIN32_FIND_DATA findHandle;
HANDLE hFind = NULL;
char fileSearch[MAX_PATH];
/* Same place, different layout. */
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
SDL_strlcpy(oldDirectory, output, sizeof(oldDirectory));
2020-01-01 21:29:24 +01:00
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
SDL_snprintf(fileSearch, sizeof(fileSearch), "%s\\*.vvvvvv", oldDirectory);
2020-01-01 21:29:24 +01:00
hFind = FindFirstFile(fileSearch, &findHandle);
if (hFind == INVALID_HANDLE_VALUE)
{
printf("Could not find directory %s\n", oldDirectory);
}
else do
{
if ((findHandle.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
{
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
SDL_snprintf(oldLocation, sizeof(oldLocation), "%s%s", oldDirectory, findHandle.cFileName);
SDL_snprintf(newLocation, sizeof(newLocation), "%slevels\\%s", output, findHandle.cFileName);
2020-01-01 21:29:24 +01:00
PLATFORM_copyFile(oldLocation, newLocation);
}
} while (FindNextFile(hFind, &findHandle));
#else
#error See PLATFORM_migrateSaveData
#endif
}
static void PLATFORM_copyFile(const char *oldLocation, const char *newLocation)
2020-01-01 21:29:24 +01:00
{
char *data;
size_t length, bytes_read, bytes_written;
2020-01-01 21:29:24 +01:00
/* Read data */
FILE *file = fopen(oldLocation, "rb");
if (!file)
{
printf("Cannot open/copy %s\n", oldLocation);
return;
}
fseek(file, 0, SEEK_END);
length = ftell(file);
fseek(file, 0, SEEK_SET);
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
data = (char*) SDL_malloc(length);
if (data == NULL)
{
VVV_exit(1);
}
bytes_read = fread(data, 1, length, file);
2020-01-01 21:29:24 +01:00
fclose(file);
if (bytes_read != length)
{
printf("An error occurred when reading from %s\n", oldLocation);
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
SDL_free(data);
return;
}
2020-01-01 21:29:24 +01:00
/* Write data */
file = fopen(newLocation, "wb");
if (!file)
{
printf("Could not write to %s\n", newLocation);
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
SDL_free(data);
2020-01-01 21:29:24 +01:00
return;
}
bytes_written = fwrite(data, 1, length, file);
2020-01-01 21:29:24 +01:00
fclose(file);
Reduce dependency on libc functions During 2.3 development, there's been a gradual shift to using SDL stdlib functions instead of libc functions, but there are still some libc functions (or the same libc function but from the STL) in the code. Well, this patch replaces all the rest of them in one fell swoop. SDL's stdlib can replace most of these, but its SDL_min() and SDL_max() are inadequate - they aren't really functions, they're more like macros with a nasty penchant for double-evaluation. So I just made my own VVV_min() and VVV_max() functions and placed them in Maths.h instead, then replaced all the previous usages of min(), max(), std::min(), std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max(). Additionally, there's no SDL_isxdigit(), so I just implemented my own VVV_isxdigit(). SDL has SDL_malloc() and SDL_free(), but they have some refcounting built in to them, so in order to use them with LodePNG, I have to replace the malloc() and free() that LodePNG uses. Which isn't too hard, I did it in a new file called ThirdPartyDeps.c, and LodePNG is now compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition. Lastly, I also refactored the awful strcpy() and strcat() usages in PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save migration is getting axed in 2.4, but it still bothers me to have something like that in the codebase otherwise. Without further ado, here is the full list of functions that the codebase now uses: - SDL_strlcpy() instead of strcpy() - SDL_strlcat() instead of strcat() - SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above) - VVV_min() instead of min(), std::min(), or SDL_min() - VVV_max() instead of max(), std::max(), or SDL_max() - VVV_isxdigit() instead of isxdigit() - SDL_strcmp() instead of strcmp() - SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi() - SDL_strstr() instead of strstr() - SDL_strlen() instead of strlen() - SDL_sscanf() instead of sscanf() - SDL_getenv() instead of getenv() - SDL_malloc() instead of malloc() (replacing in LodePNG as well) - SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
SDL_free(data);
2020-01-01 21:29:24 +01:00
/* WTF did we just do */
printf("Copied:\n\tOld: %s\n\tNew: %s\n", oldLocation, newLocation);
if (bytes_written != length)
{
printf("Warning: an error occurred when writing to %s\n", newLocation);
}
2020-01-01 21:29:24 +01:00
}
bool FILESYSTEM_openDirectoryEnabled(void)
{
/* This is just a check to see if we're on a desktop or tenfoot setup.
* If you're working on a tenfoot-only build, add a def that always
* returns false!
*/
2020-04-18 17:38:27 +02:00
return !SDL_GetHintBoolean("SteamTenfoot", SDL_FALSE);
}
bool FILESYSTEM_openDirectory(const char *dname)
{
char url[MAX_PATH];
SDL_snprintf(url, sizeof(url), "file://%s", dname);
if (SDL_OpenURL(url) == -1)
{
printf("Error opening directory: %s\n", SDL_GetError());
return false;
}
return true;
}
bool FILESYSTEM_delete(const char *name)
{
return PHYSFS_delete(name) != 0;
}