mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Corrected talking heads code of Use32BitHeadGraphics
Minor code correction.
This commit is contained in:
@@ -516,9 +516,62 @@ void __fastcall trans_cscale(long i_width, long i_height, long s_width, long s_h
|
||||
}
|
||||
}
|
||||
|
||||
//void __declspec(naked) __stdcall buf_to_buf(void* to_buf, long to_width, void* from_buf, long from_width, long width, long height) {
|
||||
// __asm jmp fo::funcoffs::srcCopy_;
|
||||
//}
|
||||
// Engine function buf_to_buf_ with SSE implementation
|
||||
void __cdecl buf_to_buf(void* src, long width, long height, long src_width, void* dst, long dst_width) {
|
||||
if (height <= 0 || width <= 0) return;
|
||||
|
||||
size_t blockCount = width / 64; // 64 bytes
|
||||
size_t remainder = width % 64;
|
||||
size_t remainderD = remainder / 4;
|
||||
size_t remainderB = remainder % 4;
|
||||
size_t s_pitch = src_width - width;
|
||||
size_t d_pitch = dst_width - width;
|
||||
|
||||
__asm {
|
||||
mov ebx, s_pitch;
|
||||
mov edx, d_pitch;
|
||||
mov esi, src;
|
||||
mov edi, dst;
|
||||
mov eax, height;
|
||||
startLoop:
|
||||
mov ecx, blockCount;
|
||||
test ecx, ecx;
|
||||
jz copySmall;
|
||||
copyBlock: // copies block of 64 bytes
|
||||
movups xmm0, [esi];
|
||||
movups xmm1, [esi + 16];
|
||||
movups xmm2, [esi + 32];
|
||||
movups xmm3, [esi + 48];
|
||||
movups [edi], xmm0;
|
||||
movups [edi + 16], xmm1;
|
||||
movups [edi + 32], xmm2;
|
||||
movups [edi + 48], xmm3;
|
||||
add esi, 64;
|
||||
lea edi, [edi + 64];
|
||||
dec ecx; // blockCount
|
||||
jnz copyBlock;
|
||||
// copies the remaining bytes
|
||||
mov ecx, remainderD;
|
||||
rep movsd;
|
||||
mov ecx, remainderB;
|
||||
rep movsb;
|
||||
add esi, ebx; // s_pitch
|
||||
add edi, edx; // d_pitch
|
||||
dec eax; // height
|
||||
jnz startLoop;
|
||||
jmp end;
|
||||
copySmall: // copies the small size data
|
||||
mov ecx, remainderD;
|
||||
rep movsd;
|
||||
mov ecx, remainderB;
|
||||
rep movsb;
|
||||
add esi, ebx; // s_pitch
|
||||
add edi, edx; // d_pitch
|
||||
dec eax; // height
|
||||
jnz copySmall;
|
||||
end:
|
||||
}
|
||||
}
|
||||
|
||||
long __fastcall get_game_config_string(const char* outValue, const char* section, const char* param) {
|
||||
__asm {
|
||||
@@ -531,6 +584,7 @@ long __fastcall get_game_config_string(const char* outValue, const char* section
|
||||
////////////////////////////////////
|
||||
// X-Macro for wrapper functions. //
|
||||
////////////////////////////////////
|
||||
|
||||
#define WRAP_WATCOM_FUNC0(retType, name) \
|
||||
retType __stdcall name() { \
|
||||
WRAP_WATCOM_CALL0(name##_) \
|
||||
|
||||
@@ -214,7 +214,8 @@ void __fastcall displayInWindow(long w_here, long width, long height, void* data
|
||||
|
||||
void __fastcall trans_cscale(long i_width, long i_height, long s_width, long s_height, long xy_shift, long w_width, void* data);
|
||||
|
||||
//void __declspec() __stdcall buf_to_buf(void* to_buf, long to_width, void* from_buf, long from_width, long width, long height);
|
||||
// Engine function buf_to_buf_ with SSE implementation
|
||||
void __cdecl buf_to_buf(void* src, long width, long height, long src_width, void* dst, long dst_width);
|
||||
|
||||
long __fastcall get_game_config_string(const char* outValue, const char* section, const char* param);
|
||||
|
||||
|
||||
@@ -62,7 +62,10 @@ void __stdcall ForceGraphicsRefresh(DWORD d) {
|
||||
}
|
||||
|
||||
void GetMouse(int* x, int* y) {
|
||||
*x = mouseX; *y = mouseY; mouseX = 0; mouseY = 0;
|
||||
*x = mouseX;
|
||||
*y = mouseY;
|
||||
mouseX = 0;
|
||||
mouseY = 0;
|
||||
}
|
||||
|
||||
static BYTE LMouse = 0;
|
||||
@@ -354,7 +357,8 @@ private:
|
||||
public:
|
||||
/*** Constructor ***/
|
||||
FakeDirectInput(IDirectInput* Real) {
|
||||
RealInput = Real; Refs = 1;
|
||||
RealInput = Real;
|
||||
Refs = 1;
|
||||
}
|
||||
|
||||
/*** IUnknown methods ***/
|
||||
|
||||
+23
-21
@@ -69,7 +69,7 @@ static DWORD windowTop = 0;
|
||||
static HWND window;
|
||||
static DWORD windowStyle = WS_CAPTION | WS_BORDER | WS_MINIMIZEBOX;
|
||||
|
||||
static unsigned int windowData;
|
||||
static int windowData;
|
||||
|
||||
static DWORD ShaderVersion;
|
||||
|
||||
@@ -120,7 +120,7 @@ static const char* gpuEffect =
|
||||
// blend highlights
|
||||
"if (showhl) {"
|
||||
"float4 h = tex2D(s3, saturate((Tex - cornerhl) / sizehl));"
|
||||
"result = saturate(result + h.rgb);" // saturate(result * (1 - h.a) * h.rgb * h.a)"
|
||||
"result = saturate(result + h);" // saturate(result * (1 - h.a) * h.rgb * h.a)"
|
||||
"}"
|
||||
"return float4(result.r, result.g, result.b, 1);"
|
||||
"}"
|
||||
@@ -556,7 +556,7 @@ void Graphics::ShowMovieFrame(IDirect3DTexture9* tex) {
|
||||
Present();
|
||||
}
|
||||
|
||||
void Graphics::SetHighlightTexture(IDirect3DTexture9* htex) {
|
||||
void Graphics::SetHighlightTexture(IDirect3DTexture9* htex, int xPos, int yPos) {
|
||||
gpuBltEffect->SetTexture(gpuBltHighlight, htex);
|
||||
|
||||
float size[2];
|
||||
@@ -564,11 +564,8 @@ void Graphics::SetHighlightTexture(IDirect3DTexture9* htex) {
|
||||
size[1] = 200.0f * rcpres[1];
|
||||
gpuBltEffect->SetFloatArray(gpuBltHighlightSize, size, 2);
|
||||
|
||||
int xPos = ((GetGameWidthRes() - 640) / 2);
|
||||
size[0] = (126.0f + xPos) * rcpres[0];
|
||||
int h = GetGameHeightRes();
|
||||
int yPos = (h > 480) ? ((h - 480) / 2) - 33 : 14;
|
||||
size[1] = (float)yPos * rcpres[1];
|
||||
size[1] = (16.0f + yPos) * rcpres[1];
|
||||
gpuBltEffect->SetFloatArray(gpuBltHighlightCorner, size, 2);
|
||||
}
|
||||
|
||||
@@ -581,11 +578,6 @@ void Graphics::SetHeadTex(IDirect3DTexture9* tex, int width, int height, int xof
|
||||
size[1] = (float)height * rcpres[1];
|
||||
gpuBltEffect->SetFloatArray(gpuBltHeadSize, size, 2);
|
||||
|
||||
// adjust head texture position for HRP 4.1.8
|
||||
int h = GetGameHeightRes();
|
||||
if (h > 480) yoff += ((h - 480) / 2) - 47; // TODO: get dialog interface position
|
||||
xoff += ((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);
|
||||
@@ -659,6 +651,7 @@ public:
|
||||
int pitch = dRect.Pitch;
|
||||
|
||||
if (Graphics::GPUBlt) {
|
||||
//fo::func::buf_to_buf(lockTarget, width, mveDesc.dwHeight, width, dRect.pBits, pitch); // SSE
|
||||
char* pBits = (char*)dRect.pBits;
|
||||
for (DWORD y = 0; y < mveDesc.dwHeight; y++) {
|
||||
CopyMemory(&pBits[y * pitch], &lockTarget[y * width], width);
|
||||
@@ -875,7 +868,8 @@ public:
|
||||
HRESULT __stdcall SetEntries(DWORD a, DWORD b, DWORD c, LPPALETTEENTRY destPal) { // used to set palette for splash screen, fades, subtitles
|
||||
if (!windowInit || c == 0 || b + c > 256) return DDERR_INVALIDPARAMS;
|
||||
|
||||
CopyMemory(&palette[b], destPal, c * 4);
|
||||
CopyMemory(&palette[b], destPal, c * 4); // __movsd(&palette[b], (unsigned long*)destPal, c); // SSE
|
||||
|
||||
if (Graphics::GPUBlt && gpuPalette) {
|
||||
D3DLOCKED_RECT rect;
|
||||
if (!FAILED(gpuPalette->LockRect(0, &rect, 0, D3DLOCK_DISCARD))) {
|
||||
@@ -884,10 +878,10 @@ public:
|
||||
}
|
||||
} else {
|
||||
// X8B8G8R8 format
|
||||
for (DWORD i = b; i < b + c; i++) { // swap color B <> R
|
||||
BYTE clr = *(BYTE*)((DWORD)&palette[i]); // B
|
||||
*(BYTE*)((DWORD)&palette[i]) = *(BYTE*)((DWORD)&palette[i] + 2); // R
|
||||
*(BYTE*)((DWORD)&palette[i] + 2) = clr;
|
||||
for (size_t i = b; i < b + c; i++) { // swap color B <> R
|
||||
BYTE clr = *(BYTE*)((long)&palette[i]); // B
|
||||
*(BYTE*)((long)&palette[i]) = *(BYTE*)((long)&palette[i] + 2); // R
|
||||
*(BYTE*)((long)&palette[i] + 2) = clr;
|
||||
}
|
||||
primaryDDSurface->SetPalette(0); // update
|
||||
if (FakeDirectDrawSurface::IsPlayMovie) return DD_OK; // prevents flickering at the beginning of playback (w/o HRP & GPUBlt=2)
|
||||
@@ -1077,8 +1071,12 @@ HRESULT __stdcall InitFakeDirectDrawCreate(void*, IDirectDraw** b, void*) {
|
||||
moveWindowKey[0] &= 0xFF;
|
||||
}
|
||||
windowData = GetConfigInt("Graphics", "WindowData", 0);
|
||||
windowLeft = windowData >> 16;
|
||||
windowTop = windowData & 0xFFFF;
|
||||
if (windowData > 0) {
|
||||
windowLeft = windowData >> 16;
|
||||
windowTop = windowData & 0xFFFF;
|
||||
} else {
|
||||
windowData = 0;
|
||||
}
|
||||
}
|
||||
|
||||
rcpres[0] = 1.0f / (float)gWidth;
|
||||
@@ -1100,6 +1098,7 @@ static __declspec(naked) void game_init_hook() {
|
||||
}
|
||||
|
||||
static double fadeMulti;
|
||||
|
||||
static __declspec(naked) void palette_fade_to_hook() {
|
||||
__asm {
|
||||
push ebx; // _fade_steps
|
||||
@@ -1143,13 +1142,16 @@ void Graphics::init() {
|
||||
fadeMulti = ((double)fadeMulti) / 100.0;
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
// Replace the srcCopy_ function with an SSE implementation
|
||||
//MakeJump(0x4D36D4, fo::func::buf_to_buf); // buf_to_buf_
|
||||
}
|
||||
|
||||
void Graphics::exit() {
|
||||
if (Graphics::mode) {
|
||||
if (Graphics::mode == 5) {
|
||||
unsigned int data = windowTop | (windowLeft << 16);
|
||||
if (data != windowData) SetConfigInt("Graphics", "WindowData", data);
|
||||
int data = windowTop | (windowLeft << 16);
|
||||
if (data >= 0 && data != windowData) SetConfigInt("Graphics", "WindowData", data);
|
||||
}
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public:
|
||||
|
||||
static const float* rcpresGet();
|
||||
|
||||
static void SetHighlightTexture(IDirect3DTexture9* htex);
|
||||
static void SetHighlightTexture(IDirect3DTexture9* htex, int xPos, int yPos);
|
||||
static void SetHeadTex(IDirect3DTexture9* tex, int width, int height, int xoff, int yoff, int showHighlight);
|
||||
static void SetHeadTechnique();
|
||||
static void SetDefaultTechnique();
|
||||
|
||||
@@ -85,6 +85,7 @@ static long reactionID;
|
||||
0-000-1000-00000000-0000-000000000000
|
||||
ID3 Type ID2 ID1 .lst index
|
||||
*/
|
||||
|
||||
static bool GetHeadFrmName(char* name) {
|
||||
int headFid = (*(DWORD*)FO_VAR_lips_draw_head)
|
||||
? fo::var::lipsFID
|
||||
@@ -119,6 +120,11 @@ static bool LoadFrm(Frm* frm) {
|
||||
char buf[MAX_PATH];
|
||||
int pathLen = sprintf_s(buf, "%s\\art\\heads\\%s\\", fo::var::patches, frm->path);
|
||||
if (pathLen > 250) return false;
|
||||
|
||||
if (!(GetFileAttributes(frm->path) & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
frm->broken = 1;
|
||||
return false;
|
||||
}
|
||||
IDirect3DTexture9** textures = new IDirect3DTexture9*[frm->frames];
|
||||
for (int i = 0; i < frm->frames; i++) {
|
||||
sprintf(&buf[pathLen], "%d.png", i);
|
||||
@@ -166,11 +172,24 @@ static bool LoadFrm(Frm* frm) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static fo::Window* dialogWin = nullptr;
|
||||
|
||||
static void __fastcall DrawHeadFrame(Frm* frm, int frameno) {
|
||||
if (frm && !frm->broken) {
|
||||
if (!frm->loaded && !LoadFrm(frm)) goto loadFail;
|
||||
fo::FrmFrameData* frame = fo::func::frame_ptr((fo::FrmHeaderData*)frm, frameno, 0);
|
||||
Graphics::SetHeadTex(frm->textures[frameno], frame->width, frame->height, frame->x + frm->xshift, frame->y + frm->yshift, (frm->showHighlights == 2));
|
||||
|
||||
if (dialogWin == nullptr) {
|
||||
dialogWin = fo::func::GNW_find(fo::var::dialogueBackWindow);
|
||||
if (texHighlight) Graphics::SetHighlightTexture(texHighlight, dialogWin->wRect.left, dialogWin->wRect.top);
|
||||
}
|
||||
Graphics::SetHeadTex(frm->textures[frameno],
|
||||
frame->width,
|
||||
frame->height,
|
||||
frame->x + frm->xshift + dialogWin->wRect.left,
|
||||
frame->y + frm->yshift + dialogWin->wRect.top,
|
||||
(frm->showHighlights == 2)
|
||||
);
|
||||
showHighlights = frm->showHighlights;
|
||||
return;
|
||||
}
|
||||
@@ -198,6 +217,7 @@ void __declspec(naked) gdDestroyHeadWindow_hack() {
|
||||
__asm {
|
||||
call Graphics::SetDefaultTechnique;
|
||||
mov showHighlights, 0;
|
||||
//mov dialogWin, 0; // uncomment if the dialog window position is supposed to change
|
||||
pop ebp;
|
||||
pop edi;
|
||||
pop edx;
|
||||
@@ -237,6 +257,7 @@ noScroll:
|
||||
static void TalkingHeadsInit() {
|
||||
if (!Graphics::GPUBlt) return;
|
||||
|
||||
*(DWORD*)FO_VAR_lips_draw_head = 0; // fix for non-speaking heads
|
||||
HookCalls(TransTalkHook, {0x44AFB4, 0x44B00B});
|
||||
MakeJump(0x44AD01, gdDisplayFrame_hack); // Draw Frm
|
||||
MakeJump(0x4472F8, gdDestroyHeadWindow_hack);
|
||||
@@ -246,7 +267,6 @@ static void TalkingHeadsInit() {
|
||||
char buf[MAX_PATH];
|
||||
sprintf_s(buf, "%s\\art\\stex\\highlight.png", fo::var::patches);
|
||||
if (!FAILED(D3DXCreateTextureFromFileExA(d3d9Device, buf, 0, 0, 1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, 0, &texHighlight))) {
|
||||
Graphics::SetHighlightTexture(texHighlight);
|
||||
LoadGameHook::OnGameModeChange() += [](DWORD state) {
|
||||
static bool setHeadTech = false;
|
||||
if (showHighlights == 2) {
|
||||
|
||||
Reference in New Issue
Block a user