diff options
| author | Stanislaw Halik <sthalik@misaki.pl> | 2017-06-18 18:27:49 +0200 | 
|---|---|---|
| committer | Stanislaw Halik <sthalik@misaki.pl> | 2017-06-18 18:48:42 +0200 | 
| commit | e92d209598e115acc9ed7bf90bed61be80238536 (patch) | |
| tree | f50e95f762d4f6844f0b4d5c13f7ffe60a188903 /proto-ft | |
| parent | e88c7b29ea9ec9fcd6ac6b15c965085152100d2e (diff) | |
proto/ft: use explicit atomic load/store
"volatile" is too underspecified.
Also cleanup some old code.
Diffstat (limited to 'proto-ft')
| -rw-r--r-- | proto-ft/ftnoir_protocol_ft.cpp | 131 | ||||
| -rw-r--r-- | proto-ft/ftnoir_protocol_ft.h | 10 | ||||
| -rw-r--r-- | proto-ft/ftnoir_protocol_ft_dialog.cpp | 24 | 
3 files changed, 105 insertions, 60 deletions
diff --git a/proto-ft/ftnoir_protocol_ft.cpp b/proto-ft/ftnoir_protocol_ft.cpp index 2c4a0bd1..16a8fbe1 100644 --- a/proto-ft/ftnoir_protocol_ft.cpp +++ b/proto-ft/ftnoir_protocol_ft.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015 Stanislaw Halik <sthalik@misaki.pl> +/* Copyright (c) 2013-2015, 2017 Stanislaw Halik <sthalik@misaki.pl>   * Copyright (c) 2015 Wim Vriend   *   * Permission to use, copy, modify, and/or distribute this software for any @@ -6,11 +6,16 @@   * copyright notice and this permission notice appear in all copies.   */ +#include "compat/ndebug-guard.hpp" +#include <cassert> +  #include "ftnoir_protocol_ft.h"  #include "csv/csv.h"  #include "opentrack-library-path.h" +#include <atomic>  #include <cmath> +#include <windows.h>  check_for_first_run freetrack::runonce_check = check_for_first_run(); @@ -19,7 +24,7 @@ freetrack::freetrack() :      pMemData((FTHeap*) shm.ptr()),      viewsStart(nullptr),      viewsStop(nullptr), -    intGameID(0) +    intGameID(-1)  {      runonce_check.set_enabled(s.close_protocols_on_exit);      QObject::connect(&s.close_protocols_on_exit, @@ -34,10 +39,42 @@ freetrack::~freetrack()          viewsStop();          FTIRViewsLib.unload();      } -    dummyTrackIR.kill();      dummyTrackIR.close();  } +static_assert(sizeof(LONG) == sizeof(std::int32_t), ""); + +inline void store(float volatile& place, const float value) +{ +    union +    { +        float f32; +        LONG i32 alignas(alignof(float)); +    } value_; + +    value_.f32 = value; + +    static_assert(sizeof(value_) == sizeof(float), ""); +    static_assert(offsetof(decltype(value_), f32) == offsetof(decltype(value_), i32), ""); + +    (void)InterlockedExchange((LONG volatile*)&place, value_.i32); +} + +inline void store(std::int32_t volatile& place, std::int32_t value) +{ +    (void)InterlockedExchange((LONG volatile*) &place, value); +} + +inline void store(std::uint8_t volatile& place, std::uint8_t value) +{ +    (void)InterlockedExchange8((char volatile*) &place, char(value)); +} + +inline std::int32_t load(std::int32_t volatile& place) +{ +    return InterlockedCompareExchange((volatile LONG*) &place, 0, 0); +} +  void freetrack::pose(const double* headpose)  {      const float yaw = -degrees_to_rads(headpose[Yaw]); @@ -50,52 +87,39 @@ void freetrack::pose(const double* headpose)      const bool is_crossing_90 = std::fabs(headpose[Pitch] - 90) < 1e-4;      const float pitch = -degrees_to_rads(is_crossing_90 ? 89.86 : headpose[Pitch]); -    FTHeap* ft = pMemData; -    FTData* data = &ft->data; - -    data->RawX = 0; -    data->RawY = 0; -    data->RawZ = 0; -    data->RawPitch = 0; -    data->RawYaw = 0; -    data->RawRoll = 0; - -    data->X = tx; -    data->Y = ty; -    data->Z = tz; -    data->Yaw = yaw; -    data->Pitch = pitch; -    data->Roll = roll; - -    data->X1 = data->DataID; -    data->X2 = 0; -    data->X3 = 0; -    data->X4 = 0; -    data->Y1 = 0; -    data->Y2 = 0; -    data->Y3 = 0; -    data->Y4 = 0; - -    int32_t id = ft->GameID; +    FTHeap volatile* ft = pMemData; +    FTData volatile* data = &ft->data; + +    store(data->X, tx); +    store(data->Y, ty); +    store(data->Z, tz); + +    store(data->Yaw, yaw); +    store(data->Pitch, pitch); +    store(data->Roll, roll); + +    const std::int32_t id = load(ft->GameID);      if (intGameID != id)      {          QString gamename; -        { -            unsigned char table[8] = { 0,0,0,0, 0,0,0,0 }; +        unsigned char table[8] {}; -            (void) CSV::getGameData(id, table, gamename); +        (void)CSV::getGameData(id, (unsigned char*)table, gamename); + +        for (unsigned k = 0; k < 8; k++) +            store(pMemData->table[k], table[k]); + +        store(ft->GameID2, id); +        store(data->DataID, 0); -            for (int i = 0; i < 8; i++) -                pMemData->table[i] = table[i]; -        } -        ft->GameID2 = id;          intGameID = id; +          QMutexLocker foo(&game_name_mutex);          connected_game = gamename;      } - -    data->DataID += 1; +    else +        (void)InterlockedAdd((LONG volatile*)&data->DataID, 1);  }  float freetrack::degrees_to_rads(double degrees) @@ -130,14 +154,14 @@ void freetrack::start_tirviews()  }  void freetrack::start_dummy() { -    QString program = OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH "TrackIR.exe"; +    static const QString program = OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH "TrackIR.exe";      dummyTrackIR.setProgram("\"" + program + "\"");      dummyTrackIR.start();  }  void freetrack::set_protocols(bool ft, bool npclient)  { -    const QString program_dir = OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH; +    static const QString program_dir = OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH;      // Registry settings (in HK_USER)      QSettings settings_ft("Freetrack", "FreetrackClient"); @@ -178,19 +202,30 @@ bool freetrack::correct()      set_protocols(use_ft, use_npclient); -    if (s.useTIRViews) { +    if (s.useTIRViews && use_npclient)          start_tirviews(); -    } - -    // more games need the dummy executable than previously thought -    start_dummy();      pMemData->data.DataID = 1;      pMemData->data.CamWidth = 100;      pMemData->data.CamHeight = 250; -    pMemData->GameID2 = 0; + +#if 0 +    store(pMemData->data.X1, float(100)); +    store(pMemData->data.Y1, float(200)); +    store(pMemData->data.X2, float(300)); +    store(pMemData->data.Y2, float(200)); +    store(pMemData->data.X3, float(300)); +    store(pMemData->data.Y3, float(100)); +#endif + +    store(pMemData->GameID2, 0); +      for (int i = 0; i < 8; i++) -        pMemData->table[i] = 0; +        store(pMemData->table[i], 0); + +    // more games need the dummy executable than previously thought +    if (use_npclient) +        start_dummy();      return true;  } diff --git a/proto-ft/ftnoir_protocol_ft.h b/proto-ft/ftnoir_protocol_ft.h index e5a63e17..5b8e848f 100644 --- a/proto-ft/ftnoir_protocol_ft.h +++ b/proto-ft/ftnoir_protocol_ft.h @@ -18,12 +18,16 @@  #include <QString>  #include <QMutex>  #include <QMutexLocker> + +#include <cinttypes> +#include "freetrackclient/fttypes.h" +  #include "compat/shm.h"  #include "options/options.hpp" -#include "freetrackclient/fttypes.h" -#include <memory>  #include "mutex.hpp" +#include <memory> +  using namespace options;  struct settings : opts { @@ -54,7 +58,7 @@ public:  private:      settings s;      PortableLockedShm shm; -    FTHeap *pMemData; +    FTHeap volatile *pMemData;      QLibrary FTIRViewsLib;      QProcess dummyTrackIR; diff --git a/proto-ft/ftnoir_protocol_ft_dialog.cpp b/proto-ft/ftnoir_protocol_ft_dialog.cpp index 36846273..5b3ad3b2 100644 --- a/proto-ft/ftnoir_protocol_ft_dialog.cpp +++ b/proto-ft/ftnoir_protocol_ft_dialog.cpp @@ -9,6 +9,7 @@   * copyright notice and this permission notice appear in all copies.             *   */  #include "ftnoir_protocol_ft.h" +#include "opentrack-library-path.h"  #include <QDebug>  #include <QFileDialog> @@ -29,17 +30,17 @@ FTControls::FTControls()      tie_setting(s.intUsedInterface, ui.cbxSelectInterface); -    QFile memhacks_pathname(QCoreApplication::applicationDirPath() + "/TIRViews.dll"); +    static const QFile memhacks_pathname(OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH "TIRViews.dll");      if (!memhacks_pathname.exists()) { -        ui.chkTIRViews->setChecked( false ); -        ui.chkTIRViews->setEnabled ( false ); +        ui.chkTIRViews->setEnabled(false);      }      else { -        ui.chkTIRViews->setEnabled ( true ); +        ui.chkTIRViews->setEnabled(true);      }  } -void FTControls::doOK() { +void FTControls::doOK() +{      s.b->save();      close();  } @@ -49,13 +50,18 @@ void FTControls::doCancel()      close();  } -void FTControls::selectDLL() { -    QString filename = QFileDialog::getOpenFileName( this, tr("Select the desired NPClient DLL"), QCoreApplication::applicationDirPath() + "/NPClient.dll", tr("Dll file (*.dll);;All Files (*)")); +void FTControls::selectDLL() +{ +    QString filename = QFileDialog::getOpenFileName(this, +                                                    tr("Select the desired NPClient DLL"), +                                                    OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH "/NPClient.dll", +                                                    tr("Dll file (*.dll);;All Files (*)")); -    if (! filename.isEmpty() ) { +    if (!filename.isEmpty()) +    {              QSettings node("NaturalPoint", "NATURALPOINT\\NPClient Location");              QFileInfo dllname(filename); -            node.setValue( "Path" , dllname.dir().path() ); +            node.setValue("Path", dllname.dir().path());      }  }  | 
