/*************************************************************************** Make a directory in write path and set a variable to point to it. ***************************************************************************/ static void make_dir(char *dest, const char *dirname, const char *subdir) { strcpy(dest, dirname); if (subdir != NULL) { strcat(dest, "/"); strcat(dest, subdir); } { size_t l = strlen(dest); if (dest[l - 1] != '/') { dest[l] = '/'; dest[l + 1] = '\0'; } } PHYSFS_mkdir(dest); if (!PHYSFS_mkdir(dest)) { debug(LOG_FATAL, "Unable to create directory \"%s\" in write dir \"%s\"!", dest, PHYSFS_getWriteDir()); exit(EXIT_FAILURE); } }
static bool readSurfaces( const char *filename, std::vector< RenderSurface > &surfaces ) { uint64_t hashedName = HashedString( 0, filename ); char outfile[256]; PHYSFS_mkdir( "static_models/" ); sprintf( outfile, "static_models/%08x_%08x.sm", (uint32_t)(hashedName>>32), (uint32_t)(hashedName&0xffffffff) ); PHYSFS_File *model = PHYSFS_openRead( outfile ); if ( model ) { unsigned int ver, numSurf; PHYSFS_readULE32( model, &ver ); PHYSFS_readULE32( model, &numSurf ); surfaces.resize( numSurf ); for ( uint32_t i=0; i<surfaces.size(); i++ ) { RenderSurface &surf = surfaces[i]; PHYSFS_readCStr( model, surf.name ); std::string mat; PHYSFS_readCStr( model, mat ); surf.mat = materialManager()->Load( mat.c_str() ); ModelGeometry *geom = new ModelGeometry; surf.geom = geom; PHYSFS_readSLE32( model, &geom->m_numIndices ); PHYSFS_readSLE32( model, &geom->m_numVerts ); geom->m_indices = new unsigned short[geom->m_numIndices]; geom->m_verts = new ModelVert[geom->m_numVerts]; PHYSFS_read( model, geom->m_indices, sizeof(uint16_t)*geom->m_numIndices, 1 ); PHYSFS_read( model, geom->m_verts, sizeof(geom->m_verts[0])*geom->m_numVerts, 1 ); } PHYSFS_close( model ); return true; } return false; }
void save_screen_shot(int automap_flag) { static int savenum=0; char savename[13+sizeof(SCRNS_DIR)]; unsigned char *buf; if (!GameArg.DbgGlReadPixelsOk){ if (!automap_flag) HUD_init_message_literal(HM_DEFAULT, "glReadPixels not supported on your configuration"); return; } stop_time(); if (!PHYSFSX_exists(SCRNS_DIR,0)) PHYSFS_mkdir(SCRNS_DIR); //try making directory do { sprintf(savename, "%sscrn%04d.tga",SCRNS_DIR, savenum++); } while (PHYSFSX_exists(savename,0)); if (!automap_flag) HUD_init_message(HM_DEFAULT, "%s 'scrn%04d.tga'", TXT_DUMPING_SCREEN, savenum-1 ); #ifndef OGLES glReadBuffer(GL_FRONT); #endif buf = d_malloc(grd_curscreen->sc_w*grd_curscreen->sc_h*3); write_bmp(savename,grd_curscreen->sc_w,grd_curscreen->sc_h,buf); d_free(buf); start_time(); }
bool Resources::mkdir(const char* directory) { if(!PHYSFS_mkdir(directory)) { PError << "couldn't create directory '" << directory << "': " << PHYSFS_getLastError() << endl; return PFalse; }; return PTrue; }
static void writeSurfaces( const char *filename, std::vector< RenderSurface > &surfaces ) { uint64_t hashedName = HashedString( 0, filename ); char outfile[256]; PHYSFS_mkdir( "static_models/" ); sprintf( outfile, "static_models/%08x_%08x.sm", (uint32_t)(hashedName>>32), (uint32_t)(hashedName&0xffffffff) ); PHYSFS_File *model = PHYSFS_openWrite( outfile ); if ( model ) { PHYSFS_writeULE32( model, 0x090 ); PHYSFS_writeULE32( model, surfaces.size() ); for ( uint32_t i=0; i<surfaces.size(); i++ ) { RenderSurface const &surf = surfaces[i]; PHYSFS_writeCStr( model, surf.name.c_str() ); PHYSFS_writeCStr( model, surf.mat->Name() ); const ModelGeometry *geom = surf.geom; PHYSFS_writeSLE32( model, geom->m_numIndices ); PHYSFS_writeSLE32( model, geom->m_numVerts ); PHYSFS_write( model, geom->m_indices, sizeof(uint16_t)*geom->m_numIndices, 1 ); PHYSFS_write( model, geom->m_verts, sizeof(geom->m_verts[0])*geom->m_numVerts, 1 ); } PHYSFS_close( model ); } }
bool ResourceManager::setupWriteDir(const std::string& appWriteDirName) { std::string userDir = PHYSFS_getUserDir(); std::string dirName; #ifndef WIN32 dirName = stdext::format(".%s", appWriteDirName); #else dirName = appWriteDirName; #endif std::string writeDir = userDir + dirName; if(!PHYSFS_setWriteDir(writeDir.c_str())) { if(!PHYSFS_setWriteDir(userDir.c_str())) { g_logger.error("User directory not found."); return false; } if(!PHYSFS_mkdir(dirName.c_str())) { g_logger.error("Cannot create directory for saving configurations."); return false; } if(!PHYSFS_setWriteDir(writeDir.c_str())) { g_logger.error("Unable to set write directory."); return false; } } addToSearchPath(writeDir, true); //g_logger.debug(stdext::format("Setup write dir %s", writeDir)); return true; }
AddonManager::AddonManager(const std::string& addon_directory, std::vector<Config::Addon>& addon_config) : m_downloader(), m_addon_directory(addon_directory), m_repository_url("https://raw.githubusercontent.com/SuperTux/addons/master/index-0_5.nfo"), m_addon_config(addon_config), m_installed_addons(), m_repository_addons(), m_has_been_updated(false), m_transfer_status() { if(!PHYSFS_mkdir(m_addon_directory.c_str())) { std::ostringstream msg; msg << "Couldn't create directory for addons '" << m_addon_directory << "': " << PHYSFS_getLastError(); throw std::runtime_error(msg.str()); } add_installed_addons(); // FIXME: We should also restore the order here for(auto& addon : m_addon_config) { if (addon.enabled) { try { enable_addon(addon.id); } catch(const std::exception& err) { log_warning << "failed to enable addon from config: " << err.what() << std::endl; } } } if(PHYSFS_exists(ADDON_INFO_PATH)) { try { m_repository_addons = parse_addon_infos(ADDON_INFO_PATH); } catch(const std::exception& err) { log_warning << "parsing repository.nfo failed: " << err.what() << std::endl; } } else { log_info << "repository.nfo doesn't exist, not loading" << std::endl; } if (!g_config->repository_url.empty() && g_config->repository_url != m_repository_url) { m_repository_url = g_config->repository_url; } }
bool CResourceManager::CreateDirectory(const std::string& directory) { if (PHYSFS_isInit()) { return PHYSFS_mkdir(CleanPath(directory).c_str()); } return false; }
void Mkdir(std::string path) { if (!IsLoaded()) { Logger::begin("Filesystem", Logger::LogLevel_Error) << "FS not loaded" << Logger::end(); assert(false); return; } PHYSFS_mkdir(path.c_str()); }
void vsFile::EnsureWriteDirectoryExists( const vsString &writeDirectoryName ) // static method { if ( !DirectoryExists(writeDirectoryName) ) { int mkdirResult = PHYSFS_mkdir( writeDirectoryName.c_str() ); vsAssert( mkdirResult != 0, vsFormatString("Failed to create directory '%s%s%s': %s", PHYSFS_getWriteDir(), PHYSFS_getDirSeparator(), writeDirectoryName.c_str(), PHYSFS_getLastError()) ); } }
bool FileSystem::CreateDirectory(const Path & path) { auto genericString = path.generic_string(); int returnCode = PHYSFS_mkdir(genericString.c_str()) != 0; if (returnCode == 0) { GetContext().GetLogger()->log(LOG_LOG, "Failed to create directory, error: %s", PHYSFS_getLastError()); //printf("Failed to create directory, error: %s\n", PHYSFS_getLastError()); } return returnCode != 0; }
/******************************** * EntityCompiler_ExtractRoutines * count the anomunt of entities @ data: int * @ origdir: @ fname: */ static void EntityCompiler_ExtractRoutines(void * data, const char *origdir, const char *fname) { if ( g_str_has_suffix(fname, ".inc") && !g_str_has_prefix(fname, "private_") ) { gchar * internal_file_path = g_strdup_printf("%s/%s", origdir, fname); gchar * content = NULL; PHYSFS_mkdir(origdir); PHYSFS_delete( internal_file_path ); if ( Meg_file_get_contents(internal_file_path, &content, NULL, NULL) ) Meg_file_set_contents(internal_file_path, content, -1, NULL); } }
bool physfsDrive::MakeDir(const char * dir) { char newdir[CROSS_LEN]; strcpy(newdir,basedir); strcat(newdir,dir); CROSS_FILENAME(newdir); dirCache.ExpandName(newdir); normalize(newdir,basedir); if (PHYSFS_mkdir(newdir)) { CROSS_FILENAME(newdir); dirCache.CacheOut(newdir,true); return true; } return false; }
static int cmd_mkdir(char *args) { if (*args == '\"') { args++; args[strlen(args) - 1] = '\0'; } /* if */ if (PHYSFS_mkdir(args)) printf("Successful.\n"); else printf("Failure. reason: %s.\n", PHYSFS_getLastError()); return(1); } /* cmd_mkdir */
AddonManager::AddonManager(const std::string& addon_directory, std::vector<Config::Addon>& addon_config) : m_downloader(), m_addon_directory(addon_directory), m_repository_url("https://raw.githubusercontent.com/SuperTux/addons/master/index-0_4_0.nfo"), m_addon_config(addon_config), m_installed_addons(), m_repository_addons(), m_has_been_updated(false), m_transfer_status() { PHYSFS_mkdir(m_addon_directory.c_str()); add_installed_addons(); // FIXME: We should also restore the order here for(auto& addon : m_addon_config) { if (addon.enabled) { try { enable_addon(addon.id); } catch(const std::exception& err) { log_warning << "failed to enable addon from config: " << err.what() << std::endl; } } } if(PHYSFS_exists(ADDON_INFO_PATH)) { try { m_repository_addons = parse_addon_infos(ADDON_INFO_PATH); } catch(const std::exception& err) { log_warning << "parsing repository.nfo failed: " << err.what() << std::endl; } } else { log_info << "repository.nfo doesn't exist, not loading" << std::endl; } }
bool physfsFile::prepareWrite() { const char *wdir = PHYSFS_getWriteDir(); if (wdir == NULL) { LOG_MSG("PHYSFS could not fulfill write request: no write directory set."); return false; } //LOG_MSG("Goto write (%s at %i)",pname,PHYSFS_tell(fhandle)); const char *fdir = PHYSFS_getRealDir(pname); PHYSFS_uint64 pos = PHYSFS_tell(fhandle); char *slash = strrchr(pname,'/'); if (slash && slash != pname) { *slash = 0; PHYSFS_mkdir(pname); *slash = '/'; } if (strcmp(fdir,wdir)) { /* we need COW */ //LOG_MSG("COW",pname,PHYSFS_tell(fhandle)); PHYSFS_file *whandle = PHYSFS_openWrite(pname); if (whandle == NULL) { LOG_MSG("PHYSFS copy-on-write failed: %s.",PHYSFS_getLastError()); return false; } char buffer[65536]; PHYSFS_sint64 size; PHYSFS_seek(fhandle, 0); while ((size = PHYSFS_read(fhandle,buffer,1,65536)) > 0) { if (PHYSFS_write(whandle,buffer,1,(PHYSFS_uint32)size) != size) { LOG_MSG("PHYSFS copy-on-write failed: %s.",PHYSFS_getLastError()); PHYSFS_close(whandle); return false; } } PHYSFS_seek(whandle, pos); PHYSFS_close(fhandle); fhandle = whandle; } else { // megayuck - physfs on posix platforms uses O_APPEND. We illegally access the fd directly and clear that flag. //LOG_MSG("noCOW",pname,PHYSFS_tell(fhandle)); PHYSFS_close(fhandle); fhandle = PHYSFS_openAppend(pname); #ifndef WIN32 fcntl(**(int**)fhandle->opaque,F_SETFL,0); #endif PHYSFS_seek(fhandle, pos); } return true; }
/* * Compiles src lua source to dest lua bytecode * Bytecode is quicker to load as it is preparsed and optimized. * This function does NOT understands ToME virtual paths they * need to be converted first, this is intentionnal */ s32b tome_compile_lua(char *src) { char *split; char dest[2048]; Proto *tf; PHYSFS_file *dump; /* Clear error state */ PHYSFS_getLastError(); /* A new empty lua state */ compile_lua_state = lua_open(0); tf = load(src); /* If we dump we need to optimize */ if (tome_compile_lua_optimizing) luaU_optchunk(tf); /* Dump to a file */ if (tome_compile_lua_stripping) strip(tf); /* Make up the destination file .lua => .lb */ strncpy(dest, src, 2048); dest[strlen(dest) - 2] = 'b'; dest[strlen(dest) - 1] = '\0'; /* Make sure distination exists */ split = strrchr(dest, '/'); *split = '\0'; PHYSFS_mkdir(dest); *split = '/'; dump = efopen(dest, "wb"); if (dump == NULL) quit("Could not compile lua: error writting"); PHYSFS_getLastError(); luaU_dumpchunk_file(tf, dump); my_fclose(dump); /* Clean up */ /* For a strange reasons this totaly panics lua ... lua_close(compile_lua_state); */ return 0; }
// ---------------------------------------------------------------------------- void Editor::readConfigFile(IFileSystem* file_system) { IXMLReader* xml_reader = file_system->createXMLReader(path(PHYSFS_getBaseDir()) + "config.xml"); if (!xml_reader) { path dir = PHYSFS_getUserDir(); m_config_loc = dir + "/.stk-te"; xml_reader = file_system->createXMLReader(m_config_loc + "/config.xml"); if (!xml_reader) { PHYSFS_setWriteDir(dir.c_str()); PHYSFS_mkdir(".stk-te"); return; } } else m_config_loc = PHYSFS_getBaseDir(); const stringw node_name(L"data_dir"); const stringw res(L"res"); const stringw exe(L"exe"); while (xml_reader->read()) { if (xml_reader->getNodeType() == EXN_ELEMENT) { if (res.equals_ignore_case(xml_reader->getNodeName())) { m_screen_size = dimension2du( atol(((stringc)xml_reader->getAttributeValueSafe(L"x")).c_str()), atol(((stringc)xml_reader->getAttributeValueSafe(L"y")).c_str())); } else if (node_name.equals_ignore_case(xml_reader->getNodeName())) { m_data_loc = xml_reader->getAttributeValueSafe(L"path"); m_icons_loc = m_data_loc + "editor/icons/"; } else if (exe.equals_ignore_case(xml_reader->getNodeName())) { m_exe_loc = xml_reader->getAttributeValueSafe(L"path"); } } } xml_reader->drop(); } // readConfigFile
// ---------------------------------------------------------------------------- void Editor::initDataLoc() { IFileSystem* file_system = m_device->getFileSystem(); if (!file_system->addFileArchive((m_data_loc + "editor/xml").c_str(), false, false, EFAT_FOLDER, "", &m_xml_dir)) { std::cerr << "Bad news: i couldn't find the xml directory.\n"; std::cerr << "Maybe the whole editor folder is missing? :(\n"; exit(-1); } file_system->addFileArchive(m_data_loc, false, false, EFAT_FOLDER); m_valid_data_dir = true; initAfterDataDirKnown(); path p = m_data_loc.c_str(); p += "editor/maps"; m_maps_path = new c8[p.size() + 1]; strcpy(m_maps_path, p.c_str()); if (!PHYSFS_exists(p.c_str())) { std::cerr << "Warning: maps directory doesn't exist. Creating...\n"; PHYSFS_setWriteDir(m_data_loc.c_str()); PHYSFS_mkdir("editor/maps"); } p = m_data_loc.c_str(); p += "music"; m_music_loc = new c8[p.size() + 1]; strcpy(m_music_loc, p.c_str()); m_track_dir = m_data_loc.c_str(); m_track_dir += "tracks/"; file_system->changeWorkingDirectoryTo(m_def_wd); m_tex_sel = TexSel::getTexSel(); m_toolbox = ToolBox::getToolBox(); file_system->addFileArchive((m_data_loc + "editor").c_str(), false, false, EFAT_FOLDER); } // setDataLoc
void VideoSystem::do_take_screenshot() { SDLSurfacePtr surface = make_screenshot(); if (!surface) { log_warning << "Creating the screenshot has failed" << std::endl; return; } const std::string screenshots_dir = "/screenshots"; if (!PHYSFS_exists(screenshots_dir.c_str())) { if (!PHYSFS_mkdir(screenshots_dir.c_str())) { log_warning << "Creating '" << screenshots_dir << "' failed" << std::endl; return; } } auto find_filename = [&]() -> boost::optional<std::string> { for (int num = 0; num < 1000000; ++num) { std::ostringstream oss; oss << "screenshot" << std::setw(6) << std::setfill('0') << num << ".png"; const std::string screenshot_filename = FileSystem::join(screenshots_dir, oss.str()); if (!PHYSFS_exists(screenshot_filename.c_str())) { return screenshot_filename; } } return boost::none; }; auto filename = find_filename(); if (!filename) { log_info << "Failed to find filename to save screenshot" << std::endl; } else { if (SDLSurface::save_png(*surface, *filename)) { log_info << "Wrote screenshot to \"" << *filename << "\"" << std::endl; } } }
/**Initialize the PhysFS system * \return Nonzero on success. */ int Filesystem::Init( const char* argv0 ) { int retval; if ( (retval = PHYSFS_init(argv0)) == 0 ) LogMsg(ERR,"Error initializing PhysicsFS. Reason: %s\n",PHYSFS_getLastError()); if ( (retval = PHYSFS_setSaneConfig("games", "epiar", NULL, 0, 0 ) ) == 0 ) LogMsg(ERR,"Could not set sane paths for PhysFS: %s\n", PHYSFS_getLastError()); // Set up userDir if ( (retval = PHYSFS_mkdir("Resources/Definitions/") ) == 0 ) LogMsg(ERR,"Could not set up the user dir: %s\n", PHYSFS_getLastError()); #ifdef DATADIR // If using autotools, include this prefix to help binary find data files for cases where 'make install' was used if ( (retval = PHYSFS_addToSearchPath(DATADIR, 1)) == 0 ) LogMsg(INFO,"Not using DATADIR directory due to error, probably 'make install' not run yet. Reason: %s\n", PHYSFS_getLastError()); #endif /* DATADIR */ return retval; }
void probeDir(const std::string& dirname) { if (PHYSFS_isDirectory(dirname.c_str()) == 0) { if (PHYSFS_exists(dirname.c_str())) { PHYSFS_delete(dirname.c_str()); } if (PHYSFS_mkdir(dirname.c_str())) { std::cout << PHYSFS_getWriteDir() << dirname << " created" << std::endl; } else { std::cout << "Warning: Creation of" << PHYSFS_getWriteDir() << dirname << " failed!" << std::endl; } } }
static void levTestLoad(const char* level) { static char savegameName[80]; bool retval; retval = levLoadData(level, NULL, GTYPE_SCENARIO_START); ASSERT(retval, "levLoadData failed selftest"); ASSERT(checkResearchStats(), "checkResearchStats failed selftest"); ASSERT(checkStructureStats(), "checkStructureStats failed selftest"); fprintf(stdout, "\t\tLoaded: %s\n", level); strcpy(savegameName, "selftest/"); PHYSFS_mkdir(savegameName); strcat(savegameName, level); strcat(savegameName, ".gam"); retval = saveGame(savegameName, GTYPE_SAVE_START); ASSERT(retval, "saveGame failed selftest"); strcpy(savegameName, "selftest/"); // we need to recreate string, because saveGame clobbered it strcat(savegameName, level); strcat(savegameName, ".gam"); retval = levReleaseAll(); assert(retval == true); fprintf(stdout, "\t\tSaved: %s\n", savegameName); }
bool physfsDrive::FileCreate(DOS_File * * file,const char * name,Bit16u attributes) { char newname[CROSS_LEN]; strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); dirCache.ExpandName(newname); normalize(newname,basedir); /* Test if file exists, don't add to dirCache then */ bool existing_file=PHYSFS_exists(newname); char *slash = strrchr(newname,'/'); if (slash && slash != newname) { *slash = 0; if (!PHYSFS_isDirectory(newname)) return false; PHYSFS_mkdir(newname); *slash = '/'; } PHYSFS_file * hand=PHYSFS_openWrite(newname); if (!hand){ LOG_MSG("Warning: file creation failed: %s (%s)",newname,PHYSFS_getLastError()); return false; } /* Make the 16 bit device information */ *file=new physfsFile(name,hand,0x202,newname,true); (*file)->flags=OPEN_READWRITE; if(!existing_file) { strcpy(newname,basedir); strcat(newname,name); CROSS_FILENAME(newname); dirCache.AddEntry(newname, true); } return true; }
bool FileSystem::mkdir(const std::string& dirname) { return PHYSFS_mkdir(dirname.c_str()); }
static void getPlatformUserDir(char * const tmpstr, size_t const size) { #if defined(WZ_OS_WIN) // When WZ_PORTABLE is passed, that means we want the config directory at the same location as the program file DWORD dwRet; wchar_t tmpWStr[MAX_PATH]; #ifndef WZ_PORTABLE if ( SUCCEEDED( SHGetFolderPathW( NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, tmpWStr ) ) ) { #else if (dwRet = GetCurrentDirectoryW(MAX_PATH, tmpWStr)) { if(dwRet > MAX_PATH) { debug(LOG_FATAL, "Buffer exceeds maximum path to create directory. Exiting."); exit(1); } #endif if (WideCharToMultiByte(CP_UTF8, 0, tmpWStr, -1, tmpstr, size, NULL, NULL) == 0) { debug(LOG_FATAL, "Config directory encoding conversion error."); exit(1); } strlcat(tmpstr, PHYSFS_getDirSeparator(), size); } else #elif defined(WZ_OS_MAC) FSRef fsref; OSErr error = FSFindFolder(kUserDomain, kApplicationSupportFolderType, false, &fsref); if (!error) error = FSRefMakePath(&fsref, (UInt8 *) tmpstr, size); if (!error) strlcat(tmpstr, PHYSFS_getDirSeparator(), size); else #endif if (PHYSFS_getUserDir()) { strlcpy(tmpstr, PHYSFS_getUserDir(), size); // Use PhysFS supplied UserDir (As fallback on Windows / Mac, default on Linux) } // If PhysicsFS fails (might happen if environment variable HOME is unset or wrong) then use the current working directory else if (getCurrentDir(tmpstr, size)) { strlcat(tmpstr, PHYSFS_getDirSeparator(), size); } else { debug(LOG_FATAL, "Can't get UserDir?"); abort(); } } static void initialize_ConfigDir(void) { char tmpstr[PATH_MAX] = { '\0' }; if (strlen(configdir) == 0) { getPlatformUserDir(tmpstr, sizeof(tmpstr)); if (!PHYSFS_setWriteDir(tmpstr)) // Workaround for PhysFS not creating the writedir as expected. { debug(LOG_FATAL, "Error setting write directory to \"%s\": %s", tmpstr, PHYSFS_getLastError()); exit(1); } if (!PHYSFS_mkdir(WZ_WRITEDIR)) // s.a. { debug(LOG_FATAL, "Error creating directory \"%s\": %s", WZ_WRITEDIR, PHYSFS_getLastError()); exit(1); } // Append the Warzone subdir sstrcat(tmpstr, WZ_WRITEDIR); sstrcat(tmpstr, PHYSFS_getDirSeparator()); if (!PHYSFS_setWriteDir(tmpstr)) { debug( LOG_FATAL, "Error setting write directory to \"%s\": %s", tmpstr, PHYSFS_getLastError() ); exit(1); } } else { sstrcpy(tmpstr, configdir); // Make sure that we have a directory separator at the end of the string if (tmpstr[strlen(tmpstr) - 1] != PHYSFS_getDirSeparator()[0]) sstrcat(tmpstr, PHYSFS_getDirSeparator()); debug(LOG_WZ, "Using custom configuration directory: %s", tmpstr); if (!PHYSFS_setWriteDir(tmpstr)) // Workaround for PhysFS not creating the writedir as expected. { debug(LOG_FATAL, "Error setting write directory to \"%s\": %s", tmpstr, PHYSFS_getLastError()); exit(1); } // NOTE: This is currently only used for mingw builds for now. #if defined (WZ_CC_MINGW) if (!OverrideRPTDirectory(tmpstr)) { // since it failed, we just use our default path, and not the user supplied one. debug(LOG_ERROR, "Error setting exception hanlder to use directory %s", tmpstr); } #endif } // User's home dir first so we allways see what we write PHYSFS_addToSearchPath( PHYSFS_getWriteDir(), PHYSFS_PREPEND ); PHYSFS_permitSymbolicLinks(1); debug(LOG_WZ, "Write dir: %s", PHYSFS_getWriteDir()); debug(LOG_WZ, "Base dir: %s", PHYSFS_getBaseDir()); }
int realmain(int argc, char *argv[]) { // The libcrypto startup stuff... May or may not actually be needed for anything at all. ERR_load_crypto_strings(); // This is needed for descriptive error messages. OpenSSL_add_all_algorithms(); // Don't actually use the EVP functions, so probably not needed. OPENSSL_config(nullptr); // What does this actually do? #ifdef WZ_OS_WIN RAND_screen(); // Uses a screenshot as a random seed, on systems lacking /dev/random. #endif wzMain(argc, argv); int utfargc = argc; const char** utfargv = (const char**)argv; #ifdef WZ_OS_MAC cocoaInit(); #endif debug_init(); debug_register_callback( debug_callback_stderr, NULL, NULL, NULL ); #if defined(WZ_OS_WIN) && defined(DEBUG_INSANE) debug_register_callback( debug_callback_win32debug, NULL, NULL, NULL ); #endif // WZ_OS_WIN && DEBUG_INSANE // ***** // NOTE: Try *NOT* to use debug() output routines without some other method of informing the user. All this output is sent to /dev/nul at this point on some platforms! // ***** if (!getUTF8CmdLine(&utfargc, &utfargv)) { return EXIT_FAILURE; } QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); // make Qt treat all C strings in Warzone as UTF-8 setupExceptionHandler(utfargc, utfargv, version_getFormattedVersionString()); /*** Initialize PhysicsFS ***/ initialize_PhysicsFS(utfargv[0]); /*** Initialize translations ***/ initI18n(); // find early boot info if (!ParseCommandLineEarly(utfargc, utfargv)) { return EXIT_FAILURE; } /* Initialize the write/config directory for PhysicsFS. * This needs to be done __after__ the early commandline parsing, * because the user might tell us to use an alternative configuration * directory. */ initialize_ConfigDir(); /*** Initialize directory structure ***/ make_dir(ScreenDumpPath, "screenshots", NULL); make_dir(SaveGamePath, "savegames", NULL); PHYSFS_mkdir("savegames/campaign"); PHYSFS_mkdir("savegames/skirmish"); make_dir(MultiCustomMapsPath, "maps", NULL); // MUST have this to prevent crashes when getting map PHYSFS_mkdir("music"); PHYSFS_mkdir("logs"); // a place to hold our netplay, mingw crash reports & WZ logs PHYSFS_mkdir("userdata"); // a place to store per-mod data user generated data memset(rulesettag, 0, sizeof(rulesettag)); // tag to add to userdata to find user generated stuff make_dir(MultiPlayersPath, "multiplay", NULL); make_dir(MultiPlayersPath, "multiplay", "players"); if (!customDebugfile) { // there was no custom debug file specified (--debug-file=blah) // so we use our write directory to store our logs. time_t aclock; struct tm *newtime; char buf[PATH_MAX]; time( &aclock ); // Get time in seconds newtime = localtime( &aclock ); // Convert time to struct // Note: We are using fopen(), and not physfs routines to open the file // log name is logs/(or \)WZlog-MMDD_HHMMSS.txt snprintf(buf, sizeof(buf), "%slogs%sWZlog-%02d%02d_%02d%02d%02d.txt", PHYSFS_getWriteDir(), PHYSFS_getDirSeparator(), newtime->tm_mon + 1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec ); debug_register_callback( debug_callback_file, debug_callback_file_init, debug_callback_file_exit, buf ); // FIXME: Change this to LOG_WZ on next release debug(LOG_INFO, "Using %s debug file", buf); } // NOTE: it is now safe to use debug() calls to make sure output gets captured. check_Physfs(); debug(LOG_WZ, "Warzone 2100 - %s", version_getFormattedVersionString()); debug(LOG_WZ, "Using language: %s", getLanguage()); debug(LOG_WZ, "Backend: %s", BACKEND); debug(LOG_MEMORY, "sizeof: SIMPLE_OBJECT=%ld, BASE_OBJECT=%ld, DROID=%ld, STRUCTURE=%ld, FEATURE=%ld, PROJECTILE=%ld", (long)sizeof(SIMPLE_OBJECT), (long)sizeof(BASE_OBJECT), (long)sizeof(DROID), (long)sizeof(STRUCTURE), (long)sizeof(FEATURE), (long)sizeof(PROJECTILE)); /* Put in the writedir root */ sstrcpy(KeyMapPath, "keymap.map"); // initialise all the command line states war_SetDefaultStates(); debug(LOG_MAIN, "initializing"); PhysicsEngineHandler engine; // register abstract physfs filesystem loadConfig(); // parse the command line if (!ParseCommandLine(utfargc, utfargv)) { return EXIT_FAILURE; } // Save new (commandline) settings saveConfig(); // Find out where to find the data scanDataDirs(); // Now we check the mods to see if they exist or not (specified on the command line) // They are all capped at 100 mods max(see clparse.c) // FIX ME: I know this is a bit hackish, but better than nothing for now? { char *modname; char modtocheck[256]; int i = 0; int result = 0; // check global mods for(i=0; i < 100; i++) { modname = global_mods[i]; if (modname == NULL) { break; } ssprintf(modtocheck, "mods/global/%s", modname); result = PHYSFS_exists(modtocheck); result |= PHYSFS_isDirectory(modtocheck); if (!result) { debug(LOG_ERROR, "The (global) mod (%s) you have specified doesn't exist!", modname); } else { info("(global) mod (%s) is enabled", modname); } } // check campaign mods for(i=0; i < 100; i++) { modname = campaign_mods[i]; if (modname == NULL) { break; } ssprintf(modtocheck, "mods/campaign/%s", modname); result = PHYSFS_exists(modtocheck); result |= PHYSFS_isDirectory(modtocheck); if (!result) { debug(LOG_ERROR, "The mod_ca (%s) you have specified doesn't exist!", modname); } else { info("mod_ca (%s) is enabled", modname); } } // check multiplay mods for(i=0; i < 100; i++) { modname = multiplay_mods[i]; if (modname == NULL) { break; } ssprintf(modtocheck, "mods/multiplay/%s", modname); result = PHYSFS_exists(modtocheck); result |= PHYSFS_isDirectory(modtocheck); if (!result) { debug(LOG_ERROR, "The mod_mp (%s) you have specified doesn't exist!", modname); } else { info("mod_mp (%s) is enabled", modname); } } } if (!wzMain2(war_getFSAA(), war_getFullscreen(), war_GetVsync())) { return EXIT_FAILURE; } int w = pie_GetVideoBufferWidth(); int h = pie_GetVideoBufferHeight(); char buf[256]; ssprintf(buf, "Video Mode %d x %d (%s)", w, h, war_getFullscreen() ? "fullscreen" : "window"); addDumpInfo(buf); debug(LOG_MAIN, "Final initialization"); if (!frameInitialise()) { return EXIT_FAILURE; } if (!screenInitialise()) { return EXIT_FAILURE; } if (!pie_LoadShaders()) { return EXIT_FAILURE; } war_SetWidth(pie_GetVideoBufferWidth()); war_SetHeight(pie_GetVideoBufferHeight()); pie_SetFogStatus(false); pie_ScreenFlip(CLEAR_BLACK); pal_Init(); pie_LoadBackDrop(SCREEN_RANDOMBDROP); pie_SetFogStatus(false); pie_ScreenFlip(CLEAR_BLACK); if (!systemInitialise()) { return EXIT_FAILURE; } //set all the pause states to false setAllPauseStates(false); // Copy this info to be used by the crash handler for the dump file ssprintf(buf,"Using Backend: %s", BACKEND); addDumpInfo(buf); ssprintf(buf,"Using language: %s", getLanguageName()); addDumpInfo(buf); // Do the game mode specific initialisation. switch(GetGameMode()) { case GS_TITLE_SCREEN: startTitleLoop(); break; case GS_SAVEGAMELOAD: initSaveGameLoad(); break; case GS_NORMAL: startGameLoop(); break; default: debug(LOG_ERROR, "Weirdy game status, I'm afraid!!"); break; } #if defined(WZ_CC_MSVC) && defined(DEBUG) debug_MEMSTATS(); #endif debug(LOG_MAIN, "Entering main loop"); wzMain3(); saveConfig(); systemShutdown(); #ifdef WZ_OS_WIN // clean up the memory allocated for the command line conversion for (int i=0; i<argc; i++) { const char*** const utfargvF = &utfargv; free((void *)(*utfargvF)[i]); } free(utfargv); #endif wzShutdown(); debug(LOG_MAIN, "Completed shutting down Warzone 2100"); return EXIT_SUCCESS; }
//**************************************************************************************** // Challenge menu //***************************************************************************************** bool addChallenges() { char sPath[PATH_MAX]; const char *sSearchPath = "challenges"; UDWORD slotCount; static char sSlotCaps[totalslots][totalslotspace]; static char sSlotTips[totalslots][totalslotspace]; static char sSlotFile[totalslots][totalslotspace]; char **i, **files; (void) PHYSFS_mkdir(sSearchPath); // just in case psRequestScreen = widgCreateScreen(); // init the screen widgSetTipFont(psRequestScreen, font_regular); /* add a form to place the tabbed form on */ W_FORMINIT sFormInit; sFormInit.formID = 0; //this adds the blue background, and the "box" behind the buttons -Q sFormInit.id = CHALLENGE_FORM; sFormInit.style = WFORM_PLAIN; sFormInit.x = (SWORD) CHALLENGE_X; sFormInit.y = (SWORD) CHALLENGE_Y; sFormInit.width = CHALLENGE_W; // we need the form to be long enough for all resolutions, so we take the total number of items * height // and * the gaps, add the banner, and finally, the fudge factor ;) sFormInit.height = (slotsInColumn * CHALLENGE_ENTRY_H + CHALLENGE_HGAP * slotsInColumn) + CHALLENGE_BANNER_DEPTH + 20; sFormInit.disableChildren = true; sFormInit.pDisplay = intOpenPlainForm; widgAddForm(psRequestScreen, &sFormInit); // Add Banner sFormInit.formID = CHALLENGE_FORM; sFormInit.id = CHALLENGE_BANNER; sFormInit.x = CHALLENGE_HGAP; sFormInit.y = CHALLENGE_VGAP; sFormInit.width = CHALLENGE_W - (2 * CHALLENGE_HGAP); sFormInit.height = CHALLENGE_BANNER_DEPTH; sFormInit.disableChildren = false; sFormInit.pDisplay = displayLoadBanner; sFormInit.UserData = 0; widgAddForm(psRequestScreen, &sFormInit); // Add Banner Label W_LABINIT sLabInit; sLabInit.formID = CHALLENGE_BANNER; sLabInit.id = CHALLENGE_LABEL; sLabInit.style = WLAB_ALIGNCENTRE; sLabInit.x = 0; sLabInit.y = 3; sLabInit.width = CHALLENGE_W - (2 * CHALLENGE_HGAP); //CHALLENGE_W; sLabInit.height = CHALLENGE_BANNER_DEPTH; //This looks right -Q sLabInit.pText = "Challenge"; widgAddLabel(psRequestScreen, &sLabInit); // add cancel. W_BUTINIT sButInit; sButInit.formID = CHALLENGE_BANNER; sButInit.x = 8; sButInit.y = 8; sButInit.width = iV_GetImageWidth(IntImages, IMAGE_NRUTER); sButInit.height = iV_GetImageHeight(IntImages, IMAGE_NRUTER); sButInit.UserData = PACKDWORD_TRI(0, IMAGE_NRUTER , IMAGE_NRUTER); sButInit.id = CHALLENGE_CANCEL; sButInit.pTip = _("Close"); sButInit.pDisplay = intDisplayImageHilight; widgAddButton(psRequestScreen, &sButInit); // add slots sButInit = W_BUTINIT(); sButInit.formID = CHALLENGE_FORM; sButInit.width = CHALLENGE_ENTRY_W; sButInit.height = CHALLENGE_ENTRY_H; sButInit.pDisplay = displayLoadSlot; for (slotCount = 0; slotCount < totalslots; slotCount++) { sButInit.id = slotCount + CHALLENGE_ENTRY_START; if (slotCount < slotsInColumn) { sButInit.x = 22 + CHALLENGE_HGAP; sButInit.y = (SWORD)((CHALLENGE_BANNER_DEPTH + (2 * CHALLENGE_VGAP)) + ( slotCount * (CHALLENGE_VGAP + CHALLENGE_ENTRY_H))); } else if (slotCount >= slotsInColumn && (slotCount < (slotsInColumn *2))) { sButInit.x = 22 + (2 * CHALLENGE_HGAP + CHALLENGE_ENTRY_W); sButInit.y = (SWORD)((CHALLENGE_BANNER_DEPTH + (2 * CHALLENGE_VGAP)) + ( (slotCount % slotsInColumn) * (CHALLENGE_VGAP + CHALLENGE_ENTRY_H))); } else { sButInit.x = 22 + (3 * CHALLENGE_HGAP + (2 * CHALLENGE_ENTRY_W)); sButInit.y = (SWORD)((CHALLENGE_BANNER_DEPTH + (2 * CHALLENGE_VGAP)) + ( (slotCount % slotsInColumn) * (CHALLENGE_VGAP + CHALLENGE_ENTRY_H))); } widgAddButton(psRequestScreen, &sButInit); } // fill slots. slotCount = 0; sstrcpy(sPath, sSearchPath); sstrcat(sPath, "/*.ini"); debug(LOG_SAVE, "Searching \"%s\" for challenges", sPath); // add challenges to buttons files = PHYSFS_enumerateFiles(sSearchPath); for (i = files; *i != NULL; ++i) { W_BUTTON *button; char description[totalslotspace]; char highscore[totalslotspace]; const char *name, *difficulty, *map, *givendescription; inifile *inif; // See if this filename contains the extension we're looking for if (!strstr(*i, ".ini")) { // If it doesn't, move on to the next filename continue; } /* First grab any high score associated with this challenge */ inif = inifile_load(CHALLENGE_SCORES); sstrcpy(sPath, *i); sPath[strlen(sPath) - 4] = '\0'; // remove .ini sstrcpy(highscore, "no score"); if (inif) { char key[64]; bool victory; int seconds; ssprintf(key, "%s:Player", sPath); name = inifile_get(inif, key, "NO NAME"); ssprintf(key, "%s:Victory", sPath); victory = inifile_get_as_bool(inif, key, false); ssprintf(key, "%s:Seconds", sPath); seconds = inifile_get_as_int(inif, key, -1); if (seconds > 0) { getAsciiTime(key, seconds * GAME_TICKS_PER_SEC); ssprintf(highscore, "%s by %s (%s)", key, name, victory ? "Victory" : "Survived"); } inifile_delete(inif); } ssprintf(sPath, "%s/%s", sSearchPath, *i); inif = inifile_load(sPath); inifile_set_current_section(inif, "challenge"); if (!inif) { debug(LOG_ERROR, "Could not open \"%s\"", sPath); continue; } name = inifile_get(inif, "Name", "BAD NAME"); map = inifile_get(inif, "Map", "BAD MAP"); difficulty = inifile_get(inif, "difficulty", "BAD DIFFICULTY"); givendescription = inifile_get(inif, "description", ""); ssprintf(description, "%s, %s, %s. %s", map, difficulty, highscore, givendescription); button = (W_BUTTON*)widgGetFromID(psRequestScreen, CHALLENGE_ENTRY_START + slotCount); debug(LOG_SAVE, "We found [%s]", *i); /* Set the button-text */ sstrcpy(sSlotCaps[slotCount], name); // store it! sstrcpy(sSlotTips[slotCount], description); // store it, too! sstrcpy(sSlotFile[slotCount], sPath); // store filename inifile_delete(inif); /* Add button */ button->pTip = sSlotTips[slotCount]; button->pText = sSlotCaps[slotCount]; button->pUserData = (void *)sSlotFile[slotCount]; slotCount++; // go to next button... if (slotCount == totalslots) { break; } } PHYSFS_freeList(files); challengesUp = true; return true; }
bool mkdir(const char *const dirname) { return PHYSFS_mkdir(dirname); }
// Initialise PhysicsFS, set up basic search paths and add arguments from .ini file. // The .ini file can be in either the user directory or the same directory as the program. // The user directory is searched first. void PHYSFSX_init(int argc, char *argv[]) { #if defined(__unix__) const char *path = NULL; #endif #ifdef macintosh // Mac OS 9 char base_dir[PATH_MAX]; int bundle = 0; #else #define base_dir PHYSFS_getBaseDir() #endif PHYSFS_init(argv[0]); atexit(PHYSFSX_deinit); PHYSFS_permitSymbolicLinks(1); #ifdef macintosh strcpy(base_dir, PHYSFS_getBaseDir()); if (strstr(base_dir, ".app:Contents:MacOSClassic")) // the Mac OS 9 program is still in the .app bundle { char *p; bundle = 1; if (base_dir[strlen(base_dir) - 1] == ':') base_dir[strlen(base_dir) - 1] = '\0'; p = strrchr(base_dir, ':'); *p = '\0'; // path to 'Contents' p = strrchr(base_dir, ':'); *p = '\0'; // path to bundle p = strrchr(base_dir, ':'); *p = '\0'; // path to directory containing bundle } #endif #if (defined(__APPLE__) && defined(__MACH__)) // others? chdir(base_dir); // make sure relative hogdir paths work #endif #if defined(__unix__) char fullPath[PATH_MAX + 5]; # if !(defined(__APPLE__) && defined(__MACH__)) path = "~/.d2x-rebirth/"; # else path = "~/Library/Preferences/D2X Rebirth/"; # endif if (path[0] == '~') // yes, this tilde can be put before non-unix paths. { const char *home = PHYSFS_getUserDir(); strcpy(fullPath, home); // prepend home to the path path++; if (*path == *PHYSFS_getDirSeparator()) path++; strncat(fullPath, path, PATH_MAX + 5 - strlen(home)); } else strncpy(fullPath, path, PATH_MAX + 5); PHYSFS_setWriteDir(fullPath); if (!PHYSFS_getWriteDir()) { // need to make it char *p; char ancestor[PATH_MAX + 5]; // the directory which actually exists char child[PATH_MAX + 5]; // the directory relative to the above we're trying to make strcpy(ancestor, fullPath); while (!PHYSFS_getWriteDir() && ((p = strrchr(ancestor, *PHYSFS_getDirSeparator())))) { if (p[1] == 0) { // separator at the end (intended here, for safety) *p = 0; // kill this separator if (!((p = strrchr(ancestor, *PHYSFS_getDirSeparator())))) break; // give up, this is (usually) the root directory } p[1] = 0; // go to parent PHYSFS_setWriteDir(ancestor); } strcpy(child, fullPath + strlen(ancestor)); for (p = child; (p = strchr(p, *PHYSFS_getDirSeparator())); p++) *p = '/'; PHYSFS_mkdir(child); PHYSFS_setWriteDir(fullPath); } PHYSFS_addToSearchPath(PHYSFS_getWriteDir(), 1); #endif PHYSFS_addToSearchPath(base_dir, 1); InitArgs( argc,argv ); PHYSFS_removeFromSearchPath(base_dir); if (!PHYSFS_getWriteDir()) { PHYSFS_setWriteDir(base_dir); if (!PHYSFS_getWriteDir()) Error("can't set write dir: %s\n", PHYSFS_getLastError()); else PHYSFS_addToSearchPath(PHYSFS_getWriteDir(), 0); } //tell PHYSFS where hogdir is if (GameArg.SysHogDir) PHYSFS_addToSearchPath(GameArg.SysHogDir,1); #if defined(__unix__) else if (!GameArg.SysNoHogDir) PHYSFS_addToSearchPath(SHAREPATH, 1); #endif PHYSFSX_addRelToSearchPath("data", 1); // 'Data' subdirectory // For Macintosh, add the 'Resources' directory in the .app bundle to the searchpaths #if defined(__APPLE__) && defined(__MACH__) { ProcessSerialNumber psn = { 0, kCurrentProcess }; FSRef fsref; OSStatus err; err = GetProcessBundleLocation(&psn, &fsref); if (err == noErr) err = FSRefMakePath(&fsref, (ubyte *)fullPath, PATH_MAX); if (err == noErr) { strncat(fullPath, "/Contents/Resources/", PATH_MAX + 4 - strlen(fullPath)); fullPath[PATH_MAX + 4] = '\0'; PHYSFS_addToSearchPath(fullPath, 1); } } #elif defined(macintosh) if (bundle) { base_dir[strlen(base_dir)] = ':'; // go back in the bundle base_dir[strlen(base_dir)] = ':'; // go back in 'Contents' strncat(base_dir, ":Resources:", PATH_MAX - 1 - strlen(base_dir)); base_dir[PATH_MAX - 1] = '\0'; PHYSFS_addToSearchPath(base_dir, 1); } #endif }