mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
(WIP) Added DirectDraw graphics mode for built-in HRP
Moved some code from Graphics.cpp to WinProc.cpp
This commit is contained in:
@@ -46,11 +46,6 @@ static void __cdecl main_death_scene_hook_buf_to_buf(fo::FrmData* frm, long w, l
|
||||
long x = 0;
|
||||
long y = 0;
|
||||
Image::GetAspectSize(width, height, &x, &y, w, h);
|
||||
|
||||
//if (x >= w) { // extract x/y image position
|
||||
// y = x / w;
|
||||
// x -= y * w;
|
||||
//}
|
||||
if (x || y) {
|
||||
dst += x + (y * Setting::ScreenWidth());
|
||||
}
|
||||
|
||||
+14
-6
@@ -8,9 +8,10 @@
|
||||
|
||||
#include "..\main.h"
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
#include "..\Utils.h"
|
||||
#include "..\Modules\LoadOrder.h"
|
||||
#include "..\Translate.h"
|
||||
#include "..\Utils.h"
|
||||
#include "..\Modules\Graphics.h"
|
||||
#include "..\Modules\LoadOrder.h"
|
||||
|
||||
#include "viewmap\ViewMap.h"
|
||||
#include "SplashScreen.h"
|
||||
@@ -45,6 +46,8 @@ static bool SCALE_2X;
|
||||
static long SCR_WIDTH = 640;
|
||||
static long SCR_HEIGHT = 480;
|
||||
|
||||
static long GRAPHICS_MODE = 2;
|
||||
|
||||
bool Setting::IsEnabled() { return enabled; }
|
||||
long Setting::ScreenWidth() { return SCR_WIDTH; }
|
||||
long Setting::ScreenHeight() { return SCR_HEIGHT; }
|
||||
@@ -110,7 +113,7 @@ static bool DisableExtHRP(const char* runFileName, std::string &cmdline) {
|
||||
DWORD restore1[10] = {0};
|
||||
_fwrite_nolock(restore1, 4, sizeof(restore1), ft);
|
||||
|
||||
fclose(ft);
|
||||
std::fclose(ft);
|
||||
cmdline.append(" -restart");
|
||||
|
||||
MessageBoxA(0, "High Resolution Patch has been successfully deactivated.", "sfall", MB_TASKMODAL | MB_ICONINFORMATION);
|
||||
@@ -223,8 +226,6 @@ void Setting::init(const char* exeFileName, std::string &cmdline) {
|
||||
|
||||
// Read High Resolution config
|
||||
|
||||
// = IniReader::GetInt("Main", "WINDOWED", 0, f2ResIni);
|
||||
// = IniReader::GetInt("Main", "WINDOWED_FULLSCREEN", 0, f2ResIni);
|
||||
/*
|
||||
if (IniReader::GetInt("Main", "SCALE_2X", 0, f2ResIni)) {
|
||||
SCR_WIDTH /= 2;
|
||||
@@ -236,7 +237,14 @@ void Setting::init(const char* exeFileName, std::string &cmdline) {
|
||||
SCALE_2X = true;
|
||||
};
|
||||
*/
|
||||
//gDirectDrawMode = IniReader::GetInt("Main", "GRAPHICS_MODE", 2, f2ResIni) == 1;
|
||||
|
||||
int windowed = (sf::IniReader::GetInt("Main", "WINDOWED", 0, f2ResIni) != 0) ? 1 : 0;
|
||||
if (windowed && sf::IniReader::GetInt("Main", "WINDOWED_FULLSCREEN", 0, f2ResIni)) windowed += 1;
|
||||
|
||||
int gMode = sf::IniReader::GetInt("Main", "GRAPHICS_MODE", 2, f2ResIni);
|
||||
if (gMode < 0 || gMode > 2) gMode = 2;
|
||||
if (gMode <= 1) sf::Graphics::mode = 1 + windowed; // DD7: 1 or 2/3 (vanilla 16(24) bit)
|
||||
if (gMode == 2) sf::Graphics::mode = 4 + windowed; // DX9: 4 or 5/6 (sfall)
|
||||
|
||||
MainMenuScreen::SCALE_BUTTONS_AND_TEXT_MENU = (sf::IniReader::GetInt("MAINMENU", "SCALE_BUTTONS_AND_TEXT_MENU", 0, f2ResIni) != 0);
|
||||
MainMenuScreen::USE_HIRES_IMAGES = (sf::IniReader::GetInt("MAINMENU", "USE_HIRES_IMAGES", 1, f2ResIni) != 0);
|
||||
|
||||
+36
-11
@@ -21,6 +21,7 @@ namespace sf = sfall;
|
||||
long MoviesScreen::MOVIE_SIZE;
|
||||
|
||||
static RECT movieToSize;
|
||||
//static bool useDDraw = false;
|
||||
|
||||
static void __fastcall SetMovieSize() {
|
||||
long sWidth = Setting::ScreenWidth();
|
||||
@@ -68,7 +69,7 @@ static void __declspec(naked) nfConfig_hack() {
|
||||
}
|
||||
|
||||
// surface: _nf_mve_buf1
|
||||
static long __cdecl movie_MVE_ShowFrame(IDirectDrawSurface* surface, int bW, int bH, int x, int y, int w, int h) {
|
||||
static void __cdecl movie_MVE_ShowFrame(IDirectDrawSurface* surface, int bW, int bH, int x, int y, int w, int h) {
|
||||
RECT movieSize;
|
||||
movieSize.left = x;
|
||||
movieSize.right = x + bW;
|
||||
@@ -82,7 +83,27 @@ static long __cdecl movie_MVE_ShowFrame(IDirectDrawSurface* surface, int bW, int
|
||||
//FO_VAR_lastMovieBW = bW
|
||||
//FO_VAR_lastMovieBH = bH
|
||||
|
||||
return surface->Blt(&movieToSize, surface, &movieSize, MoviesScreen::MOVIE_SIZE, 0); // for sfall DX9
|
||||
surface->Blt(&movieToSize, surface, &movieSize, MoviesScreen::MOVIE_SIZE, 0); // for sfall DX9
|
||||
}
|
||||
|
||||
// surface: _nf_mve_buf1
|
||||
static void __cdecl movieShowFrame(IDirectDrawSurface* surface, int bW, int bH, int x, int y, int w, int h) {
|
||||
//if (fo::var::getInt(FO_VAR_GNWWin) == -1) return;
|
||||
|
||||
RECT movieSize;
|
||||
movieSize.left = x;
|
||||
movieSize.right = x + bW;
|
||||
movieSize.top = y;
|
||||
movieSize.bottom = y + bH;
|
||||
|
||||
fo::var::setInt(FO_VAR_lastMovieX) = movieToSize.left;
|
||||
fo::var::setInt(FO_VAR_lastMovieY) = movieToSize.top;
|
||||
fo::var::setInt(FO_VAR_lastMovieW) = movieToSize.right - movieToSize.left;
|
||||
fo::var::setInt(FO_VAR_lastMovieH) = movieToSize.bottom - movieToSize.top;
|
||||
//FO_VAR_lastMovieBW = bW
|
||||
//FO_VAR_lastMovieBH = bH
|
||||
|
||||
//surface->Blt(&movieToSize, surface, &movieSize, MoviesScreen::MOVIE_SIZE, 0);
|
||||
}
|
||||
|
||||
// Adjust Y position
|
||||
@@ -146,6 +167,17 @@ skip:
|
||||
}
|
||||
}
|
||||
|
||||
// Direct output to texture is used for DirectX9, and buffered method (output to GNWWin window) is used for DirectDraw
|
||||
void MoviesScreen::SetDrawMode(bool mode) {
|
||||
//useDDraw = mode;
|
||||
// movieStart_ hack
|
||||
if (mode) {
|
||||
sf::SafeWrite8(0x487781, sf::CodeType::JumpShort); // force Buffered
|
||||
} else {
|
||||
sf::SafeWrite16(0x487781, 0x9090); // force Direct
|
||||
}
|
||||
}
|
||||
|
||||
void MoviesScreen::init() {
|
||||
|
||||
if (MOVIE_SIZE < 0) MOVIE_SIZE = 0;
|
||||
@@ -158,20 +190,13 @@ void MoviesScreen::init() {
|
||||
//sf::SafeWrite8(0x44E7DE, 55); // for debugging
|
||||
|
||||
// movieStart_
|
||||
// Direct output to texture is used for DirectX9, and buffered method (output to GNWWin window) is used for DirectDraw
|
||||
if (0) {
|
||||
sf::SafeWrite8(0x487781, sf::CodeType::JumpShort); // force Buffered
|
||||
} else {
|
||||
sf::SafeWrite16(0x487781, 0x9090); // force Direct
|
||||
}
|
||||
|
||||
sf::SafeWrite32(0x4877D0, (DWORD)&movie_MVE_ShowFrame); // replace movie_MVE_ShowFrame_ with sfall function
|
||||
sf::SafeWrite32(0x4877D0, (DWORD)&movie_MVE_ShowFrame); // replace engine movie_MVE_ShowFrame_ with sfall function (for DX9)
|
||||
sf::SafeWrite32(0x487813, (DWORD)&movieShowFrame); // replace engine movieShowFrame_ with sfall function (for DD7)
|
||||
|
||||
sf::MakeCall(0x4F5D40, nfConfig_hack);
|
||||
|
||||
// openSubtitle_
|
||||
sf::HookCall(0x48738E, Setting::ScreenWidth); // replace windowGetXres_
|
||||
|
||||
// doSubtitle_ hacks
|
||||
sf::SafeWrite32(0x487580, Setting::ScreenHeight());
|
||||
sf::HookCall(0x4875BE, doSubtitle_hook);
|
||||
|
||||
@@ -12,8 +12,10 @@ namespace HRP
|
||||
class MoviesScreen {
|
||||
public:
|
||||
static void init();
|
||||
|
||||
|
||||
static long MOVIE_SIZE;
|
||||
|
||||
static void SetDrawMode(bool mode);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+62
-171
@@ -18,14 +18,16 @@
|
||||
|
||||
#include "..\main.h"
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
#include "..\InputFuncs.h"
|
||||
#include "..\version.h"
|
||||
//#include "..\InputFuncs.h"
|
||||
#include "..\WinProc.h"
|
||||
#include "LoadGameHook.h"
|
||||
#include "ScriptShaders.h"
|
||||
|
||||
#include "SubModules\DirectDraw.h"
|
||||
#include "SubModules\WindowRender.h"
|
||||
|
||||
#include "..\HRP\Init.h"
|
||||
#include "..\HRP\MoviesScreen.h"
|
||||
|
||||
#include "Graphics.h"
|
||||
|
||||
@@ -49,6 +51,9 @@ IDirectDrawPalette* primaryPalette = nullptr; // aka _GNW95_DDPrimaryPalette
|
||||
static DWORD ResWidth;
|
||||
static DWORD ResHeight;
|
||||
|
||||
static DWORD gWidth;
|
||||
static DWORD gHeight;
|
||||
|
||||
DWORD Graphics::GPUBlt;
|
||||
DWORD Graphics::mode;
|
||||
bool Graphics::IsWindowMode;
|
||||
@@ -56,9 +61,6 @@ bool Graphics::IsWindowMode;
|
||||
bool Graphics::PlayAviMovie = false;
|
||||
bool Graphics::AviMovieWidthFit = false;
|
||||
|
||||
//static DWORD yoffset;
|
||||
//static DWORD xoffset;
|
||||
|
||||
bool DeviceLost = false;
|
||||
//static bool mainTexLock = false; // for preventing a crash during the locked state of the texture
|
||||
static char textureFilter; // 1 - auto, 2 - force
|
||||
@@ -67,34 +69,10 @@ static DDSURFACEDESC surfaceDesc;
|
||||
static DDSURFACEDESC mveDesc;
|
||||
static D3DSURFACE_DESC movieDesc;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
static struct PALCOLOR {
|
||||
union {
|
||||
DWORD xRGB;
|
||||
struct {
|
||||
BYTE R;
|
||||
BYTE G;
|
||||
BYTE B;
|
||||
BYTE x;
|
||||
};
|
||||
};
|
||||
} *palette;
|
||||
#pragma pack(pop)
|
||||
|
||||
//static bool paletteInit = false;
|
||||
|
||||
static DWORD gWidth;
|
||||
static DWORD gHeight;
|
||||
|
||||
static long moveWindowKey[2];
|
||||
static DirectDraw::PALCOLOR* palette;
|
||||
|
||||
static bool windowInit = false;
|
||||
static long windowLeft = 0;
|
||||
static long windowTop = 0;
|
||||
static HWND window;
|
||||
static DWORD windowStyle = WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU;
|
||||
|
||||
static int windowData;
|
||||
|
||||
static DWORD ShaderVersion;
|
||||
|
||||
@@ -146,16 +124,6 @@ static VertexFormat ShaderVertices[] = {
|
||||
{639.5, 479.5, 0, 1, 1, 1} // 3 - bottom right
|
||||
};
|
||||
|
||||
HWND Graphics::GetFalloutWindowInfo(RECT* rect) {
|
||||
if (rect) {
|
||||
rect->left = windowLeft;
|
||||
rect->top = windowTop;
|
||||
rect->right = gWidth;
|
||||
rect->bottom = gHeight;
|
||||
}
|
||||
return window;
|
||||
}
|
||||
|
||||
long Graphics::GetGameWidthRes() {
|
||||
return (fo::var::scr_size.offx - fo::var::scr_size.x) + 1;
|
||||
}
|
||||
@@ -175,14 +143,6 @@ static void WindowInit() {
|
||||
ScriptShaders::LoadGlobalShader();
|
||||
}
|
||||
|
||||
static void SetWindowToCenter() {
|
||||
RECT desktop;
|
||||
GetWindowRect(GetDesktopWindow(), &desktop);
|
||||
|
||||
windowLeft = (desktop.right / 2) - (gWidth / 2);
|
||||
windowTop = (desktop.bottom / 2) - (gHeight / 2);
|
||||
}
|
||||
|
||||
// pixel size for the current game resolution
|
||||
const float* Graphics::rcpresGet() {
|
||||
return rcpres;
|
||||
@@ -264,7 +224,7 @@ static void ResetDevice(bool create) {
|
||||
"Texture format error", MB_TASKMODAL | MB_ICONWARNING);
|
||||
Graphics::GPUBlt = 0;
|
||||
}
|
||||
if (Graphics::GPUBlt == 0) palette = new PALCOLOR[256];
|
||||
if (Graphics::GPUBlt == 0) palette = new DirectDraw::PALCOLOR[256];
|
||||
|
||||
#if !(NDEBUG) && !(_DEBUG)
|
||||
D3DXCreateFontA(d3d9Device, 24, 0, 500, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial", &font); // create a font
|
||||
@@ -379,48 +339,7 @@ static void DrawFPS() {}
|
||||
#endif
|
||||
|
||||
static void Present() {
|
||||
if ((moveWindowKey[0] != 0 && KeyDown(moveWindowKey[0])) ||
|
||||
(moveWindowKey[1] != 0 && KeyDown(moveWindowKey[1])))
|
||||
{
|
||||
int winX, winY;
|
||||
GetMouse(&winX, &winY);
|
||||
windowLeft += winX;
|
||||
windowTop += winY;
|
||||
|
||||
RECT r, r2;
|
||||
r.left = windowLeft;
|
||||
r.right = windowLeft + gWidth;
|
||||
r.top = windowTop;
|
||||
r.bottom = windowTop + gHeight;
|
||||
AdjustWindowRect(&r, WS_CAPTION | WS_BORDER, false);
|
||||
|
||||
r.right -= (r.left - windowLeft);
|
||||
r.left = windowLeft;
|
||||
r.bottom -= (r.top - windowTop);
|
||||
r.top = windowTop;
|
||||
|
||||
if (GetWindowRect(GetShellWindow(), &r2)) {
|
||||
if (r.right > r2.right) {
|
||||
DWORD move = r.right - r2.right;
|
||||
windowLeft -= move;
|
||||
r.right -= move;
|
||||
} else if (r.left < r2.left) {
|
||||
DWORD move = r2.left - r.left;
|
||||
windowLeft += move;
|
||||
r.right += move;
|
||||
}
|
||||
if (r.bottom > r2.bottom) {
|
||||
DWORD move = r.bottom - r2.bottom;
|
||||
windowTop -= move;
|
||||
r.bottom -= move;
|
||||
} else if (r.top < r2.top) {
|
||||
DWORD move = r2.top - r.top;
|
||||
windowTop += move;
|
||||
r.bottom += move;
|
||||
}
|
||||
}
|
||||
MoveWindow(window, windowLeft, windowTop, r.right - windowLeft, r.bottom - windowTop, true);
|
||||
}
|
||||
WinProc::Moving();
|
||||
|
||||
if (d3d9Device->Present(0, 0, 0, 0) == D3DERR_DEVICELOST) {
|
||||
#ifndef NDEBUG
|
||||
@@ -969,9 +888,9 @@ public:
|
||||
}
|
||||
// copy and swap color B <> R
|
||||
do {
|
||||
((PALCOLOR*)pal.pBits)[b].R = destPal->R << 2;
|
||||
((PALCOLOR*)pal.pBits)[b].G = destPal->G << 2;
|
||||
((PALCOLOR*)pal.pBits)[b].B = destPal->B << 2;
|
||||
((DirectDraw::PALCOLOR*)pal.pBits)[b].R = destPal->R << 2;
|
||||
((DirectDraw::PALCOLOR*)pal.pBits)[b].G = destPal->G << 2;
|
||||
((DirectDraw::PALCOLOR*)pal.pBits)[b].B = destPal->B << 2;
|
||||
destPal++;
|
||||
b++;
|
||||
} while (--c);
|
||||
@@ -1074,36 +993,23 @@ public:
|
||||
HRESULT __stdcall RestoreDisplayMode() { return DD_OK; }
|
||||
|
||||
HRESULT __stdcall SetCooperativeLevel(HWND a, DWORD b) { // called 0x4CB005 GNW95_init_DirectDraw_
|
||||
char windowTitle[128];
|
||||
window = a;
|
||||
WinProc::SetHWND(window);
|
||||
|
||||
if (!d3d9Device) {
|
||||
CoInitialize(0);
|
||||
ResetDevice(true); // create
|
||||
}
|
||||
dlog("Creating D3D9 Device window...", DL_MAIN);
|
||||
if (d3d9Device) return DD_OK;
|
||||
|
||||
if (ResWidth != gWidth || ResHeight != gHeight) {
|
||||
std::sprintf(windowTitle, "%s @sfall " VERSION_STRING " %ix%i >> %ix%i", (const char*)0x50AF08, ResWidth, ResHeight, gWidth, gHeight);
|
||||
} else {
|
||||
std::sprintf(windowTitle, "%s @sfall " VERSION_STRING, (const char*)0x50AF08);
|
||||
}
|
||||
SetWindowTextA(a, windowTitle);
|
||||
CoInitialize(0);
|
||||
ResetDevice(true); // create
|
||||
|
||||
//dlog("Creating D3D9 Device window...", DL_MAIN);
|
||||
WinProc::SetTitle(gWidth, gHeight);
|
||||
|
||||
if (Graphics::mode >= 5) {
|
||||
SetWindowLongA(a, GWL_STYLE, windowStyle);
|
||||
RECT r;
|
||||
r.left = 0;
|
||||
r.right = gWidth;
|
||||
r.top = 0;
|
||||
r.bottom = gHeight;
|
||||
AdjustWindowRect(&r, windowStyle, false);
|
||||
r.right -= r.left;
|
||||
r.bottom -= r.top;
|
||||
SetWindowPos(a, HWND_NOTOPMOST, windowLeft, windowTop, r.right, r.bottom, SWP_FRAMECHANGED | SWP_SHOWWINDOW);
|
||||
long windowStyle = (Graphics::mode == 5) ? (WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU) : WS_OVERLAPPED;
|
||||
WinProc::SetStyle(windowStyle);
|
||||
}
|
||||
|
||||
dlogr(" Done", DL_MAIN);
|
||||
//dlogr(" Done", DL_MAIN);
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
@@ -1161,34 +1067,10 @@ HRESULT __stdcall InitFakeDirectDrawCreate(void*, IDirectDraw** b, void*) {
|
||||
else if (Graphics::GPUBlt == 2) Graphics::GPUBlt = 0; // Use CPU
|
||||
|
||||
if (Graphics::mode == 5) {
|
||||
moveWindowKey[0] = IniReader::GetConfigInt("Input", "WindowScrollKey", 0);
|
||||
if (moveWindowKey[0] < 0) {
|
||||
switch (moveWindowKey[0]) {
|
||||
case -1:
|
||||
moveWindowKey[0] = DIK_LCONTROL;
|
||||
moveWindowKey[1] = DIK_RCONTROL;
|
||||
break;
|
||||
case -2:
|
||||
moveWindowKey[0] = DIK_LMENU;
|
||||
moveWindowKey[1] = DIK_RMENU;
|
||||
break;
|
||||
case -3:
|
||||
moveWindowKey[0] = DIK_LSHIFT;
|
||||
moveWindowKey[1] = DIK_RSHIFT;
|
||||
break;
|
||||
default:
|
||||
moveWindowKey[0] = 0;
|
||||
}
|
||||
} else {
|
||||
moveWindowKey[0] &= 0xFF;
|
||||
}
|
||||
windowData = IniReader::GetConfigInt("Graphics", "WindowData", -1);
|
||||
if (windowData > 0) {
|
||||
windowLeft = windowData >> 16;
|
||||
windowTop = windowData & 0xFFFF;
|
||||
} else if (windowData == -1) {
|
||||
SetWindowToCenter();
|
||||
}
|
||||
WinProc::SetMoveKeys();
|
||||
|
||||
WinProc::SetSize(gWidth, gHeight);
|
||||
WinProc::LoadPosition();
|
||||
}
|
||||
|
||||
rcpres[0] = 1.0f / (float)gWidth;
|
||||
@@ -1275,39 +1157,49 @@ void __stdcall Graphics::ForceGraphicsRefresh(DWORD d) {
|
||||
}
|
||||
|
||||
void Graphics::BackgroundClearColor(long indxColor) {
|
||||
if (GPUBlt) {
|
||||
D3DLOCKED_RECT buf;
|
||||
mainTex->LockRect(0, &buf, 0, D3DLOCK_DISCARD);
|
||||
std::memset(buf.pBits, indxColor, ResWidth * ResHeight);
|
||||
mainTex->UnlockRect(0);
|
||||
if (Graphics::mode >= 4) {
|
||||
if (GPUBlt) {
|
||||
D3DLOCKED_RECT buf;
|
||||
mainTex->LockRect(0, &buf, 0, D3DLOCK_DISCARD);
|
||||
std::memset(buf.pBits, indxColor, ResWidth * ResHeight);
|
||||
mainTex->UnlockRect(0);
|
||||
} else {
|
||||
DDSURFACEDESC desc;
|
||||
primarySurface->GetSurfaceDesc(&desc);
|
||||
std::memset(desc.lpSurface, indxColor, ResWidth * ResHeight);
|
||||
}
|
||||
} else {
|
||||
DDSURFACEDESC desc;
|
||||
primarySurface->GetSurfaceDesc(&desc);
|
||||
std::memset(desc.lpSurface, indxColor, ResWidth * ResHeight);
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::init() {
|
||||
Graphics::mode = IniReader::GetConfigInt("Graphics", "Mode", 0);
|
||||
int gMode = IniReader::GetConfigInt("Graphics", "Mode", 4);
|
||||
if (gMode >= 4) Graphics::mode = gMode;
|
||||
|
||||
if (Graphics::mode == 6) {
|
||||
windowStyle = WS_OVERLAPPED;
|
||||
} else if (Graphics::mode != 4 && Graphics::mode != 5) {
|
||||
//windowStyle = WS_OVERLAPPED;
|
||||
} else if (Graphics::mode < 0 && Graphics::mode > 5) {
|
||||
Graphics::mode = 0;
|
||||
}
|
||||
IsWindowMode = (mode == 5 || mode == 6);
|
||||
//IsWindowMode = (mode == 2 || mode == 5 || mode == 6);
|
||||
|
||||
if (Graphics::mode) {
|
||||
// DirectX9 mode
|
||||
if (Graphics::mode >= 4) {
|
||||
dlog("Applying DX9 graphics patch.", DL_INIT);
|
||||
#define _DLL_NAME "d3dx9_43.dll"
|
||||
HMODULE h = LoadLibraryEx(_DLL_NAME, 0, LOAD_LIBRARY_AS_DATAFILE);
|
||||
if (!h) {
|
||||
MessageBoxA(0, "You have selected DirectX graphics mode, but " _DLL_NAME " is missing.\n"
|
||||
"Switch back to mode 0, or install an up to date version of DirectX.", "Error", MB_TASKMODAL | MB_ICONERROR);
|
||||
dlogr(" Failed", DL_INIT);
|
||||
MessageBoxA(0, "Switching back to DirectDraw mode.\n"
|
||||
"You have selected DirectX graphics mode, but " _DLL_NAME " is missing.\n"
|
||||
"Install an up to date version of DirectX 9.0c.", "Error", MB_TASKMODAL | MB_ICONERROR);
|
||||
#undef _DLL_NAME
|
||||
ExitProcess(-1);
|
||||
} else {
|
||||
FreeLibrary(h);
|
||||
Graphics::mode -= 3; //ExitProcess(-1);
|
||||
goto DDInit;
|
||||
}
|
||||
FreeLibrary(h);
|
||||
|
||||
SafeWrite8(0x50FB6B, '2'); // Set call DirectDrawCreate2
|
||||
HookCall(0x44260C, game_init_hook);
|
||||
|
||||
@@ -1328,20 +1220,19 @@ void Graphics::init() {
|
||||
LoadGameHook::OnGameReset() += []() {
|
||||
ForceGraphicsRefresh(0); // disable refresh
|
||||
};
|
||||
} else {
|
||||
DDInit:
|
||||
if (HRP::Setting::IsEnabled()) DirectDraw::init(Graphics::mode);
|
||||
}
|
||||
|
||||
if (HRP::Setting::IsEnabled()) HRP::MoviesScreen::SetDrawMode(Graphics::mode < 4);
|
||||
|
||||
WindowRender::init();
|
||||
}
|
||||
|
||||
void Graphics::exit() {
|
||||
if (Graphics::mode) {
|
||||
RECT rect;
|
||||
if (Graphics::mode == 5 && GetWindowRect(window, &rect)) {
|
||||
int data = rect.top | (rect.left << 16);
|
||||
if (data >= 0 && data != windowData) IniReader::SetConfigInt("Graphics", "WindowData", data);
|
||||
}
|
||||
CoUninitialize();
|
||||
}
|
||||
WinProc::SavePosition(Graphics::mode);
|
||||
if (Graphics::mode >= 4) CoUninitialize();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -60,7 +60,6 @@ public:
|
||||
static DWORD GPUBlt;
|
||||
static bool IsWindowMode;
|
||||
|
||||
static HWND GetFalloutWindowInfo(RECT* rect);
|
||||
static long GetGameWidthRes();
|
||||
static long GetGameHeightRes();
|
||||
|
||||
@@ -90,7 +89,7 @@ public:
|
||||
static __forceinline void UpdateDDSurface(BYTE* surface, int width, int height, int widthFrom, RECT* rect) {
|
||||
long x = rect->left;
|
||||
long y = rect->top;
|
||||
if (Graphics::mode == 0) {
|
||||
if (Graphics::mode < 4) { // DirecrDraw
|
||||
__asm {
|
||||
xor eax, eax;
|
||||
push y;
|
||||
@@ -99,10 +98,10 @@ public:
|
||||
push width;
|
||||
push eax; // yFrom
|
||||
push eax; // xFrom
|
||||
push eax; // heightFrom
|
||||
push height; // heightFrom
|
||||
push widthFrom;
|
||||
push surface;
|
||||
call ds:[FO_VAR_scr_blit]; // GNW95_ShowRect_(int from, int widthFrom, int heightFrom, int xFrom, int yFrom, int width, int height, int x, int y)
|
||||
call ds:[FO_VAR_scr_blit]; // call GNW95_ShowRect_(int from, int widthFrom, int heightFrom, int xFrom, int yFrom, int width, int height, int x, int y)
|
||||
add esp, 9*4;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -560,10 +560,6 @@ static __declspec(naked) void LostFocus() {
|
||||
void Movies::init() {
|
||||
dlog("Applying movie patch.", DL_INIT);
|
||||
|
||||
//if (*((DWORD*)0x00518DA0) != 0x00503300) {
|
||||
// dlog("Error: The value at address 0x001073A0 is not equal to 0x00503300.", DL_INIT);
|
||||
//}
|
||||
|
||||
// Pause and resume movie/sound playback when the game loses focus
|
||||
fo::func::set_focus_func(LostFocus);
|
||||
|
||||
@@ -590,13 +586,13 @@ void Movies::init() {
|
||||
WIP: Task
|
||||
Implement subtitle output from the need to play an mve file in the background.
|
||||
*/
|
||||
if (Graphics::mode != 0) {
|
||||
if (Graphics::mode >= 4) {
|
||||
int allowDShowMovies = IniReader::GetConfigInt("Graphics", "AllowDShowMovies", 0);
|
||||
if (allowDShowMovies > 0) {
|
||||
Graphics::AviMovieWidthFit = (allowDShowMovies >= 2);
|
||||
MakeJump(0x44E690, gmovie_play_hack);
|
||||
HookCall(0x44E993, gmovie_play_hook_stop);
|
||||
/* NOTE: At this address 0x487781, HRP changes the callback procedure to display mve frames. */
|
||||
/* NOTE: At this address 0x487781 (movieStart_), HRP changes the callback procedure to display mve frames. */
|
||||
}
|
||||
}
|
||||
dlogr(" Done", DL_INIT);
|
||||
|
||||
@@ -69,7 +69,7 @@ void __stdcall SetShaderMode(DWORD d, DWORD mode) {
|
||||
}
|
||||
|
||||
int __stdcall LoadShader(const char* file) {
|
||||
if (!Graphics::mode || strstr(file, "..") || strstr(file, ":")) return -1;
|
||||
if (Graphics::mode < 4 || strstr(file, "..") || strstr(file, ":")) return -1;
|
||||
char buf[MAX_PATH];
|
||||
sprintf_s(buf, "%s\\shaders\\%s", fo::var::master_db_handle->path, file); // fo::var::patches
|
||||
for (DWORD d = 0; d < shadersSize; d++) {
|
||||
@@ -220,7 +220,7 @@ void ScriptShaders::Release() {
|
||||
}
|
||||
|
||||
void ScriptShaders::init() {
|
||||
if (Graphics::mode) {
|
||||
if (Graphics::mode >= 4) {
|
||||
for each (const auto& shaderFile in IniReader::GetConfigList("Graphics", "GlobalShaderFile", "", 1024)) {
|
||||
if (shaderFile.length() > 3) gShaderFiles.push_back(GlobalShader(shaderFile));
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ LRESULT CALLBACK SoundWndProc(HWND wnd, UINT msg, WPARAM w, LPARAM l) {
|
||||
|
||||
static void CreateSndWnd() {
|
||||
dlog("Creating sfall sound callback window.", DL_INIT);
|
||||
if (Graphics::mode == 0) CoInitialize(0);
|
||||
if (Graphics::mode < 4) CoInitialize(0);
|
||||
|
||||
WNDCLASSEX wcx;
|
||||
std::memset(&wcx, 0, sizeof(wcx));
|
||||
@@ -1068,7 +1068,7 @@ void Sound::init() {
|
||||
}
|
||||
|
||||
void Sound::exit() {
|
||||
if (soundwindow && Graphics::mode == 0) CoUninitialize();
|
||||
if (soundwindow && Graphics::mode < 4) CoUninitialize();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
* sfall
|
||||
* Copyright (C) 2008-2021 The sfall team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma comment(lib, "ddraw.lib")
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "..\..\main.h"
|
||||
#include "..\..\FalloutEngine\Fallout2.h"
|
||||
#include "..\..\WinProc.h"
|
||||
|
||||
#include "..\..\HRP\Init.h"
|
||||
|
||||
#include "DirectDraw.h"
|
||||
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
static HWND window;
|
||||
static DWORD mode;
|
||||
static bool windowedMode;
|
||||
|
||||
static IDirectDraw* ddObject; // same as _GNW95_DDObject
|
||||
static IDirectDrawSurface* ddPrimarySurface;
|
||||
static IDirectDrawSurface* ddBackSurface;
|
||||
static IDirectDrawPalette* ddPalette;
|
||||
static IDirectDrawClipper* ddClipper;
|
||||
|
||||
static DirectDraw::PALCOLOR* paletteRGB;
|
||||
|
||||
//class ConvertPalette {
|
||||
DWORD PaletteToRGB24(BYTE r, BYTE g, BYTE b) {
|
||||
return (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
// R5G5B5
|
||||
DWORD PaletteToRGB15(BYTE r, BYTE g, BYTE b) {
|
||||
DWORD color = r / 8;
|
||||
color <<= 5;
|
||||
color |= (g / 8);
|
||||
color <<= 5;
|
||||
return color | (b / 8);
|
||||
}
|
||||
|
||||
// R5G6B5
|
||||
DWORD PaletteToRGB16(BYTE r, BYTE g, BYTE b) {
|
||||
DWORD color = r / 8;
|
||||
color <<= 6;
|
||||
color |= (g / 4);
|
||||
color <<= 5;
|
||||
return color | (b / 8);
|
||||
}
|
||||
|
||||
void CopyPaletteSurface16bit() {
|
||||
}
|
||||
//};
|
||||
|
||||
//static void CopyPaletteSurfaceFunc;
|
||||
//static void ConvertPaletteFunc;
|
||||
|
||||
void SetWindow() {
|
||||
WinProc::SetHWND(window);
|
||||
WinProc::SetSize(HRP::Setting::ScreenWidth(), HRP::Setting::ScreenHeight());
|
||||
WinProc::SetTitle(HRP::Setting::ScreenWidth(), HRP::Setting::ScreenHeight());
|
||||
if (mode == 2) WinProc::LoadPosition();
|
||||
|
||||
if (windowedMode) {
|
||||
DWORD windowStyle = (mode == 3) ? WS_OVERLAPPED : (WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU);
|
||||
WinProc::SetStyle(windowStyle);
|
||||
}
|
||||
}
|
||||
|
||||
static long __stdcall DirectDrawInit(DWORD, IDirectDraw* _ddObject, DWORD) {
|
||||
window = (HWND)fo::var::getInt(FO_VAR_GNW95_hwnd);
|
||||
SetWindow();
|
||||
|
||||
HRESULT hr = DirectDrawCreate(0, &_ddObject, 0);
|
||||
if (FAILED(hr)) return -1;
|
||||
|
||||
ddObject = _ddObject;
|
||||
|
||||
hr = ddObject->SetCooperativeLevel(window, (windowedMode) ? DDSCL_NORMAL : DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_MULTITHREADED);
|
||||
if (FAILED(hr)) return -1;
|
||||
|
||||
if (!windowedMode) {
|
||||
hr = ddObject->SetDisplayMode(HRP::Setting::ScreenWidth(), HRP::Setting::ScreenHeight(), 32);
|
||||
if (FAILED(hr)) return -1;
|
||||
}
|
||||
|
||||
DDSURFACEDESC ddsd;
|
||||
std::memset(&ddsd, 0, sizeof(DDSURFACEDESC));
|
||||
ddsd.dwSize = sizeof(DDSURFACEDESC);
|
||||
ddsd.dwFlags = DDSD_CAPS;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||||
|
||||
hr = ddObject->CreateSurface(&ddsd, &ddPrimarySurface, 0);
|
||||
if (FAILED(hr)) return -1;
|
||||
|
||||
std::memset(&ddsd, 0, sizeof(DDSURFACEDESC));
|
||||
ddsd.dwSize = sizeof(DDSURFACEDESC);
|
||||
ddPrimarySurface->GetSurfaceDesc(&ddsd);
|
||||
|
||||
if (ddsd.ddpfPixelFormat.dwRGBBitCount != 32) {
|
||||
MessageBoxA(window, "The current video mode (not TrueColor) is not supported.", "DirectDraw", 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fo::var::setInt(0x51E2B4) = (DWORD)ddPrimarySurface; //FO_VAR_GNW95_DDPrimarySurface
|
||||
fo::var::setInt(0x51E2B8) = (DWORD)ddPrimarySurface; //FO_VAR_GNW95_DDRestoreSurface
|
||||
|
||||
// Create DirectDraw clipper for windowed mode
|
||||
if (windowedMode) {
|
||||
ddObject->CreateClipper(0, &ddClipper, 0);
|
||||
ddClipper->SetHWnd(0, window);
|
||||
hr = ddPrimarySurface->SetClipper(ddClipper);
|
||||
if (FAILED(hr)) return -1;
|
||||
}
|
||||
|
||||
// Create the backbuffer surface
|
||||
std::memset(&ddsd, 0, sizeof(DDSURFACEDESC));
|
||||
ddsd.dwSize = sizeof(DDSURFACEDESC);
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; // | DDSD_PIXELFORMAT;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; // | DDSCAPS_SYSTEMMEMORY
|
||||
ddsd.dwWidth = HRP::Setting::ScreenWidth() + 1;
|
||||
ddsd.dwHeight = HRP::Setting::ScreenHeight() + 1;
|
||||
//ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
||||
//ddsd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
|
||||
//ddsd.ddpfPixelFormat.dwRGBBitCount = 8;
|
||||
|
||||
hr = ddObject->CreateSurface(&ddsd, &ddBackSurface, 0);
|
||||
if (FAILED(hr)) return -1;
|
||||
|
||||
std::memset(&ddsd, 0, sizeof(DDSURFACEDESC));
|
||||
ddsd.dwSize = sizeof(DDSURFACEDESC);
|
||||
ddBackSurface->GetSurfaceDesc(&ddsd);
|
||||
|
||||
// set greyscale (delete)
|
||||
for (size_t i = 0; i < 256; i++) {
|
||||
paletteRGB[i].xRGB = (i << 16) | (i << 8) | i;
|
||||
}
|
||||
|
||||
hr = ddObject->CreatePalette(DDPCAPS_ALLOW256 | DDPCAPS_8BIT, (PALETTEENTRY*)paletteRGB, &ddPalette, 0);
|
||||
if (FAILED(hr)) return -1;
|
||||
|
||||
fo::var::setInt(0x51E2BC) = (DWORD)ddPalette; // FO_VAR_GNW95_DDPrimaryPalette
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BufToBuf_32bit(BYTE* src, int width, int height, DWORD* dst, int pitch) {
|
||||
while (height--) {
|
||||
int x = width;
|
||||
while (x--) dst[x] = paletteRGB[src[x]].xRGB;
|
||||
src += width;
|
||||
dst += pitch;
|
||||
};
|
||||
}
|
||||
|
||||
static void __cdecl GNW95_ShowRect(BYTE* srcSurface, int sWidth, int sHeight, int sX, int sY, int width, int height, int x, int y) {
|
||||
WinProc::Moving();
|
||||
|
||||
if (sHeight > 0 && sWidth > 0 && fo::var::getInt(FO_VAR_GNW95_isActive)) {
|
||||
DDSURFACEDESC desc;
|
||||
std::memset(&desc, 0, sizeof(DDSURFACEDESC));
|
||||
desc.dwSize = sizeof(DDSURFACEDESC);
|
||||
|
||||
while (true) {
|
||||
HRESULT hr = ddBackSurface->Lock(0, &desc, DDLOCK_WAIT, 0);
|
||||
if (!hr) break;
|
||||
// 0x887601C2
|
||||
if (hr != DDERR_SURFACELOST || ddBackSurface->Restore()) return;
|
||||
}
|
||||
|
||||
int pitch = desc.lPitch / 4;
|
||||
|
||||
DWORD* dst = (DWORD*)desc.lpSurface;
|
||||
dst += (x + (y * pitch));
|
||||
|
||||
BYTE* src = srcSurface;
|
||||
src += sX + (sY * sWidth);
|
||||
|
||||
BufToBuf_32bit(src, sWidth, sHeight, dst, pitch);
|
||||
ddBackSurface->Unlock(desc.lpSurface);
|
||||
|
||||
RECT backRect;
|
||||
backRect.left = x;
|
||||
backRect.top = y;
|
||||
backRect.right = x + width;
|
||||
backRect.bottom = y + height;
|
||||
|
||||
POINT point;
|
||||
point.x = 0;
|
||||
point.y = 0;
|
||||
if (mode == 2) ClientToScreen(window, &point);
|
||||
|
||||
RECT primRect;
|
||||
primRect.left = point.x + x;
|
||||
primRect.top = point.y + y;
|
||||
primRect.right = point.x + x + width;
|
||||
primRect.bottom = point.y + y + height;
|
||||
|
||||
// Draw
|
||||
while (ddPrimarySurface->Blt(&primRect, ddBackSurface, &backRect, DDBLT_WAIT, 0) == DDERR_SURFACELOST) ddPrimarySurface->Restore();
|
||||
}
|
||||
}
|
||||
|
||||
static void __fastcall SetPalette(fo::PALETTE* pal, long start, long count) {
|
||||
// copy and swap color B <> R
|
||||
while (count--) {
|
||||
paletteRGB[start++].xRGB = PaletteToRGB24(pal->B << 2, pal->G << 2, pal->R << 2);
|
||||
pal++;
|
||||
};
|
||||
|
||||
//ddPalette->SetEntries(0, start, count, (PALETTEENTRY*)paletteRGB);
|
||||
}
|
||||
|
||||
static __declspec(naked) void GNW95_SetPaletteEntries_hack_replacement() {
|
||||
__asm {
|
||||
push ebx;
|
||||
mov ecx, eax;
|
||||
call SetPalette;
|
||||
test ebx, ebx;
|
||||
jz skip;
|
||||
// update
|
||||
mov eax, FO_VAR_scr_size;
|
||||
call fo::funcoffs::win_refresh_all_;
|
||||
skip:
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static __declspec(naked) void GNW95_SetPalette_hack_replacement() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
mov ecx, eax;
|
||||
xor edx, edx;
|
||||
push 256;
|
||||
call SetPalette;
|
||||
// update
|
||||
mov eax, FO_VAR_scr_size;
|
||||
call fo::funcoffs::win_refresh_all_;
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static IDirectDraw* GNW95_reset_mode_hack() {
|
||||
ddBackSurface->Release();
|
||||
if (ddClipper) {
|
||||
ddClipper->Release();
|
||||
ddClipper = nullptr;
|
||||
}
|
||||
ddPrimarySurface = nullptr;
|
||||
ddPalette = nullptr;
|
||||
ddBackSurface = nullptr;
|
||||
|
||||
return ddObject;
|
||||
}
|
||||
|
||||
void DirectDraw::init(long gMode) {
|
||||
mode = gMode;
|
||||
windowedMode = (gMode == 2 || gMode == 3);
|
||||
|
||||
if (gMode == 2) WinProc::SetMoveKeys();
|
||||
|
||||
paletteRGB = new DirectDraw::PALCOLOR[256];
|
||||
|
||||
// GNW95_init_DirectDraw_
|
||||
MakeCall(0x4CAFE6, DirectDrawInit, 1); // GNW95_init_DirectDraw_
|
||||
SafeWrite8(0x4CAFEE, CodeType::Jump);
|
||||
SafeWrite32(0x4CAFEF, 433); // jmp 0x4CB1A4
|
||||
|
||||
// GNW95_init_mode_ex_
|
||||
SafeWrite32(0x4CAE72, (DWORD)&GNW95_ShowRect); // replace engine GNW95_ShowRect_ with sfall function
|
||||
|
||||
MakeJump(fo::funcoffs::GNW95_SetPaletteEntries_ + 1, GNW95_SetPaletteEntries_hack_replacement); // 0x4CB310
|
||||
MakeJump(fo::funcoffs::GNW95_SetPalette_, GNW95_SetPalette_hack_replacement); // 0x4CB568
|
||||
|
||||
MakeCall(0x4CB1FD, GNW95_reset_mode_hack);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* sfall
|
||||
* Copyright (C) 2008-2021 The sfall team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
class DirectDraw {
|
||||
public:
|
||||
static void init(long);
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct PALCOLOR {
|
||||
union {
|
||||
DWORD xRGB;
|
||||
struct {
|
||||
BYTE R;
|
||||
BYTE G;
|
||||
BYTE B;
|
||||
BYTE x;
|
||||
};
|
||||
};
|
||||
};
|
||||
#pragma pack(pop)
|
||||
};
|
||||
|
||||
}
|
||||
@@ -291,7 +291,7 @@ void TalkingHeads::init() {
|
||||
// Disable centering the screen if NPC has talking head
|
||||
HookCall(0x445224, gdialogInitFromScript_hook);
|
||||
|
||||
if (Graphics::mode && IniReader::GetConfigInt("Graphics", "Use32BitHeadGraphics", 0)) {
|
||||
if (Graphics::mode >= 4 && IniReader::GetConfigInt("Graphics", "Use32BitHeadGraphics", 0)) {
|
||||
LoadGameHook::OnAfterGameInit() += TalkingHeadsInit;
|
||||
}
|
||||
}
|
||||
|
||||
+152
-2
@@ -7,27 +7,44 @@
|
||||
#include "main.h"
|
||||
#include "FalloutEngine\Fallout2.h"
|
||||
|
||||
#include "InputFuncs.h"
|
||||
#include "version.h"
|
||||
|
||||
#include "WinProc.h"
|
||||
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
static HWND window;
|
||||
static Rectangle win;
|
||||
|
||||
static long moveWindowKey[2];
|
||||
static long windowData;
|
||||
|
||||
static long reqGameQuit;
|
||||
static bool cCursorShow = true;
|
||||
static bool bkgndErased = false;
|
||||
|
||||
static int __stdcall WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
RECT rect;
|
||||
//POINT point;
|
||||
|
||||
switch (msg) {
|
||||
//case WM_CREATE:
|
||||
// break;
|
||||
|
||||
case WM_DESTROY:
|
||||
__asm xor eax, eax;
|
||||
__asm call fo::funcoffs::exit_;
|
||||
case WM_ERASEBKGND:
|
||||
return 1;
|
||||
|
||||
case WM_ERASEBKGND:
|
||||
if (bkgndErased || !window) return 1;
|
||||
bkgndErased = true;
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
if (GetUpdateRect(hWnd, &rect, 0) == 1) {
|
||||
if (GetUpdateRect(hWnd, &rect, 0) != 0) {
|
||||
rect.right -= 1;
|
||||
rect.bottom -= 1;
|
||||
__asm {
|
||||
@@ -112,8 +129,141 @@ void WinProc::SetWindowProc() {
|
||||
SetWindowLongA((HWND)fo::var::getInt(FO_VAR_GNW95_hwnd), GWL_WNDPROC, (LONG)WindowProc);
|
||||
}
|
||||
|
||||
void WinProc::SetHWND(HWND _window) {
|
||||
window = _window;
|
||||
}
|
||||
|
||||
void WinProc::SetSize(long w, long h) {
|
||||
win.x = 0;
|
||||
win.x = 0;
|
||||
win.width = w;
|
||||
win.height = h;
|
||||
}
|
||||
|
||||
// Sets the window style and its position
|
||||
void WinProc::SetStyle(long windowStyle) {
|
||||
SetWindowLongA(window, GWL_STYLE, windowStyle);
|
||||
RECT r;
|
||||
r.left = 0;
|
||||
r.right = win.width;
|
||||
r.top = 0;
|
||||
r.bottom = win.height;
|
||||
AdjustWindowRect(&r, windowStyle, false);
|
||||
r.right -= r.left;
|
||||
r.bottom -= r.top;
|
||||
SetWindowPos(window, HWND_NOTOPMOST, win.x, win.y, r.right, r.bottom, SWP_FRAMECHANGED | SWP_SHOWWINDOW);
|
||||
}
|
||||
|
||||
void WinProc::SetTitle(long wWidth, long wHeight) {
|
||||
char windowTitle[128];
|
||||
|
||||
if (HRP::Setting::ScreenWidth() != wWidth || HRP::Setting::ScreenHeight() != wHeight) {
|
||||
std::sprintf(windowTitle, "%s @sfall " VERSION_STRING " %ix%i >> %ix%i", (const char*)0x50AF08, HRP::Setting::ScreenWidth(), HRP::Setting::ScreenHeight(), wWidth, wHeight);
|
||||
} else {
|
||||
std::sprintf(windowTitle, "%s @sfall " VERSION_STRING, (const char*)0x50AF08);
|
||||
}
|
||||
SetWindowTextA(window, windowTitle);
|
||||
}
|
||||
|
||||
void WinProc::SetMoveKeys() {
|
||||
moveWindowKey[0] = IniReader::GetConfigInt("Input", "WindowScrollKey", 0);
|
||||
if (moveWindowKey[0] < 0) {
|
||||
switch (moveWindowKey[0]) {
|
||||
case -1:
|
||||
moveWindowKey[0] = DIK_LCONTROL;
|
||||
moveWindowKey[1] = DIK_RCONTROL;
|
||||
break;
|
||||
case -2:
|
||||
moveWindowKey[0] = DIK_LMENU;
|
||||
moveWindowKey[1] = DIK_RMENU;
|
||||
break;
|
||||
case -3:
|
||||
moveWindowKey[0] = DIK_LSHIFT;
|
||||
moveWindowKey[1] = DIK_RSHIFT;
|
||||
break;
|
||||
default:
|
||||
moveWindowKey[0] = 0;
|
||||
}
|
||||
} else {
|
||||
moveWindowKey[0] &= 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
void WinProc::Moving() {
|
||||
if ((moveWindowKey[0] != 0 && KeyDown(moveWindowKey[0])) ||
|
||||
(moveWindowKey[1] != 0 && KeyDown(moveWindowKey[1])))
|
||||
{
|
||||
int winX, winY;
|
||||
GetMouse(&winX, &winY);
|
||||
win.x += winX;
|
||||
win.y += winY;
|
||||
|
||||
RECT r, r2;
|
||||
r.left = win.x;
|
||||
r.right = win.x + win.width;
|
||||
r.top = win.y;
|
||||
r.bottom = win.y + win.height;
|
||||
AdjustWindowRect(&r, WS_CAPTION, false);
|
||||
|
||||
r.right -= (r.left - win.x);
|
||||
r.left = win.x;
|
||||
r.bottom -= (r.top - win.y);
|
||||
r.top = win.y;
|
||||
|
||||
if (GetWindowRect(GetShellWindow(), &r2)) {
|
||||
if (r.right > r2.right) {
|
||||
DWORD move = r.right - r2.right;
|
||||
win.x -= move;
|
||||
r.right -= move;
|
||||
} else if (r.left < r2.left) {
|
||||
DWORD move = r2.left - r.left;
|
||||
win.x += move;
|
||||
r.right += move;
|
||||
}
|
||||
if (r.bottom > r2.bottom) {
|
||||
DWORD move = r.bottom - r2.bottom;
|
||||
win.y -= move;
|
||||
r.bottom -= move;
|
||||
} else if (r.top < r2.top) {
|
||||
DWORD move = r2.top - r.top;
|
||||
win.y += move;
|
||||
r.bottom += move;
|
||||
}
|
||||
}
|
||||
MoveWindow(window, win.x, win.y, r.right - win.x, r.bottom - win.y, true);
|
||||
}
|
||||
}
|
||||
|
||||
void WinProc::SetToCenter(long wWidth, long wHeight, long* outX, long* outY) {
|
||||
RECT desktop;
|
||||
GetWindowRect(GetDesktopWindow(), &desktop);
|
||||
|
||||
*outX = (desktop.right / 2) - (wWidth / 2);
|
||||
*outY = (desktop.bottom / 2) - (wHeight / 2);
|
||||
}
|
||||
|
||||
void WinProc::LoadPosition() {
|
||||
windowData = IniReader::GetConfigInt("Graphics", "WindowData", -1);
|
||||
if (windowData > 0) {
|
||||
win.x = windowData >> 16;
|
||||
win.y = windowData & 0xFFFF;
|
||||
} else if (windowData == -1) {
|
||||
WinProc::SetToCenter(win.width, win.height, &win.x, &win.y);
|
||||
}
|
||||
}
|
||||
|
||||
void WinProc::SavePosition(long mode) {
|
||||
RECT rect;
|
||||
if ((mode == 2 || mode == 5) && GetWindowRect(window, &rect)) {
|
||||
int data = rect.top | (rect.left << 16);
|
||||
if (data >= 0 && data != windowData) IniReader::SetConfigInt("Graphics", "WindowData", data);
|
||||
}
|
||||
}
|
||||
|
||||
void WinProc::init() {
|
||||
// Replace the engine WindowProc_ with sfall one
|
||||
MakeJump(0x4DE9FC, WindowProc); // WindowProc_
|
||||
|
||||
HookCall(0x481B2A, main_menu_loop_hook);
|
||||
|
||||
//SafeWrite8(0x4DEB0D, 1); // for test
|
||||
|
||||
@@ -14,6 +14,20 @@ public:
|
||||
static void init();
|
||||
|
||||
static void SetWindowProc();
|
||||
|
||||
static void SetHWND(HWND _window);
|
||||
static void SetSize(long w, long h);
|
||||
static void SetTitle(long gWidth, long gHeight);
|
||||
|
||||
//Sets the window style and its position
|
||||
static void SetStyle(long windowStyle);
|
||||
|
||||
static void SetMoveKeys();
|
||||
static void Moving();
|
||||
|
||||
static void SetToCenter(long wWidth, long wHeight, long* outX, long* outY);
|
||||
static void LoadPosition();
|
||||
static void SavePosition(long mode);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+9
-5
@@ -20,12 +20,16 @@
|
||||
|
||||
extern ddrawDll ddraw;
|
||||
|
||||
typedef HRESULT (__stdcall *DDrawCreateProc)(void* a, void* b, void* c);
|
||||
//typedef HRESULT (__stdcall *DDrawCreateProc)(DWORD a, IDirectDraw* b, DWORD c);
|
||||
|
||||
HRESULT __stdcall FakeDirectDrawCreate(void* a, void* b, void* c) {
|
||||
DDrawCreateProc proc = (DDrawCreateProc)ddraw.DirectDrawCreate;
|
||||
if (!proc) return -1;
|
||||
return proc(a, b, c);
|
||||
//HRESULT __stdcall FakeDirectDrawCreate(DWORD a, IDirectDraw* b, DWORD c) {
|
||||
// DDrawCreateProc proc = (DDrawCreateProc)ddraw.DirectDrawCreate;
|
||||
// if (!proc) return -1;
|
||||
// return proc(a, b, c);
|
||||
//}
|
||||
|
||||
__declspec(naked) void FakeDirectDrawCreate() {
|
||||
__asm jmp [ddraw.DirectDrawCreate];
|
||||
}
|
||||
|
||||
__declspec(naked) void FakeAcquireDDThreadLock() {
|
||||
|
||||
@@ -359,6 +359,7 @@
|
||||
<ClInclude Include="Modules\Scripting\Handlers\Math.h" />
|
||||
<ClInclude Include="Modules\SpeedPatch.h" />
|
||||
<ClInclude Include="Modules\SubModules\CombatBlock.h" />
|
||||
<ClInclude Include="Modules\SubModules\DirectDraw.h" />
|
||||
<ClInclude Include="Modules\SubModules\EnginePerks.h" />
|
||||
<ClInclude Include="Modules\SubModules\ObjectName.h" />
|
||||
<ClInclude Include="Modules\SubModules\WindowRender.h" />
|
||||
@@ -495,6 +496,7 @@
|
||||
<ClCompile Include="Modules\Scripting\Handlers\Math.cpp" />
|
||||
<ClCompile Include="Modules\SpeedPatch.cpp" />
|
||||
<ClCompile Include="Modules\SubModules\CombatBlock.cpp" />
|
||||
<ClCompile Include="Modules\SubModules\DirectDraw.cpp" />
|
||||
<ClCompile Include="Modules\SubModules\EnginePerks.cpp" />
|
||||
<ClCompile Include="Modules\SubModules\ObjectName.cpp" />
|
||||
<ClCompile Include="Modules\SubModules\WindowRender.cpp" />
|
||||
|
||||
@@ -434,6 +434,9 @@
|
||||
<ClInclude Include="HRP\MoviesScreen.h">
|
||||
<Filter>HRP</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Modules\SubModules\DirectDraw.h">
|
||||
<Filter>Modules\SubModules</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp" />
|
||||
@@ -803,6 +806,9 @@
|
||||
<ClCompile Include="HRP\MoviesScreen.cpp">
|
||||
<Filter>HRP</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Modules\SubModules\DirectDraw.cpp">
|
||||
<Filter>Modules\SubModules</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="version.rc" />
|
||||
|
||||
Reference in New Issue
Block a user