Custom events again....

JB3DG

Resource contributor
Well i now have everything working for the key event system except this:

Code:
    <MouseRect>
      <Cursor>Hand</Cursor>
      <MouseFlags>LeftSingle+RightSingle</MouseFlags>
      <CallbackCode>
        (M:Event) 'RightSingle'   scmi 0 == if{ (>K:0x00011000) }
        (M:Event) 'LeftSingle'  scmi 0 == if{ (>K:0x00011001) }
      </CallbackCode>
    </MouseRect>
if i do this:
Code:
   <MouseRect>
      <Cursor>Hand</Cursor>
      <MouseFlags>LeftSingle</MouseFlags>
      <EventID>0x11002</EventID>      
    </MouseRect>
it works fine and i pick it up in the breakpoints during debug. However sending them using the left/right click I dont get a reaction. Can someone help here? im dealing with a 3 position switch hence the need for the 2 key events.
 

n4gix

Resource contributor
Searching the forum here http://www.fsdeveloper.com/forum/showthread.php?t=94652&highlight=EventID

I've located a post of mine from 09/13/2011:

It is really simple enough. The "fs_event" example I was using as a prototype was incomplete! The second DWORD isn't "unknown" at all, but should be "evdata." Then it's simply a matter of setting up a case evaluation for the 2nd DWORD:

Code:
void __stdcall My_Event_Handler(DWORD event_id,DWORD evdata,PVOID user_buffer,DWORD user_param)
{
	if(event_id == 0x18107)
	{
		switch (evdata)
		{
		case 0:
		     MBattSw=0 ; /* set local C variable */
		     break;
		case 1:
		     MBattSw=1 ; /* set local C variable */
		     break;
		}
	}
	if(event_id == 0x18108)
	{
		switch (evdata)
		{
		case 0:
			break;
		case 1:
			break;
		case 2:
			break;
		case 3:
			break;
		}
	}
	if(event_id == 0x18109)
	{
		switch (evdata)
		{
		case 0:
			break;
		case 1:
			break;
		case 2:
			break;
		case 3:
			break;
		case 4:
			break;
		case 5:
			break;
		case 6:
			break;
		}
	}

}
 

JB3DG

Resource contributor
Im not trying to send anything through the key event im trying to send the key event. With that said....the if(event_id == 0xwhatever) isnt being triggered and as a result, neither is the evdata switch statement inside it.
 
Last edited:

taguilo

Resource contributor
Well i now have everything working for the key event system except this:

Code:
    <MouseRect>
      <Cursor>Hand</Cursor>
      <MouseFlags>LeftSingle+RightSingle</MouseFlags>
      <CallbackCode>
        (M:Event) 'RightSingle'   scmi 0 == if{ (>K:0x00011000) }
        (M:Event) 'LeftSingle'  scmi 0 == if{ (>K:0x00011001) }
      </CallbackCode>
    </MouseRect>
if i do this:
Code:
   <MouseRect>
      <Cursor>Hand</Cursor>
      <MouseFlags>LeftSingle</MouseFlags>
      <EventID>0x11002</EventID>      
    </MouseRect>
it works fine and i pick it up in the breakpoints during debug. However sending them using the left/right click I dont get a reaction. Can someone help here? im dealing with a 3 position switch hence the need for the 2 key events.
Hi,

You can't do (>K:0x00011000) or similar.
I know very little about XML animation code but, can't be possible to write:

Code:
<MouseRect>
     <Cursor>Hand</Cursor>
      <MouseFlags>LeftSingle</MouseFlags>
      <EventID>0x11002</EventID>      
</MouseRect>
<MouseRect>
     <Cursor>Hand</Cursor>
      <MouseFlags>RightSingle</MouseFlags>
      <EventID>0x11001</EventID>      
</MouseRect>
using the proper hex code in each <EventID>?

Tom
 

n4gix

Resource contributor
Absolutely not unfortunately. If you have a knob or switch, you can have one, and only one mouse area. This means that we need a method to "stack" multiple separate mouse buttons & wheel to a single mouse area.

"WarpD" (Ed) has assurred me that we can trigger a custom event using the (>K:0xnnnnnn) format*, which is why he sent me a massive Excel file with some 300 custom event ids defined to match up with his event handler.

I've got no reason to doubt him since he wouldn't have spent 40+ hours creating the document for a technique that he didn't already know works... :D

So, I'm fairly confident that the real issue lies in how the event handler has been set up. Unfortunately, I don't have sufficent knowledge of C++ myself, so am unable to provide much in the way of help.

*NOTA BENE:

Whenever any KEY_XXX event is triggered, a #define in the gauges.h file translates this into the hex equivalent:

#define KEY_ID_MIN 0x00010000
#define KEY_AP_MASTER (KEY_ID_MIN + 44)

So, using the form
(>K:0x00010044) is precisely the same as using
(>K:KEY_AP_MASTER)
 

taguilo

Resource contributor
Absolutely not unfortunately. If you have a knob or switch, you can have one, and only one mouse area. This means that we need a method to "stack" multiple separate mouse buttons & wheel to a single mouse area.
Oh, that's a pity. Somehow I figured it was like you state...

Whenever any KEY_XXX event is triggered, a #define in the gauges.h file translates this into the hex equivalent:

#define KEY_ID_MIN 0x00010000
#define KEY_AP_MASTER (KEY_ID_MIN + 44)

So, using the form
(>K:0x00010044) is precisely the same as using
(>K:KEY_AP_MASTER)
Bill, KEY_XXXX events are C (#,++) tokens, but <CallbackCode> is an XML structured function, in where K: events are passed not as token but as string names (the same as for SimConnect), without the KEY_ prefix.
I don't know how both systems can be combined to give the same result, maybe it's not possible at all.

Tom

EDIT: I guess it should be possible to pass an XML LVar type and use execute_calculator_code to capture its value in a C++ gauge
 
Last edited:
Anyone checked the FSX SDK documentation???

Take a peek at the following:

<EventValueInc>
<EventValueDec>

They are useable within a <PartInfo> entry. I found this in the "Creating A New Animation" section of the SDK for the "Using Modeling Tools" document.
 

taguilo

Resource contributor
Anyone checked the FSX SDK documentation???

Take a peek at the following:

<EventValueInc>
<EventValueDec>

They are useable within a <PartInfo> entry. I found this in the "Creating A New Animation" section of the SDK for the "Using Modeling Tools" document.
So <EventValueInc> and <EventValueDec> can be used in <CallbackCode>, or both are exclusive to <CallbackJumpDragging> ?

Tom
 
There are several forms of Callback scripting... I merely pointed out one.

If you want to send a custom key event... with data... then you'd have something like: "1 (>K:0x11000)". Also, I don't think you want to have all the leading zeros I'm seeing in the very first post's code.
 

n4gix

Resource contributor
So <EventValueInc> and <EventValueDec> can be used in <CallbackCode>, or both are exclusive to <CallbackJumpDragging> ?

Tom
The only example of them being used is within the <CallbackJumpDragging> structure. That is the problem. No other methods were explicated and no discussion for use was provided in the SDK. :(

The only issue I can see with Jon's current attempt is that he's declaring a numeric type for both the event_id and the evdata. They should be declared as DWORD instead.
 
Last edited:

taguilo

Resource contributor
There are several forms of Callback scripting... I merely pointed out one.

If you want to send a custom key event... with data... then you'd have something like: "1 (>K:0x11000)". Also, I don't think you want to have all the leading zeros I'm seeing in the very first post's code.
Unfortunately "1 (>K:0x11000)" is not possible as this syntax belongs to the XML scripting system, not the <Tokenized> xml file parser.
However, <EventID> does support named ID and custom 0xnnn numbers as it is described in the SDK.

On the other hand, it is far more easy to handle "custom" events via XML LVars and register them in the C gauges that requiere to monitor their values -or use execute_calculator_code to extract the values directly.

Tom
 

n4gix

Resource contributor
On the other hand, it is far more easy to handle "custom" events via XML LVars and register them in the C gauges that requiere to monitor their values -or use execute_calculator_code to extract the values directly.
Tom, while L:vars are (mostly) passed correctly during a multi-player connection, they are NOT passed at all during a Shared Cockpit multi-player connection. Even in standard multi-player, the latency for passing L:var data may be delayed up to several seconds.

That is the one and only purpose for using custom event_ids at all.

The basic idea is that if the copilot flips a custom (non-stock) switch, that same switch must also be "flipped" immediately in the remote pilot's cockpit. Since L:vars are not transmitted to the remote shared-cockpit, another technique must be used, and that is where custom event_ids step in the save the day. The C gauge running in the remote a/c receives the custom event_id, and then generates and sends the L:var to "flip the switch."

That is precisely why both the F-18 and the EH101 make extensive use of custom event_ids. They are the only two truly shared-cockpit compatible default aircraft.
 
Last edited:
Unfortunately "1 (>K:0x11000)" is not possible as this syntax belongs to the XML scripting system, not the <Tokenized> xml file parser.
However, <EventID> does support named ID and custom 0xnnn numbers as it is described in the SDK.

On the other hand, it is far more easy to handle "custom" events via XML LVars and register them in the C gauges that requiere to monitor their values -or use execute_calculator_code to extract the values directly.

Tom
The SDK disagrees with your statement that it's not possible, this is directly from the SDK:

Code:
        <CallbackCode>
                (L:Inertial Data,number) ++ 3 % (>L:Inertial Data,number)
        </CallbackCode>
I see no reason why that can't read:
Code:
        <CallbackCode>
                1 (>K:0x11000)
        </CallbackCode>
 

JB3DG

Resource contributor
Well im still stuck....I am now sending the event like this:

Code:
(M:Event) 'LeftSingle'  scmp 0 == if{ (&gt;K:0x11001) }
        (M:Event) 'RightSingle'   scmp 0 == if{ (&gt;K:0x11000) }
And it is simply not being detected by my event handler. So...what to do?

I also switched to using the DWORD format but still to no avail. What is the 4th parameter in your example Bill? Cuz if i include it in my function the sim crashes with a pointer error. The strange part is it is not a NULL pointer error....

Here's my entire event handler:

Code:
void FSAPI EventHandler(DWORD event_id, DWORD evdata, PVOID user_buffer)
{
	if(event_id == 0x11000)
	{
		switch(evdata)
		{
		case 0:
			if(batt == 1)
			 {
				 batt --;
			 }			 
			 if(batt == 0)
			 {
				 trigger_key_event(KEY_TOGGLE_MASTER_BATTERY, 0);
				 batt += 2;
			 }
			break;
		}
	}
	if(event_id == 0x11001)
	{
		switch(evdata)
		{
		case 0:
			if(batt == 2)
			 {
				 batt -= 2;
				 trigger_key_event(KEY_TOGGLE_MASTER_BATTERY, 0);			 
			 }
			 if(batt == 0)			 
			 {				 
				 if(eng_master == true)				 
				 {					
					 trigger_key_event(KEY_TOGGLE_STARTER1, 0);				 
				 }				 
				 batt ++;			 
			 }
			break;
		}
	}
    switch(event_id)
    {		
		 case 0x11002:
			 eng_master = !eng_master;
			 trigger_key_event(KEY_TOGGLE_MASTER_IGNITION_SWITCH, 0);
			 break;
		 case 0x11003:
			 stop_start = !stop_start;
			 break;
		 //case KEY_TOGGLE_MASTER_IGNITION_SWITCH:
		//	 test = ! test;
		//	 break;
         default:
             break;
    }
	 return;
}
Note i am currently using case 0 for the evdata switch statement cuz i really dont know what is being passed to it when i just do (>K:0x11000) instead of 1 (>K:0x11000). However during testing i set up a breakpoint in the debugger at the if statement to see what events are being passed. It detects any other event except the 0x11000 or 0x11001. So...im stumped.

Just for the record, i test the callbackjumpdragging option to make sure the events werent being blocked or something and it worked fine. But then again, that system doesnt support leftclick/right click....:banghead:
 
Last edited:

taguilo

Resource contributor
The SDK disagrees with your statement that it's not possible, this is directly from the SDK:

Code:
        <CallbackCode>
                (L:Inertial Data,number) ++ 3 % (>L:Inertial Data,number)
        </CallbackCode>
I see no reason why that can't read:
Code:
        <CallbackCode>
                1 (>K:0x11000)
        </CallbackCode>
Simply because "0x11000" doesn't exist as a constant identifier -or string "pointer"- in the class that handles the K: "events".

When you write (>K:EVENT_ANY), the script parser identifies, first the "K:" string, and the the string that follows, for example "EVENT_ANY".
The "K:" is evaluated as "an event call" then the "string pointer" is passed to the proper class. In the class, there is a list of constant identifiers, properties or whatever you want to call them, something like:

"Event_any", 0x00012
"Another_Event_any", 0x00015
"More_of_the_same", 0x000nnn

the string pointer passed is then compared with each one of the list, and if one gives a match, then the associated ID number is passed to a function that executes the event, which I guess it is the ordinary trigger_key_event()

Now, if the string pointer doesn't match, the processing function returns false and the effective result is to happen nothing. Note also that UPPERCASE_EVENT as we write them in (K: ) scripts is conventional, we could eventually write , for example, (>K:Flaps_Inc) instead of (>K:FLAPS_INC) without trouble.

Naturally, the whole set of "events identifiers" described in the SDK are included in that list. I guess that it wouldn't be practical to include an identifier for each one of the available 0x00nn values reserved for custom events -from 0x11000 to 0x1FFFF, how many lines does this represent???

This concepts applies the same for (A: ) vars, (L: ) vars, (C: ) vars, etc, etc,
they are all managed by similar classes, (see Cabin_Comfort example in SDK)

Tom
 

taguilo

Resource contributor
Well im still stuck....I am now sending the event like this:

Code:
(M:Event) 'LeftSingle'  scmp 0 == if{ (&gt;K:0x11001) }
        (M:Event) 'RightSingle'   scmp 0 == if{ (&gt;K:0x11000) }
And it is simply not being detected by my event handler. So...what to do?
Unfortunately, nothing with this method. But you can try:


Code:
     <MouseRect>
        <Cursor>Hand</Cursor> 
        <MouseFlags>LeftSingle+RightSingle+Wheel</MouseFlags> 
         <CallbackJumpDragging>
             <XMovement>
                <Delta>nDelta</Delta> 
                <EventIdInc>0x11001</EventIdInc> 
                <EventIdDec>0x11002</EventIdDec> 
            </XMovement>
        </CallbackJumpDragging>
    </MouseRect>

Where nDelta is "the mouse movement in screen co-ordinates required for one increment or one decrement key event to be triggered" -see the SDK

Tom
 

taguilo

Resource contributor
Tom, while L:vars are (mostly) passed correctly during a multi-player connection, they are NOT passed at all during a Shared Cockpit multi-player connection. Even in standard multi-player, the latency for passing L:var data may be delayed up to several seconds.

That is the one and only purpose for using custom event_ids at all.
I didn't know that; thank you Bill for clarifying this issue. I think that if, in certain cases, using <CallbackCode> is completely unavoidable, a custom module could be programmed to handle "custom events" from inside the callback script.
For example: '0x11003' (>C:EVENTS:CUSTOM_EVENT) would pass the actual event id as a string to the module, where it is "casted" to a valid identifier and passed to trigger_key_event()...Just an idea....

Tom
 

JB3DG

Resource contributor
Code:
     <MouseRect>
        <Cursor>Hand</Cursor> 
        <MouseFlags>LeftSingle+RightSingle+Wheel</MouseFlags> 
         <CallbackJumpDragging>
             <XMovement>
                <Delta>nDelta</Delta> 
                <EventIdInc>0x11001</EventIdInc> 
                <EventIdDec>0x11002</EventIdDec> 
            </XMovement>
        </CallbackJumpDragging>
    </MouseRect>

Where nDelta is "the mouse movement in screen co-ordinates required for one increment or one decrement key event to be triggered" -see the SDK

Tom
Problem is LeftSingle/RightSingle is not supported with this method. Well...at least, in my testing, it doesnt work.

I also tried going to my gauges.h and editing this line from this:

typedef void (*GAUGE_KEY_EVENT_HANDLER) (ID32 event, UINT32 evdata, PVOID userdata);

to this

typedef void (*GAUGE_KEY_EVENT_HANDLER) (DWORD event_id, DWORD evdata, PVOID userdata, DWORD user_param);

but to no avail. And if i include the 4th parameter in my actual function i get a pointer error.

Just to make sure we are not beating a dead horse here....Bill? Ed? Have either of you actually tested this method of sending events?

One other thing i tried was creating a actual #define in gauges.h with a name for my custom event but when i tried using (>K:EVENT_NAME) in the modeldef it still didnt work. Maybe that might be the way to go but then i will need someone to tell me how the system works cuz in XML, (>K:KEY_VOR2_OBI_INC) will not work but (>K:VOR2_OBI_INC) will. How does this dropping of the KEY_ work?
 
Last edited:

taguilo

Resource contributor
One other thing i tried was creating a actual #define in gauges.h with a name for my custom event but when i tried using (>K:EVENT_NAME) in the modeldef it still didnt work. Maybe that might be the way to go but then i will need someone to tell me how the system works cuz in XML, (>K:KEY_VOR2_OBI_INC) will not work but (>K:VOR2_OBI_INC) will. How does this dropping of the KEY_ work?
Hi, did you read my #15 post in this thread? I gave an ample explanation on how K: events are treated by the scripting parser.
Answering your question, KEY_EVENT_ANY are tokens, (#define) for each one of the numeric ID assigned to simulator events, and are those used as arguments in trigger_key_event() C function.
Constant identifiers like EVENT_ANY are strings of text used as pointers within an Event class, and work as described in post #15

Hope this helps

Tom
 

n4gix

Resource contributor
I also switched to using the DWORD format but still to no avail. What is the 4th parameter in your example Bill? Cuz if i include it in my function the sim crashes with a pointer error. The strange part is it is not a NULL pointer error....

Here's my entire event handler:

Code:
void FSAPI EventHandler(DWORD event_id, DWORD evdata, PVOID user_buffer)
void __stdcall My_Event_Handler(DWORD event_id,DWORD evdata,PVOID user_buffer,DWORD user_param)
 
Top