diff --git a/CMakeLists.txt b/CMakeLists.txt index 6834e363..1df5847d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,9 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(wxBUILD_SHARED OFF) -add_subdirectory(libs/lua-5.1.4) -add_subdirectory(libs/cartridge) +add_subdirectory(components/lua-5.1.4) +add_subdirectory(components/cartridge) +add_subdirectory(components/storage) message(STATUS "Fetching wxWidgets...") @@ -65,6 +66,7 @@ if (APPLE) COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ + $ "$/Contents/MacOS/" ) endif () diff --git a/Readme.md b/Readme.md index 081036ac..eced4406 100644 --- a/Readme.md +++ b/Readme.md @@ -22,6 +22,7 @@ This project is a desktop application for simulating and running Wherigo geocach ## Project Structure - `main/` - Application entry point and UI - `libs/cartridge/` - Cartridge parsing and media handling +- `libs/storage/` - Storage management - `libs/lua-5.1.4/` - Lua interpreter ## License diff --git a/libs/cartridge/CMakeLists.txt b/components/cartridge/CMakeLists.txt similarity index 86% rename from libs/cartridge/CMakeLists.txt rename to components/cartridge/CMakeLists.txt index a4a00fe6..1969368c 100644 --- a/libs/cartridge/CMakeLists.txt +++ b/components/cartridge/CMakeLists.txt @@ -21,6 +21,8 @@ add_library(cartridge SHARED ${CARTRIDGE_SRC}) set_target_properties(cartridge PROPERTIES VERSION ${CARTRIDGE_VERSION} SOVERSION ${CARTRIDGE_VERSION_MAJOR} + CXX_STANDARD 23 + CXX_STANDARD_REQUIRED ON ) target_include_directories(cartridge @@ -28,3 +30,8 @@ target_include_directories(cartridge ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}/include ) + +target_link_libraries(cartridge + PRIVATE + storage +) diff --git a/libs/cartridge/include/cartridge/binary_reader.h b/components/cartridge/include/cartridge/binary_reader.h similarity index 78% rename from libs/cartridge/include/cartridge/binary_reader.h rename to components/cartridge/include/cartridge/binary_reader.h index ba3e24e9..f9b3734d 100644 --- a/libs/cartridge/include/cartridge/binary_reader.h +++ b/components/cartridge/include/cartridge/binary_reader.h @@ -17,9 +17,11 @@ // SOFTWARE. #pragma once +#include #include #include #include +#include namespace cartridge { @@ -29,25 +31,25 @@ enum class Endian { Little, Big }; class BinaryReader { public: - explicit BinaryReader(const std::vector &data, + explicit BinaryReader(std::span data, Endian endian = Endian::Little); void seek(int offset, SeekOrigin origin); - uint8_t getByte(); - int16_t getShort(); - uint16_t getUShort(); - int32_t getLong(); - uint32_t getULong(); - double getDouble(); - std::string getASCIIZ(); - [[nodiscard]] const std::vector& data() const { return _data; } + [[nodiscard]] uint8_t getByte(); + [[nodiscard]] int16_t getShort(); + [[nodiscard]] uint16_t getUShort(); + [[nodiscard]] int32_t getLong(); + [[nodiscard]] uint32_t getULong(); + [[nodiscard]] double getDouble(); + [[nodiscard]] std::string getASCIIZ(); + [[nodiscard]] std::span data() const { return _data; } private: - template T readInt(size_t size); - static bool isSystemLittleEndian(); + template [[nodiscard]] T readInt(size_t size); + [[nodiscard]] static bool isSystemLittleEndian(); static void swapBytes(uint8_t *data, size_t size); - const std::vector &_data; + std::span _data; Endian _endian; size_t _index; }; diff --git a/libs/cartridge/include/cartridge/cartridge.h b/components/cartridge/include/cartridge/cartridge.h similarity index 100% rename from libs/cartridge/include/cartridge/cartridge.h rename to components/cartridge/include/cartridge/cartridge.h diff --git a/libs/cartridge/include/cartridge/lat_lng.h b/components/cartridge/include/cartridge/lat_lng.h similarity index 100% rename from libs/cartridge/include/cartridge/lat_lng.h rename to components/cartridge/include/cartridge/lat_lng.h diff --git a/libs/cartridge/include/cartridge/media.h b/components/cartridge/include/cartridge/media.h similarity index 100% rename from libs/cartridge/include/cartridge/media.h rename to components/cartridge/include/cartridge/media.h diff --git a/libs/cartridge/include/cartridge/parser.h b/components/cartridge/include/cartridge/parser.h similarity index 88% rename from libs/cartridge/include/cartridge/parser.h rename to components/cartridge/include/cartridge/parser.h index ff3533a3..382b5063 100644 --- a/libs/cartridge/include/cartridge/parser.h +++ b/components/cartridge/include/cartridge/parser.h @@ -21,4 +21,8 @@ namespace cartridge { std::unique_ptr parseData(const std::vector& bytes); +std::unique_ptr parseFile(const std::string& filePath); + +std::unique_ptr parseCartridge(); + } // namespace cartridge diff --git a/libs/cartridge/src/binary_reader.cpp b/components/cartridge/src/binary_reader.cpp similarity index 92% rename from libs/cartridge/src/binary_reader.cpp rename to components/cartridge/src/binary_reader.cpp index 374f887b..ed8bacd6 100644 --- a/libs/cartridge/src/binary_reader.cpp +++ b/components/cartridge/src/binary_reader.cpp @@ -19,10 +19,12 @@ #include "cartridge/binary_reader.h" #include +#include +#include namespace cartridge { -BinaryReader::BinaryReader(const std::vector &data, +BinaryReader::BinaryReader(std::span data, const Endian endian) : _data(data), _endian(endian), _index(0) {} @@ -78,14 +80,11 @@ std::string BinaryReader::getASCIIZ() { } bool BinaryReader::isSystemLittleEndian() { - uint16_t num = 1; - return *reinterpret_cast(&num) == 1; + return std::endian::native == std::endian::little; } void BinaryReader::swapBytes(uint8_t *data, size_t size) { - for (size_t i = 0; i < size / 2; ++i) { - std::swap(data[i], data[size - 1 - i]); - } + std::ranges::reverse(data, data + size); } } // namespace cartridge diff --git a/libs/cartridge/src/cartridge.cpp b/components/cartridge/src/cartridge.cpp similarity index 81% rename from libs/cartridge/src/cartridge.cpp rename to components/cartridge/src/cartridge.cpp index 6e33e179..a36e1a81 100644 --- a/libs/cartridge/src/cartridge.cpp +++ b/components/cartridge/src/cartridge.cpp @@ -46,39 +46,40 @@ Cartridge::Cartridge(std::string cartridgeGuid, double altitude, std::unique_ptr Cartridge::create(BinaryReader &reader) { try { - uint16_t count = reader.getUShort(); + const uint16_t count = reader.getUShort(); std::map references; for (uint16_t index = 0; index < count; ++index) { - int objectId = reader.getShort(); - int address = reader.getLong(); + const int objectId = reader.getShort(); + const int address = reader.getLong(); references.emplace(objectId, address); } reader.getLong(); // header length - double latitude = reader.getDouble(); - double longitude = reader.getDouble(); - double altitude = reader.getDouble(); + const double latitude = reader.getDouble(); + const double longitude = reader.getDouble(); + const double altitude = reader.getDouble(); reader.getLong(); // unknown 0 reader.getLong(); // unknown 1 - int splashScreenId = reader.getShort(); - int smallIconId = reader.getShort(); - std::string typeOfCartridge = reader.getASCIIZ(); - std::string playerName = reader.getASCIIZ(); + const int splashScreenId = reader.getShort(); + const int smallIconId = reader.getShort(); + const std::string typeOfCartridge = reader.getASCIIZ(); + const std::string playerName = reader.getASCIIZ(); reader.getLong(); // unknown 2 reader.getLong(); // unknown 3 - std::string cartridgeName = reader.getASCIIZ(); - std::string cartridgeGuid = reader.getASCIIZ(); - std::string cartridgeDesc = reader.getASCIIZ(); - std::string startLocationDesc = reader.getASCIIZ(); - std::string version = reader.getASCIIZ(); - std::string author = reader.getASCIIZ(); - std::string company = reader.getASCIIZ(); - std::string recommendedDevice = reader.getASCIIZ(); + const std::string cartridgeName = reader.getASCIIZ(); + const std::string cartridgeGuid = reader.getASCIIZ(); + const std::string cartridgeDesc = reader.getASCIIZ(); + const std::string startLocationDesc = reader.getASCIIZ(); + const std::string version = reader.getASCIIZ(); + const std::string author = reader.getASCIIZ(); + const std::string company = reader.getASCIIZ(); + const std::string recommendedDevice = reader.getASCIIZ(); reader.getLong(); // unknown 4 - std::string completionCode = reader.getASCIIZ(); + const std::string completionCode = reader.getASCIIZ(); // Rohdaten aus dem Reader extrahieren - const std::vector &bytes = reader.data(); + const auto bytes_span = reader.data(); + const std::vector bytes(bytes_span.begin(), bytes_span.end()); return std::make_unique( cartridgeGuid, altitude, author, cartridgeDesc, cartridgeName, company, @@ -114,9 +115,8 @@ std::unique_ptr Cartridge::getMedia(const int objectId) { if (m_lastObject == objectId && m_lastMedia) { return std::make_unique(*m_lastMedia); } - auto it = m_references.find(objectId); - if (it != m_references.end()) { - int address = it->second; + if (auto it = m_references.find(objectId); it != m_references.end()) { + const int address = it->second; BinaryReader reader(m_bytes, Endian::Little); auto media = Media::create(reader, objectId, address); if (media && media->getData().size() < 128000) { diff --git a/libs/cartridge/src/lat_lng.cpp b/components/cartridge/src/lat_lng.cpp similarity index 89% rename from libs/cartridge/src/lat_lng.cpp rename to components/cartridge/src/lat_lng.cpp index e619a88c..556bf632 100644 --- a/libs/cartridge/src/lat_lng.cpp +++ b/components/cartridge/src/lat_lng.cpp @@ -19,8 +19,7 @@ #include "cartridge/lat_lng.h" #include -#include -#include +#include namespace cartridge { @@ -48,9 +47,8 @@ std::string LatLng::_format(double value, const std::string &suffix) { return ""; } const double minutes = (value - degrees) * 60.0; - std::ostringstream oss; - oss << (isNegative ? suffix.substr(1, 1) : suffix.substr(0, 1)) << " " - << degrees << "\u00B0 " << std::fixed << std::setprecision(3) << minutes; - return oss.str(); + return std::format("{} {}\u00B0 {:.3f}", + isNegative ? suffix.substr(1, 1) : suffix.substr(0, 1), + degrees, minutes); } } // namespace cartridge diff --git a/libs/cartridge/src/media.cpp b/components/cartridge/src/media.cpp similarity index 72% rename from libs/cartridge/src/media.cpp rename to components/cartridge/src/media.cpp index fc50850f..9180e074 100644 --- a/libs/cartridge/src/media.cpp +++ b/components/cartridge/src/media.cpp @@ -19,6 +19,7 @@ #include "cartridge/media.h" #include +#include namespace cartridge { @@ -28,67 +29,48 @@ Media::Media(std::string objectType, const std::vector &data) std::unique_ptr Media::create(BinaryReader &reader, const int objectId, const int address) { try { - std::vector data; int objectType = 0; reader.seek(address, SeekOrigin::Begin); - if (objectId == 0) { - data = readMediaData(reader); - } else { - if (reader.getByte() != 0) { - objectType = reader.getLong(); - data = readMediaData(reader); - } - } + std::vector data = (objectId == 0) + ? readMediaData(reader) + : (reader.getByte() != 0) + ? (objectType = reader.getLong(), readMediaData(reader)) + : std::vector{}; + if (!data.empty()) { return std::make_unique(getObjectTypeString(objectType), data); } return nullptr; } catch ([[maybe_unused]] const std::exception &ex) { - // Logging analog zu Dart: print('Exception: $ex'); return nullptr; } } std::vector Media::readMediaData(BinaryReader &reader) { const int32_t length = reader.getLong(); - std::vector data; - data.reserve(length); + std::vector data(length); for (int32_t i = 0; i < length; ++i) { - data.push_back(reader.getByte()); + data[i] = reader.getByte(); } return data; } -std::string Media::getObjectTypeString(int objectType) { +std::string Media::getObjectTypeString(const int objectType) { switch (objectType) { - case -1: - return "deleted"; - case 0: - return "luac"; - case 1: - return "bmp"; - case 2: - return "png"; - case 3: - return "jpg"; - case 4: - return "gif"; - case 17: - return "wav"; - case 18: - return "mp3"; - case 19: - return "fdl"; - case 20: - return "snd"; - case 21: - return "ogg"; - case 33: - return "swf"; - case 49: - return "txt"; - default: - return "invalid (" + std::to_string(objectType) + ")"; + case -1: return "deleted"; + case 0: return "luac"; + case 1: return "bmp"; + case 2: return "png"; + case 3: return "jpg"; + case 4: return "gif"; + case 17: return "wav"; + case 18: return "mp3"; + case 19: return "fdl"; + case 20: return "snd"; + case 21: return "ogg"; + case 33: return "swf"; + case 49: return "txt"; + default: return std::format("invalid ({})", objectType); } } diff --git a/components/cartridge/src/parser.cpp b/components/cartridge/src/parser.cpp new file mode 100644 index 00000000..6d870f54 --- /dev/null +++ b/components/cartridge/src/parser.cpp @@ -0,0 +1,101 @@ +// MIT License +// Copyright (c) 2026 by Peter Siegmund (mars3142) +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include "cartridge/parser.h" +#include "storage/storage.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace cartridge { + +std::unique_ptr parseData(const std::vector &bytes) { + try { + constexpr std::array header = {0x02, 0x0a, 0x43, 0x41, + 0x52, 0x54, 0x00}; + BinaryReader reader(bytes, Endian::Little); + + if (!std::ranges::all_of(header, [&reader](const uint8_t expected) { + return reader.getByte() == expected; + })) { + return nullptr; + } + + return Cartridge::create(reader); + } catch (...) { + return nullptr; + } +} + +std::unique_ptr parseFile(const std::string &filePath) { + storage::Storage storage; + auto result = storage.readFile(filePath); + if (!result) { + std::println(std::cerr, "Fehler beim Lesen der Datei: {}", filePath); + return nullptr; + } + return parseData(*result); +} + +std::unique_ptr parseCartridge() { + auto cartridge = parseFile("/Volumes/Coding/git.mars3142.dev/mars3142/" + "wx_wherigo/cartridges/the_ombos_idol_-_c.gwc"); + if (!cartridge) { + std::println(std::cerr, "Cartridge konnte nicht geladen werden."); + return nullptr; + } + + const int count = cartridge->mediaCount(); + const std::filesystem::path outDir = + "/Volumes/Coding/git.mars3142.dev/mars3142/wx_wherigo/cartridges"; + storage::Storage storage; + + for (const int i : std::views::iota(0, count)) { + auto media = cartridge->getMedia(i); + if (!media) { + std::println(std::cerr, "Media-Objekt an Index {} ist nullptr.", i); + continue; + } + + const auto &data = media->getData(); + if (data.empty()) { + std::println(std::cerr, "Media-Daten an Index {} sind leer.", i); + continue; + } + + std::string ext = media->getObjectType(); + if (ext.empty()) { + std::println(std::cerr, "Media-Extension an Index {} ist leer.", i); + ext = "bin"; + } + + const std::filesystem::path outFile = outDir / std::format("file{}.{}", i, ext); + + if (auto writeResult = storage.writeFile(outFile.string(), data); !writeResult) { + std::println(std::cerr, "Fehler beim Schreiben der Datei: {}", outFile.string()); + } + } + return cartridge; +} + +} // namespace cartridge diff --git a/libs/cartridge/version.h.in b/components/cartridge/version.h.in similarity index 100% rename from libs/cartridge/version.h.in rename to components/cartridge/version.h.in diff --git a/components/storage/CMakeLists.txt b/components/storage/CMakeLists.txt new file mode 100644 index 00000000..3ead2dbb --- /dev/null +++ b/components/storage/CMakeLists.txt @@ -0,0 +1,26 @@ +set(STORAGE_VERSION_MAJOR 1) +set(STORAGE_VERSION_MINOR 0) +set(STORAGE_VERSION_PATCH 0) +set(STORAGE_VERSION "${STORAGE_VERSION_MAJOR}.${STORAGE_VERSION_MINOR}.${STORAGE_VERSION_PATCH}") + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/version.h.in + ${CMAKE_CURRENT_BINARY_DIR}/include/storage/version.h + @ONLY +) + +set(STORAGE_SRC + src/storage.cpp +) + +add_library(storage SHARED ${STORAGE_SRC}) +set_target_properties(storage PROPERTIES + VERSION ${STORAGE_VERSION} + SOVERSION ${STORAGE_VERSION_MAJOR} +) + +target_include_directories(storage + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_BINARY_DIR}/include +) diff --git a/components/storage/include/storage/storage.h b/components/storage/include/storage/storage.h new file mode 100644 index 00000000..cc9ce371 --- /dev/null +++ b/components/storage/include/storage/storage.h @@ -0,0 +1,50 @@ +// MIT License +// Copyright (c) 2026 by Peter Siegmund (mars3142) +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include "storage/storage_error.h" + +#include +#include +#include + +namespace storage { + +class Storage { +public: + /** + * Liest eine Datei von einem Pfad. + * @param path Der Dateipfad. + * @return Ein expected mit den Dateidaten oder einem StorageError. + */ + [[nodiscard]] std::expected, StorageError> readFile( + const std::string &path) const; + + /** + * Schreibt Daten in eine Datei. + * @param path Der Dateipfad. + * @param data Die zu schreibenden Daten. + * @return Ein expected oder einem StorageError. + */ + [[nodiscard]] std::expected writeFile( + const std::string &path, + const std::vector &data) const; +}; + +} // namespace storage diff --git a/libs/cartridge/src/parser.cpp b/components/storage/include/storage/storage_error.h similarity index 64% rename from libs/cartridge/src/parser.cpp rename to components/storage/include/storage/storage_error.h index eeb0cfbd..9fdb782d 100644 --- a/libs/cartridge/src/parser.cpp +++ b/components/storage/include/storage/storage_error.h @@ -16,29 +16,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -#include "cartridge/parser.h" +#pragma once -#include -#include -#include -#include +namespace storage { -namespace cartridge { +enum class StorageError { + FileNotFound, + ReadError, + WriteError, +}; -std::unique_ptr parseData(const std::vector &bytes) { - try { - constexpr std::array header = {0x02, 0x0a, 0x43, 0x41, - 0x52, 0x54, 0x00}; - BinaryReader reader(bytes, Endian::Little); - for (const unsigned char i : header) { - if (reader.getByte() != i) { - return nullptr; - } - } - return Cartridge::create(reader); - } catch (...) { - return nullptr; - } -} - -} // namespace cartridge +} // namespace storage diff --git a/components/storage/src/storage.cpp b/components/storage/src/storage.cpp new file mode 100644 index 00000000..4f720e15 --- /dev/null +++ b/components/storage/src/storage.cpp @@ -0,0 +1,59 @@ +// MIT License +// Copyright (c) 2026 by Peter Siegmund (mars3142) +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include "storage/storage.h" + +#include + +namespace storage { + +std::expected, StorageError> Storage::readFile( + const std::string &path) const { + std::ifstream file(path, std::ios::binary | std::ios::ate); + if (!file) { + return std::unexpected(StorageError::FileNotFound); + } + + const std::streamsize size = file.tellg(); + if (size < 0) { + return std::unexpected(StorageError::ReadError); + } + file.seekg(0, std::ios::beg); + + std::vector data(static_cast(size)); + if (!file.read(reinterpret_cast(data.data()), size)) { + return std::unexpected(StorageError::ReadError); + } + return data; +} + +std::expected Storage::writeFile( + const std::string &path, + const std::vector &data) const { + std::ofstream file(path, std::ios::binary); + if (!file) { + return std::unexpected(StorageError::WriteError); + } + file.write(reinterpret_cast(data.data()), data.size()); + if (!file.good()) { + return std::unexpected(StorageError::WriteError); + } + return {}; +} + +} // namespace storage diff --git a/components/storage/version.h.in b/components/storage/version.h.in new file mode 100644 index 00000000..9c27a4eb --- /dev/null +++ b/components/storage/version.h.in @@ -0,0 +1,7 @@ +#pragma once + +#define STORAGE_VERSION_MAJOR @STORAGE_VERSION_MAJOR@ +#define STORAGE_VERSION_MINOR @STORAGE_VERSION_MINOR@ +#define STORAGE_VERSION_PATCH @STORAGE_VERSION_PATCH@ +#define STORAGE_VERSION "@STORAGE_VERSION@" + diff --git a/main/src/cApp.cpp b/main/src/cApp.cpp index 57285457..b86e218c 100644 --- a/main/src/cApp.cpp +++ b/main/src/cApp.cpp @@ -1,8 +1,11 @@ #include "cApp.h" #include "ui/cFrame.h" +#include + bool cApp::OnInit() { + auto cart = cartridge::parseCartridge(); auto *frame = new cFrame(); return frame->Show(true); }