further WIP on launcher

This commit is contained in:
milek7
2019-08-24 01:28:55 +02:00
parent ad58c617d4
commit aa9bee57da
20 changed files with 225 additions and 94 deletions

View File

@@ -4,10 +4,12 @@
#include "utilities.h"
#include "renderer.h"
#include "McZapkie/MOVER.h"
#include "application.h"
#include "Logs.h"
#include <filesystem>
ui::scenerylist_panel::scenerylist_panel(scenery_scanner &scanner)
: ui_panel(STR("Scenario list"), false), scanner(scanner)
: ui_panel(STR("Scenario list"), false), scanner(scanner), placeholder_mini("textures/mini/other")
{
}
@@ -25,7 +27,7 @@ void ui::scenerylist_panel::render()
std::string prev_prefix;
bool collapse_open = false;
for (auto const &desc : scanner.scenarios) {
for (auto &desc : scanner.scenarios) {
std::string name = desc.path.stem().string();
std::string prefix = name.substr(0, name.find_first_of("-_"));
if (prefix.empty())
@@ -110,7 +112,7 @@ void ui::scenerylist_panel::render()
if (ImGui::BeginChild("child5", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar)) {
ImGuiListClipper clipper(selected_scenery->trainsets.size());
while (clipper.Step()) for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
auto const &trainset = selected_scenery->trainsets[i];
auto &trainset = selected_scenery->trainsets[i];
ImGui::PushID(i);
if (ImGui::Selectable("##set", selected_trainset == &trainset, 0, ImVec2(0, 30)))
selected_trainset = &trainset;
@@ -124,8 +126,57 @@ void ui::scenerylist_panel::render()
if (selected_trainset) {
ImGui::NextColumn();
ImGui::TextWrapped(selected_trainset->description.c_str());
ImGui::Button(STR_C("Launch"), ImVec2(-1, 0));
if (ImGui::Button(STR_C("Launch"), ImVec2(-1, 0))) {
bool found = false;
for (auto &veh : selected_trainset->vehicles) {
if (veh.drivertype.size() > 0 && veh.drivertype != "nobody") {
Global.local_start_vehicle = ToLower(veh.name);
Global.SceneryFile = selected_scenery->path;
std::string set = "trainset ";
set += selected_trainset->name + " ";
set += selected_trainset->track + " ";
set += std::to_string(selected_trainset->offset) + " ";
set += std::to_string(selected_trainset->velocity) + " ";
for (const auto &veh : selected_trainset->vehicles) {
set += "node -1 0 " + veh.name + " dynamic ";
set += veh.vehicle->path.parent_path().generic_string() + " ";
set += veh.skin->skin + " ";
set += veh.vehicle->path.stem().generic_string() + " ";
set += std::to_string(veh.offset) + " " + veh.drivertype + " ";
set += std::to_string(veh.coupling);
if (veh.params.size() > 0)
set += "." + veh.params;
set += " " + std::to_string(veh.loadcount) + " ";
if (veh.loadcount > 0)
set += veh.loadtype + " ";
set += "enddynamic ";
}
set += "endtrainset";
WriteLog(set);
Global.trainset_overrides.push_back(std::make_pair(selected_trainset->file_bounds.first, set));
Application.pop_mode();
Application.push_mode(eu07_application::mode::scenarioloader);
found = true;
break;
}
}
if (!found)
ImGui::OpenPopup("missing_driver");
}
if (ImGui::BeginPopup("missing_driver")) {
ImGui::TextUnformatted(STR_C("Trainset not occupied"));
if (ImGui::Button(STR_C("OK"), ImVec2(-1, 0)))
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
}
}
}
} ImGui::EndChild();
@@ -134,7 +185,7 @@ void ui::scenerylist_panel::render()
ImGui::End();
}
void ui::scenerylist_panel::draw_trainset(const trainset_desc &trainset)
void ui::scenerylist_panel::draw_trainset(trainset_desc &trainset)
{
static std::unordered_map<coupling, std::string> coupling_names =
{
@@ -150,70 +201,93 @@ void ui::scenerylist_panel::draw_trainset(const trainset_desc &trainset)
{ coupling::uic, STRN("uic") }
};
draw_droptarget();
int position = 0;
draw_droptarget(trainset, position++);
ImGui::SameLine(15.0f);
for (auto const &dyn_desc : trainset.vehicles) {
if (dyn_desc.skin && dyn_desc.skin->mini.get() != -1) {
ImGui::PushID(static_cast<const void*>(&dyn_desc));
deferred_image *mini = nullptr;
glm::ivec2 size = dyn_desc.skin->mini.size();
float width = 30.0f / size.y * size.x;
ImGui::Image(reinterpret_cast<void*>(dyn_desc.skin->mini.get()), ImVec2(width, 30), ImVec2(0, 1), ImVec2(1, 0));
if (dyn_desc.skin && dyn_desc.skin->mini.get() != -1)
mini = &dyn_desc.skin->mini;
else
mini = &placeholder_mini;
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
std::string name = (dyn_desc.vehicle->path.parent_path() / dyn_desc.vehicle->path.stem()).string();
std::string skin = dyn_desc.skin->skin;
ImGui::Text(STR_C("ID: %s"), dyn_desc.name.c_str());
ImGui::NewLine();
ImGui::PushID(static_cast<const void*>(&dyn_desc));
ImGui::Text(STR_C("Type: %s"), name.c_str());
ImGui::Text(STR_C("Skin: %s"), skin.c_str());
ImGui::NewLine();
glm::ivec2 size = mini->size();
float width = 30.0f / size.y * size.x;
ImGui::Image(reinterpret_cast<void*>(mini->get()), ImVec2(width, 30), ImVec2(0, 1), ImVec2(1, 0));
if (dyn_desc.drivertype != "nobody")
ImGui::Text(STR_C("Occupied: %s"), dyn_desc.drivertype.c_str());
if (dyn_desc.loadcount > 0)
ImGui::Text(STR_C("Load: %s: %d"), dyn_desc.loadtype.c_str(), dyn_desc.loadcount);
if (!dyn_desc.params.empty())
ImGui::Text(STR_C("Parameters: %s"), dyn_desc.params.c_str());
ImGui::NewLine();
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
std::string name = (dyn_desc.vehicle->path.parent_path() / dyn_desc.vehicle->path.stem()).string();
std::string skin = dyn_desc.skin->skin;
ImGui::Text(STR_C("ID: %s"), dyn_desc.name.c_str());
ImGui::NewLine();
ImGui::TextUnformatted(STR_C("Coupling:"));
ImGui::Text(STR_C("Type: %s"), name.c_str());
ImGui::Text(STR_C("Skin: %s"), skin.c_str());
ImGui::NewLine();
for (int i = 1; i <= 0x100; i <<= 1) {
bool dummy = true;
if (dyn_desc.drivertype != "nobody")
ImGui::Text(STR_C("Occupied: %s"), dyn_desc.drivertype.c_str());
if (dyn_desc.loadcount > 0)
ImGui::Text(STR_C("Load: %s: %d"), dyn_desc.loadtype.c_str(), dyn_desc.loadcount);
if (!dyn_desc.params.empty())
ImGui::Text(STR_C("Parameters: %s"), dyn_desc.params.c_str());
ImGui::NewLine();
if (dyn_desc.coupling & i) {
std::string label = STRN("unknown");
auto it = coupling_names.find(static_cast<coupling>(i));
if (it != coupling_names.end())
label = it->second;
ImGui::Checkbox(Translations.lookup_c(label.c_str()), &dummy);
}
ImGui::TextUnformatted(STR_C("Coupling:"));
for (int i = 1; i <= 0x100; i <<= 1) {
bool dummy = true;
if (dyn_desc.coupling & i) {
std::string label = STRN("unknown");
auto it = coupling_names.find(static_cast<coupling>(i));
if (it != coupling_names.end())
label = it->second;
ImGui::Checkbox(Translations.lookup_c(label.c_str()), &dummy);
}
ImGui::EndTooltip();
}
ImGui::SameLine(0, 0);
float originX = ImGui::GetCursorPosX();
ImGui::SameLine(originX - 7.5f);
draw_droptarget();
ImGui::SameLine(originX);
ImGui::PopID();
ImGui::EndTooltip();
}
ImGui::SameLine(0, 0);
float originX = ImGui::GetCursorPosX();
ImGui::SameLine(originX - 7.5f);
draw_droptarget(trainset, position++);
ImGui::SameLine(originX);
ImGui::PopID();
}
}
void ui::scenerylist_panel::draw_droptarget()
#include "Logs.h"
void ui::scenerylist_panel::draw_droptarget(trainset_desc &trainset, int position)
{
ImGui::Dummy(ImVec2(15, 30));
if (ImGui::BeginDragDropTarget()) {
ImGui::AcceptDragDropPayload("skin");
const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("vehicle_pure");
if (payload) {
skin_set *ptr = *(reinterpret_cast<skin_set**>(payload->Data));
std::shared_ptr<skin_set> skin;
for (auto &s : ptr->vehicle.lock()->matching_skinsets)
if (s.get() == ptr)
skin = s;
trainset.vehicles.emplace(trainset.vehicles.begin() + position);
dynamic_desc &desc = trainset.vehicles[position];
desc.name = skin->skin + "_" + std::to_string((int)LocalRandom(0.0, 10000000.0));
desc.vehicle = skin->vehicle.lock();
desc.skin = skin;
}
ImGui::EndDragDropTarget();
}
}

View File

@@ -14,10 +14,11 @@ class scenerylist_panel : public ui_panel
private:
scenery_scanner &scanner;
scenery_desc const *selected_scenery = nullptr;
trainset_desc const *selected_trainset = nullptr;
scenery_desc *selected_scenery = nullptr;
trainset_desc *selected_trainset = nullptr;
deferred_image placeholder_mini;
void draw_trainset(const trainset_desc &trainset);
void draw_droptarget();
void draw_trainset(trainset_desc &trainset);
void draw_droptarget(trainset_desc &trainset, int position);
};
} // namespace ui

View File

@@ -11,7 +11,7 @@ scenery_scanner::scenery_scanner(ui::vehicles_bank &bank)
void scenery_scanner::scan()
{
for (auto &f : std::filesystem::directory_iterator("scenery")) {
std::filesystem::path path(f.path());
std::filesystem::path path(std::filesystem::relative(f.path(), "scenery/"));
if (*(path.filename().string().begin()) == '$')
continue;
@@ -30,7 +30,9 @@ void scenery_scanner::scan_scn(std::filesystem::path path)
scenery_desc &desc = scenarios.back();
desc.path = path;
cParser parser(path.string(), cParser::buffer_FILE);
std::string file_path = "scenery/" + path.string();
cParser parser(file_path, cParser::buffer_FILE);
parser.expandIncludes = false;
while (!parser.eof()) {
parser.getTokens();
@@ -38,7 +40,7 @@ void scenery_scanner::scan_scn(std::filesystem::path path)
parse_trainset(parser);
}
std::ifstream stream(path.string(), std::ios_base::binary | std::ios_base::in);
std::ifstream stream(file_path, std::ios_base::binary | std::ios_base::in);
int line_counter = 0;
std::string line;
@@ -67,7 +69,7 @@ void scenery_scanner::scan_scn(std::filesystem::path path)
desc.links.push_back(std::make_pair(file, label));
}
else if (line[3] == 'o') {
for (trainset_desc &trainset : desc.trainsets) {
for (auto &trainset : desc.trainsets) {
if (line_counter < trainset.file_bounds.first
|| line_counter > trainset.file_bounds.second)
continue;
@@ -82,7 +84,7 @@ void scenery_scanner::parse_trainset(cParser &parser)
{
scenery_desc &desc = scenarios.back();
desc.trainsets.emplace_back();
trainset_desc &trainset = desc.trainsets.back();
auto &trainset = desc.trainsets.back();
trainset.file_bounds.first = parser.Line();
parser.getTokens(4);
@@ -94,7 +96,6 @@ void scenery_scanner::parse_trainset(cParser &parser)
dynamic_desc &dyn = trainset.vehicles.back();
std::string datafolder, skinfile, mmdfile, params;
int offset;
parser.getTokens(2); // range_max, range_min
parser.getTokens(1, false); // name
@@ -104,7 +105,7 @@ void scenery_scanner::parse_trainset(cParser &parser)
break;
parser.getTokens(7, false);
parser >> datafolder >> skinfile >> mmdfile >> offset >> dyn.drivertype >> params >> dyn.loadcount;
parser >> datafolder >> skinfile >> mmdfile >> dyn.offset >> dyn.drivertype >> params >> dyn.loadcount;
size_t params_pos = params.find('.');
if (params_pos != -1 && params_pos < params.size()) {

View File

@@ -8,9 +8,10 @@
struct dynamic_desc {
std::string name;
std::string drivertype;
std::string drivertype = "nobody";
std::string loadtype;
float offset;
std::string loadtype = "none";
int loadcount;
unsigned int coupling;

View File

@@ -16,6 +16,7 @@ void ui::vehicles_bank::scan_textures()
{
if (line.size() < 3)
continue;
if (line.back() == '\r')
line.pop_back();
@@ -41,6 +42,9 @@ void ui::vehicles_bank::parse_entry(const std::string &line)
std::string param;
while (std::getline(stream, param, '=')) {
if (param.back() == ' ')
param.pop_back();
if (line[0] == '!')
parse_category_entry(param);
else if (line[0] == '*' && line[1] == '*')
@@ -110,7 +114,10 @@ void ui::vehicles_bank::parse_texture_info(const std::string &target, const std:
std::getline(stream, mini, ',');
std::getline(stream, miniplus, ',');
auto vehicle = get_vehicle(model);
skin_set set;
set.vehicle = vehicle;
set.group = mini;
if (!mini.empty())
@@ -118,6 +125,8 @@ void ui::vehicles_bank::parse_texture_info(const std::string &target, const std:
if (!miniplus.empty())
set.mini = std::move(deferred_image("textures/mini/" + ToLower(miniplus)));
else if (!mini.empty())
set.mini = std::move(deferred_image("textures/mini/" + ToLower(mini)));
set.skin = ToLower(target);
erase_extension(set.skin);
@@ -129,7 +138,6 @@ void ui::vehicles_bank::parse_texture_info(const std::string &target, const std:
}
*/
auto vehicle = get_vehicle(model);
group_map[set.group].insert(vehicle);
vehicle->matching_skinsets.push_back(std::make_shared<skin_set>(std::move(set)));
}

View File

@@ -22,14 +22,17 @@ enum class vehicle_type {
unknown
};
struct vehicle_desc;
struct skin_set {
std::weak_ptr<vehicle_desc> vehicle;
std::string skin;
//std::vector<std::filesystem::path> skins;
deferred_image mini;
std::string group;
};
struct vehicle_desc;
struct texture_rule {
std::shared_ptr<vehicle_desc> previous_vehicle;
std::vector<std::pair<std::string, std::string>> replace_rules;

View File

@@ -3,7 +3,7 @@
#include "renderer.h"
ui::vehiclepicker_panel::vehiclepicker_panel()
: ui_panel(STR("Select vehicle"), false)
: ui_panel(STR("Select vehicle"), false), placeholder_mini("textures/mini/other")
{
bank.scan_textures();
}
@@ -162,7 +162,8 @@ void ui::vehiclepicker_panel::render()
//std::string label = skin->skins[0].stem().string();
std::string label = skin->skin;
if (selectable_image(label.c_str(), skin == selected_skinset, &skin->mini, true))
auto mini = skin->mini ? &skin->mini : &placeholder_mini;
if (selectable_image(label.c_str(), skin == selected_skinset, mini, skin))
selected_skinset = skin;
}
}
@@ -173,7 +174,7 @@ void ui::vehiclepicker_panel::render()
ImGui::End();
}
bool ui::vehiclepicker_panel::selectable_image(const char *desc, bool selected, const deferred_image* image, bool pickable)
bool ui::vehiclepicker_panel::selectable_image(const char *desc, bool selected, const deferred_image* image, const skin_set *pickable)
{
bool ret = ImGui::Selectable(desc, selected, 0, ImVec2(0, 30));
if (pickable)
@@ -194,10 +195,10 @@ bool ui::vehiclepicker_panel::selectable_image(const char *desc, bool selected,
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
ImGui::InvisibleButton(desc, ImVec2(width, 30));
if (ImGui::BeginDragDropSource()) {
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAutoExpirePayload)) {
ImGui::Image(reinterpret_cast<void*>(tex), ImVec2(width, 30), ImVec2(0, 1), ImVec2(1, 0));
ImGui::SetDragDropPayload("skin", "aaaa", 5);
ImGui::SetDragDropPayload("vehicle_pure", &pickable, sizeof(skin_set*));
ImGui::EndDragDropSource();
}

View File

@@ -13,13 +13,14 @@ class vehiclepicker_panel : public ui_panel
void render() override;
private:
bool selectable_image(const char *desc, bool selected, const deferred_image *image, bool pickable = false);
bool selectable_image(const char *desc, bool selected, const deferred_image *image, const skin_set *pickable = nullptr);
vehicle_type selected_type = vehicle_type::none;
std::shared_ptr<const vehicle_desc> selected_vehicle;
const std::string *selected_group = nullptr;
const skin_set *selected_skinset = nullptr;
bool display_by_groups = false;
deferred_image placeholder_mini;
vehicles_bank bank;
};