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

@@ -8,9 +8,8 @@
<button name='okay' type='regular' top='69' left='263'>OK</button>
<pict type='dlog' num='16' top='8' left='8'/>
<text top='3' left='50' width='271' height='63'>
This scenario was created by Blades of Exile v2.0 or later,
This scenario was created by Blades of Exile v2.1 or later,
and can't be run using this copy.
You can find an upgrade at www.spidweb.com,
or get one from Spiderweb Software.
You can find an upgrade on the forums at &lt;http://spiderwebforums.ipbhost.com/&gt;.
</text>
</dialog>

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;
}