Hi svarni,
uns wird keiner helfen und Dein Problem ist ja wenigstens zu lösen.
Angenommen Du spielst unter Windows, ich habe von Linux keine Ahnung.
Hole Dir von MS die VS2013 für lau. (Die ist zwar nicht komplett, so wie die NotSoLau Versionen, sollte aber m.W. hier reichen.)
Hole Dir VJoy und die SDL2
Installiere das alles. Starte das Visual Studio und lasse Dir von der Framework eine MFC Dialoganwendung erstellen.
Gehe im CMyDialog::OnInitDialog() ans Ende und starte einen Worker
z.B.
BOOL CFSThrottleManagerDialog::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Starte den ThrottleManagerThread
m_Event[0].ResetEvent();
m_Event[1].ResetEvent();
m_pThread[0] = AfxBeginThread(ProcessJoystick, this);
return TRUE;
}
Ein paar Helper
void CFSThrottleManagerDialog::OnBnClickedStopButton()
{
if (IsThreadRunning())
{
// Signalisiere dem FSThrottleMangerThread das Ende an
m_Event[0].SetEvent();
// und warte bis Thread sich beendet hat
WaitForSingleObject(m_pThread[0]->m_hThread, INFINITE);
}
}
bool CFSThrottleManagerDialog::IsThreadRunning()
{
EnterCriticalSection(&csThrottleManager);
bool bThreadRunning = m_bThreadRunning;
LeaveCriticalSection(&csThrottleManager);
return bThreadRunning;
}
Der Thread
UINT ProcessJoystick(LPVOID pParam)
{
// Helper: Aufruf der eigentlichen WorkerThreadFunktion hier
// AfxEndThread() ruft keine Destruktoren auf. Dadurch können
// Memory Leaks entstehen. Bspw. CString
// Im Workerthread werden, wie in jeder anderen Funktion
// die Destruktoren aufgerufen.
//
// Oder man verzichtet im Workerthread auf AfxEndThread()
// und ruft einfach return nRetCode; auf.
//
UINT nRetCode = ProcessJoystickWorker(pParam);
AfxEndThread(nRetCode);
return 0;
}
Der eigentliche Worker
UINT ProcessJoystickWorker(LPVOID pParam)
{
CFSThrottleManagerDialog* pDialog = (CFSThrottleManagerDialog*)pParam;
pDialog->SetThreadRunning(true);
SDL_Joystick *Joystick = NULL;
SDL_bool done = SDL_FALSE;
JOYSTICK_POSITION_V2 vJoyReport1;
SDL_Init(SDL_INIT_JOYSTICK)
// Enumeriere alle bekannten Joysticks
for (i = 0; i < SDL_NumJoysticks(); ++i)
{
strName = SDL_JoystickNameForIndex(i);
if (strName.CompareNoCase(strJoystick) == 0)
{
nJoystick = i; // Joystick gefunden
break;
}
}
if (!vJoyEnabled())
{
// Ende der Fahnenstange, vJoy ist nicht in Betrieb
}
// Ermittle den Status vom vJoy Device bevor wir diesen anfordern
VjdStat status = GetVJDStatus(nvJoy1)
AcquireVJD(nvJoy1);
Joystick = SDL_JoystickOpen(nJoystick);
// Initialisier die beiden vJoy
memset(&vJoyReport1, 0, sizeof(vJoyReport1));
vJoyReport1.bDevice = (BYTE)nvJoy1;
while (!done)
{
DWORD dwRet = WaitForMultipleObjects(2, hEvent, FALSE, 10);
// Stoppe den Loop
if (dwRet == WAIT_OBJECT_0)
{
done = SDL_TRUE;
break;
}
SDL_JoystickUpdate();
// Hier kommt Deine Mathe für die Beeinflussung des Leistungshebels
// ich mache hier meine für ein anderes Spiel
vJoyReport1.wAxisZ = (SDL_JoystickGetAxis(Joystick, nThrottle1) + 32768) / 2; // Motor 1
UpdateVJD(nvJoy1, (PVOID)(&vJoyReport1));
}
// Thread soll sich beenden
// bischen aufräumen und fertig
RelinquishVJD(nvJoy1);
if (Joystick)
SDL_JoystickClose(Joystick);
// Schliesse Subsystem und SDL
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
SDL_Quit();
pDialog->SetThreadRunning(false);
return nRetCode;
}
und somit hast Du schon 90% des benötigten Codes. Ein bisschen Feinschliff noch und ab geht die Post.
Leider lässt sich mein Wunsch nur von egosoft erfüllen. Da habe ich deutlich schlechtere Karten
Ahoj
-Uwe