Jump to content
The simFlight Network Forums

Recommended Posts

Posted
Hope this is the right place to post this, sorry if it isn't.

 

I'm trying to create a program that will remove AI traffic that isn't going to or departing a particular airport to save on FPS. I've never coded anything for FS for at all, so apologies if some of my questions seem daft.

 

I've managed to succesfully write an "empty" program that simply connects and disconnects from FSUIPC, so far so good. Now the part where I'm completely lost is in figuring out how to then access the AI details- whats the simplest way to access the list of current AI traffic. The SDK mentions the offset area from D000-FFF contains AI information- I understand the premise of the memory offsets and the hexadecimal notation, but I think I'm misunderstanding what they are for; for example, what is the "base" address they are offset from, or is there a simpler sort of get method which will let me not have to worry about the exact memory addresses? Basically, in my C++ code, what do I need to do to get a list/table/array of pointers to all AI traffic being processed by the sim at a given time? From there, the SDK seems to be pretty straightforward about how to interact with an individual aircraft once I have the pointer to it, but I'm confused as how I get to that part.

 

Second, once I identify the aircraft I plan on removing, I wanted to use the traffic zapper in FSUIPC, and I can't find any documentation about this. Does the traffic zapper work as some kind of "at will" traffic remover, or have I misunderstood? How do I call it and how do I specify which AI to use it on?

 

thanks

Posted
I understand the premise of the memory offsets and the hexadecimal notation, but I think I'm misunderstanding what they are for; for example, what is the "base" address they are offset from, or is there a simpler sort of get method which will let me not have to worry about the exact memory addresses?

 

There term "offset" is really historical. Originally the FS6IPC interface from which FSUIPC was a development provided access directly into an FS98 module called "GLOBALS.DLL" which conveniently collected all of the FS data you might want to access into one contiguous memory area. The interface allowed any of the bytes, words, etc, in this area to be read or written by reference to its offset, in bytes, from the start of the area.

 

These days, with FS data encapsulated inside separate C++ objects and hardly ever directly accessible, the Offsets have really become just "tokens" for the data they purport to contain. It's complex code in FSUIPC which interprets these tokens and reads or writes the data in whatever way is appropriate and possible. This may, for instance, be by actually calling procedures within FS, or hooking some transactions, or even sending requests and waiting for answers. To continue giving the illusion of a fully synchronous interface, FSUIPC does actually automatically obtain all the information regularly and keeps it in its own "Offset" data area. This enables it to satisfy most read requests immediately (exceptions include weather requests for a specific WX station or location, as there are so many, and similarly specific lengthy data about AI traffic). But writes always invoke some code to do something.

 

So, forget "memory addresses". Use offset values as tokens.

 

Basically, in my C++ code, what do I need to do to get a list/table/array of pointers to all AI traffic being processed by the sim at a given time?

 

No pointers. Your data in your memory. Just read the whole array(s) into your own C++ defined structure. For Ground traffic that's 3840 bytes at offset E080 (96 entries of 40 bytes) plus, if needed, the 1920 bytes at D040. Then separate arrays for the airborne traffic. Bear in mind that FSUIPC only supplies details for the nearest 96 airborne and 96 ground aircraft  If you need all AI you'd have to resort to SimConnect (for FSX).

 

 

Second, once I identify the aircraft I plan on removing, I wanted to use the traffic zapper in FSUIPC, and I can't find any documentation about this. Does the traffic zapper work as some kind of "at will" traffic remover, or have I misunderstood? How do I call it and how do I specify which AI to use it on?

 

You misunderstand. The Traffic Zapper added control in FSUIPC is simply an implementation of using the AI deletion facility in the SDK to delete aircraft by user request. The aircraft is deletes is chosen based on range, direction and so on. It is fully documented along with the parameters for it in the FSUIPC documentation (user & advanced guides), not the SDK. It is not something you'd use from a program to delete aircraft of your choice (unless you move the user aircraft to face the aircraft to be deleted and make sure it is in range!!)

 

The deletion facility in the SDK is documented against offset 2900.

 

Regards

Pete
Posted (edited)

Thanks for the help- I've now gotten the program to look through all of the AI aircraft being handled and then put the Object ID's of the ones I want to delete into a list. How should I use these IDs to remove the aircraft? The simconnect SDK talks about how to delete traffic that your program has added, but not ones that are added by traffic files. Does FSUIPC povide a handy deletion function? Maybe the simplest way would just be to remove the aircraft from AI control and then teleport it to the south pole or something like that?

 

EDIT: I just tried using simconnect to teleport the AI aircraft to the south pole, which works correctly, but many of them are still being kept track of by the sim even when they are outside of the bubble, so that's out.

Edited by andqui
Posted

How should I use these IDs to remove the aircraft? The simconnect SDK talks about how to delete traffic that your program has added, but not ones that are added by traffic files. Does FSUIPC povide a handy deletion function?

 

Yes, of course it does. That's why I pointed you to offset 2900. Did you not look it up? You can send assorted commands to it, and also delete it. It's written up in black and white.

 

Regards

Pete

Posted

My apologies, I misunderstood what you wrote, I thought that pertained to the zapper.

 

Anyways, I have my DWORD object id. The way I understand it, 0x2900 for 4 bytes long is the where to enter this ID, and 0x2904 for 4 bytes long is where to enter 65535 for the delete command, correct? What I've tried is this:

 

FSUIPC_Write(0x2900, 4, WHATGOESHERE, &writeResult) to write the object ID into 2900

and

FSUIPC_Write(0x2904, 4, WHATGOESHERE, &writeResult) to write the command for that object,

 

and then in the if under those two booleans is FSUIPC_Process to execute it. As you can see, I'm confused as to what goes in the command parameter, and I've tried casting the DWORD and the int as various things to get it to compile without seeing an effect in the sim.

 

To sum it up, what do I replace "WHATGOESHERE" in the above lines with in order to enter 1. the DWORD object ID and 2. the 65535 delete command. Better yet, is there a way to combine the two into one write command? Thanks for your patience, my programming skills are amateur-level and this is all very new.

Posted

My apologies, I misunderstood what you wrote, I thought that pertained to the zapper.

 

Anyways, I have my DWORD object id. The way I understand it, 0x2900 for 4 bytes long is the where to enter this ID, and 0x2904 for 4 bytes long is where to enter 65535 for the delete command, correct? What I've tried is this:

 

FSUIPC_Write(0x2900, 4, WHATGOESHERE, &writeResult) to write the object ID into 2900

and

FSUIPC_Write(0x2904, 4, WHATGOESHERE, &writeResult) to write the command for that object,

 

and then in the if under those two booleans is FSUIPC_Process to execute it. As you can see, I'm confused as to what goes in the command parameter, and I've tried casting the DWORD and the int as various things to get it to compile without seeing an effect in the sim.

 

To sum it up, what do I replace "WHATGOESHERE" in the above lines with in order to enter 1. the DWORD object ID and 2. the 65535 delete command. Better yet, is there a way to combine the two into one write command? Thanks for your patience, my programming skills are amateur-level and this is all very new.

 

Oh dear, I shouldn't need to repeat the documentation here. :-(

 

Offset 2900 is 12 bytes long, exactly as documented. It is a structure (or an array) of 3 4-byte values (DWORDs will do), and should be written as one entity of 12 bytes.

 

As for "WHATGOESHERE", do you not see that the FSUIPC_Write command has a BYTE pointer in that position? You simply need to put a pointer to the structure there, and cast it as (BYTE *).

 

If you are managing to read the AI data I would have thought that you'd already discovered you had to point to where you want the data read into. The write is no different, you point to where you want it written out from. They are exactly alike, it is only the direction of travel which changes!

 

For example using arrays:

 

DWORD dwCmd[3];

...

dwCmd[0] = id;

dwCmd[1] = 0xFFFF;

dwCmd[2] = 0;

FSUIPC_Write(0x2900, 12, (BYTE *) dwCmd, &writeResult);

...

 

The command will be sent on the next Process call.

 

If you are new to programming I suspect C/C++ is rather like jumping in the deep end. Did you not consider something simpler first?

 

Regards

Pete

Posted (edited)
I was looking things up and stumbled upon this old thread, which probably confused me, with regards to the 12-byte length.


But I stand corrected.

 

I wouldn't say I'm new to programming, but the only programs I've written are for my own use and for parsing/dealing with large amounts of data only really using the standard c++/java libraries/functions/methods. I'm quite proficient when it comes to things I already understand but learning new stuff is challenging, as you probably have already noticed ;) And I didn't start with something simpler because I couldn't find anyone interested in writing this for me; I'm trying to write a program that takes in a "focus" ICAO and then deletes all AI traffic that isn't going to or leaving that airport, to maintain 100% traffic density at the focus airport and save FPS in really busy areas by removing "irrelevant" AI. I've been able to grab all the AI details with simconnect, and then this is the code I have once I've decided that a particular AI aircraft is irrelevant and needs to go:

 

DWORD FsuipcResult;

if (FSUIPC_Open(SIM_FSX,&FsuipcResult))

{

cout << "\nFSUIPC connected to Flight Simulator!";

}

else

{

cout << "\nFSUIPC NOT connected to Flight Simulator!";

}

printf("\nObjectID=%d  registration=\"%s\ from=\"%s\ to=\"%s\"", ObjectID, pS->registration, pS->from, pS->to);

 

//delete aircraft

DWORD writeResult;

DWORD dwCmd[3];

dwCmd[0]=ObjectID;

dwCmd[1]=0xFFFF;

dwCmd[2]=0;

 

if(FSUIPC_Write(0x2900, 12, (BYTE*) dwCmd, &writeResult))

{

cout << "\nWrite succesful";

}

else

{

cout << "\nWrite unsuccesful";

}

if(FSUIPC_Process(&writeResult))

{

cout << "\nProcess succesful";

}

else

{

cout << "\nProcess unsuccessful";

}

FSUIPC_Close();

 

The program is picking out the right traffic to delete- the line where I print out ID/tail#/from/to fires for each target aircraft is working correctly and fires for each of the "bad" aircraft I see in the traffic toolbox. I get the FSUIPC is connected message for each of these aircraft (its probably unnecessary opening/closing over and over, but early on can't hurt until I confirm things are working), and the &FsuipcResult DWORD is 0, so FSUIPC is connecting OK each time. Then, I get the "write successful" and "process successful" messages each time, and the writeResult DWORD is 0 as well, so the command is being written and processed correctly for each aircraft. The only problem is that nothing happens in the sim- in the traffic toolbox explorer, each of the target AI aircraft that I know the program is correctly identifying keeps on going as if nothing happened, which seems likely, so one of the inputs is wrong somewhere.

 

Maybe the ID's that I have are wrong or in the wrong format? In the traffic explorer, the container ID's are listed as hex values, whereas DWORD is an unsigned int, correct? Is there a hex conversion I need to perform to pass in as the input ID?

 

thanks again for the help

Edited by andqui
Posted
I was looking things up and stumbled upon this old thread, which probably confused me, with regards to the 12-byte length.

 

Yes, but the important part there is this:

 

"FSUIPC takes action

when it sees the ID being written, so make sure the other bits are either

written at the same time (same FSUIPC Write), or beforehand."

 

You had them in the wrong order in any case. Really, when using something like C/C++, which is so good with arrays and structures it would be daft to be less efficient than you can be. One call to FSUIPC_Write is all that's neded for a structure or array.

 

I've been able to grab all the AI details with simconnect

 

If you are using SimConnect to read AI details, why not use it to delete them too?

 

SimConnect's AI ID codes are not the same as those used in FSUIPC. The ID FSUIPC needs it the one from its AI arrays. I think one is the negative of the other, but I'm not certain without delving into code which I've not got time to do at present.

 

The program is picking out the right traffic to delete- the line where I print out ID/tail#/from/to fires for each target aircraft is working correctly and fires for each of the "bad" aircraft I see in the traffic toolbox. I get the FSUIPC is connected message for each of these aircraft (its probably unnecessary opening/closing over and over, but early on can't hurt until I confirm things are working),

 

Not just opening and closing, but also Process. You should build up a block of Write requests and do one Process. It is extremely inefficient otherwise as you are cauing process switching each time, as well as an excess of messges being queued.
 
Maybe the ID's that I have are wrong or in the wrong format? In the traffic explorer, the container ID's are listed as hex values, whereas DWORD is an unsigned int, correct?

 

You've not been programming long, then? How numbers are represented, whether in binary (1010), hex (A) or decimal (10) or even octal (12) makes absolutely no difference -- in the computer they are all binary.

Binary 1010 = hex A = decimal 10 = octal 12. This is a fundamental thing to understand in any programming! You provide whatever representation is easiest to use or understand, depending on the circumstance and how you feel at the time.

 

Use my TrafficLook program to compare the IDs you are seeing with the IDs FSUIPC would supply.

 

Also bear in mind that FSUIPC only handles the nearest 96 ground and 96 airborne traffic, so probably many of those you get from SimConnect may not in fact be known to FSUIPC.  Whether the correctly transformed ID will still work for deletion through FSUIPC I really don't know. I've never mixed things.

 

Pete

Posted

If you are using SimConnect to read AI details, why not use it to delete them too?

 

SimConnect's AI ID codes are not the same as those used in FSUIPC. The ID FSUIPC needs it the one from its AI arrays. I think one is the negative of the other, but I'm not certain without delving into code which I've not got time to do at present.

 

That would probably explain it, then. The hex conversion was a stretch, I agree.

 

As to deleting with simconnect, there's this:

http://www.fsdeveloper.com/wiki/index.php?title=Traffic_-_SimConnect_-_Removal_of

Which says that unless you're an embedded DLL or module within FSX (mine is a standalone exe), you need to go via FSUIPC, which is what led me to ask here.

 

There's also this,

http://msdn.microsoft.com/en-us/library/cc526983.aspx#SimConnect_AIRemoveObject,

which only applies to traffic you've added through code, not traffic present in bgl's (I tried).

 

I used simconnect to get the aircraft because of the 200 km radius and the unlimited # of aircraft, which matches what I'm trying to do to delete them to improve performance. Anyways, I'll give transforming the ID a try, and if it doesn't work I'll focus on trying to slew them out of range, unless you think there's a better way to do it. Thanks for your time.

Posted

I used simconnect to get the aircraft because of the 200 km radius and the unlimited # of aircraft, which matches what I'm trying to do to delete them to improve performance.

 

Of course, anything further away than around 10 nm doesn't get displayed and is only processed an infrequent intervals, so I don't think you'll notice any difference really. It's the imaging which really hits performance. Those not in the immediate vcinity only get a max 4 fps also.

 

Anyways, I'll give transforming the ID a try

 

It'll either be the negative (i.e. -id) or that plus or minus 1. TrafficLook can show the IDs I'm seeing, for comparison.

 

Pete

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • 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.