Jump to content

Drakoz

Members
  • Posts

    272
  • Joined

  • Last visited

Everything posted by Drakoz

  1. Not quite sure what you are asking - what is your goal? To replace the Warthog stick with the Cougar stick? Is this because you only have the FA-18C stick for your Warthog, but want to use the F16C style stick on the Cougar instead? The HOTAS Cougar Joystick (&HCougar) uses the same button names as the Warthog Joystick (&Joystick). The only exception is the Warthog stick has a pushbutton on Hat 4 (H4P) but the Cougar does not if I remember correctly. So if you replace &Joystick with &HCougar, your script should work with the same commands for the Cougar joystick. Is that what you mean? If you are translating Warthog with F18 stick to the Cougar, it is the same - same button names on the Cougar, except I believe the F18 stick has a couple more push buttons on Hat 2 and 3 (H2P and H3P) which are not on the Cougar. If you aren't using the Cougar Throttle, you don't even need to connect it, nor do you need to add any special commands for the Cougar Throttle. Or if you just want the Cougar Joystick and Throttle to work along with the Warthog Stick and Throttle, they work the same except for button/switch differences of course. You just need to add more commands for the Cougar. I hope this helps. If not, please explain what your goal is.
  2. The trim hat (or the top most hat) on the Warthog is the chosen DirectX "Hat" which means by definition, it is an 8-way hat whereas the other hats are treated as independent 4-way switches by default (4 independent switches instead of a treated as a hat). To turn the 8-way hat into 4 independent switches, you need program the up, down, left, right settings directly in your sim or use TARGET. So you need to program the hat positions not as a HAT in game, but as separate switch positions. If DCS can't do that (or do it the way you want), then you can use TARGET (either the TARGET GUI, or the TARGET Script editor) to do it. Using TARGET, if you program only the UP, DOWN, RIGHT, LEFT click positions, the 4 corner positions will not have any effect because they will be disabled. This is because when using TARGET, none of the buttons are configured as DirectX buttons by default. In fact none of them are configured period until you configure them. So the top hat on the Warthog is not configured as the DirectX hat by default.
  3. I was surprised the GUI does not support this feature since it is so useful. I checked and as Frederf said, it is not there. It is a simple thing to do with the TEMPO() command as Frederf said using the TARGET Script Editor, or once you create a profile using the GUI, you can View the Script, and edit the script file to add the TEMPO command. But that script must then be compiled and run in the Script Editor I believe. I don't use the GUI so I am unsure of that.
  4. Ya, I would continue to look at possible hardware issues. You also should contact Thrustmaster support. Then again, if this is only happening with the TARGET Device Analyzer, my experience with that program is that it is very buggy. I stopped using it, but your question prompted me to try it again. It is actually working OK. The issues I had were it would not close without crashing, and it wasn't able to correctly identify the game controller devices. But that problem has gone away. Anyway, I don't really trust that program to be reliable.
  5. An Exception is a pretty serious error, either due to corrupted software, or a hardware issue. Since it is a fresh install of Windows, that hopefully rules out corrupted software. It might be a piece of software is missing or you have an older version (like required dependencies such as Microsoft supplied libraries). Though a fresh install of Windows should have everything up to date. The fact that it happens sometimes and not others, and because you mention in the past you have reinstalled the software and it fixed things, but it keeps coming back - this is all indicative of an intermittent hardware issue like a USB port issue or maybe something wrong with your Cougar. Have you tried connecting the Cougar to different USB ports? Like direct on the motherboard back panel vs. a hub vs. a USB port on your PC case (which probably connects to your motherboard). Again, maybe you have a loose or intermittently bad USB connector? Do you have any other Thrustmaster devices to try this with? Or does this happen if there are no USB game controllers attached? I think the analyzer only works with Thrustmaster devices, but non-Thrustmaster devices might be affecting it. What other USB game controllers are attached? I have seen the Thrustmaster Device Analyzer have some difficulties and I never figured out why, but I wondered if it had trouble with non-Thrustmaster devices connected. The difficulties were UI issues and not quite running correctly, but never saw it crash.
  6. It looks like someone did a custom mounting plate, unless Wheel Stand Pro sells this plate. I have the setup pictured (the Deluxe V2 setup), with the standard plate. It would be a simple conversion to remove the large rectangular plate and make a plate that goes from the Wheel Stand Pro to the Warthog stick. It is just a question of whether anyone is selling it, or if you have the skills and tools to make one. You might even be able to drill the Wheel Stand Pro's existing top mount with a hole pattern that matches the Warthog stick base. In the picture, it looks like the Warthog is mounted directly to the stand's top mount. Where did the pictures come from? Was there any explanation?
  7. I know people have had issues with this over the years for various reasons. There are a few threads that discuss it in details so a search should find some solutions. I don't know the general solution as I haven't experienced it. What version of TARGET are you running? They just released a new version to support the TCA Boeing yoke and throttle quadrant. I haven't tried that version yet, but previous versions have been very stable for me. USB can sometimes be finicky and that might cause TARGET to crash. So maybe plug your devices into a different hub or different connectors on your PC. It isn't common that a script can lock up TARGET, even if you are doing custom C programming, but yes, please post your script. Normally script errors just cause the script to stop running. Locking up TARGET is usually more indicative of an overall software or hardware issue. Sometimes completely removing and reinstalling all Thrustmaster drivers (like your Warthog drivers) and TARGET can help, though in previous threads on this, many try that and still have issues - leading me to believe it is more specific to an individual computer. Hence why I comment on trying different USB ports or a different USB hub.
  8. Glad you found the issue. It might work to use a hot glue gun to glue the wire harness to the PCB connector. Put a dab along the top of the connector to hold them together. Don't let the glue get down inside the connector. Try to keep the glue just on the plastic parts. Thrustmaster has done that in the past for other products. This is a common issue with throttle devices (different brands and models over the years - like the Logitech G940 Throttle for example was notorious for this issue). Usually they are designed to have a specific wire routing that prevents the issue from happening, but sometimes in production, the wires get routed the wrong way. If you can find a way to route the wires that puts the least stress or pull on the wires, this will likely keep it working fine. The glue gun thing will help guarantee it, and hot glue can be removed later. Not permanent. Just don't get over zealous on the amount of glue.
  9. It may be the wire that goes from the throttle part to the base is getting pulled or stretched. Maybe the connector is loose. If out of warranty, I would start by opening it up and making sure all connectors are seated properly, and make sure the wire that moves as you move the throttle is routed correctly so that it doesn't get pulled or yanked. Not sure if that'll solve the problem, but it is where to start. Of course, if in warranty, contact Thrustmaster.
  10. My recommendation is get it repaired by TM or the guy you mentioned (or get a new board from TM), but if you want to dive into repairing it yourself, here is some info. For small devices like this part, the marking is not an actual part number, but instead a code. If you have searched for this marking and found nothing that is why. Usually they list the marking code in the PDF datasheet for the specific device (under the component marking section). Sadly, the internet search engines do not do a good job of searching PDF files for such obscure information. I did a quick search of some catalogs that list component marking like this, but did not find anything starting with NGW or even NG. Such catalogs are hit and miss. A longer search may yield results, but you'll need to spend time searching PDF files manually. How did the inspection conclude it was Q2? Sorry, but have to ask. Things are not always so simple to say one transistor is the problem, if it even is a transistor. These 3 pin SOT23 packages are used for everything from transistors to power supplies to simple "tiny logic" single gate logic devices. If I were to figure out what it is, I would start reverse engineering that area of the circuit to see what the part likely is - to help decide if it is a general purpose transistor, or something more specific (a special transistor, or something completely different). Understanding the circuit helps understand what kind of device it is, and how much it matters to find the exact replacement vs. something more generic. Chances are there are many generic parts that will perform the same function. For example, if Q2 is a transistor, it is probably acting as a switch (maybe turning on a power supply or enabling a circuit). You can tell this if the input voltage to the base (of a BJT) or the gate (of a FET) is either 0 or 3.3V or 5V (depending on the power supply used on the board). If this is true, you can probably get away with any general purpose BJT or FET, and not worry about an exact replacement. But make sure you know, is it a NPN or PNP (for BJT), or NMOS or PMOS (for a FET) and the right pinout - there is no standard pinout for a transistor. If the input voltage is not 0V or railed to the power supply, but is instead between 0V and the power supply, then it is being used, not as a switch, but as something more analog. In that case, you really need to find a matching part. This is unlikely though, because circuits like a joystick do not usually use an analog circuit like that. The variable analog part of a joystick/throttle is the signal coming from the pots or hall effect sensors. Everything else is likely digital or switched voltages using a transistor as a switch. Again, all that assumes it is a transistor. It could be a power supply or reference voltage. One pin goes to Vin (the input voltage) which would be the board power supply, one pin goes to ground, and one pin is the output (say taking 3.3V and convering it to 2.5V). You need to know what that output V is. If you figure out that is what it is, then there are lots of options that can replace it. An exact match is not required. This is all very technical and likely beyond most people, but if you have a basis of understanding of electronics, hopefully this helps.
  11. Mostly not. The Force 3D is a completely different FFB stick by software and hardware design. I think the gimbal is sort of similar to the G940, but not as sturdy. I don't know if it uses pots, or a hall effect sensor, but some of the cheaper Logitech FFB sticks do not use hall effect sensors.
  12. I was about to try Matric yesterday too, but my Android tablet is too old (it only runs Android 4.4.1, but Matric needs Android 5.x) and my other mobile devices are iOS (iPhone and iPad). Matric looks great. I hope you can consider creating an iOS version. Sadly, Roccat is dead for iOS, and perhaps dead in general as far as new development. It really surprises me there aren't several apps of this type. Or maybe the problem is there are far too many crappy ones so everybody gave up on them. I know I have looked for apps like this several times over the years, but it is difficult to weed out the bad ones from the ones that are worth spending your time (and money) on. Roccat was one of the good ones.
  13. Thanks for the post zappa! I have an Arturia Beatstep which has 17 encoder knobs and 16 pads (very similar to the keyboard pictured by zappa but no piano keys). It is relatively small and with software to convert MIDI to keyboard keys or axis info, it can be an excellent flight sim controller. They are cheap (about $100 new, or $60 on eBay) and you get a lot for that money. I mean 16 rotary encoders - I can't build a DIY 16 encoder box on my own for that price. I was planning to use the encoders to turn radio knobs primarily, but also light dimmers and other multi-position switches or trim wheels. There are several MIDI to keyboard software options, but none of the ones I looked at where turn key, or well done enough for prime time. FreePie is a great choice for those willing to do custom code. I was planning to write some custom software to do this eventually. Many MIDI controllers have RGB color LEDs on their pads, so I wanted to use data from DCS (via DCSBios) to also set pad LED color based on button states in the aircraft (e.g. the autopilot modes on the Blackshark). But like so many things, this is a long term project. So I'll try out the your FreePie script first. Thanks! https://www.arturia.com/products/hybrid-synths/beatstep/overview
  14. I remember reading that some people were able to remove a screw that was holding the cable down, or reroute the cable (???). But I actually haven't done it to my throttles (I have 2) since I use a Warthog Throttle. The key point is that the cable is too short, and if it gets routed poorly or held up, it will pull on the cable as you move the throttle lever back and forth, and pulling on the cable either chaffs the wires, or more likely causes them to break at the connector. If you can slacken the cable and/or prevent it from snagging and getting pulled tight, it should be fine. For more details, there are many topics discussing this issue on the Internet. Search on it and you should find lots of great info about the issue.
  15. No, as you probably assume, this is not normal. There is a known issue with the G940 Throttle where bad routing of a wire harness can result in disconnecting or breaking the wires. I think these wires go to some of the buttons or pots in the right throttle lever. This topic discusses the issue: https://forums.eagle.ru/showthread.php?p=1473835 Do a search, and you'll find many topics on this issue around the Internet. But the topic above has a link to the SimHQ.com forums which has a picture of the cable. The issue is common enough that everyone with a G940 Throttle should take their's apart and make sure the cable isn't being stressed because eventually it can break the wires.
  16. Sorry to hear the news. If it helps any, I have bought 4 sticks used off eBay and all of them work fine. Most of them were listed as untested, but that is often because people don't know how to deal with a FFB stick. My point being, you just had uncommon bad luck, so keep looking for a good deal, and you should be able to find another one, but one that works.
  17. Using a 0 to block (or set to nothing) a MapKey command for one profile to over ride the setting in the other profile should work. I just took your code and ran it and it worked fine. Since I didn't have your Macro files, I changed the Macros to quoted characters such as 'a' (and also commented out the View commands on the Throttle Hat), but that makes no difference. Below is the code I ran. I have no idea why it didn't work for you unless there is something special or weird about the macros you defined. Try my code below exactly as typed and see if it works. // ========================================================== include "target.tmh" //include "DCS_Default.ttm" //include "DCS_1.ttm" //include "DCS_2.ttm" int main() { // Configure exlude list Configure(&T16000,MODE_EXCLUDED); Configure(&T16000L,MODE_EXCLUDED); Configure(&TWCSThrottle,MODE_EXCLUDED); Configure(&HCougar,MODE_EXCLUDED); Configure(&LMFD,MODE_EXCLUDED); Configure(&RMFD,MODE_EXCLUDED); Configure(&TFRPRudder,MODE_EXCLUDED); Configure(&TFRPHARudder,MODE_EXCLUDED); //Configure(&Throttle,MODE_EXCLUDED); 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); //****************************************************************** // 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"); SetUpFA18(); // Configure FA18 specific mappings. (Default to FA18 config on startup) } // end main() int SetUpFA18() { printf("Setting up config for FA18...\xa"); // Swap to F16config when shifted Left Throttle Button pressed MapKey(&Throttle, LTB, EXEC("SetUpF16();")); // ... MapKey(&Joystick, H4U, 'a'); // a -letter MapKey(&Joystick, H3U, 'b'); // b -letter } int SetUpF16() { printf("Setting up config for F16...\xa"); // Swap to FA18 config when shifted Left Throttle Button pressed MapKey(&Throttle, LTB, EXEC("SetUpFA18();")); // Place all RIO specific configs here // This can include all normal config commands like MapKey, MapAxis, etc // ... MapKey(&Joystick, H4U, 'c'); // c -letter //MapKey(&Joystick, H3U, 'd'); // d -letter MapKey(&Joystick, H3U, 0); // if this zero is used instead of macro etc it blocks everything (weird) } //****************************************************************** int EventHandle(int type, alias o, int x) { DefaultMapping(&o, x); } //****************************************************************** Some further info: TARGET doesn't care if you map it to 'a' or 0, they are just numbers and it doesn't care what the number is. For example, 'a' is 97 (97 is the ASCII code for a lower case a). Well, yes, 0 is special in that a 0 does nothing (does not press a key because this is an ASCII NULL, or non-character), but it is all stored and handled the same way by MapKey() and TARGET. Perhaps more important to realize is, all mappings start out as 0, so if you remap something back to 0, you are just making it like it was when you first started. I believe the example you started from came from an earlier post on this thread. In fact, a lot of little details about your code are pulled directly from my own common DCS script template, but the profile swapping method used in your code was created by someone else (I forget who, but he is a regular here as well). My own profile swapping script has morphed into a much more complex example. If you are curious, check the link below. It is for Train Sim World, which I'm sure nobody here cares about, but half the reason I did my TSW script was to demonstrate some of the more advanced topics like profile swapping. There is a decent amount of documentation included with the download. It swaps between 28 different locomotives, using the THR_FC lever, or two buttons to swap profiles. It also has LED and audible feedback (beeps and verbal feedback) to let you know what profile you have chosen. https://forums.dovetailgames.com/threads/thurstmaster-target-script-for-warthog-throttle-saitek-tq-profile.3634/ In my script, I have a single function called CommonConfig() which sets all the common configuration for all profiles. Then I call a specific config function that sets up things specific to a single profile. This is because there is no way to call any of the configuration in main() a second time, so I moved most the original setup to CommonConfig(). When I change profiles, I always call CommonConfig() again to reset everything back to the common setup, and then call the custom function for the new selected profile. This helps provide some consistency and reduces possible conflicts. Not sure if any of that helps, except to say that what you did should work.
  18. Kraken, based on responses, I'm not convinced this is a sensor issue - at least I haven't heard a statement that confirms this. A failed sensor is very uncommon. So, perhaps to simplify the discussion, I need you to perform a specific test using the Windows Game Controllers dialog. This is the place where if you press a button, you should get the stick to perform demo movements like you mentioned. It doesn't happen with the Logitech Gaming Software. It occurs in the Logitech G940 Properties window found in the Windows Game Controllers control panel. So.... Connect the stick to USB on your computer and connect power. Just for consistency, make sure your computer is booted up to Windows. The order of these operations shouldn't matter. The stick should center when you connect it's power cable. Does it? I believe you said previously that it does. But just trying to make sure we are on the same page. Load the Windows Game Controllers control panel. On Win 10 (I know, you are running Win7), you should be able to press the Windows key, type "game controllers" (without the quotes), and it will give you the "Setup Game Controllers" control panel at the top of the list search list. Under Win7, I believe this still works the same, but if not, you'll need to find the Game Controllers control panel in the Windows 7 control panel. Anyway, run that control panel. You can get to the same control panel from the Logitech Profiler (Logitech Gaming Software) software. Load the Logitech Profiler software, click on Device, then Game Controllers... This loads the Windows Game Controllers control panel. But if you run the control panel this way, I want you to exit the Logitech Profiler, or make sure it isn't applying any profile to the stick. Otherwise it may conflict with the test below. To exit the profiler, you must close the window AND make sure it is no longer running on your task bar (it runs in the background, so check the taskbar). Maybe you know all the above, but I wanted to make sure you are in the Windows control panel, and not the Logitech software, and the Logitech software is not running. In the Control Panel, find the Logitech G940 Joystick in the list and double click on it. This brings up the Logitech G940 Joystick Properties. Now, if you move the HAT switch (the lower center hat), it should cause the stick to move to full lock in the direction you move the hat. Other buttons should cause other demo actions like vibration, or wild movements. Not all buttons perform a function. If it doesn't move, click on Settings in the dialog box and make sure "Enable Force Feedback" is selected and close the Settings dialog. You must close the dialog for the change to take effect. Now press the HAT, or Trigger or a few other buttons. Does it move (again with your hand wrapped around the sensor). If this does not work, then yes, there is something further wrong. BTW, it shouldn't matter, but in the Settings dialog, is "Enable Centering Spring in Force Feedback Games" is selected. Just curious. So if the above doesn't work, I would uninstall all the Logitech software, reboot, and reinstall it. I think you said you already did that. If not, do it now. If reinstalling the software fails, then (and only them) I might consider there is a hardware fault. So yes, maybe the previous owner disassembled it and forgot to connect the hand sensor again. But let's exhaust the possible software causes before tearing things apart. Sorry for the long (and perhaps obvious) suggestions. I'm just trying to be thorough. Let us know what you find. And regarding things like the inconsistent feel of the Y axis vs. X axis or Y forward vs Y backward, don't worry about that stuff right now. I own several G940's and they exhibit quite some variation on the feel of the gimbal. It isn't a very good gimbal, so it has some crunchy feel, and yes, the Y axis is the most inconsistent.
  19. Does the F-16 speed brake have a mappable axis in DCS? If so, you can also map a button to control a DirectX axis. That may give full control out and back in.
  20. It isn't the simple solution you are probably looking for, but this is how you do it: MapKey(&Joystick, S3, REXEC(1, 500, "ActKey(PULSE+KEYON+'a');") ); This will repeat the a key every 500ms and it will do it only for as long as you have the APENG button pressed. Other notes.... (for full clarity) Make sure the REXEC has a different handle for each instance you create. I mean, the REXEC(1, ...), that 1 should be different for each REXEC you use in your script. Because this is an REXEC (same for EXEC), you must use Actkey() to press a key. PULSE means the key will be pressed and released for the default time (25ms). KEYON is needed to press the 'a'. The 'a' is released automatically. If you did the above and added RNOSTOP as follows... MapKey (&Joystick, S3, REXEC(1, 500, "ActKey(PULSE+KEYON+'a');", RNOSTOP) ); ... then the A key would be pressed every 500ms continuously regardless of releasing the S3 button. It will continue until you issue a StopAutoRepeat command as follows... MapKey(&Joystick, S4, EXEC("StopAutoRepeat(1);") ); ...where the 1 would be replaced with the handle number of the REXEC you want to stop.
  21. Instead of putting a NULL in the file you write, just make sure to add the NULL to strings you read from the file. This shouldn't be needed in C, but in TARGET, I don't trust functions to handle NULLs correctly. More importantly, a text file is generally supposed to be human readable in a common text editor, and a NULL is considered a binary code. So if you write NULLs to a text file, you are breaking with convention of the file being a text file. Or worse, if you or someone edits the text file in a common text editor, there is a good chance the NULLs might unknowingly be removed, breaking your ability to correctly read the file from your script. Instead, depend on EOL (end of line such as CR, LF, or CR/LF) as this is the intended way to tell the end of a line. This is the other reason I used fputc and fgetc in my example. I wanted to play with controlling these characters exactly whereas I wasn't sure if fwrite and fread would give me that. You are further along than me on this since you have been playing with this stuff more, so not sure I'm offering much advice. Maybe some of the stuff you tried isn't working exactly right because of TARGET not being correct in its string handling. I think all the str...() functions add/delete and handle NULLs correctly, but maybe some of your strings didn't have NULLs added correctly in the first place which maybe cause issues with the some of the str...() functions. Or rather, I've seen the str... functions add NULLs, but maybe in some cases, they aren't adding NULLs because they expect a NULL to exist there already. In my experience, printf has always handled strings exactly as expected - meaning if no NULL, printf prints the entire buffer until it finds a random NULL. If the NULL is where I wanted it to be (because I added), printf has always printed the string correctly.
  22. Ha, calling you lazy. No in fact, I was actually being lazy because I didn't want to figure out fread(). So thanks for your example. ;) Regarding the NULL. Ah, now I get it what you were doing. Yes, the reason you get the garbage on your &myJson string when you print it is because there is no NULL character at the end of the string. In normal C, all string functions would add a NULL (a zero) to the end of the string and all such functions recognize the NULL as the end of the string even if the buffer or variable holding that string is longer. printf() is looking for that NULL so it knows when it should stop printing characters. So when you create a string like this: alias str1 = "This is my string"; everything works because TARGET seems to terminate the string with a NULL after the g in "string" (I believe) and hence str...() functions or printf() knows where the end of the string is. This is how C works normally. But for strings defined like this (which is not standard for C): char str2; Dim(&str2, 256); // create an array of char, 256 characters long, which really creates a string Now the string referenced by &str2, is 256 characters long, and there is no guarantee that the string will end in a NULL as the 256 bytes of memory is not cleared when created. What ever garbage was in memory when it was created is what you get. So in TARGET, because of this non-standard way of creating and handling strings, we have to add a NULL to the end of our strings manually. In my example, the line "buf[i+1] = 0;" is where I added the NULL, where i is the string length. I was able to do this because by using fgetc, I knew the length of my string because I counted every character in my file until I found a CR/LF character pair for the end of a line. In your case, you would do the same, but you would have to parse the line of text you read with fread() to find the end of line. And, in fact, this is why I was a bit "lazy" and did not try fread because I wasn't sure I would get the CR/LF using fread, or if fread would return the number of characters correctly. But your example shows that fread does return the string length, so it works after all. I should have known that I guess. Again, thanks for showing this. Hence, perhaps you should replace your line: strdel(&myJson, myResult-1, buf); with this line: myJson[myResult] = 0; Because the string is myResult long, myJson[myResult-1] is the last character in the string, so we place a NULL at myJson[myResult] and it terminates the string. I'm not saying this or any other method is the "correct" way to do it, but when it comes to strings, thinking of them as arrays of char helps a great deal with basic string manipulation. That is how all the str...() functions are working with these strings. What I don't know because I didn't test it is, I don't know if strdel() adds a NULL to the end of the valid string characters after deleting the characters. I assume it does because in fact, deleting characters off the right end of a string is actually accomplished not by actually deleting anything, but by adding a NULL character right after the character marked by myResult-1 in your example. Regarding strings and array of char In case you don't understand &str vs str[0], remember, a string is actually a single dimensional array of char. Say we have: alias str3 = "Hello"; This is the same as: char str4[] = {'H', 'e', 'l', 'l', 'o', 0} // NULL added to the end of the string Where a letter enclosed in ' ' is a single byte or a char, and str4[] is an array of char. &str3 refers to the entire string, and str3[0] is equal to H. In C (and I assume in TARGET), str[6] would be a NULL. But I haven't really tested this to confirm. Also, above, we can say &str3 and str3[0] as valid representations of str3, and we can also say str4[0] as well, but we cannot say &str4 because str4 is not an alias. Again, I'm shooting a little from the hip here. I haven't completely tested these things, so a couple details may be off (regular C programmers out there will probably tell me where I'm being an idiot). But my goal is to explain how strings work in TARGET because TARGET does not do strings the way C does them. And often, it is a royal pain in the behind. To understand this better, go read up on arrays and pointers in C and it might start to make more sense.
  23. Ya, I was thinking about that too. Dim() allocates memory, but I don't know if or how it deallocates that memory. I assume it does, just like it would deallocate a variable, because there are several examples of Dim() in target.tmh inside functions that get called over and over again. But I agree, if your variable is global, might as well allocate the memory with Dim() in main(), or before you call your file read function.
  24. Hmm, it works for me. Well, actually, you didn't define fp, so I had to add that. But even without it, I didn't get a crash. I just got a Runtime error, symbol not found: fp.... and the script continued to run. Anyway, here is the code I used - your same code, but I added int fp and a printf statement. I set this in main(): ActKey(KEYON+REXEC(20,5000,"fnsReadStatusJson();",RNOSTOP)); Then I copied and pasted your function into a script of mine, added the char myJson; and alias for the file name, and added int fp;. So this is your code. I didn't do anything that should have changed it other than the int fp;. char myJson; alias StatusFile = "Myfile.cfg"; int fnsReadStatusJson() { int buf = 512; int myResult; int fp; Dim(&myJson, buf); myJson[0] = 0; fp = fopen(&StatusFile, "r"); if (fp) { myResult = fread(&myJson, 1, buf, fp); fclose(fp); if (myResult == 0) { printf("File Read Error: %s\x0a", &StatusFile); } else { strdel(&myJson, myResult-1, buf); // <<< having to do this this is annoying } } else { printf("Status.json file not found.\x0a"); } printf("fnsReadStatusJson: %s\xa", &myJson); } The file I read contains the following text (a single line of text with a CR/LF at the end of the line). pro_ProfileSelection=26 This is a file I am reading with my own function very similar to yours, so I just replaced my function with yours and called it with the REXEC() in main() as explained above. What are the contents of your json file? Maybe it is something in the file you are reading. Or some other issue.... Does that other program have the file open at the same time you run the TARGET Script? ====================== It is funny my own function to read a configuration file is very similar to yours. Right down to the part where we both figured out we have to add a NULL to the char[0] element of our alias (buf[0]=0 in my version). But I ended up using fgetc(fp) instead of fread() - mostly because I wanted to try character IO on a file instead of taking the easy way out of using fread(). :D But I notice you don't add a NULL to the end of &myJson after you read the line from your file. I assume this somehow doesn't matter for your script? If I remember correctly, I had to add a NULL to the end of &buf because the string functions wouldn't work with it otherwise. See the buf[i+1] = 0 line. pro_ProfileSelection and pro_ProfileChanged are globals. Everything else are local variables in my function. Anyway, my function below also worked in an REXEC except every now and then, it would print this error. No lockup, just the error, and the script would continue running: Compile error in Eval: Syntax error: 26e, in "26e" I assume this is an issue with using fgetc() perhaps failing??? It never happens when I run the routine by itself (not in an REXEC). So maybe there are some unpredictable results from doing file IO in an REXEC. Here is my config file read routine: //****************************************************************** // ConfigFileRead() // Read the configuration file to set parameters saved from the last time the script was run. // For now, this only means the selected profile (e.g. file should contain "pro_ProfileSelection=XX" where XX is the profile number). // The config filename is set by the ConfigFile define below. This file is expected to be in the TARGET Scripts folder. define ConfigFile "Drakoz_TrainSimWorld_Config.cfg" int ConfigFileRead() { int fp, i, p, bufe; char buf; Dim(&buf, 256); // buffer used to store the line read from the config file char parm; Dim(&parm, 256); // buffer used to hold the parameters (name or value) read from the config file buf[0]=0; // Make sure buf has a null to terminate the string fp = fopen(ConfigFile, "r"); if (fp) { i = 0; while (1) { p = fgetc(fp); // read a char if ((p==0xD) | (p==0xA) | (p==-1)) break; // if char is CR, LF, or EOF exit buf[i] = p; // add char to buffer i = i + 1; if (i>254) break; // just in case the text from file exceeds our buffer size } buf[i+1] = 0; // place a null at end of buffer to terminate the string fclose(fp); } bufe = strchr(&buf, '='); // find the = in the line (e.g. pro_ProfileSelection=12) if (bufe > 0) { strsub(&parm, &buf, 0, bufe-1); // get the parameter name (e.g. pro_ProfileSelection) if (strcmp(&parm, "pro_ProfileSelection") == 0) { // if paramater name = pro_ProfileSelection... strsub(&parm, &buf, bufe+1, strlen(&buf)-1); // find the parameter value (e.g. 12) p = ieval(&parm); // convert parameter value from text to integer if ((p > 0) & (p <= pro_NumOfProfiles)) { // if parameter value between 0 and max number of profiles... pro_ProfileSelection = p; // set new profile pro_ProfileChanged = 1; // Set profile has changed so we will speak the profile name later. } } } printf("ConfigFileRead: %d\xa", pro_ProfileSelection); }
×
×
  • Create New...