Include new-format scenarios in the Custom Scenario list

- Note: It still assumes the basic scenarios are old-format.
This commit is contained in:
2015-02-11 17:02:28 -05:00
parent bb98455e4f
commit 120561ae64
5 changed files with 68 additions and 88 deletions

View File

@@ -57,7 +57,7 @@ extern cUniverse univ;
extern sf::Texture pc_gworld;
extern std::map<eSkill,short> skill_max;
extern cScenarioList scen_headers;
extern std::vector<scen_header_type> scen_headers;
short sign_mode,person_graphic,store_person_graphic,store_sign_mode;
long num_talk_entries;
@@ -1398,18 +1398,18 @@ static void put_scen_info(cDialog& me) {
sout.str("");
sout << i + 1;
std::string n = sout.str();
if(scen_headers.size() > (store_scen_page_on * 3 + i) && scen_headers.data(store_scen_page_on * 3 + i).flag1 != 0) {
if(scen_headers.size() > (store_scen_page_on * 3 + i)) {
me["pic" + n].show();
dynamic_cast<cPict&>(me["pic" + n]).setPict(scen_headers.data(store_scen_page_on * 3 + i).intro_pic);
dynamic_cast<cPict&>(me["pic" + n]).setPict(scen_headers[store_scen_page_on * 3 + i].intro_pic);
sout.str("");
sout << scen_headers.strs(store_scen_page_on * 3 + i).name;
sout << " v" << int(scen_headers.data(store_scen_page_on * 3 + i).ver[0]);
sout << '.' << int(scen_headers.data(store_scen_page_on * 3 + i).ver[1]);
sout << '.' << int(scen_headers.data(store_scen_page_on * 3 + i).ver[2]);
sout << " - | Difficulty: " << difficulty[scen_headers.data(store_scen_page_on * 3 + i).difficulty];
sout << ", Rating: " << ratings[scen_headers.data(store_scen_page_on * 3 + i).rating];
sout << " |" << scen_headers.strs(store_scen_page_on * 3 + i).who1;
sout << " |" << scen_headers.strs(store_scen_page_on * 3 + i).who2;
sout << scen_headers[store_scen_page_on * 3 + i].name;
sout << " v" << int(scen_headers[store_scen_page_on * 3 + i].ver[0]);
sout << '.' << int(scen_headers[store_scen_page_on * 3 + i].ver[1]);
sout << '.' << int(scen_headers[store_scen_page_on * 3 + i].ver[2]);
sout << " - | Difficulty: " << difficulty[scen_headers[store_scen_page_on * 3 + i].difficulty];
sout << ", Rating: " << ratings[scen_headers[store_scen_page_on * 3 + i].rating];
sout << " |" << scen_headers[store_scen_page_on * 3 + i].who1;
sout << " |" << scen_headers[store_scen_page_on * 3 + i].who2;
me["desc" + n].setText(sout.str());
me["start" + n].show();
}

View File

@@ -37,7 +37,7 @@ extern sf::RenderWindow mini_map;
extern short which_combat_type;
extern short cur_town_talk_loaded;
extern cUniverse univ;
cScenarioList scen_headers;
std::vector<scen_header_type> scen_headers;
extern bool mac_is_intel;
bool loaded_yet = false, got_nagged = false,ae_loading = false;
@@ -465,14 +465,6 @@ void build_scen_headers() {
std::cout << progDir << '\n' << scenDir << std::endl;
scen_headers.clear();
fs::directory_iterator iter(scenDir);
// TODO: Double-check that kFSIterateFlat is identical to the behaviour of Boost's directory_iterator
#if 0
err = FSOpenIterator(&folderRef, kFSIterateFlat, &iter);
if(err != noErr){
printf("Error opening iterator!\n");
return;
}
#endif
while(iter != fs::directory_iterator()) {
fs::file_status stat = iter->status();
@@ -486,59 +478,64 @@ void build_scen_headers() {
}
// This is only called at startup, when bringing headers of active scenarios.
// This wipes out the scenario record, so be sure not to call it while in an active scenario.
bool load_scenario_header(fs::path file/*,short header_entry*/){
bool file_ok = false;
long len;
bool mac_header = true;
// TODO: This will only accept old-format scenarios!
// TODO: Rewrite using ifstream, or maybe ifstream_buf
FILE* file_id = fopen(file.string().c_str(), "rb");
if(file_id == NULL) {
return false;
}
scen_header_type curScen;
len = (long) sizeof(scen_header_type);
if(fread(&curScen, len, 1, file_id) < 1){
fclose(file_id); return false;
}
if((curScen.flag1 == 10) && (curScen.flag2 == 20)
&& (curScen.flag3 == 30)
&& (curScen.flag4 == 40)) {
file_ok = true;
mac_header = true;
} else
if((curScen.flag1 == 20) && (curScen.flag2 == 40)
&& (curScen.flag3 == 60)
&& (curScen.flag4 == 80)) {
file_ok = true;
mac_header = false;
std::string fname = file.filename().string();
int dot = fname.find_first_of('.');
if(dot == std::string::npos)
return false; // If it has no file extension, it's not a valid scenario.
if(fname.substr(dot) == ".exs") {
std::ifstream fin(file.string(), std::ios::binary);
if(fin.fail()) return false;
scenario_header_flags curScen;
long len = (long) sizeof(scenario_header_flags);
if(!fin.read((char*)&curScen, len)) return false;
if(curScen.flag1 == 10 && curScen.flag2 == 20 && curScen.flag3 == 30 && curScen.flag4 == 40)
file_ok = true; // Legacy Mac scenario
else if(curScen.flag1 == 20 && curScen.flag2 == 40 && curScen.flag3 == 60 && curScen.flag4 == 80)
file_ok = true; // Legacy Windows scenario
else if(curScen.flag1 == 'O' && curScen.flag2 == 'B' && curScen.flag3 == 'O' && curScen.flag4 == 'E')
file_ok = true; // Unpacked OBoE scenario
} else if(fname.substr(dot) == ".boes") {
if(fs::is_directory(file)) {
if(fs::exists(file/"header.exs"))
return load_scenario_header(file/"header.exs");
} else {
unsigned char magic[2];
std::ifstream fin(file.string(), std::ios::binary);
if(fin.fail()) return false;
if(!fin.read((char*)magic, 2)) return false;
// Check for the gzip magic number
if(magic[0] == 0x1f && magic[1] == 0x8b)
file_ok = true;
}
if(!file_ok) {
fclose(file_id);
return false;
}
if(!file_ok) return false;
// So file is OK, so load in string data and close it.
fclose(file_id);
// So file is (probably) OK, so load in string data and close it.
cScenario temp_scenario;
load_scenario(file, temp_scenario);
scen_header_str_type scen_strs;
scen_strs.name = temp_scenario.scen_name;
scen_strs.who1 = temp_scenario.who_wrote[0];
scen_strs.who2 = temp_scenario.who_wrote[1];
std::string curScenarioName(file.filename().string());
scen_strs.file = curScenarioName;
if(scen_strs.file == "valleydy.exs" ||
scen_strs.file == "stealth.exs" ||
scen_strs.file == "zakhazi.exs"/* ||
scen_strs.file == "busywork.exs" */)
if(!load_scenario(file, temp_scenario))
return false;
scen_headers.push_back(curScen,scen_strs);
scen_header_type scen_head;
scen_head.name = temp_scenario.scen_name;
scen_head.who1 = temp_scenario.who_wrote[0];
scen_head.who2 = temp_scenario.who_wrote[1];
scen_head.file = fname;
scen_head.intro_pic = temp_scenario.intro_pic;
scen_head.rating = temp_scenario.rating;
scen_head.difficulty = temp_scenario.difficulty;
std::copy(temp_scenario.format.ver, temp_scenario.format.ver + 3, scen_head.ver);
std::copy(temp_scenario.format.prog_make_ver, temp_scenario.format.prog_make_ver + 3, scen_head.prog_make_ver);
if(scen_head.file.substr(0,dot) == "valleydy" ||
scen_head.file.substr(0,dot) == "stealth" ||
scen_head.file.substr(0,dot) == "zakhazi"/* ||
scen_strs.file.substr(0,dot) == "busywork" */)
return false;
scen_headers.push_back(scen_head);
return true;
}

View File

@@ -36,27 +36,11 @@
#define CDST cd_set_text_edit_str
#define CDSN cd_set_text_edit_num
struct scen_header_type {
unsigned char flag1, flag2, flag3, flag4;
unsigned char ver[3],min_run_ver,prog_make_ver[3],num_towns;
unsigned char out_width,out_height,difficulty,intro_pic,rating;
};
struct scen_header_str_type{
struct scen_header_type{
int intro_pic, rating, difficulty, ver[3], prog_make_ver[3];
std::string name, who1, who2, file;
};
class cScenarioList {
std::vector<scen_header_type> d;
std::vector<scen_header_str_type> s;
public:
void clear() {d.clear(); s.clear();}
size_t size() {return d.size();}
void push_back(scen_header_type& head, scen_header_str_type& strs) {d.push_back(head); s.push_back(strs);}
scen_header_type& data(size_t i) {return d.at(i);}
scen_header_str_type& strs(size_t i) {return s.at(i);}
};
struct effect_pat_type {
unsigned short pattern[9][9];
};

View File

@@ -27,7 +27,7 @@ extern bool play_sounds,party_in_memory;
extern long register_flag;
extern sf::RenderWindow mainPtr;
extern location ul;
extern cScenarioList scen_headers;;
extern std::vector<scen_header_type> scen_headers;
extern cUniverse univ;
extern eGameMode overall_mode;
@@ -94,11 +94,11 @@ bool handle_startup_press(location the_point) {
scen = pick_a_scen();
if(scen < 0) break;
if(scen_headers.data(scen).prog_make_ver[0] >= 2) {
if(scen_headers[scen].prog_make_ver[0] > 2 || scen_headers[scen].prog_make_ver[1] > 0) {
cChoiceDlog("scen-version-mismatch").show();
break;
}
scen_name = scen_headers.strs(scen).file;
scen_name = scen_headers[scen].file;
put_party_in_scen(scen_name);
break;
}