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");
uint32_t T5_Result
Represents an error code that may be returned by the Tilt Five⢠API.
#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 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.
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 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 t5ReleaseGlasses(T5_Glasses 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 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 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 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.
#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.
constexpr iterator_traits< _InputIterator >::difference_type count(_InputIterator __first, _InputIterator __last, const _Tp &__value)
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...
Client provided information for use with t5CreateGlasses()
const char * applicationId
The application ID.
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.
Gameboard pose information to be retrieved by enumerating the output of t5GetGameboardPoses()
Wand stream configuration.
bool enabled
Enable or disable the entire stream. True = enabled.
T5_Vec2 stick
Stick (X/Y) - Analog, Range [-1.0 - 1.0], 0 = Centered, 1.0 = Top/Right.
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.