int vsFile::DirectoryContents( vsArray<vsString>* result, const vsString &dirName ) // static method { result->Clear(); char **files = PHYSFS_enumerateFiles(dirName.c_str()); char **i; std::vector<char*> s; for (i = files; *i != NULL; i++) s.push_back(*i); std::sort(s.begin(), s.end(), sortFilesByModificationDate(dirName)); for (size_t i = 0; i < s.size(); i++) result->AddItem( s[i] ); PHYSFS_freeList(files); return result->ItemCount(); }
static int cmd_getsearchpath(char *args) { char **rc = PHYSFS_getSearchPath(); if (rc == NULL) printf("Failure. reason: %s.\n", PHYSFS_getLastError()); else { int dir_count; char **i; for (i = rc, dir_count = 0; *i != NULL; i++, dir_count++) printf("%s\n", *i); printf("\n total (%d) directories.\n", dir_count); PHYSFS_freeList(rc); } /* else */ return(1); } /* cmd_getcdromdirs */
static int cmd_getcdromdirs(char *args) { char **rc = PHYSFS_getCdRomDirs(); if (rc == NULL) printf("Failure. Reason: [%s].\n", PHYSFS_getLastError()); else { int dir_count; char **i; for (i = rc, dir_count = 0; *i != NULL; i++, dir_count++) printf("%s\n", *i); printf("\n total (%d) drives.\n", dir_count); PHYSFS_freeList(rc); } /* else */ return(1); } /* cmd_getcdromdirs */
std::vector<std::string> FileSystem::enumerateFiles(const std::string& directory, const std::string& extension, bool keepExtension) { std::vector<std::string> files; char** filenames = PHYSFS_enumerateFiles(directory.c_str()); // now test which files have type extension for (int i = 0; filenames[i] != 0; ++i) { std::string tmp = filenames[i]; int position = tmp.length() - extension.length(); if (position >= 0 && tmp.substr(position) == extension) { files.push_back(std::string(tmp.begin(), keepExtension ? (tmp.end()) : (tmp.end() - extension.length()) )); } } // free the file list PHYSFS_freeList(filenames); return files; }
// Mount the archive under the mountpoint, and enumerate the archive according to lookin static bool CheckInMap(const char *archive, const char *mountpoint,const char *lookin) { bool mapmod = false; if (!PHYSFS_mount(archive, mountpoint, PHYSFS_APPEND)) { // We already checked to see if this was valid before, and now, something went seriously wrong. debug(LOG_FATAL, "Could not mount %s, because: %s. Please delete the file, and run the game again. Game will now exit.", archive, PHYSFS_getLastError()); exit(-1); } std::string checkpath = lookin; checkpath.append("/"); char **filelist = PHYSFS_enumerateFiles(lookin); for (char **file = filelist; *file != NULL; ++file) { std::string checkfile = *file; if (PHYSFS_isDirectory((checkpath+checkfile).c_str())) { if (checkfile.compare("wrf")==0 || checkfile.compare("stats")==0 ||checkfile.compare("components")==0 || checkfile.compare("anims")==0 || checkfile.compare("effects")==0 ||checkfile.compare("messages")==0 || checkfile.compare("audio")==0 || checkfile.compare("sequenceaudio")==0 ||checkfile.compare("misc")==0 || checkfile.compare("features")==0 || checkfile.compare("script")==0 ||checkfile.compare("structs")==0 || checkfile.compare("tileset")==0 || checkfile.compare("images")==0 || checkfile.compare("texpages")==0 || checkfile.compare("skirmish")==0 ) { debug(LOG_WZ, "Detected: %s %s" , archive, checkfile.c_str()); mapmod = true; break; } } } PHYSFS_freeList(filelist); if (!PHYSFS_removeFromSearchPath(archive)) { debug(LOG_ERROR, "Could not unmount %s, %s", archive, PHYSFS_getLastError()); } return mapmod; }
void init_libs() { char **lib_physfs_list; char **i; lib_details *d, *tmp; printf("lib_tools.c:init_libs() - Locate libraries:\n"); lib_physfs_list = PHYSFS_enumerateFiles("libs"); for(i=lib_physfs_list; *i != NULL; i++) { printf("%s\n",*i); #ifdef __APPLE__ if(strlen(*i) > 6 && !strcmp(*i + strlen(*i) - 6, ".dylib")) { #elif __MINGW32__ if(strlen(*i) > 4 && !strcmp(*i + strlen(*i) - 4, ".dll")) { #else if(strlen(*i) > 3 && !strcmp(*i + strlen(*i) - 3, ".so")) { #endif // I know this isn't portable, but f**k it d = malloc(sizeof(lib_details)); strncpy(d->filename,*i,MAX_LIBFN_LEN); d->loaded = 0; LL_APPEND(libs_list,d); printf("lib_tools.c:init_libs() - Located %s\n", *i); } } PHYSFS_freeList(lib_physfs_list); printf("lib_tools.c:init_libs() - Start cache system:\n"); init_lib_cache(); printf("lib_tools.c:init_libs() - Refreshing cache:\n"); LL_FOREACH_SAFE(libs_list,d,tmp) { refresh_lib_cache(d->filename); } printf("lib_tools.c:init_libs() - Loading libs:\n"); LL_FOREACH_SAFE(libs_list,d,tmp) { printf("lib_tools.c:init_libs() - Loading %s:\n",d->filename); load_lib(d->filename); } }
/*************************************************************************** Delete a savegame. saveGameName should be a .gam extension save game filename reference. We delete this file, any .es file with the same name, and any files in the directory with the same name. ***************************************************************************/ void deleteSaveGame(char* saveGameName) { char **files, **i; ASSERT( strlen(saveGameName) < MAX_STR_LENGTH,"deleteSaveGame; save game name too long" ); PHYSFS_delete(saveGameName); saveGameName[strlen(saveGameName)-4] = '\0';// strip extension strcat(saveGameName,".es"); // remove script data if it exists. PHYSFS_delete(saveGameName); saveGameName[strlen(saveGameName)-3] = '\0';// strip extension // check for a directory and remove that too. files = PHYSFS_enumerateFiles(saveGameName); for (i = files; *i != NULL; ++i) { char del_file[PATH_MAX]; // Construct the full path to the file by appending the // filename to the directory it is in. snprintf(del_file, sizeof(del_file), "%s/%s", saveGameName, *i); debug(LOG_SAVE, "Deleting [%s].", del_file); // Delete the file if (!PHYSFS_delete(del_file)) { debug(LOG_ERROR, "Warning [%s] could not be deleted due to PhysicsFS error: %s", del_file, PHYSFS_getLastError()); } } PHYSFS_freeList(files); if (!PHYSFS_delete(saveGameName)) // now (should be)empty directory { debug(LOG_ERROR, "Warning directory[%s] could not be deleted because %s", saveGameName,PHYSFS_getLastError()); } return; }
static void add_missions_to_list(mle *mission_list, char *path, char *rel_path, int anarchy_mode) { char **find, **i, *ext; find = PHYSFS_enumerateFiles(path); for (i = find; *i != NULL; i++) { if (strlen(path) + strlen(*i) + 1 >= PATH_MAX) continue; // path is too long strcat(rel_path, *i); if (PHYSFS_isDirectory(path)) { strcat(rel_path, "/"); add_missions_to_list(mission_list, path, rel_path, anarchy_mode); *(strrchr(path, '/')) = 0; } else if ((ext = strrchr(*i, '.')) && (!strnicmp(ext, ".msn", 4) || !strnicmp(ext, ".mn2", 4))) if (read_mission_file(&mission_list[num_missions], rel_path, ML_MISSIONDIR)) { if (anarchy_mode || !mission_list[num_missions].anarchy_only_flag) { mission_list[num_missions].builtin_hogsize = 0; num_missions++; } else d_free(mission_list[num_missions].path); } if (num_missions >= MAX_MISSIONS) { break; } (strrchr(path, '/'))[1] = 0; // chop off the entry } PHYSFS_freeList(find); }
std::vector<std::string> CResourceManager::ListDirectories(const std::string &directory) { std::vector<std::string> result; if (PHYSFS_isInit()) { char **files = PHYSFS_enumerateFiles(CleanPath(directory).c_str()); for (char **i = files; *i != nullptr; i++) { std::string path = CleanPath(directory) + "/" + (*i); if (PHYSFS_isDirectory(path.c_str())) { result.push_back(*i); } } PHYSFS_freeList(files); } return result; }
std::vector<std::string> geDirList(const std::string_view path, const std::string_view rootPath) { std::vector<std::string> vecDirs; auto dirs = PHYSFS_enumerateFiles(path.data()); if (dirs != nullptr) { PHYSFS_Stat fileStat; for (char** dir = dirs; *dir != nullptr; dir++) { if (PHYSFS_stat(*dir, &fileStat) == 0) { continue; } if (fileStat.filetype != PHYSFS_FILETYPE_DIRECTORY) { continue; } if (**dir == '.') { continue; } if (rootPath.empty() == false) { auto realDir = PHYSFS_getRealDir(*dir); if (realDir != nullptr) { if (rootPath != realDir) { continue; } } } vecDirs.push_back(*dir); } PHYSFS_freeList(dirs); } return vecDirs; }
vector<OSFileEntry> OSBasics::parsePhysFSFolder(String pathString, bool showHidden) { vector<OSFileEntry> returnVector; char **rc = PHYSFS_enumerateFiles(pathString.c_str()); char **i; String fullPath; String fname; for (i = rc; *i != NULL; i++) { fname = string(*i); fullPath = pathString + "/" + fname; if((fname.c_str()[0] != '.' || (fname.c_str()[0] == '.' && showHidden)) && fname != "..") { if(PHYSFS_isDirectory(fullPath.c_str())) { returnVector.push_back(OSFileEntry(pathString, fname, OSFileEntry::TYPE_FOLDER)); } else { returnVector.push_back(OSFileEntry(pathString, fname, OSFileEntry::TYPE_FILE)); } } } PHYSFS_freeList(rc); return returnVector; }
/// Display a random backdrop from files in dirname starting with basename. /// dirname must have a trailing slash. void screen_SetRandomBackdrop(const char *dirname, const char *basename) { std::vector<std::string> names; // vector to hold the strings we want char **rc = PHYSFS_enumerateFiles(dirname); // all the files in dirname // Walk thru the files in our dir, adding the ones that start with basename to our vector of strings size_t len = strlen(basename); for (char **i = rc; *i != NULL; i++) { // does our filename start with basename? if (!strncmp(*i, basename, len)) { names.push_back(*i); } } PHYSFS_freeList(rc); // pick a random name from our vector of names int ran = rand() % names.size(); std::string full_path = std::string(dirname) + names[ran]; screen_SetBackDropFromFile(full_path.c_str()); }
/**Enumerates all files available in a path. * \param path String pointing to the path * \return Nonzero on success (not necessarily true?) */ list<string> Filesystem::Enumerate( const string& path, const string &suffix ) { list<string> files; char **rc = NULL; string fname; rc = PHYSFS_enumerateFiles(path.c_str()); if (rc == NULL) { LogMsg(ERR,"Failure to enumerate %s. reason: %s.\n", path.c_str(),PHYSFS_getLastError()); } else { int file_count; char **i; for (i = rc, file_count = 0; *i != NULL; i++, file_count++) { fname = string(*i); // Skip Makefiles if( fname == "Makefile.am") continue; // Skip hidden files if( fname[0] == '.' ) continue; // Check if the suffix matches if(fname.size() > suffix.size()) { if( std::equal(fname.begin() + fname.size() - suffix.size(), fname.end(), suffix.begin()) ) { files.push_back( fname ); } } } LogMsg(INFO,"\n total (%d) files.\n", file_count); PHYSFS_freeList(rc); //return 1; } return files; }
std::vector<std::string> getFileList(const std::string_view filePath, const std::string_view fileExt, bool getFullPath) { std::vector<std::string> vec; auto files = PHYSFS_enumerateFiles(filePath.data()); if (files != nullptr) { PHYSFS_Stat fileStat; for (char** file = files; *file != nullptr; file++) { auto file2 = std::string(filePath) + '/' + std::string(*file); if (Utils::endsWith(file2, fileExt) == false) { continue; } if (PHYSFS_stat(file2.c_str(), &fileStat) == 0) { continue; } if (fileStat.filetype == PHYSFS_FILETYPE_REGULAR) { if (getFullPath == true) { vec.push_back(file2); } else { vec.push_back(std::string(*file)); } } } PHYSFS_freeList(files); } return vec; }
void Sound::loadWaves() { //Load Waves std::string filename; std::string directory = "sounds/"; std::string fullname; Mix_Chunk *chunk; SDL_RWops* file; char **rc = PHYSFS_enumerateFiles( directory.c_str() ); char **i; for (i = rc; *i != NULL; i++) { fullname = directory; fullname.append( *i ); filename.assign( *i ); if(PHYSFS_isDirectory(fullname.c_str())) continue; try { file = getPhysfsSDLRWops( fullname.c_str() ); chunk = Mix_LoadWAV_RW( file, 1); if(!chunk) { std::stringstream msg; msg << "Couldn't read soundfile '" << fullname << "': " << SDL_GetError(); throw std::runtime_error(msg.str()); } std::string idName = getIdName( filename ); waves.insert( std::pair<std::string,Mix_Chunk*>(idName, chunk) ); } catch(std::exception& e) { std::cerr << "Error: " << e.what() << "\n"; } } PHYSFS_freeList(rc); }
bool Lux::Core::FileHandler::ResourcePathExists(const String a_Path) { char** path = PHYSFS_getSearchPath(); if (path == nullptr) { String errstr("Error fetching the search path. "); errstr.append(PHYSFS_getLastError()); Utility::ThrowError(errstr); } // Search for the string inside the current search path bool retval = false; for (char** i = path; i != nullptr; i++) { if (a_Path.compare(*i) == 0) { retval = true; break; } } PHYSFS_freeList(path); // Free the list return retval; }
bool buildMapList() { if (!loadLevFile("gamedesc.lev", mod_campaign, false, NULL)) { return false; } loadLevFile("addon.lev", mod_multiplay, false, NULL); MapFileList realFileNames = listMapFiles(); for (MapFileList::iterator realFileName = realFileNames.begin(); realFileName != realFileNames.end(); ++realFileName) { std::string realFilePathAndName = PHYSFS_getRealDir(realFileName->c_str()) + *realFileName; PHYSFS_addToSearchPath(realFilePathAndName.c_str(), PHYSFS_APPEND); char **filelist = PHYSFS_enumerateFiles(""); for (char **file = filelist; *file != NULL; ++file) { size_t len = strlen(*file); if (len > 10 && !strcasecmp(*file + (len - 10), ".addon.lev")) // Do not add addon.lev again { loadLevFile(*file, mod_multiplay, true, realFileName->c_str()); } // add support for X player maps using a new name to prevent conflicts. if (len > 13 && !strcasecmp(*file + (len - 13), ".xplayers.lev")) { loadLevFile(*file, mod_multiplay, true, realFileName->c_str()); } } PHYSFS_freeList(filelist); PHYSFS_removeFromSearchPath(realFilePathAndName.c_str()); } return true; }
int ui_get_filename( char * filename, const char * filespec, const char * message ) { char InputText[PATH_MAX]; char *p; int i; file_browser *b; UI_DIALOG *dlg; window *wind; int rval = 0; MALLOC(b, file_browser, 1); if (!b) return 0; if ((p = strrchr(filename, '/'))) { *p++ = 0; strcpy(b->view_dir, filename); strcpy(InputText, p); } else { strcpy(b->view_dir, ""); strcpy(InputText, filename); } b->filename_list = file_getfilelist(&b->num_files, filespec, b->view_dir); if (!b->filename_list) { d_free(b); return 0; } b->directory_list = file_getdirlist(&b->num_dirs, b->view_dir); if (!b->directory_list) { PHYSFS_freeList(b->filename_list); d_free(b); return 0; } //ui_messagebox( -2,-2, 1,"DEBUG:0", "Ok" ); for (i=0; i<35; i++) b->spaces[i] = ' '; b->spaces[34] = 0; dlg = ui_create_dialog( 200, 100, 400, 370, static_cast<dialog_flags>(DF_DIALOG | DF_MODAL), (int (*)(UI_DIALOG *, d_event *, void *))browser_handler, b ); b->user_file = ui_add_gadget_inputbox( dlg, 60, 30, PATH_MAX, 40, InputText ); b->listbox1 = ui_add_gadget_listbox(dlg, 20, 110, 125, 200, b->num_files, b->filename_list); b->listbox2 = ui_add_gadget_listbox(dlg, 210, 110, 100, 200, b->num_dirs, b->directory_list); b->button1 = ui_add_gadget_button( dlg, 20, 330, 60, 25, "Ok", NULL ); b->button2 = ui_add_gadget_button( dlg, 100, 330, 60, 25, "Cancel", NULL ); b->help_button = ui_add_gadget_button( dlg, 180, 330, 60, 25, "Help", NULL ); dlg->keyboard_focus_gadget = (UI_GADGET *)b->user_file; b->button1->hotkey = KEY_CTRLED + KEY_ENTER; b->button2->hotkey = KEY_ESC; b->help_button->hotkey = KEY_F1; b->listbox1->hotkey = KEY_ALTED + KEY_F; b->listbox2->hotkey = KEY_ALTED + KEY_D; b->user_file->hotkey = KEY_ALTED + KEY_A; ui_gadget_calc_keys(dlg); b->filename = filename; b->filespec = filespec; b->message = message; wind = ui_dialog_get_window(dlg); while (window_exists(wind)) event_process(); //key_flush(); if (b->filename_list) PHYSFS_freeList(b->filename_list); if (b->directory_list) PHYSFS_freeList(b->directory_list); rval = b->filename_list != NULL; d_free(b); return rval; }
/** Searches in the given search directory for files ending with the * given extension. Then will create a window with buttons for each * found file. * \param searchDir the directory to search in * \param fileExtension the extension files should end with, if the * extension has a dot (.) then this dot _must_ be present as * the first char in this parameter * \param mode (purpose unknown) * \param numPlayers (purpose unknown) */ void addMultiRequest(const char* searchDir, const char* fileExtension, UDWORD mode, UBYTE mapCam, UBYTE numPlayers) { W_FORMINIT sFormInit; W_BUTINIT sButInit; UDWORD players; char** fileList; char** currFile; const unsigned int extensionLength = strlen(fileExtension); const unsigned int buttonsX = (mode == MULTIOP_MAP) ? 22 : 17; unsigned int numButtons, count, butPerForm, i; static char tips[NBTIPS][MAX_STR_LENGTH]; context = mode; if(mode == MULTIOP_MAP) { // only save these when they select MAP button current_tech = mapCam; current_numplayers = numPlayers; } fileList = PHYSFS_enumerateFiles(searchDir); if (!fileList) { debug(LOG_FATAL, "addMultiRequest: Out of memory"); abort(); return; } // Count number of required buttons numButtons = 0; for (currFile = fileList; *currFile != NULL; ++currFile) { const unsigned int fileNameLength = strlen(*currFile); // Check to see if this file matches the given extension if (fileNameLength > extensionLength && strcmp(&(*currFile)[fileNameLength - extensionLength], fileExtension) == 0) ++numButtons; } if(mode == MULTIOP_MAP) // if its a map, also look in the predone stuff. { char* map; if ((map = enumerateMultiMaps(&players, true, mapCam, numPlayers))) { free(map); numButtons++; while ((map = enumerateMultiMaps(&players, false, mapCam, numPlayers))) { free(map); numButtons++; } } } psRScreen = widgCreateScreen(); ///< move this to intinit or somewhere like that.. (close too.) widgSetTipFont(psRScreen,font_regular); /* Calculate how many buttons will go on a single form */ butPerForm = ((M_REQUEST_W - 0 - 4) / (R_BUT_W +4)) * ((M_REQUEST_H - 0- 4) / (R_BUT_H+ 4)); /* add a form to place the tabbed form on */ memset(&sFormInit, 0, sizeof(W_FORMINIT)); sFormInit.formID = 0; sFormInit.id = M_REQUEST; sFormInit.style = WFORM_PLAIN; sFormInit.x = (SWORD)(M_REQUEST_X+D_W); sFormInit.y = (SWORD)(M_REQUEST_Y+D_H); sFormInit.width = M_REQUEST_W; sFormInit.height = M_REQUEST_H; sFormInit.disableChildren = true; sFormInit.pDisplay = intOpenPlainForm; widgAddForm(psRScreen, &sFormInit); /* Add the tabs */ memset(&sFormInit, 0, sizeof(W_FORMINIT)); sFormInit.formID = M_REQUEST; sFormInit.id = M_REQUEST_TAB; sFormInit.style = WFORM_TABBED; sFormInit.x = 2; sFormInit.y = 2; sFormInit.width = M_REQUEST_W; sFormInit.height = M_REQUEST_H-4; sFormInit.numMajor = numForms(numButtons, butPerForm); sFormInit.majorPos = WFORM_TABTOP; sFormInit.minorPos = WFORM_TABNONE; sFormInit.majorSize = OBJ_TABWIDTH+2; sFormInit.majorOffset = OBJ_TABOFFSET; sFormInit.tabVertOffset = (OBJ_TABHEIGHT/2); sFormInit.tabMajorThickness = OBJ_TABHEIGHT; sFormInit.pUserData = &StandardTab; sFormInit.pTabDisplay = intDisplayTab; // TABFIXME: // This appears to be the map pick screen, when we have lots of maps // this will need to change. if (sFormInit.numMajor > MAX_TAB_STD_SHOWN) { ASSERT(sFormInit.numMajor < MAX_TAB_SMALL_SHOWN,"Too many maps! Need scroll tabs here."); sFormInit.pUserData = &SmallTab; sFormInit.majorSize /= 2; } for (i = 0; i < sFormInit.numMajor; ++i) { sFormInit.aNumMinors[i] = 2; } widgAddForm(psRScreen, &sFormInit); // Add the close button. memset(&sButInit, 0, sizeof(W_BUTINIT)); sButInit.formID = M_REQUEST; sButInit.id = M_REQUEST_CLOSE; sButInit.style = WBUT_PLAIN; sButInit.x = M_REQUEST_W - CLOSE_WIDTH - 3; sButInit.y = 0; sButInit.width = CLOSE_WIDTH; sButInit.height = CLOSE_HEIGHT; sButInit.pTip = _("Close"); sButInit.FontID = font_regular; sButInit.pDisplay = intDisplayImageHilight; sButInit.UserData = PACKDWORD_TRI(0,IMAGE_CLOSEHILIGHT , IMAGE_CLOSE); widgAddButton(psRScreen, &sButInit); /* Put the buttons on it *//* Set up the button struct */ memset(&sButInit, 0, sizeof(W_BUTINIT)); sButInit.formID = M_REQUEST_TAB; sButInit.id = M_REQUEST_BUT; sButInit.style = WBUT_PLAIN; sButInit.x = buttonsX; sButInit.y = 4; sButInit.width = R_BUT_W; sButInit.height = R_BUT_H; sButInit.pUserData = NULL; sButInit.pDisplay = displayRequestOption; sButInit.FontID = font_regular; for (currFile = fileList, count = 0; *currFile != NULL && count < (butPerForm * 4); ++currFile) { const unsigned int tip_index = check_tip_index(sButInit.id - M_REQUEST_BUT); const unsigned int fileNameLength = strlen(*currFile); const unsigned int tipStringLength = fileNameLength - extensionLength; // Check to see if this file matches the given extension if (!(fileNameLength > extensionLength) || strcmp(&(*currFile)[fileNameLength - extensionLength], fileExtension) != 0) continue; // Set the tip and add the button // Copy all of the filename except for the extension into the tiptext string strlcpy(tips[tip_index], *currFile, MIN(tipStringLength + 1, sizeof(tips[tip_index]))); sButInit.pTip = tips[tip_index]; sButInit.pText = tips[tip_index]; if(mode == MULTIOP_MAP) // if its a map, set player flag. { const char* mapText; unsigned int mapTextLength; sButInit.UserData = (*currFile)[0] - '0'; if( (*currFile)[1] != 'c') { continue; } // Chop off description mapText = strrchr(*currFile, '-') + 1; if (mapText - 1 == NULL) continue; mapTextLength = tipStringLength - (mapText - *currFile); strlcpy(tips[tip_index], mapText, MIN(mapTextLength + 1, sizeof(tips[tip_index]))); } ++count; widgAddButton(psRScreen, &sButInit); /* Update the init struct for the next button */ sButInit.id += 1; sButInit.x = (SWORD)(sButInit.x + (R_BUT_W+ 4)); if (sButInit.x + R_BUT_W+ 2 > M_REQUEST_W) { sButInit.x = buttonsX; sButInit.y = (SWORD)(sButInit.y +R_BUT_H + 4); } if (sButInit.y +R_BUT_H + 4 > M_REQUEST_H) { sButInit.y = 4; sButInit.majorID += 1; } } // Make sure to return memory back to PhyscisFS PHYSFS_freeList(fileList); if(mode == MULTIOP_MAP) { char* mapName; if ((mapName = enumerateMultiMaps(&players, true, mapCam, numPlayers))) { do { unsigned int tip_index = check_tip_index(sButInit.id-M_REQUEST_BUT); // add number of players to string. sstrcpy(tips[tip_index], mapName); free(mapName); sButInit.pTip = tips[tip_index]; sButInit.pText = tips[tip_index]; sButInit.UserData = players; widgAddButton(psRScreen, &sButInit); sButInit.id += 1; sButInit.x = (SWORD)(sButInit.x + (R_BUT_W+ 4)); if (sButInit.x + R_BUT_W+ 2 > M_REQUEST_W) { sButInit.x = buttonsX; sButInit.y = (SWORD)(sButInit.y +R_BUT_H + 4); } if (sButInit.y +R_BUT_H + 4 > M_REQUEST_H) { sButInit.y = 4; sButInit.majorID += 1; } } while ((mapName = enumerateMultiMaps(&players, false, mapCam, numPlayers))); } } multiRequestUp = true; // if it's map select then add the cam style buttons. if(mode == MULTIOP_MAP) { memset(&sButInit, 0, sizeof(W_BUTINIT)); sButInit.formID = M_REQUEST; sButInit.id = M_REQUEST_C1; sButInit.style = WBUT_PLAIN; sButInit.x = 4; sButInit.y = 258; sButInit.width = 17; sButInit.height = 17; sButInit.UserData = 1; sButInit.FontID = font_regular; sButInit.pTip = _("Technology level 1"); sButInit.pDisplay = displayCamTypeBut; widgAddButton(psRScreen, &sButInit); sButInit.id = M_REQUEST_C2; sButInit.y += 22; sButInit.UserData = 2; sButInit.pTip = _("Technology level 2"); widgAddButton(psRScreen, &sButInit); sButInit.id = M_REQUEST_C3; sButInit.y += 22; sButInit.UserData = 3; sButInit.pTip = _("Technology level 3"); widgAddButton(psRScreen, &sButInit); sButInit.id = M_REQUEST_AP; sButInit.y = 17; sButInit.UserData = 0; sButInit.pTip = _("Any number of players"); sButInit.pDisplay = displayNumPlayersBut; widgAddButton(psRScreen, &sButInit); sButInit.id = M_REQUEST_2P; sButInit.y += 22; sButInit.UserData = 2; sButInit.pTip = _("2 players"); widgAddButton(psRScreen, &sButInit); sButInit.id = M_REQUEST_3P; sButInit.y += 22; sButInit.UserData = 3; sButInit.pTip = _("3 players"); widgAddButton(psRScreen, &sButInit); sButInit.id = M_REQUEST_4P; sButInit.y += 22; sButInit.UserData = 4; sButInit.pTip = _("4 players"); widgAddButton(psRScreen, &sButInit); sButInit.id = M_REQUEST_5P; sButInit.y += 22; sButInit.UserData = 5; sButInit.pTip = _("5 players"); widgAddButton(psRScreen, &sButInit); sButInit.id = M_REQUEST_6P; sButInit.y += 22; sButInit.UserData = 6; sButInit.pTip = _("6 players"); widgAddButton(psRScreen, &sButInit); sButInit.id = M_REQUEST_7P; sButInit.y += 22; sButInit.UserData = 7; sButInit.pTip = _("7 players"); widgAddButton(psRScreen, &sButInit); sButInit.id = M_REQUEST_8P; sButInit.y += 22; sButInit.UserData = 8; sButInit.pTip = _("8 players"); widgAddButton(psRScreen, &sButInit); } }
void freeList(void *listVar) { PHYSFS_freeList(listVar); }
//**************************************************************************************** // 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; }
void freeList(char** list) { PHYSFS_freeList(list); }
void initPhysfs(const char* argv0) { if(!PHYSFS_init(argv0)) { std::stringstream msg; msg << "Couldn't initialize physfs: " << PHYSFS_getLastError(); throw std::runtime_error(msg.str()); } // Initialize physfs (this is a slightly modified version of // PHYSFS_setSaneConfig const char* application = /* PACKAGE_NAME */ "lincity"; const char* userdir = PHYSFS_getUserDir(); const char* dirsep = PHYSFS_getDirSeparator(); char* writedir = new char[strlen(userdir) + strlen(application) + 2]; // Set configuration directory sprintf(writedir, "%s.%s", userdir, application); if(!PHYSFS_setWriteDir(writedir)) { // try to create the directory char* mkdir = new char[strlen(application) + 2]; sprintf(mkdir, ".%s", application); if(!PHYSFS_setWriteDir(userdir) || !PHYSFS_mkdir(mkdir)) { std::ostringstream msg; msg << "Failed creating configuration directory '" << writedir << "': " << PHYSFS_getLastError(); delete[] writedir; delete[] mkdir; throw std::runtime_error(msg.str()); } delete[] mkdir; if(!PHYSFS_setWriteDir(writedir)) { std::ostringstream msg; msg << "Failed to use configuration directory '" << writedir << "': " << PHYSFS_getLastError(); delete[] writedir; throw std::runtime_error(msg.str()); } } PHYSFS_addToSearchPath(writedir, 0); delete[] writedir; // Search for archives and add them to the search path const char* archiveExt = "zip"; char** rc = PHYSFS_enumerateFiles("/"); size_t extlen = strlen(archiveExt); for(char** i = rc; *i != 0; ++i) { size_t l = strlen(*i); if((l > extlen) && ((*i)[l - extlen - 1] == '.')) { const char* ext = (*i) + (l - extlen); if(strcasecmp(ext, archiveExt) == 0) { const char* d = PHYSFS_getRealDir(*i); char* str = new char[strlen(d) + strlen(dirsep) + l + 1]; sprintf(str, "%s%s%s", d, dirsep, *i); PHYSFS_addToSearchPath(str, 1); delete[] str; } } } PHYSFS_freeList(rc); // when started from source dir... std::string dir = PHYSFS_getBaseDir(); dir += "/data"; std::string testfname = dir; testfname += "/images/tiles/images.xml"; FILE* f = fopen(testfname.c_str(), "r"); if(f) { fclose(f); if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) { #ifdef DEBUG std::cout << "Warning: Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << "\n"; #endif } } #if defined(APPDATADIR) || defined(ENABLE_BINRELOC) std::string datadir; #ifdef ENABLE_BINRELOC BrInitError error; if (br_init (&error) == 0 && error != BR_INIT_ERROR_DISABLED) { printf ("Warning: BinReloc failed to initialize (error code %d)\n", error); printf ("Will fallback to hardcoded default path.\n"); } char* brdatadir = br_find_data_dir("/usr/local/share"); datadir = brdatadir; datadir += "/" PACKAGE_NAME; free(brdatadir); #else datadir = APPDATADIR; #endif if(!PHYSFS_addToSearchPath(datadir.c_str(), 1)) { std::cout << "Couldn't add '" << datadir << "' to physfs searchpath: " << PHYSFS_getLastError() << "\n"; } #endif // allow symbolic links PHYSFS_permitSymbolicLinks(1); //show search Path for(char** i = PHYSFS_getSearchPath(); *i != NULL; i++) printf("[%s] is in the search path.\n", *i); // ugly: set LINCITY_HOME environment variable const char* lincityhome = PHYSFS_getRealDir("colour.pal"); if(lincityhome == 0) { throw std::runtime_error("Couldn't locate lincity data (colour.pal)."); } std::cout << "LINCITY_HOME: " << lincityhome << "\n"; char tmp[256]; snprintf(tmp, sizeof(tmp), "LINCITY_HOME=%s", lincityhome); putenv(tmp); }
void initialize(const char* argv0, const char* , const char* application) { if(!PHYSFS_init(argv0)) throw Exception("failure while initialising physfs: %s", PHYSFS_getLastError()); const char* basedir = PHYSFS_getBaseDir(); const char* userdir = PHYSFS_getUserDir(); const char* dirsep = PHYSFS_getDirSeparator(); char* writedir = new char[strlen(userdir) + strlen(application) + 2]; sprintf(writedir, "%s.%s", userdir, application); if(!PHYSFS_setWriteDir(writedir)) { // try to create the directory... char* mkdir = new char[strlen(application)+2]; sprintf(mkdir, ".%s", application); if(!PHYSFS_setWriteDir(userdir) || ! PHYSFS_mkdir(mkdir)) { delete[] writedir; delete[] mkdir; throw Exception("failed creating configuration directory: '%s': %s", writedir, PHYSFS_getLastError()); } delete[] mkdir; if (!PHYSFS_setWriteDir(writedir)) { throw Exception("couldn't set configuration directory to '%s': %s", writedir, PHYSFS_getLastError()); } } PHYSFS_addToSearchPath(writedir, 0); PHYSFS_addToSearchPath(basedir, 1); delete[] writedir; /* Root out archives, and add them to search path... */ char* archiveExt = "zip"; if (archiveExt != NULL) { char **rc = PHYSFS_enumerateFiles("/"); char **i; size_t extlen = strlen(archiveExt); char *ext; for (i = rc; *i != NULL; i++) { size_t l = strlen(*i); if ((l > extlen) && ((*i)[l - extlen - 1] == '.')) { ext = (*i) + (l - extlen); if (strcasecmp(ext, archiveExt) == 0) { const char *d = PHYSFS_getRealDir(*i); char* str = new char[strlen(d) + strlen(dirsep) + l + 1]; sprintf(str, "%s%s%s", d, dirsep, *i); PHYSFS_addToSearchPath(str, 1); delete[] str; } /* if */ } /* if */ } /* for */ PHYSFS_freeList(rc); } /* if */ }
void physfsDrive::closedir(void *handle) { struct opendirinfo *oinfo = (struct opendirinfo *)handle; if (handle == NULL) return; if (oinfo->files != NULL) PHYSFS_freeList(oinfo->files); free(oinfo); }
// //////////////////////////////////////////////////////////////////////////// bool addLoadSave(LOADSAVE_MODE savemode, const char *title) { bool bLoad = true; char NewSaveGamePath[PATH_MAX] = {'\0'}; bLoadSaveMode = savemode; UDWORD slotCount; static char sSlotCaps[totalslots][totalslotspace]; static char sSlotTips[totalslots][totalslotspace]; char **i, **files; switch(savemode) { case LOAD_FRONTEND_MISSION: case LOAD_INGAME_MISSION: case LOAD_MISSIONEND: ssprintf(NewSaveGamePath, "%s%s/", SaveGamePath, "campaign"); break; case LOAD_FRONTEND_SKIRMISH: case LOAD_INGAME_SKIRMISH: ssprintf(NewSaveGamePath, "%s%s/", SaveGamePath, "skirmish"); break; case SAVE_MISSIONEND: case SAVE_INGAME_MISSION: ssprintf(NewSaveGamePath, "%s%s/", SaveGamePath, "campaign"); bLoad = false; break; case SAVE_INGAME_SKIRMISH: ssprintf(NewSaveGamePath, "%s%s/", SaveGamePath, "skirmish"); bLoad = false; break; default: ASSERT("Invalid load/save mode!", "Invalid load/save mode!"); ssprintf(NewSaveGamePath, "%s%s/", SaveGamePath, "campaign"); break; } mode = bLoad; debug(LOG_SAVE, "called (%d, %s)", bLoad, title); if ((bLoadSaveMode == LOAD_INGAME_MISSION) || (bLoadSaveMode == SAVE_INGAME_MISSION) || (bLoadSaveMode == LOAD_INGAME_SKIRMISH) || (bLoadSaveMode == SAVE_INGAME_SKIRMISH)) { if (!bMultiPlayer || (NetPlay.bComms ==0)) { gameTimeStop(); if(GetGameMode() == GS_NORMAL) { bool radOnScreen = radarOnScreen; // Only do this in main game. bRender3DOnly = true; radarOnScreen = false; displayWorld(); // Just display the 3d, no interface radarOnScreen = radOnScreen; bRender3DOnly = false; } setGamePauseStatus( true ); setGameUpdatePause(true); setScriptPause(true); setScrollPause(true); setConsolePause(true); } forceHidePowerBar(); intRemoveReticule(); } psRequestScreen = new W_SCREEN; WIDGET *parent = psRequestScreen->psForm; /* add a form to place the tabbed form on */ // 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 ;) IntFormAnimated *loadSaveForm = new IntFormAnimated(parent); loadSaveForm->id = LOADSAVE_FORM; loadSaveForm->setGeometry(LOADSAVE_X, LOADSAVE_Y, LOADSAVE_W, slotsInColumn*(LOADENTRY_H + LOADSAVE_HGAP) + LOADSAVE_BANNER_DEPTH + 20); // Add Banner W_FORMINIT sFormInit; sFormInit.formID = LOADSAVE_FORM; sFormInit.id = LOADSAVE_BANNER; sFormInit.x = LOADSAVE_HGAP; sFormInit.y = LOADSAVE_VGAP; sFormInit.width = LOADSAVE_W-(2*LOADSAVE_HGAP); sFormInit.height = LOADSAVE_BANNER_DEPTH; sFormInit.pDisplay = displayLoadBanner; sFormInit.UserData = bLoad; widgAddForm(psRequestScreen, &sFormInit); // Add Banner Label W_LABINIT sLabInit; sLabInit.formID = LOADSAVE_BANNER; sLabInit.FontID = font_large; sLabInit.id = LOADSAVE_LABEL; sLabInit.style = WLAB_ALIGNCENTRE; sLabInit.x = 0; sLabInit.y = 0; sLabInit.width = LOADSAVE_W-(2*LOADSAVE_HGAP); //LOADSAVE_W; sLabInit.height = LOADSAVE_BANNER_DEPTH; //This looks right -Q sLabInit.pText = title; widgAddLabel(psRequestScreen, &sLabInit); // add cancel. W_BUTINIT sButInit; sButInit.formID = LOADSAVE_BANNER; sButInit.x = 8; sButInit.y = 10; 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 = LOADSAVE_CANCEL; sButInit.style = WBUT_PLAIN; sButInit.pTip = _("Close"); sButInit.pDisplay = intDisplayImageHilight; widgAddButton(psRequestScreen, &sButInit); // add slots sButInit = W_BUTINIT(); sButInit.formID = LOADSAVE_FORM; sButInit.style = WBUT_PLAIN; sButInit.width = LOADENTRY_W; sButInit.height = LOADENTRY_H; sButInit.pDisplay = displayLoadSlot; for(slotCount = 0; slotCount< totalslots; slotCount++) { sButInit.id = slotCount+LOADENTRY_START; if(slotCount < slotsInColumn) { sButInit.x = 22 + LOADSAVE_HGAP; sButInit.y = (SWORD)((LOADSAVE_BANNER_DEPTH +(2*LOADSAVE_VGAP)) + ( slotCount*(LOADSAVE_VGAP+LOADENTRY_H))); } else if (slotCount >= slotsInColumn && (slotCount < (slotsInColumn *2))) { sButInit.x = 22 + (2*LOADSAVE_HGAP + LOADENTRY_W); sButInit.y = (SWORD)((LOADSAVE_BANNER_DEPTH +(2* LOADSAVE_VGAP)) + ( (slotCount % slotsInColumn)*(LOADSAVE_VGAP+LOADENTRY_H))); } else { sButInit.x = 22 + (3*LOADSAVE_HGAP + (2*LOADENTRY_W)); sButInit.y = (SWORD)((LOADSAVE_BANNER_DEPTH +(2* LOADSAVE_VGAP)) + ( (slotCount % slotsInColumn)*(LOADSAVE_VGAP+LOADENTRY_H))); } widgAddButton(psRequestScreen, &sButInit); } // fill slots. slotCount = 0; debug(LOG_SAVE, "Searching \"%s\" for savegames", NewSaveGamePath); // add savegame filenames minus extensions to buttons files = PHYSFS_enumerateFiles(NewSaveGamePath); for (i = files; *i != NULL; ++i) { W_BUTTON *button; char savefile[256]; time_t savetime; struct tm *timeinfo; // See if this filename contains the extension we're looking for if (!strstr(*i, sExt)) { // If it doesn't, move on to the next filename continue; } button = (W_BUTTON*)widgGetFromID(psRequestScreen, LOADENTRY_START + slotCount); debug(LOG_SAVE, "We found [%s]", *i); /* Figure save-time */ snprintf(savefile, sizeof(savefile), "%s/%s", NewSaveGamePath, *i); savetime = PHYSFS_getLastModTime(savefile); timeinfo = localtime(&savetime); strftime(sSlotTips[slotCount], sizeof(sSlotTips[slotCount]), "%x %X", timeinfo); /* Set the button-text */ (*i)[strlen(*i) - 4] = '\0'; // remove .gam extension sstrcpy(sSlotCaps[slotCount], *i); //store it! /* Add button */ button->pTip = sSlotTips[slotCount]; button->pText = sSlotCaps[slotCount]; slotCount++; // goto next but... if (slotCount == totalslots) { break; } } PHYSFS_freeList(files); bLoadSaveUp = true; return true; }
//**************************************************************************************** // Load menu/save menu? //***************************************************************************************** static BOOL _addLoadSave(BOOL bLoad, const char *sSearchPath, const char *sExtension, const char *title) { W_FORMINIT sFormInit; W_BUTINIT sButInit; W_LABINIT sLabInit; UDWORD slotCount; // removed hardcoded values! change with the defines above! -Q static char sSlotCaps[totalslots][totalslotspace]; static char sSlotTips[totalslots][totalslotspace]; char **i, **files; const char* checkExtension; mode = bLoad; debug(LOG_SAVE, "called (%d, %s, %s, %s)", bLoad, sSearchPath, sExtension, title); if ((bLoadSaveMode == LOAD_INGAME) || (bLoadSaveMode == SAVE_INGAME)) { if (!bMultiPlayer || (NetPlay.bComms ==0)) { gameTimeStop(); if(GetGameMode() == GS_NORMAL) { BOOL radOnScreen = radarOnScreen; // Only do this in main game. bRender3DOnly = true; radarOnScreen = false; displayWorld(); // Just display the 3d, no interface pie_UploadDisplayBuffer(); // Upload the current display back buffer into system memory. radarOnScreen = radOnScreen; bRender3DOnly = false; } setGamePauseStatus( true ); setGameUpdatePause(true); setScriptPause(true); setScrollPause(true); setConsolePause(true); } forceHidePowerBar(); intRemoveReticule(); } (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 */ memset(&sFormInit, 0, sizeof(W_FORMINIT)); sFormInit.formID = 0; //this adds the blue background, and the "box" behind the buttons -Q sFormInit.id = LOADSAVE_FORM; sFormInit.style = WFORM_PLAIN; sFormInit.x = (SWORD) LOADSAVE_X; sFormInit.y = (SWORD) LOADSAVE_Y; sFormInit.width = LOADSAVE_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 * LOADENTRY_H + LOADSAVE_HGAP* slotsInColumn)+ LOADSAVE_BANNER_DEPTH+20; sFormInit.disableChildren = true; sFormInit.pDisplay = intOpenPlainForm; widgAddForm(psRequestScreen, &sFormInit); // Add Banner sFormInit.formID = LOADSAVE_FORM; sFormInit.id = LOADSAVE_BANNER; sFormInit.x = LOADSAVE_HGAP; sFormInit.y = LOADSAVE_VGAP; sFormInit.width = LOADSAVE_W-(2*LOADSAVE_HGAP); sFormInit.height = LOADSAVE_BANNER_DEPTH; sFormInit.disableChildren = false; sFormInit.pDisplay = displayLoadBanner; sFormInit.UserData = bLoad; widgAddForm(psRequestScreen, &sFormInit); // Add Banner Label memset(&sLabInit, 0, sizeof(W_LABINIT)); sLabInit.formID = LOADSAVE_BANNER; sLabInit.id = LOADSAVE_LABEL; sLabInit.style = WLAB_ALIGNCENTRE; sLabInit.x = 0; sLabInit.y = 3; sLabInit.width = LOADSAVE_W-(2*LOADSAVE_HGAP); //LOADSAVE_W; sLabInit.height = LOADSAVE_BANNER_DEPTH; //This looks right -Q sLabInit.pText = title; sLabInit.FontID = font_regular; widgAddLabel(psRequestScreen, &sLabInit); // add cancel. memset(&sButInit, 0, sizeof(W_BUTINIT)); sButInit.formID = LOADSAVE_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 = LOADSAVE_CANCEL; sButInit.style = WBUT_PLAIN; sButInit.pTip = _("Close"); sButInit.FontID = font_regular; sButInit.pDisplay = intDisplayImageHilight; widgAddButton(psRequestScreen, &sButInit); // add slots memset(&sButInit, 0, sizeof(W_BUTINIT)); sButInit.formID = LOADSAVE_FORM; sButInit.style = WBUT_PLAIN; sButInit.width = LOADENTRY_W; sButInit.height = LOADENTRY_H; sButInit.pDisplay = displayLoadSlot; sButInit.FontID = font_regular; for(slotCount = 0; slotCount< totalslots; slotCount++) { sButInit.id = slotCount+LOADENTRY_START; if(slotCount < slotsInColumn) { sButInit.x = 22 + LOADSAVE_HGAP; sButInit.y = (SWORD)((LOADSAVE_BANNER_DEPTH +(2*LOADSAVE_VGAP)) + ( slotCount*(LOADSAVE_VGAP+LOADENTRY_H))); } else if (slotCount >= slotsInColumn && (slotCount < (slotsInColumn *2))) { sButInit.x = 22 + (2*LOADSAVE_HGAP + LOADENTRY_W); sButInit.y = (SWORD)((LOADSAVE_BANNER_DEPTH +(2* LOADSAVE_VGAP)) + ( (slotCount % slotsInColumn)*(LOADSAVE_VGAP+LOADENTRY_H))); } else { sButInit.x = 22 + (3*LOADSAVE_HGAP + (2*LOADENTRY_W)); sButInit.y = (SWORD)((LOADSAVE_BANNER_DEPTH +(2* LOADSAVE_VGAP)) + ( (slotCount % slotsInColumn)*(LOADSAVE_VGAP+LOADENTRY_H))); } widgAddButton(psRequestScreen, &sButInit); } // fill slots. slotCount = 0; sstrcpy(sPath, sSearchPath); // setup locals. sstrcpy(sExt, sExtension); debug(LOG_SAVE, "Searching \"%s\" for savegames", sSearchPath); // Check for an extension like ".ext", not "ext" sasprintf((char**)&checkExtension, ".%s", sExtension); // add savegame filenames minus extensions to buttons files = PHYSFS_enumerateFiles(sSearchPath); for (i = files; *i != NULL; ++i) { W_BUTTON *button; char savefile[256]; time_t savetime; // See if this filename contains the extension we're looking for if (!strstr(*i, checkExtension)) { // If it doesn't, move on to the next filename continue; } button = (W_BUTTON*)widgGetFromID(psRequestScreen, LOADENTRY_START + slotCount); debug(LOG_SAVE, "We found [%s]", *i); /* Figure save-time */ snprintf(savefile, sizeof(savefile), "%s/%s", sSearchPath, *i); savetime = PHYSFS_getLastModTime(savefile); sstrcpy(sSlotTips[slotCount], ctime(&savetime)); /* Set the button-text */ (*i)[strlen(*i) - 4] = '\0'; // remove .gam extension sstrcpy(sSlotCaps[slotCount], *i); //store it! /* Add button */ button->pTip = sSlotTips[slotCount]; button->pText = sSlotCaps[slotCount]; slotCount++; // goto next but... if (slotCount == totalslots) { break; } } PHYSFS_freeList(files); bLoadSaveUp = true; return true; }
static MapFileList listMapFiles() { MapFileList ret, filtered, oldSearchPath; char **subdirlist = PHYSFS_enumerateFiles("maps"); for (char **i = subdirlist; *i != NULL; ++i) { std::string wzfile = *i; if (*i[0] == '.' || wzfile.substr(wzfile.find_last_of(".")+1) != "wz") { continue; } std::string realFileName = std::string("maps/") + *i; ret.push_back(realFileName); } PHYSFS_freeList(subdirlist); // save our current search path(s) debug(LOG_WZ, "Map search paths:"); char **searchPath = PHYSFS_getSearchPath(); for (char **i = searchPath; *i != NULL; i++) { debug(LOG_WZ, " [%s]", *i); oldSearchPath.push_back(*i); PHYSFS_removeFromSearchPath(*i); } PHYSFS_freeList(searchPath); for (MapFileList::iterator realFileName = ret.begin(); realFileName != ret.end(); ++realFileName) { std::string realFilePathAndName = PHYSFS_getWriteDir() + *realFileName; PHYSFS_addToSearchPath(realFilePathAndName.c_str(), PHYSFS_APPEND); int unsafe = 0; char **filelist = PHYSFS_enumerateFiles("multiplay/maps"); for (char **file = filelist; *file != NULL; ++file) { std::string isDir = std::string("multiplay/maps/") + *file; if (PHYSFS_isDirectory(isDir.c_str())) continue; std::string checkfile = *file; debug(LOG_WZ,"checking ... %s", *file); if (checkfile.substr(checkfile.find_last_of(".")+ 1) == "gam") { if (unsafe++ > 1) { debug(LOG_ERROR, "Map packs are not supported! %s NOT added.", realFilePathAndName.c_str()); break; } } } PHYSFS_freeList(filelist); if (unsafe < 2) { filtered.push_back(realFileName->c_str()); } PHYSFS_removeFromSearchPath(realFilePathAndName.c_str()); } // restore our search path(s) again for (MapFileList::iterator restorePaths = oldSearchPath.begin(); restorePaths != oldSearchPath.end(); ++restorePaths) { PHYSFS_addToSearchPath(restorePaths->c_str(), PHYSFS_APPEND); } debug(LOG_WZ, "Search paths restored"); printSearchPath(); return filtered; }
static int browser_handler(UI_DIALOG *dlg, d_event *event, file_browser *b) { int rval = 0; if (event->type == EVENT_UI_DIALOG_DRAW) { ui_dprintf_at( dlg, 10, 5, "%s", b->message ); ui_dprintf_at( dlg, 20, 32,"N&ame" ); ui_dprintf_at( dlg, 20, 86,"&Files" ); ui_dprintf_at( dlg, 210, 86,"&Dirs" ); ui_dprintf_at( dlg, 20, 60, "%s", b->spaces ); ui_dprintf_at( dlg, 20, 60, "%s", b->view_dir ); return 1; } if (GADGET_PRESSED(b->button2)) { PHYSFS_freeList(b->filename_list); b->filename_list = NULL; PHYSFS_freeList(b->directory_list); b->directory_list = NULL; ui_close_dialog(dlg); return 1; } if (GADGET_PRESSED(b->help_button)) { ui_messagebox( -1, -1, 1, "Sorry, no help is available!", "Ok" ); rval = 1; } if (event->type == EVENT_UI_LISTBOX_MOVED) { if ((ui_event_get_gadget(event) == (UI_GADGET *)b->listbox1) && (b->listbox1->current_item >= 0) && b->filename_list[b->listbox1->current_item]) ui_inputbox_set_text(b->user_file, b->filename_list[b->listbox1->current_item]); if ((ui_event_get_gadget(event) == (UI_GADGET *)b->listbox2) && (b->listbox2->current_item >= 0) && b->directory_list[b->listbox2->current_item]) ui_inputbox_set_text(b->user_file, b->directory_list[b->listbox2->current_item]); rval = 1; } if (GADGET_PRESSED(b->button1) || GADGET_PRESSED(b->user_file) || (event->type == EVENT_UI_LISTBOX_SELECTED)) { char *p; if (ui_event_get_gadget(event) == (UI_GADGET *)b->listbox2) strcpy(b->user_file->text, b->directory_list[b->listbox2->current_item]); strncpy(b->filename, b->view_dir, PATH_MAX); p = b->user_file->text; while (!strncmp(p, "..", 2)) // shorten the path manually { char *sep = strrchr(b->filename, '/'); if (sep) *sep = 0; else *b->filename = 0; // look directly in search paths p += 2; if (*p == '/') p++; } if (*b->filename && *p) strncat(b->filename, "/", PATH_MAX - strlen(b->filename)); strncat(b->filename, p, PATH_MAX - strlen(b->filename)); if (!PHYSFS_isDirectory(b->filename)) { PHYSFS_file *TempFile; TempFile = PHYSFS_openRead(b->filename); if (TempFile) { // Looks like a valid filename that already exists! PHYSFS_close(TempFile); ui_close_dialog(dlg); return 1; } // File doesn't exist, but can we create it? TempFile = PHYSFS_openWrite(b->filename); if (TempFile) { // Looks like a valid filename! PHYSFS_close(TempFile); PHYSFS_delete(b->filename); ui_close_dialog(dlg); return 1; } } else { if (b->filename[strlen(b->filename) - 1] == '/') // user typed a separator on the end b->filename[strlen(b->filename) - 1] = 0; strcpy(b->view_dir, b->filename); PHYSFS_freeList(b->filename_list); b->filename_list = file_getfilelist(&b->num_files, b->filespec, b->view_dir); if (!b->filename_list) { PHYSFS_freeList(b->directory_list); b->directory_list = NULL; ui_close_dialog(dlg); return 1; } ui_inputbox_set_text(b->user_file, b->filespec); PHYSFS_freeList(b->directory_list); b->directory_list = file_getdirlist(&b->num_dirs, b->view_dir); if (!b->directory_list) { PHYSFS_freeList(b->filename_list); b->filename_list = NULL; ui_close_dialog(dlg); return 1; } ui_listbox_change(dlg, b->listbox1, b->num_files, b->filename_list); ui_listbox_change(dlg, b->listbox2, b->num_dirs, b->directory_list); //i = TICKER; //while ( TICKER < i+2 ); } rval = 1; } return rval; }
bool buildMapList() { if (!loadLevFile("gamedesc.lev", mod_campaign, false, NULL)) { return false; } loadLevFile("addon.lev", mod_multiplay, false, NULL); WZ_Maps.clear(); MapFileList realFileNames = listMapFiles(); for (MapFileList::iterator realFileName = realFileNames.begin(); realFileName != realFileNames.end(); ++realFileName) { bool mapmod = false; struct WZmaps CurrentMap; std::string realFilePathAndName = PHYSFS_getRealDir(realFileName->c_str()) + *realFileName; PHYSFS_addToSearchPath(realFilePathAndName.c_str(), PHYSFS_APPEND); char **filelist = PHYSFS_enumerateFiles(""); for (char **file = filelist; *file != NULL; ++file) { std::string checkfile = *file; size_t len = strlen(*file); if (len > 10 && !strcasecmp(*file + (len - 10), ".addon.lev")) // Do not add addon.lev again { loadLevFile(*file, mod_multiplay, true, realFileName->c_str()); } // add support for X player maps using a new name to prevent conflicts. if (len > 13 && !strcasecmp(*file + (len - 13), ".xplayers.lev")) { loadLevFile(*file, mod_multiplay, true, realFileName->c_str()); } } PHYSFS_freeList(filelist); if (PHYSFS_removeFromSearchPath(realFilePathAndName.c_str()) == 0) { debug(LOG_ERROR, "Could not unmount %s", PHYSFS_getLastError()); } // check what kind of map it is if (!PHYSFS_mount(realFilePathAndName.c_str(), "WZMap", PHYSFS_APPEND)) { debug(LOG_FATAL, "Could not mount %s, because: %s. Please delete the file, and run the game again. Game will now exit.", realFilePathAndName.c_str(), PHYSFS_getLastError()); exit(-1); } filelist = PHYSFS_enumerateFiles("WZMap"); for (char **file = filelist; *file != NULL; ++file) { if (PHYSFS_isDirectory(*file)) { std::string checkfile = *file; if (checkfile.compare("wrf")==0 || checkfile.compare("stats")==0 ||checkfile.compare("components")==0 || checkfile.compare("anims")==0 || checkfile.compare("effects")==0 ||checkfile.compare("messages")==0 || checkfile.compare("audio")==0 || checkfile.compare("sequenceaudio")==0 ||checkfile.compare("misc")==0 || checkfile.compare("features")==0 || checkfile.compare("script")==0 ||checkfile.compare("structs")==0 || checkfile.compare("tileset")==0 || checkfile.compare("images")==0 || checkfile.compare("texpages")==0 ) { mapmod = true; break; } } } PHYSFS_freeList(filelist); CurrentMap.MapName = realFileName->c_str(); CurrentMap.isMapMod = mapmod; WZ_Maps.push_back(CurrentMap); if (PHYSFS_removeFromSearchPath(realFilePathAndName.c_str()) == 0) { debug(LOG_ERROR, "Could not unmount %s", PHYSFS_getLastError()); } } return true; }