/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ #include "Engine/StdH.h" #include #include #include #include #include #include // rcg12122001 Moved this over to the CDynamicLoader abstraction, even though // this is somewhat win32-specific. Hey, you never know; maybe a Linux // version will show up, so we might as well leave the IFeel interface // in place... //Imm_GetProductName CDynamicLoader *_hLib = NULL; BOOL (*immCreateDevice)(HINSTANCE &hInstance, HWND &hWnd) = NULL; void (*immDeleteDevice)(void) = NULL; BOOL (*immProductName)(char *strProduct,int iMaxCount) = NULL; BOOL (*immLoadFile)(const char *fnFile) = NULL; void (*immUnloadFile)(void) = NULL; void (*immPlayEffect)(const char *pstrEffectName) = NULL; void (*immStopEffect)(const char *pstrEffectName) = NULL; void (*immChangeGain)(const float fGain) = NULL; FLOAT ifeel_fGain = 1.0f; INDEX ifeel_bEnabled = FALSE; #ifndef NDEBUG #define IFEEL_DLL_NAME "Bin/Debug/ImmWrapper.dll" #else #define IFEEL_DLL_NAME "Bin/ImmWrapper.dll" #endif void ifeel_GainChange(void *ptr) { IFeel_ChangeGain(ifeel_fGain); } CTString IFeel_GetProductName() { char strProduct[MAX_PATH]; if(immProductName != NULL) { if(immProductName(strProduct,MAX_PATH)) { return strProduct; } } return ""; } CTString IFeel_GetProjectFileName() { CTString strIFeelTable; CTFileName fnIFeelTable = (CTString)"Data\\IFeel.txt"; CTString strDefaultProjectFile = "Data\\Default.ifr"; // get product name CTString strProduct = IFeel_GetProductName(); try { strIFeelTable.Load_t(fnIFeelTable); } catch(char *strErr) { CPrintF("%s\n",strErr); return ""; } CTString strLine; // read up to 1000 devices for(INDEX idev=0;idev<1000;idev++) { char strDeviceName[256]; char strProjectFile[256]; strLine = strIFeelTable; // read first line strLine.OnlyFirstLine(); if(strLine==strIFeelTable) { break; } // remove that line strIFeelTable.RemovePrefix(strLine); strIFeelTable.DeleteChar(0); // read device name and project file name strIFeelTable.ScanF("\"%256[^\"]\" \"%256[^\"]\"",&strDeviceName,&strProjectFile); // check if this is default if(strcmp(strDeviceName,"Default")==0) strDefaultProjectFile = strProjectFile; // check if this is current device if(strProduct == strDeviceName) return strProjectFile; } // device was not found, return default project file CPrintF("No project file specified for device '%s'.\nUsing default project file\n", (const char *) strProduct); return strDefaultProjectFile; } // inits imm ifeel device BOOL IFeel_InitDevice(HINSTANCE &hInstance, HWND &hWnd) { _pShell->DeclareSymbol("void inp_IFeelGainChange(INDEX);", (void *) &ifeel_GainChange); _pShell->DeclareSymbol("persistent user FLOAT inp_fIFeelGain post:inp_IFeelGainChange;", (void *) &ifeel_fGain); _pShell->DeclareSymbol("const user INDEX sys_bIFeelEnabled;", (void *) &ifeel_bEnabled); IFeel_ChangeGain(ifeel_fGain); // load iFeel lib CTFileName fnmExpanded; ExpandFilePath(EFP_READ | EFP_NOZIPS,(CTString)IFEEL_DLL_NAME,fnmExpanded); if(_hLib!=NULL) return FALSE; #ifdef PLATFORM_WIN32 UINT iOldErrorMode = SetErrorMode( SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS); #endif _hLib = CDynamicLoader::GetInstance(fnmExpanded); #ifdef PLATFORM_WIN32 SetErrorMode(iOldErrorMode); #endif const char *err = _hLib->GetError(); if (err != NULL) { CPrintF("Error loading ImmWraper.dll.\n\tIFeel disabled\nError: %s\n", err); delete _hLib; _hLib = NULL; return FALSE; } // take func pointers immCreateDevice = (BOOL(*)(HINSTANCE &hInstance, HWND &hWnd)) _hLib->FindSymbol("Imm_CreateDevice"); immDeleteDevice = (void(*)(void)) _hLib->FindSymbol("Imm_DeleteDevice"); immProductName = (BOOL(*)(char *strProduct,int iMaxCount)) _hLib->FindSymbol("Imm_GetProductName"); immLoadFile = (BOOL(*)(const char *fnFile))_hLib->FindSymbol("Imm_LoadFile"); immUnloadFile = (void(*)(void))_hLib->FindSymbol("immUnloadFile"); immPlayEffect = (void(*)(const char *pstrEffectName))_hLib->FindSymbol("Imm_PlayEffect"); immStopEffect = (void(*)(const char *pstrEffectName))_hLib->FindSymbol("Imm_StopEffect"); immChangeGain = (void(*)(const float fGain))_hLib->FindSymbol("Imm_ChangeGain"); // create device if(immCreateDevice == NULL) { return FALSE; } BOOL hr = immCreateDevice(hInstance,hWnd); if(!hr) { CPrintF("IFeel mouse not found.\n"); IFeel_DeleteDevice(); return FALSE; } CPrintF("IFeel mouse '%s' initialized\n",(const char*)IFeel_GetProductName()); ifeel_bEnabled = TRUE; return TRUE; } // delete imm ifeel device void IFeel_DeleteDevice() { if(immDeleteDevice != NULL) immDeleteDevice(); immCreateDevice = NULL; immDeleteDevice = NULL; immProductName = NULL; immLoadFile = NULL; immUnloadFile = NULL; immPlayEffect = NULL; immStopEffect = NULL; immChangeGain = NULL; if(_hLib != NULL) delete _hLib; _hLib = NULL; } // loads project file BOOL IFeel_LoadFile(CTFileName fnFile) { CTFileName fnmExpanded; ExpandFilePath(EFP_READ | EFP_NOZIPS,fnFile,fnmExpanded); if(immLoadFile!=NULL) { BOOL hr = immLoadFile((const char*)fnmExpanded); if(hr) { CPrintF("IFeel project file '%s' loaded\n", (const char *) fnFile); return TRUE; } else { CPrintF("Error loading IFeel project file '%s'\n", (const char *) fnFile); return FALSE; } } return FALSE; } // unloads project file void IFeel_UnloadFile() { if(immUnloadFile!=NULL) immUnloadFile(); } // plays effect from ifr file void IFeel_PlayEffect(char *pstrEffectName) { IFeel_ChangeGain(ifeel_fGain); if(immPlayEffect!=NULL) immPlayEffect(pstrEffectName); } // stops effect from ifr file void IFeel_StopEffect(char *pstrEffectName) { if(immStopEffect!=NULL) immStopEffect(pstrEffectName); } // change gain void IFeel_ChangeGain(FLOAT fGain) { if(immChangeGain!=NULL) { immChangeGain(fGain); //CPrintF("Changing IFeel gain to '%g'\n",fGain); } }