GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Fri Oct 31, 2014 5:55 pm

All times are UTC




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: [problem]g-sensor on an image (teeter game)
PostPosted: Tue May 05, 2009 6:34 pm 
Offline
Familiar Face

Joined: Sun Apr 26, 2009 6:21 am
Posts: 8
here I am again with a new problem... I'm trying to make a moving picture with G-sensor event. But, in the code below, the G-sensor can't be used to change the picture. The reference for the g-sensor to the picture is not right...

could someone help me with this kind of teeter game?
I need to know, how to make the picture move according to the g-sensoris movement.

Code:
#include <gtk/gtk.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>

static Display  *display;
static Window   rootWindow;
ushort debug = 0;

/* we're reading this kind of events:
struct input_event {
    struct timeval time;
    __u16 code;
    __u16 type;
    __s32 value;
};

*/



/* Define step for easier tweking of movement */
#define STEP 10

/* Struct with all of the data we need inside callbacks. */
typedef struct _Data Data;
struct _Data
{
    GtkWidget *image;
    GtkWidget *fixed;
    gint       pos[2];
};

#define Data data

#define BIG_DIFFERENCE 400
/* this ----v idea doesn't seem to be working right, for later investigation */
#define LONG_TIME 0

#define EVENT_PATH "/dev/input/event3"

struct input_event current_a, current_b, current_c;

int read_packet(int from, struct input_event *x, struct input_event *y, struct input_event *z, struct input_event *syn)  {
   void* packet = NULL;
   void* packet_memcpy_result = NULL;
   int packet_size=sizeof(struct input_event);
   int size_of_packet=4*packet_size;
   int bytes_read = 0;

   packet = malloc(size_of_packet);

   if(!packet) {
      fprintf(stderr, "malloc failed\n");
      exit(1);
   }

   bytes_read = read (from, packet, size_of_packet);

   if (bytes_read < packet_size) {
      fprintf(stderr, "fread failed\n");
      exit(1);
   }

   /* obtain the full packet */
   packet_memcpy_result = memcpy(x, packet, packet_size);
   packet_memcpy_result = memcpy(y, packet+packet_size, packet_size);
   packet_memcpy_result = memcpy(z, packet+2*packet_size, packet_size);
   packet_memcpy_result = memcpy(syn, packet+3*packet_size, packet_size);
   free(packet);
   if(syn->type == EV_SYN)
      return(1);
   else
      return(0);
}

int very_different_than_previously(struct input_event event_a, struct input_event event_b, struct input_event event_c) {
/*
   if(   (abs(current_x.time.tv_sec - event_x.time.tv_sec) > LONG_TIME) &&
*/
   if(
      (
       (abs(current_a.value - event_a.value) >= BIG_DIFFERENCE) ||
       (abs(current_b.value - event_b.value) >= BIG_DIFFERENCE) ||
       (abs(current_c.value - event_c.value) >= BIG_DIFFERENCE)
      )
     ) return(1);
   else
      return(0);
}
void reset_current_position(struct input_event event_a, struct input_event event_b, struct input_event event_c) {
   current_a.value=event_a.time.tv_sec = event_a.time.tv_sec;

   current_a.value=event_a.value;
   current_b.value=event_b.value;
   current_c.value=event_c.value;
}

ushort neighbour(int value, int target, int neighbour) {
   return ( target-abs(neighbour) < value && value <= target+abs(neighbour) );
}


void swap_orientation(struct input_event event_a, struct input_event event_b, struct input_event event_c) {
   __s32 a = event_a.value;
   __s32 b = event_b.value;
   __s32 c = event_c.value;

   //if(very_different_than_previously(event_a, event_b, event_c)) {
      //printf("(a,b,c) = (%d,%d,%d) == ", a, b, c);

      printf("Types: a(%d), b(%d), c(%d)\n", event_a.type, event_b.type, event_c.type);
      printf("Codes: a(%d), b(%d), c(%d)\n", event_a.code, event_b.code, event_c.code);
      printf("Value: a(%d), b(%d), c(%d)\n", event_a.value, event_b.value, event_c.value);

      if(c > a && c > b && neighbour(a, 0, 20) && neighbour(c,1000,200)) {
/*             Data->pos[1] += STEP;
            gtk_fixed_move( GTK_FIXED( Data->fixed ), Data->image, Data->pos[0], Data->pos[1] );
*/      } else if(b < 100 && b < c && neighbour(b,-1000,200)) {
         data.pos[0] += 20;
         data.pos[1] += 20;
                        tester (data);
      } else if(b > a && b > c && neighbour(b,1000,200)) {
         printf("vertical upside down");
      } else if(a > b && a > c && neighbour(a,1000,500)) {
         printf("right");
      } else if(a < b && a < c && neighbour(a,-1000,500)) {
         printf("left");
      }

   printf("\n");
   //}

}

void tester (Data *data)
{
data->pos[1] += STEP;
    gtk_fixed_move( GTK_FIXED( data->fixed ), data->image,
                    data->pos[0], data->pos[1] );
}


/* Movement callbacks */
void
down( GtkButton *button,
      Data      *data )
{
    data->pos[1] += STEP;
    gtk_fixed_move( GTK_FIXED( data->fixed ), data->image,
                    data->pos[0], data->pos[1] );
}

void
up( GtkButton *button,
    Data      *data )
{
    data->pos[1] -= STEP;
    gtk_fixed_move( GTK_FIXED( data->fixed ), data->image,
                    data->pos[0], data->pos[1] );
}

void
left( GtkButton *button,
      Data      *data )
{
    data->pos[0] -= STEP;
    gtk_fixed_move( GTK_FIXED( data->fixed ), data->image,
                    data->pos[0], data->pos[1] );
}

void
right( GtkButton *button,
       Data      *data )
{
    data->pos[0] += STEP;
    gtk_fixed_move( GTK_FIXED( data->fixed ), data->image,
                    data->pos[0], data->pos[1] );
}

/* Main */
int
main (int argc, char*argv[])
{
   GtkWidget*window;
   GtkWidget*image;
   GtkWidget*fixed;
   GtkWidget*buttonDown;
   GtkWidget*buttonUp;
   GtkWidget*buttonRight;
   GtkWidget*buttonLeft;

   Data      data;

   gtk_init (&argc, &argv);

   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
   gtk_window_set_default_size(GTK_WINDOW(window), 100, 100);
   gtk_window_set_title(GTK_WINDOW(window), "ball");
   gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
   gtk_container_set_border_width (GTK_CONTAINER(window), 2);

   image = gtk_image_new_from_file("/Ball.png");
   fixed = gtk_fixed_new();   
   buttonDown = gtk_button_new_with_label("down");   
   buttonUp = gtk_button_new_with_label("up");
   buttonRight = gtk_button_new_with_label("right");
   buttonLeft = gtk_button_new_with_label("left");

   gtk_container_add(GTK_CONTAINER(window), fixed);

   g_signal_connect(G_OBJECT(buttonDown), "clicked", G_CALLBACK(down), &data);
   g_signal_connect(G_OBJECT(buttonUp), "clicked", G_CALLBACK(up), &data);
   g_signal_connect(G_OBJECT(buttonRight), "clicked", G_CALLBACK(right), &data);
   g_signal_connect(G_OBJECT(buttonLeft), "clicked", G_CALLBACK(left), &data);

   g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), G_OBJECT(window));

   gtk_fixed_put(GTK_FIXED(fixed), image, 180, 220);
   gtk_fixed_put(GTK_FIXED(fixed), buttonDown, 200,310);
   gtk_fixed_put(GTK_FIXED(fixed), buttonUp, 200, 150);
   gtk_fixed_put(GTK_FIXED(fixed), buttonRight, 300, 230);
   gtk_fixed_put(GTK_FIXED(fixed), buttonLeft, 100, 230);

   gtk_widget_set_size_request(buttonDown, 100,80);
   gtk_widget_set_size_request(buttonUp, 100, 80);
   gtk_widget_set_size_request(buttonRight, 100,80);
   gtk_widget_set_size_request(buttonLeft, 100, 80);

   data.image = image;
   data.fixed = fixed;
   data.pos[0] = 180;
   data.pos[1] = 220;

   gtk_widget_show_all(window);

   gtk_main();

   return 0;

   int file = -1;
   char * time=(char*)malloc(20);
   struct input_event syn, a, b, c;

   file = open(EVENT_PATH, O_RDONLY);
   if (file < 0) {
      fprintf(stderr, "Can't open '%s': %s\n",EVENT_PATH,strerror(errno));
      exit(1);
   }

   if(argc > 1) debug=1;

   /* initialize current position */
   read_packet(file, &current_a, &current_b, &current_c, &syn);

   display = XOpenDisplay(":0");
   if (display == NULL) {
      fprintf (stderr, "Can't open display %s\n", XDisplayName(":0"));
      exit(1);
   }

   
   while(1) {
      //printf("Reading packet...");
      if(read_packet(file, &a, &b, &c, &syn)) {
         swap_orientation(a,b,c);
      } else printf("Skipped a packet\n");
   }

}




Top
 Profile  
 
 Post subject:
PostPosted: Tue May 05, 2009 8:25 pm 
Offline
Never Seen the Sunlight

Joined: Wed Jul 23, 2008 10:31 am
Posts: 2406
Location: Slovenia
Hello.

I cannot offer you specific help since I know nothing about g-sensor and events that are produced, but what I can give you is a generic layout of an application.

Your application will generally need 4 stages:
  1. GUI creation stage
  2. opening of event input for reading
  3. displaying GUI and reacting to events
  4. cleaning (closing input, etc.)

I wrote a sample application that demonstrates the core principles that I mentioned before. This applications randomly moves one circle 30 times per second (random movement will be replaced by g-sensor defined move in your final application). When the circle touches the target circle, the application displays "Success" label. I hope you'll find it useful. And if you have any questions, just ask.
Code:
#include <gtk/gtk.h>

#define STEP 20
#define SIZE 300

/* Data storage */
typedef struct _Data Data;
struct _Data
{
   gint       pos[2];
   gint       target[2];
   gboolean   win;
   GtkWidget *draw;
};

/* Declarations */
static gboolean
cb_expose( GtkWidget      *draw,
         GdkEventExpose *event,
         Data           *data );

static gboolean
handle_events( Data *data );

static void
update_coords( gint *pos );


/* Main */
int
main( int    argc,
     char **argv )
{
   GtkWidget *window;
   GtkWidget *draw;
   Data       data;

   gtk_init( &argc, &argv );

   /*
    * Create GUI (stage 1)
    */
   window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
   g_signal_connect( G_OBJECT( window ), "destroy",
                 G_CALLBACK( gtk_main_quit ), NULL );
   gtk_window_set_default_size( GTK_WINDOW( window ), SIZE, SIZE );

   draw = gtk_drawing_area_new();
   g_signal_connect( G_OBJECT( draw ), "expose-event",
                 G_CALLBACK( cb_expose ), &data );
   gtk_container_add( GTK_CONTAINER( window ), draw );

   /*
    * Open file descriptors for reading (stage 2)
    */

   /* NOT IMPLEMENTED IN THIS SAMPLE, SINCE THIS IS HIGHLY
    * APPLICATION DEPENDENT. */

   /*
    * Display GUI and react to events (stage 3)
    */
   data.pos[0] = 150;
   data.pos[1] = 150;
   data.target[0] = 30;
   data.target[1] = 100;
   data.win = FALSE;
   data.draw = draw;

   g_timeout_add( 33, (GSourceFunc)handle_events, &data );
   gtk_widget_show_all( window );
   gtk_main();

   /*
    * Close file descriptors and do any cleaning (stage 4)
    */

   /* NOT IMPLEMENTED IN THIS SAMPLE. */


   return( 0 );
}

static gboolean
cb_expose( GtkWidget      *draw,
         GdkEventExpose *event,
         Data           *data )
{
   /* Draw point at the location, pointed to by pos coordinates. */
   cairo_t *cr;

   cr = gdk_cairo_create( event->window );

   if( data->win )
   {
      PangoLayout *layout;
      gint         x, y, w, h;
      
      layout = gtk_widget_create_pango_layout( draw, "Success!" );
      pango_layout_get_pixel_size( layout, &w, &h );
      x = ( SIZE - w ) / 2;
      y = ( SIZE - h ) / 2;

      cairo_move_to( cr, x, y );
      pango_cairo_show_layout( cr, layout );
      g_object_unref( G_OBJECT( layout ) );
   }

   cairo_arc( cr, data->pos[0], data->pos[1], STEP, 0, 2 * G_PI );
   cairo_fill( cr );
   cairo_arc( cr, data->target[0], data->target[1], STEP, 0, 2 * G_PI );
   cairo_fill( cr );
   cairo_destroy( cr );

   return( FALSE );
}

static gboolean
handle_events( Data *data )
{
   /* Obtain new coordinates. This is where you should put your function
    * that really handles the events (I call some simple, pseudo random
    * coordinate generator). */
   update_coords( data->pos );

   /* Did we win already? */
   if( ( data->target[0] - 1 - STEP * 1.41 ) < data->pos[0] &&
      ( data->target[0] + 1 + STEP * 1.41 ) > data->pos[0] &&
      ( data->target[1] - 1 - STEP * 1.41 ) < data->pos[1] &&
      ( data->target[1] + 1 + STEP * 1.41 ) > data->pos[1] )
      data->win = TRUE;

   /* Queue redraw so the changes are visible on screen. */
   gtk_widget_queue_draw( data->draw );

   return( ! data->win );
}

static void
update_coords( gint *pos )
{
   register gint i;

   for( i = 0; i < 2; i++ )
      pos[i] = CLAMP( g_random_int_range( pos[i] - STEP, pos[i] + STEP ),
                  0, SIZE );
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group