New Release Interplanetary Modular Spacecraft RC9

OK..These are my findings:
Using this base path
C:\Program Files (x86)\Orbiter-base_dir\Orbit-e2\Config\Vessels\IMS\SBB41BRev2\Connection_Parts

I find that the filename:
123456789012345678901234567890 (30 chars) > No CTD
1234567890123456789012345678901 (31 chars) > CTD

In the path one level higher (...\Vessels\IMS\SBB41BRev2\)

the filename
Connection_Parts1234567890123456789012345678901 > No CTD
Connection_Parts12345678901234567890123456789012> CTD

Which makes sence in that respect that the pathname (and backslash) is included in the count.

I hope that you guys can make some sense of it. I included my total path from the root so you best can decide from where the count starts.

And so cool that you look into the coding of the D3D9 :thumbup:

Everything runs so much smoother in D3D9 enviroment when the ships increase in size. Granted you have to have some decent HW...But you are nontheless rewarded for good HW. Not the case under the vanilla Client

Thanks! Looks indeed like a 64 character limit is somehow in the game:
Code:
0        1         2         3         4         5         6
1234567890123456789012345678901234567890123456789012345678901234

IMS\SBB41BRev2\Connection_Parts\123456789012345678901234567890   OK
IMS\SBB41BRev2\Connection_Parts\1234567890123456789012345678901  CTD
IMS\SBB41BRev2\Connection_Parts1234567890123456789012345678901   OK
IMS\SBB41BRev2\Connection_Parts12345678901234567890123456789012  CTD


---------- Post added at 20:02 ---------- Previous post was at 19:41 ----------

Ok, I'm pretty sure now that the crash is due to the invalid parameter handler invokation of sprintf_s, as previously quoted from the MSDN. This handler mechanism is described as follows:

MSDN said:
The behavior of the C Runtime when an invalid parameter is found is to call the currently assigned invalid parameter handler. The default invalid parameter invokes Watson crash reporting, which causes the application to crash and asks the user if they want to load the crash dump to Microsoft for analysis. In Debug mode, an invalid parameter also results in a failed assertion.
 
Long module directories+names causing problems sounds familiar to me

Hmm... this long names getting truncated and then causing crashes sounds VERY familiar to me. That might be the cause for all those modules where if I named more than 10 with only the last 2 characters of the name different Orbiter would crash, but if I changed the naming convention every 10 modules I could add hundreds of modules together w/out a problem. The crash would occur while it was loading all the DLLs for all the modules during initialization of the scenario.

Sounds like Y2K to me.... ;) I happened to have had some experience with Y2K coding problems in some code I inherited and had to fix on Jan 1, 2000...

BTW, I posted a copy of my SSTV pre-integration scenario somewhere on here.. if anyone wants a REALLY challenging integration for D3D9 + IMS 1.0 RC2.3 testing. ;)

Dantassii
HUMONGOUS IMS shipbuilder
 
That might be the cause for all those modules where if I named more than 10 with only the last 2 characters of the name different Orbiter would crash, but if I changed the naming convention every 10 modules I could add hundreds of modules together w/out a problem.

As similar as it sounds, the problem is unrelated. The problem there was that I was tracing the vessel stack before all vessels were fully initialised, so their dockports were pointing to the wrong partner. Which, for some weird reason that is totally beyond me, seemed to be related to vessel names, but the problem vanished once I waited until the first frame to trace the whole stack.

BTW, I posted a copy of my SSTV pre-integration scenario somewhere on here.. if anyone wants a REALLY challenging integration for D3D9 + IMS 1.0 RC2.3 testing.

As mentioned earlier, D3D9 client can't load the scenario. I first thought that it's simply too large and was causing trouble because of that, now it looks as if it would be because of the same problem Micheal_Chr discovered.

I'll be able to tell more once I can build the D3D9 client... which is a bit of a problem, because I need 10 hours to download DirectXSDK, and usually I'm expieriencing problems while downloading (like, you know, having to put my laptop into standby somewhere along the way, or it overheating, or similar fun stuff. I wish Microsoft would have a scaled down version with only libs and headers, or at least a torrent option...)

Then again, if I can catch a good moment, it might take only half an hour... technically I have a 2Mb/s connection, but that usually fluctuates between 10 Kb/s and 1.5 Mb/s...

Ok, I'm pretty sure now that the crash is due to the invalid parameter handler invokation of sprintf_s, as previously quoted from the MSDN. This handler mechanism is described as follows:

But why would it be invoked in the first place?

EDIT:

If the buffer is too small for the text being printed then the buffer is set to an empty string and the invalid parameter handler is invoked.

Ok... so sprintf_s does not just write the string as long as there is space. If there's not enough buffer space, it invokes the invalid parameter handler. So yeah... here clearly lies our problem. Although the code block is generally for loading skin configurations, sprintf_s gets executed in any case... and crashes when the input is more than 62 characters long (why 62? I'd have expected it to be at least 63... the terminator could still be placed) because it invokes the invalid parameter handler.

The easiest solution would be to make the buffer larger, but I'm not sure if that couldn't lead to results not expected by the programers in the following comparison...?

---------- Post added at 11:09 AM ---------- Previous post was at 10:22 AM ----------

Who'd have thought, I had the good fortune of catching my connection at a good time when I got home... I can build the client now.

What I don't seem to be able to do is debugging it... My breakpoints remain inactive (put one into InitModule just to make sure). I've built in debug configuration, and using the modules\server\orbiter.exe executable. What do I have to do to debug this thing?
 
Last edited:
How to compile it in debug mode...

What I don't seem to be able to do is debugging it... My breakpoints remain inactive (put one into InitModule just to make sure). I've built in debug configuration, and using the modules\server\orbiter.exe executable. What do I have to do to debug this thing?

Threaten it with a complete re-write from scratch... that seemed to work for IMS 1.0 R2.3 (In the form of IMS 2.0). ;)

Dantassii
HUMONGOUS IMS shipbuilder
 
I identified the problem... I'm compiling in release, although debug is selected in visual studio. But when I access the project properties, it always shows Active(release), no matter what I select in visual studio. I can edit the debug configuration, but it doesn't help, because the active option is always release.

What am I supposed to do?

---------- Post added at 02:19 PM ---------- Previous post was at 02:00 PM ----------

Ok, got that fixed in the configuration manager, but still I can't trigger a breakpoint. What's the matter with this thing?

EDIT:
Right, it churns out a dll with a different name. Finally I can get to work... :facepalm:

---------- Post added at 02:33 PM ---------- Previous post was at 02:19 PM ----------

Face was spot on. The reason why the limit is 62 characters and not 63 is, of course, because the function appends an additional # in front of the string.

Increasing the buffer size to 256 solves the problem, and should also preempt any mistaken identities when comparing to the full classname stored in pSkins. It's still potentially dangerous, but IMS has a pretty deep folder structure and also pretty long filenames at times, but doesn't remotely reach 255 characters yet. I think 256 should be save. I wouldn't like to start a small rewrite over the whole client here, I'll just break more than I'll fix...

Now let's see if I can hunt down that bug with AddAnimationComponent. Now there's a real challenge :shifty:
 
Now let's see if I can hunt down that bug with AddAnimationComponent. Now there's a real challenge

I can hear a very feint and distant drum roll - however I believe its getting closer :-)
 
Tough nut...

The crash happens when deleting animstate, seemingly when nanim > 1, but I'm not sure if there's really a relation. Fact is that it doesn't seem to happen if there's only 1 animation, but I doubt this is directly connected.

I looked at everything involving animstate and can't find anything wrong. Most probably, something else writes accidentaly into its memory, and that could be virtually anything... :facepalm:

As far as I can see, creating the animations (AddAnimationComponent) is not the clients duty (pleeeeease correct me if I'm wrong), it gets the animation data from orbiter. So the possibility of orbiter itself writing out of memory and D3D9Client just getting in the way due to no fault of its own is still there. The critical operations pertaining to the crash all happen on AddMesh.
 
Last edited:
The crash happens when deleting animstate, seemingly when nanim > 1, but I'm not sure if there's really a relation. Fact is that it doesn't seem to happen if there's only 1 animation, but I doubt this is directly connected.

Could you post the stack trace, please?
 
We interrupted this bug hunt for getting moderately drunk and getting a night's sleep... let's see if we can find the bugger before the kids need feeding :lol:

Could you post the stack trace, please?

Ah yes, I always forget that that exists :facepalm: Must have been the alcohol working pre-emptively. There is a function that adds the animations, and it only gets called when adding a component during sim-time. And it does lots of pointery stuff: Animate(UINT, double, UINT) currently looks like the most promising culprit. Let's see, then...
 
of was down yesterday, and now i don't have time to post. so let's just say that it's fixed.
 
So, finally a bit of time for posting a bit more in detail.

Most work on RC3 is finished now. I still have to take a look at the crash that seems to happen in systems other than sol, but apart from that, things look good... better than I ever expected, really.

After fixing the problem with D3D9 client, I ported some more code back from IMS2, related to the rotation of docking ports. Coupled with the new streamlined mass-integration, the results are pretty astonishing. I integrated Dantassiis Lunar Station as a quick test. Integration took about 3 minutes. No crashes along the way. No meshes missing or rotated wrongly. It's the way it should always have been, but which I didn't really believe to feasible for IMS anymore.
There's still the thing with a crash on exit, or reload if the launchpad wasn't shut down. I'm afraid I haven't found a cure for that yet, but in the great scheme of things it's a rather minor inconvienience.

Anyways, now for the D3D9 specific details. The animation problem was, as expected, an opperation that wrote out of bounds. It was just a bit difficult to track down, because there's nothing wrong with the code per se. Rather the dynamic adding of animations creates a problem that was not foreseen when the client was written, and caused an otherwise fine function to missbehave. That needed a saveguard.

The problem in a bit more detail is this: D3D9 client initialises animations and allocates memory to store the state of those both at loadup, and dinamically when a mesh is added.
This happens in the function InitAnimations(UINT) in vVessel.cpp.

The trouble is, this function only is called when a mesh is added. nanim receives the number of animations the vessel currently has, but this is before new animations are added.

IMS (and presumably any other add-on that creates animations on the fly) then goes on to add the new animations if neccessary. After doing so, vVessel::Update() is called in the client, which calls UpdateAnimations(UINT = -1).

The new animations will have been added in the meantime. Meaning, nanim will receive the new number of animations, while InitAnimations only got the old number of animations, without the newly added ones.

As a result of this, UpdateAnimations writes over the allocated length of animstate in the block at the end.

I fixed the problem by introducing a new block into UpdateAnimations that checks for newly added animations and calls InitAnimations for them. The block seems a bit overcomplicated. The problem is I need the meshindex, and at this point (called from Update()) The meshindex passed to UpdateAnimations is invalid, so I have to extract all meshindices first, and of course I had to check for duplicity, since I don't want to call InitAnimations over and over for the same mesh. I used a vector, which means I had to include vector.h in vVessel.cpp:

Code:
void vVessel::UpdateAnimations (UINT mshidx)
{
	double newstate;
	
	UINT oldnAnim = nanim;
	nanim = vessel->GetAnimPtr(&anim);

	if (nanim>0 && animstate==NULL) {
		LogErr("[ANOMALY] UpdateAnimations() called before the animations are initialized. Calling InitAnimations()...");
		InitAnimations();
	}

	if (nanim > oldnAnim)
	//animations have been added without being initialised
	{
		std::vector<UINT> meshesToInitialise;
		for (UINT i = oldnAnim; i < nanim; ++i)
		//extracting meshindices for uninitialised animations.
		//this might seem overly complicated, but it seems savest
		//it guarantees that all new animations are initialised, and are initialised only once
		{
			for (UINT j = 0; j < anim[i].ncomp; ++j)
			{
				bool alreadyNoted = false;
				for (UINT jj = 0;  jj < meshesToInitialise.size(); ++jj)
				{
					if (anim[i].comp[j]->trans->mesh == meshesToInitialise[jj])
					{
						alreadyNoted = true;
						break;
					}
				}
				if (!alreadyNoted)
				{
					meshesToInitialise.push_back(anim[i].comp[j]->trans->mesh);
				}
			}
		}
		for (UINT i = 0; i < meshesToInitialise.size(); ++i)
		{
			InitAnimations(meshesToInitialise[i]);
		}
	}

	for (UINT i = 0; i < nanim; i++) {
		if (!anim[i].ncomp) continue;
		if (animstate[i] != (newstate = anim[i].state)) {
			Animate(i, newstate, mshidx);
			animstate[i] = newstate;
		}
	}
}

I'm probably breaking a convention on every line I wrote here, and I don't know if the inclusion of vector is welcome, as there seems to be an avid evasion of both string and vector in the whole client. I could have made a fixed size array with a size that seems large enough, but I'd rather play it save... :shifty:

Anyways, for those reasons I'm somewhat reluctant to commit the changes. The other change was to increase the buffer size in ParseSkins (also vVessel.cpp) to 256, like this:

Code:
void vVessel::ParseSkins()
{
        char classname[256];

        D3D9Client *gc = scn->GetClient();
        DWORD start = 0;

        sprintf_s(classname, 256, "#%s", vessel->GetClassNameA());

These corrections make D3D9Client work with IMS without problems. So where should I go from here? Post the changes in the (suspiciously inactive) D3D9 forum? Make a pull request (as I said, I'm a bit reluctant about this... somoene will probably feel the urge to rewrite that block anyways)? Put a temporary fixed version up with RC3 until there's a new official build?

It is also possible that it would be sufficient to call InitAnimations just once, even if more than one mesh was added (doesn't happen in IMS, so I didn't test)... as far as I can see it wouldn't make much of a difference, but the function requiring a meshindex made me suspicious.
 
Last edited:
Anyways, for those reasons I'm somewhat reluctant to commit the changes.

Commit... into what? As long as you don't have commit/push access to the Codeplex repo, you can't "break" things, anyway. If you mean commit into a DVCS, by all means please do so! It is your private local clone then, anyway.

These corrections make D3D9Client work with IMS without problems. So where should I go from here? Post the changes in the (suspiciously inactive) D3D9 forum? Make a pull request (as I said, I'm a bit reluctant about this... somoene will probably feel the urge to rewrite that block anyways)? Put a temporary fixed version up with RC3 until there's a new official build?

I would first communicate it to the official maintainer, which is jarmonik. Best would be posting a patch (like in SVN-patch-file) in the dev-thread. I doubt that anybody will bite your head off for some broken rules, they should be glad to have somebody registering, tracking down, and even presenting a fix for such a severe problem.

If there is no reaction until your project is ready for prime-time, simply fork the project and do your own D3D9 release. That's one of the advantages (or disadvantages depending on your view-point) of open source: everybody can take the code, make it better, and release it again.

I could give you push access to my OVP repository, so you could push your code changes and updated binaries there. Or you could roll your own. As long as you keep the rest untouched (especially credits and readmes), I don't see a reason why this could be an offending thing to do, especially if you give the mentioned head-start notice and wait a few days for reaction.

my :2cents:
 
Last edited:
This is truly amazing...Well done....no...extremely well done Jededia. :thumbup:
I guess that Alcohol sometimes help....lol
 
Ummm, just a minor note Jedidia

If the persistent crash you're looking at is the one I posted, I strongly doubt that it is related to out of sol systems. Its the same issue that I experienced with Odyssey Station & a whole host of large vessels a while back. I very strongly suspect that it is related to some sort of module/vessel parameter going out of bounds, since the crash almost always happens when systems on a given vessel are fried, and it can be reproduced to happen at the same MJD almost every time (I think just within error limits while using time accel).

Are you sure that IMS has nothing that might remotely act like a MET timer variable?
 
Last edited:
Did you try to integrate the SSTV or just the Lunar Station?

After fixing the problem with D3D9 client, I ported some more code back from IMS2, related to the rotation of docking ports. Coupled with the new streamlined mass-integration, the results are pretty astonishing. I integrated Dantassii's Lunar Station as a quick test. Integration took about 3 minutes. No crashes along the way. No meshes missing or rotated wrongly. It's the way it should always have been, but which I didn't really believe to feasible for IMS anymore.

Did you try the SSTV? It's 3x as big as the last Lunar Station scenario that I uploaded. I have run a few more missions since then but the Lunar Station is getting REALLY slow to build at this time because of all those HUMONGOUS fuel tanks I have to bring up to it. 1 More HUMONGOUS fuel tank mission to go before I get to go back to 'design mode'. I think I'll bring up the remainder of the radiators and some other structural parts before doing more fuel tank missions.

BTW, did you ever get a chance to look into the vertical radiator deploy/assignment problem? If you have 2 radiators located in the same position left/right and front/back (they are vertically offset) you can only deploy/assign stuff to 1 of them. It seems kinda random which one gets it and sometimes you can deploy 1.. but assign to the other.. and if you assign something to an undeployed radiator.. well.. it don't do you any good. BTW, the Lunar Station has some vertically aligned radiators on it (I think) so it would be as good a thing as any to test out solutions on.

I can't wait until I can integrate the Lunar Station in 3 minutes.. last time it took me almost 90 minutes and required 3 restarts and about 2 dozen CTDs...

Dantassii
HUMONGOUS IMS shipbuilder
 
Last edited:
BTW, did you ever get a chance to look into the vertical radiator deploy/assignment problem?

Ah no, that's another one I didn't get around to yet. The problem here is that I have difficulties reproducing the situation... I.E. I probably don't understand correctly how they have to be aligned. If you give me a scenario (a small one, preferably, so I actually see what I'm doing) it would help a lot.

---------- Post added at 08:11 PM ---------- Previous post was at 03:40 PM ----------

Say Bruce, that orbital yards scenario... which config files does it use exactly? certainly not the default ones, or at least not the default folder structure.
 
Ah no, that's another one I didn't get around to yet. The problem here is that I have difficulties reproducing the situation... I.E. I probably don't understand correctly how they have to be aligned. If you give me a scenario (a small one, preferably, so I actually see what I'm doing) it would help a lot.

Sadly, NOW I can't seem to get it to happen. Every time I build something that has vertically stacked radiators (including a partial integration of the current Lunar Station!) all the radiators are deployable and useable!

The simplest scenario that I saw it happen on (and it doesn't do it now) was a Control Module with a BM230 Nuclear Reactor attached to it's port 2 (via port 1 on the BM230) and then put 4 radiators on ports 3, 4, 5, and 6 of the BM230 and integrate. No matter how much I zoomed in on the cooling display, I could never get all 4 radiators to deploy (the best I was able to do was get 3 deployed).

Of course, that exact scenario this afternoon showed all 4 radiators and allowed me to deploy them and assign the reactor to them...

Murphy!!!!!

If I'm able to duplicate the problem again, I'll be sure to send you a copy of the scenario, but knowing my luck, it will NEVER happen again.

Dantassii
HUMONGOUS IMS shipbuilder
aka Murphy's Law Magnet
 
Back
Top