Don't share the same temporary scenario directory between all programs

(Also fixes loading of unpacked scenarios)
This commit is contained in:
2015-06-30 12:44:56 -04:00
parent 0e70e716aa
commit cea602ce6d
7 changed files with 39 additions and 30 deletions

View File

@@ -1957,6 +1957,7 @@ static void readSpecialNodesFromStream(std::istream& stream, std::vector<cSpecia
nodes[p.first] = p.second;
}
extern std::string scenario_temp_dir_name;
bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, bool only_header) {
// First determine whether we're dealing with a packed or unpacked scenario.
bool is_packed = true;
@@ -1977,7 +1978,7 @@ bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, bool only_head
}
}
auto getFile = [&](std::string relpath) -> std::istream& {
if(is_packed) return pack.getFile(relpath);
if(is_packed) return pack.getFile("scenario/" + relpath);
if(fin.is_open()) fin.close();
fin.clear();
fin.open((file_to_load/relpath).string().c_str());
@@ -1997,29 +1998,29 @@ bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, bool only_head
TiXmlBase::SetCondenseWhiteSpace(true); // Make sure this is enabled, because the dialog engine disables it
{
// First, load up the binary header data.
std::istream& header = getFile("scenario/header.exs");
std::istream& header = getFile("header.exs");
header.read(reinterpret_cast<char*>(&scenario.format), sizeof(scenario_header_flags));
// Then, the main scenario data.
std::istream& scen_data = getFile("scenario/scenario.xml");
std::istream& scen_data = getFile("scenario.xml");
readScenarioFromXml(xmlDocFromStream(scen_data, "scenario.xml"), scenario);
if(only_header) return true;
// Next, terrain types...
std::istream& terrain = getFile("scenario/terrain.xml");
std::istream& terrain = getFile("terrain.xml");
readTerrainFromXml(xmlDocFromStream(terrain, "terrain.xml"), scenario);
// ...items...
std::istream& items = getFile("scenario/items.xml");
std::istream& items = getFile("items.xml");
readItemsFromXml(xmlDocFromStream(items, "items.xml"), scenario);
// ...and monsters.
std::istream& monsters = getFile("scenario/monsters.xml");
std::istream& monsters = getFile("monsters.xml");
readMonstersFromXml(xmlDocFromStream(monsters, "monsters.xml"), scenario);
// Finally, the special nodes.
std::istream& nodes = getFile("scenario/scenario.spec");
std::istream& nodes = getFile("scenario.spec");
readSpecialNodesFromStream(nodes, scenario.scen_specials, "scenario.spec");
}
@@ -2029,15 +2030,15 @@ bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, bool only_head
scenario.outdoors[x][y] = new cOutdoors(scenario);
std::string file_basename = "out" + std::to_string(x) + '~' + std::to_string(y);
// First the main data.
std::istream& outdoors = getFile("scenario/out/" + file_basename + ".xml");
std::istream& outdoors = getFile("out/" + file_basename + ".xml");
readOutdoorsFromXml(xmlDocFromStream(outdoors, file_basename + ".xml"), *scenario.outdoors[x][y]);
// Then the map.
std::istream& out_map = getFile("scenario/out/" + file_basename + ".map");
std::istream& out_map = getFile("out/" + file_basename + ".map");
loadOutMapData(load_map(out_map, false, file_basename + ".map"), loc(x,y), scenario);
// And the special nodes.
std::istream& out_spec = getFile("scenario/out/" + file_basename + ".spec");
std::istream& out_spec = getFile("out/" + file_basename + ".spec");
readSpecialNodesFromStream(out_spec, scenario.outdoors[x][y]->specials, file_basename + ".spec");
}
}
@@ -2046,19 +2047,19 @@ bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, bool only_head
for(size_t i = 0; i < scenario.towns.size(); i++) {
std::string file_basename = "town" + std::to_string(i);
// First the main data.
std::istream& town = getFile("scenario/towns/" + file_basename + ".xml");
std::istream& town = getFile("towns/" + file_basename + ".xml");
readTownFromXml(xmlDocFromStream(town, file_basename + ".xml"), scenario.towns[i], scenario);
// Then the map.
std::istream& town_map = getFile("scenario/towns/" + file_basename + ".map");
std::istream& town_map = getFile("towns/" + file_basename + ".map");
loadTownMapData(load_map(town_map, true, file_basename + ".map"), i, scenario);
// And the special nodes.
std::istream& town_spec = getFile("scenario/towns/" + file_basename + ".spec");
std::istream& town_spec = getFile("towns/" + file_basename + ".spec");
readSpecialNodesFromStream(town_spec, scenario.towns[i]->specials, file_basename + ".spec");
// Don't forget the dialogue nodes.
std::istream& town_talk = getFile("scenario/towns/talk" + std::to_string(i) + ".xml");
std::istream& town_talk = getFile("towns/talk" + std::to_string(i) + ".xml");
readDialogueFromXml(xmlDocFromStream(town_talk, "talk.xml"), scenario.towns[i]->talking, i);
}
@@ -2066,7 +2067,7 @@ bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, bool only_head
// First figure out where they are in the filesystem. The implementation of this depends on whether the scenario is packed.
int num_graphic_sheets = 0;
if(is_packed) {
fs::remove_all(tempDir/"scenario");
fs::remove_all(tempDir/scenario_temp_dir_name);
std::bitset<65536> have_pic = {0};
for(auto& file : pack) {
std::string fname = file.filename;
@@ -2089,9 +2090,10 @@ bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, bool only_head
if(fname.substr(dot,4) != ".wav") continue;
if(!std::all_of(fname.begin() + 19, fname.begin() + dot, isdigit)) continue;
} else continue;
fs::path path = tempDir/fname;
fname = fname.substr(9);
fs::path path = tempDir/scenario_temp_dir_name/fname;
fs::create_directories(path.parent_path());
std::istream& f = pack.getFile(fname);
std::istream& f = file.contents;
std::ofstream fout(path.string().c_str(), std::ios::binary);
fout << f.rdbuf();
fout.close();
@@ -2099,8 +2101,8 @@ bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, bool only_head
// This is a bit of trickery to get it to only count the first consecutive range of sheets
while(have_pic[num_graphic_sheets])
num_graphic_sheets++;
ResMgr::pushPath<ImageRsrc>(tempDir/"scenario"/"graphics");
ResMgr::pushPath<SoundRsrc>(tempDir/"scenario"/"sounds");
ResMgr::pushPath<ImageRsrc>(tempDir/scenario_temp_dir_name/"graphics");
ResMgr::pushPath<SoundRsrc>(tempDir/scenario_temp_dir_name/"sounds");
} else {
if(fs::is_directory(file_to_load/"graphics"))
ResMgr::pushPath<ImageRsrc>(file_to_load/"graphics");
@@ -2338,8 +2340,8 @@ bool tryLoadPictFromResourceFile(fs::path& gpath, sf::Image& graphics_store);
void load_spec_graphics_v1(fs::path scen_file) {
static const char*const noGraphics = "The game will still work without the custom graphics, but some things will not look right.";
fs::remove_all(tempDir/"scenario/graphics");
fs::remove_all(tempDir/"scenario/sounds");
fs::remove_all(tempDir/scenario_temp_dir_name/"graphics");
fs::remove_all(tempDir/scenario_temp_dir_name/"sounds");
fs::path path(scen_file);
std::cout << "Loading scenario graphics... (" << path << ")\n";
// Tried path.replace_extension, but that only deleted the extension, so I have to do it manually

View File

@@ -489,6 +489,7 @@ void cCustomGraphics::copy_graphic(pic_num_t dest, pic_num_t src, size_t numSlot
*last_src = temp.getTexture();
}
extern std::string scenario_temp_dir_name;
void cCustomGraphics::convert_sheets() {
if(!is_old) return;
int num_graphics = count();
@@ -499,7 +500,7 @@ void cCustomGraphics::convert_sheets() {
if(num_graphics % 100) numSheets++;
sheets = new sf::Texture[numSheets];
extern fs::path tempDir;
fs::path pic_dir = tempDir/"scenario/graphics";
fs::path pic_dir = tempDir/scenario_temp_dir_name/"graphics";
for(size_t i = 0; i < numSheets; i++) {
sf::IntRect subrect;
subrect.top = i * 280;
@@ -525,7 +526,7 @@ void cCustomGraphics::replace_sheet(size_t num, sf::Image& newSheet) {
// Then we need to do some extra stuff to ensure the dialog engine also sees the change
extern fs::path tempDir;
std::string sheetname = "sheet" + std::to_string(num);
fs::path tmpPath = tempDir/"scenario/graphics"/(sheetname + ".png");
fs::path tmpPath = tempDir/scenario_temp_dir_name/"graphics"/(sheetname + ".png");
newSheet.saveToFile(tmpPath.string().c_str());
ResMgr::free<ImageRsrc>(sheetname);
}