From a30f640eb98ce35d8b81f2f53db9e25228e6fdaa Mon Sep 17 00:00:00 2001 From: NovaRain Date: Wed, 29 Dec 2021 06:20:20 +0800 Subject: [PATCH] [HRP] Added support for reading .rix images larger than 640x480 --- sfall/HRP/SplashScreen.cpp | 65 ++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/sfall/HRP/SplashScreen.cpp b/sfall/HRP/SplashScreen.cpp index 08265680..2d4e1383 100644 --- a/sfall/HRP/SplashScreen.cpp +++ b/sfall/HRP/SplashScreen.cpp @@ -6,6 +6,7 @@ #include "..\main.h" #include "..\FalloutEngine\Fallout2.h" +#include "..\Utils.h" #include "..\Modules\Graphics.h" #include "Image.h" @@ -22,6 +23,10 @@ namespace sf = sfall; // 2 - image will stretch to fill the screen long SplashScreen::SPLASH_SCRN_SIZE; +static WORD rixWidth; +static WORD rixHeight; +static BYTE* rixBuffer; + static void __cdecl game_splash_screen_hack_scr_blit(BYTE* srcPixels, long srcWidth, long srcHeight, long srcX, long srcY, long width, long height, long x, long y) { RECT rect; long w = Setting::ScreenWidth(); @@ -29,6 +34,13 @@ static void __cdecl game_splash_screen_hack_scr_blit(BYTE* srcPixels, long srcWi // TODO: Load an alternative 32-bit BMP image or DirectX texture // stretch texture for DirectX + + if (rixBuffer) { + srcWidth = rixWidth; + srcHeight = rixHeight; + srcPixels = rixBuffer; + } + if (SplashScreen::SPLASH_SCRN_SIZE || srcWidth > w || srcHeight > h) { if (SplashScreen::SPLASH_SCRN_SIZE == 1) { x = 0; @@ -50,30 +62,55 @@ static void __cdecl game_splash_screen_hack_scr_blit(BYTE* srcPixels, long srcWi sf::Graphics::UpdateDDSurface(resizeBuff, w, h, w, &rect); delete[] resizeBuff; - return; + } else { + // original size to center screen + + rect.left = ((Setting::ScreenWidth() - srcWidth) / 2) + x; + rect.right = (rect.left + srcWidth) - 1; + + rect.top = ((Setting::ScreenHeight() - srcHeight) / 2) + y; + rect.bottom = (rect.top + srcHeight) - 1; + + sf::Graphics::UpdateDDSurface(srcPixels, srcWidth, srcHeight, srcWidth, &rect); + } + if (rixBuffer) { + delete[] rixBuffer; + rixBuffer = nullptr; } - // original size to center screen - - rect.left = ((Setting::ScreenWidth() - srcWidth) / 2) + x; - rect.right = (rect.left + srcWidth) - 1 ; - - rect.top = ((Setting::ScreenHeight() - srcHeight) / 2) + y; - rect.bottom = (rect.top + srcHeight) - 1; - - sf::Graphics::UpdateDDSurface(srcPixels, srcWidth, srcHeight, srcWidth, &rect); } // Fixes colored screen border when the index 0 of the palette contains a color with a non-black (zero) value -static void __fastcall Clear(fo::PALETTE* palette) { +static void Clear(fo::PALETTE* palette) { long index = Image::GetDarkColor(palette); if (index != 0) sf::Graphics::BackgroundClearColor(index); } +static fo::DbFile* __fastcall ReadRIX(fo::DbFile* file, fo::PALETTE* palette) { + fo::func::db_fseek(file, 4, SEEK_SET); + fo::func::db_freadShort(file, &rixWidth); + fo::func::db_freadShort(file, &rixHeight); + + rixWidth = sf::ByteSwapW(rixWidth); + rixHeight = sf::ByteSwapW(rixHeight); + + if (rixWidth != 640 || rixHeight != 480) { + size_t size = rixWidth * rixHeight; + rixBuffer = new BYTE[size]; + + fo::func::db_fseek(file, 4 + 768, SEEK_CUR); + fo::func::db_fread(rixBuffer, 1, size, file); + } + Clear(palette); + + return file; +} + static void __declspec(naked) game_splash_screen_hook() { __asm { - call fo::funcoffs::db_fclose_; - mov ecx, ebp; // .rix palette - jmp Clear; + mov ecx, eax; // file + mov edx, ebp; // .rix palette + call ReadRIX; + jmp fo::funcoffs::db_fclose_; } }