diff --git a/.gitmodules b/.gitmodules index 7e5d49257..dee567e15 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "LunadllNewLauncher/SMBXLauncher/PGE_File_Formats"] path = LunadllNewLauncher/SMBXLauncher/PGE_File_Formats url = https://github.com/Wohlhabend-Networks/PGE-File-Library-STL.git +[submodule "LunaDll/libs/PGE_File_Formats"] + path = LunaDll/libs/PGE_File_Formats + url = https://github.com/WohlSoft/PGE-File-Library-STL diff --git a/LunaDll/libs/PGE_File_Formats b/LunaDll/libs/PGE_File_Formats new file mode 160000 index 000000000..345f688ca --- /dev/null +++ b/LunaDll/libs/PGE_File_Formats @@ -0,0 +1 @@ +Subproject commit 345f688ca3d4dd8b55918e0bf11826e49c843284 diff --git a/LunaDll/libs/PGE_File_Formats/.gitignore b/LunaDll/libs/PGE_File_Formats/.gitignore deleted file mode 100644 index b7128c520..000000000 --- a/LunaDll/libs/PGE_File_Formats/.gitignore +++ /dev/null @@ -1,30 +0,0 @@ -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - -*.error diff --git a/LunaDll/libs/PGE_File_Formats/CSVReader.h b/LunaDll/libs/PGE_File_Formats/CSVReader.h deleted file mode 100644 index 1a99253a8..000000000 --- a/LunaDll/libs/PGE_File_Formats/CSVReader.h +++ /dev/null @@ -1,1066 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2016 Kevin Waldock - * - * 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 -#ifndef CSVReader_H -#define CSVReader_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "invoke_default.hpp" - -namespace CSVReader -{ - // ========= Exceptions START =========== - /*! - * \brief Exception for parsing errors. - */ - class parse_error : public std::logic_error - { - private: - int _line; - int _field; - public: - explicit parse_error(const char *msg, int line, int field) : std::logic_error(msg), _line(line), _field(field) {} - explicit parse_error(std::string msg, int line, int field) : parse_error(msg.c_str(), line, field) {} - - inline int get_line_number() const - { - return _line; - } - inline int get_field_number() const - { - return _field; - } - }; - // ========= Exceptions END =========== - - - - // ========= Utils START =========== - // This is a feature built-in for C++14 - namespace detail - { - template - class index_sequence {}; - - template - struct make_index_sequence : make_index_sequence < N - 1, N - 1, I... > {}; - - template - struct make_index_sequence<0, I...> : index_sequence {}; - } - - // This is for the CSVBatchReader - // This template class depends on .push_back() - template - struct CommonContainerUtils - { - static void Add(ContainerT *container, const ContainerValueT &value) - { - container->push_back(value); - } - }; - - namespace detail - { - - template - class CSVReaderBase - { - protected: - size_t _currentCharIndex; - CharT _sep; - StrT _currentLine; // Will be written by the derived class - int _fieldTracker; // Will be written by the derived class - int _lineTracker; // Will be written by the derived class - - CSVReaderBase(CharT sep) : _currentCharIndex(0u), _sep(sep), - _currentLine(""), _fieldTracker(0), _lineTracker(0) {} - - inline StrT NextField() - { - size_t newCharIndex = _currentCharIndex; - if(!StrTUtils::find(_currentLine, _sep, newCharIndex)) - newCharIndex = StrTUtils::length(_currentLine); - - StrT next = StrTUtils::substring(_currentLine, _currentCharIndex, newCharIndex - _currentCharIndex); - _currentCharIndex = newCharIndex + 1; - return next; - } - - inline void SkipField() - { - size_t newCharIndex = _currentCharIndex; - if(!StrTUtils::find(_currentLine, _sep, newCharIndex)) - newCharIndex = StrTUtils::length(_currentLine); - _currentCharIndex = newCharIndex + 1; - } - - inline bool HasNext() - { - return _currentCharIndex <= StrTUtils::length(_currentLine); - } - - template - inline void SafeConvert(ToType *to, const StrT &from) - { - try - { - Converter::Convert(to, from); - } - catch(...) - { - ThrowParseErrorInCatchContext(); - } - } - - inline void ThrowParseErrorInCatchContext() - { - std::throw_with_nested(parse_error(std::string("Failed to parse field ") + std::to_string(_fieldTracker) + " at line " + std::to_string(_lineTracker), _lineTracker, _fieldTracker)); - } - }; - } - // ========= Utils END =========== - - - - // ========= Readers START =========== - template > - struct IfStreamReader - { - using target_ifstream = std::basic_ifstream; - using target_string = std::basic_string; - typedef target_string string_type; - - target_ifstream *_reader; - IfStreamReader(target_ifstream *reader) : _reader(reader) {} - - target_string read_line() - { - target_string str; - std::getline(*_reader, str); - return str; - } - }; - template - constexpr IfStreamReader MakeIfStreamReader(std::basic_ifstream *reader) - { - return IfStreamReader(reader); - } - - template - struct StringReader - { - using target_istringstream = std::basic_istringstream; - using target_string = std::basic_string; - typedef target_string string_type; - - target_istringstream _txt; - StringReader(target_string str) : _txt(str) {} - - target_string read_line() - { - target_string str; - std::getline(_txt, str); - return str; - } - }; - template - constexpr StringReader MakeStringReader(const std::basic_string &str) - { - return StringReader(str); - } - - template - struct DirectReader - { - typedef StrT string_type; - - DirectReader(const StrT &data) : _data(data) {} - StrT read_line() - { - return _data; - } - private: - StrT _data; - }; - template - constexpr DirectReader MakeDirectReader(const StrT &data) - { - return DirectReader(data); - } - - // ========= Readers END =========== - - - - - - - - // ========= Special Attributes START =========== - // 1. Alternative Parameter - CSVDiscard - /*! - * \brief Special CSVReader parameter value for ignoring a field. - */ - struct CSVDiscard {}; - - // 2. Alternative Parameter - CSVValidator - /*! - * \brief Special CSVReader parameter value for validating a field. - * \see MakeCSVValidator() - */ - template - struct CSVValidator - { - typedef T value_type; - CSVValidator(T *value, const ValidatorFunc &validatorFunction) : _value(value), _validatorFunction(validatorFunction) {} - - bool Validate() const - { - return idef::invoke_or_noop(idef::default_if_nullptr(_validatorFunction, [](T *) - { - return true; - }), _value); - } - T *Get() - { - return _value; - } - private: - T *_value; - ValidatorFunc _validatorFunction; - }; - /*! - * \brief Creates a new CSVValidator. - * \see CSVValidator - */ - template - constexpr CSVValidator MakeCSVValidator(T *value, ValidatorFunc validatorFunction) - { - return CSVValidator(value, validatorFunction); - } - - // 3. Alternative Parameter - CSVPostProcessor - /*! - * \brief Special CSVReader parameter value for post processing a field. - * \see MakeCSVPostProcessor() - * - * The post processor will be called before the value will be writting into the pointer. - */ - template - struct CSVPostProcessor - { - typedef T value_type; - - CSVPostProcessor(T *value, const PostProcessorFunc &postProcessorFunction) : CSVPostProcessor(value, postProcessorFunction, nullptr) {} - CSVPostProcessor(T *value, const PostProcessorFunc &postProcessorFunction, const ValidatorFunc &validatorFunction) - : _value(value), _validatorFunction(validatorFunction), _postProcessorFunction(postProcessorFunction) {} - - bool Validate() const - { - return idef::invoke_or_noop(idef::default_if_nullptr(_validatorFunction, [](T *) - { - return true; - }), _value); - } - inline void PostProcess() - { - idef::invoke_or_noop(_postProcessorFunction, *_value); - } - T *Get() - { - return _value; - } - private: - T *_value; - ValidatorFunc _validatorFunction; - PostProcessorFunc _postProcessorFunction; - }; - /*! - * \brief Creates a new CSVPostProcessor. - * \see CSVPostProcessor - */ - template - constexpr CSVPostProcessor MakeCSVPostProcessor(T *value, PostProcessorFunc postProcessorFunction) - { - return CSVPostProcessor(value, postProcessorFunction); - } - /*! - * \brief Creates a new CSVPostProcessor. - * \see CSVPostProcessor - */ - template - constexpr CSVPostProcessor MakeCSVPostProcessor(T *value, PostProcessorFunc postProcessorFunction, ValidatorFunc validatorFunction) - { - return CSVPostProcessor(value, postProcessorFunction, validatorFunction); - } - - - - // 4. Alternative parameter - CSVOptional - /*! - * \brief Special CSVReader parameter value for marking a field as optional. - * \see MakeCSVOptional() - * - * If the reader cannot read further, then the default value is used - * instead of throwing an exception. - */ - template - struct CSVOptional - { - typedef T value_type; - - CSVOptional(T* value, const T defVal, bool shouldAssignDefaultOnEmpty) : CSVOptional(value, defVal, shouldAssignDefaultOnEmpty, nullptr) {} - CSVOptional(T* value, const T defVal, bool shouldAssignDefaultOnEmpty, const ValidatorFunc& validatorFunction) : - CSVOptional(value, defVal, shouldAssignDefaultOnEmpty, validatorFunction, nullptr) {} - CSVOptional(T* value, const T defVal, bool shouldAssignDefaultOnEmpty, const ValidatorFunc& validatorFunction, const PostProcessorFunc& postProcessorFunction) : - _value(value), _defaultValue(defVal), _shouldAssignDefaultOnEmpty(shouldAssignDefaultOnEmpty), - _validatorFunction(validatorFunction), _postProcessorFunction(postProcessorFunction) {} - - bool Validate() const - { - return idef::invoke_or_noop(idef::default_if_nullptr(_validatorFunction, [](T *) - { - return true; - }), _value); - } - inline void PostProcess() - { - idef::invoke_or_noop(_postProcessorFunction, *_value); - } - inline void AssignDefault() - { - *_value = _defaultValue; - } - inline T *Get() - { - return _value; - } - inline bool ShouldAssingDefaultOnEmpty() const { - return _shouldAssignDefaultOnEmpty; - } - private: - T *_value; - T _defaultValue; - bool _shouldAssignDefaultOnEmpty; - ValidatorFunc _validatorFunction; - PostProcessorFunc _postProcessorFunction; - }; - /*! - * \brief Creates a new CSVOptional. - * \see CSVOptional - */ - template - constexpr CSVOptional MakeCSVOptional(T* value, OT defVal) { - return CSVOptional(value, defVal, false, nullptr, nullptr); - } - /*! - * \brief Creates a new CSVOptional. - * \see CSVOptional - */ - template - constexpr CSVOptional MakeCSVOptional(T* value, OT defVal, ValidatorFunc validatorFunction) { - return CSVOptional(value, defVal, false, validatorFunction, nullptr); - } - /*! - * \brief Creates a new CSVOptional. - * \see CSVOptional - */ - template - constexpr CSVOptional MakeCSVOptional(T* value, OT defVal, ValidatorFunc validatorFunction, PostProcessorFunc postProcessorFunction) { - return CSVOptional(value, defVal, false, validatorFunction, postProcessorFunction); - } - - /*! - * \brief Creates a new CSVOptional. - * \see CSVOptional - */ - template - constexpr CSVOptional MakeCSVOptionalEmpty(T* value, OT defVal) { - return CSVOptional(value, defVal, true, nullptr, nullptr); - } - /*! - * \brief Creates a new CSVOptional. - * \see CSVOptional - */ - template - constexpr CSVOptional MakeCSVOptionalEmpty(T* value, OT defVal, ValidatorFunc validatorFunction) { - return CSVOptional(value, defVal, true, validatorFunction, nullptr); - } - /*! - * \brief Creates a new CSVOptional. - * \see CSVOptional - */ - template - constexpr CSVOptional MakeCSVOptionalEmpty(T* value, OT defVal, ValidatorFunc validatorFunction, PostProcessorFunc postProcessorFunction) { - return CSVOptional(value, defVal, true, validatorFunction, postProcessorFunction); - } - - // 5. Reader in Reader - CSVOptional - /*! - * \brief Special CSVReader parameter value for creating a sub-reader. - * \see MakeCSVSubReader() - * This class can read fields, which are seperated again with another token. - */ - template - struct CSVSubReader; - - // 6. Reading in container - /*! - * \brief Special CSVReader parameter value for reading a collection of literal types. - * \see MakeCSVBatchReader - */ - template - struct CSVBatchReader : detail::CSVReaderBase - { - private: - Container* _container; - PostProcessorFunc _postProcessorFunction; - public: - - CSVBatchReader(CharT sep, Container* container, const PostProcessorFunc &postProcessorFunction) : - detail::CSVReaderBase(sep), _container(container), _postProcessorFunction(postProcessorFunction) {} - - inline void ReadDataLine(const StrT &val) - { - this->_currentLine = val; - while(this->HasNext()) - { - StrT from = this->NextField(); - if(from == "") - continue; - ContainerValueT to; - this->SafeConvert(&to, from); - idef::invoke_or_noop(_postProcessorFunction, to); - ContainerUtils::Add(_container, to); - } - } - }; - - // 7. Reading with iteration - /*! - * \brief Special CSVReader parameter value for iterating through an unknown number of types. - * \see MakeCSVIterator() - */ - template - struct CSVIterator : detail::CSVReaderBase - { - private: - bool _isOptional; - IteratorFunc _iteratorFunc; - public: - CSVIterator(CharT sep, bool isOptional, const IteratorFunc &iteratorFunc) : - detail::CSVReaderBase(sep), _isOptional(isOptional), _iteratorFunc(iteratorFunc) {} - - inline void ReadDataLine(const StrT &val) - { - this->_currentLine = val; - while(this->HasNext()) - { - StrT next = this->NextField(); - if(!(next == "")) - _iteratorFunc(next); - } - } - - bool IsOptional() const - { - return _isOptional; - } - }; - - - // ========= Special Attributes END =========== - - - /* - * The Default CSV Converter uses the STL library to do the most of the conversion. - */ - /*! - * \brief The default converter to convert strings to literal types. - */ - template - struct DefaultCSVConverter - { - static void Convert(double *out, const StrType &field) - { - *out = std::stod(field); - } - static void Convert(float *out, const StrType &field) - { - *out = std::stof(field); - } - static void Convert(int *out, const StrType &field) - { - *out = std::stoi(field); - } - static void Convert(long *out, const StrType &field) - { - *out = std::stol(field); - } - static void Convert(long long *out, const StrType &field) - { - *out = std::stoll(field); - } - static void Convert(long double *out, const StrType &field) - { - *out = std::stold(field); - } - static void Convert(unsigned int *out, const StrType &field) - { - *out = static_cast(std::stoul(field)); - } - static void Convert(unsigned long *out, const StrType &field) - { - *out = std::stoul(field); - } - static void Convert(unsigned long long *out, const StrType &field) - { - *out = std::stoull(field); - } - static void Convert(bool *out, const StrType &field) - { - if(field == "0" || field == "") // FIXME: Is it correct? Or too hackish? - *out = false; - else if(field == "!0" || field == "1") // FIXME: Is it correct? Or too hackish? - *out = true; - else - throw std::invalid_argument(std::string("Could not convert to bool (must be empty, \"0\", \"!0\" or \"1\"), got \"") + field + std::string("\"")); - } - static void Convert(StrType *out, const StrType &field) - { - *out = field; - } - }; - - - /*! - * \brief The default wrapper for strings (Works for STL strings) - * \see MakeCSVReaderFromBasicString() - */ - template - struct DefaultStringWrapper - { - using target_string = std::basic_string; - - static bool find(const target_string &str, StrElementType sep, size_t &findIndex) - { - size_t pos = str.find(sep, findIndex); - if(pos == target_string::npos) - return false; - findIndex = pos; - return true; - } - - static size_t length(const target_string &str) - { - return str.length(); - } - - static target_string substring(const target_string &str, size_t pos, size_t count) - { - return str.substr(pos, count); - } - }; - - - - - - /*! - * \brief Provides features to read out CSV data. - * \see MakeCSVReader() - * - * This class provides features to read out CSV data and converting them directly to literal types. - * - * Use MakeCSVReader or MakeCSVReaderFromBasicString for easy construction of this class. - * - */ - template - class CSVReader : detail::CSVReaderBase - { - private: - Reader *_reader; - int _currentTotalFields; - bool _requireReadLine; - public: - CSVReader(Reader *reader, CharT sep) : detail::CSVReaderBase(sep), _reader(reader), - _currentTotalFields(0), _requireReadLine(true) {} - CSVReader(const CSVReader &other) = delete; - CSVReader(CSVReader &&other) = default; - ~CSVReader() = default; - - private: - inline void ThrowIfOutOfBounds() - { - if(this->_currentCharIndex > StrTUtils::length(this->_currentLine)) - throw parse_error("Expected " + std::to_string(this->_currentTotalFields) + " CSV-Fields, got " - + std::to_string(this->_fieldTracker) + " at line " - + std::to_string(this->_lineTracker) + "!", this->_lineTracker, this->_fieldTracker); - } - template - void ReadNext(T nextVal, RestValues &&... restVals) - { - static_assert(std::is_pointer::value, "All values which are unpacked must be pointers (except CSVDiscard, CSVVaildate, CSVDiscard, CSVOptional, CSVSubReader)!"); - ThrowIfOutOfBounds(); - - //Here do conversion code - this->SafeConvert(nextVal, this->NextField()); - - this->_fieldTracker++; - ReadNext(std::forward(restVals)...); - } - - template - void ReadNext(CSVDiscard, RestValues &&... restVals) - { - this->_fieldTracker++; - this->SkipField(); - ReadNext(std::forward(restVals)...); - } - - template - void ReadNext(CSVValidator nextVal, RestValues &&... restVals) - { - ThrowIfOutOfBounds(); - - this->SafeConvert(nextVal.Get(), this->NextField()); - - if(!nextVal.Validate()) - throw std::logic_error("Validation failed at field " + std::to_string(this->_fieldTracker) + " at line " + std::to_string(this->_lineTracker) + "!"); - - this->_fieldTracker++; - ReadNext(std::forward(restVals)...); - } - - template - void ReadNext(CSVPostProcessor nextVal, RestValues &&... restVals) - { - ThrowIfOutOfBounds(); - - this->SafeConvert(nextVal.Get(), this->NextField()); - if(!nextVal.Validate()) - throw std::logic_error("Validation failed at field " + std::to_string(this->_fieldTracker) + " at line " + std::to_string(this->_lineTracker) + "!"); - nextVal.PostProcess(); - - this->_fieldTracker++; - ReadNext(std::forward(restVals)...); - } - - template - void ReadNext(CSVOptional optionalObj, RestValues &&... restVals) - { - // If we already reached the end, then assign default - if(this->_currentCharIndex >= StrTUtils::length(this->_currentLine)) - optionalObj.AssignDefault(); - else - { - StrT nextField = this->NextField(); - if(!optionalObj.ShouldAssingDefaultOnEmpty() || StrTUtils::length(nextField) > 0) { - this->SafeConvert(optionalObj.Get(), nextField); - if (!optionalObj.Validate()) - throw std::logic_error("Validation failed at field " + std::to_string(this->_fieldTracker) + " at line " + std::to_string(this->_lineTracker) + "!"); - optionalObj.PostProcess(); - } else { - optionalObj.AssignDefault(); - } - } - - this->_fieldTracker++; - ReadNext(std::forward(restVals)...); - } - - template - void ReadNext(CSVSubReader subReaderObj, RestValues &&... restVals) - { - if(!subReaderObj.IsOptional()) - ThrowIfOutOfBounds(); - - // We don't have to check for subReaderObj.IsOptional again, because - // ThrowIfOutOfBounds() would have thrown already - if(!(this->_currentCharIndex >= StrTUtils::length(this->_currentLine))) - { - try - { - subReaderObj.ReadDataLine(this->NextField()); - } - catch(...) - { - this->ThrowParseErrorInCatchContext(); - } - } - - this->_fieldTracker++; - ReadNext(std::forward(restVals)...); - } - - template - void ReadNext(CSVBatchReader subBatchReaderObj, RestValues &&... restVals) - { - ThrowIfOutOfBounds(); - - try - { - subBatchReaderObj.ReadDataLine(this->NextField()); - } - catch(...) - { - this->ThrowParseErrorInCatchContext(); - } - - this->_fieldTracker++; - ReadNext(std::forward(restVals)...); - } - - template - void ReadNext(CSVIterator iteratorObj, RestValues &&... restVals) - { - if(!iteratorObj.IsOptional()) - ThrowIfOutOfBounds(); - - // We don't have to check for iteratorObj.IsOptional again, because - // ThrowIfOutOfBounds() would have thrown already - if(!(this->_currentCharIndex >= StrTUtils::length(this->_currentLine))) - { - try - { - iteratorObj.ReadDataLine(this->NextField()); - } - catch(...) - { - this->ThrowParseErrorInCatchContext(); - } - } - - this->_fieldTracker++; - ReadNext(std::forward(restVals)...); - } - - void ReadNext() {} - public: - /*! - * \brief Read the next data line and pushes the result directly to the parameter. - * - * allValues must be pointer with the exception of: - * * CSVDiscard - * * CSVValidator - * * CSVPostProcessor - * * CSVOptional - * * CSVSubReader - * * CSVBatchReader - * * CSVIterator - * - * \throws std::nested_exception When a parsing or conversion error happens. - * - */ - template - CSVReader &ReadDataLine(Values &&... allValues) - { - this->_lineTracker++; - this->_currentCharIndex = 0; - _currentTotalFields = sizeof...(allValues); - this->_fieldTracker = 0; // We need the tracker at 0 (because of out of range exception) - if(_requireReadLine) - this->_currentLine = _reader->read_line(); - ReadNext(std::forward(allValues)...); - _requireReadLine = true; - - - return *this; - } - - - /*! - * \brief Read the next data line and calls iteration function with passing every field. - * - * \throws std::nested_exception When a parsing or conversion error happens. - */ - template - CSVReader& IterateDataLine(const IteratorFunc &iteratorFunc) - { - this->_lineTracker++; - this->_currentCharIndex = 0; - this->_fieldTracker = 0; // We need the tracker at 0 (because of out of range exception) - _currentTotalFields = 0; - - if(_requireReadLine) - this->_currentLine = _reader->read_line(); - while(this->HasNext()) - { - StrT next = this->NextField(); - if(!(next == "")) - iteratorFunc(next); - } - _requireReadLine = true; - - return *this; - } - - - // Begins with 1 - /*! - * \brief Read out (peeking) a field without going to the next line. - */ - template - T ReadField(int fieldNum) - { - if(_requireReadLine) - this->_currentLine = _reader->read_line(); - _requireReadLine = false; - this->_currentCharIndex = 0; - - StrT field; - for(int i = 1; i < fieldNum; i++) - { - if(this->_currentCharIndex >= StrTUtils::length(this->_currentLine)) - throw std::logic_error("Expected " + std::to_string(fieldNum) + " CSV-Fields, got " + std::to_string(i - 1) + " @ line " + std::to_string(this->_lineTracker) + "!"); - - this->SkipField(); - } - field = this->NextField(); - - T value; - Converter::Convert(&value, field); - return value; - } - - }; - - /*! - * \brief Creates a new CSVReader. - * \see CSVReader - * - * StrT template argument is the string class type. - * StrTUtils is a wrapper for the StrT class providing following static functions: - * static bool find(const StrT& str, CharT sep, size_t& findIndex) - * static size_t length(const target_string& str) - * static target_string substring(const target_string& str, size_t pos, size_t count) - * - * Converter is a wrapper for converting StrT fields to literal types: - * template - * static void Convert(T* out, const StrType& field) - */ - template - constexpr CSVReader MakeCSVReader(Reader *reader, CharT /*sep*/) - { - return CSVReader(reader); - } - - - namespace detail - { - template - struct CSVReaderFromReaderType - { - typedef typename Reader::string_type string_type; - typedef typename string_type::value_type value_type; - typedef typename string_type::traits_type traits_type; - typedef typename string_type::allocator_type allocator_type; - - typedef CSVReader, DefaultCSVConverter> full_type; - }; - } - - /*! - * \brief Creates a new CSVReader for STL strings. (std::string, std::wstring, ...) - * \see CSVReader - */ - template - constexpr typename detail::CSVReaderFromReaderType::full_type MakeCSVReaderFromBasicString(Reader *reader, CharT sep) - { - typedef detail::CSVReaderFromReaderType csv_reader_type; - typedef typename csv_reader_type::value_type value_type; - - static_assert(std::is_same::value, "Value type of basic_string must be the same as the type of the seperator!"); - return typename csv_reader_type::full_type(reader, sep); - } - - - template - struct CSVSubReader - { - public: - CSVSubReader(CharT sep, bool isOptional, Values &&... allValues) : _sep(sep), _val(allValues...), _isOptional(isOptional) - {} - - void ReadDataLine(const StrT &val) - { - ReadDataLineImpl(val, detail::make_index_sequence {}); - } - - bool IsOptional() const - { - return _isOptional; - } - - private: - template - void ReadDataLineImpl(const StrT &val, detail::index_sequence) - { - DirectReader subReader(val); - CSVReader subCSVReader(&subReader, _sep); - subCSVReader.ReadDataLine(std::get(_val)...); - } - - CharT _sep; - std::tuple _val; - bool _isOptional; - }; - - /*! - * \brief Creates a new CSVSubReader. - * \see CSVSubReader - */ - template - constexpr CSVSubReader MakeCSVSubReader(const CSVReader &, SubChar sep, RestValues &&... values) - { - return CSVSubReader(sep, false, std::forward(values)...); - } - - /*! - * \brief Creates a new CSVSubReader, which is optional. It acts the same as CSVOptional - * \see CSVSubReader - * \see CSVOptional - */ - template - constexpr CSVSubReader MakeCSVOptionalSubReader(const CSVReader &, SubChar sep, RestValues &&... values) - { - return CSVSubReader(sep, true, std::forward(values)...); - } - - - - namespace detail - { - template - struct CSVBatchReaderFromContainer - { - typedef typename ContainerT::value_type ContainerValueT; - typedef CommonContainerUtils ContainerUtils; - - typedef CSVBatchReader full_type; - }; - } - - /*! - * \brief Creates a new CSVBatchReader - * \see CSVBatchReader - * - * An overload without PostProcessor - */ - template // The value converter - constexpr typename detail::CSVBatchReaderFromContainer::full_type - MakeCSVBatchReader(const CSVReader &, CharT sep, ContainerT *container) - { - typedef detail::CSVBatchReaderFromContainer csv_batch_reader_type; - - return typename csv_batch_reader_type::full_type(sep, container, nullptr); - } - - /*! - * \brief Creates a new CSVBatchReader - * \see CSVBatchReader - * - * This will create a new CSVBatchReader. The ContainerT type is required to - * expose the value type with ContainerT::value_type (STL compatible). - * - * In addition you can pass an optional PostProcessor function. - */ - template - constexpr typename detail::CSVBatchReaderFromContainer::full_type - MakeCSVBatchReader(const CSVReader &, SubCharT sep, ContainerT *container, const PostProcessorFunc &postProcessorFunc) - { - typedef detail::CSVBatchReaderFromContainer csv_batch_reader_type; - - return typename csv_batch_reader_type::full_type(sep, container, postProcessorFunc); - } - - - /*! - * \brief Creates a new CSVIterator - * \see CSVIterator - */ - template - constexpr CSVIterator - MakeCSVIterator(const CSVReader &, SubChar sep, const IteratorFunc &iteratorFunc) - { - return CSVIterator(sep, false, iteratorFunc); - } - - template - constexpr CSVIterator - MakeCSVOptionalIterator(const CSVReader &, SubChar sep, const IteratorFunc &iteratorFunc) - { - return CSVIterator(sep, true, iteratorFunc); - } -} - - - - -#endif diff --git a/LunaDll/libs/PGE_File_Formats/CSVReaderPGE.h b/LunaDll/libs/PGE_File_Formats/CSVReaderPGE.h deleted file mode 100644 index c007196f9..000000000 --- a/LunaDll/libs/PGE_File_Formats/CSVReaderPGE.h +++ /dev/null @@ -1,159 +0,0 @@ -#pragma once -#ifndef CSVREADERQT -#define CSVREADERQT - -#include "CSVReader.h" - -#include "pge_file_lib_globs.h" - -#if !defined(_MSC_VER) || _MSC_VER > 1800 - -namespace CSVReader -{ - struct CSVPGEReader - { - typedef PGESTRING string_type; - CSVPGEReader(PGE_FileFormats_misc::TextInput *reader) : _reader(reader) {} - - PGESTRING read_line() - { - return _reader->readLine(); - } - private: - PGE_FileFormats_misc::TextInput *_reader; - }; - - #ifdef PGE_FILES_QT - struct CSVPGESTRINGUtils - { - static bool find(const QString &str, QChar sep, size_t &findIndex) - { - int pos = str.indexOf(sep, findIndex); - if(pos == -1) - return false; - findIndex = static_cast(pos); - return true; - } - - static size_t length(const QString &str) - { - return static_cast(str.length()); - } - - static QString substring(const QString &str, size_t pos, size_t count) - { - return str.mid(pos, count); - } - }; - #else - struct CSVPGESTRINGUtils : DefaultStringWrapper, std::allocator> {}; - #endif - - #ifdef PGE_FILES_QT - struct CSVPGESTRINGConverter - { - static void Convert(double *out, const QString &field) - { - bool ok = true; - *out = field.toDouble(&ok); - if(!ok) - throw std::invalid_argument("Could not convert to double"); - } - static void Convert(float *out, const QString &field) - { - bool ok = true; - *out = field.toFloat(&ok); - if(!ok) - throw std::invalid_argument("Could not convert to float"); - } - static void Convert(int *out, const QString &field) - { - bool ok = true; - *out = field.toInt(&ok); - if(!ok) - throw std::invalid_argument("Could not convert to int"); - } - static void Convert(long *out, const QString &field) - { - bool ok = true; - *out = field.toLong(&ok); - if(!ok) - throw std::invalid_argument("Could not convert to long"); - } - static void Convert(long long *out, const QString &field) - { - bool ok = true; - *out = field.toLongLong(&ok); - if(!ok) - throw std::invalid_argument("Could not convert to long long"); - } - static void Convert(long double *out, const QString &field) - { - bool ok = true; - *out = field.toDouble(&ok); - if(!ok) - throw std::invalid_argument("Could not convert to long double"); - } - static void Convert(unsigned int *out, const QString &field) - { - bool ok = true; - *out = static_cast(field.toULong(&ok)); - if(!ok) - throw std::invalid_argument("Could not convert to unsigned int"); - } - static void Convert(unsigned long *out, const QString &field) - { - bool ok = true; - *out = field.toULong(&ok); - if(!ok) - throw std::invalid_argument("Could not convert to unsigned long"); - } - static void Convert(unsigned long long *out, const QString &field) - { - bool ok = true; - *out = field.toULongLong(&ok); - if(!ok) - throw std::invalid_argument("Could not convert to unsigned long long"); - } - static void Convert(bool *out, const QString &field) - { - if(field == "0" || field == "") // FIXME: Is it correct? Or too hackish? - *out = false; - else if(field == "!0" || field == "1") // FIXME: Is it correct? Or too hackish? - *out = true; - else - throw std::invalid_argument(std::string("Could not convert to bool (must be empty, \"0\", \"!0\" or \"1\"), got \"") + field.toStdString() + std::string("\"")); - } - static void Convert(QString *out, const QString &field) - { - *out = field; - } - }; - #else - struct CSVPGESTRINGConverter : DefaultCSVConverter {}; - #endif - - namespace detail - { - template - struct CSVReaderFromPGESTRING - { - typedef typename Reader::string_type string_type; - typedef typename string_type::value_type value_type; - - typedef CSVReader full_type; - }; - } - - template - constexpr typename detail::CSVReaderFromPGESTRING::full_type MakeCSVReaderForPGESTRING(Reader *reader, CharT sep) - { - return typename detail::CSVReaderFromPGESTRING::full_type(reader, sep); - } - -} - -#endif - - -#endif // CSVREADERQT diff --git a/LunaDll/libs/PGE_File_Formats/CSVUtils.h b/LunaDll/libs/PGE_File_Formats/CSVUtils.h deleted file mode 100644 index 262bcfb70..000000000 --- a/LunaDll/libs/PGE_File_Formats/CSVUtils.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#ifndef CSVUtils_H -#define CSVUtils_H - -#include -#include - -// prints the explanatory string of an exception. If the exception is nested, -// recurses to print the explanatory of the exception it holds -inline std::string exception_to_pretty_string(const std::exception& e, int level = 0) -{ - std::string prettyString = std::string(static_cast(level), ' ') + "exception: " + std::string(e.what()) + "\n"; - #if !defined(_MSC_VER) || _MSC_VER > 1800 - try { - std::rethrow_if_nested(e); //This thing is not presented in MSVC2013 :-P - } - catch (const std::exception& e) { - prettyString += exception_to_pretty_string(e, level + 1); - } - catch (...) {} - #endif - - return prettyString; -} - -#endif - diff --git a/LunaDll/libs/PGE_File_Formats/ConvertUTF.h b/LunaDll/libs/PGE_File_Formats/ConvertUTF.h deleted file mode 100644 index 72fe686f0..000000000 --- a/LunaDll/libs/PGE_File_Formats/ConvertUTF.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2001-2004 Unicode, Inc. - * - * Disclaimer - * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. - * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. - */ - -#pragma once -#ifndef CONVERT_UTF_H -#define CONVERT_UTF_H - -/* --------------------------------------------------------------------- - - Conversions between UTF32, UTF-16, and UTF-8. Header file. - - Several funtions are included here, forming a complete set of - conversions between the three formats. UTF-7 is not included - here, but is handled in a separate source file. - - Each of these routines takes pointers to input buffers and output - buffers. The input buffers are const. - - Each routine converts the text between *sourceStart and sourceEnd, - putting the result into the buffer between *targetStart and - targetEnd. Note: the end pointers are *after* the last item: e.g. - *(sourceEnd - 1) is the last item. - - The return result indicates whether the conversion was successful, - and if not, whether the problem was in the source or target buffers. - (Only the first encountered problem is indicated.) - - After the conversion, *sourceStart and *targetStart are both - updated to point to the end of last text successfully converted in - the respective buffers. - - Input parameters: - sourceStart - pointer to a pointer to the source buffer. - The contents of this are modified on return so that - it points at the next thing to be converted. - targetStart - similarly, pointer to pointer to the target buffer. - sourceEnd, targetEnd - respectively pointers to the ends of the - two buffers, for overflow checking only. - - These conversion functions take a ConversionFlags argument. When this - flag is set to strict, both irregular sequences and isolated surrogates - will cause an error. When the flag is set to lenient, both irregular - sequences and isolated surrogates are converted. - - Whether the flag is strict or lenient, all illegal sequences will cause - an error return. This includes sequences such as: , , - or in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code - must check for illegal sequences. - - When the flag is set to lenient, characters over 0x10FFFF are converted - to the replacement character; otherwise (when the flag is set to strict) - they constitute an error. - - Output parameters: - The value "sourceIllegal" is returned from some routines if the input - sequence is malformed. When "sourceIllegal" is returned, the source - value will point to the illegal value that caused the problem. E.g., - in UTF-8 when a sequence is malformed, it points to the start of the - malformed sequence. - - Author: Mark E. Davis, 1994. - Rev History: Rick McGowan, fixes & updates May 2001. - Fixes & updates, Sept 2001. - ------------------------------------------------------------------------- */ - -/* --------------------------------------------------------------------- - The following 4 definitions are compiler-specific. - The C standard does not guarantee that wchar_t has at least - 16 bits, so wchar_t is no less portable than unsigned short! - All should be unsigned values to avoid sign extension during - bit mask & shift operations. ------------------------------------------------------------------------- */ - -typedef unsigned int UTF32; /* at least 32 bits */ -typedef unsigned short UTF16; /* at least 16 bits */ -typedef unsigned char UTF8; /* typically 8 bits */ -typedef unsigned char Boolean; /* 0 or 1 */ - -/* Some fundamental constants */ -#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD -#define UNI_MAX_BMP (UTF32)0x0000FFFF -#define UNI_MAX_UTF16 (UTF32)0x0010FFFF -#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF -#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF - -typedef enum { - conversionOK, /* conversion successful */ - sourceExhausted, /* partial character in source, but hit end */ - targetExhausted, /* insuff. room in target for conversion */ - sourceIllegal /* source sequence is illegal/malformed */ -} ConversionResult; - -typedef enum { - strictConversion = 0, - lenientConversion -} ConversionFlags; - -/* This is for C++ and does no harm in C */ -#ifdef __cplusplus -extern "C" { -#endif - -ConversionResult PGEFF_ConvertUTF8toUTF16 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); - -ConversionResult PGEFF_ConvertUTF16toUTF8 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); - -ConversionResult PGEFF_ConvertUTF8toUTF32 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); - -ConversionResult PGEFF_ConvertUTF32toUTF8 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); - -ConversionResult PGEFF_ConvertUTF16toUTF32 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); - -ConversionResult PGEFF_ConvertUTF32toUTF16 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); - -Boolean PGEFF_isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); - -#ifdef __cplusplus -} -#endif - -/* --------------------------------------------------------------------- */ -#endif //CONVERT_UTF_H diff --git a/LunaDll/libs/PGE_File_Formats/ConvertUTF_PGEFF.c b/LunaDll/libs/PGE_File_Formats/ConvertUTF_PGEFF.c deleted file mode 100644 index 440f9acfb..000000000 --- a/LunaDll/libs/PGE_File_Formats/ConvertUTF_PGEFF.c +++ /dev/null @@ -1,683 +0,0 @@ -/* - * Copyright 2001-2004 Unicode, Inc. - * - * Disclaimer - * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. - * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. - */ - -/* --------------------------------------------------------------------- - - Conversions between UTF32, UTF-16, and UTF-8. Source code file. - Author: Mark E. Davis, 1994. - Rev History: Rick McGowan, fixes & updates May 2001. - Sept 2001: fixed const & error conditions per - mods suggested by S. Parent & A. Lillich. - June 2002: Tim Dodd added detection and handling of incomplete - source sequences, enhanced error detection, added casts - to eliminate compiler warnings. - July 2003: slight mods to back out aggressive FFFE detection. - Jan 2004: updated switches in from-UTF8 conversions. - Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. - - See the header file "ConvertUTF.h" for complete documentation. - - EDIT: 2017-02-04, Vitaly Novichkov: - Functions now has PGEFF_ prefix to avoid conflict of using same library with others. ------------------------------------------------------------------------- */ - -#include "ConvertUTF.h" -#ifdef CVTUTF_DEBUG -#include -#endif - -static const int halfShift = 10; /* used for shifting by 10 bits */ - -static const UTF32 halfBase = 0x0010000UL; -static const UTF32 halfMask = 0x3FFUL; - -#define UNI_SUR_HIGH_START (UTF32)0xD800 -#define UNI_SUR_HIGH_END (UTF32)0xDBFF -#define UNI_SUR_LOW_START (UTF32)0xDC00 -#define UNI_SUR_LOW_END (UTF32)0xDFFF -#define False 0 -#define True 1 - -/* --------------------------------------------------------------------- */ - -ConversionResult PGEFF_ConvertUTF32toUTF16( - const UTF32 **sourceStart, const UTF32 *sourceEnd, - UTF16 **targetStart, UTF16 *targetEnd, ConversionFlags flags) -{ - ConversionResult result = conversionOK; - const UTF32 *source = *sourceStart; - UTF16 *target = *targetStart; - while(source < sourceEnd) - { - UTF32 ch; - if(target >= targetEnd) - { - result = targetExhausted; - break; - } - ch = *source++; - if(ch <= UNI_MAX_BMP) /* Target is a character <= 0xFFFF */ - { - /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */ - if(ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) - { - if(flags == strictConversion) - { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - else - { - *target++ = UNI_REPLACEMENT_CHAR; - } - } - else - { - *target++ = (UTF16)ch; /* normal case */ - } - } - else if(ch > UNI_MAX_LEGAL_UTF32) - { - if(flags == strictConversion) - { - result = sourceIllegal; - } - else - { - *target++ = UNI_REPLACEMENT_CHAR; - } - } - else - { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if(target + 1 >= targetEnd) - { - --source; /* Back up source pointer! */ - result = targetExhausted; - break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult PGEFF_ConvertUTF16toUTF32( - const UTF16 **sourceStart, const UTF16 *sourceEnd, - UTF32 **targetStart, UTF32 *targetEnd, ConversionFlags flags) -{ - ConversionResult result = conversionOK; - const UTF16 *source = *sourceStart; - UTF32 *target = *targetStart; - UTF32 ch, ch2; - while(source < sourceEnd) - { - const UTF16 *oldSource = source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if(ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) - { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if(source < sourceEnd) - { - ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if(ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) - { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) - + (ch2 - UNI_SUR_LOW_START) + halfBase; - ++source; - } - else if(flags == strictConversion) /* it's an unpaired high surrogate */ - { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - else /* We don't have the 16 bits following the high surrogate. */ - { - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } - else if(flags == strictConversion) - { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if(ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) - { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - if(target >= targetEnd) - { - source = oldSource; /* Back up source pointer! */ - result = targetExhausted; - break; - } - *target++ = ch; - } - *sourceStart = source; - *targetStart = target; - #ifdef CVTUTF_DEBUG - if(result == sourceIllegal) - { - fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2); - fflush(stderr); - } - #endif - return result; -} - -/* --------------------------------------------------------------------- */ - -/* - * Index into the table below with the first byte of a UTF-8 sequence to - * get the number of trailing bytes that are supposed to follow it. - * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is - * left as-is for anyone who may want to do such conversion, which was - * allowed in earlier algorithms. - */ -static const char trailingBytesForUTF8[256] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 -}; - -/* - * Magic values subtracted from a buffer value during UTF8 conversion. - * This table contains as many values as there might be trailing bytes - * in a UTF-8 sequence. - */ -static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, - 0x03C82080UL, 0xFA082080UL, 0x82082080UL - }; - -/* - * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed - * into the first byte, depending on how many bytes follow. There are - * as many entries in this table as there are UTF-8 sequence types. - * (I.e., one byte sequence, two byte... etc.). Remember that sequencs - * for *legal* UTF-8 will be 4 or fewer bytes total. - */ -static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -/* --------------------------------------------------------------------- */ - -/* The interface converts a whole buffer to avoid function-call overhead. - * Constants have been gathered. Loops & conditionals have been removed as - * much as possible for efficiency, in favor of drop-through switches. - * (See "Note A" at the bottom of the file for equivalent code.) - * If your compiler supports it, the "isLegalUTF8" call can be turned - * into an inline function. - */ - -/* --------------------------------------------------------------------- */ - -ConversionResult PGEFF_ConvertUTF16toUTF8( - const UTF16 **sourceStart, const UTF16 *sourceEnd, - UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags) -{ - ConversionResult result = conversionOK; - const UTF16 *source = *sourceStart; - UTF8 *target = *targetStart; - while(source < sourceEnd) - { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - const UTF16 *oldSource = source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if(ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) - { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if(source < sourceEnd) - { - UTF32 ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if(ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) - { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) - + (ch2 - UNI_SUR_LOW_START) + halfBase; - ++source; - } - else if(flags == strictConversion) /* it's an unpaired high surrogate */ - { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - else /* We don't have the 16 bits following the high surrogate. */ - { - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } - else if(flags == strictConversion) - { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if(ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) - { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* Figure out how many bytes the result will require */ - if(ch < (UTF32)0x80) - { - bytesToWrite = 1; - } - else if(ch < (UTF32)0x800) - { - bytesToWrite = 2; - } - else if(ch < (UTF32)0x10000) - { - bytesToWrite = 3; - } - else if(ch < (UTF32)0x110000) - { - bytesToWrite = 4; - } - else - { - bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - } - - target += bytesToWrite; - if(target > targetEnd) - { - source = oldSource; /* Back up source pointer! */ - target -= bytesToWrite; - result = targetExhausted; - break; - } - - switch(bytesToWrite) /* note: everything falls through. */ - { - case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); - } - - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -/* - * Utility routine to tell whether a sequence of bytes is legal UTF-8. - * This must be called with the length pre-determined by the first byte. - * If not calling this from ConvertUTF8to*, then the length can be set by: - * length = trailingBytesForUTF8[*source]+1; - * and the sequence is illegal right away if there aren't that many bytes - * available. - * If presented with a length > 4, this returns false. The Unicode - * definition of UTF-8 goes up to 4-byte sequences. - */ - -static Boolean isLegalUTF8(const UTF8 *source, int length) -{ - UTF8 a; - const UTF8 *srcptr = source + length; - - switch(length) - { - default: - return False; - /* Everything else falls through when "true"... */ - case 4: if((a = (*--srcptr)) < 0x80 || a > 0xBF) return False; - case 3: if((a = (*--srcptr)) < 0x80 || a > 0xBF) return False; - case 2: if((a = (*--srcptr)) > 0xBF) return False; - switch(*source) - { - /* no fall-through in this inner switch */ - case 0xE0: if(a < 0xA0) return False; break; - case 0xED: if(a > 0x9F) return False; break; - case 0xF0: if(a < 0x90) return False; break; - case 0xF4: if(a > 0x8F) return False; break; - default: if(a < 0x80) return False; - } - case 1: - if(*source >= 0x80 && *source < 0xC2) return False; - } - - if(*source > 0xF4) return False; - return True; -} - -/* --------------------------------------------------------------------- */ - -/* - * Exported function to return whether a UTF-8 sequence is legal or not. - * This is not used here; it's just exported. - */ -Boolean PGEFF_isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) -{ - int length = trailingBytesForUTF8[*source] + 1; - if(source + length > sourceEnd) - { - return False; - } - return isLegalUTF8(source, length); -} - -/* --------------------------------------------------------------------- */ - -ConversionResult PGEFF_ConvertUTF8toUTF16( - const UTF8 **sourceStart, const UTF8 *sourceEnd, - UTF16 **targetStart, UTF16 *targetEnd, ConversionFlags flags) -{ - ConversionResult result = conversionOK; - const UTF8 *source = *sourceStart; - UTF16 *target = *targetStart; - while(source < sourceEnd) - { - UTF32 ch = 0; - unsigned short extraBytesToRead = (unsigned short)trailingBytesForUTF8[*source]; - if(source + extraBytesToRead >= sourceEnd) - { - result = sourceExhausted; - break; - } - /* Do this check whether lenient or strict */ - if(! isLegalUTF8(source, extraBytesToRead + 1)) - { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch(extraBytesToRead) - { - case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - - ch -= offsetsFromUTF8[extraBytesToRead]; - - if(target >= targetEnd) - { - source -= (extraBytesToRead + 1); /* Back up source pointer! */ - result = targetExhausted; - break; - } - if(ch <= UNI_MAX_BMP) /* Target is a character <= 0xFFFF */ - { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if(ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) - { - if(flags == strictConversion) - { - source -= (extraBytesToRead + 1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - else - { - *target++ = UNI_REPLACEMENT_CHAR; - } - } - else - { - *target++ = (UTF16)ch; /* normal case */ - } - } - else if(ch > UNI_MAX_UTF16) - { - if(flags == strictConversion) - { - result = sourceIllegal; - source -= (extraBytesToRead + 1); /* return to the start */ - break; /* Bail out; shouldn't continue */ - } - else - { - *target++ = UNI_REPLACEMENT_CHAR; - } - } - else - { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if(target + 1 >= targetEnd) - { - source -= (extraBytesToRead + 1); /* Back up source pointer! */ - result = targetExhausted; - break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult PGEFF_ConvertUTF32toUTF8( - const UTF32 **sourceStart, const UTF32 *sourceEnd, - UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags) -{ - ConversionResult result = conversionOK; - const UTF32 *source = *sourceStart; - UTF8 *target = *targetStart; - while(source < sourceEnd) - { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - ch = *source++; - if(flags == strictConversion) - { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if(ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) - { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* - * Figure out how many bytes the result will require. Turn any - * illegally large UTF32 things (> Plane 17) into replacement chars. - */ - if(ch < (UTF32)0x80) - { - bytesToWrite = 1; - } - else if(ch < (UTF32)0x800) - { - bytesToWrite = 2; - } - else if(ch < (UTF32)0x10000) - { - bytesToWrite = 3; - } - else if(ch <= UNI_MAX_LEGAL_UTF32) - { - bytesToWrite = 4; - } - else - { - bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - result = sourceIllegal; - } - - target += bytesToWrite; - if(target > targetEnd) - { - --source; /* Back up source pointer! */ - target -= bytesToWrite; - result = targetExhausted; - break; - } - - switch(bytesToWrite) /* note: everything falls through. */ - { - case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); - } - - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult PGEFF_ConvertUTF8toUTF32( - const UTF8 **sourceStart, const UTF8 *sourceEnd, - UTF32 **targetStart, UTF32 *targetEnd, ConversionFlags flags) -{ - ConversionResult result = conversionOK; - const UTF8 *source = *sourceStart; - UTF32 *target = *targetStart; - while(source < sourceEnd) - { - UTF32 ch = 0; - unsigned short extraBytesToRead = (unsigned short)trailingBytesForUTF8[*source]; - if(source + extraBytesToRead >= sourceEnd) - { - result = sourceExhausted; - break; - } - /* Do this check whether lenient or strict */ - if(! isLegalUTF8(source, extraBytesToRead + 1)) - { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch(extraBytesToRead) - { - case 5: ch += *source++; ch <<= 6; - case 4: ch += *source++; ch <<= 6; - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - - ch -= offsetsFromUTF8[extraBytesToRead]; - - if(target >= targetEnd) - { - source -= (extraBytesToRead + 1); /* Back up the source pointer! */ - result = targetExhausted; - break; - } - if(ch <= UNI_MAX_LEGAL_UTF32) - { - /* - * UTF-16 surrogate values are illegal in UTF-32, and anything - * over Plane 17 (> 0x10FFFF) is illegal. - */ - if(ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) - { - if(flags == strictConversion) - { - source -= (extraBytesToRead + 1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - else - { - *target++ = UNI_REPLACEMENT_CHAR; - } - } - else - { - *target++ = ch; - } - } - else /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ - { - result = sourceIllegal; - *target++ = UNI_REPLACEMENT_CHAR; - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- - - Note A. - The fall-through switches in UTF-8 reading code save a - temp variable, some decrements & conditionals. The switches - are equivalent to the following loop: - { - int tmpBytesToRead = extraBytesToRead+1; - do { - ch += *source++; - --tmpBytesToRead; - if (tmpBytesToRead) ch <<= 6; - } while (tmpBytesToRead > 0); - } - In UTF-8 writing code, the switches on "bytesToWrite" are - similarly unrolled loops. - - --------------------------------------------------------------------- */ diff --git a/LunaDll/libs/PGE_File_Formats/File_FormatsQT.pri b/LunaDll/libs/PGE_File_Formats/File_FormatsQT.pri deleted file mode 100644 index c28ce1101..000000000 --- a/LunaDll/libs/PGE_File_Formats/File_FormatsQT.pri +++ /dev/null @@ -1,21 +0,0 @@ -#---------------------------------------------------------------------------- -# -# Platformer Game Engine by Wohlstand, a free platform for game making -# Copyright (c) 2014-2016 Vitaly Novichkov -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -DEFINES += PGE_FILES_QT -include($$PWD/File_FormatsSTL.pri) diff --git a/LunaDll/libs/PGE_File_Formats/File_FormatsSTL.pri b/LunaDll/libs/PGE_File_Formats/File_FormatsSTL.pri deleted file mode 100644 index fca35d511..000000000 --- a/LunaDll/libs/PGE_File_Formats/File_FormatsSTL.pri +++ /dev/null @@ -1,66 +0,0 @@ -#---------------------------------------------------------------------------- -# -# Platformer Game Engine by Wohlstand, a free platform for game making -# Copyright (c) 2014-2016 Vitaly Novichkov -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -CONFIG += C++11 - -!contains(DEFINES, PGE_FILES_QT): SOURCES += $$PWD/ConvertUTF_PGEFF.c - -SOURCES += $$PWD/file_formats.cpp \ - $$PWD/file_rw_lvl.cpp \ - $$PWD/file_rw_lvl_38a.cpp \ - $$PWD/file_rw_lvlx.cpp \ - $$PWD/file_rw_meta.cpp \ - $$PWD/file_rw_npc_txt.cpp \ - $$PWD/file_rw_sav.cpp \ - $$PWD/file_rw_wld.cpp \ - $$PWD/file_rw_wldx.cpp \ - $$PWD/file_rw_smbx64_cnf.cpp \ - $$PWD/file_rwopen.cpp \ - $$PWD/file_strlist.cpp \ - $$PWD/lvl_filedata.cpp \ - $$PWD/npc_filedata.cpp \ - $$PWD/pge_x.cpp \ - $$PWD/save_filedata.cpp \ - $$PWD/smbx64.cpp \ - $$PWD/smbx64_cnf_filedata.cpp \ - $$PWD/wld_filedata.cpp \ - $$PWD/pge_file_lib_globs.cpp \ - $$PWD/file_rw_savx.cpp \ - $$PWD/file_rw_lvl_38a_old.cpp \ - $$PWD/file_rw_wld_38a.cpp - -HEADERS += $$PWD/file_formats.h \ - $$PWD/file_strlist.h \ - $$PWD/lvl_filedata.h \ - $$PWD/meta_filedata.h \ - $$PWD/npc_filedata.h \ - $$PWD/pge_x.h \ - $$PWD/pge_x_macro.h \ - $$PWD/save_filedata.h \ - $$PWD/smbx64.h \ - $$PWD/smbx64_macro.h \ - $$PWD/wld_filedata.h \ - $$PWD/pge_file_lib_globs.h \ - $$PWD/pge_file_lib_sys.h \ - $$PWD/smbx64_cnf_filedata.h \ - $$PWD/CSVReader.h \ - $$PWD/CSVReaderPGE.h \ - $$PWD/CSVUtils.h \ - $$PWD/pge_ff_units.h \ - $$PWD/smbx38a_private.h diff --git a/LunaDll/libs/PGE_File_Formats/LICENSE b/LunaDll/libs/PGE_File_Formats/LICENSE deleted file mode 100644 index 9cecc1d46..000000000 --- a/LunaDll/libs/PGE_File_Formats/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - {one line to give the program's name and a brief idea of what it does.} - Copyright (C) {year} {name of author} - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - {project} Copyright (C) {year} {fullname} - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/LunaDll/libs/PGE_File_Formats/README.md b/LunaDll/libs/PGE_File_Formats/README.md deleted file mode 100644 index 230bb1ba5..000000000 --- a/LunaDll/libs/PGE_File_Formats/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# PGE File Library v 0.3.1.13 ----- -This library is a part of PGE Project. ----- -Supported file formats: - -``` -PGE-X Family: -*.lvlx PGE-X Level File - Read/Write -*.wldx PGE-X World File - Read/Write -*.savx PGE-X Game save File - Read/Write -*.meta PGE-X non-SMBX64 Meta File - Read/Write -SMBX-64 Family: -*.lvl SMBX 1...64 Level File - Read/Write -*.wld SMBX 1...64 World File - Read/Write -*.sav SMBX 1...64 Game save File - Read only -*.dat SMBX 1...64 Game config File - Read/Write -*.txt SMBX64 NPC Custom text config - Read/Write -SMBX-38A Family: -*.lvl SMBX-38A Level File - Read/Write -*.wld SMBX-38A World File - Read/(planned)Write -*.wls SMBX-38A World settings - (planned)Read/Write -*.sav SMBX-38A Game save File - (planned)Read/Write -``` - ----- -Use library with this header: - -```cpp -#include "file_formats.h" -``` - ----- - -Library parses and generates files or RAW text strings. -You can read file as from file, also from the memory, -you can use the openLevelFile() or openWorldFile() functions to open -necessary file more convenient. - -# Notes for files of SMBX-64 format: -1) If you saving file from raw data yourself, you must save a text file with CRLF -for SMBX-* formats, or file will be not readable by SMBX Engine. -You can write a file like binary, but when you detecting '\n' byte, -write a CRLF ("\r\n") bytes instead! - -2) When you saving a level file (World file is not requires that) into Legacy Engine's format, -you must prepare data structure before saving it: -```C++ -FileFormats::smbx64LevelPrepare(YourLevelData); //To initialize order priorities fields and mark all star NPCs -``` - -3) If you trying to use PGE File data in the LunaLUA, before fill internal arrays, need to apply next set of the functions: - -```C++ -FileFormats::smbx64LevelPrepare(YourLevelData); //To initialize order priorities fields and mark all star NPCs -FileFormats::smbx64LevelSortBlocks(YourLevelData); //Order blocks -FileFormats::smbx64LevelSortBGOs(YourLevelData); //Order BGO's -``` - diff --git a/LunaDll/libs/PGE_File_Formats/charsetconvert.h b/LunaDll/libs/PGE_File_Formats/charsetconvert.h deleted file mode 100644 index 2e6e78300..000000000 --- a/LunaDll/libs/PGE_File_Formats/charsetconvert.h +++ /dev/null @@ -1,214 +0,0 @@ -#ifndef CHARSETCONVERT_H -#define CHARSETCONVERT_H - -#define SI_NO_MBSTOWCS_NULL - -#define SI_Case SI_GenericCase -#define SI_NoCase SI_GenericNoCase - -#include -#include "ConvertUTF.h" -#include - -/** - * Converts UTF-8 to a wchar_t (or equivalent) using the Unicode reference - * library functions. This can be used on all platforms. - */ -template -class SI_ConvertW { - bool m_bStoreIsUtf8; -protected: - SI_ConvertW() { } -public: - SI_ConvertW(bool a_bStoreIsUtf8) : m_bStoreIsUtf8(a_bStoreIsUtf8) { } - - /* copy and assignment */ - SI_ConvertW(const SI_ConvertW & rhs) { operator=(rhs); } - SI_ConvertW & operator=(const SI_ConvertW & rhs) { - m_bStoreIsUtf8 = rhs.m_bStoreIsUtf8; - return *this; - } - - static size_t utf8len(const char *s) - { - size_t len = 0; - while(*s) - len += (*(s++)&0xC0)!=0x80; - return len; - } - - /** Calculate the number of SI_CHAR required for converting the input - * from the storage format. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to SI_CHAR. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @return Number of SI_CHAR required by the string when - * converted. If there are embedded NULL bytes in the - * input data, only the string up and not including - * the NULL byte will be converted. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeFromStore( - const char * a_pInputData, - size_t a_uInputDataLen) - { - //SI_ASSERT(a_uInputDataLen != (size_t) -1); - - if (m_bStoreIsUtf8) { - return utf8len(a_pInputData); - } - -#if defined(SI_NO_MBSTOWCS_NULL) || (!defined(_MSC_VER) && !defined(_linux)) - // fall back processing for platforms that don't support a NULL dest to mbstowcs - // worst case scenario is 1:1, this will be a sufficient buffer size - (void)a_pInputData; - return a_uInputDataLen; -#else - // get the actual required buffer size - return mbstowcs(NULL, a_pInputData, a_uInputDataLen); -#endif - } - - /** Convert the input string from the storage format to SI_CHAR. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to SI_CHAR. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @param a_pOutputData Pointer to the output buffer to received the - * converted data. - * @param a_uOutputDataSize Size of the output buffer in SI_CHAR. - * @return true if all of the input data was successfully - * converted. - */ - bool ConvertFromStore( - const char * a_pInputData, - size_t a_uInputDataLen, - SI_CHAR * a_pOutputData, - size_t a_uOutputDataSize) - { - if (m_bStoreIsUtf8) { - // This uses the Unicode reference implementation to do the - // conversion from UTF-8 to wchar_t. The required files are - // ConvertUTF.h and ConvertUTF.c which should be included in - // the distribution but are publically available from unicode.org - // at http://www.unicode.org/Public/PROGRAMS/CVTUTF/ - ConversionResult retval; - const UTF8 * pUtf8 = (const UTF8 *) a_pInputData; - if (sizeof(SI_CHAR) == sizeof(UTF32)) { - UTF32 * pUtf32 = (UTF32 *) a_pOutputData; - retval = PGEFF_ConvertUTF8toUTF32( - &pUtf8, pUtf8 + a_uInputDataLen, - &pUtf32, pUtf32 + a_uOutputDataSize, - lenientConversion); - } - else if (sizeof(SI_CHAR) == sizeof(UTF16)) { - UTF16 * pUtf16 = (UTF16 *) a_pOutputData; - retval = PGEFF_ConvertUTF8toUTF16( - &pUtf8, pUtf8 + a_uInputDataLen, - &pUtf16, pUtf16 + a_uOutputDataSize, - lenientConversion); - } - return retval == conversionOK; - } - - // convert to wchar_t - size_t retval = mbstowcs(a_pOutputData, - a_pInputData, a_uOutputDataSize); - return retval != (size_t)(-1); - } - - /** Calculate the number of char required by the storage format of this - * data. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated string to calculate the number of - * bytes required to be converted to storage format. - * @return Number of bytes required by the string when - * converted to storage format. This size always - * includes space for the terminating NULL character. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeToStore( - const SI_CHAR * a_pInputData) - { - if (m_bStoreIsUtf8) { - // worst case scenario for wchar_t to UTF-8 is 1 wchar_t -> 6 char - size_t uLen = 0; - while (a_pInputData[uLen]) - { - ++uLen; - } - return (6 * uLen) + 1; - } - else { - size_t uLen = wcstombs(NULL, a_pInputData, 0); - if (uLen == (size_t)(-1)) { - return uLen; - } - return uLen + 1; // include NULL terminator - } - } - - /** Convert the input string to the storage format of this data. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated source string to convert. All of - * the data will be converted including the - * terminating NULL character. - * @param a_pOutputData Pointer to the buffer to receive the converted - * string. - * @param a_uOutputDataSize Size of the output buffer in char. - * @return true if all of the input data, including the - * terminating NULL character was successfully - * converted. - */ - bool ConvertToStore( - const SI_CHAR * a_pInputData, - char * a_pOutputData, - size_t a_uOutputDataSize - ) - { - if (m_bStoreIsUtf8) { - // calc input string length (SI_CHAR type and size independent) - size_t uInputLen = 0; - while (a_pInputData[uInputLen]) { - ++uInputLen; - } - ++uInputLen; // include the NULL char - - // This uses the Unicode reference implementation to do the - // conversion from wchar_t to UTF-8. The required files are - // ConvertUTF.h and ConvertUTF.c which should be included in - // the distribution but are publically available from unicode.org - // at http://www.unicode.org/Public/PROGRAMS/CVTUTF/ - ConversionResult retval; - UTF8 * pUtf8 = (UTF8 *) a_pOutputData; - if (sizeof(SI_CHAR) == sizeof(UTF32)) { - const UTF32 * pUtf32 = (const UTF32 *) a_pInputData; - retval = PGEFF_ConvertUTF32toUTF8( - &pUtf32, pUtf32 + uInputLen, - &pUtf8, pUtf8 + a_uOutputDataSize, - lenientConversion); - } - else if (sizeof(SI_CHAR) == sizeof(UTF16)) { - const UTF16 * pUtf16 = (const UTF16 *) a_pInputData; - retval = PGEFF_ConvertUTF16toUTF8( - &pUtf16, pUtf16 + uInputLen, - &pUtf8, pUtf8 + a_uOutputDataSize, - lenientConversion); - } - return retval == conversionOK; - } - else { - size_t retval = wcstombs(a_pOutputData, - a_pInputData, a_uOutputDataSize); - return retval != (size_t) -1; - } - } -}; - -#endif // CHARSETCONVERT_H - diff --git a/LunaDll/libs/PGE_File_Formats/file_formats.cpp b/LunaDll/libs/PGE_File_Formats/file_formats.cpp deleted file mode 100644 index 1bb4c124c..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_formats.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "pge_file_lib_sys.h" -#include "pge_file_lib_globs.h" - -#include "file_formats.h" -#ifdef PGE_EDITOR -#include -#endif - -PGESTRING FileFormats::errorString = ""; - -PGESTRING FileFormats::removeQuotes(PGESTRING str) -{ - PGESTRING target = str; - #ifdef PGE_FILES_QT - if(target.isEmpty()) - return target; - if(target[0] == QChar('\"')) - target.remove(0, 1); - if((!target.isEmpty()) && (target[target.size() - 1] == QChar('\"'))) - target.remove(target.size() - 1, 1); - #else - if(target.empty()) - return target; - if(target[0] == '\"') - target.erase(target.begin() + 0); - if((!target.empty()) && (target[target.size() - 1] == '\"')) - target.erase(target.begin() + (std::string::difference_type)target.size() - 1); - #endif - return target; -} - -PGESTRING FileFormats::getErrorString(FileFormats::ErrorCodes errCode) -{ - switch(errCode) - { - case Success: - return ""; - case ERROR_NotExist: - return "File not exist"; - case ERROR_AccessDenied: - return "Access denied"; - case ERROR_InvalidSyntax: - return "Invalid file format"; - case ERROR_PGEX_SectionNotClosed: - return "PGE-X Section is not closed"; - case ERROR_PGEX_InvalidSyntax: - return "PGE-X Invalid data entry syntax"; - case ERROR_PGEX_InvalidDataType: - return "PGE-X Invalid data type"; - } - return "Unknown error"; -} - -/***************************************************************************/ -#ifdef PGE_EDITOR -CrashData::CrashData() : used(false), untitled(false), modifyed(false), fmtID(0), fmtVer(64) {} - -CrashData::CrashData(const CrashData &_cd) -{ - this->used = _cd.used; - this->untitled = _cd.untitled; - this->modifyed = _cd.modifyed; - this->fmtID = _cd.fmtID; - this->fmtVer = _cd.fmtVer; - this->fullPath = _cd.fullPath; - this->filename = _cd.filename; - this->path = _cd.path; -} - -CrashData::CrashData(CrashData &_cd) -{ - this->used = _cd.used; - this->untitled = _cd.untitled; - this->modifyed = _cd.modifyed; - this->fmtID = _cd.fmtID; - this->fmtVer = _cd.fmtVer; - this->fullPath = _cd.fullPath; - this->filename = _cd.filename; - this->path = _cd.path; -} - -void CrashData::reset() -{ - used = false; - untitled = false; - modifyed = false; - fmtID = 0; - fmtVer = 0; - fullPath.clear(); - filename.clear(); - path.clear(); -} -#endif diff --git a/LunaDll/libs/PGE_File_Formats/file_formats.h b/LunaDll/libs/PGE_File_Formats/file_formats.h deleted file mode 100644 index 7647b2a46..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_formats.h +++ /dev/null @@ -1,977 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/*! \file file_formats.h - * \brief Main header of PGE File Library which includes all provided features set - */ - -#pragma once -#ifndef FILE_FORMATS_H -#define FILE_FORMATS_H - -#include "pge_file_lib_globs.h" -#include "lvl_filedata.h" -#include "npc_filedata.h" -#include "wld_filedata.h" -#include "save_filedata.h" -#include "smbx64_cnf_filedata.h" - -#ifdef __GNUC__ -#define DEPRECATED(func) func __attribute__ ((deprecated)) -#elif defined(_MSC_VER) -#define DEPRECATED(func) __declspec(deprecated) func -#else -#pragma message("WARNING: You need to implement DEPRECATED for this compiler") -#define DEPRECATED(func) func -#endif - -/*! - * \brief PGE File library class of static functions. - * Library is buildable in both Qt and STL applications - */ -#ifdef PGE_FILES_QT -class FileFormats: PGE_FILES_INHERED -{ - Q_OBJECT -#else -class FileFormats -{ -#endif - -public: - - /******************************non-SMBX64 Meda-data file***********************************/ - /*! - * \brief Parses non-SMBX64 meta-data from additional *.meta files - * there are contains data which impossible to save into SMBX64 LVL file - * therefore it will be saved into additional *.meta file - * \param [__in] filePath Full path to file with meta-data - * \param [__out] FileData Meta-data structure - * \return true if file successfully opened and parsed, false if error occouped - */ - static bool ReadNonSMBX64MetaDataF(PGESTRING filePath, MetaData &FileData); - /*! - * \brief Parses non-SMBX64 meta-data from additional *.meta files - * there are contains data which impossible to save into SMBX64 LVL file - * therefore it will be saved into additional *.meta file - * \param [__in] rawdata Raw data of the meta-data - * \param [__in] filePath Full path to file with meta-data (needed to detect custom directory info) - * \param [__out] FileData Meta-data structure - * \return true if file successfully opened and parsed, false if error occouped - */ - static bool ReadNonSMBX64MetaDataRaw(PGESTRING &rawdata, PGESTRING filePath, MetaData &FileData); - /*! - * \brief Parses non-SMBX64 meta-data from additional *.meta files - * there are contains data which impossible to save into SMBX64 LVL file - * therefore it will be saved into additional *.meta file - * \param [__in] in File input descriptor - * \param [__out] FileData FileData Meta-data structure - * \return true if file successfully opened and parsed, false if error occouped - */ - static bool ReadNonSMBX64MetaDataFile(PGE_FileFormats_misc::TextInput &in, MetaData /*output*/ &FileData); - /*! - * \brief Saves data of non-SMBX meta-data into the file from Meta-data structure - * \param [__in] filePath Full path to file where need to save - * \param [__in] metaData Meta-data structure - * \return true if file successfully opened and parsed, false if error occouped - */ - static bool WriteNonSMBX64MetaDataF(PGESTRING filePath, MetaData &metaData); - /*! - * \brief Generates raw data of non-SMBX meta-data from level data structure - * \param [__in] metaData Meta-data structure - * \param [__out] rawdata raw PGE-X data of meta-data structure - * \return true if file successfully opened and parsed, false if error occouped - */ - static bool WriteNonSMBX64MetaDataRaw(MetaData &metaData, PGESTRING &rawdata); - /*! - * \brief Writes raw data of non-SMBX meta-data from level data through file descriptor - * \param [__inout] out File output descriptor - * \param [__in] metaData Meta-data structure - * \return true if file successfully opened and parsed, false if error occouped - */ - static bool WriteNonSMBX64MetaData(PGE_FileFormats_misc::TextOutput &out, MetaData /*Output*/ &metaData); - - - /******************************Level files***********************************/ - /*! - * \brief Supported level file formats - */ - enum LevelFileFormat - { - //! PGE-X LVLX Level File format - LVL_PGEX = 0, - //! SMBX1...64 LVL Level File format - LVL_SMBX64, - //! SMBX-38A LVL Level File format - LVL_SMBX38A, - }; - /*! - * \brief Parses a level file with auto-detection of a file type (SMBX1...64 LVL or PGE-LVLX) - * \param [__in] filePath Full path to file which must be opened - * \param [__out] FileData Level data structure - * \return true if file successfully opened and parsed, false if error occouped - */ - static bool OpenLevelFile(PGESTRING filePath, LevelData &FileData); - /*! - * \brief Parses a level file header only with auto-detection of a file type (SMBX1...64 LVL or PGE-LVLX) - * \param [__in] filePath Full path to file which must be opened - * \param [__out] data Level data structure (with initialized header data only) - * \return true if file successfully opened and parsed, false if error occouped - */ - static bool OpenLevelFileHeader(PGESTRING filePath, LevelData &data); - /*! - * \brief Save a level file to the disk - * \param [__in] FileData Level data structure - * \param [__in] filePath Path to file to save encoded in UTF-8 (for STL-version) - * \param [__in] format Target file format (PGE LVLX, SMBX1...64 LVL, SMBX-38A LVL) - * \param [__in] FormatVersion Version of target SMBX1...64 file. Takes no effect for other file formats - * \return true if file successfully saved - */ - static bool SaveLevelFile(LevelData &FileData, PGESTRING filePath, LevelFileFormat format, unsigned int FormatVersion = 64); - /*! - * \brief Save a level file to the raw string - * \param FileData Level data structure - * \param filePath Path to file to save encoded in UTF-8 (for STL-version) - * \param format Target file format (PGE LVLX, SMBX1...64 LVL, SMBX-38A LVL) - * \param FormatVersion Version of target SMBX1...64 file. Takes no effect for other file formats - * \return true if data successfully generated - */ - static bool SaveLevelData(LevelData &FileData, PGESTRING &RawData, LevelFileFormat format, unsigned int FormatVersion = 64); - - // SMBX64 LVL File - /*! - * \brief Parses SMBX1...64 level file header and skips other part of a file - * \param [__in] filePath Full path to level file - * \param [__out] FileData Level data structure (with initialized header data only) - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX64LvlFileHeader(PGESTRING filePath, LevelData &FileData); - /*! - * \brief Parses SMBX1...64 level file data - * \param [__in] filePath Full path to the file (if empty, custom data in the episode and in the custom directories are will be inaccessible) - * \param [__out] FileData Level data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX64LvlFileF(PGESTRING filePath, LevelData &FileData); - /*! - * \brief Parses SMBX1...64 level file data - * \param [__in] rawdata Raw data of the SMBX1...64 level file - * \param [__in] filePath Full path to the file (if empty, custom data in the episode and in the custom directories are will be inaccessible) - * \param [__Out] FileData - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX64LvlFileRaw(PGESTRING &rawdata, PGESTRING filePath, LevelData &FileData); - /*! - * \brief ReadSMBX64LvlFile - * \param [__in] in - * \param [__out] FileData - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX64LvlFile(PGE_FileFormats_misc::TextInput &in, LevelData /*output*/ &FileData); - /*! - * \brief Generates SMBX1...64 Level file data and saves into file - * \param [__in] filePath Target file path - * \param [__in] FileData Level data structure - * \param [__in] file_format SMBX file format version number (from 0 to 64) [Example of level in SMBX0 format is intro.dat included with SMBX 1.0] - * \return true if file successfully saved, false if error occouped - */ - static bool WriteSMBX64LvlFileF(PGESTRING filePath, LevelData &FileData, unsigned int file_format = 64); - /*! - * \brief Generates SMBX1...64 Level file data and saves into raw string - * \param [__in] FileData Target file path - * \param [__out] rawdata Level data structure - * \param [__in] file_format SMBX file format version number (from 0 to 64) [Example of level in SMBX0 format is intro.dat included with SMBX 1.0] - * \return true if file successfully saved, false if error occouped - */ - static bool WriteSMBX64LvlFileRaw(LevelData &FileData, PGESTRING &rawdata, unsigned int file_format = 64); - /*! - * \brief Generates SMBX1...64 Level file data and saves it through file output descriptor - * \param [__inout] out Output file descriptor - * \param [__in] FileData Target file path - * \param [__in] file_format SMBX file format version number (from 0 to 64) [Example of level in SMBX0 format is intro.dat included with SMBX 1.0] - * \return true if file successfully saved, false if error occouped - */ - static bool WriteSMBX64LvlFile(PGE_FileFormats_misc::TextOutput &out, LevelData /*output*/ &FileData, unsigned int file_format = 64); - - // SMBX-38A LVL File - /*! - * \brief Parses SMBX-38A level file header and skips other part of a file - * \param [__in] filePath Full path to level file - * \param [__out] FileData Level data structure (with initialized header data only) - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX38ALvlFileHeader(PGESTRING filePath, LevelData &FileData); - /*! - * \brief Parses SMBX-38A level file data from file - * \param [__in] filePath Full path to flie - * \param [__out] FileData - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX38ALvlFileF(PGESTRING filePath, LevelData &FileData); - /*! - * \brief Parses SMBX-38A level file data from raw data string - * \param [__in] rawdata Raw-data string contains SMBX-38A Level file data - * \param [__in] filePath Full path to the file (if empty, custom data in the episode and in the custom directories are will be inaccessible) - * \param [__out] FileData Level data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX38ALvlFileRaw(PGESTRING &rawdata, PGESTRING filePath, LevelData &FileData); - /*! - * \brief Parses SMBX-38A level file data from raw data string - * \param [__in] in File input descriptor - * \param [__out] FileData FileData Level data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX38ALvlFile(PGE_FileFormats_misc::TextInput &in, LevelData /*output*/ &FileData); - /*! - * \brief Parses SMBX-38A level file data from raw data string (Old algorithm) - * \param [__in] in File input descriptor - * \param [__out] FileData FileData Level data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX38ALvlFile_OLD(PGE_FileFormats_misc::TextInput &in, LevelData &FileData); - /*! - * \brief Generates SMBX-38A Level file data and saves into file - * \param [__in] filePath Target file path - * \param [__in] FileData Level data structure - * \return true if file successfully saved, false if error occouped - */ - static bool WriteSMBX38ALvlFileF(PGESTRING filePath, LevelData &FileData); - /*! - * \brief Generates SMBX-38A Level file data and saves into raw string - * \param [__in] FileData Target file path - * \param [__out] rawdata Raw data string in the SMBX-38A level format - * \return true if file successfully saved, false if error occouped - */ - static bool WriteSMBX38ALvlFileRaw(LevelData &FileData, PGESTRING &rawdata); - /*! - * \brief Generates SMBX-38A Level file data and saves it through file output descriptor - * \param [__inout] out Output file descriptor - * \param [__in] FileData Target file path - * \return true if file successfully saved, false if error occouped - */ - static bool WriteSMBX38ALvlFile(PGE_FileFormats_misc::TextOutput &out, LevelData &FileData); - - - - // PGE Extended Level File - /*! - * \brief Parses PGE-X Level file header from the file - * \param filePath Full path to PGE-X Level file - * \param FileData Level data structure (with initialized header data only) - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadExtendedLvlFileHeader(PGESTRING filePath, LevelData &FileData); - /*! - * \brief Parses PGE-X level file data from file - * \param [__in] filePath Full path to the file - * \param [__out] FileData Level data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadExtendedLvlFileF(PGESTRING filePath, LevelData &FileData); - /*! - * \brief Parses PGE-X level file data from raw data string - * \param [__in] rawdata Raw data string in the PGE-X level format - * \param [__in] filePath Full path to the file (if empty, custom data in the episode and in the custom directories are will be inaccessible) - * \param [__out] FileData Level data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadExtendedLvlFileRaw(PGESTRING &rawdata, PGESTRING filePath, LevelData &FileData); - /*! - * \brief Parses PGE-X level file data from file input descriptor - * \param [__in] in File Input descriptor - * \param [__out] FileData Level data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadExtendedLvlFile(PGE_FileFormats_misc::TextInput &in, LevelData /*output*/ &FileData); - /*! - * \brief Generates PGE-X Level file - * \param [__in] filePath Target file path - * \param [__in] FileData Level data structure - * \return true if file successfully saved, false if error occouped - */ - static bool WriteExtendedLvlFileF(PGESTRING filePath, LevelData &FileData); - /*! - * \brief Generates PGE-X Level raw data string - * \param [__in] FileData Level data structure - * \param [__out] rawdata Raw data string in the PGE-X level format - * \return true if file successfully saved, false if error occouped - */ - static bool WriteExtendedLvlFileRaw(LevelData &FileData, PGESTRING &rawdata); - /*! - * \brief Generates PGE-X Level data and sends into file output descriptor - * \param [__inout] out Output file descriptor - * \param [__in] FileData Level data structure - * \return true if file successfully saved, false if error occouped - */ - static bool WriteExtendedLvlFile(PGE_FileFormats_misc::TextOutput &out, LevelData /*output*/ &FileData); - - // Lvl Data - /*! - * \brief Generates blank initialized level data structure - * \return Level data structure - */ - static LevelData CreateLevelData(); - /*! - * \brief Initializes blank level data structure - * \param NewFileData blank level data structure - */ - static void CreateLevelData(LevelData &NewFileData); - /*! - * \brief Initializes header only of the blank level data structure - * \param NewFileData blank level data structure - */ - static void CreateLevelHeader(LevelData &NewFileData); - /*! - * \brief Initializes Level specific NPC entry structure with default properties - * \return Initialized with default properties level specific NPC entry structure - */ - static LevelNPC CreateLvlNpc(); - /*! - * \brief Initializes Level specific Warp entry structure with default properties - * \return Initialized with default properties level specific Warp entry structure - */ - static LevelDoor CreateLvlWarp(); - /*! - * \brief Initializes Level specific Block entry structure with default properties - * \return Initialized with default properties level specific Block entry structure - */ - static LevelBlock CreateLvlBlock(); - /*! - * \brief Initializes Level specific Background Object entry structure with default properties - * \return Initialized with default properties level specific Background Object entry structure - */ - static LevelBGO CreateLvlBgo(); - /*! - * \brief Initializes Level specific Physical Environment Zone entry structure with default properties - * \return Initialized with default properties level specific Physical Environment Zone entry structure - */ - static LevelPhysEnv CreateLvlPhysEnv(); - /*! - * \brief Initializes Level specific Layer entry structure with default properties - * \return Initialized with default properties level specific Layer entry structure - */ - static LevelLayer CreateLvlLayer(); - /*! - * \brief Initializes Level specific SMBX64 Event entry structure with default properties - * \return Initialized with default properties level specific SMBX64 Event entry structure - */ - static LevelSMBX64Event CreateLvlEvent(); - /*! - * \brief Initializes Level specific Player spawn point entry structure with default properties - * \return Initialized with default properties level specific Player spawn point entry structure - */ - static PlayerPoint CreateLvlPlayerPoint(unsigned int id = 0); - /*! - * \brief Initializes Level specific Section Settings entry structure with default properties - * \return Initialized with default properties level specific Section Settings entry structure - */ - static LevelSection CreateLvlSection(); - /*! - * \brief Initalizes Level specific Variable entry - * \param vname name of variable - * \return Initialized with default properties level specific Variable entry - */ - static LevelVariable CreateLvlVariable(PGESTRING vname); - /*! - * \brief Initalizes Level specific Script Entry - * \param name name of script - * \param lang language code of script (Lua, Luna-Autocode or Tea-Script) - * \return Initialized with default properties level specific Script entry - */ - static LevelScript CreateLvlScript(PGESTRING name, int lang = LevelScript::LANG_LUA); - - /*! - * \brief Appends internal layers and events if not exists - * \param FileData initalized and filled level file - */ - static void LevelAddInternalEvents(LevelData &FileData); - /*! - * \brief Optimizing level data for SMBX64 Standard requirements - * \param [__inout] lvl Level data structure object - */ - static void smbx64LevelPrepare(LevelData &lvl); - /*! - * \brief Counts number of SMBX-64 Stars (NPC-97 and NPC-196). Friendly NPC's are not counts as stars. - * \param [__inout] lvl Level data structure - * \return number of found SMBX-64 stars - */ - static int smbx64CountStars(LevelData &lvl); - /*! - * \brief Sorts blocks array by Y->X positions in the given level data structure. - * By SMBX64 standard, blocks array must be sorted because it is required for - * NPC's collision detection algorithm of SMBX Engine - * \param [__inout] lvl Level data structure object - */ - static void smbx64LevelSortBlocks(LevelData &lvl); - /*! - * \brief Sorts Background objects by special order priority value - * Modifying of order priority values allowing to force specific non-foreground BGO's - * to be rendered foreground - * \param [__inout] lvl Level data structure object - */ - static void smbx64LevelSortBGOs(LevelData &lvl); - - - /******************************World map files***********************************/ - /*! - * \brief Supported world map file formats - */ - enum WorldFileFormat - { - //! PGE-X WLDX World map file format - WLD_PGEX = 0, - //! SMBX1...64 WLD World map file format - WLD_SMBX64, - //! SMBX-38A WLD World map file format - WLD_SMBX38A - }; - - /*! - * \brief Parses a world map file with auto-detection of a file type (SMBX1...64 LVL or PGE-WLDX) - * \param [__in] filePath Full path to file which must be opened - * \param [__out] data World data structure - * \return true on success file reading, false if error was occouped - */ - static bool OpenWorldFile(PGESTRING filePath, WorldData &data); - /*! - * \brief Parses a world map file header only with auto-detection of a file type (SMBX1...64 LVL or PGE-WLDX) - * \param [__in] filePath Full path to file which must be opened - * \param [__out] data World data structure (with initialized header data only) - * \return true on success file reading, false if error was occouped - */ - static bool OpenWorldFileHeader(PGESTRING filePath, WorldData &data); - /*! - * \brief Save a world file to the disk - * \param [__in] FileData World data structure - * \param [__in] filePath Path to file to save encoded in UTF-8 (for STL-version) - * \param [__in] format Target file format (PGE WLDX, SMBX1...64 WLD, SMBX-38A WLD) - * \param [__in] FormatVersion Version of target SMBX1...64 file. Takes no effect for other file formats - * \return true if file successfully saved - */ - static bool SaveWorldFile(WorldData &FileData, PGESTRING filePath, WorldFileFormat format, unsigned int FormatVersion = 64); - /*! - * \brief Save a world map file to the raw string - * \param [__in] FileData World data structure - * \param [__in] filePath Path to file to save encoded in UTF-8 (for STL-version) - * \param [__in] format Target file format (PGE WLDX, SMBX1...64 WLD, SMBX-38A WLD) - * \param [__in] FormatVersion Version of target SMBX1...64 file. Takes no effect for other file formats - * \return true if data successfully generated - */ - static bool SaveWorldData(WorldData &FileData, PGESTRING &RawData, WorldFileFormat format, unsigned int FormatVersion = 64); - - - // SMBX64 WLD File - /*! - * \brief Parsed SMBX1...64 World map file header only - * \param [__in] filePath Full path to file to open - * \param [__out] Filedata World data structure (with initialized header data only) - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX64WldFileHeader(PGESTRING filePath, WorldData &FileData); - /*! - * \brief Parses SMBX1...64 World map file from raw data from file - * \param [__in] filePath Full path to file to open - * \param [__out] FileData World data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX64WldFileF(PGESTRING filePath, WorldData &FileData); - /*! - * \brief Parses SMBX1...64 World map file from raw data from raw-data string - * \param [__in] rawdata Raw-data string which contains SMBX1...64 World map data - * \param [__in] filePath - * \param [__out] FileData World data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX64WldFileRaw(PGESTRING &rawdata, PGESTRING filePath, WorldData &FileData); - /*! - * \brief Parses SMBX1...64 World map file from raw data from file input descriptor - * \param [__in] in File Input descriptor - * \param [__out] FileData World data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX64WldFile(PGE_FileFormats_misc::TextInput &in, WorldData /*output*/ &FileData); - /*! - * \brief Saves level data into file of SMBX1...64 World map format - * \param [__in] filePath Target file path - * \param [__in] FileData World map data structure - * \param [__in] file_format SMBX file format version number (from 0 to 64) [Example of level in SMBX0 format is intro.dat included with SMBX 1.0] - * \return true if file successfully saved, false if error occouped - */ - static bool WriteSMBX64WldFileF(PGESTRING filePath, WorldData &FileData, unsigned int file_format = 64); - /*! - * \brief Generates raw data string in SMBX1...64 World map format - * \param [__in] FileData World map data structure - * \param [__out] rawdata Raw data string in SMBX1...64 World map format - * \param [__in] file_format SMBX file format version number (from 0 to 64) [Example of level in SMBX0 format is intro.dat included with SMBX 1.0] - * \return true if file successfully saved, false if error occouped - */ - static bool WriteSMBX64WldFileRaw(WorldData &FileData, PGESTRING &rawdata, unsigned int file_format = 64); - /*! - * \brief Writes world map data into file output descriptor of SMBX1...64 World map format - * \param [__inout] out Output file descriptor - * \param [__in] FileData World map data structure - * \param [__in] file_format SMBX file format version number (from 0 to 64) [Example of level in SMBX0 format is intro.dat included with SMBX 1.0] - * \return true if file successfully saved, false if error occouped - */ - static bool WriteSMBX64WldFile(PGE_FileFormats_misc::TextOutput &out, WorldData /*output*/ &FileData, unsigned int file_format = 64); - - // SMBX-38A WLD File - /*! - * \brief Parses SMBX-38A world map file header and skips other part of a file - * \param [__in] filePath Full path to world map file - * \param [__out] FileData Level data structure (with initialized header data only) - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX38AWldFileHeader(PGESTRING filePath, WorldData &FileData); - /*! - * \brief Parses SMBX-38A world map file data from file - * \param [__in] filePath Full path to flie - * \param [__out] FileData - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX38AWldFileF(PGESTRING filePath, WorldData &FileData); - /*! - * \brief Parses SMBX-38A world map file data from raw data string - * \param [__in] rawdata Raw-data string contains SMBX-38A Level file data - * \param [__in] filePath Full path to the file (if empty, custom data in the episode and in the custom directories are will be inaccessible) - * \param [__out] FileData Level data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX38AWldFileRaw(PGESTRING &rawdata, PGESTRING filePath, WorldData &FileData); - /*! - * \brief Parses SMBX-38A world map file data from raw data string - * \param [__in] in File input descriptor - * \param [__out] FileData FileData Level data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX38AWldFile(PGE_FileFormats_misc::TextInput &in, WorldData /*output*/ &FileData); - /*! - * \brief Generates SMBX-38A Level file data and saves into file - * \param [__in] filePath Target file path - * \param [__in] FileData Level data structure - * \return true if file successfully saved, false if error occouped - */ - static bool WriteSMBX38AWldFileF(PGESTRING filePath, WorldData &FileData); - /*! - * \brief Generates SMBX-38A Level file data and saves into raw string - * \param [__in] FileData Target file path - * \param [__out] rawdata Raw data string in the SMBX-38A world map format - * \return true if file successfully saved, false if error occouped - */ - static bool WriteSMBX38AWldFileRaw(WorldData &FileData, PGESTRING &rawdata); - /*! - * \brief Generates SMBX-38A Level file data and saves it through file output descriptor - * \param [__inout] out Output file descriptor - * \param [__in] FileData Target file path - * \return true if file successfully saved, false if error occouped - */ - static bool WriteSMBX38AWldFile(PGE_FileFormats_misc::TextOutput &out, WorldData &FileData); - - // PGE Extended World map File - /*! - * \brief Parsed PGE-X World map file header only - * \param filePath Full path to file which must be opened - * \param FileData World data structure (with initialized header data only) - * \return true if file successfully saved, false if error occouped - */ - static bool ReadExtendedWldFileHeader(PGESTRING filePath, WorldData &FileData); - /*! - * \brief Parses PGE-X World map file from file - * \param [__in] filePath - * \param [__out] FileData World map data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadExtendedWldFileF(PGESTRING filePath, WorldData &FileData); - /*! - * \brief Parses PGE-X World map file from raw data string - * \param [__in] rawdata Raw data strign with PGE-X World map data - * \param [__in] filePath Full path to the file (if empty, custom data in the episode and in the custom directories are will be inaccessible) - * \param [__out] FileData World map data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadExtendedWldFileRaw(PGESTRING &rawdata, PGESTRING filePath, WorldData &FileData); - /*! - * \brief Parses PGE-X World map file from file input descriptor - * \param [__in] in File Input descriptor - * \param [__out] FileData World map data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadExtendedWldFile(PGE_FileFormats_misc::TextInput &in, WorldData /*output*/ &FileData); - /*! - * \brief Saves world map data into file of PGE-X World map format - * \param [__in] filePath Target file path - * \param [__in] FileData World map data structure - * \return true if file successfully saved, false if error occouped - */ - static bool WriteExtendedWldFileF(PGESTRING filePath, WorldData &FileData); - /*! - * \brief Generates raw data string in PGE-X World map format - * \param [__in] FileData World map data structure - * \param [__out] rawdata Raw data string in PGE-X World map format - * \return true if file successfully saved, false if error occouped - */ - static bool WriteExtendedWldFileRaw(WorldData &FileData, PGESTRING &rawdata); - /*! - * \brief Generates data into file output descriptor in PGE-X World map format - * \param [__inout] out Output file descriptor - * \param [__in] FileData World map data structure - * \return true if file successfully saved, false if error occouped - */ - static bool WriteExtendedWldFile(PGE_FileFormats_misc::TextOutput &out, WorldData /*output*/ &FileData); - - //Wld Data - /*! - * \brief Initializes world map structure header - * \param [__out] NewFileData World map data structure with initialized header only - */ - static void CreateWorldHeader(WorldData &NewFileData); - /*! - * \brief Generates blank initialized World map data structure - * \param [__out] NewFileData World map data structure - */ - static void CreateWorldData(WorldData &NewFileData); - /*! - * \brief Generates blank initialized World map data structure - * \return World map data structure - */ - static WorldData CreateWorldData(); - /*! - * \brief Initializes World map specific Tile entry structure with default properties - * \return Initialized with default properties World map specific Tile entry structure - */ - static WorldTerrainTile CreateWldTile(); - /*! - * \brief Initializes World map specific Scenery entry structure with default properties - * \return Initialized with default properties World map specific Scenery entry structure - */ - static WorldScenery CreateWldScenery(); - /*! - * \brief Initializes World map specific Path entry structure with default properties - * \return Initialized with default properties World map specific Path entry structure - */ - static WorldPathTile CreateWldPath(); - /*! - * \brief Initializes World map specific Level Entrance point entry structure with default properties - * \return Initialized with default properties World map specific Level Entrance point entry structure - */ - static WorldLevelTile CreateWldLevel(); - /*! - * \brief Initializes World map specific Music Box entry structure with default properties - * \return Initialized with default properties World map specific Music Box entry structure - */ - static WorldMusicBox CreateWldMusicbox(); - - - /****************************Save of game file********************************/ - - // SMBX1..64 SAV file - /*! - * \brief Parses SMBX1...64 Game save data from file - * \param [__in] filePath File path to open - * \param [__out] FileData Game save data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX64SavFileF(PGESTRING filePath, GamesaveData &FileData); - /*! - * \brief Parses SMBX1...64 Game save data from raw data string - * \param [__in] rawdata raw data string in SMBX1..64 game save format - * \param [__in] filePath Path to original file - * \param [__out] FileData Game save data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX64SavFileRaw(PGESTRING &rawdata, PGESTRING filePath, GamesaveData &FileData); - /*! - * \brief Parses SMBX1...64 Game save data from input descriptor - * \param [__in] in File Input descriptor - * \param [__out] FileData Game save data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX64SavFile(PGE_FileFormats_misc::TextInput &in, GamesaveData /*output*/ &FileData); - - //PGE-X SAVX file - /*! - * \brief Parses PGE-X level file data from file - * \param [__in] filePath Full path to the file - * \param [__out] FileData Game save data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadExtendedSaveFileF(PGESTRING filePath, GamesaveData &FileData); - /*! - * \brief Parses PGE-X level file data from raw data string - * \param [__in] rawdata Raw data string in the PGE-X Game save format - * \param [__in] filePath Full path to the file - * \param [__out] FileData Game save data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadExtendedSaveFileRaw(PGESTRING &rawdata, PGESTRING filePath, GamesaveData &FileData); - /*! - * \brief Parses PGE-X level file data from file input descriptor - * \param [__in] in File Input descriptor - * \param [__out] FileData Game save data structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadExtendedSaveFile(PGE_FileFormats_misc::TextInput &in, GamesaveData &FileData); - /*! - * \brief Saves Game save data into file of PGE-X Game save format - * \param [__in] filePath Target file path - * \param [__in] FileData Game save data structure - * \return true if file successfully saved, false if error occouped - */ - static bool WriteExtendedSaveFileF(PGESTRING filePath, GamesaveData &FileData); - /*! - * \brief Generates raw data string in PGE-X Game save format - * \param [__in] FileData World map data structure - * \param [__out] rawdata Raw data string in PGE-X Game save format - * \return true if file successfully saved, false if error occouped - */ - static bool WriteExtendedSaveFileRaw(GamesaveData &FileData, PGESTRING &rawdata); - /*! - * \brief WriteExtendedWldFile - * \param [__inout] out Output file descriptor - * \param [__in] FileData Game save data structure - * \return true if file successfully saved, false if error occouped - */ - static bool WriteExtendedSaveFile(PGE_FileFormats_misc::TextOutput &out, GamesaveData &FileData); - - //Save Data - /*! - * \brief Initializes blank game save data structure with default preferences - * \return Blank Game Save data structure - */ - static GamesaveData CreateGameSaveData(); - /*! - * \brief Inirializes Game Save specific playable character state entry - * \return Blank game save specific playable character state entry - */ - static saveCharState CreateSavCharacterState(); - - /****************************SMBX64 Config file********************************/ - - /*! - * \brief Parses SMBX Engine config file raw data string - * \param [__in] RawData raw data string in SMBX Engine config file format - * \return SMBX Engine specific config structure - */ - DEPRECATED(static SMBX64_ConfigFile ReadSMBX64ConfigFile(PGESTRING RawData)); - - - /*! - * \brief Parses SMBX Engine config data from file - * \param [__in] filePath Filepath to open - * \param [__out] FileData SMBX Engine specific config structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX64ConfigFileF(PGESTRING filePath, SMBX64_ConfigFile &FileData); - /*! - * \brief Parses SMBX Engine config data from raw data string - * \param [__in] rawdata Raw data string contains SMBX Engine config data - * \param [__in] filePath - * \param [__out] FileData SMBX Engine specific config structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX64ConfigFileRaw(PGESTRING &rawdata, PGESTRING filePath, SMBX64_ConfigFile &FileData); - /*! - * \brief Parses SMBX Engine config data from file input descriptor - * \param [__in] in File Input descriptor - * \param [__out] FileData SMBX Engine specific config structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadSMBX64ConfigFile(PGE_FileFormats_misc::TextInput &in, SMBX64_ConfigFile /*output*/ &FileData); - - - - /*! - * \brief Generates SMBX Engine specific config file raw data string - * \param [__in] FileData SMBX Engine specific config structure - * \param [__in] file_format SMBX file format version number (from 0 to 64) - * \return raw data string in SMBX Engine config file format - */ - DEPRECATED(static PGESTRING WriteSMBX64ConfigFile(SMBX64_ConfigFile &FileData, unsigned int file_format)); - - - /*! - * \brief Saves SMBX Engine specific config data into file of SMBX1...64 World map format - * \param [__in] filePath Target file path - * \param [__in] FileData World map data structure - * \param [__in] file_format SMBX file format version number (from 0 to 64) [Example of level in SMBX0 format is intro.dat included with SMBX 1.0] - * \return true if file successfully saved, false if error occouped - */ - static bool WriteSMBX64ConfigFileF(PGESTRING filePath, SMBX64_ConfigFile &FileData, unsigned int file_format = 64); - /*! - * \brief Generates raw data string in SMBX1...64 SMBX Engine specific config format - * \param [__in] FileData World map data structure - * \param [__out] rawdata Raw data string in SMBX1...64 World map format - * \param [__in] file_format SMBX file format version number (from 0 to 64) [Example of level in SMBX0 format is intro.dat included with SMBX 1.0] - * \return true if file successfully saved, false if error occouped - */ - static bool WriteSMBX64ConfigFileRaw(SMBX64_ConfigFile &FileData, PGESTRING &rawdata, unsigned int file_format = 64); - /*! - * \brief Writes data into file output descriptor of SMBX1...64 SMBX Engine specific config format - * \param [__inout] out Output file descriptor - * \param [__in] FileData SMBX Engine specific config data structure - * \param [__in] file_format SMBX file format version number (from 0 to 64) [Example of level in SMBX0 format is intro.dat included with SMBX 1.0] - * \return true if file successfully saved, false if error occouped - */ - static bool WriteSMBX64ConfigFile(PGE_FileFormats_misc::TextOutput &out, SMBX64_ConfigFile &FileData, unsigned int file_format = 64); - - - /******************************NPC.txt file***********************************/ - // SMBX64 NPC.TXT File - /*! - * \brief Parses SMBX64 NPC.txt config data from file - * \param [__in] filePath Filepath to open - * \param [__out] FileData SMBX Engine specific config structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadNpcTXTFileF(PGESTRING filePath, NPCConfigFile &FileData, bool IgnoreBad = false); - /*! - * \brief Parses SMBX64 NPC.txt config data from raw data string - * \param [__in] rawdata Raw data string contains SMBX Engine config data - * \param [__out] FileData SMBX Engine specific config structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadNpcTXTFileRAW(PGESTRING &rawdata, NPCConfigFile &FileData, bool IgnoreBad = false); - /*! - * \brief Parses SMBX64 NPC.txt config data from file input descriptor - * \param [__in] in File Input descriptor - * \param [__out] FileData SMBX Engine specific config structure - * \return true if file successfully parsed, false if error occouped - */ - static bool ReadNpcTXTFile(PGE_FileFormats_misc::TextInput &in, NPCConfigFile &FileData, bool IgnoreBad = false); - - /*! - * \brief Saves world map data into file of SMBX64 NPC.txt config data format - * \param [__in] filePath Target file path - * \param [__in] FileData SMBX64 NPC.txt config data structure - * \return true if file successfully saved, false if error occouped - */ - static bool WriteNPCTxtFileF(PGESTRING filePath, NPCConfigFile &FileData); - /*! - * \brief Generates raw data string in SMBX64 NPC.txt config data format - * \param [__in] FileData SMBX64 NPC.txt config data structure - * \param [__out] rawdata Raw data string in SMBX64 NPC.txt config data format - * \return true if file successfully saved, false if error occouped - */ - static bool WriteNPCTxtFileRaw(NPCConfigFile &FileData, PGESTRING &rawdata); - /*! - * \brief Generates data into file output descriptor in SMBX64 NPC.txt config data format - * \param [__inout] out Output file descriptor - * \param [__in] FileData World map data structure - * \return true if file successfully saved, false if error occouped - */ - static bool WriteNPCTxtFile(PGE_FileFormats_misc::TextOutput &out, NPCConfigFile &FileData); - - /*! - * \brief Initialize blank NPC Customizing Config data structure - * \return Blank NPC Customizing Config data structure - */ - static NPCConfigFile CreateEmpytNpcTXT(); - - /******************************Common stuff***********************************/ - /*! - * \brief File parse error codes - */ - enum ErrorCodes - { - //! file has been successfully parses - Success = 0, - //! Requested file is not exist - ERROR_NotExist, - //! Access to requested file is denied by operation system - ERROR_AccessDenied, - //! File contains invalid format syntax - ERROR_InvalidSyntax, - //! PGE-X File contains a not closed data section - ERROR_PGEX_SectionNotClosed, - //! PGE-X File contains invalid syntax in the data entried - ERROR_PGEX_InvalidSyntax, - //! PGE-X File data field has invalid data type - ERROR_PGEX_InvalidDataType - }; - /*! - * \brief Get detailed information from returned error code - * \param errCode Returned error code by file parser - * \return Understandable error description - */ - static PGESTRING getErrorString(ErrorCodes errCode); - - /*! - * \brief SMBX64 Standrd specific violation codes - */ - enum SMBX64_violations - { - //! File data is conforms to the SMBX64 Standard - SMBX64_FINE = 0x000, - //! File data structure has exited limit of section entries - SMBX64EXC_SECTIONS = 0x001, - //! File data structure has exited limit of block entries - SMBX64EXC_BLOCKS = 0x002, - //! File data structure has exited limit of Background Object entries - SMBX64EXC_BGOS = 0x004, - //! File data structure has exited limit of NPC entries - SMBX64EXC_NPCS = 0x008, - //! File data structure has exited limit of Water boxes entries - SMBX64EXC_WATERBOXES = 0x010, - //! File data structure has exited limit of Warp entries - SMBX64EXC_WARPS = 0x020, - //! File data structure has exited limit of Layer entries - SMBX64EXC_LAYERS = 0x040, - //! File data structure has exited limit of Event entries - SMBX64EXC_EVENTS = 0x080, - //! File data structure has exited limit of Tile entries - SMBX64EXC_TILES = 0x100, - //! File data structure has exited limit of Scenery entries - SMBX64EXC_SCENERIES = 0x200, - //! File data structure has exited limit of Path entries - SMBX64EXC_PATHS = 0x400, - //! File data structure has exited limit of Level Entrance point entries - SMBX64EXC_LEVELS = 0x800, - //! File data structure has exited limit of Music Box entries - SMBX64EXC_MUSICBOXES = 0x1000 - }; - - //Check SMBX64 limits - /*! - * \brief Validates level file data structure to conformation to SMBX64 Standard - * \param lvl Level file data structure - * \return SMBX64 Standrd specific violation code - */ - static int smbx64LevelCheckLimits(LevelData &lvl); - /*! - * \brief Validates World map file data structure to conformation to SMBX64 Standard - * \param wld World map file data structure - * \return SMBX64 Standrd specific violation code - */ - static int smbx64WorldCheckLimits(WorldData &wld); - - /******************************Internal stuff***********************************/ - /*! - * \brief Removes edge dobule quoties characters from a string - * for example '"Meow"' (without signgle-quotes characters) - * will be converted into 'Meow' (without signgle-quotes characters) - * \param str Input string with quites characters at begin and end of string - * \return String with removed double quotes at edges. - * If string has no double quotes at edges, input string will be retured with no changes - */ - static PGESTRING removeQuotes(PGESTRING str); - //! String which contains info about last happened error - static PGESTRING errorString; -}; - -#endif // FILE_FORMATS_H diff --git a/LunaDll/libs/PGE_File_Formats/file_rw_lvl.cpp b/LunaDll/libs/PGE_File_Formats/file_rw_lvl.cpp deleted file mode 100644 index 298233a3b..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_rw_lvl.cpp +++ /dev/null @@ -1,1439 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "pge_file_lib_sys.h" -#include "file_formats.h" -#include "file_strlist.h" -#include "smbx64.h" -#include "smbx64_macro.h" -#include "CSVUtils.h" - -//********************************************************* -//****************READ FILE FORMAT************************* -//********************************************************* -struct LevelEvent_layers -{ - PGESTRING hide; - PGESTRING show; - PGESTRING toggle; -}; - -bool FileFormats::ReadSMBX64LvlFileHeader(PGESTRING filePath, LevelData &FileData) -{ - errorString.clear(); - CreateLevelHeader(FileData); - FileData.meta.RecentFormat = LevelData::SMBX64; - FileData.meta.RecentFormatVersion = 64; - PGE_FileFormats_misc::TextFileInput inf; - - if(!inf.open(filePath, false)) - { - FileData.meta.ReadFileValid = false; - return false; - } - - PGE_FileFormats_misc::FileInfo in_1(filePath); - FileData.meta.filename = in_1.basename(); - FileData.meta.path = in_1.dirpath(); - inf.seek(0, PGE_FileFormats_misc::TextFileInput::begin); - SMBX64_FileBegin(); -#define nextLineH() line = inf.readCVSLine(); - - try - { - nextLineH(); //Read first line - SMBX64::ReadUInt(&file_format, line); //File format number - FileData.meta.RecentFormatVersion = file_format; - - if(file_format >= 17) - { - nextLineH(); //Read second Line - SMBX64::ReadUInt(&FileData.stars, line); //Number of stars - } - else FileData.stars = 0; - - if(file_format >= 60) - { - nextLineH(); //Read third line - SMBX64::ReadStr(&FileData.LevelName, line); //LevelTitle - } - else FileData.LevelName = ""; - - FileData.CurSection = 0; - FileData.playmusic = 0; - FileData.meta.ReadFileValid = true; - return true; - } - catch(const std::exception &err) - { - if(file_format > 0) - FileData.meta.ERROR_info = "Detected file format: SMBX-" + fromNum(file_format) + " is invalid\n"; - else - FileData.meta.ERROR_info = "It is not an SMBX level file\n"; - - #ifdef PGE_FILES_QT - FileData.meta.ERROR_info += QString::fromStdString(exception_to_pretty_string(err)); - #else - FileData.meta.ERROR_info += exception_to_pretty_string(err); - #endif - FileData.meta.ERROR_linenum = inf.getCurrentLineNumber(); - FileData.meta.ERROR_linedata = line; - FileData.meta.ReadFileValid = false; - return false; - } -} - -bool FileFormats::ReadSMBX64LvlFileF(PGESTRING filePath, LevelData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileInput file; - - if(!file.open(filePath, false)) - { - errorString = "Failed to open file for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadSMBX64LvlFile(file, FileData); -} - -bool FileFormats::ReadSMBX64LvlFileRaw(PGESTRING &rawdata, PGESTRING filePath, LevelData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextInput file; - - if(!file.open(&rawdata, filePath)) - { - errorString = "Failed to open raw string for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadSMBX64LvlFile(file, FileData); -} - -bool FileFormats::ReadSMBX64LvlFile(PGE_FileFormats_misc::TextInput &in, LevelData &FileData) -{ - SMBX64_FileBegin(); - PGESTRING filePath = in.getFilePath(); - errorString.clear(); - //SMBX64_File( RawData ); - int i; //counters - CreateLevelData(FileData); - FileData.meta.RecentFormat = LevelData::SMBX64; - FileData.meta.RecentFormatVersion = 64; - FileData.LevelName = ""; - FileData.stars = 0; - FileData.CurSection = 0; - FileData.playmusic = 0; - //Enable strict mode for SMBX LVL file format - FileData.meta.smbx64strict = true; - //Begin all ArrayID's here; - FileData.blocks_array_id = 1; - FileData.bgo_array_id = 1; - FileData.npc_array_id = 1; - FileData.doors_array_id = 1; - FileData.physenv_array_id = 1; - FileData.layers_array_id = 1; - FileData.events_array_id = 1; - FileData.layers.clear(); - FileData.events.clear(); - LevelSection section; - int sct; - PlayerPoint players; - LevelBlock blocks; - LevelBGO bgodata; - LevelNPC npcdata; - LevelDoor doors; - LevelPhysEnv waters; - LevelLayer layers; - LevelSMBX64Event events; - LevelEvent_layers events_layers; - LevelEvent_Sets events_sets; - - //Add path data - if(!IsEmpty(filePath)) - { - PGE_FileFormats_misc::FileInfo in_1(filePath); - FileData.meta.filename = in_1.basename(); - FileData.meta.path = in_1.dirpath(); - } - - try - { - ///////////////////////////////////////Begin file/////////////////////////////////////// - nextLine(); //Read first line - SMBX64::ReadUInt(&file_format, line);//File format number - FileData.meta.RecentFormatVersion = file_format; - - if(ge(17)) - { - nextLine(); - SMBX64::ReadUInt(&FileData.stars, line); //Number of stars - } - else FileData.stars = 0; - - if(ge(60)) - { - nextLine(); //LevelTitle - SMBX64::ReadStr(&FileData.LevelName, line); - } - - //total sections - sct = (ge(8) ? 21 : 6); - - ////////////SECTION Data////////// - for(i = 0; i < sct; i++) - { - section = CreateLvlSection(); - nextLine(); - SMBX64::ReadSIntFromFloat(§ion.size_left, line); - nextLine(); - SMBX64::ReadSIntFromFloat(§ion.size_top, line); - nextLine(); - SMBX64::ReadSIntFromFloat(§ion.size_bottom, line); //bottom - nextLine(); - SMBX64::ReadSIntFromFloat(§ion.size_right, line); //right - nextLine(); - SMBX64::ReadUInt(§ion.music_id, line); //Music ID - nextLine(); - SMBX64::ReadUInt(§ion.bgcolor, line); //BG Color - nextLine(); - SMBX64::ReadCSVBool(§ion.wrap_h, line); //Connect sides of section - nextLine(); - SMBX64::ReadCSVBool(§ion.OffScreenEn, line);//Offscreen exit - nextLine(); - SMBX64::ReadUInt(§ion.background, line); //BackGround id - - if(ge(1)) - { - nextLine(); //Don't walk to left (no turn back) - SMBX64::ReadCSVBool(§ion.lock_left_scroll, line); - } - - if(ge(30)) - { - nextLine(); //Underwater - SMBX64::ReadCSVBool(§ion.underwater, line); - } - - if(ge(2)) - { - nextLine(); //Custom Music - SMBX64::ReadStr(§ion.music_file, line); - } - - //Very important data! I'ts a camera position in the editor! - section.PositionX = section.size_left - 10; //left - section.PositionY = section.size_top - 10; //top - section.id = i; - - if(i < static_cast(FileData.sections.size())) - FileData.sections[static_cast(i)] = section; //Replace if already exists - else - FileData.sections.push_back(section); //Add Section in main array - } - - if(lt(8)) - for(; i < 21; i++) - { - section = CreateLvlSection(); - section.id = i; - - if(i < static_cast(FileData.sections.size())) - FileData.sections[static_cast(i)] = section; //Replace if already exists - else - FileData.sections.push_back(section); //Add Section in main array - } - - //Player's point config - for(i = 0; i < 2; i++) - { - players = CreateLvlPlayerPoint(); - nextLine(); - SMBX64::ReadSIntFromFloat(&players.x, line);//Player x - nextLine(); - SMBX64::ReadSIntFromFloat(&players.y, line);//Player y - nextLine(); - SMBX64::ReadUInt(&players.w, line);//Player w - nextLine(); - SMBX64::ReadUInt(&players.h, line);//Player h - players.id = static_cast(i) + 1u; - - if(players.x != 0 && players.y != 0 && players.w != 0 && players.h != 0) //Don't add into array non-exist point - FileData.players.push_back(players); //Add player in array - } - - ////////////Block Data////////// - nextLine(); - - while(line != "next") - { - blocks = CreateLvlBlock(); - SMBX64::ReadSIntFromFloat(&blocks.x, line); - nextLine(); - SMBX64::ReadSIntFromFloat(&blocks.y, line); - nextLine(); - SMBX64::ReadSIntFromFloat(&blocks.h, line); - nextLine(); - SMBX64::ReadSIntFromFloat(&blocks.w, line); - nextLine(); - SMBX64::ReadUInt(&blocks.id, line); - long xnpcID; - nextLine(); - SMBX64::ReadUInt(&xnpcID, line); //Containing NPC id - { - //Convert NPC-ID value from SMBX1/2 to SMBX64 - switch(xnpcID) - { - case 100: - xnpcID = 1009; - break;//Mushroom - - case 101: - xnpcID = 1001; - break;//Goomba - - case 102: - xnpcID = 1014; - break;//Fire flower - - case 103: - xnpcID = 1034; - break;//Super leaf - - case 104: - xnpcID = 1035; - break;//Shoe - - default: - break; - } - - //Convert NPC-ID value from SMBX64 into PGE format - if(xnpcID != 0) - { - if(xnpcID > 1000) - xnpcID = xnpcID - 1000; - else - xnpcID *= -1; - } - - blocks.npc_id = xnpcID; - } - nextLine(); - SMBX64::ReadCSVBool(&blocks.invisible, line); - - if(ge(61)) - { - nextLine(); - SMBX64::ReadCSVBool(&blocks.slippery, line); - } - - if(ge(10)) - { - nextLine(); - SMBX64::ReadStr(&blocks.layer, line); - } - - if(ge(14)) - { - nextLine(); - SMBX64::ReadStr(&blocks.event_destroy, line); - nextLine(); - SMBX64::ReadStr(&blocks.event_hit, line); - nextLine(); - SMBX64::ReadStr(&blocks.event_emptylayer, line); - } - - blocks.meta.array_id = FileData.blocks_array_id++; - blocks.meta.index = static_cast(FileData.blocks.size()); //Apply element index - FileData.blocks.push_back(blocks); //AddBlock into array - nextLine(); - } - - ////////////BGO Data////////// - nextLine(); - - while(line != "next") - { - bgodata = CreateLvlBgo(); - SMBX64::ReadSIntFromFloat(&bgodata.x, line); - nextLine(); - SMBX64::ReadSIntFromFloat(&bgodata.y, line); - nextLine(); - SMBX64::ReadUInt(&bgodata.id, line); - - if(ge(10)) - { - nextLine(); - SMBX64::ReadStr(&bgodata.layer, line); - } - - bgodata.smbx64_sp = -1; - - if((file_format < 10) && (bgodata.id == 65)) //set foreground for BGO-65 (SMBX 1.0) - { - bgodata.z_mode = LevelBGO::Foreground1; - bgodata.smbx64_sp = 80; - } - - bgodata.meta.array_id = FileData.bgo_array_id++; - bgodata.meta.index = static_cast(FileData.bgo.size()); //Apply element index - FileData.bgo.push_back(bgodata); //Add Background object into array - nextLine(); - } - - ////////////NPC Data////////// - nextLine(); - - while(line != "next") - { - npcdata = CreateLvlNpc(); - SMBX64::ReadSIntFromFloat(&npcdata.x, line); - nextLine(); - SMBX64::ReadSIntFromFloat(&npcdata.y, line); - nextLine(); - SMBX64::ReadSInt(&npcdata.direct, line); //NPC direction - nextLine(); - SMBX64::ReadUInt(&npcdata.id, line); //NPC id - npcdata.special_data = 0; - npcdata.contents = 0; - - switch(npcdata.id) - { - //SMBX64 Fixed special options for NPC - /*parakoopas*/ - case 76: - case 121: - case 122: - case 123: - case 124: - case 161: - case 176: - case 177: - /*Paragoomba*/ - case 243: - case 244: - /*Cheep-Cheep*/ - case 28: - case 229: - case 230: - case 232: - case 233: - case 234: - case 236: - /*WarpSelection*/ - case 288: - case 289: - /*firebar*/ - case 260: - if( - ((npcdata.id != 76) && (npcdata.id != 28)) - || - ( - ((ge(15)) && (npcdata.id == 76)) - || ((ge(31)) && (npcdata.id == 28)) - ) - ) - { - nextLine(); - SMBX64::ReadSInt(&npcdata.special_data, line); //NPC special option - } - break; - /*Containers*/ - case 91: /*buried*/ - case 96: /*egg*/ - case 283:/*Bubble*/ - case 284:/*SMW Lakitu*/ - nextLine(); - SMBX64::ReadSInt(&npcdata.contents, line); - if(npcdata.id == 91) - { - switch(npcdata.contents) - { - /*WarpSelection*/ - case 288: /*case 289:*/ /*firebar*/ /*case 260:*/ - nextLine(); - SMBX64::ReadSInt(&npcdata.special_data, line); - break; - default: - break; - } - } - break; - default: - break; - } - - if(ge(3)) - { - nextLine(); - SMBX64::ReadCSVBool(&npcdata.generator, line); //Generator enabled - npcdata.generator_direct = 1; - npcdata.generator_type = 1; - if(npcdata.generator) - { - nextLine(); - SMBX64::ReadSInt(&npcdata.generator_direct, line); //Generator direction (1, 2, 3, 4) - if(npcdata.generator_direct < 0) - npcdata.generator_direct = 1; //Fix of old accidental mistake causes -1 value - nextLine(); - SMBX64::ReadUInt(&npcdata.generator_type, line); //Generator type [1] Warp, [2] Projectile - nextLine(); - SMBX64::ReadUInt(&npcdata.generator_period, line); //Generator period ( sec*10 ) [1-600] - } - } - - if(ge(5)) - { - nextLine(); - //strVarMultiLine(npcdata.msg, line)//Message - SMBX64::ReadStr(&npcdata.msg, line);//Message - } - if(ge(6)) - { - nextLine(); - SMBX64::ReadCSVBool(&npcdata.friendly, line);//Friendly NPC - nextLine(); - SMBX64::ReadCSVBool(&npcdata.nomove, line); //Don't move NPC - } - if(ge(9)) - { - nextLine(); - SMBX64::ReadCSVBool(&npcdata.is_boss, line); //Set as boss flag - } - else - { - switch(npcdata.id) - { - //set boss flag to TRUE for old file formats automatically - case 15: - case 39: - case 86: - npcdata.is_boss = true; - break; - default: - break; - } - } - - if(ge(10)) - { - nextLine(); - SMBX64::ReadStr(&npcdata.layer, line); - nextLine(); - SMBX64::ReadStr(&npcdata.event_activate, line); - nextLine(); - SMBX64::ReadStr(&npcdata.event_die, line); - nextLine(); - SMBX64::ReadStr(&npcdata.event_talk, line); - } - if(ge(14)) - { - nextLine(); //No more objects in layer event - SMBX64::ReadStr(&npcdata.event_emptylayer, line); - } - if(ge(63)) - { - nextLine(); //Layer name to attach - SMBX64::ReadStr(&npcdata.attach_layer, line); - } - npcdata.meta.array_id = FileData.npc_array_id++; - npcdata.meta.index = static_cast(FileData.npc.size()); //Apply element index - FileData.npc.push_back(npcdata); //Add NPC into array - nextLine(); - } - - ////////////Warp and Doors Data////////// - nextLine(); - - while( - ((line != "next") && (file_format >= 10)) - || ((file_format < 10) && (!IsEmpty(line)) && (!in.eof())) - ) - { - doors = CreateLvlWarp(); - doors.isSetIn = true; - doors.isSetOut = true; - SMBX64::ReadSIntFromFloat(&doors.ix, line); //Entrance x - nextLine(); - SMBX64::ReadSIntFromFloat(&doors.iy, line); //Entrance y - nextLine(); - SMBX64::ReadSIntFromFloat(&doors.ox, line); //Exit x - nextLine(); - SMBX64::ReadSIntFromFloat(&doors.oy, line); //Exit y - nextLine(); - SMBX64::ReadUInt(&doors.idirect, line); //Entrance direction: [3] down, [1] up, [2] left, [4] right - nextLine(); - SMBX64::ReadUInt(&doors.odirect, line); //Exit direction: [1] down [3] up [4] left [2] right - nextLine(); - SMBX64::ReadUInt(&doors.type, line); //Door type: [1] pipe, [2] door, [0] instant - - if(ge(3)) - { - nextLine(); - SMBX64::ReadStr(&doors.lname, line); //Warp to level - nextLine(); - SMBX64::ReadUInt(&doors.warpto, line); //Normal entrance or Warp to other door - nextLine(); - SMBX64::ReadCSVBool(&doors.lvl_i, line); //Level Entrance (cannot enter) - doors.isSetIn = ((doors.lvl_i) ? false : true); - } - - if(ge(4)) //-V112 - { - nextLine(); - SMBX64::ReadCSVBool(&doors.lvl_o, line); //-V112 - doors.isSetOut = (((doors.lvl_o) ? false : true) || (doors.lvl_i)); - nextLine(); - SMBX64::ReadSInt(&doors.world_x, line); //WarpTo X - nextLine(); - SMBX64::ReadSInt(&doors.world_y, line); //WarpTo y - } - - if(ge(7)) - { - nextLine(); //Need a stars - SMBX64::ReadUInt(&doors.stars, line); - } - - if(ge(12)) - { - nextLine(); - SMBX64::ReadStr(&doors.layer, line); //Layer - nextLine(); - SMBX64::ReadCSVBool(&doors.unknown, line); - } //, always FALSE - - if(ge(23)) - { - nextLine(); //Deny vehicles - SMBX64::ReadCSVBool(&doors.novehicles, line); - } - - if(ge(25)) - { - nextLine(); //Allow carried items - SMBX64::ReadCSVBool(&doors.allownpc, line); - } - - if(ge(26)) - { - nextLine(); //Locked - SMBX64::ReadCSVBool(&doors.locked, line); - } - - doors.meta.array_id = FileData.doors_array_id++; - doors.meta.index = static_cast(FileData.doors.size()); //Apply element index - FileData.doors.push_back(doors); //Add NPC into array - nextLine(); - } - - ////////////Water/QuickSand Data////////// - if(file_format >= 29) - { - nextLine(); - - while(line != "next") - { - waters = CreateLvlPhysEnv(); - SMBX64::ReadSIntFromFloat(&waters.x, line); - nextLine(); - SMBX64::ReadSIntFromFloat(&waters.y, line); - nextLine(); - SMBX64::ReadUInt(&waters.w, line); - nextLine(); - SMBX64::ReadUInt(&waters.h, line); - nextLine(); - SMBX64::ReadUInt(&waters.unknown, line); //Unused value - - if(ge(62)) - { - nextLine(); - SMBX64::ReadCSVBool(&waters.env_type, line); - } - - nextLine(); - SMBX64::ReadStr(&waters.layer, line); - waters.meta.array_id = FileData.physenv_array_id++; - waters.meta.index = static_cast(FileData.physez.size()); //Apply element index - FileData.physez.push_back(waters); //Add Water area into array - nextLine(); - } - } - - if(ge(10)) - { - ////////////Layers Data////////// - nextLine(); - - while((line != "next") && (!in.eof()) && (!IsEmpty(line))) - { - SMBX64::ReadStr(&layers.name, line); //Layer name - nextLine(); - SMBX64::ReadCSVBool(&layers.hidden, line); //hidden layer - layers.locked = false; - layers.meta.array_id = FileData.layers_array_id++; - FileData.layers.push_back(layers); //Add Water area into array - nextLine(); - } - - ////////////Events Data////////// - nextLine(); - - while((!IsEmpty(line)) && (!in.eof())) - { - events = CreateLvlEvent(); - SMBX64::ReadStr(&events.name, line);//Event name - - if(ge(11)) - { - nextLine(); - SMBX64::ReadStr(&events.msg, line);//Event message - } - - if(ge(14)) - { - nextLine(); - SMBX64::ReadUInt(&events.sound_id, line); - } - - if(ge(18)) - { - nextLine(); - SMBX64::ReadUInt(&events.end_game, line); - } - - PGELIST events_layersArr; - events_layersArr.clear(); - events.layers_hide.clear(); - events.layers_show.clear(); - events.layers_toggle.clear(); - - for(i = 0; i < sct; i++) - { - nextLine(); - SMBX64::ReadStr(&events_layers.hide, line); //Hide layer - nextLine(); - SMBX64::ReadStr(&events_layers.show, line); //Show layer - - if(ge(14)) - { - nextLine(); - SMBX64::ReadStr(&events_layers.toggle, line);//Toggle layer - } - else - events_layers.toggle.clear(); - - if(!IsEmpty(events_layers.hide)) - events.layers_hide.push_back(events_layers.hide); - - if(!IsEmpty(events_layers.show)) - events.layers_show.push_back(events_layers.show); - - if(!IsEmpty(events_layers.toggle)) - events.layers_toggle.push_back(events_layers.toggle); - - events_layersArr.push_back(events_layers); - } - - if(ge(13)) - { - events.sets.clear(); - - for(i = 0; i < 21; i++) - { - events_sets.id = i; - nextLine(); - SMBX64::ReadSInt(&events_sets.music_id, line); //Set Music - nextLine(); - SMBX64::ReadSInt(&events_sets.background_id, line); //Set Background - nextLine(); - SMBX64::ReadSInt(&events_sets.position_left, line); //Set Position to: LEFT - nextLine(); - SMBX64::ReadSInt(&events_sets.position_top, line); //Set Position to: TOP - nextLine(); - SMBX64::ReadSInt(&events_sets.position_bottom, line); //Set Position to: BOTTOM - nextLine(); - SMBX64::ReadSInt(&events_sets.position_right, line); //Set Position to: RIGHT - events.sets.push_back(events_sets); - } - } - - if(ge(26)) - { - nextLine(); - SMBX64::ReadStr(&events.trigger, line); //Trigger - nextLine(); - SMBX64::ReadUInt(&events.trigger_timer, line); - } //Start trigger event after x [1/10 sec]. Etc. 153,2 sec - - if(ge(27)) - { - nextLine(); //Don't smoke tobacco, let's healthy! :D - SMBX64::ReadCSVBool(&events.nosmoke, line); - } - - if(ge(28)) - { - nextLine(); - SMBX64::ReadCSVBool(&events.ctrl_altjump, line);//Hold ALT-JUMP player control - nextLine(); - SMBX64::ReadCSVBool(&events.ctrl_altrun, line); //ALT-RUN - nextLine(); - SMBX64::ReadCSVBool(&events.ctrl_down, line); //DOWN - nextLine(); - SMBX64::ReadCSVBool(&events.ctrl_drop, line); //DROP - nextLine(); - SMBX64::ReadCSVBool(&events.ctrl_jump, line); //JUMP - nextLine(); - SMBX64::ReadCSVBool(&events.ctrl_left, line); //LEFT - nextLine(); - SMBX64::ReadCSVBool(&events.ctrl_right, line); //RIGHT - nextLine(); - SMBX64::ReadCSVBool(&events.ctrl_run, line); //RUN - nextLine(); - SMBX64::ReadCSVBool(&events.ctrl_start, line); //START - nextLine(); - SMBX64::ReadCSVBool(&events.ctrl_up, line); //UP - events.ctrls_enable = events.ctrlKeyPressed(); - events.ctrl_lock_keyboard = events.ctrls_enable; - } - - if(ge(32)) //-V112 - { - nextLine(); - SMBX64::ReadCSVBool(&events.autostart, line); //Auto start - nextLine(); - SMBX64::ReadStr(&events.movelayer, line); //Layer for movement - nextLine(); - SMBX64::ReadFloat(&events.layer_speed_x, line); //Layer moving speed – horizontal - nextLine(); - SMBX64::ReadFloat(&events.layer_speed_y, line); //Layer moving speed – vertical - - if(!IsEmpty(events.movelayer)) - { - LevelEvent_MoveLayer mvl; - mvl.name = events.movelayer; - mvl.speed_x = events.layer_speed_x; - mvl.speed_y = events.layer_speed_y; - events.moving_layers.push_back(mvl); - } - } - - if(ge(33)) - { - nextLine(); - SMBX64::ReadFloat(&events.move_camera_x, line); //Move screen horizontal speed - nextLine(); - SMBX64::ReadFloat(&events.move_camera_y, line); //Move screen vertical speed - nextLine(); - SMBX64::ReadSInt(&events.scroll_section, line); //Scroll section x, (in file value is x-1) - - if(((events.move_camera_x != 0.0) || (events.move_camera_y != 0.0)) && (events.scroll_section < static_cast(events.sets.size()))) - { - pge_size_t section = static_cast(events.scroll_section); - LevelEvent_Sets &set = events.sets[section]; - set.autoscrol = true; - set.autoscrol_x = static_cast(events.move_camera_x); - set.autoscrol_y = static_cast(events.move_camera_y); - set.expression_autoscrool_x = fromNum(events.move_camera_x); - set.expression_autoscrool_y = fromNum(events.move_camera_y); - } - } - - events.meta.array_id = FileData.events_array_id++; - FileData.events.push_back(events); - nextLine(); - } - } - - LevelAddInternalEvents(FileData); - ///////////////////////////////////////EndFile/////////////////////////////////////// - FileData.meta.ReadFileValid = true; - return true; - } - catch(const std::exception &err) - { - if(file_format > 0) - FileData.meta.ERROR_info = "Detected file format: SMBX-" + fromNum(file_format) + " is invalid\n"; - else - FileData.meta.ERROR_info = "It is not an SMBX level file\n"; - - #ifdef PGE_FILES_QT - FileData.meta.ERROR_info += QString::fromStdString(exception_to_pretty_string(err)); - #else - FileData.meta.ERROR_info += exception_to_pretty_string(err); - #endif - FileData.meta.ERROR_linenum = in.getCurrentLineNumber(); - FileData.meta.ERROR_linedata = line; - FileData.meta.ReadFileValid = false; - return false; - } -} - - - - - - - - -//********************************************************* -//****************WRITE FILE FORMAT************************ -//********************************************************* - -bool FileFormats::WriteSMBX64LvlFileF(PGESTRING filePath, LevelData &FileData, unsigned int file_format) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileOutput file; - - if(!file.open(filePath, false, true, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Fail to open file for write"; - return false; - } - - return WriteSMBX64LvlFile(file, FileData, file_format); -} - -bool FileFormats::WriteSMBX64LvlFileRaw(LevelData &FileData, PGESTRING &rawdata, unsigned int file_format) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextOutput file; - - if(!file.open(&rawdata, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open raw string for write"; - return false; - } - - return WriteSMBX64LvlFile(file, FileData, file_format); -} - -bool FileFormats::WriteSMBX64LvlFile(PGE_FileFormats_misc::TextOutput &out, LevelData &FileData, unsigned int file_format) -{ - pge_size_t i, j; - //Count placed stars on this level - FileData.stars = 0; - - for(i = 0; i < FileData.npc.size(); i++) - { - if(FileData.npc[i].is_star) - FileData.stars++; - } - - //Sort blocks array by X->Y - smbx64LevelSortBlocks(FileData); - //Sort BGO's array by SortPriority->X->Y - smbx64LevelSortBGOs(FileData); - - //Prevent out of range: 0....64 - if(file_format > 64) file_format = 64; - - FileData.meta.RecentFormat = LevelData::SMBX64; - FileData.meta.RecentFormatVersion = file_format; - out << SMBX64::WriteSInt(file_format); //Format version - - if(file_format >= 17) - out << SMBX64::WriteSInt(FileData.stars); //Number of stars - - if(file_format >= 60) - out << SMBX64::WriteStr(FileData.LevelName); //Level name - - pge_size_t s_limit = 21; - - if(file_format < 8) - s_limit = 6; - - //qDebug() << "sections "<= 1) - out << SMBX64::WriteCSVBool(section.lock_left_scroll); - - if(file_format >= 30) - out << SMBX64::WriteCSVBool(section.underwater); - - if(file_format >= 2) - out << SMBX64::WriteStr(section.music_file); - } - - for(; i < s_limit ; i++) //Protector - { - if(file_format < 1) - out << "0\n0\n0\n0\n0\n16291944\n#FALSE#\n#FALSE#\n0\n"; - else if(file_format < 2) - out << "0\n0\n0\n0\n0\n16291944\n#FALSE#\n#FALSE#\n0\n#FALSE#\n"; - else if(file_format < 30) - out << "0\n0\n0\n0\n0\n16291944\n#FALSE#\n#FALSE#\n0\n#FALSE#\n\"\"\n"; - else - out << "0\n0\n0\n0\n0\n16291944\n#FALSE#\n#FALSE#\n0\n#FALSE#\n#FALSE#\n\"\"\n"; - } - - //append dummy section data, if array size is less than 21 - //qDebug() << "i="<< i; - //Players start point - int playerpoints = 0; - - for(j = 1; j <= 2 && playerpoints < 2; j++) - { - bool found = false; - - for(i = 0; i < FileData.players.size(); i++) - { - PlayerPoint &player = FileData.players[i]; - if(player.id != static_cast(j)) - continue; - - out << SMBX64::WriteSInt(player.x); - out << SMBX64::WriteSInt(player.y); - out << SMBX64::WriteSInt(player.w); - out << SMBX64::WriteSInt(player.h); - playerpoints++; - found = true; - } - - if(!found) - { - out << "0\n0\n0\n0\n"; - playerpoints++; - } - } - - for(; playerpoints < 2; playerpoints++) //Protector - out << "0\n0\n0\n0\n"; - - //Blocks - for(pge_size_t blkID = 0; blkID < FileData.blocks.size(); blkID++) - { - LevelBlock &block = FileData.blocks[blkID]; - out << SMBX64::WriteSInt(block.x); - out << SMBX64::WriteSInt(block.y); - out << SMBX64::WriteSInt(block.h); - out << SMBX64::WriteSInt(block.w); - out << SMBX64::WriteSInt(block.id); - long npcID = block.npc_id; - - if(npcID < 0) - { - npcID *= -1; - if(npcID > 99) npcID = 99; - } - else if(npcID != 0) - { - npcID += 1000; - - if(file_format < 18) - { - long xnpcID = npcID; - - //Convert NPC-ID value from SMBX64 to SMBX1/2 - switch(xnpcID) - { - case 1009://Mushroom - xnpcID = 100; - break; - - case 1001://Goomba - xnpcID = 101; - break; - - case 1014://Fire flower - xnpcID = 102; - break; - - case 1034://Super leaf - xnpcID = 103; - break; - - case 1035://Shoe - xnpcID = 104; - break; - - default: - break; - } - - npcID = xnpcID; - } - } - - out << SMBX64::WriteSInt(npcID); - out << SMBX64::WriteCSVBool(block.invisible); - - if(file_format >= 61) - out << SMBX64::WriteCSVBool(block.slippery); - - if(file_format >= 10) - out << SMBX64::WriteStr(block.layer); - - if(file_format >= 14) - { - out << SMBX64::WriteStr(block.event_destroy); - out << SMBX64::WriteStr(block.event_hit); - out << SMBX64::WriteStr(block.event_emptylayer); - } - } - - out << "\"next\"\n";//Separator - - //BGOs - for(pge_size_t bgoID = 0; bgoID < FileData.bgo.size(); bgoID++) - { - LevelBGO &bgo1 = FileData.bgo[bgoID]; - out << SMBX64::WriteSInt(bgo1.x); - out << SMBX64::WriteSInt(bgo1.y); - out << SMBX64::WriteSInt(bgo1.id); - - if(file_format >= 10) - out << SMBX64::WriteStr(bgo1.layer); - } - - out << "\"next\"\n";//Separator - - //NPCs - for(i = 0; i < FileData.npc.size(); i++) - { - LevelNPC &npc = FileData.npc[i]; - //Section size - out << SMBX64::WriteSInt(npc.x); - out << SMBX64::WriteSInt(npc.y); - out << SMBX64::WriteSInt(npc.direct); - out << SMBX64::WriteSInt(npc.id); - - if(file_format >= 10) - { - switch(npc.id) - { - //SMBX64 Fixed special options for NPC - /*Items*/ - /*parakoopa*/ case 76: - case 121: - case 122: - case 123: - case 124: - case 161: - case 176: - case 177: - - /*paragoomba*/ - case 243: - case 244: - - /*Cheep-Cheep*/ - case 28: - case 229: - case 230: - case 232: - case 233: - case 234: - case 236: - - /*WarpSelection*/ - case 288: - case 289: - - /*firebar*/ - case 260: - if( - ((npc.id != 76) && (npc.id != 28)) || - ( - ((file_format >= 15) && (npc.id == 76)) || - ((file_format >= 31) && (npc.id == 28)) - ) - ) - out << SMBX64::WriteSInt(npc.special_data); - - break; - - /*Containers*/ - case 283:/*Bubble*/ - case 91: /*buried*/ - case 284:/*SMW Lakitu*/ - case 96: /*egg*/ - out << SMBX64::WriteSInt(npc.contents); - - //Warp Section value for included into herb magic potion - if((npc.id == 91) && (npc.contents == 288)) - out << SMBX64::WriteSInt(npc.special_data); - - break; - - default: - break; - } - } - - if(file_format >= 3) - { - out << SMBX64::WriteCSVBool(npc.generator); - - if(npc.generator) - { - out << SMBX64::WriteSInt(npc.generator_direct); - out << SMBX64::WriteSInt(npc.generator_type); - out << SMBX64::WriteSInt(npc.generator_period); - } - } - - if(file_format >= 5) - out << SMBX64::WriteStr_multiline(npc.msg); - - if(file_format >= 6) - { - out << SMBX64::WriteCSVBool(npc.friendly); - out << SMBX64::WriteCSVBool(npc.nomove); - } - - if(file_format >= 9) - out << SMBX64::WriteCSVBool(npc.is_boss); - - if(file_format >= 10) - { - out << SMBX64::WriteStr(npc.layer); - out << SMBX64::WriteStr(npc.event_activate); - out << SMBX64::WriteStr(npc.event_die); - out << SMBX64::WriteStr(npc.event_talk); - } - - if(file_format >= 14) - out << SMBX64::WriteStr(npc.event_emptylayer); - - if(file_format >= 63) - out << SMBX64::WriteStr(npc.attach_layer); - } - - out << "\"next\"\n";//Separator - - //Doors - for(i = 0; i < FileData.doors.size(); i++) - { - LevelDoor &warp = FileData.doors[i]; - if(((!warp.lvl_o) && (!warp.lvl_i)) || ((warp.lvl_o) && (!warp.lvl_i))) - if(!warp.isSetIn) continue; // Skip broken door - - if(((!warp.lvl_o) && (!warp.lvl_i)) || ((warp.lvl_i))) - if(!warp.isSetOut) continue; // Skip broken door - - out << SMBX64::WriteSInt(warp.ix); - out << SMBX64::WriteSInt(warp.iy); - out << SMBX64::WriteSInt(warp.ox); - out << SMBX64::WriteSInt(warp.oy); - out << SMBX64::WriteSInt(warp.idirect); - out << SMBX64::WriteSInt(warp.odirect); - out << SMBX64::WriteSInt(warp.type); - - if(file_format >= 3) - { - out << SMBX64::WriteStr(warp.lname); - out << SMBX64::WriteSInt(warp.warpto); - out << SMBX64::WriteCSVBool(warp.lvl_i); - } - - if(file_format >= 4) //-V112 - { - out << SMBX64::WriteCSVBool(warp.lvl_o); - out << SMBX64::WriteSInt(warp.world_x); - out << SMBX64::WriteSInt(warp.world_y); - } - - if(file_format >= 7) - out << SMBX64::WriteSInt(warp.stars); - - if(file_format >= 12) - { - out << SMBX64::WriteStr(warp.layer); - out << SMBX64::WriteCSVBool(warp.unknown); - } - - if(file_format >= 23) - out << SMBX64::WriteCSVBool(warp.novehicles); - - if(file_format >= 25) - out << SMBX64::WriteCSVBool(warp.allownpc); - - if(file_format >= 26) - out << SMBX64::WriteCSVBool(warp.locked); - } - - //Water - if(file_format >= 29) - { - out << "\"next\"\n";//Separator - - for(i = 0; i < FileData.physez.size(); i++) - { - LevelPhysEnv &physEnv = FileData.physez[i]; - out << SMBX64::WriteSInt(physEnv.x); - out << SMBX64::WriteSInt(physEnv.y); - out << SMBX64::WriteSInt(physEnv.w); - out << SMBX64::WriteSInt(physEnv.h); - out << SMBX64::WriteSInt(physEnv.unknown); - - if(file_format >= 62) - out << SMBX64::WriteCSVBool(physEnv.env_type != LevelPhysEnv::ENV_WATER); - - out << SMBX64::WriteStr(physEnv.layer); - } - } - - if(file_format >= 10) - { - out << "\"next\"\n";//Separator - - //Layers - for(i = 0; i < FileData.layers.size(); i++) - { - LevelLayer &layer = FileData.layers[i]; - out << SMBX64::WriteStr(layer.name); - out << SMBX64::WriteCSVBool(layer.hidden); - } - - out << "\"next\"\n";//Separator - LevelEvent_layers layerSet; - - for(i = 0; i < FileData.events.size(); i++) - { - LevelSMBX64Event &event = FileData.events[i]; - out << SMBX64::WriteStr(event.name); - - if(file_format >= 11) - out << SMBX64::WriteStr_multiline(event.msg); - - if(file_format >= 14) - out << SMBX64::WriteSInt(event.sound_id); - - if(file_format >= 18) - out << SMBX64::WriteSInt(event.end_game); - - PGELIST events_layersArr; - - //event.layers.clear(); - for(j = 0; j < 20; j++) - { - layerSet.hide = - ((j < event.layers_hide.size()) ? - event.layers_hide[j] : ""); - layerSet.show = - ((j < event.layers_show.size()) ? - event.layers_show[j] : "");; - layerSet.toggle = - ((j < event.layers_toggle.size()) ? - event.layers_toggle[j] : ""); - events_layersArr.push_back(layerSet); - } - - for(j = 0; j < events_layersArr.size() && j < s_limit - 1; j++) - { - LevelEvent_layers &eLayer = events_layersArr[j]; - out << SMBX64::WriteStr(eLayer.hide); - out << SMBX64::WriteStr(eLayer.show); - - if(file_format >= 14) - out << SMBX64::WriteStr(eLayer.toggle); - } - - for(; j < s_limit; j++) - { - if(file_format >= 14) - out << "\"\"\n\"\"\n\"\"\n"; //(21st element is SMBX 1.3 bug protector) - else - out << "\"\"\n\"\"\n"; - } - - if(file_format >= 13) - { - for(j = 0; j < event.sets.size() && j < s_limit; j++) - { - LevelEvent_Sets &set = event.sets[j]; - out << SMBX64::WriteSInt(set.music_id); - out << SMBX64::WriteSInt(set.background_id); - out << SMBX64::WriteSInt(set.position_left); - out << SMBX64::WriteSInt(set.position_top); - out << SMBX64::WriteSInt(set.position_bottom); - out << SMBX64::WriteSInt(set.position_right); - } - - for(; j < s_limit; j++) // Protector - out << "0\n0\n0\n-1\n-1\n-1\n"; - } - - if(file_format >= 26) - { - out << SMBX64::WriteStr(event.trigger); - out << SMBX64::WriteSInt(event.trigger_timer); - } - - if(file_format >= 27) - out << SMBX64::WriteCSVBool(event.nosmoke); - - if(file_format >= 28) - { - out << SMBX64::WriteCSVBool(event.ctrl_altjump); - out << SMBX64::WriteCSVBool(event.ctrl_altrun); - out << SMBX64::WriteCSVBool(event.ctrl_down); - out << SMBX64::WriteCSVBool(event.ctrl_drop); - out << SMBX64::WriteCSVBool(event.ctrl_jump); - out << SMBX64::WriteCSVBool(event.ctrl_left); - out << SMBX64::WriteCSVBool(event.ctrl_right); - out << SMBX64::WriteCSVBool(event.ctrl_run); - out << SMBX64::WriteCSVBool(event.ctrl_start); - out << SMBX64::WriteCSVBool(event.ctrl_up); - } - - if(file_format >= 32) //-V112 - { - out << SMBX64::WriteCSVBool(event.autostart > 0); - out << SMBX64::WriteStr(event.movelayer); - out << SMBX64::WriteFloat(event.layer_speed_x); - out << SMBX64::WriteFloat(event.layer_speed_y); - } - - if(file_format >= 33) - { - out << SMBX64::WriteFloat(event.move_camera_x); - out << SMBX64::WriteFloat(event.move_camera_y); - out << SMBX64::WriteSInt(event.scroll_section); - } - } - } - - return true; -} diff --git a/LunaDll/libs/PGE_File_Formats/file_rw_lvl_38a.cpp b/LunaDll/libs/PGE_File_Formats/file_rw_lvl_38a.cpp deleted file mode 100644 index bdcf44321..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_rw_lvl_38a.cpp +++ /dev/null @@ -1,2157 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "pge_file_lib_sys.h" -#include "file_formats.h" -#include "file_strlist.h" - -#include "smbx38a_private.h" - -// Settings -static constexpr uint32_t newest_file_format = 68; - -/*********** Pre-defined values dependent to NPC Generator Effect field value **************/ - -/* - -FIELD to Types/Directions conversion table -2 1 0 3 4 <- types (PGE/SMBX64) -0 1 2 3 4 <- types (SMBX-38A) - ___ directions - / -0 0 0 0 0 0 -1 5 9 13 17 1 -2 6 10 14 18 2 -3 7 11 15 19 3 -4 8 12 16 20 4 -9 13 17 21 25 9 -10 14 18 22 26 10 -11 15 19 23 27 11 -12 16 20 24 28 12 - -*/ - -const int SMBX38A_NpcGeneratorTypes[29] = - //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 -{ 0, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4 }; - -const int SMBX38A_NpcGeneratorDirections[29] = - //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 -{ 0, 1, 2, 3, 4, 1, 2, 3, 4, 9, 10, 11, 12, 1, 2, 3, 4, 1, 2, 3, 4, 9, 10, 11, 12, 9, 10, 11, 12}; - - -//********************************************************* -//****************READ FILE FORMAT************************* -//********************************************************* - -bool FileFormats::ReadSMBX38ALvlFileHeader(PGESTRING filePath, LevelData &FileData) -{ - errorString.clear(); - CreateLevelHeader(FileData); - FileData.meta.RecentFormat = LevelData::SMBX38A; - #if !defined(_MSC_VER) || _MSC_VER > 1800 - PGE_FileFormats_misc::TextFileInput inf; - uint32_t file_version = 0; - - if(!inf.open(filePath, false)) - { - FileData.meta.ReadFileValid = false; - return false; - } - - PGE_FileFormats_misc::FileInfo in_1(filePath); - FileData.meta.filename = in_1.basename(); - FileData.meta.path = in_1.dirpath(); - inf.seek(0, PGE_FileFormats_misc::TextFileInput::begin); - - try - { - CSVPGEReader readerBridge(&inf); - auto dataReader = MakeCSVReaderForPGESTRING(&readerBridge, '|'); - PGESTRING fileIndentifier = dataReader.ReadField(1); - dataReader.ReadDataLine(); - - if(!PGE_StartsWith(fileIndentifier, "SMBXFile")) - throw std::logic_error("Invalid file format"); - - file_version = toUInt(PGE_SubStr(fileIndentifier, 8, -1)); - - while(!inf.eof()) - { - PGESTRING identifier = dataReader.ReadField(1); - - if(identifier == "A") - { - PGESTRING s[4]; - dataReader.ReadDataLine(CSVDiscard(), // Skip the first field (this is already "identifier") - &FileData.stars, - MakeCSVPostProcessor(&FileData.LevelName, PGEUrlDecodeFunc), - MakeCSVOptional(&FileData.open_level_on_fail, PGESTRING(""), nullptr, PGEUrlDecodeFunc),//3 - MakeCSVOptionalEmpty(&FileData.open_level_on_fail_warpID, 0u), - MakeCSVOptionalSubReader(dataReader, ',', - MakeCSVOptional(&s[0], PGESTRING(""), nullptr, PGEUrlDecodeFunc), - MakeCSVOptional(&s[1], PGESTRING(""), nullptr, PGEUrlDecodeFunc), - MakeCSVOptional(&s[2], PGESTRING(""), nullptr, PGEUrlDecodeFunc), - MakeCSVOptional(&s[3], PGESTRING(""), nullptr, PGEUrlDecodeFunc) - )); - - for(uint32_t i = 0; i < 4; i++) - { - if(!IsEmpty(s[i])) - { - LevelData::MusicOverrider mo; - mo.type = LevelData::MusicOverrider::SPECIAL; - mo.id = (i + 1); - mo.fileName = s[i]; - FileData.music_overrides.push_back(mo); - } - } - } - else - dataReader.ReadDataLine(); - } - } - catch(const std::exception &err) - { - FileData.meta.ReadFileValid = false; - FileData.meta.ERROR_info = "Invalid file format, detected file SMBX-" + fromNum(file_version) + " format\n" - "Caused by: \n" + PGESTRING(exception_to_pretty_string(err).c_str()); - FileData.meta.ERROR_linenum = inf.getCurrentLineNumber(); - FileData.meta.ERROR_linedata = ""; - return false; - } - catch(...) - { - /* - * This is an attempt to fix crash on Windows 32 bit release assembly, - * and possible, on some other platforms too - */ - FileData.meta.ReadFileValid = false; - FileData.meta.ERROR_info = "Invalid file format, detected file SMBX-" + fromNum(file_version) + " format\n" - "Caused by unknown exception\n"; - FileData.meta.ERROR_linenum = inf.getCurrentLineNumber(); - FileData.meta.ERROR_linedata = ""; - return false; - } - - FileData.CurSection = 0; - FileData.playmusic = 0; - return true; - #else - FileData.meta.ReadFileValid = false; - FileData.meta.ERROR_info = "Unsupported on MSVC2013"; - return false; - #endif -} - -bool FileFormats::ReadSMBX38ALvlFileF(PGESTRING filePath, LevelData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileInput file; - - if(!file.open(filePath, false)) - { - errorString = "Failed to open file for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadSMBX38Level(file, FileData); -} - -bool FileFormats::ReadSMBX38ALvlFileRaw(PGESTRING &rawdata, PGESTRING filePath, LevelData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextInput file; - - if(!file.open(&rawdata, filePath)) - { - errorString = "Failed to open raw string for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadSMBX38Level(file, FileData); -} - -struct LevelEvent_layers -{ - PGESTRING hide; - PGESTRING show; - PGESTRING toggle; -}; - - - -/**********************************************************************************************/ -bool FileFormats::ReadSMBX38ALvlFile(PGE_FileFormats_misc::TextInput &in, LevelData &FileData) -{ - SMBX38A_FileBeginN(); - PGESTRING filePath = in.getFilePath(); - errorString.clear(); - CreateLevelData(FileData); - FileData.meta.RecentFormat = LevelData::SMBX38A; - #if !defined(_MSC_VER) || _MSC_VER > 1800 - FileData.LevelName = "" ; - FileData.stars = 0; - FileData.CurSection = 0; - FileData.playmusic = 0; - //Enable strict mode for SMBX LVL file format - FileData.meta.smbx64strict = false; - //Begin all ArrayID's here; - FileData.blocks_array_id = 1; - FileData.bgo_array_id = 1; - FileData.npc_array_id = 1; - FileData.doors_array_id = 1; - FileData.physenv_array_id = 1; - FileData.layers_array_id = 1; - FileData.events_array_id = 1; - FileData.layers.clear(); - FileData.events.clear(); - LevelSection section; - PlayerPoint playerdata; - LevelBlock blockdata; - LevelBGO bgodata; - LevelNPC npcdata; - LevelDoor doordata; - LevelPhysEnv phyEnv; - LevelLayer layerdata; - LevelSMBX64Event eventdata; - //LevelEvent_Sets event_sets; - LevelVariable vardata; - LevelScript scriptdata; - LevelItemSetup38A customcfg; - - PGESTRING identifier; - uint32_t file_version = 0; - - //Add path data - if(!IsEmpty(filePath)) - { - PGE_FileFormats_misc::FileInfo in_1(filePath); - FileData.meta.filename = in_1.basename(); - FileData.meta.path = in_1.dirpath(); - } - - in.seek(0, PGE_FileFormats_misc::TextFileInput::begin); - - try - { - CSVPGEReader readerBridge(&in); - auto dataReader = MakeCSVReaderForPGESTRING(&readerBridge, '|'); - PGESTRING fileIndentifier = dataReader.ReadField(1); - dataReader.ReadDataLine(); - - if(!PGE_StartsWith(fileIndentifier, "SMBXFile")) - throw std::logic_error("Invalid file format"); - - file_version = toUInt(PGE_SubStr(fileIndentifier, 8, -1)); - - while(!in.eof()) - { - identifier = dataReader.ReadField(1); - - if(identifier == "A") - { - // FIXME: Remove copy from line 77 - // A|param1|param2[|param3|param4]| - // A|param1|param2|param3|param4|s1,s2,s3,s4 - /* - exception: Failed to parse field 4 at line 2 - exception: Could not convert to unsigned int - - Field type A - */ - // 0 1 2 3 4{} - // A|0|%4C%61%79%65%72%20%53%70%69%6E%21| |,,, - PGESTRING s[4]; - dataReader.ReadDataLine(CSVDiscard(), // Skip the first field (this is already "identifier") - &FileData.stars, - MakeCSVPostProcessor(&FileData.LevelName, PGEUrlDecodeFunc), - MakeCSVOptional(&FileData.open_level_on_fail, PGESTRING(""), nullptr, PGEUrlDecodeFunc),//3 - MakeCSVOptionalEmpty(&FileData.open_level_on_fail_warpID, 0u), - MakeCSVOptionalSubReader(dataReader, ',', - MakeCSVOptional(&s[0], PGESTRING(""), nullptr, PGEUrlDecodeFunc), - MakeCSVOptional(&s[1], PGESTRING(""), nullptr, PGEUrlDecodeFunc), - MakeCSVOptional(&s[2], PGESTRING(""), nullptr, PGEUrlDecodeFunc), - MakeCSVOptional(&s[3], PGESTRING(""), nullptr, PGEUrlDecodeFunc) - )); - - for(uint32_t i = 0; i < 4; i++) - { - if(!IsEmpty(s[i])) - { - LevelData::MusicOverrider mo; - mo.type = LevelData::MusicOverrider::SPECIAL; - mo.id = (i + 1); - mo.fileName = s[i]; - FileData.music_overrides.push_back(mo); - } - } - } - else if(identifier == "P1") - { - // P1|x1|y1 - playerdata = CreateLvlPlayerPoint(1); - dataReader.ReadDataLine(CSVDiscard(), &playerdata.x, &playerdata.y); - FileData.players.push_back(playerdata); - } - else if(identifier == "P2") - { - // P2|x2|y2 - // FIXME: Copy from above (can be solved with switch?) - playerdata = CreateLvlPlayerPoint(2); - dataReader.ReadDataLine(CSVDiscard(), &playerdata.x, &playerdata.y); - FileData.players.push_back(playerdata); - } - else if(identifier == "M") - { - // M|id|x|y|w|h|b1|b2|b3|b4|b5|b6|music|background|musicfile - section = CreateLvlSection(); - double x = 0.0, y = 0.0, w = 0.0, h = 0.0; - PGESTRING scroll_lock_x; - PGESTRING scroll_lock_y; - dataReader.ReadDataLine(CSVDiscard(), - //id=[1-SectionMAX] - MakeCSVPostProcessor(§ion.id, [](int §ionID) - { - sectionID--; - if(sectionID < 0) sectionID = 0; - }), - //x=Left size[-left/+right] - &x, - //y=Top size[-down/+up] - &y, - //w=width of the section[if (w < 800) w = 800] - &w,//MakeCSVPostProcessor(&w, MakeMinFunc(800.0)), - //h=height of the section[if (h < 600) h = 600] - &h,//MakeCSVPostProcessor(&h, MakeMinFunc(600.0)), - //b1=under water?[0=false !0=true] - §ion.underwater, - //b2=is x-level wrap[0=false !0=true] - §ion.wrap_h, - //b3=enable off screen exit[0=false !0=true] - §ion.OffScreenEn, - //b4=no turn back(x)[0=no x-scrolllock 1=scrolllock left 2=scrolllock right] - &scroll_lock_x, - //b5=no turn back(y)[0=no y-scrolllock 1=scrolllock up 2=scrolllock down] - &scroll_lock_y, - //b6=is y-level wrap[0=false !0=true] - §ion.wrap_v, - //music=music number[same as smbx1.3] - §ion.music_id, - //background=background number[same as the filename in 'background2' folder] - §ion.background, - //musicfile=custom music file[***urlencode!***] - MakeCSVPostProcessor(§ion.music_file, PGEUrlDecodeFunc)); - SMBX38A_mapBGID_From(section.background);//Convert into SMBX64 ID set - section.lock_left_scroll = (scroll_lock_x == "1"); - section.lock_right_scroll = (scroll_lock_x == "2"); - section.lock_up_scroll = (scroll_lock_y == "1"); - section.lock_down_scroll = (scroll_lock_y == "2"); - - if((x != 0.0) || (y != 0.0) || (w != 0.0) || (h != 0.0)) - { - section.size_left = static_cast(round(x)); - section.size_top = static_cast(round(y)); - section.size_right = static_cast(round(x + w)); - section.size_bottom = static_cast(round(y + h)); - } - - //Very important data! I'ts a camera position in the editor! - section.PositionX = section.size_left - 10; - section.PositionY = section.size_top - 10; - - if(section.id < static_cast(FileData.sections.size())) - FileData.sections[static_cast(section.id)] = section;//Replace if already exists - else - FileData.sections.push_back(section); //Add Section in main array - } - else if(identifier == "B") - { - // B|layer[,name]|id[,dx,dy]|x|y|contain|b11[,b12]|b2|[e1,e2,e3,e4]|w|h - blockdata = CreateLvlBlock(); - dataReader.ReadDataLine(CSVDiscard(), - MakeCSVSubReader(dataReader, ',', - //layer=layer name["" == "Default"][***urlencode!***] - MakeCSVPostProcessor(&blockdata.layer, PGELayerOrDefault), - //name=block's name[***urlencode!***] - MakeCSVOptional(&blockdata.gfx_name, "") - ), - MakeCSVSubReader(dataReader, ',', - //id=block id - &blockdata.id, - //dx=graphics extend x - MakeCSVOptional(&blockdata.gfx_dx, 0), - //dy=graphics extend y - MakeCSVOptional(&blockdata.gfx_dy, 0) - ), - //x=block position x - &blockdata.x, //FIXME rounding error? - //y=block position y - &blockdata.y, - /* contain=containing npc number - [1001-1000+NPCMAX] npc-id - [1-999] coin number - [0] nothing - */ - MakeCSVOptionalEmpty(&blockdata.npc_id, 0, nullptr, [](long & npcValue) - { - npcValue = (npcValue < 1000 ? -1 * npcValue : npcValue - 1000); - }), - MakeCSVSubReader(dataReader, ',', - //b11=slippery[0=false !0=true] - &blockdata.slippery, - //b12=wing type - MakeCSVOptional(&blockdata.motion_ai_id, 0) - ), - //b2=invisible[0=false !0=true] - &blockdata.invisible, - MakeCSVSubReader(dataReader, ',', - //e1=block destory event name[***urlencode!***] - MakeCSVPostProcessor(&blockdata.event_destroy, PGEUrlDecodeFunc), - //e2=block hit event name[***urlencode!***] - MakeCSVPostProcessor(&blockdata.event_hit, PGEUrlDecodeFunc), - //e3=no more object in layer event name[***urlencode!***] - MakeCSVPostProcessor(&blockdata.event_emptylayer, PGEUrlDecodeFunc), - //e4=block onscreen event name[***urlencode!***] - MakeCSVOptional(&blockdata.event_on_screen, "", nullptr, PGEUrlDecodeFunc) - ), - //w=width, if w < 0 then block's autoscale = true - &blockdata.w, - //h=height - &blockdata.h); - blockdata.autoscale = (blockdata.w < 0); - if(blockdata.w < 0) - blockdata.w *= -1; - blockdata.meta.array_id = FileData.blocks_array_id++; - FileData.blocks.push_back(blockdata); - } - else if(identifier == "T") - { - // T|layer|id[,dx,dy]|x|y - bgodata = CreateLvlBgo(); - dataReader.ReadDataLine(CSVDiscard(), - MakeCSVPostProcessor(&bgodata.layer, PGELayerOrDefault), - MakeCSVSubReader(dataReader, ',', - &bgodata.id, - MakeCSVOptional(&bgodata.gfx_dx, 0), - MakeCSVOptional(&bgodata.gfx_dy, 0) - ), - &bgodata.x, - &bgodata.y); - bgodata.meta.array_id = FileData.bgo_array_id++; - FileData.bgo.push_back(bgodata); - } - else if(identifier == "N") - { - // N|layer[,name]|id[,dx,dy]|x|y|b1,b2,b3,b4|sp|[e1,e2,e3,e4,e5,e6,e7]|a1,a2|c1[,c2,c3,c4,c5,c6,c7]|msg| - // N|layer[,name]|id[,dx,dy]|x|y|b1,b2,b3,b4|sp|[e1,e2,e3,e4,e5,e6,e7]|a1,a2|c1[,c2,c3,c4,c5,c6,c7]|msg| - npcdata = CreateLvlNpc(); - npcdata.generator_period_orig_unit = PGE_FileLibrary::TimeUnit::FrameOneOf65sec; - double specialData; - int genType; // We have to handle that later :( - dataReader.ReadDataLine(CSVDiscard(), - MakeCSVSubReader(dataReader, ',', - MakeCSVPostProcessor(&npcdata.layer, PGELayerOrDefault), - MakeCSVOptional(&npcdata.gfx_name, "") - ), - MakeCSVSubReader(dataReader, ',', - &npcdata.id, - MakeCSVOptional(&npcdata.gfx_dx, 0), - MakeCSVOptional(&npcdata.gfx_dy, 0) - ), - &npcdata.x, - &npcdata.y, - MakeCSVSubReader(dataReader, ',', - MakeCSVPostProcessor(&npcdata.direct, [](int &value) - { - value = value * -1; - }), - &npcdata.friendly, - &npcdata.nomove, - &npcdata.contents), - &specialData, - MakeCSVSubReader(dataReader, ',', - MakeCSVOptional(&npcdata.event_die, "", nullptr, PGEUrlDecodeFunc), - MakeCSVOptional(&npcdata.event_talk, "", nullptr, PGEUrlDecodeFunc), - MakeCSVOptional(&npcdata.event_activate, "", nullptr, PGEUrlDecodeFunc), - MakeCSVOptional(&npcdata.event_emptylayer, "", nullptr, PGEUrlDecodeFunc), - MakeCSVOptional(&npcdata.event_grab, "", nullptr, PGEUrlDecodeFunc), - MakeCSVOptional(&npcdata.event_nextframe, "", nullptr, PGEUrlDecodeFunc), - MakeCSVOptional(&npcdata.event_touch, "", nullptr, PGEUrlDecodeFunc) - ), - MakeCSVSubReader(dataReader, ',', - MakeCSVOptionalEmpty(&npcdata.attach_layer, "", nullptr, PGEUrlDecodeFunc), - MakeCSVOptionalEmpty(&npcdata.send_id_to_variable, "", nullptr, PGEUrlDecodeFunc) - ), - MakeCSVSubReader(dataReader, ',', - &npcdata.generator, - MakeCSVOptional(&npcdata.generator_period_orig, 65), - MakeCSVOptional(&genType, 0), - MakeCSVOptional(&npcdata.generator_custom_angle, 0.0), - MakeCSVOptional(&npcdata.generator_branches, 1), - MakeCSVOptional(&npcdata.generator_angle_range, 360.0), - MakeCSVOptional(&npcdata.generator_initial_speed, 10.0) - ), - MakeCSVPostProcessor(&npcdata.msg, PGEUrlDecodeFunc) - ); - - if(npcdata.contents > 0) - { - long contID = npcdata.contents; - npcdata.contents = static_cast(npcdata.id); - //b4=[1=npc91][2=npc96][3=npc283][4=npc284][5=npc300][6=npc347] - static const uint64_t ContNPCID[] = - { - // 1 2 3 4 5 6 - 0, 91, 96, 283, 284, 300, 347, 0 - }; - if((contID > 0) && (contID <= 6)) - npcdata.id = ContNPCID[contID]; - else - npcdata.contents = 0; //Invalid container type - - if((contID > 101) && (contID <= 107)) - npcdata.meta.custom_params += "\"wings:\"" + fromNum(contID) + ","; - } - - npcdata.special_data = static_cast(round(specialData)); - - switch(npcdata.id) - { - case 15: - case 39: - case 86: //Bind "Is Boss" flag for supported NPC's - npcdata.is_boss = static_cast(npcdata.special_data); - npcdata.special_data = 0; - break; - default: - break; - } - - switch(genType) - { - case 0: - npcdata.generator_type = LevelNPC::NPC_GENERATOR_APPEAR; - npcdata.generator_direct = LevelNPC::NPC_GEN_CENTER; - break; - default: - if(genType < 29) - { - npcdata.generator_type = SMBX38A_NpcGeneratorTypes[genType]; - npcdata.generator_direct = SMBX38A_NpcGeneratorDirections[genType]; - } - else - { - npcdata.generator_type = LevelNPC::NPC_GENERATOR_APPEAR; - npcdata.generator_direct = LevelNPC::NPC_GEN_CENTER; - } - } - - //Convert value into SMBX64 and PGEX compatible - switch(npcdata.generator_type) - { - case 0: - npcdata.generator_type = LevelNPC::NPC_GENERATPR_PROJECTILE; - break; - case 1: - npcdata.generator_type = LevelNPC::NPC_GENERATOR_WARP; - break; - case 4: - npcdata.generator_type = LevelNPC::NPC_GENERATOR_APPEAR; - break; - } - - npcdata.generator_period = PGE_FileLibrary::TimeUnitsCVT(static_cast(npcdata.generator_period_orig), - PGE_FileLibrary::TimeUnit::FrameOneOf65sec, - PGE_FileLibrary::TimeUnit::Decisecond); - npcdata.meta.array_id = FileData.npc_array_id++; - FileData.npc.push_back(npcdata); - } - else if(identifier == "Q") - { - // Q|layer|x|y|w|h|b1,b2,b3,b4,b5|event - phyEnv = CreateLvlPhysEnv(); - dataReader.ReadDataLine(CSVDiscard(), - MakeCSVPostProcessor(&phyEnv.layer, PGELayerOrDefault), - &phyEnv.x, - &phyEnv.y, - &phyEnv.w, - &phyEnv.h, - MakeCSVSubReader(dataReader, ',', - MakeCSVPostProcessor(&phyEnv.env_type, [](int &value) - { - value--; - }), - &phyEnv.friction, - &phyEnv.accel_direct, - &phyEnv.accel, - &phyEnv.accel), - MakeCSVPostProcessor(&phyEnv.touch_event, PGEUrlDecodeFunc) - ); - phyEnv.meta.array_id = FileData.physenv_array_id++; - FileData.physez.push_back(phyEnv); - } - else if(identifier == "W") - { - // W|layer|x|y|ex|ey|type|enterd|exitd|sn,msg,hide|locked,noyoshi,canpick,bomb,hidef,anpc,mini,size|lik|liid|noexit|wx|wy|le|we - doordata = CreateLvlWarp(); - int type = 0; - dataReader.ReadDataLine(CSVDiscard(), - //layer=layer name["" == "Default"][***urlencode!***] - MakeCSVPostProcessor(&doordata.layer, PGELayerOrDefault), - //x=entrance position x - &doordata.ix, - //y=entrance postion y - &doordata.iy, - //ex=exit position x - &doordata.ox, - //ey=exit position y - &doordata.oy, - //type=[1=pipe][2=door][0=instant][3=portal/loop] - &type, - //enterd=entrance direction[1=up 2=left 3=down 4=right] - &doordata.idirect, - //exitd=exit direction[1=up 2=left 3=down 4=right] - MakeCSVPostProcessor(&doordata.odirect, [](int &value) - { - switch(value)//Convert into SMBX64/PGE-X Compatible form - { - case 1: - value = LevelDoor::EXIT_UP; - break; - case 2: - value = LevelDoor::EXIT_LEFT; - break; - case 3: - value = LevelDoor::EXIT_DOWN; - break; - case 4: - value = LevelDoor::EXIT_RIGHT; - break; - } - }), - MakeCSVSubReader(dataReader, ',', - //sn=need stars for enter - &doordata.stars, - //msg=a message when you have not enough stars - MakeCSVPostProcessor(&doordata.stars_msg, PGEUrlDecodeFunc), - //hide=hide the star number in this warp - &doordata.star_num_hide), - MakeCSVSubReader(dataReader, ',', - //locked=locked - &doordata.locked, - //noyoshi=no yoshi - &doordata.novehicles, - //canpick=allow npc - &doordata.allownpc, - //bomb=need a bomb - &doordata.need_a_bomb, - //hide=hide the entry scene - &doordata.hide_entering_scene, - //anpc=allow npc interlevel - &doordata.allownpc_interlevel, - //mini=Mini-Only - MakeCSVOptional(&doordata.special_state_required, false), - //size=Warp Size(pixel) - MakeCSVOptional(&doordata.length_i, 32u), - MakeCSVOptional(&doordata.two_way, false), - MakeCSVOptional(&doordata.cannon_exit_speed, 0.0) - ), - //lik=warp to level[***urlencode!***] - MakeCSVPostProcessor(&doordata.lname, PGEUrlDecodeFunc), - //liid=normal enterance / to warp[0-WARPMAX] - &doordata.warpto, - //noexit=level entrance - &doordata.lvl_i, - //wx=warp to x on world map - &doordata.world_x, - //wy=warp to y on world map - &doordata.world_y, - //le=level exit - MakeCSVOptional(&doordata.lvl_o, false), - //we=warp event[***urlencode!***] - MakeCSVOptional(&doordata.event_enter, "", nullptr, PGEUrlDecodeFunc) - ); - // type%100=[0=instant][1=pipe][2=door][3=loop] - doordata.type = type % 100; - // type/100=[0=none][1=Scroll][2=Fade] - doordata.transition_effect = type / 100; - doordata.length_o = doordata.length_i; - doordata.isSetIn = (doordata.lvl_i ? false : true); - doordata.isSetOut = (doordata.lvl_o ? false : true) || doordata.lvl_i; - doordata.cannon_exit = (doordata.cannon_exit_speed > 0.0); - if(doordata.cannon_exit_speed <= 0) - doordata.cannon_exit_speed = 10.0; - doordata.meta.array_id = FileData.doors_array_id++; - FileData.doors.push_back(doordata); - } - else if(identifier == "L") - { - // L|name|status - layerdata = CreateLvlLayer(); - dataReader.ReadDataLine(CSVDiscard(), - MakeCSVPostProcessor(&layerdata.name, PGELayerOrDefault), - MakeCSVPostProcessor(&layerdata.hidden, PGEFilpBool) - ); - layerdata.meta.array_id = FileData.layers_array_id++; - FileData.layers.push_back(layerdata); - } - else if(identifier == "E") - { - // E|name|msg|ea|el|elm|epy|eps|eef|ecn|evc|ene - eventdata = CreateLvlEvent(); - // Here we can just align the section id with the index of the set - // It is an unsafe method, however, we should be safe when reading from the file, where the data object is empty. - eventdata.sets.clear(); - - for(int q = 0; q < static_cast(FileData.sections.size()); q++) - { - LevelEvent_Sets set; - set.id = static_cast(q); - eventdata.sets.push_back(set); - } - - // Temp Field 11 - double timer_def_interval_raw; - // This variable is used for the spawn npc section. - // The first two values are static ones, after that they come in packages (see below) - int spawnNpcReaderCurrentIndex = 0; - dataReader.ReadDataLine(CSVDiscard(), - MakeCSVPostProcessor(&eventdata.name, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&eventdata.msg, PGEUrlDecodeFunc), - MakeCSVSubReader(dataReader, ',', - &eventdata.autostart, - MakeCSVPostProcessor(&eventdata.autostart_condition, PGEUrlDecodeFunc) - ), - MakeCSVSubReader(dataReader, '/', - &eventdata.nosmoke, - MakeCSVBatchReader(dataReader, ',', &eventdata.layers_show, PGEUrlDecodeFunc), - MakeCSVBatchReader(dataReader, ',', &eventdata.layers_hide, PGEUrlDecodeFunc), - MakeCSVBatchReader(dataReader, ',', &eventdata.layers_toggle, PGEUrlDecodeFunc) - ), - MakeCSVIterator(dataReader, '/', [&eventdata](const PGESTRING & nextFieldStr) - { - auto fieldReader = MakeDirectReader(nextFieldStr); - auto fullReader = MakeCSVReaderForPGESTRING(&fieldReader, ','); - LevelEvent_MoveLayer movingLayer; - fullReader.ReadDataLine(MakeCSVPostProcessor(&movingLayer.name, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&movingLayer.expression_x, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&movingLayer.expression_y, PGEUrlDecodeFunc), - &movingLayer.way - ); - SMBX38A_Exp2Double(movingLayer.expression_x, movingLayer.speed_x); - SMBX38A_Exp2Double(movingLayer.expression_y, movingLayer.speed_y); - eventdata.moving_layers.push_back(movingLayer); - eventdata.movelayer = movingLayer.name; - eventdata.layer_speed_x = movingLayer.speed_x; - eventdata.layer_speed_y = movingLayer.speed_y; - }), - MakeCSVSubReader(dataReader, ',', - &eventdata.ctrls_enable, - &eventdata.ctrl_drop, - &eventdata.ctrl_altrun, - &eventdata.ctrl_run, - &eventdata.ctrl_jump, - &eventdata.ctrl_altjump, - &eventdata.ctrl_up, - &eventdata.ctrl_down, - &eventdata.ctrl_left, - &eventdata.ctrl_right, - &eventdata.ctrl_start, - &eventdata.ctrl_lock_keyboard - ), - MakeCSVSubReader(dataReader, '/', - MakeCSVIterator(dataReader, ':', [&eventdata](const PGESTRING & nextFieldStr) - { - auto fieldReader = MakeDirectReader(nextFieldStr); - auto fullReader = MakeCSVReaderForPGESTRING(&fieldReader, ','); - int sectionID = fullReader.ReadField(1) - 1; - LevelEvent_Sets &nextSet = eventdata.sets[static_cast(sectionID)]; - bool customSize = false; - bool canAutoscroll = false; - fullReader.ReadDataLine(CSVDiscard(), - MakeCSVPostProcessor(&nextSet.position_left, [&customSize](long & value) - { - switch(value) - { - case 0: - value = LevelEvent_Sets::LESet_Nothing; - break; - - case 1: - value = LevelEvent_Sets::LESet_ResetDefault; - break; - - case 2: - customSize = true; - value = 0; - break; - } - }), - MakeCSVPostProcessor(&nextSet.expression_pos_x, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&nextSet.expression_pos_y, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&nextSet.expression_pos_w, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&nextSet.expression_pos_h, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&nextSet.autoscrol, [&canAutoscroll](bool & value) - { - canAutoscroll = value; - }), - MakeCSVPostProcessor(&nextSet.expression_autoscrool_x, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&nextSet.expression_autoscrool_y, PGEUrlDecodeFunc) - ); - - if(customSize) - { - SMBX38A_Exp2Int(nextSet.expression_pos_x, nextSet.position_left); - SMBX38A_Exp2Int(nextSet.expression_pos_y, nextSet.position_top); - SMBX38A_Exp2Int(nextSet.expression_pos_w, nextSet.position_right); - SMBX38A_Exp2Int(nextSet.expression_pos_h, nextSet.position_bottom); - - if(IsEmpty(nextSet.expression_pos_w)) - nextSet.position_right += nextSet.position_left; - - if(IsEmpty(nextSet.expression_pos_h)) - nextSet.position_bottom += nextSet.position_top; - } - - if(canAutoscroll) - { - SMBX38A_Exp2Float(nextSet.expression_autoscrool_x, nextSet.autoscrol_x); - SMBX38A_Exp2Float(nextSet.expression_autoscrool_y, nextSet.autoscrol_y); - //SMBX64 backwarth compatibility: - eventdata.scroll_section = nextSet.id;//Set ID of autoscrollable section :-P - eventdata.move_camera_x = static_cast(nextSet.autoscrol_x); - eventdata.move_camera_y = static_cast(nextSet.autoscrol_y); - } - else - { - nextSet.autoscrol_x = 0.f; - nextSet.autoscrol_y = 0.f; - // Doesn't even make sense: - // eventdata.move_camera_x = 0.f; - // eventdata.move_camera_y = 0.f; - } - - eventdata.scroll_section = static_cast(sectionID); - }), - MakeCSVIterator(dataReader, ':', [&eventdata](const PGESTRING & nextFieldStr) - { - auto fieldReader = MakeDirectReader(nextFieldStr); - auto fullReader = MakeCSVReaderForPGESTRING(&fieldReader, ','); - int sectionID = fullReader.ReadField(1) - 1; - LevelEvent_Sets &nextSet = eventdata.sets[static_cast(sectionID)]; - bool customBG = false; - long bgID = 0; - fullReader.ReadDataLine(CSVDiscard(), - MakeCSVPostProcessor(&nextSet.background_id, [&customBG](long & value) - { - switch(value) - { - case 0: - value = LevelEvent_Sets::LESet_Nothing; - break; - - case 1: - value = LevelEvent_Sets::LESet_ResetDefault; - break; - - case 2: - customBG = true; - value = 0; - break; - } - }), - &bgID - ); - - if(customBG) - nextSet.background_id = bgID; - - SMBX38A_mapBGID_From(nextSet.background_id);//Convert into SMBX64 ID set - }), - MakeCSVIterator(dataReader, ':', [&eventdata](const PGESTRING & nextFieldStr) - { - auto fieldReader = MakeDirectReader(nextFieldStr); - auto fullReader = MakeCSVReaderForPGESTRING(&fieldReader, ','); - int sectionID = fullReader.ReadField(1) - 1; - LevelEvent_Sets &nextSet = eventdata.sets[static_cast(sectionID)]; - bool customMusic = false; - long music_id; - fullReader.ReadDataLine(CSVDiscard(), - MakeCSVPostProcessor(&nextSet.music_id, [&customMusic](long & value) - { - switch(value) - { - case 0: - value = LevelEvent_Sets::LESet_Nothing; - break; - - case 1: - value = LevelEvent_Sets::LESet_ResetDefault; - break; - - default: - case 2: - customMusic = true; - value = 0; - break; - } - }), - &music_id, - MakeCSVOptional(&nextSet.music_file, "", nullptr, PGEUrlDecodeFunc) - ); - - if(customMusic) - nextSet.music_id = music_id; - }) - ), - MakeCSVIterator(dataReader, '/', [&eventdata, &spawnNpcReaderCurrentIndex](const PGESTRING & nextFieldStr) - { - switch(spawnNpcReaderCurrentIndex) - { - case 0: - if(!SMBX64::IsUInt(nextFieldStr)) - throw std::invalid_argument("Cannot convert field 1 to int."); - - eventdata.sound_id = toLong(nextFieldStr); - spawnNpcReaderCurrentIndex++; - break; - - case 1: - if(!SMBX64::IsUInt(nextFieldStr)) - throw std::invalid_argument("Cannot convert field 2 to int."); - - eventdata.end_game = toLong(nextFieldStr); - spawnNpcReaderCurrentIndex++; - break; - - default: - auto fieldReader = MakeDirectReader(nextFieldStr); - auto fullReader = MakeCSVReaderForPGESTRING(&fieldReader, ','); - LevelEvent_SpawnEffect effect; - fullReader.ReadDataLine(&effect.id, - MakeCSVPostProcessor(&effect.expression_x, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&effect.expression_y, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&effect.expression_sx, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&effect.expression_sy, PGEUrlDecodeFunc), - &effect.gravity, - &effect.fps, - &effect.max_life_time - ); - SMBX38A_Exp2Int(effect.expression_x, effect.x); - SMBX38A_Exp2Int(effect.expression_y, effect.y); - SMBX38A_Exp2Double(effect.expression_sx, effect.speed_x); - SMBX38A_Exp2Double(effect.expression_sy, effect.speed_y); - eventdata.spawn_effects.push_back(effect); - break; - } - }), - // &effects, - MakeCSVIterator(dataReader, '/', [&eventdata](const PGESTRING & nextFieldStr) - { - auto fieldReader = MakeDirectReader(nextFieldStr); - auto fullReader = MakeCSVReaderForPGESTRING(&fieldReader, ','); - LevelEvent_SpawnNPC spawnnpc; - fullReader.ReadDataLine(&spawnnpc.id, - MakeCSVPostProcessor(&spawnnpc.expression_x, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&spawnnpc.expression_y, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&spawnnpc.expression_sx, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&spawnnpc.expression_sy, PGEUrlDecodeFunc), - &spawnnpc.special - ); - SMBX38A_Exp2Int(spawnnpc.expression_x, spawnnpc.x); - SMBX38A_Exp2Int(spawnnpc.expression_y, spawnnpc.y); - SMBX38A_Exp2Double(spawnnpc.expression_sx, spawnnpc.speed_x); - SMBX38A_Exp2Double(spawnnpc.expression_sy, spawnnpc.speed_y); - eventdata.spawn_npc.push_back(spawnnpc); - }), - // &spawn_npcs, - MakeCSVIterator(dataReader, '/', [&eventdata](const PGESTRING & nextFieldStr) - { - auto fieldReader = MakeDirectReader(nextFieldStr); - auto fullReader = MakeCSVReaderForPGESTRING(&fieldReader, ','); - LevelEvent_UpdateVariable updVar; - fullReader.ReadDataLine(MakeCSVPostProcessor(&updVar.name, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&updVar.newval, PGEUrlDecodeFunc) - ); - eventdata.update_variable.push_back(updVar); - }), - // &update_var, - MakeCSVSubReader(dataReader, '/', - MakeCSVSubReader(dataReader, ',', - MakeCSVPostProcessor(&eventdata.trigger, PGEUrlDecodeFunc), - &eventdata.trigger_timer_orig - ), - MakeCSVSubReader(dataReader, ',', - &eventdata.timer_def.enable, - &eventdata.timer_def.count, - &timer_def_interval_raw, - &eventdata.timer_def.count_dir, - &eventdata.timer_def.show), - &eventdata.trigger_api_id, - MakeCSVPostProcessor(&eventdata.trigger_script, PGEUrlDecodeFunc) - ) - ); - eventdata.trigger_timer_unit = PGE_FileLibrary::TimeUnit::FrameOneOf65sec; - eventdata.trigger_timer = PGE_FileLibrary::TimeUnitsCVT(eventdata.trigger_timer_orig, - PGE_FileLibrary::TimeUnit::FrameOneOf65sec, - PGE_FileLibrary::TimeUnit::Decisecond); - eventdata.timer_def.interval = PGE_FileLibrary::TimeUnitsCVT(timer_def_interval_raw, - PGE_FileLibrary::TimeUnit::FrameOneOf65sec, - PGE_FileLibrary::TimeUnit::Millisecond); - eventdata.meta.array_id = FileData.events_array_id++; - FileData.events.push_back(eventdata); - } - else if(identifier == "V") - { - // V|name|value - vardata = CreateLvlVariable("var"); - dataReader.ReadDataLine(CSVDiscard(), - MakeCSVPostProcessor(&vardata.name, PGEUrlDecodeFunc), - &vardata.value /* save variable value as string - because in PGE is planned to have - variables to be universal */ - ); - FileData.variables.push_back(vardata); - } - else if(identifier == "S") - { - // S|name|script - scriptdata = CreateLvlScript("doScript", LevelScript::LANG_TEASCRIPT); - dataReader.ReadDataLine(CSVDiscard(), - MakeCSVPostProcessor(&scriptdata.name, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&scriptdata.script, PGEBase64DecodeFunc) - ); - FileData.scripts.push_back(scriptdata); - } - else if(identifier == "Su") - { - // Su|name|scriptu - scriptdata = CreateLvlScript("doScript", LevelScript::LANG_TEASCRIPT); - dataReader.ReadDataLine(CSVDiscard(), - MakeCSVPostProcessor(&scriptdata.name, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&scriptdata.script, PGEBase64DecodeFuncA) - ); - //Convert to LF - PGE_ReplSTRING(scriptdata.script, "\r\n", "\n"); - FileData.scripts.push_back(scriptdata); - } - else if((identifier == "CB") || (identifier == "CT") || (identifier == "CE") ) - { - // CB|id|data :custom block/background/effect - customcfg = LevelItemSetup38A(); - if(identifier == "CB") - customcfg.type = LevelItemSetup38A::BLOCK; - else if(identifier == "CT") - customcfg.type = LevelItemSetup38A::BGO; - else - customcfg.type = LevelItemSetup38A::EFFECT; - - dataReader.ReadDataLine(CSVDiscard(), - &customcfg.id, - MakeCSVIterator(dataReader, ',', - [&customcfg](const PGESTRING & nextFieldStr) - { - LevelItemSetup38A::Entry e; - SMBX38A_CC_decode(e.key, e.value, nextFieldStr); - customcfg.data.push_back(e); - }) - ); - FileData.custom38A_configs.push_back(customcfg); - } - else if(identifier == "CW") - { - // CW|cdata1|cdata2|...|cdatan :custom sound: same as wls file format - dataReader.IterateDataLine([&FileData](const PGESTRING & nextFieldStr) - { - if(nextFieldStr == "CW") - return; - - auto fieldReader = MakeDirectReader(nextFieldStr); - auto fullReader = MakeCSVReaderForPGESTRING(&fieldReader, ','); - LevelData::MusicOverrider mo; - fullReader.ReadDataLine(&mo.id, - MakeCSVPostProcessor(&mo.fileName, PGEUrlDecodeFunc) - ); - FileData.sound_overrides.push_back(mo); - }); - } - else - dataReader.ReadDataLine(); - }//while is not EOF - } - catch(const std::exception &err) - { - // First we try to extract the line number out of the nested exception. - const std::exception *curErr = &err; - const std::nested_exception *possibleNestedException = dynamic_cast(curErr); - - if(possibleNestedException) - { - try - { - std::rethrow_exception(possibleNestedException->nested_ptr()); - } - catch(const parse_error &parseErr) - { - FileData.meta.ERROR_linenum = static_cast(parseErr.get_line_number()); - } - catch(...) - { - // Do Nothing - } - } - - // Now fill in the error data. - FileData.meta.ReadFileValid = false; - FileData.meta.ERROR_info = "Invalid file format, detected file SMBX-" + fromNum(file_version) + " format\n" - "Caused by: \n" + PGESTRING(exception_to_pretty_string(err).c_str()); - if(!IsEmpty(identifier)) - FileData.meta.ERROR_info += "\n Field type " + identifier; - - // If we were unable to find error line number from the exception, then get the line number from the file reader. - if(FileData.meta.ERROR_linenum == 0) - FileData.meta.ERROR_linenum = in.getCurrentLineNumber(); - - FileData.meta.ERROR_linedata = ""; - return false; - } - catch(...) - { - /* - * This is an attempt to fix crash on Windows 32 bit release assembly, - * and possible, on some other platforms too - */ - // Now fill in the error data. - FileData.meta.ReadFileValid = false; - FileData.meta.ERROR_info = "Invalid file format, detected file SMBX-" + fromNum(file_version) + " format\n" - "Caused by unknown exception\n"; - if(!IsEmpty(identifier)) - FileData.meta.ERROR_info += "\n Field type " + identifier; - // If we were unable to find error line number from the exception, then get the line number from the file reader. - if(FileData.meta.ERROR_linenum == 0) - FileData.meta.ERROR_linenum = in.getCurrentLineNumber(); - FileData.meta.ERROR_linedata = ""; - return false; - } - - LevelAddInternalEvents(FileData); - FileData.CurSection = 0; - FileData.playmusic = 0; - FileData.meta.ReadFileValid = true; - return true; - #else - FileData.meta.ReadFileValid = false; - FileData.meta.ERROR_info = "Unsupported on MSVC2013"; - return false; - #endif -} - - -//********************************************************* -//****************WRITE FILE FORMAT************************ -//********************************************************* - -bool FileFormats::WriteSMBX38ALvlFileF(PGESTRING filePath, LevelData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileOutput file; - - if(!file.open(filePath, false, true, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open file for write"; - return false; - } - - return WriteSMBX38ALvlFile(file, FileData); -} - -bool FileFormats::WriteSMBX38ALvlFileRaw(LevelData &FileData, PGESTRING &rawdata) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextOutput file; - - if(!file.open(&rawdata, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open raw string for write"; - return false; - } - - return WriteSMBX38ALvlFile(file, FileData); -} - -bool FileFormats::WriteSMBX38ALvlFile(PGE_FileFormats_misc::TextOutput &out, LevelData &FileData) -{ - pge_size_t i = 0; - FileData.meta.RecentFormat = LevelData::SMBX38A; - //Count placed stars on this level - FileData.stars = smbx64CountStars(FileData); -#define layerNotDef(lr) ( ((lr) != "Default") ? PGE_URLENC(lr) : "" ) - //======================================================== - //Data type markers: - //A – Level header settings - //P1, P2 – Player spawn points - //M – Section settings - //B – blocks - //T – Background objects - //N – Non-playable characters - //Q – Liquid/Environment boxes - //W – Warp entries - //L – Layers - //E – Events - //V – Local level variables - //S – UTF-8 encoded local level scripts - //Su – ASCII-encoded local level scripts - //-------------------------------------------------------- - //line 1: - // SMBXFile?? - // ??=Version number - out << "SMBXFile" << fromNum(newest_file_format) << "\n"; - //next line: level settings - // A|param1|param2[|param3|param4] - // []=optional - out << "A"; - // param1=the number of stars on this level - out << "|" << fromNum(FileData.stars); - // param2=level title - out << "|" << PGE_URLENC(FileData.LevelName); - - if(!IsEmpty(FileData.open_level_on_fail)) - { - // param3=a filename, when player died, the player will be sent to this level. - out << "|" << PGE_URLENC(FileData.open_level_on_fail); - // param4=normal entrance / to warp [0-WARPMAX] - out << "|" << fromNum(FileData.open_level_on_fail_warpID); - } else { - out << "|||"; - } - //Custom special musics - { - //s1=P-Switch Music Filename[***urlencode!***] - //s2=Stopwatch Music Filename[***urlencode!***] - //s3=Starman Music Filename[***urlencode!***] - //s4=MegaMushroom Music Filename[***urlencode!***] - PGESTRING s[4]; - for(pge_size_t i = 0; i < FileData.music_overrides.size(); i++) - { - LevelData::MusicOverrider &mo = FileData.music_overrides[i]; - if(mo.type == LevelData::MusicOverrider::SPECIAL) - { - if(mo.id < 4) - s[i] = mo.fileName; - } - } - - for(int i = 0; i < 4; i++) - { - if(i > 0) - out << ","; - out << PGE_URLENC(s[i]); - } - } - - out << "\n"; - - //next line: player start points - for(i = 0; i < FileData.players.size(); i++) - { - // P1|x1|y1 - // P2|x2|y2 - PlayerPoint &pl = FileData.players[i]; - out << "P" << fromNum(pl.id); - // x1=first player position x - // x2=second player position x - out << "|" << fromNum(pl.x); - // y1=first player position y - // y2=second player position y - out << "|" << fromNum(pl.y); - out << "\n"; - } - - //next line: section properties - for(i = 0; i < FileData.sections.size(); i++) - { - // M|id|x|y|w|h|b1|b2|b3|b4|b5|b6|music|background|musicfile - LevelSection &sct = FileData.sections[i]; - out << "M"; - // id=[1-SectionMAX] - out << "|" << fromNum(sct.id + 1); - // x=Left size[-left/+right] - out << "|" << fromNum(sct.size_left); - // y=Top size[-down/+up] - out << "|" << fromNum(sct.size_top); - // w=width of the section[if (w < 800) w = 800] - out << "|" << fromNum(sct.size_right - sct.size_left); - // h=height of the section[if (h < 600) h = 600] - out << "|" << fromNum(sct.size_bottom - sct.size_top); - // b1=under water?[0=false !0=true] - out << "|" << fromNum((int)sct.underwater); - // b2=is x-level wrap[0=false !0=true] - out << "|" << fromNum(sct.wrap_h); - // b3=enable off screen exit[0=false !0=true] - out << "|" << fromNum((int)sct.OffScreenEn); - - // b4=no turn back(x)[0=no x-scrolllock 1=scrolllock left 2=scrolllock right] - if((!sct.lock_left_scroll) && (!sct.lock_right_scroll)) - out << "|" << fromNum(0); - else if((sct.lock_left_scroll) && (!sct.lock_right_scroll)) - out << "|" << fromNum(1); - else - out << "|" << fromNum(2); - - // b5=no turn back(y)[0=no y-scrolllock 1=scrolllock up 2=scrolllock down] - if((!sct.lock_up_scroll) && (!sct.lock_down_scroll)) - out << "|" << fromNum(0); - else if((sct.lock_up_scroll) && (!sct.lock_down_scroll)) - out << "|" << fromNum(1); - else - out << "|" << fromNum(2); - - // b6=is y-level wrap[0=false !0=true] - out << "|" << fromNum(sct.wrap_v); - // music=music number[same as smbx1.3] - out << "|" << fromNum(sct.music_id); - // background=background number[same as the filename in 'background2' folder] - out << "|" << fromNum(SMBX38A_mapBGID_To(sct.background)); - // musicfile=custom music file[***urlencode!***] - out << "|" << PGE_URLENC(sct.music_file); - out << "\n"; - } - - //next line: blocks - for(i = 0; i < FileData.blocks.size(); i++) - { - // B|layer[,name]|id[,dx,dy]|x|y|contain|b11[,b12]|b2|[e1,e2,e3,e4]|w|h - LevelBlock &blk = FileData.blocks[i]; - out << "B"; - // layer=layer name["" == "Default"][***urlencode!***] - out << "|" << layerNotDef(blk.layer); - // only if name != "" - // name=block's name - if(!IsEmpty(blk.gfx_name)) - out << "," << PGE_URLENC(blk.gfx_name); - // id=block id - out << "|" << fromNum(blk.id); - if((blk.gfx_dx) > 0 || (blk.gfx_dy > 0)) - { - // dx=graphics extend x - out << "," << fromNum(blk.gfx_dx); - // dy=graphics extend y - out << "," << fromNum(blk.gfx_dy); - } - // x=block position x - out << "|" << fromNum(blk.x); - // y=block position y - out << "|" << fromNum(blk.y); - // contain=containing npc number - // [1001-1000+NPCMAX] npc-id - // [1-999] coin number - // [0] nothing - out << "|" << ((blk.npc_id == 0) ? "" - : fromNum(blk.npc_id <= 0 ? (-1 * blk.npc_id) : (blk.npc_id + 1000)) ); - // b11=slippery[0=false !0=true] - out << "|" << fromNum((int)blk.slippery); - // b12=wing type - // b2=invisible[0=false !0=true] - out << "," << fromNum(blk.motion_ai_id); - out << "|" << fromNum((int)blk.invisible); - // e1=block destory event name[***urlencode!***] - out << "|" << PGE_URLENC(blk.event_destroy); - // e2=block hit event name[***urlencode!***] - out << "," << PGE_URLENC(blk.event_hit); - // e3=no more object in layer event name[***urlencode!***]4 - out << "," << PGE_URLENC(blk.event_emptylayer); - // e4=block onscreen event name[***urlencode!***] - out << "," << PGE_URLENC(blk.event_on_screen); - // w=width - out << "|" << fromNum(blk.autoscale ? (-1 * blk.w) : blk.w); - // h=height - out << "|" << fromNum(blk.h); - out << "\n"; - } - - //next line: backgrounds - for(i = 0; i < FileData.bgo.size(); i++) - { - // T|layer|id|x|y - LevelBGO &bgo = FileData.bgo[i]; - out << "T"; - // layer=layer name["" == "Default"][***urlencode!***] - out << "|" << layerNotDef(bgo.layer); - // id=background id - out << "|" << fromNum(bgo.id); - if((bgo.gfx_dx) > 0 || (bgo.gfx_dy > 0)) - { - // dx=graphics extend x - out << "," << fromNum(bgo.gfx_dx); - // dy=graphics extend y - out << "," << fromNum(bgo.gfx_dy); - } - // x=background position x - out << "|" << fromNum(bgo.x); - // y=background position y - out << "|" << fromNum(bgo.y); - out << "\n"; - } - - //next line: npcs - for(i = 0; i < FileData.npc.size(); i++) - { - LevelNPC &npc = FileData.npc[i]; - //Pre-convert some data into SMBX-38A compatible format - long npcID = (long)npc.id; - long containerType = 0; - long specialData = npc.special_data; - switch(npcID)//Convert npcID and contents ID into container type - { - case 91: - containerType = 1; - break; - case 96: - containerType = 2; - break; - case 283: - containerType = 3; - break; - case 284: - containerType = 4; - break; - case 300: - containerType = 5; - break; - case 347: - containerType = 6; - break; - default: - containerType = 0; - break; - } - if(containerType != 0) - { - //Set NPC-ID of contents as main NPC-ID for this NPC - npcID = npc.contents; - } - - //Convert "Is Boss" flag into special ID - switch(npc.id) - { - case 15: - case 39: - case 86: - if(npc.is_boss) - specialData = (long)npc.is_boss; - break; - default: - break; - } - - //Convert generator type and direction into SMBX-38A Compatible format - long genType_1 = npc.generator_type; - - //Swap "Appear" and "Projectile" types - switch(genType_1) - { - case 0: - genType_1 = 2; - break; - case 2: - genType_1 = 0; - break; - } - - long genType_2 = npc.generator_direct; - long genType = (genType_2 != 0) ? ((4 * genType_1) + genType_2) : 0 ; - // N|layer|id|x|y|b1,b2,b3,b4|sp|e1,e2,e3,e4,e5,e6,e7|a1,a2|c1[,c2,c3,c4,c5,c6,c7]|msg| - out << "N"; - // layer=layer name["" == "Default"][***urlencode!***] - out << "|" << layerNotDef(npc.layer); - //only if name != "" - //name=npc's name - if(!IsEmpty(npc.gfx_name)) - out << "," << PGE_URLENC(npc.gfx_name); - // id=npc id - out << "|" << fromNum(npcID); - if((npc.gfx_dx) > 0 || (npc.gfx_dy > 0)) - { - // dx=graphics extend x - out << "," << fromNum(npc.gfx_dx); - // dy=graphics extend y - out << "," << fromNum(npc.gfx_dy); - } - // x=npc position x - out << "|" << fromNum(npc.x); - // y=npc position y - out << "|" << fromNum(npc.y); - // b1=[1]left [0]random [-1]right - out << "|" << fromNum(-1 * npc.direct); - // b2=friendly npc - out << "," << fromNum((int)npc.friendly); - // b3=don't move npc - out << "," << fromNum((int)npc.nomove); - // b4=[1=npc91][2=npc96][3=npc283][4=npc284][5=npc300] - out << "," << fromNum(containerType); - // sp=special option - out << "|" << fromNum(specialData); - // [***urlencode!***] - // e1=death event - out << "|" << PGE_URLENC(npc.event_die); - // e2=talk event - out << "," << PGE_URLENC(npc.event_talk); - // e3=activate event - out << "," << PGE_URLENC(npc.event_activate); - // e4=no more object in layer event - out << "," << PGE_URLENC(npc.event_emptylayer); - // e5=grabed event - out << "," << PGE_URLENC(npc.event_grab); - // e6=next frame event - out << "," << PGE_URLENC(npc.event_nextframe); - // e7=touch event - out << "," << PGE_URLENC(npc.event_touch); - // a1=layer name to attach - out << "|" << PGE_URLENC(npc.attach_layer); - // a2=variable name to send - out << "," << PGE_URLENC(npc.send_id_to_variable); - // c1=generator enable - out << "|" << fromNum((int)npc.generator); - - // [if c1!=0] - if(npc.generator) - { - // c2=generator period[1 frame] - //Convert deciseconds into frames with rounding - SMBX38A_RestoreOrigTime(npc.generator_period_orig, (long)npc.generator_period, PGE_FileLibrary::TimeUnit::Decisecond); - out << "," << fromNum(npc.generator_period_orig); - // c3=generator effect - // c3-1 [1=warp][0=projective][4=no effect] - // c3-2 [0=center][1=up][2=left][3=down][4=right][9=up+left][10=left+down][11=down+right][12=right+up] - // if (c3-2)!=0 - // c3=4*(c3-1)+(c3-2) - // else - // c3=0 - out << "," << fromNum(genType); - // c4=generator direction[angle][when c3=0] - out << "," << fromNum(npc.generator_custom_angle); - // c5=batch[when c3=0][MAX=32] - out << "," << fromNum(npc.generator_branches); - // c6=angle range[when c3=0] - out << "," << fromNum(npc.generator_angle_range); - // c7=speed[when c3=0][float] - out << "," << fromNum(npc.generator_initial_speed); - } - - // msg=message by this npc talkative[***urlencode!***] - out << "|" << PGE_URLENC(npc.msg); - out << "\n"; - } - - //next line: warps - for(i = 0; i < FileData.doors.size(); i++) - { - LevelDoor &door = FileData.doors[i]; - - if(((!door.lvl_o) && (!door.lvl_i)) || ((door.lvl_o) && (!door.lvl_i))) - if(!door.isSetIn) continue; // Skip broken warp entry - - if(((!door.lvl_o) && (!door.lvl_i)) || ((door.lvl_i))) - if(!door.isSetOut) continue; // Skip broken warp entry - - int oDirect = door.odirect; - - switch(oDirect)//Convert from SMBX64/PGE-X into SMBX-38A compatible form - { - case LevelDoor::EXIT_UP: - oDirect = 1; - break; - - case LevelDoor::EXIT_LEFT: - oDirect = 2; - break; - - case LevelDoor::EXIT_DOWN: - oDirect = 3; - break; - - case LevelDoor::EXIT_RIGHT: - oDirect = 4; - break; - } - - // W|layer|x|y|ex|ey|type|enterd|exitd|sn,msg,hide|locked,noyoshi,canpick,bomb,hidef,anpc,mini,size|lik|liid|noexit|wx|wy|le|we - out << "W"; - // layer=layer name["" == "Default"][***urlencode!***] - out << "|" << layerNotDef(door.layer); - // x=entrance position x - out << "|" << fromNum(door.ix); - // y=entrance postion y - out << "|" << fromNum(door.iy); - // ex=exit position x - out << "|" << fromNum(door.ox); - // ey=exit position y - out << "|" << fromNum(door.oy); - // type=[1=pipe][2=door][0=instant] - { - //type%100=[0=instant][1=pipe][2=door] - int type = door.type; - //type/100=[0=none][1=Scroll][2=Fade] - type += door.transition_effect * 100; - out << "|" << fromNum(type); - } - // enterd=entrance direction[1=up 2=left 3=down 4=right] - out << "|" << fromNum(door.idirect); - // exitd=exit direction[1=up 2=left 3=down 4=right] - out << "|" << fromNum(oDirect); - // sn=need stars for enter - out << "|" << fromNum(door.stars); - // msg=a message when you have not enough stars - out << "," << PGE_URLENC(door.stars_msg); - // hide=hide the star number in this warp - out << "," << fromNum((int)door.star_num_hide); - // locked=locked - out << "|" << fromNum((int)door.locked); - // noyoshi=no yoshi - out << "," << fromNum((int)door.novehicles); - // canpick=allow npc - out << "," << fromNum((int)door.allownpc); - // bomb=need a bomb - out << "," << fromNum((int)door.need_a_bomb); - // hide=hide the entry scene - out << "," << fromNum((int)door.hide_entering_scene); - // anpc=allow npc interlevel - out << "," << fromNum((int)door.allownpc_interlevel); - // mini=Mini-Only - out << "," << fromNum((int)door.special_state_required); - // size=Warp Size(pixel) - out << "," << fromNum(door.length_i); - if(door.two_way || door.cannon_exit) - { - // ts = two-way - out << "," << fromNum((int)door.two_way); - // cannon = Pipe Cannon Force - out << "," << fromNum(door.cannon_exit ? door.cannon_exit_speed : 0.0); - } - // lik=warp to level[***urlencode!***] - out << "|" << PGE_URLENC(door.lname); - // liid=normal enterance / to warp[0-WARPMAX] - out << "|" << fromNum(door.warpto); - // noexit=level entrance - out << "|" << fromNum((int)door.lvl_i); - // wx=warp to x on world map - out << "|" << fromNum(door.world_x); - // wy=warp to y on world map - out << "|" << fromNum(door.world_y); - // le=level exit - out << "|" << fromNum((int)door.lvl_o); - // we=warp event[***urlencode!***] - out << "|" << PGE_URLENC(door.event_enter); - out << "\n"; - } - - //next line: waters - for(i = 0; i < FileData.physez.size(); i++) - { - LevelPhysEnv &pez = FileData.physez[i]; - /*TRIVIA: It is NOT a PEZ candy brand, just "Physical Environment Zone" :-P*/ - // Q|layer|x|y|w|h|b1,b2,b3,b4,b5|event - out << "Q"; - // layer=layer name["" == "Default"][***urlencode!***] - out << "|" << layerNotDef(pez.layer); - // x=position x - out << "|" << fromNum(pez.x); - // y=position y - out << "|" << fromNum(pez.y); - // w=width - out << "|" << fromNum(pez.w); - // h=height - out << "|" << fromNum(pez.h); - // b1=liquid type - // 01-Water[friction=0.5] - // 02-Quicksand[friction=0.1] - // 03-Custom Water - // 04-Gravitational Field - // 05-Event Once - // 06-Event Always - // 07-NPC Event Once - // 08-NPC Event Always - // 09-Click Event - // 10-Collision Script - // 11-Click Script - // 12-Collision Event - // 13-Air - out << "|" << fromNum((pez.env_type + 1)); - // b2=friction - out << "," << fromNum(pez.friction); - // b3=Acceleration Direction - out << "," << fromNum(pez.accel_direct); - // b4=Acceleration - out << "," << fromNum(pez.accel); - // b5=Maximum Velocity - out << "," << fromNum(pez.max_velocity); - // event=touch event - out << "|" << PGE_URLENC(pez.touch_event); - out << "\n"; - } - - for(i = 0; i < FileData.layers.size(); i++) - { - LevelLayer &lyr = FileData.layers[i]; - //next line: layers - // L|name|status - out << "L"; - // name=layer name[***urlencode!***] - out << "|" << PGE_URLENC(lyr.name); - // status=is vizible layer - out << "|" << fromNum((int)(!lyr.hidden)); - out << "\n"; - } - - //next line: events - for(i = 0; i < FileData.events.size(); i++) - { - LevelSMBX64Event &evt = FileData.events[i]; - // E|name|msg|ea|el|elm|epy|eps|eef|ecn|evc|ene - out << "E"; - // name=event name[***urlencode!***] - out << "|" << PGE_URLENC(evt.name); - // msg=show message after start event[***urlencode!***] - out << "|" << PGE_URLENC(evt.msg); - // ea=val,syntax - // val=[0=not auto start][1=auto start when level start][2=auto start when match all condition][3=start when called and match all condidtion] - out << "|" << fromNum(evt.autostart); - // syntax=condidtion expression[***urlencode!***] - out << "," << PGE_URLENC(evt.autostart_condition); - // el=b/s1,s2...sn/h1,h2...hn/t1,t2...tn - // b=no smoke[0=false !0=true] - out << "|" << fromNum((int)evt.nosmoke); - // [***urlencode!***] - out << "/"; - - // s(n)=show layer - for(pge_size_t j = 0; j < evt.layers_show.size(); j++) - { - if(j > 0) out << ","; - - out << PGE_URLENC(evt.layers_show[j]); - } - - out << "/"; - - // l(n)=hide layer - for(pge_size_t j = 0; j < evt.layers_hide.size(); j++) - { - if(j > 0) out << ","; - - out << PGE_URLENC(evt.layers_hide[j]); - } - - out << "/"; - - // t(n)=toggle layer - for(pge_size_t j = 0; j < evt.layers_toggle.size(); j++) - { - if(j > 0) out << ","; - - out << PGE_URLENC(evt.layers_toggle[j]); - } - - out << "|"; - - // elm=elm1/elm2...elmn - for(pge_size_t j = 0; j < evt.moving_layers.size(); j++) - { - if(j > 0) out << "/"; - - // elm(n)=layername,horizontal syntax,vertical syntax,way - // layername=layer name for movement[***urlencode!***] - LevelEvent_MoveLayer &mvl = evt.moving_layers[j]; - //Convert all floats into strings if expression fields are empty - PGESTRING expression_x = mvl.expression_x; - PGESTRING expression_y = mvl.expression_y; - SMBX38A_Num2Exp_URLEN(mvl.speed_x, expression_x); - SMBX38A_Num2Exp_URLEN(mvl.speed_y, expression_y); - out << PGE_URLENC(mvl.name); - // horizontal syntax,vertical syntax[***urlencode!***][syntax] - out << "," << expression_x; - out << "," << expression_y; - // way=[0=by speed][1=by Coordinate] - out << "," << fromNum(mvl.way); - } - - out << "|"; - // epy=b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12 - // b1=enable player controls - out << fromNum(evt.ctrls_enable); - // b2=drop - out << "," << fromNum(evt.ctrl_drop); - // b3=alt run - out << "," << fromNum(evt.ctrl_altrun); - // b4=run - out << "," << fromNum(evt.ctrl_run); - // b5=jump - out << "," << fromNum(evt.ctrl_jump); - // b6=alt jump - out << "," << fromNum(evt.ctrl_altjump); - // b7=up - out << "," << fromNum(evt.ctrl_up); - // b8=down - out << "," << fromNum(evt.ctrl_down); - // b9=left - out << "," << fromNum(evt.ctrl_left); - // b10=right - out << "," << fromNum(evt.ctrl_right); - // b11=start - out << "," << fromNum(evt.ctrl_start); - // b12=lock keyboard - out << "," << fromNum(evt.ctrl_lock_keyboard); - out << "|"; - // eps=esection/ebackground/emusic - // esection=es1:es2...esn - // ebackground=eb1:eb2...ebn - // emusic=em1:em2...emn - bool size_set_added = false; - - for(pge_size_t j = 0; j < evt.sets.size(); j++) - { - long section_pos = evt.sets[j].position_left; - switch(section_pos) - { - case -1: - continue; - case -2: - section_pos = 1; - break; - default: - section_pos = 2; - break; - } - //Convert floats into expressions if there are empty - PGESTRING expression_x = evt.sets[j].expression_pos_x; - PGESTRING expression_y = evt.sets[j].expression_pos_y; - PGESTRING expression_w = evt.sets[j].expression_pos_w; - PGESTRING expression_h = evt.sets[j].expression_pos_h; - PGESTRING expression_as_x = evt.sets[j].expression_autoscrool_x; - PGESTRING expression_as_y = evt.sets[j].expression_autoscrool_y; - - if(section_pos >= 2) - { - SMBX38A_Num2Exp_URLEN(evt.sets[j].position_left, expression_x); - SMBX38A_Num2Exp_URLEN(evt.sets[j].position_top, expression_y); - SMBX38A_Num2Exp_URLEN(evt.sets[j].position_right - evt.sets[j].position_left, expression_w); - SMBX38A_Num2Exp_URLEN(evt.sets[j].position_bottom - evt.sets[j].position_top, expression_h); - } - - if(evt.sets[j].autoscrol) - { - SMBX38A_Num2Exp_URLEN(evt.sets[j].autoscrol_x, expression_as_x); - SMBX38A_Num2Exp_URLEN(evt.sets[j].autoscrol_y, expression_as_y); - } - else - { - expression_as_x = PGE_URLENC(expression_as_x); - expression_as_y = PGE_URLENC(expression_as_y); - } - - // es=id,x,y,w,h,auto,sx,sy - if(size_set_added) out << ":"; - - size_set_added = true; - // id=section id - out << fromNum(evt.sets[j].id + 1); - // stype=[0=don't change][1=default][2=custom] - out << "," << fromNum(section_pos); - // x=left x coordinates for section [id][***urlencode!***][syntax] - out << "," << expression_x; - // y=top y coordinates for section [id][***urlencode!***][syntax] - out << "," << expression_y; - // w=width for section [id][***urlencode!***][syntax] - out << "," << expression_w; - // h=height for section [id][***urlencode!***][syntax] - out << "," << expression_h; - // auto=enable autoscroll controls[0=false !0=tru - out << "," << fromNum((int)evt.sets[j].autoscrol); - // sx=move screen horizontal syntax[***urlencode!***][syntax] - out << "," << expression_as_x; - // sy=move screen vertical syntax[***urlencode!***][syntax] - out << "," << expression_as_y; - } - - out << "/"; - bool bg_set_added = false; - - for(pge_size_t j = 0; j < evt.sets.size(); j++) - { - long section_bg = evt.sets[j].background_id; - switch(section_bg) - { - case -1: - continue; - case -2: - section_bg = 1; - break; - default: - section_bg = 2; - break; - } - // eb=id,btype,backgroundid - if(bg_set_added) out << ":"; - - bg_set_added = true; - // id=section id - out << fromNum(evt.sets[j].id + 1); - // btype=[0=don't change][1=default][2=custom] - out << "," << fromNum(section_bg); - // backgroundid=[when btype=2]custom background id - out << "," << fromNum(evt.sets[j].background_id >= 0 ? SMBX38A_mapBGID_To(evt.sets[j].background_id) : 0); - } - - out << "/"; - bool muz_set_added = false; - for(pge_size_t j = 0; j < evt.sets.size(); j++) - { - long section_muz = evt.sets[j].music_id; - switch(section_muz) - { - case -1: - continue; - case -2: - section_muz = 1; - break; - default: - section_muz = 2; - break; - } - // em=id,mtype,musicid,customfile - if(muz_set_added) - out << ":"; - muz_set_added = true; - // id=section id - out << fromNum(evt.sets[j].id + 1); - // mtype=[0=don't change][1=default][2=custom] - out << "," << fromNum(section_muz); - // musicid=[when mtype=2]custom music id - out << "," << fromNum(evt.sets[j].music_id >= 0 ? evt.sets[j].music_id : 0); - // customfile=[when mtype=3]custom music file name[***urlencode!***] - out << "," << PGE_URLENC(evt.sets[j].music_file); - } - - out << "|"; - // eef=sound/endgame/ce1/ce2...cen - // sound=play sound number - out << fromNum(evt.sound_id); - // endgame=[0=none][1=bowser defeat] - out << "/" << fromNum(evt.end_game); - - for(pge_size_t j = 0; j < evt.spawn_effects.size(); j++) - { - LevelEvent_SpawnEffect &eff = evt.spawn_effects[j]; - //if(j<(evt.spawn_effects.size()-1)) - out << "/"; - //Convert floats into expressions if there are empty - PGESTRING expression_x = eff.expression_x; - PGESTRING expression_y = eff.expression_y; - PGESTRING expression_sx = eff.expression_sx; - PGESTRING expression_sy = eff.expression_sy; - SMBX38A_Num2Exp_URLEN(eff.x, expression_x); - SMBX38A_Num2Exp_URLEN(eff.y, expression_y); - SMBX38A_Num2Exp_URLEN(eff.speed_x, expression_sx); - SMBX38A_Num2Exp_URLEN(eff.speed_y, expression_sy); - // ce(n)=id,x,y,sx,sy,grv,fsp,life - // id=effect id - out << fromNum(eff.id); - // x=effect position x[***urlencode!***][syntax] - out << "," << expression_x; - // y=effect position y[***urlencode!***][syntax] - out << "," << expression_y; - // sx=effect horizontal speed[***urlencode!***][syntax] - out << "," << expression_sx; - // sy=effect vertical speed[***urlencode!***][syntax] - out << "," << expression_sy; - // grv=to decide whether the effects are affected by gravity[0=false !0=true] - out << "," << fromNum((int)eff.gravity); - // fsp=frame speed of effect generated - out << "," << fromNum(eff.fps); - // life=effect existed over this time will be destroyed. - out << "," << fromNum(eff.max_life_time); - } - - out << "|"; - - // ecn=cn1/cn2...cnn - for(pge_size_t j = 0; j < evt.spawn_npc.size(); j++) - { - LevelEvent_SpawnNPC &snpc = evt.spawn_npc[j]; - //Convert floats into expressions if there are empty - PGESTRING expression_x = snpc.expression_x; - PGESTRING expression_y = snpc.expression_y; - PGESTRING expression_sx = snpc.expression_sx; - PGESTRING expression_sy = snpc.expression_sy; - SMBX38A_Num2Exp_URLEN(snpc.x, expression_x); - SMBX38A_Num2Exp_URLEN(snpc.y, expression_y); - SMBX38A_Num2Exp_URLEN(snpc.speed_x, expression_sx); - SMBX38A_Num2Exp_URLEN(snpc.speed_y, expression_sy); - // cn(n)=id,x,y,sx,sy,sp - if(j > 0) out << "/"; - // id=npc id - out << fromNum(snpc.id); - // x=npc position x[***urlencode!***][syntax] - out << "," << expression_x; - // y=npc position y[***urlencode!***][syntax] - out << "," << expression_y; - // sx=npc horizontal speed[***urlencode!***][syntax] - out << "," << expression_sx; - // sy=npc vertical speed[***urlencode!***][syntax] - out << "," << expression_sy; - // sp=advanced settings of generated npc - out << "," << fromNum(snpc.special); - } - - out << "|"; - - // evc=vc1/vc2...vcn - for(pge_size_t j = 0; j < evt.update_variable.size(); j++) - { - LevelEvent_UpdateVariable &uvar = evt.update_variable[j]; - - if(j > 0) - out << "/"; - - // vc(n)=name,newvalue - out << PGE_URLENC(uvar.name); - // name=variable name[***urlencode!***] - out << "," << PGE_URLENC(uvar.newval); - // newvalue=new value[***urlencode!***][syntax] - } - - out << "|"; - // ene=nextevent/timer/apievent/scriptname - // nextevent=name,delay - // name=trigger event name[***urlencode!***] - out << PGE_URLENC(evt.trigger); - // delay=trigger delay[1 frame] - SMBX38A_RestoreOrigTime(evt.trigger_timer_orig, evt.trigger_timer, PGE_FileLibrary::TimeUnit::Decisecond); - out << "," << fromNum(evt.trigger_timer_orig); - // timer=enable,count,interval,type,show - // enable=enable the game timer controlling[0=false !0=true] - out << "/" << fromNum((int)evt.timer_def.enable); - // count=set the time left of the game timer - out << "," << fromNum(evt.timer_def.count); - // interval=set the time count interval of the game timer - out << "," << fromNum(PGE_FileLibrary::TimeUnitsCVT(evt.timer_def.interval, - PGE_FileLibrary::TimeUnit::Millisecond, - PGE_FileLibrary::TimeUnit::FrameOneOf65sec)); - // type=to choose the way timer counts[0=counting down][1=counting up] - out << "," << fromNum(evt.timer_def.count_dir); - // show=to choose whether the game timer is showed in hud[0=false !0=true] - out << "," << fromNum(evt.timer_def.show); - // apievent=the id of apievent - out << "/" << fromNum(evt.trigger_api_id); - // scriptname=script name[***urlencode!***] - out << "/" << PGE_URLENC(evt.trigger_script); - out << "\n"; - } - - //next line: variables - for(LevelVariable &var : FileData.variables) - { - // V|name|value - out << "V"; - // name=variable name[***urlencode!***] - out << "|" << PGE_URLENC(var.name); - - // value=initial value of the variable - if(!SMBX64::IsSInt(var.value))//if is not signed integer, set value as zero - out << "|" << fromNum(0); - else - out << "|" << var.value; - - out << "\n"; - } - - //next line: scripts - for(LevelScript &script : FileData.scripts) - { - // S|name|script - out << "S"; - // Su|name|scriptu - // name=name of script[***urlencode!***] - out << "|" << PGE_URLENC(script.name); - // script=script[***base64encode!***][utf-8] - PGESTRING scriptT = script.script; - - /* ********** Disabled appending "\n" until 38A will fix an inability to ignore empty lines in scripts ********** */ - //if(scriptT.size() > 0 && (PGEGetChar(scriptT[scriptT.size() - 1]) != '\n')) - // scriptT.append("\n"); - - //Convert into CRLF - PGE_ReplSTRING(scriptT, "\n", "\r\n"); - out << "|" << PGE_BASE64ENC_nopad(scriptT);//"=" ending makes SMBX-38A fail to interpret scripts - // scriptu=script[***base64encode!***][ASCII] - out << "\n"; - } - - //next line: Custom block - for(LevelItemSetup38A &is : FileData.custom38A_configs) - { - // V|name|value - switch(is.type) - { - case LevelItemSetup38A::BLOCK: - out << "CB"; - break; - case LevelItemSetup38A::BGO: - out << "CT"; - break; - case LevelItemSetup38A::EFFECT: - out << "CE"; - break; - case LevelItemSetup38A::UNKNOWN: - default: - out << "CUnk"; - break; - } - // id = object id - out << "|" << fromNum(is.id); - - for(pge_size_t j = 0; j < is.data.size(); j++) - { - LevelItemSetup38A::Entry &e = is.data[j]; - out << ((j == 0) ? "|" : ","); - out << SMBX38A_CC_encode(e.key, e.value); - } - out << "\n"; - } - - if(FileData.sound_overrides.size() > 0) - { - out << "CW"; - for(LevelData::MusicOverrider &mo : FileData.sound_overrides) - { - out << "|" << fromNum(mo.id) << "," << PGE_URLENC(mo.fileName); - } - out << "\n"; - } - - return true; -} diff --git a/LunaDll/libs/PGE_File_Formats/file_rw_lvl_38a_old.cpp b/LunaDll/libs/PGE_File_Formats/file_rw_lvl_38a_old.cpp deleted file mode 100644 index 999a60859..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_rw_lvl_38a_old.cpp +++ /dev/null @@ -1,2430 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "pge_file_lib_sys.h" -#include "file_formats.h" -#include "file_strlist.h" - -#include "smbx38a_private.h" - -void old38a_SplitCSVStr(PGESTRINGList &dst, PGESTRING &Src) -{ - dst.clear(); - for(pge_size_t i = 0; i < Src.size();) - { - PGESTRING Buffer = ""; - PGEChar cur = ' '; - do - { - cur = Src[static_cast(i++)]; - if(cur != ',') Buffer.push_back(cur); - } - while((i < Src.size()) && (cur != ',')); - - dst.push_back(Buffer); - } -} - -#define SMBX38A_SplitSubLine(dst, src) SMBX38A_SplitLine(dst, src, '/') -void SMBX38A_SplitLine(PGESTRINGList &dst, PGESTRING &Src, char sep = '|') -{ - dst.clear(); - - for(pge_size_t i = 0; i < Src.size();) - { - PGESTRING Buffer = ""; - PGEChar cur = ' '; - do - { - cur = Src[i++]; - - if(cur != sep) Buffer.push_back(cur); - } - while((i < Src.size()) && (cur != sep)); - dst.push_back(Buffer); - } -} - -bool FileFormats::ReadSMBX38ALvlFile_OLD(PGE_FileFormats_misc::TextInput &in, LevelData &FileData) -{ - SMBX38A_FileBegin(); - PGESTRING filePath = in.getFilePath(); - errorString.clear(); - CreateLevelData(FileData); - FileData.meta.RecentFormat = LevelData::SMBX38A; - FileData.LevelName = ""; - FileData.stars = 0; - FileData.CurSection = 0; - FileData.playmusic = 0; - //Enable strict mode for SMBX LVL file format - FileData.meta.smbx64strict = false; - //Begin all ArrayID's here; - FileData.blocks_array_id = 1; - FileData.bgo_array_id = 1; - FileData.npc_array_id = 1; - FileData.doors_array_id = 1; - FileData.physenv_array_id = 1; - FileData.layers_array_id = 1; - FileData.events_array_id = 1; - FileData.layers.clear(); - FileData.events.clear(); - LevelSection section; - PlayerPoint playerdata; - LevelBlock blockdata; - LevelBGO bgodata; - LevelNPC npcdata; - LevelDoor doordata; - LevelPhysEnv waters; - LevelLayer layerdata; - LevelSMBX64Event eventdata; - //LevelEvent_Sets event_sets; - LevelVariable vardata; - LevelScript scriptdata; - - //Add path data - if(!IsEmpty(filePath)) - { - PGE_FileFormats_misc::FileInfo in_1(filePath); - FileData.meta.filename = in_1.basename(); - FileData.meta.path = in_1.dirpath(); - } - - in.seek(0, PGE_FileFormats_misc::TextFileInput::begin); - PGESTRINGList currentLine; - nextLine(); //Read first line - - if(!PGE_StartsWith(line, "SMBXFile")) //File format number - goto badfile; - else file_format = 65; - - while(!in.eof()) - { - nextLine(); //Read second Line - SMBX38A_SplitLine(currentLine, line); - - if(currentLine.size() == 0) - continue; - - if(currentLine[0] == "A") //Level settings - { - for(int i = 1; i < static_cast(currentLine.size()); i++) - { - PGESTRING &cLine = currentLine[i]; - - switch(i) - { - case 1://Number of stars - { - if(!SMBX64::IsUInt(cLine)) - goto badfile; - else FileData.stars = toInt(cLine); - } - break; - - case 2://Level title (URL Encoded!) - { - FileData.LevelName = PGE_URLDEC(cLine); - } - break; - - //param3=a filename, when player died, the player will be sent to this level. - case 3: - { - FileData.open_level_on_fail = PGE_URLDEC(cLine); - } - break; - - //param4=normal entrance / to warp [0-WARPMAX] - case 4: - { - if(!SMBX64::IsUInt(cLine)) - goto badfile; - else - FileData.open_level_on_fail_warpID = toUInt(cLine); - } - break; - } - } - } - else if(currentLine[0] == "P1") //Player 1 point - { - playerdata = CreateLvlPlayerPoint(1); - - for(int i = 1; i < static_cast(currentLine.size()); i++) - { - PGESTRING &cLine = currentLine[i]; - - switch(i) - { - case 1://Pos X - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else - playerdata.x = static_cast(toFloat(cLine)); - } - break; - - case 2://Pos Y - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else playerdata.y = static_cast(toFloat(cLine)); - } - break; - } - } - - FileData.players.push_back(playerdata); - } - else if(currentLine[0] == "P2") //Player 2 point - { - playerdata = CreateLvlPlayerPoint(2); - - for(int i = 1; i < static_cast(currentLine.size()); i++) - { - PGESTRING &cLine = currentLine[i]; - - switch(i) - { - case 1://Pos X - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else - playerdata.x = static_cast(toFloat(cLine)); - } - break; - - case 2://Pos Y - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else - playerdata.y = static_cast(toFloat(cLine)); - } - break; - } - } - - FileData.players.push_back(playerdata); - } - else if(currentLine[0] == "M") //Section - { - //M|id|x|y|w|h|b1|b2|b3|b4|b5|b6|music|background|musicfile - section = CreateLvlSection(); - double x = 0.0, y = 0.0, w = 0.0, h = 0.0; - - for(int i = 1; i < static_cast(currentLine.size()); i++) - { - PGESTRING &cLine = currentLine[i]; - - switch(i) - { - //"id=[1-SectionMAX] - case 1: - { - if(!SMBX64::IsUInt(cLine)) - goto badfile; - else section.id = (toInt(cLine) - 1); - - if(section.id < 0) section.id = 0; - } - break; - - //"x=Left size[-left/+right] - case 2: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else x = toDouble(cLine); - } - break; - - //"y=Top size[-down/+up] - case 3: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else y = toDouble(cLine); - } - break; - - //"w=width of the section[if (w < 800) w = 800] - case 4: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else w = toDouble(cLine); - - if((w < 800.0) && (w != 0.0)) w = 800.0; - } - break; - - //"h=height of the section[if (h < 600) h = 600] - case 5: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else h = toDouble(cLine); - - if((h < 600.0) && (h != 0.0)) h = 600.0; - } - break; - - //"b1=under water?[0=false !0=true] - case 6: - { - section.underwater = (cLine != "0"); - } - break; - - //"b2=is x-level wrap[0=false !0=true] - case 7: - { - section.wrap_h = (cLine != "0"); - } - break; - - //"b3=enable off screen exit[0=false !0=true] - case 8: - { - section.OffScreenEn = (cLine != "0"); - } - break; - - //"b4=no turn back(x)[0=no x-scrolllock 1=scrolllock left 2=scrolllock right] - case 9: - { - section.lock_left_scroll = (cLine == "1"); - section.lock_right_scroll = (cLine == "2"); - } - break; - - //"b5=no turn back(y)[0=no y-scrolllock 1=scrolllock up 2=scrolllock down] - case 10: - { - section.lock_up_scroll = (cLine == "1"); - section.lock_down_scroll = (cLine == "2"); - } - break; - - //"b6=is y-level wrap[0=false !0=true] - case 11: - { - section.wrap_v = (cLine != "0"); - } - break; - - //"music=music number[same as smbx1.3] - case 12: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else section.music_id = static_cast(toDouble(cLine)); - } - break; - - //"background=background number[same as the filename in 'background2' folder] - case 13: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else section.background = static_cast(toFloat(cLine)); - } - break; - - //"musicfile=custom music file[***urlencode!***] - case 14: - { - section.music_file = PGE_URLDEC(cLine); - } - break; - } - } - - SMBX38A_mapBGID_From(section.background);//Convert into SMBX64 ID set - section.size_left = static_cast(round(x)); - section.size_top = static_cast(round(y)); - section.size_right = static_cast(round(x + w)); - section.size_bottom = static_cast(round(y + h)); - //Very important data! I'ts a camera position in the editor! - section.PositionX = section.size_left - 10; - section.PositionY = section.size_top - 10; - - if(section.id < static_cast(FileData.sections.size())) - FileData.sections[section.id] = section; //Replace if already exists - else - FileData.sections.push_back(section); //Add Section in main array - } - else if(currentLine[0] == "B") //Blocks - { - //B|layer|id|x|y|contain|b1|b2|e1,e2,e3|w|h - blockdata = CreateLvlBlock(); - - for(int i = 1; i < static_cast(currentLine.size()); i++) - { - PGESTRING &cLine = currentLine[i]; - - switch(i) - { - // layer=layer name["" == "Default"][***urlencode!***] - case 1: - { - blockdata.layer = (IsEmpty(cLine) ? "Default" : PGE_URLDEC(cLine)); - } - break; - - // id=block id - case 2: - { - if(!SMBX64::IsUInt(cLine)) - goto badfile; - else blockdata.id = toULong(cLine); - } - break; - - // x=block position x - case 3: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else blockdata.x = static_cast(round(toDouble(cLine))); - } - break; - - // y=block position y - case 4: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else blockdata.y = static_cast(round(toDouble(cLine))); - } - break; - - // contain=containing npc number - // [1001-1000+NPCMAX] npc-id - // [1-999] coin number - // [0] nothing - case 5: - { - if(!SMBX64::IsUInt(cLine)) - goto badfile; - else - { - long npcid = toInt(cLine); - blockdata.npc_id = ((npcid < 1000) ? -1 * npcid : npcid - 1000); - } - } - break; - - // b1=slippery[0=false !0=true] - case 6: - { - blockdata.slippery = (cLine != "0"); - } - break; - - // b2=invisible[0=false !0=true] - case 7: - { - blockdata.invisible = (cLine != "0"); - } - break; - - case 8: - { - PGESTRINGList bevents; - old38a_SplitCSVStr(bevents, cLine); - - for(int j = 0; j < static_cast(bevents.size()); j++) - { - PGESTRING &dLine = bevents[j]; - - switch(j) - { - // e1=block destory event name[***urlencode!***] - case 0: - blockdata.event_destroy = PGE_URLDEC(dLine); - break; - - // e2=block hit event name[***urlencode!***] - case 1: - blockdata.event_hit = PGE_URLDEC(dLine); - break; - - // e3=no more object in layer event name[***urlencode!***]4 - case 2: - blockdata.event_emptylayer = PGE_URLDEC(dLine); - break; - } - } - } - break; - - // w=width - case 9: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else blockdata.w = (long)round(toDouble(cLine)); - } - break; - - // h=height - case 10: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else blockdata.h = (long)round(toDouble(cLine)); - } - break; - } - } - - blockdata.meta.array_id = FileData.blocks_array_id++; - FileData.blocks.push_back(blockdata); - } - else if(currentLine[0] == "T") //BGOs - { - //T|layer|id|x|y - bgodata = CreateLvlBgo(); - - for(int i = 1; i < (signed)currentLine.size(); i++) - { - PGESTRING &cLine = currentLine[i]; - - switch(i) - { - // layer=layer name["" == "Default"][***urlencode!***] - case 1: - { - bgodata.layer = (cLine == "" ? "Default" : PGE_URLDEC(cLine)); - } - break; - - // id=background id - case 2: - { - if(!SMBX64::IsUInt(cLine)) - goto badfile; - else bgodata.id = toULong(cLine); - } - break; - - // x=background position x - case 3: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else bgodata.x = (long)round(toDouble(cLine)); - } - break; - - // y=background position y - case 4: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else bgodata.y = (long)round(toDouble(cLine)); - } - break; - } - } - - bgodata.meta.array_id = FileData.bgo_array_id++; - FileData.bgo.push_back(bgodata); - } - else if(currentLine[0] == "N") //NPC - { - npcdata = CreateLvlNpc(); - - for(int i = 1; i < (signed)currentLine.size(); i++) - { - //next line: npcs - //N|layer|id|x|y|b1,b2,b3,b4|sp|e1,e2,e3,e4,e5,e6,e7|a1,a2|c1[,c2,c3,c4,c5,c6,c7]|msg| - PGESTRING &cLine = currentLine[i]; - - switch(i) - { - //layer=layer name["" == "Default"][***urlencode!***] - case 1: - { - npcdata.layer = (cLine == "" ? "Default" : PGE_URLDEC(cLine)); - } - break; - - //id=npc id - case 2: - { - if(!SMBX64::IsUInt(cLine)) - goto badfile; - else npcdata.id = static_cast(toInt(cLine)); - } - break; - - //x=npc position x - case 3: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else npcdata.x = static_cast(std::round(toFloat(cLine))); - } - break; - - //y=npc position y - case 4: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else npcdata.y = static_cast(std::round(toFloat(cLine))); - } - break; - - //b1=[-1]left [0]random [1]right - //b2=friendly npc - //b3=don't move npc - //b4=[1=npc91][2=npc96][3=npc283][4=npc284][5=npc300] - case 5: - { - PGESTRINGList physparams; - old38a_SplitCSVStr(physparams, cLine); - - for(int j = 0; j < (signed)physparams.size(); j++) - { - PGESTRING &dLine = physparams[j]; - - switch(j) - { - //b1=[1]left [0]random [-1]right - case 0: - if(!SMBX64::IsSInt(dLine)) - goto badfile; - else npcdata.direct = -1 * toInt(dLine);//Convert into SMBX64/PGE-X Compatible form - - break; - - //b2=friendly npc - case 1: - npcdata.friendly = ((dLine != "") && (dLine != "0")); - break; - - //b3=don't move npc - case 2: - npcdata.nomove = ((dLine != "") && (dLine != "0")); - break; - - //b4=[1=npc91][2=npc96][3=npc283][4=npc284][5=npc300] - case 3: - - //CONTAINER with packed NPC - if(!SMBX64::IsSInt(dLine)) - goto badfile; - - int contID = toInt(dLine); - - if(contID == 0) - break; - - npcdata.contents = static_cast(npcdata.id); - - switch(contID) - { - case 1: - npcdata.id = 91; - break; - - case 2: - npcdata.id = 96; - break; - - case 3: - npcdata.id = 283; - break; - - case 4: - npcdata.id = 284; - break; - - case 5: - npcdata.id = 300; - break; - } - - break; - } - } - } - break; - - //sp=special option - case 6: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else - { - npcdata.special_data = (long)round(toDouble(cLine)); - - switch(npcdata.id) - { - case 15: - case 39: - case 86: //Bind "Is Boss" flag for supported NPC's - npcdata.is_boss = (bool)npcdata.special_data; - npcdata.special_data = 0; - - default: - break; - } - } - } - break; - - //Event slots - case 7: - { - PGESTRINGList nevents; - old38a_SplitCSVStr(nevents, cLine); - - for(int j = 0; j < (signed)nevents.size(); j++) - { - PGESTRING &dLine = nevents[j]; - - switch(j) // [***urlencode!***] - { - // e1=death event - case 0: - npcdata.event_die = PGE_URLDEC(dLine); - break; - - // e2=talk event - case 1: - npcdata.event_talk = PGE_URLDEC(dLine); - break; - - // e3=activate event - case 2: - npcdata.event_activate = PGE_URLDEC(dLine); - break; - - // e4=no more object in layer event - case 3: - npcdata.event_emptylayer = PGE_URLDEC(dLine); - break; - - // e5=grabed event - case 4: - npcdata.event_grab = PGE_URLDEC(dLine); - break; - - // e6=next frame event - case 5: - npcdata.event_nextframe = PGE_URLDEC(dLine); - break; - - // e7=touch event - case 6: - npcdata.event_touch = PGE_URLDEC(dLine); - break; - } - } - } - break; - - //Attach layer / Updated variable with - case 8: - { - PGESTRINGList nelayers; - old38a_SplitCSVStr(nelayers, cLine); - - for(int j = 0; j < (signed)nelayers.size(); j++) - { - PGESTRING &dLine = nelayers[j]; - - switch(j) // [***urlencode!***] - { - // a1=layer name to attach - case 0: - npcdata.attach_layer = PGE_URLDEC(dLine); - break; - - // a2=variable name to send - case 1: - npcdata.send_id_to_variable = PGE_URLDEC(dLine); - break; - } - } - } - break; - - //Generators - case 9: - { - PGESTRINGList nevents; - old38a_SplitCSVStr(nevents, cLine); - - for(int j = 0; j < (signed)nevents.size(); j++) - { - PGESTRING &dLine = nevents[j]; - - if((j > 0) && (!npcdata.generator)) break; - - switch(j) - { - //c1=generator enable - case 0: - npcdata.generator = ((dLine != "") && (dLine != "0")); - break; - - //[if c1!=0] - // c2=generator period[1 frame] - case 1: - if(!SMBX64::IsSInt(dLine)) - goto badfile; - else npcdata.generator_period = (int)round((toDouble(dLine) * 10.0) / 65.0); //Convert into deci-seconds - - break; - - // c3=generator effect - // c3-1[1=warp][0=projective][4=no effect] - // c3-2[0=center][1=up][2=left][3=down][4=right] - // [9=up+left][10=left+down][11=down+right][12=right+up] - // if (c3-2)!=0 - // c3=4*(c3-1)+(c3-2) - // else - // c3=0 - case 2: - if(!SMBX64::IsSInt(dLine)) - goto badfile; - else - { - int gentype = toInt(dLine); - - switch(gentype) - { - case 0: - npcdata.generator_type = LevelNPC::NPC_GENERATOR_APPEAR; - npcdata.generator_direct = LevelNPC::NPC_GEN_CENTER; - break; - - default: - if(gentype < 29) - { - npcdata.generator_type = SMBX38A_NpcGeneratorTypes[gentype]; - npcdata.generator_direct = SMBX38A_NpcGeneratorDirections[gentype]; - } - else - { - npcdata.generator_type = LevelNPC::NPC_GENERATOR_APPEAR; - npcdata.generator_direct = LevelNPC::NPC_GEN_CENTER; - } - } - - //Convert value into SMBX64 and PGEX compatible - switch(npcdata.generator_type) - { - case 0: - npcdata.generator_type = LevelNPC::NPC_GENERATPR_PROJECTILE; - break; - - case 1: - npcdata.generator_type = LevelNPC::NPC_GENERATOR_WARP; - break; - - case 4: - npcdata.generator_type = LevelNPC::NPC_GENERATOR_APPEAR; - break; - } - } - - break; - - // c4=generator direction[angle][when c3=0] - case 3: - { - if(!SMBX64::IsFloat(dLine)) - goto badfile; - else npcdata.generator_custom_angle = toFloat(dLine); - } - break; - - // c5=batch[when c3=0][MAX=32] - case 4: - { - if(!SMBX64::IsFloat(dLine)) - goto badfile; - else npcdata.generator_branches = (long)fabs(round(toFloat(dLine))); - } - break; - - // c6=angle range[when c3=0] - case 5: - { - if(!SMBX64::IsFloat(dLine)) - goto badfile; - else npcdata.generator_angle_range = fabs(toFloat(dLine)); - } - break; - - // c7=speed[when c3=0][float] - case 6: - { - if(!SMBX64::IsFloat(dLine)) - goto badfile; - else npcdata.generator_initial_speed = toFloat(dLine); - } - break; - } - } - } - break; - - //msg=message by this npc talkative[***urlencode!***] - case 10: - { - npcdata.msg = PGE_URLDEC(cLine); - } - break; - } - } - - npcdata.meta.array_id = FileData.npc_array_id++; - FileData.npc.push_back(npcdata); - } - else if(currentLine[0] == "Q") //next line: waters - { - //Q|layer|x|y|w|h|b1,b2,b3,b4,b5|event - waters = CreateLvlPhysEnv(); - - for(int i = 1; i < (signed)currentLine.size(); i++) - { - PGESTRING &cLine = currentLine[i]; - - switch(i) - { - // layer=layer name["" == "Default"][***urlencode!***] - case 1: - { - waters.layer = (cLine == "" ? "Default" : PGE_URLDEC(cLine)); - } - break; - - //x=position x - case 2: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else waters.x = (long)round(toFloat(cLine)); - } - break; - - //y=position y - case 3: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else waters.y = (long)round(toFloat(cLine)); - } - break; - - //w=width - case 4: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else waters.w = (long)round(toFloat(cLine)); - } - break; - - //h=height - case 5: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else waters.h = (long)round(toFloat(cLine)); - } - break; - - case 6: - { - PGESTRINGList nevents; - old38a_SplitCSVStr(nevents, cLine); - - for(int j = 0; j < (signed)nevents.size(); j++) - { - PGESTRING &dLine = nevents[j]; - - switch(j) - { - //b1=liquid type - // 01-Water[friction=0.5] - // 02-Quicksand[friction=0.1] - // 03-Custom Water - // 04-Gravitational Field - // 05-Event Once - // 06-Event Always - // 07-NPC Event Once - // 08-NPC Event Always - // 09-Click Event - // 10-Collision Script - // 11-Click Script - // 12-Collision Event - // 13-Air chamber - case 0: - { - if(!SMBX64::IsFloat(dLine)) - goto badfile; - else waters.env_type = (int)round(toFloat(dLine)) - 1; - } - break; - - //b2=friction - case 1: - { - if(!SMBX64::IsFloat(dLine)) - goto badfile; - else waters.friction = toFloat(dLine); - } - break; - - //b3=Acceleration Direction - case 2: - { - if(!SMBX64::IsFloat(dLine)) - goto badfile; - else waters.accel_direct = toFloat(dLine); - } - break; - - //b4=Acceleration - case 3: - { - if(!SMBX64::IsFloat(dLine)) - goto badfile; - else waters.accel = toFloat(dLine); - } - break; - - //b5=Maximum Velocity - case 4: - { - if(!SMBX64::IsFloat(dLine)) - goto badfile; - else waters.accel = toFloat(dLine); - } - break; - } - } - } - break; - - //event=touch event - case 7: - { - waters.touch_event = PGE_URLDEC(cLine); - } - break; - } - } - - waters.meta.array_id = FileData.physenv_array_id++; - FileData.physez.push_back(waters); - } - else if(currentLine[0] == "W") //next line: warps - { - //W|layer|x|y|ex|ey|type|enterd|exitd|sn,msg,hide|locked,noyoshi,canpick,bomb,hidef,anpc|lik|liid|noexit|wx|wy|le|we - doordata = CreateLvlWarp(); - - for(int i = 1; i < (signed)currentLine.size(); i++) - { - PGESTRING &cLine = currentLine[i]; - - switch(i) - { - case 1: - { - doordata.layer = (cLine == "" ? "Default" : PGE_URLDEC(cLine)); - } - break; - - //x=entrance position x - case 2: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else doordata.ix = (long)round(toFloat(cLine)); - } - break; - - //y=entrance postion y - case 3: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else doordata.iy = (long)round(toFloat(cLine)); - } - break; - - //ex=exit position x - case 4: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else doordata.ox = (long)round(toFloat(cLine)); - } - break; - - //ey=exit position y - case 5: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else doordata.oy = (long)round(toFloat(cLine)); - } - break; - - //type=[1=pipe][2=door][0=instant] - case 6: - { - if(!SMBX64::IsUInt(cLine)) - goto badfile; - else doordata.type = toInt(cLine); - } - break; - - //enterd=entrance direction[1=up 2=left 3=down 4=right] - case 7: - { - if(!SMBX64::IsUInt(cLine)) - goto badfile; - else doordata.idirect = toInt(cLine); - } - break; - - //exitd=exit direction[1=up 2=left 3=down 4=right] - case 8: - { - if(!SMBX64::IsUInt(cLine)) - goto badfile; - else switch(toInt(cLine))//Convert into SMBX64/PGE-X Compatible form - { - case 1: - doordata.odirect = LevelDoor::EXIT_UP; - break; - - case 2: - doordata.odirect = LevelDoor::EXIT_LEFT; - break; - - case 3: - doordata.odirect = LevelDoor::EXIT_DOWN; - break; - - case 4: - doordata.odirect = LevelDoor::EXIT_RIGHT; - break; - } - } - break; - - case 9: - { - PGESTRINGList bevents; - old38a_SplitCSVStr(bevents, cLine); - - for(int j = 0; j < (signed)bevents.size(); j++) - { - PGESTRING &dLine = bevents[j]; - - switch(j) - { - //sn=need stars for enter - case 0: - { - if(!SMBX64::IsSInt(dLine)) - goto badfile; - else doordata.stars = toInt(dLine); - } - break; - - //msg=a message when you have not enough stars - case 1: - { - doordata.stars_msg = PGE_URLDEC(dLine); - } - break; - - //hide=hide the star number in this warp - case 2: - { - if(!SMBX64::IsUInt(dLine)) - goto badfile; - else doordata.star_num_hide = (dLine != "0"); - } - break; - } - } - } - break; - - case 10: - { - PGESTRINGList bevents; - old38a_SplitCSVStr(bevents, cLine); - - for(int j = 0; j < (signed)bevents.size(); j++) - { - PGESTRING &dLine = bevents[j]; - - switch(j) - { - //locked=locked - case 0: - { - if(!SMBX64::IsUInt(dLine)) - goto badfile; - else doordata.locked = (bool)toInt(dLine); - } - break; - - //noyoshi=no yoshi - case 1: - { - if(!SMBX64::IsUInt(dLine)) - goto badfile; - else doordata.novehicles = (bool)toInt(dLine); - } - break; - - //canpick=allow npc - case 2: - { - if(!SMBX64::IsUInt(dLine)) - goto badfile; - else doordata.allownpc = (bool)toInt(dLine); - } - break; - - //bomb=need a bomb - case 3: - { - if(!SMBX64::IsUInt(dLine)) - goto badfile; - else doordata.need_a_bomb = (bool)toInt(dLine); - } - break; - - //hide=hide the entry scene - case 4: - { - if(!SMBX64::IsUInt(dLine)) - goto badfile; - else doordata.hide_entering_scene = (bool)toInt(dLine); - } - break; - - //anpc=allow npc interlevel - case 5: - { - if(!SMBX64::IsUInt(dLine)) - goto badfile; - else doordata.allownpc_interlevel = (bool)toInt(dLine); - } - break; - - //Since SMBX-66-38A: { - //mini=Mini-Only - case 6: - { - if(!SMBX64::IsUInt(dLine)) - goto badfile; - else doordata.special_state_required = (bool)toInt(dLine); - } - break; - - //size=Warp Size(pixel) - case 7: - { - if(!SMBX64::IsUInt(dLine)) - goto badfile; - else doordata.length_i = toInt(dLine); - - doordata.length_o = doordata.length_i; - } - break; - } - - // }//Since SMBX-66-38A - } - } - break; - - //lik=warp to level[***urlencode!***] - case 11: - { - doordata.lname = PGE_URLDEC(cLine); - } - break; - - //liid=normal enterance / to warp[0-WARPMAX] - case 12: - { - if(!SMBX64::IsUInt(cLine)) - goto badfile; - else doordata.warpto = toInt(cLine); - } - break; - - //noexit=level entrance - case 13: - { - if(!SMBX64::IsUInt(cLine)) - goto badfile; - else doordata.lvl_i = (bool)toInt(cLine); - - doordata.isSetIn = ((doordata.lvl_i) ? false : true); - } - break; - - //wx=warp to x on world map - case 14: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else doordata.world_x = (long)round(toFloat(cLine)); - } - break; - - //wy=warp to y on world map - case 15: - { - if(!SMBX64::IsFloat(cLine)) - goto badfile; - else doordata.world_y = (long)round(toFloat(cLine)); - } - break; - - //le=level exit - case 16: - { - if(!SMBX64::IsUInt(cLine)) - goto badfile; - else doordata.lvl_o = (bool)toInt(cLine); - - doordata.isSetOut = (((doordata.lvl_o) ? false : true) || (doordata.lvl_i)); - } - break; - - //we=warp event[***urlencode!***] - case 17: - { - doordata.event_enter = PGE_URLDEC(cLine); - } - break; - } - } - - doordata.meta.array_id = FileData.doors_array_id++; - FileData.doors.push_back(doordata); - } - else if(currentLine[0] == "L") //Layers - { - //L|name|status - layerdata = CreateLvlLayer(); - - for(int i = 1; i < (signed)currentLine.size(); i++) - { - PGESTRING &cLine = currentLine[i]; - - switch(i) - { - // layer=layer name["" == "Default"][***urlencode!***] - case 1: - { - layerdata.name = PGE_URLDEC(cLine); - } - break; - - // status=is vizible layer - case 2: - { - layerdata.hidden = (cLine == "0"); - } - break; - } - } - - layerdata.meta.array_id = FileData.layers_array_id++; - FileData.layers.push_back(layerdata); - } - else if(currentLine[0] == "E") //next line: events - { - //E|name|msg|ea|el|elm|epy|eps|eef|ecn|evc|ene - eventdata = CreateLvlEvent(); - - for(int i = 1; i < (signed)currentLine.size(); i++) - { - PGESTRING &cLine = currentLine[i]; - - switch(i) - { - // name=event name[***urlencode!***] - case 1: - { - eventdata.name = PGE_URLDEC(cLine); - } - break; - - // msg=spawn message - case 2: - { - eventdata.msg = PGE_URLDEC(cLine); - } - break; - - //ea=val,syntax - case 3: - { - PGESTRINGList autorun; - old38a_SplitCSVStr(autorun, cLine); - - for(int j = 0; j < (signed)autorun.size(); j++) - { - PGESTRING &dLine = autorun[j]; - - switch(j) - { - // val=[0=not auto start][1=auto start when level start][2=auto start when match all condition][3=start when called and match all condidtion] - case 0: - if(!SMBX64::IsFloat(dLine)) - goto badfile; - - eventdata.autostart = (int)round(toFloat(dLine)); - break; - - // syntax=condidtion expression[***urlencode!***] - case 1: - eventdata.autostart_condition = PGE_URLDEC(dLine); - break; - } - } - } - break; - - //el=b/s1,s2...sn/h1,h2...hn/t1,t2...tn - case 4: - { - PGESTRINGList EvPref; - SMBX38A_SplitSubLine(EvPref, cLine); - - for(int j = 0; j < (signed)EvPref.size(); j++) - { - PGESTRING &dLine = EvPref[j]; - - switch(j) - { - // b=no smoke[0=false !0=true] - case 0: - eventdata.nosmoke = (dLine != "0"); - break; - - // [***urlencode!***] - // s(n)=show layer - case 1: - { - PGESTRINGList showlayers; - old38a_SplitCSVStr(showlayers, dLine); - - for(int k = 0; k < (signed)showlayers.size(); k++) - eventdata.layers_show.push_back(PGE_URLDEC(showlayers[k])); - } - break; - - // l(n)=hide layer - case 2: - { - PGESTRINGList hidelayers; - old38a_SplitCSVStr(hidelayers, dLine); - - for(int k = 0; k < (signed)hidelayers.size(); k++) - eventdata.layers_hide.push_back(PGE_URLDEC(hidelayers[k])); - } - break; - - // t(n)=toggle layer - case 3: - { - PGESTRINGList togglelayers; - old38a_SplitCSVStr(togglelayers, dLine); - - for(int k = 0; k < (signed)togglelayers.size(); k++) - eventdata.layers_toggle.push_back(PGE_URLDEC(togglelayers[k])); - } - break; - } - } - } - break; - - //elm=elm1/elm2...elmn - case 5: - { - // elm(n)=layername,horizontal syntax,vertical syntax,way - // layername=layer name for movement[***urlencode!***] - // horizontal syntax, vertical syntax[***urlencode!***][syntax] - // way=[0=by speed][1=by Coordinate] - PGESTRINGList EvMvLayers; - SMBX38A_SplitSubLine(EvMvLayers, cLine); - - for(int j = 0; j < (signed)EvMvLayers.size(); j++) - { - LevelEvent_MoveLayer ml; - PGESTRING &dLine = EvMvLayers[j]; - PGESTRINGList movelayers; - old38a_SplitCSVStr(movelayers, dLine); - - for(int k = 0; k < (signed)movelayers.size(); k++) - { - PGESTRING &eLine = movelayers[k]; - - switch(k) - { - case 0: - ml.name = PGE_URLDEC(eLine); - eventdata.movelayer = ml.name; - break; - - case 1: - ml.expression_x = PGE_URLDEC(eLine); - SMBX38A_Exp2Double(ml.expression_x, ml.speed_x); - eventdata.layer_speed_x = ml.speed_x; - break; - - case 2: - ml.expression_y = PGE_URLDEC(eLine); - SMBX38A_Exp2Double(ml.expression_y, ml.speed_y); - eventdata.layer_speed_y = ml.speed_y; - break; - - case 3: - if(!SMBX64::IsUInt(eLine)) - goto badfile; - - ml.way = toInt(eLine); - break; - } - } - - eventdata.moving_layers.push_back(ml); - } - } - break; - - //1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 - //epy=b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12 - case 6: - { - PGESTRINGList PlrCtrls; - old38a_SplitCSVStr(PlrCtrls, cLine); - - for(int j = 0; j < (signed)PlrCtrls.size(); j++) - { - PGESTRING &dLine = PlrCtrls[j]; - - switch(j) - { - // b1=enable player controls - case 0: - eventdata.ctrls_enable = (dLine != "0"); - break; - - // b2=drop - case 1: - eventdata.ctrl_drop = (dLine != "0"); - break; - - // b3=alt run - case 2: - eventdata.ctrl_altrun = (dLine != "0"); - break; - - // b4=run - case 3: - eventdata.ctrl_run = (dLine != "0"); - break; - - // b5=jump - case 4: - eventdata.ctrl_jump = (dLine != "0"); - break; - - // b6=alt jump - case 5: - eventdata.ctrl_altjump = (dLine != "0"); - break; - - // b7=up - case 6: - eventdata.ctrl_up = (dLine != "0"); - break; - - // b8=down - case 7: - eventdata.ctrl_down = (dLine != "0"); - break; - - // b9=left - case 8: - eventdata.ctrl_left = (dLine != "0"); - break; - - // b10=right - case 9: - eventdata.ctrl_right = (dLine != "0"); - break; - - // b11=start - case 10: - eventdata.ctrl_start = (dLine != "0"); - break; - - // b12=lock keyboard - case 11: - eventdata.ctrl_lock_keyboard = (dLine != "0"); - break; - } - } - } - break; - - //eps=esection/ebackground/emusic - case 7: - { - // esection=es1:es2...esn - // ebackground=eb1:eb2...ebn - // emusic=em1:em2...emn - PGESTRINGList EvSets; - SMBX38A_SplitSubLine(EvSets, cLine); - PGESTRINGList ev_sections; - PGESTRINGList ev_bgs; - PGESTRINGList ev_musics; - - //Collect entries - for(int j = 0; j < (signed)EvSets.size(); j++) - { - PGESTRING &dLine = EvSets[j]; - - switch(j) - { - case 0: - SMBX38A_SplitLine(ev_sections, dLine, ':'); - break; - - case 1: - SMBX38A_SplitLine(ev_bgs, dLine, ':'); - break; - - case 2: - SMBX38A_SplitLine(ev_musics, dLine, ':'); - break; - } - } - - //fill entries - eventdata.sets.clear(); - - for(int q = 0; q < (signed)FileData.sections.size(); q++) - { - LevelEvent_Sets set; - set.id = q; - eventdata.sets.push_back(set); - } - - int evSetsSize = ev_sections.size(); - - if(evSetsSize < (signed)ev_bgs.size()) - evSetsSize = ev_bgs.size(); - - if(evSetsSize < (signed)ev_musics.size()) - evSetsSize = ev_musics.size(); - - for(int j = 0; j < evSetsSize; j++) - { - //SECTIONS - if(j < (signed)ev_sections.size()) - { - PGESTRINGList params; - old38a_SplitCSVStr(params, ev_sections[j]); - // es=id,stype,x,y,w,h,auto,sx,sy - int id = -1; - bool customSizes = false; - bool autoscroll = false; - - for(int k = 0; k < (signed)params.size(); k++) - { - if((k > 0) && - ((id < 0) || (id >= (signed)eventdata.sets.size())) - )//Append sections - { - if(id < 0) goto badfile; //Missmatched section ID! - - int last = eventdata.sets.size() - 1; - - while(id >= (signed)eventdata.sets.size()) - { - LevelEvent_Sets set; - set.id = last; - eventdata.sets.push_back(set); - last++; - } - } - - PGESTRING &eLine = params[k]; - - switch(k) - { - //id=section id - case 0: - if(!SMBX64::IsUInt(eLine)) - goto badfile; - - id = toInt(eLine) - 1; - break; - - //stype=[0=don't change][1=default][2=custom] - case 1: - if(!SMBX64::IsUInt(eLine)) - goto badfile; - - switch(toInt(eLine)) - { - case 0: - eventdata.sets[id].position_left = LevelEvent_Sets::LESet_Nothing; - break; - - case 1: - eventdata.sets[id].position_left = LevelEvent_Sets::LESet_ResetDefault; - break; - - case 2: - customSizes = true; - break; - } - - break; - - //x=left x coordinates for section [id][***urlencode!***][syntax] - case 2: - if(customSizes) - { - eventdata.sets[id].expression_pos_x = PGE_URLDEC(eLine); - SMBX38A_Exp2Int(eventdata.sets[id].expression_pos_x, eventdata.sets[id].position_left); - } - - break; - - //y=top y coordinates for section [id][***urlencode!***][syntax] - case 3: - if(customSizes) - { - eventdata.sets[id].expression_pos_y = PGE_URLDEC(eLine); - SMBX38A_Exp2Int(eventdata.sets[id].expression_pos_y, eventdata.sets[id].position_top); - } - else - eventdata.sets[id].position_top = -1; - - break; - - //w=width for section [id][***urlencode!***][syntax] - case 4: - if(customSizes) - { - eventdata.sets[id].expression_pos_w = PGE_URLDEC(eLine); - SMBX38A_Exp2Int(eventdata.sets[id].expression_pos_w, eventdata.sets[id].position_right); - - if(IsEmpty(eventdata.sets[id].expression_pos_w)) - eventdata.sets[id].position_right += eventdata.sets[id].position_left; - } - else - eventdata.sets[id].position_right = -1; - - break; - - //h=height for section [id][***urlencode!***][syntax] - case 5: - if(customSizes) - { - eventdata.sets[id].expression_pos_h = PGE_URLDEC(eLine); - SMBX38A_Exp2Int(eventdata.sets[id].expression_pos_h, eventdata.sets[id].position_bottom); - - if(IsEmpty(eventdata.sets[id].expression_pos_h)) - eventdata.sets[id].position_bottom += eventdata.sets[id].position_top; - } - else - eventdata.sets[id].position_bottom = -1; - - break; - - //auto=enable autoscroll controls[0=false !0=true] - case 6: - autoscroll = (eLine != "0"); - eventdata.sets[id].autoscrol = autoscroll; - break; - - //sx=move screen horizontal syntax[***urlencode!***][syntax] - case 7: - if(autoscroll) - { - eventdata.sets[id].expression_autoscrool_x = PGE_URLDEC(eLine); - SMBX38A_Exp2Float(eventdata.sets[id].expression_autoscrool_x, eventdata.sets[id].autoscrol_x); - eventdata.scroll_section = id; - eventdata.move_camera_x = eventdata.sets[id].autoscrol_x; - } - else - { - eventdata.sets[id].autoscrol_x = 0.f; - eventdata.scroll_section = id; - eventdata.move_camera_x = 0.f; - } - - break; - - //sy=move screen vertical syntax[***urlencode!***][syntax] - case 8: - if(autoscroll) - { - eventdata.sets[id].expression_autoscrool_y = PGE_URLDEC(eLine); - SMBX38A_Exp2Float(eventdata.sets[id].expression_autoscrool_y, eventdata.sets[id].autoscrol_y); - eventdata.scroll_section = id; - eventdata.move_camera_y = eventdata.sets[id].autoscrol_y; - } - else - { - eventdata.sets[id].autoscrol_y = 0.f; - eventdata.scroll_section = id; - eventdata.move_camera_y = 0.f; - } - - break; - } - } - } - - //BACKGROUNDS - if(j < (signed)ev_bgs.size()) - { - PGESTRINGList params; - old38a_SplitCSVStr(params, ev_bgs[j]); - //eb=id,btype,backgroundid - int id = -1; - bool customBg = false; - - for(int k = 0; k < (signed)params.size(); k++) - { - if((k > 0) && - ((id < 0) || (id >= (signed)eventdata.sets.size())) - )//Append sections - { - if(id < 0) goto badfile; //Missmatched section ID! - - int last = eventdata.sets.size() - 1; - - while(id >= (signed)eventdata.sets.size()) - { - LevelEvent_Sets set; - set.id = last; - eventdata.sets.push_back(set); - last++; - } - } - - PGESTRING &eLine = params[k]; - - switch(k) - { - //id=section id - case 0: - if(!SMBX64::IsUInt(eLine)) - goto badfile; - - id = toInt(eLine) - 1; - break; - - //btype=[0=don't change][1=default][2=custom] - case 1: - if(!SMBX64::IsUInt(eLine)) - goto badfile; - - switch(toInt(eLine)) - { - case 0: - eventdata.sets[id].background_id = LevelEvent_Sets::LESet_Nothing; - break; - - case 1: - eventdata.sets[id].background_id = LevelEvent_Sets::LESet_ResetDefault; - break; - - case 2: - customBg = true; - eventdata.sets[id].background_id = 0; - break; - } - - break; - - //backgroundid=[when btype=2]custom background id - case 2: - if(customBg) - { - if(!SMBX64::IsFloat(eLine)) - goto badfile; - - eventdata.sets[id].background_id = (long)round(toFloat(eLine)); - SMBX38A_mapBGID_From(eventdata.sets[id].background_id);//Convert into SMBX64 ID set - } - - break; - } - } - } - - //em=id,mtype,musicid,customfile - // id=section id - // mtype=[0=don't change][1=default][2=custom] - // musicid=[when mtype=2]custom music id - // customfile=[when mtype=3]custom music file name[***urlencode!***] - //MUSICS - if(j < (signed)ev_musics.size()) - { - PGESTRINGList params; - old38a_SplitCSVStr(params, ev_musics[j]); - //em=id,mtype,musicid,customfile - int id = -1; - bool customMusics = false; - - for(int k = 0; k < (signed)params.size(); k++) - { - if((k > 0) && - ((id < 0) || (id >= (signed)eventdata.sets.size())) - )//Append sections - { - if(id < 0) goto badfile; //Missmatched section ID! - - int last = eventdata.sets.size() - 1; - - while(id >= (signed)eventdata.sets.size()) - { - LevelEvent_Sets set; - set.id = last; - eventdata.sets.push_back(set); - last++; - } - } - - PGESTRING &eLine = params[k]; - - switch(k) - { - //id=section id - case 0: - if(!SMBX64::IsUInt(eLine)) - goto badfile; - - id = toInt(eLine) - 1; - break; - - //mtype=[0=don't change][1=default][2=custom] - case 1: - if(!SMBX64::IsUInt(eLine)) - goto badfile; - - switch(toInt(eLine)) - { - case 0: - eventdata.sets[id].music_id = LevelEvent_Sets::LESet_Nothing; - break; - - case 1: - eventdata.sets[id].music_id = LevelEvent_Sets::LESet_ResetDefault; - break; - - case 2: - default: - customMusics = true; - eventdata.sets[id].music_id = 0; - break; - } - - break; - - //musicid=[when mtype=2]custom music id - case 2: - if(customMusics) - { - if(!SMBX64::IsFloat(eLine)) - goto badfile; - - eventdata.sets[id].music_id = (long)round(toDouble(eLine)); - } - - break; - - case 3: - if(customMusics) - { - eventdata.sets[id].music_file = PGE_URLDEC(eLine); - - if(eventdata.sets[id].music_file == "0") - eventdata.sets[id].music_file.clear(); - } - - break; - } - } - } - } - } - break; - - //eef=sound/endgame/ce1/ce2...cen - case 8: - { - PGESTRINGList Effects; - SMBX38A_SplitSubLine(Effects, cLine); - - for(int j = 0; j < (signed)Effects.size(); j++) - { - PGESTRING &dLine = Effects[j]; - - switch(j) - { - //sound=play sound number - case 0: - if(!SMBX64::IsUInt(dLine)) - goto badfile; - - eventdata.sound_id = toInt(dLine); - break; - - // endgame=[0=none][1=bowser defeat] - case 1: - if(!SMBX64::IsUInt(dLine)) - goto badfile; - - eventdata.end_game = toInt(dLine); - break; - - default: - { - LevelEvent_SpawnEffect effect; - PGESTRINGList EffectsToSpawn; - old38a_SplitCSVStr(EffectsToSpawn, dLine); - - for(int k = 0; k < (signed)EffectsToSpawn.size(); k++) - { - //ce(n)=id,x,y,sx,sy,grv,fsp,life - PGESTRING &eLine = EffectsToSpawn[k]; - - switch(k) - { - // id=effect id - case 0: - if(!SMBX64::IsUInt(eLine)) - goto badfile; - - effect.id = toInt(eLine); - break; - - // x=effect position x[***urlencode!***][syntax] - case 1: - effect.expression_x = PGE_URLDEC(eLine); - SMBX38A_Exp2Int(effect.expression_x, effect.x); - break; - - // y=effect position y[***urlencode!***][syntax] - case 2: - effect.expression_y = PGE_URLDEC(eLine); - SMBX38A_Exp2Int(effect.expression_y, effect.y); - break; - - // sx=effect horizontal speed[***urlencode!***][syntax] - case 3: - effect.expression_sx = PGE_URLDEC(eLine); - SMBX38A_Exp2Double(effect.expression_sx, effect.speed_x); - break; - - // sy=effect vertical speed[***urlencode!***][syntax] - case 4: - effect.expression_sy = PGE_URLDEC(eLine); - SMBX38A_Exp2Double(effect.expression_sy, effect.speed_y); - break; - - // grv=to decide whether the effects are affected by gravity[0=false !0=true] - case 5: - effect.gravity = (eLine != "0"); - break; - - // fsp=frame speed of effect generated - case 6: - if(!SMBX64::IsUInt(eLine)) - goto badfile; - - effect.fps = toInt(eLine); - break; - - // life=effect existed over this time will be destroyed. - case 7: - if(!SMBX64::IsUInt(eLine)) - goto badfile; - - effect.max_life_time = toInt(eLine); - break; - } - } - - eventdata.spawn_effects.push_back(effect); - } - break; - } - } - } - break; - - //ecn=cn1/cn2...cnn - case 9: - { - PGESTRINGList SpawnNPCs; - SMBX38A_SplitSubLine(SpawnNPCs, cLine); - - //cn(n)=id,x,y,sx,sy,sp - for(int j = 0; j < (signed)SpawnNPCs.size(); j++) - { - LevelEvent_SpawnNPC spawnnpc; - PGESTRING &dLine = SpawnNPCs[j]; - PGESTRINGList SpawnNPC; - old38a_SplitCSVStr(SpawnNPC, dLine); - - for(int k = 0; k < (signed)SpawnNPC.size(); k++) - { - PGESTRING &eLine = SpawnNPC[k]; - - switch(k) - { - //id=npc id - case 0: - if(!SMBX64::IsUInt(eLine)) - goto badfile; - - spawnnpc.id = toInt(eLine); - break; - - //x=npc position x[***urlencode!***][syntax] - case 1: - spawnnpc.expression_x = PGE_URLDEC(eLine); - SMBX38A_Exp2Int(spawnnpc.expression_x, spawnnpc.x); - break; - - //y=npc position y[***urlencode!***][syntax] - case 2: - spawnnpc.expression_y = PGE_URLDEC(eLine); - SMBX38A_Exp2Int(spawnnpc.expression_y, spawnnpc.y); - break; - - //sx=npc horizontal speed[***urlencode!***][syntax] - case 3: - spawnnpc.expression_sx = PGE_URLDEC(eLine); - SMBX38A_Exp2Double(spawnnpc.expression_sx, spawnnpc.speed_x); - break; - - //sy=npc vertical speed[***urlencode!***][syntax] - case 4: - spawnnpc.expression_sy = PGE_URLDEC(eLine); - SMBX38A_Exp2Double(spawnnpc.expression_sy, spawnnpc.speed_y); - break; - - //sp=advanced settings of generated npc - case 5: - if(!SMBX64::IsSInt(eLine)) - goto badfile; - - spawnnpc.special = toInt(eLine); - break; - } - } - - eventdata.spawn_npc.push_back(spawnnpc); - } - } - break; - - //evc=vc1/vc2...vcn - case 10: - { - LevelEvent_UpdateVariable updVar; - PGESTRINGList updVars; - old38a_SplitCSVStr(updVars, cLine); - - // vc(n)=name,newvalue - for(int j = 0; j < (signed)updVars.size(); j++) - { - PGESTRING &dLine = updVars[j]; - - switch(j) - { - //name=variable name[***urlencode!***] - case 0: - updVar.name = PGE_URLDEC(dLine); - break; - - //newvalue=new value[***urlencode!***][syntax] - case 1: - updVar.newval = PGE_URLDEC(dLine); - break; - } - } - - if(!IsEmpty(updVar.name)) - eventdata.update_variable.push_back(updVar); - } - break; - - //ene=nextevent/timer/apievent/scriptname - case 11: - { - PGESTRINGList extraProps; - SMBX38A_SplitSubLine(extraProps, cLine); - - for(int j = 0; j < (signed)extraProps.size(); j++) - { - PGESTRING &dLine = extraProps[j]; - - switch(j) - { - //nextevent=name,delay - case 0: - { - PGESTRINGList TriggerEvent; - old38a_SplitCSVStr(TriggerEvent, dLine); - - for(int k = 0; k < (signed)TriggerEvent.size(); k++) - { - PGESTRING &eLine = TriggerEvent[k]; - - switch(k) - { - //name=trigger event name[***urlencode!***] - case 0: - eventdata.trigger = PGE_URLDEC(eLine); - break; - - //delay=trigger delay[1 frame] - case 1: - if(!SMBX64::IsUInt(eLine)) - goto badfile; - - //Convert 1/65 seconds into 1/10 seconds for SMBX-64 Standard - eventdata.trigger_timer = (long)round(SMBX64::t65_to_ms(toFloat(eLine)) / 100.0); - break; - } - } - } - break; - - //timer=enable,count,interval,type,show - case 1: - { - PGESTRINGList Timer; - old38a_SplitCSVStr(Timer, dLine); - - for(int k = 0; k < (signed)Timer.size(); k++) - { - PGESTRING &eLine = Timer[k]; - - switch(k) - { - //enable=enable the game timer controlling[0=false !0=true] - case 0: - eventdata.timer_def.enable = (eLine != "0"); - break; - - //count=set the time left of the game timer - case 1: - if(!SMBX64::IsUInt(eLine)) - goto badfile; - - //Convert 1/65 seconds into milliseconds units - eventdata.timer_def.count = toInt(eLine); - break; - - //interval=set the time count interval of the game timer - case 2: - if(!SMBX64::IsFloat(eLine)) - goto badfile; - - //Convert 1/65 seconds into milliseconds units - eventdata.timer_def.interval = SMBX64::t65_to_ms(toDouble(eLine)); - break; - - //type=to choose the way timer counts[0=counting down][1=counting up] - case 3: - if(!SMBX64::IsUInt(eLine)) - goto badfile; - - eventdata.timer_def.count_dir = toInt(eLine); - break; - - //show=to choose whether the game timer is showed in hud[0=false !0=true] - case 4: - eventdata.timer_def.show = (eLine != "0"); - break; - } - } - } - break; - - // apievent=the id of apievent - case 2: - if(!SMBX64::IsUInt(dLine)) - goto badfile; - - eventdata.trigger_api_id = toInt(dLine); - break; - - // scriptname=script name[***urlencode!***] - case 3: - eventdata.trigger_script = PGE_URLDEC(dLine); - break; - } - } - } - break; - } - } - - eventdata.meta.array_id = FileData.events_array_id++; - FileData.events.push_back(eventdata); - } - else if(currentLine[0] == "V") //next line: variables - { - //V|name|value - vardata = CreateLvlVariable("var"); - - for(int i = 1; i < (signed)currentLine.size(); i++) - { - PGESTRING &cLine = currentLine[i]; - - switch(i) - { - //name=variable name[***urlencode!***] - case 1: - { - vardata.name = PGE_URLDEC(cLine); - } - break; - - //value=initial value of the variable - case 2: - { - if(!SMBX64::IsUInt(cLine)) - goto badfile; - else vardata.value = cLine; /*save variable value as string - - because in PGE is planned to have - variables to be universal*/ - } - break; - } - } - - FileData.variables.push_back(vardata); - } - else if(currentLine[0] == "S") //next line: scripts - { - //S|name|script - scriptdata = CreateLvlScript("doScript", LevelScript::LANG_TEASCRIPT); - - for(int i = 1; i < (signed)currentLine.size(); i++) - { - PGESTRING &cLine = currentLine[i]; - - switch(i) - { - //name=name of script[***urlencode!***] - case 1: - { - scriptdata.name = PGE_URLDEC(cLine); - } - break; - - //script=script[***base64encode!***][utf-8] - case 2: - { - scriptdata.script = PGE_BASE64DEC(cLine); - } - break; - } - } - - FileData.variables.push_back(vardata); - } - else if(currentLine[0] == "Su") //next line: scripts (saved as ASCII) - { - //Su|name|scriptu - scriptdata = CreateLvlScript("doScript", LevelScript::LANG_TEASCRIPT); - - for(int i = 1; i < (signed)currentLine.size(); i++) - { - PGESTRING &cLine = currentLine[i]; - - switch(i) - { - //name=name of script[***urlencode!***] - case 1: - { - scriptdata.name = PGE_URLDEC(cLine); - } - break; - - //scriptu=script[***base64encode!***][ASCII] - case 2: - { - scriptdata.script = PGE_BASE64DEC_A(cLine); - PGE_ReplSTRING(scriptdata.script, "\r\n", "\n"); - } - break; - } - } - - FileData.scripts.push_back(scriptdata); - } - }//while is not EOF - - LevelAddInternalEvents(FileData); - FileData.CurSection = 0; - FileData.playmusic = 0; - FileData.meta.ReadFileValid = true; - return true; -badfile: - FileData.meta.ReadFileValid = false; - FileData.meta.ERROR_info = "Invalid file format, detected file SMBX-" + fromNum(file_format) + "format"; - FileData.meta.ERROR_linenum = in.getCurrentLineNumber(); - FileData.meta.ERROR_linedata = line; - return false; -} diff --git a/LunaDll/libs/PGE_File_Formats/file_rw_lvlx.cpp b/LunaDll/libs/PGE_File_Formats/file_rw_lvlx.cpp deleted file mode 100644 index f6e0f685e..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_rw_lvlx.cpp +++ /dev/null @@ -1,2452 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "pge_file_lib_sys.h" -#include "file_formats.h" -#include "file_strlist.h" -#include "pge_x.h" -#include "pge_x_macro.h" -#include - -//********************************************************* -//****************READ FILE FORMAT************************* -//********************************************************* -bool FileFormats::ReadExtendedLvlFileHeader(PGESTRING filePath, LevelData &FileData) -{ - CreateLevelHeader(FileData); - FileData.meta.RecentFormat = LevelData::PGEX; - PGE_FileFormats_misc::TextFileInput inf; - - if(!inf.open(filePath, true)) - { - FileData.meta.ReadFileValid = false; - return false; - } - - PGESTRING line; - int str_count = 0; - bool valid = false; - PGE_FileFormats_misc::FileInfo in_1(filePath); - FileData.meta.filename = in_1.basename(); - FileData.meta.path = in_1.dirpath(); -#define NextLine(line) str_count++;line = inf.readLine(); - - //Find level header part - do - { - str_count++; - NextLine(line); - } - while((line != "HEAD") && (!IsNULL(line))); - - PGESTRINGList header; - bool closed = false; - - if(line != "HEAD")//Header not found, this level is head-less - goto skipHeaderParse; - - NextLine(line); - while((line != "HEAD_END") && (!IsNULL(line))) - { - header.push_back(line); - str_count++; - NextLine(line); - if(line == "HEAD_END") - closed = true; - } - - if(!closed) - goto badfile; - - for(pge_size_t qq = 0; qq < header.size(); qq++) - { - PGESTRING &header_line = header[qq]; - PGELISTdata = PGEFile::splitDataLine(header_line, &valid); - - for(pge_size_t i = 0; i < data.size(); i++) - { - if(data[i].size() != 2) - goto badfile; - - if(data[i][0] == "TL") //Level Title - { - if(PGEFile::IsQoutedString(data[i][1])) - FileData.LevelName = PGEFile::X2STRING(data[i][1]); - else - goto badfile; - } - else if(data[i][0] == "SZ") //Starz number - { - if(PGEFile::IsIntU(data[i][1])) - FileData.stars = toInt(data[i][1]); - else - goto badfile; - } - else if(data[i][0] == "DL") //Open Level on player's fail - { - if(PGEFile::IsQoutedString(data[i][1])) - FileData.open_level_on_fail = PGEFile::X2STRING(data[i][1]); - else - goto badfile; - } - else if(data[i][0] == "DE") //Target WarpID of fail-level entrace - { - if(PGEFile::IsIntU(data[i][1])) - FileData.open_level_on_fail_warpID = toUInt(data[i][1]); - else - goto badfile; - } - } - } - -skipHeaderParse: - FileData.CurSection = 0; - FileData.playmusic = 0; - FileData.meta.ReadFileValid = true; - return true; -badfile: - FileData.meta.ERROR_info = "Invalid file format"; - FileData.meta.ERROR_linenum = static_cast(str_count); - FileData.meta.ERROR_linedata = line; - FileData.meta.ReadFileValid = false; - return false; -} - - - -bool FileFormats::ReadExtendedLvlFileF(PGESTRING filePath, LevelData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileInput file; - - if(!file.open(filePath, true)) - { - errorString = "Failed to open file for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadExtendedLvlFile(file, FileData); -} - -bool FileFormats::ReadExtendedLvlFileRaw(PGESTRING &rawdata, PGESTRING filePath, LevelData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextInput file; - - if(!file.open(&rawdata, filePath)) - { - errorString = "Failed to open raw string for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadExtendedLvlFile(file, FileData); -} - -bool FileFormats::ReadExtendedLvlFile(PGE_FileFormats_misc::TextInput &in, LevelData &FileData) -{ - PGESTRING errorString; - PGESTRING filePath = in.getFilePath(); - PGESTRING line; /*Current Line data*/ - //LevelData FileData; - CreateLevelData(FileData); - FileData.meta.RecentFormat = LevelData::PGEX; - - //Add path data - if(filePath.size() > 0) - { - PGE_FileFormats_misc::FileInfo in_1(filePath); - FileData.meta.filename = in_1.basename(); - FileData.meta.path = in_1.dirpath(); - } - - FileData.meta.untitled = false; - FileData.meta.modified = false; - LevelSection lvl_section; - PlayerPoint player; - LevelBlock block; - LevelBGO bgodata; - LevelNPC npcdata; - LevelDoor door; - LevelPhysEnv physiczone; - LevelLayer layer; - LevelSMBX64Event event; - LevelVariable variable; - LevelScript script; - LevelItemSetup38A customcfg38A; - ///////////////////////////////////////Begin file/////////////////////////////////////// - PGEX_FileParseTree(in.readAll()); - PGEX_FetchSection() //look sections - { - PGEX_FetchSection_begin() - ///////////////////HEADER////////////////////// - PGEX_Section("HEAD") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_StrVal("TL", FileData.LevelName) //Level Title - PGEX_USIntVal("SZ", FileData.stars) //Starz number - PGEX_StrVal("DL", FileData.open_level_on_fail) //Open level on fail - PGEX_UIntVal("DE", FileData.open_level_on_fail_warpID) //Open level's warpID on fail - } - } - }//HEADER - ///////////////////////////////MetaDATA///////////////////////////////////////////// - PGEX_Section("META_BOOKMARKS") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - Bookmark meta_bookmark; - meta_bookmark.bookmarkName.clear(); - meta_bookmark.x = 0; - meta_bookmark.y = 0; - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_StrVal("BM", meta_bookmark.bookmarkName) //Bookmark name - PGEX_FloatVal("X", meta_bookmark.x) // Position X - PGEX_FloatVal("Y", meta_bookmark.y) // Position Y - } - FileData.metaData.bookmarks.push_back(meta_bookmark); - } - } - ////////////////////////meta bookmarks//////////////////////// -#ifdef PGE_EDITOR - PGEX_Section("META_SYS_CRASH") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - FileData.metaData.crash.used = true; - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_BoolVal("UT", FileData.metaData.crash.untitled) //Untitled - PGEX_BoolVal("MD", FileData.metaData.crash.modifyed) //Modyfied - PGEX_SIntVal("FF", FileData.metaData.crash.fmtID) //Recent File format - PGEX_UIntVal("FV", FileData.metaData.crash.fmtVer) //Recent File format version - PGEX_StrVal("N", FileData.metaData.crash.filename) //Filename - PGEX_StrVal("P", FileData.metaData.crash.path) //Path - PGEX_StrVal("FP", FileData.metaData.crash.fullPath) //Full file Path - } - } - }//meta sys crash -#endif - ///////////////////////////////MetaDATA//End//////////////////////////////////////// - ///////////////////SECTION////////////////////// - PGEX_Section("SECTION") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - lvl_section = CreateLvlSection(); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_USIntVal("SC", lvl_section.id) //Section ID - PGEX_SLongVal("L", lvl_section.size_left) //Left side - PGEX_SLongVal("R", lvl_section.size_right)//Right side - PGEX_SLongVal("T", lvl_section.size_top) //Top side - PGEX_SLongVal("B", lvl_section.size_bottom)//Bottom side - PGEX_UIntVal("MZ", lvl_section.music_id)//Stuff music ID - PGEX_UIntVal("BG", lvl_section.background)//Stuff music ID - PGEX_StrVal("MF", lvl_section.music_file) //External music file path - PGEX_BoolVal("CS", lvl_section.wrap_h)//Connect sides horizontally - PGEX_BoolVal("CSV", lvl_section.wrap_v)//Connect sides vertically - PGEX_BoolVal("OE", lvl_section.OffScreenEn)//Offscreen exit - PGEX_BoolVal("SR", lvl_section.lock_left_scroll)//Right-way scroll only (No Turn-back) - PGEX_BoolVal("SL", lvl_section.lock_right_scroll)//Left-way scroll only (No Turn-forward) - PGEX_BoolVal("SD", lvl_section.lock_up_scroll)//Down-way scroll only (No Turn-forward) - PGEX_BoolVal("SU", lvl_section.lock_down_scroll)//Up-way scroll only (No Turn-forward) - PGEX_BoolVal("UW", lvl_section.underwater)//Underwater bit - } - lvl_section.PositionX = lvl_section.size_left - 10; - lvl_section.PositionY = lvl_section.size_top - 10; - //add captured value into array - bool found = false; - pge_size_t q = 0; - pge_size_t sections_count = FileData.sections.size(); - - if(lvl_section.id >= (int)sections_count) - { - pge_size_t needToAdd = (FileData.sections.size() - 1) - static_cast(lvl_section.id); - while(needToAdd > 0) - { - LevelSection dummySct = CreateLvlSection(); - dummySct.id = (int)FileData.sections.size(); - FileData.sections.push_back(dummySct); - needToAdd--; - } - } - - for(q = 0; q < sections_count; q++) - { - if(FileData.sections[q].id == lvl_section.id) - { - found = true; - break; - } - } - - if(found) - FileData.sections[q] = lvl_section; - else - FileData.sections.push_back(lvl_section); - } - }//SECTION - ///////////////////STARTPOINT////////////////////// - PGEX_Section("STARTPOINT") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - player = CreateLvlPlayerPoint(); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_UIntVal("ID", player.id) //ID of player point - PGEX_SLongVal("X", player.x) - PGEX_SLongVal("Y", player.y) - PGEX_SIntVal("D", player.direction) - } - //add captured value into array - bool found = false; - pge_size_t q = 0; - pge_size_t playersCount = FileData.players.size(); - for(q = 0; q < playersCount; q++) - { - if(FileData.players[q].id == player.id) - { - found = true; - break; - } - } - - PlayerPoint sz = CreateLvlPlayerPoint(player.id); - player.w = sz.w; - player.h = sz.h; - - if(found) - FileData.players[q] = player; - else - FileData.players.push_back(player); - } - }//STARTPOINT - ///////////////////BLOCK////////////////////// - PGEX_Section("BLOCK") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - block = CreateLvlBlock(); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_ULongVal("ID", block.id) //Block ID - PGEX_SLongVal("X", block.x) // Position X - PGEX_SLongVal("Y", block.y) //Position Y - PGEX_USLongVal("W", block.w) //Width - PGEX_USLongVal("H", block.h) //Height - PGEX_BoolVal("AS", block.autoscale)//Enable auto-Scaling - PGEX_StrVal("GXN", block.gfx_name) //38A GFX-Name - PGEX_SLongVal("GXX", block.gfx_dx) //38A graphics extend x - PGEX_SLongVal("GXY", block.gfx_dy) //38A graphics extend y - PGEX_SLongVal("CN", block.npc_id) //Contains (coins/NPC) - PGEX_BoolVal("IV", block.invisible) //Invisible - PGEX_BoolVal("SL", block.slippery) //Slippery - PGEX_StrVal("LR", block.layer) //Layer name - PGEX_StrVal("ED", block.event_destroy) //Destroy event slot - PGEX_StrVal("EH", block.event_hit) //Hit event slot - PGEX_StrVal("EE", block.event_emptylayer) //Hit event slot - PGEX_StrVal("XTRA", block.meta.custom_params)//Custom JSON data tree - } - block.meta.array_id = FileData.blocks_array_id++; - block.meta.index = static_cast(FileData.blocks.size()); - FileData.blocks.push_back(block); - } - }//BLOCK - ///////////////////BGO////////////////////// - PGEX_Section("BGO") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - bgodata = CreateLvlBgo(); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_ULongVal("ID", bgodata.id) //BGO ID - PGEX_SLongVal("X", bgodata.x) //X Position - PGEX_SLongVal("Y", bgodata.y) //Y Position - PGEX_SLongVal("GXX", bgodata.gfx_dx) //38A graphics extend x - PGEX_SLongVal("GXY", bgodata.gfx_dy) //38A graphics extend y - PGEX_FloatVal("ZO", bgodata.z_offset) //Z Offset - PGEX_SIntVal("ZP", bgodata.z_mode) //Z Position - PGEX_SLongVal("SP", bgodata.smbx64_sp) //SMBX64 Sorting priority - PGEX_StrVal("LR", bgodata.layer) //Layer name - PGEX_StrVal("XTRA", bgodata.meta.custom_params)//Custom JSON data tree - } - bgodata.meta.array_id = FileData.bgo_array_id++; - bgodata.meta.index = static_cast(FileData.bgo.size()); - FileData.bgo.push_back(bgodata); - } - }//BGO - ///////////////////NPC////////////////////// - PGEX_Section("NPC") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - npcdata = CreateLvlNpc(); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_ULongVal("ID", npcdata.id) //NPC ID - PGEX_SLongVal("X", npcdata.x) //X position - PGEX_SLongVal("Y", npcdata.y) //Y position - PGEX_StrVal("GXN", npcdata.gfx_name) //38A GFX-Name - PGEX_SLongVal("GXX", npcdata.gfx_dx) //38A graphics extend x - PGEX_SLongVal("GXY", npcdata.gfx_dy) //38A graphics extend y - PGEX_SIntVal("D", npcdata.direct) //Direction - PGEX_SLongVal("CN", npcdata.contents) //Contents of container-NPC - PGEX_SLongVal("S1", npcdata.special_data) //Special value 1 - PGEX_SLongVal("S2", npcdata.special_data2) //Special value 2 - PGEX_BoolVal("GE", npcdata.generator) //Generator - PGEX_SIntVal("GT", npcdata.generator_type) //Generator type - PGEX_SIntVal("GD", npcdata.generator_direct) //Generator direction - PGEX_USIntVal("GM", npcdata.generator_period) //Generator period - PGEX_FloatVal("GA", npcdata.generator_custom_angle) //Generator custom angle - PGEX_USIntVal("GB", npcdata.generator_branches) //Generator number of branches - PGEX_FloatVal("GR", npcdata.generator_angle_range) //Generator angle range - PGEX_FloatVal("GS", npcdata.generator_initial_speed) //Generator custom initial speed - PGEX_StrVal("MG", npcdata.msg) //Message - PGEX_BoolVal("FD", npcdata.friendly) //Friendly - PGEX_BoolVal("NM", npcdata.nomove) //Don't move - PGEX_BoolVal("BS", npcdata.is_boss) //Enable boss mode! - PGEX_StrVal("LR", npcdata.layer) //Layer - PGEX_StrVal("LA", npcdata.attach_layer) //Attach Layer - PGEX_StrVal("SV", npcdata.send_id_to_variable) //Send ID to variable - PGEX_StrVal("EA", npcdata.event_activate) //Event slot "Activated" - PGEX_StrVal("ED", npcdata.event_die) //Event slot "Death/Take/Destroy" - PGEX_StrVal("ET", npcdata.event_talk) //Event slot "Talk" - PGEX_StrVal("EE", npcdata.event_emptylayer) //Event slot "Layer is empty" - PGEX_StrVal("EG", npcdata.event_grab)//Event slot "On grab" - PGEX_StrVal("EO", npcdata.event_touch)//Event slot "On touch" - PGEX_StrVal("EF", npcdata.event_nextframe)//Evemt slot "Trigger every frame" - PGEX_StrVal("XTRA", npcdata.meta.custom_params)//Custom JSON data tree - } - npcdata.meta.array_id = FileData.npc_array_id++; - npcdata.meta.index = static_cast(FileData.npc.size()); - FileData.npc.push_back(npcdata); - } - }//TILES - ///////////////////PHYSICS////////////////////// - PGEX_Section("PHYSICS") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - physiczone = CreateLvlPhysEnv(); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_USIntVal("ET", physiczone.env_type) //Environment type - PGEX_SLongVal("X", physiczone.x) //X position - PGEX_SLongVal("Y", physiczone.y) //Y position - PGEX_USLongVal("W", physiczone.w) //Width - PGEX_USLongVal("H", physiczone.h) //Height - PGEX_StrVal("LR", physiczone.layer) //Layer - PGEX_FloatVal("FR", physiczone.friction) //Friction - PGEX_FloatVal("AD", physiczone.accel_direct) //Custom acceleration direction - PGEX_FloatVal("AC", physiczone.accel) //Custom acceleration - PGEX_FloatVal("MV", physiczone.max_velocity) //Maximal velocity - PGEX_StrVal("EO", physiczone.touch_event) //Touch event/script - PGEX_StrVal("XTRA", physiczone.meta.custom_params)//Custom JSON data tree - } - physiczone.meta.array_id = FileData.physenv_array_id++; - physiczone.meta.index = static_cast(FileData.physez.size()); - FileData.physez.push_back(physiczone); - } - }//PHYSICS - ///////////////////DOORS////////////////////// - PGEX_Section("DOORS") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - door = CreateLvlWarp(); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_SLongVal("IX", door.ix) //Input point - PGEX_SLongVal("IY", door.iy) //Input point - PGEX_SLongVal("OX", door.ox) //Output point - PGEX_SLongVal("OY", door.oy) //Output point - PGEX_UIntVal("IL", door.length_i) //Length of entrance (input) point - PGEX_UIntVal("OL", door.length_o) //Length of exit (output) point - PGEX_USIntVal("DT", door.type) //Input point - PGEX_USIntVal("ID", door.idirect) //Input direction - PGEX_USIntVal("OD", door.odirect) //Output direction - PGEX_SLongVal("WX", door.world_x) //Target world map point - PGEX_SLongVal("WY", door.world_y) //Target world map point - PGEX_StrVal("LF", door.lname) //Target level file - PGEX_USLongVal("LI", door.warpto) //Target level file's input warp - PGEX_BoolVal("ET", door.lvl_i) //Level Entrance - PGEX_BoolVal("EX", door.lvl_o) //Level exit - PGEX_USIntVal("SL", door.stars) //Stars limit - PGEX_StrVal("SM", door.stars_msg) //Message about stars/leeks - PGEX_BoolVal("NV", door.novehicles) //No Vehicles - PGEX_BoolVal("SH", door.star_num_hide) //Don't show stars number - PGEX_BoolVal("AI", door.allownpc) //Allow grabbed items - PGEX_BoolVal("LC", door.locked) //Door is locked - PGEX_BoolVal("LB", door.need_a_bomb) //Door is blocked, need bomb to unlock - PGEX_BoolVal("HS", door.hide_entering_scene) //Don't show entering scene - PGEX_BoolVal("AL", door.allownpc_interlevel) //Allow NPC's inter-level - PGEX_BoolVal("SR", door.special_state_required) //Required a special state to enter - PGEX_BoolVal("PT", door.cannon_exit) //Cannon exit - PGEX_FloatVal("PS", door.cannon_exit_speed) //Cannon exit speed - PGEX_StrVal("LR", door.layer) //Layer - PGEX_StrVal("EE", door.event_enter) //On-Enter event slot - PGEX_BoolVal("TW", door.two_way) //Two-way warp - PGEX_StrVal("XTRA", door.meta.custom_params)//Custom JSON data tree - } - door.isSetIn = (!door.lvl_i); - door.isSetOut = (!door.lvl_o || (door.lvl_i)); - - if(!door.isSetIn && door.isSetOut) - { - door.ix = door.ox; - door.iy = door.oy; - } - - if(!door.isSetOut && door.isSetIn) - { - door.ox = door.ix; - door.oy = door.iy; - } - - door.meta.array_id = FileData.doors_array_id++; - door.meta.index = static_cast(FileData.doors.size()); - FileData.doors.push_back(door); - } - }//DOORS - ///////////////////LAYERS////////////////////// - PGEX_Section("LAYERS") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - layer = CreateLvlLayer(); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_StrVal("LR", layer.name) //Layer name - PGEX_BoolVal("HD", layer.hidden) //Hidden - PGEX_BoolVal("LC", layer.locked) //Locked - } - //add captured value into array - bool found = false; - pge_size_t q = 0; - for(q = 0; q < FileData.layers.size(); q++) - { - if(FileData.layers[q].name == layer.name) - { - found = true; - break; - } - } - - if(found) - { - layer.meta.array_id = FileData.layers[q].meta.array_id; - FileData.layers[q] = layer; - } - else - { - layer.meta.array_id = FileData.layers_array_id++; - FileData.layers.push_back(layer); - } - } - }//LAYERS - //EVENTS comming soon - // else - // if(sct.first=="EVENTS_CLASSIC") //Action-styled events - // { - // foreach(PGESTRINGList value, sectData) //Look markers and values - // { - // // if(v.marker=="TL") //Level Title - // // { - // // if(PGEFile::IsQStr(v.value)) - // // FileData.LevelName = PGEFile::X2STR(v.value); - // // else - // // goto badfile; - // // } - // // else - // // if(v.marker=="SZ") //Starz number - // // { - // // if(PGEFile::IsIntU(v.value)) - // // FileData.stars = toInt(v.value); - // // else - // // goto badfile; - // // } - // } - // }//EVENTS - ///////////////////EVENTS_CLASSIC////////////////////// - PGEX_Section("EVENTS_CLASSIC") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - event = CreateLvlEvent(); - PGESTRINGList musicSets; - PGESTRINGList bgSets; - PGESTRINGList ssSets; - PGESTRINGList movingLayers; - PGESTRINGList newSectionSettingsSets; - PGESTRINGList spawnNPCs; - PGESTRINGList spawnEffectss; - PGESTRINGList variablesToUpdate; - PGELIST controls; - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_StrVal("ET", event.name) //Event Title - PGEX_StrVal("MG", event.msg) //Event Message - PGEX_USLongVal("SD", event.sound_id) //Play Sound ID - PGEX_USLongVal("EG", event.end_game) //End game algorithm - PGEX_StrArrVal("LH", event.layers_hide) //Hide layers - PGEX_StrArrVal("LS", event.layers_show) //Show layers - PGEX_StrArrVal("LT", event.layers_toggle) //Toggle layers - //Legacy values (without SMBX-38A values support) - PGEX_StrArrVal("SM", musicSets) //Switch music - PGEX_StrArrVal("SB", bgSets) //Switch background - PGEX_StrArrVal("SS", ssSets) //Section Size - //------------------- - //New values (with SMBX-38A values support) - PGEX_StrArrVal("SSS", newSectionSettingsSets) //Section settings in new format - //------------------- - //---SMBX-38A entries----- - PGEX_StrArrVal("MLA", movingLayers) //NPC's to spawn - PGEX_StrArrVal("SNPC", spawnNPCs) //NPC's to spawn - PGEX_StrArrVal("SEF", spawnEffectss) //Effects to spawn - PGEX_StrArrVal("UV", variablesToUpdate) //Variables to update - PGEX_StrVal("TSCR", event.trigger_script) //Trigger script - PGEX_USIntVal("TAPI", event.trigger_api_id) //Trigger script - PGEX_BoolVal("TMR", event.timer_def.enable) //Enable timer - PGEX_USLongVal("TMC", event.timer_def.count) //Count of timer units - PGEX_FloatVal("TMI", event.timer_def.interval) //Interval of timer tick - PGEX_USIntVal("TMD", event.timer_def.count_dir) //Direction of count - PGEX_BoolVal("TMV", event.timer_def.show) //Show timer on screen - //------------------- - PGEX_StrVal("TE", event.trigger) //Trigger event - PGEX_USLongVal("TD", event.trigger_timer) //Trigger delay - PGEX_BoolVal("DS", event.nosmoke) //Disable smoke - PGEX_USIntVal("AU", event.autostart) //Auto start - PGEX_StrVal("AUC", event.autostart_condition) //Auto start condition - PGEX_BoolArrVal("PC", controls) //Player controls - PGEX_StrVal("ML", event.movelayer) //Move layer - PGEX_FloatVal("MX", event.layer_speed_x) //Layer motion speed X - PGEX_FloatVal("MY", event.layer_speed_y) //Layer motion speed Y - PGEX_SLongVal("AS", event.scroll_section) //Autoscroll section ID - PGEX_FloatVal("AX", event.move_camera_x) //Autoscroll speed X - PGEX_FloatVal("AY", event.move_camera_y) //Autoscroll speed Y - } - - //Parse new-style parameters - if(!newSectionSettingsSets.empty()) - { - for(pge_size_t q = 0; q < newSectionSettingsSets.size(); q++) - { - LevelEvent_Sets sectionSet; - bool valid = false; - PGELIST sssData = PGEFile::splitDataLine(newSectionSettingsSets[q], &valid); - - if(!valid) - { - errorString = "Wrong section settings event encoded sub-entry"; - goto badfile; - } - - for(pge_size_t ssi = 0; ssi < sssData.size(); ssi++) - { - PGESTRINGList ¶m = sssData[ssi]; - - if(param[0] == "ID") - { - errorString = "Invalid sectionID value type"; - - if(PGEFile::IsIntU(param[1])) - sectionSet.id = toLong(param[1]); - else - goto badfile; - } - else if(param[0] == "SL") - { - errorString = "Invalid Section size left value type"; - - if(PGEFile::IsIntS(param[1])) - sectionSet.position_left = toLong(param[1]); - else - goto badfile; - } - else if(param[0] == "ST") - { - errorString = "Invalid Section size top value type"; - - if(PGEFile::IsIntS(param[1])) - sectionSet.position_top = toLong(param[1]); - else - goto badfile; - } - else if(param[0] == "SB") - { - errorString = "Invalid Section size bottom value type"; - - if(PGEFile::IsIntS(param[1])) - sectionSet.position_bottom = toLong(param[1]); - else - goto badfile; - } - else if(param[0] == "SR") - { - errorString = "Invalid Section size right value type"; - - if(PGEFile::IsIntS(param[1])) - sectionSet.position_right = toLong(param[1]); - else - goto badfile; - } - else if(param[0] == "SXX") - { - errorString = "Invalid Section pos x expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - sectionSet.expression_pos_x = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "SYX") - { - errorString = "Invalid Section pos y expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - sectionSet.expression_pos_y = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "SWX") - { - errorString = "Invalid Section pos w expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - sectionSet.expression_pos_w = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "SWH") - { - errorString = "Invalid Section pos h expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - sectionSet.expression_pos_h = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "MI") - { - errorString = "Invalid Section music ID value type"; - - if(PGEFile::IsIntS(param[1])) - sectionSet.music_id = toLong(param[1]); - else - goto badfile; - } - else if(param[0] == "MF") - { - errorString = "Invalid Section music file value type"; - - if(PGEFile::IsQoutedString(param[1])) - sectionSet.music_file = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "BG") - { - errorString = "Invalid Section background ID value type"; - - if(PGEFile::IsIntS(param[1])) - sectionSet.background_id = toLong(param[1]); - else - goto badfile; - } - else if(param[0] == "AS") - { - errorString = "Invalid Section Autoscroll value type"; - - if(PGEFile::IsBool(param[1])) - sectionSet.autoscrol = static_cast(toInt(param[1])); - else - goto badfile; - } - else if(param[0] == "AX") - { - errorString = "Invalid Section Autoscroll X value type"; - - if(PGEFile::IsFloat(param[1])) - sectionSet.autoscrol_x = toFloat(param[1]); - else - goto badfile; - } - else if(param[0] == "AY") - { - errorString = "Invalid Section Autoscroll Y value type"; - - if(PGEFile::IsFloat(param[1])) - sectionSet.autoscrol_y = toFloat(param[1]); - else - goto badfile; - } - else if(param[0] == "AXX") - { - errorString = "Invalid Section Autoscroll X expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - sectionSet.expression_autoscrool_x = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "AYX") - { - errorString = "Invalid Section Autoscroll y expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - sectionSet.expression_autoscrool_y = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - }//for parameters - - if( - ((sectionSet.id < 0) || (sectionSet.id >= static_cast(event.sets.size()))) - )//Append sections - { - if(sectionSet.id < 0) - { - errorString = "Section settings event contains negative section ID value or missed!"; - goto badfile;//Missmatched section ID! - } - - long last = static_cast(event.sets.size() - 1); - - while(sectionSet.id >= static_cast(event.sets.size())) - { - LevelEvent_Sets set; - set.id = last; - event.sets.push_back(set); - last++; - } - } - - event.sets[static_cast(sectionSet.id)] = sectionSet; - }//for section settings entries - }//If new-styled section settings are gotten - //Parse odl-style parameters - else - { - //Apply MusicSets - pge_size_t q = 0; - - for(q = 0; q < event.sets.size() && q < musicSets.size(); q++) - { - event.sets[q].id = static_cast(q); - if(!PGEFile::IsIntS(musicSets[q])) goto badfile; - event.sets[q].music_id = toLong(musicSets[q]); - } - - //Apply Background sets - for(q = 0; q < event.sets.size() && q < bgSets.size(); q++) - { - event.sets[q].id = static_cast(q); - if(!PGEFile::IsIntS(bgSets[q])) goto badfile; - event.sets[q].background_id = toLong(bgSets[q]); - } - - //Apply section sets - for(q = 0; q < event.sets.size() && q < ssSets.size(); q++) - { - event.sets[q].id = static_cast(q); - PGESTRINGList sizes; - PGE_SPLITSTRING(sizes, ssSets[q], ","); - - if(sizes.size() != 4) goto badfile; //-V112 - - if(!PGEFile::IsIntS(sizes[0])) goto badfile; - event.sets[q].position_left = toLong(sizes[0]); - - if(!PGEFile::IsIntS(sizes[1])) goto badfile; - event.sets[q].position_top = toLong(sizes[1]); - - if(!PGEFile::IsIntS(sizes[2])) goto badfile; - event.sets[q].position_bottom = toLong(sizes[2]); - - if(!PGEFile::IsIntS(sizes[3])) goto badfile; - event.sets[q].position_right = toLong(sizes[3]); - } - } - - //Parse Moving layers - if(!movingLayers.empty()) - { - for(pge_size_t q = 0; q < movingLayers.size(); q++) - { - LevelEvent_MoveLayer moveLayer; - bool valid = false; - PGELIST mlaData = PGEFile::splitDataLine(movingLayers[q], &valid); - - if(!valid) - { - errorString = "Wrong Move layer event encoded sub-entry"; - goto badfile; - } - - for(pge_size_t ssi = 0; ssi < mlaData.size(); ssi++) - { - PGESTRINGList ¶m = mlaData[ssi]; - - if(param[0] == "LN") - { - errorString = "Invalid Moving layer name value type"; - - if(PGEFile::IsQoutedString(param[1])) - moveLayer.name = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "SX") - { - errorString = "Invalid movelayer speed X value type"; - - if(PGEFile::IsFloat(param[1])) - moveLayer.speed_x = toDouble(param[1]); - else - goto badfile; - } - else if(param[0] == "SY") - { - errorString = "Invalid movelayer speed Y value type"; - - if(PGEFile::IsFloat(param[1])) - moveLayer.speed_y = toDouble(param[1]); - else - goto badfile; - } - else if(param[0] == "AXX") - { - errorString = "Invalid movelayer speed X expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - moveLayer.expression_x = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "AYX") - { - errorString = "Invalid movelayer speed Y expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - moveLayer.expression_y = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "MW") - { - errorString = "Invalid movelayer way type value type"; - - if(PGEFile::IsIntU(param[1])) - moveLayer.way = toInt(param[1]); - else - goto badfile; - } - }//for parameters - - event.moving_layers.push_back(moveLayer); - }//for moving layers entries - }//If SMBX38A moving layers are gotten - - //Parse NPCs to spawn - if(!spawnNPCs.empty()) - { - for(pge_size_t q = 0; q < spawnNPCs.size(); q++) - { - LevelEvent_SpawnNPC spawnNPC; - bool valid = false; - PGELIST mlaData = PGEFile::splitDataLine(spawnNPCs[q], &valid); - - if(!valid) - { - errorString = "Wrong Spawn NPC event encoded sub-entry"; - goto badfile; - } - - for(pge_size_t ssi = 0; ssi < mlaData.size(); ssi++) - { - PGESTRINGList ¶m = mlaData[ssi]; - - if(param[0] == "ID") - { - errorString = "Invalid Spawn NPC ID value type"; - - if(PGEFile::IsIntU(param[1])) - spawnNPC.id = toLong(param[1]); - else - goto badfile; - } - else if(param[0] == "SX") - { - errorString = "Invalid Spawn NPC X value type"; - - if(PGEFile::IsFloat(param[1])) - spawnNPC.x = static_cast(toFloat(param[1])); - else - goto badfile; - } - else if(param[0] == "SY") - { - errorString = "Invalid Spawn NPC Y value type"; - - if(PGEFile::IsFloat(param[1])) - spawnNPC.y = static_cast(toFloat(param[1])); - else - goto badfile; - } - else if(param[0] == "SXX") - { - errorString = "Invalid Spawn NPC X expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - spawnNPC.expression_x = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "SYX") - { - errorString = "Invalid Spawn NPC X expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - spawnNPC.expression_y = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "SSX") - { - errorString = "Invalid Spawn NPC X value type"; - - if(PGEFile::IsFloat(param[1])) - spawnNPC.speed_x = static_cast(toFloat(param[1])); - else - goto badfile; - } - else if(param[0] == "SSY") - { - errorString = "Invalid Spawn NPC Y value type"; - - if(PGEFile::IsFloat(param[1])) - spawnNPC.speed_y = static_cast(toFloat(param[1])); - else - goto badfile; - } - else if(param[0] == "SSXX") - { - errorString = "Invalid Spawn NPC Speed X expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - spawnNPC.expression_sx = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "SSYX") - { - errorString = "Invalid Spawn NPC Speed Y expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - spawnNPC.expression_sy = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "SSS") - { - errorString = "Invalid Spawn NPC Special value type"; - - if(PGEFile::IsIntU(param[1])) - spawnNPC.special = toLong(param[1]); - else - goto badfile; - } - }//for parameters - - event.spawn_npc.push_back(spawnNPC); - }//for Spawn NPC - }//If SMBX38A NPC Spawning lists are gotten - - //Parse Effects to spawn - if(!spawnEffectss.empty()) - { - for(pge_size_t q = 0; q < spawnEffectss.size(); q++) - { - LevelEvent_SpawnEffect spawnEffect; - bool valid = false; - PGELIST mlaData = PGEFile::splitDataLine(spawnEffectss[q], &valid); - - if(!valid) - { - errorString = "Wrong Spawn Effect event encoded sub-entry"; - goto badfile; - } - - for(pge_size_t ssi = 0; ssi < mlaData.size(); ssi++) - { - PGESTRINGList ¶m = mlaData[ssi]; - - if(param[0] == "ID") - { - errorString = "Invalid Spawn Effect ID value type"; - - if(PGEFile::IsIntU(param[1])) - spawnEffect.id = toLong(param[1]); - else - goto badfile; - } - else if(param[0] == "SX") - { - errorString = "Invalid Spawn Effect X value type"; - - if(PGEFile::IsFloat(param[1])) - spawnEffect.x = static_cast(toFloat(param[1])); - else - goto badfile; - } - else if(param[0] == "SY") - { - errorString = "Invalid Spawn Effect Y value type"; - - if(PGEFile::IsFloat(param[1])) - spawnEffect.y = static_cast(toFloat(param[1])); - else - goto badfile; - } - else if(param[0] == "SXX") - { - errorString = "Invalid Spawn NPC X expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - spawnEffect.expression_x = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "SYX") - { - errorString = "Invalid Spawn NPC X expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - spawnEffect.expression_y = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "SSX") - { - errorString = "Invalid Spawn NPC X value type"; - - if(PGEFile::IsFloat(param[1])) - spawnEffect.speed_x = toDouble(param[1]); - else - goto badfile; - } - else if(param[0] == "SSY") - { - errorString = "Invalid Spawn NPC Y value type"; - - if(PGEFile::IsFloat(param[1])) - spawnEffect.speed_y = toDouble(param[1]); - else - goto badfile; - } - else if(param[0] == "SSXX") - { - errorString = "Invalid Spawn NPC Speed X expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - spawnEffect.expression_sx = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "SSYX") - { - errorString = "Invalid Spawn NPC Speed Y expression value type"; - - if(PGEFile::IsQoutedString(param[1])) - spawnEffect.expression_sy = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "FP") - { - errorString = "Invalid Spawn Effect FPS value type"; - - if(PGEFile::IsIntS(param[1])) - spawnEffect.fps = toInt(param[1]); - else - goto badfile; - } - else if(param[0] == "TTL") - { - errorString = "Invalid Spawn Effect time to live value type"; - - if(PGEFile::IsIntS(param[1])) - spawnEffect.max_life_time = toInt(param[1]); - else - goto badfile; - } - else if(param[0] == "GT") - { - errorString = "Invalid Spawn Effect Gravity value type"; - - if(PGEFile::IsBool(param[1])) - spawnEffect.gravity = static_cast(toInt(param[1])); - else - goto badfile; - } - }//for parameters - - event.spawn_effects.push_back(spawnEffect); - }//for Spawn Effect - }//If SMBX38A Effect Spawning lists are gotten - - //Parse Variables to update - if(!variablesToUpdate.empty()) - { - for(pge_size_t q = 0; q < variablesToUpdate.size(); q++) - { - LevelEvent_UpdateVariable variableToUpdate; - bool valid = false; - PGELIST mlaData = PGEFile::splitDataLine(variablesToUpdate[q], &valid); - - if(!valid) - { - errorString = "Wrong Variable to update event encoded sub-entry"; - goto badfile; - } - - for(pge_size_t ssi = 0; ssi < mlaData.size(); ssi++) - { - PGESTRINGList ¶m = mlaData[ssi]; - - if(param[0] == "N") - { - errorString = "Invalid Variable to update name value type"; - - if(PGEFile::IsQoutedString(param[1])) - variableToUpdate.name = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - else if(param[0] == "V") - { - errorString = "Invalid Variable to update new value type"; - - if(PGEFile::IsQoutedString(param[1])) - variableToUpdate.newval = PGEFile::X2STRING(param[1]); - else - goto badfile; - } - }//for parameters - - event.update_variable.push_back(variableToUpdate); - }//for Variable update events - }//If SMBX38A variable update lists are gotten - - //Convert boolean array into control flags - // SMBX64-only - if(controls.size() >= 1) event.ctrl_up = controls[0]; - if(controls.size() >= 2) event.ctrl_down = controls[1]; - if(controls.size() >= 3) event.ctrl_left = controls[2]; - if(controls.size() >= 4) event.ctrl_right = controls[3]; //-V112 - if(controls.size() >= 5) event.ctrl_run = controls[4]; - if(controls.size() >= 6) event.ctrl_jump = controls[5]; - if(controls.size() >= 7) event.ctrl_drop = controls[6]; - if(controls.size() >= 8) event.ctrl_start = controls[7]; - if(controls.size() >= 9) event.ctrl_altrun = controls[8]; - if(controls.size() >= 10) event.ctrl_altjump = controls[9]; - // SMBX64-only end - // SMBX-38A begin - if(controls.size() >= 11) event.ctrls_enable = controls[10]; - if(controls.size() >= 12) event.ctrl_lock_keyboard = controls[11]; - // SMBX-38A end - //add captured value into array - bool found = false; - pge_size_t q = 0; - - for(q = 0; q < FileData.events.size(); q++) - { - if(FileData.events[q].name == event.name) - { - found = true; - break; - } - } - - if(found) - { - event.meta.array_id = FileData.events[q].meta.array_id; - FileData.events[q] = event; - } - else - { - event.meta.array_id = FileData.events_array_id++; - FileData.events.push_back(event); - } - } - }//EVENTS_CLASSIC - ///////////////////VARIABLES////////////////////// - PGEX_Section("VARIABLES") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - variable = CreateLvlVariable("unknown"); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_StrVal("N", variable.name) //Variable name - PGEX_StrVal("V", variable.value) //Variable value - } - FileData.variables.push_back(variable); - } - }//VARIABLES - ///////////////////SCRIPTS////////////////////// - PGEX_Section("SCRIPTS") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - script = CreateLvlScript("unknown", LevelScript::LANG_LUA); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_StrVal("N", script.name) //Variable name - PGEX_SIntVal("L", script.language) //Variable name - PGEX_StrVal("S", script.script) //Script text - } - - switch(script.language) - { - case LevelScript::LANG_LUA: - case LevelScript::LANG_TEASCRIPT: - case LevelScript::LANG_AUTOCODE: - break; - - default: - script.language = LevelScript::LANG_LUA; //LUA by default if any other language code! - } - - FileData.variables.push_back(variable); - } - }//SCRIPTS - ///////////////////CUSTOM ITEM CONFIGS (38A)////////////////////// - PGEX_Section("CUSTOM_ITEMS_38A") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - customcfg38A = LevelItemSetup38A(); - PGESTRINGList data; - unsigned int type = 0; - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_UIntVal("T", type) //Type of item - PGEX_UIntVal("ID", customcfg38A.id) - PGEX_StrArrVal("D", data) //Variable value - } - errorString = "Wrong pair syntax"; - for(PGESTRING &s : data) - { - LevelItemSetup38A::Entry e; - PGESTRINGList pair; - PGE_SPLITSTRING(pair, s, "="); - if(pair.size() < 2) - goto badfile; - - if(PGEFile::IsIntU(pair[0])) - e.key = (int32_t)toUInt(pair[0]); - else goto badfile; - - if(PGEFile::IsIntS(pair[1])) - e.value = toLong(pair[1]); - else goto badfile; - - customcfg38A.data.push_back(e); - } - customcfg38A.type = (LevelItemSetup38A::ItemType)type; - FileData.custom38A_configs.push_back(customcfg38A); - } - }//CUSTOM_ITEMS_38A - } - ///////////////////////////////////////EndFile/////////////////////////////////////// - errorString.clear(); //If no errors, clear string; - FileData.meta.ReadFileValid = true; - return true; -badfile: //If file format is not correct - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linenum = in.getCurrentLineNumber(); - FileData.meta.ERROR_linedata = line; - FileData.meta.ReadFileValid = false; - return false; -} - - - -//********************************************************* -//****************WRITE FILE FORMAT************************ -//********************************************************* - -bool FileFormats::WriteExtendedLvlFileF(PGESTRING filePath, LevelData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileOutput file; - - if(!file.open(filePath, true, false, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open file for write"; - return false; - } - - return WriteExtendedLvlFile(file, FileData); -} - -bool FileFormats::WriteExtendedLvlFileRaw(LevelData &FileData, PGESTRING &rawdata) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextOutput file; - - if(!file.open(&rawdata, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open raw string for write"; - return false; - } - - return WriteExtendedLvlFile(file, FileData); -} - -bool FileFormats::WriteExtendedLvlFile(PGE_FileFormats_misc::TextOutput &out, LevelData &FileData) -{ - pge_size_t i; - FileData.meta.RecentFormat = LevelData::PGEX; - //Count placed stars on this level - FileData.stars = 0; - - for(i = 0; i < FileData.npc.size(); i++) - { - if(FileData.npc[i].is_star) - FileData.stars++; - } - - //HEAD section - if((!IsEmpty(FileData.LevelName)) || - (FileData.stars > 0) || - (!IsEmpty(FileData.open_level_on_fail)) || - (FileData.open_level_on_fail_warpID > 0)) - { - out << "HEAD\n"; - - if(!IsEmpty(FileData.LevelName)) - out << PGEFile::value("TL", PGEFile::WriteStr(FileData.LevelName)); // Level title - - out << PGEFile::value("SZ", PGEFile::WriteInt(FileData.stars)); // Stars number - - if(!IsEmpty(FileData.open_level_on_fail)) - out << PGEFile::value("DL", PGEFile::WriteStr(FileData.open_level_on_fail)); // Open level on fail - - if(FileData.open_level_on_fail_warpID > 0) - out << PGEFile::value("DE", PGEFile::WriteInt(FileData.open_level_on_fail_warpID)); // Open WarpID of level on fail - - out << "\n"; - out << "HEAD_END\n"; - } - - //////////////////////////////////////MetaData//////////////////////////////////////////////// - //Bookmarks - if(!FileData.metaData.bookmarks.empty()) - { - out << "META_BOOKMARKS\n"; - - for(i = 0; i < FileData.metaData.bookmarks.size(); i++) - { - Bookmark &bm = FileData.metaData.bookmarks[i]; - //Bookmark name - out << PGEFile::value("BM", PGEFile::WriteStr(bm.bookmarkName)); - out << PGEFile::value("X", PGEFile::WriteRoundFloat(bm.x)); - out << PGEFile::value("Y", PGEFile::WriteRoundFloat(bm.y)); - out << "\n"; - } - - out << "META_BOOKMARKS_END\n"; - } - -#ifdef PGE_EDITOR - - //Some System information - if(FileData.metaData.crash.used) - { - out << "META_SYS_CRASH\n"; - out << PGEFile::value("UT", PGEFile::WriteBool(FileData.metaData.crash.untitled)); - out << PGEFile::value("MD", PGEFile::WriteBool(FileData.metaData.crash.modifyed)); - out << PGEFile::value("FF", PGEFile::WriteInt(FileData.metaData.crash.fmtID)); - out << PGEFile::value("FV", PGEFile::WriteInt(FileData.metaData.crash.fmtVer)); - out << PGEFile::value("N", PGEFile::WriteStr(FileData.metaData.crash.filename)); - out << PGEFile::value("P", PGEFile::WriteStr(FileData.metaData.crash.path)); - out << PGEFile::value("FP", PGEFile::WriteStr(FileData.metaData.crash.fullPath)); - out << "\n"; - out << "META_SYS_CRASH_END\n"; - } - -#endif - //////////////////////////////////////MetaData///END////////////////////////////////////////// - //SECTION section - //Count available level sections - pge_size_t totalSections = 0; - - for(i = 0; i < FileData.sections.size(); i++) - { - LevelSection §ion = FileData.sections[i]; - - if( - (section.size_bottom == 0) && - (section.size_left == 0) && - (section.size_right == 0) && - (section.size_top == 0) - ) - continue; //Skip unitialized sections - - totalSections++; - } - - //Don't store section data entry if no data to add - if(totalSections > 0) - { - out << "SECTION\n"; - - for(i = 0; i < FileData.sections.size(); i++) - { - LevelSection §ion = FileData.sections[i]; - - if( - (section.size_bottom == 0) && - (section.size_left == 0) && - (section.size_right == 0) && - (section.size_top == 0) - ) - continue; //Skip unitialized sections - - out << PGEFile::value("SC", PGEFile::WriteInt(section.id)); // Section ID - out << PGEFile::value("L", PGEFile::WriteInt(section.size_left)); // Left size - out << PGEFile::value("R", PGEFile::WriteInt(section.size_right)); // Right size - out << PGEFile::value("T", PGEFile::WriteInt(section.size_top)); // Top size - out << PGEFile::value("B", PGEFile::WriteInt(section.size_bottom)); // Bottom size - out << PGEFile::value("MZ", PGEFile::WriteInt(section.music_id)); // Music ID - out << PGEFile::value("MF", PGEFile::WriteStr(section.music_file)); // Music file - out << PGEFile::value("BG", PGEFile::WriteInt(section.background)); // Background ID - //out << PGEFile::value("BG", PGEFile::WriteStr(section.background_file)); // Background file - - if(section.wrap_h) - out << PGEFile::value("CS", PGEFile::WriteBool(section.wrap_h)); // Connect sides horizontally - - if(section.wrap_v) - out << PGEFile::value("CSV", PGEFile::WriteBool(section.wrap_v)); // Connect sides vertically - - if(section.OffScreenEn) - out << PGEFile::value("OE", PGEFile::WriteBool(section.OffScreenEn)); // Offscreen exit - - if(section.lock_left_scroll) - out << PGEFile::value("SR", PGEFile::WriteBool(section.lock_left_scroll)); // Right-way scroll only (No Turn-back) - - if(section.lock_right_scroll) - out << PGEFile::value("SL", PGEFile::WriteBool(section.lock_right_scroll)); // Left-way scroll only (No Turn-back) - - if(section.lock_up_scroll) - out << PGEFile::value("SD", PGEFile::WriteBool(section.lock_up_scroll)); // Down-way scroll only (No Turn-back) - - if(section.lock_down_scroll) - out << PGEFile::value("SU", PGEFile::WriteBool(section.lock_down_scroll)); // Up-way scroll only (No Turn-back) - - if(section.underwater) - out << PGEFile::value("UW", PGEFile::WriteBool(section.underwater)); // Underwater bit - - //out << PGEFile::value("SL", PGEFile::WriteBool(section.noforward)); // Left-way scroll only (No Turn-forward) - out << "\n"; - } - - out << "SECTION_END\n"; - } - - //STARTPOINT section - int totalPlayerPoints = 0; - - for(i = 0; i < FileData.players.size(); i++) - { - PlayerPoint &pp = FileData.players[i]; - - if((pp.w == 0) && (pp.h == 0)) - continue; //Skip empty points - - totalPlayerPoints++; - } - - //Don't store section data entry if no data to add - if(totalPlayerPoints > 0) - { - out << "STARTPOINT\n"; - - for(i = 0; i < FileData.players.size(); i++) - { - PlayerPoint &pp = FileData.players[i]; - - if((pp.w == 0) && - (pp.h == 0)) - continue; //Skip empty points - - out << PGEFile::value("ID", PGEFile::WriteInt(pp.id)); // Player ID - out << PGEFile::value("X", PGEFile::WriteInt(pp.x)); // Player X - out << PGEFile::value("Y", PGEFile::WriteInt(pp.y)); // Player Y - out << PGEFile::value("D", PGEFile::WriteInt(pp.direction)); // Direction -1 left, 1 right - out << "\n"; - } - - out << "STARTPOINT_END\n"; - } - - //BLOCK section - if(!FileData.blocks.empty()) - { - out << "BLOCK\n"; - LevelBlock defBlock = CreateLvlBlock(); - - for(i = 0; i < FileData.blocks.size(); i++) - { - LevelBlock &blk = FileData.blocks[i]; - //Type ID - out << PGEFile::value("ID", PGEFile::WriteInt(blk.id)); // Block ID - //Position - out << PGEFile::value("X", PGEFile::WriteInt(blk.x)); // Block X - out << PGEFile::value("Y", PGEFile::WriteInt(blk.y)); // Block Y - //Size - out << PGEFile::value("W", PGEFile::WriteInt(blk.w)); // Block Width (sizable only) - out << PGEFile::value("H", PGEFile::WriteInt(blk.h)); // Block Height (sizable only) - if(blk.autoscale != defBlock.autoscale) - out << PGEFile::value("AS", PGEFile::WriteBool(blk.autoscale));// AutoScale - - if(!IsEmpty(blk.gfx_name)) - out << PGEFile::value("GXN", PGEFile::WriteStr(blk.gfx_name));// 38A GFX-Name - if(blk.gfx_dx > 0) //38A graphics extend x - out << PGEFile::value("GXX", PGEFile::WriteInt(blk.gfx_dx)); // 38A graphics extend x - if(blk.gfx_dy > 0) //38A graphics extend y - out << PGEFile::value("GXX", PGEFile::WriteInt(blk.gfx_dy)); // 38A graphics extend y - - //Included NPC - if(blk.npc_id != 0) //Write only if not zero - out << PGEFile::value("CN", PGEFile::WriteInt(blk.npc_id)); // Included NPC - - //Boolean flags - if(blk.invisible) - out << PGEFile::value("IV", PGEFile::WriteBool(blk.invisible)); // Invisible - if(blk.slippery) - out << PGEFile::value("SL", PGEFile::WriteBool(blk.slippery)); // Slippery flag - //Layer - if(blk.layer != defBlock.layer) //Write only if not default - out << PGEFile::value("LR", PGEFile::WriteStr(blk.layer)); // Layer - //Event Slots - if(!IsEmpty(blk.event_destroy)) - out << PGEFile::value("ED", PGEFile::WriteStr(blk.event_destroy)); - if(!IsEmpty(blk.event_hit)) - out << PGEFile::value("EH", PGEFile::WriteStr(blk.event_hit)); - if(!IsEmpty(blk.event_emptylayer)) - out << PGEFile::value("EE", PGEFile::WriteStr(blk.event_emptylayer)); - if(!IsEmpty(blk.meta.custom_params)) - out << PGEFile::value("XTRA", PGEFile::WriteStr(blk.meta.custom_params)); - - out << "\n"; - } - - out << "BLOCK_END\n"; - } - - //BGO section - if(!FileData.bgo.empty()) - { - out << "BGO\n"; - LevelBGO defBGO = CreateLvlBgo(); - - for(i = 0; i < FileData.bgo.size(); i++) - { - LevelBGO &bgo = FileData.bgo[i]; - out << PGEFile::value("ID", PGEFile::WriteInt(bgo.id)); // BGO ID - //Position - out << PGEFile::value("X", PGEFile::WriteInt(bgo.x)); // BGO X - out << PGEFile::value("Y", PGEFile::WriteInt(bgo.y)); // BGO Y - if(bgo.gfx_dx > 0) //38A graphics extend x - out << PGEFile::value("GXX", PGEFile::WriteInt(bgo.gfx_dx)); // 38A graphics extend x - if(bgo.gfx_dy > 0) //38A graphics extend y - out << PGEFile::value("GXX", PGEFile::WriteInt(bgo.gfx_dy)); // 38A graphics extend y - if(fabs(bgo.z_offset - defBGO.z_offset) > DBL_EPSILON) - out << PGEFile::value("ZO", PGEFile::WriteFloat(bgo.z_offset)); // BGO Z-Offset - if(bgo.z_mode != defBGO.z_mode) - out << PGEFile::value("ZP", PGEFile::WriteInt(bgo.z_mode)); // BGO Z-Mode - if(bgo.smbx64_sp != -1) - out << PGEFile::value("SP", PGEFile::WriteInt(bgo.smbx64_sp)); // BGO SMBX64 Sort Priority - if(bgo.layer != defBGO.layer) //Write only if not default - out << PGEFile::value("LR", PGEFile::WriteStr(bgo.layer)); // Layer - if(!IsEmpty(bgo.meta.custom_params)) - out << PGEFile::value("XTRA", PGEFile::WriteStr(bgo.meta.custom_params)); - out << "\n"; - } - - out << "BGO_END\n"; - } - - //NPC section - if(!FileData.npc.empty()) - { - out << "NPC\n"; - LevelNPC defNPC = CreateLvlNpc(); - - for(i = 0; i < FileData.npc.size(); i++) - { - LevelNPC &npc = FileData.npc[i]; - out << PGEFile::value("ID", PGEFile::WriteInt(npc.id)); // NPC ID - //Position - out << PGEFile::value("X", PGEFile::WriteInt(npc.x)); // NPC X - out << PGEFile::value("Y", PGEFile::WriteInt(npc.y)); // NPC Y - - if(!IsEmpty(npc.gfx_name)) - out << PGEFile::value("GXN", PGEFile::WriteStr(npc.gfx_name));// 38A GFX-Name - if(npc.gfx_dx > 0) //38A graphics extend x - out << PGEFile::value("GXX", PGEFile::WriteInt(npc.gfx_dx)); // 38A graphics extend x - if(npc.gfx_dy > 0) //38A graphics extend y - out << PGEFile::value("GXX", PGEFile::WriteInt(npc.gfx_dy)); // 38A graphics extend y - - out << PGEFile::value("D", PGEFile::WriteInt(npc.direct)); // NPC Direction - - if(npc.contents != 0) - out << PGEFile::value("CN", PGEFile::WriteInt(npc.contents)); // Contents of container - if(npc.special_data != defNPC.special_data) - out << PGEFile::value("S1", PGEFile::WriteInt(npc.special_data)); // Special value 1 - if(npc.special_data2 != defNPC.special_data2) - out << PGEFile::value("S2", PGEFile::WriteInt(npc.special_data2)); // Special value 2 - - if(npc.generator) - { - out << PGEFile::value("GE", PGEFile::WriteBool(npc.generator)); // NPC Generator - out << PGEFile::value("GT", PGEFile::WriteInt(npc.generator_type)); // Generator type - out << PGEFile::value("GD", PGEFile::WriteInt(npc.generator_direct)); // Generator direct - out << PGEFile::value("GM", PGEFile::WriteInt(npc.generator_period)); // Generator time - - if(npc.generator_direct == 0) - { - out << PGEFile::value("GA", PGEFile::WriteFloat(npc.generator_custom_angle)); // Generator custom angle - out << PGEFile::value("GB", PGEFile::WriteInt(npc.generator_branches)); // Generator branches - out << PGEFile::value("GR", PGEFile::WriteFloat(npc.generator_angle_range)); // Generator angle range - out << PGEFile::value("GS", PGEFile::WriteFloat(npc.generator_initial_speed)); // Generator initial speed - } - } - - if(!IsEmpty(npc.msg)) - out << PGEFile::value("MG", PGEFile::WriteStr(npc.msg)); // Message - if(npc.friendly) - out << PGEFile::value("FD", PGEFile::WriteBool(npc.friendly)); // Friendly - if(npc.nomove) - out << PGEFile::value("NM", PGEFile::WriteBool(npc.nomove)); // Idle - if(npc.is_boss) - out << PGEFile::value("BS", PGEFile::WriteBool(npc.is_boss)); // Set as boss - if(npc.layer != defNPC.layer) //Write only if not default - out << PGEFile::value("LR", PGEFile::WriteStr(npc.layer)); // Layer - if(!IsEmpty(npc.attach_layer)) - out << PGEFile::value("LA", PGEFile::WriteStr(npc.attach_layer)); // Attach layer - if(!IsEmpty(npc.send_id_to_variable)) - out << PGEFile::value("SV", PGEFile::WriteStr(npc.send_id_to_variable)); //Send ID to variable - - //Event slots - if(!IsEmpty(npc.event_activate)) - out << PGEFile::value("EA", PGEFile::WriteStr(npc.event_activate)); - if(!IsEmpty(npc.event_die)) - out << PGEFile::value("ED", PGEFile::WriteStr(npc.event_die)); - if(!IsEmpty(npc.event_talk)) - out << PGEFile::value("ET", PGEFile::WriteStr(npc.event_talk)); - if(!IsEmpty(npc.event_emptylayer)) - out << PGEFile::value("EE", PGEFile::WriteStr(npc.event_emptylayer)); - if(!IsEmpty(npc.event_grab)) - out << PGEFile::value("EG", PGEFile::WriteStr(npc.event_grab)); - if(!IsEmpty(npc.event_touch)) - out << PGEFile::value("EO", PGEFile::WriteStr(npc.event_touch)); - if(!IsEmpty(npc.event_touch)) - out << PGEFile::value("EF", PGEFile::WriteStr(npc.event_nextframe)); - if(!IsEmpty(npc.meta.custom_params)) - out << PGEFile::value("XTRA", PGEFile::WriteStr(npc.meta.custom_params)); - - out << "\n"; - } - - out << "NPC_END\n"; - } - - //PHYSICS section - if(!FileData.physez.empty()) - { - out << "PHYSICS\n"; - LevelPhysEnv defPhys = CreateLvlPhysEnv(); - - for(i = 0; i < FileData.physez.size(); i++) - { - LevelPhysEnv &physEnv = FileData.physez[i]; - out << PGEFile::value("ET", PGEFile::WriteInt(physEnv.env_type)); - //Position - out << PGEFile::value("X", PGEFile::WriteInt(physEnv.x)); // Physic Env X - out << PGEFile::value("Y", PGEFile::WriteInt(physEnv.y)); // Physic Env Y - //Size - out << PGEFile::value("W", PGEFile::WriteInt(physEnv.w)); // Physic Env Width - out << PGEFile::value("H", PGEFile::WriteInt(physEnv.h)); // Physic Env Height - - if(physEnv.env_type == LevelPhysEnv::ENV_CUSTOM_LIQUID) - out << PGEFile::value("FR", PGEFile::WriteFloat(physEnv.friction)); //Friction - if(physEnv.accel_direct >= 0.0) - out << PGEFile::value("AD", PGEFile::WriteFloat(physEnv.accel_direct)); //Acceleration direction - if(physEnv.accel != 0.0) - out << PGEFile::value("AC", PGEFile::WriteFloat(physEnv.accel)); //Acceleration - if(physEnv.max_velocity != 0.0) - out << PGEFile::value("MV", PGEFile::WriteFloat(physEnv.max_velocity)); //Max-velocity - if(physEnv.layer != defPhys.layer) //Write only if not default - out << PGEFile::value("LR", PGEFile::WriteStr(physEnv.layer)); // Layer - if(!IsEmpty(physEnv.touch_event)) - out << PGEFile::value("EO", PGEFile::WriteStr(physEnv.touch_event)); // Touch event slot - if(!IsEmpty(physEnv.meta.custom_params)) - out << PGEFile::value("XTRA", PGEFile::WriteStr(physEnv.meta.custom_params)); - - out << "\n"; - } - - out << "PHYSICS_END\n"; - } - - //DOORS section - if(!FileData.doors.empty()) - { - out << "DOORS\n"; - LevelDoor defDoor = CreateLvlWarp(); - - for(i = 0; i < FileData.doors.size(); i++) - { - LevelDoor &warp = FileData.doors[i]; - - if(((!warp.lvl_o) && (!warp.lvl_i)) || ((warp.lvl_o) && (!warp.lvl_i))) - if(!warp.isSetIn) continue; // Skip broken door - - if(((!warp.lvl_o) && (!warp.lvl_i)) || ((warp.lvl_i))) - if(!warp.isSetOut) continue; // Skip broken door - - //Entrance - if(warp.isSetIn) - { - out << PGEFile::value("IX", PGEFile::WriteInt(warp.ix)); // Warp Input X - out << PGEFile::value("IY", PGEFile::WriteInt(warp.iy)); // Warp Input Y - } - - if(warp.isSetOut) - { - out << PGEFile::value("OX", PGEFile::WriteInt(warp.ox)); // Warp Output X - out << PGEFile::value("OY", PGEFile::WriteInt(warp.oy)); // Warp Output Y - } - - if(warp.length_i != 32) //-V112 - out << PGEFile::value("IL", PGEFile::WriteInt(warp.length_i)); //Length of entrance - - if(warp.length_o != 32) //-V112 - out << PGEFile::value("OL", PGEFile::WriteInt(warp.length_o)); //Length of exit - - out << PGEFile::value("DT", PGEFile::WriteInt(warp.type)); // Warp type - out << PGEFile::value("ID", PGEFile::WriteInt(warp.idirect)); // Warp Input direction - out << PGEFile::value("OD", PGEFile::WriteInt(warp.odirect)); // Warp Outpu direction - - if(warp.world_x != -1 && warp.world_y != -1) - { - out << PGEFile::value("WX", PGEFile::WriteInt(warp.world_x)); // World X - out << PGEFile::value("WY", PGEFile::WriteInt(warp.world_y)); // World Y - } - - if(!IsEmpty(warp.lname)) - { - out << PGEFile::value("LF", PGEFile::WriteStr(warp.lname)); // Warp to level file - out << PGEFile::value("LI", PGEFile::WriteInt(warp.warpto)); // Warp arrayID - } - - if(warp.lvl_i) - out << PGEFile::value("ET", PGEFile::WriteBool(warp.lvl_i)); // Level Entance - if(warp.lvl_o) - out << PGEFile::value("EX", PGEFile::WriteBool(warp.lvl_o)); // Level Exit - if(warp.stars > 0) - out << PGEFile::value("SL", PGEFile::WriteInt(warp.stars)); // Need a stars - if(!IsEmpty(warp.stars_msg)) - out << PGEFile::value("SM", PGEFile::WriteStr(warp.stars_msg)); // Message for start requirement - if(warp.star_num_hide) - out << PGEFile::value("SH", PGEFile::WriteBool(warp.star_num_hide)); // Don't show number of stars - if(warp.novehicles) - out << PGEFile::value("NV", PGEFile::WriteBool(warp.novehicles)); // Deny Vehicles - if(warp.allownpc) - out << PGEFile::value("AI", PGEFile::WriteBool(warp.allownpc)); // Allow Items - if(warp.locked) - out << PGEFile::value("LC", PGEFile::WriteBool(warp.locked)); // Locked door - if(warp.need_a_bomb) - out << PGEFile::value("LB", PGEFile::WriteBool(warp.need_a_bomb)); //Need a bomb to open door - if(warp.hide_entering_scene) - out << PGEFile::value("HS", PGEFile::WriteBool(warp.hide_entering_scene)); //Hide entrance scene - if(warp.allownpc_interlevel) - out << PGEFile::value("AL", PGEFile::WriteBool(warp.allownpc_interlevel)); //Allow Items inter-level - if(warp.special_state_required) - out << PGEFile::value("SR", PGEFile::WriteBool(warp.special_state_required));//Special state required - if(warp.cannon_exit) - { - out << PGEFile::value("PT", PGEFile::WriteBool(warp.cannon_exit));//cannon exit - out << PGEFile::value("PS", PGEFile::WriteFloat(warp.cannon_exit_speed));//cannon exit projectile speed - } - if(warp.layer != defDoor.layer) //Write only if not default - out << PGEFile::value("LR", PGEFile::WriteStr(warp.layer)); // Layer - if(!IsEmpty(warp.event_enter)) //Write only if not default - out << PGEFile::value("EE", PGEFile::WriteStr(warp.event_enter)); // On-Enter event - if(warp.two_way) - out << PGEFile::value("TW", PGEFile::WriteBool(warp.two_way)); //Two-way warp - if(!IsEmpty(warp.meta.custom_params)) - out << PGEFile::value("XTRA", PGEFile::WriteStr(warp.meta.custom_params)); - - out << "\n"; - } - - out << "DOORS_END\n"; - } - - //LAYERS section - if(!FileData.layers.empty()) - { - out << "LAYERS\n"; - - for(i = 0; i < FileData.layers.size(); i++) - { - LevelLayer &layer = FileData.layers[i]; - out << PGEFile::value("LR", PGEFile::WriteStr(layer.name)); // Layer name - - if(layer.hidden) - out << PGEFile::value("HD", PGEFile::WriteBool(layer.hidden)); // Hidden - - if(layer.locked) - out << PGEFile::value("LC", PGEFile::WriteBool(layer.locked)); // Locked - - out << "\n"; - } - - out << "LAYERS_END\n"; - } - - //EVENTS section (action styled) - //EVENT sub-section of action-styled events - - //EVENTS_CLASSIC (SMBX-Styled events) - if(!FileData.events.empty()) - { - out << "EVENTS_CLASSIC\n"; - bool addArray = false; - - for(i = 0; i < FileData.events.size(); i++) - { - LevelSMBX64Event &event = FileData.events[i]; - out << PGEFile::value("ET", PGEFile::WriteStr(event.name)); // Event name - - if(!IsEmpty(event.msg)) - out << PGEFile::value("MG", PGEFile::WriteStr(event.msg)); // Show Message - - if(event.sound_id != 0) - out << PGEFile::value("SD", PGEFile::WriteInt(event.sound_id)); // Play Sound ID - - if(event.end_game != 0) - out << PGEFile::value("EG", PGEFile::WriteInt(event.end_game)); // End game - - if(!event.layers_hide.empty()) - out << PGEFile::value("LH", PGEFile::WriteStrArr(event.layers_hide)); // Hide Layers - - if(!event.layers_show.empty()) - out << PGEFile::value("LS", PGEFile::WriteStrArr(event.layers_show)); // Show Layers - - if(!event.layers_toggle.empty()) - out << PGEFile::value("LT", PGEFile::WriteStrArr(event.layers_toggle)); // Toggle Layers - - /* - PGESTRINGList musicSets; - addArray=false; - for(int ttt=0; ttt<(signed)event.sets.size(); ttt++) - { - musicSets.push_back(fromNum(event.sets[ttt].music_id)); - } - for(int tt=0; tt<(signed)musicSets.size(); tt++) - { if(musicSets[tt]!="-1") addArray=true; } - - if(addArray) out << PGEFile::value("SM", PGEFile::WriteStrArr(musicSets)); // Change section's musics - - - addArray=false; - for(int ttt=0; ttt<(signed)event.sets.size(); ttt++) - { - musicSets.push_back(event.sets[ttt].music_file); - } - for(int tt=0; tt<(signed)musicSets.size(); tt++) - { if(!musicSets[tt].PGESTRINGisEmpty()) addArray=true; } - - if(addArray) out << PGEFile::value("SMF", PGEFile::WriteStrArr(musicSets)); // Change section's music files - - - PGESTRINGList backSets; - addArray=false; - for(int tt=0; tt<(signed)event.sets.size(); tt++) - { - backSets.push_back(fromNum(event.sets[tt].background_id)); - } - for(int tt=0; tt<(signed)backSets.size(); tt++) - { if(backSets[tt]!="-1") addArray=true; } - - if(addArray) out << PGEFile::value("SB", PGEFile::WriteStrArr(backSets)); // Change section's backgrounds - - - PGESTRINGList sizeSets; - addArray=false; - for(int tt=0; tt<(signed)event.sets.size(); tt++) - { - LevelEvent_Sets &x=event.sets[tt]; - QString sizeSect= fromNum(x.position_left)+","+ - fromNum(x.position_top)+","+ - fromNum(x.position_bottom)+","+ - fromNum(x.position_right); - if(sizeSect != "-1,0,0,0") - addArray=true; - sizeSets.push_back(sizeSect); - } - if(addArray) - out << PGEFile::value("SS", PGEFile::WriteStrArr(sizeSets));// Change section's sizes - */ - PGESTRINGList sectionSettingsSets; - - for(pge_size_t tt = 0; tt < event.sets.size(); tt++) - { - bool hasParams = false; - PGESTRING sectionSettings; - LevelEvent_Sets &x = event.sets[tt]; - sectionSettings += PGEFile::value("ID", PGEFile::WriteInt(x.id)); - bool customSize = (x.position_left != LevelEvent_Sets::LESet_Nothing) && - (x.position_left != LevelEvent_Sets::LESet_ResetDefault); - - if(x.position_left != -1) - { - sectionSettings += PGEFile::value("SL", PGEFile::WriteInt(x.position_left)); - hasParams = true; - } - - if(customSize && (x.position_top != 0)) - { - sectionSettings += PGEFile::value("ST", PGEFile::WriteInt(x.position_top)); - hasParams = true; - } - - if(customSize && (x.position_bottom != 0)) - { - sectionSettings += PGEFile::value("SB", PGEFile::WriteInt(x.position_bottom)); - hasParams = true; - } - - if(customSize && (x.position_right != 0)) - { - sectionSettings += PGEFile::value("SR", PGEFile::WriteInt(x.position_right)); - hasParams = true; - } - - if(!IsEmpty(x.expression_pos_x) && (x.expression_pos_x != "0")) - { - sectionSettings += PGEFile::value("SXX", PGEFile::WriteStr(x.expression_pos_x)); - hasParams = true; - } - - if(!IsEmpty(x.expression_pos_y) && (x.expression_pos_y != "0")) - { - sectionSettings += PGEFile::value("SYX", PGEFile::WriteStr(x.expression_pos_y)); - hasParams = true; - } - - if(!IsEmpty(x.expression_pos_w) && (x.expression_pos_w != "0")) - { - sectionSettings += PGEFile::value("SWX", PGEFile::WriteStr(x.expression_pos_w)); - hasParams = true; - } - - if(!IsEmpty(x.expression_pos_h) && (x.expression_pos_h != "0")) - { - sectionSettings += PGEFile::value("SHX", PGEFile::WriteStr(x.expression_pos_h)); - hasParams = true; - } - - if(x.music_id != LevelEvent_Sets::LESet_Nothing) - { - sectionSettings += PGEFile::value("MI", PGEFile::WriteInt(x.music_id)); - hasParams = true; - } - - if(!IsEmpty(x.music_file)) - { - sectionSettings += PGEFile::value("MF", PGEFile::WriteStr(x.music_file)); - hasParams = true; - } - - if(x.background_id != LevelEvent_Sets::LESet_Nothing) - { - sectionSettings += PGEFile::value("BG", PGEFile::WriteInt(x.background_id)); - hasParams = true; - } - - if(x.autoscrol) - { - sectionSettings += PGEFile::value("AS", PGEFile::WriteBool(x.autoscrol)); - hasParams = true; - } - - if(x.autoscrol_x != 0.0f) - { - sectionSettings += PGEFile::value("AX", PGEFile::WriteFloat(x.autoscrol_x)); - hasParams = true; - } - - if(x.autoscrol_y != 0.0f) - { - sectionSettings += PGEFile::value("AY", PGEFile::WriteFloat(x.autoscrol_y)); - hasParams = true; - } - - if(!IsEmpty(x.expression_autoscrool_x) && (x.expression_autoscrool_x != "0")) - { - sectionSettings += PGEFile::value("AXX", PGEFile::WriteStr(x.expression_autoscrool_x)); - hasParams = true; - } - - if(!IsEmpty(x.expression_autoscrool_y) && (x.expression_autoscrool_y != "0")) - { - sectionSettings += PGEFile::value("AYX", PGEFile::WriteStr(x.expression_autoscrool_y)); - hasParams = true; - } - - if(hasParams) - sectionSettingsSets.push_back(sectionSettings); - } - - if(!sectionSettingsSets.empty()) - out << PGEFile::value("SSS", PGEFile::WriteStrArr(sectionSettingsSets));//Change section's settings - - if(!IsEmpty(event.trigger)) - { - out << PGEFile::value("TE", PGEFile::WriteStr(event.trigger)); // Trigger Event - - if(event.trigger_timer > 0) - out << PGEFile::value("TD", PGEFile::WriteInt(event.trigger_timer)); // Trigger delay - } - - if(!IsEmpty(event.trigger_script)) - out << PGEFile::value("TSCR", PGEFile::WriteStr(event.trigger_script)); - - if(event.trigger_api_id != 0) - out << PGEFile::value("TAPI", PGEFile::WriteInt(event.trigger_api_id)); - - if(event.nosmoke) - out << PGEFile::value("DS", PGEFile::WriteBool(event.nosmoke)); // Disable Smoke - - if(event.autostart > 0) - out << PGEFile::value("AU", PGEFile::WriteInt(event.autostart)); // Autostart event - - if(!IsEmpty(event.autostart_condition)) - out << PGEFile::value("AUC", PGEFile::WriteStr(event.autostart_condition)); // Autostart condition event - - PGELIST controls; - controls.push_back(event.ctrl_up); - controls.push_back(event.ctrl_down); - controls.push_back(event.ctrl_left); - controls.push_back(event.ctrl_right); - controls.push_back(event.ctrl_run); - controls.push_back(event.ctrl_jump); - controls.push_back(event.ctrl_drop); - controls.push_back(event.ctrl_start); - controls.push_back(event.ctrl_altrun); - controls.push_back(event.ctrl_altjump); - controls.push_back(event.ctrls_enable); - controls.push_back(event.ctrl_lock_keyboard); - addArray = false; - - for(pge_size_t tt = 0; tt < controls.size(); tt++) - { - if(controls[tt]) addArray = true; - } - - if(addArray) out << PGEFile::value("PC", PGEFile::WriteBoolArr(controls)); // Create boolean array - - if(!IsEmpty(event.movelayer)) - { - out << PGEFile::value("ML", PGEFile::WriteStr(event.movelayer)); // Move layer - out << PGEFile::value("MX", PGEFile::WriteFloat(event.layer_speed_x)); // Move layer X - out << PGEFile::value("MY", PGEFile::WriteFloat(event.layer_speed_y)); // Move layer Y - } - - if(!event.moving_layers.empty()) - { - PGESTRINGList moveLayers; - - for(pge_size_t j = 0; j < event.moving_layers.size(); j++) - { - LevelEvent_MoveLayer &mvl = event.moving_layers[j]; - PGESTRING moveLayer; - - if(IsEmpty(mvl.name)) - continue; - - moveLayer += PGEFile::value("LN", PGEFile::WriteStr(mvl.name)); - - if(mvl.speed_x != 0.0) - moveLayer += PGEFile::value("SX", PGEFile::WriteFloat(mvl.speed_x)); - - if(!IsEmpty(mvl.expression_x) && (mvl.expression_x != "0")) - moveLayer += PGEFile::value("SXX", PGEFile::WriteStr(mvl.expression_x)); - - if(mvl.speed_y != 0.0) - moveLayer += PGEFile::value("SY", PGEFile::WriteFloat(mvl.speed_y)); - - if(!IsEmpty(mvl.expression_y) && (mvl.expression_y != "0")) - moveLayer += PGEFile::value("SYX", PGEFile::WriteStr(mvl.expression_y)); - - if(mvl.way != 0) - moveLayer += PGEFile::value("MW", PGEFile::WriteInt(mvl.way)); - - moveLayers.push_back(moveLayer); - } - - out << PGEFile::value("MLA", PGEFile::WriteStrArr(moveLayers)); - } - - //NPC's to spawn - if(!event.spawn_npc.empty()) - { - PGESTRINGList spawnNPCs; - - for(pge_size_t j = 0; j < event.spawn_npc.size(); j++) - { - PGESTRING spawnNPC; - LevelEvent_SpawnNPC &npc = event.spawn_npc[j]; - spawnNPC += PGEFile::value("ID", PGEFile::WriteInt(npc.id)); - - if(npc.x != 0) - spawnNPC += PGEFile::value("SX", PGEFile::WriteInt(npc.x)); - - if(!IsEmpty(npc.expression_x) && (npc.expression_x != "0")) - spawnNPC += PGEFile::value("SXX", PGEFile::WriteStr(npc.expression_x)); - - if(npc.y != 0) - spawnNPC += PGEFile::value("SY", PGEFile::WriteInt(npc.y)); - - if(!IsEmpty(npc.expression_y) && (npc.expression_y != "0")) - spawnNPC += PGEFile::value("SYX", PGEFile::WriteStr(npc.expression_y)); - - if(npc.speed_x != 0.0) - spawnNPC += PGEFile::value("SSX", PGEFile::WriteFloat(npc.speed_x)); - - if(!IsEmpty(npc.expression_sx) && (npc.expression_sx != "0")) - spawnNPC += PGEFile::value("SSXX", PGEFile::WriteStr(npc.expression_sx)); - - if(npc.speed_y != 0.0) - spawnNPC += PGEFile::value("SSY", PGEFile::WriteFloat(npc.speed_y)); - - if(!IsEmpty(npc.expression_sy) && (npc.expression_sy != "0")) - spawnNPC += PGEFile::value("SSYX", PGEFile::WriteStr(npc.expression_sy)); - - if(npc.special != 0) - spawnNPC += PGEFile::value("SSS", PGEFile::WriteInt(npc.special)); - - spawnNPCs.push_back(spawnNPC); - } - - out << PGEFile::value("SNPC", PGEFile::WriteStrArr(spawnNPCs)); - } - - //Effects to spawn - if(!event.spawn_effects.empty()) - { - PGESTRINGList spawnEffects; - - for(pge_size_t j = 0; j < event.spawn_effects.size(); j++) - { - PGESTRING spawnEffect; - LevelEvent_SpawnEffect &effect = event.spawn_effects[j]; - spawnEffect += PGEFile::value("ID", PGEFile::WriteInt(effect.id)); - - if(effect.x != 0) - spawnEffect += PGEFile::value("SX", PGEFile::WriteInt(effect.x)); - if(!IsEmpty(effect.expression_x) && (effect.expression_x != "0")) - spawnEffect += PGEFile::value("SXX", PGEFile::WriteStr(effect.expression_x)); - if(effect.y != 0) - spawnEffect += PGEFile::value("SY", PGEFile::WriteInt(effect.y)); - if(!IsEmpty(effect.expression_y) && (effect.expression_y != "0")) - spawnEffect += PGEFile::value("SYX", PGEFile::WriteStr(effect.expression_y)); - if(effect.speed_x != 0.0) - spawnEffect += PGEFile::value("SSX", PGEFile::WriteFloat(effect.speed_x)); - if(!IsEmpty(effect.expression_sx) && (effect.expression_sx != "0")) - spawnEffect += PGEFile::value("SSXX", PGEFile::WriteStr(effect.expression_sx)); - if(effect.speed_y != 0.0) - spawnEffect += PGEFile::value("SSY", PGEFile::WriteFloat(effect.speed_y)); - if(!IsEmpty(effect.expression_sy) && (effect.expression_sy != "0")) - spawnEffect += PGEFile::value("SSYX", PGEFile::WriteStr(effect.expression_sy)); - if(effect.fps != 0) - spawnEffect += PGEFile::value("FP", PGEFile::WriteInt(effect.fps)); - if(effect.max_life_time != 0) - spawnEffect += PGEFile::value("TTL", PGEFile::WriteInt(effect.max_life_time)); - if(effect.gravity) - spawnEffect += PGEFile::value("GT", PGEFile::WriteBool(effect.gravity)); - spawnEffects.push_back(spawnEffect); - } - - out << PGEFile::value("SEF", PGEFile::WriteStrArr(spawnEffects)); - } - - out << PGEFile::value("AS", PGEFile::WriteInt(event.scroll_section)); // Move camera - out << PGEFile::value("AX", PGEFile::WriteFloat(event.move_camera_x)); // Move camera x - out << PGEFile::value("AY", PGEFile::WriteFloat(event.move_camera_y)); // Move camera y - - //Variables to update - if(!event.update_variable.empty()) - { - PGESTRINGList updateVars; - - for(pge_size_t j = 0; j < event.update_variable.size(); j++) - { - PGESTRING updateVar; - LevelEvent_UpdateVariable &updVar = event.update_variable[j]; - updateVar += PGEFile::value("N", PGEFile::WriteStr(updVar.name)); - updateVar += PGEFile::value("V", PGEFile::WriteStr(updVar.newval)); - updateVars.push_back(updateVar); - } - - out << PGEFile::value("UV", PGEFile::WriteStrArr(updateVars)); - } - - if(event.timer_def.enable) - { - out << PGEFile::value("TMR", PGEFile::WriteBool(event.timer_def.enable)); //Enable timer - out << PGEFile::value("TMC", PGEFile::WriteInt(event.timer_def.count)); //Time left (ticks) - out << PGEFile::value("TMI", PGEFile::WriteFloat(event.timer_def.interval)); //Tick Interval - out << PGEFile::value("TMD", PGEFile::WriteInt(event.timer_def.count_dir)); //Count direction - out << PGEFile::value("TMV", PGEFile::WriteBool(event.timer_def.show)); //Is timer vizible - } - - out << "\n"; - } - - out << "EVENTS_CLASSIC_END\n"; - - //VARIABLES section - if(!FileData.variables.empty()) - { - out << "VARIABLES\n"; - - for(auto &var : FileData.variables) - { - out << PGEFile::value("N", PGEFile::WriteStr(var.name)); // Variable name - if(!IsEmpty(var.value)) - out << PGEFile::value("V", PGEFile::WriteStr(var.value)); // Value - out << "\n"; - } - - out << "VARIABLES_END\n"; - } - - //SCRIPTS section - if(!FileData.scripts.empty()) - { - out << "SCRIPTS\n"; - - for(auto &script : FileData.scripts) - { - out << PGEFile::value("N", PGEFile::WriteStr(script.name)); // Variable name - out << PGEFile::value("L", PGEFile::WriteInt(script.language));// Code of language - if(!IsEmpty(script.script)) - out << PGEFile::value("S", PGEFile::WriteStr(script.script)); // Script text - out << "\n"; - } - - out << "SCRIPTS_END\n"; - } - - //CUSTOM_ITEMS_38A section - if(!FileData.custom38A_configs.empty()) - { - out << "CUSTOM_ITEMS_38A\n"; - for(auto &cfg : FileData.custom38A_configs) - { - out << PGEFile::value("T", PGEFile::WriteInt(cfg.type)); - out << PGEFile::value("ID", PGEFile::WriteInt(cfg.id)); - PGESTRINGList data; - for(auto &e : cfg.data) - data.push_back( PGEFile::WriteInt(e.key) + "=" + PGEFile::WriteInt(e.value)); - out << PGEFile::value("D", PGEFile::WriteStrArr(data)); - out << "\n"; - } - out << "CUSTOM_ITEMS_38A_END\n"; - } - } - - return true; -} diff --git a/LunaDll/libs/PGE_File_Formats/file_rw_meta.cpp b/LunaDll/libs/PGE_File_Formats/file_rw_meta.cpp deleted file mode 100644 index 8582e8bf2..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_rw_meta.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "file_formats.h" -#include "file_strlist.h" -#include "pge_x.h" - -//********************************************************* -//****************READ FILE FORMAT************************* -//********************************************************* - -bool FileFormats::ReadNonSMBX64MetaDataF(PGESTRING filePath, MetaData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileInput file; - - if(!file.open(filePath, true)) - { - errorString = "Failed to open file for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadNonSMBX64MetaDataFile(file, FileData); -} - -bool FileFormats::ReadNonSMBX64MetaDataRaw(PGESTRING &rawdata, PGESTRING filePath, MetaData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextInput file; - - if(!file.open(&rawdata, filePath)) - { - errorString = "Failed to open raw string for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadNonSMBX64MetaDataFile(file, FileData); -} - -bool FileFormats::ReadNonSMBX64MetaDataFile(PGE_FileFormats_misc::TextInput &in, MetaData &FileData) -{ - PGESTRING errorString; - int str_count = 0; //Line Counter - PGESTRING line; //Current Line data - ///////////////////////////////////////Begin file/////////////////////////////////////// - PGEFile pgeX_Data(in.readAll()); - - if(!pgeX_Data.buildTreeFromRaw()) - { - errorString = pgeX_Data.lastError(); - goto badfile; - } - - for(pge_size_t section = 0; section < pgeX_Data.dataTree.size(); section++) //look sections - { - PGEFile::PGEX_Entry &f_section = pgeX_Data.dataTree[section]; - - if(f_section.name == "META_BOOKMARKS") - { - if(f_section.type != PGEFile::PGEX_Struct) - { - errorString = PGESTRING("Wrong section data syntax:\nSection [") + f_section.name + "%1]"; - goto badfile; - } - - for(pge_size_t sdata = 0; sdata < f_section.data.size(); sdata++) - { - if(f_section.data[sdata].type != PGEFile::PGEX_Struct) - { - errorString = PGESTRING("Wrong data item syntax:\nSection [") + - f_section.name + "]\nData line " + - fromNum(sdata) + ")"; - goto badfile; - } - - PGEFile::PGEX_Item x = f_section.data[sdata]; - Bookmark meta_bookmark; - meta_bookmark.bookmarkName = ""; - meta_bookmark.x = 0; - meta_bookmark.y = 0; - - for(pge_size_t sval = 0; sval < x.values.size(); sval++) //Look markers and values - { - PGEFile::PGEX_Val v = x.values[sval]; - errorString = PGESTRING("Wrong value syntax\nSection [") + - f_section.name + "]\nData line " + - fromNum(sdata) + "\nMarker " + - v.marker + "\nValue " + - v.value; - - if(v.marker == "BM") //Bookmark name - { - if(PGEFile::IsQoutedString(v.value)) - meta_bookmark.bookmarkName = PGEFile::X2STRING(v.value); - else - goto badfile; - } - else if(v.marker == "X") // Position X - { - if(PGEFile::IsIntS(v.value)) - meta_bookmark.x = toInt(v.value); - else - goto badfile; - } - else if(v.marker == "Y") //Position Y - { - if(PGEFile::IsIntS(v.value)) - meta_bookmark.y = toInt(v.value); - else - goto badfile; - } - } - - FileData.bookmarks.push_back(meta_bookmark); - } - } - } - - ///////////////////////////////////////EndFile/////////////////////////////////////// - errorString.clear(); //If no errors, clear string; - FileData.meta.ReadFileValid = true; - return true; -badfile: //If file format is not correct - //BadFileMsg(filePath+"\nError message: "+errorString, str_count, line); - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linenum = str_count; - FileData.meta.ERROR_linedata = line; - FileData.meta.ReadFileValid = false; - FileData.bookmarks.clear(); - return false; -} - - - - - - -//********************************************************* -//****************WRITE FILE FORMAT************************ -//********************************************************* - -bool FileFormats::WriteNonSMBX64MetaDataF(PGESTRING filePath, MetaData &metaData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileOutput file; - - if(!file.open(filePath, true, false, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open file for write"; - return false; - } - - return WriteNonSMBX64MetaData(file, metaData); -} - -bool FileFormats::WriteNonSMBX64MetaDataRaw(MetaData &metaData, PGESTRING &rawdata) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextOutput file; - - if(!file.open(&rawdata, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open raw string for write"; - return false; - } - - return WriteNonSMBX64MetaData(file, metaData); -} - -bool FileFormats::WriteNonSMBX64MetaData(PGE_FileFormats_misc::TextOutput &out, MetaData &metaData) -{ - pge_size_t i; - - //Bookmarks - if(!metaData.bookmarks.empty()) - { - out << "META_BOOKMARKS\n"; - - for(i = 0; i < metaData.bookmarks.size(); i++) - { - Bookmark &bm = metaData.bookmarks[i]; - //Bookmark name - out << PGEFile::value("BM", PGEFile::WriteStr(bm.bookmarkName)); - out << PGEFile::value("X", PGEFile::WriteRoundFloat(bm.x)); - out << PGEFile::value("Y", PGEFile::WriteRoundFloat(bm.y)); - out << "\n"; - } - - out << "META_BOOKMARKS_END\n"; - } - - return true; -} diff --git a/LunaDll/libs/PGE_File_Formats/file_rw_npc_txt.cpp b/LunaDll/libs/PGE_File_Formats/file_rw_npc_txt.cpp deleted file mode 100644 index 24c2b2ba0..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_rw_npc_txt.cpp +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "file_formats.h" -#include "file_strlist.h" -#include "smbx64.h" - -#include - -//********************************************************* -//****************READ FILE FORMAT************************* -//********************************************************* -bool FileFormats::ReadNpcTXTFileF(PGESTRING filePath, NPCConfigFile &FileData, bool IgnoreBad) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileInput file; - if(!file.open(filePath, false)) - { - errorString = "Failed to open file for read"; - FileData.ReadFileValid = false; - return false; - } - return ReadNpcTXTFile(file, FileData, IgnoreBad); -} - -bool FileFormats::ReadNpcTXTFileRAW(PGESTRING &rawdata, NPCConfigFile &FileData, bool IgnoreBad) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextInput file; - if(!file.open(&rawdata)) - { - errorString = "Failed to open raw string for read"; - FileData.ReadFileValid = false; - return false; - } - return ReadNpcTXTFile(file, FileData, IgnoreBad); -} - - - -static inline PGESTRING invalidLine_SINT(long line, PGESTRING data) -{ - return fromNum(line) + ": " + data + " \n"; -} - -static inline PGESTRING invalidLine_UINT(long line, PGESTRING data) -{ - return fromNum(line) + ": " + data + " \n"; -} - -static inline PGESTRING invalidLine_FLT(long line, PGESTRING data) -{ - return fromNum(line) + ": " + data + " \n"; -} - -static inline PGESTRING invalidLine_BOOL(long line, PGESTRING data) -{ - return fromNum(line) + ": " + data + " \n"; -} - -bool FileFormats::ReadNpcTXTFile(PGE_FileFormats_misc::TextInput &inf, NPCConfigFile &FileData, bool IgnoreBad) -{ - PGESTRING line; //Current Line data - PGESTRINGList Params; - FileData = CreateEmpytNpcTXT(); - bool doLog = !IgnoreBad; - - auto handlerSInt = [&](bool &dest_en, int32_t &dest, PGESTRING &input) - { - input = PGESTR_Simpl(input); - input = PGE_RemSubSTRING(input, " ");//Delete spaces - if(!SMBX64::IsSInt(input)) - { - if(doLog) - FileData.unknownLines += invalidLine_SINT(inf.getCurrentLineNumber(), line); - } - else - { - if(input.size() > 9) - dest = 0; - else - { - dest = toInt(input); - dest_en = true; - } - } - }; - - auto handlerUInt = [&](bool &dest_en, uint32_t &dest, PGESTRING &input) - { - input = PGESTR_Simpl(input); - input = PGE_RemSubSTRING(input, " ");//Delete spaces - if(!SMBX64::IsUInt(input)) - { - if(doLog) - FileData.unknownLines += invalidLine_UINT(inf.getCurrentLineNumber(), line); - } - else - { - if(input.size() > 9) - dest = 0; - else - { - dest = toUInt(input); - dest_en = true; - } - } - }; - - auto handlerBool = [&](bool &dest_en, bool &dest, PGESTRING &input) - { - input = PGESTR_Simpl(input); - input = PGE_RemSubSTRING(input, " ");//Delete spaces - if(!SMBX64::IsBool(input)) - { - if(doLog) - FileData.unknownLines += invalidLine_BOOL(inf.getCurrentLineNumber(), line); - } - else - { - if(input.size() > 9) - dest = 0; - else - { - dest = static_cast(toInt(input)); - dest_en = true; - } - } - }; - - auto handlerDouble = [&](bool &dest_en, double &dest, PGESTRING &input) - { - input = PGESTR_Simpl(input); - input = PGE_RemSubSTRING(input, " ");//Delete spaces - if(!SMBX64::IsFloat(input)) - { - if(doLog) - FileData.unknownLines += invalidLine_FLT(inf.getCurrentLineNumber(), line); - } - else - { - dest = toDouble(input); - dest_en = true; - } - }; - - auto handlerString = [&](bool &dest_en, PGESTRING &dest, PGESTRING &input) - { - dest = removeQuotes(input); - dest_en = !IsEmpty(input); - }; - - typedef PGEHASH> NpcCfgHandlerMap; - #define SINT_ENTRY(param_name) { #param_name, [&](PGESTRING ¶m) { handlerSInt(FileData.en_##param_name, FileData.param_name, param);} } - #define UINT_ENTRY(param_name) { #param_name, [&](PGESTRING ¶m) { handlerUInt(FileData.en_##param_name, FileData.param_name, param);} } - #define BOOL_ENTRY(param_name) { #param_name, [&](PGESTRING ¶m) { handlerBool(FileData.en_##param_name, FileData.param_name, param);} } - #define STR_ENTRY(param_name) { #param_name, [&](PGESTRING ¶m) { handlerString(FileData.en_##param_name, FileData.param_name, param);} } - #define FLT_ENTRY(param_name) { #param_name, [&](PGESTRING ¶m) { handlerDouble(FileData.en_##param_name, FileData.param_name, param);} } - - NpcCfgHandlerMap paramsHandler = - { - SINT_ENTRY(gfxoffsetx), - SINT_ENTRY(gfxoffsety), - UINT_ENTRY(width), - UINT_ENTRY(height), - UINT_ENTRY(gfxwidth), - UINT_ENTRY(gfxheight), - UINT_ENTRY(score), - UINT_ENTRY(health), - BOOL_ENTRY(playerblock), - BOOL_ENTRY(playerblocktop), - BOOL_ENTRY(npcblock), - BOOL_ENTRY(npcblocktop), - BOOL_ENTRY(grabside), - BOOL_ENTRY(grabtop), - BOOL_ENTRY(jumphurt), - BOOL_ENTRY(nohurt), - BOOL_ENTRY(noblockcollision), - BOOL_ENTRY(cliffturn), - BOOL_ENTRY(noyoshi), - BOOL_ENTRY(foreground), - FLT_ENTRY(speed), - BOOL_ENTRY(nofireball), - BOOL_ENTRY(nogravity), - UINT_ENTRY(frames), - UINT_ENTRY(framespeed), - UINT_ENTRY(framestyle), - BOOL_ENTRY(noiceball), - // Non-SMBX64 parameters (not working in SMBX <=1.3) - BOOL_ENTRY(nohammer), - BOOL_ENTRY(noshell), - STR_ENTRY(name), - STR_ENTRY(description), - STR_ENTRY(image), - STR_ENTRY(icon), - STR_ENTRY(script), - STR_ENTRY(group), - STR_ENTRY(category), - UINT_ENTRY(grid), - SINT_ENTRY(gridoffsetx), - SINT_ENTRY(gridoffsety), - UINT_ENTRY(gridalign), - }; - - //Read NPC.TXT File config -#define NextLine(line) line = inf.readCVSLine(); - - do - { - NextLine(line) - if(IsEmpty(PGE_RemSubSTRING(line, " "))) - continue;//Skip empty strings - - #ifdef PGE_FILES_QT - Params = line.split("=", QString::SkipEmptyParts); // split the Parameter and value (example: chicken=2) - #else - PGE_SPLITSTRING(Params, line, "="); - #endif - - if(Params.size() != 2) // If string does not contain strings with "=" as separator - { - if(doLog) - FileData.unknownLines += fromNum(inf.getCurrentLineNumber()) + ": " + line + " \n"; - if(doLog || (Params.size() < 2)) - continue; - } - - Params[0] = PGESTR_Simpl(Params[0]); - Params[0] = PGE_RemSubSTRING(Params[0], " "); //Delete spaces - Params[0] = PGESTR_toLower(Params[0]);//To lower case - - NpcCfgHandlerMap::iterator hand = paramsHandler.find(Params[0]); - if(hand != paramsHandler.end()) - { - #ifdef PGE_FILES_QT - (*hand)(Params[1]); - #else - (hand->second)(Params[1]); - #endif - } - else if(doLog)//Store unknown value into warnings list - FileData.unknownLines += fromNum(inf.getCurrentLineNumber()) + ": " + line + "\n"; - } - while(!inf.eof()); - - FileData.ReadFileValid = true; - return true; -} - - - - -//********************************************************* -//****************WRITE FILE******************************* -//********************************************************* -bool FileFormats::WriteNPCTxtFileF(PGESTRING filePath, NPCConfigFile &FileData) -{ - PGE_FileFormats_misc::TextFileOutput file; - if(!file.open(filePath, false, true, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open file for write"; - return false; - } - return WriteNPCTxtFile(file, FileData); -} - -bool FileFormats::WriteNPCTxtFileRaw(NPCConfigFile &FileData, PGESTRING &rawdata) -{ - PGE_FileFormats_misc::RawTextOutput file; - if(!file.open(&rawdata, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open target raw string for write"; - return false; - } - return WriteNPCTxtFile(file, FileData); -} - -//Convert NPC Options structore to text for saving -bool FileFormats::WriteNPCTxtFile(PGE_FileFormats_misc::TextOutput &out, NPCConfigFile &FileData) -{ - if(FileData.en_gfxoffsetx) - out << "gfxoffsetx=" + fromNum(FileData.gfxoffsetx) + "\n"; - if(FileData.en_gfxoffsety) - out << "gfxoffsety=" + fromNum(FileData.gfxoffsety) + "\n"; - if(FileData.en_gfxwidth) - out << "gfxwidth=" + fromNum(FileData.gfxwidth) + "\n"; - if(FileData.en_gfxheight) - out << "gfxheight=" + fromNum(FileData.gfxheight) + "\n"; - if(FileData.en_foreground) - out << "foreground=" + fromBoolToNum(FileData.foreground) + "\n"; - if(FileData.en_width) - out << "width=" + fromNum(FileData.width) + "\n"; - if(FileData.en_height) - out << "height=" + fromNum(FileData.height) + "\n"; - - if(FileData.en_score) - out << "score=" + fromNum(FileData.score) + "\n"; - if(FileData.en_health) - out << "health=" + fromNum(FileData.health) + "\n"; - - if(FileData.en_playerblock) - out << "playerblock=" + fromBoolToNum(FileData.playerblock) + "\n"; - - if(FileData.en_playerblocktop) - out << "playerblocktop=" + fromBoolToNum(FileData.playerblocktop) + "\n"; - - if(FileData.en_npcblock) - out << "npcblock=" + fromBoolToNum(FileData.npcblock) + "\n"; - - if(FileData.en_npcblocktop) - out << "npcblocktop=" + fromBoolToNum(FileData.npcblocktop) + "\n"; - if(FileData.en_grabside) - out << "grabside=" + fromBoolToNum(FileData.grabside) + "\n"; - if(FileData.en_grabtop) - out << "grabtop=" + fromBoolToNum(FileData.grabtop) + "\n"; - if(FileData.en_jumphurt) - out << "jumphurt=" + fromBoolToNum(FileData.jumphurt) + "\n"; - if(FileData.en_nohurt) - out << "nohurt=" + fromBoolToNum(FileData.nohurt) + "\n"; - if(FileData.en_speed) - out << "speed=" + fromNum(FileData.speed) + "\n"; - if(FileData.en_noblockcollision) - out << "noblockcollision=" + fromBoolToNum(FileData.noblockcollision) + "\n"; - if(FileData.en_cliffturn) - out << "cliffturn=" + fromBoolToNum(FileData.cliffturn) + "\n"; - if(FileData.en_noyoshi) - out << "noyoshi=" + fromBoolToNum(FileData.noyoshi) + "\n"; - if(FileData.en_nofireball) - out << "nofireball=" + fromBoolToNum(FileData.nofireball) + "\n"; - if(FileData.en_nogravity) - out << "nogravity=" + fromBoolToNum(FileData.nogravity) + "\n"; - if(FileData.en_noiceball) - out << "noiceball=" + fromBoolToNum(FileData.noiceball) + "\n"; - if(FileData.en_frames) - out << "frames=" + fromNum(FileData.frames) + "\n"; - if(FileData.en_framespeed) - out << "framespeed=" + fromNum(FileData.framespeed) + "\n"; - if(FileData.en_framestyle) - out << "framestyle=" + fromNum(FileData.framestyle) + "\n"; - - //Extended - if(FileData.en_nohammer) - out << "nohammer=" + fromBoolToNum(FileData.nohammer) + "\n"; - if(FileData.en_noshell) - out << "noshell=" + fromBoolToNum(FileData.noshell) + "\n"; - if(FileData.en_name && !IsEmpty(FileData.name)) - out << "name=" + SMBX64::WriteStr(FileData.name); - if(FileData.en_description && !IsEmpty(FileData.description)) - out << "description=" + SMBX64::WriteStr(FileData.description); - if(FileData.en_image && !IsEmpty(FileData.image)) - out << "image=" + SMBX64::WriteStr(FileData.image); - if(FileData.en_icon && !IsEmpty(FileData.icon)) - out << "icon=" + SMBX64::WriteStr(FileData.icon); - if(FileData.en_script && !IsEmpty(FileData.script)) - out << "script=" + SMBX64::WriteStr(FileData.script); - if(FileData.en_group && !IsEmpty(FileData.group)) - out << "group=" + SMBX64::WriteStr(FileData.group); - if(FileData.en_category && !IsEmpty(FileData.category)) - out << "category=" + SMBX64::WriteStr(FileData.category); - if(FileData.en_grid) - out << "grid=" + fromNum(FileData.grid) + "\n"; - if(FileData.en_gridoffsetx) - out << "gridoffsetx=" + fromNum(FileData.gridoffsetx) + "\n"; - if(FileData.en_gridoffsety) - out << "gridoffsety=" + fromNum(FileData.gridoffsety) + "\n"; - if(FileData.en_gridalign) - out << "gridalign=" + fromNum(FileData.gridalign) + "\n"; - - return true; -} diff --git a/LunaDll/libs/PGE_File_Formats/file_rw_sav.cpp b/LunaDll/libs/PGE_File_Formats/file_rw_sav.cpp deleted file mode 100644 index 268cb28ab..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_rw_sav.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifdef PGE_FILES_QT -#include -#include -#else -#include -#include /* PATH_MAX */ -#endif - -#include "file_formats.h" -#include "file_strlist.h" -#include "save_filedata.h" -#include "smbx64.h" -#include "smbx64_macro.h" -#include "CSVUtils.h" - -//********************************************************* -//****************READ FILE FORMAT************************* -//********************************************************* - -bool FileFormats::ReadSMBX64SavFileF(PGESTRING filePath, GamesaveData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileInput file; - if(!file.open(filePath, false)) - { - errorString = "Failed to open file for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - return ReadSMBX64SavFile(file, FileData); -} - -bool FileFormats::ReadSMBX64SavFileRaw(PGESTRING &rawdata, PGESTRING filePath, GamesaveData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextInput file; - if(!file.open(&rawdata, filePath)) - { - errorString = "Failed to open raw string for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - return ReadSMBX64SavFile(file, FileData); -} - -bool FileFormats::ReadSMBX64SavFile(PGE_FileFormats_misc::TextInput &in, GamesaveData &FileData) -{ - SMBX64_FileBegin(); - PGESTRING filePath = in.getFilePath(); - errorString.clear(); - //SMBX64_File( RawData ); - - int i; //counters - int arrayIdCounter = 0; - //GamesaveData FileData; - FileData = CreateGameSaveData(); - - FileData.meta.untitled = false; - - //Add path data - if(!IsEmpty(filePath)) - { - PGE_FileFormats_misc::FileInfo in_1(filePath); - FileData.meta.filename = in_1.basename(); - FileData.meta.path = in_1.dirpath(); - } - - //Enable strict mode for SMBX LVL file format - FileData.meta.smbx64strict = true; - - try - { - ///////////////////////////////////////Begin file/////////////////////////////////////// - nextLine(); - SMBX64::ReadUInt(&file_format, line);//File format number - FileData.meta.RecentFormatVersion = file_format; - nextLine(); - SMBX64::ReadUInt(&FileData.lives, line); //Number of lives - nextLine(); - SMBX64::ReadUInt(&FileData.coins, line); //Number of coins - nextLine(); - SMBX64::ReadSInt(&FileData.worldPosX, line); //World map pos X - nextLine(); - SMBX64::ReadSInt(&FileData.worldPosY, line); //World map pos Y - - for(i = 0; i < (ge(56) ? 5 : 2) ; i++) - { - saveCharState charState; - charState = CreateSavCharacterState(); - nextLine(); - SMBX64::ReadUInt(&charState.state, line);//Character's power up state - nextLine(); - SMBX64::ReadUInt(&charState.itemID, line); //ID of item in the slot - if(ge(10)) - { - nextLine(); //Type of mount - SMBX64::ReadUInt(&charState.mountType, line); - } - nextLine(); - SMBX64::ReadUInt(&charState.mountID, line); //ID of mount - if(lt(10)) - { - if(charState.mountID > 0) charState.mountType = 1; - } - if(ge(56)) - { - nextLine(); //ID of mount - SMBX64::ReadUInt(&charState.health, line); - } - FileData.characterStates.push_back(charState); - } - - nextLine(); - SMBX64::ReadUInt(&FileData.musicID, line);//ID of music - nextLine(); - if(line == "" || in.eof()) - goto successful; - - if(ge(56)) - { - SMBX64::ReadCSVBool(&FileData.gameCompleted, line); //Game was complited - } - - arrayIdCounter = 1; - - nextLine(); - while((line != "next") && (!in.eof())) - { - visibleItem level; - level.first = (unsigned int)arrayIdCounter; - level.second = false; - SMBX64::ReadCSVBool(&level.second, line); //Is level shown - - FileData.visibleLevels.push_back(level); - arrayIdCounter++; - nextLine(); - } - - arrayIdCounter = 1; - nextLine(); - while((line != "next") && (!in.eof())) - { - visibleItem level; - level.first = (unsigned int)arrayIdCounter; - level.second = false; - SMBX64::ReadCSVBool(&level.second, line); //Is path shown - - FileData.visiblePaths.push_back(level); - arrayIdCounter++; - nextLine(); - } - - arrayIdCounter = 1; - nextLine(); - while((line != "next") && (!in.eof())) - { - visibleItem level; - level.first = (unsigned int)arrayIdCounter; - level.second = false; - SMBX64::ReadCSVBool(&level.second, line); //Is Scenery shown - - FileData.visibleScenery.push_back(level); - arrayIdCounter++; - nextLine(); - } - - if(ge(7)) - { - nextLine(); - while((line != "next") && (!IsNULL(line))) - { - starOnLevel gottenStar; - gottenStar.first = ""; - gottenStar.second = 0; - - SMBX64::ReadStr(&gottenStar.first, line);//Level file - if(ge(16)) - { - nextLine(); //Section ID - SMBX64::ReadUInt(&gottenStar.second, line); - } - - FileData.gottenStars.push_back(gottenStar); - nextLine(); - } - } - - if(ge(21)) - { - nextLine(); - if(line == "" || in.eof()) - goto successful; - SMBX64::ReadUInt(&FileData.totalStars, line);//Total Number of stars - } - -successful: - ///////////////////////////////////////EndFile/////////////////////////////////////// - FileData.meta.ReadFileValid = true; - return true; - } - catch(const std::exception &err) - { - if(file_format > 0) - FileData.meta.ERROR_info = "Detected file format: SMBX-" + fromNum(file_format) + " is invalid\n"; - else - FileData.meta.ERROR_info = "It is not an SMBX game save file\n"; - #ifdef PGE_FILES_QT - FileData.meta.ERROR_info += QString::fromStdString(exception_to_pretty_string(err)); - #else - FileData.meta.ERROR_info += exception_to_pretty_string(err); - #endif - FileData.meta.ERROR_linenum = in.getCurrentLineNumber(); - FileData.meta.ERROR_linedata = line; - FileData.meta.ReadFileValid = false; - return false; - } -} - diff --git a/LunaDll/libs/PGE_File_Formats/file_rw_savx.cpp b/LunaDll/libs/PGE_File_Formats/file_rw_savx.cpp deleted file mode 100644 index bac036f91..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_rw_savx.cpp +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "file_formats.h" -#include "file_strlist.h" -#include "pge_x.h" -#include "pge_x_macro.h" - -#ifdef PGE_FILES_QT -#include -#include -#endif - -//********************************************************* -//****************READ FILE FORMAT************************* -//********************************************************* -bool FileFormats::ReadExtendedSaveFileF(PGESTRING filePath, GamesaveData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileInput file; - - if(!file.open(filePath, true)) - { - errorString = "Failed to open file for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadExtendedSaveFile(file, FileData); -} - -bool FileFormats::ReadExtendedSaveFileRaw(PGESTRING &rawdata, PGESTRING filePath, GamesaveData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextInput file; - - if(!file.open(&rawdata, filePath)) - { - errorString = "Failed to open raw string for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadExtendedSaveFile(file, FileData); -} - -bool FileFormats::ReadExtendedSaveFile(PGE_FileFormats_misc::TextInput &in, GamesaveData &FileData) -{ - FileData = CreateGameSaveData(); - PGESTRING errorString; - PGEX_FileBegin(); - saveCharState plr_state; - visibleItem vz_item; - starOnLevel star_level; - //Add path data - PGESTRING fPath = in.getFilePath(); - - if(!IsEmpty(fPath)) - { - PGE_FileFormats_misc::FileInfo in_1(fPath); - FileData.meta.filename = in_1.basename(); - FileData.meta.path = in_1.dirpath(); - } - - FileData.characterStates.clear(); - FileData.currentCharacter.clear(); - FileData.meta.untitled = false; - FileData.meta.modified = false; - ///////////////////////////////////////Begin file/////////////////////////////////////// - PGEX_FileParseTree(in.readAll()); - PGEX_FetchSection() - { - PGEX_FetchSection_begin() - ///////////////////HEADER////////////////////// - PGEX_Section("SAVE_HEADER") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_USIntVal("LV", FileData.lives) - PGEX_UIntVal("CN", FileData.coins) - PGEX_UIntVal("PT", FileData.points) - PGEX_UIntVal("TS", FileData.totalStars) - PGEX_SIntVal("WX", FileData.worldPosX) - PGEX_SIntVal("WY", FileData.worldPosY) - PGEX_ULongVal("HW", FileData.last_hub_warp) - PGEX_UIntVal("MI", FileData.musicID) - PGEX_StrVal("MF", FileData.musicFile) - PGEX_BoolVal("GC", FileData.gameCompleted) - } - } - }//Header - ///////////////////CHARACTERS////////////////////// - PGEX_Section("CHARACTERS") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - plr_state = CreateSavCharacterState(); - PGEX_Values() - { - PGEX_ValueBegin() - PGEX_ULongVal("ID", plr_state.id) - PGEX_ULongVal("ST", plr_state.state) - PGEX_ULongVal("IT", plr_state.itemID) - PGEX_UIntVal("MT", plr_state.mountType) - PGEX_UIntVal("MI", plr_state.mountID) - PGEX_UIntVal("HL", plr_state.health) - } - FileData.characterStates.push_back(plr_state); - } - }//CHARACTERS - ///////////////////CHARACTERS_PER_PLAYERS////////////////////// - PGEX_Section("CHARACTERS_PER_PLAYERS") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - unsigned long character = 0; - PGEX_Values() - { - PGEX_ValueBegin() - PGEX_ULongVal("ID", character) - } - FileData.currentCharacter.push_back(character); - } - }//CHARACTERS_PER_PLAYERS - ///////////////////VIZ_LEVELS////////////////////// - PGEX_Section("VIZ_LEVELS") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - vz_item.first = 0; - vz_item.second = false; - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_UIntVal("ID", vz_item.first) - PGEX_BoolVal("V", vz_item.second) - } - FileData.visibleLevels.push_back(vz_item); - } - }//VIZ_LEVELS - ///////////////////VIZ_PATHS////////////////////// - PGEX_Section("VIZ_PATHS") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - vz_item.first = 0; - vz_item.second = false; - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_UIntVal("ID", vz_item.first) - PGEX_BoolVal("V", vz_item.second) - } - FileData.visiblePaths.push_back(vz_item); - } - }//VIZ_PATHS - ///////////////////VIZ_SCENERY////////////////////// - PGEX_Section("VIZ_SCENERY") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - vz_item.first = 0; - vz_item.second = false; - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_UIntVal("ID", vz_item.first) - PGEX_BoolVal("V", vz_item.second) - } - FileData.visibleScenery.push_back(vz_item); - } - }//VIZ_SCENERY - ///////////////////STARS////////////////////// - PGEX_Section("STARS") - { - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - PGEX_ItemBegin(PGEFile::PGEX_Struct); - star_level.first = ""; - star_level.second = 0; - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_StrVal("L", star_level.first) - PGEX_USIntVal("S", star_level.second) - } - FileData.gottenStars.push_back(star_level); - } - }//STARS - } - ///////////////////////////////////////EndFile/////////////////////////////////////// - errorString.clear(); //If no errors, clear string; - FileData.meta.ReadFileValid = true; - return true; -badfile: //If file format not corrects - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linenum = str_count; - FileData.meta.ERROR_linedata = line; - FileData.meta.ReadFileValid = false; - return false; -} - - -//********************************************************* -//****************WRITE FILE FORMAT************************ -//********************************************************* - -bool FileFormats::WriteExtendedSaveFileF(PGESTRING filePath, GamesaveData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileOutput file; - - if(!file.open(filePath, true, false, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open file for write"; - return false; - } - - return WriteExtendedSaveFile(file, FileData); -} - -bool FileFormats::WriteExtendedSaveFileRaw(GamesaveData &FileData, PGESTRING &rawdata) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextOutput file; - - if(!file.open(&rawdata, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open raw string for write"; - return false; - } - - return WriteExtendedSaveFile(file, FileData); -} - -bool FileFormats::WriteExtendedSaveFile(PGE_FileFormats_misc::TextOutput &out, GamesaveData &FileData) -{ - pge_size_t i; - out << "SAVE_HEADER\n"; - out << PGEFile::value("LV", PGEFile::WriteInt(FileData.lives)); - out << PGEFile::value("CN", PGEFile::WriteInt(FileData.coins)); - out << PGEFile::value("PT", PGEFile::WriteInt(FileData.points)); - out << PGEFile::value("TS", PGEFile::WriteInt(FileData.totalStars)); - out << PGEFile::value("WX", PGEFile::WriteInt(FileData.worldPosX)); - out << PGEFile::value("WY", PGEFile::WriteInt(FileData.worldPosY)); - out << PGEFile::value("HW", PGEFile::WriteInt(FileData.last_hub_warp)); - out << PGEFile::value("MI", PGEFile::WriteInt(FileData.musicID)); - out << PGEFile::value("MF", PGEFile::WriteStr(FileData.musicFile)); - out << PGEFile::value("GC", PGEFile::WriteBool(FileData.gameCompleted)); - out << "\n"; - out << "SAVE_HEADER_END\n"; - - if(!FileData.characterStates.empty()) - { - out << "CHARACTERS\n"; - - for(i = 0; i < FileData.characterStates.size(); i++) - { - saveCharState &chState = FileData.characterStates[i]; - out << PGEFile::value("ID", PGEFile::WriteInt(chState.id)); - out << PGEFile::value("ST", PGEFile::WriteInt(chState.state)); - out << PGEFile::value("IT", PGEFile::WriteInt(chState.itemID)); - out << PGEFile::value("MT", PGEFile::WriteInt(chState.mountType)); - out << PGEFile::value("MI", PGEFile::WriteInt(chState.mountID)); - out << PGEFile::value("HL", PGEFile::WriteInt(chState.health)); - out << "\n"; - } - - out << "CHARACTERS_END\n"; - } - - if(!FileData.currentCharacter.empty()) - { - out << "CHARACTERS_PER_PLAYERS\n"; - - for(i = 0; i < FileData.currentCharacter.size(); i++) - { - out << PGEFile::value("ID", PGEFile::WriteInt(FileData.currentCharacter[i])); - out << "\n"; - } - - out << "CHARACTERS_PER_PLAYERS_END\n"; - } - - if(!FileData.visibleLevels.empty()) - { - out << "VIZ_LEVELS\n"; - - for(i = 0; i < FileData.visibleLevels.size(); i++) - { - visibleItem &slevel = FileData.visibleLevels[i]; - out << PGEFile::value("ID", PGEFile::WriteInt(slevel.first)); - out << PGEFile::value("V", PGEFile::WriteBool(slevel.second)); - out << "\n"; - } - - out << "VIZ_LEVELS_END\n"; - } - - if(!FileData.visiblePaths.empty()) - { - out << "VIZ_PATHS\n"; - - for(i = 0; i < FileData.visiblePaths.size(); i++) - { - visibleItem &slevel = FileData.visiblePaths[i]; - out << PGEFile::value("ID", PGEFile::WriteInt(slevel.first)); - out << PGEFile::value("V", PGEFile::WriteBool(slevel.second)); - out << "\n"; - } - - out << "VIZ_PATHS_END\n"; - } - - if(!FileData.visibleScenery.empty()) - { - out << "VIZ_SCENERY\n"; - - for(i = 0; i < FileData.visibleScenery.size(); i++) - { - visibleItem &slevel = FileData.visibleScenery[i]; - out << PGEFile::value("ID", PGEFile::WriteInt(slevel.first)); - out << PGEFile::value("V", PGEFile::WriteBool(slevel.second)); - out << "\n"; - } - - out << "VIZ_SCENERY_END\n"; - } - - if(!FileData.gottenStars.empty()) - { - out << "STARS\n"; - - for(i = 0; i < FileData.gottenStars.size(); i++) - { - starOnLevel &slevel = FileData.gottenStars[i]; - out << PGEFile::value("L", PGEFile::WriteStr(slevel.first)); - out << PGEFile::value("S", PGEFile::WriteInt(slevel.second)); - out << "\n"; - } - - out << "STARS_END\n"; - } - - out << "\n"; - return true; -} diff --git a/LunaDll/libs/PGE_File_Formats/file_rw_smbx64_cnf.cpp b/LunaDll/libs/PGE_File_Formats/file_rw_smbx64_cnf.cpp deleted file mode 100644 index a1ac66940..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_rw_smbx64_cnf.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "file_formats.h" -#include "file_strlist.h" -#include "save_filedata.h" -#include "smbx64.h" -#include "smbx64_macro.h" -#include "CSVUtils.h" - -//********************************************************* -//****************READ FILE FORMAT************************* -//********************************************************* -bool FileFormats::ReadSMBX64ConfigFileF(PGESTRING filePath, SMBX64_ConfigFile &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileInput file; - - if(!file.open(filePath, false)) - { - errorString = "Failed to open file for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadSMBX64ConfigFile(file, FileData); -} - -bool FileFormats::ReadSMBX64ConfigFileRaw(PGESTRING &rawdata, PGESTRING filePath, SMBX64_ConfigFile &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextInput file; - - if(!file.open(&rawdata, filePath)) - { - errorString = "Failed to open raw string for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadSMBX64ConfigFile(file, FileData); -} - -SMBX64_ConfigFile FileFormats::ReadSMBX64ConfigFile(PGESTRING RawData) -{ - SMBX64_ConfigFile FileData; - PGE_FileFormats_misc::RawTextInput file(&RawData, ""); - ReadSMBX64ConfigFile(file, FileData); - return FileData; -} - -//SMBX64_ConfigFile FileFormats::ReadSMBX64ConfigFile(PGESTRING RawData) -bool FileFormats::ReadSMBX64ConfigFile(PGE_FileFormats_misc::TextInput &in, SMBX64_ConfigFile &FileData) -{ - SMBX64_FileBegin(); - errorString.clear(); - - try - { - ///////////////////////////////////////Begin file/////////////////////////////////////// - //File format number - nextLine(); - SMBX64::ReadUInt(&file_format, line); - - //Full screen mode - if(ge(16)) - { - nextLine(); - SMBX64::ReadCSVBool(&FileData.fullScreen, line); - } - - for(unsigned int i = 0; i < 2; i++) - { - SMBX64_ConfigPlayer plr; - nextLine(); - SMBX64::ReadUInt(&plr.controllerType, line); - nextLine(); - SMBX64::ReadUInt(&plr.k_up, line); - nextLine(); - SMBX64::ReadUInt(&plr.k_down, line); - nextLine(); - SMBX64::ReadUInt(&plr.k_left, line); - nextLine(); - SMBX64::ReadUInt(&plr.k_right, line); - nextLine(); - SMBX64::ReadUInt(&plr.k_run, line); - nextLine(); - SMBX64::ReadUInt(&plr.k_jump, line); - nextLine(); - SMBX64::ReadUInt(&plr.k_drop, line); - nextLine(); - SMBX64::ReadUInt(&plr.k_pause, line); - - if(ge(19)) - { - nextLine(); - SMBX64::ReadUInt(&plr.k_altjump, line); - nextLine(); - SMBX64::ReadUInt(&plr.k_altrun, line); - } - - nextLine(); - SMBX64::ReadUInt(&plr.j_run, line); - nextLine(); - SMBX64::ReadUInt(&plr.j_jump, line); - nextLine(); - SMBX64::ReadUInt(&plr.j_drop, line); - nextLine(); - SMBX64::ReadUInt(&plr.j_pause, line); - - if(ge(19)) - { - nextLine(); - SMBX64::ReadUInt(&plr.j_altjump, line); - nextLine(); - SMBX64::ReadUInt(&plr.j_altrun, line); - } - - plr.id = i + 1; - FileData.players.push_back(plr); - } - - ///////////////////////////////////////EndFile/////////////////////////////////////// - FileData.meta.ReadFileValid = true; - return true; - } - catch(const std::exception &err) - { - if(file_format > 0) - FileData.meta.ERROR_info = "Detected file format: SMBX-" + fromNum(file_format) + " is invalid\n"; - else - FileData.meta.ERROR_info = "It is not an SMBX game settings file\n"; - - #ifdef PGE_FILES_QT - FileData.meta.ERROR_info += QString::fromStdString(exception_to_pretty_string(err)); - #else - FileData.meta.ERROR_info += exception_to_pretty_string(err); - #endif - FileData.meta.ERROR_linenum = in.getCurrentLineNumber(); - FileData.meta.ERROR_linedata = line; - FileData.meta.ReadFileValid = false; - return false; - } -} - -//********************************************************* -//****************WRITE FILE FORMAT************************ -//********************************************************* -bool FileFormats::WriteSMBX64ConfigFileF(PGESTRING filePath, SMBX64_ConfigFile &FileData, unsigned int file_format) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileOutput file; - - if(!file.open(filePath, false, true, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open file for write"; - return false; - } - - return WriteSMBX64ConfigFile(file, FileData, file_format); -} - -bool FileFormats::WriteSMBX64ConfigFileRaw(SMBX64_ConfigFile &FileData, PGESTRING &rawdata, unsigned int file_format) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextOutput file; - - if(!file.open(&rawdata, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open raw string for write"; - return false; - } - - return WriteSMBX64ConfigFile(file, FileData, file_format); -} - -PGESTRING FileFormats::WriteSMBX64ConfigFile(SMBX64_ConfigFile &FileData, unsigned int file_format) -{ - PGESTRING raw; - WriteSMBX64ConfigFileRaw(FileData, raw, file_format); - return raw; -} - -bool FileFormats::WriteSMBX64ConfigFile(PGE_FileFormats_misc::TextOutput &out, SMBX64_ConfigFile &FileData, unsigned int file_format) -{ - pge_size_t i = 0; - - //Prevent out of range: 0....64 - if(file_format > 64) - file_format = 64; - - out << SMBX64::WriteSInt(file_format); //Format version - - if(file_format >= 16) out << SMBX64::WriteCSVBool(FileData.fullScreen); - - while(FileData.players.size() > 2) - { - SMBX64_ConfigPlayer plr; - FileData.players.push_back(plr); - } - - for(i = 0; i < FileData.players.size(); i++) - { - out << SMBX64::WriteSInt(FileData.players[i].controllerType); - out << SMBX64::WriteSInt(FileData.players[i].k_up); - out << SMBX64::WriteSInt(FileData.players[i].k_down); - out << SMBX64::WriteSInt(FileData.players[i].k_left); - out << SMBX64::WriteSInt(FileData.players[i].k_right); - out << SMBX64::WriteSInt(FileData.players[i].k_run); - out << SMBX64::WriteSInt(FileData.players[i].k_jump); - out << SMBX64::WriteSInt(FileData.players[i].k_drop); - out << SMBX64::WriteSInt(FileData.players[i].k_pause); - - if(file_format >= 19) - { - out << SMBX64::WriteSInt(FileData.players[i].k_altjump); - out << SMBX64::WriteSInt(FileData.players[i].k_altrun); - } - - out << SMBX64::WriteSInt(FileData.players[i].j_run); - out << SMBX64::WriteSInt(FileData.players[i].j_jump); - out << SMBX64::WriteSInt(FileData.players[i].j_drop); - out << SMBX64::WriteSInt(FileData.players[i].j_pause); - - if(file_format >= 19) - { - out << SMBX64::WriteSInt(FileData.players[i].j_altjump); - out << SMBX64::WriteSInt(FileData.players[i].j_altrun); - } - } - - return true; -} diff --git a/LunaDll/libs/PGE_File_Formats/file_rw_wld.cpp b/LunaDll/libs/PGE_File_Formats/file_rw_wld.cpp deleted file mode 100644 index 3196c98e5..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_rw_wld.cpp +++ /dev/null @@ -1,590 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "pge_file_lib_sys.h" -#include "file_formats.h" -#include "wld_filedata.h" -#include "file_strlist.h" -#include "smbx64.h" -#include "smbx64_macro.h" -#include "CSVUtils.h" - -//********************************************************* -//****************READ FILE FORMAT************************* -//********************************************************* - -bool FileFormats::ReadSMBX64WldFileHeader(PGESTRING filePath, WorldData &FileData) -{ - SMBX64_FileBegin(); - errorString.clear(); - CreateWorldHeader(FileData); - FileData.meta.RecentFormat = WorldData::SMBX64; - FileData.meta.RecentFormatVersion = 64; - - PGE_FileFormats_misc::TextFileInput in; - if(!in.open(filePath, false)) - { - FileData.meta.ReadFileValid = false; - return false; - } - - PGE_FileFormats_misc::FileInfo in_1(filePath); - FileData.meta.filename = in_1.basename(); - FileData.meta.path = in_1.dirpath(); - - in.seek(0, PGE_FileFormats_misc::TextFileInput::begin); - - FileData.meta.untitled = false; - FileData.meta.modified = false; - - //Enable strict mode for SMBX WLD file format - FileData.meta.smbx64strict = true; - - try - { - nextLine(); //Read first Line - SMBX64::ReadUInt(&file_format, line); //File format number - FileData.meta.RecentFormatVersion = file_format; - - nextLine(); - SMBX64::ReadStr(&FileData.EpisodeTitle, line); //Episode name - #if 0 //More detail header! - if(ge(55)) - { - nextLine(); - SMBX64::ReadCSVBool(&FileData.nocharacter1, line);//Edisode without Mario - nextLine(); - SMBX64::ReadCSVBool(&FileData.nocharacter2, line);//Edisode without Luigi - nextLine(); - SMBX64::ReadCSVBool(&FileData.nocharacter3, line);//Edisode without Peach - nextLine(); - SMBX64::ReadCSVBool(&FileData.nocharacter4, line);//Edisode without Toad - if(ge(56)) - { - nextLine(); - SMBX64::ReadCSVBool(&FileData.nocharacter5, line);//Edisode without Link - } - //Convert into the bool array - FileData.nocharacter.push_back(FileData.nocharacter1); - FileData.nocharacter.push_back(FileData.nocharacter2); - FileData.nocharacter.push_back(FileData.nocharacter3); - FileData.nocharacter.push_back(FileData.nocharacter4); - FileData.nocharacter.push_back(FileData.nocharacter5); - } - - if(ge(3)) - { - nextLine(); - SMBX64::ReadStr(&FileData.IntroLevel_file, line);//Autostart level - nextLine(); - SMBX64::ReadCSVBool(&FileData.HubStyledWorld, line); //Don't use world map on this episode - nextLine(); - SMBX64::ReadCSVBool(&FileData.restartlevel, line);//Restart level on playable character's death - } - - if(ge(20)) - { - nextLine(); - SMBX64::ReadUInt(&FileData.stars, line);//Stars number - } - - if(file_format >= 17) - { - nextLine(); - SMBX64::ReadStr(&FileData.author1, line); //Author 1 - nextLine(); - SMBX64::ReadStr(&FileData.author2, line); //Author 2 - nextLine(); - SMBX64::ReadStr(&FileData.author3, line); //Author 3 - nextLine(); - SMBX64::ReadStr(&FileData.author4, line); //Author 4 - nextLine(); - SMBX64::ReadStr(&FileData.author5, line); //Author 5 - - FileData.authors.clear(); - FileData.authors += (IsEmpty(FileData.author1)) ? "" : FileData.author1 + "\n"; - FileData.authors += (IsEmpty(FileData.author2)) ? "" : FileData.author2 + "\n"; - FileData.authors += (IsEmpty(FileData.author3)) ? "" : FileData.author3 + "\n"; - FileData.authors += (IsEmpty(FileData.author4)) ? "" : FileData.author4 + "\n"; - FileData.authors += (IsEmpty(FileData.author5)) ? "" : FileData.author5; - } - #endif - - FileData.meta.ReadFileValid = true; - in.close(); - return true; - } - catch(const std::exception &err) - { - in.close(); - if(file_format > 0) - FileData.meta.ERROR_info = "Detected file format: SMBX-" + fromNum(file_format) + " is invalid\n"; - else - FileData.meta.ERROR_info = "It is not an SMBX world map file\n"; - #ifdef PGE_FILES_QT - FileData.meta.ERROR_info += QString::fromStdString(exception_to_pretty_string(err)); - #else - FileData.meta.ERROR_info += exception_to_pretty_string(err); - #endif - FileData.meta.ERROR_linenum = in.getCurrentLineNumber(); - FileData.meta.ERROR_linedata = line; - FileData.meta.ReadFileValid = false; - return false; - } -} - - - -bool FileFormats::ReadSMBX64WldFileF(PGESTRING filePath, WorldData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileInput file; - if(!file.open(filePath, false)) - { - errorString = "Failed to open file for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - return ReadSMBX64WldFile(file, FileData); -} - -bool FileFormats::ReadSMBX64WldFileRaw(PGESTRING &rawdata, PGESTRING filePath, WorldData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextInput file; - if(!file.open(&rawdata, filePath)) - { - errorString = "Failed to open raw string for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - return ReadSMBX64WldFile(file, FileData); -} - -bool FileFormats::ReadSMBX64WldFile(PGE_FileFormats_misc::TextInput &in, WorldData &FileData) -{ - SMBX64_FileBegin(); - PGESTRING filePath = in.getFilePath(); - - CreateWorldData(FileData); - - FileData.meta.RecentFormat = WorldData::SMBX64; - FileData.meta.RecentFormatVersion = 64; - - //Add path data - if(!IsEmpty(filePath)) - { - PGE_FileFormats_misc::FileInfo in_1(filePath); - FileData.meta.filename = in_1.basename(); - FileData.meta.path = in_1.dirpath(); - } - - FileData.meta.untitled = false; - FileData.meta.modified = false; - - //Enable strict mode for SMBX WLD file format - FileData.meta.smbx64strict = true; - - WorldTerrainTile tile; - WorldScenery scen; - WorldPathTile pathitem; - WorldLevelTile lvlitem; - WorldMusicBox musicbox; - - try - { - ///////////////////////////////////////Begin file/////////////////////////////////////// - //File format number - nextLine(); - SMBX64::ReadUInt(&file_format, line); - FileData.meta.RecentFormatVersion = file_format; - - //Episode title - nextLine(); - SMBX64::ReadStr(&FileData.EpisodeTitle, line); - - if(ge(55)) - { - nextLine(); - SMBX64::ReadCSVBool(&FileData.nocharacter1, line);//Edisode without Mario - nextLine(); - SMBX64::ReadCSVBool(&FileData.nocharacter2, line);//Edisode without Luigi - nextLine(); - SMBX64::ReadCSVBool(&FileData.nocharacter3, line);//Edisode without Peach - nextLine(); - SMBX64::ReadCSVBool(&FileData.nocharacter4, line);//Edisode without Toad - if(ge(56)) - { - nextLine(); - SMBX64::ReadCSVBool(&FileData.nocharacter5, line);//Edisode without Link - } - //Convert into the bool array - FileData.nocharacter.push_back(FileData.nocharacter1); - FileData.nocharacter.push_back(FileData.nocharacter2); - FileData.nocharacter.push_back(FileData.nocharacter3); - FileData.nocharacter.push_back(FileData.nocharacter4); - FileData.nocharacter.push_back(FileData.nocharacter5); - } - - if(ge(3)) - { - nextLine(); - SMBX64::ReadStr(&FileData.IntroLevel_file, line);//Autostart level - nextLine(); - SMBX64::ReadCSVBool(&FileData.HubStyledWorld, line); //Don't use world map on this episode - nextLine(); - SMBX64::ReadCSVBool(&FileData.restartlevel, line);//Restart level on playable character's death - } - - if(ge(20)) - { - nextLine(); - SMBX64::ReadUInt(&FileData.stars, line);//Stars number - } - - if(file_format >= 17) - { - nextLine(); - SMBX64::ReadStr(&FileData.author1, line); //Author 1 - nextLine(); - SMBX64::ReadStr(&FileData.author2, line); //Author 2 - nextLine(); - SMBX64::ReadStr(&FileData.author3, line); //Author 3 - nextLine(); - SMBX64::ReadStr(&FileData.author4, line); //Author 4 - nextLine(); - SMBX64::ReadStr(&FileData.author5, line); //Author 5 - - FileData.authors.clear(); - FileData.authors += (IsEmpty(FileData.author1)) ? "" : FileData.author1 + "\n"; - FileData.authors += (IsEmpty(FileData.author2)) ? "" : FileData.author2 + "\n"; - FileData.authors += (IsEmpty(FileData.author3)) ? "" : FileData.author3 + "\n"; - FileData.authors += (IsEmpty(FileData.author4)) ? "" : FileData.author4 + "\n"; - FileData.authors += (IsEmpty(FileData.author5)) ? "" : FileData.author5; - } - - - ////////////Tiles Data////////// - nextLine(); - while((line != "next") && (!in.eof())) - { - tile = CreateWldTile(); - SMBX64::ReadSIntFromFloat(&tile.x, line);//Tile x - nextLine(); - SMBX64::ReadSIntFromFloat(&tile.y, line);//Tile y - nextLine(); - SMBX64::ReadUInt(&tile.id, line);//Tile ID - - tile.meta.array_id = FileData.tile_array_id; - FileData.tile_array_id++; - tile.meta.index = (unsigned int)FileData.tiles.size(); //Apply element index - - FileData.tiles.push_back(tile); - nextLine(); - } - - ////////////Scenery Data////////// - nextLine(); - while((line != "next") && (!in.eof())) - { - scen = CreateWldScenery(); - SMBX64::ReadSIntFromFloat(&scen.x, line);//Scenery x - nextLine(); - SMBX64::ReadSIntFromFloat(&scen.y, line);//Scenery y - nextLine(); - SMBX64::ReadUInt(&scen.id, line);//Scenery ID - - scen.meta.array_id = FileData.scene_array_id; - FileData.scene_array_id++; - scen.meta.index = (unsigned int)FileData.scenery.size(); //Apply element index - - FileData.scenery.push_back(scen); - - nextLine(); - } - - ////////////Paths Data////////// - nextLine(); - while((line != "next") && (!in.eof())) - { - pathitem = CreateWldPath(); - SMBX64::ReadSIntFromFloat(&pathitem.x, line);//Path x - nextLine(); - SMBX64::ReadSIntFromFloat(&pathitem.y, line);//Path y - nextLine(); - SMBX64::ReadUInt(&pathitem.id, line); //Path ID - - pathitem.meta.array_id = FileData.path_array_id; - FileData.path_array_id++; - pathitem.meta.index = (unsigned int)FileData.paths.size(); //Apply element index - - FileData.paths.push_back(pathitem); - - nextLine(); - } - - ////////////LevelBox Data////////// - nextLine(); - while((line != "next") && (!in.eof())) - { - lvlitem = CreateWldLevel(); - - SMBX64::ReadSIntFromFloat(&lvlitem.x, line);//Level x - nextLine(); - SMBX64::ReadSIntFromFloat(&lvlitem.y, line);//Level y - nextLine(); - SMBX64::ReadUInt(&lvlitem.id, line);//Level ID - nextLine(); - SMBX64::ReadStr(&lvlitem.lvlfile, line);//Level file - nextLine(); - SMBX64::ReadStr(&lvlitem.title, line);//Level title - nextLine(); - SMBX64::ReadSInt(&lvlitem.top_exit, line);//Top exit - nextLine(); - SMBX64::ReadSInt(&lvlitem.left_exit, line);//Left exit - nextLine(); - SMBX64::ReadSInt(&lvlitem.bottom_exit, line);//bottom exit - nextLine(); - SMBX64::ReadSInt(&lvlitem.right_exit, line);//right exit - if(ge(4)) - { - nextLine(); //Enter via Level's warp - SMBX64::ReadUInt(&lvlitem.entertowarp, line); - } - - if(ge(22)) - { - nextLine(); - SMBX64::ReadCSVBool(&lvlitem.alwaysVisible, line);//Always Visible - nextLine(); - SMBX64::ReadCSVBool(&lvlitem.pathbg, line);//Path background - nextLine(); - SMBX64::ReadCSVBool(&lvlitem.gamestart, line);//Game start point - nextLine(); - SMBX64::ReadSInt(&lvlitem.gotox, line);//Goto x on World map - nextLine(); - SMBX64::ReadSInt(&lvlitem.gotoy, line);//Goto y on World map - nextLine(); - SMBX64::ReadCSVBool(&lvlitem.bigpathbg, line);//Big Path background - } - else - { - if(lvlitem.id == 1) - lvlitem.gamestart = true; - } - - lvlitem.meta.array_id = FileData.level_array_id; - FileData.level_array_id++; - lvlitem.meta.index = (unsigned int)FileData.levels.size(); //Apply element index - - FileData.levels.push_back(lvlitem); - - nextLine(); - } - - ////////////MusicBox Data////////// - nextLine(); - while((line != "next") && (line != "") && (!in.eof())) - { - musicbox = CreateWldMusicbox(); - SMBX64::ReadSIntFromFloat(&musicbox.x, line);//MusicBox x - nextLine(); - SMBX64::ReadSIntFromFloat(&musicbox.y, line);//MusicBox y - nextLine(); - SMBX64::ReadUInt(&musicbox.id, line);//MusicBox ID - - musicbox.meta.array_id = FileData.musicbox_array_id; - FileData.musicbox_array_id++; - musicbox.meta.index = (unsigned int)FileData.music.size(); //Apply element index - - FileData.music.push_back(musicbox); - - nextLine(); - } - nextLine(); // Read last line - ///////////////////////////////////////EndFile/////////////////////////////////////// - FileData.meta.ReadFileValid = true; - return true; - } - catch(const std::exception &err) - { - if(file_format > 0) - FileData.meta.ERROR_info = "Detected file format: SMBX-" + fromNum(file_format) + " is invalid\n"; - else - FileData.meta.ERROR_info = "It is not an SMBX world map file\n"; - #ifdef PGE_FILES_QT - FileData.meta.ERROR_info += QString::fromStdString(exception_to_pretty_string(err)); - #else - FileData.meta.ERROR_info += exception_to_pretty_string(err); - #endif - FileData.meta.ERROR_linenum = in.getCurrentLineNumber(); - FileData.meta.ERROR_linedata = line; - FileData.meta.ReadFileValid = false; - return false; - } -} - - -//********************************************************* -//****************WRITE FILE FORMAT************************ -//********************************************************* - -bool FileFormats::WriteSMBX64WldFileF(PGESTRING filePath, WorldData &FileData, unsigned int file_format) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileOutput file; - if(!file.open(filePath, false, true, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open file for write"; - return false; - } - return WriteSMBX64WldFile(file, FileData, file_format); -} - -bool FileFormats::WriteSMBX64WldFileRaw(WorldData &FileData, PGESTRING &rawdata, unsigned int file_format) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextOutput file; - if(!file.open(&rawdata, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open raw string for write"; - return false; - } - return WriteSMBX64WldFile(file, FileData, file_format); -} - -bool FileFormats::WriteSMBX64WldFile(PGE_FileFormats_misc::TextOutput &out, WorldData &FileData, unsigned int file_format) -{ - pge_size_t i; - - //Prevent out of range: 0....64 - if(file_format > 64) - file_format = 64; - - FileData.meta.RecentFormat = WorldData::SMBX64; - FileData.meta.RecentFormatVersion = file_format; - - out << SMBX64::WriteSInt(file_format); //Format version - out << SMBX64::WriteStr(FileData.EpisodeTitle); //Episode title - - FileData.nocharacter1 = (FileData.nocharacter.size() > 0) ? FileData.nocharacter[0] : false; - FileData.nocharacter2 = (FileData.nocharacter.size() > 1) ? FileData.nocharacter[1] : false; - FileData.nocharacter3 = (FileData.nocharacter.size() > 2) ? FileData.nocharacter[2] : false; - FileData.nocharacter4 = (FileData.nocharacter.size() > 3) ? FileData.nocharacter[3] : false; - FileData.nocharacter5 = (FileData.nocharacter.size() > 4) ? FileData.nocharacter[4] : false; - - if(file_format >= 55) - { - out << SMBX64::WriteCSVBool(FileData.nocharacter1); - out << SMBX64::WriteCSVBool(FileData.nocharacter2); - out << SMBX64::WriteCSVBool(FileData.nocharacter3); - out << SMBX64::WriteCSVBool(FileData.nocharacter4); - if(file_format >= 56) - out << SMBX64::WriteCSVBool(FileData.nocharacter5); - } - if(file_format >= 3) - { - out << SMBX64::WriteStr(FileData.IntroLevel_file); - out << SMBX64::WriteCSVBool(FileData.HubStyledWorld); - out << SMBX64::WriteCSVBool(FileData.restartlevel); - } - if(file_format >= 20) - out << SMBX64::WriteSInt(FileData.stars); - - PGESTRINGList credits; - PGE_SPLITSTRING(credits, FileData.authors, "\n"); - FileData.author1 = (credits.size() > 0) ? credits[0] : ""; - FileData.author2 = (credits.size() > 1) ? credits[1] : ""; - FileData.author3 = (credits.size() > 2) ? credits[2] : ""; - FileData.author4 = (credits.size() > 3) ? credits[3] : ""; - FileData.author5 = (credits.size() > 4) ? credits[4] : ""; - - if(file_format >= 17) - { - out << SMBX64::WriteStr(FileData.author1); - out << SMBX64::WriteStr(FileData.author2); - out << SMBX64::WriteStr(FileData.author3); - out << SMBX64::WriteStr(FileData.author4); - out << SMBX64::WriteStr(FileData.author5); - } - - for(i = 0; i < FileData.tiles.size(); i++) - { - out << SMBX64::WriteSInt(FileData.tiles[i].x); - out << SMBX64::WriteSInt(FileData.tiles[i].y); - out << SMBX64::WriteSInt(FileData.tiles[i].id); - } - out << "\"next\"\n";//Separator - - for(i = 0; i < FileData.scenery.size(); i++) - { - out << SMBX64::WriteSInt(FileData.scenery[i].x); - out << SMBX64::WriteSInt(FileData.scenery[i].y); - out << SMBX64::WriteSInt(FileData.scenery[i].id); - } - out << "\"next\"\n";//Separator - - for(i = 0; i < FileData.paths.size(); i++) - { - out << SMBX64::WriteSInt(FileData.paths[i].x); - out << SMBX64::WriteSInt(FileData.paths[i].y); - out << SMBX64::WriteSInt(FileData.paths[i].id); - } - out << "\"next\"\n";//Separator - - for(i = 0; i < FileData.levels.size(); i++) - { - out << SMBX64::WriteSInt(FileData.levels[i].x); - out << SMBX64::WriteSInt(FileData.levels[i].y); - out << SMBX64::WriteSInt(FileData.levels[i].id); - out << SMBX64::WriteStr(FileData.levels[i].lvlfile); - out << SMBX64::WriteStr(FileData.levels[i].title); - out << SMBX64::WriteSInt(FileData.levels[i].top_exit); - out << SMBX64::WriteSInt(FileData.levels[i].left_exit); - out << SMBX64::WriteSInt(FileData.levels[i].bottom_exit); - out << SMBX64::WriteSInt(FileData.levels[i].right_exit); - if(file_format >= 4) - out << SMBX64::WriteSInt(FileData.levels[i].entertowarp); - if(file_format >= 22) - { - out << SMBX64::WriteCSVBool(FileData.levels[i].alwaysVisible); - out << SMBX64::WriteCSVBool(FileData.levels[i].pathbg); - out << SMBX64::WriteCSVBool(FileData.levels[i].gamestart); - out << SMBX64::WriteSInt(FileData.levels[i].gotox); - out << SMBX64::WriteSInt(FileData.levels[i].gotoy); - out << SMBX64::WriteCSVBool(FileData.levels[i].bigpathbg); - } - } - out << "\"next\"\n";//Separator - - for(i = 0; i < FileData.music.size(); i++) - { - out << SMBX64::WriteSInt(FileData.music[i].x); - out << SMBX64::WriteSInt(FileData.music[i].y); - out << SMBX64::WriteSInt(FileData.music[i].id); - } - out << "\"next\"\n";//Separator - - return true; -} diff --git a/LunaDll/libs/PGE_File_Formats/file_rw_wld_38a.cpp b/LunaDll/libs/PGE_File_Formats/file_rw_wld_38a.cpp deleted file mode 100644 index 1ff9d3fc1..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_rw_wld_38a.cpp +++ /dev/null @@ -1,833 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "pge_file_lib_sys.h" -#include "file_formats.h" -#include "file_strlist.h" - -#include "smbx38a_private.h" - -// Settings -//static constexpr uint32_t newest_file_format = 68; //TODO: Uncomment when implement 38A World writing support - -//********************************************************* -//****************READ FILE FORMAT************************* -//********************************************************* - -bool FileFormats::ReadSMBX38AWldFileHeader(PGESTRING filePath, WorldData& FileData) -{ - errorString.clear(); - CreateWorldHeader(FileData); - FileData.meta.RecentFormat = WorldData::SMBX38A; - #if !defined(_MSC_VER) || _MSC_VER > 1800 - PGE_FileFormats_misc::TextFileInput inf; - - if(!inf.open(filePath, false)) - { - FileData.meta.ReadFileValid = false; - return false; - } - - PGE_FileFormats_misc::FileInfo in_1(filePath); - FileData.meta.filename = in_1.basename(); - FileData.meta.path = in_1.dirpath(); - inf.seek(0, PGE_FileFormats_misc::TextFileInput::begin); - uint32_t file_version = 0; - - try - { - CSVPGEReader readerBridge(&inf); - auto dataReader = MakeCSVReaderForPGESTRING(&readerBridge, '|'); - PGESTRING fileIndentifier = dataReader.ReadField(1); - dataReader.ReadDataLine(); - - if(!PGE_StartsWith(fileIndentifier, "SMBXFile")) - throw std::logic_error("Invalid file format"); - - file_version = toUInt(PGE_SubStr(fileIndentifier, 8, -1)); - - while(!inf.eof()) - { - PGESTRING identifier = dataReader.ReadField(1); - - if(identifier == "WS1") - { - dataReader.ReadDataLine(CSVDiscard(), // Skip the first field (this is already "identifier") - // wn=episode name[***urlencode!***] - MakeCSVPostProcessor(&FileData.EpisodeTitle, PGEUrlDecodeFunc), - // bp(n)=don't use player(n) as player's character - MakeCSVSubReader(dataReader, ',', - MakeCSVOptional(&FileData.nocharacter1, false), - MakeCSVOptional(&FileData.nocharacter2, false), - MakeCSVOptional(&FileData.nocharacter3, false), - MakeCSVOptional(&FileData.nocharacter4, false), - MakeCSVOptional(&FileData.nocharacter5, false) - ), - MakeCSVSubReader(dataReader, ',', - // asn=auto start level file name[***urlencode!***] - MakeCSVPostProcessor(&FileData.IntroLevel_file, PGEUrlDecodeFunc), - // gon=game over level file name[***urlencode!***] - MakeCSVOptional(&FileData.GameOverLevel_file, "", nullptr, PGEUrlDecodeFunc) - ), - MakeCSVSubReader(dataReader, ',', - // dtp=disable two player[0=false !0=true] - MakeCSVOptional(&FileData.restrictSinglePlayer, false), - // nwm=no world map[0=false !0=true] - MakeCSVOptional(&FileData.HubStyledWorld, false), - // rsd=restart last level on player's character death[0=false !0=true] - MakeCSVOptional(&FileData.restartlevel, false), - // dcp=disable change player[0=false !0=true] - MakeCSVOptional(&FileData.restrictCharacterSwitch, false), - // sc=save machine code to sav file[0=false !0=true] - MakeCSVOptional(&FileData.restrictSecureGameSave, false), - // sm=save mode - MakeCSVOptional(&FileData.saveResumePolicy, 0), - // asg=auto save game[0=false !0=true] - MakeCSVOptional(&FileData.saveAuto, false), - // smb3=smb3 style world map[0=false !0=true] - MakeCSVOptional(&FileData.showEverything, false), - // dss=No Entry Scene - MakeCSVOptional(&FileData.disableEnterScreen, false) - ), - MakeCSVSubReader(dataReader, ',', - // sn=star number - MakeCSVOptional(&FileData.stars, 0), - // mis=max item number in world inventory - MakeCSVOptional(&FileData.inventoryLimit, 0) - ), - // acm=anti cheat mode[0=don't allow in list !0=allow in list] - &FileData.cheatsPolicy, - // sc=enable save locker[0=false !0=true] - &FileData.saveLocker - ); - FileData.charactersFromS64(); - } - else if(identifier == "WS2") - { - dataReader.ReadDataLine(CSVDiscard(), - // credits=[1] - // #DEFT#xxxxxx[***base64encode!***] - // xxxxxx=name1 /n name2 /n ... - // [2] - // #CUST#xxxxxx[***base64encode!***] - // xxxxxx=any string - MakeCSVPostProcessor(&FileData.authors, [](PGESTRING& value) - { - PGESTRING prefix = PGE_SubStr(value, 0, 6); - if((prefix == "#DEFT#") || (prefix == "#CUST#")) - PGE_RemStrRng(value, 0, 6); - value = PGE_BASE64DEC(value); - }) - ); - } - else if(identifier == "WS3") - { - PGESTRING cheatsList; - dataReader.ReadDataLine(CSVDiscard(), - // list=xxxxxx[***base64encode!***] (list of forbidden) - // xxxxxx=string1,string2...stringn - MakeCSVPostProcessor(&cheatsList, [&](PGESTRING& value) - { - PGESTRING list = PGE_URLDEC(value); - PGE_SPLITSTRING(FileData.cheatsList, list, ","); - }) - ); - } - else if(identifier == "WS4") - { - dataReader.ReadDataLine(CSVDiscard(), - // se=save locker syntax[***urlencode!***][syntax] - MakeCSVPostProcessor(&FileData.saveLockerEx, PGEUrlDecodeFunc), - // msg=message when save was locked[***urlencode!***] - MakeCSVPostProcessor(&FileData.saveLockerMsg, PGEUrlDecodeFunc) - ); - } - else - { - break; //Abort on first non-head line to don't fetch entire file - //dataReader.ReadDataLine(); - } - } - } - catch(const std::exception &err) - { - FileData.meta.ReadFileValid = false; - FileData.meta.ERROR_info = "Invalid file format, detected file SMBX-" + fromNum(file_version) + " format\n" - "Caused by: \n" + PGESTRING(exception_to_pretty_string(err).c_str()); - FileData.meta.ERROR_linenum = inf.getCurrentLineNumber(); - FileData.meta.ERROR_linedata = ""; - return false; - } - - FileData.CurSection = 0; - FileData.playmusic = 0; - return true; - #else - FileData.meta.ReadFileValid = false; - FileData.meta.ERROR_info = "Unsupported on MSVC2013"; - return false; - #endif -} - -bool FileFormats::ReadSMBX38AWldFileF(PGESTRING filePath, WorldData& FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileInput file; - - if(!file.open(filePath, false)) - { - errorString = "Failed to open file for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadSMBX38AWldFile(file, FileData); -} - -bool FileFormats::ReadSMBX38AWldFileRaw(PGESTRING& rawdata, PGESTRING filePath, WorldData& FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextInput file; - - if(!file.open(&rawdata, filePath)) - { - errorString = "Failed to open raw string for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadSMBX38AWldFile(file, FileData); -} - -bool FileFormats::ReadSMBX38AWldFile(PGE_FileFormats_misc::TextInput& in, WorldData& FileData) -{ - SMBX38A_FileBeginN(); - PGESTRING filePath = in.getFilePath(); - errorString.clear(); - - CreateWorldData(FileData); - - FileData.meta.RecentFormat = WorldData::SMBX38A; - - #if !defined(_MSC_VER) || _MSC_VER > 1800 - FileData.EpisodeTitle = "" ; - FileData.stars = 0; - FileData.CurSection = 0; - FileData.playmusic = 0; - - //Enable strict mode for SMBX LVL file format - FileData.meta.smbx64strict = false; - - //Begin all ArrayID's here; - FileData.tile_array_id = 1; - FileData.scene_array_id = 1; - FileData.path_array_id = 1; - FileData.level_array_id = 1; - FileData.musicbox_array_id = 1; - - WorldTerrainTile tile; - WorldScenery scen; - WorldPathTile pathitem; - WorldLevelTile lvlitem; - WorldMusicBox musicbox; - WorldAreaRect arearect; - WorldLayer layer; - WorldEvent38A event; - WorldItemSetup38A customcfg; - - PGESTRING identifier; - uint32_t file_version = 0; - - //Add path data - if(!IsEmpty(filePath)) - { - PGE_FileFormats_misc::FileInfo in_1(filePath); - FileData.meta.filename = in_1.basename(); - FileData.meta.path = in_1.dirpath(); - } - - in.seek(0, PGE_FileFormats_misc::TextFileInput::begin); - - try - { - CSVPGEReader readerBridge(&in); - auto dataReader = MakeCSVReaderForPGESTRING(&readerBridge, '|'); - PGESTRING fileIndentifier = dataReader.ReadField(1); - dataReader.ReadDataLine(); - - if(!PGE_StartsWith(fileIndentifier, "SMBXFile")) - throw std::logic_error("Invalid file format"); - - file_version = toUInt(PGE_SubStr(fileIndentifier, 8, -1)); - - while(!in.eof()) - { - identifier = dataReader.ReadField(1); - - if(identifier == "WS1") - { - dataReader.ReadDataLine(CSVDiscard(), // Skip the first field (this is already "identifier") - // wn=episode name[***urlencode!***] - MakeCSVPostProcessor(&FileData.EpisodeTitle, PGEUrlDecodeFunc), - // bp(n)=don't use player(n) as player's character - MakeCSVSubReader(dataReader, ',', - MakeCSVOptional(&FileData.nocharacter1, false), - MakeCSVOptional(&FileData.nocharacter2, false), - MakeCSVOptional(&FileData.nocharacter3, false), - MakeCSVOptional(&FileData.nocharacter4, false), - MakeCSVOptional(&FileData.nocharacter5, false) - ), - MakeCSVSubReader(dataReader, ',', - // asn=auto start level file name[***urlencode!***] - MakeCSVPostProcessor(&FileData.IntroLevel_file, PGEUrlDecodeFunc), - // gon=game over level file name[***urlencode!***] - MakeCSVOptional(&FileData.GameOverLevel_file, "", nullptr, PGEUrlDecodeFunc) - ), - MakeCSVSubReader(dataReader, ',', - // dtp=disable two player[0=false !0=true] - MakeCSVOptional(&FileData.restrictSinglePlayer, false), - // nwm=no world map[0=false !0=true] - MakeCSVOptional(&FileData.HubStyledWorld, false), - // rsd=restart last level on player's character death[0=false !0=true] - MakeCSVOptional(&FileData.restartlevel, false), - // dcp=disable change player[0=false !0=true] - MakeCSVOptional(&FileData.restrictCharacterSwitch, false), - // sc=save machine code to sav file[0=false !0=true] - MakeCSVOptional(&FileData.restrictSecureGameSave, false), - // sm=save mode - MakeCSVOptional(&FileData.saveResumePolicy, 0), - // asg=auto save game[0=false !0=true] - MakeCSVOptional(&FileData.saveAuto, false), - // smb3=smb3 style world map[0=false !0=true] - MakeCSVOptional(&FileData.showEverything, false), - // dss=No Entry Scene - MakeCSVOptional(&FileData.disableEnterScreen, false) - ), - MakeCSVSubReader(dataReader, ',', - // sn=star number - MakeCSVOptional(&FileData.stars, 0), - // mis=max item number in world inventory - MakeCSVOptional(&FileData.inventoryLimit, 0) - ), - // acm=anti cheat mode[0=don't allow in list !0=allow in list] - &FileData.cheatsPolicy, - // sc=enable save locker[0=false !0=true] - &FileData.saveLocker - ); - FileData.charactersFromS64(); - } - else if(identifier == "WS2") - { - dataReader.ReadDataLine(CSVDiscard(), - // credits=[1] - // #DEFT#xxxxxx[***base64encode!***] - // xxxxxx=name1 /n name2 /n ... - // [2] - // #CUST#xxxxxx[***base64encode!***] - // xxxxxx=any string - MakeCSVPostProcessor(&FileData.authors, [](PGESTRING& value) - { - PGESTRING prefix = PGE_SubStr(value, 0, 6); - if((prefix == "#DEFT#") || (prefix == "#CUST#")) - PGE_RemStrRng(value, 0, 6); - value = PGE_BASE64DEC(value); - }) - ); - } - else if(identifier == "WS3") - { - PGESTRING cheatsList; - dataReader.ReadDataLine(CSVDiscard(), - // list=xxxxxx[***base64encode!***] (list of forbidden) - // xxxxxx=string1,string2...stringn - MakeCSVPostProcessor(&cheatsList, [&](PGESTRING& value) - { - PGESTRING list = PGE_URLDEC(value); - PGE_SPLITSTRING(FileData.cheatsList, list, ","); - }) - ); - } - else if(identifier == "WS4") - { - dataReader.ReadDataLine(CSVDiscard(), - // se=save locker syntax[***urlencode!***][syntax] - MakeCSVPostProcessor(&FileData.saveLockerEx, PGEUrlDecodeFunc), - // msg=message when save was locked[***urlencode!***] - MakeCSVPostProcessor(&FileData.saveLockerMsg, PGEUrlDecodeFunc) - ); - } - else if(identifier == "T") - { - tile = WorldTerrainTile(); - dataReader.ReadDataLine(CSVDiscard(), - MakeCSVSubReader(dataReader, ',', - &tile.id, - MakeCSVOptional(&tile.gfx_dx, 0), - MakeCSVOptional(&tile.gfx_dy, 0) - ), - &tile.x, - &tile.y, - MakeCSVPostProcessor(&tile.layer, PGELayerOrDefault) - ); - tile.meta.array_id = FileData.tile_array_id++; - FileData.tiles.push_back(tile); - } - else if(identifier == "S") - { - scen = WorldScenery(); - dataReader.ReadDataLine(CSVDiscard(), - MakeCSVSubReader(dataReader, ',', - &scen.id, - MakeCSVOptional(&scen.gfx_dx, 0), - MakeCSVOptional(&scen.gfx_dy, 0) - ), - &scen.x, - &scen.y, - MakeCSVPostProcessor(&scen.layer, PGELayerOrDefault) - ); - scen.meta.array_id = FileData.scene_array_id++; - FileData.scenery.push_back(scen); - } - else if(identifier == "P") - { - pathitem = WorldPathTile(); - dataReader.ReadDataLine(CSVDiscard(), - MakeCSVSubReader(dataReader, ',', - &pathitem.id, - MakeCSVOptional(&pathitem.gfx_dx, 0), - MakeCSVOptional(&pathitem.gfx_dy, 0) - ), - &pathitem.x, - &pathitem.y, - MakeCSVPostProcessor(&pathitem.layer, PGELayerOrDefault) - ); - pathitem.meta.array_id = FileData.path_array_id++; - FileData.paths.push_back(pathitem); - } - else if(identifier == "M") - { - musicbox = WorldMusicBox(); - arearect = WorldAreaRect(); - arearect.flags = WorldAreaRect::SETUP_CHANGE_MUSIC; - //M|10|416|1312| | |32|32|1 |,0 - //M|1 |384|384 | | |32|32|1 |%66%61%72%74,1 - //M|id|x |y |name|layer|w |h |flag|te,eflag |ie1,ie2,ie3 - dataReader.ReadDataLine(CSVDiscard(), - //id=music id - &arearect.music_id, - //x=Area position x - &arearect.x, - //y=Area position y - &arearect.y, - //name=custom music name[***urlencode!***] - MakeCSVPostProcessor(&arearect.music_file, PGEUrlDecodeFunc), - //layer=layer name["" == "Default"][***urlencode!***] - MakeCSVOptional(&arearect.layer, "Default", nullptr, PGELayerOrDefault), - //w=width - MakeCSVOptional(&arearect.w, 32), - //h=height - MakeCSVOptional(&arearect.h, 32), - //flag=area settings[***Bitwise operation***] - // 0=False !0=True - // b1=(flag & 1) World Music - // b2=(flag & 2) Set Viewport - // b3=(flag & 4) Ship Route - // b4=(flag & 8) Forced Walking - // b5=(flag & 16) Item-triggered events - MakeCSVOptional(&arearect.flags, WorldAreaRect::SETUP_CHANGE_MUSIC), - MakeCSVOptionalSubReader(dataReader, ',', - //te:Touch Event[***urlencode!***] - MakeCSVOptional(&arearect.eventTouch, "", nullptr, PGELayerOrDefault), - //eflag: 0=Triggered every time entering - // 1=Triggered on entrance and level completion - // 2=Triggered only once - MakeCSVOptional(&arearect.eventTouchPolicy, 0) - ), - MakeCSVOptionalSubReader(dataReader, ',', - //ie1=Hammer Event[***urlencode!***] - MakeCSVOptional(&arearect.eventBreak, "", nullptr, PGELayerOrDefault), - //ie2=Warp Whistle Event[***urlencode!***] - MakeCSVOptional(&arearect.eventWarp, "", nullptr, PGELayerOrDefault), - //ie3=Anchor Event[***urlencode!***] - MakeCSVOptional(&arearect.eventAnchor, "", nullptr, PGELayerOrDefault) - ) - ); - if((arearect.flags == WorldAreaRect::SETUP_CHANGE_MUSIC) && - (arearect.w == 32) && (arearect.h == 32)) - { - //Store as generic music-box point - musicbox.id = arearect.music_id; - musicbox.music_file = arearect.music_file; - musicbox.x = arearect.x; - musicbox.y = arearect.y; - musicbox.layer = arearect.layer; - musicbox.meta.array_id = FileData.musicbox_array_id++; - FileData.music.push_back(musicbox); - } - else - { - //Store as separated "Area-rect" type - arearect.meta.array_id = FileData.arearect_array_id++; - FileData.arearects.push_back(arearect); - } - } - else if(identifier == "L") - { - //L|id[,dx,dy]|x|y|fn|n|eu\el\ed\er|wx|wy|wlz|bg,pb,av,ls,f,nsc,otl,li,lcm|s|Layer|Lmt - lvlitem = WorldLevelTile(); - lvlitem.left_exit_extra.exit_codes = {0, 0}; - lvlitem.top_exit_extra.exit_codes = {0, 0}; - lvlitem.right_exit_extra.exit_codes = {0, 0}; - lvlitem.bottom_exit_extra.exit_codes = {0, 0}; - dataReader.ReadDataLine(CSVDiscard(), - MakeCSVSubReader(dataReader, ',', - //id=level id - &lvlitem.id, - //dx=graphics extend x - MakeCSVOptional(&lvlitem.gfx_dx, 0), - //dx=graphics extend y - MakeCSVOptional(&lvlitem.gfx_dy, 0) - ), - //x=level position x - &lvlitem.x, - //x=level position y - &lvlitem.y, - //fn=level file name[***urlencode!***] - MakeCSVPostProcessor(&lvlitem.lvlfile, PGEUrlDecodeFunc), - //n=level name[***urlencode!***] - MakeCSVPostProcessor(&lvlitem.title, PGEUrlDecodeFunc), - //eu\el\ed\er=e[up\left\down\right] - // e=c1,c2,c3,c4 - // c1,c2,c3=level exit type - // c4=condidtion expression[***urlencode!***][syntax] - // exit = (c1 || c2 || c3) && c4 - MakeCSVSubReader(dataReader, '\\', - MakeCSVSubReader(dataReader, ',' - &lvlitem.top_exit, - &lvlitem.top_exit_extra.exit_codes[0], - &lvlitem.top_exit_extra.exit_codes[1], - MakeCSVPostProcessor(&lvlitem.top_exit_extra.expression, PGEUrlDecodeFunc) - ), - MakeCSVSubReader(dataReader, ',' - &lvlitem.left_exit, - &lvlitem.left_exit_extra.exit_codes[0], - &lvlitem.left_exit_extra.exit_codes[1], - MakeCSVPostProcessor(&lvlitem.left_exit_extra.expression, PGEUrlDecodeFunc) - ), - MakeCSVSubReader(dataReader, ',' - &lvlitem.bottom_exit, - &lvlitem.bottom_exit_extra.exit_codes[0], - &lvlitem.bottom_exit_extra.exit_codes[1], - MakeCSVPostProcessor(&lvlitem.bottom_exit_extra.expression, PGEUrlDecodeFunc) - ), - MakeCSVSubReader(dataReader, ',' - &lvlitem.right_exit, - &lvlitem.right_exit_extra.exit_codes[0], - &lvlitem.right_exit_extra.exit_codes[1], - MakeCSVPostProcessor(&lvlitem.right_exit_extra.expression, PGEUrlDecodeFunc) - ) - ), - //wx=go to world map position x - &lvlitem.gotox, - //wx=go to world map position y - &lvlitem.gotoy, - //wlz=nunber of doors to warp - &lvlitem.entertowarp, - MakeCSVSubReader(dataReader, ',', - //bg=big background - MakeCSVOptional(&lvlitem.bigpathbg, false), - //pb=path background - MakeCSVOptional(&lvlitem.pathbg, false), - //av=always visible - MakeCSVOptional(&lvlitem.alwaysVisible, false), - //ls=is game start point - MakeCSVOptional(&lvlitem.gamestart, false), - //f=forced - MakeCSVOptional(&lvlitem.forceStart, false), - //nsc=no star coin count - MakeCSVOptional(&lvlitem.disableStarCoinsCount, false), - //otl=destory after clear - MakeCSVOptional(&lvlitem.destroyOnCompleting, false), - //li=level ID - MakeCSVOptional(&lvlitem.levelID, 0), - //lcm=Affected by Music Box - MakeCSVOptional(&lvlitem.controlledByAreaRects, false) - ), - //TODO: Implement this - //s=entrance syntax - // s=ds1/ds2...dsn - // ds=ds1,ds2[***urlencode!***][syntax] - // ds1=condidtion expression - // ds2=index - MakeCSVOptionalIterator(dataReader, '/', [&lvlitem](const PGESTRING & nextFieldStr) - { - WorldLevelTile::EnterCondition e; - auto fieldReader = MakeDirectReader(nextFieldStr); - auto fullReader = MakeCSVReaderForPGESTRING(&fieldReader, ','); - fullReader.ReadDataLine( - MakeCSVPostProcessor(&e.condition, PGEUrlDecodeFunc), - MakeCSVPostProcessor(&e.levelIndex, PGEUrlDecodeFunc) - ); - lvlitem.enter_cond.push_back(e); - }), - //layer=layer name["" == "Default"][***urlencode!***] - MakeCSVOptional(&lvlitem.layer, "Default", nullptr, PGELayerOrDefault), - //TODO: Implement this - //Lmt=Level Movement Command - // lmt=NodeInfo\PathInfo - // NodeInfo=Node1:Node2:...:NodeN - // Node=x,y,chance - // PathInfo=Path1:Path2:...:PathN - // Path=NodeID1,NodeID2 - MakeCSVOptionalSubReader(dataReader, '\\', - MakeCSVOptionalIterator(dataReader, ':', [&lvlitem](const PGESTRING & nextFieldStr) - { - WorldLevelTile::Movement::Node node; - auto fieldReader = MakeDirectReader(nextFieldStr); - auto fullReader = MakeCSVReaderForPGESTRING(&fieldReader, ','); - fullReader.ReadDataLine( - &node.x, - &node.y, - &node.chance - ); - lvlitem.movement.nodes.push_back(node); - }), - MakeCSVOptionalIterator(dataReader, ':', [&lvlitem](const PGESTRING & nextFieldStr) - { - WorldLevelTile::Movement::Line line; - auto fieldReader = MakeDirectReader(nextFieldStr); - auto fullReader = MakeCSVReaderForPGESTRING(&fieldReader, ','); - fullReader.ReadDataLine( - &line.node1, - &line.node2 - ); - lvlitem.movement.paths.push_back(line); - }) - ) - ); - lvlitem.meta.array_id = FileData.level_array_id++; - FileData.levels.push_back(lvlitem); - } - else if(identifier == "WL") - { - layer = WorldLayer(); - dataReader.ReadDataLine(CSVDiscard(), - MakeCSVPostProcessor(&layer.name, PGELayerOrDefault), - &layer.hidden - ); - layer.meta.array_id = FileData.layers_array_id++; - FileData.layers.push_back(layer); - } - else if(identifier == "WE") - { - event = WorldEvent38A(); - //TODO: Implement world map events support - //next line: events - // WE|name|layer|layerm|world|other - dataReader.ReadDataLine(CSVDiscard(), - // name=event name[***urlencode!***] - MakeCSVPostProcessor(&event.name, PGELayerOrDefault) - // layer=way/hidelist/showlist/togglelist - // list=name1,name2,name3...namen - // name[***urlencode!***] - // if (way % 10 == 1) nosmoke = true; - // if (way > 10) object_state = true; else layer_state = true; - // layerm=movementcommand1\movementcommand2\...\movementcommandn - // movementcommand=way,layer,hp,vp,ap - // way:0=speed,1=coordinate,2=moveto,4=spin - // layer=layer name[***urlencode!***] - // hp=Horizontal Parameter[***urlencode!***] - // vp=Vertical Parameter[***urlencode!***] - // ap=Additional Parameter[***urlencode!***] - // world=aw/cs,le,inpc,msgc,syntax,msg - // aw=AutoStart Settings - // 0=Not Auto Start - // 1=Triggered on loading the world the first time. - // 2=Triggered every time loading the world. - // 3=Triggered on level exit. - // cs=Start when match all condition[0=false !0=true] - // le:0=This is a Normal Event. - // 1=This is a Level Enter/Exit Event. - // inpc=Interrupt the process if 'false' returned - // msgc=Show a message if 'false' returned - // syntax=Condition expression[***urlencode!***] - // msg=message[***urlencode!***] - // other=sd/ld/event,delay/script/msg/wwx,wwy,lockl - // sd=play sound number - // ld=lock keyboard (frames) - // event=trigger event name[***urlencode!***] - // delay=trigger delay[1 frame] - // script=script name[***urlencode!***] - // msg=show message after start event[***urlencode!***] - // wwx=Warp Whistle: Map Warp Location x - // wwy=Warp Whistle: Map Warp Location y - // if (wwx == -1 && wwy == -1) [means not moving] - // lockl=[Level ID]Affected by Anchor - ); - event.meta.array_id = FileData.events38A_array_id++; - FileData.events38A.push_back(event); - } - else if((identifier == "WCT") || (identifier == "WCS") || (identifier == "WCL") ) - { - //custom object data: - // WCT|id|data :custom tile - // WCS|id|data :custom scene - // WCL|id|data :custom level - // id=object id - // data=[HEX]value|[HEX]value... - // [HEX]=0001 :gfxwidth - // [HEX]=0002 :gfxheight - // [HEX]=0003 :frames - customcfg = WorldItemSetup38A(); - if(identifier == "WCT") - customcfg.type = WorldItemSetup38A::TERRAIN; - else if(identifier == "WCS") - customcfg.type = WorldItemSetup38A::SCENERY; - else - customcfg.type = WorldItemSetup38A::LEVEL; - - dataReader.ReadDataLine(CSVDiscard(), - &customcfg.id, - MakeCSVIterator(dataReader, ',', [&customcfg](const PGESTRING & nextFieldStr) - { - WorldItemSetup38A::Entry e; - SMBX38A_CC_decode(e.key, e.value, nextFieldStr); - customcfg.data.push_back(e); - }) - ); - FileData.custom38A_configs.push_back(customcfg); - } - else - dataReader.ReadDataLine(); - }//while is not EOF - } - catch(const std::exception &err) - { - // First we try to extract the line number out of the nested exception. - const std::exception *curErr = &err; - const std::nested_exception *possibleNestedException = dynamic_cast(curErr); - - if(possibleNestedException) - { - try - { - std::rethrow_exception(possibleNestedException->nested_ptr()); - } - catch(const parse_error &parseErr) - { - FileData.meta.ERROR_linenum = static_cast(parseErr.get_line_number()); - } - catch(...) - { - // Do Nothing - } - } - - // Now fill in the error data. - FileData.meta.ReadFileValid = false; - FileData.meta.ERROR_info = "Invalid file format, detected file SMBX-" + fromNum(file_version) + " format\n" - "Caused by: \n" + PGESTRING(exception_to_pretty_string(err).c_str()); - - // If we were unable to find error line number from the exception, then get the line number from the file reader. - if(FileData.meta.ERROR_linenum == 0) - FileData.meta.ERROR_linenum = in.getCurrentLineNumber(); - - FileData.meta.ERROR_linedata = ""; - return false; - } - catch(...) - { - /* - * This is an attempt to fix crash on Windows 32 bit release assembly, - * and possible, on some other platforms too - */ - // Now fill in the error data. - FileData.meta.ReadFileValid = false; - FileData.meta.ERROR_info = "Invalid file format, detected file SMBX-" + fromNum(file_version) + " format\n" - "Caused by unknown exception\n"; - if(!IsEmpty(identifier)) - FileData.meta.ERROR_info += "\n Field type " + identifier; - // If we were unable to find error line number from the exception, then get the line number from the file reader. - if(FileData.meta.ERROR_linenum == 0) - FileData.meta.ERROR_linenum = in.getCurrentLineNumber(); - FileData.meta.ERROR_linedata = ""; - return false; - } - - FileData.CurSection = 0; - FileData.playmusic = 0; - FileData.meta.ReadFileValid = true; - return true; - #else - FileData.meta.ReadFileValid = false; - FileData.meta.ERROR_info = "Unsupported on MSVC2013"; - return false; - #endif -} - - - -//********************************************************* -//****************WRITE FILE FORMAT************************ -//********************************************************* - -bool FileFormats::WriteSMBX38AWldFileF(PGESTRING filePath, WorldData& FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileOutput file; - - if(!file.open(filePath, false, true, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open file for write"; - return false; - } - - return WriteSMBX38AWldFile(file, FileData); -} - -bool FileFormats::WriteSMBX38AWldFileRaw(WorldData& FileData, PGESTRING& rawdata) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextOutput file; - - if(!file.open(&rawdata, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open raw string for write"; - return false; - } - - return WriteSMBX38AWldFile(file, FileData); -} - -bool FileFormats::WriteSMBX38AWldFile(PGE_FileFormats_misc::TextOutput& out, WorldData& FileData) -{ - (void)out; - errorString = "Not implemented yet. Comming soon!"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; -} - diff --git a/LunaDll/libs/PGE_File_Formats/file_rw_wldx.cpp b/LunaDll/libs/PGE_File_Formats/file_rw_wldx.cpp deleted file mode 100644 index 41cd8960e..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_rw_wldx.cpp +++ /dev/null @@ -1,687 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "file_formats.h" -#include "file_strlist.h" -#include "wld_filedata.h" -#include "pge_x.h" -#include "pge_x_macro.h" -#include "pge_file_lib_sys.h" - -//********************************************************* -//****************READ FILE FORMAT************************* -//********************************************************* - -//WorldData FileFormats::ReadExtendedWorldFile(PGEFILE &inf) -//{ -// QTextStream in(&inf); //Read File -// in.setCodec("UTF-8"); - -// return ReadExtendedWldFile( in.readAll(), inf.fileName() ); -//} - -bool FileFormats::ReadExtendedWldFileHeader(PGESTRING filePath, WorldData &FileData) -{ - CreateWorldHeader(FileData); - FileData.meta.RecentFormat = WorldData::PGEX; - PGE_FileFormats_misc::TextFileInput inf; - - if(!inf.open(filePath, true)) - { - FileData.meta.ReadFileValid = false; - return false; - } - - PGESTRING line; - int str_count = 0; - bool valid = false; - PGE_FileFormats_misc::FileInfo in_1(filePath); - FileData.meta.filename = in_1.basename(); - FileData.meta.path = in_1.dirpath(); - - //Find level header part - do - { - str_count++; - line = inf.readLine(); - } - while((line != "HEAD") && (!inf.eof())); - - PGESTRINGList header; - bool closed = false; - - if(line != "HEAD")//Header not found, this world map is head-less - goto skipHeaderParse; - - str_count++; - line = inf.readLine(); - - while((line != "HEAD_END") && (!inf.eof())) - { - header.push_back(line); - str_count++; - line = inf.readLine(); - - if(line == "HEAD_END") - closed = true; - } - - if(!closed) - goto badfile; - - for(pge_size_t zzz = 0; zzz < header.size(); zzz++) - { - PGESTRING &header_line = header[zzz]; - PGELISTdata = PGEFile::splitDataLine(header_line, &valid); - - for(pge_size_t i = 0; i < data.size(); i++) - { - if(data[i].size() != 2) goto badfile; - - if(data[i][0] == "TL") //Episode Title - { - if(PGEFile::IsQoutedString(data[i][1])) - FileData.EpisodeTitle = PGEFile::X2STRING(data[i][1]); - else - goto badfile; - } - else if(data[i][0] == "DC") //Disabled characters - { - if(PGEFile::IsBoolArray(data[i][1])) - FileData.nocharacter = PGEFile::X2BollArr(data[i][1]); - else - goto badfile; - } - else if(data[i][0] == "IT") //Intro level - { - if(PGEFile::IsQoutedString(data[i][1])) - FileData.IntroLevel_file = PGEFile::X2STRING(data[i][1]); - else - goto badfile; - } - else if(data[i][0] == "HB") //Hub Styled - { - if(PGEFile::IsBool(data[i][1])) - FileData.HubStyledWorld = static_cast(toInt(data[i][1])); - else - goto badfile; - } - else if(data[i][0] == "RL") //Restart level on fail - { - if(PGEFile::IsBool(data[i][1])) - FileData.restartlevel = static_cast(toInt(data[i][1])); - else - goto badfile; - } - else if(data[i][0] == "SZ") //Starz number - { - if(PGEFile::IsIntU(data[i][1])) - FileData.stars = toUInt(data[i][1]); - else - goto badfile; - } - else if(data[i][0] == "CD") //Credits list - { - if(PGEFile::IsQoutedString(data[i][1])) - FileData.authors = PGEFile::X2STRING(data[i][1]); - else - goto badfile; - } - } - } - -skipHeaderParse: - FileData.CurSection = 0; - FileData.playmusic = 0; - FileData.meta.ReadFileValid = true; - inf.close(); - return true; -badfile: - inf.close(); - FileData.meta.ERROR_info = "Invalid file format"; - FileData.meta.ERROR_linenum = str_count; - FileData.meta.ERROR_linedata = line; - FileData.meta.ReadFileValid = false; - return false; -} - -bool FileFormats::ReadExtendedWldFileF(PGESTRING filePath, WorldData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileInput file; - - if(!file.open(filePath, true)) - { - errorString = "Failed to open file for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadExtendedWldFile(file, FileData); -} - -bool FileFormats::ReadExtendedWldFileRaw(PGESTRING &rawdata, PGESTRING filePath, WorldData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextInput file; - - if(!file.open(&rawdata, filePath)) - { - errorString = "Failed to open raw string for read"; - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linedata = ""; - FileData.meta.ERROR_linenum = -1; - FileData.meta.ReadFileValid = false; - return false; - } - - return ReadExtendedWldFile(file, FileData); -} - -bool FileFormats::ReadExtendedWldFile(PGE_FileFormats_misc::TextInput &in, WorldData &FileData) -{ - PGESTRING errorString; - PGEX_FileBegin(); - PGESTRING filePath = in.getFilePath(); - CreateWorldData(FileData); - FileData.meta.RecentFormat = WorldData::PGEX; - - //Add path data - if(!IsEmpty(filePath)) - { - PGE_FileFormats_misc::FileInfo in_1(filePath); - FileData.meta.filename = in_1.basename(); - FileData.meta.path = in_1.dirpath(); - } - - FileData.meta.untitled = false; - FileData.meta.modified = false; - WorldTerrainTile tile; - WorldScenery scen; - WorldPathTile pathitem; - WorldMusicBox musicbox; - WorldLevelTile lvlitem; - ///////////////////////////////////////Begin file/////////////////////////////////////// - PGEX_FileParseTree(in.readAll()); - PGEX_FetchSection() //look sections - { - PGEX_FetchSection_begin() - ///////////////////HEADER////////////////////// - PGEX_Section("HEAD") - { - str_count++; - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - str_count += 8; - PGEX_ItemBegin(PGEFile::PGEX_Struct); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_StrVal("TL", FileData.EpisodeTitle) //Episode Title - PGEX_BoolArrVal("DC", FileData.nocharacter) //Disabled characters - PGEX_StrVal("IT", FileData.IntroLevel_file) //Intro level - PGEX_BoolVal("HB", FileData.HubStyledWorld) //Hub Styled - PGEX_BoolVal("RL", FileData.restartlevel) //Restart level on fail - PGEX_UIntVal("SZ", FileData.stars) //Starz number - PGEX_StrVal("CD", FileData.authors) //Credits list - } - } - }//head - ///////////////////////////////MetaDATA///////////////////////////////////////////// - PGEX_Section("META_BOOKMARKS") - { - str_count++; - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - str_count++; - PGEX_ItemBegin(PGEFile::PGEX_Struct); - Bookmark meta_bookmark; - meta_bookmark.bookmarkName = ""; - meta_bookmark.x = 0; - meta_bookmark.y = 0; - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_StrVal("BM", meta_bookmark.bookmarkName) //Bookmark name - PGEX_SIntVal("X", meta_bookmark.x) // Position X - PGEX_SIntVal("Y", meta_bookmark.y) // Position Y - } - FileData.metaData.bookmarks.push_back(meta_bookmark); - } - } - ////////////////////////meta bookmarks//////////////////////// -#ifdef PGE_EDITOR - PGEX_Section("META_SYS_CRASH") - { - str_count++; - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - str_count++; - PGEX_ItemBegin(PGEFile::PGEX_Struct); - PGEX_Values() //Look markers and values - { - FileData.metaData.crash.used = true; - PGEX_ValueBegin() - PGEX_BoolVal("UT", FileData.metaData.crash.untitled) //Untitled - PGEX_BoolVal("MD", FileData.metaData.crash.modifyed) //Modyfied - PGEX_SIntVal("FF", FileData.metaData.crash.fmtID) //Recent File format - PGEX_UIntVal("FV", FileData.metaData.crash.fmtVer) //Recent File format version - PGEX_StrVal("N", FileData.metaData.crash.filename) //Filename - PGEX_StrVal("P", FileData.metaData.crash.path) //Path - PGEX_StrVal("FP", FileData.metaData.crash.fullPath) //Full file Path - } - } - }//meta sys crash -#endif - ///////////////////////////////MetaDATA//End//////////////////////////////////////// - ///////////////////TILES////////////////////// - PGEX_Section("TILES") - { - str_count++; - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - str_count++; - PGEX_ItemBegin(PGEFile::PGEX_Struct); - tile = CreateWldTile(); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_UIntVal("ID", tile.id) //Tile ID - PGEX_SIntVal("X", tile.x) //X Position - PGEX_SIntVal("Y", tile.y) //Y Position - PGEX_StrVal("XTRA", tile.meta.custom_params)//Custom JSON data tree - } - tile.meta.array_id = FileData.tile_array_id++; - tile.meta.index = static_cast(FileData.tiles.size()); - FileData.tiles.push_back(tile); - } - }//TILES - ///////////////////SCENERY////////////////////// - PGEX_Section("SCENERY") - { - str_count++; - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - str_count++; - PGEX_ItemBegin(PGEFile::PGEX_Struct); - scen = CreateWldScenery(); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_UIntVal("ID", scen.id) //Scenery ID - PGEX_SIntVal("X", scen.x) //X Position - PGEX_SIntVal("Y", scen.y) //Y Position - PGEX_StrVal("XTRA", scen.meta.custom_params)//Custom JSON data tree - } - scen.meta.array_id = FileData.scene_array_id++; - scen.meta.index = static_cast(FileData.scenery.size()); - FileData.scenery.push_back(scen); - } - }//SCENERY - ///////////////////PATHS////////////////////// - PGEX_Section("PATHS") - { - str_count++; - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - str_count++; - PGEX_ItemBegin(PGEFile::PGEX_Struct); - pathitem = CreateWldPath(); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_UIntVal("ID", pathitem.id) //Path ID - PGEX_SIntVal("X", pathitem.x) //X Position - PGEX_SIntVal("Y", pathitem.y) //Y Position - PGEX_StrVal("XTRA", pathitem.meta.custom_params)//Custom JSON data tree - } - pathitem.meta.array_id = FileData.path_array_id++; - pathitem.meta.index = static_cast(FileData.paths.size()); - FileData.paths.push_back(pathitem); - } - }//PATHS - ///////////////////MUSICBOXES////////////////////// - PGEX_Section("MUSICBOXES") - { - str_count++; - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - str_count++; - PGEX_ItemBegin(PGEFile::PGEX_Struct); - musicbox = CreateWldMusicbox(); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_UIntVal("ID", musicbox.id) //MISICBOX ID - PGEX_SIntVal("X", musicbox.x) //X Position - PGEX_SIntVal("Y", musicbox.y) //X Position - PGEX_StrVal("MF", musicbox.music_file) //Custom music file - PGEX_StrVal("XTRA", musicbox.meta.custom_params)//Custom JSON data tree - } - musicbox.meta.array_id = FileData.musicbox_array_id++; - musicbox.meta.index = static_cast(FileData.music.size()); - FileData.music.push_back(musicbox); - } - }//MUSICBOXES - ///////////////////LEVELS////////////////////// - PGEX_Section("LEVELS") - { - str_count++; - PGEX_SectionBegin(PGEFile::PGEX_Struct); - PGEX_Items() - { - str_count++; - PGEX_ItemBegin(PGEFile::PGEX_Struct); - lvlitem = CreateWldLevel(); - PGEX_Values() //Look markers and values - { - PGEX_ValueBegin() - PGEX_UIntVal("ID", lvlitem.id) //LEVEL IMAGE ID - PGEX_SIntVal("X", lvlitem.x) //X Position - PGEX_SIntVal("Y", lvlitem.y) //X Position - PGEX_StrVal("LF", lvlitem.lvlfile) //Target level file - PGEX_StrVal("LT", lvlitem.title) //Level title - PGEX_UIntVal("EI", lvlitem.entertowarp) //Entrance Warp ID (if 0 - start level from default points) - PGEX_SIntVal("ET", lvlitem.top_exit) //Open top path on exit type - PGEX_SIntVal("EL", lvlitem.left_exit) //Open left path on exit type - PGEX_SIntVal("ER", lvlitem.right_exit) //Open right path on exit type - PGEX_SIntVal("EB", lvlitem.bottom_exit) //Open bottom path on exit type - PGEX_SIntVal("WX", lvlitem.gotox) //Goto world map X - PGEX_SIntVal("WY", lvlitem.gotoy) //Goto world map Y - PGEX_BoolVal("AV", lvlitem.alwaysVisible) //Always visible - PGEX_BoolVal("SP", lvlitem.gamestart) //Is Game start point - PGEX_BoolVal("BP", lvlitem.pathbg) //Path background - PGEX_BoolVal("BG", lvlitem.bigpathbg) //Big path background - PGEX_StrVal("XTRA", lvlitem.meta.custom_params)//Custom JSON data tree - } - lvlitem.meta.array_id = FileData.level_array_id++; - lvlitem.meta.index = static_cast(FileData.levels.size()); - FileData.levels.push_back(lvlitem); - } - }//LEVELS - } - ///////////////////////////////////////EndFile/////////////////////////////////////// - errorString.clear(); //If no errors, clear string; - FileData.meta.ReadFileValid = true; - return true; -badfile: //If file format not corrects - FileData.meta.ERROR_info = errorString; - FileData.meta.ERROR_linenum = str_count; - FileData.meta.ERROR_linedata = line; - FileData.meta.ReadFileValid = false; - return false; -} - - - -//********************************************************* -//****************WRITE FILE FORMAT************************ -//********************************************************* - -bool FileFormats::WriteExtendedWldFileF(PGESTRING filePath, WorldData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileOutput file; - - if(!file.open(filePath, true, false, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open file for write"; - return false; - } - - return WriteExtendedWldFile(file, FileData); -} - -bool FileFormats::WriteExtendedWldFileRaw(WorldData &FileData, PGESTRING &rawdata) -{ - errorString.clear(); - PGE_FileFormats_misc::RawTextOutput file; - - if(!file.open(&rawdata, PGE_FileFormats_misc::TextOutput::truncate)) - { - errorString = "Failed to open raw string for write"; - return false; - } - - return WriteExtendedWldFile(file, FileData); -} - -bool FileFormats::WriteExtendedWldFile(PGE_FileFormats_misc::TextOutput &out, WorldData &FileData) -{ - pge_size_t i; - bool addArray = false; - FileData.meta.RecentFormat = WorldData::PGEX; - addArray = false; - - for(pge_size_t z = 0; z < FileData.nocharacter.size(); z++) - { - bool x = FileData.nocharacter[z]; - if(x) addArray = true; - } - - //HEAD section - if( - (!IsEmpty(FileData.EpisodeTitle)) || - (addArray) || - (!IsEmpty(FileData.IntroLevel_file)) || - (FileData.HubStyledWorld) || - (FileData.restartlevel) || - (FileData.stars > 0) || - (!IsEmpty(FileData.authors)) - ) - { - out << "HEAD\n"; - - if(!IsEmpty(FileData.EpisodeTitle)) - out << PGEFile::value("TL", PGEFile::WriteStr(FileData.EpisodeTitle)); // Episode title - - addArray = false; - - for(pge_size_t z = 0; z < FileData.nocharacter.size(); z++) - { - bool x = FileData.nocharacter[z]; - if(x) addArray = true; - } - - if(addArray) - out << PGEFile::value("DC", PGEFile::WriteBoolArr(FileData.nocharacter)); // Disabled characters - if(!IsEmpty(FileData.IntroLevel_file)) - out << PGEFile::value("IT", PGEFile::WriteStr(FileData.IntroLevel_file)); // Intro level - if(FileData.HubStyledWorld) - out << PGEFile::value("HB", PGEFile::WriteBool(FileData.HubStyledWorld)); // Hub-styled episode - if(FileData.restartlevel) - out << PGEFile::value("RL", PGEFile::WriteBool(FileData.restartlevel)); // Restart on fail - if(FileData.stars > 0) - out << PGEFile::value("SZ", PGEFile::WriteInt(FileData.stars)); // Total stars number - if(!IsEmpty(FileData.authors)) - out << PGEFile::value("CD", PGEFile::WriteStr(FileData.authors)); // Credits - - out << "\n"; - out << "HEAD_END\n"; - } - - //////////////////////////////////////MetaData//////////////////////////////////////////////// - //Bookmarks - if(!FileData.metaData.bookmarks.empty()) - { - out << "META_BOOKMARKS\n"; - - for(i = 0; i < FileData.metaData.bookmarks.size(); i++) - { - Bookmark &bm = FileData.metaData.bookmarks[i]; - //Bookmark name - out << PGEFile::value("BM", PGEFile::WriteStr(bm.bookmarkName)); - out << PGEFile::value("X", PGEFile::WriteRoundFloat(bm.x)); - out << PGEFile::value("Y", PGEFile::WriteRoundFloat(bm.y)); - out << "\n"; - } - - out << "META_BOOKMARKS_END\n"; - } - -#ifdef PGE_EDITOR - - //Some System information - if(FileData.metaData.crash.used) - { - out << "META_SYS_CRASH\n"; - out << PGEFile::value("UT", PGEFile::WriteBool(FileData.metaData.crash.untitled)); - out << PGEFile::value("MD", PGEFile::WriteBool(FileData.metaData.crash.modifyed)); - out << PGEFile::value("FF", PGEFile::WriteInt(FileData.metaData.crash.fmtID)); - out << PGEFile::value("FV", PGEFile::WriteInt(FileData.metaData.crash.fmtVer)); - out << PGEFile::value("N", PGEFile::WriteStr(FileData.metaData.crash.filename)); - out << PGEFile::value("P", PGEFile::WriteStr(FileData.metaData.crash.path)); - out << PGEFile::value("FP", PGEFile::WriteStr(FileData.metaData.crash.fullPath)); - out << "\n"; - out << "META_SYS_CRASH_END\n"; - } - -#endif - //////////////////////////////////////MetaData///END////////////////////////////////////////// - - if(!FileData.tiles.empty()) - { - out << "TILES\n"; - - for(i = 0; i < FileData.tiles.size(); i++) - { - WorldTerrainTile &tt = FileData.tiles[i]; - out << PGEFile::value("ID", PGEFile::WriteInt(tt.id)); - out << PGEFile::value("X", PGEFile::WriteInt(tt.x)); - out << PGEFile::value("Y", PGEFile::WriteInt(tt.y)); - if(!IsEmpty(tt.meta.custom_params)) - out << PGEFile::value("XTRA", PGEFile::WriteStr(tt.meta.custom_params)); - out << "\n"; - } - - out << "TILES_END\n"; - } - - if(!FileData.scenery.empty()) - { - out << "SCENERY\n"; - - for(i = 0; i < FileData.scenery.size(); i++) - { - WorldScenery &ws = FileData.scenery[i]; - out << PGEFile::value("ID", PGEFile::WriteInt(ws.id)); - out << PGEFile::value("X", PGEFile::WriteInt(ws.x)); - out << PGEFile::value("Y", PGEFile::WriteInt(ws.y)); - if(!IsEmpty(ws.meta.custom_params)) - out << PGEFile::value("XTRA", PGEFile::WriteStr(ws.meta.custom_params)); - out << "\n"; - } - - out << "SCENERY_END\n"; - } - - if(!FileData.paths.empty()) - { - out << "PATHS\n"; - - for(i = 0; i < FileData.paths.size(); i++) - { - WorldPathTile &wp = FileData.paths[i]; - out << PGEFile::value("ID", PGEFile::WriteInt(wp.id)); - out << PGEFile::value("X", PGEFile::WriteInt(wp.x)); - out << PGEFile::value("Y", PGEFile::WriteInt(wp.y)); - if(!IsEmpty(wp.meta.custom_params)) - out << PGEFile::value("XTRA", PGEFile::WriteStr(wp.meta.custom_params)); - out << "\n"; - } - - out << "PATHS_END\n"; - } - - if(!FileData.music.empty()) - { - out << "MUSICBOXES\n"; - - for(i = 0; i < FileData.music.size(); i++) - { - WorldMusicBox &wm = FileData.music[i]; - out << PGEFile::value("ID", PGEFile::WriteInt(wm.id)); - out << PGEFile::value("X", PGEFile::WriteInt(wm.x)); - out << PGEFile::value("Y", PGEFile::WriteInt(wm.y)); - if(!IsEmpty(wm.music_file)) - out << PGEFile::value("MF", PGEFile::WriteStr(wm.music_file)); - if(!IsEmpty(wm.meta.custom_params)) - out << PGEFile::value("XTRA", PGEFile::WriteStr(wm.meta.custom_params)); - out << "\n"; - } - - out << "MUSICBOXES_END\n"; - } - - if(!FileData.levels.empty()) - { - out << "LEVELS\n"; - WorldLevelTile defLvl = CreateWldLevel(); - - for(i = 0; i < FileData.levels.size(); i++) - { - WorldLevelTile < = FileData.levels[i]; - out << PGEFile::value("ID", PGEFile::WriteInt(lt.id)); - out << PGEFile::value("X", PGEFile::WriteInt(lt.x)); - out << PGEFile::value("Y", PGEFile::WriteInt(lt.y)); - if(!IsEmpty(lt.title)) - out << PGEFile::value("LT", PGEFile::WriteStr(lt.title)); - if(!IsEmpty(lt.lvlfile)) - out << PGEFile::value("LF", PGEFile::WriteStr(lt.lvlfile)); - if(lt.entertowarp != defLvl.entertowarp) - out << PGEFile::value("EI", PGEFile::WriteInt(lt.entertowarp)); - if(lt.left_exit != defLvl.left_exit) - out << PGEFile::value("EL", PGEFile::WriteInt(lt.left_exit)); - if(lt.top_exit != defLvl.top_exit) - out << PGEFile::value("ET", PGEFile::WriteInt(lt.top_exit)); - if(lt.right_exit != defLvl.right_exit) - out << PGEFile::value("ER", PGEFile::WriteInt(lt.right_exit)); - if(lt.bottom_exit != defLvl.bottom_exit) - out << PGEFile::value("EB", PGEFile::WriteInt(lt.bottom_exit)); - if(lt.gotox != defLvl.gotox) - out << PGEFile::value("WX", PGEFile::WriteInt(lt.gotox)); - if(lt.gotoy != defLvl.gotoy) - out << PGEFile::value("WY", PGEFile::WriteInt(lt.gotoy)); - if(lt.alwaysVisible) - out << PGEFile::value("AV", PGEFile::WriteBool(lt.alwaysVisible)); - if(lt.gamestart) - out << PGEFile::value("SP", PGEFile::WriteBool(lt.gamestart)); - if(lt.pathbg) - out << PGEFile::value("BP", PGEFile::WriteBool(lt.pathbg)); - if(lt.bigpathbg) - out << PGEFile::value("BG", PGEFile::WriteBool(lt.bigpathbg)); - if(!IsEmpty(lt.meta.custom_params)) - out << PGEFile::value("XTRA", PGEFile::WriteStr(lt.meta.custom_params)); - out << "\n"; - } - - out << "LEVELS_END\n"; - } - - return true; -} diff --git a/LunaDll/libs/PGE_File_Formats/file_rwopen.cpp b/LunaDll/libs/PGE_File_Formats/file_rwopen.cpp deleted file mode 100644 index 113ef12c2..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_rwopen.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifdef PGE_FILES_QT -#include -#include -#endif - -#include "file_formats.h" -#include "pge_file_lib_globs.h" - -bool FileFormats::OpenLevelFile(PGESTRING filePath, LevelData &FileData) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileInput file; - PGESTRING firstLine; - if(!file.open(filePath)) - { - FileData.meta.ReadFileValid = false; - FileData.meta.ERROR_info="Can't open file"; - FileData.meta.ERROR_linedata=""; - FileData.meta.ERROR_linenum=-1; - errorString = FileData.meta.ERROR_info; - return false; - } - firstLine = file.read(8); - file.close(); - - if( PGE_StartsWith( firstLine, "SMBXFile" ) ) - { - //Read SMBX65-38A LVL File - if(!ReadSMBX38ALvlFileF( filePath, FileData )) - { - errorString = FileData.meta.ERROR_info; - return false; - } - } - else if( PGE_DetectSMBXFile( firstLine ) ) - { - //Read SMBX LVL File - if(!ReadSMBX64LvlFileF( filePath, FileData )) - { - errorString = FileData.meta.ERROR_info; - return false; - } - } - else - { //Read PGE LVLX File - if(!ReadExtendedLvlFileF( filePath, FileData )) - { - errorString = FileData.meta.ERROR_info; - return false; - } - } - - if(PGE_FileFormats_misc::TextFileInput::exists(filePath+".meta")) - { - if( ! ReadNonSMBX64MetaDataF( filePath+".meta", FileData.metaData ) ) - errorString = "Can't open meta-file"; - } - - return true; -} - -bool FileFormats::OpenLevelFileHeader(PGESTRING filePath, LevelData& data) -{ - errorString.clear(); - - PGE_FileFormats_misc::TextFileInput file; - PGESTRING firstLine; - if(!file.open(filePath)) - { - data.meta.ReadFileValid = false; - data.meta.ERROR_info="Can't open file"; - data.meta.ERROR_linedata=""; - data.meta.ERROR_linenum=-1; - return false; - } - firstLine = file.readLine(); - file.close(); - - if( PGE_StartsWith(firstLine, "SMBXFile") ) - { - //Read SMBX65-38A LVL File - return ReadSMBX38ALvlFileHeader( filePath, data ); - } - else if( PGE_DetectSMBXFile(firstLine) ) - { - //Read SMBX LVL File - return ReadSMBX64LvlFileHeader( filePath, data ); - } - else - { //Read PGE LVLX File - return ReadExtendedLvlFileHeader( filePath, data ); - } -} - - -bool FileFormats::SaveLevelFile(LevelData &FileData, PGESTRING filePath, LevelFileFormat format, unsigned int FormatVersion) -{ - errorString.clear(); - switch(format) - { - case LVL_PGEX: - { - smbx64CountStars(FileData); - if(!FileFormats::WriteExtendedLvlFileF(filePath, FileData)) - { - errorString="Cannot save file "+filePath+"."; - return false; - } - return true; - } - //break; - case LVL_SMBX64: - { - //Apply SMBX64-specific things to entire array - smbx64LevelPrepare(FileData); - - if(!FileFormats::WriteSMBX64LvlFileF( filePath, FileData, FormatVersion)) - { - errorString="Cannot save file "+filePath+"."; - return false; - } - - //save additional meta data - if( !FileData.metaData.bookmarks.empty() ) - { - if(!FileFormats::WriteNonSMBX64MetaDataF(filePath+".meta", FileData.metaData)) - { - errorString="Cannot save file "+filePath+".meta."; - return false; - } - } - return true; - } - //break; - case LVL_SMBX38A: - { - if(!FileFormats::WriteSMBX38ALvlFileF(filePath, FileData)) - { - errorString="Cannot save file "+filePath+"."; - return false; - } - return true; - } - //break; - } - errorString = "Unsupported file type"; - return false; -} - -bool FileFormats::SaveLevelData(LevelData &FileData, PGESTRING &RawData, LevelFileFormat format, unsigned int FormatVersion) -{ - errorString.clear(); - switch(format) - { - case LVL_PGEX: - { - smbx64CountStars(FileData); - WriteExtendedLvlFileRaw(FileData, RawData); - return true; - } - //break; - case LVL_SMBX64: - { - smbx64LevelPrepare(FileData); - WriteSMBX64LvlFileRaw(FileData, RawData, FormatVersion); - return true; - } - //break; - case LVL_SMBX38A: - { - FileFormats::WriteSMBX38ALvlFileRaw(FileData, RawData); - return true; - } - //break; - } - errorString = "Unsupported file type"; - return false; -} - - - -bool FileFormats::OpenWorldFile(PGESTRING filePath, WorldData &data) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileInput file; - - PGESTRING firstLine; - if(!file.open(filePath)) - { - data.meta.ERROR_info="Can't open file"; - data.meta.ERROR_linedata=""; - data.meta.ERROR_linenum=-1; - data.meta.ReadFileValid = false; - return false; - } - - firstLine = file.read(8); - file.close(); - - if( PGE_StartsWith( firstLine, "SMBXFile" ) ) - { - //Read SMBX-38A WLD File - if(!ReadSMBX38AWldFileF( filePath, data )) - { - errorString = data.meta.ERROR_info; - return false; - } - } - else if( PGE_DetectSMBXFile(firstLine) ) - { - //Read SMBX WLD File - if(!ReadSMBX64WldFileF( filePath, data )) - { - errorString = data.meta.ERROR_info; - return false; - } - } - else - { - //Read PGE WLDX File - if(!ReadExtendedWldFileF( filePath, data )) - { - errorString = data.meta.ERROR_info; - return false; - } - } - - if( PGE_FileFormats_misc::TextFileInput::exists(filePath+".meta") ) - { - if( ! ReadNonSMBX64MetaDataF( filePath+".meta", data.metaData ) ) - errorString = "Can't open meta-file"; - } - - return true; -} - -bool FileFormats::OpenWorldFileHeader(PGESTRING filePath, WorldData& data) -{ - errorString.clear(); - PGE_FileFormats_misc::TextFileInput file; - if(!file.open(filePath)) - { - data.meta.ERROR_info = "Can't open file"; - data.meta.ERROR_linedata = ""; - data.meta.ERROR_linenum = -1; - data.meta.ReadFileValid = false; - return false; - } - PGESTRING firstLine; - firstLine = file.readLine(); - file.close(); - - if( PGE_StartsWith(firstLine, "SMBXFile") ) - { - //Read SMBX-38A WLD File - return ReadSMBX38AWldFileHeader( filePath, data ); - } - else if( PGE_DetectSMBXFile(firstLine) ) - { //Read SMBX WLD File - return ReadSMBX64WldFileHeader( filePath, data ); - } - else - { //Read PGE WLDX File - return ReadExtendedWldFileHeader( filePath, data); - } -} - -bool FileFormats::SaveWorldFile(WorldData &FileData, PGESTRING filePath, FileFormats::WorldFileFormat format, unsigned int FormatVersion) -{ - errorString.clear(); - switch(format) - { - case WLD_PGEX: - { - if(!FileFormats::WriteExtendedWldFileF(filePath, FileData)) - { - errorString="Cannot save file "+filePath+"."; - return false; - } - return true; - } - //break; - case WLD_SMBX64: - { - if(!FileFormats::WriteSMBX64WldFileF( filePath, FileData, FormatVersion)) - { - errorString="Cannot save file "+filePath+"."; - return false; - } - - //save additional meta data - if( !FileData.metaData.bookmarks.empty() ) - { - if(!FileFormats::WriteNonSMBX64MetaDataF(filePath+".meta", FileData.metaData)) - { - errorString="Cannot save file "+filePath+".meta."; - return false; - } - } - return true; - } - //break; - case WLD_SMBX38A: - { - if(!FileFormats::WriteSMBX38AWldFileF(filePath, FileData)) - { - errorString = "Cannot save file " + filePath + "."; - return false; - } - return true; - } - //break; - } - errorString = "Unsupported file type"; - return false; -} - -bool FileFormats::SaveWorldData(WorldData &FileData, PGESTRING &RawData, FileFormats::WorldFileFormat format, unsigned int FormatVersion) -{ - errorString.clear(); - switch(format) - { - case WLD_PGEX: - { - WriteExtendedWldFileRaw(FileData, RawData); - return true; - } - //break; - case WLD_SMBX64: - { - WriteSMBX64WldFileRaw(FileData, RawData, FormatVersion); - return true; - } - //break; - case WLD_SMBX38A: - { - WriteSMBX38AWldFileRaw(FileData, RawData); - return true; - } - //break; - } - errorString = "Unsupported file type"; - return false; -} - - diff --git a/LunaDll/libs/PGE_File_Formats/file_strlist.cpp b/LunaDll/libs/PGE_File_Formats/file_strlist.cpp deleted file mode 100644 index 70525bb53..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_strlist.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "pge_file_lib_globs.h" -#include "file_strlist.h" - -FileStringList::FileStringList() -{ - lineID=0; -} - -FileStringList::FileStringList(PGESTRING fileData) -{ - addData(fileData); -} - -FileStringList::~FileStringList() -{ - buffer.clear(); -} - -void FileStringList::addData(const PGESTRING &fileData) -{ - buffer.clear(); - #ifdef PGE_FILES_QT - buffer = fileData.split(QRegExp("[\r\n]"), QString::SkipEmptyParts); - #else - PGE_SPLITSTRING(buffer, fileData, "\n"); - #endif - lineID = 0; -} - -PGESTRING FileStringList::readLine() -{ - PGESTRING sent; - - if(!isEOF()) - { - sent = buffer[static_cast(lineID)]; - lineID++; - } - return sent; -} - -bool FileStringList::isEOF() -{ - return (lineID >= (signed)buffer.size()); -} - -bool FileStringList::atEnd() -{ - return isEOF(); -} - diff --git a/LunaDll/libs/PGE_File_Formats/file_strlist.h b/LunaDll/libs/PGE_File_Formats/file_strlist.h deleted file mode 100644 index 72ca2bc73..000000000 --- a/LunaDll/libs/PGE_File_Formats/file_strlist.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/*! - * \file file_strlist.h - * \brief Contains defition of a FileStringList class - a string container - * which automatically splits lines by line feeds - */ - -#pragma once -#ifndef FILE_STRLIST_H -#define FILE_STRLIST_H - -#ifdef PGE_FILES_QT -#include -#include -#include -typedef QString PGESTRING; -typedef QStringList PGESTRINGList; -#else -#include -#include -typedef std::string PGESTRING; -typedef std::vector PGESTRINGList; -#endif - -/*! - * \brief Provides string container automatically splited from entire file data - */ -#ifdef PGE_FILES_QT -class FileStringList:public QObject -{ - Q_OBJECT -#else -class FileStringList -{ -#endif - -public: - /*! - * \brief Constructor - */ - FileStringList(); - - /*! - * \brief Constructor with pre-set data - * \param fileData file data which will be splited by line-feeds - */ - FileStringList(PGESTRING fileData); - - /*! - * Destructor - */ - ~FileStringList(); - - /*! - * \brief Changes filedata and rebuilds list of lines - * \param fileData file data which will be splited by line-feeds - */ - void addData(const PGESTRING& fileData); - - /*! - * \brief Returns current line contents and incements internal line counter - * \return contents of current line - */ - PGESTRING readLine(); - - /*! - * \brief Are all lines was gotten? - * \return true if internal line counter is equal or more than total number of lines - */ - bool isEOF(); - - /*! - * \brief Are all lines was gotten? - * \return true if internal line counter is equal or more than total number of lines - */ - bool atEnd(); -private: - /*! - * \brief Contains splited list of string lines - */ - PGESTRINGList buffer; - - /*! - * \brief Internal counter of gotten lines - */ - long lineID; -}; - -#endif // FILE_STRLIST_H - diff --git a/LunaDll/libs/PGE_File_Formats/invoke_default.hpp b/LunaDll/libs/PGE_File_Formats/invoke_default.hpp deleted file mode 100644 index 3bece8f83..000000000 --- a/LunaDll/libs/PGE_File_Formats/invoke_default.hpp +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef INVOKE_DEFAULT_HHHHH -#define INVOKE_DEFAULT_HHHHH -#include -#include -#include - -namespace idef -{ - namespace detail - { - template - struct remove_const_ref - { - using type = typename std::remove_reference::type>::type; - }; - - template - struct default_if_nullptr_impl - { - using func_type = PossibleFunc; - static const func_type &Get(const PossibleFunc &pf, const DefaultFunc & /*df*/) - { - return pf; - } - }; - - template - struct default_if_nullptr_impl - { - using func_type = DefaultFunc; - static const func_type &Get(std::nullptr_t /*pf*/, const DefaultFunc &df) - { - return df; - } - }; - - - template - struct invoke_or_noop_impl - { - template - static Ret invoke(Func &&f, Args &&... args) - { - return f(std::forward(args)...); - } - }; - - template<> - struct invoke_or_noop_impl - { - template - static Ret invoke(Func && /*f*/, Args &&... /*args*/) - { - return Ret(); - } - }; - } - - template - auto default_if_nullptr(const PossibleFunc &pf, const DefaultFunc &df) -> - const typename detail::default_if_nullptr_impl::type, DefaultFunc>::func_type & - { - using impl_type = detail::default_if_nullptr_impl::type, DefaultFunc>; - return impl_type::Get(pf, df); - } - - template - Ret invoke_or_noop(Func f, Args &&... args) - { - static_assert(std::is_default_constructible::value || std::is_same::value, "Return value must be default constructible!"); - return detail::invoke_or_noop_impl::template invoke(std::forward(f), std::forward(args)...); - } -} - -#endif diff --git a/LunaDll/libs/PGE_File_Formats/lvl_filedata.cpp b/LunaDll/libs/PGE_File_Formats/lvl_filedata.cpp deleted file mode 100644 index 2c07bc4de..000000000 --- a/LunaDll/libs/PGE_File_Formats/lvl_filedata.cpp +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "file_formats.h" -#include "lvl_filedata.h" - -#include - -/*********************************************************************************/ -/***************************SMBX64-Specific features******************************/ -/*********************************************************************************/ - -//Built-in order priorities per SMBX-64 BGO's -const int _smbx64_bgo_sort_priorities[190] = -{ - 77, 75, 75, 75, 75, 75, 75, 75, 75, 75, 20, 20, 75, 10, 75, 75, 75, 75, 75, 75, 75, 75, 125, 125, 125, 26, - 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 125, 125, 75, 80, 125, 125, 125, 30, - 75, 75, 75, 75, 75, 75, 75, 20, 20, 75, 75, 75, 26, 25, 75, 125, 125, 90, 90, 90, 90, 90, 10, 10, 10, 10, 30, - 75, 75, 26, 26, 75, 75, 75, 98, 98, 75, 75, 75, 98, 75, 75, 75, 75, 75, 75, 99, 75, 75, 75, 75, 98, 98, 125, - 98, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 76, 76, 76, 75, 75, - 75, 75, 75, 125, 125, 80, 80, 90, 75, 125, 75, 125, 75, 75, 75, 75, 75, 75, 75, 75, 125, 125, 125, 125, 25, - 25, 75, 75, 75, 75, 26, 26, 26, 26, 26, 26, 75, 75, 25, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 75, 125, 125, 75, 75 -}; - -void FileFormats::smbx64LevelPrepare(LevelData &lvl) -{ - //Set SMBX64 specific option to BGO - for(pge_size_t q = 0; q < lvl.bgo.size(); q++) - { - if(lvl.bgo[q].smbx64_sp < 0) - { - if((lvl.bgo[q].id > 0) && (lvl.bgo[q].id <= (unsigned)190)) - lvl.bgo[q].smbx64_sp_apply = _smbx64_bgo_sort_priorities[lvl.bgo[q].id - 1]; - } - else - lvl.bgo[q].smbx64_sp_apply = lvl.bgo[q].smbx64_sp; - } - - //Mark & Count Stars - lvl.stars = smbx64CountStars(lvl); -} - -int FileFormats::smbx64CountStars(LevelData &lvl) -{ - int stars = 0; - for(pge_size_t q = 0; q < lvl.npc.size(); q++) - { - LevelNPC &npc = lvl.npc[q]; - npc.is_star = ((npc.id == 97) || (npc.id == 196)) && !npc.friendly; - if(npc.is_star) - stars += 1; - } - return stars; -} - -void FileFormats::smbx64LevelSortBlocks(LevelData &lvl) -{ - if(lvl.blocks.size() <= 1) return; //Nothing to sort! - - class my_stack : public std::stack< int > - { - public: - using std::stack::c; // expose the container - }; - - my_stack beg; - my_stack end; - LevelBlock piv; - int i = 0, L, R, swapv; - beg.push(0); - end.push((int)lvl.blocks.size()); -#define ST(x) static_cast(x) - while(i >= 0) - { - L = beg.c[ST(i)]; - R = end.c[ST(i)] - 1; - if(L < R) - { - piv = lvl.blocks[ST(L)]; - while(L < R) - { - while(( - (lvl.blocks[ST(R)].x > piv.x) || - ((lvl.blocks[ST(R)].x == piv.x) && (lvl.blocks[ST(R)].y > piv.y)) || - ((lvl.blocks[ST(R)].x == piv.x) && (lvl.blocks[ST(R)].y == piv.y) && (lvl.blocks[ST(R)].meta.array_id >= piv.meta.array_id)) - ) && (L < R)) R--; - if(L < R) lvl.blocks[ST(L++)] = lvl.blocks[ST(R)]; - - while( - ( - (lvl.blocks[ST(L)].x < piv.x) || - ((lvl.blocks[ST(L)].x == piv.x) && (lvl.blocks[ST(L)].y < piv.y)) || - ((lvl.blocks[ST(L)].x == piv.x) && (lvl.blocks[ST(L)].y == piv.y) && (lvl.blocks[ST(L)].meta.array_id <= piv.meta.array_id)) - ) && (L < R)) L++; - if(L < R) lvl.blocks[ST(R--)] = lvl.blocks[ST(L)]; - } - lvl.blocks[ST(L)] = piv; - beg.push(L + 1); - end.push(end.c[ST(i)]); - end.c[ST(i++)] = (L); - if((end.c[ST(i)] - beg.c[ST(i)]) > (end.c[ST(i - 1)] - beg.c[ST(i - 1)])) - { - swapv = beg.c[ST(i)]; - beg.c[ST(i)] = beg.c[ST(i - 1)]; - beg.c[ST(i - 1)] = swapv; - swapv = end.c[ST(i)]; - end.c[ST(i)] = end.c[ST(i - 1)]; - end.c[ST(i - 1)] = swapv; - } - } - else - { - i--; - beg.pop(); - end.pop(); - } - } -#undef ST -} - -void FileFormats::smbx64LevelSortBGOs(LevelData &lvl) -{ - if(lvl.bgo.size() <= 1) return; //Nothing to sort! - - class my_stack : public std::stack< int > - { - public: - using std::stack::c; // expose the container - }; - - my_stack beg; - my_stack end; - LevelBGO piv; - int i = 0, L, R, swapv; - beg.push(0); - end.push((int)lvl.bgo.size()); -#define ST(x) static_cast(x) - while(i >= 0) - { - L = beg.c[ST(i)]; - R = end.c[ST(i)] - 1; - if(L < R) - { - piv = lvl.bgo[ST(L)]; - while(L < R) - { - while(( - (lvl.bgo[ST(R)].smbx64_sp_apply > piv.smbx64_sp_apply) || - /*((lvl.bgo[R].smbx64_sp_apply == piv.smbx64_sp_apply) && (lvl.bgo[R].x > piv.x))|| - ((lvl.bgo[R].smbx64_sp_apply == piv.smbx64_sp_apply) && (lvl.bgo[R].x == piv.x) && (lvl.bgo[R].y > piv.y))|| - ((lvl.bgo[R].smbx64_sp_apply == piv.smbx64_sp_apply) && (lvl.bgo[R].x == piv.x) && (lvl.bgo[R].y == piv.y) && (lvl.bgo[R].array_id >= piv.array_id))*/ - ((lvl.bgo[ST(R)].smbx64_sp_apply == piv.smbx64_sp_apply) && (lvl.bgo[ST(R)].meta.array_id >= piv.meta.array_id)) - ) && (L < R)) R--; - if(L < R) lvl.bgo[ST(L++)] = lvl.bgo[ST(R)]; - - while( - ( - (lvl.bgo[ST(L)].smbx64_sp_apply < piv.smbx64_sp_apply) || - /*((lvl.bgo[L].smbx64_sp_apply == piv.smbx64_sp_apply) && (lvl.bgo[L].x < piv.x))|| - ((lvl.bgo[L].smbx64_sp_apply == piv.smbx64_sp_apply) && (lvl.bgo[L].x == piv.x) && (lvl.bgo[L].y < piv.y))|| - ((lvl.bgo[L].smbx64_sp_apply == piv.smbx64_sp_apply) && (lvl.bgo[L].x == piv.x) && (lvl.bgo[L].y == piv.y) && (lvl.bgo[L].array_id <= piv.array_id))*/ - ((lvl.bgo[ST(L)].smbx64_sp_apply == piv.smbx64_sp_apply) && (lvl.bgo[ST(L)].meta.array_id <= piv.meta.array_id)) - ) && (L < R)) L++; - if(L < R) lvl.bgo[ST(R--)] = lvl.bgo[ST(L)]; - } - lvl.bgo[ST(L)] = piv; - beg.push(L + 1); - end.push(end.c[ST(i)]); - end.c[ST(i++)] = (L); - if((end.c[ST(i)] - beg.c[ST(i)]) > (end.c[ST(i - 1)] - beg.c[ST(i - 1)])) - { - swapv = beg.c[ST(i)]; - beg.c[ST(i)] = beg.c[ST(i - 1)]; - beg.c[ST(i - 1)] = swapv; - swapv = end.c[ST(i)]; - end.c[ST(i)] = end.c[ST(i - 1)]; - end.c[ST(i - 1)] = swapv; - } - } - else - { - i--; - beg.pop(); - end.pop(); - } - } -#undef ST -} - -int FileFormats::smbx64LevelCheckLimits(LevelData &lvl) -{ - int errorCode = SMBX64_FINE; - //Sections limit - if(lvl.sections.size() > 21) errorCode |= SMBX64EXC_SECTIONS; - //Blocks limit - if(lvl.blocks.size() > 16384) errorCode |= SMBX64EXC_BLOCKS; - //BGO limits - if(lvl.bgo.size() > 8000) errorCode |= SMBX64EXC_BGOS; - //NPC limits - if(lvl.npc.size() > 5000) errorCode |= SMBX64EXC_NPCS; - //Warps limits - if(lvl.doors.size() > 199) errorCode |= SMBX64EXC_WARPS; - //Physical Environment zones - if(lvl.physez.size() > 450) errorCode |= SMBX64EXC_WATERBOXES; - //Layers limits - if(lvl.layers.size() > 100) errorCode |= SMBX64EXC_LAYERS; - //Events limits - if(lvl.events.size() > 100) errorCode |= SMBX64EXC_EVENTS; - - return errorCode; -} -/*********************************************************************************/ - - - -//******************************************************************** -//*******************Structure initializators************************* -//******************************************************************** - -//Default dataSets -LevelNPC FileFormats::CreateLvlNpc() -{ - return LevelNPC(); -} - -LevelDoor FileFormats::CreateLvlWarp() -{ - return LevelDoor(); -} - -LevelBlock FileFormats::CreateLvlBlock() -{ - return LevelBlock(); -} - -LevelBGO FileFormats::CreateLvlBgo() -{ - return LevelBGO(); -} - -LevelPhysEnv FileFormats::CreateLvlPhysEnv() -{ - return LevelPhysEnv(); -} - -LevelSMBX64Event FileFormats::CreateLvlEvent() -{ - LevelSMBX64Event dummyEvent; - - dummyEvent.name = ""; - dummyEvent.msg = ""; - dummyEvent.sound_id = 0; - dummyEvent.end_game = 0; - dummyEvent.trigger = ""; - dummyEvent.trigger_timer = 0; - dummyEvent.nosmoke = false; - dummyEvent.ctrls_enable = false; - dummyEvent.ctrl_altjump = false; - dummyEvent.ctrl_altrun = false; - dummyEvent.ctrl_down = false; - dummyEvent.ctrl_drop = false; - dummyEvent.ctrl_jump = false; - dummyEvent.ctrl_left = false; - dummyEvent.ctrl_right = false; - dummyEvent.ctrl_run = false; - dummyEvent.ctrl_start = false; - dummyEvent.ctrl_up = false; - dummyEvent.ctrl_lock_keyboard = false; - dummyEvent.autostart = LevelSMBX64Event::AUTO_None; - dummyEvent.autostart_condition = ""; - dummyEvent.movelayer = ""; - dummyEvent.layer_speed_x = 0.0; - dummyEvent.layer_speed_y = 0.0; - dummyEvent.move_camera_x = 0.0; - dummyEvent.move_camera_y = 0.0; - dummyEvent.scroll_section = 0; - dummyEvent.trigger_api_id = 0; - dummyEvent.layers_hide.clear(); - dummyEvent.layers_show.clear(); - dummyEvent.layers_toggle.clear(); - - LevelEvent_Sets events_sets; - dummyEvent.sets.clear(); - for(int j = 0; j < 21; j++) - { - events_sets.id = j; - events_sets.music_id = -1; - events_sets.background_id = -1; - events_sets.position_left = -1; - events_sets.position_top = 0; - events_sets.position_bottom = 0; - events_sets.position_right = 0; - dummyEvent.sets.push_back(events_sets); - } - - return dummyEvent; -} - -LevelVariable FileFormats::CreateLvlVariable(PGESTRING vname) -{ - LevelVariable var; - var.name = vname; - var.value = ""; - return var; -} - -LevelScript FileFormats::CreateLvlScript(PGESTRING name, int lang) -{ - LevelScript scr; - scr.language = lang; - scr.name = name; - scr.script = ""; - return scr; -} - -LevelSection FileFormats::CreateLvlSection() -{ - return LevelSection(); -} - -LevelLayer FileFormats::CreateLvlLayer() -{ - return LevelLayer(); -} - -PlayerPoint FileFormats::CreateLvlPlayerPoint(unsigned int id) -{ - PlayerPoint dummyPlayer; - dummyPlayer.id = id; - switch(id) - { - case 1: - dummyPlayer.h = 54; - break; - case 2: - dummyPlayer.h = 60; - break; - default: - dummyPlayer.h = 32; //-V112 - } - - return dummyPlayer; -} - -void FileFormats::LevelAddInternalEvents(LevelData &FileData) -{ - LevelLayer layers; - LevelSMBX64Event events; - - layers = CreateLvlLayer(); - - //Append system layers if not exist - bool def = false, desb = false, spawned = false; - - for(pge_size_t lrID = 0; lrID < FileData.layers.size(); lrID++) - { - LevelLayer &lr = FileData.layers[lrID]; - if(lr.name == "Default") def = true; - else if(lr.name == "Destroyed Blocks") desb = true; - else if(lr.name == "Spawned NPCs") spawned = true; - } - - if(!def) - { - layers.hidden = false; - layers.name = "Default"; - FileData.layers.push_back(layers); - } - if(!desb) - { - layers.hidden = true; - layers.name = "Destroyed Blocks"; - FileData.layers.push_back(layers); - } - if(!spawned) - { - layers.hidden = false; - layers.name = "Spawned NPCs"; - FileData.layers.push_back(layers); - } - - //Append system events if not exist - //Level - Start - //P Switch - Start - //P Switch - End - bool lstart = false, pstart = false, pend = false; - for(pge_size_t evID = 0; evID < FileData.events.size(); evID++) - { - LevelSMBX64Event &ev = FileData.events[evID]; - if(ev.name == "Level - Start") lstart = true; - else if(ev.name == "P Switch - Start") pstart = true; - else if(ev.name == "P Switch - End") pend = true; - } - - events = CreateLvlEvent(); - - if(!lstart) - { - events.meta.array_id = FileData.events_array_id; - FileData.events_array_id++; - - events.name = "Level - Start"; - FileData.events.push_back(events); - } - if(!pstart) - { - events.meta.array_id = FileData.events_array_id; - FileData.events_array_id++; - - events.name = "P Switch - Start"; - FileData.events.push_back(events); - } - if(!pend) - { - events.meta.array_id = FileData.events_array_id; - FileData.events_array_id++; - - events.name = "P Switch - End"; - FileData.events.push_back(events); - } -} - - -void FileFormats::CreateLevelHeader(LevelData &NewFileData) -{ - NewFileData.CurSection = 0; - NewFileData.playmusic = 0; - NewFileData.meta = FileFormatMeta(); - - NewFileData.open_level_on_fail = ""; - NewFileData.open_level_on_fail_warpID = 0; - - NewFileData.LevelName = ""; - NewFileData.stars = 0; -} - -void FileFormats::CreateLevelData(LevelData &NewFileData) -{ - CreateLevelHeader(NewFileData); - - NewFileData.bgo_array_id = 1; - NewFileData.blocks_array_id = 1; - NewFileData.doors_array_id = 1; - NewFileData.events_array_id = 1; - NewFileData.layers_array_id = 1; - NewFileData.npc_array_id = 1; - NewFileData.physenv_array_id = 1; - - NewFileData.sections.clear(); - //Create Section array - LevelSection section; - for(int i = 0; i < 21; i++) - { - section = CreateLvlSection(); - section.id = i; - NewFileData.sections.push_back(section); - } - - NewFileData.players.clear(); - //Create players array - //PlayerPoint players = dummyLvlPlayerPoint(); - // for(int i=0; i<2;i++) - // { - // players.id++; - // NewFileData.players.push_back(players); - // } - - NewFileData.blocks.clear(); - NewFileData.bgo.clear(); - NewFileData.npc.clear(); - NewFileData.doors.clear(); - NewFileData.physez.clear(); - - NewFileData.layers.clear(); - NewFileData.variables.clear(); - NewFileData.scripts.clear(); - - //Create system layers - //Default - //Destroyed Blocks - //Spawned NPCs - - LevelLayer layers; - layers.hidden = false; - layers.locked = false; - layers.name = "Default"; - layers.meta.array_id = NewFileData.layers_array_id++; - NewFileData.layers.push_back(layers); - - layers.hidden = true; - layers.locked = false; - layers.name = "Destroyed Blocks"; - layers.meta.array_id = NewFileData.layers_array_id++; - NewFileData.layers.push_back(layers); - - layers.hidden = false; - layers.locked = false; - layers.name = "Spawned NPCs"; - layers.meta.array_id = NewFileData.layers_array_id++; - NewFileData.layers.push_back(layers); - - NewFileData.events.clear(); - //Create system events - //Level - Start - //P Switch - Start - //P Switch - End - - LevelSMBX64Event events = CreateLvlEvent(); - - events.meta.array_id = NewFileData.events_array_id; - NewFileData.events_array_id++; - - events.name = "Level - Start"; - NewFileData.events.push_back(events); - - events.meta.array_id = NewFileData.events_array_id; - NewFileData.events_array_id++; - - events.name = "P Switch - Start"; - NewFileData.events.push_back(events); - - events.meta.array_id = NewFileData.events_array_id; - NewFileData.events_array_id++; - - events.name = "P Switch - End"; - NewFileData.events.push_back(events); -} - -LevelData FileFormats::CreateLevelData() -{ - LevelData NewFileData; - CreateLevelData(NewFileData); - return NewFileData; -} - - - -bool LevelData::eventIsExist(PGESTRING title) -{ - for(auto &e : events) - { - if(e.name == title) - return true; - } - return false; -} - -bool LevelData::layerIsExist(PGESTRING title) -{ - for(auto &l : layers) - { - if(l.name == title) - return true; - } - return false; -} - -bool LevelSMBX64Event::ctrlKeyPressed() -{ - return ctrl_up || - ctrl_down || - ctrl_left || - ctrl_right || - ctrl_jump || - ctrl_altjump || - ctrl_run || - ctrl_altrun || - ctrl_drop || - ctrl_start; -} diff --git a/LunaDll/libs/PGE_File_Formats/lvl_filedata.h b/LunaDll/libs/PGE_File_Formats/lvl_filedata.h deleted file mode 100644 index 11eb545c0..000000000 --- a/LunaDll/libs/PGE_File_Formats/lvl_filedata.h +++ /dev/null @@ -1,999 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/*! - * \file lvl_filedata.h - * \brief Contains data structure definitions for a level file data - */ - -#pragma once -#ifndef LVL_FILEDATA_H -#define LVL_FILEDATA_H - -#include "pge_file_lib_globs.h" -#include "meta_filedata.h" -#include "pge_ff_units.h" - -#ifndef DEFAULT_LAYER_NAME -#define DEFAULT_LAYER_NAME "Default" -#endif - -//////////////////////Level file Data////////////////////// -/*! - * \brief Level specific Section entry structure. Defines prererences of one section - */ -struct LevelSection -{ - //! ID of section (starts from 0) - int id = 0; - //! Y-Position of top side of section - long size_top = 0; - //! Y-Position of bottom side of section - long size_bottom = 0; - //! X-Position of left side of section - long size_left = 0; - //! X-Position of right side of section - long size_right = 0; - //! ID of default music in this section (starts from 1, 0 is silence) - unsigned int music_id = 0; - //! [UNUSED] RGBA defines color of background if image is not defined. - long bgcolor = 16291944; - //! Enables horisontal wrap - bool wrap_h = false; - //! Enables vertical wrap - bool wrap_v = false; - //! Level will be exited when playable character will exit out of screen - bool OffScreenEn = false; - //! ID of background image of this section - unsigned int background = 0; - //! Enable lock of walking to left direction - bool lock_left_scroll = false; - //! Enable lock of walking to right direction - bool lock_right_scroll = false; - //! Enable lock of walking to up direction - bool lock_up_scroll = false; - //! Enable lock of walking to down direction - bool lock_down_scroll = false; - //! Sets default physical environment of this section is - water - bool underwater = false; - //! Custom music file which will be playd if music ID defined to "Custom" music id - PGESTRING music_file; - - /* - * Editor-only parameters which are not saving into file - */ - //! Recent camera X position - long PositionX = -10; - //! Recent camera Y position - long PositionY = -10; -}; - -/*! - * \brief Level specific Player spawn point entry definition structure. - */ -struct PlayerPoint -{ - //! Defined ID of player - unsigned int id = 0; - //! X-position of player spawn point - long x = 0; - //! Y-position of player spawn point - long y = 0; - //! Height of player spawn point (used to calculate position of bottom to place playable character correctly) - long h = 32; - //! Wodth of player spawn point (used to calculate position of bottom to place playable character correctly) - long w = 24; - //! Initial direction of playable character (-1 is left, 1 is right, 0 is right by default) - int direction = 1; - //! User data pointer, Useful in the editors to have direct pointer to pre-placed elements - void *userdata = nullptr; -}; - -/*! - * \brief Level specific Block entry structure. Defines preferences of each block - */ -struct LevelBlock -{ - //! X position of block - long x = 0; - //! Y position of block - long y = 0; - //! Height of sizable block (takes no effect on non-sizable blocks in PGE Engine, - //! but takes effect in the SMBX Engine) - long h = 0; - //! Width of sizable block (takes no effect on non-sizable blocks in PGE Engine, - //! but takes effect in the SMBX Engine) - long w = 0; - //! Automatically scale cropping of the block size (if false, sprite will be cropped to fit into defined size) - bool autoscale = true; - //! ID of block type defined in the lvl_blocks.ini - unsigned long id = 0; - //! ID of the included NPC (0 - empty, <0 - number of coins, >0 - NPC-ID of included NPC) - long npc_id = 0; - //! Block is invizible until player will impacted to it at bottom side - bool invisible = false; - //! Block has a splippery surface - bool slippery = false; - //! Use the special AI to make block be movable - uint32_t motion_ai_id = 0; - //! Name of a parent layer. Default value is "Default" - PGESTRING layer = DEFAULT_LAYER_NAME; - //! 38A: Custom graphic file base name (default is empty) - PGESTRING gfx_name; - //! 38A: Graphics extend x - long gfx_dx = 0; - //! 38A: Graphics extend y - long gfx_dy = 0; - //! Trigger event on destroying of this block - PGESTRING event_destroy; - //! Trigger event on hiting of this block - PGESTRING event_hit; - //! Trigger event on destroying of this block and at sametime parent layer has no more other objects - PGESTRING event_emptylayer; - //! Trigger eveny when block entering into vizible screen area - PGESTRING event_on_screen; - - /* - * Editor-only parameters which are not saving into file - */ - //! Helper meta-data - ElementMeta meta; - //! Array-ID is an unique key value identificates each unique block object. - //! Re-counts on each file reloading - //unsigned int array_id; - //! Recent array index where block was saved (used to speed-up settings synchronization) - //unsigned int index; - //! User data pointer, Useful in the editors to have direct pointer to pre-placed elements - //void* userdata; -}; - - -/*! - * \brief Level specific Background object entry structure. Defines preferences of each Background object - */ -struct LevelBGO -{ - /* - * SMBX64 - */ - //! X position of Background Object - long x = 0; - //! Y position of Background Object - long y = 0; - //! ID of background object type defined in the lvl_bgo.ini - unsigned long id =0 ; - //! Name of a parent layer. Default value is "Default" - PGESTRING layer = DEFAULT_LAYER_NAME; - - /* - * Extended - */ - //! 38A: Graphics extend x - long gfx_dx = 0; - //! 38A: Graphics extend y - long gfx_dy = 0; - /*! - * \brief Z order Modes of background objects - */ - enum zmodes - { - //! Background-2 (under sizable blocks) - Background2 = -2, - //! Background-1 (over sizable blocks, under regular blocks) - Background1 = -1, - //! Use config default Z-Mode (which defined in the lvl_bgo.ini) - ZDefault = 0, - //! Foreground-1 (over regular blocks, but under lava blocks and foreground NPC's) - Foreground1 = 1, - //! Foreground-2 (over everything) - Foreground2 = 2 - }; - - //! Z-Mode of displaying of BGO - int z_mode = ZDefault; - //! Z-Offset relative to current of Z-value - double z_offset = 0.0; - - /*! SMBX64 Order priority. Defines priority for ordering of entries in array of BGO's before writing into a SMBX-lvl file. \ - -1 - use system default order priority */ - long smbx64_sp = -1; - /* - * Editor-only parameters which are not saving into file - */ - //! Automatically calculated value of SMBX64 Order priority - long smbx64_sp_apply = -1; - //! Helper meta-data - ElementMeta meta; -}; - - -/*! - * \brief Level specific NPC entry structure. Defines preferences of each NPC - */ -struct LevelNPC -{ - //! X position of NPC - long x = 0; - //! Y position of NPC - long y = 0; - //! Initial direction of NPC (-1 left, 1 right, 0 left or right randomly) - int direct = -1; - //! ID of NPC type defined in the lvl_npc.ini - uint64_t id = 0; - //! 38A: Custom graphic file base name (default is empty) - PGESTRING gfx_name; - //! 38A: Graphics extend x - long gfx_dx = 0; - //! 38A: Graphics extend y - long gfx_dy = 0; - //! Contained NPC in this container. - long contents = 0; - //! User-data integer #1 used for configuring some NPC-AI's (kept for SMBX64) - long special_data = 0; - //! User-data integer #2 used for configuring some NPC-AI's (kept for SMBX64) - long special_data2 = 0; - //! Makes a generator of this NPC - bool generator = false; - /*! - * \brief List of NPC Generator directions - */ - enum GeneratorDirection - { - //! Custom NPC Generator direction - NPC_GEN_CENTER = 0, - //! Up NPC Generator direction - NPC_GEN_UP = 1, - //! Left NPC Generator direction - NPC_GEN_LEFT = 2, - //! Down NPC Generator direction - NPC_GEN_DOWN = 3, - //! Right NPC Generator direction - NPC_GEN_RIGHT = 4, - //! Up-Left NPC Generator direction - NPC_GEN_UP_LEFT = 9, - //! Left-Down NPC Generator direction - NPC_GEN_LEFT_DOWN = 10, - //! Down-Right NPC Generator direction - NPC_GEN_DOWN_RIGHT = 11, - //! Right-Up NPC Generator direction - NPC_GEN_RIGHT_UP = 12 - }; - //! Generator direction [1] up, [2] left, [3] down, [4] right - int generator_direct = NPC_GEN_UP; - /*! - * \brief NPC Generator types list - */ - enum GeneratorTypes - { - NPC_GENERATOR_APPEAR = 0, - NPC_GENERATOR_WARP = 1, - NPC_GENERATPR_PROJECTILE = 2, - NPC_GENERATPR_CUSTOM1 = 3, - NPC_GENERATPR_CUSTOM2 = 4 - }; - //! Generator type 0 - instant appearence, 1 - warp, 2 - projectile shoot - int generator_type = NPC_GENERATOR_WARP; - //! Original unit type - PGE_FileLibrary::TimeUnit generator_period_orig_unit = PGE_FileLibrary::TimeUnit::Decisecond; - //! Generator's delay between each shoot in deci-seconds - int generator_period = 20; - //! Generator's delay between each shoot in original units - long generator_period_orig = 130; - //! Generator's custom angle in degrees (applying if generator direction is equal to 0 [center]) - double generator_custom_angle = 0.0; - //! Generator's branches (how much need spawn at one loop) (applying if generator direction is equal to 0 [center]) - int generator_branches = 1; - //! Generator's range of multi-shooting (how much need spawn at one loop) (applying if generator direction is equal to 0 [center]) - double generator_angle_range = 360.0; - //! Generator's initial NPC's speed (how much need spawn at one loop) (applying if generator direction is equal to 0 [center]) - double generator_initial_speed = 10.0; - //! Talking message. If not empty, NPC will be talkable - PGESTRING msg; - //! NPC will not communicate and will not collide with playable characters - bool friendly = false; - //! NPC will stay idle and will always keep look to the playable character - bool nomove = false; - //! Enables some boss-specific NPC-AI features (Used by NPC-AI) - bool is_boss = false; - //! Name of a parent layer. Default value is "Default" - PGESTRING layer = DEFAULT_LAYER_NAME; - //! Trigger event on actiovation of this NPC (on appearence on screen) - PGESTRING event_activate; - //! Trigger event on death of this NPC - PGESTRING event_die; - //! Trigger event on player's attempt to talk with this NPC - PGESTRING event_talk; - //! Trigger event on destroying of this block and at sametime parent layer has no more other objects - PGESTRING event_emptylayer; - //! Trigger event when player will grab this NPC - PGESTRING event_grab; - //! Trigger event every game logic loop - PGESTRING event_nextframe; - //! Trigger event when player will touch this NPC - PGESTRING event_touch; - //! Attach layer to this NPC. All memberes of this layer are will follow to motion of this NPC. - PGESTRING attach_layer; - //! Variable name where NPC-ID will be written - PGESTRING send_id_to_variable; - - /* - * Editor-only parameters which are not saving into file - */ - //!< Is this NPC a star (Copying from lvl_npc.ini config on file read). Stars are special bonus which required by player to be able enter into some doors/warps - bool is_star = false; - //! Helper meta-data - ElementMeta meta; -}; - -/*! - * \brief Level specific Warp entry structure. Defines preferences of each Warp entry - */ -struct LevelDoor -{ - //! X position of Entrance point - long ix = 0; - //! Y position of Entrance point - long iy = 0; - //! [Editing only, is not saving into file] is entrance point placed to the level - bool isSetIn = false; - - //! X position of Exit point - long ox = 0; - //! Y position of Exit point - long oy = 0; - //! [Editing only, is not saving into file] is exit point placed to the level - bool isSetOut = false; - /*! - * \brief List of possible entrance directions - */ - enum EntranceDirectopn - { - ENTRANCE_UP = 1, - ENTRANCE_LEFT = 2, - ENTRANCE_DOWN = 3, - ENTRANCE_RIGHT = 4 - }; - //! Direction of entrance point: [3] down, [1] up, [2] left, [4] right (not same as exit!) - int idirect = ENTRANCE_UP; - /*! - * \brief List of possible exit direction values - */ - enum ExitDirectopn - { - EXIT_DOWN = 1, - EXIT_RIGHT = 2, - EXIT_UP = 3, - EXIT_LEFT = 4 - }; - //! Direction of exit point: [1] down [3] up [4] left [2] right (not same as entrance!) - int odirect = EXIT_DOWN; - /*! - * \brief Type of warp: Instant teleport, pipe or door - */ - enum WarpType - { - WARP_INSTANT = 0, - WARP_PIPE = 1, - WARP_DOOR = 2, - WARP_PORTAL = 3 - }; - //! Warp type: [1] pipe, [2] door, [0] instant (zero velocity-X after exit), [3] portal (instant with Keeping of velocities) - int type = WARP_INSTANT; - enum WarpTransitEffect - { - TRANSIT_NONE, - TRANSIT_SCROLL, - TRANSIT_FADE, - TRANSIT_CIRCLE_FADE - }; - //! Transition effect - int transition_effect = TRANSIT_NONE; - //! Target level filename (Exit from this leven and enter to target level) - PGESTRING lname; - //! Warp Array-ID in the target level (if 0 - enter into target level at spawn point) - long warpto = 0; - //! Level entrance (this point can be used only as entrance point where player will enter into level) - bool lvl_i = false; - //! Level exit (entering into this warp will trigger exiting of level) - bool lvl_o = false; - //! Target World map X coordinate - long world_x = -1; - //! Target World map Н coordinate - long world_y = -1; - //! Stars/Leeks required to be allowed for enter into this warp - int stars = 0; - //! Message if player has no necessary stars/leeks collected - PGESTRING stars_msg; - //! Don't show stars number in the target level - bool star_num_hide = false; - //! Name of a parent layer. Default value is "Default" - PGESTRING layer = DEFAULT_LAYER_NAME; - //! [Unused] resrved boolean flag, always false - bool unknown = false; - //! Unmount all vehicles when player tried to enter into this warp. (all vehucles are will be returned back on exiting from level) - bool novehicles = false; - //! Allows player to move through this warp carried NPC's - bool allownpc = false; - //! Player need to carry a key to be allowed to enter into this warp - bool locked = false; - //! Player need to explode lock with a bomb to enter into this warp - bool need_a_bomb = false; - //! Hide the entry scene - bool hide_entering_scene = false; - //! Allows player to move through this warp carried NPC's to another level - bool allownpc_interlevel = false; - //! Required special state of playable character allowed to enter this warp - bool special_state_required = false; - //! Length of entrance zone: How wide will be entrance point - unsigned int length_i = 32u; - //! Length of exit zone: How wide will be exit point - unsigned int length_o = 32u; - //! Trigger event on enter - PGESTRING event_enter; - //! Is this warp a two-way (possible to enter from both sides) - bool two_way = false; - //! Cannon shoot warp exit - bool cannon_exit = false; - //! Cannon shoot projectile speed (pixels per 1/65 seconds) - double cannon_exit_speed = 10.0; - - /* - * Editor-only parameters which are not saving into file - */ - //! Helper meta-data - ElementMeta meta; - //! User data pointer for entrance, Useful in the editors to have direct pointer to pre-placed elements - void *userdata_enter = nullptr; - //! User data pointer for exit, Useful in the editors to have direct pointer to pre-placed elements - void *userdata_exit = nullptr; -}; - -/*! - * \brief Level specific Physical Environment entry structure. Defines preferences of each Physical Environment entry - */ -struct LevelPhysEnv -{ - //! X position of physical environment zone - long x = 0; - //! Y position of physical environment zone - long y = 0; - //! Height of physical environment zone - long h = 0; - //! Width of physical environment zone - long w = 0; - //! [Unused] reserved long integer value, always 0 - long unknown = 0; - - enum EnvTypes - { - ENV_WATER = 0, - ENV_QUICKSAND = 1, - ENV_CUSTOM_LIQUID = 2, - ENV_GRAVITATIONAL_FIELD = 3, - ENV_TOUCH_EVENT_ONCE_PLAYER = 4, - ENV_TOUCH_EVENT_PLAYER = 5, - ENV_TOUCH_EVENT_ONCE_NPC = 6, - ENV_TOUCH_EVENT_NPC = 7, - ENV_CLICK_EVENT = 8, - ENV_COLLISION_SCRIPT = 9, - ENV_CLICK_SCRIPT = 10, - ENV_COLLISION_EVENT = 11, - ENV_AIR = 12, - ENV_TOUCH_EVENT_ONCE_NPC1 = 13, - ENV_TOUCH_EVENT_NPC1 = 14, - ENV_NPC_HURTING_FIELD = 15 - }; - //! Enable quicksand physical environment, overwise water physical environment - int env_type = ENV_WATER; - //! Name of a parent layer. Default value is "Default" - PGESTRING layer = DEFAULT_LAYER_NAME; - //! Custom liquid friction (works with "custom liquid" type) - double friction = 0.5; - //! Acceleration direction (works with "custom liquid" type) - double accel_direct = -1.0; - //! Acceleration (works with "custom liquid" type) - double accel = 0.0; - //! Max velocity (works with "custom liquid" type) - double max_velocity = 0.0; - //! Touch event (or script) name - PGESTRING touch_event; - /* - * Editor-only parameters which are not saving into file - */ - //! Helper meta-data - ElementMeta meta; -}; - -/*! - * \brief Level specific Layer entry structure - */ -struct LevelLayer -{ - //! Name of layer - PGESTRING name; - //! Is this layer hidden? - bool hidden = false; - //! Are all members of this layer are locked for modifying? - bool locked = false; - - /* - * Editor-only parameters which are not saving into file - */ - //! Helper meta-data - ElementMeta meta; -}; - -/*! - * \brief Level events specific settings set per each section - */ -struct LevelEvent_Sets -{ - enum SetActions - { - LESet_Nothing = -1, - LESet_ResetDefault = -2, - }; - - //!ID of section - long id = -1; - - //! Set new Music ID in this section (-1 - do nothing, -2 - reset to defaint, >=0 - set music ID) - long music_id = LESet_Nothing; - //! Set new Custom Music File path - PGESTRING music_file; - //! Set new Background ID in this section (-1 - do nothing, -2 - reset to defaint, >=0 - set background ID) - long background_id = LESet_Nothing; - - //! Change section borders if not (-1 - do nothing, -2 set default, any other values - set X position of left section boundary) - long position_left = LESet_Nothing; - //! Change Y position of top section boundary - long position_top = 0; - //! Change Y position of bottom section boundary - long position_bottom = 0; - //! Change X position of right section boundary - long position_right = 0; - - //! Ariphmetical expression calculates position X - PGESTRING expression_pos_x; - //! Ariphmetical expression calculates position Y - PGESTRING expression_pos_y; - //! Ariphmetical expression calculates width of section - PGESTRING expression_pos_w; - //! Ariphmetical expression calculates height of section - PGESTRING expression_pos_h; - - //! Enable autoscroll for this section - bool autoscrol = false; - //! X speed of autoscrool - float autoscrol_x = 0.0; - //! Y speed of autoscrool - float autoscrol_y = 0.0; - - //! Ariphmetical expression calculates autoscrool X - PGESTRING expression_autoscrool_x; - //! Ariphmetical expression calculates autoscrool y - PGESTRING expression_autoscrool_y; -}; - -/*! - * \brief Movable layer configuration - */ -struct LevelEvent_MoveLayer -{ - //! Name of moving layer - PGESTRING name = ""; - //! Speed X of layer - double speed_x = 0.0; - //! Speed Y of layer - double speed_y = 0.0; - - //! Expression for X speed/coordinate - PGESTRING expression_x; - - //! Expression for Y speed/coordinate - PGESTRING expression_y; - - //! List of available layer motion ways - enum LayerMotionWay - { - //! Set moving speed - LM_Speed = 0, - //! Move to coordinate offset relative to initial position - LM_Coordinate = 1 - }; - //! Way to do layer motion - int way = LM_Speed; -}; - -/*! - * \brief Spawn effect task declaration - */ -struct LevelEvent_SpawnEffect -{ - //! Effect ID to spawn - long id = 0; - //! Spawn effect at X - long x = 0; - //! Spawn effect at Y - long y = 0; - //! Expression for X position - PGESTRING expression_x; - //! Expression for Y position - PGESTRING expression_y; - //! Initial speed X (pixels per 1/65 second) - double speed_x = 0.0; - //! Initial speed Y (pixels per 1/65 second) - double speed_y = 0.0; - //! Expression for X speed - PGESTRING expression_sx; - //! Expression for Y speed - PGESTRING expression_sy; - //! Spawn effect with gravity (to decide whether the effects are affected by gravity) - bool gravity = false; - //! Frame speed of spawned effect - int fps = -1;//Default FPS - //! Life time of effect (1/65 seconds) (effect existed over this time will be destroyed.) - int max_life_time = -1;//Default life time -}; - -/*! - * \brief Declaration of spawn NPC command - */ -struct LevelEvent_SpawnNPC -{ - //! Spawn NPC-ID - long id = 0; - //! Spawn NPC at X position - long x = 0; - //! Spawn NPC at Y position - long y = 0; - //! Spawn NPC with initial keenetic speed X - double speed_x = 0.0; - //! Spawn NPC with initial keenetic speed Y - double speed_y = 0.0; - //! Expression for X position - PGESTRING expression_x; - //! Expression for Y position - PGESTRING expression_y; - //! Expression for X speed - PGESTRING expression_sx; - //! Expression for Y speed - PGESTRING expression_sy; - //! Additional special parameter: advanced settings of generated npc - long special = 0; -}; - -/*! - * \brief Declaration of variable update command - */ -struct LevelEvent_UpdateVariable -{ - //! Variable name to update - PGESTRING name; - //! Variable value to update - PGESTRING newval; -}; - -struct LevelEvent_SetTimer -{ - //! Enable timer - bool enable = false; - //! Time left (ticks) - long count = 0; - //! Lenght of every tick (miliseconds per every tick) - double interval = 1000.0; - enum CountDirection - { - DIR_REVERSE = 0, - DIR_FORWARD = 1 - }; - //! Count direction - int count_dir = DIR_REVERSE; - //! Show timer - bool show = false; -}; - -/*! - * \brief Level specific Classic Event Entry structure - */ -struct LevelSMBX64Event -{ - //! Name of event - PGESTRING name; - //! Message box to spawn if not empty - PGESTRING msg; - //! Sound ID to play if not zero - long sound_id = 0; - //! Trigger end of game and go to credits screen if not zero - long end_game = 0; - - //! Don't show smoke effect on show/hide/toggle layer visibility - bool nosmoke = false; - //! List of layers to hide - PGESTRINGList layers_hide; - //! List of layers to show - PGESTRINGList layers_show; - //! List of layers to toggle (hide visible and show invisible) - PGESTRINGList layers_toggle; - - //! List of section settings per each section to apply - PGELIST sets; - //! Trigger another event if not empty - PGESTRING trigger; - //! Original unit type - PGE_FileLibrary::TimeUnit trigger_timer_unit = PGE_FileLibrary::TimeUnit::Decisecond; - //! Trigger another event after time in deci-seconds - long trigger_timer = 0; - //! Trigger another event after time in original units - long trigger_timer_orig = 0; - //! Hold key controllers holding - bool ctrls_enable = false; - /*! - * \brief Check is one of control keys pressed - * \return true if one of keys is pressed - */ - bool ctrlKeyPressed(); - //! Hold "Up" key controllers - bool ctrl_up = false; - //! Hold "Down" key controllers - bool ctrl_down = false; - //! Hold "Left" key controllers - bool ctrl_left = false; - //! Hold "Right" key controllers - bool ctrl_right = false; - //! Hold "Jump" key controllers - bool ctrl_jump = false; - //! Hold "Alt-jump" key controllers - bool ctrl_altjump = false; - //! Hold "Run" key controllers - bool ctrl_run = false; - //! Hold "Alt-run" key controllers - bool ctrl_altrun = false; - - //! Hold "Start" key controllers - bool ctrl_start = false; - //! Hold "Drop" key controllers - bool ctrl_drop = false; - - //! Temporary lock player controllers input - bool ctrl_lock_keyboard = false; - - enum AutoStartCond - { - AUTO_None = 0, - AUTO_LevelStart = 1, - AUTO_MatchAll = 3, - AUTO_CallAndMatch = 4 - }; - //! Trigger event automatically on level startup - int autostart = AUTO_None; - //! Conditional expression for event autostart - PGESTRING autostart_condition; - //! Array of extra moving layers - PGELIST moving_layers; - //! Effects to spawn; - PGELIST spawn_effects; - //! NPC's to spawn; - PGELIST spawn_npc; - //! Variables to update; - PGELIST update_variable; - //! Timer definition - LevelEvent_SetTimer timer_def; - //! Trigger script by name - PGESTRING trigger_script; - //! Trigger API function by ID (SMBX-38A) - int trigger_api_id = 0; - - //! Install layer motion settings for layer if is not empt - PGESTRING movelayer; - //! Set layer X motion in pixels per 1/65 - double layer_speed_x = 0.0; - //! Set layer Y motion in pixels per 1/65 - double layer_speed_y = 0.0; - //! Setup autoscrool X speed in pixels per 1/65 - double move_camera_x = 0.0; - //! Setup autoscrool Y speed in pixels per 1/65 - double move_camera_y = 0.0; - //! Setup autoscrool for section ID (starts from 0) - long scroll_section = 0; - - /* - * Editor-only parameters which are not saving into file - */ - //! Helper meta-data - ElementMeta meta; -}; - -/*! - * \brief Level Variable entry - */ -struct LevelVariable -{ - PGESTRING name; - PGESTRING value; -}; - -/*! - * \brief Level Script entry - */ -struct LevelScript -{ - enum ScriptLangs - { - LANG_LUA = 0, - LANG_AUTOCODE = 1, - LANG_TEASCRIPT - }; - PGESTRING name; - PGESTRING script; - int language = LANG_LUA; -}; - -/** - * @brief Custom element settings (used by 38A) - */ -struct LevelItemSetup38A -{ - enum ItemType - { - UNKNOWN = -1, - BLOCK = 0, - BGO = 1, - EFFECT = 2, - } type = UNKNOWN; - - int64_t id = 0; - struct Entry - { - int32_t key = 0; - int64_t value = 0; - }; - PGELIST data; -}; - -/*! - * \brief Level data structure. Contains all available settings and element lists on the level. - */ -struct LevelData -{ - /* - * Level header - */ - //! Total number of stars on the level - int stars = 0; - - //!Helper meta-data - FileFormatMeta meta; - - /*! - * \brief File format - */ - enum FileFormat - { - //! PGE-X LVLX File Format - PGEX = 0, - //! SMBX1...64 LVL File format - SMBX64, - //! SMBX-38A LVL File Format - SMBX38A - }; - - //! Understandable name of the level - PGESTRING LevelName; - //! If not empty, start this level when player was failed - PGESTRING open_level_on_fail; - //! Target WarpID (0 - regular entrance, >=1 - WarpID of entrance) - unsigned int open_level_on_fail_warpID = 0; - - struct MusicOverrider - { - enum Type { - LEVEL = 0, - SPECIAL = 1 - }; - Type type = Type::LEVEL; - uint32_t id = 0; - PGESTRING fileName; - }; - - //! Override default musics - PGELIST music_overrides; - //! Override default sound effects - PGELIST sound_overrides; - - /* - * Level data - */ - //! Sections settings array - PGELIST sections; - - //! Player spawn points array - PGELIST players; - - //! Array of all presented Blocks in this level - PGELIST blocks; - //! Last used block's array ID - unsigned int blocks_array_id = 1; - - //! Array of all presented Background objects in this level - PGELIST bgo; - //! Last used Background object array ID - unsigned int bgo_array_id = 1; - - //! Array of all presented NPCs in this level - PGELIST npc; - //! Last used NPC's array ID - unsigned int npc_array_id = 1; - - //! Array of all presented Warp Entries in this level - PGELIST doors; - //! Last used warp's array ID - unsigned int doors_array_id = 1; - - //! Array of all presented Physical Environment Zones in this level - PGELIST physez; - //! Last used Physical Environment Zone's array ID - unsigned int physenv_array_id = 1; - - //! Array of all presented layers in this level - PGELIST layers; - //! Last used Layer's array ID - unsigned int layers_array_id = 1; - - //! Array of all presented events in this level - PGELIST events; - //! Last used Event's array ID - unsigned int events_array_id = 1; - - PGELIST variables; - PGELIST scripts; - - //! SMBX-38A specific custom configs - PGELIST custom38A_configs; - - //! Meta-data: Position bookmarks, Auto-Script configuration, etc., Crash meta-data, etc. - MetaData metaData; - - /* - * Editor-only parameters which are not saving into file - */ - //! ID of currently editing section - int CurSection = 0; - //! is music playing button pressed? - bool playmusic = false; - - /* - * Helpful functions - */ - /*! - * \brief Checks is event with specified title exist in this level - * \param title Event name which need to check for existsing - * \return true if requested event is exists - */ - bool eventIsExist(PGESTRING title); - /*! - * \brief Checks is layer with specified title exist in this level - * \param title Layer name which need to check for existsing - * \return true if requested event is exists - */ - bool layerIsExist(PGESTRING title); -}; - - - -#endif // LVL_FILEDATA_H diff --git a/LunaDll/libs/PGE_File_Formats/meta_filedata.h b/LunaDll/libs/PGE_File_Formats/meta_filedata.h deleted file mode 100644 index f69ec6fb5..000000000 --- a/LunaDll/libs/PGE_File_Formats/meta_filedata.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -/*! - * \file meta_filedata.h - * \brief Contains defition of the common meta-data structures and classes - */ -#pragma once -#ifndef META_FILEDATA_H -#define META_FILEDATA_H - -#include "pge_file_lib_globs.h" -#include - -/** - * @brief Common data structure meta-data - */ -struct FileFormatMeta -{ - FileFormatMeta(): - ReadFileValid(true), - ERROR_linenum(-1), - RecentFormat(0), - RecentFormatVersion(0), - modified(true), - untitled(true), - smbx64strict(false) - {} - //! Is file parsed correctly, false if some error is occouped - bool ReadFileValid; - //! Error messsage - PGESTRING ERROR_info; - //! Line data where error was occouped - PGESTRING ERROR_linedata; - //! Number of line where error was occouped - long ERROR_linenum; - //! Recently used (open or save) file format - int RecentFormat; - //! Recently used format version (for SMBX1...64 files only) - unsigned int RecentFormatVersion; - //! Is file was modified since open? - bool modified; - //! Is this level made from scratch and was not saved into file? - bool untitled; - //! Enable SMBX64 Standard restrictions - //! (disable unsupported features and warn about limit exiting) - bool smbx64strict; - //! Recent file name since file was opened - PGESTRING filename; - //! Recent file path where file was located since it was opened - PGESTRING path; -}; - -/** - * @brief Common element meta-data - */ -struct ElementMeta -{ - ElementMeta() : - array_id(0), - index(0), - userdata(nullptr) {} - //! Array-ID is an unique key value identificates each unique element object. - //! Re-counts on each file reloading - unsigned int array_id; - //! Recent array index where element was saved (used to speed-up settings synchronization) - unsigned int index; - //! JSON-like string with a custom properties (without master brackets, like "param":"value,["subparam":value]) - PGESTRING custom_params; - //! User data pointer, Useful in the editors to have direct pointer to pre-placed elements - void *userdata; -}; - -/*! - * \brief Position bookmark entry structure - */ -struct Bookmark -{ - PGESTRING bookmarkName; //!< Name of bookmark - double x; //!< Bookmarked X position of the camera - double y; //!< Bookmarked Y position of the camera -}; - -#ifdef PGE_EDITOR -/*! - * \brief Contains backup of helpful techincal data used by PGE Editor - */ -class CrashData -{ - public: - /*! - * \brief Constructor - */ - explicit CrashData(); - /*! - * \brief Copy constructor - * \param _cd another CrashData object - */ - CrashData(const CrashData &_cd); - /*! - * \brief Copy constructor - * \param _cd another CrashData object - */ - CrashData(CrashData &_cd); - /*! - * \brief Sets default preferences - */ - void reset(); - //! Is crash data was used by editor (if false, LVLX writer will not record crash data into file) - bool used; - //! Is this level was untitled since crash occopued? - bool untitled; - //! Is this level was modified before crash occouped? - bool modifyed; - //! Recent file format ID (specific enum in the format structure declaration) - int fmtID; - //! Recent file format version - unsigned int fmtVer; - //! Full original file path file which was opened before crash occouped - PGESTRING fullPath; - //! Full episode path of file which was opened before crash occouped - PGESTRING path; - //! Base file name of file which was opened before crash occouped - PGESTRING filename; -}; -#endif - -/*! - * \brief Contains additional helpful meda-data used by PGE Applications - */ -struct MetaData -{ - //! Array of all position bookmarks presented in the opened file - PGEVECTOR bookmarks; - - /* For Editor application only*/ -#ifdef PGE_EDITOR - //! Crash backup of Editor's special data - CrashData crash; -#endif - - //!Helper meta-data - FileFormatMeta meta; -}; - -#endif // META_FILEDATA_H diff --git a/LunaDll/libs/PGE_File_Formats/npc_filedata.cpp b/LunaDll/libs/PGE_File_Formats/npc_filedata.cpp deleted file mode 100644 index defc4bf4e..000000000 --- a/LunaDll/libs/PGE_File_Formats/npc_filedata.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifdef PGE_EDITOR -#include -#endif - -#include "file_formats.h" -#include "npc_filedata.h" - -NPCConfigFile FileFormats::CreateEmpytNpcTXT() -{ - return NPCConfigFile(); -} diff --git a/LunaDll/libs/PGE_File_Formats/npc_filedata.h b/LunaDll/libs/PGE_File_Formats/npc_filedata.h deleted file mode 100644 index fe622a086..000000000 --- a/LunaDll/libs/PGE_File_Formats/npc_filedata.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/*! - * \file npc_filedata.h - * \brief Contains defition of the SMBX64-NPC.txt config data structure - */ - -#pragma once -#ifndef NPC_FILEDATA_H -#define NPC_FILEDATA_H - -#include "pge_file_lib_globs.h" - -/*! - * \brief SMBX64-NPC.txt File Data structure - */ -struct NPCConfigFile -{ - bool ReadFileValid = false; - PGESTRING unknownLines; - -/* - * SMBX64 Standard - */ - //! Is GFX-Offset X field using? - bool en_gfxoffsetx = false; - //! GFX-Offset X field - int32_t gfxoffsetx = 0; - - //! Is GFX-Offset Y field using? - bool en_gfxoffsety = false; - //! GFX-Offset Y field - int32_t gfxoffsety = 0; - - //! Is Width field using? - bool en_width = false; - //! Width field - uint32_t width = 0; - - //! Is height field using? - bool en_height = false; - //! Height field - uint32_t height = 0; - - //! Is GFX-Width field using? - bool en_gfxwidth = false; - //! GFX-Width field - uint32_t gfxwidth = 0; - - //! Is GFX-Height field using? - bool en_gfxheight = false; - //! GFX-Height field - uint32_t gfxheight = 0; - - //! Is Score field using? - bool en_score = false; - //! Score rewards field (from 0 to 13) - uint32_t score = 0; - - //! Is "Block player at side" flag using? - bool en_playerblock = false; - //! "Block player at side" flag - bool playerblock = false; - - //! Is "Player can stay on top" flag using? - bool en_playerblocktop = false; - //! "Player can stay on top" flag - bool playerblocktop = false; - - //! Is "Block other NPC at side" flag using? - bool en_npcblock = false; - //! "Block other NPC at side" flag - bool npcblock = false; - - //! Is "NPC Can stay on top" flag using? - bool en_npcblocktop = false; - //! "NPC Can stay on top" flag - bool npcblocktop = false; - - //! Is "Allow to grab at side" flag using? - bool en_grabside = false; - //! "Allow to grab at side" flag - bool grabside = false; - - //! Is "Allow to grab at top" flag using? - bool en_grabtop = false; - //! "Allow to grab at top" flag - bool grabtop = false; - - //! Is "Hurt player on stomp attempt" flag using? - bool en_jumphurt = false; - //! "Hurt player on stomp attempt" flag - bool jumphurt = false; - - //! Is "Safe for playable character" flag using? - bool en_nohurt = false; - //! "Safe for playable character" flag - bool nohurt = false; - - //! Is "Don't collide with blocks" flag using? - bool en_noblockcollision = false; - //! "Don't collide with blocks" flag - bool noblockcollision = false; - - //! Is "Turn on cliff" flag using? - bool en_cliffturn = false; - //! "Turn on cliff" flag - bool cliffturn = false; - - //! Is "Not eatable" flag using? - bool en_noyoshi = false; - //! "Not eatable" flag - bool noyoshi = false; - - //! Is "Foreground render" flag using? - bool en_foreground = false; - //! "Foreground render" flag - bool foreground = false; - - //! Is Speed modifier field us using? - bool en_speed = false; - //! Speed modifier field - double speed = 1.0; - - //! Is "Immune to fire" flag using? - bool en_nofireball = false; - //! "Immune to fire" flag - bool nofireball = false; - - //! Is "Zero gravity" flag using? - bool en_nogravity = false; - //! Zero gravity flag - bool nogravity = false; - - //! Is Frames number field using? - bool en_frames = false; - //! Frames number field - uint32_t frames = 0; - - //! Is Frame speed modifier field using? - bool en_framespeed = false; - //! Frame speed modifier field - uint32_t framespeed = 0; - - //! Is frame style field using? - bool en_framestyle = false; - //! Frame style field - uint32_t framestyle = 0; - - //! Is "Immune to ice" flag using? - bool en_noiceball = false; - //! "Immune to ice" flag - bool noiceball = false; - - -/* - * Extended - */ - //! Is "Immune to hammers/axes/knifes" flag using? - bool en_nohammer = false; - //! "Immune to hammers/axes/knifes" flag - bool nohammer = false; - - //! Is "Immune to thrown NPC's" flag using? - bool en_noshell = false; - //! "Immune to thrown NPC's" flag - bool noshell = false; - - //! Is NPC's Custom name field using? - bool en_name = false; - //! NPC's Custom name - PGESTRING name; - - //! Is NPC's Custom description field using? - bool en_description = false; - //! NPC's Custom description - PGESTRING description; - - //! Is custom health level field using? - bool en_health = false; - //! Custom health level field - uint32_t health = 0; - - //! Is custom image file name field using? - bool en_image = false; - //! Is custom image file name field using? - PGESTRING image; - - //! Is custom in-editor icon image file name field using? - bool en_icon = false; - //! Is custom in-editor icon image file name field using? - PGESTRING icon; - - //! Is custom AI script filename field using? - bool en_script = false; - //! Custom AI Script filename field - PGESTRING script; - - //! Is custom group name of NPC using? - bool en_group = false; - //! Custom group name of NPC - PGESTRING group; - - //! Is custom category name of NPC using? - bool en_category = false; - //! Custom category name of NPC - PGESTRING category; - - //! Is custom aligning grid size field using? - bool en_grid = false; - //! Custom aligning grid size field - uint32_t grid = 1; - - //! Is custom grid offset X field using? - bool en_gridoffsetx = false; - //! Custom grid offset X field - int32_t gridoffsetx = 0; - - //! Is custom grid offset Y field using? - bool en_gridoffsety = false; - //! Custom grid offset Y field - int32_t gridoffsety = 0; - - //! Is custom grid align style field using? - bool en_gridalign = false; - //! Custom grid align style field - uint32_t gridalign = 0; - -}; - -#endif // NPC_FILEDATA_H diff --git a/LunaDll/libs/PGE_File_Formats/pge_ff_units.h b/LunaDll/libs/PGE_File_Formats/pge_ff_units.h deleted file mode 100644 index 77dfb9a33..000000000 --- a/LunaDll/libs/PGE_File_Formats/pge_ff_units.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once -#ifndef PGE_FF_UNITS_H -#define PGE_FF_UNITS_H - -namespace PGE_FileLibrary -{ - -enum class TimeUnit -{ - FrameOneOf65sec = -1, - Millisecond = 0, - Decisecond, - Second -}; - -template -NumT TimeUnitsCVT(const NumT &in, TimeUnit from, TimeUnit into) -{ - if(from == into) - return in; - long double value = static_cast(in); - switch(from) - { - case TimeUnit::FrameOneOf65sec: - switch(into) - { - case TimeUnit::Millisecond: - return static_cast( (value * 1000.0l) / 65.0l ); - case TimeUnit::Decisecond: - return static_cast( (value * 10.0l) / 65.0l ); - case TimeUnit::Second: - return static_cast( value / 65.0l ); - default:; - case TimeUnit::FrameOneOf65sec: - return in;//Nothing to do - }; - case TimeUnit::Millisecond: - switch(into) - { - case TimeUnit::FrameOneOf65sec: - return static_cast( (value / 1000.0l) * 65.0l ); - case TimeUnit::Decisecond: - return static_cast( value / 1000.0l ); - case TimeUnit::Second: - return static_cast( value / 10.0l ); - default:; - case TimeUnit::Millisecond: - return in;//Nothing to do - }; - case TimeUnit::Decisecond: - switch(into) - { - case TimeUnit::FrameOneOf65sec: - return static_cast( (value / 10.0l) * 65.0l ); - case TimeUnit::Millisecond: - return static_cast( value * 100.0l ); - case TimeUnit::Second: - return static_cast( value / 10.0l ); - default:; - case TimeUnit::Decisecond: - return in;//Nothing to do - }; - case TimeUnit::Second: - switch(into) - { - case TimeUnit::FrameOneOf65sec: - return static_cast( value * 65.0l ); - case TimeUnit::Millisecond: - return static_cast( value * 1000.0l ); - case TimeUnit::Decisecond: - return static_cast( value * 10.0l ); - default:; - case TimeUnit::Second: - return in;//Nothing to do - }; - }; - return in; -} - -}//PGE_FileLibrary -#endif // PGE_FF_UNITS_H diff --git a/LunaDll/libs/PGE_File_Formats/pge_file_lib_globs.cpp b/LunaDll/libs/PGE_File_Formats/pge_file_lib_globs.cpp deleted file mode 100644 index 3fcccae1b..000000000 --- a/LunaDll/libs/PGE_File_Formats/pge_file_lib_globs.cpp +++ /dev/null @@ -1,1330 +0,0 @@ -#include "pge_file_lib_globs.h" -#ifdef _WIN32 -#include "windows.h" -#endif -#ifndef PGE_FILES_QT -#include /* PATH_MAX */ -#include -#include -#include -#include "charsetconvert.h" -#ifndef PATH_MAX -/* - * Needed to shut up CLang's static analyzer that showing usage of this - * macro as "not exists" even I have limits.h included here. - * For other cases it's just a dead code - */ -#define PATH_MAX 2048 -#endif -#else -#include -#endif -#include - -namespace PGE_FileFormats_misc -{ - #ifndef PGE_FILES_QT - #ifdef _WIN32 - static std::wstring Str2WStr(const std::string &str) - { - std::wstring dest; - dest.resize(str.size()); - int newlen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &dest[0], str.length()); - dest.resize(newlen); - return dest; - } - - static std::string WStr2Str(const std::wstring &wstr) - { - std::string dest; - dest.resize((wstr.size() * 2)); - int newlen = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), &dest[0], dest.size(), NULL, NULL); - dest.resize(newlen); - return dest; - } - - FILE *utf8_fopen(const char *file, const char *mode) - { - wchar_t wfile[MAX_PATH + 1]; - wchar_t wmode[21]; - int wfile_len = strlen(file); - int wmode_len = strlen(mode); - wfile_len = MultiByteToWideChar(CP_UTF8, 0, file, wfile_len, wfile, MAX_PATH); - wmode_len = MultiByteToWideChar(CP_UTF8, 0, mode, wmode_len, wmode, 20); - wfile[wfile_len] = L'\0'; - wmode[wmode_len] = L'\0'; - return _wfopen(wfile, wmode); - } - - #else -#define utf8_fopen fopen - #endif - - void split(std::vector &dest, const std::string &str, const std::string &separator) - { - dest.clear(); - std::string::size_type begin = 0; - std::string::size_type end = 0; - std::string::size_type sepLen = separator.size(); - do{ - end = str.find(separator, begin); - std::string s = str.substr(begin, end - begin); - if(!s.empty()) - dest.push_back(s); - begin = end + sepLen; - } while(end != std::string::npos); - } - - void replaceAll(std::string &str, const std::string &from, const std::string &to) - { - if(from.empty()) - return; - size_t start_pos = 0; - while((start_pos = str.find(from, start_pos)) != std::string::npos) - { - str.replace(start_pos, from.length(), to); - start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' - } - } - - void RemoveSub(std::string &sInput, const std::string &sub) - { - std::string::size_type foundpos = sInput.find(sub); - if(foundpos != std::string::npos) - sInput.erase(sInput.begin() + std::string::difference_type(foundpos), - sInput.begin() + std::string::difference_type(foundpos + sub.length())); - } - - bool hasEnding(std::string const &fullString, std::string const &ending) - { - if(fullString.length() >= ending.length()) - return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending)); - else - return false; - } - #endif - - PGESTRING url_encode(const PGESTRING &sSrc) - { - if(IsEmpty(sSrc)) - return sSrc; - const char DEC2HEX[16 + 1] = "0123456789ABCDEF"; - #ifndef PGE_FILES_QT - const uint8_t *pSrc = reinterpret_cast(sSrc.c_str()); - #else - std::string ssSrc = sSrc.toStdString(); - const uint8_t *pSrc = reinterpret_cast(ssSrc.c_str()); - #endif - const size_t SRC_LEN = static_cast(sSrc.length()); - std::unique_ptr pStart(new uint8_t[SRC_LEN * 3]); - uint8_t *pEnd = pStart.get(); - const uint8_t *const SRC_END = pSrc + SRC_LEN; - for(; pSrc < SRC_END; ++pSrc) - { - //Do full encoding! - *pEnd++ = '%'; - *pEnd++ = static_cast(DEC2HEX[*pSrc >> 4]); - *pEnd++ = static_cast(DEC2HEX[*pSrc & 0x0F]); - } - #ifndef PGE_FILES_QT - PGESTRING sResult((char *)pStart.get(), (char *)pEnd); - #else - PGESTRING sResult = QString::fromUtf8(reinterpret_cast(pStart.get()), static_cast(pEnd - pStart.get())); - #endif - return sResult; - } - - #ifndef PGE_FILES_QT - const char HEX2DEC[256] = - { - /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ - /* 0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 1 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 2 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 3 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, - - /* 4 */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 5 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 6 */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 7 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - - /* 8 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 9 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* A */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* B */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - - /* C */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* D */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* E */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* F */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - }; - - PGESTRING url_decode(const std::string &sSrc) - { - if(sSrc.empty()) - return sSrc; - // Note from RFC1630: "Sequences which start with a percent - // sign but are not followed by two hexadecimal characters - // (0-9, A-F) are reserved for future extension" - const uint8_t *pSrc = (const unsigned char *)sSrc.c_str(); - const size_t SRC_LEN = sSrc.length(); - const uint8_t *const SRC_END = pSrc + SRC_LEN; - // last decodable '%' - const uint8_t *const SRC_LAST_DEC = SRC_END - 2; - - char *pStart = (char*)malloc(SRC_LEN + 1); - if(!pStart) - return ""; - memset(pStart, 0, SRC_LEN + 1); - char *pEnd = pStart; - - while(pSrc < SRC_LAST_DEC) - { - if(*pSrc == '%') - { - char dec1, dec2; - if(-1 != (dec1 = HEX2DEC[*(pSrc + 1)]) - && -1 != (dec2 = HEX2DEC[*(pSrc + 2)])) - { - *pEnd++ = static_cast((dec1 << 4) + dec2); - pSrc += 3; - continue; - } - } - - *pEnd++ = static_cast(*pSrc++); - } - - // the last 2- chars - while(pSrc < SRC_END) - *pEnd++ = static_cast(*pSrc++); - - std::string::size_type pLen = static_cast(pEnd - pStart); - std::string sResult(pStart, pLen); - free(pStart); - return sResult; - } - #endif - - - static const std::string base64_chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - - static inline bool is_base64(unsigned char c) - { - return (isalnum(c) || (c == '+') || (c == '/')); - } - - #ifdef PGE_FILES_QT - /* - #define PGE_BASE64ENC_W(src) QString::fromStdString(PGE_FileFormats_misc::base64_encodeW(src.toStdWString())) - #define PGE_BASE64DEC_W(src) src.fromStdWString(PGE_FileFormats_misc::base64_decodeW(src.toStdString())) - */ - QString base64_encodeW(QString &source, bool no_padding) - { - return QString::fromStdString( - base64_encode(reinterpret_cast(source.utf16()), - static_cast(source.size()) * sizeof(uint16_t), no_padding) - ); - } - - QString base64_decodeW(QString &source) - { - std::string sout = base64_decode(source.toStdString()); - QString out; - out.setUtf16(reinterpret_cast(sout.data()), static_cast(sout.size() / 2)); - return out; - } - QString base64_encodeA(QString &source, bool no_padding) - { - return QString::fromStdString( - base64_encode(reinterpret_cast(source.toLatin1().data()), - static_cast(source.size()), no_padding) - ); - } - - QString base64_decodeA(QString &source) - { - std::string sout = base64_decode(source.toStdString()); - return QString::fromLatin1(sout.data(), static_cast(sout.size())); - } - - QString base64_encode(QString &source, bool no_padding) - { - std::string out = source.toStdString(); - if((out.size() == 0) || (out[out.size() - 1] != '\0')) - out.push_back('\0'); - return QString::fromStdString( - base64_encode(reinterpret_cast(out.data()), - out.size(), no_padding) - ); - } - - QString base64_decode(QString &source) - { - std::string sout = base64_decode(source.toStdString()); - return QString::fromUtf8(sout.data(), static_cast(sout.size())); - } - - #else - std::string base64_encodeW(std::string &source, bool no_padding) - { - SI_ConvertW utf8(true); - size_t new_len = utf8.SizeFromStore(source.c_str(), source.length()); - std::wstring t; - t.resize(new_len); - if(utf8.ConvertFromStore(source.c_str(), source.length(), (wchar_t *)t.c_str(), new_len)) - return base64_encode(reinterpret_cast(t.c_str()), t.size(), no_padding); - return ""; - } - - std::string base64_decodeW(std::string &source) - { - std::string out = base64_decode(source); - #ifdef DEBUG_BUILD - FILE *x = utf8_fopen("test.txt", "ab"); - // for(size_t i=0; i utf8(true); - size_t new_len = outw.length() * 2; //utf8.SizeToStore(outw.c_str()); - std::string out2; - out2.resize(new_len); - if(utf8.ConvertToStore(outw.c_str(), (char *)out2.c_str(), new_len)) - return out2; - return ""; - } - - std::string base64_encodeA(std::string &source, bool no_padding) - { - return base64_encode(reinterpret_cast(source.c_str()), source.size(), no_padding); - } - - std::string base64_decodeA(std::string &source) - { - return base64_decode(source); - } - #endif - - std::string base64_encode(std::string const &source, bool no_padding) - { - return base64_encode(reinterpret_cast(source.c_str()), source.size(), no_padding); - } - - std::string base64_encode(const uint8_t *bytes_to_encode, size_t in_len, bool no_padding) - { - std::string ret; - int i = 0; - int j = 0; - unsigned char char_array_3[3]; - unsigned char char_array_4[4]; - - while(in_len--) - { - char_array_3[i++] = *(bytes_to_encode++); - if(i == 3) - { - char_array_4[0] = static_cast((char_array_3[0] & 0xfc) >> 2); - char_array_4[1] = static_cast(((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4)); - char_array_4[2] = static_cast(((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6)); - char_array_4[3] = static_cast(char_array_3[2] & 0x3f); - - for(i = 0; (i < 4) ; i++) - ret += base64_chars[char_array_4[i]]; - i = 0; - } - } - - if(i) - { - for(j = i; j < 3; j++) - char_array_3[j] = '\0'; - - char_array_4[0] = static_cast((char_array_3[0] & 0xfc) >> 2); - char_array_4[1] = static_cast(((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4)); - char_array_4[2] = static_cast(((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6)); - char_array_4[3] = static_cast(char_array_3[2] & 0x3f); - - for(j = 0; (j < i + 1); j++) - ret += base64_chars[char_array_4[j]]; - - while(i++ < 3) - { - if(!no_padding) ret += '='; - } - } - - return ret; - } - - std::string base64_decode(std::string const &encoded_string) - { - size_t in_len = encoded_string.size(); - size_t i = 0; - size_t j = 0; - size_t in_ = 0; - unsigned char char_array_4[4], char_array_3[3]; - std::string ret; - - while(in_len-- && (encoded_string[in_] != '=') && is_base64(static_cast(encoded_string[in_]))) - { - char_array_4[i++] = static_cast(encoded_string[in_]); - in_++; - if(i == 4) - { - for(i = 0; i < 4; i++) - char_array_4[i] = static_cast(base64_chars.find(static_cast(char_array_4[i]))); - char_array_3[0] = static_cast((char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4)); - char_array_3[1] = static_cast(((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2)); - char_array_3[2] = static_cast(((char_array_4[2] & 0x3) << 6) + char_array_4[3]); - for(i = 0; (i < 3); i++) - ret += static_cast(char_array_3[i]); - i = 0; - } - } - - if(i) - { - for(j = i; j < 4; j++) - char_array_4[j] = 0; - - for(j = 0; j < 4; j++) - char_array_4[j] = static_cast(base64_chars.find(static_cast(char_array_4[j]))); - - char_array_3[0] = static_cast((char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4)); - char_array_3[1] = static_cast(((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2)); - char_array_3[2] = static_cast(((char_array_4[2] & 0x3) << 6) + char_array_4[3]); - - for(j = 0; (j < i - 1); j++) - ret += static_cast(char_array_3[j]); - } - - //Remove zero from end - if(ret.size() > 0) - { - if(ret[ret.size() - 1] == '\0') - ret.resize(ret.size() - 1); - } - - return ret; - } - - bool TextFileInput::exists(PGESTRING filePath) - { - #ifdef PGE_FILES_QT - return QFile::exists(filePath); - #else - FILE *x = utf8_fopen(filePath.c_str(), "rb"); - if(x) - { - fclose(x); - return true; - } - return false; - #endif - } - - - /*****************BASE TEXT I/O CLASS***************************/ - TextInput::TextInput() : _lineNumber(0) {} - TextInput::~TextInput() {} - PGESTRING TextInput::read(int64_t) - { - return ""; - } - PGESTRING TextInput::readLine() - { - return ""; - } - PGESTRING TextInput::readCVSLine() - { - return ""; - } - PGESTRING TextInput::readAll() - { - return ""; - } - bool TextInput::eof() - { - return true; - } - int64_t TextInput::tell() - { - return 0; - } - int TextInput::seek(int64_t, TextInput::positions) { return -1; } - PGESTRING TextInput::getFilePath() - { - return _filePath; - } - void TextInput::setFilePath(PGESTRING path) - { - _filePath = path; - } - long TextInput::getCurrentLineNumber() - { - return _lineNumber; - } - - - TextOutput::TextOutput() : _lineNumber(0) {} - TextOutput::~TextOutput() {} - int TextOutput::write(PGESTRING) - { - return 0; - } - int64_t TextOutput::tell() - { - return 0; - } - int TextOutput::seek(int64_t, TextOutput::positions) { return -1; } - PGESTRING TextOutput::getFilePath() - { - return _filePath; - } - void TextOutput::setFilePath(PGESTRING path) - { - _filePath = path; - } - long TextOutput::getCurrentLineNumber() - { - return _lineNumber; - } - /*****************BASE TEXT I/O CLASS***************************/ - - - /*****************RAW TEXT I/O CLASS***************************/ - RawTextInput::RawTextInput() : TextInput(), _pos(0), _data(0), _isEOF(true) {} - - RawTextInput::RawTextInput(PGESTRING *rawString, PGESTRING filepath) : TextInput(), _pos(0), _data(0), _isEOF(true) - { - if(!open(rawString, filepath)) - _data = nullptr; - } - - RawTextInput::~RawTextInput() {} - - bool RawTextInput::open(PGESTRING *rawString, PGESTRING filepath) - { - if(!rawString) return false; - _data = rawString; - _filePath = filepath; - _pos = 0; - _isEOF = _data->size() == 0; - _lineNumber = 0; - return true; - } - - void RawTextInput::close() - { - _isEOF = true; - _data = NULL; - _filePath.clear(); - _pos = 0; - _lineNumber = 0; - } - - PGESTRING RawTextInput::read(int64_t len) - { - if(!_data) - return ""; - if(_isEOF) - return ""; - - if((_pos + len) >= static_cast(_data->size())) - { - len = static_cast(_data->size()) - _pos; - _isEOF = true; - } - PGESTRING buf(static_cast(len + 1), '\0'); - #ifdef PGE_FILES_QT - buf = _data->mid(static_cast(_pos), static_cast(len)); - #else - buf = _data->substr(static_cast(_pos), static_cast(len)); - #endif - _pos += len; - return buf; - } - - PGESTRING RawTextInput::readLine() - { - if(!_data) - return ""; - if(_isEOF) - return ""; - PGESTRING buffer; - PGEChar cur; - do - { - #ifdef PGE_FILES_QT - cur = (*_data)[static_cast(_pos++)]; - #else - cur = (*_data)[static_cast(_pos++)]; - #endif - if(_pos >= static_cast(_data->size())) - { - _pos = static_cast(_data->size()); - _isEOF = true; - } - if((cur != '\r') && (cur != '\n')) - buffer.push_back(cur); - } - while((cur != '\n') && !_isEOF); - _lineNumber++; - return buffer; - } - - PGESTRING RawTextInput::readCVSLine() - { - if(!_data) return ""; - if(_isEOF) return ""; - bool quoteIsOpen = false; - PGESTRING buffer; - PGEChar cur; - do - { - #ifdef PGE_FILES_QT - cur = (*_data)[static_cast(_pos++)]; - #else - cur = (*_data)[static_cast(_pos++)]; - #endif - if(_pos >= static_cast(_data->size())) - { - _pos = static_cast(_data->size()); - _isEOF = true; - } - if(cur == '\"') - quoteIsOpen = !quoteIsOpen; - else - { - if((cur != '\r') && (((cur != '\n') && (cur != ',')) || (quoteIsOpen))) - buffer.push_back(cur); - if(cur == '\n') _lineNumber++; - } - } - while((((cur != '\n') && (cur != ',')) || quoteIsOpen) && (!_isEOF)); - return buffer; - } - - PGESTRING RawTextInput::readAll() - { - if(!_data) return ""; - return *_data; - } - - bool RawTextInput::eof() - { - return _isEOF; - } - - int64_t RawTextInput::tell() - { - return _pos; - } - - int RawTextInput::seek(int64_t pos, TextInput::positions relativeTo) - { - if(!_data) - return -1; - - switch(relativeTo) - { - case current: - _pos += pos; - break; - case end: - _pos = static_cast(_data->size()) + pos; - break; - case begin: - default: - _pos = pos; - break; - } - if(_pos < 0) _pos = 0; - if(_pos >= static_cast(_data->size())) - { - _pos = static_cast(_data->size()); - _isEOF = true; - } - else - _isEOF = false; - return 0; - } - - - - RawTextOutput::RawTextOutput() : TextOutput(), _pos(0), _data(0) {} - - RawTextOutput::RawTextOutput(PGESTRING *rawString, outputMode mode) : TextOutput(), _pos(0), _data(0) - { - if(!open(rawString, mode)) - _data = nullptr; - } - - RawTextOutput::~RawTextOutput() {} - - bool RawTextOutput::open(PGESTRING *rawString, outputMode mode) - { - if(!rawString) return false; - _data = rawString; - _pos = 0; - _lineNumber = 0; - if(mode == truncate) - _data->clear(); - else if(mode == append) - _pos = static_cast(_data->size()); - return true; - } - - void RawTextOutput::close() - { - _data = NULL; - _pos = 0; - _lineNumber = 0; - } - - int RawTextOutput::write(PGESTRING buffer) - { - if(!_data) return -1; - int written = 0; -fillEnd: - if(_pos >= static_cast(_data->size())) - { - int64_t oldSize = static_cast(_data->size()); - _data->append(buffer); - _pos = static_cast(_data->size()); - written += (static_cast(_data->size()) - oldSize); - } - else - { - while((_pos < static_cast(_data->size())) && (!IsEmpty(buffer))) - { - _data[_pos++] = buffer[0]; - written++; - PGE_RemStrRng(buffer, 0, 1); - } - if(!IsEmpty(buffer)) - goto fillEnd; - } - return written; - } - - int64_t RawTextOutput::tell() - { - return _pos; - } - - int RawTextOutput::seek(int64_t pos, TextOutput::positions relativeTo) - { - if(!_data) - return -1; - switch(relativeTo) - { - case current: - _pos += pos; - break; - case end: - _pos = static_cast(_data->size()) + pos; - break; - case begin: - default: - _pos = pos; - break; - } - if(_pos < 0) - { - _pos = 0; - return -1; - } - if(_pos >= (signed)_data->size()) - _pos = static_cast(_data->size()); - return 0; - } - - TextOutput &TextOutput::operator<<(const PGESTRING &s) - { - this->write(s); - return *this; - } - - TextOutput &TextOutput::operator <<(const char *s) - { - this->write(s); - return *this; - } - /*****************RAW TEXT I/O CLASS***************************/ - - - - /*****************FILE TEXT I/O CLASS***************************/ - - TextFileInput::TextFileInput() : - TextInput() - #ifndef PGE_FILES_QT - , stream(NULL) - #endif - {} - - TextFileInput::TextFileInput(PGESTRING filePath, bool utf8) : - TextInput() - #ifndef PGE_FILES_QT - , stream(NULL) - #endif - { - if(!open(filePath, utf8)) - { - #ifndef PGE_FILES_QT - stream = NULL; - #else - file.close(); - #endif - } - } - - TextFileInput::~TextFileInput() - { - close(); - } - - bool TextFileInput::open(PGESTRING filePath, bool utf8) - { - _filePath = filePath; - _lineNumber = 0; - #ifdef PGE_FILES_QT - bool state = false; - file.setFileName(filePath); - state = file.open(QIODevice::ReadOnly | QIODevice::Text); - if(!state) return false; - stream.setDevice(&file); - if(utf8) - stream.setCodec("UTF-8"); - else - { - stream.setAutoDetectUnicode(true); - stream.setLocale(QLocale::system()); - stream.setCodec(QTextCodec::codecForLocale()); - } - return true; - #else - (void)utf8; - stream = utf8_fopen(filePath.c_str(), "rb"); - return (bool)stream; - #endif - } - - void TextFileInput::close() - { - _filePath.clear(); - _lineNumber = 0; - #ifdef PGE_FILES_QT - file.close(); - #else - if(stream) - fclose(stream); - stream = NULL; - #endif - } - - PGESTRING TextFileInput::read(int64_t len) - { - #ifdef PGE_FILES_QT - if(!file.isOpen()) return ""; - char *buf = new char[static_cast(len + 1)]; - buf[0] = '\0'; - int gotten = static_cast(file.read(buf, static_cast(len))); - if(gotten >= 0) - buf[gotten] = '\0'; - QString out(buf); - delete[] buf; - return out;//stream.read(len); - #else - if(!stream) - return ""; - std::string buf(static_cast(len + 1), '\0'); - size_t lenR = fread(&buf[0], 1, static_cast(len), stream); - (void)lenR; - return buf; - #endif - } - - PGESTRING TextFileInput::readLine() - { - #ifdef PGE_FILES_QT - if(!file.isOpen()) return ""; - return stream.readLine(); - #else - if(!stream) - return ""; - - std::string out; - out.reserve(1024); - int C = 0; - do - { - C = fgetc(stream); - if( (C != '\n') && (C != '\r') && (C != EOF) ) - out.push_back(static_cast(C)); - } - while((C != '\n') && (C != EOF)); - - if(out.size() == 0) - return ""; - - out.shrink_to_fit(); - - _lineNumber++; - return out; - #endif - } - - PGESTRING TextFileInput::readCVSLine() - { - bool quoteIsOpen = false; - std::string buffer; - #ifdef PGE_FILES_QT - char cur = 0; - if(!file.isOpen()) - return ""; - - do - { - file.getChar(&cur); - if(cur == '\"') - quoteIsOpen = !quoteIsOpen; - else - { - if((cur != '\r') && (((cur != '\n') && (cur != ',')) || (quoteIsOpen))) - buffer.push_back(cur); - if(cur == '\n') _lineNumber++; - } - } - while( (((cur != '\n') && (cur != ',')) || quoteIsOpen) - && !file.atEnd()); - return QString::fromStdString(buffer); - #else - buffer.reserve(1024); - if(!stream) - return ""; - - int gc; - char cur; - if(!feof(stream)) - do - { - gc = fgetc(stream); - if(gc == EOF) - break; - cur = static_cast(gc); - if(cur == '\"') - quoteIsOpen = !quoteIsOpen; - else - { - if((cur != '\r') && (((cur != '\n') && (cur != ',')) || (quoteIsOpen))) - buffer.push_back(cur); - if(cur == '\n') - _lineNumber++; - } - } - while( (((cur != '\n') && (cur != ',')) || quoteIsOpen) ); - buffer.shrink_to_fit(); - return buffer; - #endif - } - - PGESTRING TextFileInput::readAll() - { - #ifdef PGE_FILES_QT - return stream.readAll(); - #else - if(!stream) return ""; - std::string out; - out.reserve(10240); - fseek(stream, 0, SEEK_SET); - int x = 0; - do - { - x = fgetc(stream); - if((x != '\r') && (x != EOF)) - out.push_back(static_cast(x)); - } - while(!feof(stream)); - return out; - #endif - } - - bool TextFileInput::eof() - { - #ifdef PGE_FILES_QT - return stream.atEnd(); - #else - return feof(stream); - #endif - } - - int64_t TextFileInput::tell() - { - #ifdef PGE_FILES_QT - return static_cast(file.pos()); - #else - return static_cast(ftell(stream)); - #endif - } - - int TextFileInput::seek(int64_t pos, TextFileInput::positions relativeTo) - { - #ifdef PGE_FILES_QT - (void)relativeTo; - switch(relativeTo) - { - case current: - file.seek(file.pos() + pos); - break; - case begin: - file.seek(pos); - stream.seek(pos); - break; - case end: - file.seek(file.size() - pos); - break; - default: - file.seek(pos); - stream.seek(pos); - break; - } - return 0; - #else - int s = 0; - switch(relativeTo) - { - case current: - s = SEEK_CUR; - break; - case begin: - s = SEEK_SET; - break; - case end: - s = SEEK_END; - break; - default: - s = SEEK_SET; - break; - } - return fseek(stream, pos, s); - #endif - } - - - - - TextFileOutput::TextFileOutput() : TextOutput(), m_forceCRLF(false) - { - #ifndef PGE_FILES_QT - stream = NULL; - #endif - } - - TextFileOutput::TextFileOutput(PGESTRING filePath, bool utf8, bool forceCRLF, TextOutput::outputMode mode) : TextOutput() - { - if(!open(filePath, utf8, forceCRLF, mode)) - { - #ifndef PGE_FILES_QT - stream = NULL; - #else - file.close(); - #endif - } - } - - TextFileOutput::~TextFileOutput() - { - close(); - } - - bool TextFileOutput::open(PGESTRING filePath, bool utf8, bool forceCRLF, TextOutput::outputMode mode) - { - m_forceCRLF = forceCRLF; - _filePath = filePath; - _lineNumber = 0; - #ifdef PGE_FILES_QT - bool state = false; - file.setFileName(filePath); - if(mode == truncate) - state = file.open(QIODevice::WriteOnly | QIODevice::Truncate); - else if(mode == append) - state = file.open(QIODevice::WriteOnly | QIODevice::Append); - else - state = file.open(QIODevice::WriteOnly); - if(!state) return false; - if(!m_forceCRLF) - { - stream.setDevice(&file); - if(utf8) - stream.setCodec("UTF-8"); - else - { - stream.setAutoDetectUnicode(true); - stream.setLocale(QLocale::system()); - stream.setCodec(QTextCodec::codecForLocale()); - } - } - return true; - #else - (void)utf8; - const char *tmode = NULL; - if(mode == truncate) - tmode = "wb"; - else if(mode == append) - tmode = "ab"; - else - tmode = "wb"; - stream = utf8_fopen(filePath.c_str(), tmode); - return (stream != NULL); - #endif - } - - void TextFileOutput::close() - { - _filePath.clear(); - _lineNumber = 0; - #ifdef PGE_FILES_QT - file.close(); - #else - if(stream) - fclose(stream); - stream = NULL; - #endif - } - - int TextFileOutput::write(PGESTRING buffer) - { - pge_size_t writtenBytes = 0; - if(m_forceCRLF) - { - #ifdef PGE_FILES_QT - buffer.replace("\n", "\r\n"); - writtenBytes = static_cast(file.write(buffer.toLocal8Bit())); - #else - for(pge_size_t i = 0; i < buffer.size(); i++) - { - if(buffer[i] == '\n') - { - //Force writing CRLF to prevent fakse damage of file on SMBX in Windows - static const char bytes[2] = {0x0D, 0x0A}; - size_t bytesNum = 2; - bytesNum = fwrite(&bytes, 1, 2, stream); - if(bytesNum == 0) - return -1; - writtenBytes += bytesNum; - } - else - { - pge_size_t bytesNum = 1; - fputc(buffer[i], stream); - writtenBytes += bytesNum; - } - } - #endif - } - else - { - writtenBytes = static_cast(buffer.size()); - #ifdef PGE_FILES_QT - stream << buffer; - #else - fwrite(buffer.c_str(), 1, buffer.size(), stream); - #endif - } - return static_cast(writtenBytes); - } - - int64_t TextFileOutput::tell() - { - #ifdef PGE_FILES_QT - if(!m_forceCRLF) - return static_cast(stream.pos()); - else - return static_cast(file.pos()); - #else - return ftell(stream); - #endif - } - - int TextFileOutput::seek(int64_t pos, TextOutput::positions relativeTo) - { - #ifdef PGE_FILES_QT - (void)relativeTo; - if(!m_forceCRLF) - stream.seek(pos); - else - file.seek(pos); - return 0; - #else - int s; - switch(relativeTo) - { - case current: - s = SEEK_CUR; - break; - case begin: - s = SEEK_SET; - break; - case end: - s = SEEK_END; - break; - default: - s = SEEK_SET; - break; - } - return fseek(stream, pos, s); - #endif - } - - /*****************FILE TEXT I/O CLASS***************************/ - - - - FileInfo::FileInfo() - {} - - FileInfo::FileInfo(PGESTRING filepath) - { - setFile(filepath); - } - - void FileInfo::setFile(PGESTRING filepath) - { - filePath = filepath; - rebuildData(); - } - - PGESTRING FileInfo::suffix() - { - return _suffix; - } - - PGESTRING FileInfo::filename() - { - return _filename; - } - - PGESTRING FileInfo::fullPath() - { - return filePath; - } - - PGESTRING FileInfo::basename() - { - return _basename; - } - - PGESTRING FileInfo::dirpath() - { - return _dirpath; - } - - void FileInfo::rebuildData() - { - #ifdef _WIN32 -#define PATH_MAXLEN MAX_PATH - #else -#define PATH_MAXLEN PATH_MAX - #endif - int i; - _suffix.clear(); - _filename.clear(); - _dirpath.clear(); - _basename.clear(); - - //Take full path - #ifdef PGE_FILES_QT - filePath = QFileInfo(filePath).absoluteFilePath(); - #else - #ifndef _WIN32 - char *rez = NULL; - char buf[PATH_MAXLEN + 1]; - rez = realpath(filePath.c_str(), buf); - if(rez) - filePath = buf; - #else - wchar_t bufW[MAX_PATH + 1]; - int ret = 0; - ret = GetFullPathNameW(Str2WStr(filePath).c_str(), MAX_PATH, bufW, NULL); - if(ret != 0) - filePath = WStr2Str(bufW); - std::replace(filePath.begin(), filePath.end(), '\\', '/'); - #endif - #endif - - //Read directory path - i = static_cast(filePath.size() - 1); - for(; i >= 0; i--) - { - if((filePath[static_cast(i)] == '/') || (filePath[static_cast(i)] == '\\')) - break; - } - - if(i >= 0) - { - #ifndef PGE_FILES_QT - _dirpath = filePath.substr(0, static_cast(i)); - #else - _dirpath = filePath.left(i); - #endif - } - - //Take file suffix - i = static_cast(filePath.size()) - 1; - for(; i > 0; i--) - { - if(filePath[static_cast(i)] == '.') - break; - } - - if(i > 0) - i++; - if(i == (static_cast(filePath.size()) - 1)) - goto skipSuffix; - for(; i < static_cast(filePath.size()); i++) - _suffix.push_back( - static_cast( - tolower( - PGEGetChar(filePath[static_cast(i)]) - ) - ) - ); -skipSuffix: - - //Take file name without path - i = static_cast(filePath.size()) - 1; - for(; i >= 0; i--) - { - if((filePath[static_cast(i)] == '/') || (filePath[static_cast(i)] == '\\')) break; - } - if(i > 0) - i++; - - if(i >= (static_cast(filePath.size()) - 1)) - goto skipFilename; - for(; i < static_cast(filePath.size()); i++) - _filename.push_back(filePath[static_cast(i)]); - -skipFilename: - //Take base file name - _basename = _filename; - for(i = static_cast(_basename.size()) - 1; i > 0; i--) - { - if(_basename[static_cast(i)] == '.') - { - _basename.resize(static_cast(i)); - break; - } - } - } -} diff --git a/LunaDll/libs/PGE_File_Formats/pge_file_lib_globs.h b/LunaDll/libs/PGE_File_Formats/pge_file_lib_globs.h deleted file mode 100644 index e40d6539d..000000000 --- a/LunaDll/libs/PGE_File_Formats/pge_file_lib_globs.h +++ /dev/null @@ -1,712 +0,0 @@ -/*! \file pge_file_lib_globs.h - \brief Contains internal settings and references for PGE File Library - - All defined here macroses are allows to build PGE File Library for both - Qt and STL libraries set. -*/ -#pragma once -#ifndef PGE_FILE_LIB_GLOBS_H_ -#define PGE_FILE_LIB_GLOBS_H_ - -/*! \def PGE_FILES_QT - \brief If this macro is defined, Qt version of PGE File Library will be built -*/ - -/*! \def PGE_ENGINE - \brief If this macro is defined, this library builds as part of PGE Engine -*/ - -/*! \def PGE_EDITOR - \brief If this macro is defined, this library builds as part of PGE Editor -*/ - -/*! \def PGEChar - \brief A macro which equal to 'char' if PGE File Library built in the STL mode - and equal to QChar if PGE File Library built in the Qt mode -*/ - -/*! \def PGESTRING - \brief A macro which equal to std::string if PGE File Library built in the STL mode - and equal to QString if PGE File Library built in the Qt mode -*/ - -/*! \def PGESTRINGList - \brief A macro which equal to std::vector if PGE File Library built in the STL mode - and equal to QStringList if PGE File Library built in the Qt mode -*/ - -/*! \def PGELIST - \brief A macro which equal to std::vector if PGE File Library built in the STL mode - and equal to QList if PGE File Library built in the Qt mode -*/ - -/*! \def PGEVECTOR - \brief A macro which equal to std::vector if PGE File Library built in the STL mode - and equal to QVector if PGE File Library built in the Qt mode -*/ - -#include - -#ifdef PGE_FILES_QT -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(PGE_ENGINE)||defined(PGE_EDITOR) -#include -#endif -#define PGE_FILES_INHERED public QObject -typedef QString PGESTRING; -typedef int pge_size_t; -inline PGESTRING PGESTR_Simpl(const PGESTRING &str) -{ - return str.simplified(); -} -inline PGESTRING PGESTR_toLower(const PGESTRING &str) -{ - return str.toLower(); -} -#define PGEGetChar(chr) chr.toLatin1() -typedef QChar PGEChar; -typedef QStringList PGESTRINGList; -#define PGEVECTOR QVector -#define PGELIST QList -typedef int pge_size_t; -#define PGEPAIR QPair -#define PGEMAP QMap -#define PGEHASH QHash -typedef QFile PGEFILE; -inline void PGE_SPLITSTRING(PGESTRINGList &dst, PGESTRING &src, PGESTRING sep) -{ - dst = src.split(sep); -} -inline PGESTRING PGE_ReplSTRING(PGESTRING &src, PGESTRING from, PGESTRING to) -{ - return src.replace(from, to); -} -inline PGESTRING PGE_RemSubSTRING(PGESTRING &src, PGESTRING substr) -{ - return src.remove(substr); -} -inline PGESTRING PGE_RemStrRng(PGESTRING &str, int pos, int len) -{ - return str.remove(pos, len); -} -inline PGESTRING PGE_SubStr(PGESTRING &str, int pos, int len = -1) -{ - return str.mid(pos, len); -} -inline bool IsNULL(const PGESTRING str) -{ - return str.isNull(); -} -inline bool IsEmpty(const PGESTRING &str) -{ - return str.isEmpty(); -} -inline bool IsEmpty(const PGESTRINGList &str) -{ - return str.isEmpty(); -} -inline int toInt(PGESTRING str) -{ - return str.toInt(); -} -inline unsigned int toUInt(PGESTRING str) -{ - return str.toUInt(); -} -inline long toLong(PGESTRING str) -{ - return str.toLong(); -} -inline unsigned long toULong(PGESTRING str) -{ - return str.toULong(); -} -inline float toFloat(PGESTRING str) -{ - return str.toFloat(); -} -inline double toDouble(PGESTRING str) -{ - return str.toDouble(); -} -inline PGESTRING removeSpaces(PGESTRING src) -{ - return src.remove(' '); -} -template -PGESTRING fromNum(T num) -{ - return QString::number(num); -} -inline PGESTRING fromBoolToNum(bool num) -{ - return QString::number(static_cast(num)); -} -namespace PGE_FileFormats_misc -{ - PGESTRING url_encode(const PGESTRING &sSrc); - std::string base64_encode(uint8_t const *bytes_to_encode, size_t in_len, bool no_padding = false); - std::string base64_encode(std::string const &source, bool no_padding = false); - std::string base64_decode(std::string const &encoded_string); - QString base64_encode(QString &source, bool no_padding = false); - QString base64_decode(QString &source); - QString base64_encodeW(QString &source, bool no_padding = false); - QString base64_decodeW(QString &source); - QString base64_encodeA(QString &source, bool no_padding = false); - QString base64_decodeA(QString &source); -} -inline PGESTRING PGE_URLENC(const PGESTRING &src) -{ - return PGE_FileFormats_misc::url_encode(src); -} -inline PGESTRING PGE_URLDEC(const PGESTRING &src) -{ - /* Don't call fromPercentEncoding() on Windows with empty string, - * or crash will happen! */ - if(IsEmpty(src)) - return PGESTRING(); - return QUrl::fromPercentEncoding(src.toUtf8()); -} -#define PGE_BASE64ENC(src) PGE_FileFormats_misc::base64_encode(src) -#define PGE_BASE64ENC_nopad(src) PGE_FileFormats_misc::base64_encode(src, true) -#define PGE_BASE64DEC(src) PGE_FileFormats_misc::base64_decode(src) -#define PGE_BASE64ENC_W(src) PGE_FileFormats_misc::base64_encodeW(src) -#define PGE_BASE64DEC_W(src) PGE_FileFormats_misc::base64_decodeW(src) -#define PGE_BASE64ENC_A(src) PGE_FileFormats_misc::base64_encodeA(src) -#define PGE_BASE64DEC_A(src) PGE_FileFormats_misc::base64_decodeA(src) -#else -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define PGE_FILES_INGERED -typedef std::string PGESTRING; -typedef std::string::size_type pge_size_t; -inline PGESTRING PGESTR_Simpl(PGESTRING str) -{ - str.erase(std::remove_if(str.begin(), str.end(), ::isspace), str.end()); - return str; -} -inline PGESTRING PGESTR_toLower(PGESTRING str) -{ - std::transform(str.begin(), str.end(), str.begin(), ::tolower); - return str; -} -#define PGEGetChar(chr) chr -typedef char PGEChar; -typedef std::vector PGESTRINGList; -#define PGEVECTOR std::vector -#define PGELIST std::vector -typedef size_t pge_size_t; -#define PGEPAIR std::pair -#define PGEMAP std::map -#define PGEHASH std::unordered_map -typedef std::fstream PGEFILE; -namespace PGE_FileFormats_misc -{ - void split(std::vector &dest, const std::string &str, const std::string& separator); - void replaceAll(std::string &str, const std::string &from, const std::string &to); - void RemoveSub(std::string &sInput, const std::string &sub); - bool hasEnding(std::string const &fullString, std::string const &ending); - PGESTRING url_encode(const PGESTRING &sSrc); - PGESTRING url_decode(const std::string &sSrc); - std::string base64_encode(unsigned char const *bytes_to_encode, size_t in_len, bool no_padding = false); - std::string base64_encode(std::string const &source, bool no_padding = false); - std::string base64_decode(std::string const &encoded_string); - std::string base64_encodeW(std::string &source, bool no_padding = false); - std::string base64_decodeW(std::string &source); - std::string base64_encodeA(std::string &source, bool no_padding = false); - std::string base64_decodeA(std::string &source); -} -inline void PGE_SPLITSTRING(PGESTRINGList &dst, const PGESTRING &src, const PGESTRING &sep) -{ - dst.clear(); - PGE_FileFormats_misc::split(dst, src, sep); -} -inline PGESTRING PGE_ReplSTRING(PGESTRING src, PGESTRING from, PGESTRING to) -{ - PGE_FileFormats_misc::replaceAll(src, from, to); - return src; -} - -inline PGESTRING PGE_RemSubSTRING(PGESTRING src, PGESTRING substr) -{ - PGE_FileFormats_misc::RemoveSub(src, substr); - return src; -} -inline PGESTRING PGE_RemStrRng(PGESTRING &str, int pos, int len) -{ - str.erase(static_cast(pos), static_cast(len)); - return str; -} -inline PGESTRING PGE_SubStr(PGESTRING &str, std::string::size_type pos, std::string::size_type len = std::string::npos) -{ - return str.substr(pos, len); -} -inline bool IsNULL(const PGESTRING str) -{ - return (str.empty()); -} -inline bool IsEmpty(const PGESTRING &str) -{ - return str.empty(); -} -inline bool IsEmpty(const PGESTRINGList &str) -{ - return str.empty(); -} -inline int toInt(PGESTRING str) -{ - return std::atoi(str.c_str()); -} -inline unsigned int toUInt(PGESTRING str) -{ - return static_cast(std::atol(str.c_str())); -} -inline long toLong(PGESTRING str) -{ - return std::atol(str.c_str()); -} -inline unsigned long toULong(PGESTRING str) -{ - return static_cast(std::atoll(str.c_str())); -} -inline float toFloat(PGESTRING str) -{ - return static_cast(std::atof(str.c_str())); -} -inline double toDouble(PGESTRING str) -{ - return std::atof(str.c_str()); -} -inline PGESTRING removeSpaces(PGESTRING src) -{ - return PGE_RemSubSTRING(src, " "); -} -template -PGESTRING fromNum(T num) -{ - std::ostringstream n; - n << num; - return n.str(); -} - -inline PGESTRING fromBoolToNum(bool num) -{ - std::ostringstream n; - n << static_cast(num); - return n.str(); -} -#define PGE_URLENC(src) PGE_FileFormats_misc::url_encode(src) -#define PGE_URLDEC(src) PGE_FileFormats_misc::url_decode(src) -#define PGE_BASE64ENC(src) PGE_FileFormats_misc::base64_encode(src) -#define PGE_BASE64ENC_nopad(src) PGE_FileFormats_misc::base64_encode(src, true) -#define PGE_BASE64DEC(src) PGE_FileFormats_misc::base64_decode(src) -#define PGE_BASE64ENC_W(src) PGE_FileFormats_misc::base64_encodeW(src) -#define PGE_BASE64DEC_W(src) PGE_FileFormats_misc::base64_decodeW(src) -#define PGE_BASE64ENC_A(src) PGE_FileFormats_misc::base64_encodeA(src) -#define PGE_BASE64DEC_A(src) PGE_FileFormats_misc::base64_decodeA(src) -#endif - -inline bool PGE_StartsWith(PGESTRING src, PGESTRING with) -{ -#ifdef PGE_FILES_QT - return src.startsWith(with, Qt::CaseSensitive); -#else - return !src.compare(0, with.size(), with); -#endif -} - -inline bool PGE_DetectSMBXFile(PGESTRING src) -{ - /* - * First line of SMBX1...64 file must contain number from 0 to 64 - */ - src.push_back('\n');//Append double line feed to end (for case if sent first line only) - src.push_back('\n'); - - if((src.size() < 3)) - return false;//If line too short - - if((src[1] != '\n') && (src[2] != '\n') && - (src[1] != '\r') && (src[2] != '\r')) - return false;//If line contains no line feeds (also possible CRLF) - - if((src[0] < '0') && (src[0] > '9')) - return false;//If first character is not numeric - - if((src[1] != '\r') && (src[1] != '\n') && (src[1] < '0') && (src[1] > '9')) - return false;//If second character is not numeric and is not line feed - - PGESTRING number; - number.push_back(src[0]); - - if((src[1] != '\n') && (src[1] != '\r')) - number.push_back(src[1]); - - int version = toInt(number); - - if(version > 64) //Unsupported version number! - return false; - - return true; -} - -/*! - * Misc I/O classes used by PGE File Library internally - */ -namespace PGE_FileFormats_misc -{ - /*! - * \brief Provides cross-platform file path calculation for a file names or paths - */ - class FileInfo - { - public: - /*! - * \brief Constructor - */ - FileInfo(); - /*! - * \brief Constructor with pre-opening of a file - * \param filepath relative or absolute file path - */ - FileInfo(PGESTRING filepath); - /*! - * \brief Sets file which will be used to calculate file information - * \param filepath - */ - void setFile(PGESTRING filepath); - /*! - * \brief Returns file extension (last part of filename after last dot) - * \return file suffix or name extension (last part of filename after last dot) - */ - PGESTRING suffix(); - /*! - * \brief Returns full filename without path - * \return full filename without path - */ - PGESTRING filename(); - /*! - * \brief Returns absolute path to file - * \return absolute path to file - */ - PGESTRING fullPath(); - /*! - * \brief Returns base name part (first part of file name before first dot) - * \return base name part (first part of file name before first dot) - */ - PGESTRING basename(); - /*! - * \brief Returns full directory path where actual file is located - * \return full directory path where actual file is located - */ - PGESTRING dirpath(); - private: - /*! - * \brief Recalculates all internal fields - */ - void rebuildData(); - /*! - * \brief Current filename - */ - PGESTRING filePath; - /*! - * \brief Current filename without directory path - */ - PGESTRING _filename; - /*! - * \brief File name suffix (last part of file name after last dot) - */ - PGESTRING _suffix; - /*! - * \brief Base name (first part of file name before first dot) - */ - PGESTRING _basename; - /*! - * \brief Full directory path where file is located - */ - PGESTRING _dirpath; - }; - - - class TextInput - { - public: - /*! - * \brief Relative positions of carriage - */ - enum positions - { - //! Relative to current position - current = 0, - //! Relative to begin of file - begin, - //! Relative to end of file - end - }; - - TextInput(); - virtual ~TextInput(); - virtual PGESTRING read(int64_t len); - virtual PGESTRING readLine(); - virtual PGESTRING readCVSLine(); - virtual PGESTRING readAll(); - virtual bool eof(); - virtual int64_t tell(); - virtual int seek(int64_t pos, positions relativeTo); - virtual PGESTRING getFilePath(); - virtual void setFilePath(PGESTRING path); - virtual long getCurrentLineNumber(); - protected: - PGESTRING _filePath; - long _lineNumber; - }; - - class TextOutput - { - public: - /*! - * \brief Relative positions of carriage - */ - enum positions - { - //! Relative to current position - current = 0, - //! Relative to begin of file - begin, - //! Relative to end of file - end - }; - enum outputMode - { - truncate = 0, - append, - overwrite - }; - - TextOutput(); - virtual ~TextOutput(); - virtual int write(PGESTRING buffer); - virtual int64_t tell(); - virtual int seek(int64_t pos, positions relativeTo); - virtual PGESTRING getFilePath(); - virtual void setFilePath(PGESTRING path); - virtual long getCurrentLineNumber(); - TextOutput &operator<<(const PGESTRING &s); - TextOutput &operator<<(const char *s); - protected: - PGESTRING _filePath; - long _lineNumber; - }; - - - class RawTextInput: public TextInput - { - public: - RawTextInput(); - RawTextInput(PGESTRING *rawString, PGESTRING filepath = ""); - virtual ~RawTextInput(); - bool open(PGESTRING *rawString, PGESTRING filepath = ""); - void close(); - virtual PGESTRING read(int64_t len); - virtual PGESTRING readLine(); - virtual PGESTRING readCVSLine(); - virtual PGESTRING readAll(); - virtual bool eof(); - virtual int64_t tell(); - virtual int seek(int64_t _pos, positions relativeTo); - private: - int64_t _pos; - PGESTRING *_data; - bool _isEOF; - }; - - class RawTextOutput: public TextOutput - { - public: - RawTextOutput(); - RawTextOutput(PGESTRING *rawString, outputMode mode = truncate); - virtual ~RawTextOutput(); - bool open(PGESTRING *rawString, outputMode mode = truncate); - void close(); - int write(PGESTRING buffer); - int64_t tell(); - int seek(int64_t _pos, positions relativeTo); - private: - long long _pos; - PGESTRING *_data; - }; - - - - /*! - * \brief Provides cross-platform text file reading interface - */ - class TextFileInput: public TextInput - { - public: - /*! - * \brief Checks is requested file exist - * \param filePath Full or relative path to the file - * \return true if file exists - */ - static bool exists(PGESTRING filePath); - /*! - * \brief Constructor - */ - TextFileInput(); - /*! - * \brief Constructor with pre-opening of the file - * \param filePath Full or relative path to the file - * \param utf8 Use UTF-8 encoding or will be used local 8-bin encoding - */ - TextFileInput(PGESTRING filePath, bool utf8 = false); - /*! - * \brief Destructor - */ - virtual ~TextFileInput(); - /*! - * \brief Opening of the file - * \param filePath Full or relative path to the file - * \param utf8 Use UTF-8 encoding or will be used local 8-bin encoding - */ - bool open(PGESTRING filePath, bool utf8 = false); - /*! - * \brief Close currently opened file - */ - void close(); - /*! - * \brief Reads requested number of characters from a file - * \param Maximal lenght of characters to read from file - * \return string contains requested line of characters - */ - PGESTRING read(int64_t len); - /*! - * \brief Reads whole line before line feed character - * \return string contains gotten line - */ - PGESTRING readLine(); - /*! - * \brief Reads whole line before line feed character or before first unquoted comma - * \return string contains gotten line - */ - PGESTRING readCVSLine(); - /*! - * \brief Reads all data from a file at current position of carriage - * \return - */ - PGESTRING readAll(); - /*! - * \brief Is carriage position at end of file - * \return true if carriage position at end of file - */ - bool eof(); - /*! - * \brief Returns current position of carriage relative to begin of file - * \return current position of carriage relative to begin of file - */ - int64_t tell(); - /*! - * \brief Changes position of carriage to specific file position - * \param pos Target position of carriage - * \param relativeTo defines relativity of target position of carriage (current position, begin of file or end of file) - */ - int seek(int64_t pos, positions relativeTo); - private: -#ifdef PGE_FILES_QT - //! File handler used in Qt version of PGE file Library - QFile file; - //! File input stream used in Qt version of PGE file Library - QTextStream stream; -#else - //! File input stream used in STL version of PGE file Library - FILE *stream; -#endif - }; - - - class TextFileOutput: public TextOutput - { - public: - /*! - * \brief Checks is requested file exist - * \param filePath Full or relative path to the file - * \return true if file exists - */ - static bool exists(PGESTRING filePath); - /*! - * \brief Constructor - */ - TextFileOutput(); - /*! - * \brief Constructor with pre-opening of the file - * \param filePath Full or relative path to the file - * \param utf8 Use UTF-8 encoding or will be used local 8-bin encoding - */ - TextFileOutput(PGESTRING filePath, bool utf8 = false, bool forceCRLF = false, outputMode mode = truncate); - /*! - * \brief Destructor - */ - virtual ~TextFileOutput(); - /*! - * \brief Opening of the file - * \param filePath Full or relative path to the file - * \param utf8 Use UTF-8 encoding or will be used local 8-bin encoding - */ - bool open(PGESTRING filePath, bool utf8 = false, bool forceCRLF = false, outputMode mode = truncate); - /*! - * \brief Close currently opened file - */ - void close(); - /*! - * \brief Reads requested number of characters from a file - * \param Maximal lenght of characters to read from file - * \return string contains requested line of characters - */ - int write(PGESTRING buffer); - /*! - * \brief Returns current position of carriage relative to begin of file - * \return current position of carriage relative to begin of file - */ - int64_t tell(); - /*! - * \brief Changes position of carriage to specific file position - * \param pos Target position of carriage - * \param relativeTo defines relativity of target position of carriage (current position, begin of file or end of file) - */ - int seek(int64_t pos, positions relativeTo); - private: - bool m_forceCRLF; -#ifdef PGE_FILES_QT - //! File handler used in Qt version of PGE file Library - QFile file; - //! File input stream used in Qt version of PGE file Library - QTextStream stream; -#else - //! File input stream used in STL version of PGE file Library - FILE *stream; -#endif - }; - -} - -#endif // PGE_FILE_LIB_GLOBS_H_ diff --git a/LunaDll/libs/PGE_File_Formats/pge_file_lib_sys.h b/LunaDll/libs/PGE_File_Formats/pge_file_lib_sys.h deleted file mode 100644 index 05b5c7439..000000000 --- a/LunaDll/libs/PGE_File_Formats/pge_file_lib_sys.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once -#ifndef PGE_FILE_LIB_SYS_H_ -#define PGE_FILE_LIB_SYS_H_ - -/*! - * \file pge_file_lib_sys.h - * \brief Contains internally used global haders lists - * - */ - -#ifdef PGE_FILES_QT -#include -#include -#include -#include -#include -#include -#include -#else -#include -#include -#include -#include /* PATH_MAX */ -#endif - -#endif // PGE_FILE_LIB_SYS_H_ diff --git a/LunaDll/libs/PGE_File_Formats/pge_file_library.cmake b/LunaDll/libs/PGE_File_Formats/pge_file_library.cmake deleted file mode 100644 index 6a14b6d85..000000000 --- a/LunaDll/libs/PGE_File_Formats/pge_file_library.cmake +++ /dev/null @@ -1,32 +0,0 @@ -# message("Path to PGE File Library is [${CMAKE_CURRENT_LIST_DIR}]") -include_directories(${CMAKE_CURRENT_LIST_DIR}/../) - -set(PGE_FILE_LIBRARY_SRCS) - -list(APPEND PGE_FILE_LIBRARY_SRCS - ${CMAKE_CURRENT_LIST_DIR}/ConvertUTF_PGEFF.c - ${CMAKE_CURRENT_LIST_DIR}/file_formats.cpp - ${CMAKE_CURRENT_LIST_DIR}/file_rw_lvl.cpp - ${CMAKE_CURRENT_LIST_DIR}/file_rw_lvl_38a.cpp - ${CMAKE_CURRENT_LIST_DIR}/file_rw_lvlx.cpp - ${CMAKE_CURRENT_LIST_DIR}/file_rw_meta.cpp - ${CMAKE_CURRENT_LIST_DIR}/file_rw_npc_txt.cpp - ${CMAKE_CURRENT_LIST_DIR}/file_rw_sav.cpp - ${CMAKE_CURRENT_LIST_DIR}/file_rw_wld.cpp - ${CMAKE_CURRENT_LIST_DIR}/file_rw_wldx.cpp - ${CMAKE_CURRENT_LIST_DIR}/file_rw_smbx64_cnf.cpp - ${CMAKE_CURRENT_LIST_DIR}/file_rwopen.cpp - ${CMAKE_CURRENT_LIST_DIR}/file_strlist.cpp - ${CMAKE_CURRENT_LIST_DIR}/lvl_filedata.cpp - ${CMAKE_CURRENT_LIST_DIR}/npc_filedata.cpp - ${CMAKE_CURRENT_LIST_DIR}/pge_x.cpp - ${CMAKE_CURRENT_LIST_DIR}/save_filedata.cpp - ${CMAKE_CURRENT_LIST_DIR}/smbx64.cpp - ${CMAKE_CURRENT_LIST_DIR}/smbx64_cnf_filedata.cpp - ${CMAKE_CURRENT_LIST_DIR}/wld_filedata.cpp - ${CMAKE_CURRENT_LIST_DIR}/pge_file_lib_globs.cpp - ${CMAKE_CURRENT_LIST_DIR}/file_rw_savx.cpp - ${CMAKE_CURRENT_LIST_DIR}/file_rw_lvl_38a_old.cpp - ${CMAKE_CURRENT_LIST_DIR}/file_rw_wld_38a.cpp -) - diff --git a/LunaDll/libs/PGE_File_Formats/pge_x.cpp b/LunaDll/libs/PGE_File_Formats/pge_x.cpp deleted file mode 100644 index 4d168f965..000000000 --- a/LunaDll/libs/PGE_File_Formats/pge_x.cpp +++ /dev/null @@ -1,931 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifdef PGE_FILES_QT -#include -#include -#else -#include -#endif - -#include "pge_x.h" -#include "file_strlist.h" - -namespace PGEExtendedFormat -{ - static const char *heximal_valid_chars = "0123456789ABCDEFabcdef"; - static const pge_size_t heximal_valid_chars_len = 22; - - bool isDegit(PGEChar c) - { - return ((c >= '0') && (c <= '9')); - } - - bool isValid(PGESTRING &s, const char *valid_chars, const pge_size_t &valid_chars_len) - { - if(IsEmpty(s)) return false; - pge_size_t i, j; - for(i = 0; i < s.size(); i++) - { - bool found = false; - for(j = 0; j < valid_chars_len; j++) - { - if(PGEGetChar(s[i]) == valid_chars[j]) - { - found = true; - break; - } - } - if(!found) return false; - } - return true; - } -} - - -#ifdef PGE_FILES_QT -PGEFile::PGEFile(QObject *parent) - : QObject(parent) -#else -PGEFile::PGEFile() -#endif -{ - m_lastError = ""; - m_rawData = ""; -} - -#ifdef PGE_FILES_QT -PGEFile::PGEFile(const PGEFile &pgeFile, QObject *parent) - : QObject(parent) -#else -PGEFile::PGEFile(const PGEFile & pgeFile) -#endif -{ - m_rawData = pgeFile.m_rawData; - m_rawDataTree = pgeFile.m_rawDataTree; - m_lastError = pgeFile.m_lastError; -} - -PGEFile::PGEFile(const PGESTRING &_rawData) -{ - m_rawData = _rawData; - m_lastError = ""; -} - -PGESTRING PGEFile::removeQuotes(PGESTRING str) -{ - PGESTRING target = PGE_RemStrRng(str, 0, 1); - target = PGE_RemStrRng(target, static_cast(target.size() - 1), 1); - return target; -} - -void PGEFile::setRawData(const PGESTRING &_rawData) -{ - m_rawData = _rawData; -} - -bool PGEFile::buildTreeFromRaw() -{ - PGEXSct PGEXsection; - - FileStringList in; - in.addData(m_rawData); - - //Read raw data sections - bool sectionOpened = false; - while(!in.atEnd()) - { - PGEXsection.first = in.readLine(); - PGEXsection.second.clear(); - - //Skip empty parts - PGESTRING pgex_sectionName = removeSpaces(PGEXsection.first); - if(IsEmpty(pgex_sectionName)) continue; - - sectionOpened = true; - PGESTRING data; - while(!in.atEnd()) - { - data = in.readLine(); - if(data == PGEXsection.first + "_END") - { - sectionOpened = false; // Close Section - break; - } - PGEXsection.second.push_back(data); - } - m_rawDataTree.push_back(PGEXsection); - } - - if(sectionOpened) - { - m_lastError = PGESTRING("Section [" + PGEXsection.first + "] is not closed"); - return false; - } - - //Building tree - - for(pge_size_t z = 0; z < m_rawDataTree.size(); z++) - { - bool valid = true; - PGEX_Entry subTree = buildTree(m_rawDataTree[z].second, &valid); - if(valid) - { - //Store like subtree - subTree.type = PGEX_Struct; - subTree.name = m_rawDataTree[z].first; - dataTree.push_back(subTree); - } - else - { - //Store like plain text - PGEX_Item dataItem; - dataItem.type = PGEX_PlainText; - subTree.data.clear(); - subTree.subTree.clear(); - PGEX_Val dataValue; - dataValue.marker = "PlainText"; - for(pge_size_t i = 0; i < m_rawDataTree[z].second.size(); i++) - dataValue.value += m_rawDataTree[z].second[i] + "\n"; - dataItem.values.push_back(dataValue); - subTree.name = m_rawDataTree[z].first; - subTree.type = PGEX_PlainText; - subTree.data.push_back(dataItem); - dataTree.push_back(subTree); - valid = true; - } - } - - return true; -} - - -PGEFile::PGEX_Entry PGEFile::buildTree(PGESTRINGList &src_data, bool *_valid) -{ - PGEX_Entry entryData; - - bool valid = true; - for(pge_size_t q = 0; q < src_data.size(); q++) - { - if(IsSectionTitle(removeSpaces(src_data[q]))) - { - //Build and store subTree - PGESTRING nameOfTree = removeSpaces(src_data[q]); - PGESTRINGList rawSubTree; - q++; - for(; q < src_data.size() && src_data[q] != nameOfTree + "_END" ; q++) - { - rawSubTree.push_back(src_data[q]); - } - PGEX_Entry subTree = buildTree(rawSubTree, &valid); - if(valid) - { - //Store like subtree - subTree.name = nameOfTree; - entryData.subTree.push_back(subTree); - entryData.type = PGEX_Struct; - } - else - { - //Store like plain text - subTree.name = nameOfTree; - subTree.subTree.clear(); - subTree.type = PGEX_PlainText; - subTree.data.clear(); - - PGEX_Item dataItem; - PGEX_Val dataValue; - dataItem.type = PGEX_PlainText; - - dataValue.marker = nameOfTree; - //foreach(PGESTRING x, rawSubTree) dataValue.value += x+"\n"; - for(pge_size_t i = 0; i < rawSubTree.size(); i++) - dataValue.value += rawSubTree[i] + "\n"; - dataItem.values.push_back(dataValue); - subTree.data.push_back(dataItem); - entryData.subTree.push_back(subTree); - entryData.type = PGEX_Struct; - valid = true; - } - - } - else - { - PGEX_Item dataItem; - PGESTRING &srcData_nc = src_data[q]; - enum States - { - STATE_MARKER = 0, - STATE_VALUE = 1, - STATE_ERROR = 2 - }; - pge_size_t state = 0, size = srcData_nc.size(), tail = srcData_nc.size() - 1; - PGEX_Val dataValue; - int escape = 0; - for(pge_size_t i = 0; i < size; i++) - { - if(state == STATE_ERROR) - { - valid = false; - break; - } - PGEChar c = srcData_nc[i]; - if(escape > 0) - { - escape--; - } - if((c == '\\') && (escape == 0)) - { - //Skip escape sequence - escape = 2; - } - switch(state) - { - case STATE_MARKER: - if((c == ';') && (escape == 0)) - { - state = STATE_ERROR; - continue; - } - if((c == ':') && (escape == 0)) - { - state = STATE_VALUE; - continue; - } - dataValue.marker.push_back(c); - break; - case STATE_VALUE: - if((c == ':') && (escape == 0)) - { - state = STATE_ERROR; - continue; - } - if(((c == ';') && (escape == 0)) || (i == tail)) - { - //STORE DATA - dataItem.values.push_back(dataValue); - dataValue.marker.clear(); - dataValue.value.clear(); - state = STATE_MARKER; - continue; - } - dataValue.value.push_back(c); - break; - //case STATE_ERROR: //Dead code - //break; - } - } - dataItem.type = PGEX_Struct; - entryData.type = PGEX_Struct; - entryData.data.push_back(dataItem); - // PGE_SPLITSTRING(fields, srcData_nc, ";"); - // PGEX_Item dataItem; - // dataItem.type = PGEX_Struct; - // for(int i=0;i<(signed)fields.size(); i++) - // { - // PGESTRING fields_ns = removeSpaces(fields[i]); - // if(IsEmpty(fields_ns)) continue; - - // //Store data into list - // PGESTRINGList value; - // PGE_SPLITSTRING(value, fields[i], ":"); - - // if( value.size() != 2 ) - // { - // valid = false; break; - // } - - // PGEX_Val dataValue; - // dataValue.marker = value[0]; - // dataValue.value = value[1]; - // dataItem.values.push_back(dataValue); - // } - // entryData.type = PGEX_Struct; - // entryData.data.push_back(dataItem); - } - if(!valid) break; - } - - if(_valid) *_valid = valid; - return entryData; -} - - - -PGESTRING PGEFile::lastError() -{ - return m_lastError; -} - - -bool PGEFile::IsSectionTitle(PGESTRING in) -{ - for(pge_size_t i = 0; i < in.size(); i++) - { - #ifdef PGE_FILES_QT - char cc = in[i].toLatin1(); - #else - char &cc = in[i]; - #endif - if( - ((cc < 'A') || (cc > 'Z')) && - ((cc < '0') || (cc > '9')) && - (cc != '_') - ) - return false; - } - return true; -} - - -//validatos -bool PGEFile::IsQoutedString(PGESTRING in) // QUOTED STRING -{ - //return QRegExp("^\"(?:[^\"\\\\]|\\\\.)*\"$").exactMatch(in); - pge_size_t i = 0; - bool escape = false; - for(i = 0; i < in.size(); i++) - { - if(i == 0) - { - if(in[i] != '"') - return false; - } - else if(i == in.size() - 1) - { - if((in[i] != '"') || escape) - return false; - } - else if((in[i] == '\\') && !escape) - { - escape = true; - continue; - } - else if((in[i] == '"') && !escape) - { - return false; - } - else if((in[i] == '"') && !escape) - { - return false; - } - escape = false; - } - if(i == 0) return false; - return true; -} - -bool PGEFile::IsHex(PGESTRING in) // Heximal string -{ - using namespace PGEExtendedFormat; - return isValid(in, heximal_valid_chars, heximal_valid_chars_len); -} - -bool PGEFile::IsBool(PGESTRING in) // Boolean -{ - if((in.size() != 1) || (IsEmpty(in))) - return false; - return ((PGEGetChar(in[0]) == '1') || (PGEGetChar(in[0]) == '0')); -} - -bool PGEFile::IsIntU(PGESTRING in) // Unsigned Int -{ - using namespace PGEExtendedFormat; - #ifdef PGE_FILES_QT - PGEChar *data = in.data(); - #else - PGEChar *data = (char *)in.data(); - #endif - pge_size_t strSize = in.size(); - for(pge_size_t i = 0; i < strSize; i++) - { - PGEChar c = *data++; - if((c < '0') || (c > '9')) return false; - } - return true; -} - -bool PGEFile::IsIntS(PGESTRING in) // Signed Int -{ - using namespace PGEExtendedFormat; - - if(IsEmpty(in)) return false; - - if((in.size() == 1) && (!isDegit(in[0]))) return false; - if((!isDegit(in[0])) && (PGEGetChar(in[0]) != '-')) return false; - - #ifdef PGE_FILES_QT - PGEChar *data = in.data() + 1; - #else - PGEChar *data = (char *)in.data() + 1; - #endif - pge_size_t strSize = in.size(); - for(pge_size_t i = 1; i < strSize; i++) - { - PGEChar c = *data++; - if((c < '0') || (c > '9')) return false; - } - - return true; -} - -bool PGEFile::IsFloat(PGESTRING &in) // Float Point numeric -{ - using namespace PGEExtendedFormat; - - if(IsEmpty(in)) - return false; - - if((in.size() == 1) && (!isDegit(in[0]))) - return false; - if((!isDegit(in[0])) && (PGEGetChar(in[0]) != '-') && (PGEGetChar(in[0]) != '.') && (PGEGetChar(in[0]) != ',')) - return false; - - bool decimal = false; - bool pow10 = false; - bool sign = false; - for(pge_size_t i = ((PGEGetChar(in[0]) == '-') ? 1 : 0); i < in.size(); i++) - { - if((!decimal) && (!pow10)) - { - if((PGEGetChar(in[i]) == '.') || (PGEGetChar(in[i]) == ',')) - { - in[i] = '.'; //replace comma with a dot - decimal = true; - if(i == (in.size() - 1)) - return false; - continue; - } - } - if(!pow10) - { - if((PGEGetChar(in[i]) == 'E') || (PGEGetChar(in[i]) == 'e')) - { - pow10 = true; - if(i == (in.size() - 1)) return false; - continue; - } - } - else - { - if(!sign) - { - sign = true; - if((PGEGetChar(in[i]) == '+') || (PGEGetChar(in[i]) == '-')) - { - if(i == (in.size() - 1)) - return false; - continue; - } - } - } - if(!isDegit(in[i])) return false; - } - - return true; -} - -bool PGEFile::IsBoolArray(PGESTRING in) // Boolean array -{ - using namespace PGEExtendedFormat; - return isValid(in, "01", 2); -} - -bool PGEFile::IsIntArray(PGESTRING in) // Boolean array -{ - using namespace PGEExtendedFormat; - #ifdef PGE_FILES_QT - return QRegExp("^\\[(\\-?\\d+,?)*\\]$").exactMatch(in); - #else - //FIXME - std::regex rx("^\\[(\\-?\\d+,?)*\\]$"); - return std::regex_match(in, rx); - #endif -} - -bool PGEFile::IsStringArray(PGESTRING in) // String array -{ - bool valid = true; - pge_size_t i = 0, depth = 0, comma = 0; - bool escape = false; - while(i < in.size()) - { - switch(depth) - { - case 0://outside array - if(in[i] == '[') - { - depth = 1; - comma++; - } - else valid = false; - break; - case 1://between entries - switch(comma) - { - case 0: - if(in[i] == ']') depth = 0; //Close array - else if(in[i] == ',') comma++; //Close array - else valid = false; - break; - case 1: - if(in[i] == '"') depth = 2; //Open value - else valid = false; - } - break; - case 2://Inside entry - if((in[i] == '"') && (!escape)) - { - depth = 1; //Close value - comma = 0; - } - else if((in[i] == '[') && (!escape)) - { - valid = false; - } - else if((in[i] == ']') && (!escape)) - { - valid = false; - } - else if((in[i] == ',') && (!escape)) - { - valid = false; - } - else if((in[i] == '\\') && (!escape)) - { - escape = true; - break; - } - escape = false; - break; - } - if(!valid) break;//Stop parsing on invalid - i++; - } - return valid; -} - - -PGESTRINGList PGEFile::X2STRArr(PGESTRING in, bool *_valid) -{ - PGESTRINGList strArr; - PGESTRING entry; - bool valid = true; - pge_size_t i = 0, depth = 0, comma = 0; - bool escape = false; - while(i < in.size()) - { - switch(depth) - { - case 0://outside array - if(in[i] == '[') - { - depth = 1; - comma++; - } - else valid = false; - break; - case 1://between entries - switch(comma) - { - case 0: - if(in[i] == ']') depth = 0; //Close array - else if(in[i] == ',') comma++; //Close array - else valid = false; - break; - case 1: - if(in[i] == '"') depth = 2; //Open value - else valid = false; - } - break; - case 2://Inside entry - if((in[i] == '"') && (!escape)) - { - strArr.push_back(X2STRING(entry)); //Close value - entry.clear(); - depth = 1; - comma = 0; - } - else if((in[i] == '[') && (!escape)) - { - valid = false; - break; - } - else if((in[i] == ']') && (!escape)) - { - valid = false; - break; - } - else if((in[i] == ',') && (!escape)) - { - valid = false; - break; - } - else if((in[i] == '\\') && (!escape)) - { - escape = true; - break; - } - entry.push_back(in[i]); - escape = false; - break; - } - if(!valid) break;//Stop parsing on invalid - i++; - } - if(_valid) *_valid = valid; - return strArr; -} - -PGELIST PGEFile::X2BollArr(PGESTRING src) -{ - PGELIST arr; - for(pge_size_t i = 0; i < src.size(); i++) - arr.push_back(src[i] == '1'); - return arr; -} - -PGELIST PGEFile::splitDataLine(PGESTRING src_data, bool *_valid) -{ - PGELIST entryData; - bool valid = true; - enum States - { - STATE_MARKER = 0, - STATE_VALUE = 1, - STATE_ERROR = 2 - }; - pge_size_t state = 0, size = src_data.size(), tail = src_data.size() - 1; - PGESTRING marker; - PGESTRING value; - int escape = 0; - for(pge_size_t i = 0; i < size; i++) - { - if(state == STATE_ERROR) - { - valid = false; - break; - } - PGEChar c = src_data[i]; - if(escape > 0) - { - escape--; - } - if((c == '\\') && (escape == 0)) - { - //Skip escape sequence - escape = 2; - } - switch(state) - { - case STATE_MARKER: - if((c == ';') && (escape == 0)) - { - state = STATE_ERROR; - continue; - } - if((c == ':') && (escape == 0)) - { - state = STATE_VALUE; - continue; - } - marker.push_back(c); - break; - case STATE_VALUE: - if((c == ':') && (escape == 0)) - { - state = STATE_ERROR; - continue; - } - if(((c == ';') && (escape == 0)) || (i == tail)) - { - //STORE ENTRY! - PGESTRINGList fields; - fields.push_back(marker); - fields.push_back(value); - entryData.push_back(fields); - marker.clear(); - value.clear(); - state = STATE_MARKER; - continue; - } - value.push_back(c); - break; - //case STATE_ERROR: //Dead code - //break; - } - } - if(_valid) * _valid = valid; - return entryData; -} - -PGESTRING PGEFile::hStrS(PGESTRING input) -{ - return PGEGetChar(input); -} - -PGESTRING PGEFile::WriteStrArr(PGESTRINGList &input) -{ - PGESTRING output; - if(IsEmpty(input)) - return PGESTRING(""); - output.append("["); - for(pge_size_t i = 0; i < input.size(); i++) - { - output.append(WriteStr(input[i])); - output.append(i < input.size() - 1 ? "," : ""); - } - output.append("]"); - return output; -} - -PGESTRING PGEFile::WriteIntArr(PGELIST input) -{ - PGESTRING output; - if(input.empty()) return PGESTRING(""); - output.append("["); - for(pge_size_t i = 0; i < input.size(); i++) - { - output.append(fromNum(input[i]) + (i < input.size() - 1 ? "," : "")); - } - output.append("]"); - return output; -} - -PGESTRING PGEFile::WriteBoolArr(PGELIST input) -{ - PGESTRING output; - for(pge_size_t i = 0; i < input.size(); i++) - { - output.append(input[i] ? "1" : "0"); - } - return output; -} - -PGESTRING PGEFile::X2STRING(PGESTRING input) -{ - restoreString(input, true); - return input; -} - -void PGEFile::restoreString(PGESTRING &input, bool removeQuotes) -{ - PGESTRING &output = input; - const pge_size_t first = 0;//For convenience to understand - pge_size_t j = 0, size = input.size(), tail = input.size() - 1; - for(pge_size_t i = 0; i < size; i++, j++) - { - if(removeQuotes && ((i == first) || (i == tail))) - { -ReCheckQuotie: - //Skip quotie character at begin/end - if(input[i] == '\"') - { - i++; - if(i == tail) goto ReCheckQuotie; - } - if(i >= size) - break; - } - if(input[i] == '\\') - { - pge_size_t k = i + 1; - if(k >= size) - { - output[j] = '\\'; - continue; - } - char c = PGEGetChar(input[k]); - switch(c) - { - case 'n': - output[j] = '\n'; - i++; - break; - case 'r': - output[j] = '\r'; - i++; - break; - case '\"': - output[j] = '\"'; - i++; - break; - case ';': - output[j] = ';'; - i++; - break; - case ':': - output[j] = ':'; - i++; - break; - case '[': - output[j] = '['; - i++; - break; - case ']': - output[j] = ']'; - i++; - break; - case ',': - output[j] = ','; - i++; - break; - case '%': - output[j] = '%'; - i++; - break; - case '\\': - output[j] = '\\'; - i++; - break; - default: - output[j++] = input[i]; - output[j] = input[k]; - i++; - break; - } - } - else - { - output[j] = input[i]; - } - } - output.resize(j); -} - -void PGEFile::escapeString(PGESTRING &output, const PGESTRING &input, bool addQuotes) -{ - pge_size_t j = 0, size = input.size(); - output.resize(size * 2 + (addQuotes ? 2 : 0)); - if(addQuotes) - output[j++] = '\"'; - for(pge_size_t i = 0; i < size; i++, j++) - { - char c = PGEGetChar(input[i]); - switch(c) - { - case '\n': - output[j++] = '\\'; - output[j] = 'n'; - break; - case '\r': - output[j++] = '\\'; - output[j] = 'r'; - break; - case '\"': - output[j++] = '\\'; - output[j] = '\"'; - break; - case ';': - output[j++] = '\\'; - output[j] = ';'; - break; - case ':': - output[j++] = '\\'; - output[j] = ':'; - break; - case '[': - output[j++] = '\\'; - output[j] = '['; - break; - case ']': - output[j++] = '\\'; - output[j] = ']'; - break; - case ',': - output[j++] = '\\'; - output[j] = ','; - break; - case '%': - output[j++] = '\\'; - output[j] = '%'; - break; - case '\\': - output[j++] = '\\'; - output[j] = '\\'; - break; - default: - output[j] = input[i]; - break; - } - } - if(addQuotes) - output[j++] = '\"'; - output.resize(j); -} - diff --git a/LunaDll/libs/PGE_File_Formats/pge_x.h b/LunaDll/libs/PGE_File_Formats/pge_x.h deleted file mode 100644 index 2a43aad2e..000000000 --- a/LunaDll/libs/PGE_File_Formats/pge_x.h +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/*! \file pge_x.h - * - * \brief Contains PGE-X Format worker class allows to parse, generate and validate PGE-X based files - * - */ - -#pragma once -#ifndef PGE_X_H -#define PGE_X_H - -#include "pge_file_lib_globs.h" - -/*! - * \brief Container of raw PGE-X data section - */ -typedef PGEPAIR PGEXSct; - -/*! - * \brief Provides parsing, generation and validating tools for PGE-X baded file formats such as LVLX, WLDX, SAVX and many other - */ -#ifdef PGE_FILES_QT -class PGEFile: PGE_FILES_INHERED -{ - Q_OBJECT -#else -class PGEFile -{ -#endif - - public: - /*! - * \brief Defines type of section or sub-section type of items - */ - enum PGEX_Item_type - { - //! Structured data - PGEX_Struct = 0, - //! Any random plain text data - PGEX_PlainText - }; - - /*! - * \brief PGE-X Encoded Item field - */ - struct PGEX_Val - { - //! Name of the entry field - PGESTRING marker; - //! Encoded value of the entry field - PGESTRING value; - }; - - /*! - * \brief PGE-X Data Item - */ - struct PGEX_Item - { - //! Type of entry - PGEX_Item_type type; - //! List of available values - PGELIST values; - }; - - /*! - * \brief PGE-X Data tree branch - */ - struct PGEX_Entry - { - //! Name of branch - PGESTRING name; - //! Type of contained items - PGEX_Item_type type; - //! List of contained items except subtrees - PGELIST data; - //! List of contained sub-branches - PGELIST subTree; - }; - -#ifdef PGE_FILES_QT - /*! - * \brief QObject-based constructor Constructor - * \param parent Parent QObject - */ - PGEFile(QObject *parent = NULL); - /*! - * \brief QObject-based constructor copy Constructor - * \param pgeFile Another PGEFile object - * \param parent Parent QObject - */ - PGEFile(const PGEFile &pgeFile, QObject *parent = NULL); -#else - /*! - * \brief Constructor - */ - PGEFile(); - /*! - * \brief Copy Constructor - * \param pgeFile Another PGEFile object - */ - PGEFile(const PGEFile& pgeFile); -#endif - /*! - * \brief Constructor with pre-storing of raw data - * \param _rawData - */ - PGEFile(const PGESTRING &_rawData); - /*! - * \brief Stores raw data string - * \param _rawData String contains raw data of entire file - */ - void setRawData(const PGESTRING& _rawData); - /*! - * \brief Parses stored raw data into the data tree - * \return - */ - bool buildTreeFromRaw(); - /*! - * \brief Returns last occouped error - * \return Last occouped error - */ - PGESTRING lastError(); - - //! Full data tree of all parsed data - PGELIST dataTree; - - private: - //! Last occouped error - PGESTRING m_lastError; - //! Stored raw data set - PGESTRING m_rawData; - //! Unparsed data separated to their data sections - PGELIST m_rawDataTree; - - //Static functions - public: - /*! - * \brief Builds a branch of PGE-X data tree - * \param List of raw data lines - * \param _valid given value will accept 'true' if everything is fine or false if error was occouped - * \return Parsed PGE-X tree branch - */ - static PGEX_Entry buildTree(PGESTRINGList &src_data, bool *_valid = 0); - - - // /////////////Validators/////////////// - /*! - * \brief Validates title of data section - * \param in Input string which would be a title of the data section - * \return True if data section title is valid - */ - static bool IsSectionTitle(PGESTRING in); - - /*! - * \brief Is given value is a quoted string? - * \param in Input data string with data required to valitade - * \return true if given value is passed or false if value is invalid - */ - static bool IsQoutedString(PGESTRING in);// QUOTED STRING - /*! - * \brief Is given value is a heximal number? - * \param in Input data string with data required to valitade - * \return true if given value is passed or false if value is invalid - */ - static bool IsHex(PGESTRING in);// Hex Encoded String - /*! - * \brief Is given value is an unsigned integer number? - * \param in Input data string with data required to valitade - * \return true if given value is passed or false if value is invalid - */ - static bool IsIntU(PGESTRING in);// UNSIGNED INT - /*! - * \brief Is given value is a signed integer number? - * \param in Input data string with data required to valitade - * \return true if given value is passed or false if value is invalid - */ - static bool IsIntS(PGESTRING in);// SIGNED INT - /*! - * \brief Is given value is a floating point number? - * \param in Input data string with data required to valitade - * \return true if given value is passed or false if value is invalid - */ - static bool IsFloat(PGESTRING &in);// FLOAT - /*! - * \brief Is given value is a boolean degit? - * \param in Input data string with data required to valitade - * \return true if given value is passed or false if value is invalid - */ - static bool IsBool(PGESTRING in);//BOOL - /*! - * \brief Is given value is a boolean array (string contains 0 or 1 degits only)? - * \param in Input data string with data required to valitade - * \return true if given value is passed or false if value is invalid - */ - static bool IsBoolArray(PGESTRING in);//Boolean array - /*! - * \brief Is given value is an integer array? - * \param in Input data string with data required to valitade - * \return true if given value is passed or false if value is invalid - */ - static bool IsIntArray(PGESTRING in);//Integer array - /*! - * \brief Is given value is a string array? - * \param in Input data string with data required to valitade - * \return true if given value is passed or false if value is invalid - */ - static bool IsStringArray(PGESTRING in);//String array - - //Split string into data values - static PGELIST splitDataLine(PGESTRING src_data, bool *valid = 0); - - //PGE Extended File parameter string generators - /*! - * \brief Encode integer numeric value into PGE-X string - * \param input signed or unsigned integer - * \return Encoded PGE-X raw string - */ - template - static inline PGESTRING WriteInt(T &input) - { - return fromNum(input); - } - /*! - * \brief Encode floating point numeric value with rounding into PGE-X string - * \param input floating point number - * \return Encoded PGE-X raw string - */ - template - static inline PGESTRING WriteRoundFloat(T &input) - { - return fromNum(std::round(input)); - } - /*! - * \brief Encode boolean value into PGE-X string - * \param input boolean flag - * \return Encoded PGE-X raw string - */ - static inline PGESTRING WriteBool(bool &input) - { - return PGESTRING((input) ? "1" : "0"); - } - - /*! - * \brief Encode floating point numeric value into PGE-X string - * \param input floating point number - * \return Encoded PGE-X raw string - */ - template - static PGESTRING WriteFloat(T &input) - { - return fromNum(input); - } - - /*! - * \brief Encode string into PGE-X escaped string - * \param input Plain text string - * \return Encoded PGE-X raw string - */ - static inline PGESTRING WriteStr(PGESTRING &input) - { - PGESTRING output; - escapeString(output, input, true); - return output; - } - static inline PGESTRING WriteStr(const char *input) - { - PGESTRING in(input); - PGESTRING output; - escapeString(output, in, true); - return output; - } - /*! - * \brief [WIP] This function must encode string into heximal line - * \param input Plain text string - * \return Encoded PGE-X raw string - */ - static PGESTRING hStrS(PGESTRING input); - /*! - * \brief Encode string-array into PGE-X escaped string - * \param input List of plain text strings - * \return Encoded PGE-X raw string - */ - static PGESTRING WriteStrArr(PGESTRINGList &input); - /*! - * \brief Encode array of integers into PGE-X escaped string - * \param input List of integer numbers - * \return Encoded PGE-X raw string - */ - static PGESTRING WriteIntArr(PGELIST input); - /*! - * \brief Encode array of booleans into PGE-X escaped string - * \param input List of boolean flags - * \return Encoded PGE-X raw string - */ - static PGESTRING WriteBoolArr(PGELIST input); - - /*! - * \brief Decodes PGE-X string into plain text string - * \param input Encoded PGE-X string value - * \return Plain text string - */ - static PGESTRING X2STRING(PGESTRING input); - /*! - * \brief Decodes PGE-X String array into array of plain text strings - * \param src Encoded PGE-X string value - * \return List of plain text strings - */ - static PGESTRINGList X2STRArr(PGESTRING in, bool *_valid = NULL); - /*! - * \brief Decodes PGE-X Boolean array into array of boolean flags - * \param src Encoded PGE-X boolean array - * \return List of boolean flags - */ - static PGELIST X2BollArr(PGESTRING src); - - /*! - * \brief Applies PGE-X escape sequensions to the plain text string - * \param [__out] output Target string where result will be recorded - * \param [__in] input plain text string - * \param [__in] addQuotes adds quotes to begin and end of the output string - */ - static void escapeString(PGESTRING &output, const PGESTRING &input, bool addQuotes = false); - /*! - * \brief Decodes PGE-X escape-sequensions - * \param [__inout] input Plain text string with applied escape sequensions - */ - static void restoreString(PGESTRING &input, bool removeQuotes = false); - - /*! - * \brief Builds PGE-X raw value with specific marker and raw data string - * \param marker Name of field - * \param data PGE-X raw string - * \return PGE-X Entry field - */ - static inline PGESTRING value(PGESTRING &&marker, PGESTRING &&data) - { - PGESTRING out; - out += marker + ":" + data + ";"; - return out; - } - - /*! - * \brief Removed double quites from begin and end of string if there are exists - * \param str Plain text string - * \return Plain text string with removed double quotes at begin and at end - */ - static PGESTRING removeQuotes(PGESTRING str); -}; - - -#endif // PGE_X_H diff --git a/LunaDll/libs/PGE_File_Formats/pge_x_macro.h b/LunaDll/libs/PGE_File_Formats/pge_x_macro.h deleted file mode 100644 index 82dad9965..000000000 --- a/LunaDll/libs/PGE_File_Formats/pge_x_macro.h +++ /dev/null @@ -1,155 +0,0 @@ -/*! - * \file pge_x_macro.h - * - * \brief Contains helper macroses for making PGE-X format based parsers - * - */ - -#pragma once -#ifndef PGE_X_MACRO_H -#define PGE_X_MACRO_H - -/*! \def PGEX_FileBegin() - \brief Placing at begin of the parsing function -*/ -#define PGEX_FileBegin() int str_count=0; /*Line Counter*/\ - PGESTRING line; /*Current Line data*/ - -/*! \def PGEX_FileParseTree(raw) - \brief Parse PGE-X Tree from raw data -*/ -#define PGEX_FileParseTree(raw) PGEFile pgeX_Data(raw);\ - if( !pgeX_Data.buildTreeFromRaw() )\ - {\ - errorString = pgeX_Data.lastError();\ - goto badfile;\ - } - -/*! \def PGEX_FetchSection() - \brief Prepare to fetch all data from specified section -*/ -#define PGEX_FetchSection() for(pge_size_t section=0; section < pgeX_Data.dataTree.size(); section++) -/*! \def PGEX_FetchSection_begin() - \brief Prepare to detect separate data of different sections -*/ -#define PGEX_FetchSection_begin() PGEFile::PGEX_Entry &f_section = pgeX_Data.dataTree[section];\ - if(IsEmpty(f_section.name)) continue; -/*! \def PGEX_Section(sct) - \brief Defines block of fields for section of specified name -*/ -#define PGEX_Section(sct) else if(f_section.name == sct) -/*! \def PGEX_SectionBegin(stype) - \brief Run syntax of raw data in this section for specified data type -*/ -#define PGEX_SectionBegin(stype) if(f_section.type != stype) \ -{ \ - errorString=PGESTRING("Wrong section data syntax:\nSection ["+f_section.name+"]");\ - goto badfile;\ -} -/*! \def PGEX_Items() - \brief Prepare to read items from this section -*/ -#define PGEX_Items() for(pge_size_t sdata = 0; sdata < f_section.data.size(); sdata++) -/*! \def PGEX_ItemBegin(stype) - \brief Declares block with a list of values -*/ -#define PGEX_ItemBegin(stype) if(f_section.data[sdata].type != stype) \ -{ \ - errorString=PGESTRING("Wrong data item syntax:\nSection ["+f_section.name+"]\nData line "+fromNum(sdata));\ - goto badfile;\ -}\ -PGEFile::PGEX_Item x = f_section.data[sdata]; - -/*! \def PGEX_Values() - \brief Declares block with a list of values -*/ -#define PGEX_Values() for(pge_size_t sval=0; sval < x.values.size(); sval++) -/*! \def PGEX_ValueBegin() - \brief Initializes getting of the values -*/ -#define PGEX_ValueBegin() PGEFile::PGEX_Val v = x.values[sval];\ - errorString=PGESTRING("Wrong value syntax\nSection ["+f_section.name+ \ - "]\nData line "+fromNum(sdata) \ - +"\nMarker "+v.marker+"\nValue "+v.value);\ - if(IsEmpty(v.marker)) continue; - -/*! \def PGEX_StrVal(Mark, targetValue) - \brief Parse Plain text string value by requested Marker and write into target variable -*/ -#define PGEX_StrVal(Mark, targetValue) else if(v.marker==Mark) { if(PGEFile::IsQoutedString(v.value)) \ - targetValue = PGEFile::X2STRING(v.value); \ - else goto badfile; } -/*! \def PGEX_StrArrVal(Mark, targetValue) - \brief Parse Plain text string array value by requested Marker and write into target variable -*/ -#define PGEX_StrArrVal(Mark, targetValue) else if(v.marker==Mark) { bool valid=false;\ - targetValue = PGEFile::X2STRArr(v.value, &valid); \ - if(!valid) goto badfile; } - -/*! \def PGEX_BoolVal(Mark, targetValue) - \brief Parse boolean flag value by requested Marker and write into target variable -*/ -#define PGEX_BoolVal(Mark, targetValue) if(v.marker==Mark) { if(PGEFile::IsBool(v.value)) \ - targetValue = static_cast(toInt(v.value));\ - else goto badfile; } - -/*! \def PGEX_BoolArrVal(Mark, targetValue) - \brief Parse boolean flags array value by requested Marker and write into target variable -*/ -#define PGEX_BoolArrVal(Mark, targetValue) else if(v.marker==Mark) { if(PGEFile::IsBoolArray(v.value)) \ - targetValue = PGEFile::X2BollArr(v.value); \ - else goto badfile; } - -/*! \def PGEX_UIntVal(Mark, targetValue) - \brief Parse unsigned integer value by requested Marker and write into target variable -*/ -#define PGEX_USIntVal(Mark, targetValue) if(v.marker==Mark) { if(PGEFile::IsIntU(v.value)) \ - targetValue = toInt(v.value);\ - else goto badfile; } - -/*! \def PGEX_UIntVal(Mark, targetValue) - \brief Parse unsigned integer value by requested Marker and write into target variable -*/ -#define PGEX_UIntVal(Mark, targetValue) if(v.marker==Mark) { if(PGEFile::IsIntU(v.value)) \ - targetValue = toUInt(v.value);\ - else goto badfile; } - -/*! \def PGEX_SIntVal(Mark, targetValue) - \brief Parse signed integer value by requested Marker and write into target variable -*/ -#define PGEX_SIntVal(Mark, targetValue) if(v.marker==Mark) { if(PGEFile::IsIntS(v.value)) \ - targetValue = toInt(v.value);\ - else goto badfile; } - -/*! \def PGEX_SLongVal(Mark, targetValue) - \brief Parse signed long integer value by requested Marker and write into target variable -*/ -#define PGEX_SLongVal(Mark, targetValue) if(v.marker==Mark) { if(PGEFile::IsIntS(v.value)) \ - targetValue = toLong(v.value);\ - else goto badfile; } - -/*! \def PGEX_ULongVal(Mark, targetValue) - \brief Parse unsigned long integer value by requested Marker and write into target variable -*/ -#define PGEX_ULongVal(Mark, targetValue) if(v.marker==Mark) { if(PGEFile::IsIntU(v.value)) \ - targetValue = toULong(v.value);\ - else goto badfile; } - -/*! \def PGEX_USLongVal(Mark, targetValue) - \brief Parse unsigned long integer value by requested Marker and write into target variable -*/ -#define PGEX_USLongVal(Mark, targetValue) if(v.marker==Mark) { if(PGEFile::IsIntU(v.value)) \ - targetValue = toLong(v.value);\ - else goto badfile; } - - -/*! \def PGEX_FloatVal(Mark, targetValue) - \brief Parse floating point value by requested Marker and write into target variable -*/ -#define PGEX_FloatVal(Mark, targetValue) if(v.marker==Mark) { if(PGEFile::IsFloat(v.value)) \ - targetValue = toDouble(v.value);\ - else goto badfile; } - - -#endif // PGE_X_MACRO_H - diff --git a/LunaDll/libs/PGE_File_Formats/save_filedata.cpp b/LunaDll/libs/PGE_File_Formats/save_filedata.cpp deleted file mode 100644 index 73b7f1ab2..000000000 --- a/LunaDll/libs/PGE_File_Formats/save_filedata.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "file_formats.h" - -//********************************************************* -//****************Sctructure initalizers******************* -//********************************************************* - -saveCharState FileFormats::CreateSavCharacterState() -{ - saveCharState newData; - - newData.id = 1; - newData.health = 0; - newData.itemID = 0; - newData.mountID = 0; - newData.mountType = 0; - newData.state = 1; - - return newData; -} - - -GamesaveData FileFormats::CreateGameSaveData() -{ - GamesaveData newData; - - newData.meta.RecentFormatVersion = 0; - - newData.lives = 3; - newData.coins = 0; - newData.points = 0; - newData.totalStars = 0; - - newData.last_hub_warp = 0; - - newData.musicID = 0; - newData.musicFile = ""; - - newData.worldPosX = 0; - newData.worldPosY = 0; - newData.gameCompleted = false; - - newData.characterStates.push_back(CreateSavCharacterState()); - newData.currentCharacter.push_back(1); - - return newData; -} diff --git a/LunaDll/libs/PGE_File_Formats/save_filedata.h b/LunaDll/libs/PGE_File_Formats/save_filedata.h deleted file mode 100644 index 4f08ebf2c..000000000 --- a/LunaDll/libs/PGE_File_Formats/save_filedata.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/*! - * \file save_filedata.h - * - * \brief Contains structure definitions for a game save data - * - */ - -#pragma once -#ifndef SAVE_FILEDATA_H -#define SAVE_FILEDATA_H - -#include "pge_file_lib_globs.h" -#include "meta_filedata.h" - -//! Game Save specific Visible element entry -typedef PGEPAIR visibleItem; -//! Game Save specific gotten star entry -typedef PGEPAIR starOnLevel; - -/*! - * \brief Recent state of each playable character - */ -struct saveCharState -{ - saveCharState() : id(1), state(1), itemID(0), mountType(0), mountID(0), health(1) {} - //! ID of playable character - unsigned long id; - //! Curent ID of playable character's state - unsigned long state; - //! Current item ID in the item slot (SMBX64-only) - unsigned long itemID; - //! Mounted vehicle type (SMBX64-only) - unsigned int mountType; - //! Mounted vehicle ID (SMBX64-only) - unsigned int mountID; - //! Recent health level - unsigned int health; -}; - -/*! - * \brief Recent playable character ID per player ID - */ -struct savePlayerState -{ - //! ID of playable character - int characterID; -}; - -/*! - * \brief Game save data structure - */ -struct GamesaveData -{ - //! Helper meta-data - FileFormatMeta meta; - - int lives; //!< Number of lives - unsigned int coins; //!< Number of coins - unsigned int points; //!< Number of points - unsigned int totalStars; //!< Total stars - - long worldPosX; //!< Last world map position X - long worldPosY; //!< Last world map position Y - - unsigned long last_hub_warp; //!< Last entered/exited warp Array-ID on the HUB-based episodes. - - unsigned int musicID; //!< Current world music ID - PGESTRING musicFile; //!< Current world music file (custom music) - - bool gameCompleted; //!< Is episode was completed in last time - - PGEVECTOR characterStates; - PGELIST currentCharacter; - - //Visible state of world map items - PGEVECTOR visibleLevels; - PGEVECTOR visiblePaths; - PGEVECTOR visibleScenery; - PGEVECTOR gottenStars; -}; - -#endif // SAVE_FILEDATA_H diff --git a/LunaDll/libs/PGE_File_Formats/smbx38a_private.h b/LunaDll/libs/PGE_File_Formats/smbx38a_private.h deleted file mode 100644 index a7cda67db..000000000 --- a/LunaDll/libs/PGE_File_Formats/smbx38a_private.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once -#ifndef SMBX38A_PRIVATE_H -#define SMBX38A_PRIVATE_H - -#include -#include "smbx64.h" -#include "smbx64_macro.h" -#include "CSVReaderPGE.h" -#include "CSVUtils.h" -#include "pge_ff_units.h" - -using namespace CSVReader; - -extern const int SMBX38A_NpcGeneratorTypes[29]; -extern const int SMBX38A_NpcGeneratorDirections[29]; - -//for Header readers. -//Use it if you want read file partially -//(you must create QTextStream in(&fstream); !!!) -#define SMBX38A_FileBegin() int file_format=0; /*File format number*/\ - PGESTRING line; /*Current Line data*/ -#define SMBX38A_FileBeginN() /*int file_format=0;*/ /*File format number*/\ - PGESTRING line; /*Current Line data*/ - -#if !defined(_MSC_VER) || _MSC_VER > 1800 -#define ReadSMBX38Level ReadSMBX38ALvlFile -#else -#define ReadSMBX38Level ReadSMBX38ALvlFile_OLD -#endif - -//Jump to next line -#ifdef nextLine -#undef nextLine -#endif -#define nextLine() line = in.readLine(); - -// Common functions -static auto PGEUrlDecodeFunc = [](PGESTRING &data) -{ - data = PGE_URLDEC(data); -}; -static auto PGEBase64DecodeFunc = [](PGESTRING &data) -{ - data = PGE_BASE64DEC(data); -}; -static auto PGEBase64DecodeFuncA = [](PGESTRING &data) -{ - data = PGE_BASE64DEC_A(data); -}; -static auto PGELayerOrDefault = [](PGESTRING &data) -{ - data = (data == "" ? "Default" : PGE_URLDEC(data)); -}; -static auto PGEFilpBool = [](bool &value) -{ - value = !value; -}; - -template -constexpr std::function MakeMinFunc(T min) -{ - return [ = ](T & value) - { - if(value < min) - value = min; - }; -} - -/*! - * \brief Converts floating point number value from the expression field. - * \param [__inout] expression Expression field. Clears if valid floating point number has been detected - * \param [__out] target Target value - */ -inline void SMBX38A_Exp2Float(PGESTRING &expression, float &target) -{ - if(!SMBX64::IsFloat(expression)) - target = 0.0f; - else - { - target = toFloat(expression); - expression.clear(); - } -} - -/*! - * \brief Converts floating point number value from the expression field. - * \param [__inout] expression Expression field. Clears if valid floating point number has been detected - * \param [__out] target Target value - */ -inline void SMBX38A_Exp2Double(PGESTRING &expression, double &target) -{ - if(!SMBX64::IsFloat(expression)) - target = 0.0; - else - { - target = toDouble(expression); - expression.clear(); - } -} - - -/*! - * \brief Converts integer value from the expression field (with rounding possible floating point number value). - * \param [__inout] expression Expression field. Clears if valid floating point number has been detected - * \param [__out] target Target value - */ -template -inline void SMBX38A_Exp2Int(PGESTRING &expression, T &target) -{ - if(!SMBX64::IsFloat(expression)) - target = 0; - else - { - target = static_cast(round(toDouble(expression))); - expression.clear(); - } -} - -template -inline void SMBX38A_Num2Exp(T source, PGESTRING &expression) -{ - if(IsEmpty(expression)) - expression = fromNum(source); -} - -template -inline void SMBX38A_Num2Exp_URLEN(T source, PGESTRING &expression) -{ - if(IsEmpty(expression)) - expression = fromNum(source); - else - expression = PGE_URLENC(expression); -} - -template -inline void SMBX38A_mapBGID_From(T &bgID) -{ - if(bgID == 2) - bgID = 13; - else if((bgID >= 3) && (bgID <= 13)) - bgID -= 1; -} - -template -inline T SMBX38A_mapBGID_To(T bgID) -{ - if(bgID == 13) - bgID = 2; - else if((bgID >= 2) && (bgID <= 12)) - bgID += 1; - - return bgID; -} - -template -inline void SMBX38A_RestoreOrigTime(NumT &orig, const NumT &cur, PGE_FileLibrary::TimeUnit unit) -{ - NumT value = PGE_FileLibrary::TimeUnitsCVT(orig, - PGE_FileLibrary::TimeUnit::FrameOneOf65sec, - unit); - if(value != cur) - orig = PGE_FileLibrary::TimeUnitsCVT(cur, - unit, - PGE_FileLibrary::TimeUnit::FrameOneOf65sec); -} - -static inline void SMBX38A_CC_decode(int32_t &destKey, int64_t &destValue, const PGESTRING &key) -{ - if(IsEmpty(key) || (key.size() < 4)) - { - destKey = 0; - destValue = 0; - } - #ifdef PGE_FILES_QT - std::string skey = key.toStdString(); - #else - const std::string &skey = key; - #endif - std::string k = skey.substr(0, 4); - destKey = std::strtol(k.c_str(), NULL, 16); - - std::string v = skey.substr(4); - if(!v.empty()) - destValue = std::strtol(v.c_str(), NULL, 16); -} - -static inline PGESTRING SMBX38A_CC_encode(const int32_t &srcKey, const int64_t &srcValue) -{ - char keyBuf[6] = {0}; - char valueBuf[52] = {0}; - int kb_l = std::snprintf(keyBuf, 5, "%04X", (const unsigned int)srcKey); - keyBuf[kb_l] = '\0'; - int kv_l = std::snprintf(valueBuf, 51, "%X", (const unsigned int)srcValue); - valueBuf[kv_l] = '\0'; - #ifdef PGE_FILES_QT - return QString::fromUtf8(keyBuf, 4) + QString::fromUtf8(valueBuf, kv_l); - #else - return PGESTRING(keyBuf, 4) + PGESTRING(valueBuf, kv_l); - #endif -} - -#endif // SMBX38A_PRIVATE_H diff --git a/LunaDll/libs/PGE_File_Formats/smbx64.cpp b/LunaDll/libs/PGE_File_Formats/smbx64.cpp deleted file mode 100644 index bc969163a..000000000 --- a/LunaDll/libs/PGE_File_Formats/smbx64.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "smbx64.h" - -namespace smbx64Format -{ - //const char *uint_vc = "0123456789"; - //const int uint_vc_len = 10; - - bool isDegit(PGEChar c) - { - return ((c >= '0') && (c <= '9')); - } - - bool isValid(PGESTRING &s, const char *valid_chars, const pge_size_t &valid_chars_len) - { - if(IsEmpty(s)) return false; - pge_size_t i, j; - for(i = 0; i < s.size(); i++) - { - bool found = false; - for(j = 0; j < valid_chars_len; j++) - { - if(PGEGetChar(s[i]) == valid_chars[j]) - { - found = true; - break; - } - } - if(!found) return false; - } - return true; - } -} - -// /////////////Validators/////////////// -//returns FALSE on wrong data - -bool SMBX64::IsUInt(PGESTRING in) // UNSIGNED INT -{ - using namespace smbx64Format; - #ifdef PGE_FILES_QT - PGEChar *data = in.data(); - #else - PGEChar *data = (char *)in.data(); - #endif - pge_size_t strSize = in.size(); - for(pge_size_t i = 0; i < strSize; i++) - { - PGEChar c = *data++; - if((c < '0') || (c > '9')) return false; - } - return true; -} - -bool SMBX64::IsSInt(PGESTRING in) // SIGNED INT -{ - using namespace smbx64Format; - if(IsEmpty(in)) return false; - - if((in.size() == 1) && (!isDegit(in[0]))) return false; - if((!isDegit(in[0])) && (PGEGetChar(in[0]) != '-')) return false; - - #ifdef PGE_FILES_QT - PGEChar *data = in.data() + 1; - #else - PGEChar *data = (char *)in.data() + 1; - #endif - pge_size_t strSize = in.size(); - for(pge_size_t i = 1; i < strSize; i++) - { - PGEChar c = *data++; - if((c < '0') || (c > '9')) return false; - } - - return true; -} - -bool SMBX64::IsFloat(PGESTRING &in) // SIGNED FLOAT -{ - using namespace smbx64Format; - - if(IsEmpty(in)) return true; - - if((in.size() == 1) && (!isDegit(in[0]))) return false; - if((!isDegit(in[0])) && (PGEGetChar(in[0]) != '-') && (PGEGetChar(in[0]) != '.') && (PGEGetChar(in[0]) != ',')) return false; - - bool decimal = false; - bool pow10 = false; - bool sign = false; - for(pge_size_t i = ((PGEGetChar(in[0]) == '-') ? 1 : 0); i < in.size(); i++) - { - if((!decimal) && (!pow10)) - { - if((PGEGetChar(in[i]) == '.') || (PGEGetChar(in[i]) == ',')) - { - in[i] = '.'; //replace comma with a dot - decimal = true; - if(i == (in.size() - 1)) return false; - continue; - } - } - if(!pow10) - { - if((PGEGetChar(in[i]) == 'E') || (PGEGetChar(in[i]) == 'e')) - { - pow10 = true; - if(i == (in.size() - 1)) return false; - continue; - } - } - else - { - if(!sign) - { - sign = true; - if((PGEGetChar(in[i]) == '+') || (PGEGetChar(in[i]) == '-')) - { - if(i == (in.size() - 1)) return false; - continue; - } - } - } - if(!isDegit(in[i])) return false; - } - return true; -} - -bool SMBX64::IsQuotedString(PGESTRING in) -{ - //This is INVERTED validator. If false - good, true - bad. -#define QStrGOOD true -#define QStrBAD false - pge_size_t i = 0; - for(i = 0; i < in.size(); i++) - { - if(i == 0) - { - if(in[i] != '"') return QStrBAD; - } - else if(i == in.size() - 1) - { - if(in[i] != '"') return QStrBAD; - } - else if(in[i] == '"') return QStrBAD; - else if(in[i] == '"') return QStrBAD; - } - if(i == 0) return QStrBAD; //This is INVERTED validator. If false - good, true - bad. - return QStrGOOD; -} - diff --git a/LunaDll/libs/PGE_File_Formats/smbx64.h b/LunaDll/libs/PGE_File_Formats/smbx64.h deleted file mode 100644 index 9e7639994..000000000 --- a/LunaDll/libs/PGE_File_Formats/smbx64.h +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/*! \file smbx64.h - * \brief Contains static class with SMBX64 standard file format fields validation and generation functions - */ - -#pragma once -#ifndef SMBX64_H -#define SMBX64_H - -#include "pge_file_lib_globs.h" - -/*! - * \brief SMBX64 Standard validation and raw data conversion functions - */ -namespace SMBX64 -{ - /*******************Readers With Exception throwers********************/ - inline void ReadUInt(unsigned int*out, PGESTRING &input) - { - #ifdef PGE_FILES_QT - bool ok=true; - *out = input.toUInt(&ok); - if(!ok) throw std::invalid_argument("Could not convert to unsigned int"); - #else - *out = static_cast(std::stoul(input)); - #endif - } - - inline void ReadUInt(unsigned long*out, PGESTRING &input) - { - #ifdef PGE_FILES_QT - bool ok=true; - *out = input.toULong(&ok); - if(!ok) throw std::invalid_argument("Could not convert to unsigned long"); - #else - *out = std::stoul(input); - #endif - } - - inline void ReadUInt(unsigned long long*out, PGESTRING &input) - { - #ifdef PGE_FILES_QT - bool ok=true; - *out = input.toULongLong(&ok); - if(!ok) throw std::invalid_argument("Could not convert to unsigned long long"); - #else - *out = std::stoull(input); - #endif - } - inline void ReadUInt(int*out, PGESTRING &input) - { - #ifdef PGE_FILES_QT - bool ok=true; - *out = static_cast(input.toUInt(&ok)); - if(!ok) throw std::invalid_argument("Could not convert to unsigned int"); - #else - *out = static_cast(static_cast(std::stoul(input))); - #endif - } - inline void ReadUInt(long*out, PGESTRING &input) - { - #ifdef PGE_FILES_QT - bool ok=true; - *out = static_cast(input.toULong(&ok)); - if(!ok) throw std::invalid_argument("Could not convert to unsigned long"); - #else - *out = static_cast(std::stoul(input)); - #endif - } - inline void ReadUInt(long long*out, PGESTRING &input) - { - #ifdef PGE_FILES_QT - bool ok=true; - *out = static_cast(input.toULongLong(&ok)); - if(!ok) throw std::invalid_argument("Could not convert to unsigned long long"); - #else - *out = static_cast(std::stoull(input)); - #endif - } - - inline void ReadSInt(int*out, PGESTRING &input) - { - #ifdef PGE_FILES_QT - bool ok=true; - *out = input.toInt(&ok); - if(!ok) throw std::invalid_argument("Could not convert to int"); - #else - *out = std::stoi(input); - #endif - } - - inline void ReadSInt(long*out, PGESTRING &input) - { - #ifdef PGE_FILES_QT - bool ok=true; - *out = input.toLong(&ok); - if(!ok) throw std::invalid_argument("Could not convert to long"); - #else - *out = std::stol(input); - #endif - } - inline void ReadSInt(long long*out, PGESTRING &input) - { - #ifdef PGE_FILES_QT - bool ok=true; - *out = input.toLongLong(&ok); - if(!ok) throw std::invalid_argument("Could not convert to long long"); - #else - *out = std::stoll(input); - #endif - } - inline void ReadFloat(float*out, PGESTRING &input) - { - PGE_ReplSTRING(input, ",", ".");//Allow to parse floats of both comma and dot standard - #ifdef PGE_FILES_QT - bool ok=true; - *out = input.toFloat(&ok); - if(!ok) throw std::invalid_argument("Could not convert to Float"); - #else - *out = std::stof(input); - #endif - } - inline void ReadFloat(double*out, PGESTRING &input) - { - PGE_ReplSTRING(input, ",", ".");//Allow to parse floats of both comma and dot standard - #ifdef PGE_FILES_QT - bool ok=true; - *out = input.toDouble(&ok); - if(!ok) throw std::invalid_argument("Could not convert to Float"); - #else - *out = std::stod(input); - #endif - } - inline void ReadBool(bool*out, PGESTRING &input) - { - if(input == "0" || input == "") // FIXME: Is it correct? Or too hackish? - *out = false; - else if(input != "0") // FIXME: Is it correct? Or too hackish? - *out = true; - else - throw std::invalid_argument(std::string("Could not convert to bool (must be empty, \"0\", \"!0\" or \"1\")")); - } - - inline void ReadCSVBool(bool*out, PGESTRING &input) - { - if(input == "#FALSE#") - *out = false; - else if(input == "#TRUE#") - *out = true; - else if(input == "false") - *out = false; - else if(input == "true") - *out = true; - else if( input == "0" || input == "" ) - *out = false; - else if( input == "!0" || input == "1" ) - *out = true; - else - throw std::invalid_argument(std::string("Could not convert CSV Bool (must be #TRUE# or #FALSE#)")); - } - - inline void ReadCSVBool(int*out, PGESTRING &input) - { - if(input == "#FALSE#") - *out = 0; - else if(input == "#TRUE#") - *out = 1; - else if(input == "false") - *out = 0; - else if(input == "true") - *out = 1; - else if( input == "0" || input == "" ) - *out = 0; - else if( input == "!0" || input == "1" ) - *out = 1; - else - throw std::invalid_argument(std::string("Could not convert CSV Bool (must be #TRUE# or #FALSE#)")); - } - - inline void ReadCSVBool(long*out, PGESTRING &input) - { - if(input == "#FALSE#") - *out = 0; - else if(input == "#TRUE#") - *out = 1; - else if(input == "false") - *out = 0; - else if(input == "true") - *out = 1; - else if( input == "0" || input == "" ) - *out = 0; - else if( input == "!0" || input == "1" ) - *out = 1; - else - throw std::invalid_argument(std::string("Could not convert CSV Bool (must be #TRUE# or #FALSE#)")); - } - - inline void ReadSIntFromFloat(int*out, PGESTRING &input) - { - #ifdef PGE_FILES_QT - bool ok=true; - *out = qRound(input.toDouble(&ok)); - if(!ok) throw std::invalid_argument("Could not convert to Double"); - #else - *out = static_cast(std::round(std::stod(input))); - #endif - } - - inline void ReadSIntFromFloat(long*out, PGESTRING &input) - { - #ifdef PGE_FILES_QT - bool ok=true; - *out = static_cast(std::round(input.toDouble(&ok))); - if(!ok) throw std::invalid_argument("Could not convert to Double"); - #else - *out = static_cast(std::round(std::stod(input))); - #endif - } - inline void ReadStr(PGESTRING*out, PGESTRING &input) - { - if(IsEmpty(input)) - { - out->clear(); - return; - } - *out = input; - PGESTRING &target = *out; - if(target[0] == PGEChar('\"')) - PGE_RemStrRng(target, 0, 1); - if( (!IsEmpty(target)) && (target[target.size()-1] == PGEChar('\"')) ) - PGE_RemStrRng(target, target.size()-1, 1); - target = PGE_ReplSTRING(target, "\"", "\'");//Correct damaged by SMBX line - } - - - - - /*********************Validations**********************/ - /*! - * \brief Validate Unsigned Integer value - * \param in raw value - * \return true if value is valid - */ - bool IsUInt(PGESTRING in); - /*! - * \brief Validate Signed Integer value - * \param in raw value - * \return true if value is valid - */ - bool IsSInt(PGESTRING in); - /*! - * \brief Validate Floating Point value - * \param in raw value - * \return true if value is valid - */ - bool IsFloat(PGESTRING &in); - /*! - * \brief Validate quoted string value - * \param in raw value - * \return true if value is valid - */ - bool IsQuotedString(PGESTRING in); - /*! - * \brief Validate CSV-boolean value (#TRUE# or #FALSE#) - * \param in raw value - * \return true if value is INVALID - */ - inline bool IsCSVBool(PGESTRING in) //Worded BOOL - { - return ( (in=="#TRUE#")||(in=="#FALSE#") ); - } - - /*! - * \brief Validate digital boolean value (0 or 1) - * \param in raw value - * \return true if value is valid - */ - inline bool IsBool(PGESTRING in) //Digital BOOL - { - if((in.size()!=1) || (IsEmpty(in)) ) - return false; - return ((PGEGetChar(in[0])=='1')||(PGEGetChar(in[0])=='0')); - } - - /*! - * \brief Converts CVS-bool raw string into boolean value - * \param in raw value - * \return boolean equivalent - */ - inline bool wBoolR(PGESTRING in) - { return ((in=="#TRUE#")?true:false); } - - /******************RAW to Internal**********************/ - /*! - * \brief Convert from SMBX64 string to internal with damage correction - * \param in raw value - * \return fixed string vale - */ - inline PGESTRING StrToStr(PGESTRING in) - { - PGESTRING target = in; - if(IsEmpty(target)) - return target; - if(target[0]==PGEChar('\"')) - PGE_RemStrRng(target, 0, 1); - if((!IsEmpty(target)) && (target[target.size()-1]==PGEChar('\"'))) - PGE_RemStrRng(target, target.size()-1, 1); - target=PGE_ReplSTRING(target, "\"", "\'");//Correct damaged by SMBX line - return target; - } - - /******************Internal to RAW**********************/ - /*! - * \brief Generate raw string from integer value - * \param input Source signed integer value - * \return ASCII encoded signed integer value - */ - template - inline PGESTRING WriteSInt(T input) - { return fromNum(static_cast(input))+"\n"; } - - /*! - * \brief Generate raw string from unsigned integer value - * \param input Source unsigned integer value - * \return ASCII encoded unsigned integer value - */ - template - inline PGESTRING WriteUInt(T input) - { return fromNum(static_cast(input))+"\n"; } - - /*! - * \brief Generate raw CVS-bool string from boolean value - * \param input Source boolean value - * \return ASCII encoded CVS-bool value - */ - inline PGESTRING WriteCSVBool(bool input) - { return PGESTRING( (input)?"#TRUE#":"#FALSE#" )+"\n"; } - - /*! - * \brief Convert string into valid CVS string line (line feeds are will be removed) - * \param input Source string - * \return Valid CVS string - */ - inline PGESTRING WriteStr(PGESTRING input) - { - input = PGE_RemSubSTRING(input, "\n"); - input = PGE_RemSubSTRING(input, "\r"); - input = PGE_RemSubSTRING(input, "\t"); - input = PGE_RemSubSTRING(input, "\""); - return PGESTRING("\"")+input+PGESTRING("\"\n"); - } - - /*! - * \brief Convert string into valid CVS string line (with line feeds keeping) - * \param input Source string - * \return Valid CVS string - */ - inline PGESTRING WriteStr_multiline(PGESTRING input) - { - input = PGE_RemSubSTRING(input, "\t"); - input = PGE_ReplSTRING(input, "\"", "'"); - return PGESTRING("\"")+input+PGESTRING("\"\n"); - } - - /*! - * \brief Generate raw string from floating point value - * \param input Source floating point vale - * \return ASCII encoded floating point value - */ - inline PGESTRING WriteFloat(float input) - { return fromNum(input)+"\n"; } - - /*! - * \brief Generate raw string from double floating point value - * \param input Source floating point vale - * \return ASCII encoded floating point value - */ - inline PGESTRING WriteFloat(double input) - { return fromNum(input)+"\n"; } - - - /******************Units converters**********************/ - /*! - * \brief Convert 1/65 seconds into milliseconds - * \param t65 1/65 time value - * \return millisecond time equivalent - */ - inline double t65_to_ms(double t65) - { return t65 * (1000.0/65.0); } - - /*! - * \brief Convert milliseconds into 1/65 seconds - * \param ms time in milliseconds - * \return 1/65 second time equivalent - */ - inline double ms_to_65(double ms) - { return ms * (65.0/1000.0); } - -} - - -#endif // SMBX64_H - diff --git a/LunaDll/libs/PGE_File_Formats/smbx64_cnf_filedata.cpp b/LunaDll/libs/PGE_File_Formats/smbx64_cnf_filedata.cpp deleted file mode 100644 index 5944d3c78..000000000 --- a/LunaDll/libs/PGE_File_Formats/smbx64_cnf_filedata.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "smbx64_cnf_filedata.h" - -SMBX64_ConfigPlayer::SMBX64_ConfigPlayer() -{ - id = 0; - controllerType = 0; - k_up = 0; - k_down = 0; - k_left = 0; - k_right = 0; - k_run = 0; - k_jump = 0; - k_drop = 0; - k_pause = 0; - k_altjump = 0; //>=19 - k_altrun = 0; //>=19 - j_run = 0; - j_jump = 0; - j_drop = 0; - j_pause = 0; - j_altjump = 0; //>=19 - j_altrun = 0; //>=19 -} - - -SMBX64_ConfigFile::SMBX64_ConfigFile() -{ - fullScreen = false; -} diff --git a/LunaDll/libs/PGE_File_Formats/smbx64_cnf_filedata.h b/LunaDll/libs/PGE_File_Formats/smbx64_cnf_filedata.h deleted file mode 100644 index cadc88603..000000000 --- a/LunaDll/libs/PGE_File_Formats/smbx64_cnf_filedata.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/*! \file smbx64_cnf_filedata.h - * \brief Contains definition of SMBX Engine settings data structure - */ - -#pragma once -#ifndef SMBX64_CNF_FILEDATA_H -#define SMBX64_CNF_FILEDATA_H - -#include "pge_file_lib_globs.h" -#include "meta_filedata.h" - -struct SMBX64_ConfigPlayer -{ - SMBX64_ConfigPlayer(); - unsigned int id; - unsigned int controllerType; - unsigned int k_up; - unsigned int k_down; - unsigned int k_left; - unsigned int k_right; - unsigned int k_run; - unsigned int k_jump; - unsigned int k_drop; - unsigned int k_pause; - unsigned int k_altjump;//>=19 - unsigned int k_altrun;//>=19 - unsigned int j_run; - unsigned int j_jump; - unsigned int j_drop; - unsigned int j_pause; - unsigned int j_altjump;//>=19 - unsigned int j_altrun;//>=19 -}; - -struct SMBX64_ConfigFile -{ - SMBX64_ConfigFile(); - - //!Helper meta-data - FileFormatMeta meta; - - bool fullScreen;//>=16 - PGEVECTOR players; -}; - -#endif // SMBX64_CNF_FILEDATA_H diff --git a/LunaDll/libs/PGE_File_Formats/smbx64_macro.h b/LunaDll/libs/PGE_File_Formats/smbx64_macro.h deleted file mode 100644 index 4367df157..000000000 --- a/LunaDll/libs/PGE_File_Formats/smbx64_macro.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#ifndef SMBX64_MACRO_H -#define SMBX64_MACRO_H - -/*! \file smbx64_macro.h - * \brief Contains helper macroses for making SMBX64 Standard format based parsers - */ - -/* - Small set of macroses used to organize SMBX64 specific file read functions. -*/ - -//(you must create and open PGE_FileFormats_misc::TextInput ∈ !!!) -#define SMBX64_FileBegin() unsigned int file_format = 0; /*File format number*/\ - PGESTRING line; /*Current Line data*/ - -//Jump to next line -#define nextLine() line = in.readCVSLine(); - -//Version comparison -#define ge(v) file_format>=v -#define gt(v) file_format>v -#define le(v) file_format<=v -#define lt(v) file_format - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "file_formats.h" -#include "wld_filedata.h" - - -int FileFormats::smbx64WorldCheckLimits(WorldData &wld) -{ - int errorCode = 0; - - //Tiles limit - if(wld.tiles.size() > 20000) errorCode |= SMBX64EXC_TILES; - //Sceneries limit - if(wld.scenery.size() > 5000) errorCode |= SMBX64EXC_SCENERIES; - //Paths limit - if(wld.paths.size() > 2000) errorCode |= SMBX64EXC_PATHS; - //Levels limit - if(wld.levels.size() > 400) errorCode |= SMBX64EXC_LEVELS; - //Music boxes limit - if(wld.music.size() > 1000) errorCode |= SMBX64EXC_MUSICBOXES; - - return errorCode; -} - - -WorldTerrainTile FileFormats::CreateWldTile() -{ - return WorldTerrainTile(); -} - -WorldScenery FileFormats::CreateWldScenery() -{ - return WorldScenery(); -} - -WorldPathTile FileFormats::CreateWldPath() -{ - return WorldPathTile(); -} - -WorldLevelTile FileFormats::CreateWldLevel() -{ - return WorldLevelTile(); -} - -WorldMusicBox FileFormats::CreateWldMusicbox() -{ - return WorldMusicBox(); -} - -void FileFormats::CreateWorldHeader(WorldData &NewFileData) -{ - NewFileData = WorldData(); -} - - -void FileFormats::CreateWorldData(WorldData &NewFileData) -{ - CreateWorldHeader(NewFileData); - - NewFileData.tiles.clear(); - NewFileData.tile_array_id = 0; - NewFileData.scenery.clear(); - NewFileData.scene_array_id = 0; - NewFileData.paths.clear(); - NewFileData.path_array_id = 0; - NewFileData.levels.clear(); - NewFileData.level_array_id = 0; - NewFileData.music.clear(); - NewFileData.musicbox_array_id = 0; - NewFileData.arearects.clear(); - NewFileData.arearect_array_id = 0; - NewFileData.layers.clear(); - NewFileData.layers_array_id = 0; -} - -WorldData FileFormats::CreateWorldData() -{ - WorldData NewFileData; - CreateWorldData(NewFileData); - return NewFileData; -} diff --git a/LunaDll/libs/PGE_File_Formats/wld_filedata.h b/LunaDll/libs/PGE_File_Formats/wld_filedata.h deleted file mode 100644 index c7cd7dea3..000000000 --- a/LunaDll/libs/PGE_File_Formats/wld_filedata.h +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Platformer Game Engine by Wohlstand, a free platform for game making - * Copyright (c) 2014-2017 Vitaly Novichkov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/*! - * \file wld_filedata.h - * \brief Contains data structure definitions for a world map file data - */ - -#pragma once -#ifndef WLD_FILEDATA_H -#define WLD_FILEDATA_H - -#include "pge_file_lib_globs.h" -#include "meta_filedata.h" - -#ifndef DEFAULT_LAYER_NAME -#define DEFAULT_LAYER_NAME "Default" -#endif - -//////////////////////World file Data////////////////////// -/** - * @brief Terrain tile - */ -struct WorldTerrainTile -{ - //! Position X - long x = 0; - //! Position Y - long y = 0; - //! ID of terrain tile - unsigned long id = 0; - //! 38A: Graphics extend x - long gfx_dx = 0; - //! 38A: Graphics extend y - long gfx_dy = 0; - //! Name of a parent layer. Default value is "Default" - PGESTRING layer = DEFAULT_LAYER_NAME; - - /* - * Editor-only parameters which are not saving into file - */ - //! Helper meta-data - ElementMeta meta; -}; - -/** - * @brief Scenery object - */ -struct WorldScenery -{ - //! Position X - long x = 0; - //! Position Y - long y = 0; - //! ID of scenery object - unsigned long id = 0; - //! 38A: Graphics extend x - long gfx_dx = 0; - //! 38A: Graphics extend y - long gfx_dy = 0; - //! Name of a parent layer. Default value is "Default" - PGESTRING layer = DEFAULT_LAYER_NAME; - - /* - * Editor-only parameters which are not saving into file - */ - //! Helper meta-data - ElementMeta meta; -}; - -/** - * @brief Path tile - */ -struct WorldPathTile -{ - //! Position X - long x = 0; - //! Position Y - long y = 0; - //! ID of path tile - unsigned long id = 0; - //! 38A: Graphics extend x - long gfx_dx = 0; - //! 38A: Graphics extend y - long gfx_dy = 0; - //! Name of a parent layer. Default value is "Default" - PGESTRING layer = DEFAULT_LAYER_NAME; - - /* - * Editor-only parameters which are not saving into file - */ - //! Helper meta-data - ElementMeta meta; -}; - -/** - * @brief Level entrance tile - */ -struct WorldLevelTile -{ - //! Position X - long x = 0; - //! PositionY - long y = 0; - //! 38A: Graphics extend x - long gfx_dx = 0; - //! 38A: Graphics extend y - long gfx_dy = 0; - //! ID of level entrance object - unsigned long id = 0; - //! Target level file to enter - PGESTRING lvlfile; - //! Visible title of the level - PGESTRING title; - //! Open top path on exit code - int top_exit = -1; - //! Open left path on exit code - int left_exit = -1; - //! Open bottom path on exit code - int bottom_exit = -1; - //! Open right path on exit code - int right_exit = -1; - - struct OpenCondition - { - //! List of additional exit codes to open this path - PGELIST exit_codes; - //! Expression required to open paths on any direction - PGESTRING expression; - }; - //! Additional conditions to open top path - OpenCondition top_exit_extra; - //! Additional conditions to open left path - OpenCondition left_exit_extra; - //! Additional conditions to open bottom path - OpenCondition bottom_exit_extra; - //! Additional conditions to open right path - OpenCondition right_exit_extra; - - struct EnterCondition - { - PGESTRING condition; - PGESTRING levelIndex; - }; - //! Conditions to enter the level - PGELIST enter_cond; - //! Target Warp-ID to enter level - unsigned long entertowarp = 0; - //! Level is always shown on map even not opened - bool alwaysVisible = false; - //! Show path background image under main sprite - bool pathbg = false; - //! Is this level entrance point is initial position of player on game start - bool gamestart = false; - //! Teleport to X coordinate of the world map (-1 don't teleport) - long gotox = -1; - //! Teleport to Y coordinate of the world map (-1 don't teleport) - long gotoy = -1; - //! Show big path background image under main sprite - bool bigpathbg = false; - //! Forcedly start level on player touches the level entrance cell - bool forceStart = false; - //! Ignore star coins while counting stars - bool disableStarCoinsCount = false; - //! Close level entrance when it has been completed - bool destroyOnCompleting = false; - //! Level movement will be affected by touching of rectangular areas - bool controlledByAreaRects = false; - //! 38A: Level-ID - long levelID = 0; - //! Name of a parent layer. Default value is "Default" - PGESTRING layer = DEFAULT_LAYER_NAME; - /** - * @brief Move entrance point to another position every failed attempt to complete this level - */ - struct Movement - { - struct Node - { - long x = 0; - long y = 0; - long chance = 100; - }; - struct Line - { - long node1 = 0; - long node2 = 0; - }; - //! Nodes - PGELIST nodes; - //! Path that connects nodes - PGELIST paths; - } movement; - - /* - * Editor-only parameters which are not saving into file - */ - //! Helper meta-data - ElementMeta meta; -}; - -/** - * @brief Music box object - */ -struct WorldMusicBox -{ - //! Position X - long x = 0; - //! Position Y - long y = 0; - //! ID of starnard music box - unsigned long id = 0; - //! Custom music file to play on touch - PGESTRING music_file; - //! Name of a parent layer. Default value is "Default" - PGESTRING layer = DEFAULT_LAYER_NAME; - - /* - * Editor-only parameters which are not saving into file - */ - //! Helper meta-data - ElementMeta meta; -}; - -/** - * @brief Rectangular zone to catch events - */ -struct WorldAreaRect -{ - //! Position X - long x = 0; - //! Position Y - long y = 0; - //! Width size - long w = 32; - //! Height size - long h = 32; - //! ID of music to toggle on touch - unsigned long music_id = 0; - //! Custom music file to play on touch - PGESTRING music_file; - //! Name of a parent layer. Default value is "Default" - PGESTRING layer = DEFAULT_LAYER_NAME; - - enum Flags - { - //! Area takes no settings - SETUP_NOTHING = 0x00, - //! Toggle music on touch - SETUP_CHANGE_MUSIC = 0x01, - //! Changes size of viewport - SETUP_SET_VIEWPORT = 0x02, - //! Set route area for self-moving object - SETUP_OBJECTS_ROUTE= 0x04, - //! Autowalking area by current direction - SETUP_AUTOWALKING = 0x08, - //! Item-triggered events - SETUP_ITEM_EVENTS = 0x0F - }; - //! Special markers of this area functionality - uint32_t flags = SETUP_NOTHING; - //! Touch event slot - PGESTRING eventTouch; - - enum TouchPolicy{ - TOUCH_TRIGGER_EVERY_ENTER = 0, - TOUCH_TRIGGER_ENTER_AND_LEVEL_COMPLETION = 1, - TOUCH_TRIGGER_ONCE = 2 - }; - uint32_t eventTouchPolicy = TOUCH_TRIGGER_EVERY_ENTER; - //! Break action event slot - PGESTRING eventBreak; - //! Warp action item use event slot - PGESTRING eventWarp; - //! Anchor event slot - PGESTRING eventAnchor; - - /* - * Editor-only parameters which are not saving into file - */ - //! Helper meta-data - ElementMeta meta; -}; - -/*! - * \brief World map specific Layer entry structure - */ -struct WorldLayer -{ - //! Name of layer - PGESTRING name; - //! Is this layer hidden? - bool hidden = false; - //! Are all members of this layer are locked for modifying? - bool locked = false; - /* - * Editor-only parameters which are not saving into file - */ - //! Helper meta-data - ElementMeta meta; -}; - -struct WorldEvent38A -{ - //! Name of the event - PGESTRING name; - - //TODO: Implement other fields!!! - - /* - * Editor-only parameters which are not saving into file - */ - //! Helper meta-data - ElementMeta meta; -}; - -/** - * @brief Custom element settings (used by 38A) - */ -struct WorldItemSetup38A -{ - enum ItemType - { - UNKNOWN = -1, - TERRAIN = 0, - SCENERY = 1, - LEVEL = 2, - } type = UNKNOWN; - - int64_t id = 0; - struct Entry - { - int32_t key = 0; - int64_t value = 0; - }; - PGELIST data; -}; - -/** - * @brief World map data structure - */ -struct WorldData -{ - //! Helper meta-data - FileFormatMeta meta; - /*! - * \brief File format - */ - enum FileFormat - { - //! PGE-X WLDX file format - PGEX=0, - //! SMBX1...64 WLD file format - SMBX64, - //! SMBX-38A WLD file format - SMBX38A - }; - - //! Title of the episode - PGESTRING EpisodeTitle = ""; - //! Disable SMBX64 Character 1 - bool nocharacter1 = false; - //! Disable SMBX64 Character 2 - bool nocharacter2 = false; - //! Disable SMBX64 Character 3 - bool nocharacter3 = false; - //! Disable SMBX64 Character 4 - bool nocharacter4 = false; - //! Disable SMBX64 Character 5 - bool nocharacter5 = false; - - //! List of disabled playable characters (boolean array by ID of each playable character) - PGELIST nocharacter; - - inline void charactersFromS64() - { - nocharacter.clear(); - nocharacter.push_back(nocharacter1); - nocharacter.push_back(nocharacter2); - nocharacter.push_back(nocharacter3); - nocharacter.push_back(nocharacter4); - nocharacter.push_back(nocharacter5); - } - - inline void charactersToS64() - { - nocharacter1 = nocharacter.size() > 0 ? nocharacter[0] : false; - nocharacter2 = nocharacter.size() > 1 ? nocharacter[1] : false; - nocharacter3 = nocharacter.size() > 2 ? nocharacter[2] : false; - nocharacter4 = nocharacter.size() > 3 ? nocharacter[3] : false; - nocharacter5 = nocharacter.size() > 4 ? nocharacter[4] : false; - } - - PGESTRING IntroLevel_file = ""; - PGESTRING GameOverLevel_file = ""; - bool HubStyledWorld = false; - bool restartlevel = false; - - //! This episode can be played in the single player only - bool restrictSinglePlayer = false; - //! Disable ability to toggle a playabele character on the world map - bool restrictCharacterSwitch = false; - //! Use stronger securty on the game save files - bool restrictSecureGameSave = false; - //! Don't show entreance screen on each entering into the level - bool disableEnterScreen = false; - - enum CheatsPolicy - { - CHEATS_DENY_IN_LIST = false, - CHEATS_ALLOW_IN_LIST = true - }; - //! If unchecked - allow all cheats except listed, If checked - deny all except listed - bool cheatsPolicy = CHEATS_DENY_IN_LIST; - //! List of cheat codes (granted or forbidden dependent on restrictNoCheats flag state) - PGESTRINGList cheatsList; - - enum SaveMode{ - SAVE_RESUME_AT_INTRO = -1, - SAVE_RESUME_AT_WORLD_MAP = 0, - SAVE_RESUME_AT_RECENT_LEVEL = 1, - }; - //! Policy where resume game on save load - int saveResumePolicy = SAVE_RESUME_AT_WORLD_MAP; - //! Automatically save game on level completing - bool saveAuto = false; - //! Enable save locker - bool saveLocker = false; - //! Save locker expression - PGESTRING saveLockerEx = ""; - //! Message box shown on save locking - PGESTRING saveLockerMsg = ""; - //! Always show any closed cells (overwise closed cells are will be hidden until player will open them) - bool showEverything = false; - //! Cached total number of available stars on this episode - unsigned int stars = 0; - //! 38A Inventory limit - unsigned long inventoryLimit = 0; - - //! Episode credits (full text area) - PGESTRING authors = ""; - //! Episode credits (SMBX64 single-line field 1) - PGESTRING author1 = ""; - //! Episode credits (SMBX64 single-line field 2) - PGESTRING author2 = ""; - //! Episode credits (SMBX64 single-line field 3) - PGESTRING author3 = ""; - //! Episode credits (SMBX64 single-line field 4) - PGESTRING author4 = ""; - //! Episode credits (SMBX64 single-line field 5) - PGESTRING author5 = ""; - - //! List of available terrain tiles - PGELIST tiles; - unsigned int tile_array_id = 1; - //! List of available sceneries - PGELIST scenery; - unsigned int scene_array_id = 1; - //! List of available path cells - PGELIST paths; - unsigned int path_array_id = 1; - //! List of available level cells - PGELIST levels; - unsigned int level_array_id = 1; - //! List of available music boxes - PGELIST music; - unsigned int musicbox_array_id = 1; - //! List of avaiable special area rectangles - PGELIST arearects; - unsigned int arearect_array_id = 1; - - //! Array of all presented layers in this world map - PGELIST layers; - //! Last used Layer's array ID - unsigned int layers_array_id = 1; - - //! Array of all 38A-formatted events in this world map - PGELIST events38A; - //! Last used Event's array ID - unsigned int events38A_array_id = 1; - - //! SMBX-38A specific custom configs - PGELIST custom38A_configs; - - //! Meta-data: Position bookmarks, Auto-Script configuration, etc., Crash meta-data, etc. - MetaData metaData; - - /* - * Editor-only parameters which are not saving into file - */ - int CurSection = 0; - bool playmusic = false; - int currentMusic = 0; -}; - -#endif // WLD_FILEDATA_H