Jump to content

Drakoz

Members
  • Posts

    272
  • Joined

  • Last visited

Everything posted by Drakoz

  1. Regarding missed keys in TARGET, I see the problem. The TARGET GUI defaults to 25ms press time for PULSE'd commands (when you select Type Pulse for a key commmand). In some testing I did, for commmands like Left-Shift-A, the Left-Shift key is held down consistently for 25ms, but the A key is held down for less. Sometimes the A key was held down for less than 5ms. That is too short!!! This is not an issue if the key press command was the A key by itself, but combo keys like Shift-A or CTRL-A is a problem as the letter isn't held down as long as the SHIFT or CTRL. The problem is the default PULSE'd key press time should be higher in the GUI. You can change this in the TARGET GUI through the Configuration Option Menu, but it only allows a max delay of 33ms. Why, I have no idea. In the TARGET Script editor, you can set this delay to anything you want using the SetKBRate() command. Also, if you don't set a delay in the the TARGET Script editor with SetKBRate(), it defaults to 32ms. I have never had an issue with TARGET in DCS with this default, but I can see how the default of 25ms could cause all kinds of issues. Just changing the default to 32ms means you never get a key press for less than 15ms or maybe 10ms, which DCS seems to be able to handle. I would suggest setting the default delay to max (33ms) on all GUI configurations. If changing the default to 33ms isn't enough, you can use Press and Release command types and set any delay you want with the DELAY field. If defaults to 33ms, but setting it to 50ms should make sure there will never be an issue. BTW, whether run in the GUI, or the Script Editor, it is compiled and executed the same way, so this isn't an issue with the GUI being screwed up and not the Script Editor. It is simply an issue that the GUI defaults to 25ms. But this is pretty disappointing that TM set the default to 25ms and only allow a max of 33ms. I have used 100ms as the delay in some games that needed it. Sorry if this has been discussed many times. I don't use the GUI and had no idea such a fundamental issue existed with it. But now I understand why some people are having issues and hate TARGET because of it.
  2. Does it stutter in combination to any kind of message about TrackIR or a game controller disconnecting, or do you hear the USB bee-boop or boo-beep sound (like when disconnecting or connecting a USB device). I had severe issues with this for years and it is a common issue, but often people don't realize they have the problem because they just think it is a stutter on their graphics controller. In my case, it was a multitude of causes, but all related to USB devices causing a DirectX init and DCS not handling that well. You may have read people talk about Windows power saving modes for USB devices causing trouble (not just with DCS). I finally eradicated all the issues earlier this year. Anyway, my point is, make sure if it is just a very quick graphics stutter vs. the issue I am talking about which was a 2-3 second freeze up on DCS. If the latter, it is probably a USB issue. Also, regarding the key press delay, you shouldn't need a 500ms key press time in DCS. 50ms should be enough. In fact, the TARGET Script editor defaults to 32ms for PULSE'd commands and I've never had an issue with that in DCS. You can change the default. When in the GUI, and looking at the screen for programming the Warthog (e.g the Throttle), click on Configuration Options (upper middle of screen). Look for Define Pulse Event Time. On your F18.fcf file, it was set to 25 (the default for the TARGET GUI I assume). Set this to max (33ms). Now all PULSE'ed command should pulse the key for 33 ms. To test this, run your TARGET program, and click the Event Tester. Switch the APU ON/OFF switch back and forth. It should now press the A key for 20-33ms each time. With the default of 25ms selected on your original file, it was only pulsing the keys for as little as 5-10 ms sometimes in my tests (the A key was pressed for that long, but the LShift key was always 25ms). Now I see why some people have complained about TARGET missing key events. 5-10 ms. is too short. It really should be 50ms just to be safe, but the GUI won't allow setting that. Hmm. I have set default delays to 100ms before for specific games using the SetKBRate() command in the TARGET Script editor. I don't use the GUI, and I'm distressed to see TM screwed this up by not allowing larger values. So, as Weegie said, you can use Press and Release functions to add your own delay. Good call Weggie!
  3. If you try to assign everything using DirectX buttons, yes. But if you are doing that, you should not include the MFD's in the TARGET script, but instead program them directly (individualy) in DCS. Or do what SGT Coyle said to extend the max number of buttons in TARGET. But I would only do that if I needed to do shifted states or advanced programming on the MFD's while wanting to assign them as DirectX buttons. Instead, I always assign buttons as keyboard key combos. No 32 or 128 button limit anymore. Both methods work of course. [Never mind - see my next post - is that the issue you have?] If TARGET is causing intermittent buttons presses, it should be a solvable problem. I use TARGET extensively, including some significantly complex scripts (C coded TARGET scripts to map analog axis to keyboard keys in Train Sim World) and it is 100% spot on for getting all the key presses right. I would be happy to help you get it working (or have you already asked elsewhere - point me to the thread). There are a few reasons to dislike TARGET, but failure to get key presses working right is not one of them. Ha, I'm already there. Well, not a full page. But I now make check lists for all my DCS aircraft, and it includes pre-setup stuff like loading this and that software for my controllers, and checking that it is working correctly. But I do this mainly so I remember what to pre-configure for an aircraft that I haven't flown for a while. Otherwise, it becomes too overwhelming.
  4. This may or may not help... This is what I do for DCS, Discord, and Simple Radio (SRS). This allows me to use Discord, and SRS's 3 radios on my HOTAS without having to touch the keyboard (good for VR), but also allows me to talk on Discord and SRS using my keyboard if my HOTAS is not configured yet. I use TARGET to program my HOTAS, but you can set these key combos in any gaming setup software you like. Key combos were chosen specifically to not conflict with DCS, Windows, or a few other games I play. Discord - Settings -> Voice & Video -> Set Push to Talk = RWIN+F12 - Settings -> Keybinds -> Add "Toggle Mute" = RWIN+RCTRL+F12 SRS Set under SRS Controls tab - R_CTL+F9 PTT Radio 1 (Radio 1 set to F9, Radio 1 Modifier set to RCTRL) - R_CTL+F10 PTT Radio 2 (Radio 2 set to F10, Radio 2 Modifier set to RCTRL) - R_CTL+F11 PTT Radio 3 (Radio 3 set to F11, Radio 3 Modifier set to RCTRL) - R_CTL+F12 PTT for Intercom only (e.g. multi-crew or request ground support on some aircraft) (Intercom Select = F12, Modifier = RCTRL) - R_SHIFT+\ PTT for selected radio (Push to Talk - PTT = \, PTT Modifier = RSHIFT) - R_CTL+\ Select next radio (Select Next Radio = \, ..Next Radio Modifier = RCTRL) Note, if you are running out of SHIFT/CTRL/ALT key combos, it is easy to assign stuff to RWIN+(key) or LWIN+(key) combos, or even the Windows APPS+(key) combo because these keys are not often used in games or DCS. You may need to make sure you don't duplicate a real Windows WIN key function, though DCS seems to block WIN and APPS key commands from going to Windows. I normally map Radio 1, 2, and 3 on the Warthog Throttle MIC switch (forward, down and back), and map the Discord PTT and Mute buttons on some accessible buttons on either the stick or the throttle depending on which aircraft I'm flying. We normally fly with SRS, so Discord is just for pre and post flight discussions. This works for aircraft like the A-10C (as this is exactly how the A-10C works) or other aircraft with separate PTT buttons for each radio. Or for example, on the Huey, SRS automatically changes the radio audio channel selector to the correct channel when I PTT the different radios. On other aircraft that only have a single PTT button (e.g. Gazelle), I tap the Radio 1, 2, or 3 PTT button which causes SRS to select that radio, and then press the RSHIFT+\ SRS PTT (assigned to a convenient button on my stick) which acts as PTT for the currently selected radio. If I don't want to assign the MIC switch to the Radio 1, 2, 3 PTT, I can use RCTRL+\ to ask SRS to select the next radio in a round robin fashion. RCTRL+F12 for SRS Intercom Only PTT is needed for aircraft like the Huey because you sometimes need to be on Intercom to speak with ground crew. This causes SRS to select the Huey's Intercom audio channel. It might also be needed for multi-crew like in the F14, but I haven't tried that yet. To not waste buttons, since the joystick "trigger" is often the radio button even on some military aircraft (not the Fire button), for sticks that have a dual stage trigger, TG1 (first trigger step) is assigned as Discord PTT, and TG2 (2nd Trigger) is assigned as SRS PTT. I then assign a shifted TG1 to mute or unmute Discord. Now one button can talk on 3 radios, and Discord without issues of speaking on Discord and SRS at the same time. Meaning, if I mute Discord, I can press TG1 while passing through to TG2 without transmitting on Discord. All this can be done with any common joystick to keyboard mapping software. I use TARGET scripts for the Warthog Throttle, and the Logitech G940 programming software for my G940 FFB stick. BTW, I tend to avoid setting joystick keys (e.g. DX1, DX2) directly in DCS. Using external software to program all this means I don't have to reconfigure all my key binds in DCS due to a major update or re-install of the software. To each their own. Complicated? No more than anything else in DCS. Once I chose these keys, I just duplicated the configuration code for all my aircraft (in TARGET) and never have to think twice about it.
  5. OK, I get it. This is the age old problem. It is difficult to get a good geo referenced map out of DCS (the F10 map). Flappie has done an excellent job hand creating one for the Caucasus in GeoTIFF format (https://forums.eagle.ru/showthread.php?t=244363) and the easiest way to get an MBTiles version of it is to download the excellent CombatFlite program which uses MBTiles maps (what ForeFlight needs). The MBTiles maps are in the installation directory. But, all the other maps in CombatFlight are just real world sectionals - which don't always match the DCS map perfectly (airports and navigation beacons aren't always the same). BTW, CombatFlite (free download - https://www.combatflite.com/) can be used to plan DCS missions, and export Google Earth .kmz files for waypoints and other geometric information (hand drawn routes, zones, etc.) which can be imported into ForeFlight as well. See ForeFlight's webpage on importing this stuff here: https://foreflight.com/support/user-content/ CombatFlite integrates with the DCS Mission Editor to make all this much more easy. CombatFlite exports .KMZ files. This is just a compressed .KML file. You can unpack a .KMZ file with common ZIP programs like 7zip, WinRAR, etc. If all else fails, rename the .KMZ to .ZIP and Windows can unzip it with a double click. Then you can import the included .KML into ForeFlight directly as explained at the ForeFlight link above. Or maybe ForeFlight works with KMZ files? I haven't tried it. Holton181, thanks for your excellent work on DCS to GPS!!
  6. Has anyone made DCS maps for ForeFlight for DCS? I mean, once the maps are made, everyone should be able to share them. I have the ForeFlight USA Subscription, but what I really want is the DCS map from DCS as an imported overlay for ForeFlight. There is a lot of DCS specific info there that doesn't match current sectionals.
  7. I had the issue with DCS to GPS not working because of Simple Radio (SRS). I use ForeFlight. DCS to GPS would connect for about 3 seconds, and then disconnect as others have described. I then moved the DCS to GPS lines in Export.lua to before the SRS lines and DCS to GPS now works great, and so far SRS seems to be fine as well. Here is my Export.lua file in case it helps. I'm running DCS BIOS (the version created by the DCSFlightPanels guys). DCS to GPS, SRS, and Tacview. dofile(lfs.writedir()..[[scripts\DCS-BIOS\BIOS.lua]]) -- Export of NMEA sentences to be used with any application or device capable of using them. -- Uncomment only one of the two lines below corresponding to your DCS Saved Games path. You might need to edit the path if different than any of them. userprofile = os.getenv ("userprofile"):gsub("\\","/") -- dofile(userprofile .. "/Saved Games/DCS/Scripts/DCS_NMEA.lua") dofile(userprofile .. "/Saved Games/DCS.openbeta/Scripts/DCS_NMEA.lua") local dcsSr=require('lfs');dofile(dcsSr.writedir()..[[scripts\DCS-SimpleRadioStandalone.lua]]) local Tacviewlfs=require('lfs');dofile(Tacviewlfs.writedir()..'Scripts/TacviewGameExport.lua')
  8. dmonds, OK, I reviewed DefaultMapping() for nesting issues as well as found my previous notes about how EventHandle() and DefaultMapping() should be called, and realize I got it wrong. Instead of calling DefaultMapping(), you should use the following command instead: DefEventHandler(EV_HID_INPUT_DATA, &Throttle, THR_FC); See below for the details.... How to call EventHandle() or DefaultMapping() manually To call EventHandle() or DefaultMapping() manually, you need to call DefEventHandler(). DefEventHandler() is defined in target.tmh. For example, in this discussion at SimHQ (Activate a layer by code), I explain how to call DefEventHandler() to manually change the layer (IO or UMD) using TARGET code instead of using the assigned IO or UMD shift buttons. dmonds, this is similar to your original question where you wanted to change an axis and get it to update. But in my case, I changed the IO or UMD layer status, and had to get TARGET to accept and update the change. I had to call DefEventHandler(), which does a few checks, and then calls EventHandle(). Here is my example from the SimHQ forums which explains the proper way to call DefEventHandler(). I am using the Warthog Throttle MSP button for my IO button, and the Warthog Throttle Boat Switch (BSF, BSB) for my U, M, and D modes. Hence, I have the following command in my script: SetShiftButton(&Joystick, MSP, &Joystick, BSF, BSB); You set the mode (I, O, U, M, or D) by manually setting the Throttle[<button>] value equal to 1 or 0 (1 is pressed, 0 is not pressed). Then call the DefEventHandler(). DefEventHandler() does a few important checks, and then calls EvenHandle() and EventHandle() then calls DefaultMapping() which handles all events. In this case, we are tricking TARGET into thinking that the MSP or Boat Switch changed. In my example, I just used EXEC() routines connected to other buttons to fire off the change in IO or UMD. You can confirm it changed by pressing TG1 and seeing which number is pressed in an keyboard event viewer. Also, if you actually press the IO or UMD buttons, it will override this of course because it will set a new IO or UMD mode. // Set Shift mode to I MapKey(&Joystick, S1, EXEC("Throttle[MSP]=1; DefEventHandler(EV_HID_INPUT_DATA, &Throttle, MSP);")); // Set Shift mode to O MapKey(&Joystick, S2, EXEC("Throttle[MSP]=0; DefEventHandler(EV_HID_INPUT_DATA, &Throttle, MSP);")); // Set UMD mode to U MapKey(&Joystick, H1U, EXEC("Throttle[bSF]=1; DefEventHandler(EV_HID_INPUT_DATA, &Throttle, BSF);")); // Set UMD mode to M (reset U mode) MapKey(&Joystick, H1D, EXEC("Throttle[bSF]=0; DefEventHandler(EV_HID_INPUT_DATA, &Throttle, BSF);")); // Set UMD mode to M (reset D mode) MapKey(&Joystick, H1L, EXEC("Throttle[bSB]=0; DefEventHandler(EV_HID_INPUT_DATA, &Throttle, BSB);")); // Set UMD mode to D MapKey(&Joystick, H1R, EXEC("Throttle[bSB]=1; DefEventHandler(EV_HID_INPUT_DATA, &Throttle, BSB);")); // Use TG1 to test the result MapKeyIOUMD(&Joystick, TG1, '4', // IU '3', // OU '2', // IM '1', // OM '6', // ID '5' // OD ); For Resetting the U or D mode to M, any action that sets M mode will reset either U or D. Originally I said just call DefaultMapping(), but because there are some important checks and configurations that occur in DefEventHandler(), calling DefaultMapping() or EventHandle() directly is a bad idea. This is what TARGET does for all new events as well (the background TARGET Service calls DefEvenHandler() in reaction to any new button press or axis change). Also, in this example, I use EV_HID_INPUT_DATA, but it has no impact on the result. You could probably leave it as 0 and it would still work. But EV_HID_INPUT_DATA seems to be the proper value for a generic controller input change. See hid.tmh for the definition of EV_HID_INPUT_DATA, though it is not clearly explained. I think this is related to a legacy feature, or something that was not completely implemented. EventHandle() completely ignores it, and DefaultMapping() doesn't even receive this value. Note, if you look at DefEventHandle() in target.tmh, you'll see it calls _evh(), but has no reference to EventHandle(). But, actually, _evh() is EventHandle(). This is set up in the if(Init(&EventHandle)) return 1; line at the start of every TARGET script. Go look at Init() in target.tmh if you want to see how it happens. What about Nesting issues in DefaultMapping() I am still unsure about this. DafaultMapping() does affect a few global variables, and makes some calls to Map() and ActKey(), which may cause some issues depending on how you call DefaultMapping() (or DefEventHandler() ). For example you know how there are certain times when you are not allowed to call SEQ, CHAIN, EXEC, TEMPO, etc. (read the TARGET manual on these commands for further explanation). This is exactly the kind of issue I am talking about. The first thing DefEventHandle() does is set alloc_locked = 1. This prevents ASMAlloc() from working to prevent nesting or other issues. ASMAlloc() is used by SEQ, CHAIN, etc. Search on ASMAlloc() in target.tmh and you'll see what I mean. Anyway, the answer is, if you call DefEventHandle(), be aware your code may do something abnormal depending how or where you call it. If so, rethink how you are calling, and perhaps use the techniques described for calling SEQ, CHAIN, EXEC, TEMPO, etc. instead to call DefEventHandle(). Using Virtual Buttons for IO and UMD Shift Layers Finally, I'll repost my comments from SimHQ on how to do the IO and UMD stuff without having to assign actual buttons. Virtual Buttons were discussed a lot in the early pages of the TARGET - Advanced programming forum topic. But here is a quick explaination of using virtual buttons to control IO and UMD purely in code, without having to assign a specific button to do it. Here is an updated code example using VBI, VBU, and VBD (buttons I created for the Warthog Joystick) as virtual IO and UMD buttons. This code example is a complete program. Copy and paste into the TARGET script editor and it will run. I did this to point out that the defines for VBI, VBU and VBD must be outside of main(), or must be in your .ttm file. This example does not use a .ttm. You have a maximum of 52 real + virtual buttons which are numbered 0 through 51. This maximum is defined by MAXKEYDATA in target.tmh. The Warthog Throttle uses all 52 of them, but the Warthog Joystick and most other TARGET supported devices use less than 52 buttons. You can see this in the defines.tmh file. Look at the "Warthog Joystick interface" definition. It has slots 0 - 18, assigned to real buttons, and 29 - 32 assigned to virtual buttons. So it is safe to use slots 40, 41, and 42. So I assigned VBI, VBU and VBD as 40, 41, and 42 and used them for the Warthog Joystick. If Joystick[VBI] = 1, then the virtual button is "pressed", and = 0 means released. Now, everything you can do with a real button, you can do with VBI, VBU and VBD, including assigning them as the IO Shift and UMD Mode buttons. include "target.tmh" // Define virtual buttons for IO Shift and UMD mode for Warthog Joystick define VBI 40 // Mode I virtual button define VBU 41 // Mode U virtual button define VBD 42 // Mode D virtual button int main() { if(Init(&EventHandle)) return 1; SetShiftButton(&Joystick, VBI, &Joystick, VBU, VBD, 0); // IO Shift and UMD Setup (%DEV1, I button, $DEV, U, D, Toggle settings) MapKey(&Joystick, S1, EXEC("Joystick[VBI]=1; DefEventHandler(EV_HID_INPUT_DATA, &Joystick, VBI);")); MapKey(&Joystick, S2, EXEC("Joystick[VBI]=0; DefEventHandler(EV_HID_INPUT_DATA, &Joystick, VBI);")); MapKey(&Joystick, H1U, EXEC("Joystick[VBU]=1; DefEventHandler(EV_HID_INPUT_DATA, &Joystick, VBU);")); MapKey(&Joystick, H1D, EXEC("Joystick[VBU]=0; DefEventHandler(EV_HID_INPUT_DATA, &Joystick, VBU);")); MapKey(&Joystick, H1L, EXEC("Joystick[VBD]=0; DefEventHandler(EV_HID_INPUT_DATA, &Joystick, VBD);")); MapKey(&Joystick, H1R, EXEC("Joystick[VBD]=1; DefEventHandler(EV_HID_INPUT_DATA, &Joystick, VBD);")); // Test the result MapKeyIOUMD(&Joystick, TG1, '4', // IU '3', // OU '2', // IM '1', // OM '6', // ID '5' // OD ); } int EventHandle(int type, alias o, int x) { DefaultMapping(&o, x); } If you want to use a different Thrustmaster device, make sure the numbers you choose do not conflict with the device definition in defines.tmh. If you increase MAXKEYDATA in target.tmh to a larger value, you can create more virtual buttons, up to 256 total buttons (real + virtual) because the joy1[], joy2[], joy3[], etc. arrays defined in hid.tmh allow for up to 256 buttons total. Note, joy1[], joy2[], etc. are the actual arrays which &Joystick, &Throttle, &HCougar, etc. point to. See my post on SimHQ on Re: How to detect Shift key for more details on these arrays. Understanding them goes a long way toward understanding how to do all these more advanced TARGET scripts. That post also explains the layer_sw[] array, which is used to set the IO and UMD keys, for anyone that is curious. Again, it is not my intent to redirect this conversation to SimHQ. If you read anything I linked to SimHQ and want to ask a question, please redirect the question here on the ED forums. There appears to be a much larger Thrustmaster TARGET audience here.
  9. Cool. I'll try it out as well as I want to look at the nesting of DefaultMapping() a bit more to alleviate my previous concerns.
  10. I have several ideas on how to solve this, but I'm not 100% sure about exactly the issue you are seeing. Can you post your TARGET script so I can see what you mean? I'll look at it and make some suggestions. In the mean time, you may want to read this forum topic at SimHQ (SimHQ: Set an axis to a particular value) where I go into detail on many of the techniques that may help you. If you have questions, please post here on the ED forums. It is not my intention to divert this conversation to another forum, and I think there is a much bigger audience here. In the topic above, I explain stuff like how to use DXAxis() to set an axis to a specific value, or how to create your own scripts to manually apply curves. Although that might be more difficult than simply using SetSCurve(), doing so would allow you to more easily control syncing up the physical lever on the Warthog with the position calculated for that axis in TARGET and prevent a jump like you are experiencing. I also have an example of a script that will allow you to move a lever until it is in sync with what TARGET thinks the lever is at, and then enable that lever to work - hence preventing a jump. But toward your primary question.... Causing TARGET to update an axis without moving the axis At first, I considered that you might just call EventHandle() from your button press that changes the axis curve, but then I realized that if you create a call to EventHandle() as a result of performing a button press (which causes a call to EventHandle() already), you would be calling EventHandle() within EventHangle(), which is perhaps not a good idea. Since calling EventHandle() is really just calling DefaultMapping(), you would be calling DefaultMapping() within itself (nested), and I believe all the code in DefaultMapping() is designed to run unnested. I haven't tried this, so it might be worth a try (CORRECTION: I did try this - see my post below). Worst thing is TARGET might lock up, or just do weird things. The code might look like the following. I'm using EACON on the Throttle to change the curve. EAOFF would set a different curve for example. MapKey(&Throttle, EACON, CHAIN( SetSCurve(&Joystick, THR_FC, 0, 0, 0, 0, 0), // Set new curve (my example is just a flat curve, no deadzone) EXEC("DefaultMapping(&Thorttle, THR_FC);" ) // This will cause TARGET to recalculate the curve and move the axis ), ); But since changing the state of EACON would call EventHandle(), and since the commands for EACON also does an EXEC to call DefaultMapping(), I believe this will be a nested call to DefaultMapping(), and that might screw up some global variables that expect DefaultMapping() to NOT be nested. Again, please post your code, and I can make some better suggestions. Regards, Michael
  11. Another way to do it is to create virtual Shift IO or UMD buttons, and then set the UMD or IO state manually instead of using the SetShifttButton() command. This allows you to use MapKeyIO() or MapKeyUMD() normally vs. the method posted by SGT Coyle above. Both methods work great, and which you use depends on how you want to do your coding. I posted how to do this in detail at SimHQ (see link below). http://simhq.com/forum/ubbthreads.php/topics/4422100/activate-a-layer-by-code I'll restate the main details below so as to not divert the discussion to another forum. First, an example that explains how to manually change the IO or UMD state of a normal button - this is important to understand before showing how to create virtual buttons and do the same thing with a virtual button. I am using the Warthog Throttle MSP button for my IO button, and the Warthog Throttle Boat Switch (BSF, BSB) for my U, M, and D modes. But these techniques will work with any TARGET compatible device. Below, I mention Throttle[<button>]. This is really just &Throttle. &Throttle references the array Throttle[], and Throttle[] contains the current state of all the buttons and axis from the Warthog Throttle. For example, Throttle[MSP] equals the state of the Warthog Throttle MSP button (hence why I said <button> to generically mean you can insert any button name between the []). For other devices, you would use Joystick[] for the Warthog Joystick (referenced normally as &Joystick), T16000[] for the T16000 stick and throttle (referenced normally as &T16000), etc. These arrays are how TARGET tracks the current state of all buttons and axis for all connected devices, and they allow us a lot of power to manipulate stuff. So, you can set the mode (I, O, U, M, or D) by setting the Throttle[<button>] value equal to 1 or 0 (1 is pressed, 0 is not pressed). Then call the EventHandler. But understand that EventHandle() in the bottom of your script file is not the master Event Handler. Instead, we have to call DefEventHandler() which is in target.tmh. DefEventHandler() does a few checks, and then calls EvenHandle() and EventHandle() then calls DefaultMapping() which handles all events. In this case, we are tricking TARGET into thinking that the MSP or Boat Switch changed. In my example, I just used EXEC() routines connected to other buttons to fire off the change in IO or UMD. You can confirm it changed by pressing TG1. Also, if you actually press the IO or UMD buttons, it will override this of course because it will set a new IO or UMD mode. SetShiftButton(&Joystick, MSP, &Joystick, BSF, BSB); // Set Shift mode to I MapKey(&Joystick, S1, EXEC("Throttle[MSP]=1; DefEventHandler(EV_HID_INPUT_DATA, &Throttle, MSP);")); // Set Shift mode to O MapKey(&Joystick, S2, EXEC("Throttle[MSP]=0; DefEventHandler(EV_HID_INPUT_DATA, &Throttle, MSP);")); // Set UMD mode to U MapKey(&Joystick, H1U, EXEC("Throttle[bSF]=1; DefEventHandler(EV_HID_INPUT_DATA, &Throttle, BSF);")); // Set UMD mode to M (reset U mode) MapKey(&Joystick, H1D, EXEC("Throttle[bSF]=0; DefEventHandler(EV_HID_INPUT_DATA, &Throttle, BSF);")); // Set UMD mode to M (reset D mode) MapKey(&Joystick, H1L, EXEC("Throttle[bSB]=0; DefEventHandler(EV_HID_INPUT_DATA, &Throttle, BSB);")); // Set UMD mode to D MapKey(&Joystick, H1R, EXEC("Throttle[bSB]=1; DefEventHandler(EV_HID_INPUT_DATA, &Throttle, BSB);")); // Use TG1 to test the result MapKeyIOUMD(&Joystick, TG1, '4', // IU '3', // OU '2', // IM '1', // OM '6', // ID '5' // OD ); For Resetting the U or D mode to M, any action that sets M mode will reset either U or D. It may work just as well to call EventHandle() directly (e.g. EventHandle(EV_HID_INPUT_DATA, &Throttle, MSP); ), but probably better to call DefEvenHandler() as this is what TARGET does for all new events. Also, in this example, EV_HID_INPUT_DATA has no impact on the result. You could probably leave it as 0 and it would still work. But EV_HID_INPUT_DATA seems to be the proper value for a generic controller input change. See hid.tmh for the definition of EV_HID_INPUT_DATA, though it is not clearly explained. I think this is related to a legacy feature, or something that was not completely implemented. EventHandle() completely ignores it. But, I hear you say, you don't want to have to assign a real button as the IO or UMD buttons using SetShiftButton(). So we can use virtual buttons. You can create virtual buttons to achieve this. Here is an updated code example using VBI, VBU, and VBD (buttons I created for the Warthog Joystick) as virtual IO and UMD buttons. This code example is a complete program. Copy and paste into the TARGET script editor and it will run. It should work with minor changes for the T16000. I did this to point out that the defines for VBI, VBU and VBD must be outside of main(), or must be in your .ttm file. This example does not use a .ttm. You have a maximum of 52 real + virtual buttons which are numbered 0 through 51 (this has been discussed earlier in this thread). This maximum is defined by MAXKEYDATA in target.tmh. The Warthog Throttle uses all 52 of them, but the Warthog Joystick and most other TARGET supported devices use less than 52 buttons. You can see this in the defines.tmh file. Look at the "Warthog Joystick interface" definition. It has slots 0 - 18, assigned to real buttons, and 29 - 32 assigned to virtual buttons. So it is safe to use slots 40, 41, and 42. So I assigned VBI, VBU and VBD as 40, 41, and 42 and used them for the Warthog Joystick. If Joystick[VBI] = 1, then the virtual button is "pressed", and = 0 means released. Now, everything you can do with a real button, you can do with VBI, VBU and VBD, including assigning them as the IO Shift and UMD Mode buttons. My example below uses joystick buttons, but you can do the same by putting the EXEC() commands in a KeyAxis() command for the T16000 Throttle as SGT Coyle suggested. include "target.tmh" // Define virtual buttons for IO Shift and UMD mode for Warthog Joystick define VBI 40 // Mode I virtual button define VBU 41 // Mode U virtual button define VBD 42 // Mode D virtual button int main() { if(Init(&EventHandle)) return 1; SetShiftButton(&Joystick, VBI, &Joystick, VBU, VBD, 0); // IO Shift and UMD Setup (%DEV1, I button, $DEV, U, D, Toggle settings) MapKey(&Joystick, S1, EXEC("Joystick[VBI]=1; DefEventHandler(EV_HID_INPUT_DATA, &Joystick, VBI);")); MapKey(&Joystick, S2, EXEC("Joystick[VBI]=0; DefEventHandler(EV_HID_INPUT_DATA, &Joystick, VBI);")); MapKey(&Joystick, H1U, EXEC("Joystick[VBU]=1; DefEventHandler(EV_HID_INPUT_DATA, &Joystick, VBU);")); MapKey(&Joystick, H1D, EXEC("Joystick[VBU]=0; DefEventHandler(EV_HID_INPUT_DATA, &Joystick, VBU);")); MapKey(&Joystick, H1L, EXEC("Joystick[VBD]=0; DefEventHandler(EV_HID_INPUT_DATA, &Joystick, VBD);")); MapKey(&Joystick, H1R, EXEC("Joystick[VBD]=1; DefEventHandler(EV_HID_INPUT_DATA, &Joystick, VBD);")); // Test the result MapKeyIOUMD(&Joystick, TG1, '4', // IU '3', // OU '2', // IM '1', // OM '6', // ID '5' // OD ); } int EventHandle(int type, alias o, int x) { DefaultMapping(&o, x); } If you want to use a different Thrustmaster device, make sure the numbers you choose do not conflict with the device definition in defines.tmh. I assume if you increase MAXKEYDATA in target.tmh to a larger value, you can create more virtual buttons, up to 256 total buttons (real + virtual) because the joy1[], joy2[], joy3[], etc. arrays defined in hid.tmh allow for up to 256 buttons total. Note, joy1[], joy2[], etc. are the actual arrays which &Joystick, &Throttle, &HCougar, etc. point to. See my post on SimHQ on "Re: How to detect Shift key" http://simhq.com/forum/ubbthreads.php/topics/4408901/re-how-to-detect-shift-key#Post4408901 for more details on these arrays. Understanding them goes a long way toward understanding how to do all these more advanced TARGET scripts. And for some more commentary on all this, go back to where I originally posted all this on SimHQ. http://simhq.com/forum/ubbthreads.php/topics/4422100/activate-a-layer-by-code
  12. OK, I was just going to ask that (if you were doing duplicate define names in the two different .ttm files). BTW, an include (.ttm file called with an include statement or other files like target.tmh) should be treated as if the text of that file is inserted into your main .tmc file exactly where the include statement is. And in fact that is exactly what happens during compiling. As you discovered, you can't define the same name twice in a single .ttm file or anywhere in the entire compiled set of files for that matter, "included" or otherwise.. But there is another way to do it using variables instead of defines. For example I might define the following in a .ttm file: (SGT_Coyle, I just saw you have done variables before but hopefully this will enhance your understanding - if not sorry for the redundancy) define WipersIncrease 'v' // Window Wiper - increase speed define WipersDecrease L_SHIFT+'v' // Window Wiper - decrease speed But I can do a similar thing with integer variables as follows: int wipersIncrease = 'v'; int wipersDecrease = L_SHIFT+'v'; 'v' is a variable of type char but a char is just an 8 bit integer. Hence why I use an int variable (int wipersIncrease for example). It can be used just like a define, but a define is a constant - can't change it. A variable can be changed. And it also means you can create variables just like defines with SHIFT, ALT, CTRL, etc. as I did with wipersDecrease. BTW, I tend to start defines with a capital letter but variables with lower case. It helps me remember which is a define vs. a variable. Then you can use this variable just like you would a define macro. For example: int wpersIncrease = 'v'; int wipersDecrease = L_SHIFT+'v'; // EAC Switch MapKeyIO(&Throttle, EACON, 0, PULSE+wipersIncrease); MapKeyIO(&Throttle, EACOFF, 0, PULSE+wipersDecrease); Here I added a PULSE command to the two wiper variables. It all works just like a define. It is important to think about where you define the variables, though. Variables created before main() will be global which will include any variables you create in a .ttm file which is included before main(). All functions will see them, and anywhere you change the variable, it changes it globally. But if you create the variable inside a function the variable is only visible in that function. And its value will bw lost when you leave that function. This is all just standard C programming. Here is a complex example which uses both global int variables and local int variables. This is just a small subset of a Target program I wrote for Train Sim World which allows changing the config profile for 7 different locomotive engines. It uses the same concept of a common config function (see CommonConfig()) as well as custom configuration functions for each different engine. Don't worry about all the details in my example. I stripped this down to just to show the examples of how I handled windshield wipers and engine headlights differently for several engines. In some cases I used defines in the .ttm and in others I used int variables. In some I used variables with defines to build complex chains. Look for the following variables in the code. These three are global for controlling the windshield wipers: wiperCHAINUP wiperCHAINDN wiperCHAINUPCount; But these are defined only inside specific functions and are visible only inside those functions: headlightFrontFwd headlightFrontBkd headlightRearFwd headlightRearBkd Note, this example will not compile and run. I stripped it down too much. If you want to see the full script, you can see it here: https://forums.dovetailgames.com/threads/thurstmaster-target-script-for-warthog-throttle-saitek-tq-profile.3634/ Or just download the script here (with documentation): http://akhara.com/drop/TrainSimWorld/TSW_TARGET_Script_Drakoz_v2_1.zip Here is the .tmc: include "target.tmh" include "Drakoz_TrainSimWorld.ttm" // Default Engine Profile // This script is designed to have different control setups for different engines. // This is mainly to control the difference of separate throttle and brake levers (e.g. SD40-2, GP38) // vs. combined throttle/brake levers (e.g. AC4400CW). // Choices: // pro_ProfileSelection = // pro_SD40GP38 - EMD SD40-2, GP38-2, GP40-2 (LED 00001 = 1) // pro_AC4400CW - GE AC4400CW (LED 00010 = 2) // pro_BR43 - British Rail Class 43 HST (LED 00011 = 3) // pro_BR166 - British Rail Class 166 (LED 00100 = 4) // pro_BR66 - British Rail Class 66 (LED 00101 = 5) // pro_DBBR422 - DB BR 442 Talent 2 EMU (LED 00110 = 6) // pro_ACS64 - Amtrak ACS-64 (LED 00111 = 7) //int pro_ProfileSelection = pro_SD40GP38; int pro_ProfileSelection = pro_ACS64; int wiperCHAINUP, wiperCHAINDN, wiperCHAINUPCount; // global vars used for window wiper switch up/down commands int main() { // ... // Call functions to make custom configuration for each profile // Allows creating MapKey() and other configurations specific to each engine type. // Configurations in pro_CallCustomConfigs() will override any previous MapKey(), KeyAxis(), etc. commands. pro_CallCustomConfigs(); } // end main() //****************************************************************** // CommonConfig() // Configurations (MapKey, KeyAxis, Axis setup, etc.) that is common to all engines should be set up here. // This function will be called every time a profile change occurs before setting any custom configuration for specific engines. int CommonConfig() { // Engine Fuel Flow Left/Right Switches MapKeyIO(&Throttle, EFRNORM, 0, CHAIN(LOCK+DOWN+WipersIncrease, D(500), UP+WipersIncrease, LOCK)); MapKeyIO(&Throttle, EFROVER, 0, CHAIN(LOCK+DOWN+WipersDecrease, D(1100), UP+WipersDecrease, LOCK)); // Engine Operate Switch - Left MapKeyIO (&Throttle, EOLIGN, 0, PULSE+HeadlightsRearFwd); MapKeyIO (&Throttle, EOLNORM, 0, 0); MapKeyRIO(&Throttle, EOLMOTOR, 0, 0); MapKeyIO (&Throttle, EOLMOTOR, 0, PULSE+HeadlightsRearBkd); // Engine Operate Switch - Right MapKeyIO (&Throttle, EORIGN, 0, PULSE+HeadlightsFwd); MapKeyIO (&Throttle, EORNORM, 0, 0); MapKeyRIO(&Throttle, EORMOTOR, 0, 0); MapKeyIO (&Throttle, EORMOTOR, 0, PULSE+HeadlightsBkd); // Autopilot button and switch wiperCHAINUP = CHAIN(LOCK+DOWN+WipersIncrease, D(250), UP+WipersIncrease, D(25), LOCK); MapKeyIO(&Throttle, APPAT, 0, // Repeat WipersIncrease until APPAT turned off, or count reached CHAIN( EXEC("wiperCHAINUPCount=5;"), // Set to number of time to repeat REXEC(REXEC_Wiper, 1000, // 1 second delay between repeats "ActKey(KEYON+wiperCHAINUP);" // press wiper key "wiperCHAINUPCount=wiperCHAINUPCount-1;" // decrement count and if = 0, stop the REXEC "if (wiperCHAINUPCount <= 0) StopAutoRepeat(REXEC_Wiper);" ) ) ); wiperCHAINDN = CHAIN(LOCK+DOWN+WipersDecrease, D(250), UP+WipersDecrease, D(25), LOCK); MapKeyIO(&Throttle, APALT, 0, // Repeat WipersDecrease until APALT turned off, or count reached CHAIN( EXEC("wiperCHAINUPCount=5;"), REXEC(REXEC_Wiper, 1000, "ActKey(KEYON+wiperCHAINDN);" "wiperCHAINUPCount=wiperCHAINUPCount-1;" "if (wiperCHAINUPCount <= 0) StopAutoRepeat(REXEC_Wiper);" ) ) ); // ... other configs that are common to all engines } //****************************************************************** // pro_CallCustomConfigs() // Call functions to make custom configuration for each profile int pro_CallCustomConfigs() { // Do common config shared by all engines first CommonConfig(); // Then do custom config depending on profile. // MapKey(), etc. setup in custom config will overwrite the button/axis configs from the common config. if (pro_ProfileSelection == pro_SD40GP38) pro_ConfigureSD40GP38(); else if (pro_ProfileSelection == pro_AC4400CW) pro_ConfigureAC4400CW(); else if (pro_ProfileSelection == pro_BR43) pro_ConfigureBR43(); else if (pro_ProfileSelection == pro_BR166) pro_ConfigureBR166(); else if (pro_ProfileSelection == pro_BR66) pro_ConfigureBR66(); else if (pro_ProfileSelection == pro_DBBR422) pro_ConfigureDBBR422(); else if (pro_ProfileSelection == pro_ACS64) pro_ConfigureACS64(); } //****************************************************************** // pro_ConfigureSD40GP38() // Custom configuration for SD40-2, GP38-2, GP40-2 and other similar diesel engines int pro_ConfigureSD40GP38() { printf("Profile %d: pro_SD40GP38\xa", pro_SD40GP38); // ... custom config here ... } //****************************************************************** // pro_ConfigureAC4400CW() // Custom configuration for AC4400CW. int pro_ConfigureAC4400CW() { printf("Profile %d: pro_AC4400CW\xa", pro_AC4400CW); // Headlight Switch - different delays needed vs. other engines. // Following complicated CHAIN commands needed to overcome issues with SHIFT & CTL not being received properly by TSW (bug with TSW?) int headlightFrontFwd = CHAIN(LOCK+DOWN+'h', D(250), UP+'h', D(50), LOCK); int headlightFrontBkd = CHAIN(LOCK+DOWN+L_SHIFT, D(50), DOWN+'h', D(250), UP+'h', D(50), UP+L_SHIFT, D(50), LOCK); int headlightRearFwd = CHAIN(LOCK+DOWN+L_CTL, D(50), DOWN+'h', D(300), UP+'h', D(50), UP+L_CTL, D(50), LOCK); int headlightRearBkd = CHAIN(LOCK+DOWN+L_SHIFT, D(50), DOWN+L_CTL, D(50), DOWN+'h', D(300), UP+'h', D(50), UP+L_CTL, D(50), UP+L_SHIFT, D(50), LOCK); // Engine Operate Switch - Right MapKeyIO (&Throttle, EORIGN, 0, headlightFrontFwd); MapKeyIO (&Throttle, EORNORM, 0, 0); MapKeyRIO(&Throttle, EORMOTOR, 0, 0); MapKeyIO (&Throttle, EORMOTOR, 0, headlightFrontBkd); // Engine Operate Switch - Left MapKeyIO (&Throttle, EOLIGN, 0, headlightRearFwd); MapKeyIO (&Throttle, EOLNORM, 0, 0); MapKeyRIO(&Throttle, EOLMOTOR, 0, 0); MapKeyIO (&Throttle, EOLMOTOR, 0, headlightRearBkd); // ... other custom config here ... } //****************************************************************** // pro_ConfigureBR43() // Custom configuration for British Rail Class 43 HST int pro_ConfigureBR43() { printf("Profile %d: pro_BR43\xa", pro_BR43); // ... custom config here ... } //****************************************************************** // pro_ConfigureBR166() // Custom configuration for British Rail Class 166 int pro_ConfigureBR166() { printf("Profile %d: pro_BR166\xa", pro_BR166); // Headlight Switch - different delays needed vs. other engines. // Following complicated CHAIN commands needed to overcome issues with SHIFT & CTL not being received properly by TSW (bug with TSW?) int headlightFrontFwd = CHAIN(LOCK+DOWN+'h', D(400), UP+'h', D(50), LOCK); int headlightFrontBkd = CHAIN(LOCK+DOWN+L_SHIFT, D(50), DOWN+'h', D(400), UP+'h', D(50), UP+L_SHIFT, D(50), LOCK); // Engine Operate Switch - Right MapKeyIO (&Throttle, EORIGN, 0, headlightFrontFwd); MapKeyIO (&Throttle, EORNORM, 0, 0); MapKeyRIO(&Throttle, EORMOTOR, 0, 0); MapKeyIO (&Throttle, EORMOTOR, 0, headlightFrontBkd); // ... other custom config here ... } //****************************************************************** // pro_ConfigureBR66() // Custom configuration for British Rail Class 66 int pro_ConfigureBR66() { printf("Profile %d: pro_BR66\xa", pro_BR66); // Engine Operate Switch - Left // Map HeadlightsRearFwd for EOLIGN and EOLMOTOR because HeadlightsRearBkd does nothing for this engine MapKeyIO (&Throttle, EOLIGN, 0, HeadlightsRearFwd); MapKeyIO (&Throttle, EOLNORM, 0, 0); MapKeyRIO(&Throttle, EOLMOTOR, 0, 0); MapKeyIO (&Throttle, EOLMOTOR, 0, HeadlightsRearFwd); // ... other custom config here ... } //****************************************************************** // pro_ConfigureDBBR422() // Custom configuration for DB BR 442 Talent 2 EMU int pro_ConfigureDBBR422() { printf("Profile %d: pro_DBBR422 -- currently unsupported\xa", pro_DBBR422); // ... custom config here ... } //****************************************************************** // pro_ConfigureACS64() // Custom configuration for Amtrak ACS-64 int pro_ConfigureACS64() { printf("Profile %d: pro_ACS64\xa", pro_ACS64); // ... custom config here ... } //****************************************************************** int EventHandle(int type, alias o, int x) { DefaultMapping(&o, x); } //****************************************************************** And the .ttm: //****************************************************************** // Profile Selection Labels (used for the variable pro_ProfileSelection) // Do not define any profile at 0, only 1 through 31 allowed. define pro_SD40GP38 1 // EMD SD40-2, GP38-2, GP40-2 (LED 00001 = 1) define pro_AC4400CW 2 // GE AC4400CW (LED 00010 = 2) define pro_BR43 3 // British Rail Class 43 HST (LED 00011 = 3) define pro_BR166 4 // British Rail Class 166 (LED 00100 = 4) define pro_BR66 5 // British Rail Class 66 (LED 00101 = 5) define pro_DBBR422 6 // DB BR 442 Talent 2 EMU (LED 00110 = 6) define pro_ACS64 7 // Amtrak ACS-64 (LED 00111 = 7) define pro_NumOfProfiles 7 // Set to the number of profiles listed (31 max allowed) //****************************************************************** // REXEC() Handles // Place any handles for REXEC() here so we know which handle numbers we have used (0 to 99 allowed) define REXEC_Wiper 1 // Used for a repeating window wiper REXEC() function define WipersIncrease 'v' // Window Wiper - increase speed define WipersDecrease L_SHIFT+'v' // Window Wiper - decrease speed // Following complicated CHAIN commands needed to overcome issues with SHIFT & CTL not being received properly by TSW (bug with TSW?) //define HeadlightsFwd 'h' // Front Headlight - Move to next Switch Position define HeadlightsFwd CHAIN(LOCK+DOWN+'h', D(250), UP+'h', D(50), LOCK) //define HeadlightsBkd L_SHIFT+'h' // Front Headlight - Move to previous Switch Position define HeadlightsBkd CHAIN(LOCK+DOWN+L_SHIFT, D(50), DOWN+'h', D(250), UP+'h', D(50), UP+L_SHIFT, D(50), LOCK) //define HeadlightsRearFwd L_CTL+'h' // Rear Headlight - Move to next Switch Position define HeadlightsRearFwd CHAIN(LOCK+DOWN+L_CTL, D(50), DOWN+'h', D(250), UP+'h', D(50), UP+L_CTL, D(50), LOCK) //define HeadlightsRearBkd L_SHIFT+L_CTL+'h' // Rear Headlight - Move to previous Switch Position define HeadlightsRearBkd CHAIN(LOCK+DOWN+L_SHIFT, D(50), DOWN+L_CTL, D(50), DOWN+'h', D(250), UP+'h', D(50), UP+L_CTL, D(50), UP+L_SHIFT, D(50), LOCK)
  13. Glad it is working for you. The example is a simplified version of my template which I use for new files, so I left stuff in like the LEDs and such in case it was useful. I do VR now too so LEDs and printf statements are mostly for debug now. Yes good point that the Pilot function can have 100% of all commands and call it first as the default, and the RIO function just has the changes specific to the RIO. You were talking about .ttm files which it is OK to break them up as well. You just have to include both .ttm files. But include files are universal, just be aware. You can't include a .ttm file and have it only be active for only one function. Anyway, as I was saying, you can also make the Pilot and RIO functions complete by themselves, or just make the RIO function add on or modify commands from the pilot function but call the pilot function to set the base config, which makes it easier to manage them or make them separate .tmc files one day if desired. You get the idea and the rest is just personal preference how you want to do it.
  14. Here is an example of how to do it. This should work well as a template for your config. It swaps between the Pilot and RIO configs when you press the I shift key (S3 on the Warthog Joystick) and the LTB button on the Warthog Throttle. Of course it is easy to change the button combo to suit your needs. It also uses LEDs to indicate which profile is currently selected. Reply with any questions. The .tmc file: //****************************************************************** include "target.tmh" include "_Drakoz_DualConfigExample.ttm" int main() { if(Init(&EventHandle)) return 1; //****************************************************************** // Common config for Pilot and RIO //****************************************************************** // This config will be set up once and never changed. Settings are for both Pilot and RIO. //****************************************************************** // Setup some basic settings SetKBLayout(KB_ENG); // this file designed for English keyboard. SetShiftButton(&Joystick, S3, &Throttle, 0, 0, 0); // IO Shift and UMD Setup //****************************************************************** // Map DirectX axis // JoyX, JoyY MapAxis(&Joystick, JOYX, DX_X_AXIS, AXIS_NORMAL, MAP_ABSOLUTE); MapAxis(&Joystick, JOYY, DX_Y_AXIS, AXIS_NORMAL, MAP_ABSOLUTE); // Throttle - Left and Right MapAxis(&Throttle, THR_RIGHT, DX_Z_AXIS, AXIS_NORMAL, MAP_ABSOLUTE); MapAxis(&Throttle, THR_LEFT, DX_ZROT_AXIS, AXIS_NORMAL, MAP_ABSOLUTE); // Slew Control MapAxis(&Throttle, SCX, DX_XROT_AXIS, AXIS_NORMAL, MAP_ABSOLUTE); MapAxis(&Throttle, SCY, DX_YROT_AXIS, AXIS_NORMAL, MAP_ABSOLUTE); // Throttle Friction Control MapAxis(&Throttle, THR_FC, DX_SLIDER_AXIS, AXIS_NORMAL, MAP_ABSOLUTE); //****************************************************************** // LED Setup ActKey(PULSE+KEYON+LED(&Throttle, LED_INTENSITY, LEDLevel1)); // set Throttle LED back light intensity ActKey(PULSE+KEYON+LED(&Throttle, LED_ONOFF, LED_CURRENT-LED1)); // set LED 1 OFF ActKey(PULSE+KEYON+LED(&Throttle, LED_ONOFF, LED_CURRENT-LED2)); // set LED 2 OFF ActKey(PULSE+KEYON+LED(&Throttle, LED_ONOFF, LED_CURRENT-LED3)); // set LED 3 OFF ActKey(PULSE+KEYON+LED(&Throttle, LED_ONOFF, LED_CURRENT-LED4)); // set LED 4 OFF ActKey(PULSE+KEYON+LED(&Throttle, LED_ONOFF, LED_CURRENT-LED5)); // set LED 5 OFF //****************************************************************** // Throttle Controls // Coolie Switch (HAT) MapKeyIO(&Throttle, CSU, 0, DCS_ZoomInSlow); MapKeyIO(&Throttle, CSD, 0, DCS_ZoomOutSlow); MapKeyIO(&Throttle, CSL, 0, DCS_LabelsAll); MapKeyIO(&Throttle, CSR, 0, DCS_ZoomNormal); printf("----------------------------------\xa"); SetUpPilot(); // Configure Pilot specific mappings. (Default to Pilot config on startup) } // end main() int SetUpPilot() { printf("Setting up config for Pilot...\xa"); // LED1 on to indicate Pilot mode (LED2 off) ActKey(PULSE+KEYON+LED(&Throttle, LED_ONOFF, LED_CURRENT+LED1)); // set LED 1 ON ActKey(PULSE+KEYON+LED(&Throttle, LED_ONOFF, LED_CURRENT-LED2)); // set LED 2 OFF // Swap to RIO config when shifted Left Throttle Button pressed MapKeyIO(&Throttle, LTB, EXEC("SetUpRIO();"), 0); // Place all Pilot specific configs here // This can include all normal config commands like MapKey, MapAxis, etc // ... } int SetUpRIO() { printf("Setting up config for RIO...\xa"); // LED2 on to indicate RIO mode (LED1 off) ActKey(PULSE+KEYON+LED(&Throttle, LED_ONOFF, LED_CURRENT+LED2)); // set LED 2 ON ActKey(PULSE+KEYON+LED(&Throttle, LED_ONOFF, LED_CURRENT-LED1)); // set LED 1 OFF // Swap to Pilot config when shifted Left Throttle Button pressed MapKeyIO(&Throttle, LTB, EXEC("SetUpPilot();"), 0); // Place all RIO specific configs here // This can include all normal config commands like MapKey, MapAxis, etc // ... } //****************************************************************** int EventHandle(int type, alias o, int x) { DefaultMapping(&o, x); } //****************************************************************** The .ttm file: // Search for all TODO and resolve //****************************************************************** // // (Generic Blank Script File) - T.A.R.G.E.T. Macro File // //****************************************************************** // Notes about using this configuration // - See .tmc file for notes // // // //****************************************************************** // // History // MM/DD/YYYY Created - Michael Lohmeyer // TODO: Add date here // //****************************************************************** //****************************************************************** // TrackIR define TIR_Center R_CTL+APPS // Center TrackIR define TIR_Pause R_CTL+R_SHIFT+APPS // Pause TrackIR define TIR_Precision R_ALT+APPS // TrackIR Precision Mode define TIR_ProfileSmooth L_CTL+L_SHIFT+F1 // Select Smooth TrackIR Profie define TIR_ProfileFlatYawPitch L_CTL+L_SHIFT+F2 // Select FlatYawPitch TrackIR Profile //****************************************************************** // Warthog Throttle LED Settings define LEDLevelOff 0 // LED intensity off define LEDLevel1 50 // LED intensity level 1 define LEDLevel2 100 // LED intensity level 2 define LEDLevel3 150 // LED intensity level 3 define LEDLevel4 200 // LED intensity level 4 define LEDLevel5 255 // LED intensity level 5 //****************************************************************** // Standard DCS Functions define DCS_LabelsAll L_SHIFT+F10 // Toggle Labels all aircraft define DCS_ZoomInSlow USB[0x54] // Zoom in slow - Num* define DCS_ZoomOutSlow USB[0x55] // Zoom out slow - Num/ define DCS_ZoomNormal KPENT // Zoom set to normal //****************************************************************** //
  15. You can run new map commands anytime you want. Make a function call to map for pilot and one for RIO. Then use a button press or toggle switch to toggle between calling the two functions every time the button is pressed or the switch is flipped (use EXEC() to call the new mapping function). Each function can 100% remap everything as if you just ran a separate .TMC file. Of course, for those mappings that are the same for both pilot and RIO, map those the normal way just once in the main part of your .TMC.
  16. LeCuvier, thanks. Yes, if moving outside of the Thrustmaster realm, I completely understand and agree. I would like to transition to something like AutoHotKeys or Joystick Gremlin to solve that issue, or I might just create my own program to allow programming all game controllers, not just TM. Thanks for clarifying about LUA scripts. I've seen a lot of posts from people having nothing but frustration with game controller LUA scripts changing on them so I may have gotten the wrong impression. People have difficulty with TARGET too, but that is usually a matter of not taking the time to learn it - which I also don't blame people for that. It can be complicated. I am curious to know more about the TrackIR and TARGET issues you experienced.
  17. You can tell TARGET to only enable the axis you need. Since you don't have the rudder pedals connected to your throttle, just don't enable the rudder axis. You can map any T.16000 HOTAS axis to any DirectX axis using the MapAxis() command, or if you are using the TARGET GUI, there is a similar capability where you have to select the axis you want to use. In fact, in the TARGET scripting editor, if you don't enable it on purpose, the axis doesn't work. But in the GUI, you might have just enabled them all and not realized it.
  18. Here are links to the Thingiverse parts for those who have access to a 3D printer. Or you could send these to Shapeways or any other 3D printing company and get one made. Or I suggest just buy from Debolestis at his Shapeways store (https://www.shapeways.com/shops/debolestis). He made a variety of detent replacements for specific aircraft including ramped afterburner notches. I designed and printed my own for various purposes (not for DCS, but for Train Sim World - see here: https://forums.dovetailgames.com/threads/thurstmaster-target-script-for-warthog-throttle-saitek-tq-profile.3634/). Scroll down and you'll see a picture of the various parts I printed. I am pointing this out because the picture of the parts I printed shows just how rough they come out on a common "hobby" 3D printer (I have a MakerGear), and I had to adjust my 3D model to get accurate tolerances on my printer without having to shave and cut a lot on it. These printers are very accurate, but the plastic doesn't always cooperate, and on a small part like this, your results will not be as nice as you would hope. If you want something that is more smooth and much nicer finish, I strongly suggest buying one from Shapeways. I started with this one as a template: https://www.thingiverse.com/thing:1701150 But ended up designing my own completely from scratch. I don't remember if the one above worked, but it is designed to print vertically (as pictured) which actually is not the best way to get a smooth transition on the Afterburner ramp. I printed all mine laying horizontally so the direction of the laid plastic strands was the same direction of travel of the Warthog Throttle lever posts. That way the posts slide on a smooth surface (along the strands) and not over the ridges you get if you print vertically, where you would be pushing over the bumpy strands. You can print the above part horizontally as well. Here is the picture of the ones I did. Note the direction of the plastic strands. Also, these are full travel notches (they provide detents for a variety of lever positions across the entire travel of the Warthog throttle lever). The ramped Afterburner part I did is not pictured here. Here are two others in Thingiverse. I have not tried either of these. Ramped AB notch: https://www.thingiverse.com/thing:3163168 Original part: https://www.thingiverse.com/thing:3163743 A key point I'm getting at here is, if you use a push through AB notch, be aware that it can wear down the pegs that are stopped by the notch (they stick out from the left and right throttle levers down in the cavity where the AB notch goes). If you wear them down too much, repairing it requires replacing the entire lever handle, which is not cheap. So I made sure all my AB notches were as smooth as possible, including making sure the ramped AB notch I did was shallow and required minimal effort to overcome. I also use a _VERY_ small amount of grease on the AB notch ramp. I say very small because there is nothing to prevent the grease from migrating down into the electronics, so it should be a plastic compatible grease, and should just be a very thin smear on the AB notch. Grease is just very thick oil, and oil will eventually flow everywhere given the chance.
  19. The same is true with the Thrustmaster T.16000 Stick and Throttle. Sold together or separately, they are the same thing. You can also get the T.16000 with the rudder pedals as a set (stick, throttle, pedals). Exactly the same pedals as you can buy separately. The Warthog Throttle and Stick and the T.16000 Throttle and Stick all have their own USB connectors, so you can use all of them independently as well. This is different vs. the TM Cougar where the throttle plugged into the stick. Hence you could not use the throttle independent of the stick - and TM did not sell them separately because of this. I believe the pedals sold with the T.16000 are not USB. They are designed to plug into the T.16000 throttle via a RJ12 connector (same connector used for pedals sets for TM wheels), and the pedals just become 3 extra axis on the T.16000 throttle. But when bought alone, the pedals come with a RJ12 to USB adapter that allows the pedals to work via USB on their own. All of these devices are TARGET compatible, BTW, including using the RJ12 to USB adapter. So even devices that have their own USB cable can be combined in TARGET to work as a single device.
  20. I'm sure someone will say once again to stop suggesting TARGET for this, but I have to ask, if you are willing to edit LUA scripts in DCS (which can change with every release), why not instead just use TARGET, which doesn't change constantly, and works without changes over multipole minor as well as major DCS releases. I mean LUA and TARGET are both programming languages. I understand both well enough to use either, but I use TARGET for the simple reason that the DCS LUA scripts are not really intended to be edited by the end user, and hence often change radically, breaking your customizations - which is much of the complaint expressed in this forum topic. For TARGEt, yes, if you program one button in TARGET, all buttons disable instead of retaining their original DX button capability. Also, since TARGET combines controllers (if you do that), you can't assign all buttons on the stick and throttle because you run out of DX buttons. But there are solutions to these issues: 1) To keep everything defaulting to their original DX buttons using TARGET, set up a TARGET script to program only the throttle (because the Throttle has 3 way toggles and the stick does not - so "exclude" the stick). Assign the stick in DCS entirely using it's default DX buttons. Then edit the script for the Throttle so that it assigns all buttons/switches as their default Throttle DX button functions. You only have to create this script once and it works for all applications (not just DCS, but all games). Now for those rare cases where you need to make a minor change (e.g. make a 3 way switch work in all 3 positions) you can with minimal effort. Certainly less pain then editing a LUA script over and over due to DCS updates. 2) Or, to allow programming the stick and the throttle so that all buttons/switches have DX buttons, you have a problem. DirectX maxes out at 32 DX buttons and there are more than 32 buttons on the throttle and stick when combined. Or even with just the throttle alone, if you want DX button states for the center position of all Throttle 3 way switches, you run out of DX buttons. But there is a way you can change the TARGET target.tmh file to enable up to 128 DX buttons. It is not commonly known, but DirectX supports up to 128 buttons. See here: https://forums.eagle.ru/showthread.php?t=226594 This involves editing the target.tmh (and defines.tmh file I believe) which is not something you would normally edit. If a new release of TARGET comes out, you'll have to re-apply the target.tmh/defines.tmh edits again. But that is easy to do as TARGET doesn't change much with new releases, and changes these days are to enable new hardware (like the latest releasee just added the new TPR rudder pedals). So you can ignore the updates to TARGET for a long time with no detriment. You can't do that with DCS. Now, again, create a single script that assigns all stick and throttle buttons to DX buttons (there are examples in the above post I believe), and only edit that script for those rare cases where it matters. Or even better, make the script, by default, create DX button presses for the middle position for all 3 way toggles. Then you never have to edit the script. Just assign DX buttons in DCS. Now the issue still exists that you have to assign all those DX buttons in DCS, which is why I assume people are editing LUA scripts - to make it easier to make changes. So ya, no ideal solution here. But with the 128 DX button mod to TARGET, you don't have to use LUA scripting to handle the center position of the 3 way switches. You only edit the LUA scripts to assign DX buttons - a much easier edit, and much easier to transfer to new game controller LUA scripts in the future I assume. Personally, I never use DX button assignments. I use TARGET to program the buttons to press keyboard keys and I use all the default key bindings in DCS. This method takes no more effort to create in TARGET than it takes to edit DCS LUA scripts, but once done, my scripts which I created years ago still work today through multiple major and minor revisions of DCS. I'm still using my original KA-50 TARGET script, and even scripts from LOMAC and Flaming Cliffs for the A-10A and other pre-DCS aircraft which I created for the Cougar (TARGET supports the Cougar). I only had to make minor changes to re-map them to the Warthog Throttle when finally bought one, and the stick programming is the same between the Cougar and the Warthog stick. Sorry I can't offer any advice on LUA programming since I don't use it to solve these issues. But give TARGET consideration. The big advantage being once you create a TARGET script, it works, period, for years to come even if DCS completely changes the LUA scripts. And if you still absolutely hate TARGET, then use AutoHotKeys or Joystick Gremlin, two other programmable tools which can achieve the same result, but AHK or Joystick Gremlin support all game controllers, not just Thrustmaster products.
  21. To summarize, there are 3 things you need to make sure for the adapter. 1. The connector fits the G940 2. It is a 24 volts DC output (120VAC or 240VAC input depending on your country of course) 3. It is 1.75 amps or more. Here are a couple suggestions - the two listed below are actual Logitech power supplies. After looking at several cheaper options, I disqualified all of them because none of them would list the output as anything other than "DC". So I would just suggest buying one of the following, or look for someone selling these exact same parts on eBay in your country if you don't live in the USA. This one is an actual Logitech part for the Logitech G940 and various racing wheels. https://www.ebay.com/itm/Logitech-G25-G27-G29-G920-G940-Model-AD10110LF-P-N-534-00688-Power-Adapter-New/273185573820 Another Logitech Power Supply - same part as above. https://www.ebay.com/itm/GENUINE-LOGITECH-G25-G27-G29-G920-G940-AD10110LF-PN-534-00688-24V-1-75A-ADAPTER/263312394285 Alternatively. you can probably find something that will work if you have a surplus electronics store in your area. Take your G940 to the store and look for 24VDC (1.75A or higher) AC adapters, and try the cable on your G940. If the cable fits, you're done - buy it and go home. Or go to a regular retail electronics store and tell them this information (if Radio Shack was still around, that would be ideal), and you should find what you need. I hope this helps.
  22. Well, that'll do it. :( First, wiggle the AC power cord that attaches to the power brick to make sure it isn't a loose connection. If you have a multi-meter, check the output of the connector that goes to the G940. It should be about 24 volts DC. For a replacement, search eBay for "Logitech G940" and there are usually several people selling compatible power supplies. Make sure it is a 24 VDC 1.75 A output, or what ever matches the power supply you have now, and scrutinize the listing for details about why how or why they guarantee that it works for the G940. Seems these power supplies fit several Logitech devices, so they are very common on eBay. But its eBay, so read the listing carefully. Alternatively, if you have any other 24VDC power supplies with 1.75A or better output, try it. Maybe the connector will fit. Or at minimum, you can at least prove that it is the power supply and not the stick before you buy a new one.
  23. I assume you have plugged it into it's power adapter (no FFB without the power adapter) and installed the software, right? Sorry, just making sure. Also, are you gripping it fully by the handle? There is a light sensor on the side of the stick that is covered up when you grasp the stick, but if you let the stick go (uncover the sensor), then the stick will turn off the FFB motors for safety - hence the stick will just flop over. What version of the software are you running, and what Windows OS? Also, if you go into the Windows Game Controllers dialog and double click on the G940 Joystick it should bring up the dialog that shows all the stick's controls. Do they all work (all buttons and axis). On the "test" screen, when you push any button, it should cause the FFB motors to do something to the stick. Yes, it could just be that something failed on it, but you should go through the basics (check software, reinstall the drivers, etc.) to make sure it isn't a software issue. If not, click on settings and make sure Enable Force Feedback is checked. This dialog is similar to the check boxes in the main programming software (Logitech Profiler), but sometimes I have seen minor differences in the Windows dialog vs. the Logitech software. Or maybe this is where you already checked the FFB is enabled. If so, did you also check what the settings in the Logitech Profiler say? Sorry, probably not very helpful as I assume you checked all this.
  24. These questions are perhaps off topic and it might be better to start a new threat, but.... Yes, for AAR, just like for a helicopter or any time you want the most precise joystick control, any FFB stick will tend to be better than a sprung stick because they are so light and easy to move around the center point (no X or Y crossing notches which cause hesitation as you move the stick). So regarding the G940, the issues are not precision for movement (x/y pickup by the pots or hall effect sensors). The issues are lack of precision for the FFB which is a little frustrating when it comes to holding the stick with magnetic brake on a helicopter. But in AAR, you will have your hand on the stick constantly and sloppy FFB isn't an issue. For the POV, not sure which you one you mean. The lower POV hat is a 4 way button like most POV hats, and you can assign anything you want to it either in DCS, or in the Logitech Profiler software (v5.10.127 is the last version to support the G940). For the upper POV (called the mini-joystick), this is an analog X/Y mini-joystick. You can assign it to any DCS control that works with an analog axis (many DCS aircraft allow analog axis to control targeting cursors, etc.), or in the Logitech Profiler software, you can assign zones which will perform keyboard keypresses which turns the analog mini-joystick into a 4 way hat.
  25. What is the aar maneuver? Is that a recovery maneuver? I forget how the stick senses position (single hall effect sensor or separate pots or hall effect sensors - haven't had one apart for a while), but yes, all my G940 sticks track very well. I have 4 of them and no spiking or other tracking issues (for the stick X/Y). The other axis like the trim knobs use simple pots and the are noisy like any basic pot would be. Plus you have the reversal bug which really kills their usefulness. The issues I mention above about the approx 1mm play in the stick are purely related to how the stick's firmware drives the FFB motors, and due to a little bit of slop in the plastic gimbal mechanism. The firmware lets the stuck move a little bit before it starts to engage the motors enough to hold it steady. I fly helicopters mostly where I constantly use magnetic brake to hold the stick, and though the slop is a little annoying, I tend to pull the stick just slightly back further (opposite of the direction that gravity wants to pull the stick), tap magnetic brake, and let it go, and it holds the helicopter as intended. For jets or airplanes, this really isn't an issue as they don't require anywhere near the precision for holding the stick in a single spot as required for helicopters. So if aar means a "let the stick go and recover" mode, I assume the G940 will do that just fine. Similarly, for war birds, the FFB feel does everything you would expect it to - e.g. trim will move the stick as expected, staling will cause the stick to go limp, etc. But just like with a real airplane, you can't just triim the stick or yoke and expect the airplane to fly exactly straight all the time. The FFB doesn't hold the stick that perfectly. And I'll say again, make sure you update to the latest firmware, v1.42, as it both fixes the reversal bug as well as significantly improves the FFB feel. Not so jumpy or reactive to inputs after updating the firmware.
×
×
  • Create New...