diff --git a/Spore ModAPI/SourceCode/App/App.cpp b/Spore ModAPI/SourceCode/App/App.cpp index b0a51316..5f58f550 100644 --- a/Spore ModAPI/SourceCode/App/App.cpp +++ b/Spore ModAPI/SourceCode/App/App.cpp @@ -43,9 +43,9 @@ namespace App Args(const eastl::string16& path, eastl::hash_set& dstSkippedPaths, int& dstCount), Args(path, dstSkippedPaths, dstCount)); - auto_METHOD(PngEncoder, bool, EncodePNG, - Args(IO::IStream* stream, int mode), - Args(stream, mode)); + auto_METHOD(PngEncoder, bool, WriteImageToStream, + Args(IO::IStream* stream, App::PngEncoder::Format format), + Args(stream, format)); auto_STATIC_METHOD_(cIDGenerator, cIDGenerator*, Get); diff --git a/Spore ModAPI/SourceCode/DLL/AddressesApp.cpp b/Spore ModAPI/SourceCode/DLL/AddressesApp.cpp index 4b8a054f..46aae5a4 100644 --- a/Spore ModAPI/SourceCode/DLL/AddressesApp.cpp +++ b/Spore ModAPI/SourceCode/DLL/AddressesApp.cpp @@ -416,7 +416,8 @@ namespace App namespace Addresses(PngEncoder) { - DefineAddress(EncodePNG, SelectAddress(0x68E660, 0x68e190)); + DefineAddress(WriteImageToStream, SelectAddress(0x68E660, 0x68e190)); + DefineAddressAlias(EncodePNG, WriteImageToStream); } namespace Addresses(cLocaleManager) diff --git a/Spore ModAPI/SourceCode/DLL/AddressesIO.cpp b/Spore ModAPI/SourceCode/DLL/AddressesIO.cpp index 0d64ab5a..93eac6cc 100644 --- a/Spore ModAPI/SourceCode/DLL/AddressesIO.cpp +++ b/Spore ModAPI/SourceCode/DLL/AddressesIO.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include namespace Addresses(IO) @@ -220,5 +221,52 @@ namespace IO DefineAddress(Exists, SelectAddress(0x9327F0, 0x932280)); DefineAddress(Remove, SelectAddress(0x932510, 0x932860)); } + + namespace Addresses(StreamCompressionZLib) + { + DefineAddress(AddRef, SelectAddress(0x614940, 0x7685A0)); + DefineAddress(Release, SelectAddress(0x707F90, 0x67D9F0)); + DefineAddress(GetType, SelectAddress(0x672FC0, 0x67DAB0)); + DefineAddress(GetAccessFlags, SelectAddress(0x672850, 0x67D2C0)); + DefineAddress(GetState, SelectAddress(0x672860, 0x67D2D0)); + DefineAddress(Close, SelectAddress(0x672C70, 0x67D6E0)); + DefineAddress(GetSize, SelectAddress(0x672A70, 0x67D3A0)); + DefineAddress(SetSize, SelectAddress(0x9F8EB0, 0xDDE930)); + DefineAddress(GetPosition, SelectAddress(0x672930, 0x67D3B0)); + DefineAddress(SetPosition, SelectAddress(0x7A4230, 0x950E00)); + DefineAddress(GetAvailable, SelectAddress(0x60C030, 0xE21A90)); + DefineAddress(Read, SelectAddress(0xF95C60, 0x1097390)); + DefineAddress(Flush, SelectAddress(0xC65B10, 0xB1FB30)); + DefineAddress(Write, SelectAddress(0x672BD0, 0x67D640)); + DefineAddress(SetCompressedFormat, SelectAddress(0x6727D0, 0x67D240)); + DefineAddress(SetBufferSize, SelectAddress(0x6727F0, 0x67D260)); + DefineAddress(SetCompressionHint, SelectAddress(0x672830, 0x67D2A0)); + DefineAddress(Open, SelectAddress(0x672AA0, 0x67D510)); + // destructor; private for ModAPI + DefineAddress(Dispose, SelectAddress(0x67DC30, 0x67DAD0)); + } + + namespace Addresses(StreamDecompressionZLib) + { + DefineAddress(AddRef, SelectAddress(0x614940, 0x7685A0)); + DefineAddress(Release, SelectAddress(0x707F90, 0x67D9F0)); + DefineAddress(GetType, SelectAddress(0x672DA0, 0x67D830)); + DefineAddress(GetAccessFlags, SelectAddress(0x6729A0, 0x67D420)); + DefineAddress(GetState, SelectAddress(0x6729B0, 0x67D430)); + DefineAddress(Close, SelectAddress(0x672F40, 0x67D9D0)); + DefineAddress(GetSize, SelectAddress(0x672A70, 0x67D3A0)); + DefineAddress(SetSize, SelectAddress(0x9F8EB0, 0xDDE930)); + DefineAddress(GetPosition, SelectAddress(0x672A80, 0x67D4F0)); + DefineAddress(SetPosition, SelectAddress(0x7A4230, 0x950E00)); + DefineAddress(GetAvailable, SelectAddress(0x60C030, 0xE21A90)); + DefineAddress(Read, SelectAddress(0x672E90, 0x67D920)); + DefineAddress(Flush, SelectAddress(0xAF5C80, 0xB1E410)); + DefineAddress(Write, SelectAddress(0x7A4230, 0x950E00)); + DefineAddress(SetCompressedFormat, SelectAddress(0x672950, 0x67D3D0)); + DefineAddress(SetBufferSize, SelectAddress(0x672960, 0x67D3E0)); + DefineAddress(Open, SelectAddress(0x672DC0, 0x67D850)); + // destructor; private for ModAPI + DefineAddress(Dispose, SelectAddress(0x67DCE0, 0x67DB80)); + } } #endif diff --git a/Spore ModAPI/SourceCode/IO/StreamDefinitions.cpp b/Spore ModAPI/SourceCode/IO/StreamDefinitions.cpp index 3cad441d..620c59ca 100644 --- a/Spore ModAPI/SourceCode/IO/StreamDefinitions.cpp +++ b/Spore ModAPI/SourceCode/IO/StreamDefinitions.cpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace IO { @@ -395,5 +396,101 @@ namespace IO auto_METHOD(StreamNull, int, Write, Args(const void* pData, size_t nSize), Args(pData, nSize)); ////////////////////// + + + ///////////////////////////////// + //// StreamCompressionZLib.h //// + ///////////////////////////////// + + StreamCompressionZLib::StreamCompressionZLib(IStream* pOutputStream, int nHint) + : mpOutputStream(NULL), + mbOpen(false), + mbInited(false), + mpZLibStream(NULL), + mFormat(kCompressedFormatZLib), + mHint(nHint), + mpOutputBuffer(NULL), + mnOutputBufferSize(0x2000) + { + if (pOutputStream) + StreamCompressionZLib::Open(pOutputStream, nHint); + } + + StreamCompressionZLib::~StreamCompressionZLib() + { + Dispose(); + } + + auto_METHOD_(StreamCompressionZLib, int, AddRef); + auto_METHOD_(StreamCompressionZLib, int, Release); + + auto_METHOD_const_(StreamCompressionZLib, uint32_t, GetType); + auto_METHOD_const_(StreamCompressionZLib, AccessFlags, GetAccessFlags); + auto_METHOD_const_(StreamCompressionZLib, FileError, GetState); + auto_METHOD_(StreamCompressionZLib, bool, Close); + + auto_METHOD_const_(StreamCompressionZLib, size_type, GetSize); + auto_METHOD(StreamCompressionZLib, bool, SetSize, Args(size_type size), Args(size)); + auto_METHOD_const(StreamCompressionZLib, int, GetPosition, Args(PositionType positionType), Args(positionType)); + auto_METHOD(StreamCompressionZLib, bool, SetPosition, Args(int distance, PositionType positionType), Args(distance, positionType)); + auto_METHOD_const_(StreamCompressionZLib, int, GetAvailable); + + auto_METHOD(StreamCompressionZLib, int, Read, Args(void* pData, size_t nSize), Args(pData, nSize)); + auto_METHOD_(StreamCompressionZLib, bool, Flush); + auto_METHOD(StreamCompressionZLib, int, Write, Args(const void* pData, size_t nSize), Args(pData, nSize)); + + auto_METHOD(StreamCompressionZLib, bool, SetCompressedFormat, Args(CompressedFormat format), Args(format)); + auto_METHOD(StreamCompressionZLib, bool, SetBufferSize, Args(size_t nOutputBufferSize), Args(nOutputBufferSize)); + auto_METHOD(StreamCompressionZLib, bool, SetCompressionHint, Args(int hint), Args(hint)); + + auto_METHOD(StreamCompressionZLib, bool, Open, Args(IStream* pOutputStream, int nHint), Args(pOutputStream, nHint)); + + // destructor, private for ModAPI + auto_METHOD_VOID_(StreamCompressionZLib, Dispose); + + StreamDecompressionZLib::StreamDecompressionZLib(IStream* pInputStream) + : mpInputStream(NULL), + mFormat(kCompressedFormatZLib), + mbOpen(false), + mbEOF(false), + mbInited(false), + mpZLibStream(NULL), + mpInputBuffer(NULL), + mnInputBufferSize(0x2000) + {} + + StreamDecompressionZLib::~StreamDecompressionZLib() + { + Dispose(); + } + + auto_METHOD_(StreamDecompressionZLib, int, AddRef); + auto_METHOD_(StreamDecompressionZLib, int, Release); + + auto_METHOD_const_(StreamDecompressionZLib, uint32_t, GetType); + auto_METHOD_const_(StreamDecompressionZLib, AccessFlags, GetAccessFlags); + auto_METHOD_const_(StreamDecompressionZLib, FileError, GetState); + auto_METHOD_(StreamDecompressionZLib, bool, Close); + + auto_METHOD_const_(StreamDecompressionZLib, size_type, GetSize); + auto_METHOD(StreamDecompressionZLib, bool, SetSize, Args(size_type size), Args(size)); + auto_METHOD_const(StreamDecompressionZLib, int, GetPosition, Args(PositionType positionType), Args(positionType)); + auto_METHOD(StreamDecompressionZLib, bool, SetPosition, Args(int distance, PositionType positionType), Args(distance, positionType)); + auto_METHOD_const_(StreamDecompressionZLib, int, GetAvailable); + + auto_METHOD(StreamDecompressionZLib, int, Read, Args(void* pData, size_t nSize), Args(pData, nSize)); + auto_METHOD_(StreamDecompressionZLib, bool, Flush); + auto_METHOD(StreamDecompressionZLib, int, Write, Args(const void* pData, size_t nSize), Args(pData, nSize)); + + auto_METHOD(StreamDecompressionZLib, bool, SetCompressedFormat, Args(CompressedFormat format), Args(format)); + auto_METHOD(StreamDecompressionZLib, bool, SetBufferSize, Args(size_t nInputBufferSize), Args(nInputBufferSize)); + + auto_METHOD(StreamDecompressionZLib, bool, Open, Args(IStream* pInputStream), Args(pInputStream)); + + // destructor, private for ModAPI + auto_METHOD_VOID_(StreamDecompressionZLib, Dispose); + + ///////////////////////////////// + #endif } diff --git a/Spore ModAPI/Spore ModAPI.vcxproj b/Spore ModAPI/Spore ModAPI.vcxproj index f18eaec0..e98ebcc6 100644 --- a/Spore ModAPI/Spore ModAPI.vcxproj +++ b/Spore ModAPI/Spore ModAPI.vcxproj @@ -330,6 +330,7 @@ + diff --git a/Spore ModAPI/Spore ModAPI.vcxproj.filters b/Spore ModAPI/Spore ModAPI.vcxproj.filters index 80a2cf7c..42bd3567 100644 --- a/Spore ModAPI/Spore ModAPI.vcxproj.filters +++ b/Spore ModAPI/Spore ModAPI.vcxproj.filters @@ -2286,6 +2286,9 @@ Header Files + + Header Files + diff --git a/Spore ModAPI/Spore/App/Thumbnail_cImportExport.h b/Spore ModAPI/Spore/App/Thumbnail_cImportExport.h index 75f7cfe1..036141f0 100644 --- a/Spore ModAPI/Spore/App/Thumbnail_cImportExport.h +++ b/Spore ModAPI/Spore/App/Thumbnail_cImportExport.h @@ -15,7 +15,13 @@ namespace App { struct PngEncoder { - bool EncodePNG(IO::IStream* outputStream, int mode); + enum Format { + kImageFormatPNG, + kImageFormatTGA, + kImageFormatBMP + }; + + bool WriteImageToStream(IO::IStream* outputStream, Format format); /* 00h */ eastl::vector mPixelBuf; /* 14h */ uint32_t mnImageWidth; @@ -83,11 +89,11 @@ namespace App /// @param[out] dst The eastl::string where the path will be written. bool GetFolderPath(uint32_t creationType, eastl::string16& dst); - /// Used to obtain a path from a locale file, by default `0x19F76D11.locale`, similar to the one that would + /// Used to obtain a path from a locale file, by default `SaveDataFolders.locale`, similar to the one that would /// return GetFolderPath() bool FolderPathFromLocale(uint32_t instanceID, eastl::string16& dst, uint32_t tableID = 0xFFFFFFFF); - /// Encodes the given resource into a `.png` image and saves it, both in the given package and in the + /// Encodes the given resource into a `.png` Model-in-Picture and saves it, both in the given package and in the /// "My Spore Creations" in the user Documents folder. /// /// In the package, the image will be saved using the same ResourceKey as the resource, but with a TypeIDs::png type. @@ -110,7 +116,7 @@ namespace App /// @returns 'true' on success, 'false' if something failed. bool ImportPNG(const char16_t* path, ResourceKey& key); - /// Extracts information from a PNG file. It extracts both the metadata, and the data encoded within the image. + /// Extracts information from a Model-in-Picture PNG file. It extracts both the metadata, and the data encoded within the image. /// @param[out] dstMetadata /// @param[out] dstDataStream /// @returns true on success, false if something failed @@ -168,6 +174,6 @@ namespace App namespace Addresses(PngEncoder) { - DeclareAddress(EncodePNG); // 0x68E660 0x68e190 + DeclareAddress(WriteImageToStream); // 0x68E660 0x68e190 } } diff --git a/Spore ModAPI/Spore/IO/StreamCompressionZLib.h b/Spore ModAPI/Spore/IO/StreamCompressionZLib.h new file mode 100644 index 00000000..4a4d6b33 --- /dev/null +++ b/Spore ModAPI/Spore/IO/StreamCompressionZLib.h @@ -0,0 +1,169 @@ +#pragma once + +#include + +#define StreamCompressionZLibPtr eastl::intrusive_ptr +#define StreamDecompressionZLibPtr eastl::intrusive_ptr + +namespace IO +{ + enum CompressedFormat + { + kCompressedFormatZLib, + kCompressedFormatGZip + }; + + class StreamCompressionZLib : public IStream, public RefCountTemplateAtomic + { + public: + + static const uint32_t TYPE = 0x23bdad7; + + enum CompressionHint + { + kCompressionHintNone = 0, + kCompressionHintSpeed = 1, + kCompressionHintSize = 9, + kCompressionHintDefault = -1 + }; + + public: + StreamCompressionZLib(IStream* pOutputStream, int nHint); + + ~StreamCompressionZLib(); + + /* 04h */ virtual int AddRef() override; + /* 08h */ virtual int Release() override; + + /* 0Ch */ virtual uint32_t GetType() const override; + /* 10h */ virtual AccessFlags GetAccessFlags() const override; + /* 14h */ virtual FileError GetState() const override; + /* 18h */ virtual bool Close() override; + + /* 1Ch */ virtual size_type GetSize() const override; + /* 20h */ virtual bool SetSize(size_type size) override; + /* 24h */ virtual int GetPosition(PositionType positionType = PositionType::Begin) const override; + /* 28h */ virtual bool SetPosition(int distance, PositionType positionType = PositionType::Begin) override; + /* 2Ch */ virtual int GetAvailable() const override; + + /* 30h */ virtual int Read(void* pData, size_t nSize) override; + /* 34h */ virtual bool Flush() override; + /* 38h */ virtual int Write(const void* pData, size_t nSize) override; + + /* 3Ch */ virtual bool SetCompressedFormat(CompressedFormat format); + /* 40h */ virtual bool SetBufferSize(size_t nOutputBufferSize); + /* 44h */ virtual bool SetCompressionHint(int hint); + + /* 48h */ virtual bool Open(IStream* pOutputStream, int nHint); + protected: + /* 0Ch */ IStream* mpOutputStream; + /* 10h */ bool mbOpen; + /* 11h */ bool mbInited; + /* 14h */ void* mpZLibStream; // z_stream_s* + /* 18h */ CompressedFormat mFormat; + /* 1Ch */ int mHint; + /* 20h */ uint8_t* mpOutputBuffer; + /* 24h */ size_t mnOutputBufferSize; + /* 28h */ uint32_t mInputCRC; + /* 2Ch */ size_t mInputSize; + // destructor, private for ModAPI + private: + virtual void Dispose(); + }; + ASSERT_SIZE(StreamCompressionZLib, 0x30); + + namespace Addresses(StreamCompressionZLib) + { + DeclareAddress(AddRef); + DeclareAddress(Release); + DeclareAddress(GetType); + DeclareAddress(GetAccessFlags); + DeclareAddress(GetState); + DeclareAddress(Close); + DeclareAddress(GetSize); + DeclareAddress(SetSize); + DeclareAddress(GetPosition); + DeclareAddress(SetPosition); + DeclareAddress(GetAvailable); + DeclareAddress(Read); + DeclareAddress(Flush); + DeclareAddress(Write); + DeclareAddress(SetCompressedFormat); + DeclareAddress(SetBufferSize); + DeclareAddress(SetCompressionHint); + DeclareAddress(Open); + // destructor, private for ModAPI + DeclareAddress(Dispose); + } + + class StreamDecompressionZLib : public IStream, public RefCountTemplateAtomic + { + public: + + static const uint32_t TYPE = 0x2420525; + + public: + StreamDecompressionZLib(IStream* pInputStream); + + ~StreamDecompressionZLib(); + + /* 04h */ virtual int AddRef() override; + /* 08h */ virtual int Release() override; + + /* 0Ch */ virtual uint32_t GetType() const override; + /* 10h */ virtual AccessFlags GetAccessFlags() const override; + /* 14h */ virtual FileError GetState() const override; + /* 18h */ virtual bool Close() override; + + /* 1Ch */ virtual size_type GetSize() const override; + /* 20h */ virtual bool SetSize(size_type size) override; + /* 24h */ virtual int GetPosition(PositionType positionType = PositionType::Begin) const override; + /* 28h */ virtual bool SetPosition(int distance, PositionType positionType = PositionType::Begin) override; + /* 2Ch */ virtual int GetAvailable() const override; + + /* 30h */ virtual int Read(void* pData, size_t nSize) override; + /* 34h */ virtual bool Flush() override; + /* 38h */ virtual int Write(const void* pData, size_t nSize) override; + + /* 3Ch */ virtual bool SetCompressedFormat(CompressedFormat format); + /* 40h */ virtual bool SetBufferSize(size_t nInputBufferSize); + + /* 44h */ virtual bool Open(IStream* pInputStream); + protected: + /* 0Ch */ IStream* mpInputStream; + /* 10h */ CompressedFormat mFormat; + /* 14h */ bool mbOpen; + /* 15h */ bool mbEOF; + /* 16h */ bool mbInited; + /* 18h */ void* mpZLibStream; // z_stream_s* + /* 1Ch */ uint8_t* mpInputBuffer; + /* 20h */ size_t mnInputBufferSize; + // destructor, private for ModAPI + private: + virtual void Dispose(); + }; + ASSERT_SIZE(StreamDecompressionZLib, 0x24); + + namespace Addresses(StreamDecompressionZLib) + { + DeclareAddress(AddRef); + DeclareAddress(Release); + DeclareAddress(GetType); + DeclareAddress(GetAccessFlags); + DeclareAddress(GetState); + DeclareAddress(Close); + DeclareAddress(GetSize); + DeclareAddress(SetSize); + DeclareAddress(GetPosition); + DeclareAddress(SetPosition); + DeclareAddress(GetAvailable); + DeclareAddress(Read); + DeclareAddress(Flush); + DeclareAddress(Write); + DeclareAddress(SetCompressedFormat); + DeclareAddress(SetBufferSize); + DeclareAddress(Open); + // destructor, private for ModAPI + DeclareAddress(Dispose); + } +} \ No newline at end of file