Skip to content

Commit

Permalink
added asset replacement option
Browse files Browse the repository at this point in the history
  • Loading branch information
Redcrafter committed Jul 11, 2024
1 parent 2d83eee commit e2429bb
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 51 deletions.
166 changes: 115 additions & 51 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,64 +262,67 @@ static ImVec2 toImVec(const glm::vec2 vec) {
return ImVec2(vec.x, vec.y);
}

static void load_data() {
{ // load atlas
if(atlas == nullptr) {
atlas = std::make_unique<Texture>();
}

auto tex = Image(game_data.get_asset(255));
// chroma key cyan and replace with alpha
auto vptr = tex.data();
for(int i = 0; i < tex.width() * tex.height(); ++i) {
if(vptr[i] == 0xFFFFFF00) {
vptr[i] = 0;
}
}
atlas->Load(tex);
}

if(bg_tex == nullptr) {
bg_tex = std::make_unique<Texture>();
}

bg_tex->Bind();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 320 * 4, 180 * 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
bg_tex->width = 320 * 4;
bg_tex->height = 180 * 4;

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

bg_tex->LoadSubImage(320 * 0, 180 * 0, game_data.get_asset(11)); // 13
bg_tex->LoadSubImage(320 * 1, 180 * 0, game_data.get_asset(12)); // 14
bg_tex->LoadSubImage(320 * 2, 180 * 0, game_data.get_asset(13)); // 7, 8
bg_tex->LoadSubImage(320 * 3, 180 * 0, game_data.get_asset(14)); // 1

bg_tex->LoadSubImage(320 * 0, 180 * 1, game_data.get_asset(15)); // 6
bg_tex->LoadSubImage(320 * 1, 180 * 1, game_data.get_asset(16)); // 9, 11
bg_tex->LoadSubImage(320 * 2, 180 * 1, game_data.get_asset(17)); // 10
bg_tex->LoadSubImage(320 * 3, 180 * 1, game_data.get_asset(18)); // 16

bg_tex->LoadSubImage(320 * 0, 180 * 2, game_data.get_asset(19)); // 4, 5
bg_tex->LoadSubImage(320 * 1, 180 * 2, game_data.get_asset(20)); // 15
bg_tex->LoadSubImage(320 * 2, 180 * 2, game_data.get_asset(21)); // 19
bg_tex->LoadSubImage(320 * 3, 180 * 2, game_data.get_asset(22)); // 2, 3

bg_tex->LoadSubImage(320 * 0, 180 * 3, game_data.get_asset(23)); // 17
bg_tex->LoadSubImage(320 * 1, 180 * 3, game_data.get_asset(24)); // 18
bg_tex->LoadSubImage(320 * 2, 180 * 3, game_data.get_asset(26)); // 12

undo_buffer.clear();
redo_buffer.clear();
updateRender();
}

static bool load_game(const std::string& path) {
if(!std::filesystem::exists(path)) {
return false;
}

try {
game_data = GameData::load(path);

{ // load atlas
if(atlas == nullptr) {
atlas = std::make_unique<Texture>();
}

auto tex = Image(game_data.get_asset(255));
// chroma key cyan and replace with alpha
auto vptr = tex.data();
for(int i = 0; i < tex.width() * tex.height(); ++i) {
if(vptr[i] == 0xFFFFFF00) {
vptr[i] = 0;
}
}
atlas->Load(tex);
}

if(bg_tex == nullptr) {
bg_tex = std::make_unique<Texture>();
}

bg_tex->Bind();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 320 * 4, 180 * 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
bg_tex->width = 320 * 4;
bg_tex->height = 180 * 4;

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

bg_tex->LoadSubImage(320 * 0, 180 * 0, game_data.get_asset(11)); // 13
bg_tex->LoadSubImage(320 * 1, 180 * 0, game_data.get_asset(12)); // 14
bg_tex->LoadSubImage(320 * 2, 180 * 0, game_data.get_asset(13)); // 7, 8
bg_tex->LoadSubImage(320 * 3, 180 * 0, game_data.get_asset(14)); // 1

bg_tex->LoadSubImage(320 * 0, 180 * 1, game_data.get_asset(15)); // 6
bg_tex->LoadSubImage(320 * 1, 180 * 1, game_data.get_asset(16)); // 9, 11
bg_tex->LoadSubImage(320 * 2, 180 * 1, game_data.get_asset(17)); // 10
bg_tex->LoadSubImage(320 * 3, 180 * 1, game_data.get_asset(18)); // 16

bg_tex->LoadSubImage(320 * 0, 180 * 2, game_data.get_asset(19)); // 4, 5
bg_tex->LoadSubImage(320 * 1, 180 * 2, game_data.get_asset(20)); // 15
bg_tex->LoadSubImage(320 * 2, 180 * 2, game_data.get_asset(21)); // 19
bg_tex->LoadSubImage(320 * 3, 180 * 2, game_data.get_asset(22)); // 2, 3

bg_tex->LoadSubImage(320 * 0, 180 * 3, game_data.get_asset(23)); // 17
bg_tex->LoadSubImage(320 * 1, 180 * 3, game_data.get_asset(24)); // 18
bg_tex->LoadSubImage(320 * 2, 180 * 3, game_data.get_asset(26)); // 12

undo_buffer.clear();
redo_buffer.clear();
updateRender();
load_data();
return true;
} catch(std::exception& e) {
error_dialog.push(e.what());
Expand Down Expand Up @@ -753,6 +756,63 @@ class {
}
} map_exporter;

class {
bool should_open = false;
int selected_asset = 0;
std::string file_path;

public:
void draw_popup() {
if(should_open) {
ImGui::OpenPopup("Replace asset");
should_open = false;
}

if(ImGui::BeginPopupModal("Replace asset")) {
ImGui::InputInt("asset id", &selected_asset);
selected_asset = std::clamp(selected_asset, 0, (int)game_data.assets.size() - 1);

ImGui::InputText("path", &file_path);
ImGui::SameLine();

if(ImGui::Button("Search")) {
std::string path;
auto result = NFD::OpenDialog({}, nullptr, path, window);

if(result == NFD::Result::Error) {
error_dialog.push(NFD::GetError());
}
if(result == NFD::Result::Okay) {
file_path = path;
}
}

if(ImGui::Button("Replace")) {
try {
auto data = readFile(file_path.c_str());
game_data.replace_asset(std::span((uint8_t*)data.data(), data.size()), selected_asset);

ImGui::CloseCurrentPopup();
} catch(std::exception& e) {
error_dialog.push(e.what());
}

load_data();
}
ImGui::SameLine();
if(ImGui::Button("Cancel")) {
ImGui::CloseCurrentPopup();
}

ImGui::EndPopup();
}
}

void open() {
should_open = true;
}
} replacer;

void full_map_screenshot(ShaderProgram& textured_shader) {
static std::string export_path = std::filesystem::current_path().string() + "/map.png";
std::string path;
Expand Down Expand Up @@ -939,6 +999,9 @@ static ImGuiID DockSpaceOverViewport(ShaderProgram& textured_shader) {
if(ImGui::MenuItem("Dump tile textures")) {
dump_tile_textures();
}
if(ImGui::MenuItem("Replace asset")) {
replacer.open();
}

ImGui::EndDisabled();

Expand Down Expand Up @@ -1582,6 +1645,7 @@ int runViewer() {
DockSpaceOverViewport(textured_shader);
error_dialog.draw();
exe_exporter.draw_popup();
replacer.draw_popup();

// skip rendering if no data is loaded
if(game_data.loaded) {
Expand Down
5 changes: 5 additions & 0 deletions src/structures/asset.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "asset.hpp"

#include <array>
#include <filesystem>
#include <fstream>

#include "../aes.hpp"
Expand All @@ -12,7 +13,11 @@ static std::array<uint8_t, 16> keys[3] = {
};

std::vector<char> readFile(const char* path) {
if(!std::filesystem::exists(path))
throw std::runtime_error("File not found");

std::ifstream testFile(path, std::ios::binary);
testFile.exceptions(std::ifstream::badbit | std::ifstream::failbit);
return std::vector(std::istreambuf_iterator(testFile), std::istreambuf_iterator<char>());
}

Expand Down

0 comments on commit e2429bb

Please sign in to comment.