diff --git a/SonicRModLoader/FileReplacement.h b/SonicRModLoader/FileReplacement.h index 0146acd..b07ffa2 100644 --- a/SonicRModLoader/FileReplacement.h +++ b/SonicRModLoader/FileReplacement.h @@ -2,6 +2,7 @@ #define WIN32_LEAN_AND_MEAN #include +#include #include "FileMap.hpp" extern FileMap fileMap; diff --git a/SonicRModLoader/SonicRModLoader.vcxproj b/SonicRModLoader/SonicRModLoader.vcxproj index 6527c06..e26e769 100644 --- a/SonicRModLoader/SonicRModLoader.vcxproj +++ b/SonicRModLoader/SonicRModLoader.vcxproj @@ -103,6 +103,7 @@ + @@ -117,6 +118,7 @@ Create Create + diff --git a/SonicRModLoader/SonicRModLoader.vcxproj.filters b/SonicRModLoader/SonicRModLoader.vcxproj.filters index 50ff39d..74d9030 100644 --- a/SonicRModLoader/SonicRModLoader.vcxproj.filters +++ b/SonicRModLoader/SonicRModLoader.vcxproj.filters @@ -51,6 +51,9 @@ Header Files + + Header Files + @@ -80,5 +83,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/SonicRModLoader/Textures.cpp b/SonicRModLoader/Textures.cpp new file mode 100644 index 0000000..52ca565 --- /dev/null +++ b/SonicRModLoader/Textures.cpp @@ -0,0 +1,38 @@ +#include "stdafx.h" +#include +#include +#include +#include "TextConv.hpp" +#include "FileReplacement.h" +#include "FileSystem.h" +#include "Textures.h" +#include "SonicRModLoader.h" + +using std::string; +using namespace Gdiplus; + +const char *extensions[] = { ".png", ".gif", ".bmp" }; + +signed int __cdecl D3D_ReadTPageRGB_r(const char *FilePath, char *Buffer, int BytesPerChannel) +{ + string fp = FilePath; + for (size_t i = 0; i < LengthOfArray(extensions); i++) + { + ReplaceFileExtension(fp, extensions[i]); + string f2 = fileMap.replaceFile(fp.c_str()); + if (FileExists(f2)) + { + Bitmap *bmp = Bitmap::FromFile(MBStoUTF16(f2, CP_ACP).c_str()); + Rect rect(0, 0, bmp->GetWidth(), bmp->GetHeight()); + BitmapData bmpd; + bmp->LockBits(&rect, ImageLockModeRead, PixelFormat24bppRGB, &bmpd); + memcpy(Buffer, bmpd.Scan0, abs(bmpd.Stride) * bmpd.Height); + bmp->UnlockBits(&bmpd); + delete bmp; + for (int p = 0; p < BytesPerChannel; p++) + std::swap(Buffer[p * 3], Buffer[p * 3 + 2]); + return 1; + } + } + return D3D_ReadTPageRGB(FilePath, Buffer, BytesPerChannel); +} \ No newline at end of file diff --git a/SonicRModLoader/Textures.h b/SonicRModLoader/Textures.h new file mode 100644 index 0000000..eba8e86 --- /dev/null +++ b/SonicRModLoader/Textures.h @@ -0,0 +1,3 @@ +#pragma once + +signed int D3D_ReadTPageRGB_r(const char * FilePath, char * Buffer, int BytesPerChannel); diff --git a/SonicRModLoader/dllmain.cpp b/SonicRModLoader/dllmain.cpp index 61547d3..e4bb68f 100644 --- a/SonicRModLoader/dllmain.cpp +++ b/SonicRModLoader/dllmain.cpp @@ -20,6 +20,7 @@ #include "Events.h" #include "Music.h" #include "Widescreen.h" +#include "Textures.h" #include "SonicRModLoader.h" using std::ifstream; @@ -395,6 +396,9 @@ int __stdcall InitMods(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmd WriteCall((void *)0x43E901, D3D_Render2DObject_AlignLeft); // / WriteCall((void *)0x43E928, D3D_Render2DObject_AlignLeft); // 5 + // Textures + WriteCall((void*)0x407A30, D3D_ReadTPageRGB_r); + // Map of files to replace and/or swap. // This is done with a second map instead of fileMap directly // in order to handle multiple mods. diff --git a/SonicRModLoader/include/SonicRModLoader.h b/SonicRModLoader/include/SonicRModLoader.h index 6d56cb2..576c50a 100644 --- a/SonicRModLoader/include/SonicRModLoader.h +++ b/SonicRModLoader/include/SonicRModLoader.h @@ -49,6 +49,7 @@ DataPointer(WNDCLASSA, WndClass, 0x4B5398); DataPointer(HINSTANCE, hInstance, 0x4B53C4); DataPointer(HWND, hWnd, 0x4B53C8); DataPointer(int, CurrentMusicTrack, 0x502360); +DataArray(char *, TPageBuffers, 0x5D359C, 1); DataPointer(int, Windowed, 0x5EDD24); DataPointer(int, FrameEndTime, 0x7349F8); DataPointer(int, FrameStartTime, 0x7356B0); @@ -59,6 +60,10 @@ static void(__cdecl *(__cdecl *const DisplayFatalErrorWithTrace)(char *file, int static void(__cdecl *(__cdecl *const PrintDebugWithTrace)(char *file, int line))(char *, ...) = (decltype(PrintDebugWithTrace))0x404BC0; FunctionPointer(int, GetTime, (), 0x404D30); FunctionPointer(int, PrintDebug, (const char *fmt, ...), 0x404D80); +FunctionPointer(int, D3D_ReadTPageRGB, (const char *FilePath, char *Buffer, int BytesPerChannel), 0x407950); +FunctionPointer(void, D3D_LoadTPageRGB, (int page, char *filename), 0x407A00); +FunctionPointer(void, CreateTPageBuffer, (int page), 0x442720); +FunctionPointer(void, D3D_ReleaseTexture, (int page), 0x4427D0); VoidFunc(CalculateClockSpeed, 0x4332B0); FunctionPointer(void, ProcessCommandLine, (const char *a1), 0x433400); FunctionPointer(int, MainGameLoop, (), 0x43AA60);