Skip to content

Commit

Permalink
window coord fixes, ignore tiny gdi frames (affects sync in certain g…
Browse files Browse the repository at this point in the history
…ames), fix f2 recognition in eternal daughter, added "trusted only" threadmode, maybe fixed occasional frame of silence in audio+video AVIs, fixed bmd startup with threads disabled
  • Loading branch information
[email protected] committed Jun 20, 2011
1 parent 89289bf commit 4759a3e
Show file tree
Hide file tree
Showing 10 changed files with 318 additions and 134 deletions.
283 changes: 184 additions & 99 deletions src/wintasee/hooks/ddrawhooks.cpp

Large diffs are not rendered by default.

72 changes: 60 additions & 12 deletions src/wintasee/hooks/gdihooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,34 @@ static void FrameBoundaryHDCtoAVI(HDC hdc,int xSrc,int ySrc,int xRes,int yRes)
#endif
}

static const int gdiFrameBigEnoughWidth = 120;
static const int gdiFrameBigEnoughHeight = 80;
static bool HDCSizeBigEnoughForFrameBoundary(HDC hdc)
{
#ifdef UNSELECT_BEFORE_HDC_CAPTURE
// the docs say: "The bitmap identified by the hbmp parameter must not be selected into a device context when the application calls this function."
HBITMAP bitmap = (HBITMAP)SelectObject(hdc, CreateCompatibleBitmap(hdc, 1, 1));
#else
// but this appears to work fine and it's probably at least a little bit faster, so...
HBITMAP bitmap = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
#endif

BITMAPINFO bmi = {sizeof(BITMAPINFOHEADER)};
GetDIBits(hdc, bitmap, 0, 0, 0, &bmi, DIB_RGB_COLORS);

int width = bmi.bmiHeader.biWidth;
int height = bmi.bmiHeader.biHeight;
if(height < 0) height = -height;

bool bigEnough = (width >= gdiFrameBigEnoughWidth && height >= gdiFrameBigEnoughHeight);

#ifdef UNSELECT_BEFORE_HDC_CAPTURE
DeleteObject(SelectObject(hdc, bitmap));
#endif

return bigEnough;
}



int depth_SwapBuffers = 0;
Expand Down Expand Up @@ -164,6 +192,20 @@ HOOKFUNC BOOL MySwapBuffers(HDC hdc)
}




void RescaleRect(RECT& rect, RECT from, RECT to)
{
rect.left = ((rect.left - from.left) * (to.right - to.left)) / (from.right - from.left) + to.left;
rect.top = ((rect.top - from.top) * (to.bottom - to.top)) / (from.bottom - from.top) + to.top;
rect.right = ((rect.right - from.left) * (to.right - to.left)) / (from.right - from.left) + to.left;
rect.bottom = ((rect.bottom - from.top) * (to.bottom - to.top)) / (from.bottom - from.top) + to.top;
}





static HDC s_hdcSrcSaved;
static HDC s_hdcDstSaved;
static bool s_gdiPendingRefresh;
Expand All @@ -190,7 +232,11 @@ HOOKFUNC BOOL WINAPI MyStretchBlt(
if((/*s_gdiPhaseDetector.AdvanceAndCheckCycleBoundary(MAKELONG(nXOriginDest,nYOriginDest))
||*/ tls.peekedMessage) && VerifyIsTrustedCaller(!tls.callerisuntrusted))
{
isFrameBoundary = true;
if((nWidthSrc >= gdiFrameBigEnoughWidth && nHeightSrc >= gdiFrameBigEnoughHeight)
|| HDCSizeBigEnoughForFrameBoundary(hdcSrc))
{
isFrameBoundary = true;
}
}
}
}
Expand Down Expand Up @@ -245,7 +291,11 @@ HOOKFUNC BOOL WINAPI MyBitBlt(
if((/*s_gdiPhaseDetector.AdvanceAndCheckCycleBoundary(MAKELONG(nXDest,nYDest))
||*/ tls.peekedMessage) && VerifyIsTrustedCaller(!tls.callerisuntrusted))
{
isFrameBoundary = true;
if((nWidth >= gdiFrameBigEnoughWidth && nHeight >= gdiFrameBigEnoughHeight)
|| HDCSizeBigEnoughForFrameBoundary(hdcSrc))
{
isFrameBoundary = true;
}
}
}
}
Expand All @@ -271,29 +321,27 @@ HOOKFUNC BOOL WINAPI MyBitBlt(
else
{
HWND hwnd = WindowFromDC(hdcDest);
RECT rect;
if(!GetClientRect(hwnd, &rect) || (rect.right == fakeDisplayWidth && rect.bottom == fakeDisplayHeight))
RECT realRect;
if(!GetClientRect(hwnd, &realRect) || (realRect.right == fakeDisplayWidth && realRect.bottom == fakeDisplayHeight))
{
rv = BitBlt(hdcDest,nXDest,nYDest,nWidth,nHeight,hdcSrc,nXSrc,nYSrc,dwRop);
}
else
{
// support resized fake-fullscreen windows in games like Lyle in Cube Sector
// a little iffy: sprites leave pixels behind occasionally at non-integral scales
HDC hdcTemp = 0;
HDC hdc = hdcDest;
if(rect.right > fakeDisplayWidth || rect.bottom > fakeDisplayHeight)
if(realRect.right > fakeDisplayWidth || realRect.bottom > fakeDisplayHeight)
{
// sidestep clip region (it can't be expanded without switching HDCs)
hdcTemp = GetDC(hwnd);
hdc = hdcTemp;
}
// iffy, sprites leave pixels behind occasionally at non-integral scales
int x0 = (nXDest * rect.right) / fakeDisplayWidth;
int y0 = (nYDest * rect.bottom) / fakeDisplayHeight;
int x1 = ((nXDest+nWidth) * rect.right) / fakeDisplayWidth;
int y1 = ((nYDest+nHeight) * rect.bottom) / fakeDisplayHeight;
//debugprintf("%dx%d -> %dx%d ... (%d,%d,%d,%d) -> (%d,%d,%d,%d)\n", fakeDisplayWidth, fakeDisplayHeight, rect.right, rect.bottom, nXDest,nYDest,nXDest+nWidth,nYDest+nHeight, x0,y0,x1,y1);
rv = StretchBlt(hdc,x0,y0,x1-x0,y1-y0,hdcSrc,nXSrc,nYSrc,nWidth,nHeight,dwRop);
RECT dstRect = {nXDest, nYDest, nXDest+nWidth, nYDest+nHeight};
RECT fakeRect = {0, 0, fakeDisplayWidth, fakeDisplayHeight};
RescaleRect(dstRect, fakeRect, realRect);
rv = StretchBlt(hdc, dstRect.left,dstRect.top,dstRect.right-dstRect.left,dstRect.bottom-dstRect.top, hdcSrc, nXSrc,nYSrc,nWidth,nHeight, dwRop);
if(hdcTemp)
ReleaseDC(hwnd, hdcTemp);
}
Expand Down
17 changes: 13 additions & 4 deletions src/wintasee/hooks/messagehooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,9 +462,12 @@ static MessageActionFlags GetMessageActionFlags(UINT message, WPARAM wParam, LPA
case WM_SETCURSOR:
case WM_NOTIFY:
case WM_SHOWWINDOW:
case WM_COMMAND:
case WM_SYSCOMMAND:
break;//return MAF_INTERCEPT | MAF_RETURN_0; // maybe ok to ditch?
case WM_COMMAND:
if(VerifyIsTrustedCaller(!tls.callerisuntrusted))
return MAF_PASSTHROUGH | MAF_RETURN_OS; // hack to fix F2 command in Eternal Daughter
break;
default:
debuglog(LCF_MESSAGES|LCF_FREQUENT|LCF_TODO, "CONSIDER: 0x%X (%s), 0x%X, 0x%X\n", message, GetWindowsMessageName(message), wParam, lParam);
//cmdprintf("SHORTTRACE: 3,50");
Expand Down Expand Up @@ -636,7 +639,9 @@ HOOKFUNC LRESULT WINAPI MyDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPA
// MyWndProcInternal
LRESULT DispatchMessageInternal(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool ascii/*=true*/, MessageActionFlags maf/*=MAF_PASSTHROUGH|MAF_RETURN_OS*/)
{
if(/*inPauseHandler || */(tls.callerisuntrusted > (InSendMessage()?1:0))) // if it's the OS or pause handler calling us back,
LONG untrusted = tls.callerisuntrusted;
//untrusted = VerifyIsTrustedCaller(!untrusted) ? 0 : (untrusted ? untrusted : 1);
if(/*inPauseHandler || */(untrusted > (InSendMessage()?1:0))) // if it's the OS or pause handler calling us back,
{ // we can't rely on it doing so consistently across systems,
if(!(maf & (MAF_INTERCEPT|MAF_BYPASSGAME)))
{
Expand Down Expand Up @@ -1545,7 +1550,9 @@ HOOKFUNC LRESULT WINAPI MyDispatchMessageA(CONST MSG *lpMsg)
//return MyWndProcA(msg.hwnd, msg.message, msg.wParam, msg.lParam);
return DispatchMessageInternal(msg.hwnd, msg.message, msg.wParam, msg.lParam, true);
#else
LRESULT rv = DispatchMessageA(lpMsg);
// LRESULT rv = DispatchMessageA(lpMsg);
const MSG& msg = *lpMsg;
LRESULT rv = DispatchMessageInternal(msg.hwnd, msg.message, msg.wParam, msg.lParam, true, MAF_PASSTHROUGH|MAF_RETURN_OS);
return rv;
#endif
}
Expand All @@ -1559,7 +1566,9 @@ HOOKFUNC LRESULT WINAPI MyDispatchMessageW(CONST MSG *lpMsg)
//return MyWndProcW(msg.hwnd, msg.message, msg.wParam, msg.lParam);
return DispatchMessageInternal(msg.hwnd, msg.message, msg.wParam, msg.lParam, false);
#else
LRESULT rv = DispatchMessageW(lpMsg);
// LRESULT rv = DispatchMessageW(lpMsg);
const MSG& msg = *lpMsg;
LRESULT rv = DispatchMessageInternal(msg.hwnd, msg.message, msg.wParam, msg.lParam, false, MAF_PASSTHROUGH|MAF_RETURN_OS);
return rv;
#endif
}
Expand Down
8 changes: 4 additions & 4 deletions src/wintasee/hooks/threadhooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,13 @@ HOOKFUNC HANDLE WINAPI MyCreateThread(
debuglog(LCF_THREAD, __FUNCTION__"(0x%X) called, tls.curThreadCreateName = %s\n", (DWORD)lpStartAddress, tls.curThreadCreateName);
//cmdprintf("SHORTTRACE: 3,50");

if(tasflags.threadMode == 0 || tasflags.threadMode == 3 && !tls.curThreadCreateName || tasflags.threadMode == 4 && tls.curThreadCreateName)
if(tasflags.threadMode == 0 || tasflags.threadMode == 3 && !tls.curThreadCreateName || tasflags.threadMode == 4 && tls.curThreadCreateName || (tasflags.threadMode == 5 && !VerifyIsTrustedCaller(!tls.callerisuntrusted)))
{
debuglog(LCF_THREAD, __FUNCTION__": thread creation denied.\n");
cmdprintf("DENIEDTHREAD: %Iu", lpStartAddress);

const char* threadTypeName = tls.curThreadCreateName;

debuglog(LCF_THREAD, __FUNCTION__": thread creation denied. \"%s\"\n", threadTypeName?threadTypeName:"unknown_thread");
cmdprintf("DENIEDTHREAD: %Iu", lpStartAddress);

// FIXME: it's a terrible hack to choose between these two methods depending on whether we have a thread name,
// but it gets herocore working with threads disabled, and I can't think of a better solution at the moment.
// the reason it helps there is that herocore.exe crashes if it can't create a thread but works correctly if it creates a do-nothing thread,
Expand Down
31 changes: 29 additions & 2 deletions src/wintasee/hooks/windowhooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,31 +469,56 @@ HOOKFUNC BOOL WINAPI MyShowWindow(HWND hWnd, int nCmdShow)

HOOKFUNC BOOL WINAPI MyGetClientRect(HWND hWnd, LPRECT lpRect)
{
if(fakeDisplayValid && IsWindowFakeFullscreen(hWnd))
// IsWindowFakeFullscreen checks disabled because they let window position info leak to Eternal Daughter and possibly others (maybe need to use ::IsChild inside IsWindowFakeFullscreen)
// VerifyIsTrustedCaller checks added as a hack so that DirectDrawClipper can still get the real window coordinates
// TODO: instead of calling VerifyIsTrustedCaller we could probably have MyDirectDrawSurface::MyBlt set a flag for us. although maybe this way is safer.
if(fakeDisplayValid/* && IsWindowFakeFullscreen(hWnd)*/ && VerifyIsTrustedCaller(!tls.callerisuntrusted))
{
if(!lpRect)
return FALSE;
lpRect->left = 0;
lpRect->top = 0;
lpRect->right = fakeDisplayWidth;
lpRect->bottom = fakeDisplayHeight;
return TRUE;
}
return GetClientRect(hWnd, lpRect);
}
HOOKFUNC BOOL WINAPI MyGetWindowRect(HWND hWnd, LPRECT lpRect)
{
if(fakeDisplayValid && IsWindowFakeFullscreen(hWnd))
// see coments in MyGetClientRect
if(fakeDisplayValid/* && IsWindowFakeFullscreen(hWnd)*/ && VerifyIsTrustedCaller(!tls.callerisuntrusted))
{
if(!lpRect)
return FALSE;
lpRect->left = 0;
lpRect->top = 0;
lpRect->right = fakeDisplayWidth;
lpRect->bottom = fakeDisplayHeight;
return TRUE;
}
return GetWindowRect(hWnd, lpRect);
}

HOOKFUNC BOOL WINAPI MyClientToScreen(HWND hWnd, LPPOINT lpPoint)
{
// see coments in MyGetClientRect
if(fakeDisplayValid/* && IsWindowFakeFullscreen(hWnd)*/ && VerifyIsTrustedCaller(!tls.callerisuntrusted))
{
return (lpPoint != NULL);
}
return ClientToScreen(hWnd, lpPoint);
}
HOOKFUNC BOOL WINAPI MyScreenToClient(HWND hWnd, LPPOINT lpPoint)
{
// see coments in MyGetClientRect
if(fakeDisplayValid/* && IsWindowFakeFullscreen(hWnd)*/ && VerifyIsTrustedCaller(!tls.callerisuntrusted))
{
return (lpPoint != NULL);
}
return ScreenToClient(hWnd, lpPoint);
}

HOOKFUNC BOOL WINAPI MySetWindowTextA(HWND hWnd, LPCSTR lpString)
{
debuglog(LCF_WINDOW, __FUNCTION__ "(0x%X, \"%s\") called.\n", hWnd, lpString);
Expand Down Expand Up @@ -620,6 +645,8 @@ void ApplyWindowIntercepts()
MAKE_INTERCEPT(1, USER32, ShowWindow),
MAKE_INTERCEPT(1, USER32, GetClientRect),
MAKE_INTERCEPT(1, USER32, GetWindowRect),
MAKE_INTERCEPT(1, USER32, ClientToScreen),
MAKE_INTERCEPT(1, USER32, ScreenToClient),
MAKE_INTERCEPT(1, USER32, SetWindowTextA),
MAKE_INTERCEPT(1, USER32, SetWindowTextW),
//MAKE_INTERCEPT(1, USER32, InvalidateRect),
Expand Down
4 changes: 4 additions & 0 deletions src/wintasee/tramps/windowtramps.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ TRAMPFUNC BOOL WINAPI ShowWindow(HWND hWnd, int nCmdShow) TRAMPOLINE_DEF
TRAMPFUNC BOOL WINAPI GetClientRect(HWND hWnd, LPRECT lpRect) TRAMPOLINE_DEF
#define GetWindowRect TrampGetWindowRect
TRAMPFUNC BOOL WINAPI GetWindowRect(HWND hWnd, LPRECT lpRect) TRAMPOLINE_DEF
#define ClientToScreen TrampClientToScreen
TRAMPFUNC BOOL WINAPI ClientToScreen(HWND hWnd, LPPOINT lpPoint) TRAMPOLINE_DEF
#define ScreenToClient TrampScreenToClient
TRAMPFUNC BOOL WINAPI ScreenToClient(HWND hWnd, LPPOINT lpPoint) TRAMPOLINE_DEF
#define SetWindowTextA TrampSetWindowTextA
TRAMPFUNC BOOL WINAPI SetWindowTextA(HWND hWnd, LPCSTR lpString) TRAMPOLINE_DEF
#define SetWindowTextW TrampSetWindowTextW
Expand Down
9 changes: 6 additions & 3 deletions src/wintasee/wintasee.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1205,7 +1205,8 @@ void FrameBoundary(void* captureInfo, int captureInfoType)
#ifdef EMULATE_MESSAGE_QUEUES
PostMessageInternal(hwnd, WM_KEYDOWN, i, 0);
#else
SendMessage(hwnd, toggleWhitelistMessage(WM_KEYDOWN), i, 0);
//SendMessage(hwnd, toggleWhitelistMessage(WM_KEYDOWN), i, 0);
MyWndProcA(hwnd, toggleWhitelistMessage(WM_KEYDOWN), i, 0);
#endif

// also send a WM_CHAR event in case some games need it (HACK, should do this in TranslateMessage)
Expand All @@ -1219,7 +1220,8 @@ void FrameBoundary(void* captureInfo, int captureInfoType)
#ifdef EMULATE_MESSAGE_QUEUES
PostMessageInternal(hwnd, WM_CHAR, c, 0);
#else
SendMessage(hwnd, toggleWhitelistMessage(WM_CHAR), c, 0);
//SendMessage(hwnd, toggleWhitelistMessage(WM_CHAR), c, 0);
MyWndProcA(hwnd, toggleWhitelistMessage(WM_CHAR), c, 0);
#endif
}
}
Expand All @@ -1229,7 +1231,8 @@ void FrameBoundary(void* captureInfo, int captureInfoType)
#ifdef EMULATE_MESSAGE_QUEUES
PostMessageInternal(hwnd, WM_KEYUP, i, 0);
#else
SendMessage(hwnd, toggleWhitelistMessage(WM_KEYUP), i, 0);
//SendMessage(hwnd, toggleWhitelistMessage(WM_KEYUP), i, 0);
MyWndProcA(hwnd, toggleWhitelistMessage(WM_KEYUP), i, 0);
#endif
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/wintaser/inputsetup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2397,6 +2397,8 @@ void Build_Main_Menu(HMENU& MainMenu, HWND hWnd)
MENU_L(ExecMultithreading, i++, Flags | ((threadMode == 2)?MF_CHECKED:MF_UNCHECKED) | (usedThreadMode==1?MF_GRAYED:0), ID_EXEC_THREADS_ALLOW, "", "&Allow (normal thread creation)", "can't set while running after wrapped threads created");
MENU_L(ExecMultithreading, i++, Flags | ((threadMode == 3)?MF_CHECKED:MF_UNCHECKED) | (usedThreadMode==1?MF_GRAYED:0), ID_EXEC_THREADS_KNOWN, "", "Allow &known threads only", "can't set while running after wrapped threads created");
MENU_L(ExecMultithreading, i++, Flags | ((threadMode == 4)?MF_CHECKED:MF_UNCHECKED) | (usedThreadMode==1?MF_GRAYED:0), ID_EXEC_THREADS_UNKNOWN, "", "Allow &unknown threads only", "can't set while running after wrapped threads created");
MENU_L(ExecMultithreading, i++, Flags | ((threadMode == 5)?MF_CHECKED:MF_UNCHECKED) | (usedThreadMode==1?MF_GRAYED:0), ID_EXEC_THREADS_TRUSTED, "", "Allow &trusted threads only", "can't set while running after wrapped threads created");


// Timers Submenu
i = 0;
Expand Down
11 changes: 6 additions & 5 deletions src/wintaser/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,11 +312,12 @@
#define ID_INPUT_BACKGROUNDINPUTS_TASER 40376
#define ID_INPUT_BACKGROUNDINPUTS_TASEE 40377
#define ID_INPUT_BACKGROUNDINPUTS_OTHER 40378
#define ID_EXEC_THREADS_DISABLE 40380
#define ID_EXEC_THREADS_WRAP 40381
#define ID_EXEC_THREADS_ALLOW 40382
#define ID_EXEC_THREADS_KNOWN 40383
#define ID_EXEC_THREADS_UNKNOWN 40384
#define ID_EXEC_THREADS_DISABLE 40379
#define ID_EXEC_THREADS_WRAP 40380
#define ID_EXEC_THREADS_ALLOW 40381
#define ID_EXEC_THREADS_KNOWN 40382
#define ID_EXEC_THREADS_UNKNOWN 40383
#define ID_EXEC_THREADS_TRUSTED 40384
#define ID_EXEC_TIMERS_DISABLE 40385
#define ID_EXEC_TIMERS_SYNC 40386
#define ID_EXEC_TIMERS_ASYNC 40387
Expand Down
15 changes: 10 additions & 5 deletions src/wintaser/wintaser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2077,15 +2077,15 @@ void SendTASFlags()
messageSyncMode,
waitSyncMode,
aviMode,
emuMode | (((recoveringStale||(fastForwardFlags&FFMODE_SOUNDSKIP))&&fastforward) ? EMUMODE_NOPLAYBUFFERS : 0),
emuMode | (((recoveringStale||(fastForwardFlags&FFMODE_SOUNDSKIP))&&fastforward) ? EMUMODE_NOPLAYBUFFERS : 0) | ((threadMode==0||threadMode==4||threadMode==5) ? EMUMODE_VIRTUALDIRECTSOUND : 0),
forceWindowed,
fastforward,
forceSurfaceMemory,
audioFrequency,
audioBitsPerSecond,
audioChannels,
stateLoaded,
fastForwardFlags,// | (recoveringStale ? (FFMODE_FRONTSKIP|FFMODE_BACKSKIP|FFMODE_SOUNDSKIP) ? 0),
fastForwardFlags,// | (recoveringStale ? (FFMODE_FRONTSKIP|FFMODE_BACKSKIP) ? 0),
initialTime,
debugPrintMode,
timescale, timescaleDivisor,
Expand Down Expand Up @@ -3992,7 +3992,7 @@ void WriteAVIAudio()
}
}

if(aviCompressedStream /*&& aviSoundFrameCount < 30*/)
if(aviCompressedStream && (aviSoundFrameCount < 30 || aviSoundFrameCount+8 < aviFrameCount))
while(aviSoundFrameCount < aviFrameCount/*-aviEmptyFrameCount*/)
aviFrameQueue->FillEmptyAudioFrame(); // in case video started before audio

Expand Down Expand Up @@ -8402,6 +8402,11 @@ BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
tasFlagsDirty = true;
CheckDialogChanges(-1);
break;
case ID_EXEC_THREADS_TRUSTED:
threadMode = 5;
tasFlagsDirty = true;
CheckDialogChanges(-1);
break;

case ID_EXEC_TIMERS_DISABLE:
timersMode = 0;
Expand Down Expand Up @@ -8837,7 +8842,7 @@ BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
//CheckDlgButton(hDlg, IDC_AVIVIDEO, aviMode & 1);
//CheckDlgButton(hDlg, IDC_AVIAUDIO, aviMode & 2);
bool wasPlayback = playback;
TerminateDebuggerThread(6500);
TerminateDebuggerThread(12000);
if(unsaved)
SaveMovieToFile(moviefilename);
terminateRequest = false;
Expand Down Expand Up @@ -9121,7 +9126,7 @@ BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
SetWindowText(GetDlgItem(hDlg, IDC_EDIT_EXE), filename);
SendMessage(GetDlgItem(hDlg, IDC_EDIT_EXE), EM_SETSEL, -2, -1);
}
else if(!stricmp(dot, ".wtf")) // windows TAS file (input movie)
else if(!_strnicmp(dot, ".wtf", 4)) // windows TAS file (input movie)
{
SetWindowText(GetDlgItem(hDlg, IDC_EDIT_MOVIE), filename);
SendMessage(GetDlgItem(hDlg, IDC_EDIT_MOVIE), EM_SETSEL, -2, -1);
Expand Down

0 comments on commit 4759a3e

Please sign in to comment.