--- /dev/null
+COMP = gcc
+RM = rm -f
+# VERSION = 3
+OBJS = obj/shapes.o obj/display.o obj/params.o obj/vtplayer-ctrl.o obj/evenements.o obj/icons.o obj/divers.o obj/guidance.o
+LIBS = -lSDL -lGL -lGLU -lusb
+# -lefence
+# export EF_ALLOW_MALLOC_0=1
+FLAGS = -Wall -g -DDEBUG
+# -DWITHOUTVTP
+CFLAGS = $(FLAGS) -Iinclude/
+TARGET = bin/shapes
+TAR = shapes
+REPARCHIVE = shapes-vtp
+
+all :$(TARGET)
+
+$(TARGET) : $(OBJS)
+ $(COMP) $(CFLAGS) -o $@ $^ $(LIBS)
+
+clean :
+ $(RM) $(OBJS)
+
+mrproper :
+ $(RM) $(OBJS) $(TARGET) $(TARGETDEMO)
+
+tar:
+ mkdir $(REPARCHIVE)
+ mkdir $(REPARCHIVE)/src
+ mkdir $(REPARCHIVE)/include
+ mkdir $(REPARCHIVE)/data
+ mkdir $(REPARCHIVE)/bin
+ cp Makefile* $(REPARCHIVE)/
+ cp data/shape* $(REPARCHIVE)/data
+ cp data/params $(REPARCHIVE)/data
+ cp $(TARGET) $(REPARCHIVE)/bin
+ cp $(TARGET).exe $(REPARCHIVE)/bin
+ cp src/*.c $(REPARCHIVE)/src
+ cp include/*.h $(REPARCHIVE)/include
+ tar -cvzf $(TAR).tar.gz $(REPARCHIVE)
+ rm -rf $(REPARCHIVE)
+
+obj/shapes.o : src/shapes.c
+ $(COMP) $(CFLAGS) -o $@ -c $<
+
+obj/%.o : src/%.c include/%.h
+ $(COMP) $(CFLAGS) -o $@ -c $<
--- /dev/null
+COMP = i586-mingw32msvc-gcc -mwindows -Dmain=SDLmain
+RM = rm -f
+# VERSION = 3
+OBJS = obj/shapes.o obj/display.o obj/params.o obj/vtplayer-ctrl.o obj/evenements.o obj/icons.o obj/divers.o obj/guidance.o obj/gettimeofday.o
+LIBS = -lusb -mwindows -lmingw32 -lSDLmain -lSDL -lopengl32 -lglu32
+FLAGS = -Wall
+CFLAGS = $(FLAGS) -Iinclude/
+TARGET = bin/shapes.exe
+
+all : $(TARGET)
+
+$(TARGET) : $(OBJS)
+ $(COMP) $(CFLAGS) -o $@ $^ $(LIBS)
+
+clean :
+ $(RM) $(OBJS)
+
+mrproper :
+ $(RM) $(OBJS) $(TARGET)
+
+zipwin:
+ zip shapes.zip $(TARGET) data/* bin/*.dll
+
+obj/shapes.o : src/shapes.c
+ $(COMP) $(CFLAGS) -o $@ -c $<
+
+obj/%.o : src/%.c include/%.h
+ $(COMP) $(CFLAGS) -o $@ -c $<
--- /dev/null
+#ifndef __CONTROL_REQUEST_H__
+#define __CONTROL_REQUEST_H__
+
+/*-------------------------------------------------------------------------*/
+
+/* CONTROL REQUEST SUPPORT */
+
+/*
+ * USB directions
+ *
+ * This bit flag is used in endpoint descriptors' bEndpointAddress field.
+ * It's also one of three fields in control requests bRequestType.
+ */
+#define USB_DIR_OUT 0 /* to device */
+#define USB_DIR_IN 0x80 /* to host */
+
+/*
+ * USB types, the second of three bRequestType fields
+ */
+#define USB_TYPE_MASK (0x03 << 5)
+#define USB_TYPE_STANDARD (0x00 << 5)
+#define USB_TYPE_CLASS (0x01 << 5)
+#define USB_TYPE_VENDOR (0x02 << 5)
+#define USB_TYPE_RESERVED (0x03 << 5)
+
+/*
+ * USB recipients, the third of three bRequestType fields
+ */
+#define USB_RECIP_MASK 0x1f
+#define USB_RECIP_DEVICE 0x00
+#define USB_RECIP_INTERFACE 0x01
+#define USB_RECIP_ENDPOINT 0x02
+#define USB_RECIP_OTHER 0x03
+
+/*
+ * Standard requests, for the bRequest field of a SETUP packet.
+ *
+ * These are qualified by the bRequestType field, so that for example
+ * TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved
+ * by a GET_STATUS request.
+ */
+#define USB_REQ_GET_STATUS 0x00
+#define USB_REQ_CLEAR_FEATURE 0x01
+#define USB_REQ_SET_FEATURE 0x03
+#define USB_REQ_SET_ADDRESS 0x05
+#define USB_REQ_GET_DESCRIPTOR 0x06
+#define USB_REQ_SET_DESCRIPTOR 0x07
+#define USB_REQ_GET_CONFIGURATION 0x08
+#define USB_REQ_SET_CONFIGURATION 0x09
+#define USB_REQ_GET_INTERFACE 0x0A
+#define USB_REQ_SET_INTERFACE 0x0B
+#define USB_REQ_SYNCH_FRAME 0x0C
+
+/*
+ * USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and
+ * are read as a bit array returned by USB_REQ_GET_STATUS. (So there
+ * are at most sixteen features of each type.)
+ */
+#define USB_DEVICE_SELF_POWERED 0 /* (read only) */
+#define USB_DEVICE_REMOTE_WAKEUP 1 /* dev may initiate wakeup */
+#define USB_DEVICE_TEST_MODE 2 /* (high speed only) */
+#define USB_DEVICE_B_HNP_ENABLE 3 /* dev may initiate HNP */
+#define USB_DEVICE_A_HNP_SUPPORT 4 /* RH port supports HNP */
+#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /* other RH port does */
+#define USB_DEVICE_DEBUG_MODE 6 /* (special devices only) */
+
+#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
+
+#endif
--- /dev/null
+#ifndef __DISPLAY__
+#define __DISPLAY__
+#include <SDL/SDL.h>
+#include "vtplayer-ctrl.h"
+
+int setup_opengl();
+
+void draw_screen();
+
+// void load_cursor(char *name);
+// void draw_cursor(int mousex, int mousey);
+void draw_configuration(u32 config, int mousex, int mousey);
+
+int get_x_from_screen(int x);
+int get_y_from_screen(int y);
+int get_x_from_opengl(int x);
+int get_y_from_opengl(int y);
+
+#endif
--- /dev/null
+#ifndef __DIVERS__
+#define __DIVERS__
+
+#define NULLE_PART -1
+#define HAUT 0
+#define HAUT_DROITE 1
+#define DROITE 2
+#define BAS_DROITE 3
+#define BAS 4
+#define BAS_GAUCHE 5
+#define GAUCHE 6
+#define HAUT_GAUCHE 7
+#define CENTRE 8
+
+#ifdef __linux__
+#include <sys/types.h>
+#include <sys/stat.h>
+#define MKDIR(r) mkdir(r,0777)
+#else
+#include <io.h>
+#define MKDIR(r) mkdir(r)
+#endif
+
+#define BUFFERSIZE 256
+
+#define CONDITION_PT 0
+#define CONDITION_PV 1
+#define CONDITION_MT 2
+#define CONDITION_MV 3
+
+int fileExists(char *f);
+
+#endif
--- /dev/null
+#include <SDL/SDL.h>
+#include <SDL/SDL_ttf.h>
+
+#ifndef __ECRIRE__
+#define __ECRIRE__
+
+typedef struct text_t
+{
+ unsigned int texnum;
+ SDL_Surface *pixels;
+ SDL_Color color;
+ int h, w;
+} Text;
+
+/*void vTexte(char *message, short x, short y, char *font_face="./police.ttf", short font_size=16, Uint32 iColor=0, bool shaded=false, Uint32 iColorShaded=0);*/
+Text *SDL_GL_RenderText(char *text,
+ TTF_Font *font,
+ SDL_Color color);
+
+void drawText(Text, SDL_Rect *location);
+
+void freeText(Text *);
+int load_fonts();
+
+#endif
--- /dev/null
+#ifndef __EVTS__
+#define __EVTS__
+
+#include <SDL/SDL.h>
+
+struct mouse_status_t
+{
+ int x, y, b[4];//, min_screen_x, min_screen_y, max_screen_x, max_screen_y;
+ double vtpx, vtpy;
+} mouse_status;
+
+typedef struct events_t {
+ int symbol, buttons;
+} events_t;
+
+int get_mouse_x();
+int get_mouse_y();
+int get_vtp_x();
+int get_vtp_y();
+int get_mouse_b(int i);
+int get_mouse_any_button();
+/*void set_min_screen_x(int x);
+void set_min_screen_y(int y);
+void set_max_screen_x(int x);
+void set_max_screen_y(int y);*/
+events_t process_events();
+SDL_Thread *create_mouse_status_thread();
+
+#endif
--- /dev/null
+#ifndef __GETTIMEOFDAY__
+#define __GETTIMEOFDAY__
+#include <sys/time.h>
+
+int gettimeofday (struct timeval *tv, void *tz);
+int diff_time (struct timeval *debut, int precision);
+
+#endif
--- /dev/null
+#ifndef __GUIDANCE__
+#define __GUIDANCE__
+
+typedef struct shape_t
+{
+ int nbv;
+ int *x, *y;
+}shape_type;
+
+int load_shape(char *name);
+void unload_shape();
+
+void draw_shape();
+
+int get_direction(int posx, int posy);
+
+#endif
--- /dev/null
+#ifndef __ICONS__
+#define __ICONS__
+
+#include "../include/vtplayer-ctrl.h"
+
+SDL_Thread *create_tacton_thread();
+SDL_Thread *create_pins_thread();
+SDL_Thread *create_translation_thread();
+// void load_set();
+u32 get_tacton();
+
+#endif
--- /dev/null
+#ifndef __INSTRUCTIONS__
+#define __INSTRUCTIONS__
+
+void instructions(TTF_Font *font, int *pinsconfig, int min_ecran_x, int min_ecran_y, int max_ecran_x, int max_ecran_y );
+
+#endif
--- /dev/null
+#ifndef __PARAMS__
+#define __PARAMS__
+
+#include <stdlib.h>
+
+typedef struct param_list_type
+{
+ char *name;
+ char *value;
+ struct param_list_type *next;
+} param_list;
+
+//reads parameters from file
+void read_file_params();
+
+//reads parameters from command line
+int read_command_params(int argc, char *argv[]);
+
+//add parameters directly
+void add_param(char *name, char *value);
+
+//get one of the parameters value
+char *get_params(char *name);
+
+//get one of the parameters value
+void display_params();
+
+void delete_params(param_list *l);
+
+#endif
+
--- /dev/null
+#ifndef __VTPLAYER__
+#define __VTPLAYER__
+
+typedef unsigned char u8;
+typedef unsigned short int u16;
+typedef unsigned long int u32;
+
+// Initialisation de la VTplayer en scannant
+// les périphériques USB notament
+// retourne 1 si il y a eu une erreur, 0 sinon
+int init_vtplayer(void);
+
+/* "affiche" une configuration sur les pads
+ numérotation b32...b1 :
+ +----+----+----+----+ +----+----+----+----+
+ | 1 | 2 | 3 | 4 | | 17 | 18 | 19 | 20 |
+ +----+----+----+----+ +----+----+----+----+
+ | 5 | 6 | 7 | 8 | | 21 | 22 | 23 | 24 |
+ +----+----+----+----+ +----+----+----+----+
+ | 9 | 10 | 11 | 12 | | 25 | 26 | 27 | 28 |
+ +----+----+----+----+ +----+----+----+----+
+ | 13 | 14 | 15 | 16 | | 29 | 30 | 31 | 32 |
+ +----+----+----+----+ +----+----+----+----+
+*/
+
+int release_vtplayer(void)
+
+int set_pads(u32 pads);
+
+/* retourne le mouvement en x,y et les boutons enfoncés
+ - le premier octet contient le mouvement en x
+ - le deuxième octet contient le mouvement en y
+ - le troisième octet n'est pas utilisé
+ - le quatrième octet contient les boutons enfoncés (de 1 à 4)
+*/
+int get_status(u8 * data);
+
+#endif
--- /dev/null
+#!/bin/bash
+NBCONDITIONS=2
+NBPERSERIES=11
+NBSHAPES=29
+
+if [ $# -le $NBCONDITIONS ] ; then
+ echo "Usage : $0 name Condition1 Condition2 Condition 3 Condition4";
+ echo " Condition = PT | Pv | Mt | Mv";
+ exit;
+fi
+
+# shapes=(`seq 1 1 $NBSHAPES`)
+for n in `seq 0 1 $[$NBSHAPES - 1]` ; do
+ shapes[$n]=0;
+done
+
+for i in `seq 2 1 $[$NBCONDITIONS + 1]` ; do
+ #generate series for condition i
+ for j in `seq 1 1 $NBPERSERIES` ; do
+ numcircuit=$RANDOM;
+ let "numcircuit %= $NBSHAPES"
+ while [ ${shapes[$numcircuit]} -eq 1 ] ; do
+ numcircuit=$RANDOM;
+ let "numcircuit %= $NBSHAPES"
+ done
+ if [ $j -le 1 ] ; then
+ echo "sudo xinit ./bin/shapes -name $1 -condition ${!i} -shape shape$[$numcircuit + 1] -training yes -- :1 -ac -xf86config ./xorgmono.conf"
+# echo "sudo ./bin/shapes -name $1 -condition ${!i} -training yes -shape shape$[$numcircuit + 1]";
+ else
+ echo "sudo xinit ./bin/shapes -name $1 -condition ${!i} -shape shape$[$numcircuit + 1] -- :1 -ac -xf86config ./xorgmono.conf"
+# echo "sudo ./bin/shapes -name $1 -condition ${!i} -shape shape$[$numcircuit + 1]";
+ fi
+# ./bin/shapes -name $1 -condition ${!i} -shape shape$[$numcircuit + 1];
+ shapes[numcircuit]=1;
+ done
+done
+# ${shapes[$numcircuit]}
--- /dev/null
+#include <SDL/SDL.h>
+#include <SDL/SDL_image.h>
+#include <SDL/SDL_opengl.h>
+#include <SDL/SDL_ttf.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+
+#include "display.h"
+#include "evenements.h"
+#include "divers.h"
+#include "guidance.h"
+#include "params.h"
+#include "icons.h"
+
+#ifdef DEBUG
+#define dprintf(x...) printf(x)
+#else
+#define dprintf(x...)
+#endif
+
+#define COLOR_FOND 1.0, 1.0, 1.0
+
+SDL_Surface *screen = NULL;
+// SDL_Surface *cursor = NULL;
+unsigned int cursortexture;
+const SDL_VideoInfo *info;
+int max_screen_x;
+int min_screen_x;
+int max_screen_y;
+int min_screen_y;
+int resol_x;
+int resol_y;
+extern u32 tacton;
+extern int condition;
+extern int left_handed;
+
+int setup_opengl()
+{
+ dprintf("List video modes\n");
+ SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE);
+ if (modes == NULL)
+ {
+ printf("Impossible to find the screen resolution!\n");
+ return 1;
+ }
+ else if (modes == (SDL_Rect **)-1)
+ {
+ resol_x = 1024;
+ resol_y = 768;
+ }
+ else
+ {
+ resol_x = modes[0]->w;
+ resol_y = modes[0]->h;
+ }
+ dprintf("Resolution choosen: %dx%d\n", resol_x, resol_y);
+ max_screen_x = (int)(500 *((float) resol_x) / ((float) resol_y));
+ min_screen_x = - max_screen_x;
+ max_screen_y = 500;
+ min_screen_y = - max_screen_y;
+
+ dprintf("Init SDL subsystem\n");
+ if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
+ {
+ printf("Couldn't initialise Video SubSystem: %s\n", SDL_GetError());
+ return 1;
+ }
+
+ dprintf("Init GL Attributes\n");
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 8);
+
+ int flags = SDL_OPENGLBLIT | SDL_HWSURFACE | SDL_FULLSCREEN;
+ dprintf("Set video mode %dx%d %08x\n", resol_x, resol_y, flags);
+ //this appears to cause the segfault at the end of the program
+ screen = SDL_SetVideoMode(resol_x, resol_y, 0, flags);
+
+ if (!screen)
+ {
+ printf("Impossible de changer le mode video : %s\n", SDL_GetError());
+ return 1;
+ }
+
+// SDL_LockSurface(screen);
+ GLdouble ratio = (GLdouble) screen->w / screen->h;
+ printf("infos : %08x %d %d %d\n", screen->flags, screen->w, screen->h, screen->pitch);
+ printf("Video resolution: %dx%dx%d (ratio = %3.2f)\n", screen->w, screen->h, screen->format->BitsPerPixel, ratio);
+// SDL_UnlockSurface(screen);
+
+ printf("OpenGL infos\n");
+ printf("------------\n");
+ printf("Vendor : %s\n", glGetString(GL_VENDOR));
+ printf("Renderer : %s\n", glGetString(GL_RENDERER));
+ printf("Version : %s\n", glGetString(GL_VERSION));
+ printf("Extensions: %s\n", glGetString(GL_EXTENSIONS));
+
+ glClearColor(COLOR_FOND, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ dprintf("Setting viewport\n");
+ glViewport(0, 0, resol_x, resol_y);
+ switch(glGetError())
+ {
+ case GL_INVALID_VALUE:
+ printf("Wrong resolution\n");
+ return 1;
+ case GL_INVALID_OPERATION:
+ printf("Check the position of the glViewport instruction\n");
+ return 1;
+ }
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ dprintf("Setting projection\n");
+ gluOrtho2D(0, resol_x, resol_y, 0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ return 0;
+}
+
+void draw_screen()
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ //draws the shape
+ draw_shape();
+
+ //draws the cursor
+ switch (condition)
+ {
+ case CONDITION_PV:
+ draw_configuration(get_tacton(), get_mouse_x(), get_mouse_y());
+ break;
+ case CONDITION_MV:
+ draw_configuration(get_tacton(), get_vtp_x(), get_vtp_y());
+ break;
+ case CONDITION_PT:
+ draw_configuration(get_tacton(), get_mouse_x(), get_mouse_y());
+ break;
+ case CONDITION_MT:
+ draw_configuration(get_tacton(), get_vtp_x(), get_vtp_y());
+ break;
+ }
+ SDL_GL_SwapBuffers();
+}
+
+#if 0
+void load_cursor(char *name)
+{
+ cursor = IMG_Load (name);
+ if (cursor)
+ {
+ glGenTextures (1, &cursortexture);
+ glBindTexture (GL_TEXTURE_2D, cursortexture);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ SDL_Surface *temp = NULL;
+ SDL_PixelFormat format = {NULL, 32, 4, 0, 0, 0, 0, 0, 8, 16, 24, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000, 0, 255};
+ switch(cursor->format->BitsPerPixel)
+ {
+ case 24:
+ //convert to 32bits
+ temp = SDL_ConvertSurface(cursor, &format, SDL_SWSURFACE);
+ SDL_FreeSurface(cursor);
+ cursor = temp;
+ gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, cursor->w, cursor->h, GL_RGB, GL_UNSIGNED_BYTE, cursor->pixels);
+ break;
+ case 32:
+ //convert if it's ABGR
+ if (cursor->format->Rshift > cursor->format->Bshift)
+ {
+ temp = SDL_ConvertSurface(cursor, &format, SDL_SWSURFACE);
+ SDL_FreeSurface(cursor);
+ cursor = temp;
+ }
+ break;
+ }
+ gluBuild2DMipmaps(GL_TEXTURE_2D, 4, cursor->w, cursor->h, GL_RGBA, GL_UNSIGNED_BYTE, cursor->pixels);
+ }
+}
+
+void draw_cursor(int mousex, int mousey)
+{
+ if (cursor)
+ {
+ glEnable(GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_TEXTURE_2D);
+ glColor3d(1.0, 1.0, 1.0);
+ glBindTexture(GL_TEXTURE_2D, cursortexture);
+ glBegin(GL_QUADS);
+ glTexCoord2d(0,0) ; glVertex2d(mousex - 15, mousey - 15);
+ glTexCoord2d(1,0) ; glVertex2d(mousex + 15, mousey - 15);
+ glTexCoord2d(1,1) ; glVertex2d(mousex + 15, mousey + 15);
+ glTexCoord2d(0,1) ; glVertex2d(mousex - 15, mousey + 15);
+ glEnd();
+ glDisable(GL_TEXTURE_2D);
+// glColor3d(1.0, 1.0, 1.0);
+ }
+ else
+ {
+ glDisable(GL_BLEND);
+ glBegin(GL_LINES);
+ glColor3d(1.0, 0.5, 0.5);
+ glVertex2d(mousex - 10, mousey);
+ glVertex2d(mousex + 10, mousey);
+ glVertex2d(mousex, mousey-10);
+ glVertex2d(mousex, mousey+10);
+ glEnd();
+ glBegin(GL_POLYGON);
+ glColor3d(0.0, 0.0, 0.0);
+ glVertex2d(mousex - 7, mousey - 7);
+ glVertex2d(mousex + 7, mousey - 7);
+ glVertex2d(mousex + 7, mousey + 7);
+ glVertex2d(mousex - 7, mousey + 7);
+ glEnd();
+ /* glBegin(GL_POLYGON);
+ glColor3d(1.0, 1.0, 1.0);
+ glVertex2d(mousex - 5, mousey - 5);
+ glVertex2d(mousex + 5, mousey - 5);
+ glVertex2d(mousex + 5, mousey + 5);
+ glVertex2d(mousex - 5, mousey + 5);
+ glEnd();*/
+ glEnable(GL_BLEND);
+ }
+}
+#endif
+
+void draw_configuration(u32 config, int mousex, int mousey)
+{
+ glDisable(GL_BLEND);
+ int i, j;
+ for (i = 0 ; i < 4 ; i++)
+ {
+ for (j = 0 ; j < 4 ; j++)
+ {
+ glBegin(GL_POLYGON);
+ switch (condition)
+ {
+ case CONDITION_MV: case CONDITION_PV:
+ if (0x00000001 & config >> (i + 4 * j))
+ glColor3d(0.0, 0.0, 0.0);
+ else if ((0x00010000 & config >> (i + 4 * j)))
+ glColor3d(1.0, 0.0, 0.0);
+ else
+ glColor3d(0.8, 0.8, 0.8);
+ break;
+ case CONDITION_MT: case CONDITION_PT:
+ if (0x00000001 & config >> (i + 4 * j))
+ glColor3d(0.0, 0.0, 0.0);
+ else if ((0x00010000 & config >> (i + 4 * j)))
+ glColor3d(1.0, 0.0, 0.0);
+ else
+ glColor3d(0.8, 0.8, 0.8);
+ break;
+ }
+ glVertex2d(mousex - 10 + 5 * i, mousey - 10 + 5 * j);
+ glVertex2d(mousex - 4 + 5 * i, mousey - 10 + 5 * j);
+ glVertex2d(mousex - 4 + 5 * i, mousey - 5 + 5 * j);
+ glVertex2d(mousex - 10 + 5 * i, mousey - 5 + 5 * j);
+ glEnd();
+ }
+ glBegin(GL_LINE_LOOP);
+ glColor3d(0.0, 0.0, 0.0);
+ glVertex2d(mousex - 10, mousey - 10);
+ glVertex2d(mousex + 10, mousey - 10);
+ glVertex2d(mousex + 10, mousey + 10);
+ glVertex2d(mousex - 10, mousey + 10);
+ glEnd();
+ }
+ glEnable(GL_BLEND);
+}
+
+//translate the x coordinate from screen position to opengl surface
+int get_x_from_screen(int x)
+{
+ return (x * (max_screen_x - min_screen_x)) / resol_x + min_screen_x;
+}
+
+//translate the y coordinate from screen position to opengl surface
+int get_y_from_screen(int y)
+{
+ return (y * (max_screen_y - min_screen_y)) / resol_y + min_screen_y;
+}
+
+//translate the x coordinate from opengl surface to screen position
+int get_x_from_opengl(int x)
+{
+ return ((x - min_screen_x) * resol_x) / (max_screen_x - min_screen_x);
+}
+
+//translate the y coordinate from opengl surface to screen position
+int get_y_from_opengl(int y)
+{
+ return resol_y - ((y - min_screen_y) * resol_y) / (max_screen_y - min_screen_y);
+}
--- /dev/null
+#include "divers.h"
+
+#include <stdio.h>
+
+int fileExists(char *f)
+{
+ FILE *file;
+ if ((file = fopen(f, "rb")) != NULL)
+ {
+ fclose(file);
+ return 1;
+ }
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <SDL/SDL.h>
+#include <SDL/SDL_ttf.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <math.h>
+#include "ecrire.h"
+#include "divers.h"
+
+//on définit un décalage des polices. Bizarrement sous windows et linux il n'y a pas les mêmes
+//tailles pour les surfaces de rendu.
+#ifdef WIN32
+ #define TEXTSHIFT 8
+#else
+ #define TEXTSHIFT 0
+#endif
+
+SDL_Surface *text;
+TTF_Font *font, *fontsmall;
+
+//un chouilla pompé sur
+//http://64.233.183.104/search?q=cache:KPK8UvSs0_MJ:www.gamedev.net/community/forums/topic.asp%3Ftopic_id%3D284259+SDL_TTF+opengl&hl=en&client=firefox
+int arrondit(double x)
+{
+ return (int)(x + 0.5);
+}
+int nextpoweroftwo(int x)
+{
+ double logbase2 = log(x) / log(2);
+ return arrondit(pow(2,ceil(logbase2)));
+}
+
+//c'est notre fonction qui affiche un, texte
+Text *SDL_GL_RenderText(char *text, TTF_Font *font, SDL_Color color/*, SDL_Rect *location*/)
+{
+ //on va avoir besoin de quelques surfaces
+ SDL_Surface *initial;
+ SDL_Surface *intermediary;
+ //les tailles du texte
+ int w,h;
+ //la texture où on va mettre le texte
+ GLuint texture;
+ Text *t = (Text *) malloc(sizeof(Text));
+
+ //on veut écrire en blanc sur noir dansun premier temps
+ SDL_Color color2;
+ color2.r = 255;
+ color2.g = 255;
+ color2.b = 255;
+
+ //on écrit le texte sur la premi�re surface
+ if ((initial = TTF_RenderText_Blended(font, text, color2)) == NULL)
+ {
+ free(t);
+ return NULL;
+ }
+// if ((initial = TTF_RenderText_Solid(font, text, color2)) == NULL)
+// return NULL;
+
+ //on va créer une surface en puissance de 2
+ w = nextpoweroftwo(initial->w);
+ h = nextpoweroftwo(initial->h);
+
+ intermediary = SDL_CreateRGBSurface(0, w, h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
+
+ //on va copier la première surface dans la deuxième
+ SDL_BlitSurface(initial, 0, intermediary, 0);
+// SDL_UpdateRects(intermediary, 1, &location);
+ //on met le fond en transparent (alpha à 0) et le reste à la couleur voulue
+ int i;
+ for (i=0 ; i< h * w ; i++)
+ {
+ ((char *)(intermediary->pixels))[i * 4 + 3] = ((char *)(intermediary->pixels))[i * 4 + 0];
+ ((char *)(intermediary->pixels))[i * 4 + 0] = color.r;
+ ((char *)(intermediary->pixels))[i * 4 + 1] = color.g;
+ ((char *)(intermediary->pixels))[i * 4 + 2] = color.b;
+ }
+
+ //on crée une texxture openGL
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, intermediary->pixels );
+
+ t->pixels = intermediary;
+ t->texnum = texture;
+ t->color = color;
+ t->h = h;
+ t->w = w;
+// //on la paramètre
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);//GL_REPLACE);
+
+// //on l'utilise
+// glEnable(GL_TEXTURE_2D);
+// glBindTexture(GL_TEXTURE_2D, texture);
+//
+// //on s'occuppe de nos couleurs et on dit qu'on veut de la transparence
+// glColor4f(color.r/255.0, color.g/255.0, color.b/255.0, 1.0);
+// glEnable(GL_BLEND);
+// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+//
+// //on dessine le texte où on le voulait
+// glBegin(GL_QUADS);
+// glTexCoord2f(0.0f, 1.0f);
+// glVertex2f(location->x, location->y - h + TEXTSHIFT);
+// glTexCoord2f(1.0f, 1.0f);
+// glVertex2f(location->x + w, location->y - h + TEXTSHIFT);
+// glTexCoord2f(1.0f, 0.0f);
+// glVertex2f(location->x + w, location->y + TEXTSHIFT);
+// glTexCoord2f(0.0f, 0.0f);
+// glVertex2f(location->x, location->y + TEXTSHIFT);
+// glEnd();
+//
+// //on désactive la transparence
+// glDisable(GL_BLEND);
+// glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
+// // glFinish();
+// glDisable(GL_TEXTURE_2D);
+//
+// //on recopie les tailles au cas où ça intéresse quelqu'un
+// location->w = initial->w;
+// location->h = initial->h;
+
+ //on détruit les surfaces et es textures qu'on a utilisé
+ SDL_FreeSurface(initial);
+ SDL_FreeSurface(intermediary);
+// glDeleteTextures(1, &texture);
+ return t;
+}
+
+
+void drawText(Text texture, SDL_Rect *location)
+{
+// //on la paramètre
+// glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+// glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);//GL_REPLACE);
+
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ //on l'utilise
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, texture.texnum);
+ //on s'occuppe de nos couleurs et on dit qu'on veut de la transparence
+// glColor4f(texture.color.r/255.0, texture.color.g/255.0, texture.color.b/255.0, 1.0);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+/* Dessin du sprite avec transparence */
+ //on dessine le texte où on le voulait
+ glBegin(GL_QUADS);
+ glTexCoord2f(0.0f, 1.0f);
+ glVertex2f(location->x, location->y - texture.h + TEXTSHIFT);
+ glTexCoord2f(1.0f, 1.0f);
+ glVertex2f(location->x + texture.w, location->y - texture.h + TEXTSHIFT);
+ glTexCoord2f(1.0f, 0.0f);
+ glVertex2f(location->x + texture.w, location->y + TEXTSHIFT);
+ glTexCoord2f(0.0f, 0.0f);
+ glVertex2f(location->x, location->y + TEXTSHIFT);
+ glEnd();
+
+ //on désactive la transparence
+ glDisable(GL_BLEND);
+/* glFinish();*/
+ glDisable(GL_TEXTURE_2D);
+
+ //on recopie les tailles au cas où ça intéresse quelqu'un
+// location->w = initial->w;
+// location->h = initial->h;
+}
+
+void freeText(Text *text)
+{
+// SDL_FreeSurface(text->pixels);
+ glDeleteTextures(1, &text->texnum);
+ free(text);
+}
+
+int load_fonts()
+{
+ char *buffer;
+ if (fileExists("FreeMono.ttf"))
+ buffer = "FreeMono.ttf";
+ else if (fileExists("data/FreeMono.ttf"))
+ buffer = "data/FreeMono.ttf";
+ else if (fileExists("../data/FreeMono.ttf"))
+ buffer = "../data/FreeMono.ttf";
+ else
+ return 1;
+ if(TTF_Init())
+ {
+ printf("Erreur while loading TTF: %s\n", TTF_GetError());
+ return 1;
+ }
+ if(!(font = TTF_OpenFont(buffer, 50)))
+ {
+ printf("Erreur while loading the font: %s\n", TTF_GetError());
+ return 1;
+ }
+ if(!(fontsmall = TTF_OpenFont(buffer, 25)))
+ {
+ printf("Erreur while loading the font: %s\n", TTF_GetError());
+ return 1;
+ }
+ return 0;
+}
+
+
+// void SDL_GL_RenderText(char *text,
+// TTF_Font *font,
+// SDL_Color color,
+// SDL_Rect *location)
+// {
+// SDL_Surface *initial;
+// SDL_Surface *intermediary;
+// // SDL_Rect rect;
+// int w,h;
+// GLuint texture;
+//
+// // Use SDL_TTF to render our text
+// initial = TTF_RenderText_Blended(font, text, color);
+//
+// // Convert the rendered text to a known format
+// w = nextpoweroftwo(initial->w);
+// h = nextpoweroftwo(initial->h);
+//
+// intermediary = SDL_CreateRGBSurface(0, w, h, 32,
+// 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000);
+//
+// SDL_BlitSurface(initial, 0, intermediary, 0);
+//
+// // Tell GL about our new texture
+// glGenTextures(1, &texture);
+// glBindTexture(GL_TEXTURE_2D, texture);
+// glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA,
+// GL_UNSIGNED_BYTE, intermediary->pixels );
+//
+// // GL_NEAREST looks horrible, if scaled...
+// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+//
+// // prepare to render our texture
+// glEnable(GL_TEXTURE_2D);
+// glBindTexture(GL_TEXTURE_2D, texture);
+// glColor3f(1.0f, 1.0f, 1.0f);
+//
+// // Draw a quad at location
+// glBegin(GL_QUADS);
+// // Recall that the origin is in the lower-left corner
+// // That is why the TexCoords specify different corners
+// // than the Vertex coors seem to.
+// glTexCoord2f(0.0f, 1.0f);
+// glVertex2f(location->x , location->y);
+// glTexCoord2f(1.0f, 1.0f);
+// glVertex2f(location->x + w, location->y);
+// glTexCoord2f(1.0f, 0.0f);
+// glVertex2f(location->x + w, location->y + h);
+// glTexCoord2f(0.0f, 0.0f);
+// glVertex2f(location->x , location->y + h);
+// glEnd();
+//
+// // Bad things happen if we delete the texture before it finishes
+// glFinish();
+//
+// // return the deltas in the unused w,h part of the rect
+// location->w = initial->w;
+// location->h = initial->h;
+//
+// // Clean up
+// SDL_FreeSurface(initial);
+// SDL_FreeSurface(intermediary);
+// glDeleteTextures(1, &texture);
+// }
--- /dev/null
+#include <SDL/SDL.h>
+#include <SDL/SDL_thread.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "divers.h"
+#include "evenements.h"
+#include "vtplayer-ctrl.h"
+
+#define SLOWDOWN 3.0
+
+SDL_mutex * mouse_status_mutex;
+#define LOCK SDL_mutexP(mouse_status_mutex)
+#define UNLOCK SDL_mutexV(mouse_status_mutex)
+
+extern int resol_x;
+extern int resol_y;
+extern int running;
+extern int condition;
+int startx = -1, starty = -1;
+int absstartx = -1, absstarty = -1;
+int init = 1;
+
+#ifdef DEBUG
+#define dprintf(x...) printf(x)
+#else
+#define dprintf(x...)
+#endif
+
+int get_mouse_x()
+{
+ int r;
+ LOCK;
+ r = mouse_status.x;
+ UNLOCK;
+ return r;
+}
+
+int get_mouse_y()
+{
+ int r;
+ LOCK;
+ r = mouse_status.y;
+ UNLOCK;
+ return r;
+}
+
+int get_vtp_x()
+{
+ int r;
+ LOCK;
+ r = (int)mouse_status.vtpx;
+ UNLOCK;
+ return r;
+}
+
+int get_vtp_y()
+{
+ int r;
+ LOCK;
+ r = (int)mouse_status.vtpy;
+ UNLOCK;
+ return r;
+}
+
+int get_mouse_b(int i)
+{
+ int r;
+ LOCK;
+ r = mouse_status.b[i];
+ UNLOCK;
+ return r;
+}
+
+int get_mouse_any_button()
+{
+ int r;
+ LOCK;
+ r = mouse_status.b[0] || mouse_status.b[1] || mouse_status.b[2] || mouse_status.b[3];
+ UNLOCK;
+ return r;
+}
+
+/*void set_min_screen_x(int x) { LOCK; mouse_status.min_screen_x = x; UNLOCK; }
+void set_min_screen_y(int y) { LOCK; mouse_status.min_screen_y = y; UNLOCK; }
+void set_max_screen_x(int x) { LOCK; mouse_status.max_screen_x = x; UNLOCK; }
+void set_max_screen_y(int y) { LOCK; mouse_status.max_screen_y = y; UNLOCK; }
+*/
+
+int mouse_status_thread(void * p)
+{
+ int temp = 0;
+ struct
+ {
+ char rx, ry, dummy, buttons;
+ } __attribute__((packed)) evts;
+ evts.rx = 0;
+ evts.ry = 0;
+ evts.dummy = 0;
+ evts.buttons = 0;
+ while(running)
+ {
+ SDL_Delay(10);
+ if (temp++ % 100 == 0)
+ printf("mouse_status_thread still alive %d, x=%f, y=%f\n", temp, mouse_status.vtpx, mouse_status.vtpy);
+ if (get_status((u8 *) &evts) < 0)
+ continue;
+ LOCK;
+// if (condition == CONDITION_MV)
+// {
+// dprintf("vtpx=%d, vtpy=%d, dx=%d, dy=%d\n", mouse_status.vtpx, mouse_status.vtpy, (int)(evts.rx / SLOWDOWN), (int)(evts.rx / SLOWDOWN));
+ mouse_status.vtpx += evts.rx / SLOWDOWN;
+ mouse_status.vtpy += evts.ry / SLOWDOWN;
+// }
+// else
+// {
+// mouse_status.vtpx += evts.rx;
+// mouse_status.vtpy += evts.ry;
+// }
+ if (mouse_status.vtpx < 0)
+ mouse_status.vtpx = 0;
+ if (mouse_status.vtpy < 0)
+ mouse_status.vtpy = 0;
+ if (mouse_status.vtpx > resol_x)
+ mouse_status.vtpx = resol_x;
+ if (mouse_status.vtpy > resol_y)
+ mouse_status.vtpy = resol_y;
+ mouse_status.b[0] = evts.buttons & 1 ? 1 : 0;
+ mouse_status.b[1] = evts.buttons & 2 ? 1 : 0;
+ mouse_status.b[2] = evts.buttons & 4 ? 1 : 0;
+ mouse_status.b[3] = evts.buttons & 8 ? 1 : 0;
+ UNLOCK;
+ }
+ dprintf("Destroying mouse status mutex\n");
+ SDL_DestroyMutex(mouse_status_mutex);
+ dprintf("Mouse status thread quitting\n");
+ return 0;
+}
+
+SDL_Thread *create_mouse_status_thread()
+{
+ SDL_Thread *r;
+ dprintf("Create the mouse status thread\n");
+ memset(&mouse_status, 0, sizeof(mouse_status));
+ mouse_status.vtpx = resol_x / 2;
+ mouse_status.vtpy = resol_y / 2;
+ if((mouse_status_mutex = SDL_CreateMutex()) == NULL)
+ {
+ printf("Error while creating the mutex mutex : %s\n", SDL_GetError());
+ return NULL;
+ }
+ if ((r = SDL_CreateThread(mouse_status_thread, 0)) == NULL)
+ {
+ printf("Error while creating the mouse polling thread: %s\n", SDL_GetError());
+ return NULL;
+ }
+ return r;
+}
+
+events_t process_events()
+{
+ SDL_Event event;
+ SDL_MouseMotionEvent *me;
+ events_t r;
+ r.buttons = get_mouse_any_button();
+ r.symbol = 0;
+
+ while(SDL_PollEvent(&event))
+ {
+ switch(event.type)
+ {
+ case SDL_KEYDOWN:
+ r.symbol = event.key.keysym.sym;
+ return r;
+ case SDL_MOUSEMOTION:
+ if ((me = (SDL_MouseMotionEvent *)(&event)) == NULL)
+ {
+ fprintf(stderr, "Can't get mouse coordinates\n");
+ return r;
+ }
+ LOCK;
+// if (condition == CONDITION_PV)
+// {
+/* dprintf("mouse %4d %4d\n", mouse_status.x, mouse_status.y);*/
+ mouse_status.x = (me->x / SLOWDOWN) + resol_x * (0.5 - 0.5 / SLOWDOWN);
+ mouse_status.y = (me->y / SLOWDOWN) + resol_y * (0.5 - 0.5 / SLOWDOWN);
+// }
+// else
+// {
+// mouse_status.x = me->x;//me->xrel/2 + startx;
+// mouse_status.y = me->y;
+// }
+ UNLOCK;
+ break;
+ case SDL_QUIT:
+ dprintf("Caught Exit\n");
+ running = 0;
+ exit(0);
+ break;
+ }
+ }
+ return r;
+}
+
+#undef LOCK
+#undef UNLOCK
--- /dev/null
+// xsetwacom set stylus bottomx 12700 ; xsetwacom set stylus bottomy 20300
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_opengl.h>
+#include <SDL/SDL_image.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+#include <math.h>
+
+#include "divers.h"
+#include "vtplayer-ctrl.h"
+#include "icons.h"
+#include "evenements.h"
+#include "params.h"
+#include "display.h"
+#include "guidance.h"
+#define COLOR_FOND 1.0, 1.0, 1.0
+
+extern param_list *list_params;
+extern const SDL_VideoInfo *info;
+extern SDL_Surface *screen;
+extern int *pinsconfig;
+extern int currentdirection;
+extern int max_screen_x;
+extern int min_screen_x;
+extern int max_screen_y;
+extern int min_screen_y;
+extern int resol_x;
+extern int resol_y;
+extern unsigned char *shapepixels;
+int left_handed = 0;
+int condition = 0;
+FILE *logfile = NULL;
+int running = 1;
+int maxtime = 180;
+int training = 0;
+
+#ifdef DEBUG
+#define dprintf(x...) printf(x)
+#else
+#define dprintf(x...)
+#endif
+
+int main(int argc, char *argv[])
+{
+ //user name and condition
+ char *name = NULL, *conditionname = NULL, *shape = NULL, *tempstring = NULL;
+
+ if (argc > 1 && read_command_params(argc, argv) > 0)
+ {
+ name = get_params("name");
+ conditionname = get_params("condition");
+ if (conditionname && (strcmp(conditionname, "Pt") == 0))
+ condition = CONDITION_PT;
+ else if (conditionname && (strcmp(conditionname, "Pv") == 0))
+ condition = CONDITION_PV;
+ else if (conditionname && (strcmp(conditionname, "Mt") == 0))
+ condition = CONDITION_MT;
+ else if (conditionname && (strcmp(conditionname, "Mv") == 0))
+ condition = CONDITION_MV;
+ shape = get_params("shape");
+ tempstring = get_params("hand");
+ if (tempstring && (strcmp(tempstring, "left") == 0))
+ left_handed = 1;
+ tempstring = get_params("training");
+ if (tempstring && (strcmp(tempstring, "yes") == 0))
+ training = 1;
+ }
+ else
+ {
+ printf("Usage : shapes -name username -condition Pt|Pv|Mt|Mv -shape shapefile [-hand left]\n");
+ display_params();
+ return 1;
+ }
+
+ time_t tim = time(NULL);
+ struct tm *t = gmtime(&tim);
+
+ if (name)
+ {
+ char logfilename[BUFFERSIZE+1];
+ snprintf(logfilename, BUFFERSIZE, "%s-%s-%04d-%02d-%02d-%02d-%02d-%02d-%s", name, conditionname, 1900 + t->tm_year, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, shape);
+ dprintf("Logfile: %s\n",logfilename);
+ logfile = fopen(logfilename, "w");
+ if (logfile)
+ dprintf("logfile OK\n");
+ else
+ {
+ dprintf("Error with logfile\n");
+ return 1;
+ }
+ }
+
+ //read parameters
+ read_file_params();
+ tempstring = get_params("maxtime");
+ if (tempstring)
+ maxtime = atoi(tempstring);
+ display_params();
+
+ //initialize everything: SDL, VTPlayer, etc.
+#ifndef WITHOUTVTP
+ dprintf("Loading VTPlayer\n");
+ if (init_vtplayer())
+ {
+#ifdef __linux__
+ printf("Impossible to find the VTPlayer! Are you root?\n");
+#else
+ printf("Impossible to find the VTPlayer! Try to unplug/replug it.\n");
+#endif
+ return 1;
+ }
+#endif
+
+ atexit(SDL_Quit);
+ dprintf("Loading SDL\n");
+ if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
+ {
+ printf("Error while loading SDL: %s\n", SDL_GetError());
+ return 1;
+ }
+
+ dprintf("Loading SDL VideoInfo\n");
+ if ((info = SDL_GetVideoInfo()) == NULL)
+ {
+ printf("Impossible to get SDL information: %s\n", SDL_GetError());
+ return 1;
+ }
+
+ dprintf("List video modes\n");
+ SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE);
+ if (modes == NULL)
+ {
+ printf("Impossible to find the screen resolution!\n");
+ return 1;
+ }
+ else if (modes == (SDL_Rect **)-1)
+ {
+ resol_x = 1024;
+ resol_y = 768;
+ }
+ else
+ {
+ resol_x = modes[0]->w;
+ resol_y = modes[0]->h;
+ }
+ dprintf("Resolution choosen: %dx%d\n", resol_x, resol_y);
+ max_screen_x = (int)(500 *((float) resol_x) / ((float) resol_y));
+ min_screen_x = - max_screen_x;
+ max_screen_y = 500;
+ min_screen_y = - max_screen_y;
+
+ dprintf("Init SDL subsystem\n");
+ if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
+ {
+ printf("Couldn't initialise Video SubSystem: %s\n", SDL_GetError());
+ return 1;
+ }
+
+ dprintf("Init GL Attributes\n");
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 8);
+
+ int flags = SDL_OPENGL | SDL_HWSURFACE | SDL_FULLSCREEN;
+// resol_x = 1024;
+// resol_y = 768;
+ dprintf("Set video mode %dx%d %08x\n", resol_x, resol_y, flags);
+ //this appears to cause the segfault at the end of the program
+ screen = SDL_SetVideoMode(resol_x, resol_y, 0, flags);
+
+ if (!screen)
+ {
+ printf("Impossible de changer le mode video : %s\n", SDL_GetError());
+ return 1;
+ }
+
+// SDL_LockSurface(screen);
+ GLdouble ratio = (GLdouble) screen->w / screen->h;
+ printf("infos : %08x %d %d %d\n", screen->flags, screen->w, screen->h, screen->pitch);
+ printf("Video resolution: %dx%dx%d (ratio = %3.2f)\n", screen->w, screen->h, screen->format->BitsPerPixel, ratio);
+// SDL_UnlockSurface(screen);
+
+ printf("OpenGL infos\n");
+ printf("------------\n");
+ printf("Vendor : %s\n", glGetString(GL_VENDOR));
+ printf("Renderer : %s\n", glGetString(GL_RENDERER));
+ printf("Version : %s\n", glGetString(GL_VERSION));
+ printf("Extensions: %s\n", glGetString(GL_EXTENSIONS));
+
+ glClearColor(COLOR_FOND, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ dprintf("Setting viewport\n");
+ glViewport(0, 0, resol_x, resol_y);
+ switch(glGetError())
+ {
+ case GL_INVALID_VALUE:
+ printf("Wrong resolution\n");
+ return 1;
+ case GL_INVALID_OPERATION:
+ printf("Check the position of the glViewport instruction\n");
+ return 1;
+ }
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ dprintf("Setting projection\n");
+ gluOrtho2D(0, resol_x, resol_y, 0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+// SDL_ShowCursor(SDL_DISABLE);
+
+ dprintf("Load shape\n");
+ if (load_shape(shape))
+ {
+ printf("Failed to load the shape '%s'\n", shape);
+ return 1;
+ }
+
+ //we store the pixels of the shape vir the visual => tactile transation
+ glClearColor(1.0, 1.0, 1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ dprintf("Draw shape\n");
+ draw_shape();
+ dprintf("%dx%d : %d pixels\n", resol_x, resol_y, 4 * resol_x * resol_y);
+
+ shapepixels = (unsigned char *) malloc(4 * resol_x * resol_y);
+ if (!shapepixels)
+ printf("Impossible to store the pixels\n");
+ glReadPixels(0, 0, resol_x, resol_y, GL_RGBA, GL_UNSIGNED_BYTE, shapepixels);
+#ifdef DEBUG
+ SDL_Surface *temp;
+ if (!(temp = SDL_CreateRGBSurface(SDL_SWSURFACE, resol_x, resol_y, 32,
+ #if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
+ #else
+ 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
+ #endif
+ )))
+ return 1;
+ int i;
+ for (i = 0 ; i < resol_y ; i++)
+ memcpy(((char *) temp->pixels) + temp->pitch * i, shapepixels + 4 * resol_x * (resol_y - 1 - i), resol_x * 4);
+
+ int nbpixels = 0;
+ for (i = 0 ; i < 4 * resol_x * resol_y ; i += 4)
+ if (!shapepixels[i])
+ nbpixels++;
+ printf("\033[31m%d pixels colorés\033[0m, %d total\n", nbpixels, resol_x * resol_y);
+
+ char screenshotstring[BUFFERSIZE];
+ sprintf(screenshotstring, "%s.bmp", shape);
+ dprintf("Save screenshot %s\n", screenshotstring);
+ SDL_SaveBMP(temp, screenshotstring);
+ SDL_FreeSurface(temp);
+#endif
+// for (int i = 0 ; i < resolution[C_Y] ; i++)
+// memcpy(((char *) temp->pixels) + temp->pitch * i, pixels + 4 * resolution[C_X] * (resolution[C_Y] - i - 1), resolution[C_X] * 4);
+
+ SDL_Thread *mouse_status_thread = NULL, *tacton_thread = NULL, *pins_thread = NULL, *translation_thread = NULL;
+ //run the threads
+ switch (condition)
+ {
+ case CONDITION_MT:
+ if ((mouse_status_thread = create_mouse_status_thread()) == NULL)
+ {
+ printf("Impossible tu create the mouse events thread\n");
+ return 1;
+ }
+ case CONDITION_PT:
+ dprintf("Conditions T\n");
+ if ((tacton_thread = create_tacton_thread()) == NULL)
+ {
+ printf("Impossible to create the tactons thread\n");
+ return 1;
+ }
+ if ((pins_thread = create_pins_thread()) == NULL)
+ {
+ printf("Impossible to create the tactile display thread\n");
+ return 1;
+ }
+ break;
+ case CONDITION_MV:
+ if ((mouse_status_thread = create_mouse_status_thread()) == NULL)
+ {
+ printf("Impossible tu create the mouse events thread\n");
+ return 1;
+ }
+ case CONDITION_PV:
+ dprintf("Conditions V\n");
+ if ((translation_thread = create_translation_thread()) == NULL)
+ {
+ printf("Impossible to create the tactile display thread\n");
+ return 1;
+ }
+ break;
+ }
+
+ struct events_t evt;
+ while(running)
+ {
+ evt = process_events();
+ if (evt.symbol == SDLK_ESCAPE)
+ break;
+// currentdirection = (currentdirection + 1) % 9;
+ draw_screen();
+ glFinish();
+ SDL_Delay(10);
+ }
+ running = 0;
+ set_pads(0);
+
+
+ dprintf("Wait for the Threads\n");
+ int status;
+ if (mouse_status_thread)
+ {
+ dprintf("Wait mouse_status_thread\n");
+ SDL_WaitThread(mouse_status_thread, &status);
+ dprintf("Thread mouse_status_thread : %d\n", status);
+// SDL_KillThread(mouse_status_thread);
+ }
+ if (tacton_thread)
+ {
+ dprintf("Wait tacton_thread\n");
+ SDL_WaitThread(tacton_thread, &status);
+ dprintf("Thread tacton_thread : %d\n", status);
+// SDL_KillThread(tacton_thread);
+ }
+ if (pins_thread)
+ {
+ dprintf("Wait pins_thread\n");
+ SDL_WaitThread(pins_thread, &status);
+ dprintf("Thread pins_thread : %d\n", status);
+// SDL_KillThread(pins_thread);
+ }
+ if (translation_thread)
+ {
+ dprintf("Wait translation_thread\n");
+ SDL_WaitThread(translation_thread, &status);
+ dprintf("Thread translation_thread : %d\n", status);
+// SDL_KillThread(translation_thread);
+ }
+ if (name)
+ {
+ dprintf("Closes the logfile\n");
+ fclose(logfile);
+ }
+ dprintf("Unloads the shape\n");
+ unload_shape();
+ dprintf("Frees the surface\n");
+ if (shapepixels)
+ free(shapepixels);
+ dprintf("Deletes the parameters\n");
+ delete_params(list_params);
+ dprintf("Shows the cursor back\n");
+// SDL_ShowCursor(SDL_ENABLE);
+ dprintf("Freeing the screen\n");
+ if (screen)
+ SDL_FreeSurface(screen);
+// dprintf("Quit subsystem\n");
+// SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
+// dprintf("Quit SDL\n");
+// SDL_Quit();
+
+ dprintf("The end\n");
+
+ return 0;
+}
--- /dev/null
+#include <windows.h>
+
+#include "gettimeofday.h"
+
+#define FACTOR (0x19db1ded53e8000LL)
+#define NSPERSEC 10000000LL
+
+typedef long long LONGLONG;
+
+static int inited = 0;
+static LARGE_INTEGER primed_pc, primed_ft;
+static double freq;
+static int justdelta = 0;
+
+static void prime() {
+ LARGE_INTEGER ifreq;
+ if (!QueryPerformanceFrequency (&ifreq))
+ {
+ inited = -1;
+ return;
+ }
+
+ FILETIME f;
+ int priority = GetThreadPriority (GetCurrentThread ());
+ SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
+ if (!QueryPerformanceCounter (&primed_pc))
+ {
+ SetThreadPriority (GetCurrentThread (), priority);
+ inited = -1;
+ return;
+ }
+
+ GetSystemTimeAsFileTime (&f);
+ SetThreadPriority (GetCurrentThread (), priority);
+
+ inited = 1;
+ primed_ft.HighPart = f.dwHighDateTime;
+ primed_ft.LowPart = f.dwLowDateTime;
+ primed_ft.QuadPart -= FACTOR;
+ primed_ft.QuadPart /= 10;
+ freq = (double) ((double) 1000000. / (double) ifreq.QuadPart);
+ return;
+}
+
+static LONGLONG usec() {
+ if (!inited)
+ prime ();
+
+ LARGE_INTEGER now;
+ if (!QueryPerformanceCounter (&now))
+ {
+ return -1;
+ }
+
+ // FIXME: Use round() here?
+ now.QuadPart = (LONGLONG) (freq * (double) (now.QuadPart - primed_pc.QuadPart));
+ LONGLONG res = justdelta ? now.QuadPart : primed_ft.QuadPart + now.QuadPart;
+ return res;
+}
+
+int gettimeofday (struct timeval *tv, void *tz)
+{
+ LONGLONG now = usec();
+ if (now == (LONGLONG) -1)
+ return -1;
+
+ tv->tv_sec = now / 1000000;
+ tv->tv_usec = now % 1000000;
+
+ return 0;
+}
+
+//retourne des centiemes de secondes
+int diff_time (struct timeval *debut, int precision)
+{
+ struct timeval *fin = (struct timeval *) malloc(sizeof(struct timeval));
+ gettimeofday(fin, NULL);
+
+ int sec = fin->tv_sec - debut->tv_sec;
+ int msec = fin->tv_usec - debut->tv_usec;
+
+ free(fin);
+
+ return (1000000 * sec + msec)/precision;
+}
--- /dev/null
+#include "guidance.h"
+
+#include <stdio.h>
+#include <SDL/SDL.h>
+#include <SDL/SDL_image.h>
+#include <SDL/SDL_opengl.h>
+#include <SDL/SDL_ttf.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "divers.h"
+#include "display.h"
+
+#ifdef DEBUG
+#define dprintf(x...) printf(x)
+#else
+#define dprintf(x...)
+#endif
+
+extern int resol_x;
+extern int resol_y;
+extern int currentsegment;
+extern int condition;
+
+shape_type shape;
+
+int load_shape(char *name)
+{
+ if (!name)
+ {
+ printf("No shape specified\n");
+ return 1;
+ }
+
+ FILE *filename;
+ char buffer[BUFFERSIZE + 1], *namebuffer;
+ snprintf(buffer, BUFFERSIZE, "%s", name);
+ if (fileExists(buffer))
+ namebuffer = strdup(buffer);
+ else
+ {
+ snprintf(buffer, BUFFERSIZE, "data/%s", name);
+ if (fileExists(buffer))
+ namebuffer = strdup(buffer);
+ else
+ {
+ snprintf(buffer, BUFFERSIZE, "../data/%s", name);
+ if (fileExists(buffer))
+ namebuffer = strdup(buffer);
+ else
+ return 1;
+ }
+ }
+ if ((filename = fopen(namebuffer,"r")) == NULL)
+ return 1;
+ free(namebuffer);
+
+
+ //we read the number of points
+ if (fgets(buffer, BUFFERSIZE, filename) == NULL)
+ {
+ fprintf(stderr, "some Tactons are missing\n");
+ shape.nbv = 0;
+ shape.x = NULL;
+ shape.y = NULL;
+ return 1;
+ }
+ shape.nbv = atoi(buffer);
+ if (shape.nbv <= 0)
+ {
+ fprintf(stderr, "No frames\n");
+ shape.nbv = 0;
+ shape.x = NULL;
+ shape.y = NULL;
+ return 1;
+ }
+
+ shape.x = (int *) malloc(shape.nbv * sizeof(int));
+ shape.y = (int *) malloc(shape.nbv * sizeof(int));
+ int i;
+ for (i = 0 ; i < shape.nbv ; i++)
+ {
+ if (fgets(buffer, BUFFERSIZE, filename) == NULL)
+ {
+ shape.x[i] = 0;
+ shape.y[i] = 0;
+ continue;
+ }
+ int x, y;
+ sscanf(buffer, "%d,%d", &x, &y);
+ shape.x[i] = get_x_from_opengl(x);
+ shape.y[i] = get_y_from_opengl(y);// - 1;
+ dprintf("Shape: %d,%d\n",shape.x[i], shape.y[i]);
+ }
+ fclose(filename);
+ return 0;
+}
+
+void unload_shape()
+{
+ if (shape.x)
+ free(shape.x);
+ if (shape.y)
+ free(shape.y);
+}
+
+void draw_shape()
+{
+ if (shape.nbv <= 0)
+ return;
+ int i;
+
+ glBegin(GL_LINE_LOOP);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glColor3d(0.0, 0.0, 0.0);
+ for (i = 0 ; i < shape.nbv ; i++)
+ {
+ if (i == currentsegment && (condition == CONDITION_PT || condition == CONDITION_MT))
+ glColor3d(1.0, 0.0, 0.0);
+ else
+ glColor3d(0.0, 0.0, 0.0);
+ glVertex2d(shape.x[i], shape.y[i]);
+ }
+ glEnd();
+}
+
+int get_direction(int posx, int posy)
+{
+ return 1;
+}
+
--- /dev/null
+#include <SDL/SDL.h>
+#include <SDL/SDL_thread.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <time.h>
+#include <sys/time.h>
+
+#include "icons.h"
+
+#include "divers.h"
+#include "vtplayer-ctrl.h"
+#include "params.h"
+#include "evenements.h"
+#include "guidance.h"
+
+#ifdef __WIN32
+#include "gettimeofday.h"
+#endif
+
+#define EPSILON 0.0000001
+
+#define RESET 0x00000000
+
+#define RIGHT_H 0
+#define LEFT_H 1
+
+#define LEFT_H 1
+
+SDL_mutex * tacton_mutex;
+#define LOCK SDL_mutexP(tacton_mutex)
+#define UNLOCK SDL_mutexV(tacton_mutex)
+
+#ifdef DEBUG
+#define dprintf(x...) printf(x)
+#else
+#define dprintf(x...)
+#endif
+
+/// A set is composed of the icons of the 8 directions
+typedef struct set_t
+{
+ u32 *icons[8];
+ int nbframes[8];
+ int speeds[3];
+}iconset_t;
+
+iconset_t *set = NULL;
+
+int currentspeed = 100;
+int currentsegment = 0;
+unsigned char *shapepixels;
+u32 currenttacton;
+u32 tacton;
+u32 tactonfixed;
+
+extern param_list **list_params;
+extern param_list **list_params;
+extern struct mouse_status_t mouse_status;
+extern int resol_x;
+extern int resol_y;
+extern shape_type shape;
+extern int condition;
+extern int left_handed;
+extern FILE *logfile;
+extern int running;
+extern int maxtime;
+extern int training;
+
+u32 get_tacton()
+{
+ u32 r;
+ LOCK;
+ switch(condition)
+ {
+ case CONDITION_MT:
+ if (left_handed)
+ r = (tacton >> 16) + (tactonfixed << 16);
+ else
+ r = tacton + tactonfixed;
+ break;
+ case CONDITION_MV:
+ if (left_handed)
+ r = tacton >> 16;
+ else
+ r = tacton;
+ break;
+ case CONDITION_PT:
+ if (left_handed)
+ r = tacton + tactonfixed;
+ else
+ r = (tacton >> 16) + (tactonfixed << 16);
+ break;
+ case CONDITION_PV:
+ if (left_handed)
+ r = tacton;
+ else
+ r = tacton >> 16;
+ break;
+ }
+// r = tacton;
+ UNLOCK;
+ return r;
+}
+
+/// Loads a Tacton set from a text file
+// format :
+// 8 lines for the eight directions
+// separator : ';'
+// - nb frames : integer
+// - the frames : u32
+void load_set()
+{
+ FILE *f;
+ int i, j, k, currentnumber = 0;
+ char buffer[BUFFERSIZE + 1];
+ //Left handed
+ int hand = RIGHT_H;
+ char *temp;
+ if ((temp = get_params("hand")) && (strcmp(temp, "left") == 0))
+ hand = LEFT_H;
+
+ char buffer2[BUFFERSIZE + 1], *namebuffer;
+ snprintf(buffer2, BUFFERSIZE, "%s", get_params("tactonsfile"));
+ if (fileExists(buffer2))
+ namebuffer = strdup(buffer2);
+ else
+ {
+ snprintf(buffer2, BUFFERSIZE, "data/%s", get_params("tactonsfile"));
+ if (fileExists(buffer2))
+ namebuffer = strdup(buffer2);
+ else
+ {
+ snprintf(buffer2, BUFFERSIZE, "../data/%s", get_params("tactonsfile"));
+ if (fileExists(buffer2))
+ namebuffer = strdup(buffer2);
+ else
+ return;
+ }
+ }
+ if ((f = fopen(namebuffer,"r")) == NULL)
+ return;
+ free(namebuffer);
+
+ set = (iconset_t *) malloc(sizeof(iconset_t));
+
+ for (i = 0 ; i < 8 ; i++)
+ {
+ dprintf("reading Tacton %d : ", i);
+ //we read a line from the buffer
+ if (fgets(buffer, BUFFERSIZE, f) == NULL)
+ {
+ fprintf(stderr, "some Tactons are missing\n");
+ free(set);
+ set = NULL;
+ return;
+ }
+ //we get the first number : the number of frames
+ j = 0, currentnumber = 0;
+ while(j < BUFFERSIZE && j < strlen(buffer) && buffer[j] != ';')
+ {
+ if ( buffer[j] >= '0' && buffer[j] <= '9' )
+ currentnumber = currentnumber * 10 + buffer[j] - '0';
+ j++;
+ }
+ j++;
+ set->nbframes[i] = currentnumber;
+ set->icons[i] = (u32 *) malloc(set->nbframes[i] * sizeof(u32));
+ dprintf("%d frames :\n", set->nbframes[i]);
+
+ //we read the frames
+ for (k = 0 ; k < set->nbframes[i] ; k++)
+ {
+ currentnumber = 0;
+ while(j < BUFFERSIZE && j < strlen(buffer) && buffer[j] != ';')
+ {
+ if ( buffer[j] >= '0' && buffer[j] <= '9' )
+ currentnumber = currentnumber * 16 + buffer[j] - '0';
+ if ( buffer[j] >= 'a' && buffer[j] <= 'f' )
+ currentnumber = currentnumber * 16 + buffer[j] - 'a' + 10;
+ j++;
+ }
+ j++;
+ if (hand == 1)
+ set->icons[i][k] = currentnumber << 16;
+ else
+ set->icons[i][k] = currentnumber;
+ dprintf("frame %2d : %08lx\n", k, set->icons[i][k]);
+ }
+ }
+ //read speed values from parameters
+ temp = get_params("speed1");
+ if (temp)
+ set->speeds[0] = atoi(temp);
+ else
+ set->speeds[0] = 100;
+ temp = get_params("speed2");
+ if (temp)
+ set->speeds[1] = atoi(temp);
+ else
+ set->speeds[1] = 100;
+ temp = get_params("speed3");
+ if (temp)
+ set->speeds[2] = atoi(temp);
+ else
+ set->speeds[2] = 100;
+
+ dprintf("speed1 = %d, speed2 = %d, speed3 = %d\n", set->speeds[0], set->speeds[1], set->speeds[2]);
+
+ return;
+}
+
+int tacton_thread(void *p)
+{
+ int temp = 0;//, temp2=0;
+ struct timeval *now = (struct timeval *) malloc(sizeof(struct timeval));
+ struct timeval *start = (struct timeval *) malloc(sizeof(struct timeval));
+ gettimeofday(start, NULL);
+ int status = 1;
+ while(running)
+ {
+ #if 0
+// LOCK;
+ if (tacton != currenttacton)
+ {
+ status = 1;
+ gettimeofday(start, NULL);
+ currenttacton = tacton;
+ set_pads(tacton);
+// UNLOCK;
+ continue;
+ }
+// UNLOCK;
+#endif
+// printf("current=%ld, target=%ld, diff=%d\n", 1000 * now->tv_sec + now->tv_usec / 1000, currentspeed + 1000 *start->tv_sec + start->tv_usec / 1000, currentspeed);
+ gettimeofday(now, NULL);
+ unsigned int sec = now->tv_sec - start->tv_sec;
+ unsigned int msec = (unsigned int)((now->tv_usec - start->tv_usec) / 1000);
+
+ temp++;
+// if (temp % 100 == 0)
+// dprintf("tacton_thread still alive %d@%d:%d, tacton=%08lx %d:%d\n", temp, (int)now->tv_sec, (int)now->tv_usec, tacton, sec, msec);
+ if (1000 * sec + msec > currentspeed)
+ {
+// temp2 = 0;
+ status = !status;
+ start->tv_usec += 1000 * currentspeed;
+ if (start->tv_usec >= 1000000)
+ {
+ start->tv_usec -= 1000000;
+ start->tv_sec++;
+ }
+ sec = now->tv_sec - start->tv_sec;
+ msec = (unsigned int)((now->tv_usec - start->tv_usec) / 1000);
+
+// gettimeofday(start, NULL);
+
+// LOCK;
+ if (status == 1)
+ set_pads(tacton | tactonfixed);
+ else
+ set_pads(tactonfixed);
+// UNLOCK;
+ }
+// else
+// {
+// temp2++;
+// if (temp2 > 10)
+// dprintf("Too many times ! %d, tacton=%08lx %d:%d=>%d\n", temp2, tacton, sec, msec, 1000 * sec + msec);
+// }
+
+ SDL_Delay(10);
+ }
+
+ if (now)
+ free(now);
+ if (start)
+ free(start);
+
+ dprintf("Tacton thread quitting\n");
+ return (0);
+}
+
+SDL_Thread *create_tacton_thread()
+{
+ SDL_Thread *r;
+ dprintf("Create the tactons thread\n");
+ if ((r = SDL_CreateThread(tacton_thread, NULL)) == NULL)
+ {
+ printf("Impossible to run the tactons thread: %s\n", SDL_GetError());
+ return NULL;
+ }
+ return r;
+}
+
+void display_config_from_angle(double angle, int outside)
+{
+ angle += M_PI/8;
+ while (angle < EPSILON)
+ angle += 2 * M_PI;
+// LOCK;
+ if (angle < M_PI_4 + EPSILON)
+ tacton = 0x88880000;
+ else if (angle < M_PI_2 + EPSILON)
+ tacton = 0x888f0000;
+ else if (angle < 3*M_PI_4 + EPSILON)
+ tacton = 0x000f0000;
+ else if (angle < M_PI + EPSILON)
+ tacton = 0x111f0000;
+ else if (angle < 5*M_PI_4 + EPSILON)
+ tacton = 0x11110000;
+ else if (angle < 3*M_PI_2 + EPSILON)
+ tacton = 0xf1110000;
+ else if (angle < 7*M_PI_4 + EPSILON)
+ tacton = 0xf0000000;
+ else //if (angle < 2*M_PI + EPSILON)
+ tacton = 0xf8880000;
+ if (((condition == CONDITION_MT) && !left_handed) || (!(condition == CONDITION_MT) && left_handed))
+ {
+ tacton >>= 16;
+ if (outside)
+ tactonfixed = 0xffff0000;
+ else
+ tactonfixed = 0x00000000;
+ }
+ else if (outside)
+ tactonfixed = 0x0000ffff;
+ else
+ tactonfixed = 0x00000000;
+// UNLOCK;
+// set_pads(tacton);
+// dprintf("%08lx %08lx\n", config, config | 0x0000ffff);
+}
+
+int pins_thread(void *p)
+{
+// int temp = 0;
+ dprintf("Guidance start\n");
+ if (shape.nbv < 2)
+ {
+ printf("Shape too small\n");
+ return (1);
+ }
+
+ //récupération des paramètres. Il serait temps de faire une fonction sympa pour ça...
+ dprintf("Get parameters\n");
+ currentsegment = 0;
+ char *buffer;
+ buffer = get_params("distance1");
+ int distance1;
+ if (buffer)
+ distance1 = atoi(buffer);
+ else
+ distance1 = 100;
+ buffer = get_params("distance2");
+ int distance2;
+ if (buffer)
+ distance2 = atoi(buffer);
+ else
+ distance2 = 100;
+ buffer = get_params("distance3");
+ int distance3;
+ if (buffer)
+ distance3 = atoi(buffer);
+ else
+ distance3 = 100;
+ buffer = get_params("stripwidth");
+ int stripwidth;
+ if (buffer)
+ stripwidth = atoi(buffer);
+ else
+ stripwidth = 50;
+ buffer = get_params("speed1");
+ int speed1;
+ if (buffer)
+ speed1 = atoi(buffer);
+ else
+ speed1 = 50;
+ buffer = get_params("speed2");
+ int speed2;
+ if (buffer)
+ speed2 = atoi(buffer);
+ else
+ speed2 = 50;
+ buffer = get_params("speed3");
+ int speed3;
+ if (buffer)
+ speed3 = atoi(buffer);
+ else
+ speed3 = 50;
+
+ dprintf("Set coordinates function\n");
+ int (*x)(), (*y)();
+ if (condition == CONDITION_PT)
+ {
+ x = get_mouse_x;
+ y = get_mouse_y;
+ }
+ else// if (strcmp(get_params("condition"),"Mv") == 0)
+ {
+ x = get_vtp_x;
+ y = get_vtp_y;
+ }
+
+ dprintf("Compute first segment\n");
+ int abx = shape.x[1] - shape.x[0];
+ int aby = shape.y[1] - shape.y[0];
+ double abl = sqrt(abx * abx + aby * aby);
+ double segmentangle = acos(abx / abl);
+ if (aby > -EPSILON)
+ segmentangle *= -1;
+ dprintf("abx=%d, aby=%d, abl=%f, segmentangle=%f\n", abx, aby, abl, segmentangle);
+ dprintf("Run the loop\n");
+
+ struct timeval *now = (struct timeval *) malloc(sizeof(struct timeval));
+ struct timeval *start = (struct timeval *) malloc(sizeof(struct timeval));
+ gettimeofday(start, NULL);
+
+ //compute the cartesian equation of the line
+ double line_a = shape.y[(currentsegment + 1) % shape.nbv] - shape.y[currentsegment];
+ double line_b = shape.x[currentsegment] - shape.x[(currentsegment + 1) % shape.nbv];
+ double line_c = shape.x[(currentsegment + 1) % shape.nbv] * shape.y[currentsegment] - shape.x[currentsegment] * shape.y[(currentsegment + 1) % shape.nbv];
+
+ //position relative to the line for the guidance
+ double outsidepos = line_a * x() + line_b * y() + line_c;
+
+ while(running)
+ {
+ gettimeofday(now, NULL);
+ int sec = now->tv_sec - start->tv_sec;
+ int msec = (int)((now->tv_usec - start->tv_usec) / 1000);
+ if (logfile)
+ fprintf(logfile, "%ld;%d;%d;%08lx;%d\n", 1000 * (long int)sec + msec, x(), resol_y - y() - 1, tacton, currentspeed);
+// else
+// dprintf("Error with logfile\n");
+ //if maxtime is elapsed we exit the test
+ if (sec > maxtime && !training)
+ {
+ dprintf("time : %d/%d\n", sec, maxtime);
+ running = 0;
+ break;
+ }
+
+ int amx = x() - shape.x[currentsegment];
+ int amy = y() - shape.y[currentsegment];
+ double aml = sqrt(amx * amx + amy * amy);
+ int bmx = x() - shape.x[(currentsegment + 1) % shape.nbv];
+ int bmy = y() - shape.y[(currentsegment + 1) % shape.nbv];
+ double bml = sqrt(bmx * bmx + bmy * bmy);
+
+ //distance from the pointer's projection to the target
+ double between;
+// dprintf("abx=%d, aby=%d, abl=%f, amx=%d, amy=%d, aml=%f, bmx=%d, bmy=%d, bml=%f\n", abx, aby, abl, amx, amy, aml, bmx, bmy, bml);
+ if (aml > bml)
+ between = abl - (amx * abx + amy * aby) / abl;
+ else
+ between = (bmx * (-abx) + bmy * (-aby)) / abl;
+
+ //distance from the cursor to the segment
+ //we have to add fabs, otherwise sqrt(-0.0) = nan
+ double dist = sqrt(fabs(bml * bml - between * between));
+// dprintf("dist=%f, between=%f, abl=%f, aml=%f, stripwidth=%d, test=%f\n", dist, between, abl, aml, stripwidth, bml * bml - between * between);
+
+ if (between > 0)
+ {
+ //if we are before the first point
+ if ((between > abl) && (aml > stripwidth))
+ {
+ if (aml < distance1)
+ currentspeed = speed1;
+ else if (aml < distance2)
+ currentspeed = speed2;
+ else //if (between < distance3)
+ currentspeed = speed3;
+ double guideangle = acos((-amx) / aml);
+ if (amy < 0)
+ guideangle *= -1;
+ display_config_from_angle(guideangle, 1);
+ outsidepos = 0;//line_a * x() + line_b * y() + line_c;
+ }
+ else //we are between the two points
+ {
+ double newoutsidepos = line_a * x() + line_b * y() + line_c;
+ //we are in the strip
+ //we continue to guide if we come back from the outside and we didn't cross the line
+ if (dist < stripwidth && outsidepos * newoutsidepos <= EPSILON)
+ {
+ if (between < distance1)
+ currentspeed = speed1;
+ else if (between < distance2)
+ currentspeed = speed2;
+ else //if (between < distance3)
+ currentspeed = speed3;
+ display_config_from_angle(segmentangle, 0);
+ outsidepos = 0;
+ }
+ else
+ {
+ if (dist < distance1)
+ currentspeed = speed1;
+ else if (dist < distance2)
+ currentspeed = speed2;
+ else //if (dist < distance3)
+ currentspeed = speed3;
+ if (abx > 0)
+ {
+ if (amy / aml > aby / abl)
+ display_config_from_angle(segmentangle + M_PI_2, 1);
+ else
+ display_config_from_angle(segmentangle - M_PI_2, 1);
+ }
+ else if (abx < 0)
+ {
+ if (amy / aml > aby / abl)
+ display_config_from_angle(segmentangle - M_PI_2, 1);
+ else
+ display_config_from_angle(segmentangle + M_PI_2, 1);
+ }
+ else // abx == 0
+ {
+ if (aby > 0)
+ {
+ if (amx > 0)
+ display_config_from_angle(segmentangle - M_PI_2, 1);
+ else
+ display_config_from_angle(segmentangle + M_PI_2, 1);
+ }
+ else if (aby < 0)
+ {
+ if (amx > 0)
+ display_config_from_angle(segmentangle + M_PI_2, 1);
+ else
+ display_config_from_angle(segmentangle - M_PI_2, 1);
+ }
+ else // aby == 0 // should not happen
+ {
+ printf("Vector too short!\n");
+ display_config_from_angle(segmentangle, 1);
+ }
+ }
+ outsidepos = line_a * x() + line_b * y() + line_c;
+ }
+ }
+ }
+ else //we are too far => guide to the target
+ {
+ // if we are at the target
+ if (bml < stripwidth)
+ {
+ currentsegment++;
+ dprintf("Point %d/%d\n", currentsegment, shape.nbv);
+ //if we dit a complete lap
+ if (currentsegment >= shape.nbv)
+ {
+ dprintf("New lap\n");
+ currentsegment = 0;
+ }
+ abx = shape.x[(currentsegment + 1) % shape.nbv] - shape.x[currentsegment];
+ aby = shape.y[(currentsegment + 1) % shape.nbv] - shape.y[currentsegment];
+ abl = sqrt(abx * abx + aby * aby);
+ line_a = shape.y[(currentsegment + 1) % shape.nbv] - shape.y[currentsegment];
+ line_b = shape.x[currentsegment] - shape.x[(currentsegment + 1) % shape.nbv];
+ line_c = shape.x[(currentsegment + 1) % shape.nbv] * shape.y[currentsegment] - shape.x[currentsegment] * shape.y[(currentsegment + 1) % shape.nbv];
+
+ segmentangle = acos(abx / abl);
+ if (aby > -EPSILON)
+ segmentangle *= -1;
+ // dprintf("abx=%d, aby=%d, abl=%f, segmentangle=%f\n", abx, aby, abl, segmentangle);
+ display_config_from_angle(segmentangle, 0);
+// SDL_Delay(10);
+// continue;
+ }
+ else
+ {
+ if (bml < distance1)
+ currentspeed = speed1;
+ else if (bml < distance2)
+ currentspeed = speed2;
+ else //if (between < distance3)
+ currentspeed = speed3;
+ double guideangle = acos((-bmx) / bml);
+ if (bmy < 0)
+ guideangle *= -1;
+ display_config_from_angle(guideangle, 1);
+ }
+/* double guideangle = acos(bmx / bml);
+ if (bmy > 0)
+ guideangle *= -1;
+ guideangle += segmentangle - M_PI;
+ display_config_from_angle(guideangle, 1);*/
+ }
+// temp++;
+// if (temp % 100 == 0)
+// dprintf("pins_thread still alive %d, tacton=%08lx %d:%d\n", temp, tacton, sec, msec);
+
+ SDL_Delay(10);
+ }
+ dprintf("Destroying Tacton Mutex\n");
+ SDL_DestroyMutex(tacton_mutex);
+ dprintf("Pins thread quitting\n");
+ return (0);
+}
+
+SDL_Thread *create_pins_thread()
+{
+ SDL_Thread *r;
+ //load theTactons set
+// printf("Load the tactons\n");
+// load_set(get_params("tactonsfile"));
+ dprintf("Create the tacton mutex\n");
+ if((tacton_mutex = SDL_CreateMutex()) == NULL)
+ {
+ printf("Error while creating the mutex : %s\n", SDL_GetError());
+ return NULL;
+ }
+ dprintf("Create the pins thread\n");
+ if ((r = SDL_CreateThread(pins_thread, NULL)) == NULL)
+ {
+ printf("Impossible to run the pins thread: %s\n", SDL_GetError());
+ return NULL;
+ }
+ return r;
+}
+
+u32 getpixel(int x, int y)
+{
+ if (x < 0)
+ x = 0;
+ if (x >= resol_x)
+ x = resol_x - 1;
+ if (y < 0)
+ y = 0;
+ if (y >= resol_y)
+ y = resol_y - 1;
+ int pixel = 4 * (x + (resol_y - y - 1) * resol_x);
+
+ if (shapepixels[pixel])
+ return 0x00000000;
+ else
+ return 0xffffffff;
+}
+
+int translation_thread(void *p)
+{
+// int temp = 0;
+ int (*x)(), (*y)();
+ if (condition == CONDITION_PV)
+ {
+ x = get_mouse_x;
+ y = get_mouse_y;
+ }
+ else// if (strcmp(get_params("condition"),"Mv") == 0)
+ {
+ x = get_vtp_x;
+ y = get_vtp_y;
+ }
+
+ struct timeval *now = (struct timeval *) malloc(sizeof(struct timeval));
+ struct timeval *start = (struct timeval *) malloc(sizeof(struct timeval));
+ gettimeofday(start, NULL);
+ while (running)
+ {
+ gettimeofday(now, NULL);
+ int sec = now->tv_sec - start->tv_sec;
+ int msec = (now->tv_usec - start->tv_usec) / 1000;
+ if (logfile)
+ fprintf(logfile, "%ld;%d;%d;%08lx\n", 1000 * (long int)sec + msec, x(), resol_y - y() - 1, tacton);
+// else
+// dprintf("Error with logfile\n");
+ //if maxtime is elapsed we exit the test
+ if (sec > maxtime && !training)
+ {
+ dprintf("time : %d/%d\n", sec, maxtime);
+ running = 0;
+ break;
+ }
+
+// printf("%d %d\n", x(), y());
+// LOCK;
+ tacton =
+ (0x80000000 & getpixel(x() + 2, y() + 2)) + \
+ (0x40000000 & getpixel(x() + 1, y() + 2)) + \
+ (0x20000000 & getpixel(x(), y() + 2)) + \
+ (0x10000000 & getpixel(x() - 1, y() + 2)) + \
+ (0x08000000 & getpixel(x() + 2, y() + 1)) + \
+ (0x04000000 & getpixel(x() + 1, y() + 1)) + \
+ (0x02000000 & getpixel(x(), y() + 1)) + \
+ (0x01000000 & getpixel(x() - 1, y() + 1)) + \
+ (0x00800000 & getpixel(x() + 2, y())) + \
+ (0x00400000 & getpixel(x() + 1, y())) + \
+ (0x00200000 & getpixel(x(), y())) + \
+ (0x00100000 & getpixel(x() - 1, y())) + \
+ (0x00080000 & getpixel(x() + 2, y() - 1)) + \
+ (0x00040000 & getpixel(x() + 1, y() - 1)) + \
+ (0x00020000 & getpixel(x(), y() - 1)) + \
+ (0x00010000 & getpixel(x() - 1, y() - 1));
+ if (((condition == CONDITION_MV) && !left_handed) || (!(condition == CONDITION_MV) && left_handed))
+ tacton >>= 16;
+ set_pads(tacton);
+// UNLOCK;
+ SDL_Delay(30);
+ }
+ if (now)
+ free(now);
+ if (start)
+ free(start);
+ dprintf("Translation thread quitting\n");
+ return(0);
+}
+
+SDL_Thread *create_translation_thread()
+{
+ SDL_Thread *r;
+ //load theTactons set
+ dprintf("Create the conversion thread\n");
+ if ((r = SDL_CreateThread(translation_thread, NULL)) == NULL)
+ {
+ printf("Impossible to run the translation thread: %s\n", SDL_GetError());
+ return NULL;
+ }
+ return r;
+}
+
+#undef LOCK
+#undef UNLOCK
--- /dev/null
+#include <SDL/SDL.h>
+#include <SDL/SDL_ttf.h>
+#include <SDL/SDL_keysym.h>
+#include <SDL/SDL_opengl.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define COLOR_FOND 0.2, 0.2, 0.2
+#include "instructions.h"
+#include "vtplayer-ctrl.h"
+#include "divers.h"
+#include "evenements.h"
+#include "icons.h"
+
+#ifndef __DEMO__
+#include "ecrire.h"
+#endif
+
+Text *ttt[8];
+
+void draw_screen_ins(int min_ecran_x, int min_ecran_y, int max_ecran_x, int max_ecran_y, TTF_Font *font, int mousex, int mousey)
+{
+ glClearColor(COLOR_FOND, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+#ifndef __DEMO__
+// #if 0
+ SDL_Rect position;
+ position.x = - 600;
+ position.y = 450;
+ // Règle ********************************************************************************
+ drawText(*(ttt[0]), &position);
+ position.y -= 20;
+ drawText(*(ttt[1]), &position);
+ position.y -= 20;
+ drawText(*(ttt[2]), &position);
+ position.y -= 20;
+ drawText(*(ttt[3]), &position);
+ position.y -= 20;
+ drawText(*(ttt[4]), &position);
+ position.y -= 20;
+ drawText(*(ttt[5]), &position);
+ position.y -= 20;
+ drawText(*(ttt[6]), &position);
+
+ position.y = - 400;
+ position.x = - 410;
+ drawText(*(ttt[7]), &position);
+#else
+ // beuark
+// #ifdef __WIN32
+// Sleep(5);
+// #else
+// usleep(5000);
+// #endif
+ SDL_Delay(5);
+#endif
+
+ draw_cubes();
+
+ //curseur VTPLAYER
+ draw_cursor(mousex, mousey);
+// SDL_Delay(5);
+
+ SDL_GL_SwapBuffers();
+}
+
+void instructions(TTF_Font *font, int *pinsconfig, int min_ecran_x, int min_ecran_y, int max_ecran_x, int max_ecran_y )
+{
+ int mx;
+ int my;
+ struct events_t evt;
+ int pins = -1;
+ int i;
+ for (i = 0 ; i < 8 ; i++)
+ ttt[i] = NULL;
+ SDL_Color color;
+ color.r = 255;
+ color.g = 255;
+ color.b = 255;
+ ttt[0] = SDL_GL_RenderText("Vous allez sentir des icones par les cellules braille. Elles représentent 8", font, color);
+ ttt[1] = SDL_GL_RenderText("directions : haut, bas, droite, gauche, en haut à gauche, en bas à gauche, en", font, color);
+ ttt[2] = SDL_GL_RenderText("haut à droite et en bas à droite. ", font, color);
+ ttt[3] = SDL_GL_RenderText("A chaque étape vous sentirez une seule icône : vous devez cliquer dans la zone", font, color);
+ ttt[4] = SDL_GL_RenderText("correspondant à la direction que vous avez senti. Cela arrêtera l'icône. Pour", font, color);
+ ttt[5] = SDL_GL_RenderText("déclencher la suivante vous devez revenir dans la zone centrale.", font, color);
+ ttt[6] = SDL_GL_RenderText("Vous pouvez découvrir les icones dans les cases du carré ci-dessous.", font, color);
+ ttt[7] = SDL_GL_RenderText("Pressez sur Enter pour commencer quand vous serez prêt.", font, color);
+
+ while(1)
+ {
+ evt = process_events();
+ mx = get_mouse_x();
+ my = get_mouse_y();
+
+ //exemple
+ if ((pins = dans_cube(mx, my)) == CENTRE)
+ *pinsconfig = NULLE_PART;
+ else
+ *pinsconfig = pins;
+
+ if (evt.symbol == SDLK_RETURN)
+ break;
+ else if (evt.symbol == SDLK_ESCAPE)
+ exit(1);
+
+// SDL_Delay(50);
+ draw_screen_ins(min_ecran_x, min_ecran_y, max_ecran_x, max_ecran_y, font, mx, my);
+// SDL_Delay(70);
+ glFinish();
+ }
+ *pinsconfig = NULLE_PART;
+ for (i = 0 ; i < 8 ; i++)
+ freeText(ttt[i]);
+}
--- /dev/null
+#include "params.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "divers.h"
+param_list *list_params = NULL;
+
+int is_caracter(char c)
+{
+ return (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9');// || c == 'é' || c == 'è' || c == 'ç' || c == 'à' || c == 'â' || c == 'ê' || c == 'î' || c == 'ô' || c == 'û' ||c == 'ä' || c == 'ë' || c == 'ï' || c == 'ö' || c == 'ü';
+}
+
+void read_file_params()//, int *nbtests, int *gridsize, int *precision)
+{
+ FILE *fp;
+ int i;
+ char buffer[BUFFERSIZE + 1], name[BUFFERSIZE + 1], value[BUFFERSIZE + 1];
+
+ char *namebuffer;
+ if (fileExists("params"))
+ namebuffer = "params";
+ else if (fileExists("data/params"))
+ namebuffer = "data/params";
+ else if (fileExists("../data/params"))
+ namebuffer = "../data/params";
+ else
+ {
+ printf("Could not find the parameters file\n");
+ return;
+ }
+
+ if ((fp = fopen(namebuffer, "r")) == NULL)
+ {
+ printf("Impossible to read the parameters, using defaults\n");
+ return;
+ }
+ while(fgets(buffer, BUFFERSIZE, fp) != NULL)
+ {
+ if (buffer[0] == '#')
+ continue;
+ memset(name, 0, BUFFERSIZE + 1);
+ memset(value, 0, BUFFERSIZE + 1);
+ i = 0;
+ while(buffer[i] != '=' && i < strlen(buffer))
+ {
+ if (is_caracter(buffer[i]))
+ name[strlen(name)] = buffer[i];
+ i++;
+ }
+ i++;
+ while(i < strlen(buffer))
+ {
+ if (is_caracter(buffer[i]))
+ value[strlen(value)] = buffer[i];
+ i++;
+ }
+ add_param(name, value);
+ }
+ fclose (fp);
+}
+
+int read_command_params(int argc, char *argv[])
+{
+ int i, nb=0;
+ char *name = NULL;
+ for (i = 1 ; i < argc ; i++)
+ {
+ if (argv[i][0] == '-')
+ name = argv[i] + 1;
+ else if (name != NULL)
+ {
+ add_param(name, argv[i]);
+ name = NULL;
+ nb++;
+ }
+ else
+ return -1;
+ }
+ return nb;
+}
+
+void add_param(char *name, char *value)
+{
+ param_list *new = (param_list *) malloc(sizeof(param_list));
+ new->name = strdup(name);
+ new->value = strdup(value);
+ new->next = list_params;
+ list_params = new;
+}
+
+//get one of the parameters value
+char *get_params(char *name)
+{
+ param_list *temp = list_params;
+ while(temp)
+ {
+ if (strcmp(temp->name, name) == 0)
+ return temp->value;
+ temp = temp->next;
+ }
+ return NULL;
+}
+
+void display_params()
+{
+ param_list *temp = list_params;
+ while(temp)
+ {
+ printf("%s = %s\n", temp->name, temp->value);
+ temp = temp->next;
+ }
+}
+
+void delete_params(param_list *l)
+{
+ if (l)
+ {
+ delete_params(l->next);
+ free(l->name);
+ free(l->value);
+ free(l);
+ }
+}
--- /dev/null
+#include <SDL/SDL.h>
+#include <SDL/SDL_opengl.h>
+#include <SDL/SDL_ttf.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <math.h>
+
+#include "ecrire.h"
+#include "saisienom.h"
+#include "instructions.h"
+#include "vtplayer-ctrl.h"
+#include "divers.h"
+#include "fini.h"
+#include "evenements.h"
+#include "icons.h"
+
+#ifdef __WIN32
+#include "gettimeofday.h"
+#endif
+
+#define TAILLE_PROGRESSIONBAR 500
+
+#define COLOR_FOND 0.8, 0.8, 0.8
+
+//default values for these parameters
+#define NBTESTS 100
+#define TAILLE_GRILLE 10
+//1000000 = s
+//1000 = ms
+//1 = s
+#define PRECISION_TIME 1000
+#define ANIMATION_SPEED 100
+
+SDL_Surface *Screen, *text;
+char fontpath[] = "../data/FreeMono.ttf";
+char fontpath2[] = "../data/police.ttf";
+char paramsfile[] = "../data/params";
+
+struct params_type
+{
+ int nbparams;
+ char **names;
+ int **values;
+} params_vals;
+
+Text *t1;
+Text *t2;
+int lastnb;
+
+void draw_progressionbar(TTF_Font *font, int current, int total, int px, int py, int tx, int ty)
+{
+ int largeurprogression = (current * tx) / total;
+ glColor3d(0.0, 0.8, 0.0);
+ glDisable(GL_BLEND);
+ glBegin(GL_POLYGON);
+ glVertex2d(px - tx / 2, py + ty);
+ glVertex2d(px + largeurprogression - tx / 2, py + ty);
+ glVertex2d(px + largeurprogression - tx / 2, py);
+ glVertex2d(px - tx / 2, py);
+ glEnd();
+ glColor3d(0.0, 0.0, 0.0);
+ glBegin(GL_POLYGON);
+ glVertex2d(px + largeurprogression - tx / 2, py + ty);
+ glVertex2d(px + tx / 2, py + ty);
+ glVertex2d(px + tx / 2, py);
+ glVertex2d(px + largeurprogression - tx / 2, py);
+ glEnd();
+ glEnable(GL_BLEND);
+
+ SDL_Rect position;
+ position.x = - 85;
+ position.y = py + 50;
+ SDL_Color color;
+ color.r = 255;
+ color.g = 0;
+ color.b = 0;
+ char buffer[BUFFERSIZE];
+ sprintf(buffer,"%d / %d", current, total);
+ if (t2 == NULL)
+ t2 = SDL_GL_RenderText(buffer, font, color);
+ else if (current > lastnb)
+ {
+ freeText(t2);
+ t2 = SDL_GL_RenderText(buffer, font, color);
+ }
+ drawText(*t2, &position);
+/* freeText(tt);*/
+}
+
+void draw_screen(TTF_Font *font, int mousex, int mousey, int current, int total)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ draw_cubes();
+
+ SDL_Color color;
+ color.r = 50;
+ color.g = 50;
+ color.b = 255;
+ SDL_Rect position;
+ position.x = - 100;
+ position.y = 400;
+
+ drawText(*t1, &position);
+
+ draw_progressionbar(font, current, total, 0, -400, TAILLE_PROGRESSIONBAR, 50);
+
+ //curseur VTPLAYER
+ draw_cursor(mousex, mousey);
+
+ SDL_GL_SwapBuffers();
+}
+
+SDL_Surface * setup_opengl( int width, int height, int min_screen_x, int min_screen_y, int max_screen_x, int max_screen_y)
+{
+ SDL_Surface * screen;
+
+ if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
+ {
+ printf("Couldn't initialise Video SubSystem: %s\n", SDL_GetError());
+ return NULL;
+ }
+
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8);
+
+ int flags = SDL_OPENGL | SDL_HWSURFACE | SDL_FULLSCREEN;
+ if (!(screen = SDL_SetVideoMode(width, height, 0, flags)))
+ {
+ printf("Impossible de changer le mode video : %s\n", SDL_GetError());
+ return NULL;
+ }
+
+ GLdouble ratio = (GLdouble) screen->w / screen->h;
+
+ printf("infos : %d %d %d %d\n", screen->flags, screen->w, screen->h, screen->pitch);
+ printf("Video resolution: %dx%dx%d (ratio = %3.2f)\n", screen->w, screen->h, screen->format->BitsPerPixel, ratio);
+ printf("OpenGL infos\n");
+ printf("------------\n");
+ printf("Vendor : %s\n", glGetString(GL_VENDOR));
+ printf("Renderer : %s\n", glGetString(GL_RENDERER));
+ printf("Version : %s\n", glGetString(GL_VERSION));
+ printf("Extensions: %s\n", glGetString(GL_EXTENSIONS));
+
+ glClearColor(COLOR_FOND, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D(min_screen_x, max_screen_x, min_screen_y, max_screen_y);//-ratio, ratio, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+// glBlendFunc(GL_ONE, GL_ONE);//GL_ONE_MINUS_DST_COLOR, GL_ONE);//GL_ONE, GL_ONE);
+// glEnable(GL_BLEND);
+
+ return screen;
+}
+
+void read_params(char *fichier)//, int *nbtests, int *gridsize, int *precision)
+{
+ FILE *fp;
+ int value = 0, i;
+ char buffer[BUFFERSIZE + 1], name[BUFFERSIZE + 1];
+
+ if ((fp = fopen(fichier, "r")) == NULL)
+ {
+ printf("Impossible to read the parameters, using defaults\n");
+ return;
+ }
+ while(fgets(buffer, BUFFERSIZE, fp) != NULL)
+ {
+ if (buffer[0] == '#')
+ continue;
+ memset(name, 0, BUFFERSIZE+1);
+ value = 0;
+ i = 0;
+ while(buffer[i] != '=' && i < strlen(buffer))
+ {
+#ifdef __DEBUG__
+ printf("%c", buffer[i]);
+#endif
+ if (buffer[i] >= 'a' && buffer[i] <= 'z')
+ name[strlen(name)] = buffer[i];
+ i++;
+ }
+#ifdef __DEBUG__
+ printf("%c", buffer[i]);
+#endif
+ i++;
+#ifdef __DEBUG__
+ printf("%c", buffer[i]);
+#endif
+ while(i < strlen(buffer))
+ {
+#ifdef __DEBUG__
+ printf("%c", buffer[i]);
+#endif
+ if (buffer[i] >= '0' && buffer[i] <= '9')
+ value = value * 10 + buffer[i] - '0';
+ i++;
+ }
+
+ for (i = 0 ; i < params_vals.nbparams ; i++)
+ {
+ if (strcmp(name, params_vals.names[i]) == 0)
+ {
+#ifdef __DEBUG__
+ printf("=> %s = %d\n", name, value);
+#endif
+ *(params_vals.values[i]) = value;
+ }
+ }
+ }
+ fclose (fp);
+}
+
+//retourne des centiemes de secondes
+int diff_time (struct timeval *debut, int precision)
+{
+ struct timeval *fin = (struct timeval *) malloc(sizeof(struct timeval));
+ gettimeofday(fin, NULL);
+
+ int sec = fin->tv_sec - debut->tv_sec;
+ int msec = fin->tv_usec - debut->tv_usec;
+
+ free(fin);
+
+/* if (msec < 0)
+ return (1000 * (sec - 1) + msec)/(PRECISION_TIME*PRECISION_TIME) + PRECISION_TIME;
+ else*/
+ return (1000000 * sec + msec)/precision;
+}
+
+int main (int argc, char *argv[])
+{
+#ifndef __DEMO__
+ FILE *fp = NULL, *fpserie = NULL;
+ char *nom = NULL, *logfile = NULL;
+#endif
+ const SDL_VideoInfo* info = NULL;
+ TTF_Font *font, *fontsmall, *fontcursive;
+ int numset = -1, nbtests = NBTESTS, gridsize = TAILLE_GRILLE, precision = PRECISION_TIME, animationspeed = ANIMATION_SPEED;
+ char gaucher;
+
+ if (argc > 1)
+ {
+ sscanf(argv[1], "%d", &numset);
+ if (argc > 2)
+ sscanf(argv[2], "%c", &gaucher);
+ }
+ else
+ {
+ printf("Usage : shapes [iconsnumber] [g]\n");
+ return 1;
+ }
+
+ params_vals.nbparams = 4;
+ params_vals.names = (char **) malloc(4 * sizeof(char *));
+ params_vals.values = (int **) malloc(4 * sizeof(int *));
+ params_vals.names[0] = strdup("nbtests");
+ params_vals.values[0] = &nbtests;
+ params_vals.names[1] = strdup("gridsize");
+ params_vals.values[1] = &gridsize;
+ params_vals.names[2] = strdup("precisiontime");
+ params_vals.values[2] = &precision;
+ params_vals.names[3] = strdup("animationspeed");
+ params_vals.values[3] = &animationspeed;
+ read_params(paramsfile);
+
+ atexit(SDL_Quit);
+
+ if( SDL_Init(SDL_INIT_VIDEO) <0 )
+ {
+ printf("Error while loading SDL: %s\n", SDL_GetError());
+ return 1;
+ }
+ info = SDL_GetVideoInfo();
+ if(!info)
+ {
+ printf("Impossible to get SDL information: %s\n", SDL_GetError());
+ return 1;
+ }
+ if(TTF_Init())
+ {
+ printf("Erreur while loading TTF: %s\n", TTF_GetError());
+ return 1;
+ }
+ if(!(font = TTF_OpenFont(fontpath, 50)))
+ {
+ printf("Erreur while loading the font: %s\n", TTF_GetError());
+ return 1;
+ }
+ if(!(fontcursive = TTF_OpenFont(fontpath2, 50)))
+ {
+ printf("Erreur while loading the font: %s\n", TTF_GetError());
+ return 1;
+ }
+ if(!(fontsmall = TTF_OpenFont(fontpath, 25)))
+ {
+ printf("Erreur while loading the font: %s\n", TTF_GetError());
+ return 1;
+ }
+ if (init_vtplayer())
+ {
+#ifdef __linux__
+ printf("Impossible to find the VTPlayer! Are you root?\n");
+#else
+ printf("Impossible to find the VTPlayer! Try to unplug/replug it.\n");
+#endif
+ return 1;
+ }
+
+ int * pinsconfig;
+ pinsconfig = (int *) malloc(sizeof(int));
+ *pinsconfig = -1;
+ if (create_pins_thread(pinsconfig, numset, animationspeed, gaucher))
+ {
+ printf("Impossible to create the tactile display thread\n");
+ return 1;
+ }
+
+ if (create_mouse_status_thread())
+ {
+ printf("Impossible tu create the mouse events thread\n");
+ return 1;
+ }
+
+ int width, height;
+ SDL_Rect **modes;
+ modes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);
+ if (modes == NULL)
+ {
+ printf("Impossible to find the screen resolution!\n");
+ return 1;
+ }
+ else if (modes == (SDL_Rect **)-1)
+ {
+ width = 1024;
+ height = 768;
+ }
+ else
+ {
+ width = modes[0]->w;
+ height = modes[0]->h;
+ }
+
+ int max_screen_x = (int)(500 *((float) width) / ((float) height));
+ int min_screen_x = - max_screen_x;
+ int max_screen_y = 500;
+ int min_screen_y = - max_screen_y;
+
+ set_max_screen_x(max_screen_x);
+ set_max_screen_y(max_screen_y);
+ set_min_screen_x(min_screen_x);
+ set_min_screen_y(min_screen_y);
+
+// SDL_Surface *screen =
+ setup_opengl(width, height, min_screen_x, min_screen_y, max_screen_x, max_screen_y);
+
+ load_cursor("../data/cursor.png");
+
+#ifndef __DEMO__
+ //on lit le nom de l'utilisateur
+ //en verifiant que ce nom n'est pas deja utilise
+ do
+ {
+ if (nom != NULL)
+ free (nom);
+ if (logfile != NULL)
+ free (logfile);
+ nom = nomuser(min_screen_x, min_screen_y, max_screen_x, max_screen_y, font, fontcursive);
+ if ( fp != NULL )
+ fclose(fp);
+ if (strlen(nom) > 0)
+ {
+ logfile = logfilename(nom, numset);
+ fp = fopen (logfile, "r");
+ }
+ }
+ while ( strlen(nom) == 0 || fp != NULL );
+
+ //logfile = logfilename(nom, numset);
+ if (logfile == NULL || (fp = fopen (logfile, "w")) == NULL)
+ {
+ printf("Impossible to create the log file: %s\n", logfile);
+ return 1;
+ }
+
+ int grille_x = 0;
+ int grille_y = 0;
+ int mx, my;
+#endif
+
+ //affichage des instructions
+ instructions(fontsmall, pinsconfig, min_screen_x, min_screen_y, max_screen_x, max_screen_y);
+#ifndef __DEMO__
+
+ SDL_Color color;
+ color.r = 255;
+ color.g = 0;
+ color.b = 0;
+ t1 = SDL_GL_RenderText("Tests !", font, color);
+ t2 = NULL;
+ lastnb = -1;
+
+ //on dessine le nouvel ecran
+ glClearColor(COLOR_FOND, 1.0);
+ draw_screen (font, 0, 0, 0, nbtests);
+
+ //on lit la serie
+ char *seriefile = (char *) malloc((6 + (int)log10(numset) + 10) * sizeof(char));
+ sprintf(seriefile, "icons%d/serie%03d", numset, nbtests);
+ logfilename("serie", numset);
+ if ((fpserie = fopen (seriefile, "r")) == NULL)
+ generer_serie(seriefile, nbtests);
+ else if (!serie_ok(fpserie, nbtests))
+ {
+ fclose(fpserie);
+ generer_serie(seriefile, nbtests);
+ }
+ if ((fpserie = fopen (seriefile, "r")) == NULL)
+ {
+ printf("Impossible de lire la nouvelle serie\n");
+ return 1;
+ }
+
+ char tampon[16];
+ struct events_t evt;
+ struct timeval *depart = (struct timeval *) malloc(sizeof(struct timeval));
+ gettimeofday(depart, NULL);
+ int current = 0;
+
+ while (fgets (tampon, sizeof tampon, fpserie) != NULL)
+ {
+ //on lit le caractere a afficher"
+ if (sscanf(tampon,"%d", pinsconfig) != 1)
+ *pinsconfig = NULLE_PART;
+
+ //traite tout le bouzin tant que l'utilisateur n'a pas clique
+ while(1)
+ {
+ evt = process_events();
+ if (evt.buttons)
+ break;
+ if (evt.symbol == SDLK_ESCAPE)
+ {
+ fclose(fp);
+ exit(1);
+ }
+
+ //si la souris est dans une autre case de la grille on loggue
+ mx = get_mouse_x();
+ my = get_mouse_y();
+ if (mx / gridsize != grille_x || my / gridsize != grille_y)
+ {
+ grille_x = mx / gridsize;
+ grille_y = my / gridsize;
+ fprintf(fp, "%4d ; %4d ; %4d ; %4d\n", diff_time(depart, precision), grille_x, grille_y, dans_cube(mx, my));
+ }
+ draw_screen(font, get_mouse_x(), get_mouse_y(), current, nbtests);
+ glFinish();
+ SDL_Delay(10);
+ }
+ fprintf(fp, "%4d ; %4d ; %4d ; %4d ; %4d\n", diff_time(depart, precision), grille_x, grille_y, dans_cube(mx, my), *pinsconfig);
+ //il a clique : on coupe l'icone
+ *pinsconfig = NULLE_PART;
+ //on attend que le bouton soit relache et que l'utilisateur revienne au centre
+ while(1)
+ {
+ evt = process_events();
+ mx = get_mouse_x();
+ my = get_mouse_y();
+ if (!evt.buttons && dans_cube(mx, my) == CENTRE)
+ break;
+ if (evt.symbol == SDLK_ESCAPE)
+ {
+ fclose(fp);
+ exit(1);
+ }
+
+ //si la souris est dans une autre case de la grille on loggue
+ if (mx / gridsize != grille_x || my / gridsize != grille_y)
+ {
+ grille_x = mx / gridsize;
+ grille_y = my / gridsize;
+ fprintf(fp, "%4d ; %4d ; %4d ; %4d\n", diff_time(depart, precision), grille_x, grille_y, dans_cube(mx, my));
+ }
+ draw_screen(font, mx, my, current, nbtests);
+ glFinish();
+ SDL_Delay(10);
+ }
+ current++;
+ }
+ fclose(fp);
+ freeText(t1);
+ freeText(t2);
+
+ fini(fontcursive, logfile, min_screen_x, min_screen_y, max_screen_x, max_screen_y);
+#endif
+ return 0;
+}
--- /dev/null
+// xsetwacom set stylus bottomx 12700 ; xsetwacom set stylus bottomy 20300
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_opengl.h>
+#include <SDL/SDL_image.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+#include <math.h>
+
+#include "divers.h"
+#include "vtplayer-ctrl.h"
+#include "icons.h"
+#include "evenements.h"
+#include "params.h"
+#include "display.h"
+#include "guidance.h"
+#define COLOR_FOND 1.0, 1.0, 1.0
+
+extern param_list *list_params;
+extern const SDL_VideoInfo *info;
+extern SDL_Surface *screen;
+extern int *pinsconfig;
+extern int currentdirection;
+extern int max_screen_x;
+extern int min_screen_x;
+extern int max_screen_y;
+extern int min_screen_y;
+extern int resol_x;
+extern int resol_y;
+extern unsigned char *shapepixels;
+int left_handed = 0;
+int condition = 0;
+FILE *logfile = NULL;
+int running = 1;
+int maxtime = 180;
+int training = 0;
+
+#ifdef DEBUG
+#define dprintf(x...) printf(x)
+#else
+#define dprintf(x...)
+#endif
+
+int main(int argc, char *argv[])
+{
+ //user name and condition
+ char *name = NULL, *conditionname = NULL, *shape = NULL, *tempstring = NULL;
+
+ if (argc > 1 && read_command_params(argc, argv) > 0)
+ {
+ name = get_params("name");
+ conditionname = get_params("condition");
+ if (conditionname && (strcmp(conditionname, "Pt") == 0))
+ condition = CONDITION_PT;
+ else if (conditionname && (strcmp(conditionname, "Pv") == 0))
+ condition = CONDITION_PV;
+ else if (conditionname && (strcmp(conditionname, "Mt") == 0))
+ condition = CONDITION_MT;
+ else if (conditionname && (strcmp(conditionname, "Mv") == 0))
+ condition = CONDITION_MV;
+ shape = get_params("shape");
+ tempstring = get_params("hand");
+ if (tempstring && (strcmp(tempstring, "left") == 0))
+ left_handed = 1;
+ tempstring = get_params("training");
+ if (tempstring && (strcmp(tempstring, "yes") == 0))
+ training = 1;
+ }
+ else
+ {
+ printf("Usage : shapes -name username -condition Pt|Pv|Mt|Mv -shape shapefile [-hand left]\n");
+ display_params();
+ return 1;
+ }
+
+ time_t tim = time(NULL);
+ struct tm *t = gmtime(&tim);
+
+ if (name)
+ {
+ char logfilename[BUFFERSIZE+1];
+ snprintf(logfilename, BUFFERSIZE, "%s-%s-%04d-%02d-%02d-%02d-%02d-%02d-%s", name, conditionname, 1900 + t->tm_year, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, shape);
+ dprintf("Logfile: %s\n",logfilename);
+ logfile = fopen(logfilename, "w");
+ if (logfile)
+ dprintf("logfile OK\n");
+ else
+ {
+ dprintf("Error with logfile\n");
+ return 1;
+ }
+ }
+
+ //read parameters
+ read_file_params();
+ tempstring = get_params("maxtime");
+ if (tempstring)
+ maxtime = atoi(tempstring);
+ display_params();
+
+ //initialize everything: SDL, VTPlayer, etc.
+#ifndef WITHOUTVTP
+ dprintf("Loading VTPlayer\n");
+ if (init_vtplayer())
+ {
+#ifdef __linux__
+ printf("Impossible to find the VTPlayer! Are you root?\n");
+#else
+ printf("Impossible to find the VTPlayer! Try to unplug/replug it.\n");
+#endif
+ return 1;
+ }
+#endif
+
+ atexit(SDL_Quit);
+ dprintf("Loading SDL\n");
+ if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
+ {
+ printf("Error while loading SDL: %s\n", SDL_GetError());
+ return 1;
+ }
+
+ dprintf("Loading SDL VideoInfo\n");
+ if ((info = SDL_GetVideoInfo()) == NULL)
+ {
+ printf("Impossible to get SDL information: %s\n", SDL_GetError());
+ return 1;
+ }
+
+ dprintf("List video modes\n");
+ SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE);
+ if (modes == NULL)
+ {
+ printf("Impossible to find the screen resolution!\n");
+ return 1;
+ }
+ else if (modes == (SDL_Rect **)-1)
+ {
+ resol_x = 1024;
+ resol_y = 768;
+ }
+ else
+ {
+ resol_x = modes[0]->w;
+ resol_y = modes[0]->h;
+ }
+ dprintf("Resolution choosen: %dx%d\n", resol_x, resol_y);
+ max_screen_x = (int)(500 *((float) resol_x) / ((float) resol_y));
+ min_screen_x = - max_screen_x;
+ max_screen_y = 500;
+ min_screen_y = - max_screen_y;
+
+ dprintf("Init SDL subsystem\n");
+ if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
+ {
+ printf("Couldn't initialise Video SubSystem: %s\n", SDL_GetError());
+ return 1;
+ }
+
+ dprintf("Init GL Attributes\n");
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 8);
+
+ int flags = SDL_OPENGL | SDL_HWSURFACE | SDL_FULLSCREEN;
+// resol_x = 1024;
+// resol_y = 768;
+ dprintf("Set video mode %dx%d %08x\n", resol_x, resol_y, flags);
+ //this appears to cause the segfault at the end of the program
+ screen = SDL_SetVideoMode(resol_x, resol_y, 0, flags);
+
+ if (!screen)
+ {
+ printf("Impossible de changer le mode video : %s\n", SDL_GetError());
+ return 1;
+ }
+
+// SDL_LockSurface(screen);
+ GLdouble ratio = (GLdouble) screen->w / screen->h;
+ printf("infos : %08x %d %d %d\n", screen->flags, screen->w, screen->h, screen->pitch);
+ printf("Video resolution: %dx%dx%d (ratio = %3.2f)\n", screen->w, screen->h, screen->format->BitsPerPixel, ratio);
+// SDL_UnlockSurface(screen);
+
+ printf("OpenGL infos\n");
+ printf("------------\n");
+ printf("Vendor : %s\n", glGetString(GL_VENDOR));
+ printf("Renderer : %s\n", glGetString(GL_RENDERER));
+ printf("Version : %s\n", glGetString(GL_VERSION));
+ printf("Extensions: %s\n", glGetString(GL_EXTENSIONS));
+
+ glClearColor(COLOR_FOND, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ dprintf("Setting viewport\n");
+ glViewport(0, 0, resol_x, resol_y);
+ switch(glGetError())
+ {
+ case GL_INVALID_VALUE:
+ printf("Wrong resolution\n");
+ return 1;
+ case GL_INVALID_OPERATION:
+ printf("Check the position of the glViewport instruction\n");
+ return 1;
+ }
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ dprintf("Setting projection\n");
+ gluOrtho2D(0, resol_x, resol_y, 0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+// SDL_ShowCursor(SDL_DISABLE);
+
+ dprintf("Load shape\n");
+ if (load_shape(shape))
+ {
+ printf("Failed to load the shape '%s'\n", shape);
+ return 1;
+ }
+
+ //we store the pixels of the shape vir the visual => tactile transation
+ glClearColor(1.0, 1.0, 1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ dprintf("Draw shape\n");
+ draw_shape();
+ dprintf("%dx%d : %d pixels\n", resol_x, resol_y, 4 * resol_x * resol_y);
+
+ shapepixels = (unsigned char *) malloc(4 * resol_x * resol_y);
+ if (!shapepixels)
+ printf("Impossible to store the pixels\n");
+ glReadPixels(0, 0, resol_x, resol_y, GL_RGBA, GL_UNSIGNED_BYTE, shapepixels);
+#ifdef DEBUG
+ SDL_Surface *temp;
+ if (!(temp = SDL_CreateRGBSurface(SDL_SWSURFACE, resol_x, resol_y, 32,
+ #if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
+ #else
+ 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
+ #endif
+ )))
+ return 1;
+ int i;
+ for (i = 0 ; i < resol_y ; i++)
+ memcpy(((char *) temp->pixels) + temp->pitch * i, shapepixels + 4 * resol_x * (resol_y - 1 - i), resol_x * 4);
+
+ int nbpixels = 0;
+ for (i = 0 ; i < 4 * resol_x * resol_y ; i += 4)
+ if (!shapepixels[i])
+ nbpixels++;
+ printf("\033[31m%d pixels colorés\033[0m, %d total\n", nbpixels, resol_x * resol_y);
+
+ char screenshotstring[BUFFERSIZE];
+ sprintf(screenshotstring, "%s.bmp", shape);
+ dprintf("Save screenshot %s\n", screenshotstring);
+ SDL_SaveBMP(temp, screenshotstring);
+ SDL_FreeSurface(temp);
+#endif
+// for (int i = 0 ; i < resolution[C_Y] ; i++)
+// memcpy(((char *) temp->pixels) + temp->pitch * i, pixels + 4 * resolution[C_X] * (resolution[C_Y] - i - 1), resolution[C_X] * 4);
+
+ SDL_Thread *mouse_status_thread = NULL, *tacton_thread = NULL, *pins_thread = NULL, *translation_thread = NULL;
+ //run the threads
+ switch (condition)
+ {
+ case CONDITION_MT:
+ if ((mouse_status_thread = create_mouse_status_thread()) == NULL)
+ {
+ printf("Impossible tu create the mouse events thread\n");
+ return 1;
+ }
+ case CONDITION_PT:
+ dprintf("Conditions T\n");
+ if ((tacton_thread = create_tacton_thread()) == NULL)
+ {
+ printf("Impossible to create the tactons thread\n");
+ return 1;
+ }
+ if ((pins_thread = create_pins_thread()) == NULL)
+ {
+ printf("Impossible to create the tactile display thread\n");
+ return 1;
+ }
+ break;
+ case CONDITION_MV:
+ if ((mouse_status_thread = create_mouse_status_thread()) == NULL)
+ {
+ printf("Impossible tu create the mouse events thread\n");
+ return 1;
+ }
+ case CONDITION_PV:
+ dprintf("Conditions V\n");
+ if ((translation_thread = create_translation_thread()) == NULL)
+ {
+ printf("Impossible to create the tactile display thread\n");
+ return 1;
+ }
+ break;
+ }
+
+ struct events_t evt;
+ while(running)
+ {
+ evt = process_events();
+ if (evt.symbol == SDLK_ESCAPE)
+ break;
+// currentdirection = (currentdirection + 1) % 9;
+ draw_screen();
+ glFinish();
+ SDL_Delay(10);
+ }
+ running = 0;
+ set_pads(0);
+
+
+ dprintf("Wait for the Threads\n");
+ int status;
+ if (mouse_status_thread)
+ {
+ dprintf("Wait mouse_status_thread\n");
+ SDL_WaitThread(mouse_status_thread, &status);
+ dprintf("Thread mouse_status_thread : %d\n", status);
+// SDL_KillThread(mouse_status_thread);
+ }
+ if (tacton_thread)
+ {
+ dprintf("Wait tacton_thread\n");
+ SDL_WaitThread(tacton_thread, &status);
+ dprintf("Thread tacton_thread : %d\n", status);
+// SDL_KillThread(tacton_thread);
+ }
+ if (pins_thread)
+ {
+ dprintf("Wait pins_thread\n");
+ SDL_WaitThread(pins_thread, &status);
+ dprintf("Thread pins_thread : %d\n", status);
+// SDL_KillThread(pins_thread);
+ }
+ if (translation_thread)
+ {
+ dprintf("Wait translation_thread\n");
+ SDL_WaitThread(translation_thread, &status);
+ dprintf("Thread translation_thread : %d\n", status);
+// SDL_KillThread(translation_thread);
+ }
+ if (name)
+ {
+ dprintf("Closes the logfile\n");
+ fclose(logfile);
+ }
+ dprintf("Unloads the shape\n");
+ unload_shape();
+ dprintf("Frees the surface\n");
+ if (shapepixels)
+ free(shapepixels);
+ dprintf("Deletes the parameters\n");
+ delete_params(list_params);
+ dprintf("Shows the cursor back\n");
+// SDL_ShowCursor(SDL_ENABLE);
+ dprintf("Freeing the screen\n");
+ if (screen)
+ SDL_FreeSurface(screen);
+// dprintf("Quit subsystem\n");
+// SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
+// dprintf("Quit SDL\n");
+// SDL_Quit();
+
+ dprintf("The end\n");
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <usb.h>
+#include <errno.h>
+#include "vtplayer-ctrl.h"
+
+#include "control_request.h"
+
+#define STRLEN 1024
+
+// Vendir ID and Product ID (see lsusb)
+int VID = 0x1100;
+int PID = 0x0001;
+
+#define TIMEOUT 100
+
+#ifdef DEBUG
+#define dprintf(x...) printf(x)
+#else
+#define dprintf(x...)
+#endif
+
+usb_dev_handle * vtplayer_handle = NULL;
+u32 lasttacton = 0;
+
+int init_vtplayer(void)
+{
+ struct usb_bus * bus;
+ struct usb_device * dev;
+#ifdef __linux__
+ char buf[STRLEN];
+#endif
+
+ dprintf("Init usb\n");
+ usb_init();
+ dprintf("Find busses\n");
+ usb_find_busses();
+ dprintf("Find devices\n");
+ usb_find_devices();
+
+ dprintf("Explore busses\n");
+ for (bus = usb_get_busses(); bus; bus = bus->next)
+ {
+ dprintf("Parsing usb bus %s.\n", bus->dirname);
+ for (dev = bus->devices; dev; dev = dev->next)
+ {
+ dprintf(" Parsing usb device [%04X:%04X] %s\n", dev->descriptor.idVendor, dev->descriptor.idProduct, dev->filename);
+
+ if ((dev->descriptor.idVendor == VID) && (dev->descriptor.idProduct == PID))
+ {
+ if (vtplayer_handle)
+ {
+ printf("Another vtplayer is connected. Please remove one.\n");
+// return -1;
+ }
+ dprintf("Found vtplayer. Opening interface.\n");
+ if (!(vtplayer_handle = usb_open(dev)))
+ {
+ perror("vtplayer");
+ return -1;
+ }
+#ifdef __linux__
+ if (usb_get_driver_np(vtplayer_handle, 0, buf, STRLEN) == 0)
+ {
+ dprintf("Done. Interface is bound to driver %s, detaching.\n", buf);
+ if (usb_detach_kernel_driver_np(vtplayer_handle, 0) < 0)
+ {
+ perror("vtplayer");
+ return -1;
+ }
+ }
+#endif
+ dprintf("Done. Setting configuration.\n");
+ if (usb_set_configuration(vtplayer_handle, dev->config[0].bConfigurationValue) < 0)
+ {
+ perror("vtplayer");
+ return -1;
+ }
+ dprintf("Done. Claiming interface.\n");
+ if (usb_claim_interface(vtplayer_handle, 0) < 0)
+ {
+ perror("vtplayer");
+ return -1;
+ }
+ dprintf("Done. Setting alternate interface.\n");
+ if (usb_set_altinterface(vtplayer_handle, 0) < 0)
+ {
+ perror("vtplayer");
+ return -1;
+ }
+ dprintf("Done.\n");
+ }
+ }
+ }
+
+ return vtplayer_handle != NULL ? 0 : 1;
+}
+
+int release_vtplayer(void)
+{
+ if (vtplayer_handle)
+ {
+ if (usb_release_interface(vtplayer_handle, 0) < 0)
+ {
+ perror("usb_release");
+ return -1;
+ }
+ if (usb_close(vtplayer_handle) < 0)
+ {
+ perror("usb_close");
+ return -1;
+ }
+ }
+ vtplayer_handle = NULL;
+ return 0;
+}
+
+int get_status(u8 * data) {
+ return usb_interrupt_read(vtplayer_handle, 0x81, (void *)data, 4, TIMEOUT);
+}
+
+/*
+ We change the bit order so that the 4bytes set to the VTPlayer are
+ easy to read.
+ Each digit represent one line, each of its bits represent one pin.
+ => 4 digits for the left cell and 4 for the right cell.
+*/
+u32 reorder(u32 pad) {
+#define B(z, y) (((pad & (1 << (y - 1))) ? 1 : 0) << (z - 1))
+ return ~(B( 8, 1) | B( 7, 2) | B(16, 3) | B(15, 4) |
+ B(24, 17) | B(23, 18) | B(32, 19) | B(31, 20) |
+ B( 6, 5) | B( 5, 6) | B(14, 7) | B(13, 8) |
+ B(22, 21) | B(21, 22) | B(30, 23) | B(29, 24) |
+ B( 2, 9) | B( 1, 10) | B(10, 11) | B( 9, 12) |
+ B(18, 25) | B(17, 26) | B(26, 27) | B(25, 28) |
+ B( 4, 13) | B( 3, 14) | B(12, 15) | B(11, 16) |
+ B(20, 29) | B(19, 30) | B(28, 31) | B(27, 32));
+}
+
+int set_pads(u32 pads)
+{
+ if (lasttacton != pads && vtplayer_handle)
+ {
+ pads = reorder(pads);
+ lasttacton = pads;
+ int ret = usb_control_msg(vtplayer_handle, 0x21, 0x09, 0x0200, 0x0000, (void *)&pads, 4, TIMEOUT);
+ if (ret < 0)
+ {
+ switch(-ret)
+ {
+ case EBADF: //9
+ dprintf("USB ERROR: EBADF %d\n", ret);
+ break;
+ case ENXIO: //6
+ dprintf("USB ERROR: ENXIO %d\n", ret);
+ break;
+ case EBUSY: //19
+ dprintf("USB ERROR: EBUSY %d\n", ret);
+ break;
+// case (LUSBDARWINSTALL):
+// printf("USB ERROR: LUSBDARWINSTALL %d\n", ret);
+// break;
+ case EINVAL: //22
+ dprintf("USB ERROR: EINVAL %d\n", ret);
+ break;
+#ifdef __linux__
+ case ETIMEDOUT: //110
+ dprintf("USB ERROR: ETIMEDOUT %d\n", ret);
+ break;
+#endif
+ case EIO: //5
+ dprintf("USB ERROR: EIO %d\n", ret);
+ break;
+ default:
+ dprintf("USB ERROR: %d\n", ret);
+ break;
+ }
+ //Dirty fix: if the vtplayer crashes for any reasonwe reload it
+ //seems that this makes the program crashes anyway in certain circumstances
+ //This occured only once, when there was a bug in the USB driver in the Linux kernel
+ release_vtplayer();
+ init_vtplayer();
+ }
+ return ret;
+ }
+ return 0;
+}
+