#100171 - jake2431 - Sat Aug 26, 2006 6:18 pm
Code: |
void checkKeys()
{
if(key[KEY_ESC]) gameover = 1;
}
void game_loop()
{
int gameover = 0;
while(gameover != 1)
{
drawgfx();
if (keypressed())
checkKeys();
}
} |
I'm not sure why I am getting this error:
Code: |
astrofuntions.h: In function `checkKeys':
astrofuntions.h:24: error: `gameover' undeclared (first use in this function) |
When I initialize gameover in game_loop() isn't it being declared?
#100174 - gmiller - Sat Aug 26, 2006 6:28 pm
gameover's "scope" does not define it in the code where you reference it. The actual delcaration scope limits it to just the function gameloop. If you move the declaration outside the function the code would work. C/C++ does not allow inplicit forward declarations so mode the declaration to the top of the source file. If you want gameover to only be "seen" by code in this source file just put the keyword "static" in front of it to keep from having it be "seen" by all object files by default.
Last edited by gmiller on Sat Aug 26, 2006 6:31 pm; edited 2 times in total
#100175 - kevinc - Sat Aug 26, 2006 6:28 pm
But only inside game_loop. If you want it to be visible outside that function, declare it outside:
Code: |
int gameover;
void checkKeys()
{
...
}
void game_loop()
{
...
} |
_________________
http://akzeac.blogspot.com
#100177 - Cearn - Sat Aug 26, 2006 6:34 pm
EDIT: never mind, ninja'd twice.
Still: do not put functions in header files; put code in source files, compile separately and then link them.
#100192 - tepples - Sat Aug 26, 2006 7:58 pm
Cearn wrote: |
Still: do not put functions in header files |
Except inline and template functions, right?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#100205 - sajiimori - Sat Aug 26, 2006 8:30 pm
The only general way to put it is: Don't put things with linkage in header files. Unfortunately, the concept of linkage is not a beginner topic because the rules are subtle (especially for static const data and the moment of instantiation for templates), so conservative guidelines like "don't put code in headers" can help for starters.
#100209 - jake2431 - Sat Aug 26, 2006 9:22 pm
Oh thanks! I assumed that since the variable was initialized in the function where the function that used it was nested that the nested function could 'see' it. I don't know why I thought that would work.
Also, Cearn, yeah I remember that I shouldn't do that(read it in TONc of one of the C standards or somewhere), but I am not sure how compiling source files and linking them to a project works since I have never seen an example. So I am just trying to organize the code the best way I currently know how. I would love it if someone could quickly explane it. I'm sure it's simple I've just never seen it done. Also, thanks for stating that I would appreciate it very much for people to correct my standards errors so that I can become a better programmer.
#100211 - tepples - Sat Aug 26, 2006 9:29 pm
To get the hang of multiple files in a project, I'd suggest making something on the PC. The general GCC invocation syntax for this use is as follows:
Code: |
gcc -Wall -O -c file1.c -o file1.o
gcc -Wall -O -c file2.c -o file2.o
gcc -Wall -O -c file3.c -o file3.o
gcc file1.o file2.o file3.o -o file.exe
|
EDIT: correct -c flag use
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
Last edited by tepples on Sat Aug 26, 2006 9:48 pm; edited 1 time in total
#100213 - jake2431 - Sat Aug 26, 2006 9:43 pm
Oh, I am making it on the PC. I am learning Allegro right now and that is what the program is written in. I am trying to make a simple game out of the vector art routines. So a source file doesn't have to have a main funtion in it to compile? And what exactly should go into a header file?
#100223 - tepples - Sat Aug 26, 2006 9:58 pm
A header file should have function prototypes and 'extern' variable declarations.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#100241 - jake2431 - Sat Aug 26, 2006 11:34 pm
I changed them all to .c source files instead and when I try to compile I get:
Code: |
Compiler: Default compiler
Building Makefile: "C:\Documents and Settings\Jake\Desktop\AstroDelta\Makefile.win"
Executing make...
make.exe -f "C:\Documents and Settings\Jake\Desktop\AstroDelta\Makefile.win" all
gcc.exe -c main.c -o main.o -I"C:/Dev-Cpp/include"
gcc.exe -c astrostructs.c -o astrostructs.o -I"C:/Dev-Cpp/include"
gcc.exe -c draw.c -o draw.o -I"C:/Dev-Cpp/include"
gcc.exe -c astrofunctions.c -o astrofunctions.o -I"C:/Dev-Cpp/include"
gcc.exe main.o astrostructs.o draw.o astrofunctions.o AstroDelta_private.res -o "AstroDelta.exe" -L"C:/Dev-Cpp/lib" -mwindows -lalleg
draw.o(.text+0x0):draw.c: multiple definition of `erPlyrShip'
main.o(.text+0x0):main.c: first defined here
draw.o(.text+0x67):draw.c: multiple definition of `drawPlyrShip'
main.o(.text+0x67):main.c: first defined here
draw.o(.text+0xfe):draw.c: multiple definition of `erEnShip'
main.o(.text+0xfe):main.c: first defined here
draw.o(.text+0x165):draw.c: multiple definition of `drawEnShip'
main.o(.text+0x165):main.c: first defined here
draw.o(.text+0x1fc):draw.c: multiple definition of `erPlyrBullet'
main.o(.text+0x1fc):main.c: first defined here
draw.o(.text+0x201):draw.c: multiple definition of `drawPlyrBullet'
main.o(.text+0x201):main.c: first defined here
draw.o(.text+0x264):draw.c: multiple definition of `erEnBullets'
main.o(.text+0x264):main.c: first defined here
draw.o(.text+0x269):draw.c: multiple definition of `drawEnBullets'
main.o(.text+0x269):main.c: first defined here
draw.o(.text+0x2d8):draw.c: multiple definition of `drawgfx'
main.o(.text+0x2d8):main.c: first defined here
astrofunctions.o(.text+0x0):astrofunctions.c: multiple definition of `erPlyrShip'
main.o(.text+0x0):main.c: first defined here
astrofunctions.o(.text+0x67):astrofunctions.c: multiple definition of `drawPlyrShip'
main.o(.text+0x67):main.c: first defined here
astrofunctions.o(.text+0xfe):astrofunctions.c: multiple definition of `erEnShip'
main.o(.text+0xfe):main.c: first defined here
astrofunctions.o(.text+0x165):astrofunctions.c: multiple definition of `drawEnShip'
main.o(.text+0x165):main.c: first defined here
astrofunctions.o(.text+0x1fc):astrofunctions.c: multiple definition of `erPlyrBullet'
main.o(.text+0x1fc):main.c: first defined here
astrofunctions.o(.text+0x201):astrofunctions.c: multiple definition of `drawPlyrBullet'
main.o(.text+0x201):main.c: first defined here
astrofunctions.o(.text+0x264):astrofunctions.c: multiple definition of `erEnBullets'
main.o(.text+0x264):main.c: first defined here
astrofunctions.o(.text+0x269):astrofunctions.c: multiple definition of `drawEnBullets'
main.o(.text+0x269):main.c: first defined here
astrofunctions.o(.text+0x2d8):astrofunctions.c: multiple definition of `drawgfx'
main.o(.text+0x2d8):main.c: first defined here
astrofunctions.o(.text+0x308):astrofunctions.c: multiple definition of `init'
main.o(.text+0x308):main.c: first defined here
astrofunctions.o(.text+0x34b):astrofunctions.c: multiple definition of `gfx_mode'
main.o(.text+0x34b):main.c: first defined here
astrofunctions.o(.text+0x37f):astrofunctions.c: multiple definition of `checkKeys'
main.o(.text+0x37f):main.c: first defined here
astrofunctions.o(.text+0x39b):astrofunctions.c: multiple definition of `game_loop'
main.o(.text+0x39b):main.c: first defined here
astrofunctions.o(.text+0x3cb):astrofunctions.c: multiple definition of `shutdown'
main.o(.text+0x3cb):main.c: first defined here
collect2: ld returned 1 exit status
make.exe: *** [AstroDelta.exe] Error 1
Execution terminated
|
I get a lot of errors saying that I have multiple definitions.
#100242 - Sausage Boy - Sat Aug 26, 2006 11:38 pm
Don't declare the variables in every source file, use externs. for example:
blah.h:
extern int important_blah_number;
main.c:
#include "blah.h"
blah.c:
#include "blah.h"
int important_blah_number;
blfsda.c:
#include "blah.h"
qwerty.c:
#include "blah.h"
This way every source file will be able to access important_blah_number.
_________________
"no offense, but this is the gayest game ever"
#100244 - sajiimori - Sat Aug 26, 2006 11:47 pm
Are you having main.c include all the other .c files or something? It says practically everything is defined in main.c.
Remember that using #include is the same as copying and pasting the entire contents of a file into another file.
#100245 - jake2431 - Sat Aug 26, 2006 11:50 pm
I don't think they are declared in every source file, only declared once, then used in different files. Maybe I'm wrong and thinking you are saying something else.
#100249 - jake2431 - Sun Aug 27, 2006 12:01 am
main.c includes "astrofunctions.c", astrofunctions.c includes "draw.c", draw.c includes "allegro.h" and "astrostructs.c". I know that it puts the whole file into the file that it is '#include'd into, but I thought that I needed to include the files to use functions or structs from other sources.
To make the code easy to read and navigate I have my main.c allong with 3 other sourcefiles. astrofunctions.c has generic funtions used in the game, my main.c only has this Code: |
#include "astrofunctions.c"
void main(void)
{
init();//initialize game utilities
gfx_mode();//setup graphics mode
game_loop();//game's while loop
shutdown();//shutdown game
}
END_OF_MAIN(); |
because I wanted to keep it extremly simple and easy to refer back to when creating new games, astrostructs.c has ship and bullet structs that are to be used by the game_loop() in astrofunctions.c, and draw.c have vector routines for drawing ships and bullets that use variables from astrostructs.c like enShip.x or enBullet.y for example. This may be thw worst way to do things, but I have taught myself C thus far and am trying to learn better ways and this is the only way I know how(asking you guys). I've searched for numerous this on google (like "basic game structure" for example), but I can't find much relavant and when I do I am not sure if it is proper coding or just some guy's "opinion" of how it should be written.
#100254 - tepples - Sun Aug 27, 2006 12:12 am
jake2431 wrote: |
main.c includes "astrofunctions.c" |
Bad. Each .c file should include only .h files, and in the common case, .h files should contain only function prototypes (not implementations) and extern declarations. Using a separate file name suffix lets you and other developers distinguish files that define interface (.h) from files that define implementation (.c).
That should be int main(void) thank you very much.
Quote: |
I've searched for numerous this on google (like "basic game structure" for example) |
[[Header file]] should help.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#100258 - jake2431 - Sun Aug 27, 2006 12:38 am
Okay now it's int main(void) and return 0;
If I take out all the include .c I won't be able to have seperate .c files to have funtions in one structs in another and so on and so forth ? So everything except funtion prototypes and extern variables goes into the main.c? That can't be right, but when I take out the includes the code won't compile. This is turning out to be harder than I thought it would be. I know it would be simple if I had someone to show me, but alas I do not.
#100260 - tepples - Sun Aug 27, 2006 12:57 am
jake2431 wrote: |
Okay now it's int main(void) and return 0;
If I take out all the include .c I won't be able to have seperate .c files to have funtions in one structs in another and so on and so forth ? |
You keep the functions in separate .c files, but you compile them to separate .o files. You use .h files so that functions can see the functions and data in other .o files.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#100274 - poslundc - Sun Aug 27, 2006 4:19 am
jake2431 wrote: |
Okay now it's int main(void) and return 0;
If I take out all the include .c I won't be able to have seperate .c files to have funtions in one structs in another and so on and so forth ? So everything except funtion prototypes and extern variables goes into the main.c? That can't be right, but when I take out the includes the code won't compile. This is turning out to be harder than I thought it would be. I know it would be simple if I had someone to show me, but alas I do not. |
The short of it is (and I realize I'm repeating some of what's already been said, but it can't be drilled down to much simpler than this):
- Executable code (ie. your functions) and data (ie. your variables) go in .c files. Whether they're all in one .c file (not a terribly good idea) or spread out across multiple .c files that group them according to their purpose (pretty darn good idea) doesn't make a difference.
- Code that describes how to access those functions and those variables, such as:
- Structures and typedefs
- Function prototypes
- Variable declarations with the keyword extern in front of them, and
- Constants and macros
... go in header files.
- You only ever #include header files. Never #include C files.
- Every C file has a corresponding header file. If you realize a function in one C file (file "foo") needs to call a function located in a different C file (file "bar"), you #include bar's header file into foo's C file, and like magic you can call those functions.
There are some exceptions, of course. But if you can get the above to work for you then you should be in good shape.
Dan.
#100292 - jake2431 - Sun Aug 27, 2006 7:16 am
Okay, thanks guys. Thanks for that Dan. The above post is a great organization of this topic in general. That is what I want to be able to do: have seperate files for parts of the program. The only way I knew how to do it happened to be the worst way. Now I just have to figure out how to make this work.
The only thing I don't get is how including bars header file in foo make it where you can use data stored in a separate source file. Like if I have a value stored in a variable in a struct I will be able to use that value in another source file ust by including the others header file? That doesn't make since to me.
#100308 - keldon - Sun Aug 27, 2006 9:14 am
Basically think of it this way. Each .c/data file should compile independantly of any other .c file. How you achieve this is with the use of header files. The header files allow each file to know what variable names exist, their type, and their size (if applicable), but without the need to be linked to it when it compiles.
When you read about dependencies in this makefile tutorial you may get a better idea of why this is important and how it works.
#100544 - jake2431 - Mon Aug 28, 2006 4:27 pm
Thanks Keldon, that tutorial helps. I think I pretty much understand how this works now. If I get stuck trying to rework my code I will ask for more help. Another question though. Where should my structs be defined? I have them by theirselves in a header file before I change things. I want them in a separate file, but usable from other source files.
#100677 - jake2431 - Tue Aug 29, 2006 4:12 pm