Skip to content

Commit

Permalink
use nested map for SDF names to save stack space.
Browse files Browse the repository at this point in the history
Update semantics of the SDF array to (row, column) form to match
the picker space

Fix calref#674
  • Loading branch information
NQNStudios committed Mar 5, 2025
1 parent 3d48cb1 commit 94c21f0
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 40 deletions.
4 changes: 2 additions & 2 deletions src/fileio/fileio_scen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -968,10 +968,10 @@ void readScenarioFromXml(ticpp::Document&& data, cScenario& scenario) {
} else if(type == "sdf") {
int row, col;
edit->GetAttribute("row", &row);
if(row < 0 || row >= scenario.sdf_names.size())
if(row < 0 || row >= SDF_ROWS)
throw xBadVal(type, "row", std::to_string(row), edit->Row(), edit->Column(), fname);
edit->GetAttribute("col", &col);
if(col < 0 || col >= scenario.sdf_names[0].size())
if(col < 0 || col >= SDF_COLUMNS)
throw xBadVal(type, "col", std::to_string(col), edit->Row(), edit->Column(), fname);
edit->GetText(&scenario.sdf_names[row][col]);
} else if(type == "graphics") {
Expand Down
3 changes: 3 additions & 0 deletions src/global.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ namespace bp = boost::process;
const int MAX_GOLD = 30000;
const int MAX_FOOD = 25000;

const int SDF_ROWS = 350;
const int SDF_COLUMNS = 50;

inline bool str_to_bool(std::string str) {
return str == "true";
}
Expand Down
8 changes: 8 additions & 0 deletions src/scenario/scenario.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -605,3 +605,11 @@ std::string cScenario::get_feature_flag(std::string flag) {
if(iter == this->feature_flags.end()) return "";
return iter->second;
}

std::string cScenario::get_sdf_name(int row, int col) {
if(sdf_names.find(row) == sdf_names.end())
return "";
if(sdf_names[row].find(col) == sdf_names[row].end())
return "";
return sdf_names[row][col];
}
8 changes: 3 additions & 5 deletions src/scenario/scenario.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ struct scenario_header_flags {

enum eContentRating {G, PG, R, NC17};

// TODO: Duplicated in party.hpp
template<typename T, size_t x, size_t y>
using array2d = std::array<std::array<T, y>, x>;

// Used for finding town entrances in the outdoors
struct town_entrance_t {
location out_sec;
Expand Down Expand Up @@ -107,7 +103,9 @@ class cScenario {
std::vector<std::string> evt_names;
std::vector<std::string> ic_names;
std::vector<std::string> itf_names;
array2d<std::string, 350, 50> sdf_names;
std::map<int, std::map<int, std::string>> sdf_names;
std::string get_sdf_name(int row, int col);

bool adjust_diff;
bool is_legacy;
fs::path scen_file; // transient
Expand Down
12 changes: 6 additions & 6 deletions src/scenedit/scen.fileio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,13 +415,13 @@ void writeScenarioToXml(ticpp::Printer&& data, cScenario& scenario) {
data.PushText(scenario.itf_names[i]);
data.CloseElement("item-typeflag");
}
for(int x = 0; x < scenario.sdf_names.size(); x++) {
for(int y = 0; y < scenario.sdf_names[x].size(); y++) {
if(scenario.sdf_names[x][y].empty()) continue;
for(int r = 0; r < SDF_ROWS; r++) {
for(int c = 0; c < SDF_COLUMNS; c++) {
if(scenario.get_sdf_name(r, c).empty()) continue;
data.OpenElement("sdf");
data.PushAttribute("row", x);
data.PushAttribute("col", y);
data.PushText(scenario.sdf_names[x][y]);
data.PushAttribute("row", r);
data.PushAttribute("col", c);
data.PushText(scenario.sdf_names[r][c]);
data.CloseElement("sdf");
}
}
Expand Down
51 changes: 27 additions & 24 deletions src/scenedit/scen.sdfpicker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,19 @@ bool cStuffDonePicker::handle_scroll(std::string item_hit) {
if(item_hit == "up") {
if(viewport.y > 0) viewport.y -= rows;
} else if(item_hit == "down") {
if(viewport.y < scenario.sdf_names[0].size() - rows) viewport.y += rows;
if(viewport.y < SDF_ROWS - rows) viewport.y += rows;
} else if(item_hit == "left") {
if(viewport.x > 0) viewport.x -= cols;
} else if(item_hit == "right") {
if(viewport.x < scenario.sdf_names.size() - cols) viewport.x += cols;
if(viewport.x < SDF_COLUMNS - cols) viewport.x += cols;
}
if(viewport.x == 0) dlog["left"].hide();
else dlog["left"].show();
if(viewport.y == 0) dlog["up"].hide();
else dlog["up"].show();
if(viewport.x >= scenario.sdf_names.size() - cols) dlog["right"].hide();
if(viewport.x >= SDF_COLUMNS - cols) dlog["right"].hide();
else dlog["right"].show();
if(viewport.y >= scenario.sdf_names[0].size() - rows) dlog["down"].hide();
if(viewport.y >= SDF_ROWS - rows) dlog["down"].hide();
else dlog["down"].show();
fill_names();
if(!item_hit.empty()) select_active();
Expand Down Expand Up @@ -106,40 +106,43 @@ location cStuffDonePicker::run() {
}

void cStuffDonePicker::clamp_sdf() {
chosen_sdf.x = minmax(0, scenario.sdf_names.size() - 1, chosen_sdf.x);
chosen_sdf.y = minmax(0, scenario.sdf_names[0].size() - 1, chosen_sdf.y);
viewport.x = cols * floor(chosen_sdf.x / float(cols));
viewport.y = rows * floor(chosen_sdf.y / float(rows));
// Note: x and y in chosen_sdf are actually (r,c)
chosen_sdf.x = minmax(0, SDF_ROWS - 1, chosen_sdf.x);
chosen_sdf.y = minmax(0, SDF_COLUMNS - 1, chosen_sdf.y);
viewport.y = rows * floor(chosen_sdf.x / float(rows));
viewport.x = cols * floor(chosen_sdf.y / float(cols));
}

void cStuffDonePicker::fill_names() {
for(int x = 0; x < cols; x++) {
for(int y = 0; y < rows; y++) {
auto& field = grid->getChild("name", x, y);
for(int c = 0; c < cols; c++) {
for(int r = 0; r < rows; r++) {
auto& field = grid->getChild("name", c, r);
// Note: x and y in sdf are actually (c,r)
location sdf = viewport;
sdf.x += x;
sdf.y += y;
field.setText(scenario.sdf_names[sdf.x][sdf.y]);
if(x == 0) {
sdf.x += c;
sdf.y += r;
field.setText(scenario.get_sdf_name(sdf.y, sdf.x));
if(c == 0) {
// Add row labels
row_labels->getChild("row", 0, y).setTextToNum(sdf.y);
row_labels->getChild("row", 0, r).setTextToNum(sdf.y);
}
if(y == 0) {
if(r == 0) {
// Add column labels
col_labels->getChild("col", x, 0).setTextToNum(sdf.x);
col_labels->getChild("col", c, 0).setTextToNum(sdf.x);
}
}
}
}

void cStuffDonePicker::save_names() {
for(int x = 0; x < cols; x++) {
for(int y = 0; y < rows; y++) {
auto& field = grid->getChild("name", x, y);
for(int c = 0; c < cols; c++) {
for(int r = 0; r < rows; r++) {
auto& field = grid->getChild("name", c, r);
location sdf = viewport;
sdf.x += x;
sdf.y += y;
scenario.sdf_names[sdf.x][sdf.y] = field.getText();
sdf.x += c;
sdf.y += r;
if(!field.getText().empty())
scenario.sdf_names[sdf.y][sdf.x] = field.getText();
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/scenedit/scen.sdfpicker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class cTilemap;

class cStuffDonePicker {
cDialog dlog;
// Note: x and y in initial_sdf and chosen_sdf are actually (c, r) and must be flipped when
// indexing SDFs or their names in the scenario
location initial_sdf, chosen_sdf, viewport;
cTilemap* grid;
cTilemap* row_labels;
Expand Down
6 changes: 3 additions & 3 deletions src/universe/party.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ namespace legacy {
};

// TODO: Duplicated in scenario.hpp
template<typename T, size_t x, size_t y>
using array2d = std::array<std::array<T, y>, x>;
template<typename T, size_t rows, size_t cols>
using array2d = std::array<std::array<T, cols>, rows>;

struct campaign_flag_type{
array2d<unsigned char, 25, 25> idx{};
Expand Down Expand Up @@ -91,7 +91,7 @@ class cParty : public iLiving {
unsigned long age;
unsigned short gold;
unsigned short food;
array2d<unsigned char, 350, 50> stuff_done;
array2d<unsigned char, SDF_ROWS, SDF_COLUMNS> stuff_done;
// These used to be stored as magic SDFs
unsigned char hostiles_present;
bool easy_mode = false, less_wm = false;
Expand Down

0 comments on commit 94c21f0

Please sign in to comment.