Jump to content

TARGET - Advanced programming


ivanwfr

Recommended Posts

update:

- The Trigger1 and Trigger2 declarations need to be placed out (before) of the main part of the script.

- There is a ")" missing in this line:

MapKey(&Joystick,TG1, TEMPO( 0, EXEC("Trigger1();"), 500);			//	Split Trigger Function Call TG1

 

It should read:  MapKey(&Joystick, TG1, TEMPO( 0, EXEC("Trigger1();"), 500))

 

Then it compiles just fine.


Edited by Lange_666

Win11 Pro 64-bit, Ryzen 5800X3D, Corsair H115i, Gigabyte X570S UD, EVGA 3080Ti XC3 Ultra 12GB, 64 GB DDR4 G.Skill 3600. Monitors: LG 27GL850-B27 2560x1440 + Samsung SyncMaster 2443 1920x1200, HOTAS: Warthog with Virpil WarBRD base, MFG Crosswind combat pedals, TrackIR4, Rift-S.

Personal Wish List: A6 Intruder, Vietnam theater, decent ATC module, better VR performance!

Link to comment
Share on other sites

 

Fixed.

Tested and works.

TEMPO command on TG1 will produce a PULSE of DX1 on long hold (500ms).

Pull through to TG2 will produce a held command of DX2 as long as you hold TG2.

 

TriggerSplit.tmh

int	Trigger1()	{
	if(Joystick[TG2])
	ActKey(PULSE + 0);
	else if(Joystick[TG1])
	ActKey(PULSE + KEYON + DX1);
	}
	
int Trigger2()	{
	if(Joystick[TG2])
	ActKey(KEYON + DX2);
	}

 

Split Trigger.tmc

include "target.tmh"
include "TriggerSplit.tmh"
//program startup
int main()
{
    if(Init(&EventHandle)) return 1; 	// declare the event handler, return on error
	
MapKey(&Joystick,TG1, TEMPO( 0, EXEC("Trigger1();"), 500));		//	Split Trigger Function Call TG1


MapKey(&Joystick,TG2, EXEC("Trigger2();"));			//	Split Trigger Function Call TG2
MapKeyR(&Joystick,TG2, EXEC("ActKey(DX2);"));		//	Release TG2 from held by Trigger Function



}


//event handler
int EventHandle(int type, alias o, int x)
{
    DefaultMapping(&o, x);
	
	//add event handling code here
}

 


Edited by SGT Coyle

Night Ops in the Harrier

IYAOYAS


 
Link to comment
Share on other sites

YES! Working!

I stuck at &Joystick, trying to use some additional functions to blank TG1 for the TG2 press time. I know that this can be done in much better way. This is it.

I refresh my knowledge about C syntax by the way. Thank you for help.


Edited by Glow
Link to comment
Share on other sites

I'm looking to create 3 layers utilising flags and not the UMD e.g A-A, A-G, Nav for certain switches, I have been able to do this for a single switch, see below, flicking EORIGN changes the state of H1 to permanently have trim activated but otherwise it does basic views or Trim with S4 held in. However, how would I go about adding a second Flag switch on H1 e.g EOLIGN when on state would have H1 do another layer. I've tried adding another Flag but as I thought it displays both states i.e. Flag switch 1 and Flag switch 2

 

MapKey(&Throttle, EORIGN,
    SEQ    ( 
    CHAIN( 
    EXEC("trimflag = 1;"), LED(&Throttle, LED_ONOFF, LED_CURRENT+LED1)), // Trim switch
    CHAIN(
    EXEC("trimflag = 0;"), LED(&Throttle, LED_ONOFF, LED_CURRENT-LED1));

 

MapKeyIO(&JoystickF18, H1U, TrimmerDESCEND, EXEC("if(trimflag) ActKey(KEYON+TrimmerDESCEND); else ActKey(KEYON+F1_HUD_only_view_switch);"));
MapKeyRIO(&JoystickF18, H1U, 0, EXEC( "if(trimflag) ActKey(TrimmerDESCEND); else ActKey(F1_HUD_only_view_switch);"));

    

 

Many thx for any help

Asus ROG IX | Intel i7-9700K | RTX 2080TI | G.SKILL 32GB DDR4 3200MHz RAM | Samsung 970 EVO 2TB M2 | LG 43” 4K Monitor | TrackiR | Stream Deck XL | Warthog HOTAS | Cougar MFDs x 3 | Saitek Rudder Pedals | Logitech G13| Corsair Virtuoso Wireless Headset |

Link to comment
Share on other sites

OK....

I'm not sure I understand what you want to achieve.  I rewrote your .tmc code to include a function that does most of the heavy lifting.

 

TrimTEST.tmc

include "target.tmh"
include "Test.tmh"
//program startup

int main()
{
    if(Init(&EventHandle)) return 1; 	// declare the event handler, return on error
	SetShiftButton(&JoystickF18, S4, 0, 0, 0, 0);

MapKey(&Throttle,EORIGN, SEQ(
							EXEC("TrimON();"),
							EXEC("TrimOFF();")
							)
							);
							
							
MapKeyIO(&JoystickF18,H1U, DX1, EXEC("HatSwitchUP();"));
MapKeyR(&JoystickF18,H1U, EXEC("ActKey(DX1);"));					
							
							
}


//event handler
int EventHandle(int type, alias o, int x)
{
    DefaultMapping(&o, x);
	
	//add event handling code here
}

 

TEST.tmh


int trimmer;

int TrimON()	{
			trimmer = 3;
			ActKey(PULSE+KEYON+LED(&Throttle, LED_ONOFF, LED_CURRENT+LED1)); //set LED 1 On
	}
	
int TrimOFF()	{
			trimmer = 1;
			ActKey(PULSE+KEYON+LED(&Throttle, LED_ONOFF, LED_CURRENT-LED1)); //set LED 1 Off
	}
	
//**********

int	HatSwitchUP()	{
					if(trimmer > 2)
					ActKey(KEYON + DX1);
					else ActKey(KEYON + PULSE+ DX2);
									
					}

 

Night Ops in the Harrier

IYAOYAS


 
Link to comment
Share on other sites

Thx for this, so if I read this right it does what I have put above, now what if I what to use EOLIGN to create DX3 on H1U, so this is how it would look, giving me the option of using H1U for most used key DX1, then I push EORIGN and it gives me DX2, activate EOLIGN and get DX3 , deactivate EORIGN or EORIGN gives DX1 again. The idea behind what I’m trying to do is by activating the flag it changes various key presses across across the joystick and throttle e.g refuelling or landing.  Again many thx for your time

Asus ROG IX | Intel i7-9700K | RTX 2080TI | G.SKILL 32GB DDR4 3200MHz RAM | Samsung 970 EVO 2TB M2 | LG 43” 4K Monitor | TrackiR | Stream Deck XL | Warthog HOTAS | Cougar MFDs x 3 | Saitek Rudder Pedals | Logitech G13| Corsair Virtuoso Wireless Headset |

Link to comment
Share on other sites

I just wonder why you are doing it that way?

Instead of the standard S4 on the stick (IO) and the Boatswitch on the throttle (UMD) you can set whatever you want through the SetShiftButton command.

I use S3 for IO (like on the Cougar) and the pinky switch for UMD. Either way, you always lose the buttons switches who play the layer roll, if it's not S4 and the Boatswitch then in your case it are the EORIGN and EOLIGN switches, either through the SetShiftButton command or through your way of doing it. But your is much more complex.

Just MHO.

  • Like 1

Win11 Pro 64-bit, Ryzen 5800X3D, Corsair H115i, Gigabyte X570S UD, EVGA 3080Ti XC3 Ultra 12GB, 64 GB DDR4 G.Skill 3600. Monitors: LG 27GL850-B27 2560x1440 + Samsung SyncMaster 2443 1920x1200, HOTAS: Warthog with Virpil WarBRD base, MFG Crosswind combat pedals, TrackIR4, Rift-S.

Personal Wish List: A6 Intruder, Vietnam theater, decent ATC module, better VR performance!

Link to comment
Share on other sites

I’m not actually using keystrokes, I’m using Functions but it’s easier to use keystrokes in the example, the functions control custom curves, slew speeds, led flashing lights etc APilot based on switch locations (Hornet), with flags like above you can have as many options as you want e.g I have one push button but with a flag switch it can control Discord, Vaicom and in flight comms. Its a powerful tool when set up.

Asus ROG IX | Intel i7-9700K | RTX 2080TI | G.SKILL 32GB DDR4 3200MHz RAM | Samsung 970 EVO 2TB M2 | LG 43” 4K Monitor | TrackiR | Stream Deck XL | Warthog HOTAS | Cougar MFDs x 3 | Saitek Rudder Pedals | Logitech G13| Corsair Virtuoso Wireless Headset |

Link to comment
Share on other sites

Sorry m8, can you give an example, of this how is it different from the /u /m /d switches using the boat switch for example?

SYSTEM SPECS: Hardware Intel Corei7-12700KF @ 5.1/5.3p & 3.8e GHz, 64Gb RAM, 4090 FE, Dell S2716DG, Virpil T50CM3 Throttle, WinWIng Orion 2 & F-16EX + MFG Crosswinds V2, Varjo Aero
SOFTWARE: Microsoft Windows 11, VoiceAttack & VAICOM PRO

YOUTUBE CHANNEL: @speed-of-heat

1569924735_WildcardsBadgerFAASig.jpg.dbb8c2a337e37c2bfb12855f86d70fd5.jpg

Link to comment
Share on other sites

Have a look at the Target Script manual and under flags and functions and you get multiple examples of how they can be used, it’s just another level of programming, in simple terms it gives you as many UMD switches as you like, think of them as profiles, each flag represents a profile, if you want to refuel, the profile sets up you HOTAS for refueling, Startup profile, carrier landing profile, Comms Profile etc, simple apply the flag and have the HOTAS set up exactly how you need. It just takes UMD to the next level, especially good for VR where you want as much as you can on the HOTAS setup

Asus ROG IX | Intel i7-9700K | RTX 2080TI | G.SKILL 32GB DDR4 3200MHz RAM | Samsung 970 EVO 2TB M2 | LG 43” 4K Monitor | TrackiR | Stream Deck XL | Warthog HOTAS | Cougar MFDs x 3 | Saitek Rudder Pedals | Logitech G13| Corsair Virtuoso Wireless Headset |

Link to comment
Share on other sites

no  i get that, its just a var that you can read against; for state so far rock solid, and i get you can set different profiles for different events or circumstances etc... 

 

but when it comes to actuating it you still end up with a switch that you have to press in order to set the flag ? so for a flag 1,2,3 you have to sacrifice a three state switch... so what am i missing ?

SYSTEM SPECS: Hardware Intel Corei7-12700KF @ 5.1/5.3p & 3.8e GHz, 64Gb RAM, 4090 FE, Dell S2716DG, Virpil T50CM3 Throttle, WinWIng Orion 2 & F-16EX + MFG Crosswinds V2, Varjo Aero
SOFTWARE: Microsoft Windows 11, VoiceAttack & VAICOM PRO

YOUTUBE CHANNEL: @speed-of-heat

1569924735_WildcardsBadgerFAASig.jpg.dbb8c2a337e37c2bfb12855f86d70fd5.jpg

Link to comment
Share on other sites

2 hours ago, Oilman100 said:

now what if I what to use EOLIGN to create DX3 on H1U, so this is how it would look, giving me the option of using H1U for most used key DX1, then I push EORIGN and it gives me DX2, activate EOLIGN and get DX3 , deactivate EORIGN or EORIGN gives DX1 again. The idea behind what I’m trying to do is by activating the flag it changes various key presses across across the joystick and throttle e.g refuelling or landing.  Again many thx for your time

Well....
There is definitely more than one way to skin the proverbial cat with TARGET SE.  The one your choosing has advantages, but I'm not going into that here.
So, building on what we already have.

  1. You need another Function to set an additional trimmer value.
  2. You need to add an additional function call.
  3. In the function HatSwitchUP() you need to redo the checks.  When the original options were values 1 and 3 we only had to check for whether trimmer was ">" or "<" 2.  That's a problem that could be solved with a check to see if the value was between two values, but I was having trouble using "&".  So I used "==" equal to.
    exp..  change "if(trimmer>2 );" to "if (trimmer==1);" and likewise for the rest of the conditions.

So try editing my example above.  PM me if you still have issues

 

 

Night Ops in the Harrier

IYAOYAS


 
Link to comment
Share on other sites

Ok I understand, I use the switches that I rarely use, eg the two above, these flick switches are ideal for Flags and I never mapped them before, I also use EFLNORM, again I don’t really use these switches as I prefer to have the max usage on the HOTAS itself. I use the Boat switch and Pinky switch all the time so don’t want to give them up, they are also pivotal with the A-10C-2,  F-18 and F-16. It’s a preference thing but also slowly pushing what can be done with script and using the experts on this forum to get it right.

13 hours ago, SGT Coyle said:

Well....
There is definitely more than one way to skin the proverbial cat with TARGET SE.  The one your choosing has advantages, but I'm not going into that here.
So, building on what we already have.

  1. You need another Function to set an additional trimmer value.
  2. You need to add an additional function call.
  3. In the function HatSwitchUP() you need to redo the checks.  When the original options were values 1 and 3 we only had to check for whether trimmer was ">" or "<" 2.  That's a problem that could be solved with a check to see if the value was between two values, but I was having trouble using "&".  So I used "==" equal to.
    exp..  change "if(trimmer>2 );" to "if (trimmer==1);" and likewise for the rest of the conditions.

So try editing my example above.  PM me if you still have issues

 

 

Many thx, I will try it today and revert if I can’t get it work.

Asus ROG IX | Intel i7-9700K | RTX 2080TI | G.SKILL 32GB DDR4 3200MHz RAM | Samsung 970 EVO 2TB M2 | LG 43” 4K Monitor | TrackiR | Stream Deck XL | Warthog HOTAS | Cougar MFDs x 3 | Saitek Rudder Pedals | Logitech G13| Corsair Virtuoso Wireless Headset |

Link to comment
Share on other sites

14 hours ago, speed-of-heat said:

no  i get that, its just a var that you can read against; for state so far rock solid, and i get you can set different profiles for different events or circumstances etc... 

 

but when it comes to actuating it you still end up with a switch that you have to press in order to set the flag ? so for a flag 1,2,3 you have to sacrifice a three state switch... so what am i missing ?

 

I don't want to drag the thread "Off Topic" but just to answer that question.

 

You don't necessarily have to sacrifice a switch or button, the state/layer could be invoked when the aircraft is setup in a particular configuration and you use a switch to set it that way anyway. For example it could be when you activate the AAR probe, Gear, Flaps etc: (lots and lots of options). You'd use these switches to set Flags and invoke a  specific mode/layer/state. Other buttons could then have entirely different functions. I've never tried this but you could then make states for perhaps 2 flags being activated as well, when gear is down state 1, when flaps are down state 2, when gear and flaps are down state 3. That's kinda simplistic and unrealisitic but you get the idea.

 

One I use a lot is landing gear, when the gear is up my paddle on the Grip deactivates A/P when down it activates/deactivates nosewheel stg. Some aircraft actually do that anyway, but with TARGET you can set up those that don't to adopt that configuration.

 

Lots of ways to do it and IMHO a very clever way to get more out the HOTAS

Link to comment
Share on other sites

9 minutes ago, Weegie said:

 

I don't want to drag the thread "Off Topic" but just to answer that question.

 

You don't necessarily have to sacrifice a switch or button, the state/layer could be invoked when the aircraft is setup in a particular configuration and you use a switch to set it that way anyway. For example it could be when you activate the AAR probe, Gear, Flaps etc: (lots and lots of options). You'd use these switches to set Flags and invoke a  specific mode/layer/state. Other buttons could then have entirely different functions. I've never tried this but you could then make states for perhaps 2 flags being activated as well, when gear is down state 1, when flaps are down state 2, when gear and flaps are down state 3. That's kinda simplistic and unrealisitic but you get the idea.

 

One I use a lot is landing gear, when the gear is up my paddle on the Grip deactivates A/P when down it activates/deactivates nosewheel stg. Some aircraft actually do that anyway, but with TARGET you can set up those that don't to adopt that configuration.

 

Lots of ways to do it and IMHO a very clever way to get more out the HOTAS

thanks for that i sort of get it; i just struggle to find the use case that makes me want to deal with the complexity; the NWS example is a good one 

  • Thanks 1

SYSTEM SPECS: Hardware Intel Corei7-12700KF @ 5.1/5.3p & 3.8e GHz, 64Gb RAM, 4090 FE, Dell S2716DG, Virpil T50CM3 Throttle, WinWIng Orion 2 & F-16EX + MFG Crosswinds V2, Varjo Aero
SOFTWARE: Microsoft Windows 11, VoiceAttack & VAICOM PRO

YOUTUBE CHANNEL: @speed-of-heat

1569924735_WildcardsBadgerFAASig.jpg.dbb8c2a337e37c2bfb12855f86d70fd5.jpg

Link to comment
Share on other sites

  • 3 weeks later...

SetShiftButton (&devicename, btn);

so if you wanted it to be s3

SetShiftButton (&joystick,s3);

  • Like 1

SYSTEM SPECS: Hardware Intel Corei7-12700KF @ 5.1/5.3p & 3.8e GHz, 64Gb RAM, 4090 FE, Dell S2716DG, Virpil T50CM3 Throttle, WinWIng Orion 2 & F-16EX + MFG Crosswinds V2, Varjo Aero
SOFTWARE: Microsoft Windows 11, VoiceAttack & VAICOM PRO

YOUTUBE CHANNEL: @speed-of-heat

1569924735_WildcardsBadgerFAASig.jpg.dbb8c2a337e37c2bfb12855f86d70fd5.jpg

Link to comment
Share on other sites

  • 1 year later...

Hey, folks. I hope you don't mind me asking here, but on the (currently somewhat inactive) subject of advanced TARGET programming:

Has anyone managed to load a DLL and call an exported function in it? I've been banging my head on this for a while. I have a Visual Studio C++/CLI project that exports a function to display joystick mode information, and I'm just trying to call that function with a T.16000M FCS joystick button. I haven't had any luck so far.

I appear to be able to load the DLL and get the address of the exported function:

int LoadMyLibrary()
{
  int lib = LoadLibrary("UnmanagedLink.dll");
  if (lib == 0)
  {
    printf("Bad library address\xa");
    return 0;
  }
  int procAddr = GetProcAddress(lib, "_ShowAxisMessage@0"); // found with >dumpbin /EXPORTS
  if (procAddr == 0)
  {
    printf("Bad proc address\xa");
    return 0;
  }

lib and procAddr seem to have good numbers in them, and no error is generated. However, I haven't been able to figure out how to call the darned thing. I can call existing TARGET functions with an alias, like so:

int printMsg () {
  printf("This is a message.\xa");
}

int aliasMsg () {
  alias repeat = &printMsg;
  repeat();      // this works
}

It's getting the loaded procedure address into the alias and calling it that's got me stumped. I've tried various combinations of Map(), MakeProcInstance(), realloc(), setmem(), execute(), eval(), and have reached the desperation point. For example, this seems like it should work in LoadMyLibrary(), but it doesn't:

alias ShowMsg;
&ShowMsg = procAddr;
ShowMsg();           // Bad alias

It doesn't work any better if ShowMsg() is defined outside LoadMyLibrary():

int ShowMsg() {}

int LoadMyLibrary() {
  // get procAddr as above
  &ShowMsg = procAddr; // Bad alias
  ShowMsg();
}

I don't really know what constitutes a good or bad alias. There's a lot of this pattern in target.tmh: Map(&CHAIN, MakeProcInstance(&_CHAIN), MAP_IPTR_VPN), but MakeProcInstance(procAddr) doesn't work because procAddr isn't an alias, and so would generate another "bad alias" runtime error on that line.

I feel like someone somewhere must know how to use these TARGET library-related functions. Any ideas?

Link to comment
Share on other sites

In case you did not try this:
----------------------------
Just drop you dll file into the C:\Program Files (x86)\Thrustmaster\TARGET\Plugins folder

Then, when you start C:\Program Files (x86)\Thrustmaster\TARGET\x64\TARGETScriptEditor.exe
the bottom log pane will show what has been loaded.

As I understand it, as long as dll files seem=s to works just like UNIX shared objects (the libXXX.so),
those files are loaded by the dynamic loader of each exe.
All those dll files content will fill up the process global tables with all defined functions from those files.

It happens only once, as the first dll containing a function will be the priority function source, other entries
will be ignored.
That's how we can override a system function on UNIX by PRELOADING a dynamic library before the standard ones.

This means that you don't have to load anything yourself, just call your function and optionally
add their signature (declaration) into an included file like C:/Program Files (x86)/Thrustmaster/TARGET/scripts/sys.tmh

Try this and tell us how it goes...

-ivan


Edited by ivanwfr
Link to comment
Share on other sites

Hey, thanks, Ivan!

I've put the .dll into \Plugins, which causes the editor to say this when launching itself and then compiling my script:

Loaded plugin module "C:\Program Files (x86)\Thrustmaster\TARGET\Plugins\sys.dll"
Loaded plugin module "C:\Program Files (x86)\Thrustmaster\TARGET\Plugins\UnmanagedLink.dll"
Compiling script: Axis Swap.tmc
Mapped plugin module "C:\Program Files (x86)\Thrustmaster\TARGET\Plugins\sys.dll"
Failed to map plugin module "C:\Program Files (x86)\Thrustmaster\TARGET\Plugins\UnmanagedLink.dll" !
Compile Succeeded.

Here's how the .cpp file that compiles to UnmanagedLink.dll defines the exported function:

extern "C" __declspec(dllexport) int __cdecl ShowAxisMessage() {...}

That function is the only unmanaged code in the file, but as I mentioned, it's a CLI project, so there's a managed C++ namespace with a class that ShowAxisMessage() calls into.

I'm running Visual Studio 2022 Community, toolset v143. I tried recompiling it using both __stdcall and __cdecl conventions, and I tried calling both ShowAxisMessage() and _ShowAxisMessage() in the TARGET code (_ShowAxisMessage@0() causes a compile error). I'm compiling the .dll in Debug x86 mode, and optimizations are turned off. There's a bunch of project options I'm not familiar with, but I do have a couple configured, like I have "Not Using Precompiled Headers" and "Common Language Runtime Support" set. Under C++ > Language, I have "Conformance mode" set to default, since it won't compile in the default "/permissive-" mode (it complains about "two-phase name look-up"). Could it matter that I have it set to the default of "ISO C++14 Standard"? I only have C++14, C++17, and C++20 as options.

The fact that it says "Failed to map" suggests that I may have been on the right track when I tried to put Map() and MakeProcInstance() together like target.tmh does. I read a bit about MakeProcInstance online. It's ... arcane. I'm really a novice when it comes to Windows assemblies and interop.

Link to comment
Share on other sites

Well, I'm not a Visual Studio expert myself as I used it only for a few C# projects.
All those options you mention have only theoretical meaning for me.
The name space access has to be adapted to the requirements, whatever they could be.
But I won't be able to help you there and I hope someone with experience will read your message
as this is clearly a matter of familiarity with the advanced configuration details.

I have no idea as to what it means having to map a dll module for the editor.
All I could experiment was having some results with a script calling a strstr() function
that was only available when I added two sys.dll in the Plugin folder with two different names:

Spoiler
// My call_strstr.tmc file:

include "target.tmh"
int main()
{
    alias haystack = "haystack containing a needle";
    alias   needle =                       "needle";
    int          i = strstr(&haystack, &needle);	

    printf("---------------------------------------\xa");
    printf("        i = strstr(&haystack, &needle);\xa");
    printf("   strstr = [0x%p]\xa", &strstr            );
    printf(" haystack = [%s]\xa"  , &haystack          );
    printf("   needle = [%s]\xa"  , &needle            );
    printf("        i = [%d]\xa"  ,  i                 );
    printf("---------------------------------------\xa");

    return( i );
}
// Loading the editor:
Loaded plugin module "C:\Program Files (x86)\Thrustmaster\TARGET\Plugins\sys_110524.dll"(*)
Loaded plugin module "C:\Program Files (x86)\Thrustmaster\TARGET\Plugins\sys_110707.dll"(*)

// Running the editor:
Running script: C:\LOCAL\GAMES\IVANWFR\INPUT\THRUSTMASTER\HOTAS\TARGET\SCRIPTS\ivanwfr\call_strstr.tmc
Mapped plugin module "C:\Program Files (x86)\Thrustmaster\TARGET\Plugins\sys_110524.dll"
Mapped plugin module "C:\Program Files (x86)\Thrustmaster\TARGET\Plugins\sys_110707.dll"
Compile Succeeded.
---------------------------------------
        i = strstr(&haystack, &needle);
   strstr = [0x03BC47B0]
 haystack = [haystack containing a needle]
   needle = [needle]
        i = [22]
---------------------------------------
Error:"main" did not return 0(zero). Script run aborted...
Aborting script (check output above for reason)...
Script stopped!

main returned 22

 

 


Edited by ivanwfr
Link to comment
Share on other sites

  • 4 months later...

In case anyone is willing to dig into the topic Jason seems to have dropped, here's where I'm at as I look for ways to communicate simulation to the outside world using the export API.
I created a public Github repository from which you can download a ZIP archive.
 

Terminal Dashboard Text gets highlighted by value change
On 8/11/2022 at 1:08 AM, ivanwfr said:

I have some new stuff for you if you are still looking for alternatives...
I was able to find my way around Export.lua to make it work in such a way that DCS is as little involved as possible. The minimalist Export.lua file below is all it needs to work with.
Our custom code will be reloaded each time LuaExportStart is called from Mission Start or Quit and Fly Again so that custom code changes do not require reloading Export.lua.

local dir = string.gsub(os.getenv("USERPROFILE").."/Saved Games/DCS/Scripts", "\\", "/")

function LuaExportStart            ( ) dofile(dir.."/Export_task.lua") Export_task_Start            ( ) end
function LuaExportBeforeNextFrame  ( )                                 Export_task_BeforeNextFrame  ( ) end
function LuaExportAfterNextFrame   ( )                                 Export_task_AfterNextFrame   ( ) end
function LuaExportActivityNextEvent(t)                          return Export_task_ActivityNextEvent(t) end
function LuaExportStop             ( )                                 Export_task_Stop             ( ) end

For now, you have Export_LISTEN.lua which shows how to configure a LUA TCP server socket to receive what is exported.
Export_task.lua does the real work for LuaExportActivityNextEvent and LoCreateCoroutineActivity.
This is all in an exploratory phase to help understand what is involved and how we can get to where we want to go... It's not easy to swallow but it looks pretty good once every single detail becomes clear.
Windows Terminal -> Assets does a good job running luae Export_LISTEN.lua and its support for termios could come in handy.
I'm not sure if you can understand what I did without more information but I'm willing to talk about it and show you how it looks on my screen when you have time...

 


Edited by ivanwfr
Link to comment
Share on other sites

  • 11 months later...

Being relatively new to DCS and TARGET, I was happy to find this thread. It gave me some good ideas to use in my scripts, reading through everything you guys discussed here. It would be great if this thread was more active. I'll share some of my script ideas to maybe get comments and make it better or help others with their own ideas.

I wanted to make a virtual AFTERBURNER DETENT that could do the following:
- Detent function activated or deactivated at any time during a flight
- When detent active, throttle should only go into afterburner with the press of a button, throttle should be freely controlable, and when throttle moves below detent, it should click behind the detent again.

At first this was for me more a test if it could be done, but I find myself using it very often to make sure I am not accidentally in afterburner and wasting fuel.

This is how I implemented the detent.

 

 

include "target.tmh"

// -------------------- INITIALISE --------------------

char afterburnerdetent_present = 0;				// 0 - no detent present, 
								// 1 - detent present, at mil power
char afterburnerdetent_lifted = 0;				// 0 - detent prevents throttle from going into afterburner, 
								// 1 - detent is lifted and throttle moves into afterburner

define AB 77							// detent position at AB% of full throttle reach

// -------------------- MAIN --------------------

int main()
{
	Configure(&HCougar, MODE_EXCLUDED);
	Configure(&JoystickF18, MODE_EXCLUDED);
	Configure(&A320Pilot, MODE_EXCLUDED);
	Configure(&A320Copilot, MODE_EXCLUDED);
	Configure(&TCAQuadrant12, MODE_EXCLUDED);
	Configure(&TCAQuadrant34, MODE_EXCLUDED);
	Configure(&T16000, MODE_EXCLUDED);
	Configure(&T16000L, MODE_EXCLUDED);
	Configure(&LMFD, MODE_EXCLUDED);
	Configure(&RMFD, MODE_EXCLUDED);
	Configure(&TFRPRudder, MODE_EXCLUDED);
	Configure(&TWCSThrottle, MODE_EXCLUDED);
	Configure(&TFRPHARudder, MODE_EXCLUDED);
	
	if(Init(&EventHandle)) return 1;
	
	SetKBRate(40, 50);									// (a,b) a = pulse duration, b = delay duration
	SetKBLayout(KB_ENG);
	
	// -------------------- IOUMD Buttons --------------------
	
	SetShiftButton(&Joystick, S4, &Throttle, BSF, BSB, 0);
	
 
	// -------------------- THROTTLE --------------------

	// Left Throttle Button
	MapKey(&Throttle, LTB, 		EXEC( "if (afterburnerdetent_present) {"		// If detent present
						   "afterburnerdetent(0);"			//   Engage afterburner
						   "afterburnerdetent_lifted = 1;"		//   Lift detent
						   "DXAxis( DX_ZROT_AXIS, -AMAX );"		//	 Left throttle to full afterburner
						   "DXAxis( DX_Z_AXIS, -AMAX );"		//	 Right throttle to full afterburner
					  "}" ));								

	// EORMOTOR
	MapKey(&Throttle, EORMOTOR, EXEC( "afterburnerdetent_present = 1;" 		// Engage afterburner detent
					  "afterburnerdetent(1);" ));
	MapKeyR(&Throttle, EORMOTOR, EXEC( "afterburnerdetent_present = 0;" 		// Disengage afterburner detent
					   "afterburnerdetent(0);" ));

	// THR_LEFT
	MapAxis(&Throttle, THR_LEFT, DX_ZROT_AXIS, AXIS_NORMAL, MAP_ABSOLUTE);
	SetSCurve(&Throttle, THR_LEFT, 0, 0, 0, 0, 0);
	// THR_RIGHT
	MapAxis(&Throttle, THR_RIGHT, DX_Z_AXIS, AXIS_NORMAL, MAP_ABSOLUTE);
	SetSCurve(&Throttle, THR_RIGHT, 0, 0, 0, 0, 0);


} // ------- end main -------


// -------------------- AFTERBURNER DETENT --------------------

int afterburnerdetent(int x)
{
	if (x == 1) {		// Activate detent
		SetCustomCurve(&Throttle, THR_LEFT, LIST(0,0, 25,25, 50,50, AB,AB, 100,AB));
		SetCustomCurve(&Throttle, THR_RIGHT, LIST(0,0, 25,25, 50,50, AB,AB, 100,AB));			
	}
	else {			// Throttle back to full reach
		SetSCurve(&Throttle, THR_LEFT, 0, 0, 0, 0, 0);
		SetSCurve(&Throttle, THR_RIGHT, 0, 0, 0, 0, 0);
	}
}


// -------------------- EVENTHANDLE --------------------

int EventHandle(int type, alias o, int x)
{
	if ((&o == &Throttle) & (x == THR_LEFT)) {							// Detect left throttle position for afterburner detent
		if (afterburnerdetent_present & afterburnerdetent_lifted) {				// If afterburnerdetent present and detent is lifted
			if (Throttle[THR_LEFT] < (100-AB)*(2*AMAX)/100) {				//   If left throttle below afterburner detent value of AB%
				afterburnerdetent(1);							//     Re-engage detent
				afterburnerdetent_lifted = 0;						//     Detent is no longer lifted
			}
		} 
	}
	DefaultMapping(&o, x);
}

 

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...