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> <button name='okay' type='regular' top='69' left='263'>OK</button>
<pict type='dlog' num='16' top='8' left='8'/> <pict type='dlog' num='16' top='8' left='8'/>
<text top='3' left='50' width='271' height='63'> <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. and can't be run using this copy.
You can find an upgrade at www.spidweb.com, You can find an upgrade on the forums at &lt;http://spiderwebforums.ipbhost.com/&gt;.
or get one from Spiderweb Software.
</text> </text>
</dialog> </dialog>

View File

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

View File

@@ -37,7 +37,7 @@ extern sf::RenderWindow mini_map;
extern short which_combat_type; extern short which_combat_type;
extern short cur_town_talk_loaded; extern short cur_town_talk_loaded;
extern cUniverse univ; extern cUniverse univ;
cScenarioList scen_headers; std::vector<scen_header_type> scen_headers;
extern bool mac_is_intel; extern bool mac_is_intel;
bool loaded_yet = false, got_nagged = false,ae_loading = false; 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; std::cout << progDir << '\n' << scenDir << std::endl;
scen_headers.clear(); scen_headers.clear();
fs::directory_iterator iter(scenDir); 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()) { while(iter != fs::directory_iterator()) {
fs::file_status stat = iter->status(); 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 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 load_scenario_header(fs::path file/*,short header_entry*/){
bool file_ok = false; bool file_ok = false;
long len;
bool mac_header = true;
// TODO: This will only accept old-format scenarios! std::string fname = file.filename().string();
// TODO: Rewrite using ifstream, or maybe ifstream_buf int dot = fname.find_first_of('.');
FILE* file_id = fopen(file.string().c_str(), "rb"); if(dot == std::string::npos)
if(file_id == NULL) { return false; // If it has no file extension, it's not a valid scenario.
return false; if(fname.substr(dot) == ".exs") {
} std::ifstream fin(file.string(), std::ios::binary);
scen_header_type curScen; if(fin.fail()) return false;
len = (long) sizeof(scen_header_type); scenario_header_flags curScen;
if(fread(&curScen, len, 1, file_id) < 1){ long len = (long) sizeof(scenario_header_flags);
fclose(file_id); return false; if(!fin.read((char*)&curScen, len)) return false;
} if(curScen.flag1 == 10 && curScen.flag2 == 20 && curScen.flag3 == 30 && curScen.flag4 == 40)
if((curScen.flag1 == 10) && (curScen.flag2 == 20) file_ok = true; // Legacy Mac scenario
&& (curScen.flag3 == 30) else if(curScen.flag1 == 20 && curScen.flag2 == 40 && curScen.flag3 == 60 && curScen.flag4 == 80)
&& (curScen.flag4 == 40)) { file_ok = true; // Legacy Windows scenario
file_ok = true; else if(curScen.flag1 == 'O' && curScen.flag2 == 'B' && curScen.flag3 == 'O' && curScen.flag4 == 'E')
mac_header = true; file_ok = true; // Unpacked OBoE scenario
} else } else if(fname.substr(dot) == ".boes") {
if((curScen.flag1 == 20) && (curScen.flag2 == 40) if(fs::is_directory(file)) {
&& (curScen.flag3 == 60) if(fs::exists(file/"header.exs"))
&& (curScen.flag4 == 80)) { return load_scenario_header(file/"header.exs");
file_ok = true; } else {
mac_header = false; 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. // So file is (probably) OK, so load in string data and close it.
fclose(file_id);
cScenario temp_scenario; cScenario temp_scenario;
load_scenario(file, temp_scenario); if(!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" */)
return false; 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; return true;
} }

View File

@@ -36,27 +36,11 @@
#define CDST cd_set_text_edit_str #define CDST cd_set_text_edit_str
#define CDSN cd_set_text_edit_num #define CDSN cd_set_text_edit_num
struct scen_header_type { struct scen_header_type{
unsigned char flag1, flag2, flag3, flag4; int intro_pic, rating, difficulty, ver[3], prog_make_ver[3];
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{
std::string name, who1, who2, file; 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 { struct effect_pat_type {
unsigned short pattern[9][9]; unsigned short pattern[9][9];
}; };

View File

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