Jump to content
The simFlight Network Forums

Recommended Posts

Posted

Hi,

Well, now that I finally managed to get reading offsets in my think skull, I have to say that it is actually remarkably quick and easy, well done Pete and everyone else working on WideFS / FSUIPC :D

I have to agree with Pete though, there are in some cases, some REALLY strange things with VB.NET (my Language of choice), but learning a new language now, is not something that I'm up to... Who knows, maybe next year...

Anways, I'm trying to write to a offset now. I've choosen a VERY simple one to start off with (0262 - Pause Control). According to the docs, write 1 to Pause, 0 to Resume. Ok. I figured, that's easy enough....

To do this, I've used just about the same code as I use to read offsets (which, is working relatively well), and simply removed my _get, andchanged the _read to _write - ok, a bit more tweaking more than likely, but this is what I have right now:

    Public Function FSUIPC_0262(ByVal PauseGame As Boolean) As Boolean
        Dim dwOffset As Integer = &H262    ' We want to write to 0262
        Dim dwSize As Integer = 2              ' Which, is 2 Bytes
        Dim dwToken As Integer = 0
        Dim dwResult As Integer = 0

        ' Open a link to FSUIPC.
        ' BTW - Pete, is it better to open a connection and leave it open
        ' or to open / close to FSUIPC at every call?
        If myFSUIPC.FSUIPC_Open(7, dwResult) Then
            ' For the faint hearted and if there is ever something wrong with
            ' Pete's code, let's do Exception Handling.
            Try
                ' Here, we are trying to write to FSUIPC. Because 0262 expects
                ' a Integer and not a Boolean, we do some magic here.
                If PauseGame = True Then
                    ' We want to Pause the Simulator, write 1 to 0262.
                    myFSUIPC.FSUIPC_Write(dwOffset, 1, dwToken, dwResult)
                Else
                    ' Otherwise, Resume the Similator, write 0 to 0262
                    myFSUIPC.FSUIPC_Write(dwOffset, 0, dwToken, dwResult)
                End If
            Catch e As Exception
                ' TODO: Exception Handling (dwResult)
            Finally
                ' After all the writing, let's process it.
                myFSUIPC.FSUIPC_Process(dwResult)
            End Try

            ' Close up the Connection
            myFSUIPC.FSUIPC_Close()
        Else
            ' Connection to Simulator Failed
        End If
    End Function

Lots of comments added, to let Pete understand what's going on :D

The end result, is that the simulator is not paused when called as

FSUIPC_0262(True)

dwResult returns 0 at both the Write call, as well as the Process call as well. So it definately is being written, and it is being processed - without errors. But alas, the Sim just won't pause?

Thanks,

Chris.

Posted

Pete, is it better to open a connection and leave it open

or to open / close to FSUIPC at every call?

Open when your program starts, Close when it ends. It is really really really inefficient to open/close all the time. It is using memory mapped files and atoms. Each time you open Windows is asked to supply unique atom numbers for uniques strings and to open a file in memory. Each time you close, those things are closed and freed.

Think of Opening and Closing files on disk. If you wanted to read/write a single data file a lot of times, you wouldn't dream of opening it and closing it every time, would you? This is why the terms "Open" and "Close" are used. They are just as heavy.

The Reads/Writes are merely data shuffling in your own program, very very light on processor and resources. You pile as many reads and writes together as you need and as will fit into the memory file size (no bigger than a total of 30k though).

The Process call is a Message being sent from your program to the FS process. This needs a process switch to FS, then, when the response comes back, a process switch back to your program. So this is a lot heavier than Read/Write calls, but nothing like Open/Close.

Here, we are trying to write to FSUIPC. Because 0262 expects

a Integer and not a Boolean, we do some magic here.

As far as FSUIPC is concerned (and Windows and C/C++ for that matter), a Boolean is an integer -- a non-zero integer is TRUE and a zero one is FALSE. The BOOLEAN type is only there to look pretty and to make code more understandable.

We want to Pause the Simulator, write 1 to 0262.

myFSUIPC.FSUIPC_Write(dwOffset, 1, dwToken, dwResult)

...

Otherwise, Resume the Similator, write 0 to 0262

myFSUIPC.FSUIPC_Write(dwOffset, 0, dwToken, dwResult)

Hmmm. Doesn't make sense to me. My questions:

1. Is the order switched around in this VB>NET interface? It is most confusing. The original C/C++ interface was defined with:

extern BOOL FSUIPC_Read(DWORD dwOffset, DWORD dwSize, void *pDest, DWORD *pdwResult);
extern BOOL FSUIPC_Write(DWORD dwOffset, DWORD dwSize, void *pSrce, DWORD *pdwResult);

where you will see that the 2nd parameter is the SIZE of the read/write (in bytes). You have 1 or 0 there instead of the length?

2. I still don't understand this "token" thing, which you define as 0. What is that for?

3. You define the size for the writes as 2 but don't use it anywhere (doesn't the VB compiler tell you about unused variables?). How do the Read/Write routines (which are in YOUR code, they are part of what YOU can see and deal with!) know how many bytes to use?

As an example of what the C version would look like here:

FSUIPC_Write(0x0262, 2, PauseGame, &dwResult);

That's it. You wouldn't even really need a function/procedure for that! Your version is complicated and, to me, very confusing. I don't know VB or VB.NET, but surely you do need to give the size someplace?

So it definately is being written, and it is being processed - without errors. But alas, the Sim just won't pause?

I doubt if it is doing anything much. What does the FSUIPC Log say? Surely you ARE using the Log to check these things? Just enable IPC read/write logging.

Regards,

Pete

Posted

1. Is the order switched around in this VB>NET interface? It is most confusing. The original C/C++ interface was defined with:

extern BOOL FSUIPC_Read(DWORD dwOffset, DWORD dwSize, void *pDest, DWORD *pdwResult);
extern BOOL FSUIPC_Write(DWORD dwOffset, DWORD dwSize, void *pSrce, DWORD *pdwResult);

where you will see that the 2nd parameter is the SIZE of the read/write (in bytes). You have 1 or 0 there instead of the length?

Hmmm... I *hate* it when this happens. It seems things *really* changed in the .NET port....

Examples from the C# source, in the SDK:

	result = fsuipc.FSUIPC_Write(0x05DC, 1, ref token, ref dwResult);

offset, value, 'token', and result. No size specified.

Functions for writing in the FSUIPC Class for .NET:

Overloads Function FSUIPC_Write(ByVal dwOffset As Integer, ByVal Param As Byte, ByRef Token As  Integer) As Boolean)
Overloads Function FSUIPC_Write(ByVal dwOffset As Integer, ByVal Param As Short, ByRef Token As  Integer) As Boolean)
Overloads Function FSUIPC_Write(ByVal dwOffset As Integer, ByVal Param As Integer, ByRef Token As  Integer) As Boolean)
Overloads Function FSUIPC_Write(ByVal dwOffset As Integer, ByVal Param As Long, ByRef Token As  Integer) As Boolean)
Overloads Function FSUIPC_Write(ByVal dwOffset As Integer, ByVal Param As Double, ByRef Token As  Integer) As Boolean)

Not one of them reference the size... Functions definately seem different however.

2. I still don't understand this "token" thing, which you define as 0. What is that for?

Something that got added for the .NET Classes (VB and C# it seems). All I know is, if I don't specify it, it doesn't work. From the comments in the example code, it's a Variable holding a returned token index.

3. You define the size for the writes as 2 but don't use it anywhere (doesn't the VB compiler tell you about unused variables?). How do the Read/Write routines (which are in YOUR code, they are part of what YOU can see and deal with!) know how many bytes to use?

Not by default it doesn't. I'm sure there's a setting for it in the compiler though, or I always have Option Explicit On.

As an example of what the C version would look like here:

FSUIPC_Write(0x0262, 2, PauseGame, &dwResult);

That's it. You wouldn't even really need a function/procedure for that! Your version is complicated and, to me, very confusing. I don't know VB or VB.NET, but surely you do need to give the size someplace?

Hmmm... It's definately different Pete.... :( Guess I'll have to figure this one out on my own... I don't unfortunately have the clean C lib close by as I laying in bed with my laptop -grin-, but just from the example you gave below, the functions must be different...

--

C

Posted

Functions for writing in the FSUIPC Class for .NET:

Overloads Function FSUIPC_Write(ByVal dwOffset As Integer, ByVal Param As Byte, ByRef Token As  Integer) As Boolean)
Overloads Function FSUIPC_Write(ByVal dwOffset As Integer, ByVal Param As Short, ByRef Token As  Integer) As Boolean)
Overloads Function FSUIPC_Write(ByVal dwOffset As Integer, ByVal Param As Integer, ByRef Token As  Integer) As Boolean)
Overloads Function FSUIPC_Write(ByVal dwOffset As Integer, ByVal Param As Long, ByRef Token As  Integer) As Boolean)
Overloads Function FSUIPC_Write(ByVal dwOffset As Integer, ByVal Param As Double, ByRef Token As  Integer) As Boolean)

Not one of them reference the size... Functions definately seem different however.

Well, I assume the size is somehow derived from the type -- in this case you'd need the "ByVal Param As Short" (a Short will be 2 bytes, or 16-bits. However, I've no idea how the overload system selects the correct version when you give a literal value, as you have, like 1 or 0. If it assumes it's an integer, that will write 4 bytes, which will rather wreck the result -- see the next value in the offset list.

I could tell (YOU could tell) what it is actually doing by logging the IPC reads and writes in FSUIPC and checking what is happening. Didn't you do that? I'm sure I advised it -- the logging facility is one of the major tools you need to use when developing programs. The other is a debugger. I do hope VB.NET comes with one of those! With that, since you have the whole source, all the Read/Write routines, the lot, you should be able to step through everything to see what happens.

Regards,

Pete

Posted

2. I still don't understand this "token" thing, which you define as 0. What is that for?

Something that got added for the .NET Classes (VB and C# it seems). All I know is, if I don't specify it, it doesn't work. From the comments in the example code, it's a Variable holding a returned token index.

I got a copy of an email to you from Bob Scott, author of the VB.NET stuff, which seems to explain something about the need for a Token. I still don't understand the ins and outs of it -- the VB.NET stuff apparently needs separate "Gets" to transfer the contents of Reads to your program. I assume this is all to do with the fact that VB.NET isn't real "code" at all, but interpreted stuff (they use the term "managed" these days). It seems to make what I think are simple things much much more complicated.

For the benefit of other reader's I'm taking the liberty of reproducing Bob's explanation of the Token here:

The "Token" value returned by FSUIPC_Read is needed later by FSUIPC_Get to index into a FIFO buffer where the requested data will be placed by the FSUIPC_Process function. What you have done in your code is overwrite the variable dwToken each time the call to FSUIPC_Read is made by reusing a single variable in successive calls. When a read request token result is passed back, it needs to be preserved until passed to its associated FSUIPC_Get call (after the call to FSUIPC_Process).

Regards

Pete

Posted

Hi Pete,

The token thing makes semi sense to me (perhaps it's because I'm a VB kid :) ) - it basically adds a additional step to reading data from FSUIPC... I'm just a tad sad that Bob didn't go into the writing aspect in his reply. I'll more than likely just send him another quick one asking about the writing.

I did check with the logging on FSUIPC now, the offset is never written to the simulator - nevermind the data, so I'm presuming that there are other funtions that needs to be called to actually get the data to the simulator (just like Read requires Get). I'm sure the writing must work though, it's just a matter of what and how.

Just had a thought while reading through my 2nd mail to Bob, Pete... In the VB Write... Why would a token be needed at all (Given what a Token actually is - from the above). Is it not safe to presume (because of the Token reference), that the Write will also go into the FIFO Buffer?

There is no function to work with Write to push data out of that buffer (which, the Get basically does for a Read after the process call), so I'm wondering now.... It's going to be interesting to see what Bob says. IMHO and based on how I am understanding this entire thing, there should be something like the Get, for a Write call as well...

--

Chris.

Posted

Interesting...

Anyways Pete. You where right. The overloads determine the size of the variable - for 0262, the variable sent must be a short, and yes, it works.

For interest sakes, it seems the boolean is 4 bytes long, I presume thus it is converted to a integer.

You suggested this exact same thing before, I'm sure I tried it... Don't know why it didn't work then... Oh well.

As always, thanks...

--

Chris

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.