diff options
Diffstat (limited to 'proto-ft/ftnoir_protocol_ft.cpp')
| -rw-r--r-- | proto-ft/ftnoir_protocol_ft.cpp | 43 | 
1 files changed, 28 insertions, 15 deletions
| diff --git a/proto-ft/ftnoir_protocol_ft.cpp b/proto-ft/ftnoir_protocol_ft.cpp index 16a8fbe1..8e5996d8 100644 --- a/proto-ft/ftnoir_protocol_ft.cpp +++ b/proto-ft/ftnoir_protocol_ft.cpp @@ -7,7 +7,6 @@   */  #include "compat/ndebug-guard.hpp" -#include <cassert>  #include "ftnoir_protocol_ft.h"  #include "csv/csv.h" @@ -43,8 +42,9 @@ freetrack::~freetrack()  }  static_assert(sizeof(LONG) == sizeof(std::int32_t), ""); +static_assert(sizeof(LONG) == 4u, ""); -inline void store(float volatile& place, const float value) +never_inline void store(float volatile& place, const float value)  {      union      { @@ -60,17 +60,12 @@ inline void store(float volatile& place, const float value)      (void)InterlockedExchange((LONG volatile*)&place, value_.i32);  } -inline void store(std::int32_t volatile& place, std::int32_t value) +never_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) +never_inline std::int32_t load(std::int32_t volatile& place)  {      return InterlockedCompareExchange((volatile LONG*) &place, 0, 0);  } @@ -103,12 +98,30 @@ void freetrack::pose(const double* headpose)      if (intGameID != id)      {          QString gamename; -        unsigned char table[8] {}; +        union  { +            unsigned char table[8] alignas(alignof(std::int32_t)); +            std::int32_t ints[2]; +        } t; + +        t.ints[0] = 0; t.ints[1] = 0; + +        (void)CSV::getGameData(id, t.table, gamename); -        (void)CSV::getGameData(id, (unsigned char*)table, gamename); +        { +            const std::uintptr_t addr = (std::uintptr_t)(void*)&pMemData->table[0]; +            const std::uintptr_t addr_ = addr & (sizeof(LONG)-1); -        for (unsigned k = 0; k < 8; k++) -            store(pMemData->table[k], table[k]); +            // the data `happens' to be aligned by virtue of element ordering +            // inside FTHeap. there's no deeper reason behind it. + +            if (addr != addr_) +                assert("!unaligned access"); + +            static_assert(sizeof(char[8])/sizeof(LONG) == 2, ""); + +            for (unsigned k = 0; k < 2; k++) +                store(*(std::int32_t volatile*)&pMemData->table_ints[k], t.ints[k]); +        }          store(ft->GameID2, id);          store(data->DataID, 0); @@ -220,8 +233,8 @@ bool freetrack::correct()      store(pMemData->GameID2, 0); -    for (int i = 0; i < 8; i++) -        store(pMemData->table[i], 0); +    for (unsigned k = 0; k < 2; k++) +        store(*(std::int32_t volatile*)&pMemData->table_ints[k], 0);      // more games need the dummy executable than previously thought      if (use_npclient) | 
