Procházet zdrojové kódy

Final controller API changes, with NOLO controllers implemented as functional example (#113)

* Changed OHMD_CONTROLS_FUNCTIONS to OHMD_CONTROLS_HINTS for controller pipeline

* Removed old digital button queue system and implemented NOLO to use the new controller API

* Fixed unittest makefile
TheOnlyJoey před 7 roky
rodič
revize
2a3b34b612

+ 0 - 1
CMakeLists.txt

@@ -24,7 +24,6 @@ set(openhmd_source_files
 	${CMAKE_CURRENT_LIST_DIR}/src/omath.c
 	${CMAKE_CURRENT_LIST_DIR}/src/platform-posix.c
 	${CMAKE_CURRENT_LIST_DIR}/src/fusion.c
-	${CMAKE_CURRENT_LIST_DIR}/src/queue.c
 	${CMAKE_CURRENT_LIST_DIR}/src/shaders.c
 )
 

+ 1 - 15
examples/simple/simple.c

@@ -99,7 +99,6 @@ int main(int argc, char** argv)
 	print_infof(hmd, "right eye aspect:", 1, OHMD_RIGHT_EYE_ASPECT_RATIO);
 	print_infof(hmd, "distortion k:",     6, OHMD_DISTORTION_K);
 	
-	print_infoi(hmd, "digital button count:", 1, OHMD_BUTTON_COUNT);
 	print_infoi(hmd, "control count:   ", 1, OHMD_CONTROL_COUNT);
 
 	int control_count;
@@ -113,7 +112,7 @@ int main(int argc, char** argv)
 	int controls_fn[64];
 	int controls_types[64];
 
-	ohmd_device_geti(hmd, OHMD_CONTROLS_FUNCTIONS, controls_fn);
+	ohmd_device_geti(hmd, OHMD_CONTROLS_HINTS, controls_fn);
 	ohmd_device_geti(hmd, OHMD_CONTROLS_TYPES, controls_types);
 	
 	printf("%-25s", "controls:");
@@ -147,19 +146,6 @@ int main(int argc, char** argv)
 			printf("%f ", control_state[i]);
 		}
 		puts("");
-
-		// handle digital button events
-		print_infoi(hmd, "button event count:", 1, OHMD_BUTTON_EVENT_COUNT);
-		
-		int event_count = 0;
-
-		ohmd_device_geti(hmd, OHMD_BUTTON_EVENT_COUNT, &event_count);
-
-		for(int i = 0; i < event_count; i++){
-			int event[2] = {0, 0};
-			ohmd_device_geti(hmd, OHMD_BUTTON_POP_EVENT, event);
-			printf("button %d: %s", event[0], event[1] == OHMD_BUTTON_DOWN ? "down" : "up");
-		}
 			
 		ohmd_sleep(.01);
 	}

+ 6 - 15
include/openhmd.h

@@ -79,7 +79,7 @@ typedef enum {
 	OHMD_BUTTON_B       = 10,
 	OHMD_BUTTON_X       = 11,
 	OHMD_BUTTON_Y       = 12,
-} ohmd_control_function;
+} ohmd_control_hint;
 
 /** Control type. Indicates whether controls are digital or analog. */
 typedef enum {
@@ -165,28 +165,19 @@ typedef enum {
 	/** int[1] (get, ohmd_geti()): Physical vertical resolution of the device screen. */
 	OHMD_SCREEN_VERTICAL_RESOLUTION       =  1,
 
-	/** int[1] (get, ohmd_geti()): Get number of events waiting in digital input event queue. */
-	OHMD_BUTTON_EVENT_COUNT               =  2,
-	/** int[1] (get, ohmd_geti()): Get if the there was an overflow in the event queue causing events to be dropped. */
-	OHMD_BUTTON_EVENT_OVERFLOW            =  3,
-	/** int[1] (get, ohmd_geti()): Get the number of physical digital input buttons on the device. */
-	OHMD_BUTTON_COUNT                     =  4,
-	/** int[2] (get, ohmd_geti()): Performs an event pop action. Format: [button_index, button_state], where button_state is either OHMD_BUTTON_DOWN or OHMD_BUTTON_UP */
-	OHMD_BUTTON_POP_EVENT                 =  5,
-
 	/** int[1] (get, ohmd_geti()/ohmd_list_geti()): Gets the class of the device. See: ohmd_device_class. */
-	OHMD_DEVICE_CLASS                     =  6,
+	OHMD_DEVICE_CLASS                     =  2,
 	/** int[1] (get, ohmd_geti()/ohmd_list_geti()): Gets the flags of the device. See: ohmd_device_flags. */
-	OHMD_DEVICE_FLAGS                     =  7,
+	OHMD_DEVICE_FLAGS                     =  3,
 
 	/** int[1] (get, ohmd_geti()): Get the number of analog and digital controls of the device. */
-	OHMD_CONTROL_COUNT                    =  8,
+	OHMD_CONTROL_COUNT                    =  4,
 
 	/** int[OHMD_CONTROL_COUNT] (get, ohmd_geti()): Get whether controls are digital or analog. */
-	OHMD_CONTROLS_FUNCTIONS               =  9,
+	OHMD_CONTROLS_HINTS   		          =  5,
 	
 	/** int[OHMD_CONTROL_COUNT] (get, ohmd_geti()): Get what function controls serve. */
-	OHMD_CONTROLS_TYPES                   =  10,
+	OHMD_CONTROLS_TYPES                   =  6,
 } ohmd_int_value;
 
 /** A collection of data information types used for setting information with ohmd_set_data(). */

+ 1 - 2
src/Makefile.am

@@ -10,8 +10,7 @@ libopenhmd_la_SOURCES = \
 	omath.c \
 	platform-posix.c \
 	fusion.c \
-	shaders.c \
-	queue.c
+	shaders.c
 
 libopenhmd_la_LDFLAGS = -no-undefined -version-info 0:0:0
 libopenhmd_la_CPPFLAGS = -fPIC -I$(top_srcdir)/include -Wall

+ 2 - 3
src/drv_dummy/dummy.c

@@ -95,10 +95,9 @@ static ohmd_device* open_device(ohmd_driver* driver, ohmd_device_desc* desc)
 	priv->base.properties.ratio = (1280.0f / 800.0f) / 2.0f;
 	
 	// Some buttons and axes
-	priv->base.properties.digital_button_count = 4;
 	priv->base.properties.control_count = 2;
-	priv->base.properties.controls_functions[0] = OHMD_BUTTON_A;
-	priv->base.properties.controls_functions[1] = OHMD_MENU;
+	priv->base.properties.controls_hints[0] = OHMD_BUTTON_A;
+	priv->base.properties.controls_hints[1] = OHMD_MENU;
 	priv->base.properties.controls_types[0] = OHMD_ANALOG;
 	priv->base.properties.controls_types[1] = OHMD_DIGITAL;
 

+ 42 - 2
src/drv_nolo/nolo.c

@@ -120,6 +120,14 @@ static int getf(ohmd_device* device, ohmd_float_value type, float* out)
 		}
 		break;
 
+	case OHMD_CONTROLS_STATE:
+		if(priv->id > 0) {
+			for (int i = 0; i < 8; i++){
+				out[i] = priv->controller_values[i];
+			}
+		}
+		break;
+
 	default:
 		ohmd_set_error(priv->base.ctx, "invalid type given to getf (%ud)", type);
 		return -1;
@@ -230,11 +238,43 @@ static ohmd_device* open_device(ohmd_driver* driver, ohmd_device_desc* desc)
 	}
 	else if (priv->id == 1) {
 		mNOLO->controller0 = priv;
-		priv->base.properties.digital_button_count = 6;
+		priv->base.properties.control_count = 8;
+		priv->base.properties.controls_hints[0] = OHMD_ANALOG_PRESS;
+		priv->base.properties.controls_hints[1] = OHMD_TRIGGER_CLICK;
+		priv->base.properties.controls_hints[2] = OHMD_MENU;
+		priv->base.properties.controls_hints[3] = OHMD_HOME;
+		priv->base.properties.controls_hints[4] = OHMD_SQUEEZE;
+		priv->base.properties.controls_hints[5] = OHMD_GENERIC; //touching the XY pad
+		priv->base.properties.controls_hints[6] = OHMD_ANALOG_X;
+		priv->base.properties.controls_hints[7] = OHMD_ANALOG_Y;
+		priv->base.properties.controls_types[0] = OHMD_DIGITAL;
+		priv->base.properties.controls_types[1] = OHMD_DIGITAL;
+		priv->base.properties.controls_types[2] = OHMD_DIGITAL;
+		priv->base.properties.controls_types[3] = OHMD_DIGITAL;
+		priv->base.properties.controls_types[4] = OHMD_DIGITAL;
+		priv->base.properties.controls_types[5] = OHMD_DIGITAL;
+		priv->base.properties.controls_types[6] = OHMD_ANALOG;
+		priv->base.properties.controls_types[7] = OHMD_ANALOG;
 	}
 	else if (priv->id == 2) {
 		mNOLO->controller1 = priv;
-		priv->base.properties.digital_button_count = 6;
+		priv->base.properties.control_count = 8;
+		priv->base.properties.controls_hints[0] = OHMD_ANALOG_PRESS;
+		priv->base.properties.controls_hints[1] = OHMD_TRIGGER_CLICK;
+		priv->base.properties.controls_hints[2] = OHMD_MENU;
+		priv->base.properties.controls_hints[3] = OHMD_HOME;
+		priv->base.properties.controls_hints[4] = OHMD_SQUEEZE;
+		priv->base.properties.controls_hints[5] = OHMD_GENERIC; //touching the XY pad
+		priv->base.properties.controls_hints[6] = OHMD_ANALOG_X;
+		priv->base.properties.controls_hints[7] = OHMD_ANALOG_Y;
+		priv->base.properties.controls_types[0] = OHMD_DIGITAL;
+		priv->base.properties.controls_types[1] = OHMD_DIGITAL;
+		priv->base.properties.controls_types[2] = OHMD_DIGITAL;
+		priv->base.properties.controls_types[3] = OHMD_DIGITAL;
+		priv->base.properties.controls_types[4] = OHMD_DIGITAL;
+		priv->base.properties.controls_types[5] = OHMD_DIGITAL;
+		priv->base.properties.controls_types[6] = OHMD_ANALOG;
+		priv->base.properties.controls_types[7] = OHMD_ANALOG;
 	}
 
 	// Set default device properties

+ 1 - 1
src/drv_nolo/nolo.h

@@ -19,7 +19,7 @@ typedef struct {
 
 	hid_device* handle;
 	int id;
-	uint8_t button_state;
+	float controller_values[8];
 } drv_priv;
 
 typedef struct{

+ 7 - 14
src/drv_nolo/packet.c

@@ -98,7 +98,7 @@ void nolo_decode_orientation(const unsigned char* data, quatf* quat)
 
 void nolo_decode_controller(drv_priv* priv, unsigned char* data)
 {
-	uint8_t bit, newbuttonstate;
+	uint8_t bit, buttonstate;
 
 	if (data[0] != 2 || data[1] != 1) {
 	// Unknown version
@@ -117,19 +117,12 @@ void nolo_decode_controller(drv_priv* priv, unsigned char* data)
 	nolo_decode_orientation(data+3+3*2, &orientation);
 
 	//Change button state
-	newbuttonstate = data[3+3*2+4*2];
-	if (priv->button_state != newbuttonstate)
-	{
-		for (bit=0; bit<6; bit++)
-		{
-			if ((priv->button_state & 1<<bit) != (newbuttonstate & 1<<bit))
-			{
-				ohmd_digital_input_event event = { /* button index */ bit, /* button state */ (newbuttonstate & 1<<bit ? OHMD_BUTTON_DOWN : OHMD_BUTTON_UP) };
-				ohmdq_push(priv->base.digital_input_event_queue, &event);
-			}
-		}
-		priv->button_state = newbuttonstate;
-	}
+	buttonstate = data[3+3*2+4*2];
+	for (bit=0; bit<6; bit++)
+		priv->controller_values[bit] = (buttonstate & 1<<bit ? 1 : 0);
+
+	priv->controller_values[6] = data[3+3*2+4*2+2]; //X Pad
+	priv->controller_values[7] = data[3+3*2+4*2+2+1]; //Y Pad
 
 	priv->base.position = position;
 	priv->base.rotation = orientation;

+ 2 - 38
src/openhmd.c

@@ -13,8 +13,6 @@
 #include <string.h>
 #include <stdio.h>
 
-#define DIGITAL_INPUT_EVENT_QUEUE_SIZE 1024
-
 // Running automatic updates at 1000 Hz
 #define AUTOMATIC_UPDATE_SLEEP (1.0 / 1000.0)
 
@@ -214,9 +212,6 @@ ohmd_device* OHMD_APIENTRY ohmd_list_open_device_s(ohmd_context* ctx, int index,
 		device->active_device_idx = ctx->num_active_devices;
 		ctx->active_devices[ctx->num_active_devices++] = device;
 
-		if(device->properties.digital_button_count > 0)
-			device->digital_input_event_queue = ohmdq_create(ctx, sizeof(ohmd_digital_input_event), DIGITAL_INPUT_EVENT_QUEUE_SIZE);
-
 		ohmd_unlock_mutex(ctx->update_mutex);
 
 		if(device->settings.automatic_update)
@@ -246,15 +241,11 @@ int OHMD_APIENTRY ohmd_close_device(ohmd_device* device)
 
 	ohmd_context* ctx = device->ctx;
 	int idx = device->active_device_idx;
-	ohmdq* dinq = device->digital_input_event_queue;
 
 	memmove(ctx->active_devices + idx, ctx->active_devices + idx + 1,
 		sizeof(ohmd_device*) * (ctx->num_active_devices - idx - 1));
 
 	device->close(device);
-	
-	if(dinq)
-		ohmdq_destroy(dinq);
 
 	ctx->num_active_devices--;
 
@@ -441,8 +432,6 @@ int OHMD_APIENTRY ohmd_device_setf(ohmd_device* device, ohmd_float_value type, c
 
 int OHMD_APIENTRY ohmd_device_geti(ohmd_device* device, ohmd_int_value type, int* out)
 {
-	ohmdq* dinq = device->digital_input_event_queue;
-
 	switch(type){
 		case OHMD_SCREEN_HORIZONTAL_RESOLUTION:
 			*out = device->properties.hres;
@@ -451,31 +440,6 @@ int OHMD_APIENTRY ohmd_device_geti(ohmd_device* device, ohmd_int_value type, int
 		case OHMD_SCREEN_VERTICAL_RESOLUTION:
 			*out = device->properties.vres;
 			return OHMD_S_OK;
-
-		case OHMD_BUTTON_EVENT_COUNT:
-			*out = dinq ? (int)ohmdq_get_size(dinq) : 0;
-			return OHMD_S_OK;
-
-		case OHMD_BUTTON_EVENT_OVERFLOW:
-			*out = dinq ? (ohmdq_get_size(dinq) == ohmdq_get_max(dinq)) : 0;
-			return OHMD_S_OK;
-
-		case OHMD_BUTTON_COUNT:
-			*out = device->properties.digital_button_count;
-			return OHMD_S_OK;
-		
-		case OHMD_BUTTON_POP_EVENT: {
-				ohmd_digital_input_event event;
-
-				if(!ohmdq_pop(dinq, &event)){
-					return OHMD_S_INVALID_OPERATION;
-				}
-
-				out[0] = event.idx;
-				out[1] = event.state;
-
-				return OHMD_S_OK;
-			}
 		
 		case OHMD_CONTROL_COUNT:
 			*out = device->properties.control_count;
@@ -485,8 +449,8 @@ int OHMD_APIENTRY ohmd_device_geti(ohmd_device* device, ohmd_int_value type, int
 			memcpy(out, device->properties.controls_types, device->properties.control_count * sizeof(int));
 			return OHMD_S_OK;
 		
-		case OHMD_CONTROLS_FUNCTIONS:
-			memcpy(out, device->properties.controls_functions, device->properties.control_count * sizeof(int));
+		case OHMD_CONTROLS_HINTS:
+			memcpy(out, device->properties.controls_hints, device->properties.control_count * sizeof(int));
 			return OHMD_S_OK;
 
 		default:

+ 1 - 10
src/openhmdi.h

@@ -18,7 +18,6 @@
 #include "openhmd.h"
 #include "omath.h"
 #include "platform.h"
-#include "queue.h"
 
 #define OHMD_MAX_DEVICES 16
 
@@ -46,11 +45,6 @@ typedef struct {
 	ohmd_device_desc devices[OHMD_MAX_DEVICES];
 } ohmd_device_list;
 
-typedef struct {
-	int idx;
-	ohmd_button_state state; 
-} ohmd_digital_input_event;
-
 struct ohmd_driver {
 	void (*get_device_list)(ohmd_driver* driver, ohmd_device_list* list);
 	ohmd_device* (*open_device)(ohmd_driver* driver, ohmd_device_desc* desc);
@@ -61,9 +55,8 @@ struct ohmd_driver {
 typedef struct {
 		int hres;
 		int vres;
-		int digital_button_count;
 		int control_count;
-		int controls_functions[64];
+		int controls_hints[64];
 		int controls_types[64];
 
 		float hsize;
@@ -114,8 +107,6 @@ struct ohmd_device {
 
 	quatf rotation;
 	vec3f position;
-	
-	ohmdq* digital_input_event_queue;
 };
 
 

+ 0 - 97
src/queue.c

@@ -1,97 +0,0 @@
-/*
- * OpenHMD - Free and Open Source API and drivers for immersive technology.
- * Copyright (C) 2016 Fredrik Hultin.
- * Distributed under the Boost 1.0 licence, see LICENSE for full text.
- */
-
-/* Naive Thread Safe Circular Queue Implementation */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "queue.h"
-#include "openhmdi.h"
-
-struct ohmdq {
-	unsigned read_pos;
-	unsigned write_pos;
-	unsigned size;
-	unsigned max;
-	unsigned elem_size;
-	char* elems;
-	ohmd_mutex* mutex;
-};
-
-ohmdq* ohmdq_create(ohmd_context* ctx, unsigned elem_size, unsigned max)
-{
-	ohmdq* me = ohmd_alloc(ctx, sizeof(ohmdq));
-
-	me->elems = ohmd_alloc(ctx, elem_size * max);
-	me->max = max;
-	me->elem_size = elem_size;
-	me->read_pos = 0;
-	me->write_pos = 0;
-	me->size = 0;
-	me->mutex = ohmd_create_mutex(ctx);
-
-	return me;
-}
-
-bool ohmdq_push(ohmdq* me, const void* elem)
-{
-	bool ret = false;
-
-	ohmd_lock_mutex(me->mutex);	
-
-	if(me->size < me->max){
-		memcpy(me->elems + me->write_pos, elem, me->elem_size);
-		me->write_pos = (me->write_pos + me->elem_size) % (me->max * me->elem_size);
-		me->size++;
-		ret = true;
-	}
-
-	ohmd_unlock_mutex(me->mutex);	
-
-	return ret;
-}
-
-bool ohmdq_pop(ohmdq* me, void* out_elem)
-{
-	bool ret = false;
-	
-	ohmd_lock_mutex(me->mutex);	
-
-	if(me->size > 0){
-		memcpy(out_elem, me->elems + me->read_pos, me->elem_size);
-		me->read_pos = (me->read_pos + me->elem_size) % (me->max * me->elem_size);
-		me->size--;
-		ret = true;
-	}
-	
-	ohmd_unlock_mutex(me->mutex);	
-
-	return ret;
-}
-
-unsigned ohmdq_get_size(ohmdq* me)
-{
-	unsigned ret;
-
-	ohmd_lock_mutex(me->mutex);
-	ret = me->size;
-	ohmd_unlock_mutex(me->mutex);
-
-	return ret;
-}
-
-unsigned ohmdq_get_max(ohmdq* me)
-{
-	return me->max;
-}
-
-void ohmdq_destroy(ohmdq* me)
-{
-	free(me->elems);
-	ohmd_destroy_mutex(me->mutex);
-	free(me);
-}

+ 0 - 25
src/queue.h

@@ -1,25 +0,0 @@
-/*
- * OpenHMD - Free and Open Source API and drivers for immersive technology.
- * Copyright (C) 2016 Fredrik Hultin.
- * Distributed under the Boost 1.0 licence, see LICENSE for full text.
- */
-
-/* Naive Thread Safe Circular Queue */
-
-#ifndef OHMDQUEUE_H
-#define OHMDQUEUE_H
-
-#include <stdbool.h>
-
-typedef struct ohmdq ohmdq;
-typedef struct ohmd_context ohmd_context;
-
-ohmdq* ohmdq_create(ohmd_context* ctx, unsigned elem_size, unsigned max);
-void ohmdq_destroy(ohmdq* me);
-
-bool ohmdq_push(ohmdq* me, const void* elem);
-bool ohmdq_pop(ohmdq* me, void* out_elem);
-unsigned ohmdq_get_size(ohmdq* me);
-unsigned ohmdq_get_max(ohmdq* me);
-
-#endif

+ 1 - 1
tests/unittests/Makefile.am

@@ -1,5 +1,5 @@
 bin_PROGRAMS = unittests
 AM_CPPFLAGS = -Wall -Werror -I$(top_srcdir)/include -I$(top_srcdir)/src -DOHMD_STATIC
-unittests_SOURCES = main.c quat.c vec.c highlevel.c queue.c
+unittests_SOURCES = main.c quat.c vec.c highlevel.c
 unittests_LDADD = $(top_builddir)/src/libopenhmd.la -lm
 unittests_LDFLAGS = -static-libtool-libs

+ 0 - 4
tests/unittests/main.c

@@ -38,10 +38,6 @@ int main()
 	Test(test_highlevel_open_close_device);
 	Test(test_highlevel_open_close_many_devices);
 	printf("\n");
-	
-	printf("queue tests\n");
-	Test(test_ohmdq_push_pop);
-	printf("\n");
 
 	printf("all a-ok\n");
 	return 0;

+ 0 - 61
tests/unittests/queue.c

@@ -1,61 +0,0 @@
-/*
- * OpenHMD - Free and Open Source API and drivers for immersive technology.
- * Copyright (C) 2016 Fredrik Hultin.
- * Distributed under the Boost 1.0 licence, see LICENSE for full text.
- */
-
-/* Unit Tests - Queue */
-
-#include "tests.h"
-#include "openhmdi.h"
-
-void test_ohmdq_push_pop()
-{
-	ohmd_context* ctx = ohmd_ctx_create();
-	ohmdq* q = ohmdq_create(ctx, sizeof(int), 10);
-	
-	TAssert(ohmdq_get_max(q) == 10);
-
-	for(int i = 0; i < 10; i++){
-		bool ret = ohmdq_push(q, &i);
-		TAssert(ret);
-	}
-
-	TAssert(ohmdq_get_size(q) == 10);
-	
-	int val = 0;
-	bool ret = ohmdq_push(q, &val);
-	TAssert(!ret);
-
-	for(int i = 0; i < 10; i++){
-		int val = 0;
-		bool ret = ohmdq_pop(q, &val);
-		TAssert(ret);
-		TAssert(val == i);
-	}
-	
-	TAssert(ohmdq_get_size(q) == 0);
-	
-	for(int i = 0; i < 10; i++){
-		bool ret = ohmdq_push(q, &i);
-		TAssert(ret);
-	}
-
-	TAssert(ohmdq_get_size(q) == 10);
-	
-	val = 0;
-	ret = ohmdq_push(q, &val);
-	TAssert(!ret);
-
-	for(int i = 0; i < 10; i++){
-		int val = 0;
-		bool ret = ohmdq_pop(q, &val);
-		TAssert(ret);
-		TAssert(val == i);
-	}
-	
-	TAssert(ohmdq_get_size(q) == 0);
-
-	ohmdq_destroy(q);
-	ohmd_ctx_destroy(ctx);
-}

+ 0 - 3
tests/unittests/tests.h

@@ -44,7 +44,4 @@ void test_oquatf_get_mat4x4();
 void test_highlevel_open_close_device();
 void test_highlevel_open_close_many_devices();
 
-// queue tests
-void test_ohmdq_push_pop();
-
 #endif