From 7345808f273139ae12c3735838474be3b667280d Mon Sep 17 00:00:00 2001 From: 0KepOnline <78259495+0KepOnline@users.noreply.github.com> Date: Tue, 12 May 2026 16:20:38 +0300 Subject: [PATCH 1/7] Replace confusing `PNG` with `MIP` (Model-in-Picture) in `Thumbnail_cImportExport` --- Spore ModAPI/SourceCode/App/App.cpp | 14 +++---- Spore ModAPI/SourceCode/DLL/AddressesApp.cpp | 12 +++--- .../Spore/App/Thumbnail_cImportExport.h | 42 +++++++++++-------- 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/Spore ModAPI/SourceCode/App/App.cpp b/Spore ModAPI/SourceCode/App/App.cpp index b0a51316..9adaf7bd 100644 --- a/Spore ModAPI/SourceCode/App/App.cpp +++ b/Spore ModAPI/SourceCode/App/App.cpp @@ -25,27 +25,27 @@ namespace App auto_METHOD(Thumbnail_cImportExport, bool, FolderPathFromLocale, Args(uint32_t instanceID, eastl::string16& dst, uint32_t tableID), Args(instanceID, dst, tableID)); - auto_METHOD(Thumbnail_cImportExport, bool, SavePNG, + auto_METHOD(Thumbnail_cImportExport, bool, SaveMIP, Args(Resource::ResourceObject* pResource, RenderWare::Raster* pImage, Resource::Database* pDBPF, bool forceReplace, bool disableSteganography), Args(pResource, pImage, pDBPF, forceReplace, disableSteganography)); - auto_METHOD(Thumbnail_cImportExport, bool, ImportPNG, + auto_METHOD(Thumbnail_cImportExport, bool, ImportMIP, Args(const char16_t* path, ResourceKey& key), Args(path, key)); - auto_METHOD(Thumbnail_cImportExport, bool, DecodePNG, + auto_METHOD(Thumbnail_cImportExport, bool, DecodeMIP, Args(IO::IStream* stream, ThumbnailDecodedMetadata& dstMetadata, IStreamPtr& dstDataStream), Args(stream, dstMetadata, dstDataStream)); auto_METHOD_(Thumbnail_cImportExport, bool, SaveFilePaths); - auto_METHOD(Thumbnail_cImportExport, bool, ImportDirectoryPNGs, + auto_METHOD(Thumbnail_cImportExport, bool, ImportDirectoryMIPs, 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(MIPEncoder, bool, WriteImageToStream, + Args(IO::IStream* stream, App::MIPEncoder::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..3579fa83 100644 --- a/Spore ModAPI/SourceCode/DLL/AddressesApp.cpp +++ b/Spore ModAPI/SourceCode/DLL/AddressesApp.cpp @@ -407,16 +407,16 @@ namespace App DefineAddress(Get, SelectAddress(0x5F7750, 0x5F79C0)); DefineAddress(GetFolderPath, SelectAddress(0x5F9140, 0x5F92C0)); DefineAddress(FolderPathFromLocale, SelectAddress(0x5F9220, 0x5F93A0)); - DefineAddress(SavePNG, SelectAddress(0x5FA7E0, 0x5FA960)); - DefineAddress(ImportPNG, SelectAddress(0x5FC240, 0x5FC3C0)); - DefineAddress(DecodePNG, SelectAddress(0x5FBA10, 0x5FBB90)); + DefineAddress(SaveMIP, SelectAddress(0x5FA7E0, 0x5FA960)); + DefineAddress(ImportMIP, SelectAddress(0x5FC240, 0x5FC3C0)); + DefineAddress(DecodeMIP, SelectAddress(0x5FBA10, 0x5FBB90)); DefineAddress(SaveFilePaths, SelectAddress(0x5F89C0, 0x5F8B60)); - DefineAddress(ImportDirectoryPNGs, SelectAddress(0x5FC900, 0x5FCA80)); + DefineAddress(ImportDirectoryMIPs, SelectAddress(0x5FC900, 0x5FCA80)); } - namespace Addresses(PngEncoder) + namespace Addresses(MIPEncoder) { - DefineAddress(EncodePNG, SelectAddress(0x68E660, 0x68e190)); + DefineAddress(WriteImageToStream, SelectAddress(0x68E660, 0x68e190)); } namespace Addresses(cLocaleManager) diff --git a/Spore ModAPI/Spore/App/Thumbnail_cImportExport.h b/Spore ModAPI/Spore/App/Thumbnail_cImportExport.h index 75f7cfe1..65ca7fcd 100644 --- a/Spore ModAPI/Spore/App/Thumbnail_cImportExport.h +++ b/Spore ModAPI/Spore/App/Thumbnail_cImportExport.h @@ -13,9 +13,17 @@ namespace App { - struct PngEncoder { + struct MIPEncoder { + + enum Format { + kImageFormatPNG, + kImageFormatTGA, + kImageFormatBMP + }; + + bool WriteImageToStream(IO::IStream* outputStream, Format format); + - bool EncodePNG(IO::IStream* outputStream, int mode); /* 00h */ eastl::vector mPixelBuf; /* 14h */ uint32_t mnImageWidth; @@ -39,7 +47,7 @@ namespace App /* 58h */ eastl::vector mData; /* 6Ch */ int field_6C; }; - ASSERT_SIZE(PngEncoder, 0x70); + ASSERT_SIZE(MIPEncoder, 0x70); struct ThumbnailDecodedMetadata { @@ -83,11 +91,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. @@ -100,7 +108,7 @@ namespace App /// @param forceReplace [Optional] If false (by default), if the `.png` already exists in the folder, it will try writing variants like `(1)`, `(2)`,... /// @param disableSteganography [Optional] If false (by default), the data in the `.png` will be stored in a special way meant to save space. /// @returns `true` on success, `false` if something failed. - bool SavePNG(Resource::ResourceObject* pResource, RenderWare::Raster* pImage, Resource::Database* database, + bool SaveMIP(Resource::ResourceObject* pResource, RenderWare::Raster* pImage, Resource::Database* database, bool forceReplace = false, bool disableSteganography = false); /// Reads the PNG file from the given file path, and adds the creation found within to the Sporepedia if it hasn't been added yet. @@ -108,13 +116,13 @@ namespace App /// @param path The full path to the file being read. /// @param key Resource key to the creation being read. /// @returns 'true' on success, 'false' if something failed. - bool ImportPNG(const char16_t* path, ResourceKey& key); + bool ImportMIP(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 - bool DecodePNG(IO::IStream* stream, ThumbnailDecodedMetadata& dstMetadata, IStreamPtr& dstDataStream); + bool DecodeMIP(IO::IStream* stream, ThumbnailDecodedMetadata& dstMetadata, IStreamPtr& dstDataStream); /// Saves the file paths information that keeps track of which PNGs have been loaded. /// It saves it in file `0x473C3E6!0x473C3E6.0x473C3E6` of Resource::SaveAreaID::Server (`Pollination.package`) @@ -129,7 +137,7 @@ namespace App /// @param[out] dstSkippedPaths A list of paths that were skipped because they were already in mPngPathToKey or too many files were loaded /// @param[out] dstCount The number of PNGs that were imported is added to this value /// @returns True if some PNG was loaded, false otherwise - bool ImportDirectoryPNGs(const eastl::string16& directoryPath, eastl::hash_set& dstSkippedPaths, int& dstCount); + bool ImportDirectoryMIPs(const eastl::string16& directoryPath, eastl::hash_set& dstSkippedPaths, int& dstCount); static Thumbnail_cImportExport* Get(); @@ -140,7 +148,7 @@ namespace App /* 44h */ uint32_t mMachineId; // not initialized /* 48h */ eastl::hash_map field_48; /* 68h */ eastl::hash_map field_68; - /* 88h */ PngEncoder mPngEncoder; + /* 88h */ MIPEncoder mMipEncoder; /* F8h */ ResourceKey mCurImage; /* 104h */ eastl::string16 mCellsPath; /* 114h */ eastl::string16 mCreaturesPath; @@ -159,15 +167,15 @@ namespace App DeclareAddress(Get); DeclareAddress(GetFolderPath); DeclareAddress(FolderPathFromLocale); - DeclareAddress(SavePNG); - DeclareAddress(ImportPNG); - DeclareAddress(DecodePNG); // 0x5FBA10 0x5FBB90 + DeclareAddress(SaveMIP); + DeclareAddress(ImportMIP); + DeclareAddress(DecodeMIP); // 0x5FBA10 0x5FBB90 DeclareAddress(SaveFilePaths); // 0x5F89C0 0x5F8B60 - DeclareAddress(ImportDirectoryPNGs); // 0x5FC900 0x5FCA80 + DeclareAddress(ImportDirectoryMIPs); // 0x5FC900 0x5FCA80 } - namespace Addresses(PngEncoder) + namespace Addresses(MIPEncoder) { - DeclareAddress(EncodePNG); // 0x68E660 0x68e190 + DeclareAddress(WriteImageToStream); // 0x68E660 0x68e190 } } From 531e82a733ae37ab509047425a670b2b993aad19 Mon Sep 17 00:00:00 2001 From: 0KepOnline <78259495+0KepOnline@users.noreply.github.com> Date: Tue, 12 May 2026 16:21:06 +0300 Subject: [PATCH 2/7] Add `IO::StreamCompressionZLib` & `IO::StreamDecompressionZLib` Destructors are still to be implemented. --- Spore ModAPI/SourceCode/DLL/AddressesIO.cpp | 43 +++++ .../SourceCode/IO/StreamDefinitions.cpp | 104 ++++++++++++ Spore ModAPI/Spore/IO/StreamCompressionZLib.h | 160 ++++++++++++++++++ 3 files changed, 307 insertions(+) create mode 100644 Spore ModAPI/Spore/IO/StreamCompressionZLib.h diff --git a/Spore ModAPI/SourceCode/DLL/AddressesIO.cpp b/Spore ModAPI/SourceCode/DLL/AddressesIO.cpp index 0d64ab5a..fb9f0444 100644 --- a/Spore ModAPI/SourceCode/DLL/AddressesIO.cpp +++ b/Spore ModAPI/SourceCode/DLL/AddressesIO.cpp @@ -220,5 +220,48 @@ 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)); + } + + 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)); + } } #endif diff --git a/Spore ModAPI/SourceCode/IO/StreamDefinitions.cpp b/Spore ModAPI/SourceCode/IO/StreamDefinitions.cpp index 3cad441d..d5c6b64f 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,108 @@ 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() //0067dad0 + { + /*if (mbInited) + { + if (mbOpen) + Close(); + if (mpZLibStream) + { + + } + }*/ + } + + 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)); + + StreamDecompressionZLib::StreamDecompressionZLib(IStream* pInputStream) + : mpInputStream(NULL), + mFormat(kCompressedFormatZLib), + mbOpen(false), + mbEOF(false), + mbInited(false), + mpZLibStream(NULL), + mpInputBuffer(NULL), + mnInputBufferSize(0x2000) + {} + + StreamDecompressionZLib::~StreamDecompressionZLib() //0067db80 + { + /*if (mbInited) + { + + } + if (mpInputStream) + mpInputStream->Release();*/ + } + + 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)); + + ///////////////////////////////// + #endif } diff --git a/Spore ModAPI/Spore/IO/StreamCompressionZLib.h b/Spore ModAPI/Spore/IO/StreamCompressionZLib.h new file mode 100644 index 00000000..823abbfd --- /dev/null +++ b/Spore ModAPI/Spore/IO/StreamCompressionZLib.h @@ -0,0 +1,160 @@ +#pragma once + +#include + +#include + +#define StreamCompressionZLibPtr 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; + }; + 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); + } + + 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; + }; + 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); + } +} \ No newline at end of file From 7d9342960c308d01bf9e6700c1229831d0967cda Mon Sep 17 00:00:00 2001 From: 0KepOnline <78259495+0KepOnline@users.noreply.github.com> Date: Tue, 12 May 2026 16:25:26 +0300 Subject: [PATCH 3/7] Add missing `StreamDecompressionZLibPtr` define --- Spore ModAPI/Spore/IO/StreamCompressionZLib.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Spore ModAPI/Spore/IO/StreamCompressionZLib.h b/Spore ModAPI/Spore/IO/StreamCompressionZLib.h index 823abbfd..8a475e02 100644 --- a/Spore ModAPI/Spore/IO/StreamCompressionZLib.h +++ b/Spore ModAPI/Spore/IO/StreamCompressionZLib.h @@ -5,6 +5,7 @@ #include #define StreamCompressionZLibPtr eastl::intrusive_ptr +#define StreamDecompressionZLibPtr eastl::intrusive_ptr namespace IO { From 713e39af95bb64a2022d1817a76c027506a1cd2e Mon Sep 17 00:00:00 2001 From: 0KepOnline <78259495+0KepOnline@users.noreply.github.com> Date: Sun, 28 Jun 2026 03:16:41 +0300 Subject: [PATCH 4/7] Add proper destructors for `StreamCompressionZLib` --- Spore ModAPI/SourceCode/DLL/AddressesIO.cpp | 4 +++ .../SourceCode/IO/StreamDefinitions.cpp | 27 +++++++------------ Spore ModAPI/Spore ModAPI.vcxproj | 1 + Spore ModAPI/Spore ModAPI.vcxproj.filters | 3 +++ Spore ModAPI/Spore/IO/StreamCompressionZLib.h | 10 +++++++ 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/Spore ModAPI/SourceCode/DLL/AddressesIO.cpp b/Spore ModAPI/SourceCode/DLL/AddressesIO.cpp index fb9f0444..1ef26282 100644 --- a/Spore ModAPI/SourceCode/DLL/AddressesIO.cpp +++ b/Spore ModAPI/SourceCode/DLL/AddressesIO.cpp @@ -241,6 +241,8 @@ namespace IO 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) @@ -262,6 +264,8 @@ namespace IO 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 d5c6b64f..620c59ca 100644 --- a/Spore ModAPI/SourceCode/IO/StreamDefinitions.cpp +++ b/Spore ModAPI/SourceCode/IO/StreamDefinitions.cpp @@ -416,17 +416,9 @@ namespace IO StreamCompressionZLib::Open(pOutputStream, nHint); } - StreamCompressionZLib::~StreamCompressionZLib() //0067dad0 + StreamCompressionZLib::~StreamCompressionZLib() { - /*if (mbInited) - { - if (mbOpen) - Close(); - if (mpZLibStream) - { - - } - }*/ + Dispose(); } auto_METHOD_(StreamCompressionZLib, int, AddRef); @@ -453,6 +445,9 @@ namespace IO 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), @@ -464,14 +459,9 @@ namespace IO mnInputBufferSize(0x2000) {} - StreamDecompressionZLib::~StreamDecompressionZLib() //0067db80 + StreamDecompressionZLib::~StreamDecompressionZLib() { - /*if (mbInited) - { - - } - if (mpInputStream) - mpInputStream->Release();*/ + Dispose(); } auto_METHOD_(StreamDecompressionZLib, int, AddRef); @@ -497,6 +487,9 @@ namespace IO 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/IO/StreamCompressionZLib.h b/Spore ModAPI/Spore/IO/StreamCompressionZLib.h index 8a475e02..fbbe24df 100644 --- a/Spore ModAPI/Spore/IO/StreamCompressionZLib.h +++ b/Spore ModAPI/Spore/IO/StreamCompressionZLib.h @@ -68,6 +68,9 @@ namespace IO /* 24h */ size_t mnOutputBufferSize; /* 28h */ uint32_t mInputCRC; /* 2Ch */ size_t mInputSize; + // destructor, private for ModAPI + private: + virtual void Dispose(); }; ASSERT_SIZE(StreamCompressionZLib, 0x30); @@ -91,6 +94,8 @@ namespace IO DeclareAddress(SetBufferSize); DeclareAddress(SetCompressionHint); DeclareAddress(Open); + // destructor, private for ModAPI + DeclareAddress(Dispose); } class StreamDecompressionZLib : public IStream, public RefCountTemplateAtomic @@ -135,6 +140,9 @@ namespace IO /* 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); @@ -157,5 +165,7 @@ namespace IO DeclareAddress(SetCompressedFormat); DeclareAddress(SetBufferSize); DeclareAddress(Open); + // destructor, private for ModAPI + DeclareAddress(Dispose); } } \ No newline at end of file From 835fff63b7ef572c9d986b34d57a2572f210a2e2 Mon Sep 17 00:00:00 2001 From: 0KepOnline <78259495+0KepOnline@users.noreply.github.com> Date: Sun, 28 Jun 2026 05:18:59 +0300 Subject: [PATCH 5/7] Additional small fixes for `StreamCompressionZLib` --- Spore ModAPI/SourceCode/DLL/AddressesIO.cpp | 1 + Spore ModAPI/Spore/IO/StreamCompressionZLib.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Spore ModAPI/SourceCode/DLL/AddressesIO.cpp b/Spore ModAPI/SourceCode/DLL/AddressesIO.cpp index 1ef26282..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) diff --git a/Spore ModAPI/Spore/IO/StreamCompressionZLib.h b/Spore ModAPI/Spore/IO/StreamCompressionZLib.h index fbbe24df..4a4d6b33 100644 --- a/Spore ModAPI/Spore/IO/StreamCompressionZLib.h +++ b/Spore ModAPI/Spore/IO/StreamCompressionZLib.h @@ -2,8 +2,6 @@ #include -#include - #define StreamCompressionZLibPtr eastl::intrusive_ptr #define StreamDecompressionZLibPtr eastl::intrusive_ptr From 488a4709778f40b4db589c8da70981d75447e5c9 Mon Sep 17 00:00:00 2001 From: 0KepOnline <78259495+0KepOnline@users.noreply.github.com> Date: Sun, 28 Jun 2026 12:47:17 +0300 Subject: [PATCH 6/7] Revert "Replace confusing `PNG` with `MIP` (Model-in-Picture) in `Thumbnail_cImportExport`" This reverts commit 7345808f273139ae12c3735838474be3b667280d. --- Spore ModAPI/SourceCode/App/App.cpp | 14 +++---- Spore ModAPI/SourceCode/DLL/AddressesApp.cpp | 12 +++--- .../Spore/App/Thumbnail_cImportExport.h | 42 ++++++++----------- 3 files changed, 30 insertions(+), 38 deletions(-) diff --git a/Spore ModAPI/SourceCode/App/App.cpp b/Spore ModAPI/SourceCode/App/App.cpp index 9adaf7bd..b0a51316 100644 --- a/Spore ModAPI/SourceCode/App/App.cpp +++ b/Spore ModAPI/SourceCode/App/App.cpp @@ -25,27 +25,27 @@ namespace App auto_METHOD(Thumbnail_cImportExport, bool, FolderPathFromLocale, Args(uint32_t instanceID, eastl::string16& dst, uint32_t tableID), Args(instanceID, dst, tableID)); - auto_METHOD(Thumbnail_cImportExport, bool, SaveMIP, + auto_METHOD(Thumbnail_cImportExport, bool, SavePNG, Args(Resource::ResourceObject* pResource, RenderWare::Raster* pImage, Resource::Database* pDBPF, bool forceReplace, bool disableSteganography), Args(pResource, pImage, pDBPF, forceReplace, disableSteganography)); - auto_METHOD(Thumbnail_cImportExport, bool, ImportMIP, + auto_METHOD(Thumbnail_cImportExport, bool, ImportPNG, Args(const char16_t* path, ResourceKey& key), Args(path, key)); - auto_METHOD(Thumbnail_cImportExport, bool, DecodeMIP, + auto_METHOD(Thumbnail_cImportExport, bool, DecodePNG, Args(IO::IStream* stream, ThumbnailDecodedMetadata& dstMetadata, IStreamPtr& dstDataStream), Args(stream, dstMetadata, dstDataStream)); auto_METHOD_(Thumbnail_cImportExport, bool, SaveFilePaths); - auto_METHOD(Thumbnail_cImportExport, bool, ImportDirectoryMIPs, + auto_METHOD(Thumbnail_cImportExport, bool, ImportDirectoryPNGs, Args(const eastl::string16& path, eastl::hash_set& dstSkippedPaths, int& dstCount), Args(path, dstSkippedPaths, dstCount)); - auto_METHOD(MIPEncoder, bool, WriteImageToStream, - Args(IO::IStream* stream, App::MIPEncoder::Format format), - Args(stream, format)); + auto_METHOD(PngEncoder, bool, EncodePNG, + Args(IO::IStream* stream, int mode), + Args(stream, mode)); auto_STATIC_METHOD_(cIDGenerator, cIDGenerator*, Get); diff --git a/Spore ModAPI/SourceCode/DLL/AddressesApp.cpp b/Spore ModAPI/SourceCode/DLL/AddressesApp.cpp index 3579fa83..4b8a054f 100644 --- a/Spore ModAPI/SourceCode/DLL/AddressesApp.cpp +++ b/Spore ModAPI/SourceCode/DLL/AddressesApp.cpp @@ -407,16 +407,16 @@ namespace App DefineAddress(Get, SelectAddress(0x5F7750, 0x5F79C0)); DefineAddress(GetFolderPath, SelectAddress(0x5F9140, 0x5F92C0)); DefineAddress(FolderPathFromLocale, SelectAddress(0x5F9220, 0x5F93A0)); - DefineAddress(SaveMIP, SelectAddress(0x5FA7E0, 0x5FA960)); - DefineAddress(ImportMIP, SelectAddress(0x5FC240, 0x5FC3C0)); - DefineAddress(DecodeMIP, SelectAddress(0x5FBA10, 0x5FBB90)); + DefineAddress(SavePNG, SelectAddress(0x5FA7E0, 0x5FA960)); + DefineAddress(ImportPNG, SelectAddress(0x5FC240, 0x5FC3C0)); + DefineAddress(DecodePNG, SelectAddress(0x5FBA10, 0x5FBB90)); DefineAddress(SaveFilePaths, SelectAddress(0x5F89C0, 0x5F8B60)); - DefineAddress(ImportDirectoryMIPs, SelectAddress(0x5FC900, 0x5FCA80)); + DefineAddress(ImportDirectoryPNGs, SelectAddress(0x5FC900, 0x5FCA80)); } - namespace Addresses(MIPEncoder) + namespace Addresses(PngEncoder) { - DefineAddress(WriteImageToStream, SelectAddress(0x68E660, 0x68e190)); + DefineAddress(EncodePNG, SelectAddress(0x68E660, 0x68e190)); } namespace Addresses(cLocaleManager) diff --git a/Spore ModAPI/Spore/App/Thumbnail_cImportExport.h b/Spore ModAPI/Spore/App/Thumbnail_cImportExport.h index 65ca7fcd..75f7cfe1 100644 --- a/Spore ModAPI/Spore/App/Thumbnail_cImportExport.h +++ b/Spore ModAPI/Spore/App/Thumbnail_cImportExport.h @@ -13,17 +13,9 @@ namespace App { - struct MIPEncoder { - - enum Format { - kImageFormatPNG, - kImageFormatTGA, - kImageFormatBMP - }; - - bool WriteImageToStream(IO::IStream* outputStream, Format format); - + struct PngEncoder { + bool EncodePNG(IO::IStream* outputStream, int mode); /* 00h */ eastl::vector mPixelBuf; /* 14h */ uint32_t mnImageWidth; @@ -47,7 +39,7 @@ namespace App /* 58h */ eastl::vector mData; /* 6Ch */ int field_6C; }; - ASSERT_SIZE(MIPEncoder, 0x70); + ASSERT_SIZE(PngEncoder, 0x70); struct ThumbnailDecodedMetadata { @@ -91,11 +83,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 `SaveDataFolders.locale`, similar to the one that would + /// Used to obtain a path from a locale file, by default `0x19F76D11.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` Model-in-Picture and saves it, both in the given package and in the + /// Encodes the given resource into a `.png` image 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. @@ -108,7 +100,7 @@ namespace App /// @param forceReplace [Optional] If false (by default), if the `.png` already exists in the folder, it will try writing variants like `(1)`, `(2)`,... /// @param disableSteganography [Optional] If false (by default), the data in the `.png` will be stored in a special way meant to save space. /// @returns `true` on success, `false` if something failed. - bool SaveMIP(Resource::ResourceObject* pResource, RenderWare::Raster* pImage, Resource::Database* database, + bool SavePNG(Resource::ResourceObject* pResource, RenderWare::Raster* pImage, Resource::Database* database, bool forceReplace = false, bool disableSteganography = false); /// Reads the PNG file from the given file path, and adds the creation found within to the Sporepedia if it hasn't been added yet. @@ -116,13 +108,13 @@ namespace App /// @param path The full path to the file being read. /// @param key Resource key to the creation being read. /// @returns 'true' on success, 'false' if something failed. - bool ImportMIP(const char16_t* path, ResourceKey& key); + bool ImportPNG(const char16_t* path, ResourceKey& key); - /// Extracts information from a Model-in-Picture PNG file. It extracts both the metadata, and the data encoded within the image. + /// Extracts information from a 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 - bool DecodeMIP(IO::IStream* stream, ThumbnailDecodedMetadata& dstMetadata, IStreamPtr& dstDataStream); + bool DecodePNG(IO::IStream* stream, ThumbnailDecodedMetadata& dstMetadata, IStreamPtr& dstDataStream); /// Saves the file paths information that keeps track of which PNGs have been loaded. /// It saves it in file `0x473C3E6!0x473C3E6.0x473C3E6` of Resource::SaveAreaID::Server (`Pollination.package`) @@ -137,7 +129,7 @@ namespace App /// @param[out] dstSkippedPaths A list of paths that were skipped because they were already in mPngPathToKey or too many files were loaded /// @param[out] dstCount The number of PNGs that were imported is added to this value /// @returns True if some PNG was loaded, false otherwise - bool ImportDirectoryMIPs(const eastl::string16& directoryPath, eastl::hash_set& dstSkippedPaths, int& dstCount); + bool ImportDirectoryPNGs(const eastl::string16& directoryPath, eastl::hash_set& dstSkippedPaths, int& dstCount); static Thumbnail_cImportExport* Get(); @@ -148,7 +140,7 @@ namespace App /* 44h */ uint32_t mMachineId; // not initialized /* 48h */ eastl::hash_map field_48; /* 68h */ eastl::hash_map field_68; - /* 88h */ MIPEncoder mMipEncoder; + /* 88h */ PngEncoder mPngEncoder; /* F8h */ ResourceKey mCurImage; /* 104h */ eastl::string16 mCellsPath; /* 114h */ eastl::string16 mCreaturesPath; @@ -167,15 +159,15 @@ namespace App DeclareAddress(Get); DeclareAddress(GetFolderPath); DeclareAddress(FolderPathFromLocale); - DeclareAddress(SaveMIP); - DeclareAddress(ImportMIP); - DeclareAddress(DecodeMIP); // 0x5FBA10 0x5FBB90 + DeclareAddress(SavePNG); + DeclareAddress(ImportPNG); + DeclareAddress(DecodePNG); // 0x5FBA10 0x5FBB90 DeclareAddress(SaveFilePaths); // 0x5F89C0 0x5F8B60 - DeclareAddress(ImportDirectoryMIPs); // 0x5FC900 0x5FCA80 + DeclareAddress(ImportDirectoryPNGs); // 0x5FC900 0x5FCA80 } - namespace Addresses(MIPEncoder) + namespace Addresses(PngEncoder) { - DeclareAddress(WriteImageToStream); // 0x68E660 0x68e190 + DeclareAddress(EncodePNG); // 0x68E660 0x68e190 } } From 41354dc07f2e565be0260971cf702f5c4b935b64 Mon Sep 17 00:00:00 2001 From: 0KepOnline <78259495+0KepOnline@users.noreply.github.com> Date: Sun, 28 Jun 2026 13:01:28 +0300 Subject: [PATCH 7/7] Limited update of `Thumbnail_cImportExport` --- Spore ModAPI/SourceCode/App/App.cpp | 6 +++--- Spore ModAPI/SourceCode/DLL/AddressesApp.cpp | 3 ++- Spore ModAPI/Spore/App/Thumbnail_cImportExport.h | 16 +++++++++++----- 3 files changed, 16 insertions(+), 9 deletions(-) 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/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 } }