Skip to content

Commit

Permalink
added some error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
Redcrafter committed May 27, 2024
1 parent 13ae3a0 commit cad7be5
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 76 deletions.
14 changes: 11 additions & 3 deletions src/dos_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// mostly adapted from the ImHex PE pattern made by WerWolv

struct DOSHeader {
char signature[2];
uint16_t signature;
uint16_t extraPageSize;
uint16_t numberOfPages;
uint16_t relocations;
Expand Down Expand Up @@ -187,7 +187,7 @@ struct OptionalHeader {
};

struct COFFHeader {
char signature[4];
uint32_t signature;
ArchitectureType architecture;
uint16_t numberOfSections;
uint32_t timeDateStamp;
Expand Down Expand Up @@ -246,10 +246,18 @@ SegmentData getSegmentOffsets(std::span<char> data) {
auto ptr = (uint8_t*)data.data();

auto dos_header = (DOSHeader*)ptr;
if(dos_header->signature != 0x5A4D) { // 'ZM'
throw std::runtime_error("invalid dos header");
}
auto coff_header_ptr = (COFFHeader*)(ptr + dos_header->coffHeaderPointer);
if(coff_header_ptr->signature != 0x00004550) { // 'PE\0\0'
throw std::runtime_error("invalid coff_header");
}
auto coff_optional_header = (OptionalHeader*)(ptr + dos_header->coffHeaderPointer + sizeof(COFFHeader));
if(coff_optional_header->magic != PEFormat::PE32Plus) {
throw std::runtime_error("invalid coff_optional_header");
}
auto section_ptr = (SectionHeader*)(ptr + dos_header->coffHeaderPointer + sizeof(COFFHeader) + coff_header_ptr->sizeOfOptionalHeader);
// assert(coff_header_ptr->optionalHeader.magic == PEFormat::PE32Plus);
auto image_base = coff_optional_header->imageBase;

std::span<uint8_t> dat;
Expand Down
2 changes: 1 addition & 1 deletion src/glStuff.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ struct Texture {
int n;
auto* dat = stbi_load_from_memory(data.data(), data.size(), &width, &height, &n, 4);
if(dat == nullptr) {
throw std::runtime_error("missing texture");
throw std::runtime_error("failed to load texture");
}

glBindTexture(GL_TEXTURE_2D, id);
Expand Down
113 changes: 59 additions & 54 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ static void LoadAtlas(std::span<const uint8_t> data) {
int width, height, n;
auto* dat = stbi_load_from_memory(data.data(), data.size(), &width, &height, &n, 4);
if(dat == nullptr) {
throw std::runtime_error("invalid texture atlas format");
throw std::runtime_error("failed to load texture atlas");
}

atlas = std::make_unique<Texture>();
Expand Down Expand Up @@ -529,72 +529,77 @@ static void LoadAtlas(std::span<const uint8_t> data) {

static bool load_game(const std::string& path) {
if(!std::filesystem::exists(path)) {
ErrorDialog.push("File not found");
return false;
}
rawData = readFile(path.c_str());

auto sections = getSegmentOffsets(rawData);
try {
auto sections = getSegmentOffsets(rawData);

assert(sections.data.size() >= sizeof(asset_entry) * 676);
auto assets = std::span((asset_entry*)sections.data.data(), 676);
assert(sections.data.size() >= sizeof(asset_entry) * 676);
auto assets = std::span((asset_entry*)sections.data.data(), 676);

std::vector<uint8_t> decryptBuffer;
std::vector<uint8_t> decryptBuffer;

auto get_asset = [&](int id) {
assert(id >= 0 && id < 676);
auto& asset = assets[id];
assert(sections.rdata.size() >= asset.ptr - sections.rdata_pointer_offset + asset.length);
auto dat = sections.rdata.subspan(asset.ptr - sections.rdata_pointer_offset, asset.length);
auto get_asset = [&](int id) {
assert(id >= 0 && id < 676);
auto& asset = assets[id];
assert(sections.rdata.size() >= asset.ptr - sections.rdata_pointer_offset + asset.length);
auto dat = sections.rdata.subspan(asset.ptr - sections.rdata_pointer_offset, asset.length);

if(tryDecrypt(asset, dat, decryptBuffer)) {
return std::span(decryptBuffer);
if(tryDecrypt(asset, dat, decryptBuffer)) {
return std::span(decryptBuffer);
}
return dat;
};

LoadAtlas(get_asset(255));

if(bg_tex == nullptr) {
bg_tex = std::make_unique<Texture>();
}
return dat;
};
glBindTexture(GL_TEXTURE_2D_ARRAY, bg_tex->id);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 320, 180, 19, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

bg_tex->LoadSubImage(1 - 1, get_asset(14));
bg_tex->LoadSubImage(2 - 1, get_asset(22));
bg_tex->LoadSubImage(3 - 1, get_asset(22));
bg_tex->LoadSubImage(4 - 1, get_asset(19));
bg_tex->LoadSubImage(5 - 1, get_asset(19));
bg_tex->LoadSubImage(6 - 1, get_asset(15));
bg_tex->LoadSubImage(7 - 1, get_asset(13));
bg_tex->LoadSubImage(8 - 1, get_asset(13));
bg_tex->LoadSubImage(9 - 1, get_asset(16));
bg_tex->LoadSubImage(10 - 1, get_asset(17));
bg_tex->LoadSubImage(11 - 1, get_asset(16));
bg_tex->LoadSubImage(12 - 1, get_asset(26));
bg_tex->LoadSubImage(13 - 1, get_asset(11));
bg_tex->LoadSubImage(14 - 1, get_asset(12));
bg_tex->LoadSubImage(15 - 1, get_asset(20));
bg_tex->LoadSubImage(16 - 1, get_asset(18));
bg_tex->LoadSubImage(17 - 1, get_asset(23));
bg_tex->LoadSubImage(18 - 1, get_asset(24));
bg_tex->LoadSubImage(19 - 1, get_asset(21));

LoadAtlas(get_asset(255));

bg_tex = std::make_unique<Texture>();
glBindTexture(GL_TEXTURE_2D_ARRAY, bg_tex->id);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 320, 180, 19, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

bg_tex->LoadSubImage(1 - 1, get_asset(14));
bg_tex->LoadSubImage(2 - 1, get_asset(22));
bg_tex->LoadSubImage(3 - 1, get_asset(22));
bg_tex->LoadSubImage(4 - 1, get_asset(19));
bg_tex->LoadSubImage(5 - 1, get_asset(19));
bg_tex->LoadSubImage(6 - 1, get_asset(15));
bg_tex->LoadSubImage(7 - 1, get_asset(13));
bg_tex->LoadSubImage(8 - 1, get_asset(13));
bg_tex->LoadSubImage(9 - 1, get_asset(16));
bg_tex->LoadSubImage(10 - 1, get_asset(17));
bg_tex->LoadSubImage(11 - 1, get_asset(16));
bg_tex->LoadSubImage(12 - 1, get_asset(26));
bg_tex->LoadSubImage(13 - 1, get_asset(11));
bg_tex->LoadSubImage(14 - 1, get_asset(12));
bg_tex->LoadSubImage(15 - 1, get_asset(20));
bg_tex->LoadSubImage(16 - 1, get_asset(18));
bg_tex->LoadSubImage(17 - 1, get_asset(23));
bg_tex->LoadSubImage(18 - 1, get_asset(24));
bg_tex->LoadSubImage(19 - 1, get_asset(21));

for(size_t i = 0; i < 5; i++) {
maps[i] = Map(get_asset(mapIds[i]));
}
for(size_t i = 0; i < 5; i++) {
maps[i] = Map(get_asset(mapIds[i]));
}

for(auto el : spriteMapping) {
sprites[el.tile_id] = parse_sprite(get_asset(el.asset_id));
}
for(auto el : spriteMapping) {
sprites[el.tile_id] = parse_sprite(get_asset(el.asset_id));
}

uvs = parse_uvs(get_asset(254));
uvs = parse_uvs(get_asset(254));

updateRender();
updateRender();
return true;
} catch(std::exception& e) {
ErrorDialog.push(e.what());
}

ImGui::CloseCurrentPopup();
return true;
return false;
}

static void load_game_dialog() {
Expand Down Expand Up @@ -1229,7 +1234,7 @@ ImGuiID DockSpaceOverViewport() {
if(ImGui::MenuItem("Export Map")) {
static std::string lastPath = std::filesystem::current_path().string();
std::string path;
auto result = NFD::SaveDialog({{"Map", {"map"}}}, std::filesystem::current_path().string().c_str(), path, window);
auto result = NFD::SaveDialog({{"Map", {"map"}}}, lastPath.c_str(), path, window);

if(result == NFD::Result::Error) {
ErrorDialog.push(NFD::GetError());
Expand Down
1 change: 0 additions & 1 deletion src/structures/asset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include <fstream>

#include "../aes.hpp"
#include "../dos_parser.hpp"

static std::array<uint8_t, 16> keys[3] = {
{'G', 'o', 'o', 'd', 'L', 'U', 'c', 'K', 'M', 'y', 'F', 'r', 'i', 'E', 'n', 'd'},
Expand Down
1 change: 0 additions & 1 deletion src/structures/asset.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#pragma once

#include <cstdint>
#include <optional>
#include <span>
#include <vector>

Expand Down
30 changes: 20 additions & 10 deletions src/structures/entity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,16 @@ constexpr TileMapping spriteMapping[] = {
{0x9d, 0xaf, 0x33e},
};

SpriteData parse_sprite(std::span<const uint8_t> data) {
// assert(asset.info.type == AssetType::SpriteData);
assert(data.size() >= 0x30);
inline SpriteData parse_sprite(std::span<const uint8_t> data) {
if(data.size() < 0x30) {
throw std::runtime_error("invalid sprite header size");
}
auto ptr = (char*)data.data();

auto magic = *(uint32_t*)ptr;
assert(magic == 0x0003AC1D);
if(magic != 0x0003AC1D) {
throw std::runtime_error("invalid sprite header");
}

SpriteData out;
out.composite_size.x = *(uint16_t*)(ptr + 4);
Expand All @@ -233,20 +236,27 @@ SpriteData parse_sprite(std::span<const uint8_t> data) {
out.subsprite_count = *(uint8_t*)(ptr + 12);
out.animation_count = *(uint8_t*)(ptr + 13);

assert(data.size() >= 0x30 + out.animation_count * sizeof(SpriteAnimation) + out.layer_count * out.composition_count + out.subsprite_count * sizeof(SubSprite) + out.layer_count * sizeof(SpriteLayer));
auto anim_size = out.animation_count * sizeof(SpriteAnimation);
auto comp_size = out.layer_count * out.composition_count;
auto subs_size = out.subsprite_count * sizeof(SubSprite);
auto layer_size = out.layer_count * sizeof(SpriteLayer);

if(data.size() < 0x30 + anim_size + comp_size + subs_size + layer_size) {
throw std::runtime_error("invalid sprite data size");
}

ptr += 0x30;

out.animations = {(SpriteAnimation*)ptr, ((SpriteAnimation*)ptr) + out.animation_count};
ptr += out.animation_count * sizeof(SpriteAnimation);
ptr += anim_size;

out.compositions = {ptr, ptr + out.layer_count * out.composition_count};
ptr += out.layer_count * out.composition_count;
out.compositions = {ptr, ptr + comp_size};
ptr += comp_size;

out.sub_sprites = {(SubSprite*)ptr, ((SubSprite*)ptr) + out.subsprite_count};
ptr += out.subsprite_count * sizeof(SubSprite);
ptr += subs_size;

out.layers = {(SpriteLayer*)ptr, (SpriteLayer*)(ptr + out.layer_count * sizeof(SpriteLayer))};
out.layers = {(SpriteLayer*)ptr, (SpriteLayer*)(ptr) + out.layer_count};

return out;
}
2 changes: 1 addition & 1 deletion src/structures/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class Map {
8,
0xF0F0CAFE,
};
std::memcpy(data.data() + 0x10, rooms.data(), rooms.size() * sizeof(Room));
std::memcpy(data.data() + sizeof(MapHeader), rooms.data(), rooms.size() * sizeof(Room));

return data;
}
Expand Down
16 changes: 11 additions & 5 deletions src/structures/tile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,27 @@ struct uv_data {
};
static_assert(sizeof(uv_data) == 10);

std::vector<uv_data> parse_uvs(std::span<const uint8_t> data) {
assert(data.size() >= 0xC);
inline std::vector<uv_data> parse_uvs(std::span<const uint8_t> data) {
if(data.size() < 0xC) {
throw std::runtime_error("invalid uv header size");
}

auto magic = *(uint32_t *)data.data();
assert(magic == 0x00B00B00);
if(magic != 0x00B00B00) {
throw std::runtime_error("invalid uv header");
}
auto count = *(uint32_t *)(data.data() + 4);
auto unused = *(uint32_t *)(data.data() + 8); // null in the given asset

assert(data.size() >= 0xC + count * sizeof(uv_data));
if(data.size() < 0xC + count * sizeof(uv_data)) {
throw std::runtime_error("invalid uv data size");
}

auto ptr = (uv_data *)(data.data() + 0xC);
return std::vector(ptr, ptr + count);
}

std::vector<uint8_t> save_uvs(std::span<const uv_data> uvs) {
inline std::vector<uint8_t> save_uvs(std::span<const uv_data> uvs) {
std::vector<uint8_t> data(0xC + uvs.size() * sizeof(uv_data));

*((uint32_t*)data.data() + 0) = 0x00B00B00;
Expand Down
1 change: 1 addition & 0 deletions src/windows/errors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class {
for(auto& e : errors) {
ImGui::Indent();
ImGui::Text(e.c_str());
ImGui::Unindent();
}
}

Expand Down

0 comments on commit cad7be5

Please sign in to comment.