Jump to content

Explanation of DCS-BIOS cdu method calls?


sinistar

Recommended Posts

Hello community,

 

  I am looking for a bit of guidance in terms of the DCS-BIOS "API". Specifically the calls associated with the CDU display.

It seems that the common model for gathering CDU display data is code like this:

void onCduLine8Change(char* newValue) {
 printLine(8,0,newValue);
}
DcsBios::StringBuffer<24> cduLine8Buffer(0x1280, onCduLine8Change);

Where the function "printLine" is defined by the user something like:

void printLine(int row, int col, char* newValue) {
  int16_t y = row * 32 + 6;
  mylcd.Print_String(newValue,CENTER,y);
}

(This will be slightly different depending on the display library used for the particular TFT)

 

I guess my fundamental issue is that I am not very comfortable with C++ syntax, so am confused as to what this particular line is doing:

DcsBios::StringBuffer<24> cduLine8Buffer(0x1280, onCduLine8Change);

To my untrained brain, this looks like a function(method) definition of type StringBuffer<24> (inherited from the DcsBios class), but I don't think that is correct? How would it be called?

 

Also, any hints as to the two parameters passed into that function? The first looks like some type of offset(0x1280), while the second seems to be a reference to the function just declared above this call.

 

Link to comment
Share on other sites

Don't forget the inclusion of the DcsBios.h file will set up some things you won't see from the control reference.

I'm guessing the "StringBuffer<24>" part defines a function to check if a parameter has changed, and the "cduLine8Buffer" part is the last known value for comparison.

What I DO know is that the 0x1280 is the start address of the string in question, and the second parameter is the name of the subroutine to call.

There's an example of the StringBuffer class code here, but I have no idea how it works:
https://github.com/DCSFlightpanels/dcs-bios-arduino-library/blob/master/src/internal/ExportStreamListener.h

 

Link to comment
Share on other sites

14 hours ago, sinistar said:

Hello community,

 

  I am looking for a bit of guidance in terms of the DCS-BIOS "API". Specifically the calls associated with the CDU display.

It seems that the common model for gathering CDU display data is code like this:...

 

I guess my fundamental issue is that I am not very comfortable with C++ syntax, so am confused as to what this particular line is doing:

DcsBios::StringBuffer<24> cduLine8Buffer(0x1280, onCduLine8Change);

To my untrained brain, this looks like a function(method) definition of type StringBuffer<24> (inherited from the DcsBios class), but I don't think that is correct? How would it be called?

 

Also, any hints as to the two parameters passed into that function? The first looks like some type of offset(0x1280), while the second seems to be a reference to the function just declared above this call.

 

the cduLine8Buffer is a declaration of a 24 character long string buffer that holds the results of DCS updating that specific field.  the 0x1280 is an address/offset of where dcs-bios should watch for changes (that's defined by the different features of the different aircraft/etc).   As DCS changes that value, dcs bios effectively is copying that 24 characters into its (this) stringbuffer.

the second param is a callback (a function) in your code that will be called when that change occurs. 

so basically:

DCS changes something at a specific place

where DCS-BIOS is watching

so it copies the data

and then calls your method to tell your code it changed, so you can do something with it

  • Like 1
Link to comment
Share on other sites

17 hours ago, gardnerjr said:

the cduLine8Buffer is a declaration of a 24 character long string buffer that holds the results of DCS updating that specific field.  the 0x1280 is an address/offset of where dcs-bios should watch for changes (that's defined by the different features of the different aircraft/etc).   As DCS changes that value, dcs bios effectively is copying that 24 characters into its (this) stringbuffer.

the second param is a callback (a function) in your code that will be called when that change occurs. 

so basically:

DCS changes something at a specific place

where DCS-BIOS is watching

so it copies the data

and then calls your method to tell your code it changed, so you can do something with it

Thanks - it is becoming clearer now!

Are there any docs explaining the structure of that "stream" - the specifics of the CDU display (line 8 ) starting at 0x1280 for example.

 

Link to comment
Share on other sites

iirc from when i did this, you end up getting one buffer like that for each line of the CDU screen.  there are 9 lines on the screen, each with own bufffer that's 24ch wide.  if dcs updates one line, only that one callback gets called.  if dcs updates the whole CDU, each callback gets called in turn. if anything changes in that line, that callback function gets called and you effectively have to draw the whole line all at once.  if it is getting cleared, the whole buffer contents will just be empty space characters.

there's no real "structure" to it, its a 9x24 character screen.  the cdu doesn't do any graphics, its just a text display.  

Link to comment
Share on other sites

19 hours ago, gardnerjr said:

iirc from when i did this, you end up getting one buffer like that for each line of the CDU screen.  there are 9 lines on the screen, each with own bufffer that's 24ch wide.  if dcs updates one line, only that one callback gets called.  if dcs updates the whole CDU, each callback gets called in turn. if anything changes in that line, that callback function gets called and you effectively have to draw the whole line all at once.  if it is getting cleared, the whole buffer contents will just be empty space characters.

there's no real "structure" to it, its a 9x24 character screen.  the cdu doesn't do any graphics, its just a text display.  

I'm going a little deep on this because I'm seeing things which don't appear to fit that model all of the time.

One of my confusing situations shows up while monitoring the bottom line of the CDU - that with the blinking cursor (line 9). I would expect to see about two calls to that update every second (cursor-on / cursor-off) which is the case most of the time. However, every so often (maybe once every 5 blinks) there is an extra call to that update function.

This has lead me into the danger zone of trying to understand more fully what the dataflow looks like from DCS to my serial-port connected Arduino, and as a side effect, understanding better the program flow. Unfortunately, my C++ experience is very limited which is making my research more difficult.

I suppose my next route will take me into understanding the StringBuffer class defined within ExportStreamListener.h:

 

	template < unsigned int LENGTH >
	class StringBuffer : public ExportStreamListener {
		private:
			char receivingBuffer[LENGTH+1];
			char userBuffer[LENGTH+1];
			volatile bool receivingDirty;
			bool userDirty;
			void (*callback)(char*);
			void setChar(unsigned int index, unsigned char value) {
				// DCS-BIOS will occasionally send data even if it did not change
				if (receivingBuffer[index] == value) return;
				
				receivingBuffer[index] = value;
				receivingDirty = true;
			}
		public:
			StringBuffer(unsigned int address, void (*callback)(char*)) : ExportStreamListener(address, address+LENGTH) {
				memset(receivingBuffer, ' ', LENGTH-1);
				receivingBuffer[LENGTH] = '\0';
				userBuffer[LENGTH] = '\0';
				
				receivingDirty = false;
				userDirty = false;
				this->callback = callback;
			}
			virtual void onDcsBiosWrite(unsigned int address, unsigned int data) {
				unsigned int index = address - firstAddressOfInterest;
				setChar(index, ((char*)&data)[0] );
				index++;
				if (LENGTH > index) {
					setChar(index, ((char*)&data)[1] );
				}
			}
			virtual void onConsistentData() {
				if (receivingDirty) {
					noInterrupts();
					memcpy(userBuffer, receivingBuffer, LENGTH);
					receivingDirty = false;
					userDirty = true;
					interrupts();
				}
			}
			bool hasUpdatedData() {
				return userDirty;
			}
			char* getData() {
				userDirty = false;
				return userBuffer;
			}
			virtual void loop() {
				if (hasUpdatedData()) {
					if (callback) {
						callback(getData());
					}
				}
			}
	};

 

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...