summaryrefslogtreecommitdiffhomepage
path: root/proto-wine/ftnoir_protocol_wine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'proto-wine/ftnoir_protocol_wine.cpp')
-rw-r--r--proto-wine/ftnoir_protocol_wine.cpp194
1 files changed, 167 insertions, 27 deletions
diff --git a/proto-wine/ftnoir_protocol_wine.cpp b/proto-wine/ftnoir_protocol_wine.cpp
index 42fb4896..bae02b06 100644
--- a/proto-wine/ftnoir_protocol_wine.cpp
+++ b/proto-wine/ftnoir_protocol_wine.cpp
@@ -1,48 +1,52 @@
#include "ftnoir_protocol_wine.h"
+#include <qprocess.h>
+#ifndef OTR_WINE_NO_WRAPPER
+# include "csv/csv.h"
+#endif
+
+#include <cstring>
+#include <cmath>
+
#include <QString>
-#include <QStringList>
-#include <QCoreApplication>
-#include <string.h>
-#include <math.h>
-#include <sys/mman.h>
-#include <sys/stat.h> /* For mode constants */
-#include <fcntl.h> /* For O_* constants */
-#include "csv/csv.h"
-#include "compat/macros.hpp"
-#include "compat/library-path.hpp"
-
-wine::wine() : lck_shm(WINE_SHM_NAME, WINE_MTX_NAME, sizeof(WineSHM)), shm(NULL), gameid(0)
-{
- if (lck_shm.success()) {
- shm = (WineSHM*) lck_shm.ptr();
- memset(shm, 0, sizeof(*shm));
- }
- static const QString library_path(QCoreApplication::applicationDirPath() + OPENTRACK_LIBRARY_PATH);
- wrapper.setWorkingDirectory(QCoreApplication::applicationDirPath());
- wrapper.start("wine", QStringList() << (library_path + "opentrack-wrapper-wine.exe.so"));
-}
+#include <QDebug>
+
+#include "proton.h"
+
+wine::wine() = default;
wine::~wine()
{
+#ifndef OTR_WINE_NO_WRAPPER
+ bool exit = false;
if (shm) {
shm->stop = true;
- wrapper.waitForFinished(100);
+ exit = wrapper.waitForFinished(100);
+ if (exit)
+ qDebug() << "proto/wine: wrapper exit code" << wrapper.exitCode();
+ }
+ if (!exit)
+ {
+ if (wrapper.state() != QProcess::NotRunning)
+ wrapper.kill();
+ wrapper.waitForFinished(1000);
}
- wrapper.close();
+#endif
//shm_unlink("/" WINE_SHM_NAME);
}
-void wine::pose( const double *headpose )
+void wine::pose(const double *headpose, const double*)
{
if (shm)
{
lck_shm.lock();
for (int i = 3; i < 6; i++)
- shm->data[i] = headpose[i] / (180 / M_PI );
+ shm->data[i] = (headpose[i] * M_PI) / 180;
for (int i = 0; i < 3; i++)
shm->data[i] = headpose[i] * 10;
+#ifndef OTR_WINE_NO_WRAPPER
if (shm->gameid != gameid)
{
+ //qDebug() << "proto/wine: looking up gameData";
QString gamename;
QMutexLocker foo(&game_name_mutex);
/* only EZCA for FSX requires dummy process, and FSX doesn't work on Linux */
@@ -51,16 +55,152 @@ void wine::pose( const double *headpose )
gameid = shm->gameid2 = shm->gameid;
connected_game = gamename;
}
+#endif
lck_shm.unlock();
}
}
module_status wine::initialize()
{
+#ifndef OTR_WINE_NO_WRAPPER
+ static const QString library_path(OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH);
+
+ /////////////////////////
+ // determine wine path //
+ /////////////////////////
+ QString wine_path = "wine";
+
+ if (s.variant_wine) {
+ // NORMAL WINE
+
+ // resolve combo box
+ if (s.wine_select_path().toString() != "WINE") {
+ // if we are not supposed to use system wine then:
+ if (s.wine_select_path().toString() != "CUSTOM") {
+ // if we don't have a custom path then change the wine_path to the path corresponding to the selected version
+ wine_path = s.wine_select_path().toString();
+ }
+ else if (!s.wine_custom_path->isEmpty()) {
+ // if we do have a custom path and it is not empty then
+ wine_path = s.wine_custom_path;
+ }
+ }
+
+ // parse tilde if present
+ if (wine_path[0] == '~')
+ wine_path = qgetenv("HOME") + wine_path.mid(1);
+ }
+ else if (s.variant_proton)
+ {
+ // PROTON
+
+ wine_path = s.proton_path().toString() + "/bin/wine";
+ }
+ qDebug() << "proto/wine: wine_path:" << wine_path;
+
+
+ /////////////////////////////////////
+ // determine environment variables //
+ /////////////////////////////////////
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+
+ // if proton is used setup proton environment
+ if (s.variant_proton)
+ {
+ auto [proton_env, env_error_string, env_success] = make_steam_environ(s.proton_path().toString());
+ env = proton_env;
+
+ if (!env_success)
+ return error(env_error_string);
+ }
+
+ // determine wineprefix
+ if (s.variant_proton && s.variant_proton_steamplay) {
+ // wine prefix is dependend on steam
+
+ if (s.proton_appid == 0)
+ return error(tr("Must specify application id for Proton (Steam Play)"));
+
+ auto [prefix, error_string, success] = make_wineprefix(s.proton_appid);
+ qDebug() << "proto/wine: wineprefix:" << prefix;
+ env.insert("WINEPREFIX", prefix);
+
+ if (!success)
+ return error(error_string);
+ }
+ else {
+ // wine prefix was supplied via path
+
+ QString wineprefix = "";
+
+ // check if prefix was supplied via wine
+ if (s.variant_wine && !s.wineprefix->isEmpty())
+ wineprefix = s.wineprefix;
+
+ // check if prefix was supplied via proton
+ if (s.variant_proton_external && !s.protonprefix->isEmpty())
+ wineprefix = s.protonprefix;
+
+ // check if the user specified a prefix anywhere
+ if (wineprefix.isEmpty())
+ return error(tr("Prefix has not been defined!").arg(wineprefix));
+
+ // handle tilde
+ if (wineprefix[0] == '~')
+ wineprefix = qgetenv("HOME") + wineprefix.mid(1);
+
+ // return error if relative path is given
+ if (wineprefix[0] != '/')
+ return error(tr("Wine prefix must be an absolute path (given '%1')").arg(wineprefix));
+
+ qDebug() << "proto/wine: wineprefix:" << wineprefix;
+
+ env.insert("WINEPREFIX", wineprefix);
+ }
+
+ // ESYNC and FSYNC
+ if (s.esync)
+ env.insert("WINEESYNC", "1");
+ if (s.fsync)
+ env.insert("WINEFSYNC", "1");
+
+ // Headtracking Protocol
+ env.insert("OTR_WINE_PROTO", QString::number(s.protocol+1));
+
+
+ ////////////////////////////////
+ // launch the wrapper program //
+ ////////////////////////////////
+
+ wrapper.setProcessEnvironment(env);
+ wrapper.setWorkingDirectory(OPENTRACK_BASE_PATH);
+ wrapper.start(wine_path, { library_path + "opentrack-wrapper-wine.exe.so" });
+ wrapper.waitForStarted();
+ if (wrapper.state() == QProcess::ProcessState::NotRunning) {
+ return error(tr("Failed to start Wine! Make sure the binary is set correctly."));
+ }
+#endif
+
+ if (lck_shm.success())
+ {
+ shm = (WineSHM*) lck_shm.ptr();
+ memset(shm, 0, sizeof(*shm));
+
+ qDebug() << "proto/wine: shm success";
+
+ // display "waiting for game message" (overwritten once a game is detected)
+#ifndef OTR_WINE_NO_WRAPPER
+ connected_game = "waiting for game...";
+#endif
+ }
+ else {
+ qDebug() << "proto/wine: shm no success";
+ }
+
if (lck_shm.success())
return status_ok();
else
- return error(otr_tr("Can't open shared memory mapping"));
+ return error(tr("Can't open shared memory mapping"));
}
-OPENTRACK_DECLARE_PROTOCOL(wine, FTControls, wineDll)
+OPENTRACK_DECLARE_PROTOCOL(wine, FTControls, wine_metadata)