diff --git a/Source/Integration/AnimQueue.cpp b/Source/Integration/AnimQueue.cpp index e69de29b..c82b719d 100644 --- a/Source/Integration/AnimQueue.cpp +++ b/Source/Integration/AnimQueue.cpp @@ -0,0 +1,54 @@ + +#include "AnimQueue.h" + +FAnimStep FAnimQueueDecoder::ReadStep() { + FAnimStep result; + result.Hash = Decoder.read_uint64(); + result.Body = Decoder.read_string_view(); + return result; +} + +FAnimField FAnimStepDecoder::ReadField() { + FAnimField result; + result.Name = Decoder.read_string_view(); + result.Persistent = Decoder.read_bool(); + result.Type = (EAnimValueType)Decoder.read_uint8(); + switch (result.Type) { + case T_STRING: { + result.S = Decoder.read_string_view(); + break; + } + case T_NUMBER: { + result.X = Decoder.read_double(); + break; + } + case T_BOOLEAN: { + result.X = Decoder.read_bool() ? 1.0 : 0.0; + break; + } + case T_XYZ: { + result.X = Decoder.read_double(); + result.Y = Decoder.read_double(); + result.Z = Decoder.read_double(); + break; + } + default: { + Decoder.set_at_eof(); + result.Type = T_BOOLEAN; + result.X = 0; + break; + } + } + return result; +} + +FString FAnimQueueDecoder::DebugString(std::string_view queue) { + // IMPLEMENT ME + return FString(); +} + +FString FAnimStepDecoder::DebugString(const FAnimStep& step) { + // IMPLEMENT ME + return FString(); +} + diff --git a/Source/Integration/AnimQueue.h b/Source/Integration/AnimQueue.h index e69de29b..76b1b933 100644 --- a/Source/Integration/AnimQueue.h +++ b/Source/Integration/AnimQueue.h @@ -0,0 +1,121 @@ +#pragma once + +#include "CoreMinimal.h" +#include "StringDecoder.h" + +//////////////////////////////////////////////// +// +// This is copied over from Luprex source. Not ideal. +// +//////////////////////////////////////////////// + +enum EAnimValueType { + T_STRING, + T_NUMBER, + T_BOOLEAN, + T_XYZ, + T_UNINITIALIZED +}; + +//////////////////////////////////////////////// +// +// An single animation step. +// +// The body consists of a sequence of FAnimField +// records. The body is encoded, to read the +// FAnimField records you need an FAnimStepDecoder. +// +//////////////////////////////////////////////// + +struct FAnimStep { + uint32 Hash; + std::string_view Body; +}; + +//////////////////////////////////////////////// +// +// A single animation field. +// +// A field consists of a variable name, +// a persistent flag, a type, and some fields +// to hold the values. +// +// If the value is boolean, it is stored in +// X, as either 1 or 0. If the value is double, +// it is stored in X. +// +//////////////////////////////////////////////// + +struct FAnimField { + std::string_view Name; + bool Persistent; + EAnimValueType Type; + double X, Y, Z; + std::string_view S; +}; + +//////////////////////////////////////////////// +// +// An Animation Queue Decoder. +// +// This acts a lot like a stream reader, +// it reads one AnimEntry at a time from +// the animation queue until you reach +// 'end-of-file'. +// +//////////////////////////////////////////////// + +class FAnimQueueDecoder { +private: + FStringDecoder Decoder; + +public: + // Initialize the FAnimQueueDecoder with the encoded animation queue. + // + FAnimQueueDecoder(std::string_view s) : Decoder(s) {} + + // Return true if the parser has reached the end of the string. + // + bool AtEOF() { return Decoder.at_eof(); } + + // Read one animation step. + // + FAnimStep ReadStep(); + + // Convert an AnimQueue to an FString. + // + static FString DebugString(std::string_view s); +}; + +//////////////////////////////////////////////// +// +// An Animation Step Decoder. +// +// This acts a lot like a stream reader, +// it reads one FAnimField at a time from +// the animation queue until you reach +// 'end-of-file'. +// +//////////////////////////////////////////////// + +class FAnimStepDecoder { +private: + FStringDecoder Decoder; + +public: + // Initialize the FAnimStepDecoder from the FAnimStep. + // + FAnimStepDecoder(const FAnimStep &step) : Decoder(step.Body) {} + + // Return true if the parser has reached the end of the string. + // + bool AtEOF() { return Decoder.at_eof(); } + + // Read one field. + // + FAnimField ReadField(); + + // Convert an AnimStep to an FString. + // + static FString DebugString(const FAnimStep &step); +}; diff --git a/Source/Integration/StringDecoder.cpp b/Source/Integration/StringDecoder.cpp index 4fb36ea5..72e926a8 100644 --- a/Source/Integration/StringDecoder.cpp +++ b/Source/Integration/StringDecoder.cpp @@ -1,6 +1,13 @@ #include "StringDecoder.h" -std::string_view StringDecoder::read_string_view() { +FStringDecoder::FStringDecoder(std::string_view s) { + Text = s.data(); + Size = s.size(); + ErrBeyondEOF = false; + ErrStringTooLong = false; +} + +std::string_view FStringDecoder::read_string_view() { size_t length = read_length(); if (length > Size) { ErrBeyondEOF = true; @@ -11,3 +18,9 @@ std::string_view StringDecoder::read_string_view() { Size -= length; return result; } + +void FStringDecoder::set_at_eof() { + Text += Size; + Size = 0; + +} \ No newline at end of file diff --git a/Source/Integration/StringDecoder.h b/Source/Integration/StringDecoder.h index a08008cc..7fc92c30 100644 --- a/Source/Integration/StringDecoder.h +++ b/Source/Integration/StringDecoder.h @@ -1,17 +1,18 @@ #pragma once + #include "CoreMinimal.h" #include "lpx-basewriter.hpp" ///////////////////////////////////////////////////// // -// StringDecoder +// FStringDecoder // // This class is used to decipher 8-bit strings that // contain packed ints, strings, and other data. // The typical example of usage is to decipher the // serialized animation queues fed to us by Luprex. // -// The StringDecoder doesn't make a copy of the string +// The FStringDecoder doesn't make a copy of the string // you pass in, instead, it stores a pointer to it. // So be sure not to free the string until you're // done analyzing it. @@ -25,7 +26,7 @@ ///////////////////////////////////////////////////// -class StringDecoder : public BaseReader { +class FStringDecoder : public BaseReader { private: const char* Text; size_t Size; @@ -42,10 +43,9 @@ public: // void read_bytes_into(char* buffer, size_t size) { if (size > Size) { - ErrBeyondEOF = true; memset(buffer, 0, size); - Text += Size; - Size = 0; + ErrBeyondEOF = true; + set_at_eof(); } else { memcpy(buffer, Text, size); @@ -68,20 +68,19 @@ public: // Initialize the string decoder with a text to analyze. // - StringDecoder(const char* text, int size) { - Text = text; - Size = size; - ErrBeyondEOF = false; - ErrStringTooLong = false; - } + FStringDecoder(std::string_view s); // Get the size of the remaining text. // - size_t GetSize() { return Size; } + size_t get_size() { return Size; } // Return true if the remaining text is empty. // - bool AtEOF() { return Size == 0; } + bool at_eof() { return Size == 0; } + + // Move the cursor to EOF. + // + void set_at_eof(); // Read a string as a string_view //