24#define SLEEP(ms) Sleep(ms)
27#define _POSIX_C_SOURCE 199309L
32 ts.tv_sec = (ms) / 1000; \
33 ts.tv_nsec = (ms) % 1000 * 1000000; \
34 nanosleep(&ts, NULL); \
37#warning Unsupported platform - sleep unavailable, code may run too fast
42#include "include/TiltFiveNative.h"
50#define IDENTIFIER_BUFFER_SIZE 1024
51#define GLASSES_BUFFER_SIZE 1024
52#define PARAM_BUFFER_SIZE 1024
53#define WAND_BUFFER_SIZE 4
55bool checkConnection(
T5_Glasses glassesHandle,
const char*
id) {
63 switch (connectionState) {
65 printf(
"Glasses connection : '%s' -> Connected\n",
id);
69 printf(
"Glasses connection : '%s' -> Reserved\n",
id);
73 printf(
"Glasses connection : '%s' -> Not Connected\n",
id);
77 printf(
"Glasses connection : '%s' -> Device Lost\n",
id);
81 printf(
"Glasses connection : '%s' -> Unexpected state!\n",
id);
87 uint8_t
count = WAND_BUFFER_SIZE;
96 printf(
"Wand list : %u wand(s)\n",
count);
97 for (
int i = 0; i <
count; i++) {
98 printf(
" Wand found : ID=%d\n", wandListBuffer[i]);
113 for (
int i = 0; i < 100; i++) {
124 switch (event.
type) {
126 printf(
"WAND EVENT : CONNECT [%u]\n", event.
wandId);
130 printf(
"WAND EVENT : DISCONNECT [%u]\n", event.
wandId);
134 printf(
"WAND EVENT : DESYNC [%u]\n", event.
wandId);
138 printf(
"WAND EVENT : REPORT [%u] %fx%f\n",
158 switch (gameboardType) {
178 printf(
"Getting some poses");
180 bool waiting =
false;
181 for (
int i = 0; i < 1000; i++) {
186 printf(
"\nWaiting...");
207 printf(
"\nWaiting for gameboard poses...");
225 printf(
"\nGLASSES POSE : [%lu] (Board:%s) "
226 "[%6.4f, %6.4f, %6.4f] [%6.4f, %6.4f, %6.4f, %6.4f]",
237 printf(
"\nPRIMARY GAMEBOARD POSE : [%lu] (Board:%s) "
238 "[%6.4f, %6.4f, %6.4f] [%6.4f, %6.4f, %6.4f, %6.4f]",
239 gameboardPoses[0].timestampNanos,
240 gameboardTypeString(gameboardPoses[0].gameboardType),
241 gameboardPoses[0].posBOARD_STAGE.x,
242 gameboardPoses[0].posBOARD_STAGE.y,
243 gameboardPoses[0].posBOARD_STAGE.z,
244 gameboardPoses[0].rotToBOARD_STAGE.w,
245 gameboardPoses[0].rotToBOARD_STAGE.x,
246 gameboardPoses[0].rotToBOARD_STAGE.y,
247 gameboardPoses[0].rotToBOARD_STAGE.z);
260 printf(
"Watching for changes to settings... (forever)\n");
262 uint16_t
count = PARAM_BUFFER_SIZE;
271 for (
int i = 0; i <
count; i++) {
272 switch (paramBuffer[i]) {
277 printf(
"Error getting changed IPD for '%s' : %s\n",
283 printf(
"IPD changed for '%s' : %f\n",
id, value);
290 glassesHandle, paramBuffer[i], 0, buffer, &bufferSize);
292 printf(
"Error getting changed friendly name for '%s' : %s\n",
298 printf(
"Friendly name changed for '%s' : '%s'\n",
id, buffer);
310void connectGlasses(
T5_Context t5ctx,
const char*
id) {
320 printf(
"Created glasses : '%s'\n",
id);
325 if (!checkConnection(glassesHandle,
id)) {
337 printf(
"Glasses reserved : '%s'\n",
id);
340 if (!checkConnection(glassesHandle,
id)) {
357 printf(
"Glasses ready : '%s'\n",
id);
363 if (!checkConnection(glassesHandle,
id)) {
368 size_t bufferSize = IDENTIFIER_BUFFER_SIZE;
369 char recalledId[IDENTIFIER_BUFFER_SIZE];
374 }
else if (strcmp(
id, recalledId) != 0) {
375 printf(
"Mismatch getting ID for glasses : '%s' -> '%s'\n",
id, recalledId);
377 printf(
"Got ID for glasses : '%s' -> '%s'\n",
id, recalledId);
382 getPoses(glassesHandle);
387 findWands(glassesHandle);
391 if (!checkConnection(glassesHandle,
id)) {
395 printf(
"Glasses ready : '%s'\n",
id);
399 err = endlesslyWatchSettings(glassesHandle,
id);
401 printf(
"Error watching settings for glasses '%s' : %s\n",
id,
t5GetResultMessage(err));
412 if (!checkConnection(glassesHandle,
id)) {
419 findWands(glassesHandle);
424 printf(
"Destroyed glasses : '%s'\n",
id);
427size_t strnlen(
const char* str,
size_t maxLen) {
429 while ((len < maxLen) && (str[len] !=
'\0')) {
435int main(
int argc,
char** argv) {
439 .applicationVersion =
"1.0.0",
447 printf(
"Failed to create context\n");
450 printf(
"Init complete\n");
457 printf(
"Failed to get gameboard size\n");
459 printf(
"LE Gameboard size : %fm x %fm x %fm\n",
468 bool waiting =
false;
475 printf(
"Service version : %s\n", serviceVersion);
481 printf(
"Waiting for service...\n");
493 size_t bufferSize = GLASSES_BUFFER_SIZE;
494 char glassesListBuffer[GLASSES_BUFFER_SIZE];
497 size_t glassesCount = 0;
499 const char* buffPtr = glassesListBuffer;
500 size_t remainingSize = bufferSize;
504 size_t stringLength = strnlen(buffPtr, remainingSize);
505 if (stringLength == 0) {
507 }
else if (stringLength == remainingSize) {
509 printf(
"Warning: list may be missing null terminator");
513 fprintf(stderr,
"Glasses : %s\n", buffPtr);
517 connectGlasses(t5ctx, buffPtr);
521 buffPtr += stringLength + 1;
522 remainingSize -= stringLength + 1;
523 assert(buffPtr <= (glassesListBuffer + bufferSize));
526 printf(
"Listed glasses [%zu found]\n", glassesCount);
532 printf(
"Waiting for service...\n");
545 printf(
"Shutdown complete\n");
constexpr iterator_traits< _InputIterator >::difference_type count(_InputIterator __first, _InputIterator __last, const _Tp &__value)
uint32_t T5_Result
Represents an error code that may be returned by the Tilt Five⢠API.
#define T5_MAX_STRING_PARAM_LEN
The maximum number of characters allowed for string values.
T5_ConnectionState
Glasses connection state.
T5_ParamGlasses
Possible parameters that can be retrieved for glasses.
uint8_t T5_WandHandle
Opaque handle used with wands.
struct T5_ContextImpl * T5_Context
Opaque handle used with system-wide functions.
T5_GameboardType
Possible gameboard types.
struct T5_GlassesImpl * T5_Glasses
Opaque handle used with glasses.
@ kT5_ConnectionState_Disconnected
Glasses were previously exclusively connected, but the device has disconnected.
@ kT5_ConnectionState_ExclusiveConnection
Glasses are connected for exclusive use.
@ kT5_ConnectionState_NotExclusivelyConnected
Glasses have not been exclusively connected or reserved.
@ kT5_ConnectionState_ExclusiveReservation
Glasses are reserved for exclusive use.
@ kT5_ParamGlasses_Float_IPD
Interpupillary distance - Float, millimeters
@ kT5_ParamGlasses_UTF8_FriendlyName
User-facing name of the glasses - UTF8.
@ kT5_ParamSys_UTF8_Service_Version
Version of the service software - UTF8.
@ kT5_GameboardType_LE
An LE gameboard.
@ kT5_GameboardType_XE
An XE gameboard, flap laid flat.
@ kT5_GameboardType_None
No gameboard.
@ kT5_GameboardType_XE_Raised
An XE gameboard, flap raised at an angle on the kickstand.
@ kT5_WandStreamEventType_Connect
Wand connected.
@ kT5_WandStreamEventType_Disconnect
Wand disconnected.
@ kT5_WandStreamEventType_Report
Wand report (Pose, Buttons, Trigger, Stick, Battery)
@ kT5_WandStreamEventType_Desync
Stream has desynchronized.
@ kT5_GlassesPoseUsage_GlassesPresentation
The pose will be used to render images to be presented on the glasses.
T5_EXPORT T5_Result t5CreateContext(T5_Context *context, const T5_ClientInfo *clientInfo, void *platformContext)
Create a context object.
T5_EXPORT void t5DestroyContext(T5_Context *context)
Destroy a context object.
#define T5_ERROR_TRY_AGAIN
Target is not currently available.
#define T5_TIMEOUT
Timeout.
T5_EXPORT const char * t5GetResultMessage(T5_Result result)
#define T5_ERROR_NO_SERVICE
Service isn't connected.
T5_EXPORT T5_Result t5ReleaseGlasses(T5_Glasses glasses)
T5_EXPORT T5_Result t5CreateGlasses(T5_Context context, const char *id, T5_Glasses *glasses)
Create a glasses access object.
T5_EXPORT T5_Result t5GetGameboardSize(T5_Context context, T5_GameboardType gameboardType, T5_GameboardSize *gameboardSize)
Get the gameboard dimensions.
T5_EXPORT void t5DestroyGlasses(T5_Glasses *glasses)
Destroy a glasses object.
T5_EXPORT T5_Result t5ListGlasses(T5_Context context, char *buffer, size_t *bufferSize)
Enumerate all glasses.
T5_EXPORT T5_Result t5GetGameboardPoses(T5_Glasses glasses, T5_GameboardPose *buffer, uint16_t *count)
Get the latest set of gameboard poses.
T5_EXPORT T5_Result t5GetGlassesPose(T5_Glasses glasses, T5_GlassesPoseUsage usage, T5_GlassesPose *pose)
Get the latest pose of the glasses.
T5_EXPORT T5_Result t5GetGlassesConnectionState(T5_Glasses glasses, T5_ConnectionState *connectionState)
Get the exclusivity/connection status of the glasses.
T5_EXPORT T5_Result t5ReserveGlasses(T5_Glasses glasses, const char *displayName)
Reserve glasses for exclusive operations by the client.
T5_EXPORT T5_Result t5GetGlassesIdentifier(T5_Glasses glasses, char *buffer, size_t *bufferSize)
Get the device identifier of a glasses.
T5_EXPORT T5_Result t5EnsureGlassesReady(T5_Glasses glasses)
Ensure that reserved glasses are ready for exclusive operations.
T5_EXPORT T5_Result t5GetGlassesFloatParam(T5_Glasses glasses, T5_WandHandle wand, T5_ParamGlasses param, double *value)
Get a glasses floating point parameter.
T5_EXPORT T5_Result t5GetGlassesUtf8Param(T5_Glasses glasses, T5_WandHandle wand, T5_ParamGlasses param, char *buffer, size_t *bufferSize)
Get a glasses UTF-8 encoded string parameter.
T5_EXPORT T5_Result t5GetChangedGlassesParams(T5_Glasses glasses, T5_ParamGlasses *buffer, uint16_t *count)
Get a glasses-specific list of changed parameters.
T5_EXPORT T5_Result t5GetSystemUtf8Param(T5_Context context, T5_ParamSys param, char *buffer, size_t *bufferSize)
Get a system-wide UTF-8 encoded string parameter.
T5_EXPORT T5_Result t5ReadWandStreamForGlasses(T5_Glasses glasses, T5_WandStreamEvent *event, uint32_t timeoutMs)
Read from the wands event stream.
T5_EXPORT T5_Result t5ListWandsForGlasses(T5_Glasses glasses, T5_WandHandle *buffer, uint8_t *count)
List available wands connected to this glasses.
T5_EXPORT T5_Result t5ConfigureWandStreamForGlasses(T5_Glasses glasses, const T5_WandStreamConfig *config)
Configure the wand event stream.
Client provided information for use with t5CreateGlasses()
const char * applicationId
The application ID.
Gameboard pose information to be retrieved by enumerating the output of t5GetGameboardPoses()
Physical dimensions of a gameboard.
float viewableExtentNegativeY
The distance in meters from the gameboard origin to the edge of the viewable area in the negative Y d...
float viewableExtentPositiveZ
The distance in meters above the gameboard origin that the viewable area extends in the positive Z di...
float viewableExtentPositiveY
The distance in meters from the gameboard origin to the edge of the viewable area in the positive Y d...
float viewableExtentNegativeX
The distance in meters from the gameboard origin to the edge of the viewable area in the negative X d...
float viewableExtentPositiveX
The distance in meters from the gameboard origin to the edge of the viewable area in the positive X d...
Glasses pose information to be retrieved with t5GetGlassesPose()
uint64_t timestampNanos
The timestamp of the pose.
T5_GameboardType gameboardType
The type of gameboard visible for this pose.
T5_Quat rotToGLS_STAGE
The rotation that transforms points in the STAGE frame orientation to the GLS (glasses) frame orienta...
T5_Vec3 posGLS_STAGE
The position of the origin of the GLS (glasses) frame relative to the STAGE frame.
T5_Vec2 stick
Stick (X/Y) - Analog, Range [-1.0 - 1.0], 0 = Centered, 1.0 = Top/Right.
Wand stream configuration.
bool enabled
Enable or disable the entire stream. True = enabled.
Represents an event from the wand stream.
T5_WandReport report
Report (Valid if type = kT5_WandStreamEventType_Report)
T5_WandStreamEventType type
Type of event.
T5_WandHandle wandId
Opaque identifier for the wand.