Flycast Output FFB Support
This commit is contained in:
parent
ded32d7f44
commit
877111d10f
@ -32,6 +32,7 @@ xcopy ".\MAME32.dll" ".\Release.Win32\MAME 32bit Outputs" /Y
|
|||||||
xcopy ".\MAME64.dll" ".\Release.Win32\MAME 64bit Outputs" /Y
|
xcopy ".\MAME64.dll" ".\Release.Win32\MAME 64bit Outputs" /Y
|
||||||
xcopy ".\MAME32.dll" ".\Release.Win32\Supermodel 32bit Outputs" /Y
|
xcopy ".\MAME32.dll" ".\Release.Win32\Supermodel 32bit Outputs" /Y
|
||||||
xcopy ".\MAME64.dll" ".\Release.Win32\Supermodel 64bit Outputs" /Y
|
xcopy ".\MAME64.dll" ".\Release.Win32\Supermodel 64bit Outputs" /Y
|
||||||
|
xcopy ".\MAME64.dll" ".\Release.Win32\Flycast" /Y
|
||||||
cd Release.Win32
|
cd Release.Win32
|
||||||
cd Afterburner Climax
|
cd Afterburner Climax
|
||||||
rename dinput8.dll opengl32.dll
|
rename dinput8.dll opengl32.dll
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
<ClInclude Include="Game Files\DeadHeat.h" />
|
<ClInclude Include="Game Files\DeadHeat.h" />
|
||||||
<ClInclude Include="Game Files\DeadHeatRiders.h" />
|
<ClInclude Include="Game Files\DeadHeatRiders.h" />
|
||||||
<ClInclude Include="Game Files\DirtyDrivin.h" />
|
<ClInclude Include="Game Files\DirtyDrivin.h" />
|
||||||
<ClInclude Include="Game Files\Flycast.h" />
|
|
||||||
<ClInclude Include="Game Files\FordRacingOther.h" />
|
<ClInclude Include="Game Files\FordRacingOther.h" />
|
||||||
<ClInclude Include="Game Files\GaelcoTuningRace.h" />
|
<ClInclude Include="Game Files\GaelcoTuningRace.h" />
|
||||||
<ClInclude Include="Game Files\GoldenGun.h" />
|
<ClInclude Include="Game Files\GoldenGun.h" />
|
||||||
@ -88,7 +87,6 @@
|
|||||||
<ClCompile Include="Game Files\DemulNascarInputs.cpp" />
|
<ClCompile Include="Game Files\DemulNascarInputs.cpp" />
|
||||||
<ClCompile Include="Game Files\DemulSmashingDriveInputs.cpp" />
|
<ClCompile Include="Game Files\DemulSmashingDriveInputs.cpp" />
|
||||||
<ClCompile Include="Game Files\DirtyDrivin.cpp" />
|
<ClCompile Include="Game Files\DirtyDrivin.cpp" />
|
||||||
<ClCompile Include="Game Files\Flycast.cpp" />
|
|
||||||
<ClCompile Include="Game Files\FordRacingOther.cpp" />
|
<ClCompile Include="Game Files\FordRacingOther.cpp" />
|
||||||
<ClCompile Include="Game Files\GaelcoTuningRace.cpp" />
|
<ClCompile Include="Game Files\GaelcoTuningRace.cpp" />
|
||||||
<ClCompile Include="Game Files\GoldenGun.cpp" />
|
<ClCompile Include="Game Files\GoldenGun.cpp" />
|
||||||
|
@ -145,7 +145,6 @@
|
|||||||
<ClCompile Include="Game Files\WMMT5DX.cpp" />
|
<ClCompile Include="Game Files\WMMT5DX.cpp" />
|
||||||
<ClCompile Include="Game Files\CrazyTaxi.cpp" />
|
<ClCompile Include="Game Files\CrazyTaxi.cpp" />
|
||||||
<ClCompile Include="Game Files\Daytona3NSE.cpp" />
|
<ClCompile Include="Game Files\Daytona3NSE.cpp" />
|
||||||
<ClCompile Include="Game Files\Flycast.cpp" />
|
|
||||||
<ClCompile Include="Game Files\WMMT3.cpp" />
|
<ClCompile Include="Game Files\WMMT3.cpp" />
|
||||||
<ClCompile Include="Game Files\DeadHeat.cpp" />
|
<ClCompile Include="Game Files\DeadHeat.cpp" />
|
||||||
<ClCompile Include="Game Files\DeadHeatRiders.cpp" />
|
<ClCompile Include="Game Files\DeadHeatRiders.cpp" />
|
||||||
@ -348,9 +347,6 @@
|
|||||||
<ClInclude Include="Game Files\Daytona3NSE.h">
|
<ClInclude Include="Game Files\Daytona3NSE.h">
|
||||||
<Filter>Common Header Files</Filter>
|
<Filter>Common Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Game Files\Flycast.h">
|
|
||||||
<Filter>Common Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Game Files\WMMT3.h">
|
<ClInclude Include="Game Files\WMMT3.h">
|
||||||
<Filter>Common Header Files</Filter>
|
<Filter>Common Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
52
DllMain.cpp
52
DllMain.cpp
@ -27,6 +27,7 @@ along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>.
|
|||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
#include <sapi.h>
|
#include <sapi.h>
|
||||||
#include <atlcomcli.h>
|
#include <atlcomcli.h>
|
||||||
|
#include <TlHelp32.h>
|
||||||
#include "Config/PersistentValues.h"
|
#include "Config/PersistentValues.h"
|
||||||
|
|
||||||
// include all game header files here.
|
// include all game header files here.
|
||||||
@ -44,7 +45,6 @@ along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>.
|
|||||||
#include "Game Files/DirtyDrivin.h"
|
#include "Game Files/DirtyDrivin.h"
|
||||||
#include "Game Files/FordRacing.h"
|
#include "Game Files/FordRacing.h"
|
||||||
#include "Game Files/FordRacingOther.h"
|
#include "Game Files/FordRacingOther.h"
|
||||||
#include "Game Files/Flycast.h"
|
|
||||||
#include "Game Files/GaelcoTuningRace.h"
|
#include "Game Files/GaelcoTuningRace.h"
|
||||||
#include "Game Files/GRID.h"
|
#include "Game Files/GRID.h"
|
||||||
#include "Game Files/GoldenGun.h"
|
#include "Game Files/GoldenGun.h"
|
||||||
@ -892,6 +892,7 @@ int joystick_index1;
|
|||||||
int joystick1Index = -1;
|
int joystick1Index = -1;
|
||||||
int joystick_index2 = -1;
|
int joystick_index2 = -1;
|
||||||
int joystick_index3 = -1;
|
int joystick_index3 = -1;
|
||||||
|
static DWORD GameProcessID;
|
||||||
|
|
||||||
LPCSTR CustomAlternativeMaxForceLeft;
|
LPCSTR CustomAlternativeMaxForceLeft;
|
||||||
LPCSTR CustomAlternativeMaxForceRight;
|
LPCSTR CustomAlternativeMaxForceRight;
|
||||||
@ -2234,6 +2235,31 @@ DWORD WINAPI AdjustFFBStrengthLoopNoWaitEvent(LPVOID lpParam)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD MyGetProcessId(LPCTSTR ProcessName)
|
||||||
|
{
|
||||||
|
PROCESSENTRY32 pt;
|
||||||
|
HANDLE hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
|
pt.dwSize = sizeof(PROCESSENTRY32);
|
||||||
|
if (Process32First(hsnap, &pt)) {
|
||||||
|
do {
|
||||||
|
if (!lstrcmpi(pt.szExeFile, ProcessName)) {
|
||||||
|
CloseHandle(hsnap);
|
||||||
|
return pt.th32ProcessID;
|
||||||
|
}
|
||||||
|
} while (Process32Next(hsnap, &pt));
|
||||||
|
}
|
||||||
|
CloseHandle(hsnap);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL IsProcessRunning(DWORD pid)
|
||||||
|
{
|
||||||
|
HANDLE process = OpenProcess(SYNCHRONIZE, FALSE, pid);
|
||||||
|
DWORD ret = WaitForSingleObject(process, 0);
|
||||||
|
CloseHandle(process);
|
||||||
|
return ret == WAIT_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD WINAPI FFBLoop(LPVOID lpParam)
|
DWORD WINAPI FFBLoop(LPVOID lpParam)
|
||||||
{
|
{
|
||||||
hlp.log("In FFBLoop");
|
hlp.log("In FFBLoop");
|
||||||
@ -2298,10 +2324,9 @@ DWORD WINAPI FFBLoop(LPVOID lpParam)
|
|||||||
case DAYTONA_3_NSE:
|
case DAYTONA_3_NSE:
|
||||||
game = new Daytona3NSE;
|
game = new Daytona3NSE;
|
||||||
break;
|
break;
|
||||||
case SUPERMODEL_:
|
|
||||||
game = new MAMESupermodel;
|
|
||||||
break;
|
|
||||||
case MAME_:
|
case MAME_:
|
||||||
|
case SUPERMODEL_:
|
||||||
|
case FLYCAST:
|
||||||
game = new MAMESupermodel;
|
game = new MAMESupermodel;
|
||||||
break;
|
break;
|
||||||
case FORD_RACING:
|
case FORD_RACING:
|
||||||
@ -2460,9 +2485,6 @@ DWORD WINAPI FFBLoop(LPVOID lpParam)
|
|||||||
case Crazy_Taxi:
|
case Crazy_Taxi:
|
||||||
game = new CrazyTaxi;
|
game = new CrazyTaxi;
|
||||||
break;
|
break;
|
||||||
case FLYCAST:
|
|
||||||
game = new Flycast;
|
|
||||||
break;
|
|
||||||
case WMMT_3:
|
case WMMT_3:
|
||||||
game = new WMMT3;
|
game = new WMMT3;
|
||||||
break;
|
break;
|
||||||
@ -3316,6 +3338,19 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ulReasonForCall, LPVOID lpReserved)
|
|||||||
originalmmsystemGetVersion = GetProcAddress(gl_hOriginalDll, "mmsystemGetVersion");
|
originalmmsystemGetVersion = GetProcAddress(gl_hOriginalDll, "mmsystemGetVersion");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (configGameId == 22)
|
||||||
|
{
|
||||||
|
DWORD ProcessID = GetPrivateProfileInt(TEXT("Settings"), TEXT("ProcessID"), 0, settingsFilename);
|
||||||
|
|
||||||
|
if (IsProcessRunning(ProcessID))
|
||||||
|
break;
|
||||||
|
|
||||||
|
GameProcessID = MyGetProcessId(L"flycast.exe");
|
||||||
|
|
||||||
|
if (GameProcessID)
|
||||||
|
WritePrivateProfileStringA("Settings", "ProcessID", (char*)(std::to_string(GameProcessID)).c_str(), ".\\FFBPlugin.ini");
|
||||||
|
}
|
||||||
|
|
||||||
if (processName.find("FFBPluginGUI.exe") != std::string::npos)
|
if (processName.find("FFBPluginGUI.exe") != std::string::npos)
|
||||||
{
|
{
|
||||||
hlp.log("hooked FFBPluginGUI.exe, aborting");
|
hlp.log("hooked FFBPluginGUI.exe, aborting");
|
||||||
@ -3343,6 +3378,9 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ulReasonForCall, LPVOID lpReserved)
|
|||||||
hlp.log((char*)processName.c_str());
|
hlp.log((char*)processName.c_str());
|
||||||
keepRunning = false;
|
keepRunning = false;
|
||||||
|
|
||||||
|
if (configGameId == 22)
|
||||||
|
WritePrivateProfileStringA("Settings", "ProcessID", 0, ".\\FFBPlugin.ini");
|
||||||
|
|
||||||
if (haptic)
|
if (haptic)
|
||||||
SDL_HapticClose(haptic);
|
SDL_HapticClose(haptic);
|
||||||
|
|
||||||
|
@ -1,122 +0,0 @@
|
|||||||
/*This file is part of FFB Arcade Plugin.
|
|
||||||
FFB Arcade Plugin is free software : you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
FFB Arcade Plugin is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <tchar.h>
|
|
||||||
#include "Flycast.h"
|
|
||||||
#include "math.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <windows.h>
|
|
||||||
#include "SDL.h"
|
|
||||||
#include "../Common Files/CRCCheck.h"
|
|
||||||
#include "../Common Files/SignatureScanning.h"
|
|
||||||
|
|
||||||
static const char* initiald = "INITIAL ";
|
|
||||||
|
|
||||||
static bool InitialDRunning;
|
|
||||||
static bool FFBGameInit;
|
|
||||||
static bool LetsStartFFB;
|
|
||||||
static INT_PTR FFBAddress;
|
|
||||||
|
|
||||||
WNDPROC pOrigProc;
|
|
||||||
|
|
||||||
LRESULT CALLBACK HookWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
if (!LetsStartFFB)
|
|
||||||
LetsStartFFB = true;
|
|
||||||
|
|
||||||
return CallWindowProc(pOrigProc, hwnd, uMsg, wParam, lParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void getGameInfo(char* GameName)
|
|
||||||
{
|
|
||||||
if (_strcmpi(GameName, initiald) == 0)
|
|
||||||
{
|
|
||||||
FFBAddress = (INT_PTR)aAddy2 + 0xAF;
|
|
||||||
InitialDRunning = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Flycast::FFBLoop(EffectConstants* constants, Helpers* helpers, EffectTriggers* triggers) {
|
|
||||||
|
|
||||||
if (!FFBGameInit)
|
|
||||||
{
|
|
||||||
HWND hwnd = FindWindowA(0, "Flycast");
|
|
||||||
HWND hwnddojo = FindWindowA(0, "Flycast Dojo");
|
|
||||||
|
|
||||||
if (pOrigProc == NULL && hwnd)
|
|
||||||
pOrigProc = (WNDPROC)::SetWindowLongPtr((HWND)hwnd, GWLP_WNDPROC, (LONG_PTR)HookWndProc);
|
|
||||||
|
|
||||||
if (pOrigProc == NULL && hwnddojo)
|
|
||||||
pOrigProc = (WNDPROC)::SetWindowLongPtr((HWND)hwnddojo, GWLP_WNDPROC, (LONG_PTR)HookWndProc);
|
|
||||||
|
|
||||||
if (LetsStartFFB)
|
|
||||||
{
|
|
||||||
Sleep(15000);
|
|
||||||
|
|
||||||
aAddy2 = PatternScan("\x4E\x49\x54\x49\x41\x4C\x20\x44\x20\x56\x65\x72\x2E\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x30\xDF\x9C\xAB\xBA\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x00\x50\x54\x05\x00\x00\x00\x05\x00\x00\x00\x80\xAA\x6D\x68\x00\x55", "xxxxxxxx???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????xxxxxx");
|
|
||||||
|
|
||||||
long long InitialDName = helpers->ReadLong((INT_PTR)aAddy2 - 0x01, false);
|
|
||||||
|
|
||||||
char x[256] = { 0 };
|
|
||||||
|
|
||||||
std::memcpy(x, &InitialDName, 8);
|
|
||||||
|
|
||||||
std::string myString(x);
|
|
||||||
getGameInfo((char*)myString.c_str());
|
|
||||||
|
|
||||||
FFBGameInit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (InitialDRunning)
|
|
||||||
{
|
|
||||||
UINT8 ff1 = helpers->ReadByte(FFBAddress, false);
|
|
||||||
UINT8 ff2 = helpers->ReadByte(FFBAddress + 0x01, false);
|
|
||||||
UINT8 ff3 = helpers->ReadByte(FFBAddress + 0x02, false);
|
|
||||||
|
|
||||||
if ((ff1 == 0x80) && (ff3 == 0x01))
|
|
||||||
triggers->Spring(1.0);
|
|
||||||
|
|
||||||
if ((ff1 == 0x85) && (ff2 == 0x3F) && (ff3 > 0x00) && (ff3 < 0x30))
|
|
||||||
{
|
|
||||||
double percentForce = ff3 / 47.0;
|
|
||||||
double percentLength = 100;
|
|
||||||
triggers->Rumble(percentForce, percentForce, percentLength);
|
|
||||||
triggers->Sine(40, 0, percentForce);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ff1 == 0x86) && (ff2 == 0x02) && (ff3 > 0x09) && (ff3 < 0x3C))
|
|
||||||
{
|
|
||||||
double percentForce = (60 - ff3) / 43.0;
|
|
||||||
double percentLength = 100;
|
|
||||||
triggers->Spring(percentForce);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ff1 == 0x84) && (ff2 == 0x00) && (ff3 > 0x37) && (ff3 < 0x80))
|
|
||||||
{
|
|
||||||
double percentForce = (128 - ff3) / 72.0;
|
|
||||||
double percentLength = 100;
|
|
||||||
triggers->Rumble(percentForce, 0, percentLength);
|
|
||||||
triggers->Constant(constants->DIRECTION_FROM_LEFT, percentForce);
|
|
||||||
}
|
|
||||||
else if ((ff1 == 0x84) && (ff2 == 0x01) && (ff3 > 0x00) && (ff3 < 0x49))
|
|
||||||
{
|
|
||||||
double percentForce = (ff3 / 72.0);
|
|
||||||
double percentLength = 100;
|
|
||||||
triggers->Rumble(0, percentForce, percentLength);
|
|
||||||
triggers->Constant(constants->DIRECTION_FROM_RIGHT, percentForce);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
/*This file is part of FFB Arcade Plugin.
|
|
||||||
FFB Arcade Plugin is free software : you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
FFB Arcade Plugin is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "../Common Files/Game.h"
|
|
||||||
class Flycast : public Game {
|
|
||||||
|
|
||||||
public:
|
|
||||||
void FFBLoop(EffectConstants* constants, Helpers* helpers, EffectTriggers* triggers);
|
|
||||||
};
|
|
@ -14,9 +14,12 @@ along with FFB Arcade Plugin.If not, see < https://www.gnu.org/licenses/>.
|
|||||||
#include "MAMESupermodel.h"
|
#include "MAMESupermodel.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
#include <atlstr.h>
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
#include "../Common Files/SignatureScanning.h"
|
#include "../Common Files/SignatureScanning.h"
|
||||||
|
|
||||||
|
static char GameName[256];
|
||||||
|
|
||||||
//Supermodel Emulator Games
|
//Supermodel Emulator Games
|
||||||
std::string dayto2pe("dayto2pe");
|
std::string dayto2pe("dayto2pe");
|
||||||
std::string daytona2("daytona2");
|
std::string daytona2("daytona2");
|
||||||
@ -217,6 +220,12 @@ std::string victlapw("victlapw");
|
|||||||
std::string victlap("victlap");
|
std::string victlap("victlap");
|
||||||
std::string dblaxle("dblaxle");
|
std::string dblaxle("dblaxle");
|
||||||
std::string dblaxleu("dblaxleu");
|
std::string dblaxleu("dblaxleu");
|
||||||
|
//Flycast Below
|
||||||
|
std::string INITIAL("INITIAL");
|
||||||
|
std::string EIGHTEENWHEELER("18WHEELER\n");
|
||||||
|
std::string MAXIMUM("MAXIMUM");
|
||||||
|
std::string FASTER("FASTER");
|
||||||
|
std::string F355("F355");
|
||||||
|
|
||||||
//Our string to load game from
|
//Our string to load game from
|
||||||
std::string M2Active("M2Active");
|
std::string M2Active("M2Active");
|
||||||
@ -238,6 +247,9 @@ std::string AfterburnerActive("AfterburnerActive");
|
|||||||
std::string OutrunActive("OutrunActive");
|
std::string OutrunActive("OutrunActive");
|
||||||
std::string PDriftActive("PDriftActive");
|
std::string PDriftActive("PDriftActive");
|
||||||
std::string SuperChaseActive("SuperChaseActive");
|
std::string SuperChaseActive("SuperChaseActive");
|
||||||
|
std::string MaximumSpeedActive("MaximumSpeedActive");
|
||||||
|
std::string InitialDActive("InitialDActive");
|
||||||
|
std::string NaomiFFBActive("NaomiFFBActive");
|
||||||
|
|
||||||
//Names of FFB Outputs
|
//Names of FFB Outputs
|
||||||
std::string RawDrive("RawDrive");
|
std::string RawDrive("RawDrive");
|
||||||
@ -270,10 +282,10 @@ std::string mcuout1("mcuout1");
|
|||||||
std::string Bank_Motor_Speed("Bank_Motor_Speed");
|
std::string Bank_Motor_Speed("Bank_Motor_Speed");
|
||||||
std::string Bank_Motor_Direction("Bank_Motor_Direction");
|
std::string Bank_Motor_Direction("Bank_Motor_Direction");
|
||||||
std::string bank_motor_position("bank_motor_position");
|
std::string bank_motor_position("bank_motor_position");
|
||||||
|
//Flycast
|
||||||
//Emulator Name
|
std::string awffb("awffb");
|
||||||
std::string MAME("MAME");
|
std::string midiffb("midiffb");
|
||||||
std::string Supermodel("Supermodel");
|
std::string m3ffb("m3ffb");
|
||||||
|
|
||||||
HINSTANCE ProcDLL = NULL;
|
HINSTANCE ProcDLL = NULL;
|
||||||
extern int joystick_index1;
|
extern int joystick_index1;
|
||||||
@ -286,7 +298,6 @@ extern SDL_Joystick* GameController3;
|
|||||||
extern SDL_Haptic* ControllerHaptic3;
|
extern SDL_Haptic* ControllerHaptic3;
|
||||||
extern SDL_Haptic* haptic3;
|
extern SDL_Haptic* haptic3;
|
||||||
|
|
||||||
|
|
||||||
//Config Settings
|
//Config Settings
|
||||||
extern wchar_t* settingsFilename;
|
extern wchar_t* settingsFilename;
|
||||||
extern int DeviceGUID;
|
extern int DeviceGUID;
|
||||||
@ -947,6 +958,7 @@ static bool Effect3 = false;
|
|||||||
static bool DirtDevilSine = false;
|
static bool DirtDevilSine = false;
|
||||||
static bool DontSineUntilRaceStart = false;
|
static bool DontSineUntilRaceStart = false;
|
||||||
static bool HardDrivinFrame = false;
|
static bool HardDrivinFrame = false;
|
||||||
|
static bool NaomiFFBGo = false;
|
||||||
static bool Motion = false;
|
static bool Motion = false;
|
||||||
static bool MotionFalse = false;
|
static bool MotionFalse = false;
|
||||||
static bool StartEffectOnce = false;
|
static bool StartEffectOnce = false;
|
||||||
@ -960,8 +972,8 @@ HINSTANCE hPrevInstance;
|
|||||||
LPSTR lpCmdLine;
|
LPSTR lpCmdLine;
|
||||||
int nCmdShow;
|
int nCmdShow;
|
||||||
|
|
||||||
|
static const char* FlycastnameFFB;
|
||||||
const char* nameFFB;
|
const char* nameFFB;
|
||||||
const char* romFFB;
|
|
||||||
const char* EmulatorName;
|
const char* EmulatorName;
|
||||||
char* name;
|
char* name;
|
||||||
char* romname;
|
char* romname;
|
||||||
@ -977,6 +989,8 @@ int frame = 0;
|
|||||||
int HardDrivinFFB;
|
int HardDrivinFFB;
|
||||||
int StopConstant;
|
int StopConstant;
|
||||||
int newstateFFB;
|
int newstateFFB;
|
||||||
|
int oldstateFFB;
|
||||||
|
int EffectCount;
|
||||||
int stateFFB;
|
int stateFFB;
|
||||||
int stateFFB2;
|
int stateFFB2;
|
||||||
int stateFFB3;
|
int stateFFB3;
|
||||||
@ -1171,7 +1185,6 @@ void add_map_entry(id_map_entry* entry, int id, char* name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int __stdcall mame_start(int hWnd)
|
int __stdcall mame_start(int hWnd)
|
||||||
{
|
{
|
||||||
WCHAR buf[256];
|
WCHAR buf[256];
|
||||||
@ -1194,6 +1207,11 @@ int __stdcall mame_stop(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CurrentGameName(Helpers* helpers)
|
||||||
|
{
|
||||||
|
helpers->info("Game = %s", GameName);
|
||||||
|
}
|
||||||
|
|
||||||
int __stdcall mame_copydata(int id, const char* name)
|
int __stdcall mame_copydata(int id, const char* name)
|
||||||
{
|
{
|
||||||
WCHAR buf[256];
|
WCHAR buf[256];
|
||||||
@ -1202,7 +1220,10 @@ int __stdcall mame_copydata(int id, const char* name)
|
|||||||
|
|
||||||
if (id == 0)
|
if (id == 0)
|
||||||
{
|
{
|
||||||
romFFB = name;
|
//romFFB = name;
|
||||||
|
sprintf(GameName, "%s", name);
|
||||||
|
|
||||||
|
CurrentGameName(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppendTextToEditCtrl(hEdit, buf);
|
AppendTextToEditCtrl(hEdit, buf);
|
||||||
@ -1222,7 +1243,9 @@ int __stdcall mame_updatestate(const char* id, int state)
|
|||||||
wsprintf(buf, L"updatestate: id=%d (%S) state=%d\r\n", id, name, state);
|
wsprintf(buf, L"updatestate: id=%d (%S) state=%d\r\n", id, name, state);
|
||||||
AppendTextToEditCtrl(hEdit, buf);
|
AppendTextToEditCtrl(hEdit, buf);
|
||||||
|
|
||||||
nameFFB = name;
|
CStringA stringName(name);
|
||||||
|
nameFFB = stringName;
|
||||||
|
|
||||||
newstateFFB = state;
|
newstateFFB = state;
|
||||||
|
|
||||||
if (HardDrivinFrame)
|
if (HardDrivinFrame)
|
||||||
@ -1276,21 +1299,6 @@ int __stdcall mame_output(const char* name, int value)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//static BOOL CALLBACK FindWindowBySubstr(HWND hwnd, LPARAM substring)
|
|
||||||
//{
|
|
||||||
// const DWORD TITLE_SIZE = 1024;
|
|
||||||
// TCHAR windowTitle[TITLE_SIZE];
|
|
||||||
//
|
|
||||||
// if (GetWindowText(hwnd, windowTitle, TITLE_SIZE))
|
|
||||||
// {
|
|
||||||
// if (_tcsstr(windowTitle, LPCTSTR(substring)) != NULL)
|
|
||||||
// {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
static DWORD WINAPI ScanThread(LPVOID lpParam)
|
static DWORD WINAPI ScanThread(LPVOID lpParam)
|
||||||
{
|
{
|
||||||
if (romname == raveracw || romname == raveracj || romname == raveracja || romname == raverace) //Rave Racer
|
if (romname == raveracw || romname == raveracj || romname == raveracja || romname == raverace) //Rave Racer
|
||||||
@ -1331,6 +1339,74 @@ static DWORD WINAPI ScanThread(LPVOID lpParam)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int speedffb(int ffRaw) {
|
||||||
|
switch (ffRaw) {
|
||||||
|
case 0x1E:
|
||||||
|
return 31;
|
||||||
|
case 0x1C:
|
||||||
|
return 30;
|
||||||
|
case 0x1A:
|
||||||
|
return 29;
|
||||||
|
case 0x18:
|
||||||
|
return 28;
|
||||||
|
case 0x16:
|
||||||
|
return 27;
|
||||||
|
case 0x14:
|
||||||
|
return 26;
|
||||||
|
case 0x12:
|
||||||
|
return 25;
|
||||||
|
case 0x10:
|
||||||
|
return 24;
|
||||||
|
case 0x0E:
|
||||||
|
return 23;
|
||||||
|
case 0x0C:
|
||||||
|
return 22;
|
||||||
|
case 0x0A:
|
||||||
|
return 21;
|
||||||
|
case 0x08:
|
||||||
|
return 20;
|
||||||
|
case 0x06:
|
||||||
|
return 19;
|
||||||
|
case 0x04:
|
||||||
|
return 18;
|
||||||
|
case 0x02:
|
||||||
|
return 17;
|
||||||
|
|
||||||
|
case 0x1F:
|
||||||
|
return 16;
|
||||||
|
case 0x1D:
|
||||||
|
return 15;
|
||||||
|
case 0x1B:
|
||||||
|
return 14;
|
||||||
|
case 0x19:
|
||||||
|
return 13;
|
||||||
|
case 0x17:
|
||||||
|
return 12;
|
||||||
|
case 0x15:
|
||||||
|
return 11;
|
||||||
|
case 0x13:
|
||||||
|
return 10;
|
||||||
|
case 0x11:
|
||||||
|
return 9;
|
||||||
|
case 0x0F:
|
||||||
|
return 8;
|
||||||
|
case 0x0D:
|
||||||
|
return 7;
|
||||||
|
case 0x0B:
|
||||||
|
return 6;
|
||||||
|
case 0x09:
|
||||||
|
return 5;
|
||||||
|
case 0x07:
|
||||||
|
return 4;
|
||||||
|
case 0x05:
|
||||||
|
return 3;
|
||||||
|
case 0x03:
|
||||||
|
return 2;
|
||||||
|
case 0x01:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int raveracer(int ffRaw) {
|
static int raveracer(int ffRaw) {
|
||||||
switch (ffRaw) {
|
switch (ffRaw) {
|
||||||
|
|
||||||
@ -1699,7 +1775,7 @@ void MAMESupermodel::FFBLoop(EffectConstants* constants, Helpers* helpers, Effec
|
|||||||
}
|
}
|
||||||
|
|
||||||
romname = new char[256]; //name of rom being played
|
romname = new char[256]; //name of rom being played
|
||||||
sprintf(romname, "%s", romFFB);
|
sprintf(romname, "%s", GameName);
|
||||||
|
|
||||||
name = new char[256]; //name of FFB currently
|
name = new char[256]; //name of FFB currently
|
||||||
sprintf(name, "%s", nameFFB);
|
sprintf(name, "%s", nameFFB);
|
||||||
@ -2585,6 +2661,22 @@ void MAMESupermodel::FFBLoop(EffectConstants* constants, Helpers* helpers, Effec
|
|||||||
RunningFFB = "NamcoFFBActive";
|
RunningFFB = "NamcoFFBActive";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (romname == INITIAL)
|
||||||
|
{
|
||||||
|
RunningFFB = "InitialDActive";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (romname == MAXIMUM || romname == FASTER)
|
||||||
|
{
|
||||||
|
RunningFFB = "MaximumSpeedActive";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (romname == F355 || romname == EIGHTEENWHEELER)
|
||||||
|
{
|
||||||
|
RunningFFB = "NaomiFFBActive";
|
||||||
|
NaomiFFBGo = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (enableLogging == 1)
|
if (enableLogging == 1)
|
||||||
{
|
{
|
||||||
char romnametext[256];
|
char romnametext[256];
|
||||||
@ -2603,34 +2695,6 @@ void MAMESupermodel::FFBLoop(EffectConstants* constants, Helpers* helpers, Effec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (!EmuName)
|
|
||||||
//{
|
|
||||||
// //Select code to run via emulator name using partial window title to avoid issues with FPS showing etc
|
|
||||||
// const TCHAR MAMEstring[] = TEXT("MAME");
|
|
||||||
// EnumWindows(FindWindowBySubstr, (LPARAM)MAMEstring);
|
|
||||||
|
|
||||||
// const TCHAR Supermodelstring[] = TEXT("Supermodel");
|
|
||||||
// EnumWindows(FindWindowBySubstr, (LPARAM)Supermodelstring);
|
|
||||||
|
|
||||||
// if (!EnumWindows(FindWindowBySubstr, (LPARAM)MAMEstring))
|
|
||||||
// {
|
|
||||||
// EmulatorName = "MAME";
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (!EnumWindows(FindWindowBySubstr, (LPARAM)Supermodelstring))
|
|
||||||
// {
|
|
||||||
// EmulatorName = "Supermodel";
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Emulator = new char[256]; // Emulator name
|
|
||||||
// sprintf(Emulator, "%s", EmulatorName);
|
|
||||||
|
|
||||||
// if ((EmulatorName != NULL) && (EmulatorName[0] != '\0'))
|
|
||||||
// {
|
|
||||||
// EmuName = true;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
if (RomGameName && RunningFFB > 0)
|
if (RomGameName && RunningFFB > 0)
|
||||||
{
|
{
|
||||||
if (RunningFFB > 0 && EnableDamper)
|
if (RunningFFB > 0 && EnableDamper)
|
||||||
@ -3406,6 +3470,178 @@ void MAMESupermodel::FFBLoop(EffectConstants* constants, Helpers* helpers, Effec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (RunningFFB == MaximumSpeedActive)
|
||||||
|
{
|
||||||
|
if (name == awffb)
|
||||||
|
{
|
||||||
|
helpers->log("got value: ");
|
||||||
|
std::string ffs = std::to_string(newstateFFB);
|
||||||
|
helpers->log((char*)ffs.c_str());
|
||||||
|
|
||||||
|
stateFFB = newstateFFB;
|
||||||
|
UINT8 FFB = speedffb(stateFFB);
|
||||||
|
|
||||||
|
if (FFB > 0x00 && FFB < 0x11)
|
||||||
|
{
|
||||||
|
double percentForce = (FFB) / 16.0;
|
||||||
|
double percentLength = 100;
|
||||||
|
triggers->Rumble(percentForce, 0, percentLength);
|
||||||
|
triggers->Constant(constants->DIRECTION_FROM_LEFT, percentForce);
|
||||||
|
}
|
||||||
|
else if (FFB > 0x10 && FFB < 0x20)
|
||||||
|
{
|
||||||
|
double percentForce = (FFB - 16) / 16.0;
|
||||||
|
double percentLength = 100;
|
||||||
|
triggers->Rumble(0, percentForce, percentLength);
|
||||||
|
triggers->Constant(constants->DIRECTION_FROM_RIGHT, percentForce);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RunningFFB == NaomiFFBActive)
|
||||||
|
{
|
||||||
|
if (name == m3ffb)
|
||||||
|
{
|
||||||
|
helpers->log("got value: ");
|
||||||
|
std::string ffs = std::to_string(newstateFFB);
|
||||||
|
helpers->log((char*)ffs.c_str());
|
||||||
|
|
||||||
|
stateFFB = newstateFFB;
|
||||||
|
|
||||||
|
if (oldstateFFB != stateFFB)
|
||||||
|
{
|
||||||
|
if (stateFFB > 0xAF && stateFFB < 0xC0)
|
||||||
|
{
|
||||||
|
Effect1 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateFFB > 0x09 && stateFFB < 0x20)
|
||||||
|
{
|
||||||
|
double percentForce = (stateFFB - 9) / 16.0;
|
||||||
|
triggers->Springi(percentForce);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateFFB > 0x1F && stateFFB < 0x30)
|
||||||
|
{
|
||||||
|
double percentForce = (stateFFB - 31) / 16.0;
|
||||||
|
triggers->Friction(percentForce);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateFFB > 0x2F && stateFFB < 0x40)
|
||||||
|
{
|
||||||
|
double percentForce = (stateFFB - 47) / 16.0;
|
||||||
|
triggers->Rumble(percentForce, percentForce, 100);
|
||||||
|
triggers->Sine(40, 0, percentForce);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateFFB > 0x3F && stateFFB < 0x50)
|
||||||
|
{
|
||||||
|
double percentForce = (stateFFB - 63) / 16.0;
|
||||||
|
triggers->Friction(percentForce);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateFFB > 0x4F && stateFFB < 0x60)
|
||||||
|
{
|
||||||
|
double percentForce = (stateFFB - 79) / 16.0;
|
||||||
|
double percentLength = 100;
|
||||||
|
triggers->Rumble(percentForce, 0, percentLength);
|
||||||
|
triggers->Constant(constants->DIRECTION_FROM_LEFT, percentForce);
|
||||||
|
}
|
||||||
|
else if (stateFFB > 0x5F && stateFFB < 0x70)
|
||||||
|
{
|
||||||
|
if (stateFFB != 0x6A && stateFFB != 0x6B) // Annoying turn of wheel start of races??
|
||||||
|
{
|
||||||
|
double percentForce = (stateFFB - 95) / 16.0;
|
||||||
|
double percentLength = 100;
|
||||||
|
triggers->Rumble(0, percentForce, percentLength);
|
||||||
|
triggers->Constant(constants->DIRECTION_FROM_RIGHT, percentForce);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateFFB == 0x9F)
|
||||||
|
{
|
||||||
|
double percentForce = 0.4;
|
||||||
|
double percentLength = 100;
|
||||||
|
triggers->Rumble(percentForce, 0, percentLength);
|
||||||
|
triggers->Constant(constants->DIRECTION_FROM_LEFT, percentForce);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateFFB == 0xBF)
|
||||||
|
{
|
||||||
|
double percentForce = 0.4;
|
||||||
|
double percentLength = 100;
|
||||||
|
triggers->Rumble(0, percentForce, percentLength);
|
||||||
|
triggers->Constant(constants->DIRECTION_FROM_RIGHT, percentForce);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Effect1)
|
||||||
|
{
|
||||||
|
++EffectCount;
|
||||||
|
|
||||||
|
if (EffectCount >= 31)
|
||||||
|
{
|
||||||
|
Effect1 = false;
|
||||||
|
EffectCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double percentForce = (stateFFB - 143) / 16.0;
|
||||||
|
triggers->Rumble(percentForce, percentForce, 100);
|
||||||
|
triggers->Sine(60, 0, percentForce);
|
||||||
|
}
|
||||||
|
oldstateFFB = stateFFB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RunningFFB == InitialDActive)
|
||||||
|
{
|
||||||
|
if (name == midiffb)
|
||||||
|
{
|
||||||
|
helpers->log("got value: ");
|
||||||
|
std::string ffs = std::to_string(newstateFFB);
|
||||||
|
helpers->log((char*)ffs.c_str());
|
||||||
|
|
||||||
|
stateFFB = newstateFFB;
|
||||||
|
|
||||||
|
BYTE* ffb = reinterpret_cast<BYTE*>(&stateFFB);
|
||||||
|
|
||||||
|
if ((ffb[2] == 0x80) && (ffb[0] == 0x01))
|
||||||
|
{
|
||||||
|
triggers->Spring(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ffb[2] == 0x85) && (ffb[1] == 0x3F) && (ffb[0] > 0x00) && (ffb[0] < 0x30))
|
||||||
|
{
|
||||||
|
double percentForce = ffb[0] / 47.0;
|
||||||
|
double percentLength = 100;
|
||||||
|
triggers->Rumble(percentForce, percentForce, percentLength);
|
||||||
|
triggers->Sine(40, 0, percentForce);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ffb[2] == 0x86) && (ffb[1] == 0x02) && (ffb[0] > 0x09) && (ffb[0] < 0x3C))
|
||||||
|
{
|
||||||
|
double percentForce = (60 - ffb[0]) / 43.0;
|
||||||
|
double percentLength = 100;
|
||||||
|
triggers->Spring(percentForce);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ffb[2] == 0x84) && (ffb[1] == 0x00) && (ffb[0] > 0x37) && (ffb[0] < 0x80))
|
||||||
|
{
|
||||||
|
double percentForce = (128 - ffb[0]) / 72.0;
|
||||||
|
double percentLength = 100;
|
||||||
|
triggers->Rumble(percentForce, 0, percentLength);
|
||||||
|
triggers->Constant(constants->DIRECTION_FROM_LEFT, percentForce);
|
||||||
|
}
|
||||||
|
else if ((ffb[2] == 0x84) && (ffb[1] == 0x01) && (ffb[0] > 0x00) && (ffb[0] < 0x49))
|
||||||
|
{
|
||||||
|
double percentForce = (ffb[0] / 72.0);
|
||||||
|
double percentLength = 100;
|
||||||
|
triggers->Rumble(0, percentForce, percentLength);
|
||||||
|
triggers->Constant(constants->DIRECTION_FROM_RIGHT, percentForce);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (RunningFFB == RaveRacerActive) //Rave Racer
|
if (RunningFFB == RaveRacerActive) //Rave Racer
|
||||||
{
|
{
|
||||||
if (!PatternFind)
|
if (!PatternFind)
|
||||||
|
BIN
MAME32.dll
BIN
MAME32.dll
Binary file not shown.
BIN
MAME64.dll
BIN
MAME64.dll
Binary file not shown.
@ -1 +1 @@
|
|||||||
v2.0.0.17
|
v2.0.0.18
|
Loading…
x
Reference in New Issue
Block a user