API Question Custom Displays (Please help)

Hlynkacg

Aspiring rocket scientist
Addon Developer
Tutorial Publisher
Donator
Joined
Dec 27, 2010
Messages
1,868
Reaction score
4
Points
0
Location
San Diego
So after taking a hiatus from Orbiter for finals and other "real-life" obligations I'm back and looking to update my RNS addon and complete my space tug.

The biggest obstical to this, thus far has been coding custom displays for the hud and VCs. I've tried borrowing code from the ShuttleA and Delta glider but unfortunatly the API documentation is rather incomplete for a C++ newbie such as myself, and I don't understand what each line of code is actually doing.

I have two things that have been holding me up.

The first is rather simple.

I want to add some text to the Hud in the orbiter's default "glass cockpit" I've tried copy-pasting the standard sketchpad "hello world" into "callback render hud" but nothing happened. My final objective is to add a "DV remaining in m/s" to the standard hud.

The second is more complicated, I have a .Jpg image created in illustrator that represents the background of a custom display panel. I want to add text to this display based on current vessel state and then paint it as a texture in the VC.

If someone could talk me through the processes for accomplishing either of these it would be much appreciated.

:hailprobe:
 
Can you post how your source code of the clbkDrawHUD function (and the called functions) looks like? Would make it easier to point out where you are on the wrong path and what you did do right.
 
So I started with this...

Code:
bool CaterpillarOUV::clbkDrawHUD (int mode, const HUDPAINTSPEC *hps, oapi::Sketchpad *skp)
{
	skp->Text (0, 0, "I'm a HUD!", 10);

Then while digging through my SDK samples folder I found the code for Wishbone's NTR Stage which appears to have the functionality I'm looking for

Code:
HUDTextOut_CLR(skp, 10, lineY[7], GOLD, "dV since burn start: %10.2f final dV: %10.2f", dV_sinceBurnStart, dV_atShutdown);

The difficulty is that "HUDTextOut_CLR" is not a standard operation.

I found a definition for "HUDTextOut_CLR" in Wishbone's header file but don't quite understand what's happening or how it actually works.

Code:
static int lineY[] = {152, 168, 184, 200, 216, 232, 248, 264, 280, 296, 312, 328, 344, 360, 376, 392, 408};
#define HUDTextOut_CLR(skp, x, y, colour, text, ...)	{\
	DWORD old_clr = skp->SetTextColor(colour); \
	char buf[1024]; \
	sprintf_s(buf, 1024, text, __VA_ARGS__); \
	skp->Text (x+roxl, y+royl,buf, (int)strlen(buf));\
	skp->SetTextColor(old_clr);\
}

There are also these lines which appear to be some sort of scaling function but I'm not sure.

Code:
	oapiSetDefNavDisplay(1);
	oapiSetDefRCSDisplay(1);

	int s = hps->H;
	double d = (s*0.00130208);
	int sw = ((hps->W));
	int lw =  (int)(16*sw/1024);
	int lwoffset = sw - (18*lw);
	int hlw = (int) (lw/2);


	int roxl = 0;
	int royl = 0;

	double ds = s;
	double dsw = sw;
	double sc_ratio = ds/dsw;


	if (sc_ratio < 0.7284)
	{
		roxl = (lw*10);
		royl = (int) (-88*d);
	}

Any help would be appreciated.
 
Last edited:
It is a simple preprocessor macro, the code is just copied into the place and the parameters are replaced. A primitive form of the modern inline function.

It just saves the old text color when setting the new one, displays the text at the position relative to (rox1, roy1) and then resets the text color back to the old one. The text to display is generated by using a variable argument expression (...), which means text has to contain the standard printf format specifiers, and the __VA_ARGS__ macro contains all arguments passed to the macro after "text".
 
Thank for taking the time to respond

I guess my next question is what exactly do rox1 and roy1 represent? and how do I use this?

For instance if I wanted my out put to display horizonatly centered on the screen and a 3rd of the way up from the bottom, how would I go about setting doing this?

Am I limited to pixle by pixle coordinates or is there a function I can use?
 
well, then you're in luck - computers are pretty good at basic math :thumbup:


if you wanna have something at half way across horizontally and one third vertically, all you have to do is set x to half the width of the display and y to the height times .3333333


there's no need to call any special functions... just use basic math and you'll be fine


hint - you can get the width and height of the hud from the sketchpad struct pointer :cheers:
 
I guess my next question is what exactly do rox1 and roy1 represent? and how do I use this?

They represent the upper left corner of the region of the screen that you want to align your text output to. 0/0 means upper left corner of the screen, as usual.

In the code you use as example, when the aspect ratio gets wide screen, the text output is centered in a rectangle on the screen, instead of staying relative to the upper left corner of the screen.
 
Last edited:
If you wanna have something at half way across horizontally and one third vertically, all you have to do is set x to half the width of the display and y to the height times .3333333


there's no need to call any special functions... just use basic math and you'll be fine


hint - you can get the width and height of the hud from the sketchpad struct pointer :cheers:

I guess the next question I need to ask is "where can I find documentation for the sketchpad?" because I don't even know how to go about getting the current screen/hud width.
 
Last edited:
I guess the next question I need to ask is "where can I find documentation for the sketchpad?" because I don't even know how to go about getting the current screen/hud width.

In case of the HUD, it is in the HUDPAINTSPEC structure, as W and H.
 
So I've done a decent amount of experimenting. and through trial and error have gotten to the point where I can get a HUD to display what I want where I want it.

But I'm still hazy on the how/why.

Take the following scrap of code for instance,

Code:
#define HUDTextOut_CLR(skp, x, y, colour, text, ...)	{\
	DWORD old_clr = skp->SetTextColor(colour); \
	char buf[1024]; \
	sprintf_s(buf, 1024, text, __VA_ARGS__); \
	skp->Text (x+roxl, y+royl,buf, (int)strlen(buf));\
	skp->SetTextColor(old_clr);\
}

Can anyone tell me what "__VA_ARGS__" is?
 
the __VA_ARGS__ macro contains all arguments passed to the macro after "text".

Is this defined elsewhere in the code or is it a component of the OAPI / C++?

If were to start from scratch instead of modifying SDK samples how would I ensure that text contains the standard printf format specifiers?
 
Is this defined elsewhere in the code or is it a component of the OAPI / C++?

If were to start from scratch instead of modifying SDK samples how would I ensure that text contains the standard printf format specifiers?

It is a component of ANY ANSI C compiler, it is a common compiler macro (A macro that has its definition defined by the compiler)
 
Once again, thank you for taking the time to respond.

So I have the following lines of code in my clbkDrawHUD function which should (in theory) add a display the percentage of propellant remaining for both the Primary and RCS thrusters.

Code:
// Display amount of popellant remaining 
HUDTextOut_CLR(skp, 0, lineY[0], WHITE, "RCS Remaining %10.2f %%", (GetPropellantMass(ph_RCS)/RNS_RCSTANK));
HUDTextOut_CLR(skp, 0, lineY[1], WHITE, "LH2 Remaining %10.2f %%", (GetPropellantMass(ph_main)/RNS_MAINTANK));

Regardless of the amount of propellant actually in the tanks what I get is

RCS Remaining 0.00%
LH2 Remaining 0.00%

The problem appears to be that the "GetPropellantMass()" function is returning "0.0" because adding a fixed number to the equation i.e

Code:
HUDTextOut_CLR(skp, 0, lineY[1], WHITE, "LH2 Remaining %10.2f %%", (100000/RNS_MAINTANK));

returns the value I would expect.
 
Last edited:
I've developed a work around for the fuel gauge problem.

Code:
	double Main_Remaining, RCS_Remaining;
	Main_Remaining = GetFuelMass()/RNS_MAINTANK; //Return amount of propellant currently in main tanks as fraction of tank capacity
	RCS_Remaining = (GetTotalPropellantMass()-GetFuelMass())/RNS_RCSTANK; //Return amount of propellant currently in RCS tanks as fraction of tank capacity

	// Display amount of popellant remaining 
	HUDTextOut_CLR(skp, column[ 0], row[ 0], WHITE, "Propellant Remaining.");
	HUDTextOut_CLR(skp, column[ 0], row[ 1], WHITE, "Main: %10.2f %%", 100*Main_Remaining); //display main engine propellant remaining. [full tank = 100%]
	HUDTextOut_CLR(skp, column[ 0], row[ 2], WHITE, "RCS:  %10.2f %%", 100*RCS_Remaining); //display RCS propellant remaining. [full tank = 100%]

The problem is that it's ugly and not very scalable, if I decide to add a 3rd propellant resource down the line (say to track oxidizer independantly) I'm back to square-one.

Obviously I'd prefer to call the Propellant Handles directly...
Code:
	double Main_Remaining, RCS_Remaining;
	Main_Remaining = GetPropellantMass(ph_main); //Return amount of propellant currently in main tanks
	RCS_Remaining =  GetPropellantMass(ph_RCS); //Return amount of propellant currently in RCS tanks

...but when I do so the "GetPropellantMass()" function returns "0.0" regardless of the actual amount of propellant in the tanks. Does anyone have any idea why this might be happening?

---------- Post added at 08:17 PM ---------- Previous post was at 08:15 PM ----------

PS:

Is there a function to Get the current default HUD color?
 
Obviously I'd prefer to call the Propellant Handles directly...
Code:
	double Main_Remaining, RCS_Remaining;
	Main_Remaining = GetPropellantMass(ph_main); //Return amount of propellant currently in main tanks
	RCS_Remaining =  GetPropellantMass(ph_RCS); //Return amount of propellant currently in RCS tanks

...but when I do so the "GetPropellantMass()" function returns "0.0" regardless of the actual amount of propellant in the tanks. Does anyone have any idea why this might be happening?


Try this
Code:
	double Main_Remaining, RCS_Remaining;
	Main_Remaining = GetPropellantMass(&ph_main); //Return amount of propellant currently in main tanks
	RCS_Remaining =  GetPropellantMass(&ph_RCS); //Return amount of propellant currently in RCS tanks
 
Still no luck.

Forgive the newbie question but what is the signifigance of the ampersand?
 
Forgive the newbie question but what is the signifigance of the ampersand?

Depends on the operation, but first of all, it provides a pointer to a variable. is used by C-style calls by reference, for example in scanf.

I would rather expect that your propellant resources are either empty OR defined twice. How is your propellant resource line in current state?
 
It's passing the argument by reference but here it's actually my mistake. Anyway didn't hurt to try.
Your first option should have work if ph_main was initialized properly.

You should have something like this in your clbkSetClassCaps() function

Code:
ph_main = CreatePropellantResource (MAX_MAIN_FUEL)
where MAX_MAIN_FUEL is just a simple constant
 
Last edited:
I would rather expect that your propellant resources are either empty OR defined twice. How is your propellant resource line in current state?[/QUOTE]

In the class def I have.

Code:
THRUSTER_HANDLE th_main, th_rcs[16], th_group[2]; // Thruster Handles
PROPELLANT_HANDLE ph_main, ph_RCS; // Propellant Handles

Then in set class caps I have.
Code:
	ph_main = CreatePropellantResource (RNS_MAINTANK);
	ph_RCS = CreatePropellantResource (RNS_RCSTANK);

I know they're there because the thrusters work and I can view/edit thier quantities using the scenario editor. Likewise the work-around posted does in fact display the proper propellant levels.
 
Back
Top