mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Fixed and improved Use32BitHeadGraphics option:
* Fixed the position of the talking head texture when the game res is larger than 640x480. * Added the support to use textures without the need of patching talking head FRM files.
This commit is contained in:
+3
-1
@@ -70,7 +70,9 @@ GraphicsHeight=0
|
||||
;GPU is faster, but requires v2.0 pixel shader support
|
||||
GPUBlt=0
|
||||
|
||||
;Set to 1 to allow using 32 bit graphics for talking heads
|
||||
;Set to 1 to allow using 32-bit .png textures for talking heads
|
||||
;The texture files should be placed in art/heads/<name of the talking head FRM file>/ (w/o extension)
|
||||
;The files in the folder should be numbered according to the number of frames in the talking head FRM file (e.g. 0.png - 10.png)
|
||||
;Requires DX9 graphics mode and v2.0 pixel shader support (see GPUBlt option)
|
||||
Use32BitHeadGraphics=0
|
||||
|
||||
|
||||
+124
-56
@@ -27,9 +27,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <d3dx9.h>
|
||||
#include <ddraw.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
@@ -51,7 +48,9 @@ typedef IDirect3D9* (_stdcall *D3DCreateProc)(UINT version);
|
||||
|
||||
static DWORD ResWidth;
|
||||
static DWORD ResHeight;
|
||||
static DWORD GPUBlt;
|
||||
|
||||
DWORD GPUBlt;
|
||||
DWORD GraphicsMode;
|
||||
|
||||
static BYTE* titlesBuffer = nullptr;
|
||||
static DWORD movieHeight = 0;
|
||||
@@ -91,40 +90,42 @@ static IDirect3DTexture9* movieTex = 0;
|
||||
|
||||
static ID3DXEffect* gpuBltEffect;
|
||||
static const char* gpuEffect=
|
||||
"texture image;\n"
|
||||
"texture palette;\n"
|
||||
"texture head;\n"
|
||||
"sampler s0 = sampler_state { texture=<image>; MAGFILTER=POINT; MINFILTER=POINT; };\n"
|
||||
"sampler s1 = sampler_state { texture=<palette>; MAGFILTER=POINT; MINFILTER=POINT; };\n"
|
||||
"sampler s2 = sampler_state { texture=<head>; MAGFILTER=POINT; MINFILTER=POINT; };\n"
|
||||
"float2 size;\n"
|
||||
"float2 corner;\n"
|
||||
"float4 P0( in float2 Tex : TEXCOORD0 ) : COLOR0 {\n"
|
||||
" float3 result = tex1D(s1, tex2D(s0, Tex).a);\n"
|
||||
" return float4(result.b, result.g, result.r, 1);\n"
|
||||
"}\n"
|
||||
"float4 P1( in float2 Tex : TEXCOORD0 ) : COLOR0 {\n"
|
||||
" float backdrop = tex2D(s0, Tex).a;\n"
|
||||
" float3 result;\n"
|
||||
" if(abs(backdrop-(48.0/255.0))<0.001) {\n"
|
||||
//" float2 size = float2(388.0/640.0, 200.0/480.0);\n"
|
||||
//" float2 corner = float2(126.0/640.0, 14.0/480.0);\n"
|
||||
" result = tex2D(s2, saturate((Tex-corner)/size));\n"
|
||||
" } else {\n"
|
||||
" result = tex1D(s1, backdrop);\n"
|
||||
" result = float3(result.b, result.g, result.r);\n"
|
||||
" }\n"
|
||||
" return float4(result.r, result.g, result.b, 1);\n"
|
||||
"}\n"
|
||||
"technique T0\n"
|
||||
"{\n"
|
||||
" pass p0 { PixelShader = compile ps_2_0 P0(); }\n"
|
||||
"}\n"
|
||||
"technique T1\n"
|
||||
"{\n"
|
||||
" pass p1 { PixelShader = compile ps_2_0 P1(); }\n"
|
||||
"}\n"
|
||||
;
|
||||
"texture image;"
|
||||
"texture palette;"
|
||||
"texture head;"
|
||||
"sampler s0 = sampler_state { texture=<image>; };"
|
||||
"sampler s1 = sampler_state { texture=<palette>; };"
|
||||
"sampler s2 = sampler_state { texture=<head>; minFilter=linear; magFilter=linear; addressU=clamp; addressV=clamp; };"
|
||||
"float2 size;"
|
||||
"float2 corner;"
|
||||
|
||||
// shader for displaying head textures
|
||||
"float4 P1( in float2 Tex : TEXCOORD0 ) : COLOR0 {"
|
||||
" float backdrop = tex2D(s0, Tex).a;"
|
||||
" float3 result;"
|
||||
" if(abs(backdrop - 1.0) < 0.001) {" // (48.0 / 255.0) // 48 - key index color
|
||||
" result = tex2D(s2, saturate((Tex - corner) / size));"
|
||||
" } else {"
|
||||
" result = tex1D(s1, backdrop);"
|
||||
" result = float3(result.b, result.g, result.r);"
|
||||
" }"
|
||||
" return float4(result.r, result.g, result.b, 1);"
|
||||
"}"
|
||||
|
||||
"technique T1"
|
||||
"{"
|
||||
" pass p1 { PixelShader = compile ps_2_0 P1(); }"
|
||||
"}"
|
||||
|
||||
"float4 P0( in float2 Tex : TEXCOORD0 ) : COLOR0 {"
|
||||
" float3 result = tex1D(s1, tex2D(s0, Tex).a);"
|
||||
" return float4(result.b, result.g, result.r, 1);"
|
||||
"}"
|
||||
|
||||
"technique T0"
|
||||
"{"
|
||||
" pass p0 { PixelShader = compile ps_2_0 P0(); }"
|
||||
"}";
|
||||
|
||||
static D3DXHANDLE gpuBltBuf;
|
||||
static D3DXHANDLE gpuBltPalette;
|
||||
@@ -134,8 +135,6 @@ static D3DXHANDLE gpuBltHeadCorner;
|
||||
|
||||
static float rcpres[2];
|
||||
|
||||
DWORD GraphicsMode;
|
||||
|
||||
struct sShader {
|
||||
ID3DXEffect* Effect;
|
||||
bool Active;
|
||||
@@ -173,10 +172,23 @@ void GetFalloutWindowInfo(DWORD* width, DWORD* height, HWND* wnd) {
|
||||
*wnd = window;
|
||||
}
|
||||
|
||||
long Gfx_GetGameWidthRes() {
|
||||
return ptr_scr_size->offx - (ptr_scr_size->x + 1);
|
||||
}
|
||||
|
||||
long Gfx_GetGameHeightRes() {
|
||||
return ptr_scr_size->offy - (ptr_scr_size->y + 1);
|
||||
}
|
||||
|
||||
int _stdcall GetShaderVersion() {
|
||||
return ShaderVersion;
|
||||
}
|
||||
|
||||
void rcpresInit() {
|
||||
rcpres[0] = 1.0f / (float)Gfx_GetGameWidthRes();
|
||||
rcpres[1] = 1.0f / (float)Gfx_GetGameHeightRes();
|
||||
}
|
||||
|
||||
void _stdcall SetShaderMode(DWORD d, DWORD mode) {
|
||||
if (d >= shaders.size() || !shaders[d].Effect) return;
|
||||
if (mode & 0x80000000) {
|
||||
@@ -187,7 +199,7 @@ void _stdcall SetShaderMode(DWORD d, DWORD mode) {
|
||||
}
|
||||
|
||||
int _stdcall LoadShader(const char* path) {
|
||||
if ((GraphicsMode < 4) || (strstr(path, "..")) || (strstr(path, ":"))) return -1;
|
||||
if (!GraphicsMode || strstr(path, "..") || strstr(path, ":")) return -1;
|
||||
char buf[MAX_PATH];
|
||||
sprintf(buf, "%s\\shaders\\%s", *(char**)_patches, path);
|
||||
for (DWORD d = 0; d < shaders.size(); d++) {
|
||||
@@ -301,9 +313,12 @@ static void ResetDevice(bool CreateNew) {
|
||||
D3DXCreateEffect(d3d9Device, gpuEffect, strlen(gpuEffect), 0, 0, 0, 0, &gpuBltEffect, 0);
|
||||
gpuBltBuf = gpuBltEffect->GetParameterByName(0, "image");
|
||||
gpuBltPalette = gpuBltEffect->GetParameterByName(0, "palette");
|
||||
// for head textures
|
||||
gpuBltHead = gpuBltEffect->GetParameterByName(0, "head");
|
||||
gpuBltHeadSize = gpuBltEffect->GetParameterByName(0, "size");
|
||||
gpuBltHeadCorner = gpuBltEffect->GetParameterByName(0, "corner");
|
||||
|
||||
Gfx_SetDefaultTechnique();
|
||||
}
|
||||
} else {
|
||||
d3d9Device->Reset(¶ms);
|
||||
@@ -548,18 +563,31 @@ void _stdcall PlayMovieFrame() {
|
||||
Present();
|
||||
}
|
||||
|
||||
void _stdcall SetHeadTex(IDirect3DTexture9* tex, int width, int height, int xoff, int yoff) {
|
||||
if (tex) {
|
||||
void Gfx_SetHeadTex(IDirect3DTexture9* tex, int width, int height, int xoff, int yoff) {
|
||||
gpuBltEffect->SetTexture(gpuBltHead, tex);
|
||||
|
||||
float size[2];
|
||||
size[0] = ((float)width)*rcpres[0];
|
||||
size[1] = ((float)height)*rcpres[1];
|
||||
size[0] = (float)width * rcpres[0];
|
||||
size[1] = (float)height * rcpres[1];
|
||||
gpuBltEffect->SetFloatArray(gpuBltHeadSize, size, 2);
|
||||
size[0] = (126.0f + xoff + (388 - width) / 2)*rcpres[0];
|
||||
size[1] = (14.0f + yoff + (200 - height) / 2)*rcpres[1];
|
||||
|
||||
// adjust head texture position for HRP 4.1.8
|
||||
int h = Gfx_GetGameHeightRes();
|
||||
if (h > 480) yoff += ((h - 480) / 2) - 47;
|
||||
xoff += ((Gfx_GetGameWidthRes() - 640) / 2);
|
||||
|
||||
size[0] = (126.0f + xoff + ((388 - width) / 2)) * rcpres[0];
|
||||
size[1] = (14.0f + yoff + ((200 - height) / 2)) * rcpres[1];
|
||||
gpuBltEffect->SetFloatArray(gpuBltHeadCorner, size, 2);
|
||||
|
||||
Gfx_SetHeadTechnique();
|
||||
}
|
||||
|
||||
void Gfx_SetHeadTechnique() {
|
||||
gpuBltEffect->SetTechnique("T1");
|
||||
} else
|
||||
}
|
||||
|
||||
void Gfx_SetDefaultTechnique() {
|
||||
gpuBltEffect->SetTechnique("T0");
|
||||
}
|
||||
|
||||
@@ -959,8 +987,6 @@ public:
|
||||
if (!d3d9Device) {
|
||||
ResetDevice(true);
|
||||
CoInitialize(0);
|
||||
|
||||
if (GPUBlt) HeadsInit();
|
||||
}
|
||||
dlog("Creating D3D9 Device window...", DL_MAIN);
|
||||
|
||||
@@ -990,8 +1016,8 @@ public:
|
||||
HRESULT _stdcall FakeDirectDrawCreate2(void*, IDirectDraw** b, void*) {
|
||||
dlog("Initializing Direct3D...", DL_MAIN);
|
||||
|
||||
ResWidth = *(DWORD*)0x4CAD6B;
|
||||
ResHeight = *(DWORD*)0x4CAD66;
|
||||
ResWidth = *(DWORD*)0x4CAD6B; // 640
|
||||
ResHeight = *(DWORD*)0x4CAD66; // 480
|
||||
|
||||
if (!d3d9) {
|
||||
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
@@ -1023,21 +1049,63 @@ HRESULT _stdcall FakeDirectDrawCreate2(void*, IDirectDraw** b, void*) {
|
||||
}
|
||||
GPUBlt = GetPrivateProfileIntA("Graphics", "GPUBlt", 0, ini);
|
||||
if (!GPUBlt || GPUBlt > 2) GPUBlt = 2; // Swap them around to keep compatibility with old ddraw.ini's
|
||||
else if (GPUBlt == 2) GPUBlt = 0;
|
||||
else if (GPUBlt == 2) GPUBlt = 0; // Use CPU
|
||||
|
||||
if (GraphicsMode == 5) {
|
||||
ScrollWindowKey = GetPrivateProfileInt("Input", "WindowScrollKey", 0, ini);
|
||||
} else ScrollWindowKey = 0;
|
||||
|
||||
rcpres[0] = 1.0f / (float)gWidth;
|
||||
rcpres[1] = 1.0f / (float)gHeight;
|
||||
|
||||
*b = (IDirectDraw*)new FakeDirectDraw2();
|
||||
|
||||
dlogr(" Done.", DL_MAIN);
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
static double fadeMulti;
|
||||
static __declspec(naked) void palette_fade_to_hook() {
|
||||
__asm {
|
||||
push ebx; // _fade_steps
|
||||
fild [esp];
|
||||
fmul fadeMulti;
|
||||
fistp [esp];
|
||||
pop ebx;
|
||||
jmp fadeSystemPalette_;
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsInit() {
|
||||
GraphicsMode = GetPrivateProfileIntA("Graphics", "Mode", 0, ini);
|
||||
if (GraphicsMode != 4 && GraphicsMode != 5) {
|
||||
GraphicsMode = 0;
|
||||
}
|
||||
if (GraphicsMode == 4 || GraphicsMode == 5) {
|
||||
dlog("Applying DX9 graphics patch.", DL_INIT);
|
||||
#ifdef WIN2K
|
||||
#define _DLL_NAME "d3dx9_42.dll"
|
||||
#else
|
||||
#define _DLL_NAME "d3dx9_43.dll"
|
||||
#endif
|
||||
HMODULE h = LoadLibraryEx(_DLL_NAME, 0, LOAD_LIBRARY_AS_DATAFILE);
|
||||
if (!h) {
|
||||
MessageBoxA(0, "You have selected graphics mode 4 or 5, but " _DLL_NAME " is missing\nSwitch back to mode 0, or install an up to date version of DirectX", "Error", 0);
|
||||
ExitProcess(-1);
|
||||
} else {
|
||||
FreeLibrary(h);
|
||||
}
|
||||
#undef _DLL_NAME
|
||||
SafeWrite8(0x50FB6B, '2'); // Set call DirectDrawCreate2
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
fadeMulti = GetPrivateProfileIntA("Graphics", "FadeMultiplier", 100, ini);
|
||||
if (fadeMulti != 100) {
|
||||
dlog("Applying fade patch.", DL_INIT);
|
||||
HookCall(0x493B16, palette_fade_to_hook);
|
||||
fadeMulti = ((double)fadeMulti) / 100.0;
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsExit() {
|
||||
if (GraphicsMode != 0) {
|
||||
if (titlesBuffer) delete[] titlesBuffer;
|
||||
|
||||
@@ -18,10 +18,24 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <d3dx9.h>
|
||||
#include <ddraw.h>
|
||||
|
||||
extern DWORD GraphicsMode;
|
||||
extern DWORD GPUBlt;
|
||||
|
||||
void GraphicsResetOnGameLoad();
|
||||
void GraphicsInit();
|
||||
void GraphicsExit();
|
||||
|
||||
long Gfx_GetGameWidthRes();
|
||||
long Gfx_GetGameHeightRes();
|
||||
void Gfx_SetHeadTex(IDirect3DTexture9* tex, int width, int height, int xoff, int yoff);
|
||||
void Gfx_SetHeadTechnique();
|
||||
void Gfx_SetDefaultTechnique();
|
||||
void rcpresInit();
|
||||
|
||||
int _stdcall GetShaderVersion();
|
||||
int _stdcall LoadShader(const char*);
|
||||
void _stdcall ActivateShader(DWORD);
|
||||
|
||||
+11
-2
@@ -258,16 +258,25 @@ static void __declspec(naked) EndLoadHook() {
|
||||
}
|
||||
}
|
||||
|
||||
static void _stdcall GameInitialized() {
|
||||
static void __stdcall GameInitialization() {
|
||||
MusicVolInitialization();
|
||||
}
|
||||
|
||||
static void __stdcall GameInitialized() {
|
||||
rcpresInit();
|
||||
if (Use32BitTalkingHeads) TalkingHeadsSetup();
|
||||
}
|
||||
|
||||
static void __declspec(naked) GameInitHook() {
|
||||
__asm {
|
||||
pushadc;
|
||||
call GameInitialization;
|
||||
popadc;
|
||||
call main_init_system_;
|
||||
pushadc;
|
||||
call GameInitialized;
|
||||
popadc;
|
||||
jmp main_init_system_;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+149
-76
@@ -16,21 +16,17 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#include <d3d9.h>
|
||||
#include <d3dx9.h>
|
||||
#include <stdio.h>
|
||||
#include <hash_map>
|
||||
#include "FalloutEngine.h"
|
||||
|
||||
void _stdcall SetHeadTex(IDirect3DTexture9* tex, int width, int height, int xoff, int yoff);
|
||||
#include "main.h"
|
||||
|
||||
#include "FalloutEngine.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
#include "TalkingHeads.h"
|
||||
|
||||
extern IDirect3DDevice9* d3d9Device;
|
||||
static stdext::hash_map<__int64, IDirect3DTexture9**> texMap;
|
||||
typedef stdext::hash_map<__int64, IDirect3DTexture9**> :: iterator tex_itr;
|
||||
typedef stdext::hash_map<__int64, IDirect3DTexture9**> :: const_iterator tex_citr;
|
||||
static BYTE overridden=0;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct Frm {
|
||||
@@ -61,82 +57,130 @@ struct Frm {
|
||||
};
|
||||
};
|
||||
};
|
||||
struct Frame {
|
||||
WORD width;
|
||||
WORD height;
|
||||
DWORD size;
|
||||
WORD xoffset;
|
||||
WORD yoffset;
|
||||
BYTE data[1];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
static Frame* FramePointer(const Frm* frm, int frameno) {
|
||||
Frame* result;
|
||||
__asm {
|
||||
mov eax, frm;
|
||||
mov edx, frameno;
|
||||
xor ebx, ebx;
|
||||
call frame_ptr_;
|
||||
mov result, eax;
|
||||
}
|
||||
return result;
|
||||
struct TextureData {
|
||||
IDirect3DTexture9** textures;
|
||||
BYTE showHighlights;
|
||||
BYTE bakedBackground;
|
||||
int frames;
|
||||
|
||||
TextureData(IDirect3DTexture9** tex, BYTE show, BYTE baked, int frames)
|
||||
: textures(tex), showHighlights(show), bakedBackground(baked), frames(frames) {}
|
||||
};
|
||||
|
||||
typedef stdext::hash_map<__int64, TextureData> :: iterator tex_itr;
|
||||
typedef stdext::hash_map<__int64, TextureData> :: const_iterator tex_citr;
|
||||
|
||||
static stdext::hash_map<__int64, TextureData> texMap;
|
||||
|
||||
static const char* headSuffix[] = { "gv", "gf", "gn", "ng", "nf", "nb", "bn", "bf", "bv", "gp", "np", "bp" };
|
||||
|
||||
static BYTE showHighlights;
|
||||
static long reactionID;
|
||||
|
||||
bool Use32BitTalkingHeads = false;
|
||||
|
||||
/* Head FID
|
||||
0-000-1000-00000000-0000-000000000000
|
||||
ID3 Type ID2 ID1 .lst index
|
||||
*/
|
||||
static bool GetHeadFrmName(char* name) {
|
||||
int headFid = (*(DWORD*)_lips_draw_head)
|
||||
? *ptr_lipsFID
|
||||
: *ptr_fidgetFID;
|
||||
int index = headFid & 0xFFF;
|
||||
if (index >= ptr_art[8].total) return true; // OBJ_TYPE_HEAD
|
||||
int ID2 = (*(DWORD*)_fidgetFp) ? (headFid & 0xFF0000) >> 16 : reactionID;
|
||||
if (ID2 > 11) return true;
|
||||
int ID1 = (ID2 == 1 || ID2 == 4 || ID2 == 7) ? (headFid & 0xF000) >> 12 : -1;
|
||||
//if (ID1 > 3) ID1 = 3;
|
||||
const char* headLst = ptr_art[8].names; // OBJ_TYPE_HEAD
|
||||
char* fmt = (ID1 != -1) ? "%s%s%d" : "%s%s";
|
||||
_snprintf(name, 8, fmt, &headLst[13 * index], headSuffix[ID2], ID1);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void LoadFrm(Frm* frm) {
|
||||
static void StrAppend(char* buf, const char* str, int pos) {
|
||||
int i = 0;
|
||||
while (pos < MAX_PATH && str[i]) buf[pos++] = str[i++];
|
||||
buf[pos] = str[i]; // copy '\0'
|
||||
}
|
||||
|
||||
static bool LoadFrm(Frm* frm) { // backporting WIP
|
||||
if (!frm->key && GetHeadFrmName(frm->path)) {
|
||||
frm->broken = 1;
|
||||
return false;
|
||||
}
|
||||
tex_citr itr = texMap.find(frm->key);
|
||||
if (itr == texMap.end()) {
|
||||
//Load textures
|
||||
// Loading head frames textures
|
||||
*(DWORD*)_bk_disabled = 1;
|
||||
char buf[MAX_PATH];
|
||||
int pathLen = sprintf_s(buf, "%s\\art\\heads\\%s\\", *(char**)_patches, frm->path);
|
||||
if (pathLen > 250) return false;
|
||||
IDirect3DTexture9** textures = new IDirect3DTexture9*[frm->frames];
|
||||
for (int i = 0; i < frm->frames; i++) {
|
||||
sprintf(buf, "%s\\art\\heads\\%s\\%d.png", *(char**)_patches, frm->path, i);
|
||||
sprintf(&buf[pathLen], "%d.png", i);
|
||||
if (FAILED(D3DXCreateTextureFromFileExA(d3d9Device, buf, 0, 0, 1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, 0, &textures[i]))) {
|
||||
for (int j = 0; j < i; j++) textures[j]->Release();
|
||||
delete[] textures;
|
||||
frm->broken = 1;
|
||||
return;
|
||||
*(DWORD*)_bk_disabled = 0;
|
||||
return false;
|
||||
}
|
||||
ProcessBk(); // eliminate lag when loading textures
|
||||
}
|
||||
if (frm->magic != 0xABCD) { // frm file not patched
|
||||
StrAppend(buf, "highlight.off", pathLen);
|
||||
if (GetFileAttributes(buf) != INVALID_FILE_ATTRIBUTES) frm->showHighlights = 1; // disable highlights
|
||||
StrAppend(buf, "background.off", pathLen);
|
||||
if (GetFileAttributes(buf) != INVALID_FILE_ATTRIBUTES) frm->bakedBackground = 1; // fills entire frame surface with a key-color
|
||||
}
|
||||
frm->textures = textures;
|
||||
texMap[frm->key]=textures;
|
||||
texMap.insert(std::make_pair(frm->key, TextureData(textures, frm->showHighlights, frm->bakedBackground, frm->frames)));
|
||||
*(DWORD*)_bk_disabled = 0;
|
||||
} else {
|
||||
// Use preloaded textures
|
||||
frm->textures=itr->second;
|
||||
frm->textures = itr->second.textures;
|
||||
frm->showHighlights = itr->second.showHighlights;
|
||||
frm->bakedBackground = itr->second.bakedBackground;
|
||||
}
|
||||
//mask image
|
||||
// make mask image
|
||||
for (int i = 0; i < frm->frames; i++) {
|
||||
Frame* frame=FramePointer(frm, i);
|
||||
FrmSubframeData* frame = FramePtr((FrmFrameData*)frm, i, 0);
|
||||
if (frm->bakedBackground) {
|
||||
memset(frame->data, 0x30, frame->size);
|
||||
memset(frame->data, 255, frame->size);
|
||||
} else {
|
||||
for (DWORD j = 0; j < frame->size; j++) {
|
||||
if(frame->data[j]) frame->data[j]=0x30;
|
||||
if (frame->data[j]) frame->data[j] = 255; // set index color
|
||||
}
|
||||
}
|
||||
}
|
||||
frm->loaded = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void _stdcall DrawFrmHookInternal(Frm* frm, int frameno) {
|
||||
if(!frm) return;
|
||||
if(frm->magic==0xabcd&&!frm->broken) {
|
||||
if(!frm->loaded) LoadFrm(frm);
|
||||
if(frm->broken) return;
|
||||
Frame* frame=FramePointer(frm, frameno);
|
||||
SetHeadTex(frm->textures[frameno], frame->width, frame->height, frame->xoffset+frm->xshift, frame->yoffset+frm->yshift);
|
||||
overridden=!frm->showHighlights;
|
||||
} else overridden=0;
|
||||
static void __fastcall DrawHeadFrame(Frm* frm, int frameno) {
|
||||
if (frm && !frm->broken) {
|
||||
if (!frm->loaded && !LoadFrm(frm)) goto loadFail;
|
||||
FrmSubframeData* frame = FramePtr((FrmFrameData*)frm, frameno, 0);
|
||||
Gfx_SetHeadTex(frm->textures[frameno], frame->width, frame->height, frame->x + frm->xshift, frame->y + frm->yshift/*, (frm->showHighlights == 2)*/);
|
||||
showHighlights = frm->showHighlights;
|
||||
return;
|
||||
}
|
||||
loadFail:
|
||||
showHighlights = 0; // show vanilla highlights
|
||||
Gfx_SetDefaultTechnique();
|
||||
}
|
||||
|
||||
static const DWORD gdDisplayFrameRet = 0x44AD06;
|
||||
static void __declspec(naked) DrawFrmHook() {
|
||||
static void __declspec(naked) gdDisplayFrame_hack() {
|
||||
__asm {
|
||||
push edx;
|
||||
push eax;
|
||||
push edx;
|
||||
push eax;
|
||||
call DrawFrmHookInternal;
|
||||
mov ecx, eax; // frm file
|
||||
call DrawHeadFrame; // edx - frameno
|
||||
pop eax;
|
||||
pop edx;
|
||||
sub esp, 0x38;
|
||||
@@ -145,43 +189,72 @@ static void __declspec(naked) DrawFrmHook() {
|
||||
}
|
||||
}
|
||||
|
||||
static const DWORD EndSpeechHookRet=0x447299;
|
||||
void __declspec(naked) EndSpeechHook() {
|
||||
void __declspec(naked) gdDestroyHeadWindow_hack() {
|
||||
__asm {
|
||||
push label;
|
||||
push ebx;
|
||||
push ecx;
|
||||
push edx;
|
||||
push edi;
|
||||
push ebp;
|
||||
jmp EndSpeechHookRet;
|
||||
label:
|
||||
xor eax, eax;
|
||||
push eax;
|
||||
push eax;
|
||||
push eax;
|
||||
push eax;
|
||||
push eax;
|
||||
call SetHeadTex;
|
||||
call Gfx_SetDefaultTechnique;
|
||||
mov showHighlights, 0;
|
||||
pop ebp;
|
||||
pop edi;
|
||||
pop edx;
|
||||
pop ecx;
|
||||
pop ebx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) TransTalkHook() {
|
||||
__asm {
|
||||
cmp overridden, 0;
|
||||
jne skip;
|
||||
test showHighlights, 0xFF;
|
||||
jnz skip;
|
||||
jmp talk_to_translucent_trans_buf_to_buf_;
|
||||
skip:
|
||||
retn 0x18;
|
||||
}
|
||||
}
|
||||
|
||||
void HeadsInit() {
|
||||
if (GetPrivateProfileInt("Graphics", "Use32BitHeadGraphics", 0, ini)) {
|
||||
HookCall(0x44AFB4, &TransTalkHook);
|
||||
HookCall(0x44B00B, &TransTalkHook);
|
||||
MakeJump(0x44AD01, DrawFrmHook);
|
||||
MakeJump(0x447294, EndSpeechHook);
|
||||
static void __declspec(naked) gdPlayTransition_hook() {
|
||||
__asm {
|
||||
mov reactionID, ebx;
|
||||
jmp art_id_;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) gdialogInitFromScript_hook() {
|
||||
__asm {
|
||||
cmp dword ptr ds:[_dialogue_head], -1;
|
||||
jnz noScroll;
|
||||
jmp tile_scroll_to_;
|
||||
noScroll:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void TalkingHeadsSetup() {
|
||||
if (!GPUBlt) return;
|
||||
|
||||
HookCall(0x44AFB4, TransTalkHook);
|
||||
HookCall(0x44B00B, TransTalkHook);
|
||||
MakeJump(0x44AD01, gdDisplayFrame_hack); // Draw Frm
|
||||
MakeJump(0x4472F8, gdDestroyHeadWindow_hack);
|
||||
HookCall(0x44768B, gdPlayTransition_hook);
|
||||
}
|
||||
|
||||
void TalkingHeadsInit() {
|
||||
// Disable centering the screen if NPC has talking head
|
||||
HookCall(0x445224, gdialogInitFromScript_hook);
|
||||
|
||||
if (GraphicsMode && GetPrivateProfileInt("Graphics", "Use32BitHeadGraphics", 0, ini)) {
|
||||
Use32BitTalkingHeads = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TalkingHeadsExit() {
|
||||
if (!texMap.empty()) {
|
||||
for (tex_citr it = texMap.begin(); it != texMap.end(); ++it) {
|
||||
for (int i = 0; i < it->second.frames; i++) {
|
||||
it->second.textures[i]->Release();
|
||||
}
|
||||
delete[] it->second.textures;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
void HeadsInit();
|
||||
extern bool Use32BitTalkingHeads;
|
||||
|
||||
void TalkingHeadsSetup();
|
||||
void TalkingHeadsInit();
|
||||
void TalkingHeadsExit();
|
||||
|
||||
+7
-44
@@ -228,20 +228,6 @@ static __declspec(naked) void PathfinderFix() {
|
||||
}
|
||||
}
|
||||
|
||||
static double FadeMulti;
|
||||
static __declspec(naked) void palette_fade_to_hook() {
|
||||
__asm {
|
||||
//pushf;
|
||||
push ebx;
|
||||
fild [esp];
|
||||
fmul FadeMulti;
|
||||
fistp [esp];
|
||||
pop ebx;
|
||||
//popf;
|
||||
jmp fadeSystemPalette_;
|
||||
}
|
||||
}
|
||||
|
||||
static int mapSlotsScrollMax = 27 * (17 - 7);
|
||||
static __declspec(naked) void ScrollCityListFix() {
|
||||
__asm {
|
||||
@@ -875,6 +861,12 @@ static void DllMain2() {
|
||||
dlogr("Running SpeedPatchInit().", DL_INIT);
|
||||
SpeedPatchInit();
|
||||
|
||||
dlogr("Running GraphicsInit().", DL_INIT);
|
||||
GraphicsInit();
|
||||
|
||||
dlogr("Running TalkingHeadsInit().", DL_INIT);
|
||||
TalkingHeadsInit();
|
||||
|
||||
//if (GetPrivateProfileIntA("Input", "Enable", 0, ini)) {
|
||||
dlog("Applying input patch.", DL_INIT);
|
||||
SafeWriteStr(0x50FB70, "ddraw.dll");
|
||||
@@ -882,36 +874,6 @@ static void DllMain2() {
|
||||
dlogr(" Done", DL_INIT);
|
||||
//}
|
||||
|
||||
GraphicsMode = GetPrivateProfileIntA("Graphics", "Mode", 0, ini);
|
||||
if (GraphicsMode != 4 && GraphicsMode != 5) {
|
||||
GraphicsMode = 0;
|
||||
}
|
||||
if (GraphicsMode == 4 || GraphicsMode == 5) {
|
||||
dlog("Applying DX9 graphics patch.", DL_INIT);
|
||||
#ifdef WIN2K
|
||||
#define _DLL_NAME "d3dx9_42.dll"
|
||||
#else
|
||||
#define _DLL_NAME "d3dx9_43.dll"
|
||||
#endif
|
||||
HMODULE h = LoadLibraryEx(_DLL_NAME, 0, LOAD_LIBRARY_AS_DATAFILE);
|
||||
if (!h) {
|
||||
MessageBoxA(0, "You have selected graphics mode 4 or 5, but " _DLL_NAME " is missing\nSwitch back to mode 0, or install an up to date version of DirectX", "Error", 0);
|
||||
ExitProcess(-1);
|
||||
} else {
|
||||
FreeLibrary(h);
|
||||
}
|
||||
#undef _DLL_NAME
|
||||
SafeWrite8(0x50FB6B, '2'); // Set call DirectDrawCreate2
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
FadeMulti = GetPrivateProfileIntA("Graphics", "FadeMultiplier", 100, ini);
|
||||
if (FadeMulti != 100) {
|
||||
dlog("Applying fade patch.", DL_INIT);
|
||||
HookCall(0x493B16, palette_fade_to_hook);
|
||||
FadeMulti = ((double)FadeMulti) / 100.0;
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
dlogr("Running DamageModInit().", DL_INIT);
|
||||
DamageModInit();
|
||||
|
||||
@@ -1606,6 +1568,7 @@ static void _stdcall OnExit() {
|
||||
HeroAppearanceModExit();
|
||||
MoviesExit();
|
||||
GraphicsExit();
|
||||
TalkingHeadsExit();
|
||||
//SoundExit();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user