New Release D3D9Client Development

WOW64 means [W]indows [O]n [W]indows-[64], so in that folder the 32bit world lives - logical, right?
I don't know about logical :unsure:, but it sure sounds like MS.
 
@dbeachy1 , just for clarification :
The DLLs listed in this pat of Orbiter.log
Code:
000000.000: ---------------------------------------------------------------
000000.000: D3D9 DLLs  : C:\WINDOWS\SYSTEM32\d3d9.dll [v 10.0.19041.928]
000000.000:            : C:\WINDOWS\SYSTEM32\d3dx9_43.dll [v 9.29.952.3111]
000000.000: ---------------------------------------------------------------
are System DLLs, so they are not part of D3D9Client!
These are the runtime DLLs which should have been installed by DirectX End-User Runtimes (June 2010) (<= Note, this is a link) installer.

....and I've checked the code that reports this: It's bit-width-agnostic.
 
Still no luck compiling D3D9Client, and getting more confused ....
Is there a readme that explains the steps to compile, including prerequisites that need to be installed?

I installed the DirectX End-User Runtimes (June 2010) package. Do I also need to install any NVidia SDK stuff?
Should this compile with CMake, using the provided CMakeLists.txt, or do I have to use the VS solution files directly?
When compiling with CMake, the CMAKE_BINARY_DIR has to point to an Orbiter installation, correct?
When compiling directly from the VS solution directory, does the D3D9Client git repository have to be placed directly inside an Orbiter installation?
I found VS solution files in Orbitersdk/D3D9Client, but the VS2019 version only seems to be set up for x86. Should I use the VS2015 version and convert to VS2019?
I got errors relating to _wassert, had to convert all instances to assert. Has this been seen before?

Sorry for all the questions. I'm new to compiling the D3D9client, so a beginner's guide would help me a lot.
 
Still no luck compiling D3D9Client, and getting more confused ....
Is there a readme that explains the steps to compile, including prerequisites that need to be installed?
I installed the DirectX End-User Runtimes (June 2010) package. Do I also need to install any NVidia SDK stuff?
Sadly, we don't have any readme yet. There's been lot of new things to learn and I haven't found the time to write that. Also some things regarding the build process are still under development.
The End-User Runtimes are not sufficient to actually build the client you would need at-least: DirectX SDK (June 2010)
That's the latest SDK that's available as separate download. The newer DirectX SDKs are bundled with Windows 10 SDK and I haven't tried those yet. No nVidia SDK required as far as I know. If you are missing a proper SDK then there's gonna be lot of compilation errors.

Should this compile with CMake, using the provided CMakeLists.txt, or do I have to use the VS solution files directly?
I haven't tried the "Ninja" yet, so, I don't know how that works yet. I have used the CMake-GUI to create VS Solution and Project files and after that I have clicked the D3D9Client.sln to launch the VS and build the projects from there. Usually I have removed BUILD_ALL, INSTALL "Projects" from the Solution.

When compiling with CMake, the CMAKE_BINARY_DIR has to point to an Orbiter installation, correct?
Yes, that is correct, the same that is used to build the Orbiter. And the CMAKE_SOURCE_DIR must point to the local D3D9Client.git repository.

When compiling directly from the VS solution directory, does the D3D9Client git repository have to be placed directly inside an Orbiter installation?
No, I have no idea what happens if someone tries that. CMake should copy all necessary files to CMAKE_BINARY_DIR. Also CMake should copy/update the Shaders during every build.

I found VS solution files in Orbitersdk/D3D9Client, but the VS2019 version only seems to be set up for x86. Should I use the VS2015 version and convert to VS2019?
I got errors relating to _wassert, had to convert all instances to assert. Has this been seen before?
I have left the old project files in-place just in case if we need them. There's been no reports regarding "_wassert" and it's been there probably 2-3 years. I have no idea why it fails.

CMake is configured to place the modules directly in /Modules/Plugin/ they do not go to "/debug/" "/release/" sub-folders.
And the Shaders (*.fx and *.hlsl) must be in /Modules/D3D9Client/
 
Last edited:
I finally managed to compile D3D9Client x64 and run it under Orbiter x64! Thanks for your help in getting my problems worked out.

FYI, It worked straight away for me when doing a debug build, but to get it to work in a release build, I had to fix problems with _wassert and assert, by adding the following in D3D9Client.h after #include <assert.h>:
Code:
#if defined(NDEBUG)
#define _wassert(message,filename,line)
#endif

#undef assert
#define assert(x) (x)
"_wassert" was undefined for me in the Release build (which is apparently expected according to this: "The signature of the _assert function isn't available in a header file. The signature of the _wassert function is only available when the NDEBUG macro isn't defined.")

Even more worrying, "assert" was defined as
Code:
#ifdef NDEBUG

    #define assert(expression) ((void)0)

#else
  ...
in assert.h. In other words, the argument of assert wasn't even computed, leading to crashes.

I wonder if this is a change in behaviour between VS 2015 and VS 2019. Just to give you a heads-up of potential problems.
 
I finally managed to compile D3D9Client x64 and run it under Orbiter x64! Thanks for your help in getting my problems worked out.
It's great hear that it finally worked. I googled about the NDEBUG (i.e. NO DEBUG) flag and it would seem to work as intended. It's purpose seem to be disabling these debug assertions. I have never used NDEBUG flag and it looks like CMake would define it for Release builds. I wonder are there any alternatives for asserts we could use. Or should we try to undefine NDEBUG and let the asserts to work ?

How are the things with the rest of the Orbiter regarding assert behavior ?
 
According to Billy: The _assert and _wassert functions are internal CRT functions. They help minimize the code required in your object files to support assertions. We don't recommend that you call these functions directly.

Never had problems with assert(): it's there in debug builds to catch programmer errors (hard-coded stuff and not, e.g., file parse errors), and in release builds all that "instrumentation" disappears.
 
How are the things with the rest of the Orbiter regarding assert behavior ?
I have defined my own macros (in Src/Orbiter/Log.h: ASSERT and dASSERT). Log.h isn't currently exported to the SDK, so probably not visible to external plugin code. If it looks useful, I could copy it to Orbitersdk/include.
 
Never had problems with assert(): it's there in debug builds to catch programmer errors (hard-coded stuff and not, e.g., file parse errors), and in release builds all that "instrumentation" disappears.
That is fine as long as you are not relying on the side effect of the argument of assert() being evaluated even if the assertion is not tested. So you can do

res = someFunction()
assert(SUCCEEDED(res))

but not

assert(SUCCEEDED(someFunction()))

if you rely on someFunction() being called.
 
For what it's worth, in my experience and from what I've read, the contents of the assert macros should never contain code that needs to run in production. i.e., the assert documentation says this:

This macro is disabled if, at the moment of including <assert.h>, a macro with the name NDEBUG has already been defined. This allows for a coder to include as many assert calls as needed in a source code while debugging the program and then disable all of them for the production version by simply including a line like:

#define NDEBUG

at the beginning of the code, before the inclusion of <assert.h>.

Therefore, this macro is designed to capture programming errors, not user or run-time errors, since it is generally disabled after a program exits its debugging phase.

The contents of the (uppercase) ASSERT macros in Visual Studio are only ever compiled into debug builds, not release builds, so it's probably safer to just use the uppercase ASSERT macros to prevent any unexpected side effects of having business logic inside a (lowercase) assert , which may or may not run in production builds (and having any assert macros run in production builds is counter-intuitive, at least to me). But that's just my perspective, which may or may not be "correct". :)
 
Therefore, this macro is designed to capture programming errors, not user or run-time errors, since it is generally disabled after a program exits its debugging phase.

We have used the assert to capture user and run-time errors as well. I thought it's better to assert when something goes very wrong rather than CTD in some point later on. So, is there a better way to capture run-time errors in release builds (hopefully equally easy) ?
 
We have used the assert to capture user and run-time errors as well. I thought it's better to assert when something goes very wrong rather than CTD in some point later on. So, is there a better way to capture run-time errors in release builds (hopefully equally easy) ?
For runtime errors you can throw an exception, catch it somewhere upstream, log the error and exit.
 
For runtime errors you can throw an exception, catch it somewhere upstream, log the error and exit.

FWIW, I agree -- it's a lot easier for end users to post a log file than try to copy down the cryptic stuff that pops up on an assert's dialog box, IMO.

Another similar approach is to define your own macro (maybe named "PRODUCTION_ASSERT(...)"?) that invokes your own custom, static function that writes to the log file an exits if the supplied expression evaluates to false or null. But I still wouldn't want to put the actual business logic call inside the macro -- I would just save the result of the business logic call to a variable and then pass that variable to the PRODUCTION_ASSERT. For example, doing this:

Code:
const int myResult = DoSomethingCool(...);
PRODUCTION_ASSERT((myResult > 0), "DoSomethingCool returned a bad value!");

...seems much more intuitive (and safer) to me than doing this:

Code:
PRODUCTION_ASSERT((DoSomethingCool(...) > 0), "DoSomethingCool returned a bad value!");

That's just my perspective, though. Every developer has their own preferred style. :)
 
[,,,] I have never used NDEBUG flag [...]
Maybe not intentionally, but as mentioned by several people now it is used for many compile-dependent things.
When you create a Debug project/solution with Visual Studio it adds the _DEBUG definition per default[*]
and a Release project/solution adds the NDEBUG definition accordingly.

[*] Visual Studio defines _DEBUG when you specify the /MTd or /MDd option
 
What exactly does the "Enable absolute animation handling" option do, and is there any good reason for it to not be enabled by default?
 
What exactly does the "Enable absolute animation handling" option do, and is there any good reason for it to not be enabled by default?
By default Orbiter uses incremental animations meaning that for each frame the previous animation state is incremented by small amount, which includes some errors, over time these errors accumulate and the animation is no longer in the orientation it's supposed to be. (3-10 mins in worst cases)

Absolute animations updates the animation state from a default state for each frame. Which doesn't suffer from the error mentioned. But the absolute animations can fail if an add-on alters the order of operations (rotations), so, it's not 100% backwards compatible. But so-far no add-on is known to fail.
 
Absolute animations updates the animation state from a default state for each frame. Which doesn't suffer from the error mentioned. But the absolute animations can fail if an add-on alters the order of operations (rotations), so, it's not 100% backwards compatible. But so-far no add-on is known to fail.
Hi jarmonik.
Well, hate to be the first (n hopefully the last) but Absolute setting gives mega problems on my F-35B
It dumps the wheels about 2 metres below the gear on lowering.

It uses the original mesh and gear sequence (with permission), of Kev Shannow's F-35B.
Can you tell from code what I need to change to get the "order of operations" right?

Thanks n keep up the excellent work on this client please. :salute:

C++:
 // Gear anims
 
 
   //Front Gear
   static UINT GGrp1[9] = {6,7,8,9,10,11,12,13,125};
 
   static MGROUP_ROTATE gear1 (0,GGrp1, 9, _V(0,-0.9227885,3.099234), _V(1,0,0), (float)(-115*RAD));
 
 
   //Rear Gear Left
   static UINT GGrp2[4] = {14,15,16,126};
 
   static MGROUP_ROTATE gear2 (0,GGrp2, 4, _V(-1.15901,-0.4520788,-2.172986), _V(1,0,0), (float)(-99*RAD));
 
   //Rear Gear Right
   static UINT GGrp3[4] = {18,20,21,127};
 
   static MGROUP_ROTATE gear3 (0,GGrp3, 4, _V(1.15901,-0.4520788,-2.172986), _V(1,0,0), (float)(-99*RAD));
 
   
    //Front Gear Cover
   static UINT GGrp5[1] = {5};
 
   static MGROUP_ROTATE gear5 (0,GGrp5, 1, _V(0.2282761,-0.870366,3.679197), _V(0,0,1), (float)(-93*RAD));
 
   
   //Rear Cover Left
   static UINT GGrp12[2] = {173,174};
 
   static MGROUP_ROTATE gear12 (0,GGrp12, 2, _V(-1.199155,-0.3544314,-1.368714), _V(0,0,1), (float)(99*RAD));
 
   //Rear Cover Right
   static UINT GGrp13[2] = {175,176};
 
   static MGROUP_ROTATE gear13 (0,GGrp13, 2, _V(1.199155,-0.3544314,-1.368714), _V(0,0,1), (float)(-99*RAD));
 
 
 
    //Rear Gear Left2
   static UINT GGrp20[5] = {14,15,16,17,126};
 
   static MGROUP_ROTATE gear20 (0,GGrp20, 5, _V(-1.15901,-0.4520788,-2.172986), _V(0,0,1), (float)(15*RAD));
 
   //Rear Gear Right2
   static UINT GGrp21[5] = {18,19,20,21,127};
 
   static MGROUP_ROTATE gear21 (0,GGrp21, 5, _V(1.15901,-0.4520788,-2.172986), _V(0,0,1), (float)(-15*RAD));
 
     //Rear Gear Left3
   static UINT GGrp23[1] = {17};
 
   static MGROUP_ROTATE gear23 (0,GGrp23, 1, _V(-1.15901,-0.4969712,-1.226534), _V(1,0,0), (float)(50*RAD));
 
   //Rear Gear Right3
   static UINT GGrp24[1] = {19};
 
   static MGROUP_ROTATE gear24 (0,GGrp24, 1, _V(1.15901,-0.4969712,-1.226534), _V(1,0,0), (float)(50*RAD));
 
 
   anim_gear = CreateAnimation (0);
 
   AddAnimationComponent  (anim_gear, 0, 0.5, &gear1);
   AddAnimationComponent  (anim_gear, 0.2, 0.5, &gear2);
   AddAnimationComponent  (anim_gear, 0.2, 0.5, &gear3);
 
   AddAnimationComponent  (anim_gear, 0.5, 1, &gear5);
 
   AddAnimationComponent  (anim_gear, 0.5, 1, &gear12);
   AddAnimationComponent  (anim_gear, 0.5, 1, &gear13);
 
 
   AddAnimationComponent  (anim_gear, 0, 0.2, &gear20);
   AddAnimationComponent  (anim_gear, 0, 0.2, &gear21);
 
   AddAnimationComponent  (anim_gear, 0.2, 0.5, &gear23);
   AddAnimationComponent  (anim_gear, 0.2, 0.5, &gear24);
 
I can't see anything wrong in there. Although, my knowledge on creating animations is not that high. Could there be animation is somewhere that moves the entire mesh ? Also do you have a download link so that I could have a look (to see what happen inside the client) ?
Also we could have something like oapiEnableAbsoluteAnimations(VISHANDLE hVisual, bool bSetEnabled) so that absolute animations could be disabled by default and then enabled for vessels those depend on it. The error accumulation isn't a problem in landing gear but it does create problems with robotic arms and ADI balls.
 
  • Like
Reactions: JMW
Also we could have something like oapiEnableAbsoluteAnimations(VISHANDLE hVisual, bool bSetEnabled) so that absolute animations could be disabled by default and then enabled for vessels those depend on it. The error accumulation isn't a problem in landing gear but it does create problems with robotic arms and ADI balls.
Excellent idea, thank you.
I've opened a "conversation" with you as result of your questions.
?
 
Back
Top