[HRP] Added support for reading .rix images larger than 640x480

This commit is contained in:
NovaRain
2021-12-29 06:20:20 +08:00
parent 921db36478
commit a30f640eb9
+51 -14
View File
@@ -6,6 +6,7 @@
#include "..\main.h" #include "..\main.h"
#include "..\FalloutEngine\Fallout2.h" #include "..\FalloutEngine\Fallout2.h"
#include "..\Utils.h"
#include "..\Modules\Graphics.h" #include "..\Modules\Graphics.h"
#include "Image.h" #include "Image.h"
@@ -22,6 +23,10 @@ namespace sf = sfall;
// 2 - image will stretch to fill the screen // 2 - image will stretch to fill the screen
long SplashScreen::SPLASH_SCRN_SIZE; 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) { 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; RECT rect;
long w = Setting::ScreenWidth(); 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 // TODO: Load an alternative 32-bit BMP image or DirectX texture
// stretch texture for DirectX // 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 || srcWidth > w || srcHeight > h) {
if (SplashScreen::SPLASH_SCRN_SIZE == 1) { if (SplashScreen::SPLASH_SCRN_SIZE == 1) {
x = 0; 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); sf::Graphics::UpdateDDSurface(resizeBuff, w, h, w, &rect);
delete[] resizeBuff; 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 // 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); long index = Image::GetDarkColor(palette);
if (index != 0) sf::Graphics::BackgroundClearColor(index); 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() { static void __declspec(naked) game_splash_screen_hook() {
__asm { __asm {
call fo::funcoffs::db_fclose_; mov ecx, eax; // file
mov ecx, ebp; // .rix palette mov edx, ebp; // .rix palette
jmp Clear; call ReadRIX;
jmp fo::funcoffs::db_fclose_;
} }
} }