Orbiter-Forum  

Go Back   Orbiter-Forum > Orbiter Addons > OrbitHangar Addons & Comments
Register Blogs Orbinauts List Social Groups FAQ Projects Mark Forums Read

OrbitHangar Addons & Comments Addons uploaded at Orbithangar.com will automatically generate a new thread in this forum for comments. The thread link will also be included on the addons page.

Reply
 
Thread Tools
  #1  
Old
OrbitHangar's Avatar
OrbitHangar OrbitHangar is offline
Addon Comments
Arrow HUDDrawer SDK v.0.4 for Orbiter 2016
by OrbitHangar 03-01-2013, 08:01 PM


Author: enjo

'Nuff blocking other developers, who are waiting with their HUD drawing modules to bust, by Launch MFD's internal HUD drawing system! This library centralizes the internals of “VESSEL virtual table hijacking”, providing a common system where all the modules, willing to draw on HUD, are registered, and receive the HUD drawing context afterwards. A good example of a module that could use this system would be Axial Velocity HUD, which is currently not compatible with Launch MFD's former HUD drawing system (or the other way around).

Reference posts: Problem reportsolution used.

WARNING! This library is a HACK and it may stop working in future versions of Orbiter API if the library isn't maintained anymore. Note however that it's very easy to do so by updating the VesselHooking class.

Documentation available at:
OrbiterSDK\doc\HUDDrawerSDK

======================
Changes:
v. 0.4    11.09.2016
- MFD: Fixed a CTD upon clicking on buttons when list is empty

Copyright (C) 2008 Steve Arch "agentgonzo" - virtual table hijacking
Copyright (C) 2012-2016 Szymon Ender "Enjo" - created a framework



DOWNLOAD
Reply With Quote
Views 12872 Comments 39
Total Comments 39

Comments

Old 03-01-2013, 08:14 PM   #2
Enjo
Mostly harmless
 
Enjo's Avatar


Default

And here it is folks. After 5 years of damn stagnation, it's finally possible to write modules whose HUD drawing internals may be compatible with each other. Bring those HUD drawing modules on!
Enjo is offline   Reply With Quote
Old 03-09-2013, 10:27 PM   #3
ADSWNJ
Scientist
 
ADSWNJ's Avatar
Default

Need a hand, Enjo old friend!!

I wanted to do a simple demo of HUD-writing, initially to just paint a YPR XYZ offset and orientation onto the HUD, and then get a bit fancier with arrows and alignment corridors.

I have the YPR XYZ code writing to the MFD quite happily, and I have implemented a DrawHUD function to do the same on the HUD, but when I debug it, I see that the DrawHud is not being called. I suspect that I need an initialization call to hook the HUD, but I cannot see where to put it.

Here's the code:

Orientation.h:
Code:
// ==============================================================
//
// Orientation.h
//
// (c) Andrew Stokes (ADSWNJ) 2013  - licensed under LGPL
//
// All rights reserved
// ==============================================================


#include "EnjoLib/IDrawsHUD.hpp"

#ifndef __ORIENTATION_H
#define __ORIENTATION_H

class Orientation: public MFD2, public EnjoLib::IDrawsHUD {
public:
	Orientation (DWORD w, DWORD h, VESSEL *vessel);
	~Orientation ();
	char *ButtonLabel (int bt);
	int ButtonMenu (const MFDBUTTONMENU **menu) const;
	bool Update (oapi::Sketchpad *skp);
	static int MsgProc (UINT msg, UINT mfd, WPARAM wparam, LPARAM lparam);
  void IDrawsHUD();
  void DrawHUD(int mode, const HUDPAINTSPEC *hps, oapi::Sketchpad * skp);
  bool ShouldDrawHUD() const;

protected:
	oapi::Font *font;
  VESSEL *v;

  VECTOR3 gblOri, gblPos, gblVel;
  double simT, oldSimT, simStep;
  bool firstCalc;

  OBJHANDLE hTgtV;
  VESSEL *tv;
  VECTOR3 tvPos, lcltvPos, relPos, oldRelPos;
  VECTOR3 diffPos, diffDir, diffRot, oldDiffDir, oldDiffRot;
  VECTOR3 diffDirRate;

  DOCKHANDLE hDock, hMyDock;
  VECTOR3 rtvdPos, rtvdDir, rtvdRot;
  VECTOR3 gtvdPos, gtvdDir, gtvdRot;
  VECTOR3 ltvdPos, ltvdDir, ltvdRot;
  VECTOR3 dPos, dDir, dRot;
  VECTOR3 gdPos, gdDir, gdRot;

  MATRIX3 R; // Rotation matrix
  VECTOR3 lclPos;

};

#endif // !__ORIENTATION_H

Orientation.cpp:
Code:
// ==============================================================
//
// Orientation.cpp
//
// Determines orientation of GL-02 (harcoded for now) to us.
// Use with Delta-Glider scenario Smack!
//
// Real objective - provide demonstrator HUD hooking code using Enjo's new HUDDrawerSDK v0.1
//
// (c) Andrew Stokes (ADSWNJ) 2013  - licensed under LGPL
//
// All rights reserved
// ==============================================================

#define STRICT
#define ORBITER_MODULE
#include "windows.h"
#include "stdio.h"
#include "orbitersdk.h"
#include "Orientation.h"

// ==============================================================
// Global variables

int g_MFDmode; // identifier for new MFD mode

// ==============================================================
// API interface

DLLCLBK void InitModule (HINSTANCE hDLL)
{
	static char *name = "Orientation";   // MFD mode name
	MFDMODESPECEX spec;
	spec.name = name;
	spec.key = OAPI_KEY_T;                // MFD mode selection key
	spec.context = NULL;
	spec.msgproc = Orientation::MsgProc;  // MFD mode callback function

	// Register the new MFD mode with Orbiter
	g_MFDmode = oapiRegisterMFDMode (spec);
}

DLLCLBK void ExitModule (HINSTANCE hDLL)
{
	// Unregister the custom MFD mode when the module is unloaded
	oapiUnregisterMFDMode (g_MFDmode);
}

// ==============================================================
// MFD class implementation

// Constructor
Orientation::Orientation (DWORD w, DWORD h, VESSEL *vessel)
: MFD2 (w, h, vessel)
{
	v = vessel;
  hMyDock = v->GetDockHandle(0);
  v->GetDockParams(hMyDock, dPos, dDir, dRot);

  font = oapiCreateFont (w/20, true, "Fixed", FONT_NORMAL, 0);
	// Add MFD initialisation here

  hTgtV = oapiGetVesselByName("GL-02");
  tv = oapiGetVesselInterface(hTgtV);
  firstCalc = true;

}

// Destructor
Orientation::~Orientation ()
{
	oapiReleaseFont (font);
	// Add MFD cleanup code here
}


// HUD Drawing
  bool Orientation::ShouldDrawHUD() const {
    return true;
  }
  void Orientation::DrawHUD(int mode, const HUDPAINTSPEC *hps, oapi::Sketchpad * skp) {

    char buf[256];
    int xPix, yPix;
    union{ 
      struct SKPCHARSIZE {
      WORD ch;
      WORD cw;
      } s1;
      DWORD s2;
    } skpCS;


    if (mode==HUD_NONE) return; // HUD is off, so no drawing

    skp->Rectangle(hps->W-200,200,hps->W-20,400);

    xPix = hps->W-195;
    yPix = 205;

    skpCS.s2 = skp->GetCharSize();

    if (!firstCalc) {

	    skp->SetFont (font);
	
      sprintf_s(buf, "       Att    Rate");
      skp->Text (xPix, yPix, buf, strlen(buf));

      yPix = yPix + skpCS.s1.ch + 2;
      if (abs(diffDir.y)<0.1) {
        sprintf_s(buf, "Y  %7.2f  %6.3f     ", diffDir.y, diffDirRate.y);
      } else if (diffDir.y<0) {
        sprintf_s(buf, "Y  %7.2f  %6.3f     (yaw right)", diffDir.y, diffDirRate.y);
      } else {
        sprintf_s(buf, "Y  %7.2f  %6.3f     (yaw left)", diffDir.y, diffDirRate.y);
      }
      skp->Text (xPix, yPix, buf, strlen(buf));

      yPix = yPix + skpCS.s1.ch + 2;
      if (abs(diffDir.x)<0.1) {
        sprintf_s(buf, "P  %7.2f  %6.3f     ", diffDir.x, diffDirRate.x);
      } else if (diffDir.x<0) {
        sprintf_s(buf, "P  %7.2f  %6.3f     (pitch up)", diffDir.x, diffDirRate.x);
      } else {
        sprintf_s(buf, "P  %7.2f  %6.3f     (pitch down)", diffDir.x, diffDirRate.x);
      }
      skp->Text (xPix, yPix, buf, strlen(buf));

      yPix = yPix + skpCS.s1.ch + 2;
      if (abs(diffDir.z)<0.1) {
        sprintf_s(buf, "R  %7.2f  %6.3f     ", diffDir.z, diffDirRate.z);
      } else if (diffDir.z<0) {
        sprintf_s(buf, "R  %7.2f  %6.3f     (roll right)", diffDir.z, diffDirRate.z);
      } else {
        sprintf_s(buf, "R  %7.2f  %6.3f     (roll left)", diffDir.z, diffDirRate.z);
      }
      skp->Text (xPix, yPix, buf, strlen(buf));

      yPix = yPix + skpCS.s1.ch + 2;
      yPix = yPix + skpCS.s1.ch + 2;
      sprintf_s(buf, "       Pos    Vel");
      skp->Text (xPix, yPix, buf, strlen(buf));

      yPix = yPix + skpCS.s1.ch + 2;
      if (abs(relPos.x)<0.01) {
        sprintf_s(buf, "X  %7.2f  %6.3f     ", relPos.x, diffPos.x);
      } else if (relPos.x>0) {
        sprintf_s(buf, "X  %7.2f  %6.3f     (go left)", relPos.x, diffPos.x);
      } else {
        sprintf_s(buf, "X  %7.2f  %6.3f     (go right)", relPos.x, diffPos.x);
      }
      skp->Text (xPix, yPix, buf, strlen(buf));

      yPix = yPix + skpCS.s1.ch + 2;
      if (abs(relPos.y)<0.01) {
        sprintf_s(buf, "Y  %7.2f  %6.3f     ", relPos.y, diffPos.y);
      } else if (relPos.y>0) {
        sprintf_s(buf, "Y  %7.2f  %6.3f     (go down)", relPos.y, diffPos.y);
      } else {
        sprintf_s(buf, "Y  %7.2f  %6.3f     (go up)", relPos.y, diffPos.y);
      }
      skp->Text (xPix, yPix, buf, strlen(buf));

      yPix = yPix + skpCS.s1.ch + 2;
      if (abs(relPos.z)<0.01) {
        sprintf_s(buf, "Z  %7.2f  %6.3f     ", -relPos.z, diffPos.z);
      } else if (relPos.z>0) {
        sprintf_s(buf, "Z  %7.2f  %6.3f     (go backwards)", -relPos.z, diffPos.z);
      } else {
        sprintf_s(buf, "Z  %7.2f  %6.3f     (go forwards)", -relPos.z, diffPos.z);
      }
      skp->Text (xPix, yPix, buf, strlen(buf));

    } 

  }

// Return button labels
char *Orientation::ButtonLabel (int bt)
{
	// The labels for the two buttons used by our MFD mode
	static char *label[2] = {"UP", "DN"};
	return (bt < 2 ? label[bt] : 0);
}

// Return button menus
int Orientation::ButtonMenu (const MFDBUTTONMENU **menu) const
{
	// The menu descriptions for the two buttons
	static const MFDBUTTONMENU mnu[2] = {
		{"Move up", 0, '['},
		{"Move down", 0, ']'}
	};
	if (menu) *menu = mnu;
	return 2; // return the number of buttons used
}


// Repaint the MFD
bool Orientation::Update (oapi::Sketchpad *skp)
{
  int l;
  char buf[128];

	Title (skp, "Orientation");
	// Draws the MFD title

  simT = oapiGetSimTime();
  
  // Get oritnetaiotns, velocities and positions
  v->GetGlobalOrientation(gblOri);
  v->GetGlobalPos(gblPos);
  v->GetGlobalVel(gblVel);
  tv->GetGlobalPos(tvPos);
  hDock = tv->GetDockHandle(0);
  tv->GetDockParams(hDock, rtvdPos, rtvdDir, rtvdRot);


  // Find our dock XYZ offset in local coords
  tv->Local2Global(rtvdPos,gtvdPos);    // Make remote coord tgt vehicle dock position into a global coord
  v->Global2Local(gtvdPos,ltvdPos);     // And flip it back into a local tgt vehicle coords
  relPos = dPos - ltvdPos;              // My dock Pos is already in local coords, so the relative offset is just one minus the other


  // Find our Pitch Yaw offset in local coords
  rtvdDir = rtvdPos - rtvdDir;          // Turn direction vector into a point a unit distance inside the target dock, aligned correctly
  tv->Local2Global(rtvdDir,gtvdDir);    // Flip to global
  v->Global2Local(gtvdDir,ltvdDir);     // ... and back to local in our frame
  ltvdDir = ltvdDir - ltvdPos;          // Subtract the dock coords, to make the direction coord back into a vector (on our local origin)
  
  // For roll offset, use the Rot vector
  rtvdRot = rtvdPos + rtvdRot;          // Turn the rotation vector into a point offset from the dock
  tv->Local2Global(rtvdRot,gtvdRot);    // Flip to global
  v->Global2Local(gtvdRot,ltvdRot);     // ... and back to local in our frame
  ltvdRot = ltvdRot - ltvdPos;          // Subtract the dock coords, to make the rotation coord back into a vector (on our local origin)




  diffDir.x = DEG* (atan2(dDir.y, dDir.z) - atan2(ltvdDir.y, ltvdDir.z));    // DiffDir.x is PITCH
  diffDir.y = DEG* (atan2(dDir.x, dDir.z) - atan2(ltvdDir.x, ltvdDir.z));    // DiffDir.y is YAW
  diffDir.z = DEG * (atan2(ltvdRot.y, ltvdRot.x) - atan2(dRot.y, dRot.x));   // DiffDir.z is ROLL on the rotation alignment vector
  if (diffDir.x < -180.0) diffDir.x += 360.0;
  if (diffDir.y < -180.0) diffDir.y += 360.0;
  if (diffDir.z < -180.0) diffDir.z += 360.0;

  if (!firstCalc) {

    simStep = simT - oldSimT;
    diffPos = (relPos - oldRelPos) / simStep;


    diffDirRate = (diffDir - oldDiffDir) / simStep;

	  skp->SetFont (font);
	
    l = 2;
    sprintf_s(buf, "       Att    Rate");
    skp->Text (W*10/100, H*l/25, buf, strlen(buf));

    l++;
    if (abs(diffDir.y)<0.1) {
      sprintf_s(buf, "Y  %7.2f  %6.3f     ", diffDir.y, diffDirRate.y);
    } else if (diffDir.y<0) {
      sprintf_s(buf, "Y  %7.2f  %6.3f     (yaw right)", diffDir.y, diffDirRate.y);
    } else {
      sprintf_s(buf, "Y  %7.2f  %6.3f     (yaw left)", diffDir.y, diffDirRate.y);
    }
    skp->Text (W*10/100, H*l/25, buf, strlen(buf));

    l++;
    if (abs(diffDir.x)<0.1) {
      sprintf_s(buf, "P  %7.2f  %6.3f     ", diffDir.x, diffDirRate.x);
    } else if (diffDir.x<0) {
      sprintf_s(buf, "P  %7.2f  %6.3f     (pitch up)", diffDir.x, diffDirRate.x);
    } else {
      sprintf_s(buf, "P  %7.2f  %6.3f     (pitch down)", diffDir.x, diffDirRate.x);
    }
    skp->Text (W*10/100, H*l/25, buf, strlen(buf));

    l++;
    if (abs(diffDir.z)<0.1) {
      sprintf_s(buf, "R  %7.2f  %6.3f     ", diffDir.z, diffDirRate.z);
    } else if (diffDir.z<0) {
      sprintf_s(buf, "R  %7.2f  %6.3f     (roll right)", diffDir.z, diffDirRate.z);
    } else {
      sprintf_s(buf, "R  %7.2f  %6.3f     (roll left)", diffDir.z, diffDirRate.z);
    }
    skp->Text (W*10/100, H*l/25, buf, strlen(buf));

    l++;
    l++;
    sprintf_s(buf, "       Pos    Vel");
    skp->Text (W*10/100, H*l/25, buf, strlen(buf));

    l++;
    if (abs(relPos.x)<0.01) {
      sprintf_s(buf, "X  %7.2f  %6.3f     ", relPos.x, diffPos.x);
    } else if (relPos.x>0) {
      sprintf_s(buf, "X  %7.2f  %6.3f     (go left)", relPos.x, diffPos.x);
    } else {
      sprintf_s(buf, "X  %7.2f  %6.3f     (go right)", relPos.x, diffPos.x);
    }
    skp->Text (W*10/100, H*l/25, buf, strlen(buf));

    l++;
    if (abs(relPos.y)<0.01) {
      sprintf_s(buf, "Y  %7.2f  %6.3f     ", relPos.y, diffPos.y);
    } else if (relPos.y>0) {
      sprintf_s(buf, "Y  %7.2f  %6.3f     (go down)", relPos.y, diffPos.y);
    } else {
      sprintf_s(buf, "Y  %7.2f  %6.3f     (go up)", relPos.y, diffPos.y);
    }
    skp->Text (W*10/100, H*l/25, buf, strlen(buf));

    l++;
    if (abs(relPos.z)<0.01) {
      sprintf_s(buf, "Z  %7.2f  %6.3f     ", -relPos.z, diffPos.z);
    } else if (relPos.z>0) {
      sprintf_s(buf, "Z  %7.2f  %6.3f     (go backwards)", -relPos.z, diffPos.z);
    } else {
      sprintf_s(buf, "Z  %7.2f  %6.3f     (go forwards)", -relPos.z, diffPos.z);
    }
    skp->Text (W*10/100, H*l/25, buf, strlen(buf));

  } else {
    firstCalc = false;
  };
  oldSimT = simT;
  oldRelPos = relPos;
  oldDiffDir = diffDir;


	return true;
}

// MFD message parser
int Orientation::MsgProc (UINT msg, UINT mfd, WPARAM wparam, LPARAM lparam)
{
	switch (msg) {
	case OAPI_MSG_MFD_OPENED:
		// Our new MFD mode has been selected, so we create the MFD and
		// return a pointer to it.
		return (int)(new Orientation (LOWORD(wparam), HIWORD(wparam), (VESSEL*)lparam));
	}
	return 0;
}

I have an EnjoLib subdir for the project, with your IDrawsHUD cpp and hpp, and VesselHooking cpp and hpp.

My code is currently hardcoded to run on a Delta-Glider, on standard scenario Smack! in the Delta-Glider directory.

Can you have a play and show me what I am doing wrong?

By the way - the MFD updates seem to be working fine - i.e. put up docking MFD and Orientation MFD and they agree. Hopefully at some point, having a digital readout of orientation on the approach to a docking will be of use.
ADSWNJ is offline   Reply With Quote
Old 03-10-2013, 05:30 AM   #4
Enjo
Mostly harmless
 
Enjo's Avatar


Default

Great! I'm happy that you've picked it up.

Quote:
Originally Posted by ADSWNJ View Post
 ... but when I debug it, I see that the DrawHud is not being called. I suspect that I need an initialization call to hook the HUD, but I cannot see where to put it.
Works on my machine (TM). You need to enable HUDDrawer module in the Launchpad. The hooking is done through the module, and it's the only place where it should be done. By deriving from IDrawsHUD, you automatically register your module in the "Hooking control center", called by the HUDDrawer module. The registering is done through IDrawsHUD constructor, while deregistering through its destructor.

Quote:
Originally Posted by ADSWNJ View Post
 I have an EnjoLib subdir for the project, with your IDrawsHUD cpp and hpp, and VesselHooking cpp and hpp.
This is your mistake. The VesselHooking class should never be compiled into your project. The code is provided there only as a requirement for LGPL license. If you compile it in, you then have two "Control centers" which compete with each other, and this breaks Orbiter (or in your case, your instance wasn't called, as you noticed). To get definitions for VesselHooking and IDrawsHUD, you need to link VesselHooking.lib, that should reside in OrbiterSDK/lib after a normal installation of HUDDrawerSDK. Same goes for IDrawsHUD.hpp, that should reside in OrbiterSDK/include/EnjoLib. That's all you need. Once you activate your own module, the binary definitions of the IDrawsHUD and VesselHooking classes will be then read from VesselHooking.dll, that is stored in Modules dir, which guarantees a single instance of the VesselHooking class.

BTW, you don't need to declare void IDrawsHUD() in your header.

Last edited by Enjo; 03-10-2013 at 05:38 AM.
Enjo is offline   Reply With Quote
Thanked by:
Old 03-10-2013, 03:12 PM   #5
ADSWNJ
Scientist
 
ADSWNJ's Avatar
Default

Thanks Enjo

I stripped out all your source from my project. The one thing I missed the first time was to add VesselHooking.lib to the solution properties at Configuration Properties > Linker > Input > Additional Dependencies (alongside orbiter.lib and orbitersdk.lib).

Hey presto, I have scribbled on the HUD with my little orientation code (all misaligned for now, but working!).


So I can officially say that Enjo's HUD hooker is a super-simple piece of code to hook against. One include statement:
Code:
#include "EnjoLib/IDrawsHUD.hpp"
Extend your main MFD class definition to derive from EnjoLiv:IDrawsHUD:
Code:
class yourMFD: public MFD2, public EnjoLib::IDrawsHUD { ...
Add these two functions (plus an optional one for Orbiter 2006 backward compatibility if you REALLY want your new HUD-MFD to support Orbiter 2006):
Code:
  void DrawHUD(int mode, const HUDPAINTSPEC *hps, oapi::Sketchpad * skp);
  bool ShouldDrawHUD() const;
Make the ShoudDrawHUD() return true when you want it to show (or hardcode it to true).

Than pwn away on the DrawHUD() call just like you would on your MFD Update() call.

No initialization, hooking code or other nastiness to deal with at all - Enjo has abstracted all of that for all future HUD writing add-ons. How cool is that?

Last edited by ADSWNJ; 03-10-2013 at 03:14 PM.
ADSWNJ is offline   Reply With Quote
Thanked by:
Old 03-10-2013, 04:39 PM   #6
Enjo
Mostly harmless
 
Enjo's Avatar


Default

Quote:
Originally Posted by ADSWNJ View Post
 No initialization, hooking code or other nastiness to deal with at all - Enjo has abstracted all of that for all future HUD writing add-ons. How cool is that?
Beats me, but that was the goal - do all the dirty stuff so you don't have to!
Enjo is offline   Reply With Quote
Thanked by:
Old 03-10-2013, 07:05 PM   #7
ADSWNJ
Scientist
 
ADSWNJ's Avatar
Default

Just an idea for you ... if a number of addons start exploiting this hook, then the HUD may get a bit messy. Could you introduce a method for addons to request a block of space on the HUD, to play nice with other addons? eg I would ask for 150x200 pixels to put an alignment box, with a hint of right middle, and you could give me the offsets dependent on who else is on the screen. Or if you are drawing graphics, then maybe you don't mind others overwriting you, but at least you register your interest.

Likewise, you could introduce a way for addons to discover who else is on the HUD (w/versions too) and have a way to export and import data. E.g. a future glideslope talking to basesync or aerobrake, or (shock) the base Docking MFD talking to its HUD neighbors.
ADSWNJ is offline   Reply With Quote
Thanked by:
Old 03-10-2013, 08:20 PM   #8
csanders
Orbinaut
 
csanders's Avatar
Default

Quote:
Originally Posted by ADSWNJ View Post
 Just an idea for you ... if a number of addons start exploiting this hook, then the HUD may get a bit messy. Could you introduce a method for addons to request a block of space on the HUD, to play nice with other addons? eg I would ask for 150x200 pixels to put an alignment box, with a hint of right middle, and you could give me the offsets dependent on who else is on the screen. Or if you are drawing graphics, then maybe you don't mind others overwriting you, but at least you register your interest.

Likewise, you could introduce a way for addons to discover who else is on the HUD (w/versions too) and have a way to export and import data. E.g. a future glideslope talking to basesync or aerobrake, or (shock) the base Docking MFD talking to its HUD neighbors.
Or a HUD MFD that lets one select which hooked HUDs get drawn?
csanders is offline   Reply With Quote
Thanked by:
Old 03-10-2013, 11:14 PM   #9
agentgonzo
Grounded since '09
 
agentgonzo's Avatar
Default

Enjo - Love it.

I remember the genesis of this topic and initial discussions with you and Face about it. Alas, my life moved on and I haven't had any time to develop for orbiter in far far too long (though did manage to load it the other day in an attempt to intercept 2012 DA14 (but failed!!!).

Congratulations on getting this finally packaged and released. A monumentous occasion for addon hackers! Orbiter just keeps on getting better and better - I wish I had the time to play with it like I used to.

Steve/agentgonzo

---------- Post added at 23:14 ---------- Previous post was at 23:12 ----------

PS - 2008? Wow - was it really that long ago???
agentgonzo is offline   Reply With Quote
Thanked by:
Old 03-12-2013, 05:40 AM   #10
Enjo
Mostly harmless
 
Enjo's Avatar


Default

Hi Steve! Nice to see you again.

It didn't require that much actual work to do it, only some experience and motivation. The latter is actually ADSWNJ's fault, as he's proven to be somebody who's able to do something useful with my libraries

Quote:
Originally Posted by agentgonzo View Post
  PS - 2008? Wow - was it really that long ago???
Yep. The year the world's gone broke. I think it was the investment bankers' fault

Andrew:
I'm afraid that your idea smells of a bit of overcomplexity. It's not something that could be coded in a realistic time, nor having an interface as simple as it is now. However I do like csanders' idea, which will be fairly simple to implement. Technically it could be done with the HUDDrawer module, which is already there. The IDrawsHUD interface could accept an optional unique string identifier of the client module, which when defined, would allow for (de)selecting the module from a list of active Drawers through the HUDDrawer module. I'm only wondering whether it should be done as an MFD or a WinAPI window, like the Scenario Editor is done. The 2nd option seems more appropriate for something that's not supposed to display vessel data, although I personally dislike WinAPI. Perhaps it could be done with wxWidgets? Gotta try it out.


And just to prove that the IDrawsHUD client doesn't necessarily need to be an MFD, I've just implemented it in Launch MFD as a vessel's property, so that the HUD can be drawn even when the MFD itself is disabled.

---------- Post added 03-12-13 at 06:40 AM ---------- Previous post was 03-11-13 at 07:59 PM ----------

Quote:
Originally Posted by agentgonzo View Post
 I remember the genesis of this topic and initial discussions with you and Face about it. Alas, my life moved on and I haven't had any time to develop for orbiter in far far too long (though did manage to load it the other day in an attempt to intercept 2012 DA14 (but failed!!!).
And yeah. My life has also changed since since I've moved and got married. I hoped to get a working terrain in Orbiter for a long time and been postponing my playing with the sim because of that. My hardware is too poor for DX11 client so far. But I do find a lot of fun in coding for the sim all the time and keep returning to do it, because it's the only place where I can do things my way.

Last edited by Enjo; 03-12-2013 at 12:08 PM.
Enjo is offline   Reply With Quote
Thanked by:
Old 03-16-2013, 04:12 PM   #11
Enjo
Mostly harmless
 
Enjo's Avatar


Default

Version 0.2 is released.

Changes:
- Ability to select active modules through HUDDrawer MFD (see attached screenshot)
- IDrawsHUD's constructor requires module's string identifier
- Changed license to GPL

I was really struggling about the license change decision. Basically I want to avoid situations similar to Axial Velocity HUD, where the author has left the scene, and although the addon was great, it's useless now.

Andrew:
To be clear, I have nothing against your MFDs being written in LGPL and linked against HUDDrawer. It's just that some people don't share the code at all. Possibly linking LGPL code with GPL library is permitted through "linking exception". I state in the manual that I have nothing against this.

Steve:
I also hope that you have nothing against GPL. After all, it's mostly your code, and only my high level design.


I've done the active drawers selection as MFD for two reasons - I know writing MFDs better than WinAPI, and it turned out that MFD gives me more flexibility, because the MFD-based drawers, like Launch MFD and Orientation MFD are not registered and visible on the list, until the MFDs themselves are activated. Once this is done, they automatically appear on the HUDDrawer MFD, which would be harder to achieve through a WinAPI window.
Attached Thumbnails
HUDDrawerMFD.png  

Last edited by Enjo; 03-16-2013 at 04:22 PM.
Enjo is offline   Reply With Quote
Thanked by:
Old 03-16-2013, 06:25 PM   #12
ADSWNJ
Scientist
 
ADSWNJ's Avatar
Default

Looks like the simplest thing is to ask all code linking to HUDDrawer to be GPL then. As I understand it, LGPL basically allows derivative code to be open or closed, whereas GPL forces it to be open (i.e. source released with the executable). There's issues with 'degrading' a GPL to a LGPL in a derivative work, unless expressly permitted, so let's just keep everything open and shareable.

I personally would like to see every element of Orbiter, from the core to every addon, released under GPL. It would create an explosion of new ideas and innovation. Here's wishing.
ADSWNJ is offline   Reply With Quote
Thanked by:
Old 03-16-2013, 07:57 PM   #13
Enjo
Mostly harmless
 
Enjo's Avatar


Default

I see we agree here.

Quote:
Originally Posted by ADSWNJ View Post
 As I understand it, LGPL basically allows derivative code to be open or closed, whereas GPL forces it to be open (i.e. source released with the executable).
Technically speaking, linking your code with GPL library statically or dynamically, or compiling in GPL code to your project enforces the product to be GPL. LGPL is different here only in the fact that it allows you to keep your product closed source when you link an LGPL library dynamically, so that it's possible to update the product with a newer version of the library. Therefore LGPL only guarantees "Freedom" to the library itself, and it's not the only thing I'd hope to have.
Note, also, that technically it doesn't make much difference if the end product is LGPL or GPL then, because the end product won't be a subject to dynamic linking, unless you happen to create a library from it later, like it was in case of HUDDrawer's internals (now that I think of it, they were rather GPLed before, because they were part of GPLed Launch MFD anyway). So in such case, by switching from LGPL to GPL, you'd simply save some confusion later eventually.

I'd also like to note that LGPL lets some "good guys'" businesses to exist, like Linux Game Publishing, as stated in this article.
Quote:
For years, LGP has been working with libraries such as SDL, ffmpeg, and others that are licensed under the LGPL (GNU Lesser General Public License). Without these invaluable tools from the open source community, LGP would not exist, and nor would hundreds of open source projects.
So no LGPL = no high quality games for Linux. Looks like a blow for the OS. In case of Orbiter, though, such a problem doesn't exist, as the addons won't be commercial anyway, so nobody's financial future is at sake, and Orbiter can't get any better anyway, like Linux got better, thanks to Linux Game Publishing. Well, there could be some exceptions, for example asmi made a case for DX11 client, that he could add some proprietary (?) graphics code if the client wasn't GPLed. But on the other hand, what would then happen to the DX11 client once asmi leaves the scene?
Enjo is offline   Reply With Quote
Thanked by:
Old 03-16-2013, 10:51 PM   #14
Interceptor
Orbinaut
 
Interceptor's Avatar
Default

Thanks,once again Enjo.

---------- Post added at 04:51 PM ---------- Previous post was at 03:44 PM ----------

Enjo,is it possible now to use the Axiel velocity hud with the XR ships using this MFD now, could you some how make a fix for this.Thanks
Interceptor is offline   Reply With Quote
Old 03-17-2013, 12:46 AM   #15
ADSWNJ
Scientist
 
ADSWNJ's Avatar
Default

Quote:
Originally Posted by Interceptor View Post
 Enjo,is it possible now to use the Axiel velocity hud with the XR ships using this MFD now, could you some how make a fix for this.Thanks
Unfortunately not. Reason: great add on (Axial), but released without source and then the author has stopped maintaining it. So it becomes a relic, instead of a living idea. This is exactly why Enjo is moving his code to GPL, to require derivative works to release source code as well as the add on, so in some future world, the concept can be rescued and enhanced. For Axial, we would need to start the code from scratch, as doing a byte by byte disassembly is just not practical.

This is why Enjo is leading a fight here for addons to be open.
ADSWNJ is offline   Reply With Quote
Thanked by:
Reply

  Orbiter-Forum > Orbiter Addons > OrbitHangar Addons & Comments


Thread Tools

Posting Rules
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
Forum Jump


All times are GMT. The time now is 01:16 AM.

Quick Links Need Help?


About Us | Rules & Guidelines | TOS Policy | Privacy Policy

Orbiter-Forum is hosted at Orbithangar.com
Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Copyright 2007 - 2017, Orbiter-Forum.com. All rights reserved.