mirror of
https://github.com/TerryCavanagh/VVVVVV.git
synced 2026-01-30 01:48:15 +03:00
Hello WWWWWWorld!
This commit is contained in:
363
desktop_version/src/FileSystemUtils.cpp
Normal file
363
desktop_version/src/FileSystemUtils.cpp
Normal file
@@ -0,0 +1,363 @@
|
||||
#include "FileSystemUtils.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <physfs.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#define mkdir(a, b) CreateDirectory(a, NULL)
|
||||
#define VNEEDS_MIGRATION (mkdirResult != 0)
|
||||
#elif defined(__linux__) || defined(__APPLE__)
|
||||
#include <sys/stat.h>
|
||||
#include <limits.h>
|
||||
#define VNEEDS_MIGRATION (mkdirResult == 0)
|
||||
/* These are needed for PLATFORM_* crap */
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#define MAX_PATH PATH_MAX
|
||||
#endif
|
||||
|
||||
char saveDir[MAX_PATH];
|
||||
char levelDir[MAX_PATH];
|
||||
|
||||
void PLATFORM_getOSDirectory(char* output);
|
||||
void PLATFORM_migrateSaveData(char* output);
|
||||
void PLATFORM_copyFile(const char *oldLocation, const char *newLocation);
|
||||
|
||||
void FILESYSTEM_init(char *argvZero)
|
||||
{
|
||||
char output[MAX_PATH];
|
||||
int mkdirResult;
|
||||
|
||||
PHYSFS_init(argvZero);
|
||||
|
||||
/* Determine the OS user directory */
|
||||
PLATFORM_getOSDirectory(output);
|
||||
|
||||
/* Create base user directory, mount */
|
||||
mkdirResult = mkdir(output, 0777);
|
||||
|
||||
/* Mount our base user directory */
|
||||
PHYSFS_mount(output, NULL, 1);
|
||||
printf("Base directory: %s\n", output);
|
||||
|
||||
/* Create save directory */
|
||||
strcpy(saveDir, output);
|
||||
strcat(saveDir, "saves");
|
||||
strcat(saveDir, PHYSFS_getDirSeparator());
|
||||
mkdir(saveDir, 0777);
|
||||
printf("Save directory: %s\n", saveDir);
|
||||
|
||||
/* Create level directory */
|
||||
strcpy(levelDir, output);
|
||||
strcat(levelDir, "levels");
|
||||
strcat(levelDir, PHYSFS_getDirSeparator());
|
||||
mkdirResult |= mkdir(levelDir, 0777);
|
||||
printf("Level directory: %s\n", levelDir);
|
||||
|
||||
/* We didn't exist until now, migrate files! */
|
||||
if (VNEEDS_MIGRATION)
|
||||
{
|
||||
PLATFORM_migrateSaveData(output);
|
||||
}
|
||||
|
||||
/* Mount the stock content last */
|
||||
#ifdef _WIN32
|
||||
strcpy(output, PHYSFS_getBaseDir());
|
||||
strcat(output, "data.zip");
|
||||
#else
|
||||
strcpy(output, "data.zip");
|
||||
#endif
|
||||
PHYSFS_mount(output, NULL, 1);
|
||||
}
|
||||
|
||||
void FILESYSTEM_deinit()
|
||||
{
|
||||
PHYSFS_deinit();
|
||||
}
|
||||
|
||||
char *FILESYSTEM_getUserSaveDirectory()
|
||||
{
|
||||
return saveDir;
|
||||
}
|
||||
|
||||
char *FILESYSTEM_getUserLevelDirectory()
|
||||
{
|
||||
return levelDir;
|
||||
}
|
||||
|
||||
void FILESYSTEM_loadFileToMemory(const char *name, unsigned char **mem, size_t *len)
|
||||
{
|
||||
PHYSFS_File *handle = PHYSFS_openRead(name);
|
||||
if (handle == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
PHYSFS_uint32 length = PHYSFS_fileLength(handle);
|
||||
if (len != NULL)
|
||||
{
|
||||
*len = length;
|
||||
}
|
||||
*mem = (unsigned char*) malloc(length);
|
||||
PHYSFS_read(handle, *mem, 1, length);
|
||||
PHYSFS_close(handle);
|
||||
}
|
||||
|
||||
void FILESYSTEM_freeMemory(unsigned char **mem)
|
||||
{
|
||||
free(*mem);
|
||||
*mem = NULL;
|
||||
}
|
||||
|
||||
std::vector<std::string> FILESYSTEM_getLevelDirFileNames()
|
||||
{
|
||||
std::vector<std::string> list;
|
||||
char **fileList = PHYSFS_enumerateFiles("/levels");
|
||||
char **i;
|
||||
std::string builtLocation;
|
||||
|
||||
for (i = fileList; *i != NULL; i++)
|
||||
{
|
||||
if (strcmp(*i, "data") == 0)
|
||||
{
|
||||
continue; /* FIXME: lolwut -flibit */
|
||||
}
|
||||
builtLocation = "levels/";
|
||||
builtLocation += *i;
|
||||
list.push_back(builtLocation);
|
||||
}
|
||||
|
||||
PHYSFS_freeList(fileList);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void PLATFORM_getOSDirectory(char* output)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
const char *homeDir = getenv("XDG_DATA_HOME");
|
||||
if (homeDir == NULL)
|
||||
{
|
||||
strcpy(output, PHYSFS_getUserDir());
|
||||
strcat(output, ".local/share/VVVVVV/");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(output, homeDir);
|
||||
strcat(output, "/VVVVVV/");
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
strcpy(output, PHYSFS_getUserDir());
|
||||
strcat(output, "Library/Application Support/VVVVVV/");
|
||||
#elif defined(_WIN32)
|
||||
SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, output);
|
||||
strcat(output, "\\VVVVVV\\");
|
||||
#else
|
||||
#error See PLATFORM_getOSDirectory
|
||||
#endif
|
||||
}
|
||||
|
||||
void PLATFORM_migrateSaveData(char* output)
|
||||
{
|
||||
char oldLocation[MAX_PATH];
|
||||
char newLocation[MAX_PATH];
|
||||
char oldDirectory[MAX_PATH];
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
DIR *dir = NULL;
|
||||
struct dirent *de = NULL;
|
||||
DIR *subDir = NULL;
|
||||
struct dirent *subDe = NULL;
|
||||
char subDirLocation[MAX_PATH];
|
||||
const char *homeDir = getenv("HOME");
|
||||
if (homeDir == NULL)
|
||||
{
|
||||
/* Uhh, I don't want to get near this. -flibit */
|
||||
return;
|
||||
}
|
||||
strcpy(oldDirectory, homeDir);
|
||||
#if defined(__linux__)
|
||||
strcat(oldDirectory, "/.vvvvvv/");
|
||||
#elif defined(__APPLE__)
|
||||
strcat(oldDirectory, "/Documents/VVVVVV/");
|
||||
#endif
|
||||
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))
|
||||
{
|
||||
if ( strcmp(de->d_name, "..") == 0 ||
|
||||
strcmp(de->d_name, ".") == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#define COPY_SAVEFILE(name) \
|
||||
else if (strcmp(de->d_name, name) == 0) \
|
||||
{ \
|
||||
strcpy(oldLocation, oldDirectory); \
|
||||
strcat(oldLocation, name); \
|
||||
strcpy(newLocation, output); \
|
||||
strcat(newLocation, "saves/"); \
|
||||
strcat(newLocation, name); \
|
||||
PLATFORM_copyFile(oldLocation, newLocation); \
|
||||
}
|
||||
COPY_SAVEFILE("unlock.vvv")
|
||||
COPY_SAVEFILE("tsave.vvv")
|
||||
COPY_SAVEFILE("qsave.vvv")
|
||||
#undef COPY_SAVEFILE
|
||||
else if (strstr(de->d_name, ".vvvvvv.vvv") != NULL)
|
||||
{
|
||||
strcpy(oldLocation, oldDirectory);
|
||||
strcat(oldLocation, de->d_name);
|
||||
strcpy(newLocation, output);
|
||||
strcat(newLocation, "saves/");
|
||||
strcat(newLocation, de->d_name);
|
||||
PLATFORM_copyFile(oldLocation, newLocation);
|
||||
}
|
||||
else if (strstr(de->d_name, ".vvvvvv") != NULL)
|
||||
{
|
||||
strcpy(oldLocation, oldDirectory);
|
||||
strcat(oldLocation, de->d_name);
|
||||
strcpy(newLocation, output);
|
||||
strcat(newLocation, "levels/");
|
||||
strcat(newLocation, de->d_name);
|
||||
PLATFORM_copyFile(oldLocation, newLocation);
|
||||
}
|
||||
else if (strcmp(de->d_name, "Saves") == 0)
|
||||
{
|
||||
strcpy(subDirLocation, oldDirectory);
|
||||
strcat(subDirLocation, "Saves/");
|
||||
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) \
|
||||
(strcmp(subDe->d_name, name) == 0) \
|
||||
{ \
|
||||
strcpy(oldLocation, subDirLocation); \
|
||||
strcat(oldLocation, name); \
|
||||
strcpy(newLocation, output); \
|
||||
strcat(newLocation, "saves/"); \
|
||||
strcat(newLocation, name); \
|
||||
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. */
|
||||
strcpy(oldDirectory, output);
|
||||
|
||||
/* In theory we don't need to worry about this, thanks case insensitivity!
|
||||
sprintf(fileSearch, "%s\\Saves\\*.vvv", oldDirectory);
|
||||
hFind = FindFirstFile(fileSearch, &findHandle);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
printf("Could not find directory %s\\Saves\\\n", oldDirectory);
|
||||
}
|
||||
else do
|
||||
{
|
||||
if ((findHandle.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
|
||||
{
|
||||
#define COPY_SAVEFILE(name) \
|
||||
(strcmp(findHandle.cFileName, name) == 0) \
|
||||
{ \
|
||||
strcpy(oldLocation, oldDirectory); \
|
||||
strcat(oldLocation, "Saves\\"); \
|
||||
strcat(oldLocation, name); \
|
||||
strcpy(newLocation, output); \
|
||||
strcat(newLocation, "saves\\"); \
|
||||
strcat(newLocation, name); \
|
||||
PLATFORM_copyFile(oldLocation, newLocation); \
|
||||
}
|
||||
if COPY_SAVEFILE("unlock.vvv")
|
||||
else if COPY_SAVEFILE("tsave.vvv")
|
||||
else if COPY_SAVEFILE("qsave.vvv")
|
||||
#undef COPY_SAVEFILE
|
||||
}
|
||||
} while (FindNextFile(hFind, &findHandle));
|
||||
*/
|
||||
|
||||
sprintf(fileSearch, "%s\\*.vvvvvv", oldDirectory);
|
||||
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)
|
||||
{
|
||||
strcpy(oldLocation, oldDirectory);
|
||||
strcat(oldLocation, findHandle.cFileName);
|
||||
strcpy(newLocation, output);
|
||||
strcat(newLocation, "levels\\");
|
||||
strcat(newLocation, findHandle.cFileName);
|
||||
PLATFORM_copyFile(oldLocation, newLocation);
|
||||
}
|
||||
} while (FindNextFile(hFind, &findHandle));
|
||||
#else
|
||||
#error See PLATFORM_migrateSaveData
|
||||
#endif
|
||||
}
|
||||
|
||||
void PLATFORM_copyFile(const char *oldLocation, const char *newLocation)
|
||||
{
|
||||
char *data;
|
||||
long int length;
|
||||
|
||||
/* 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);
|
||||
data = (char*) malloc(length);
|
||||
fread(data, 1, length, file);
|
||||
fclose(file);
|
||||
|
||||
/* Write data */
|
||||
file = fopen(newLocation, "wb");
|
||||
if (!file)
|
||||
{
|
||||
printf("Could not write to %s\n", newLocation);
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
fwrite(data, 1, length, file);
|
||||
fclose(file);
|
||||
free(data);
|
||||
|
||||
/* WTF did we just do */
|
||||
printf("Copied:\n\tOld: %s\n\tNew: %s\n", oldLocation, newLocation);
|
||||
}
|
||||
Reference in New Issue
Block a user