Help needed with linking....

Started by
30 comments, last by Moe 22 years, 8 months ago
I seem to be having a small bit of trouble getting the files of my project to fit in with eachother well. I have a main d3d.h and d3d.cpp for my wrapper (for Direct 3D), a di.h and di.cpp (for my Direct Input wrapper), and a timer.cpp which needs to be accessed in the di.h and di.cpp. Anyway, I was wondering if anyone would be so kind as to help me out. I have bundled up the source code into a .zip file which should be accesible here. All you need to do is download it, see what I mean, and try to figure out how to fix it. Thanks in advance. Edited by - Moe on August 8, 2001 12:13:21 PM
Advertisement
Anyone?
I got it to work fine and display a nice black window, and I only had to add 9 lines.

At the top of each header, add

    #ifndef _D3D_H_       //or whatever the header is called#define _D3D_H_       ...at the end of the header#endif    


If you do that in all your headers, you can include stuff from one header to the other, although you should keep #includes out of the header file as much as possible.

There are some more things you could fix up, but I didn't know if you wanted a fix or a code review.

Edited by - Big B on August 8, 2001 7:14:15 PM
How about both.
Gamedev code reviews would be a really cool thing to start. I've only ever had 2, but in both I learned a lot. It would help newbies out and give some of the pros(not me) a chance to flex their coding skills.

Well Moe, here it goes, and DON'T TAKE ANYTHING PERSONALLY (its unprofessional):

General Comments

  • Your use of comments is good. They give a good sense of whats going on and keep it from looking like just a big ball of code.
  • Real OOPers might lambast you for having everything public. I won't because thats what my project looks like.
  • You should use const instead of #define. Its type safe and makes your code look more C++ish.
  • Don't use #pragma once, since #ifndef/#endif will take care of all your worries.
  • Overall, a good design. Its not populated with any game specific code yet, but it should be easy to use this "engine" for pretty much anything, with some additions naturally.


All line numbers are before any additions to the code.

gamestate.h

  • 13-22 - Use an enum instead of all those defines. That way you don't have to keep track of the numbers and the GAMESTATE would be its own type in a way.
  • 28 - #pragma twice? The first one isn't necessary, so the second one really isn't.
  • 30,31 - Don't need the includes in this file. Put the includes in the gamestate.cpp and use a forward declaration to declare class D3D. That way if di.h or d3d.h changes, it wouldn't change gamestate.h and everything that includes it. It will cut down on compile times if/when you have more source files that include gamestate.h
  • 56-60 - Specify the return type. By default it is an int, but that might not be so apparent to others and may complain on other compilers. Its just a good habit to get into.


di.h

  • 15 - Use const (see general comments)
  • 28 - is hWnd ever initialized? Looking through di.cpp I don't think it is. Maybe have a constructor to set it to 0 and initialize everything to NULL or 0.
  • 31,32,35,38,39,42,45 - Specify return type, same reason.


d3d.h

  • 10 - move include to d3d.cpp. Its just better to have the includes in the source (forget why).
  • 12 - mmsystem.h included twice? Just incase, right
  • 15,16 - use const.
  • 30,31,47-50 - specify return type.


gamestate.cpp

  • 63 - could be used in a destructor. That way your d3d::D3Dshutdown will be called no matter what. Its one of the advantages of OOP. You might not be able to check if everything cleaned up properly, but since your shutting down, its not your problem anymore.


d3d.cpp

  • 26,28-30,32,33 - use false instead of 0. Its a bool so treat it like one (besides, false is a keyword so it adds colour to your code)
  • 194 - could use a destructor. Same reasons.
  • 244,286 - return 2 ? Instead of 2 a constant should be used in case you decide to use 3. And why 2?


di.cpp

  • It's all good!


prototype.cpp

  • 49 - use bool instead of "BOOL" and false instead of "FALSE". Its looks more C++ish and adds colour to your code.





Whew, all done. Whether you take any of this advice or not is up to you, but I believe it would be to your advantage.

I'll let you look at my project when I have a build I am happy with, and you can tear it apart to your hearts content.

Happy Coding

P.S. - remember not to take anything personally

EDIT - dang unordered lists!


Edited by - Big B on August 8, 2001 11:40:05 PM
Don''t worry, I won''t take it personally. Thats got to be the best review of code I have ever seen. I really appreciate it. Its always nice to see people''s comments on my code. I will probably make most of those changes.

Oh, and you seem like a pretty professional coder/programmer yourself.
I have some comments to your code..

I just looked it over very quickly.

I think you should try and make the various components more independant of each other. For example your input code.

You pass your gamestate to your input code and make decisions based on that gamestate.
That will make it harder to reuse your input code another time.

And don´t call your objects something like "gs". I know gs = gamestate but when your project grows big and has a lot of objects called "gs" and "fp" and "gt" then it might get confusing. And you only call gs in your winmain code so there is really no need to make the name so short since you don´t have to type it so many times...

Well thats all...See ya...



-- Look at you hacker. A Pathetic creature of meat and bone, panting and sweating as you run through my corridors. How can you challenge a perfect, immortal machine?--

"Yeah, I''ve seen people w/ ''so-called'' lives. They are petty and thoughtless." - Nazrix
-------------Ban KalvinB !
Of all the stupid things:

I can''t get the enum thing to work. I have something like:
  //the gamestate typesenum STATE {	INIT,				//initialization	INTRO,				//show intro movie/script	MENU,				//menu state	RENDER,				//main rendering state	INGAMEMENU,			//in game menu state - eg pause, inventory...	SHUTDOWN			//shutdown};  

in gamestate.h. Now I can''t get it to work with di.h and di.cpp. The function prototype looks like this:
  InputHandler(STATE &Gamestate, TIMER &tmr);  

What am I doing wrong? I have tried everything but the stupid thing just won''t work. Anyone?
Also, how do I do that forward declaration that you described for gamestate.h? I haven''t had much experience with this type of thing.
Hi Moe,

I haven''t looked at your code, and I''m not too sure about the advice I''m about to give you, but it would probably be worth your while to look it up:

I think that the forward declaration is done with the "extern" keyword, where you declare the function in all of your files with "extern" in front it. This tells the compiler that the implementation of the function is "external" to the file, so it skips over it (of course, you''ll get an error if the function does not exist in your project at all).

Naturally, the better way to do this is to put all your global function declarations and global objects/variables in a file called globals.h. Type them all with "extern" in front. Include this file in all .cpp files as one of your standard header files. Actually implement the functions and objects in a globals.cpp file (without "extern"s ).

This technique might work for your enum problem too, but I''m REALLY not sure if you can or should do it (I''ve not had much experience with enums yet!)

If I''ve misinterpreted the words "forward declaration" then sorry for wasting your time!!! Otherwise I hope this helps you out!

Gareth

This topic is closed to new replies.

Advertisement