1
0
mirror of https://github.com/DxWnd/DxWnd.reloaded synced 2024-12-30 09:25:35 +01:00
DxWnd.reloaded/dll/winmm.cpp
gho tik 8f439ed44d v2_03_24_src
Former-commit-id: bb29306baa8026a597f5fc553493e11b2ea5bef0
2017-03-06 11:40:54 -05:00

218 lines
8.4 KiB
C++

#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NON_CONFORMING_SWPRINTFS
#include "dxwnd.h"
#include "dxwcore.hpp"
#include "syslibs.h"
#include "dxhook.h"
#include "dxhelper.h"
#include "MMSystem.h"
#include <stdio.h>
#define SUPPRESSMCIERRORS FALSE
BOOL IsWithinMCICall = FALSE;
static HookEntry_Type Hooks[]={
{HOOK_HOT_CANDIDATE, "mciSendCommandA", NULL, (FARPROC *)&pmciSendCommandA, (FARPROC)extmciSendCommandA},
{HOOK_HOT_CANDIDATE, "mciSendCommandW", NULL, (FARPROC *)&pmciSendCommandW, (FARPROC)extmciSendCommandW},
{HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator
};
static HookEntry_Type TimeHooks[]={
{HOOK_HOT_CANDIDATE, "timeGetTime", NULL, (FARPROC *)&ptimeGetTime, (FARPROC)exttimeGetTime},
{HOOK_HOT_CANDIDATE, "timeKillEvent", NULL, (FARPROC *)&ptimeKillEvent, (FARPROC)exttimeKillEvent},
{HOOK_HOT_CANDIDATE, "timeSetEvent", NULL, (FARPROC *)&ptimeSetEvent, (FARPROC)exttimeSetEvent},
{HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator
};
static HookEntry_Type RemapHooks[]={
{HOOK_HOT_CANDIDATE, "mciSendStringA", NULL, (FARPROC *)&pmciSendStringA, (FARPROC)extmciSendStringA},
{HOOK_HOT_CANDIDATE, "mciSendStringW", NULL, (FARPROC *)&pmciSendStringW, (FARPROC)extmciSendStringW},
{HOOK_IAT_CANDIDATE, 0, NULL, 0, 0} // terminator
};
void HookWinMM(HMODULE module)
{
HookLibrary(module, Hooks, "winmm.dll");
if(dxw.dwFlags2 & TIMESTRETCH) HookLibrary(module, TimeHooks, "winmm.dll");
if(dxw.dwFlags5 & REMAPMCI) HookLibrary(module, RemapHooks, "winmm.dll");
}
FARPROC Remap_WinMM_ProcAddress(LPCSTR proc, HMODULE hModule)
{
FARPROC addr;
if (addr=RemapLibrary(proc, hModule, Hooks)) return addr;
if(dxw.dwFlags2 & TIMESTRETCH)
if (addr=RemapLibrary(proc, hModule, TimeHooks)) return addr;
if(dxw.dwFlags5 & REMAPMCI)
if (addr=RemapLibrary(proc, hModule, RemapHooks)) return addr;
return NULL;
}
DWORD WINAPI exttimeGetTime(void)
{
DWORD ret;
ret = dxw.GetTickCount();
if (IsDebug) OutTrace("timeGetTime: time=%x\n", ret);
return ret;
}
MMRESULT WINAPI exttimeSetEvent(UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent)
{
MMRESULT res;
UINT NewDelay;
OutTraceDW("timeSetEvent: Delay=%d Resolution=%d Event=%x\n", uDelay, uResolution, fuEvent);
if(dxw.dwFlags4 & STRETCHTIMERS) NewDelay = dxw.StretchTime(uDelay);
else NewDelay = uDelay;
res=(*ptimeSetEvent)(NewDelay, uResolution, lpTimeProc, dwUser, fuEvent);
if(res) dxw.PushTimer(res, uDelay, uResolution, lpTimeProc, dwUser, fuEvent);
OutTraceDW("timeSetEvent: ret=%x\n", res);
return res;
}
MMRESULT WINAPI exttimeKillEvent(UINT uTimerID)
{
MMRESULT res;
OutTraceDW("timeKillEvent: TimerID=%x\n", uTimerID);
res=(*ptimeKillEvent)(uTimerID);
if(res==TIMERR_NOERROR) dxw.PopTimer(uTimerID);
OutTraceDW("timeKillEvent: ret=%x\n", res);
return res;
}
/* MCI_DGV_PUT_FRAME
The rectangle defined for MCI_DGV_RECT applies to the frame rectangle.
The frame rectangle specifies the portion of the frame buffer used as the destination of the video images obtained from the video rectangle.
The video should be scaled to fit within the frame buffer rectangle.
The rectangle is specified in frame buffer coordinates.
The default rectangle is the full frame buffer.
Specifying this rectangle lets the device scale the image as it digitizes the data.
Devices that cannot scale the image reject this command with MCIERR_UNSUPPORTED_FUNCTION.
You can use the MCI_GETDEVCAPS_CAN_STRETCH flag with the MCI_GETDEVCAPS command to determine if a device scales the image. A device returns FALSE if it cannot scale the image.
*/
MCIERROR WINAPI extmciSendCommand(mciSendCommand_Type pmciSendCommand, MCIDEVICEID IDDevice, UINT uMsg, DWORD_PTR fdwCommand, DWORD_PTR dwParam)
{
RECT saverect;
MCIERROR ret;
MCI_ANIM_RECT_PARMS *pr;
MCI_OVLY_WINDOW_PARMSW *pw;
OutTraceDW("mciSendCommand: IDDevice=%x msg=%x(%s) Command=%x(%s)\n",
IDDevice, uMsg, ExplainMCICommands(uMsg), fdwCommand, ExplainMCIFlags(uMsg, fdwCommand));
if(dxw.IsFullScreen()){
switch(uMsg){
case MCI_WINDOW:
pw = (MCI_OVLY_WINDOW_PARMSW *)dwParam;
OutTraceB("mciSendCommand: hwnd=%x CmdShow=%x\n",
pw->hWnd, pw->nCmdShow);
//fdwCommand |= MCI_ANIM_WINDOW_ENABLE_STRETCH;
//fdwCommand &= ~MCI_ANIM_WINDOW_DISABLE_STRETCH;
if(dxw.IsDesktop(pw->hWnd)) pw->hWnd = dxw.GethWnd();
break;
case MCI_PUT:
RECT client;
pr = (MCI_ANIM_RECT_PARMS *)dwParam;
OutTraceB("mciSendCommand: rect=(%d,%d),(%d,%d)\n",
pr->rc.left, pr->rc.top, pr->rc.right, pr->rc.bottom);
(*pGetClientRect)(dxw.GethWnd(), &client);
//fdwCommand |= MCI_ANIM_PUT_DESTINATION;
fdwCommand |= MCI_ANIM_RECT;
saverect=pr->rc;
pr->rc.top = (pr->rc.top * client.bottom) / dxw.GetScreenHeight();
pr->rc.bottom = (pr->rc.bottom * client.bottom) / dxw.GetScreenHeight();
pr->rc.left = (pr->rc.left * client.right) / dxw.GetScreenWidth();
pr->rc.right = (pr->rc.right * client.right) / dxw.GetScreenWidth();
OutTraceB("mciSendCommand: fixed rect=(%d,%d),(%d,%d)\n",
pr->rc.left, pr->rc.top, pr->rc.right, pr->rc.bottom);
break;
case MCI_PLAY:
if(dxw.dwFlags6 & NOMOVIES) return 0; // ???
break;
case MCI_OPEN:
if(dxw.dwFlags6 & NOMOVIES) return 275; // quite brutal, but working ....
break;
}
}
ret=(*pmciSendCommand)(IDDevice, uMsg, fdwCommand, dwParam);
if(dxw.IsFullScreen() && uMsg==MCI_PUT) pr->rc=saverect;
if (ret) OutTraceE("mciSendCommand: ERROR res=%d\n", ret);
return ret;
}
MCIERROR WINAPI extmciSendCommandA(MCIDEVICEID IDDevice, UINT uMsg, DWORD_PTR fdwCommand, DWORD_PTR dwParam)
{
return extmciSendCommand(pmciSendCommandA, IDDevice, uMsg, fdwCommand, dwParam);
}
MCIERROR WINAPI extmciSendCommandW(MCIDEVICEID IDDevice, UINT uMsg, DWORD_PTR fdwCommand, DWORD_PTR dwParam)
{
return extmciSendCommand(pmciSendCommandW, IDDevice, uMsg, fdwCommand, dwParam);
}
MCIERROR WINAPI extmciSendStringA(LPCTSTR lpszCommand, LPTSTR lpszReturnString, UINT cchReturn, HANDLE hwndCallback)
{
MCIERROR ret;
if(IsWithinMCICall) return(*pmciSendStringA)(lpszCommand, lpszReturnString, cchReturn, hwndCallback); // just proxy ...
OutTraceDW("mciSendStringA: Command=\"%s\" Return=%x Callback=%x\n", lpszCommand, cchReturn, hwndCallback);
char sMovieNickName[81];
RECT rect;
if (sscanf(lpszCommand, "put %s destination at %ld %ld %ld %ld",
sMovieNickName, &(rect.left), &(rect.top), &(rect.right), &(rect.bottom))==5){
char NewCommand[256];
// v2.03.19 height / width fix
rect.right += rect.left; // convert width to position
rect.bottom += rect.top; // convert height to position
rect=dxw.MapClientRect(&rect);
rect.right -= rect.left; // convert position to width
rect.bottom -= rect.top; // convert position to height
sprintf(NewCommand, "put %s destination at %d %d %d %d", sMovieNickName, rect.left, rect.top, rect.right, rect.bottom);
lpszCommand=NewCommand;
OutTraceDW("mciSendStringA: replaced Command=\"%s\"\n", lpszCommand);
}
IsWithinMCICall=TRUE;
ret=(*pmciSendStringA)(lpszCommand, lpszReturnString, cchReturn, hwndCallback);
IsWithinMCICall=FALSE;
if(ret) OutTraceDW("mciSendStringA ERROR: ret=%x\n", ret);
OutTraceDW("mciSendStringA: RetString=\"%s\"\n", lpszReturnString);
return ret;
}
MCIERROR WINAPI extmciSendStringW(LPCWSTR lpszCommand, LPWSTR lpszReturnString, UINT cchReturn, HANDLE hwndCallback)
{
MCIERROR ret;
WCHAR *target=L"put movie destination at ";
if(IsWithinMCICall) return(*pmciSendStringW)(lpszCommand, lpszReturnString, cchReturn, hwndCallback); // just proxy ...
OutTraceDW("mciSendStringW: Command=\"%ls\" Return=%x Callback=%x\n", lpszCommand, cchReturn, hwndCallback);
WCHAR sMovieNickName[81];
RECT rect;
if (swscanf(lpszCommand, L"put %ls destination at %ld %ld %ld %ld",
sMovieNickName, &(rect.left), &(rect.top), &(rect.right), &(rect.bottom))==5){
WCHAR NewCommand[256];
// v2.03.19 height / width fix
rect.right += rect.left; // convert width to position
rect.bottom += rect.top; // convert height to position
rect=dxw.MapClientRect(&rect);
rect.right -= rect.left; // convert position to width
rect.bottom -= rect.top; // convert position to height
swprintf(NewCommand, L"put %ls destination at %d %d %d %d", sMovieNickName, rect.left, rect.top, rect.right, rect.bottom);
lpszCommand=NewCommand;
OutTraceDW("mciSendStringW: replaced Command=\"%ls\"\n", lpszCommand);
}
IsWithinMCICall=TRUE;
ret=(*pmciSendStringW)(lpszCommand, lpszReturnString, cchReturn, hwndCallback);
IsWithinMCICall=FALSE;
if(ret) OutTraceDW("mciSendStringW ERROR: ret=%x\n", ret);
OutTraceDW("mciSendStringW: RetString=\"%ls\"\n", lpszReturnString);
return ret;
}