const char * osal_get_user_configpath(void) { static char path[1024] = { 0 }; if (getenv("HOME") != NULL) { strcpy(path, getenv("HOME")); } else { struct passwd* pwd = getpwuid(getuid()); if (pwd) strcpy(path, pwd->pw_dir); } /* append the given sub-directory to the path given by the environment variable */ if (path[strlen(path)-1] != '/') strcat(path, "/"); strcat(path, "Library/Application Support/Mupen64Plus/"); /* try to create the resulting directory tree, or return successfully if it already exists */ if (osal_mkdirp(path, 0700) != 0) { DebugMessage(M64MSG_ERROR, "Couldn't create directory: %s", path); DebugMessage(M64MSG_ERROR, "Failed to get configuration directory; Path is undefined or invalid."); return NULL; } return path; }
static int get_xdg_dir(char *destpath, const char *envvar, const char *subdir) { struct stat fileinfo; const char *envpath = getenv(envvar); /* error if this environment variable doesn't return a good string */ if (envpath == NULL || strlen(envpath) < 1) return 1; /* error if path returned by the environemnt variable isn't a valid path to a directory */ if (stat(envpath, &fileinfo) != 0 || !S_ISDIR(fileinfo.st_mode)) return 2; /* append the given sub-directory to the path given by the environment variable */ strcpy(destpath, envpath); if (destpath[strlen(destpath)-1] != '/') strcat(destpath, "/"); strcat(destpath, subdir); /* try to create the resulting directory tree, or return successfully if it already exists */ if (osal_mkdirp(destpath, 0700) != 0) { DebugMessage(M64MSG_ERROR, "Couldn't create directory: %s", destpath); return 3; } /* Success */ return 0; }
EXPORT const char * CALL ConfigGetUserConfigPath(void) { if (l_ConfigDirOverride != NULL) { osal_mkdirp(l_ConfigDirOverride, 0700); return l_ConfigDirOverride; } else return osal_get_user_configpath(); }
/********************************************************************************************************* * helper functions */ char *get_savespath() { static char path[1024]; snprintf(path, 1024, "%ssave%c", ConfigGetUserDataPath(), OSAL_DIR_SEPARATOR); path[1023] = 0; /* make sure the directory exists */ if (osal_mkdirp(path, 0700) != 0) return NULL; return path; }
static char *GetNextScreenshotPath(void) { char *ScreenshotPath; char ScreenshotFileName[20 + 8 + 1]; // generate the base name of the screenshot // add the ROM name, convert to lowercase, convert spaces to underscores strcpy(ScreenshotFileName, ROM_PARAMS.headername); for (char *pch = ScreenshotFileName; *pch != '\0'; pch++) *pch = (*pch == ' ') ? '_' : tolower(*pch); strcat(ScreenshotFileName, "-###.png"); // add the base path to the screenshot file name const char *SshotDir = ConfigGetParamString(g_CoreConfig, "ScreenshotPath"); if (SshotDir == NULL || *SshotDir == '\0') { // note the trick to avoid an allocation. we add a NUL character // instead of the separator, call mkdir, then add the separator ScreenshotPath = formatstr("%sscreenshot%c%s", ConfigGetUserDataPath(), '\0', ScreenshotFileName); if (ScreenshotPath == NULL) return NULL; osal_mkdirp(ScreenshotPath, 0700); ScreenshotPath[strlen(ScreenshotPath)] = OSAL_DIR_SEPARATORS[0]; } else { ScreenshotPath = combinepath(SshotDir, ScreenshotFileName); if (ScreenshotPath == NULL) return NULL; } // patch the number part of the name (the '###' part) until we find a free spot char *NumberPtr = ScreenshotPath + strlen(ScreenshotPath) - 7; for (; CurrentShotIndex < 1000; CurrentShotIndex++) { sprintf(NumberPtr, "%03i.png", CurrentShotIndex); FILE *pFile = fopen(ScreenshotPath, "r"); if (pFile == NULL) break; fclose(pFile); } if (CurrentShotIndex >= 1000) { DebugMessage(M64MSG_ERROR, "Can't save screenshot; folder already contains 1000 screenshots for this ROM"); return NULL; } CurrentShotIndex++; return ScreenshotPath; }
static void getStorageFileName(wchar_t * _fileName) { wchar_t strCacheFolderPath[PLUGIN_PATH_SIZE]; api().GetUserCachePath(strCacheFolderPath); wchar_t strShaderFolderPath[PLUGIN_PATH_SIZE]; swprintf(strShaderFolderPath, PLUGIN_PATH_SIZE, L"%ls/%ls", strCacheFolderPath, SHADER_STORAGE_FOLDER_NAME); wchar_t * pPath = strShaderFolderPath; if (!osal_path_existsW(strShaderFolderPath) || !osal_is_directory(strShaderFolderPath)) { if (osal_mkdirp(strShaderFolderPath) != 0) pPath = strCacheFolderPath; } swprintf(_fileName, PLUGIN_PATH_SIZE, L"%ls/GLideN64.%08lx.shaders", pPath, std::hash<std::string>()(RSP.romname)); }
static void GetBaseFilepath(char *filepath, int maxlen) { const char *SshotDir = ConfigGetParamString(g_CoreConfig, "ScreenshotPath"); // sanity check input if (filepath == NULL) return; if (maxlen < 32) { filepath[0] = 0; return; } /* get the path to store screenshots */ strncpy(filepath, SshotDir, maxlen - 24); filepath[maxlen-24] = 0; if (strlen(filepath) == 0) { snprintf(filepath, maxlen - 24, "%sscreenshot%c", ConfigGetUserDataPath(), OSAL_DIR_SEPARATOR); osal_mkdirp(filepath, 0700); } /* make sure there is a slash on the end of the pathname */ int pathlen = strlen(filepath); if (pathlen > 0 && filepath[pathlen-1] != OSAL_DIR_SEPARATOR) { filepath[pathlen] = OSAL_DIR_SEPARATOR; filepath[pathlen+1] = 0; } // add the game's name to the end, convert to lowercase, convert spaces to underscores char *pch = filepath + strlen(filepath); char ch; strncpy(pch, (char*) ROM_HEADER->nom, 20); pch[20] = '\0'; do { ch = *pch; if (ch == ' ') *pch++ = '_'; else *pch++ = tolower(ch); } while (ch != 0); return; }
const char * osal_get_user_configpath(void) { static char chHomePath[MAX_PATH]; LPITEMIDLIST pidl; LPMALLOC pMalloc; struct _stat fileinfo; // Get item ID list for the path of user's personal directory HRESULT hr = SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pidl); // get the path in a char string SHGetPathFromIDList(pidl, chHomePath); // do a bunch of crap just to free some memory hr = SHGetMalloc(&pMalloc); pMalloc->lpVtbl->Free(pMalloc, pidl); pMalloc->lpVtbl->Release(pMalloc); // tack on 'mupen64plus' if (chHomePath[strlen(chHomePath)-1] != '\\') strcat(chHomePath, "\\"); strcat(chHomePath, "Mupen64Plus"); // if this directory doesn't exist, then make it if (_stat(chHomePath, &fileinfo) == 0) { strcat(chHomePath, "\\"); return chHomePath; } else { osal_mkdirp(chHomePath, 0); if (_stat(chHomePath, &fileinfo) == 0) { strcat(chHomePath, "\\"); return chHomePath; } } /* otherwise we are in trouble */ DebugMessage(M64MSG_ERROR, "Failed to open configuration directory '%s'.", chHomePath); return NULL; }
static void getStorageFileName(wchar_t * _fileName) { wchar_t strCacheFolderPath[PLUGIN_PATH_SIZE]; api().GetUserCachePath(strCacheFolderPath); wchar_t strShaderFolderPath[PLUGIN_PATH_SIZE]; swprintf(strShaderFolderPath, PLUGIN_PATH_SIZE, L"%ls/%ls", strCacheFolderPath, SHADER_STORAGE_FOLDER_NAME); wchar_t * pPath = strShaderFolderPath; if (!osal_path_existsW(strShaderFolderPath) || !osal_is_directory(strShaderFolderPath)) { if (osal_mkdirp(strShaderFolderPath) != 0) pPath = strCacheFolderPath; } #ifdef GLES3 const wchar_t* strOpenGLType = L"GLES3"; #elif GLES3_1 const wchar_t* strOpenGLType = L"GLES3_1"; #else const wchar_t* strOpenGLType = L"OpenGL"; #endif swprintf(_fileName, PLUGIN_PATH_SIZE, L"%ls/GLideN64.%08lx.%ls.shaders", pPath, std::hash<std::string>()(RSP.romname), strOpenGLType); }
boolean TxCache::save(const wchar_t *path, const wchar_t *filename, int config) { if (_cache.empty()) return true; /* dump cache to disk */ char cbuf[MAX_PATH]; osal_mkdirp(path); /* Ugly hack to enable fopen/gzopen in Win9x */ #ifdef OS_WINDOWS wchar_t curpath[MAX_PATH]; GETCWD(MAX_PATH, curpath); CHDIR(path); #else char curpath[MAX_PATH]; GETCWD(MAX_PATH, curpath); wcstombs(cbuf, path, MAX_PATH); CHDIR(cbuf); #endif wcstombs(cbuf, filename, MAX_PATH); gzFile gzfp = gzopen(cbuf, "wb1"); DBG_INFO(80, wst("gzfp:%x file:%ls\n"), gzfp, filename); if (gzfp) { /* write header to determine config match */ gzwrite(gzfp, &config, 4); std::map<uint64, TXCACHE*>::iterator itMap = _cache.begin(); int total = 0; while (itMap != _cache.end()) { uint8 *dest = (*itMap).second->info.data; uint32 destLen = (*itMap).second->size; uint32 format = (*itMap).second->info.format; /* to keep things simple, we save the texture data in a zlib uncompressed state. */ /* sigh... for those who cannot wait the extra few seconds. changed to keep * texture data in a zlib compressed state. if the GZ_TEXCACHE or GZ_HIRESTEXCACHE * option is toggled, the cache will need to be rebuilt. */ /*if (format & GL_TEXFMT_GZ) { dest = _gzdest0; destLen = _gzdestLen; if (dest && destLen) { if (uncompress(dest, &destLen, (*itMap).second->info.data, (*itMap).second->size) != Z_OK) { dest = nullptr; destLen = 0; } format &= ~GL_TEXFMT_GZ; } }*/ if (dest && destLen) { /* texture checksum */ gzwrite(gzfp, &((*itMap).first), 8); /* other texture info */ gzwrite(gzfp, &((*itMap).second->info.width), 4); gzwrite(gzfp, &((*itMap).second->info.height), 4); gzwrite(gzfp, &format, 4); gzwrite(gzfp, &((*itMap).second->info.texture_format), 2); gzwrite(gzfp, &((*itMap).second->info.pixel_type), 2); gzwrite(gzfp, &((*itMap).second->info.is_hires_tex), 1); gzwrite(gzfp, &destLen, 4); gzwrite(gzfp, dest, destLen); } itMap++; if (_callback) (*_callback)(wst("Total textures saved to HDD: %d\n"), ++total); } gzclose(gzfp); } CHDIR(curpath); return _cache.empty(); }