Corrected talking heads code of Use32BitHeadGraphics

Minor code correction.
This commit is contained in:
NovaRain
2020-09-19 00:37:16 +08:00
parent 2eb1c64bc3
commit 806e09e501
6 changed files with 111 additions and 30 deletions
+57 -3
View File
@@ -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##_) \
+2 -1
View File
@@ -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);
+6 -2
View File
@@ -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
View File
@@ -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();
}
+1 -1
View File
@@ -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();
+22 -2
View File
@@ -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) {