mirror of
https://github.com/izzy2lost/Torch.git
synced 2026-07-06 00:18:35 -07:00
Ghost Testing
This commit is contained in:
@@ -72,6 +72,7 @@
|
||||
|
||||
#ifdef FZERO_SUPPORT
|
||||
#include "factories/fzerox/CourseFactory.h"
|
||||
#include "factories/fzerox/GhostRecordFactory.h"
|
||||
#endif
|
||||
|
||||
#ifdef NAUDIO_SUPPORT
|
||||
@@ -165,6 +166,7 @@ void Companion::Init(const ExportType type) {
|
||||
|
||||
#ifdef FZERO_SUPPORT
|
||||
this->RegisterFactory("FZX:COURSE", std::make_shared<FZX::CourseFactory>());
|
||||
this->RegisterFactory("FZX:GHOST", std::make_shared<FZX::GhostRecordFactory>());
|
||||
#endif
|
||||
|
||||
#ifdef NAUDIO_SUPPORT
|
||||
|
||||
@@ -1,9 +1,69 @@
|
||||
#include "GhostRecordFactory.h"
|
||||
#include "ghost/Ghost.h"
|
||||
|
||||
#include "utils/Decompressor.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "Companion.h"
|
||||
|
||||
#define ARRAY_COUNT(arr) (int32_t)(sizeof(arr) / sizeof(arr[0]))
|
||||
#define ALIGN16(val) (((val) + 0xF) & ~0xF)
|
||||
|
||||
uint16_t FZX::GhostRecordData::Save_CalculateChecksum(void* data, int32_t size) {
|
||||
uint8_t* dataPtr = (uint8_t*)data;
|
||||
uint16_t checksum = 0;
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
checksum += *dataPtr++;
|
||||
}
|
||||
|
||||
return checksum;
|
||||
}
|
||||
|
||||
uint16_t FZX::GhostRecordData::CalculateRecordChecksum(void) {
|
||||
uint16_t checksum = 0;
|
||||
int32_t recordChecksum = CalculateReplayChecksum();
|
||||
|
||||
checksum += Save_CalculateChecksum(&mGhostType, sizeof(mGhostType));
|
||||
checksum += Save_CalculateChecksum(&recordChecksum, sizeof(recordChecksum));
|
||||
checksum += Save_CalculateChecksum(&mCourseEncoding, sizeof(mCourseEncoding));
|
||||
checksum += Save_CalculateChecksum(&mRaceTime, sizeof(mRaceTime));
|
||||
checksum += Save_CalculateChecksum(&mUnk10, sizeof(mUnk10));
|
||||
checksum += Save_CalculateChecksum((void*)mTrackName.c_str(), mTrackName.length());
|
||||
checksum += Save_CalculateChecksum(&mGhostMachineInfo, sizeof(mGhostMachineInfo));
|
||||
|
||||
return checksum;
|
||||
}
|
||||
|
||||
uint16_t FZX::GhostRecordData::CalculateDataChecksum(void) {
|
||||
uint16_t checksum = 0;
|
||||
|
||||
checksum += Save_CalculateChecksum(&mReplayEnd, sizeof(mReplayEnd));
|
||||
checksum += Save_CalculateChecksum(&mReplaySize, sizeof(mReplaySize));
|
||||
|
||||
for (auto lapTime : mLapTimes) {
|
||||
checksum += Save_CalculateChecksum(&lapTime, sizeof(lapTime));
|
||||
}
|
||||
|
||||
checksum += Save_CalculateChecksum(mReplayData.data(), mReplayData.size());
|
||||
|
||||
return checksum;
|
||||
}
|
||||
|
||||
int32_t FZX::GhostRecordData::CalculateReplayChecksum(void) {
|
||||
int32_t checksum = 0;
|
||||
int32_t i = 0;
|
||||
|
||||
for (auto dataByte : mReplayData) {
|
||||
checksum += ((uint32_t)(uint8_t)dataByte) << ((3 - i) * 8);
|
||||
|
||||
i++;
|
||||
i %= 4;
|
||||
}
|
||||
|
||||
return checksum;
|
||||
}
|
||||
|
||||
ExportResult FZX::GhostRecordHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) {
|
||||
const auto symbol = GetSafeNode(node, "symbol", entryName);
|
||||
|
||||
@@ -12,7 +72,9 @@ ExportResult FZX::GhostRecordHeaderExporter::Export(std::ostream &write, std::sh
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
write << "extern GhostRecord " << symbol << ";\n";
|
||||
write << "extern GhostRecord " << symbol << "Record;\n";
|
||||
write << "extern GhostReplayInfo " << symbol << "ReplayInfo;\n";
|
||||
write << "extern s8 " << symbol << "Data[];\n";
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -22,9 +84,111 @@ ExportResult FZX::GhostRecordCodeExporter::Export(std::ostream &write, std::shar
|
||||
const auto offset = GetSafeNode<uint32_t>(node, "offset");
|
||||
const auto record = std::static_pointer_cast<GhostRecordData>(raw);
|
||||
|
||||
write << "GhostRecord " << symbol << " = {\n";
|
||||
write << "GhostRecord " << symbol << "Record = {\n";
|
||||
|
||||
return offset;
|
||||
write << fourSpaceTab << "0x" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << record->CalculateRecordChecksum() << std::dec << ", /* Checksum */\n";
|
||||
|
||||
write << fourSpaceTab << static_cast<GhostType>(record->mGhostType) << ",\n";
|
||||
|
||||
write << fourSpaceTab << "0x" << std::hex << std::uppercase << std::setfill('0') << std::setw(8) << record->CalculateReplayChecksum() << std::dec << ", /* Replay Checksum */\n";
|
||||
|
||||
write << fourSpaceTab << "0x" << std::hex << std::uppercase << std::setfill('0') << std::setw(8) << record->mCourseEncoding << std::dec << ", /* Course Encoding */\n";
|
||||
|
||||
write << fourSpaceTab << record->mRaceTime << ", /* Race Time */ \n";
|
||||
|
||||
write << fourSpaceTab << record->mUnk10 << ", { 0 },\n";
|
||||
|
||||
write << fourSpaceTab << "\"" << record->mTrackName << "\",\n";
|
||||
|
||||
write << fourSpaceTab << " {\n";
|
||||
write << fourSpaceTab << fourSpaceTab << static_cast<Character>(record->mGhostMachineInfo.character) << ", ";
|
||||
write << static_cast<CustomType>(record->mGhostMachineInfo.customType) << ",\n";
|
||||
|
||||
write << fourSpaceTab << fourSpaceTab << static_cast<FrontType>(record->mGhostMachineInfo.frontType) << ", ";
|
||||
write << static_cast<RearType>(record->mGhostMachineInfo.rearType) << ", ";
|
||||
write << static_cast<WingType>(record->mGhostMachineInfo.wingType) << ",\n";
|
||||
|
||||
write << fourSpaceTab << fourSpaceTab << static_cast<Logo>(record->mGhostMachineInfo.frontType) << ", ";
|
||||
write << "MACHINE_NUMBER(" << (uint32_t)record->mGhostMachineInfo.number + 1 << "), ";
|
||||
write << static_cast<Decal>(record->mGhostMachineInfo.decal) << ",\n";
|
||||
|
||||
write << fourSpaceTab << fourSpaceTab << (uint32_t)record->mGhostMachineInfo.bodyR << ", ";
|
||||
write << (uint32_t)record->mGhostMachineInfo.bodyG << ", ";
|
||||
write << (uint32_t)record->mGhostMachineInfo.bodyB << ", /* Body Color */\n";
|
||||
write << fourSpaceTab << fourSpaceTab << (uint32_t)record->mGhostMachineInfo.numberR << ", ";
|
||||
write << (uint32_t)record->mGhostMachineInfo.numberG << ", ";
|
||||
write << (uint32_t)record->mGhostMachineInfo.numberB << ", /* Number Color */\n";
|
||||
write << fourSpaceTab << fourSpaceTab << (uint32_t)record->mGhostMachineInfo.decalR << ", ";
|
||||
write << (uint32_t)record->mGhostMachineInfo.decalG << ", ";
|
||||
write << (uint32_t)record->mGhostMachineInfo.decalB << ", /* Decal Color */\n";
|
||||
write << fourSpaceTab << fourSpaceTab << (uint32_t)record->mGhostMachineInfo.cockpitR << ", ";
|
||||
write << (uint32_t)record->mGhostMachineInfo.cockpitG << ", ";
|
||||
write << (uint32_t)record->mGhostMachineInfo.cockpitB << " /* Cockpit Color */\n";
|
||||
write << fourSpaceTab << "}\n";
|
||||
|
||||
write << "};\n\n";
|
||||
|
||||
|
||||
write << "GhostReplayInfo " << symbol << "ReplayInfo = {\n";
|
||||
|
||||
write << fourSpaceTab << "0x" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << record->CalculateDataChecksum() << std::dec << ", /* Checksum */\n";
|
||||
|
||||
write << fourSpaceTab << "0,\n";
|
||||
|
||||
write << fourSpaceTab << "{ ";
|
||||
|
||||
for (int32_t i = 0; i < 3; i++) {
|
||||
write << record->mLapTimes.at(i);
|
||||
if (i != 2) {
|
||||
write << ", ";
|
||||
}
|
||||
}
|
||||
|
||||
write << " },\n";
|
||||
|
||||
write << fourSpaceTab << record->mReplayEnd << ", ";
|
||||
|
||||
write << record->mReplaySize << ",\n";
|
||||
|
||||
write << fourSpaceTab << "0, 0\n";
|
||||
|
||||
write << "};\n\n";
|
||||
|
||||
|
||||
write << "u8 " << symbol << "Data[] = {\n";
|
||||
|
||||
write << fourSpaceTab;
|
||||
|
||||
int32_t counter = 0;
|
||||
for (uint32_t i = 0; i < record->mReplaySize; i++) {
|
||||
int32_t replayData = (int32_t)record->mReplayData.at(i);
|
||||
|
||||
if (replayData == -0x80) {
|
||||
write << "";
|
||||
|
||||
replayData = ((int32_t)record->mReplayData.at(i + 1) << 8) | (int32_t)record->mReplayData.at(i + 2);
|
||||
write << "REPLAY_DATA_LARGE(" << replayData << ")";
|
||||
|
||||
i += 2;
|
||||
} else {
|
||||
write << replayData;
|
||||
}
|
||||
|
||||
if (i != record->mReplaySize - 1) {
|
||||
write << ", ";
|
||||
} else {
|
||||
write << "\n";
|
||||
break;
|
||||
}
|
||||
|
||||
if ((++counter % 3) == 0) {
|
||||
write << "\n" << fourSpaceTab;
|
||||
}
|
||||
}
|
||||
|
||||
write << "};\n\n";
|
||||
|
||||
return offset + 0x20 + 0x40 + ALIGN16(record->mReplaySize);
|
||||
}
|
||||
|
||||
ExportResult FZX::GhostRecordBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) {
|
||||
@@ -63,12 +227,78 @@ std::optional<std::shared_ptr<IParsedData>> FZX::GhostRecordFactory::parse(std::
|
||||
|
||||
reader.SetEndianness(Torch::Endianness::Big);
|
||||
|
||||
return std::make_shared<GhostRecordData>();
|
||||
// Record
|
||||
uint16_t recordChecksum = reader.ReadInt16();
|
||||
uint16_t ghostType = reader.ReadUInt16();
|
||||
int32_t replayChecksum = reader.ReadInt32();
|
||||
int32_t courseEncoding = reader.ReadInt32();
|
||||
int32_t raceTime = reader.ReadInt32();
|
||||
|
||||
uint16_t unk_10 = reader.ReadInt16();
|
||||
for (int32_t i = 0; i < 5; i++) {
|
||||
reader.ReadInt8();
|
||||
}
|
||||
|
||||
char trackNameBuffer[9];
|
||||
for (int32_t i = 0; i < ARRAY_COUNT(trackNameBuffer); i++) {
|
||||
trackNameBuffer[i] = reader.ReadChar();
|
||||
}
|
||||
std::string trackName(trackNameBuffer);
|
||||
|
||||
GhostMachineInfo ghostMachineInfo;
|
||||
|
||||
ghostMachineInfo.character = reader.ReadUByte();
|
||||
ghostMachineInfo.customType = reader.ReadUByte();
|
||||
ghostMachineInfo.frontType = reader.ReadUByte();
|
||||
ghostMachineInfo.rearType = reader.ReadUByte();
|
||||
ghostMachineInfo.wingType = reader.ReadUByte();
|
||||
ghostMachineInfo.logo = reader.ReadUByte();
|
||||
ghostMachineInfo.number = reader.ReadUByte();
|
||||
ghostMachineInfo.decal = reader.ReadUByte();
|
||||
ghostMachineInfo.bodyR = reader.ReadUByte();
|
||||
ghostMachineInfo.bodyG = reader.ReadUByte();
|
||||
ghostMachineInfo.bodyB = reader.ReadUByte();
|
||||
ghostMachineInfo.numberR = reader.ReadUByte();
|
||||
ghostMachineInfo.numberG = reader.ReadUByte();
|
||||
ghostMachineInfo.numberB = reader.ReadUByte();
|
||||
ghostMachineInfo.decalR = reader.ReadUByte();
|
||||
ghostMachineInfo.decalG = reader.ReadUByte();
|
||||
ghostMachineInfo.decalB = reader.ReadUByte();
|
||||
ghostMachineInfo.cockpitR = reader.ReadUByte();
|
||||
ghostMachineInfo.cockpitG = reader.ReadUByte();
|
||||
ghostMachineInfo.cockpitB = reader.ReadUByte();
|
||||
|
||||
// Data
|
||||
reader.Seek(0x40, LUS::SeekOffsetType::Start);
|
||||
|
||||
uint16_t dataChecksum = reader.ReadInt16();
|
||||
|
||||
reader.ReadInt16();
|
||||
|
||||
std::vector<int32_t> lapTimes;
|
||||
|
||||
for (int32_t i = 0; i < 3; i++) {
|
||||
lapTimes.push_back(reader.ReadInt32());
|
||||
}
|
||||
|
||||
int32_t replayEnd = reader.ReadInt32();
|
||||
uint32_t replaySize = reader.ReadUInt32();
|
||||
|
||||
reader.ReadInt32();
|
||||
reader.ReadInt32();
|
||||
|
||||
std::vector<int8_t> replayData;
|
||||
for (uint32_t i = 0; i < replaySize; i++) {
|
||||
replayData.push_back(reader.ReadInt8());
|
||||
}
|
||||
|
||||
return std::make_shared<GhostRecordData>(ghostType, courseEncoding, raceTime, unk_10, trackName, ghostMachineInfo, lapTimes, replayEnd, replaySize, replayData);
|
||||
}
|
||||
|
||||
/*
|
||||
std::optional<std::shared_ptr<IParsedData>> FZX::GhostRecordFactory::parse_modding(std::vector<uint8_t>& buffer, YAML::Node& node) {
|
||||
YAML::Node assetNode;
|
||||
|
||||
|
||||
try {
|
||||
std::string text((char*) buffer.data(), buffer.size());
|
||||
assetNode = YAML::Load(text.c_str());
|
||||
@@ -77,8 +307,9 @@ std::optional<std::shared_ptr<IParsedData>> FZX::GhostRecordFactory::parse_moddi
|
||||
SPDLOG_ERROR("{}", (char*) buffer.data());
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
const auto info = assetNode.begin()->second;
|
||||
|
||||
|
||||
return std::make_shared<GhostRecordData>();
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -29,14 +29,36 @@ typedef struct GhostMachineInfo {
|
||||
|
||||
class GhostRecordData : public IParsedData {
|
||||
public:
|
||||
// Records
|
||||
uint16_t mGhostType;
|
||||
int32_t mReplayChecksum;
|
||||
int32_t mCourseEncoding;
|
||||
int32_t mRaceTime;
|
||||
uint16_t mUnk10;
|
||||
std::string mTrackName; // empty for normal tracks
|
||||
GhostMachineInfo mGhostMachineInfo;
|
||||
|
||||
// Data
|
||||
std::vector<int32_t> mLapTimes;
|
||||
int32_t mReplayEnd;
|
||||
uint32_t mReplaySize;
|
||||
std::vector<int8_t> mReplayData;
|
||||
|
||||
GhostRecordData(uint16_t ghostType, int32_t replayChecksum, int32_t courseEncoding, int32_t raceTime, std::string trackName, GhostMachineInfo& ghostMachineInfo) : mGhostType(ghostType), mReplayChecksum(replayChecksum), mCourseEncoding(courseEncoding), mRaceTime(raceTime), mTrackName(trackName), mGhostMachineInfo(ghostMachineInfo) {}
|
||||
GhostRecordData(uint16_t ghostType, int32_t courseEncoding, int32_t raceTime, uint16_t unk_10, std::string trackName, GhostMachineInfo& ghostMachineInfo, std::vector<int32_t> lapTimes, int32_t replayEnd, uint32_t replaySize, std::vector<int8_t> replayData) :
|
||||
mGhostType(ghostType),
|
||||
mCourseEncoding(courseEncoding),
|
||||
mRaceTime(raceTime),
|
||||
mUnk10(unk_10),
|
||||
mTrackName(trackName),
|
||||
mGhostMachineInfo(ghostMachineInfo),
|
||||
mLapTimes(std::move(lapTimes)),
|
||||
mReplayEnd(replayEnd),
|
||||
mReplaySize(replaySize),
|
||||
mReplayData(std::move(replayData)) {}
|
||||
|
||||
uint16_t Save_CalculateChecksum(void* data, int32_t size);
|
||||
uint16_t CalculateRecordChecksum(void);
|
||||
uint16_t CalculateDataChecksum(void);
|
||||
int32_t CalculateReplayChecksum(void);
|
||||
};
|
||||
|
||||
class GhostRecordHeaderExporter : public BaseExporter {
|
||||
@@ -58,7 +80,7 @@ class GhostRecordModdingExporter : public BaseExporter {
|
||||
class GhostRecordFactory : public BaseFactory {
|
||||
public:
|
||||
std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override;
|
||||
std::optional<std::shared_ptr<IParsedData>> parse_modding(std::vector<uint8_t>& buffer, YAML::Node& data) override;
|
||||
// std::optional<std::shared_ptr<IParsedData>> parse_modding(std::vector<uint8_t>& buffer, YAML::Node& data) override;
|
||||
inline std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
|
||||
return {
|
||||
REGISTER(Code, GhostRecordCodeExporter)
|
||||
|
||||
@@ -0,0 +1,385 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <spdlog/fmt/ostr.h>
|
||||
|
||||
namespace FZX {
|
||||
enum class GhostType {
|
||||
/* 0 */ GHOST_NONE,
|
||||
/* 1 */ GHOST_PLAYER,
|
||||
/* 2 */ GHOST_STAFF,
|
||||
/* 3 */ GHOST_CELEBRITY,
|
||||
/* 4 */ GHOST_CHAMP,
|
||||
};
|
||||
|
||||
enum class Character {
|
||||
/* 00 */ CAPTAIN_FALCON,
|
||||
/* 01 */ DR_STEWART,
|
||||
/* 02 */ PICO,
|
||||
/* 03 */ SAMURAI_GOROH,
|
||||
/* 04 */ JODY_SUMMER,
|
||||
/* 05 */ MIGHTY_GAZELLE,
|
||||
/* 06 */ MR_EAD,
|
||||
/* 07 */ BABA,
|
||||
/* 08 */ OCTOMAN,
|
||||
/* 09 */ GOMAR_AND_SHIOH,
|
||||
/* 10 */ KATE_ALEN,
|
||||
/* 11 */ ROGER_BUSTER,
|
||||
/* 12 */ JAMES_MCCLOUD,
|
||||
/* 13 */ LEON,
|
||||
/* 14 */ ANTONIO_GUSTER,
|
||||
/* 15 */ BLACK_SHADOW,
|
||||
/* 16 */ MICHAEL_CHAIN,
|
||||
/* 17 */ JACK_LEVIN,
|
||||
/* 18 */ SUPER_ARROW,
|
||||
/* 19 */ MRS_ARROW,
|
||||
/* 20 */ JOHN_TANAKA,
|
||||
/* 21 */ BEASTMAN,
|
||||
/* 22 */ ZODA,
|
||||
/* 23 */ DR_CLASH,
|
||||
/* 24 */ SILVER_NEELSEN,
|
||||
/* 25 */ BIO_REX,
|
||||
/* 26 */ DRAQ,
|
||||
/* 27 */ BILLY,
|
||||
/* 28 */ THE_SKULL,
|
||||
/* 29 */ BLOOD_FALCON,
|
||||
};
|
||||
|
||||
enum class CustomType {
|
||||
/* 0 */ CUSTOM_MACHINE_DEFAULT,
|
||||
/* 1 */ CUSTOM_MACHINE_EDITED,
|
||||
/* 2 */ CUSTOM_MACHINE_SUPER_FALCON,
|
||||
/* 3 */ CUSTOM_MACHINE_SUPER_STINGRAY,
|
||||
/* 4 */ CUSTOM_MACHINE_SUPER_CAT,
|
||||
};
|
||||
|
||||
enum class FrontType {
|
||||
/* 0 */ FRONT_0,
|
||||
/* 1 */ FRONT_1,
|
||||
/* 2 */ FRONT_2,
|
||||
/* 3 */ FRONT_3,
|
||||
/* 4 */ FRONT_4,
|
||||
/* 5 */ FRONT_5,
|
||||
/* 6 */ FRONT_6,
|
||||
};
|
||||
|
||||
enum class RearType {
|
||||
/* 0 */ REAR_0,
|
||||
/* 1 */ REAR_1,
|
||||
/* 2 */ REAR_2,
|
||||
/* 3 */ REAR_3,
|
||||
/* 4 */ REAR_4,
|
||||
/* 5 */ REAR_5,
|
||||
/* 6 */ REAR_6,
|
||||
};
|
||||
|
||||
enum class WingType {
|
||||
/* 0 */ WING_NONE,
|
||||
/* 1 */ WING_1,
|
||||
/* 2 */ WING_2,
|
||||
/* 3 */ WING_3,
|
||||
/* 4 */ WING_4,
|
||||
/* 5 */ WING_5,
|
||||
/* 6 */ WING_6,
|
||||
};
|
||||
|
||||
enum class Logo {
|
||||
/* 0 */ LOGO_SHIELD,
|
||||
/* 1 */ LOGO_ARROW_PLANE,
|
||||
/* 2 */ LOGO_CIRCLE,
|
||||
/* 3 */ LOGO_SKULL,
|
||||
/* 4 */ LOGO_YELLOW_GREEN,
|
||||
/* 5 */ LOGO_KANJI,
|
||||
/* 6 */ LOGO_X,
|
||||
/* 7 */ LOGO_N64,
|
||||
};
|
||||
|
||||
enum class Decal {
|
||||
/* 0 */ DECAL_STRIPE,
|
||||
/* 1 */ DECAL_THIN_STRIPE,
|
||||
/* 2 */ DECAL_DOUBLE_STRIPE,
|
||||
/* 3 */ DECAL_TRIPLE_STRIPE_UNEVEN,
|
||||
/* 4 */ DECAL_BLOCK,
|
||||
};
|
||||
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const GhostType& ghostType) {
|
||||
std::string output;
|
||||
switch (ghostType) {
|
||||
case GhostType::GHOST_NONE:
|
||||
output = "GHOST_NONE";
|
||||
break;
|
||||
case GhostType::GHOST_PLAYER:
|
||||
output = "GHOST_PLAYER";
|
||||
break;
|
||||
case GhostType::GHOST_STAFF:
|
||||
output = "GHOST_STAFF";
|
||||
break;
|
||||
case GhostType::GHOST_CELEBRITY:
|
||||
output = "GHOST_CELEBRITY";
|
||||
break;
|
||||
case GhostType::GHOST_CHAMP:
|
||||
output = "GHOST_CHAMP";
|
||||
break;
|
||||
}
|
||||
return out << output;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const Character& character) {
|
||||
std::string output;
|
||||
switch (character) {
|
||||
case Character::CAPTAIN_FALCON:
|
||||
output = "CAPTAIN_FALCON";
|
||||
break;
|
||||
case Character::DR_STEWART:
|
||||
output = "DR_STEWART";
|
||||
break;
|
||||
case Character::PICO:
|
||||
output = "PICO";
|
||||
break;
|
||||
case Character::SAMURAI_GOROH:
|
||||
output = "SAMURAI_GOROH";
|
||||
break;
|
||||
case Character::JODY_SUMMER:
|
||||
output = "JODY_SUMMER";
|
||||
break;
|
||||
case Character::MIGHTY_GAZELLE:
|
||||
output = "MIGHTY_GAZELLE";
|
||||
break;
|
||||
case Character::MR_EAD:
|
||||
output = "MR_EAD";
|
||||
break;
|
||||
case Character::BABA:
|
||||
output = "BABA";
|
||||
break;
|
||||
case Character::OCTOMAN:
|
||||
output = "OCTOMAN";
|
||||
break;
|
||||
case Character::GOMAR_AND_SHIOH:
|
||||
output = "GOMAR_AND_SHIOH";
|
||||
break;
|
||||
case Character::KATE_ALEN:
|
||||
output = "KATE_ALEN";
|
||||
break;
|
||||
case Character::ROGER_BUSTER:
|
||||
output = "ROGER_BUSTER";
|
||||
break;
|
||||
case Character::JAMES_MCCLOUD:
|
||||
output = "JAMES_MCCLOUD";
|
||||
break;
|
||||
case Character::LEON:
|
||||
output = "LEON";
|
||||
break;
|
||||
case Character::ANTONIO_GUSTER:
|
||||
output = "ANTONIO_GUSTER";
|
||||
break;
|
||||
case Character::BLACK_SHADOW:
|
||||
output = "BLACK_SHADOW";
|
||||
break;
|
||||
case Character::MICHAEL_CHAIN:
|
||||
output = "MICHAEL_CHAIN";
|
||||
break;
|
||||
case Character::JACK_LEVIN:
|
||||
output = "JACK_LEVIN";
|
||||
break;
|
||||
case Character::SUPER_ARROW:
|
||||
output = "SUPER_ARROW";
|
||||
break;
|
||||
case Character::MRS_ARROW:
|
||||
output = "MRS_ARROW";
|
||||
break;
|
||||
case Character::JOHN_TANAKA:
|
||||
output = "JOHN_TANAKA";
|
||||
break;
|
||||
case Character::BEASTMAN:
|
||||
output = "BEASTMAN";
|
||||
break;
|
||||
case Character::ZODA:
|
||||
output = "ZODA";
|
||||
break;
|
||||
case Character::DR_CLASH:
|
||||
output = "DR_CLASH";
|
||||
break;
|
||||
case Character::SILVER_NEELSEN:
|
||||
output = "SILVER_NEELSEN";
|
||||
break;
|
||||
case Character::BIO_REX:
|
||||
output = "BIO_REX";
|
||||
break;
|
||||
case Character::DRAQ:
|
||||
output = "DRAQ";
|
||||
break;
|
||||
case Character::BILLY:
|
||||
output = "BILLY";
|
||||
break;
|
||||
case Character::THE_SKULL:
|
||||
output = "THE_SKULL";
|
||||
break;
|
||||
case Character::BLOOD_FALCON:
|
||||
output = "BLOOD_FALCON";
|
||||
break;
|
||||
}
|
||||
return out << output;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const CustomType& customType) {
|
||||
std::string output;
|
||||
switch (customType) {
|
||||
case CustomType::CUSTOM_MACHINE_DEFAULT:
|
||||
output = "CUSTOM_MACHINE_DEFAULT";
|
||||
break;
|
||||
case CustomType::CUSTOM_MACHINE_EDITED:
|
||||
output = "CUSTOM_MACHINE_EDITED";
|
||||
break;
|
||||
case CustomType::CUSTOM_MACHINE_SUPER_FALCON:
|
||||
output = "CUSTOM_MACHINE_SUPER_FALCON";
|
||||
break;
|
||||
case CustomType::CUSTOM_MACHINE_SUPER_STINGRAY:
|
||||
output = "CUSTOM_MACHINE_SUPER_STINGRAY";
|
||||
break;
|
||||
case CustomType::CUSTOM_MACHINE_SUPER_CAT:
|
||||
output = "CUSTOM_MACHINE_SUPER_CAT";
|
||||
break;
|
||||
}
|
||||
return out << output;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const FrontType& frontType) {
|
||||
std::string output;
|
||||
switch (frontType) {
|
||||
case FrontType::FRONT_0:
|
||||
output = "FRONT_0";
|
||||
break;
|
||||
case FrontType::FRONT_1:
|
||||
output = "FRONT_1";
|
||||
break;
|
||||
case FrontType::FRONT_2:
|
||||
output = "FRONT_2";
|
||||
break;
|
||||
case FrontType::FRONT_3:
|
||||
output = "FRONT_3";
|
||||
break;
|
||||
case FrontType::FRONT_4:
|
||||
output = "FRONT_4";
|
||||
break;
|
||||
case FrontType::FRONT_5:
|
||||
output = "FRONT_5";
|
||||
break;
|
||||
case FrontType::FRONT_6:
|
||||
output = "FRONT_6";
|
||||
break;
|
||||
}
|
||||
return out << output;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const RearType rearType) {
|
||||
std::string output;
|
||||
switch (rearType) {
|
||||
case RearType::REAR_0:
|
||||
output = "REAR_0";
|
||||
break;
|
||||
case RearType::REAR_1:
|
||||
output = "REAR_1";
|
||||
break;
|
||||
case RearType::REAR_2:
|
||||
output = "REAR_2";
|
||||
break;
|
||||
case RearType::REAR_3:
|
||||
output = "REAR_3";
|
||||
break;
|
||||
case RearType::REAR_4:
|
||||
output = "REAR_4";
|
||||
break;
|
||||
case RearType::REAR_5:
|
||||
output = "REAR_5";
|
||||
break;
|
||||
case RearType::REAR_6:
|
||||
output = "REAR_6";
|
||||
break;
|
||||
}
|
||||
return out << output;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const WingType& wingType) {
|
||||
std::string output;
|
||||
switch (wingType) {
|
||||
case WingType::WING_NONE:
|
||||
output = "WING_NONE";
|
||||
break;
|
||||
case WingType::WING_1:
|
||||
output = "WING_1";
|
||||
break;
|
||||
case WingType::WING_2:
|
||||
output = "WING_2";
|
||||
break;
|
||||
case WingType::WING_3:
|
||||
output = "WING_3";
|
||||
break;
|
||||
case WingType::WING_4:
|
||||
output = "WING_4";
|
||||
break;
|
||||
case WingType::WING_5:
|
||||
output = "WING_5";
|
||||
break;
|
||||
case WingType::WING_6:
|
||||
output = "WING_6";
|
||||
break;
|
||||
}
|
||||
return out << output;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const Logo& logo) {
|
||||
std::string output;
|
||||
switch (logo) {
|
||||
case Logo::LOGO_SHIELD:
|
||||
output = "LOGO_SHIELD";
|
||||
break;
|
||||
case Logo::LOGO_ARROW_PLANE:
|
||||
output = "LOGO_ARROW_PLANE";
|
||||
break;
|
||||
case Logo::LOGO_CIRCLE:
|
||||
output = "LOGO_CIRCLE";
|
||||
break;
|
||||
case Logo::LOGO_SKULL:
|
||||
output = "LOGO_SKULL";
|
||||
break;
|
||||
case Logo::LOGO_YELLOW_GREEN:
|
||||
output = "LOGO_YELLOW_GREEN";
|
||||
break;
|
||||
case Logo::LOGO_KANJI:
|
||||
output = "LOGO_KANJI";
|
||||
break;
|
||||
case Logo::LOGO_X:
|
||||
output = "LOGO_X";
|
||||
break;
|
||||
case Logo::LOGO_N64:
|
||||
output = "LOGO_N64";
|
||||
break;
|
||||
}
|
||||
return out << output;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const Decal& decal) {
|
||||
std::string output;
|
||||
switch (decal) {
|
||||
case Decal::DECAL_STRIPE:
|
||||
output = "DECAL_STRIPE";
|
||||
break;
|
||||
case Decal::DECAL_THIN_STRIPE:
|
||||
output = "DECAL_THIN_STRIPE";
|
||||
break;
|
||||
case Decal::DECAL_DOUBLE_STRIPE:
|
||||
output = "DECAL_DOUBLE_STRIPE";
|
||||
break;
|
||||
case Decal::DECAL_TRIPLE_STRIPE_UNEVEN:
|
||||
output = "DECAL_TRIPLE_STRIPE_UNEVEN";
|
||||
break;
|
||||
case Decal::DECAL_BLOCK:
|
||||
output = "DECAL_BLOCK";
|
||||
break;
|
||||
}
|
||||
return out << output;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user