add cartridge reader
Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
This commit is contained in:
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
|
||||
Reference in New Issue
Block a user