JD2022-TU1/main/extern/Camcam/LIBS/Mixer/DWInterface.cpp

350 lines
8.3 KiB
C++

#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <shlwapi.h>
#include <stdio.h>
#include "SCENE.H"
char ToUpper(char H)
{
if ((H >= 'a') && (H <= 'z')) return 'A' + H - 'a';
return H;
}
typedef void (CALLBACK *FileChangeCallback)(LPTSTR, void *M,DWORD action);
typedef struct tagDIR_MONITOR
{
OVERLAPPED ol;
HANDLE hDir;
BYTE buffer[32 * 1024];
LPARAM lParam;
DWORD notifyFilter;
BOOL fStop;
char szTrackedDir[MAX_PATH];
void *psCene;
FileChangeCallback callback;
} *HDIR_MONITOR;
HDIR_MONITOR h = NULL;
HDIR_MONITOR hLua = NULL;
VOID CALLBACK MonitorCallback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
{
TCHAR szFile[MAX_PATH];
PFILE_NOTIFY_INFORMATION pNotify;
HDIR_MONITOR pMonitor = (HDIR_MONITOR) lpOverlapped;
size_t offset = 0;
BOOL RefreshMonitoring(HDIR_MONITOR pMonitor);
if (pMonitor != h && pMonitor != hLua)
return;
if (dwErrorCode == ERROR_SUCCESS)
{
do
{
pNotify = (PFILE_NOTIFY_INFORMATION) &pMonitor->buffer[offset];
offset += pNotify->NextEntryOffset;
# if defined(UNICODE)
{
lstrcpynW(szFile, pNotify->FileName,
min(MAX_PATH, pNotify->FileNameLength / sizeof(WCHAR) + 1));
}
# else
{
int count = WideCharToMultiByte(CP_ACP, 0, pNotify->FileName,
pNotify->FileNameLength / sizeof(WCHAR),
szFile, MAX_PATH - 1, NULL, NULL);
szFile[count] = TEXT('\0');
}
# endif
pMonitor->callback(szFile, pMonitor,pNotify->Action);
} while (pNotify->NextEntryOffset != 0);
}
if (!pMonitor->fStop)
{
RefreshMonitoring(pMonitor);
}
}
//*/
/*
* Refreshes the directory monitoring.
*/
BOOL RefreshMonitoring(HDIR_MONITOR pMonitor)
{
return
ReadDirectoryChangesW(pMonitor->hDir, pMonitor->buffer, sizeof(pMonitor->buffer), TRUE,
pMonitor->notifyFilter, NULL, &pMonitor->ol, MonitorCallback);
}
/*
* Stops monitoring a directory.
*/
void StopMonitoring(HDIR_MONITOR pMonitor)
{
if (pMonitor)
{
pMonitor->fStop = TRUE;
CancelIo(pMonitor->hDir);
while (!HasOverlappedIoCompleted(&pMonitor->ol))
{
//SleepEx(5, TRUE);
Sleep(5);
}
CloseHandle(pMonitor->ol.hEvent);
CloseHandle(pMonitor->hDir);
HeapFree(GetProcessHeap(), 0, pMonitor);
}
}
/*
* Starts monitoring a directory.
*/
HDIR_MONITOR StartMonitoring(LPCTSTR szDirectory, DWORD notifyFilter, FileChangeCallback callback,void *pScene)
{
HDIR_MONITOR pMonitor = (HDIR_MONITOR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pMonitor));
pMonitor->hDir = CreateFile(szDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
strcpy(pMonitor->szTrackedDir,szDirectory);
pMonitor->psCene = pScene;
if (pMonitor->hDir != INVALID_HANDLE_VALUE)
{
pMonitor->ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
pMonitor->notifyFilter = notifyFilter;
pMonitor->callback = callback;
if (RefreshMonitoring(pMonitor))
{
return pMonitor;
}
else
{
CloseHandle(pMonitor->ol.hEvent);
CloseHandle(pMonitor->hDir);
}
}
HeapFree(GetProcessHeap(), 0, pMonitor);
return NULL;
}
void DW_WatchDirectoryCheck()
{
while (WAIT_IO_COMPLETION == MsgWaitForMultipleObjectsEx(0, NULL, 0, QS_ALLINPUT, MWMO_ALERTABLE)) ;
}
int MyStrCompare(char *S1,char *S2)
{
while (*S1 && *S2)
{
if (((*S1 == '\\') || (*S1 == '/')) &&
((*S2 == '\\') || (*S2 == '/')))
{
// OK
} else
if (ToUpper(*S1) == ToUpper(*S2))
{
// OK
} else return 0;
S2++;
S1++;
}
if ((*S1 == 0) && (*S1 == *S2)) return 1;
return 0;
}
void CALLBACK FileCallback(LPTSTR szFile, void*M,DWORD action)
{
//return;
HDIR_MONITOR Monitor;
Monitor =(HDIR_MONITOR)M;
WORLD *pScene;
u32 Counter;
char szFileComplete[MAX_PATH];
sprintf(szFileComplete,"%s%s",(char *)Monitor->szTrackedDir,szFile);
FILE *F;
F = fopen(szFileComplete,"rb");
if (!F) return; // <= File is destroyed. Return;
char Buf[32];
if (fread(Buf,1,16,F) < 4)
{
fclose(F);
return;
}
fclose(F);
F = fopen(szFileComplete,"ab");
if (!F) return; // <= File is open. Return;
fclose(F);
if (action == FILE_ACTION_MODIFIED)// && */(Dico.mpst_Dico[ID].AssociatedValue > 1))
{
pScene = (WORLD *)Monitor->psCene;
switch (GetFileNameExtend((char *)szFile))
{
case '.CCM':
#ifndef USER_MODE
#ifndef ONLINE_MODE
{
pScene->LoadIniFile((char *)szFile);
};
#endif
#endif
break;
case '.LUA':
#ifndef USER_MODE
if ((pScene->WFlags & LUA_AUTO_RELOAD) && GetFileNameExtend(pScene->ScriptNameStack[pScene->currentScript]) == '.LUA')
pScene->LoadLua(pScene->ScriptNameStack[pScene->currentScript], 2);
#endif
break;
case '.SVG':
#ifdef USE_SVG
{
return; //TO FINISH
if(strncmp(szFile, "SVG", 3) != 0) return;
//asking for reconvert SVG file
extern HWND hWnd;
char Text[2048];
sprintf(Text,"SVG file %s has been modified outside camcam\nDo you want to reconvert it to a MAD file ?",szFile);
if(MessageBox(GetDesktopWindow(),Text,"Camcam message",MB_YESNO|MB_SYSTEMMODAL) == IDYES)
{
char svgCompleteFilename[260]; strcpy(svgCompleteFilename, szFile);
char madCompleteFilename[260]; sprintf(madCompleteFilename, "Mads\\%s.mad", szFile+4);
extern bool svg2mad(char* svgFilename, char* destMadFilename);
svg2mad(svgCompleteFilename, madCompleteFilename);
}
};
#endif
break;
case '.MAD':
{
//reentrance support
static bool firstEntry = true;
static time_t lastTime;
if(!firstEntry)
{
time_t diffOfTime = time(NULL)-lastTime;
if(diffOfTime<2)
{
lastTime = time(NULL);
return;
}
}
firstEntry = false;
//asking for reimport MAD file
char Text[2048];
sprintf(Text,"MAD file %s has been modified outside camcam\nDo you want to reimport it ?",szFile);
if ((pScene->WFlags & MAD_AUTO_RELOAD) || (MessageBox(GetDesktopWindow(),Text,"Camcam message",MB_YESNO|MB_SYSTEMMODAL) == IDYES))
{
extern u32 MAD_2_CAMCAM(char *FileName);
MAD_2_CAMCAM(szFileComplete);
}
//reentrance support
lastTime = time(NULL);
};
break;
case '.MMT':
case '.MAT':
case '.MSH':
case '.OBJ':
case '.SSC':
case '.IKM':
case '.LGH':
/* a small scene must be update */
if (pScene->WFlags & LUA_AUTO_RELOAD)
pScene->TouchSmallScene(szFileComplete);
break;
case '.JPG':
case '.PNG':
case '.TGA':
case '.PSD':
case '.BMP':
case 'TEXT':
case '.TXT':
/* maybe a media must be update */
pScene->TouchMedia(szFileComplete);
if ((szFileComplete[0] == '.') && (szFileComplete[1] == '\\'))
pScene->TouchMedia(szFileComplete+2);
break;
case '.PGR':
pScene->TouchPGenerator(szFileComplete);
break;
case '.FUR':
pScene->TouchFur(szFileComplete);
break;
};
}
}
int DW_WatchDirectory(char *DirectoryToWatch,void (*fn)(void *,char *),void *pS)
{
if (h) StopMonitoring(h);
h = NULL;
h = StartMonitoring(TEXT(DirectoryToWatch),
FILE_NOTIFY_CHANGE_LAST_WRITE|FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_FILE_NAME,
FileCallback,pS);
return TRUE;
}
int DW_UnWatchDirectory()
{
if (h) StopMonitoring(h);
h= NULL;
return 1;
}
// ************** LUA DIR WATCH **************************
void CALLBACK LuaCallback(LPTSTR szFile, void*M,DWORD action)
{
HDIR_MONITOR Monitor =(HDIR_MONITOR)M;
WORLD *pScene = (WORLD *)Monitor->psCene;
ObjectEventDatas datas;
datas.type = EVENT_TYPE_STRING;
sprintf(datas.data,"%s/%s",(char *)Monitor->szTrackedDir,szFile);
//sprintf(datas.data,"%s",szFile);
pScene->LuaProcessEventDatas(EVT_onDirWatch, &datas);
}
int DWLua_WatchDirectory(char *DirectoryToWatch, void *pS)
{
if (hLua) StopMonitoring(hLua);
hLua = NULL;
hLua = StartMonitoring(TEXT(DirectoryToWatch),
FILE_NOTIFY_CHANGE_LAST_WRITE|FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME,
LuaCallback,pS);
return TRUE;
}
int DWLua_UnWatchDirectory()
{
if (hLua) StopMonitoring(hLua);
hLua = NULL;
return 1;
}