API Question calling opcLoadState from a vessel dll

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,877
Reaction score
2,131
Points
203
Location
between the planets
I'm putting in a few planned but missing features for IMS, one of which is the support for other starsystems (only really concerns thermodynamics). A long time ago I have written a framework for just such things for OrbiterGalaxy, a file format that allows developers to describe the system in more detail. It even got used in some cases.

Anyways, the only problem I'm really having is that I need the systems name from the scenario file. I thought opcLoadState might be the best way to go, since that information is at the beginning of the scenario file, and clbkLoadState gives me the scenario with the position already in the vessel block. The trouble is just, opcLoadState doesn't seem to get called in a vessel dll. Currently I just have the function defined in the cpp that contains #define ORBITER_MODULE, and it builds without problems, but it seems I have to register something more that the function gets called, or maybe it just can't be used from inside a vessel dll. Any advice?
 

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
opcLoadState is only called for a plugin module if a block with the module name is present in the scenario file. Even then, the file position pointer is set to beginning of that block and not to the beginning of the file. You'd need to call your module ENVIRONMENT.dll to get the system name. You can find more about it by searching for my posts with: ENVIRONMENT+opcLoadState keywords (because I don't know how copy paste direct link to it on my mobile phone :p).
 

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,877
Reaction score
2,131
Points
203
Location
between the planets
Hmmm... I take it there's no way to reposition in the scenario file... or getting the name of the loaded scenario file so I could load it independantly?
 

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
You could hook imported by Orbiter ifstream method for opening text files to get the scenario file name being loaded.

I can tell something more about it next week, when I'm back at home.
 

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,877
Reaction score
2,131
Points
203
Location
between the planets
I was thinking about something like this, but with a bit of experimenting I found a way to do it (ab)using the orbiter API. I'm probably exploiting a bug here, but what the hell...

If you use oapiGetItem_string on a line in the wrong format (like System Sol instead of System = Sol) it returns false and ends up at the end of the file (presumably because it recognised an invalid entry and went on searching), so it seemed completely unusable for my purposes.

However, if you use it on a tag that isn't followed by anything (like, say, BEGIN_ENVIRONMENT), it still returns false, but retains the position in the file!

As such, I have been able to cook up a function that returns the name of the solar system, which goes like this:

Code:
string GetCurrentSystem(FILEHANDLE scn, string vesselName, string className)
//gets the current system from the scenario file. returns "" if unsuccesfull
//the name of the calling vessel and its class name are neccessary to find the position in the scenario again.
//function has to be called at the BEGINNING of clbkLoadState!
{
	char getpos[1];
	char *line;
	bool systemFound = false;
	stringstream  repos("");
        string retName("");

	//needed to find position in scenario again
	repos << vesselName << ":" << className;

	//this repositions the pointer in the scenario file
	oapiReadItem_string(scn, "BEGIN_ENVIRONMENT", getpos);

	
	bool posFound = false;
	while (!posFound)
	{
		if (oapiReadScenario_nextline (scn, line))
		{
			string s(line);
			if (!systemFound && s.compare(0, 6, "System") == 0)
			{
				retName = s.substr(7);
				systemFound = true;
			}
			else if (s.compare(repos.str()) == 0)
			{
				posFound = true;
			}
		}
	}
	return retName;
}
 
Last edited:
Top