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 7418d7767b v2_02_96_src
Former-commit-id: ca9fa70709c4797019a40006f6a6a59b397bd08d
2017-03-06 11:39:54 -05:00

227 lines
8.8 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;
}
}
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);
#ifdef WFSPONLY
char *target="put movie destination at ";
if(!strncmp(lpszCommand, target, strlen(target))) {
char NewCommand[256];
RECT rect;
sscanf(&lpszCommand[strlen(target)], "%ld %ld %ld %ld", &(rect.left), &(rect.top), &(rect.right), &(rect.bottom));
rect=dxw.MapClientRect(&rect);
sprintf(NewCommand, "put movie destination at %d %d %d %d", rect.left, rect.top, rect.right, rect.bottom);
lpszCommand=NewCommand;
OutTraceDW("mciSendStringA: replaced Command=\"%s\"\n", lpszCommand);
}
#else
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];
rect=dxw.MapClientRect(&rect);
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);
}
#endif
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);
#ifdef WFSPONLY
if(!wcsncmp(lpszCommand, target, wcslen(target))) {
WCHAR NewCommand[256];
RECT rect;
swscanf(&lpszCommand[wcslen(target)], L"%ld %ld %ld %ld", &(rect.left), &(rect.top), &(rect.right), &(rect.bottom));
rect=dxw.MapClientRect(&rect);
swprintf(NewCommand, L"put movie destination at %d %d %d %d", rect.left, rect.top, rect.right, rect.bottom);
lpszCommand=NewCommand;
OutTraceDW("mciSendStringA: replaced Command=\"%ls\"\n", lpszCommand);
}
#else
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];
rect=dxw.MapClientRect(&rect);
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);
}
#endif
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;
}