Gamestudio Links
Zorro Links
Newest Posts
AlpacaZorroPlugin v1.3.0 Released
by kzhao. 05/22/24 13:41
Free Live Data for Zorro with Paper Trading?
by AbrahamR. 05/18/24 13:28
Change chart colours
by 7th_zorro. 05/11/24 09:25
Data from CSV not parsed correctly
by dr_panther. 05/06/24 18:50
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
1 registered members (AndrewAMD), 1,534 guests, and 3 spiders.
Key: Admin, Global Mod, Mod
Newest Members
LucasJoshua, Baklazhan, Hanky27, firatv, wandaluciaia
19054 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
GestIT - mouse gesture system #352488
01/03/11 22:14
01/03/11 22:14
Joined: Mar 2009
Posts: 88
Walori Offline OP
Junior Member
Walori  Offline OP
Junior Member

Joined: Mar 2009
Posts: 88
Hello folks here's a little contribution I made on my spare time. It allows you to use gestures in your application. I've included the file you need (GestIT.c) and a small demo demonstrating the system to the script.

Below you can find the two (2) source codes, copy these two to separate files. the code titled as demo.c is demonstrating the program. The titled code GestIT is the script for mouse gestures.

Screenshot of the demo.c (not update version)



demo.c

Use this to launch demo showing the gesture system, follow the instructions on the screen
Code:
#include <acknex.h>
#include "GestIT.c"
var demo_mode = -1;
TEXT* information =
{
	pos_x = 0;
	pos_y = 0;
	font = "Arial#16";
	string("This is GestIT demo\n","","");
	flags  = VISIBLE;
}
TEXT* gesture_output=
{
	strings = 21;//Should be MAX_GESTPART+1
	pos_x = 0;
	pos_y = 245;
	flags = VISIBLE;
}
void main()
{
	TEXT* printer = 
	{
		pos_x = 200;
		pos_y = 300;
		strings = 1;
		alpha = 100;
		flags = VISIBLE | TRANSLUCENT;
	}
	mouse_mode  = 4;
	read_gestures(MGST_STR_GEST_FILE);
	wait_for(read_gestures);
	gesture(280,281);
	str_cat((information.pstring)[0],"Currect gesture input file:");
	str_cat((information.pstring)[0],MGST_STR_GEST_FILE);
	str_cat((information.pstring)[0],"\nCurrect gesture output file:");
	str_cat((information.pstring)[0],MGST_STR_GEST_FILE);
	str_cat((information.pstring)[0],"_copy.txt\n");
	str_cpy((information.pstring)[1],"To enter play mode press F1\nTo enter gesture creation mode press F2\nTo Scroll through gestures press F3\n\nKill lines:");
	var temp_kill = 0;
	var i = 0;
	var a = 0;
	var line = 0;
	var time_delay;
	var temp_x = 0;
	var temp_y = 0;
	MGST* temp_gest = NULL;
	MGSTPART* temp_part = NULL;
	var fhandle = 0;
	var key_d_clear = 1;
	var key_enter_clear = 1;
	var f5_clear = 0;
	STRING* str_temp = NULL;
	var loc_temp_x = 0;
	var loc_temp_y = 0;
	var reset_gest = 0;
	var gesture_checked = 0;
	var lmb_clear = 0;
	var rmb_clear = 0;
	var play_check = 0;
	var lowest_part = 0;
	for(i=0;i<11;i++)
	{
		str_cpy((gesture_output.pstring)[i],"");
	}
	i = 0;
	MGST_KILL_LINES = 1;
	while(1)
	{
		str_cpy((information.pstring)[1],"To enter play mode press F1\nTo enter gesture creation mode press F2\nTo scroll through gestures press F3\nKill lines:");
		str_cat_num((information.pstring)[1],"%.f",MGST_KILL_LINES);
		if(key_f5 && demo_mode > 0 && f5_clear)
		{
			if(MGST_KILL_LINES >= 1)
			{
				MGST_KILL_LINES = 0;
			}
			else
			{
				MGST_KILL_LINES = 1;
			}
			f5_clear = 0;
		}
		if(key_f5)f5_clear = 1;
		if(demo_mode == 0)
		{
			str_cpy((information.pstring)[2],"\nCurrect gesture information:");
			temp_gest = gest[gesture_checked];
			if(mouse_left && ´lmb_clear == 1)
			{
				for(i=0;i<gesture_output.strings;i++)
				{
					str_cpy((gesture_output.pstring)[i],"");
				}
				MGST_KILL_LINES = 2;
				wait(1);
				MGST_KILL_LINES = 0;
				a = 0;
				gesture_checked++;
				if(gesture_checked > MGST_GEST_COUNT)gesture_checked = MGST_GEST_COUNT;
				lmb_clear = 0;
			}
			if(mouse_right && rmb_clear == 1)
			{
				for(i=0;i<gesture_output.strings;i++)
				{
					str_cpy((gesture_output.pstring)[i],"");
				}
				MGST_KILL_LINES = 2;
				wait(1);
				MGST_KILL_LINES = 0;
				a = 0;
				gesture_checked--;
				if(gesture_checked < 0)gesture_checked = 0;
				rmb_clear = 0;
			}
			if(!mouse_left)lmb_clear = 1;
			if(!mouse_right)rmb_clear = 1;
			if(temp_gest)
			{
				str_cat_num((information.pstring)[2],"\nID:%.f\nCoordinates:",temp_gest->id);	
				a = 0;
				MGST_KILL_LINES = 2;
				wait(1);
				MGST_KILL_LINES = 0;
				while(temp_gest->part[a] != NULL)
				{
					if(temp_gest->part[a] == NULL)
					{
						break;
					}
					if(a==0)
					{
						temp_x = screen_size.x/2;
						temp_y = screen_size.y/4.3;
					}
					else
					{
						temp_x = loc_temp_x;
						temp_y = loc_temp_y;
					}
					loc_temp_x = temp_x + MGST_MOVEMENT_CHECK * temp_gest->part[a]->x * 2;
					loc_temp_y = temp_y + MGST_MOVEMENT_CHECK * temp_gest->part[a]->y * 2;	
					draw_line_coord(temp_x,temp_y,loc_temp_x,loc_temp_y);
					str_cpy((gesture_output.pstring)[a],"(X,Y):");
					str_cat_num((gesture_output.pstring)[a],"(%.f,",temp_gest->part[a]->x);
					str_cat_num((gesture_output.pstring)[a],"%.f)",temp_gest->part[a]->y);
					str_cpy((gesture_output.pstring)[gesture_output.strings-1],"Gesture parts count:");
					str_cat_num((gesture_output.pstring)[gesture_output.strings-1],"%.f",a+1);
					a++;
				}
			}
			else
			{
				str_cat((information.pstring)[2],"\nID:NULL");	
			}
		}
		if(key_f1)
		{
			str_cpy((information.pstring)[1],"Now using: Play mode(Try to gesture the gestures)\nNote: If you just did a new gesture usgin this demo.c, you have to copy the gestures to gest.txt file");
			str_cpy((information.pstring)[2],"Press your defined gesture button to gest ( note,gests come in order they appear in gest file\nAfter this make a gesture in order\n\nGesture in order:");
			demo_mode = 1;
			reset_gest = 0;
			i = 0;
			MGST_CHECK_VALID = -1;
			MGST_KILL_LINES = 1;
			temp_kill = 0;
			temp_gest = NULL;
			gesture_output.flags = NULL;
			printer.flags = VISIBLE;
			printer.alpha = 100;
		}
		if(key_f2)
		{
			for(i=0;i<gesture_output.strings;i++)
			{
				str_cpy((gesture_output.pstring)[i],"");
			}
			str_cpy((information.pstring)[1],"Now using: New gesture creation");
			str_cpy((information.pstring)[2],"To create new gesture, gest it first and after press enter this will save the gesture to the database
			\nTo reset your gesture or last output, press R.Note: Pressing R will reset both if valid!\nTo save the database(dump), Press D. This will create a new file on local directory
			To exit press Esc\n\nCurrect gesture coordinates:");
			demo_mode = 2;
			reset_gest = 0;
			MGST_CHECK_VALID = -1;
			MGST_KILL_LINES = 1;
			temp_kill = 0;
			temp_gest = NULL;
			gesture_output.flags = VISIBLE;
			printer.flags = VISIBLE;
			printer.alpha = 100;
		}
		if(key_f3)
		{
			for(i=0;i<gesture_output.strings;i++)
			{
				str_cpy((gesture_output.pstring)[i],"");
			}
			str_cpy((information.pstring)[1],"To enter play mode press F1\nTo enter gesture creation mode press F2\nTo scroll through gestures press F3\n\nTo view Gestures press either mouse LMB for backward or RMB for forward");
			MGST_CHECK_VALID = -2;		
			reset_gest = 0;
			line = 0;
			demo_mode = 0;
			temp_kill = MGST_KILL_LINES;
			MGST_KILL_LINES = 0;
			temp_gest = NULL;
			gesture_output.flags = VISIBLE;
			printer.flags = NULL;
		}
		if(!key_enter)key_enter_clear = 1;
		if(demo_mode == 1 || demo_mode == 2)
		{
			printer.pos_x = mouse_pos.x + 40;
			printer.pos_y = mouse_pos.y;
			str_cpy((printer.pstring)[0],"");
			str_cat_num((printer.pstring)[0],"X_MOVEMENT:%.f",MGST_X_MOVEMENT);
			str_cat_num((printer.pstring)[0],"\nY_MOVEMENT:%.f",MGST_Y_MOVEMENT);
			if(time_delay >= 5)
			{
				printer.alpha -=1*time_step;
				if(printer.alpha <= 5)
				{
					str_cpy((printer.pstring)[0],"");
					time_delay = 0;
					line = 0;
					for(i=0;i<10;i++)
					{
						str_cpy((gesture_output.pstring)[i],"");
					}
				}
			}
			else
			{
				if(time_delay >= 0)
				{
					time_delay +=1*time_step;
				}
			}
		}
		if(demo_mode == 1)
		{
			if(gest[play_check])
			{
				str_cpy((information.pstring)[2],"Press your defined gesture button to gest ( note,gests come in order they appear in gest file\nAfter this make a gesture in order\nGesture in order:");
				str_cat_num((information.pstring)[2],"%.f",(double)play_check+1);
				/*
				THIS IS IMPORTANT PART 
				
				If the found gest is valid we need to reset it to NULL before we can continue
				with check operations
				*/
				if(found_gest)//IMPORTANT
				{
					if(found_gest == gest[play_check])
					{
						printer.alpha = 100;
						str_cpy((printer.pstring)[0],"");
						str_cpy((printer.pstring)[0],"Found gest, try the next one");
						play_check++;
						time_delay = 0;
						found_gest = NULL;//IMPORTANT
					}
					else
					{
						printer.alpha = 100;
						str_cpy((printer.pstring)[0],"");
						time_delay = 0;
						str_cpy((printer.pstring)[0],"Did not do the right gest, try again! (resetting found gesture)");
						found_gest = NULL;//IMPORTANT
					}
					beep();
				}
				/*
				END OF IMPORTANT PART
				*/
			}
			else
			{
				str_cpy((information.pstring)[2],"Press your defined gesture button to gest ( note,gests come in order they appear in gest file\nAfter this make a gesture in order\nGesture in order:");
				str_cat((information.pstring)[2],"No more gestures");
				if(printer.alpha <=55 && time_delay >= 0)
				{
					time_delay = -1;
					printer.alpha = 100;
					str_cat((printer.pstring)[0],"\nNo more gestures, press T to reset gestures and start over");
				}
				if(key_t)
				{
					str_cpy((printer.pstring)[0],"Reseted");
					found_gest = NULL;
					play_check = 0;
				}
			}
		}
		if(demo_mode == 2)
		{
			time_delay = -1;
			if(key_d && key_d_clear == 1)
			{
				str_temp = str_create(_chr(MGST_STR_GEST_FILE));
				str_cat(str_temp,"_copy.txt");
				fhandle = file_open_write(str_temp);
				if(fhandle != NULL)
				{
					for(i=0;i<MGST_MAX_GEST;i++)
					{
						if(gest[i])
						{
							for(a=0;a<MGST_MAX_GESTPART;a++)
							{
								if(gest[i]->part[a])
								{
									file_var_write(fhandle,gest[i]->part[a]->x);
									file_var_write(fhandle,gest[i]->part[a]->y);
								}
							}
							file_var_write(fhandle,-2);
						}
					}
					file_var_write(fhandle,-3);
					reset_gest = 1;
					file_close(fhandle);
					printf("File saved: %s",_chr(str_temp));
				}
				key_d_clear = 0;
			}
			if(!key_d)
			{
				key_d_clear = 1;
			}
			if(mouse_moving == 1 && vec_dist(MGST_VEC_MOUSE_OLD,mouse_pos.x) >= MGST_MOVEMENT_CHECK && MGST_CHECK_VALID)
			{
				if(!temp_gest)
				{
					temp_gest = create_gesture();
					for(i=0;i<10;i++)
					{
						str_cpy((gesture_output.pstring)[i],"");
					}
					line = 0;
				}
				else
				{
					if(MGST_X_MOVEMENT != 0 || MGST_Y_MOVEMENT != 0)
					{
						if(MGST_X_MOVEMENT != loc_temp_x || MGST_Y_MOVEMENT != loc_temp_y)
						{
							loc_temp_x = MGST_X_MOVEMENT;
							loc_temp_y = MGST_Y_MOVEMENT;
							if(temp_gest->max_part < MGST_MAX_GESTPART)
							{
								create_gesture_part(temp_gest,MGST_X_MOVEMENT,MGST_Y_MOVEMENT);
								if((gesture_output.pstring)[line])
								{
									str_cpy((gesture_output.pstring)[line],"(X,Y):");
									str_cat_num((gesture_output.pstring)[line],"(%.f,",MGST_X_MOVEMENT);
									str_cat_num((gesture_output.pstring)[line],"%.f)",MGST_Y_MOVEMENT);
									line++;
								}
								str_cpy((gesture_output.pstring)[10],"There's still room for gesture parts");
							}
							else
							{
								str_cpy((gesture_output.pstring)[10],"No room for gesture parts");
							}
						}
					}
				}
			}
			if(mouse_moving == 0)
			{
				if(key_r)
				{
					if(temp_gest)
					{
						for(i=0;i<MGST_MAX_GESTPART;i++)
						{
							if(temp_gest->part[i])
							free(temp_gest->part[i]);
						}
						free(temp_gest);
					}
					for(i=0;i<10;i++)
					{
						str_cpy((gesture_output.pstring)[i],"");
					}
					line = 0;
					reset_gest = 0;
					temp_gest = NULL;
				}
			}
			if(key_enter && temp_gest != NULL && key_enter_clear == 1)
			{
				if(temp_gest->max_part >= 1)
				{
					for(i=0;i<MGST_MAX_GEST;i++)
					{
						if(!gest[i])
						{
							gest[i] = temp_gest;
							gest[i]->id = i;
							printf("Gesture saved succesfully (information to follow)\nGesture parts: %.f\nGesture saved ID (order of appearence in the file): %.f",(double)temp_gest->max_part,(double)i);
							wait(2);
							vec_set(MGST_VEC_MOUSE_OLD,mouse_pos.x);
							temp_gest = NULL;
							break;
						}
					}
				}
				key_enter_clear = 0;
			}
		}
		wait(1);
	}
}



GestIT.c
Use this to your projects
Code:
#ifndef acknex.h
	#include <acknex.h>
#endif

#define MGST_MOVEMENT_CHECK 20//The distance the mouse has to move before a new check is called
#define MGST_MOVEMENT_ACCURACY 10//How much we give space for an error
#define MGST_END_LINE -2//Which number we have to meet before we create a new gesture struct
#define MGST_END_FILE -3//When this number is meat we've reached the end of the file
#define MGST_TIME_DELAY 2//The time that mouse is required to be stopped before we check for gesture
#define MGST_ENABLE_TRAIL//If this is enabled a trail is drawn based on mouse movement on the screen
#define MGST_MAX_GEST 200//Maxium amount of gestures(terminates the array size)
#define MGST_MAX_GESTPART 10//Maxium amount of parts in gestures

STRING* MGST_STR_ERROR_LOAD1 = "Could not open a valid gesture file. Please check the file/path given to the function\nThis function returns 0";
STRING* MGST_STR_GEST_FILE = "gests.txt";

VECTOR MGST_VEC_MOUSE_OLD;

var MGST_FOUND = -1;//Global variable used by the gesture function
var MGST_KILL_LINES = 1;//Used to kill lines made by gesture (function draw_line_coord(x1,x2,y1,y2))
var MGST_GEST_COUNT = 1;//Used for faster array checks, counts the total amount of gestures loaded
var MGST_X_MOVEMENT = 0;//Global variable of which direction mouse is moving on X axis
var MGST_Y_MOVEMENT = 0;//Global variable of mouse movement on Y axis
var MGST_CHECK_VALID = 0;//Used to check if the chek loop is valid
var temp_x = 0;//Temporary X axis movement var
var temp_y = 0;//Temporary Y axis movement var

typedef struct
{
	var x,y,z;//Coordinates, Z is free for user
}MGSTPART;//Gesture part struct

typedef struct
{
	var id;//Gesture's ID
	var part_check;//Variable that tells gesture function which part it should check next
	var max_part;//Tells how many parts we have
	MGSTPART* part[MGST_MAX_GESTPART];//Array of gesture parts, size of defined maxium gest part
}MGST;

MGST* gest[MGST_MAX_GEST];//Array for REAL gestures
MGST* gest_check[MGST_MAX_GEST];//Array for GESTURES THAT ARE CHECKED (these point to REAL gestures)
MGST* found_gest;//Pointer to the found variabel in gesture function

function draw_line_coord(x1,x2,y1,y2)
{
	var time_delay = 0;//Counter variableu
	while(1)
	{
		proc_mode = PROC_EARLY;
		if(time_delay >= 10 || MGST_KILL_LINES == 2)//if this line has existed for over 10 seconds
		{
			if(MGST_KILL_LINES == 1 || MGST_KILL_LINES == 2)
			{
				break;
			}
		}
		else
		{
			time_delay +=1*time_step;//If the time isn't meat, increase the counter
		}
		draw_line(vector(x1,x2,0), vector(0,0,250), 0);//Draw line from x1,x2
		draw_line(vector(y1,y2,0), vector(0,0,250), 100);//Draw line to y1,y2
		draw_quad(NULL, vector(x1,x2,0), NULL, vector(5,5,0), NULL, vector(0,250,0), 100, 0);//Add square to start position
		wait(1);
	}
	
}
function gesture(var key_press,var ignore_press)
{
	/*---------------------------------------------------------------------------
	Gesture main function, this function is RELEVANT for your projects.
	
	This function holds the spine of the wholse system, it calculates the gestures
	and their coordinates to the ones that are loaded to the memory. 
	
	funtion comments start here
	---------------------------------------------------------------------------*/
	/*---------------------------------------------------------------------------
	---------------------------------------------------------------------------*/
	var i,a;//Counter variables
	var time_delay  = 0;//Counter how long it takes to check the gesture after the mouse is stopped
	var found_check = 0;//Counter of how many gestures fit (faster searching through the array), THIS IS MODIFIED
	var found_start_check = 0;//same as above but this variable holds the amount of fitting gestures until the gesture loop breaks
	vec_set(MGST_VEC_MOUSE_OLD,vector(mouse_pos.x,mouse_pos.y,0));//Set mouse old to mouse position
	MGST* temp_found_gest = NULL;//Temporary gesture canditate pointer
	MGST_CHECK_VALID = -1;
	while(1)
	{
		proc_mode = PROC_LATE;
		/*---------------------------------------------------------------------------
		Preset certain parts before checking if we're pressing the key
		---------------------------------------------------------------------------*/
		// 	if(!key_pressed(key_press))//Comment out this line if you don't want reseting the gestures before user lets off the gesture button
		if(MGST_CHECK_VALID == -1)
		{
			for(i=0;i<MGST_GEST_COUNT;i++)//Count for defined maxium gest amourn
			{
				if(gest[i])//If there's a gesture with this I
				{
					gest[i]->part_check = 0;//Reset its gesture part counter
				}
				gest_check[i] = NULL;//Reset gest_check by this I
			}
			temp_found_gest = NULL;
			found_gest = NULL;
			MGST_X_MOVEMENT = 0;//Reset x mouse movement variable
			MGST_Y_MOVEMENT = 0;//Reset y movement variable
			temp_x = -10;//Reset last x movement
			temp_y = -10;//Rest last y movement
			found_start_check = 0;
			found_check = 0;
			time_delay = 0;
			MGST_FOUND = 0;//Set this variable to we want to sync mouse position to mouse old
			MGST_CHECK_VALID = 0;
		}
		if(key_pressed(key_press))
		{
			vec_set(MGST_VEC_MOUSE_OLD,vector(mouse_pos.x,mouse_pos.y,0));
		}
		while(key_pressed(key_press) && MGST_CHECK_VALID >= 0)//If wanted key is pressed continue wit htis (And we aren't reseting check)
		{
			proc_mode = PROC_LATE;
			if(MGST_CHECK_VALID == -1)//If reset variable is not NULL, break the check
			{
				break;
			}
			if(ignore_press > 0 && key_pressed(ignore_press))//If we've defined ignore press and we're pressing the button
			{
				break;//Break from this loop
			}
			MGST_CHECK_VALID = 1;//Set checking valid, check loop is valid in other words
			if(mouse_moving == 0)//If  mouse doesn't move
			{
				time_delay +=1*time_step;//Increase time delay
				if(time_delay >= MGST_TIME_DELAY)//If time delay variable is higher thand defined time delay
				{
					if(temp_found_gest)//If we have mouse gest canditate
					{
						found_gest = temp_found_gest;//Set found gest to mouse gest canditate
						temp_found_gest = NULL;
					}
					else
					{
						found_gest = NULL;//If we didn't have gest caditate set found_gest pointer to NULL
					}
					MGST_CHECK_VALID = -1;
				}
			}
			else
			{
				#ifdef MGST_ENABLE_TRAIL
					draw_line_coord(MGST_VEC_MOUSE_OLD.x,MGST_VEC_MOUSE_OLD.y,mouse_pos.x,mouse_pos.y);//If enabled lines are drawn based on mouse movement
				#endif
				time_delay = 0;//If mouse is moving set time delay to 0
			}
			if(vec_dist(MGST_VEC_MOUSE_OLD,vector(mouse_pos.x,mouse_pos.y,0)) >= MGST_MOVEMENT_CHECK && MGST_CHECK_VALID== 1)//If mouse has moved more than defined movement check
			{
				if((sign(mouse_pos.x-MGST_VEC_MOUSE_OLD.x)*(mouse_pos.x-MGST_VEC_MOUSE_OLD.x)) >= MGST_MOVEMENT_ACCURACY)//If mouse has moved more thant defined accuracy to this direction continue
				{
					MGST_X_MOVEMENT = sign((mouse_pos.x - MGST_VEC_MOUSE_OLD.x));//Set x movement to the 1,0 or -1
				}
				else
				{
					MGST_X_MOVEMENT = 0;//If mouse didn't move to this direction enough we set x movmeent to 0
				}
				if((sign(mouse_pos.y-MGST_VEC_MOUSE_OLD.y)*(mouse_pos.y-MGST_VEC_MOUSE_OLD.y)) >= MGST_MOVEMENT_ACCURACY)//Same as with X check
				{
					MGST_Y_MOVEMENT = sign((mouse_pos.y - MGST_VEC_MOUSE_OLD.y));
				}
				else
				{
					MGST_Y_MOVEMENT = 0;
				}
				vec_set(MGST_VEC_MOUSE_OLD,vector(mouse_pos.x,mouse_pos.y,0));//Set the new position for MGST_VEC_MOUSE_OLD vector
				if(MGST_X_MOVEMENT != temp_x || MGST_Y_MOVEMENT != temp_y)//If x and/or y movement were different than the last x and/or y movement
				{
					temp_x = MGST_X_MOVEMENT;//Set last variables to x movement
					temp_y = MGST_Y_MOVEMENT;//Set last variable to y movement
					if(MGST_FOUND == 1)//If function has triggered global variable to 1 we can continue with this ( we have populated gest_check array)
					{
						for(i=0;i<found_start_check;i++)//Count for defined maxium gest number
						{
							if(gest_check[i] != NULL)//If cheked gest does exist in this I
							{
								if(gest_check[i]->part[gest_check[i]->part_check] != NULL)//If the gesture part exists in the gest_check with the amount part_check gives
								{
									if(gest_check[i]->part[gest_check[i]->part_check]->x == MGST_X_MOVEMENT && 
									gest_check[i]->part[gest_check[i]->part_check]->y == MGST_Y_MOVEMENT)//If both x and y movement matched with the gesture part
									{
										gest_check[i]->part_check++;//Increase the part check so the function can check the new part in the gest
										if(gest_check[i]->part_check >= (gest_check[i]->max_part))//If we've got more in the part check variable than there are parts we have a canditate
										{
											temp_found_gest = gest_check[i];//Set canditate to this gest_check
										}
									}
									else
									{
										gest_check[i] = NULL;//If the x and/or y movement didn't match with the gest check we can erase this gest_check
										found_check--;//Decrease the amount of gestures that fit
									}
								}
								else
								{
									gest_check[i] = NULL;//If there was no part with the variable gest_check pointed in part check variable
									found_check--;//Decrease the amount of gestures that fit
								}
							}
						}
						if(found_check <= MGST_GEST_COUNT)
						{
							if(found_check == 1)
							{
								for(i=0;i<MGST_GEST_COUNT;i++)//Count for defined maxium gest
								{
									if(gest_check[i] != NULL)//If gest_check with this I exists
									{
										temp_found_gest = gest_check[i];
										break;//Break the loop
									}
								}
							}
							if(found_check <= 0)
							{
								MGST_CHECK_VALID = -1;
							}
						}
						else
						{
							MGST_FOUND = 1;
						}
					}
					else//If we've not found any gestures yet (or the user has failed in gesting)
					{
						for(i=0;i<MGST_GEST_COUNT;i++)//Count for defined maxium GEST
						{
							if(gest[i])//If gest exists with this I
							if(gest[i]->part[0])//If the first part does exists in this I
							if(gest[i]->part[0]->x == MGST_X_MOVEMENT && gest[i]->part[0]->y == MGST_Y_MOVEMENT)//If coord movement match with the part
							{
								MGST_FOUND = 1;´//Set this variable ("We've found a gesture!")
								for(a=0;a<MGST_GEST_COUNT;a++)//Count for defined maxium gest
								{
									if(gest_check[a] == NULL)//if gest check in this A pointer does not exist we can continue
									{
										gest_check[a] = gest[i];//Set gest_check to point to gest
										gest_check[a]->part_check = 1;//We've allready found the first coord and it matched so we can move to next coord
										found_check++;//Increase the amoung of gestures that fit ( THIS VARIABLE IS MODIFIED THROUGH THE FUNCTION)
										found_start_check++;//Same as above, but the amount is kept the same as long as this loop is valid, THIS VARIABLE IS NOT MODIFIED
										break;
									}
								}
							}
						}
					}
				}
			}
			
			wait(1);	
		}
		wait(2);
	}
}

function create_gesture()
{
	var i;
	MGST* gest  = malloc(sizeof(MGST));
	gest->id = 0;
	gest->part_check = 0;
	gest->max_part = 0;
	for(i=0;i<MGST_MAX_GESTPART;i++)
	{
		gest->part[i] = NULL;
	}
	return gest;
}

function create_gesture_part(MGST*gest,var x, var y)
{
	if(!gest)
	{
		return 0;
	}
	var i;
	MGSTPART* part = malloc(sizeof(MGSTPART));
	part->x = x;
	part->y = y;
	for(i=0;i<MGST_MAX_GESTPART;i++)
	{
		if(gest->part[i] == NULL)
		{
			gest->part[i] = part;
			gest->max_part++;
			break;
		}
	}
	return part;
}
function read_gestures(STRING* path)
{
	/*---------------------------------------------------------------------------
	This function reads the gesture coordinates from the file defined in th
	STRING* path
	
	This is relevant peace to the gesture system, this function is also required
	before we can use gesture function.
	---------------------------------------------------------------------------*/
	var fhandle = file_open_read(path);//Our pointer to the file
	var new_line = 1;//Trigger to start a new line
	var x_read = 0;//First variable that's read
	var y_read = 0;//Second variable that's read
	var i;//Counter
	if(fhandle == NULL)//If we couldn't open the file 
	{
		error(MGST_STR_ERROR_LOAD1);//Print an error
		return 0;//Return this function
	}
	MGST* temp = NULL;//Temporary mouse gesture pointer
	for(i=0;i<MGST_MAX_GEST;i++)//Count for the defined maxium gest amount
	{
		gest[i] = NULL;//Initialize gesture array
	}
	while(1)//Loop for reading
	{
		if(x_read == MGST_END_FILE)//If x variable has this as its value we are at the end of the file
		{
			free(temp);//Free the created mouse gest(this function creates one empty gesture before this part is checked!)
			gest[i] = NULL;//Set gesture in I as empty
			break;//Break from read loop
		}
		MGST* mgst = create_gesture();
		temp = mgst;//Set temporary gest pointer to newly allocated mouse gesture
		while(1)//Coordinate populate loop
		{
			x_read = file_var_read(fhandle);//Read the first number
			if(x_read == MGST_END_LINE || x_read == MGST_END_FILE)//If these numbers are meat
			{
				new_line = 1;//Trigger new line
				break;
			}
			y_read = file_var_read(fhandle);//Read the second number
			create_gesture_part(temp,x_read, y_read);
		}
		if(temp)//If we've got temp gesture
		{
			for(i=0;i<MGST_MAX_GEST;i++)//Count for maxium gestures
			{
				if(gest[i] == NULL)//If there's a space for gestures
				{
					temp->id = i;//Give an id for the gesture based to I
					gest[i] = temp;//Set temp to gest array in I
					MGST_GEST_COUNT++;
					temp = NULL;
					break;//Break this loop
				}
			}
		}
	}
	return 1;//Return the function
}


Instruction to demo.c demonstration file
Quote:

This article covers only the basics!

Key mapping:
D(Gesture creation) = Save new gesture file from gesture array
Enter(Gesture creation) = After creating a gesture in edit mode this will save the gesture to array
R(Gesture creation) = Reset currect gesture
LMB(Gesture creation, play mode) = Make a gesture
LMB(Gesture checking) = Next gesture
RMB(Gesture checking) = Previous gesture
F1 = Enter play mode
F2 = Enter edit mode
F3 = Scroll through gestures

How to use edit mode:
First make a gesture (if you have checked out the KILL_LINES define you will see the gesture on the screen all the time, and if you haven't check it out the lines disappear in certain time) you will see coordinates appearing to the left side of the screen and a message if you have room for new parts in gesture. When you're satisfied with the gesture press Enter, this will save the gesture to the array. If you're not satisfied with coordinates press R. Note,switching to other mode will reset the gestured gest.


Old ReadMe
Use this as a side reference
Quote:

GestIT ver 1.0 by WinKIller0 for A7 engine
This is tested with A7 ver. 7.85.4
Other version SHOULD be able to handle this (A8)
---------------------------------

Content:
I: Pros&Flaws
II: Adding to your project
III: Creating new gestures
IV: Using the demo.c
V: History
VI: Legal stuff

I:Introduction
GestIT is a mouse gesture script for Acknex 7 engine. This script
allows you to use mouse in more efficent way than the ordinary mouse
use.Here are some flaws and pros of GestIT

GestIT, flaws:
----
*Struct system, creating gestures as structs allways consume memory (obvious).
----
*Loop system, adding loops to your project allways decreases performance
----
*Open system, when the gestures are loaded from simple text file you can't
hide the gestures to your scripts (well, with modifications you can...)

GestIT, pros:
----
*Easily intergrated, all you need is one text file, add two functions calls
and you're almost done, check chapter III for details
----
*Easily modified to your needs: You can change the place the gestures are
loaded to your own file (not accesiable by end-users), you can easily
add your camera code to the gesture loop
----
*Unlimited possibilities with gestures (well almost, this system doesn't
support any sort of speed check of the mouse)
----

II: Adding to your project
----
0) Include "gesturecheck.c" to your project
----
1) Open demo.c
----
2) Copy both functions gesture(NUMBER_1,NUMBER_2) and read_gestures(FILE)
to your project's main function (IMPORTANT! Place read_gestures before
gesture function!)
----
3) Change parameters:
*FILE: The file you want to use for gesture lookup
(STRING* MGST_STR_GEST_FILE handles the file path)
*NUMBER_1 The key have to be pressed to start the gesture
*NUMBER_2 The key that makes gesture oboslute (useful if you want to
use mouse left as gesture button but you don't want to gest when right
mouse button is pressed), leave this to 0 or lower if you dont' want
to define this button
----
4) Add check whetever the found_gest if valid and catch it, in order to
full functionality of this system the found_gest MUST BE reseted to
NULL before a new gesture can begin
----
5) (Optional:)Change the defined parameters found from the GestIT.c and
comment out line #93 from GestIT.c if you don't want reset after the
user has stopped pressing the button
----
6) Play with GestIT
----

III:Creating new gestures
Gestures are done by modifieng gest.txt file (or whatever file you want
to use) with simple system:
----
1,-1 Are coordinates, they come in pairs. For an instance this is gesture
move to upper-right of the screen, -1,1 would be bottom-left of the
screen. You can also use 0 to mark not change in coordinate.
Allways remember that:
COORDINATES COME IN PAIRS and X IS ALLWAYS BEFORE Y COORDINATE
----
-2 Used to mark end of gesture line, if this is not place the read assumes
that you want more coordinates to be read to the gesture
----
-3 Means end of the file. Put this to the bottom of the file
----

IV: Using the demo.c
The demo.c contains a simple program that allows you to 1) Play with
gestures (the "game" however isn't really interactive) and 2) create your
own gestures from within the program. To change between these two
modes, press F1 or F2 at any time ( See 3 for more information)
----
1)Play mode
In the play mode you will see an instruction to upper left of your screen
Following these orders you will geet the basic idea of what you need to
do. Couple of noticable things:
*The gesture, when found, is pointed only by text next to your cursor
*You don't get any information which part you need to gest
----
2)Gesture creation mode
This is really more of a program than the play mode. You notice in the
upper left corner the instructions again, and also there's a text
"Currect gesture coordinates", below this you wil see the coordinates
that your currect gesture is making. Below this text there's a text
that tells you if there is room or if there is not room for new coordinates
When you've done your gesture, press the Enter button, this will save
the gesture to the array and you're able to save the gesture. When
finished press D button in order to create output file of gestures
(default is: "gests.txt_copy.txt"). Copy the content of this file
to your REAL gesture input file and you have your gestures ready
to be used
----
3) Controls:
Mouse movement+defined gesture button(Default LMB)
*Make a gesture

F1
*Change to play mode

F2
*Change to Gesture creation mode

Enter
*Save gesture(Only available in gesture creation mode)

D
*Save gesture output file (Note, previous file will be erased)

V: History
----
ver 1.1 Minor fix release
----
ver 1.0 First public release
----

V: Legal stuff
This is free to use, distribute and modify. No credits needed


Last edited by Walori; 01/22/11 22:03.
Re: GestIT - mouse gesture system [Re: Walori] #352617
01/04/11 19:58
01/04/11 19:58
Joined: Sep 2003
Posts: 5,900
Bielefeld, Germany
Pappenheimer Offline
Senior Expert
Pappenheimer  Offline
Senior Expert

Joined: Sep 2003
Posts: 5,900
Bielefeld, Germany
I just tried it. I'm a bit lost, I understand how to create a gesture, but I don't get how to use it and how to see that the gesture is recognized by the program.

Re: GestIT - mouse gesture system [Re: Pappenheimer] #352685
01/05/11 09:57
01/05/11 09:57
Joined: Mar 2009
Posts: 88
Walori Offline OP
Junior Member
Walori  Offline OP
Junior Member

Joined: Mar 2009
Posts: 88
Update, read below

The gestures are basicly (on first version) done with this mechanic:

1) Gesture your gesture
2) Press enter, the program will tell you that it has saved the gesture by which id and how many parts it consisted
3) Press d, a new file will be created where all the gesture coords are dumped
4) Copy the coordinates from newly created file to gests.txt

That wasn't really sayed in the engine, that why this new update (I just add the code to here, no reason to DL this). This version gives you a realtime output of coordinates and gives you more information about what should be done. So you shouldn't (hopefully) anymore feel lost. Note tho that the gesture is regodnised only in a play mode.


Here's demo.c
Code:
#include <acknex.h>
#include <default.c>
#include "GestIT.c"

var demo_mode = -1;
TEXT* information =
{
	pos_x = 0;
	pos_y = 0;
	font = "Arial#16";
	string("This is GestIT demo\n","","");
	flags  = VISIBLE;
}
TEXT* gesture_output=
{
	strings = 11;//Should be MAX_GESTPART+1
	pos_x = 0;
	pos_y = 200;
	flags = VISIBLE;
}
void main()
{
	TEXT* printer = 
	{
		pos_x = 200;
		pos_y = 300;
		strings = 1;
		alpha = 100;
		flags = VISIBLE | TRANSLUCENT;
	}
	mouse_mode  = 4;
	read_gestures(MGST_STR_GEST_FILE);
	wait_for(read_gestures);
	gesture(280,281);
	str_cat((information.pstring)[0],"Currect gesture input file:");
	str_cat((information.pstring)[0],MGST_STR_GEST_FILE);
	str_cat((information.pstring)[0],"\nCurrect gesture output file:");
	str_cat((information.pstring)[0],MGST_STR_GEST_FILE);
	str_cat((information.pstring)[0],"_copy.txt\n");
	str_cpy((information.pstring)[1],"To enter play mode press F1\nTo enter gesture creation mode press F2");
	var i = 0;
	var a = 0;
	var line = 0;
	var time_delay;
	var temp_x = 0;
	var temp_y = 0;
	MGST* temp_gest = NULL;
	MGSTPART* temp_part = NULL;
	var fhandle = 0;
	var key_d_clear = 1;
	var key_enter_clear = 1;
	STRING* str_temp = NULL;
	var loc_temp_x = 0;
	var loc_temp_y = 0;
	var reset_gest = 0;
	for(i=0;i<11;i++)
	{
		str_cpy((gesture_output.pstring)[i],"");
	}
	i = 0;
	while(1)
	{
		
		if(key_f1)
		{
			gesture_output.flags = NULL;
			str_cpy((information.pstring)[1],"Now using: Play mode(Try to gesture the gestures)\nNote: If you just did a new gesture usgin this demo.c, you have to copy the gestures to gest.txt file");
			str_cpy((information.pstring)[2],"Press your defined gesture button to gest ( note,gests come in order they appear in gest file\nAfter this make a gesture in order\nGesture in order:");
			str_cat_num((information.pstring)[2],"%.f",(double)i+1);
			demo_mode = 1;
			reset_gest = 0;
		}
		if(key_f2)
		{
			gesture_output.flags = VISIBLE;
			str_cpy((information.pstring)[1],"Now using: New gesture creation");
			str_cpy((information.pstring)[2],"To create new gesture, gest it first and after press enter this will save the gesture to the database
			\nTo reset your gesture or last output, press R.Note: Pressing R will reset both if valid!\nTo save the database(dump), Press D. This will create a new file on local directory
			To exit press Esc\n\nCurrect gesture coordinates:");
			demo_mode = 2;
			reset_gest = 0;
		}
		if(!key_enter)key_enter_clear = 1;
		if(demo_mode == 1 || demo_mode == 2)
		{
			printer.pos_x = mouse_pos.x + 40;
			printer.pos_y = mouse_pos.y;
			if(time_delay >= 5)
			{
				printer.alpha -=1*time_step;
				if(printer.alpha <= 5)
				{
					str_cpy((printer.pstring)[0],"");
					time_delay = 0;
					line = 0;
					for(i=0;i<10;i++)
					{
						str_cpy((gesture_output.pstring)[i],"");
					}
				}
			}
			else
			{
				if(time_delay >= 0)
				{
					time_delay +=1*time_step;
				}
			}
		}
		if(demo_mode == 1)
		{
			if(gest[i])
			{
				/*
				THIS IS IMPORTANT PART 
				
				If the found gest is valid we need to reset it to NULL before we can continue
				with check operations
				*/
				if(found_gest)//IMPORTANT
				{
					if(found_gest == gest[i])
					{
						printer.alpha = 100;
						str_cpy((printer.pstring)[0],"");
						str_cpy((printer.pstring)[0],"Found gest, try the next one");
						beep();
						i++;
						time_delay = 0;
						found_gest = NULL;//IMPORTANT
					}
					else
					{
						printer.alpha = 100;
						str_cpy((printer.pstring)[0],"");
						time_delay = 0;
						str_cpy((printer.pstring)[0],"Did not do the right gest, try again! (resetting found gesture)");
						found_gest = NULL;//IMPORTANT
					}
				}
				/*
				END OF IMPORTANT PART
				*/
			}
			else
			{
				if(printer.alpha <=55 && time_delay >= 0)
				{
					time_delay = -1;
					printer.alpha = 100;
					str_cat((printer.pstring)[0],"\nNo more gestures, press T to reset gestures and start over\n Or press Q to exist");
				}
				if(key_t)
				{
					str_cpy((printer.pstring)[0],"Reseted");
					found_gest = NULL;
					i = 0;
				}
				if(key_q)
				{
					sys_exit("");
				}
			}
		}
		if(demo_mode == 2)
		{
			time_delay = -1;
			if(key_d && key_d_clear == 1)
			{
				str_temp = str_create(_chr(MGST_STR_GEST_FILE));
				str_cat(str_temp,"_copy.txt");
				fhandle = file_open_write(str_temp);
				if(fhandle != NULL)
				{
					for(i=0;i<MGST_MAX_GEST;i++)
					{
						if(gest[i])
						{
							for(a=0;a<MGST_MAX_GESTPART;a++)
							{
								if(gest[i]->part[a])
								{
									file_var_write(fhandle,gest[i]->part[a]->x);
									file_var_write(fhandle,gest[i]->part[a]->y);
								}
							}
							file_var_write(fhandle,-2);
						}
					}
					file_var_write(fhandle,-3);
					reset_gest = 1;
					file_close(fhandle);
					printf("File saved: %s",_chr(str_temp));
				}
				key_d_clear = 0;
			}
			if(!key_d)
			{
				key_d_clear = 1;
			}
			str_cpy((printer.pstring)[0],"");
			str_cat_num((printer.pstring)[0],"X_MOVEMENT:%.f",MGST_X_MOVEMENT);
			str_cat_num((printer.pstring)[0],"\nY_MOVEMENT:%.f",MGST_Y_MOVEMENT);
			if(mouse_moving == 1 && vec_dist(MGST_VEC_MOUSE_OLD,mouse_pos.x) >= MGST_MOVEMENT_CHECK && MGST_CHECK_VALID)
			{
				if(!temp_gest)
				{
					temp_gest = create_gesture();
					for(i=0;i<10;i++)
					{
						str_cpy((gesture_output.pstring)[i],"");
					}
					line = 0;
				}
				else
				{
					if(MGST_X_MOVEMENT != 0 || MGST_Y_MOVEMENT != 0)
					{
						if(MGST_X_MOVEMENT != loc_temp_x || MGST_Y_MOVEMENT != loc_temp_y)
						{
							loc_temp_x = MGST_X_MOVEMENT;
							loc_temp_y = MGST_Y_MOVEMENT;
							if(temp_gest->max_part < MGST_MAX_GESTPART)
							{
								create_gesture_part(temp_gest,MGST_X_MOVEMENT,MGST_Y_MOVEMENT);
								if((gesture_output.pstring)[line])
								{
									str_cpy((gesture_output.pstring)[line],"(X,Y):");
									str_cat_num((gesture_output.pstring)[line],"(%.f,",MGST_X_MOVEMENT);
									str_cat_num((gesture_output.pstring)[line],"%.f)",MGST_Y_MOVEMENT);
									line++;
								}
								str_cpy((gesture_output.pstring)[10],"There's still room for gesture parts");
							}
							else
							{
								str_cpy((gesture_output.pstring)[10],"No room for gesture parts");
							}
						}
					}
				}
			}
			if(mouse_moving == 0)
			{
				if(key_r)
				{
					if(temp_gest)
					{
						for(i=0;i<MGST_MAX_GESTPART;i++)
						{
							if(temp_gest->part[i])
							free(temp_gest->part[i]);
						}
						free(temp_gest);
					}
					for(i=0;i<10;i++)
					{
						str_cpy((gesture_output.pstring)[i],"");
					}
					line = 0;
					reset_gest = 0;
					temp_gest = NULL;
				}
			}
			if(key_enter && temp_gest != NULL && key_enter_clear == 1)
			{
				if(temp_gest->max_part >= 1)
				{
					for(i=0;i<MGST_MAX_GEST;i++)
					{
						if(!gest[i])
						{
							gest[i] = temp_gest;
							printf("Gesture saved succesfully (information to follow)\nGesture parts: %.f\nGesture saved ID (order of appearence in the file): %.f",(double)temp_gest->max_part,(double)i);
							wait(2);
							vec_set(MGST_VEC_MOUSE_OLD,mouse_pos.x);
							temp_gest = NULL;
							break;
						}
					}
				}
				key_enter_clear = 0;
			}
		}
		wait(1);
	}
}



Here's the GestIT.c
Code:
#ifndef acknex.h
	#include <acknex.h>
#endif

#define MGST_MOVEMENT_CHECK 20//The distance the mouse has to move before a new check is called
#define MGST_MOVEMENT_ACCURACY 5//How much we give space for an error
#define MGST_END_LINE -2//Which number we have to meet before we create a new gesture struct
#define MGST_END_FILE -3//When this number is meat we've reached the end of the file
#define MGST_TIME_DELAY 2//The time that mouse is required to be stopped before we check for gesture
#define MGST_ENABLE_TRAIL//If this is enabled a trail is drawn based on mouse movement on the screen
#define MGST_MAX_GEST 200//Maxium amount of gestures(terminates the array size)
#define MGST_MAX_GESTPART 10//Maxium amount of parts in gestures

STRING* MGST_STR_ERROR_LOAD1 = "Could not open a valid gesture file. Please check the file/path given to the function\nThis function returns 0";
STRING* MGST_STR_GEST_FILE = "gests.txt";

VECTOR MGST_VEC_MOUSE_OLD;

var MGST_FOUND = -1;//Global variable used by the gesture function
var MGST_KILL_LINES = 1;//Used to kill lines made by gesture (function draw_line_coord(x1,x2,y1,y2))
var MGST_GEST_COUNT = 1;//Used for faster array checks, counts the total amount of gestures loaded
var MGST_X_MOVEMENT = 0;//Global variable of which direction mouse is moving on X axis
var MGST_Y_MOVEMENT = 0;//Global variable of mouse movement on Y axis
var MGST_RESET_CHECK = 0;//Used to reset gesture checking
var MGST_CHECK_VALID = 0;//Used to check if the chek loop is valid
var temp_x = 0;//Temporary X axis movement var
var temp_y = 0;//Temporary Y axis movement var

typedef struct
{
	var x,y,z;//Coordinates, Z is free for user
}MGSTPART;//Gesture part struct

typedef struct
{
	var id;//Gesture's ID
	var part_check;//Variable that tells gesture function which part it should check next
	var max_part;//Tells how many parts we have
	MGSTPART* part[MGST_MAX_GESTPART];//Array of gesture parts, size of defined maxium gest part
}MGST;

MGST* gest[MGST_MAX_GEST];//Array for REAL gestures
MGST* gest_check[MGST_MAX_GEST];//Array for GESTURES THAT ARE CHECKED (these point to REAL gestures)
MGST* found_gest;//Pointer to the found variabel in gesture function

function draw_line_coord(x1,x2,y1,y2)
{
	var time_delay = 0;//Counter variableu
	while(1)
	{
		if(time_delay >= 10)//if this line has existed for over 10 seconds
		{
			if(MGST_KILL_LINES == 1 || MGST_KILL_LINES == 2)
			{
				break;
			}
		}
		else
		{
			time_delay +=1*time_step;//If the time isn't meat, increase the counter
		}
		draw_line(vector(x1,x2,0), vector(0,0,250), 0);//Draw line from x1,x2
		draw_line(vector(y1,y2,0), vector(0,0,250), 100);//Draw line to y1,y2
		draw_quad(NULL, vector(x1,x2,0), NULL, vector(5,5,0), NULL, vector(0,250,0), 100, 0);//Add square to start position
		wait(1);
	}
	
}
function gesture(var key_press,var ignore_press)
{
	/*---------------------------------------------------------------------------
	Gesture main function, this function is RELEVANT for your projects.
	
	This function holds the spine of the wholse system, it calculates the gestures
	and their coordinates to the ones that are loaded to the memory. 
	
	funtion comments start here
	---------------------------------------------------------------------------*/
	/*---------------------------------------------------------------------------
	---------------------------------------------------------------------------*/
	var i,a;//Counter variables
	var time_delay  = 0;//Counter how long it takes to check the gesture after the mouse is stopped
	var found_check = 0;//Counter of how many gestures fit (faster searching through the array), THIS IS MODIFIED
	var found_start_check = 0;//same as above but this variable holds the amount of fitting gestures until the gesture loop breaks
	vec_set(MGST_VEC_MOUSE_OLD,vector(mouse_pos.x,mouse_pos.y,0));//Set mouse old to mouse position
	MGST* temp_found_gest = NULL;//Temporary gesture canditate pointer
	MGST_RESET_CHECK = 1;
	while(1)
	{
		proc_mode = PROC_LATE;
		/*---------------------------------------------------------------------------
		Preset certain parts before checking if we're pressing the key
		---------------------------------------------------------------------------*/
		// 	if(!key_pressed(key_press))//Comment out this line if you don't want reseting the gestures before user lets off the gesture button
		if(MGST_RESET_CHECK == 1)
		{
			for(i=0;i<MGST_GEST_COUNT;i++)//Count for defined maxium gest amourn
			{
				if(gest[i])//If there's a gesture with this I
				{
					gest[i]->part_check = 0;//Reset its gesture part counter
				}
				gest_check[i] = NULL;//Reset gest_check by this I
			}
			temp_found_gest = NULL;
			found_gest = NULL;
			MGST_X_MOVEMENT = 0;//Reset x mouse movement variable
			MGST_Y_MOVEMENT = 0;//Reset y movement variable
			temp_x = -10;//Reset last x movement
			temp_y = -10;//Rest last y movement
			found_start_check = 0;
			found_check = 0;
			time_delay = 0;
			MGST_FOUND = 0;//Set this variable to we want to sync mouse position to mouse old
			MGST_RESET_CHECK = 0;//Reset the reseting variable
		}
		if(key_pressed(key_press))
		{
			vec_set(MGST_VEC_MOUSE_OLD,vector(mouse_pos.x,mouse_pos.y,0));
		}
		MGST_CHECK_VALID = 0;
		while(key_pressed(key_press) && MGST_RESET_CHECK == 0)//If wanted key is pressed continue wit htis (And we aren't reseting check)
		{
			proc_mode = PROC_LATE;
			if(MGST_RESET_CHECK != 0)//If reset variable is not NULL, break the check
			{
				break;
			}
			if(ignore_press > 0 && key_pressed(ignore_press))//If we've defined ignore press and we're pressing the button
			{
				break;//Break from this loop
			}
			MGST_CHECK_VALID = 1;//Set checking valid, check loop is valid in other words
			if(mouse_moving == 0)//If  mouse doesn't move
			{
				time_delay +=1*time_step;//Increase time delay
				if(time_delay >= MGST_TIME_DELAY)//If time delay variable is higher thand defined time delay
				{
					if(temp_found_gest)//If we have mouse gest canditate
					{
						found_gest = temp_found_gest;//Set found gest to mouse gest canditate
						temp_found_gest = NULL;
					}
					else
					{
						found_gest = NULL;//If we didn't have gest caditate set found_gest pointer to NULL
					}
					MGST_RESET_CHECK = 1;
				}
			}
			else
			{
				#ifdef MGST_ENABLE_TRAIL
					draw_line_coord(MGST_VEC_MOUSE_OLD.x,MGST_VEC_MOUSE_OLD.y,mouse_pos.x,mouse_pos.y);//If enabled lines are drawn based on mouse movement
				#endif
				time_delay = 0;//If mouse is moving set time delay to 0
			}
			if(vec_dist(MGST_VEC_MOUSE_OLD,vector(mouse_pos.x,mouse_pos.y,0)) >= MGST_MOVEMENT_CHECK && MGST_RESET_CHECK == 0)//If mouse has moved more than defined movement check
			{
				if((sign(mouse_pos.x-MGST_VEC_MOUSE_OLD.x)*(mouse_pos.x-MGST_VEC_MOUSE_OLD.x)) >= MGST_MOVEMENT_ACCURACY)//If mouse has moved more thant defined accuracy to this direction continue
				{
					MGST_X_MOVEMENT = sign((mouse_pos.x - MGST_VEC_MOUSE_OLD.x));//Set x movement to the 1,0 or -1
				}
				else
				{
					MGST_X_MOVEMENT = 0;//If mouse didn't move to this direction enough we set x movmeent to 0
				}
				if((sign(mouse_pos.y-MGST_VEC_MOUSE_OLD.y)*(mouse_pos.y-MGST_VEC_MOUSE_OLD.y)) >= MGST_MOVEMENT_ACCURACY)//Same as with X check
				{
					MGST_Y_MOVEMENT = sign((mouse_pos.y - MGST_VEC_MOUSE_OLD.y));
				}
				else
				{
					MGST_Y_MOVEMENT = 0;
				}
				vec_set(MGST_VEC_MOUSE_OLD,vector(mouse_pos.x,mouse_pos.y,0));//Set the new position for MGST_VEC_MOUSE_OLD vector
				if(MGST_X_MOVEMENT != temp_x || MGST_Y_MOVEMENT != temp_y)//If x and/or y movement were different than the last x and/or y movement
				{
					temp_x = MGST_X_MOVEMENT;//Set last variables to x movement
					temp_y = MGST_Y_MOVEMENT;//Set last variable to y movement
					if(MGST_FOUND == 1)//If function has triggered global variable to 1 we can continue with this ( we have populated gest_check array)
					{
						for(i=0;i<found_start_check;i++)//Count for defined maxium gest number
						{
							if(gest_check[i] != NULL)//If cheked gest does exist in this I
							{
								if(gest_check[i]->part[gest_check[i]->part_check] != NULL)//If the gesture part exists in the gest_check with the amount part_check gives
								{
									if(gest_check[i]->part[gest_check[i]->part_check]->x == MGST_X_MOVEMENT && 
									gest_check[i]->part[gest_check[i]->part_check]->y == MGST_Y_MOVEMENT)//If both x and y movement matched with the gesture part
									{
										gest_check[i]->part_check++;//Increase the part check so the function can check the new part in the gest
										if(gest_check[i]->part_check >= (gest_check[i]->max_part))//If we've got more in the part check variable than there are parts we have a canditate
										{
											temp_found_gest = gest_check[i];//Set canditate to this gest_check
										}
									}
									else
									{
										gest_check[i] = NULL;//If the x and/or y movement didn't match with the gest check we can erase this gest_check
										found_check--;//Decrease the amount of gestures that fit
									}
								}
								else
								{
									gest_check[i] = NULL;//If there was no part with the variable gest_check pointed in part check variable
									found_check--;//Decrease the amount of gestures that fit
								}
							}
						}
						if(found_check <= MGST_GEST_COUNT)
						{
							if(found_check == 1)
							{
								for(i=0;i<MGST_GEST_COUNT;i++)//Count for defined maxium gest
								{
									if(gest_check[i] != NULL)//If gest_check with this I exists
									{
										temp_found_gest = gest_check[i];
										break;//Break the loop
									}
								}
							}
							if(found_check <= 0)
							{
								MGST_RESET_CHECK = 1;
							}
						}
						else
						{
							MGST_FOUND = 1;
						}
					}
					else//If we've not found any gestures yet (or the user has failed in gesting)
					{
						for(i=0;i<MGST_GEST_COUNT;i++)//Count for defined maxium GEST
						{
							if(gest[i])//If gest exists with this I
							if(gest[i]->part[0])//If the first part does exists in this I
							if(gest[i]->part[0]->x == MGST_X_MOVEMENT && gest[i]->part[0]->y == MGST_Y_MOVEMENT)//If coord movement match with the part
							{
								MGST_FOUND = 1;´//Set this variable ("We've found a gesture!")
								for(a=0;a<MGST_GEST_COUNT;a++)//Count for defined maxium gest
								{
									if(gest_check[a] == NULL)//if gest check in this A pointer does not exist we can continue
									{
										gest_check[a] = gest[i];//Set gest_check to point to gest
										gest_check[a]->part_check = 1;//We've allready found the first coord and it matched so we can move to next coord
										found_check++;//Increase the amoung of gestures that fit ( THIS VARIABLE IS MODIFIED THROUGH THE FUNCTION)
										found_start_check++;//Same as above, but the amount is kept the same as long as this loop is valid, THIS VARIABLE IS NOT MODIFIED
										break;
									}
								}
							}
						}
					}
				}
			}
			
			wait(1);	
		}
		wait(2);
	}
}

function create_gesture()
{
	var i;
	MGST* gest  = malloc(sizeof(MGST));
	gest->id = 0;
	gest->part_check = 0;
	gest->max_part = 0;
	for(i=0;i<MGST_MAX_GESTPART;i++)
	{
		gest->part[i] = NULL;
	}
	return gest;
}

function create_gesture_part(MGST*gest,var x, var y)
{
	if(!gest)
	{
		return 0;
	}
	var i;
	MGSTPART* part = malloc(sizeof(MGSTPART));
	part->x = x;
	part->y = y;
	for(i=0;i<MGST_MAX_GESTPART;i++)
	{
		if(gest->part[i] == NULL)
		{
			gest->part[i] = part;
			gest->max_part++;
			break;
		}
	}
	return part;
}
function read_gestures(STRING* path)
{
	/*---------------------------------------------------------------------------
	This function reads the gesture coordinates from the file defined in th
	STRING* path
	
	This is relevant peace to the gesture system, this function is also required
	before we can use gesture function.
	---------------------------------------------------------------------------*/
	var fhandle = file_open_read(path);//Our pointer to the file
	var new_line = 1;//Trigger to start a new line
	var x_read = 0;//First variable that's read
	var y_read = 0;//Second variable that's read
	var i;//Counter
	if(fhandle == NULL)//If we couldn't open the file 
	{
		error(MGST_STR_ERROR_LOAD1);//Print an error
		return 0;//Return this function
	}
	MGST* temp = NULL;//Temporary mouse gesture pointer
	for(i=0;i<MGST_MAX_GEST;i++)//Count for the defined maxium gest amount
	{
		gest[i] = NULL;//Initialize gesture array
	}
	while(1)//Loop for reading
	{
		if(x_read == MGST_END_FILE)//If x variable has this as its value we are at the end of the file
		{
			free(temp);//Free the created mouse gest(this function creates one empty gesture before this part is checked!)
			gest[i] = NULL;//Set gesture in I as empty
			break;//Break from read loop
		}
		MGST* mgst = create_gesture();
		temp = mgst;//Set temporary gest pointer to newly allocated mouse gesture
		while(1)//Coordinate populate loop
		{
			x_read = file_var_read(fhandle);//Read the first number
			if(x_read == MGST_END_LINE || x_read == MGST_END_FILE)//If these numbers are meat
			{
				new_line = 1;//Trigger new line
				break;
			}
			y_read = file_var_read(fhandle);//Read the second number
			create_gesture_part(temp,x_read, y_read);
		}
		if(temp)//If we've got temp gesture
		{
			for(i=0;i<MGST_MAX_GEST;i++)//Count for maxium gestures
			{
				if(gest[i] == NULL)//If there's a space for gestures
				{
					temp->id = i;//Give an id for the gesture based to I
					gest[i] = temp;//Set temp to gest array in I
					MGST_GEST_COUNT++;
					temp = NULL;
					break;//Break this loop
				}
			}
		}
	}
	return 1;//Return the function
}



Last edited by Walori; 01/05/11 10:03.
Re: GestIT - mouse gesture system [Re: Walori] #352967
01/06/11 21:06
01/06/11 21:06
Joined: Sep 2003
Posts: 5,900
Bielefeld, Germany
Pappenheimer Offline
Senior Expert
Pappenheimer  Offline
Senior Expert

Joined: Sep 2003
Posts: 5,900
Bielefeld, Germany
"Note tho that the gesture is recognized only in a play mode."

How do get into play mode?

Re: GestIT - mouse gesture system [Re: Pappenheimer] #353006
01/07/11 09:05
01/07/11 09:05
Joined: Mar 2009
Posts: 88
Walori Offline OP
Junior Member
Walori  Offline OP
Junior Member

Joined: Mar 2009
Posts: 88
Press F1 or F2 at any time to change between the modes.

F1= Play mode
F2= Gesture creation mode

Re: GestIT - mouse gesture system [Re: Walori] #353749
01/12/11 17:34
01/12/11 17:34
Joined: Jun 2006
Posts: 2,640
Earth
Germanunkol Offline
Expert
Germanunkol  Offline
Expert

Joined: Jun 2006
Posts: 2,640
Earth
After playing around with it for a while, I could make it save something when I press D in Edit mode. But How do I notice, in play mode, that the guesture is recognized?


~"I never let school interfere with my education"~
-Mark Twain
Re: GestIT - mouse gesture system (updated) [Re: Germanunkol] #354876
01/22/11 21:08
01/22/11 21:08
Joined: Mar 2009
Posts: 88
Walori Offline OP
Junior Member
Walori  Offline OP
Junior Member

Joined: Mar 2009
Posts: 88
Hello and sorry for a late reply, other things took over me.

In play mode after you've succesfully gestured the gesture next in line you'll get a beep sound and the mouse information text tells you you're succesful.

I've now updated the first post with the latest demo.c and GestIT scripts, check them out. Now you shouldn't have any ttroubles with gesture creation

regards


Moderated by  HeelX, Lukas, rayp, Rei_Ayanami, Superku, Tobias, TWO, VeT 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1