add cartridge reader
Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -108,4 +108,6 @@ CMakeUserPresets.json
|
|||||||
# External projects
|
# External projects
|
||||||
*-prefix/
|
*-prefix/
|
||||||
|
|
||||||
# End of https://www.toptal.com/developers/gitignore/api/cmake,clion+all
|
# End of https://www.toptal.com/developers/gitignore/api/cmake,clion+all
|
||||||
|
|
||||||
|
cartridges/
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
cmake_minimum_required(VERSION 3.14)
|
cmake_minimum_required(VERSION 3.21)
|
||||||
|
|
||||||
project(wx_wherigo LANGUAGES CXX)
|
project(wxWherigo LANGUAGES CXX)
|
||||||
|
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_C_STANDARD 23)
|
||||||
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
set(wxBUILD_SHARED OFF)
|
set(wxBUILD_SHARED OFF)
|
||||||
|
|
||||||
|
add_subdirectory(libs/lua-5.1.4)
|
||||||
|
add_subdirectory(libs/cartridge)
|
||||||
|
|
||||||
message(STATUS "Fetching wxWidgets...")
|
message(STATUS "Fetching wxWidgets...")
|
||||||
|
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
@@ -22,16 +26,45 @@ FetchContent_MakeAvailable(wxWidgets)
|
|||||||
message(STATUS "Configure project....")
|
message(STATUS "Configure project....")
|
||||||
|
|
||||||
set(SRCS
|
set(SRCS
|
||||||
src/main.cpp
|
main/src/main.cpp
|
||||||
src/MyFrame.cpp
|
main/src/cApp.cpp
|
||||||
src/WxWherigo.cpp
|
main/src/ui/cFrame.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(include)
|
if (APPLE)
|
||||||
add_executable(${PROJECT_NAME} ${SRCS})
|
add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${SRCS})
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||||
|
BUNDLE True
|
||||||
|
MACOSX_BUNDLE_GUI_IDENTIFIER dev.mars3142.${PROJECT_NAME}
|
||||||
|
MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME}
|
||||||
|
MACOSX_BUNDLE_BUNDLE_VERSION "0.1"
|
||||||
|
MACOSX_BUNDLE_SHORT_VERSION_STRING "0.1"
|
||||||
|
#MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/cmake/customtemplate.plist.in
|
||||||
|
INSTALL_RPATH "@executable_path"
|
||||||
|
)
|
||||||
|
else ()
|
||||||
|
add_executable(${PROJECT_NAME} ${SRCS})
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# Haupt-Includes
|
||||||
|
include_directories(main/include)
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME}
|
target_link_libraries(${PROJECT_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
wxcore
|
wxcore
|
||||||
wxnet
|
wxnet
|
||||||
wxbase
|
wxbase
|
||||||
|
lua
|
||||||
|
cartridge
|
||||||
|
storage
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Kopiere die .dylib-Dateien ins Bundle
|
||||||
|
if (APPLE)
|
||||||
|
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
|
$<TARGET_FILE:lua>
|
||||||
|
$<TARGET_FILE:cartridge>
|
||||||
|
"$<TARGET_BUNDLE_DIR:${PROJECT_NAME}>/Contents/MacOS/"
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
|||||||
9
License.md
Normal file
9
License.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# 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.
|
||||||
31
Readme.md
Normal file
31
Readme.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Wherigo Simulator
|
||||||
|
|
||||||
|
This project is a desktop application for simulating and running Wherigo geocaches. It allows you to play Wherigo cartridges directly on your computer, making it possible to experience geocaching adventures without a GPS device or mobile app.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- Load and execute Wherigo cartridges (.gwc files)
|
||||||
|
- Simulate geocaching locations and actions
|
||||||
|
- Desktop interface for easy navigation and interaction
|
||||||
|
- Support for media and cartridge data
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- C++23 or newer
|
||||||
|
- wxWidgets (for GUI)
|
||||||
|
- Lua 5.1.4 (for cartridge execution)
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
1. Clone this repository.
|
||||||
|
2. Build the project using CMake and your preferred compiler.
|
||||||
|
3. Download a Wherigo cartridge (PocketPC format) from [wherigo.com](https://wherigo.com)
|
||||||
|
4. Open it in the application.
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
- `main/` - Application entry point and UI
|
||||||
|
- `libs/cartridge/` - Cartridge parsing and media handling
|
||||||
|
- `libs/lua-5.1.4/` - Lua interpreter
|
||||||
|
|
||||||
|
## License
|
||||||
|
This project is licensed under the MIT License. See `License.md` for details.
|
||||||
|
|
||||||
|
## Author
|
||||||
|
Peter Siegmund (mars3142)
|
||||||
30
libs/cartridge/CMakeLists.txt
Normal file
30
libs/cartridge/CMakeLists.txt
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
set(CARTRIDGE_VERSION_MAJOR 1)
|
||||||
|
set(CARTRIDGE_VERSION_MINOR 0)
|
||||||
|
set(CARTRIDGE_VERSION_PATCH 0)
|
||||||
|
set(CARTRIDGE_VERSION "${CARTRIDGE_VERSION_MAJOR}.${CARTRIDGE_VERSION_MINOR}.${CARTRIDGE_VERSION_PATCH}")
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/version.h.in
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/include/cartridge/version.h
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
|
||||||
|
set(CARTRIDGE_SRC
|
||||||
|
src/binary_reader.cpp
|
||||||
|
src/cartridge.cpp
|
||||||
|
src/lat_lng.cpp
|
||||||
|
src/media.cpp
|
||||||
|
src/parser.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(cartridge SHARED ${CARTRIDGE_SRC})
|
||||||
|
set_target_properties(cartridge PROPERTIES
|
||||||
|
VERSION ${CARTRIDGE_VERSION}
|
||||||
|
SOVERSION ${CARTRIDGE_VERSION_MAJOR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(cartridge
|
||||||
|
PUBLIC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/include
|
||||||
|
)
|
||||||
72
libs/cartridge/include/cartridge/binary_reader.h
Normal file
72
libs/cartridge/include/cartridge/binary_reader.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
// 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 <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace cartridge {
|
||||||
|
|
||||||
|
enum class SeekOrigin { Begin, Current, End };
|
||||||
|
|
||||||
|
enum class Endian { Little, Big };
|
||||||
|
|
||||||
|
class BinaryReader {
|
||||||
|
public:
|
||||||
|
explicit BinaryReader(const std::vector<uint8_t> &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<uint8_t>& data() const { return _data; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename T> T readInt(size_t size);
|
||||||
|
static bool isSystemLittleEndian();
|
||||||
|
static void swapBytes(uint8_t *data, size_t size);
|
||||||
|
|
||||||
|
const std::vector<uint8_t> &_data;
|
||||||
|
Endian _endian;
|
||||||
|
size_t _index;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T> T BinaryReader::readInt(const size_t size) {
|
||||||
|
if (_index + size > _data.size())
|
||||||
|
throw std::out_of_range("readInt out of range");
|
||||||
|
T value = 0;
|
||||||
|
if (_endian == Endian::Little) {
|
||||||
|
for (size_t i = 0; i < size; ++i) {
|
||||||
|
value |= static_cast<T>(_data[_index + i]) << (8 * i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < size; ++i) {
|
||||||
|
value = (value << 8) | _data[_index + i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_index += size;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cartridge
|
||||||
94
libs/cartridge/include/cartridge/cartridge.h
Normal file
94
libs/cartridge/include/cartridge/cartridge.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
// 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 "cartridge/binary_reader.h"
|
||||||
|
#include "cartridge/lat_lng.h"
|
||||||
|
#include "cartridge/media.h"
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace cartridge {
|
||||||
|
|
||||||
|
class Cartridge {
|
||||||
|
public:
|
||||||
|
// Factory method to create Cartridge from BinaryReader
|
||||||
|
static std::unique_ptr<Cartridge> create(BinaryReader &reader);
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
[[nodiscard]] double altitude() const;
|
||||||
|
[[nodiscard]] const std::string &author() const;
|
||||||
|
[[nodiscard]] const LatLng &latLng() const;
|
||||||
|
[[nodiscard]] const std::string &cartridgeName() const;
|
||||||
|
[[nodiscard]] const std::string &cartridgeDesc() const;
|
||||||
|
[[nodiscard]] const std::string &cartridgeGuid() const;
|
||||||
|
[[nodiscard]] const std::string &typeOfCartridge() const;
|
||||||
|
[[nodiscard]] const std::string &playerName() const;
|
||||||
|
[[nodiscard]] const std::string &startLocationDesc() const;
|
||||||
|
[[nodiscard]] const std::string &version() const;
|
||||||
|
[[nodiscard]] const std::string &company() const;
|
||||||
|
[[nodiscard]] const std::string &recommendDevice() const;
|
||||||
|
[[nodiscard]] const std::string &completionCode() const;
|
||||||
|
|
||||||
|
// Media methods
|
||||||
|
std::unique_ptr<Media> getMedia(int objectId);
|
||||||
|
[[nodiscard]] int mediaCount() const;
|
||||||
|
std::unique_ptr<Media> splashScreen();
|
||||||
|
std::unique_ptr<Media> smallIcon();
|
||||||
|
std::unique_ptr<Media> luac();
|
||||||
|
|
||||||
|
// Comparison operators
|
||||||
|
bool operator==(const Cartridge &other) const;
|
||||||
|
bool operator!=(const Cartridge &other) const;
|
||||||
|
|
||||||
|
Cartridge(std::string cartridgeGuid, double altitude, std::string author,
|
||||||
|
std::string cartridgeDesc, std::string cartridgeName,
|
||||||
|
std::string company, std::string completionCode, LatLng latLng,
|
||||||
|
std::string playerName, std::string recommendDevice,
|
||||||
|
int smallIconId, int splashScreenId, std::string startLocationDesc,
|
||||||
|
std::string typeOfCartridge, std::string version,
|
||||||
|
std::map<int, int> references, std::vector<uint8_t> bytes);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Fields
|
||||||
|
std::string m_cartridgeGuid;
|
||||||
|
double m_altitude;
|
||||||
|
std::string m_author;
|
||||||
|
std::string m_cartridgeDesc;
|
||||||
|
std::string m_cartridgeName;
|
||||||
|
std::string m_company;
|
||||||
|
std::string m_completionCode;
|
||||||
|
LatLng m_latLng;
|
||||||
|
std::string m_playerName;
|
||||||
|
std::string m_recommendDevice;
|
||||||
|
int m_smallIconId;
|
||||||
|
int m_splashScreenId;
|
||||||
|
std::string m_startLocationDesc;
|
||||||
|
std::string m_typeOfCartridge;
|
||||||
|
std::string m_version;
|
||||||
|
std::map<int, int> m_references;
|
||||||
|
std::vector<uint8_t> m_bytes;
|
||||||
|
|
||||||
|
int m_lastObject = -1;
|
||||||
|
std::unique_ptr<Media> m_lastMedia;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cartridge
|
||||||
36
libs/cartridge/include/cartridge/lat_lng.h
Normal file
36
libs/cartridge/include/cartridge/lat_lng.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
// 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 <string>
|
||||||
|
|
||||||
|
namespace cartridge {
|
||||||
|
class LatLng {
|
||||||
|
double m_latitude;
|
||||||
|
double m_longitude;
|
||||||
|
|
||||||
|
static std::string _format(double value, const std::string& suffix);
|
||||||
|
|
||||||
|
public:
|
||||||
|
LatLng(double latitude, double longitude);
|
||||||
|
[[nodiscard]] std::string latitude() const;
|
||||||
|
[[nodiscard]] std::string longitude() const;
|
||||||
|
[[nodiscard]] std::string toString() const;
|
||||||
|
};
|
||||||
|
}
|
||||||
66
libs/cartridge/include/cartridge/media.h
Normal file
66
libs/cartridge/include/cartridge/media.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
// 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 "cartridge/binary_reader.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace cartridge {
|
||||||
|
|
||||||
|
enum class ObjectType {
|
||||||
|
Deleted = -1,
|
||||||
|
Luac = 0,
|
||||||
|
Bmp = 1,
|
||||||
|
Png = 2,
|
||||||
|
Jpg = 3,
|
||||||
|
Gif = 4,
|
||||||
|
Wav = 17,
|
||||||
|
Mp3 = 18,
|
||||||
|
Fdl = 19,
|
||||||
|
Snd = 20,
|
||||||
|
Ogg = 21,
|
||||||
|
Swf = 33,
|
||||||
|
Txt = 49,
|
||||||
|
Invalid = -9999
|
||||||
|
};
|
||||||
|
|
||||||
|
class Media {
|
||||||
|
public:
|
||||||
|
Media(std::string objectType, const std::vector<uint8_t> &data);
|
||||||
|
|
||||||
|
static std::unique_ptr<Media> create(BinaryReader &reader, int objectId,
|
||||||
|
int address);
|
||||||
|
|
||||||
|
bool operator==(const Media &other) const;
|
||||||
|
[[nodiscard]] std::size_t hash() const;
|
||||||
|
|
||||||
|
[[nodiscard]] const std::vector<uint8_t> &getData() const { return data; }
|
||||||
|
[[nodiscard]] const std::string &getObjectType() const { return objectType; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::vector<uint8_t> readMediaData(BinaryReader &reader);
|
||||||
|
static std::string getObjectTypeString(int objectType);
|
||||||
|
|
||||||
|
std::string objectType;
|
||||||
|
std::vector<uint8_t> data;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace cartridge
|
||||||
24
libs/cartridge/include/cartridge/parser.h
Normal file
24
libs/cartridge/include/cartridge/parser.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "cartridge/cartridge.h"
|
||||||
|
|
||||||
|
namespace cartridge {
|
||||||
|
|
||||||
|
std::unique_ptr<Cartridge> parseData(const std::vector<uint8_t>& bytes);
|
||||||
|
|
||||||
|
} // namespace cartridge
|
||||||
91
libs/cartridge/src/binary_reader.cpp
Normal file
91
libs/cartridge/src/binary_reader.cpp
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
// 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/binary_reader.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace cartridge {
|
||||||
|
|
||||||
|
BinaryReader::BinaryReader(const std::vector<uint8_t> &data,
|
||||||
|
const Endian endian)
|
||||||
|
: _data(data), _endian(endian), _index(0) {}
|
||||||
|
|
||||||
|
void BinaryReader::seek(const int offset, const SeekOrigin origin) {
|
||||||
|
switch (origin) {
|
||||||
|
case SeekOrigin::Begin:
|
||||||
|
_index = offset;
|
||||||
|
break;
|
||||||
|
case SeekOrigin::Current:
|
||||||
|
_index += offset;
|
||||||
|
break;
|
||||||
|
case SeekOrigin::End:
|
||||||
|
_index = _data.size() - offset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BinaryReader::getByte() {
|
||||||
|
if (_index >= _data.size())
|
||||||
|
throw std::out_of_range("getByte out of range");
|
||||||
|
return _data[_index++];
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t BinaryReader::getShort() { return readInt<int16_t>(2); }
|
||||||
|
|
||||||
|
uint16_t BinaryReader::getUShort() { return readInt<uint16_t>(2); }
|
||||||
|
|
||||||
|
int32_t BinaryReader::getLong() { return readInt<int32_t>(4); }
|
||||||
|
|
||||||
|
uint32_t BinaryReader::getULong() { return readInt<uint32_t>(4); }
|
||||||
|
|
||||||
|
double BinaryReader::getDouble() {
|
||||||
|
if (_index + 8 > _data.size())
|
||||||
|
throw std::out_of_range("getDouble out of range");
|
||||||
|
double value;
|
||||||
|
std::memcpy(&value, &_data[_index], 8);
|
||||||
|
if ((_endian == Endian::Little) != isSystemLittleEndian()) {
|
||||||
|
swapBytes(reinterpret_cast<uint8_t *>(&value), 8);
|
||||||
|
}
|
||||||
|
_index += 8;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string BinaryReader::getASCIIZ() {
|
||||||
|
std::string result;
|
||||||
|
uint8_t byte = 0;
|
||||||
|
do {
|
||||||
|
byte = getByte();
|
||||||
|
if (byte != 0)
|
||||||
|
result += static_cast<char>(byte);
|
||||||
|
} while (byte != 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BinaryReader::isSystemLittleEndian() {
|
||||||
|
uint16_t num = 1;
|
||||||
|
return *reinterpret_cast<uint8_t *>(&num) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cartridge
|
||||||
148
libs/cartridge/src/cartridge.cpp
Normal file
148
libs/cartridge/src/cartridge.cpp
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
// 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/cartridge.h"
|
||||||
|
#include "cartridge/binary_reader.h"
|
||||||
|
#include "cartridge/lat_lng.h"
|
||||||
|
#include "cartridge/media.h"
|
||||||
|
|
||||||
|
namespace cartridge {
|
||||||
|
|
||||||
|
Cartridge::Cartridge(std::string cartridgeGuid, double altitude,
|
||||||
|
std::string author, std::string cartridgeDesc,
|
||||||
|
std::string cartridgeName, std::string company,
|
||||||
|
std::string completionCode, LatLng latLng,
|
||||||
|
std::string playerName, std::string recommendDevice,
|
||||||
|
int smallIconId, int splashScreenId,
|
||||||
|
std::string startLocationDesc, std::string typeOfCartridge,
|
||||||
|
std::string version, std::map<int, int> references,
|
||||||
|
std::vector<uint8_t> bytes)
|
||||||
|
: m_cartridgeGuid(std::move(cartridgeGuid)), m_altitude(altitude),
|
||||||
|
m_author(std::move(author)), m_cartridgeDesc(std::move(cartridgeDesc)),
|
||||||
|
m_cartridgeName(std::move(cartridgeName)), m_company(std::move(company)),
|
||||||
|
m_completionCode(std::move(completionCode)), m_latLng(latLng),
|
||||||
|
m_playerName(std::move(playerName)),
|
||||||
|
m_recommendDevice(std::move(recommendDevice)), m_smallIconId(smallIconId),
|
||||||
|
m_splashScreenId(splashScreenId),
|
||||||
|
m_startLocationDesc(std::move(startLocationDesc)),
|
||||||
|
m_typeOfCartridge(std::move(typeOfCartridge)),
|
||||||
|
m_version(std::move(version)), m_references(std::move(references)),
|
||||||
|
m_bytes(std::move(bytes)) {}
|
||||||
|
|
||||||
|
std::unique_ptr<Cartridge> Cartridge::create(BinaryReader &reader) {
|
||||||
|
try {
|
||||||
|
uint16_t count = reader.getUShort();
|
||||||
|
std::map<int, int> references;
|
||||||
|
for (uint16_t index = 0; index < count; ++index) {
|
||||||
|
int objectId = reader.getShort();
|
||||||
|
int address = reader.getLong();
|
||||||
|
references.emplace(objectId, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.getLong(); // header length
|
||||||
|
double latitude = reader.getDouble();
|
||||||
|
double longitude = reader.getDouble();
|
||||||
|
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();
|
||||||
|
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();
|
||||||
|
reader.getLong(); // unknown 4
|
||||||
|
std::string completionCode = reader.getASCIIZ();
|
||||||
|
|
||||||
|
// Rohdaten aus dem Reader extrahieren
|
||||||
|
const std::vector<uint8_t> &bytes = reader.data();
|
||||||
|
|
||||||
|
return std::make_unique<Cartridge>(
|
||||||
|
cartridgeGuid, altitude, author, cartridgeDesc, cartridgeName, company,
|
||||||
|
completionCode, LatLng(latitude, longitude), playerName,
|
||||||
|
recommendedDevice, smallIconId, splashScreenId, startLocationDesc,
|
||||||
|
typeOfCartridge, version, references, bytes);
|
||||||
|
} catch (const std::exception &) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double Cartridge::altitude() const { return m_altitude; }
|
||||||
|
const std::string &Cartridge::author() const { return m_author; }
|
||||||
|
const LatLng &Cartridge::latLng() const { return m_latLng; }
|
||||||
|
const std::string &Cartridge::cartridgeName() const { return m_cartridgeName; }
|
||||||
|
const std::string &Cartridge::cartridgeDesc() const { return m_cartridgeDesc; }
|
||||||
|
const std::string &Cartridge::cartridgeGuid() const { return m_cartridgeGuid; }
|
||||||
|
const std::string &Cartridge::typeOfCartridge() const {
|
||||||
|
return m_typeOfCartridge;
|
||||||
|
}
|
||||||
|
const std::string &Cartridge::playerName() const { return m_playerName; }
|
||||||
|
const std::string &Cartridge::startLocationDesc() const {
|
||||||
|
return m_startLocationDesc;
|
||||||
|
}
|
||||||
|
const std::string &Cartridge::version() const { return m_version; }
|
||||||
|
const std::string &Cartridge::company() const { return m_company; }
|
||||||
|
const std::string &Cartridge::recommendDevice() const {
|
||||||
|
return m_recommendDevice;
|
||||||
|
}
|
||||||
|
const std::string &Cartridge::completionCode() const { return m_completionCode; }
|
||||||
|
|
||||||
|
std::unique_ptr<Media> Cartridge::getMedia(const int objectId) {
|
||||||
|
if (m_lastObject == objectId && m_lastMedia) {
|
||||||
|
return std::make_unique<Media>(*m_lastMedia);
|
||||||
|
}
|
||||||
|
auto it = m_references.find(objectId);
|
||||||
|
if (it != m_references.end()) {
|
||||||
|
int address = it->second;
|
||||||
|
BinaryReader reader(m_bytes, Endian::Little);
|
||||||
|
auto media = Media::create(reader, objectId, address);
|
||||||
|
if (media && media->getData().size() < 128000) {
|
||||||
|
m_lastObject = objectId;
|
||||||
|
m_lastMedia = std::make_unique<Media>(*media);
|
||||||
|
}
|
||||||
|
return media;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Cartridge::mediaCount() const {
|
||||||
|
return static_cast<int>(m_references.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Media> Cartridge::splashScreen() {
|
||||||
|
return getMedia(m_splashScreenId);
|
||||||
|
}
|
||||||
|
std::unique_ptr<Media> Cartridge::smallIcon() { return getMedia(m_smallIconId); }
|
||||||
|
std::unique_ptr<Media> Cartridge::luac() { return getMedia(0); }
|
||||||
|
|
||||||
|
bool Cartridge::operator==(const Cartridge &other) const {
|
||||||
|
return m_cartridgeGuid == other.m_cartridgeGuid;
|
||||||
|
}
|
||||||
|
bool Cartridge::operator!=(const Cartridge &other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cartridge
|
||||||
56
libs/cartridge/src/lat_lng.cpp
Normal file
56
libs/cartridge/src/lat_lng.cpp
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
// 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/lat_lng.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace cartridge {
|
||||||
|
|
||||||
|
LatLng::LatLng(const double latitude, const double longitude)
|
||||||
|
: m_latitude(latitude), m_longitude(longitude) {}
|
||||||
|
|
||||||
|
std::string LatLng::latitude() const { return _format(m_latitude, "NS"); }
|
||||||
|
|
||||||
|
std::string LatLng::longitude() const { return _format(m_longitude, "EW"); }
|
||||||
|
|
||||||
|
std::string LatLng::toString() const {
|
||||||
|
const std::string lat = latitude();
|
||||||
|
const std::string lon = longitude();
|
||||||
|
if (!lat.empty() && !lon.empty()) {
|
||||||
|
return lat + " " + lon;
|
||||||
|
}
|
||||||
|
return lat + lon;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string LatLng::_format(double value, const std::string &suffix) {
|
||||||
|
const bool isNegative = value < 0;
|
||||||
|
value = std::abs(value);
|
||||||
|
const int degrees = static_cast<int>(std::floor(value));
|
||||||
|
if (degrees == 360) {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
} // namespace cartridge
|
||||||
107
libs/cartridge/src/media.cpp
Normal file
107
libs/cartridge/src/media.cpp
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
// 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/media.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace cartridge {
|
||||||
|
|
||||||
|
Media::Media(std::string objectType, const std::vector<uint8_t> &data)
|
||||||
|
: objectType(std::move(objectType)), data(data) {}
|
||||||
|
|
||||||
|
std::unique_ptr<Media> Media::create(BinaryReader &reader, const int objectId,
|
||||||
|
const int address) {
|
||||||
|
try {
|
||||||
|
std::vector<uint8_t> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!data.empty()) {
|
||||||
|
return std::make_unique<Media>(getObjectTypeString(objectType), data);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
} catch ([[maybe_unused]] const std::exception &ex) {
|
||||||
|
// Logging analog zu Dart: print('Exception: $ex');
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> Media::readMediaData(BinaryReader &reader) {
|
||||||
|
const int32_t length = reader.getLong();
|
||||||
|
std::vector<uint8_t> data;
|
||||||
|
data.reserve(length);
|
||||||
|
for (int32_t i = 0; i < length; ++i) {
|
||||||
|
data.push_back(reader.getByte());
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Media::getObjectTypeString(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) + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Media::operator==(const Media &other) const {
|
||||||
|
return objectType == other.objectType && data == other.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t Media::hash() const {
|
||||||
|
const std::size_t h1 = std::hash<std::string>{}(objectType);
|
||||||
|
std::size_t h2 = 0;
|
||||||
|
for (const auto b : data)
|
||||||
|
h2 ^= std::hash<uint8_t>{}(b) + 0x9e3779b9 + (h2 << 6) + (h2 >> 2);
|
||||||
|
return h1 ^ (h2 << 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cartridge
|
||||||
44
libs/cartridge/src/parser.cpp
Normal file
44
libs/cartridge/src/parser.cpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// 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 <array>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace cartridge {
|
||||||
|
|
||||||
|
std::unique_ptr<Cartridge> parseData(const std::vector<uint8_t> &bytes) {
|
||||||
|
try {
|
||||||
|
constexpr std::array<uint8_t, 7> 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
|
||||||
7
libs/cartridge/version.h.in
Normal file
7
libs/cartridge/version.h.in
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define CARTRIDGE_VERSION_MAJOR @CARTRIDGE_VERSION_MAJOR@
|
||||||
|
#define CARTRIDGE_VERSION_MINOR @CARTRIDGE_VERSION_MINOR@
|
||||||
|
#define CARTRIDGE_VERSION_PATCH @CARTRIDGE_VERSION_PATCH@
|
||||||
|
#define CARTRIDGE_VERSION "@CARTRIDGE_VERSION@"
|
||||||
|
|
||||||
72
libs/lua-5.1.4/CMakeLists.txt
Normal file
72
libs/lua-5.1.4/CMakeLists.txt
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
# CMake build for Lua 5.1.4
|
||||||
|
cmake_minimum_required(VERSION 3.21)
|
||||||
|
project(lua LANGUAGES C)
|
||||||
|
|
||||||
|
set(LUA_SOURCES
|
||||||
|
src/lapi.c
|
||||||
|
src/lcode.c
|
||||||
|
src/ldebug.c
|
||||||
|
src/ldo.c
|
||||||
|
src/ldump.c
|
||||||
|
src/lfunc.c
|
||||||
|
src/lgc.c
|
||||||
|
src/llex.c
|
||||||
|
src/lmem.c
|
||||||
|
src/loadlib.c
|
||||||
|
src/lobject.c
|
||||||
|
src/lopcodes.c
|
||||||
|
src/lparser.c
|
||||||
|
src/lstate.c
|
||||||
|
src/lstring.c
|
||||||
|
src/ltable.c
|
||||||
|
src/ltm.c
|
||||||
|
src/lundump.c
|
||||||
|
src/lvm.c
|
||||||
|
src/lzio.c
|
||||||
|
src/lauxlib.c
|
||||||
|
src/lbaselib.c
|
||||||
|
src/ldblib.c
|
||||||
|
src/liolib.c
|
||||||
|
src/lmathlib.c
|
||||||
|
src/loslib.c
|
||||||
|
src/ltablib.c
|
||||||
|
src/lstrlib.c
|
||||||
|
src/linit.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set(LUA_VERSION_MAJOR 5)
|
||||||
|
set(LUA_VERSION_MINOR 1)
|
||||||
|
set(LUA_VERSION_PATCH 4)
|
||||||
|
set(LUA_VERSION "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}")
|
||||||
|
|
||||||
|
add_library(lua SHARED ${LUA_SOURCES})
|
||||||
|
set_target_properties(lua PROPERTIES
|
||||||
|
VERSION ${LUA_VERSION}
|
||||||
|
SOVERSION ${LUA_VERSION_MAJOR}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(lua_bin
|
||||||
|
src/lua.c
|
||||||
|
)
|
||||||
|
target_link_libraries(lua_bin PRIVATE lua)
|
||||||
|
target_include_directories(lua_bin PRIVATE src)
|
||||||
|
|
||||||
|
add_executable(luac_bin
|
||||||
|
src/luac.c
|
||||||
|
src/print.c
|
||||||
|
)
|
||||||
|
target_link_libraries(luac_bin PRIVATE lua)
|
||||||
|
target_include_directories(luac_bin PRIVATE src)
|
||||||
|
|
||||||
|
# Header files
|
||||||
|
set(LUA_HEADERS
|
||||||
|
${LUA_SRC_DIR}/lua.h
|
||||||
|
${LUA_SRC_DIR}/luaconf.h
|
||||||
|
${LUA_SRC_DIR}/lualib.h
|
||||||
|
${LUA_SRC_DIR}/lauxlib.h
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(lua
|
||||||
|
PUBLIC
|
||||||
|
${LUA_SRC_DIR}
|
||||||
|
)
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <wx/wx.h>
|
#include <wx/wx.h>
|
||||||
|
|
||||||
class WxWherigo : public wxApp
|
class cApp : public wxApp
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool OnInit() override;
|
bool OnInit() override;
|
||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
#include <wx/wx.h>
|
#include <wx/wx.h>
|
||||||
|
|
||||||
class MyFrame : public wxFrame
|
class cFrame : public wxMDIParentFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MyFrame();
|
cFrame();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnHello(wxCommandEvent& event);
|
void OnHello(wxCommandEvent& event);
|
||||||
8
main/src/cApp.cpp
Normal file
8
main/src/cApp.cpp
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#include "cApp.h"
|
||||||
|
#include "ui/cFrame.h"
|
||||||
|
|
||||||
|
bool cApp::OnInit()
|
||||||
|
{
|
||||||
|
auto *frame = new cFrame();
|
||||||
|
return frame->Show(true);
|
||||||
|
}
|
||||||
4
main/src/main.cpp
Normal file
4
main/src/main.cpp
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#include "cApp.h"
|
||||||
|
#include <wx/wx.h>
|
||||||
|
|
||||||
|
wxIMPLEMENT_APP(cApp);
|
||||||
38
main/src/ui/cFrame.cpp
Normal file
38
main/src/ui/cFrame.cpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#include "ui/cFrame.h"
|
||||||
|
|
||||||
|
enum { ID_Hello = 1 };
|
||||||
|
|
||||||
|
cFrame::cFrame() : wxMDIParentFrame(nullptr, wxID_ANY, "Hello World") {
|
||||||
|
auto *menuFile = new wxMenu;
|
||||||
|
menuFile->Append(ID_Hello, "&Hello...\tCtrl-H",
|
||||||
|
"Help string shown in status bar for this menu item");
|
||||||
|
menuFile->AppendSeparator();
|
||||||
|
menuFile->Append(wxID_EXIT);
|
||||||
|
|
||||||
|
auto *menuHelp = new wxMenu;
|
||||||
|
menuHelp->Append(wxID_ABOUT);
|
||||||
|
|
||||||
|
auto *menuBar = new wxMenuBar;
|
||||||
|
menuBar->Append(menuFile, "&File");
|
||||||
|
menuBar->Append(menuHelp, "&Help");
|
||||||
|
|
||||||
|
SetMenuBar(menuBar);
|
||||||
|
|
||||||
|
CreateStatusBar();
|
||||||
|
SetStatusText("Welcome to wxWidgets!");
|
||||||
|
|
||||||
|
Bind(wxEVT_MENU, &cFrame::OnHello, this, ID_Hello);
|
||||||
|
Bind(wxEVT_MENU, &cFrame::OnAbout, this, wxID_ABOUT);
|
||||||
|
Bind(wxEVT_MENU, &cFrame::OnExit, this, wxID_EXIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cFrame::OnExit(wxCommandEvent &event) { Close(true); }
|
||||||
|
|
||||||
|
void cFrame::OnAbout(wxCommandEvent &event) {
|
||||||
|
wxMessageBox("This is a wxWidgets Hello World example", "About Hello World",
|
||||||
|
wxOK | wxICON_INFORMATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cFrame::OnHello(wxCommandEvent &event) {
|
||||||
|
wxLogMessage("Hello world from wxWidgets!");
|
||||||
|
}
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
#include "MyFrame.h"
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
ID_Hello = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
MyFrame::MyFrame()
|
|
||||||
: wxFrame(nullptr, wxID_ANY, "Hello World")
|
|
||||||
{
|
|
||||||
auto *menuFile = new wxMenu;
|
|
||||||
menuFile->Append(ID_Hello, "&Hello...\tCtrl-H",
|
|
||||||
"Help string shown in status bar for this menu item");
|
|
||||||
menuFile->AppendSeparator();
|
|
||||||
menuFile->Append(wxID_EXIT);
|
|
||||||
|
|
||||||
auto *menuHelp = new wxMenu;
|
|
||||||
menuHelp->Append(wxID_ABOUT);
|
|
||||||
|
|
||||||
auto *menuBar = new wxMenuBar;
|
|
||||||
menuBar->Append(menuFile, "&File");
|
|
||||||
menuBar->Append(menuHelp, "&Help");
|
|
||||||
|
|
||||||
SetMenuBar( menuBar );
|
|
||||||
|
|
||||||
CreateStatusBar();
|
|
||||||
SetStatusText("Welcome to wxWidgets!");
|
|
||||||
|
|
||||||
Bind(wxEVT_MENU, &MyFrame::OnHello, this, ID_Hello);
|
|
||||||
Bind(wxEVT_MENU, &MyFrame::OnAbout, this, wxID_ABOUT);
|
|
||||||
Bind(wxEVT_MENU, &MyFrame::OnExit, this, wxID_EXIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyFrame::OnExit(wxCommandEvent& event)
|
|
||||||
{
|
|
||||||
Close(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyFrame::OnAbout(wxCommandEvent& event)
|
|
||||||
{
|
|
||||||
wxMessageBox("This is a wxWidgets Hello World example",
|
|
||||||
"About Hello World", wxOK | wxICON_INFORMATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyFrame::OnHello(wxCommandEvent& event)
|
|
||||||
{
|
|
||||||
wxLogMessage("Hello world from wxWidgets!");
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#include "WxWherigo.h"
|
|
||||||
#include "MyFrame.h"
|
|
||||||
|
|
||||||
bool WxWherigo::OnInit()
|
|
||||||
{
|
|
||||||
auto *frame = new MyFrame();
|
|
||||||
frame->Show(true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
#include <wx/wx.h>
|
|
||||||
#include "WxWherigo.h"
|
|
||||||
|
|
||||||
wxIMPLEMENT_APP(WxWherigo);
|
|
||||||
Reference in New Issue
Block a user