mouse_event and multitouch

Posted By: Joozey

mouse_event and multitouch - 03/07/11 11:15

Hi,

I am attempting to control mouse events using multitouch. The initial problem is that tablet touch only registers a mouse click when it drags, not just taps. So I can only click on panel buttons when I smudge my finger over a button, not simply tap.

So I did it over from the start, I wrote a DLL plugin which registers ev->hWnd as touch window, and set ev->ScanMessage to my own multitouch message handler function. Currently the handler assigns a value to global integer _global_MultiTouchActive. I retrieve this value in Lite-C, and print a little text on screen when I tap. This works very nice and quick.

Now I figured that if I want to simulate the left mouse button, I should call mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0) (and also LEFTUP). This starts to be a problem; the tapping response is severely delayed! It takes about half a second for the tapping to react again. Quickly pressing buttons is not possible anymore. It only happens when mouse_event is invoked.

Other than writing my own button function and check for the _global_MultiTouchActive integer in there, is there a way to somehow fix the delay with mouse_event?

Regards,
Joozey
Posted By: jcl

Re: mouse_event and multitouch - 03/07/11 13:24

I have no idea, but maybe someone else can help here?
Posted By: EvilSOB

Re: mouse_event and multitouch - 03/07/11 14:23

Joozey.

Can you try modding your plugin to JUST be a DLL?
Then try it from another application than 3DGS.

Just to see if the lag in IN your DLL,
or in the message queue between it and 3DGS,
or even withIN 3DGS itself...


Another idea...
Try adding a "slight" delay, or dummy message,
between the LEFTDOWN and the LEFTUP messages...
Posted By: Superku

Re: mouse_event and multitouch - 03/07/11 19:52

I've once written an inventory that could be controlled with the mouse, keyboard and gamepad. When you did not use the mouse, the mouse cursor was moved manually and I called mouse_event to simulate the left click the following way:

Code:
if(jump && inv_key_released2) {
	inv_key_released2 = 0;
	SetCursorPos((int)mouse_pos.x,(int)mouse_pos.y);
	mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
	wait(1);
	mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}


That has worked without any delay, don't know if this helps you, though.
Posted By: EvilSOB

Re: mouse_event and multitouch - 03/08/11 09:39

Yeah, that helps... It is doing the same thing by the looks of it.

But it DOES have a delay... the wait between the DOWN and the UP...
Thats what I was talking about.

So is it possible that for some reason the UP is not being called? (Thats what it sounds like)
For example, the function is being terminated during the wait?

Try setting "proc_mode = PROC_GLOBAL;" the the function to test for that,
or put a "beep()" after the UP so you can hear that it gets there...
Posted By: Joozey

Re: mouse_event and multitouch - 03/08/11 13:31

Yes, the function continues after the UP mouse_event, but that doesn't say much about the process of the UP function. I guess even the DOWN already takes some time, as the delay is also showing up without UP.

I constructed a bit more dirty workaround, but it doesn't involve writing a new button function. I make the button react on "over", and check in the function if the _global_MultiTouchActive is off.

Code:
#define MULTITOUCH_CHECK if( _global_MultiTouchActive == 0 && mouse_left == 0 ){ return; }

...

void button_activate()
{
  MULTITOUCH_CHECK

  ... do stuff ...
}



This works well.
Didn't yet fixed the delay though, as I didn't involve mouse_event. Right now I need to continue, and choose for the "Hurray, it works, don't touch anymore" (pun) method laugh.
Posted By: MMike

Re: mouse_event and multitouch - 03/08/11 20:32

i have a multitouch that is not a dll, uses the user32.dll..

i will try so check where it is.. and you can then test.

...ok i did find. but the application is for another kind of usage, that you might not find interesting.

its for drag 2 panels or more at the same time. the touch principles are there, but optimized for my needs..
Posted By: Joozey

Re: mouse_event and multitouch - 03/08/11 20:48

Yeah, I figured that I could retrieve RegisterTouchScreen through that indeed, just figured it a bit late laugh. Still, doesn't solve the delay for me.
Posted By: MMike

Re: mouse_event and multitouch - 03/08/11 20:53

try this.. and use 2 fingers to drag...
change the panels image because you dont have the same..

Code:
///////////////////////////////
#include <acknex.h>
#include <default.c>
#include <litec.h>

//#include <default.c>
#include <extra.h>
#include <windows.h>
#include <stdio.h>

#define NID_READY 0x80
#define NID_INTEGRATED_TOUCH 0x01
#define NID_MULTI_INPUT 0x40
#define WM_TOUCH 0x0240

#define TWF_FINETOUCH       (0x00000001)
#define TWF_WANTPALM        (0x00000002)
/*
 * Conversion of touch input coordinates to pixels
 */
#define TOUCH_COORD_TO_PIXEL(l)         ((l) / 100)

/*
 * Touch input flag values (TOUCHINPUT.dwFlags)
 */
#define TOUCHEVENTF_MOVE            0x0001
#define TOUCHEVENTF_DOWN            0x0002
#define TOUCHEVENTF_UP              0x0004
#define TOUCHEVENTF_INRANGE         0x0008
#define TOUCHEVENTF_PRIMARY         0x0010
#define TOUCHEVENTF_NOCOALESCE      0x0020
#define TOUCHEVENTF_PEN             0x0040
#define TOUCHEVENTF_PALM            0x0080

/*
 * Touch input mask values (TOUCHINPUT.dwMask)
 */
#define TOUCHINPUTMASKF_TIMEFROMSYSTEM  0x0001  // the dwTime field contains a system generated value
#define TOUCHINPUTMASKF_EXTRAINFO       0x0002  // the dwExtraInfo field is valid
#define TOUCHINPUTMASKF_CONTACTAREA     0x0004  // the cxContact and cyContact fields are valid

///////////////////////////////
//long WINAPI GetOpenClipboardWindow(long);





BOOL WINAPI RegisterTouchWindow(HWND,long ulFlags);
#define PRAGMA_API RegisterTouchWindow;user32!RegisterTouchWindow





#define PRAGMA_ZERO   // initialize variables
typedef struct _TOUCHINPUT {
  LONG      x;
  LONG      y;
  HANDLE    hSource;
  DWORD     dwID;
  DWORD     dwFlags;
  DWORD     dwMask;
  DWORD     dwTime;
  LONG dwExtraInfo;
  DWORD     cxContact;
  DWORD     cyContact;
} TOUCHINPUT;

typedef struct _ID {
  int      x;
  int      y;
  
} POINT_ID;

POINT_ID pID[100];


BOOL WINAPI GetTouchInputInfo(HANDLE hTouchInput,UINT cInputs,long pInputs,int cbSize);
#define PRAGMA_API GetTouchInputInfo;user32!GetTouchInputInfo

BOOL WINAPI GetTouchInputInfo(HANDLE hTouchInput,UINT cInputs,long pInputs,int cbSize);
#define PRAGMA_API GetTouchInputInfo;user32!GetTouchInputInfo

BOOL WINAPI CloseTouchInputHandle(HANDLE hTouchInput);
#define PRAGMA_API CloseTouchInputHandle;user32!CloseTouchInputHandle




function exits(){
	
	sys_exit("wuit");
	
	}
	
///GLOBAL VAR:
TOUCHINPUT pInputs[100];


var val_11=0;
var val_12=0;
var val_13=0;

var val_21=0;
var val_22=0;
var val_23=0;

var val_31=0;
var val_32=0;
var val_33=0;

var c_id=0;
var c_id2=0;
PANEL* stats={
	
digits(10,30,"id:%.0f",*,1,val_11);
digits(10,40,"x: %.0f",*,1,val_12);
digits(10,50,"y: %.0f",*,1,val_13);



digits(80,30,"id:%.0f",*,1,val_21);
digits(80,40,"x: %.0f",*,1,val_22);
digits(80,50,"y: %.0f",*,1,val_23);

digits(180,30,"id:%.0f",*,1,val_31);
digits(180,40,"x: %.0f",*,1,val_32);
digits(180,50,"y: %.0f",*,1,val_33);
//digits(10,35,4,*,1,pInputs[1].dwID);
	flags=SHOW;
}

function touched(PANEL* o);

PANEL* t1={
	bmap="quad2.png";
	flags=SHOW | TRANSLUCENT | LIGHT;
	pos_x=100;
	pos_y=200;
event=touched;
}
	
PANEL* t2={
	bmap="quad2.png";
	flags=SHOW | TRANSLUCENT | LIGHT;
	pos_x=300;
	pos_y=200;
event=touched;
}


function touched(PANEL* o){
	
	
if(o==t1){o.blue=222;o.red=2; o.pos_y-=40;}
if(o==t2){o.blue=222;o.red=2; o.pos_y-=40;}
	
	}

function object_ontouch(PANEL* p,TOUCHINPUT* ti){
//ONLY TOUCHES DOWN ONCE!!

//TODO: IF Skill_x is busy, add the skill_y for secundary two points manipulation
p.skill_x=ti.dwID;	

STRING* debug_str4="#10";
//PANEL is attached with the ID, that will follow move
while(p.skill_x>0){
	 
if(ti.dwFlags & TOUCHEVENTF_UP){break;}
str_for_num(debug_str4,ti.dwID);
str_cat(debug_str4," is attached to this entity");
draw_text(debug_str4,(p.pos_x)+10,(p.pos_y+10),vector(0,100,255)); // bright red text   
p.pos_x=pID[ti.dwID].x;	
p.pos_y=pID[ti.dwID].y;	
	
wait(1);
}

//Loop breaked, because finger released by flag touch_up

//Break atachment to finger on skill_x 
p.skill_x=-3;

}

function object_release(PANEL* p){
	
	p.skill_x=-1;
	}	
	
function check_detection(PANEL* p, TOUCHINPUT* ti){
//further check or alpha pixel	
if((p.pos_x<ti.x && p.pos_x+p.size_x>ti.x) && (p.pos_y<ti.y && p.pos_y+p.size_y>ti.y)){
//that px,py cursor is on the panel area. Activate detection..
object_ontouch(p, ti);
}
}

	
function detection_list(TOUCHINPUT* ti){
//all object that recieve clicks.
check_detection(t1,ti); 
check_detection(t2,ti); 
}
	
	
	
void init_vals(){

while(1){
val_11=pInputs[0].dwID;
val_12=pInputs[0].x;
val_13=pInputs[0].y;

val_21=pInputs[1].dwID;
val_21=pInputs[1].x;
val_23=pInputs[1].y;

wait(1);}



	}


function touch_object(PANEL* p, TOUCHINPUT* a){
	
	p.skill_x=a.dwID+10;
	beep();
	
	}
	
void OnTouchDownHandler(TOUCHINPUT* ti)
{//POINT p = GetTouchPoint(hWnd, ti);

 detection_list(ti); //send pointer to detection
 
// t1.skill_x=-1;
// t2.skill_x=-1;
 STRING* debug_str4="#10";
 while(ti.dwFlags & TOUCHEVENTF_DOWN){

str_for_num(debug_str4,ti.dwID);
str_cat(debug_str4," DOWN");
draw_quad(NULL,vector(ti.x+10,ti.y+10,0),NULL,vector(10,10,0),vector(1,1,0),vector(100,222,0),100,0);
draw_text(debug_str4,(ti.x)+10,(ti.y),vector(100,100,255)); // bright red text   


//if(mouse_left==1 && mouse_panel!=NULL){mouse_panel.skill_x=10;beep();}
wait(1);} 
 

 
//draw_quad(NULL,vector(dx+120,dy,0),NULL,vector(random(ti.dwID),random(ti.dwID),random(ti.dwID)),vector(1,1,0),vector(0,222,0),100,0);
}


//Global var defining moving touched at the same time.. to avoid calling move handles, every time the same id is detected as moving..
int touch_initialized[100]; //100 touches

//// activate sonar detector when mouse down and move... dispatch each object handle.
//detect the size by their pixel position.. in between the touch area, if yes, attribute it an action.
void OnTouchMoveHandler_o(TOUCHINPUT* ti)
{
if( touch_initialized[ti.dwID]==1){return;}


 
 
 STRING* debug_str4="#10";
 
 touch_initialized[ti.dwID]=1;

 while( touch_initialized[ti.dwID]==1){
 	

str_for_num(debug_str4,ti.dwID);
str_cat(debug_str4," MOVE");
draw_quad(NULL,vector(ti.x+10,ti.y+10,0),NULL,vector(10,10,0),vector(1,1,0),vector(100,222,0),100,0);
draw_text(debug_str4,(ti.x)+10,(ti.y-10),vector(0,100,255)); // bright red text   


wait(1);}



}


void OnTouchUpHandler(TOUCHINPUT* ti)
{//POINT p = GetTouchPoint(hWnd, ti);

 //t1.skill_x=-2;
 //t2.skill_x=-2;
 //touch_initialized[ti.dwID]=0;
//object_release() //TODO.. COMO associar o retirar do dedo ao entity corresponte sem interferir com outro point k ja esteja la regiastado?
}	


LRESULT OnTouch(HWND hWnd, WPARAM wParam, LPARAM lParam ){
    BOOL bHandled = FALSE;
    UINT cInputs = LOWORD(wParam); //numberof active inputs
    //PTOUCHINPUT* pInputs;

// TOUCHINPUT* PTOUCHINPUT = malloc(sizeof(TOUCHINPUT)); // creates a new SPOT struct at runtime
// memset(PTOUCHINPUT,0,sizeof(TOUCHINPUT)); // set the struct content to zero (it's undefined after malloc)
/// OBSERVA o NUMERO DE INPUTS NO ECRAN, E GERA 1 STRUCT para cada um dos inputs.
//
//TOUCHINPUT* pInputs = malloc(cInputs*sizeof(TOUCHINPUT)); // creates a new SPOT struct at runtime
//pInputs = malloc(cInputs*sizeof(TOUCHINPUT)); // creates a new SPOT struct at runtime
//zero(pInputs);
//if (cInputs!=NULL){
	//print2("exists");
	
	if (cInputs>0){
if (GetTouchInputInfo(lParam, cInputs,	pInputs, sizeof(TOUCHINPUT))){
int i;
 c_id=cInputs;
 c_id2=sizeof(pInputs)*cInputs;
 for(i=0; i<cInputs; ++i)
 
 {
 
 
 //Unit conversion
 pInputs[i].x/=100;
 pInputs[i].y/=100;
 
 pInputs[i].x-=window_pos.x;
 pInputs[i].y-=window_pos.y;
 
 pID[pInputs[i].dwID].x=pInputs[i].x;
 pID[pInputs[i].dwID].y=pInputs[i].y;
 //////////////////////////////

 if(pInputs[i].dwFlags & TOUCHEVENTF_MOVE){OnTouchMoveHandler_o(pInputs[i]);}else{
 	if(pInputs[i].dwFlags & TOUCHEVENTF_DOWN){OnTouchDownHandler(pInputs[i]);}else{
 		if(pInputs[i].dwFlags & TOUCHEVENTF_UP){	OnTouchUpHandler(pInputs[i]);}}}
 }
bHandled = TRUE;
if (bHandled){
// if you handled the message, close the touch input handle and return
CloseTouchInputHandle(lParam);
return;
}else{return DefWindowProc(hWnd, WM_TOUCH, wParam, lParam);}
}
}}


//recieve messages	
LRESULT CALLBACK OriginalHandler(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK MyMessageHandler(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
// pass touch messages to the touch handler 
case WM_TOUCH:
//error("touch");
OnTouch(hWnd, wParam, lParam);
break;
  }
 return OriginalHandler(hwnd,message,wParam,lParam);   	
 }
	
function draw_cursor(){while(1){draw_quad(NULL,vector(110,210,0),NULL,vector(10,10,0),vector(1,1,0),vector(100,222,0),100,0);wait(1);}}
	
	
	function main()
{
  vec_set(screen_size,vector(800,400,0));
  //vec_set(screen_color,vector(50,1,1)); // dark blue
  vec_set(sky_color,vector(50,1,1)); // dark blue
  video_window(NULL,NULL,0,"My New Game");
  on_esc = exits;
  level_load(NULL);
  wait(1);
  reset(camera,SHOW);
  mouse_mode=3;
  wait(1);
  
  //vec_set(camera.x,vector(-250,0,50));
  //vec_set(camera.pan,vector(0,-15,0));
int value = GetSystemMetrics(94);
if (value & NID_READY){ 
//error("ready");/* stack ready */
print2("ready");
}
if (value  & NID_MULTI_INPUT){
/* digitizer is multitouch */ 
//error("Multitouch found");
}
if (value & NID_INTEGRATED_TOUCH){
//error("integrated touch");/* Integrated touch */
}
BYTE
digitizerStatus = GetSystemMetrics(94);
if ((digitizerStatus & (0x80 + 0x40)) == 0) //Stack Ready + MultiTouch
{
error("no multitouch");
 return;
}
 
var nInputs = GetSystemMetrics(95);
//printf("number of touches= %.0f",(double)nInputs);
	
if (!RegisterTouchWindow(hWnd,0))
{error("error");}
OriginalHandler = on_message;	// store the original message loop
on_message = MyMessageHandler; // and replace it by your own
init_vals();

}


Posted By: MMike

Re: mouse_event and multitouch - 03/08/11 21:53

does that works good ?
Posted By: Joozey

Re: mouse_event and multitouch - 03/08/11 22:40

Well, good as in: no delay. But you are not using mouse_event(). So yes it works fine, like my own code.

Though I can drag one or the other, not both simultaneously. One or two fingers doesn't give a difference, and you should add rotation if you are using draw_quad anyway wink.
Posted By: MMike

Re: mouse_event and multitouch - 03/10/11 00:07

not both ? weird, it worked good here.. but ok. i will someday get a hand on this again.
Posted By: sebbi91

Re: mouse_event and multitouch - 05/29/11 15:55

@MMike:

I have a Tablet PC with Windows7 and want to make some small games for it.

I tried your script.
But the Extra.h File is missing.
I cant find this Header.

Please could you help me to get the multitouch working?
Posted By: sebbi91

Re: mouse_event and multitouch - 06/03/11 14:16

Please could you help me?
Posted By: MMike

Re: mouse_event and multitouch - 12/22/12 23:34

OK i so the file is working fine..
just comment the extra thing, because you dont need it
and change the print2 function to error("...");

(...) the message that is there of course.

And it works good.
But at the moment, GS cant detect multitouch, i mean, the engine that triggers the touch on panels its not implemented, because it sticks to the old single touch methods i think.

So, for multitouch you have to kind of trigger actions based on the multitouch positions, and develop from there.

:S
© 2024 lite-C Forums