Jump to content
The simFlight Network Forums

Paul Henty

Members
  • Posts

    1,724
  • Joined

  • Days Won

    77

Everything posted by Paul Henty

  1. Hi Johan, Attached is a new version with a non-typed Offset class. IOffset has been removed. The declaration is the same for Offset<T>, except that all constructors require the length to be specified. Instead of the strongly-typed Value property that Offset<T> has, you get and set the value via two methods: GetValue<T>() Gets the value from the offset, converting the raw bytes into type T. The only types allowed here are those allowed for Offset<T>. Note that if you want access to the raw byte array you can pass Byte[] as T. SetValue(object NewValue) Creates the raw bytes from whatever object is passed in. Again the types are limited to those allowed for Offset<T>. You can just pass a raw byte array if you need to. Writing works the same way as before; after calling SetValue() the offset will be in Write mode for the next process(). Below is some sample code showing two uses of the new class. private Offset avionics = new myOffset(0x2E80, 4); private Offset aircraftName = new Offset(0x3D00, 256); private void read_Click(object sender, EventArgs e) { FSUIPCConnection.Process(); this.checkBox1.Checked = (avionics.GetValue<int>() == 1); this.label1.Text = aircraftName.GetValue<string>(); } private void write_Click(object sender, EventArgs e) { avionics.SetValue(this.checkBox1.Checked ? 1 : 0); FSUIPCConnection.Process(); } I haven't 'sealed' the Offset class so if you need to store your own information about the offsets, or add your own methods, you can inherit it and make your own offset class. Paul
  2. Yes that is odd. I ran this code and seems it works as stated (one operand being a double is enough to force the other): public void test() { short myInt = 1715; double result1 = myInt / 256; double result2 = (double)myInt / 256; double result3 = myInt / 256.0; double result4 = myInt / 256d; double result5 = myInt / 256f; double result6 = divTest(); } public double divTest() { short myInt = 1715; return myInt / 256.0; } All the results are fine (6.69921875) except Result1 which is rounded to 6 because it's the only one where both operands are integers. Result3 and Result6 are the same as you were trying in your original code. Also, writing 256.0 is seen by the compiler as a double, not a single as I wrote in my last post. Paul
  3. Instead of splitting it out you can do the calculation in one line by casting the short to a double: public double FuelWeightPerGal { get { return (double)_fuelWeight.Value / 256d; } } Note also that in C# 256.0 is a float (Single) literal. Doubles need a 'd' at the end. Paul
  4. string val = offset.Get<string>(); Yes, I like that better; it's much cleaner. To do this properly the plain non-generic offset should be the base class to the generic offsets (so a replacement for IOffset). This will need a bit of refactoring work in the DLL, so I'll need a week or so to do this. Just giving you fair warning as it'll be a breaking change if you decide to continue down the IOffset route for now. Thanks, Paul
  5. return tempOffset.GetType().GetProperty("Value").GetGetMethod().Invoke(tempOffset, null); Ouch! Yes, I see the problem now. New version attached with public IOffset. Thanks for the explanation, it's always interesting to hear how people are using the DLL, especially if it's beyond the basic usage. Thinking more about your requirements, I could create a non-generics version of Offset and let you specify the address and length then just get the raw bytes back. I could put methods like GetInt32(), GetDouble() etc to convert the raw bytes to a proper type. A bit like the DataReader for database connections if you're familiar with that. Would that make it even easier for you? The generics are great for the normal usage where you know the offsets at design time, but I can see that they get in the way if you're creating offsets at runtime. Paul FSUIPCClient3.0_BETA.zip
  6. I've read up on this. There's a bit more to it if you have documentation and sample projects to go with the assembly. I would like to get those included in a Nuget package so I'm not going to have this done soon. I'll likely wait until the summer when I'll have time to properly release version 3 with updated docs and sample projects. Paul
  7. Hi Johan, Yes it's possible to make IOffset public. Before I do, I want to point out that the 'Value' property of IOffset is a generic 'object', so you'll likely have to cast the value if you want to do anything with it apart from ToString(). The data type can be accessed from a property on IOffset. I just want to check if that's okay for what you're doing, or will it just move the problem to elsewhere in the code? Paul
  8. Set the mixture lever for that engine to 0 (including Jets). e.g. to turn off engine 1 set 0x0890 (2 bytes) to 0. Paul
  9. Hi Hermann, I don't think there is such a flag, I certainly can't see anything in the FSUIPC offset list. The only suggestion I have is what you've already thought of: Read the aircraft name at 0x3D00 and check against a list of the built-in aircraft. Pete might have a better idea when he gets back. Paul
  10. Hi Hermann, For the 737NGX there are special offsets available, listed in the document called "Offset Mapping for PMDG 737NGX.pdf". This will be in the "modules\FSUIPC Document" folder. Looking in there I can see an offset for MCP_annunCMD_A (0x6545) and MCP_annunCMD_B (0x6547). Both are 1 byte. You'll need to check both to see if either is on. Be sure to read the top of this document as you need to edit some ini files to get these special offsets working. For other PMDG planes like the 777, I'm not sure if these offsets will work; I think probably not. There could be other ways of accessing the information such as Panel Variables (L:Vars) which you can access via a LUA plugin, but you would need to ask on PMDG forums. Paul
  11. Yes, that's a good idea. It doesn't seem too difficult to do. I'll look into it. Paul
  12. Hi Ruediger, Ready for testing. New DLL attached. Just overwrite your current DLL and XML files. The new methods added to FsLatLonPoint are: 1. For your request #1: FsLatLonPoint IntersectRadial(double Bearing, FsLatLonPoint Point, double Radial) Calculates the intersection from the current point along the Bearing to where it meets the Radial from the other Point. Check the IsValid property of the point returned to make sure it's valid. Invalid points are generated if the bearing and radial never intersect, or if the intersection is more than 200NM from the Point. This is an arbitrary limit but some limit must be placed or else some results could be hundred of thousands of miles away from the Point which doesn't make sense. I could increase the limit if required. Sample code: FsLatLonPoint myPlaneLocation = new FsLatLonPoint(); FsLatLonPoint vorLocation = new FsLatLonPoint(); double myBearing = 40; double vorRadial = 180; // find where the plane (flying bearing 040) will intersect radial 180 of the VOR: FsLatLonPoint intersection = myPlaneLocation.IntersectRadial(myBearing, vorLocation, vorRadial); if (intersection.IsValid) { // Do stuff with intersection } else { // No intersection possible, or intersection is more than 200NM from VOR } 2. For your request #2: FsLatLonPoint IntersectDMENauticalMiles(double Bearing, FsLatLonPoint Point, Double Distance) FsLatLonPoint IntersectDMEMetres(double Bearing, FsLatLonPoint Point, Double Distance) FsLatLonPoint IntersectDMEFeet(double Bearing, FsLatLonPoint Point, Double Distance) Calculates the intersection from the current point along the Bearing to where it is the specified Distance from the other Point. Check the IsValid property of the point returned to make sure it's valid. Invalid points are generated if the bearing never goes within the specified distance of the point. Sample code: (using the method for Metres) // find where the plane (flying bearing 040) will be 1km from the VOR: FsLatLonPoint intersection2 = myPlaneLocation.IntersectDMEMetres(myBearing, vorLocation, 1000); if (intersection2.IsValid) { // Do stuff with intersection } else { // No intersection possible. The bearing never comes within 1km of the VOR } Paul FSUIPCClient3.0_BETA.zip
  13. Hi Motus, I got most of this done last night, but thanks for the offer. Paul
  14. Hi Graham, Since Pete is away I can give you a few pointers. ipc.control(PMDGBaseVariable +CDUCstartVar+ 38, 1) This is a lua function to send a 'control' (aka 'event') to the flight sim. The flight sim will respond to whatever the control is meant to do, for example FSX has built in controls to turn on lights, operate the landing gear and loads more. These cannot be read like offsets they are just commands that perform actions. Some controls have a parameter if a value is needed. For example a control that toggles the parking brake does not require a parameter, but one that sets the autobrake to a certain position will. PMDG seem to use controls rather than LVars for allowing control of the aircraft (certainly the case for the 737NGX and it seems from what you've wrote that the 777 works this way as well). Developers can add their own custom controls over and above the built in ones for FSX/P3D and this is what PMDG have done. The list of built in controls is here: "modules\FSUIPC documents\List of FSX and P3D controls.pdf". The PMDG additional controls is found somewhere in their SDK, likely in a c header file (extension .h). Look for comments saying something like 'Control Events'. Here is the start of the relevant lines from the 737NGX header file: // Control Events #ifndef THIRD_PARTY_EVENT_ID_MIN #define THIRD_PARTY_EVENT_ID_MIN 0x00011000 // equals to 69632 #endif // CDU #define EVT_CDU_L_L1 (THIRD_PARTY_EVENT_ID_MIN + 534) #define EVT_CDU_L_L2 (THIRD_PARTY_EVENT_ID_MIN + 535) #define EVT_CDU_L_L3 (THIRD_PARTY_EVENT_ID_MIN + 536) #define EVT_CDU_L_L4 (THIRD_PARTY_EVENT_ID_MIN + 537) Here we can see they use a base control number of 69632 (defined as THIRD_PARTY_EVENT_ID_MIN) and then for the CDU they are adding an offset (+534 etc..) to get the final control number. The LiNDA code you posted seems to be doing something similar. They may have taken this directly from the 777 sdk header, or they may have their own way of calculating the end result. Either way you arrive at a control number that is sent. There seems to be the need to send a parameter as well as the LINDA code has ,1 on the end. This maybe explained in the SDK. I think for the 737 it signifies which mouse button to simulate. So, see if you can find the controls list in the .h file in the 777 SDK and send them in LUA code with ipc.control(). You can cross-reference the LINDA code to see that you're on the right lines or have any problems with the parameter values. Paul
  15. Hi Ruediger, Good suggestions. I'll have a look at this in the next few days, Paul
  16. I'm no expert in Lua but you might want to try using the events system rather than a tight loop that updates the offsets every 50ms. I've written the code below but I've no way of testing it. First you define a function to be called when the value of the LVar changes. This function just takes in the Lvar name and its value. All you need yo do is write the new value into the required offset. Then you register this function with the events system which will monitor the LVar value for you and call your function when it changes. writeN1(varname, value) ipc.writeUB(0x66C0, value) end event.Lvar("B200CFuelCrossfeed", 100, "writeN1") writeN2(varname, value) ipc.writeUB(0x66C1, value) end event.Lvar("B200CRvsNotReady", 100, "writeN2") writeN3(varname, value) ipc.writeUB(0x66C2, value) end event.Lvar("B200CLBld", 100, "writeN3") writeN4(varname, value) ipc.writeUB(0x66C3, value) end event.Lvar("B200CRBld", 100, "writeN4") You may find this has better performance than the continuous loop. Paul
  17. Hi Peter, Many years ago I used to work with VB6 professionally and I know the NWI/METAR facilities in FSUIPC as I have them working in my .NET DLL. If you like, I could look at your code and see if I can spot any errors and give you some guidance. You can PM me. Paul
  18. Hi Motus, Attached is version 3 beta of the DLL. Just overwrite your current DLL and XML file with the ones in the zip. There are different versions for the .NET 2 and .NET 4 framework. There are two new methods that might be useful to you... 1. FSUIPCConnection.SendControlToFs(ControlNumber, ParameterValue); This just sends the control immediately (no need for a Process() call). There are also overloads that take an Enum instead of the raw control number. For example: FSUIPCConnection.SendControlToFS(FsControl.PARKING_BRAKES, 0); will toggle the parking brake. A parameter is not required for this control so it's just set to 0. Enums available are: FsControl - the normal FSX/P3D list of controls FSUIPCControl - Additional controls added by FSUIPC FSUIPCAxesControl - Used to control axed assign directly in FSUIPC FSUIPCAutoPilotControl PMControl - Controls for Project Magenta software PMDG_737_NGX_Control - Controls defined in the PMDG 737 NGX SDK If there is no enum set for your aircraft you can just specify the integer value in decimal or hex. 2. FSUIPCConnection.SendKeyToFS(Key, Modifier, ReturnFocusToForm); This sends a key stroke to the FS window. The Modifier and ReturnFocusToForm are optional. e.g. This sends Control-L and return focus back to the application form: FSUIPCConnection.SendKeyToFS(Keys.L, SendModifierKeys.Control, this); This is also instant (no need to Process()). Both will also work over WideFS. Paul FSUIPCClient3.0_BETA.zip
  19. It depends on the aircraft; each will be different. If the developers provide control numbers (also called 'events') to turn the light on and off then you can use the DLL to send that control via offset 0x3110. To find out if there is such a control you can enable 'non axis event logging' in FSUIPC, operate the lights in the aircraft and see if anything is logged. If you run the flight sim in windowed mode you can make FSUIPC write the log to a console window in real time. If you can't see any events (controls) being logged, then you could send a key press if the lights respond to a certain key combination. If you want to try this you'll need version 3 of my DLL. Just ask and I'll give you some sample code and the new DLL. The only other way I know is via the panel L:VARS if they are provided by the author of the plane, but these are only accessible via a LUA plugin, not via the FSUIPC interface. Paul
  20. You don't need to program anything in the FSUIPC dialog. It's just an easy way of finding out your joystick and button numbers. As with the key presses, everything is set up by your C# application via the UserInputServices. Paul
  21. I'm not sure what you're trying to do with this. Do you want to detect joystick button presses in your C# application? If so, the UserInputServices deals with those too: This will detect button 1 of Joystick number 0 being pressed from Off to On. I'm pretty sure these joystick and button numbers will match up with those shown in the buttons assignment tab of FSUIPC. ui.AddJoystickButtonPress("Joy1", 0, 1, StateChange.Off_On); ui.ButtonPressed += new EventHandler<UserInputButtonEventArgs>(ui_ButtonPressed); The event hander: private void ui_ButtonPressed(object sender, UserInputButtonEventArgs e) { MessageBox.Show("Joytick Button Pressed " + e.ID); } If you're trying to do something else can you explain some more? Paul
  22. The easiest way would be to use the new beta version of the DLL as it has a feature to send controls directly to FS. I've attached it here. Just overwrite your current DLL and XML file with the new ones. To send a control call: FSUIPCConnection.SendControlToFs(ControlNumber, ParameterValue); This just sends the control immediately (no need for a Process() call). There are also overloads that take an Enum instead of the raw control number. For your request to reload the aircraft you would use: FSUIPCConnection.SendControlToFS(FsControl.RELOAD_USER_AIRCRAFT, 0); (A parameter is not required for this control so it's just set to 0). Enums available are: FsControl - the normal FSX/P3D list of controls FSUIPCControl - Additional controls added by FSUIPC FSUIPCAxesControl - Used to control axed assign directly in FSUIPC FSUIPCAutoPilotControl PMControl - Controls for Project Magenta software PMDG_737_NGX_Control - Controls defined in the PMDG 737 NGX SDK Paul FSUIPCClient3.0_BETA.zip
  23. I don't see any problems here with the shift modifier. Also tested under WideFS. Here is the code I used to add Shift-1, Ctrl-1 and Ctrl-Shift-1. All are detected as expected. ui.AddKeyPresss("Shift1", FSUIPC.ModifierKeys.Shift, Keys.D1, false); // Shift-1 ui.AddKeyPresss("Ctrl1", FSUIPC.ModifierKeys.Ctrl, Keys.D1, false); // Ctrl-1 ui.AddKeyPresss("CtrlShift1", FSUIPC.ModifierKeys.Shift | FSUIPC.ModifierKeys.Ctrl, Keys.D1, false); // Ctrl-Shift-1 The shift modifier value for this feature in FSUIPC is 1, not 4. I've rechecked all the values for the FSUIPC.ModifierKeys enum against the docs and they are correct. You don't really need to do this if you use 'false' as the last parameter when registering the key. This prevents the key from being passed onto FSX once FSUIPC has trapped it. You could try with a default aircraft loaded or try some other shift combination keys that are not numbers. Maybe one of your add-ons is getting to the shift-n keys first. Paul
  24. I wonder if Visual Studio hasn't recognised the latest DLL is new since it was built on the same day as the previous version. Can you try going to your bin\debug folder and deleting the FSUIPCClient.dll file. VS will then be forced to copy the new one in and use that. If that doesn't work, you could try removing the reference to the DLL and putting it back in. Otherwise I'll have a look tomorrow. Paul
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.