Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » How to divide a project?

This thread is locked; no one can reply to it. rss feed Print
How to divide a project?
Ilyas Salman
Member #6,762
January 2006
avatar

I searched but didn't found a clear answer or an example. I want to make a seperate file for inputs, so I did a INPUT() function that links to the other file (input.c als tried input.h), but always I had errors, can someone please give me an example for placing the input as a functon or some other method , witch will work.

Thanks very much.

Jonatan Hedborg
Member #4,886
July 2004
avatar

Im not quite sure i understand the question. How does your file-structure look at the moment?
In general, afaik, it works like this:
The .c/cpp file contains the "body" of the functions, and then you include file.h in any file where you want to use test().

//file.c
#include "file.h"

void test()
{
printf("whatever\n");
}

//file.h
void test();

EDIT: ah yes, also header guards

-------
Sweden: Free from the shackles of Democracy since 2008-06-18!

Hrvoje Ban
Member #4,537
April 2004
avatar

/* input.h - input header */

/* include guard, to prevend this file from being include more then once
 * inside singe source file
 */
#ifndef INPUT_H
#define INPUT_H

/* declaration */
void input(void);

#endif

/* input.c - input source file */
#include "input.h"

void input(void)
{
   /* ... */
}

/* main.c */
#include "input.h"

int main(void)
{
   /* ... */
   input();
   /* ... */
   return 0;

}
END_OF_MAIN()

Ilyas Salman
Member #6,762
January 2006
avatar

I still have errors, INCREDEMENT_X undeclared,...

my codes:
/////////////////////////////////////////////////////
#ifndef INPUT_C
#define INPUT_C
void INPUT(){
while (game_time > 0) {
if (key[KEY_LEFT])
sprite_position.x -= INCREMENT_X;
if (key[KEY_RIGHT])
sprite_position.x += INCREMENT_X;
if (key[KEY_UP])
sprite_position.y -= INCREMENT_Y;
if (key[KEY_DOWN])
sprite_position.y += INCREMENT_Y;
if (key[KEY_SPACE])
sprite_position.y += 0.30;

if (key[KEY_ESC])
user_wants_to_quit = TRUE;
--game_time;
}
#endif
//////////////////////////////////////////////////////
#include <allegro.h>
#include "input_now.c"
#define INCREMENT_X 0.25
#define INCREMENT_Y 0.25
volatile int game_time;
volatile int sec_counter;
typedef struct{
double x,y;
}VECTOR;
int init_timer(void);
void game_timer(void) {
game_time++;
}
END_OF_FUNCTION(game_timer);
void game_sec_timer(void) {
sec_counter++;
}
END_OF_FUNCTION(game_sec_timer);
int init_timer(void) {
install_timer();
if (install_int(game_timer, 1) < 0)
return 1;
if (install_int(game_sec_timer, 1000) < 0)
return 1;
sec_counter = 0;
game_time = 0;
LOCK_VARIABLE(game_time);
LOCK_VARIABLE(sec_counter);
LOCK_FUNCTION(game_timer);
LOCK_FUNCTION(game_sec_timer);
return 0;
}
int main() {
int current_fps = 0;
int fps = 0;
int user_wants_to_quit = FALSE;
BITMAP* le_sprite;
BITMAP* buffer;
unsigned long last_sec_counter = 0;
VECTOR sprite_position;
allegro_init();
install_keyboard();
if (init_timer() != 0) {
allegro_message("Erreur lors de l'initialisation des timers!");
return 1;
}
install_mouse();
set_color_depth(16);
if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640,480, 0, 0) != 0) {
allegro_message("Impossible d'initialiser le mode vidéo!");
return 1;
}
le_sprite = load_bitmap("ship105.bmp", NULL);
if (!le_sprite) {
set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
allegro_message ("Erreur : imposible de charger le bitmap!");
return 1;
}
buffer = create_bitmap(SCREEN_W, SCREEN_H);
if (!buffer) {
set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
allegro_message ("Erreur : imposible de créer le buffer!");
return 1;
}
sprite_position.x = SCREEN_W / 2;
sprite_position.y = SCREEN_H / 2;
/* Boucle principale du jeu */
while (user_wants_to_quit == FALSE) {
INPUT();
}
if (sec_counter != last_sec_counter) {
fps = current_fps;
last_sec_counter = sec_counter;
current_fps = 0;
}
current_fps++;
clear_bitmap(buffer);
draw_sprite(buffer, le_sprite, sprite_position.x, sprite_position.y);
text_mode(-1);
textprintf_centre(buffer, font, SCREEN_W / 2, 0, makecol(195,125,255), "FPS : %d", fps);
textprintf_centre(buffer, font, SCREEN_W / 2, 20, makecol(195,125,255), "Mouse coordinates : %d,%d", mouse_x,mouse_y);
blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
}
destroy_bitmap(le_sprite);
destroy_bitmap(buffer);
return 0;
}
END_OF_MAIN();
//////////////////////////////////////////////////////

Jonatan Hedborg
Member #4,886
July 2004
avatar

Please use the code tags. Until then i can tell you straight away that it's bad practice to include c files. it's just EVIL.
As we said, have a header file (.h) with the declaration (ie, void INPUT();, header guards and such) and a c file which you compile naturally. And then include the header file in any file you want to use INPUT(). You should also consider using a more ... normal namning convention, all-cap names are usualy macros or typedefs.

Also, you add increment_x after you include the file, so it never sees them.

-------
Sweden: Free from the shackles of Democracy since 2008-06-18!

ReyBrujo
Moderator
January 2001
avatar

You should use something like this:

// input.h
#ifndef INPUT_H
#define INPUT_H

#define INCREMENT_X 0.25
#define INCREMENT_Y 0.25

typedef struct{
    double x,y;
}VECTOR;

extern int user_wants_to_quit;
extern volatile int game_time;

#endif

1// input.c
2#include <allegro.h>
3#include "input.h"
4 
5int user_wants_to_quit = FALSE;
6 
7void INPUT(VECTOR *sprite_position){
8 while (game_time > 0) {
9 if (key[KEY_LEFT])
10 sprite_position->x -= INCREMENT_X;
11 if (key[KEY_RIGHT])
12 sprite_position->x += INCREMENT_X;
13 if (key[KEY_UP])
14 sprite_position->y -= INCREMENT_Y;
15 if (key[KEY_DOWN])
16 sprite_position->y += INCREMENT_Y;
17 if (key[KEY_SPACE])
18 sprite_position->y += 0.30;
19 
20 if (key[KEY_ESC])
21 user_wants_to_quit = TRUE;
22 --game_time;
23 }
24}

1// main.c
2#include <allegro.h>
3#include "input.h"
4 
5volatile int game_time;
6volatile int sec_counter;
7 
8int init_timer(void);
9 void game_timer(void) {
10 game_time++;
11}
12END_OF_FUNCTION(game_timer);
13 
14void game_sec_timer(void) {
15 sec_counter++;
16}
17END_OF_FUNCTION(game_sec_timer);
18 
19int init_timer(void) {
20 install_timer();
21 if (install_int(game_timer, 1) < 0)
22 return 1;
23 
24 if (install_int(game_sec_timer, 1000) < 0)
25 return 1;
26 
27 sec_counter = 0;
28 game_time = 0;
29 LOCK_VARIABLE(game_time);
30 LOCK_VARIABLE(sec_counter);
31 LOCK_FUNCTION(game_timer);
32 LOCK_FUNCTION(game_sec_timer);
33 
34 return 0;
35}
36 
37int main() {
38 int current_fps = 0;
39 int fps = 0;
40 
41 BITMAP* le_sprite;
42 BITMAP* buffer;
43 unsigned long last_sec_counter = 0;
44 VECTOR sprite_position;
45 allegro_init();
46 install_keyboard();
47 if (init_timer() != 0) {
48 allegro_message("Erreur lors de l'initialisation des timers!");
49 return 1;
50 }
51 install_mouse();
52 set_color_depth(16);
53 if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640,480, 0, 0) != 0) {
54 allegro_message("Impossible d'initialiser le mode vidéo!");
55 return 1;
56 }
57 le_sprite = load_bitmap("ship105.bmp", NULL);
58 if (!le_sprite) {
59 set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
60 allegro_message ("Erreur : imposible de charger le bitmap!");
61 return 1;
62 }
63 buffer = create_bitmap(SCREEN_W, SCREEN_H);
64 if (!buffer) {
65 set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
66 allegro_message ("Erreur : imposible de créer le buffer!");
67 return 1;
68 }
69 
70 sprite_position.x = SCREEN_W / 2;
71 sprite_position.y = SCREEN_H / 2;
72 /* Boucle principale du jeu */
73 while (user_wants_to_quit == FALSE) {
74 INPUT();
75 
76 if (sec_counter != last_sec_counter) {
77 fps = current_fps;
78 last_sec_counter = sec_counter;
79 current_fps = 0;
80 }
81 
82 current_fps++;
83 clear_bitmap(buffer);
84 draw_sprite(buffer, le_sprite, sprite_position.x, sprite_position.y);
85 text_mode(-1);
86 textprintf_centre(buffer, font, SCREEN_W / 2, 0, makecol(195,125,255), "FPS : %d", fps);
87 textprintf_centre(buffer, font, SCREEN_W / 2, 20, makecol(195,125,255), "Mouse coordinates : %d,%d", mouse_x,mouse_y);
88 blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
89 }
90 destroy_bitmap(le_sprite);
91 destroy_bitmap(buffer);
92 return 0;
93}
94END_OF_MAIN();
95//////////////////////////////////////////////////////

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Michael Faerber
Member #4,800
July 2004
avatar

--
"The basic of informatics is Microsoft Office." - An informatics teacher in our school
"Do you know Linux?" "Linux? Isn't that something for visually impaired people?"

Paul Pridham
Member #250
April 2000
avatar

You know, your life would be so much easier if you just used STL and OpenLayer.

:P

Ilyas Salman
Member #6,762
January 2006
avatar

Now, I made paste what ReyBrujo wrote, I had only one error (and few warnings), it didn't recognize the input function, I made the function extern void INPUT(); in main.cpp. Now the program begins but without input. What is the cause?

Hrvoje Ban
Member #4,537
April 2004
avatar

You don't make function by using extern (or just ending it with semicolon without body), you tell compiler that it's placed in another file.

In ReyBrujo code, in input.h INPUT takes pointer to VECTOR, but in main.cpp it's used without parameters.

EDIT: You need to change this in main.cpp

    while (user_wants_to_quit == FALSE) {
        INPUT(&sprite_position);

ReyBrujo
Moderator
January 2001
avatar

Oops! Sorry :)

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Ilyas Salman
Member #6,762
January 2006
avatar

I made the correction, but I have the same problem, I rewrite the code:

1// main.cpp
2#include <allegro.h>
3#include "Input.h"
4 
5volatile int game_time;
6volatile int sec_counter;
7 
8int init_timer(void);
9 void game_timer(void) {
10 game_time++;
11}
12END_OF_FUNCTION(game_timer);
13 
14void game_sec_timer(void) {
15 sec_counter++;
16}
17END_OF_FUNCTION(game_sec_timer);
18 
19int init_timer(void) {
20 install_timer();
21 if (install_int(game_timer, 1) < 0)
22 return 1;
23 
24 if (install_int(game_sec_timer, 1000) < 0)
25 return 1;
26 
27 sec_counter = 0;
28 game_time = 0;
29 LOCK_VARIABLE(game_time);
30 LOCK_VARIABLE(sec_counter);
31 LOCK_FUNCTION(game_timer);
32 LOCK_FUNCTION(game_sec_timer);
33 
34 return 0;
35}
36 
37int main() {
38 int current_fps = 0;
39 int fps = 0;
40 
41 BITMAP* le_sprite;
42 BITMAP* buffer;
43 unsigned long last_sec_counter = 0;
44 VECTOR sprite_position;
45 allegro_init();
46 install_keyboard();
47 if (init_timer() != 0) {
48 allegro_message("Erreur lors de l'initialisation des timers!");
49 return 1;
50 }
51 install_mouse();
52 set_color_depth(16);
53 if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640,480, 0, 0) != 0) {
54 allegro_message("Impossible d'initialiser le mode vidéo!");
55 return 1;
56 }
57 le_sprite = load_bitmap("ship105.bmp", NULL);
58 if (!le_sprite) {
59 set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
60 allegro_message ("Erreur : imposible de charger le bitmap!");
61 return 1;
62 }
63 buffer = create_bitmap(SCREEN_W, SCREEN_H);
64 if (!buffer) {
65 set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
66 allegro_message ("Erreur : imposible de créer le buffer!");
67 return 1;
68 }
69 
70 sprite_position.x = SCREEN_W / 2;
71 sprite_position.y = SCREEN_H / 2;
72 /* Boucle principale du jeu */
73 while (user_wants_to_quit == FALSE) {
74 INPUT(&sprite_position);
75 
76 if (sec_counter != last_sec_counter) {
77 fps = current_fps;
78 last_sec_counter = sec_counter;
79 current_fps = 0;
80 }
81 
82 current_fps++;
83 clear_bitmap(buffer);
84 draw_sprite(buffer, le_sprite, sprite_position.x, sprite_position.y);
85 text_mode(-1);
86 textprintf_centre(buffer, font, SCREEN_W / 2, 0, makecol(195,125,255), "FPS : %d", fps);
87 textprintf_centre(buffer, font, SCREEN_W / 2, 20, makecol(195,125,255), "Mouse coordinates : %d,%d", mouse_x,mouse_y);
88 blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
89 }
90 destroy_bitmap(le_sprite);
91 destroy_bitmap(buffer);
92 return 0;
93}
94END_OF_MAIN();

1// input.c
2#include <allegro.h>
3#include "input.h"
4 
5int user_wants_to_quit = FALSE;
6 
7void INPUT(VECTOR *sprite_position){
8 while (game_time > 0) {
9 if (key[KEY_LEFT])
10 sprite_position->x -= INCREMENT_X;
11 if (key[KEY_RIGHT])
12 sprite_position->x += INCREMENT_X;
13 if (key[KEY_UP])
14 sprite_position->y -= INCREMENT_Y;
15 if (key[KEY_DOWN])
16 sprite_position->y += INCREMENT_Y;
17 if (key[KEY_SPACE])
18 sprite_position->y += 0.30;
19 if (key[KEY_ESC])
20 user_wants_to_quit = TRUE;
21 --game_time;
22 }
23}

// input.h
#ifndef INPUT_H
#define INPUT_H

#define INCREMENT_X 0.25
#define INCREMENT_Y 0.25

typedef struct{
    double x,y;
}VECTOR;

extern int user_wants_to_quit;
extern volatile int game_time;

#endif   

ReyBrujo
Moderator
January 2001
avatar

Add void INPUT(VECTOR *); to input.h.

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Ilyas Salman
Member #6,762
January 2006
avatar

Where exactly? I placed iy before, in the vector and at the end of the vector but I had warnings at the compiler couldn't make an .exe.

Thanks.

ReyBrujo
Moderator
January 2001
avatar

After the VECTOR. Remember to link against Allegro libraries.

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Ilyas Salman
Member #6,762
January 2006
avatar

I have the same problem:

1#ifndef INPUT_H
2#define INPUT_H
3 
4#include <allegro.h>
5 
6#define INCREMENT_X 0.25
7#define INCREMENT_Y 0.25
8 
9 
10typedef struct{
11 
12 double x,y;
13}VECTOR;
14void INPUT(VECTOR *);
15 
16extern int user_wants_to_quit;
17extern volatile int game_time;
18#endif

Jonatan Hedborg
Member #4,886
July 2004
avatar

Don't forget to do a full recompile after you (only) change a header file.

-------
Sweden: Free from the shackles of Democracy since 2008-06-18!

Ilyas Salman
Member #6,762
January 2006
avatar

Yet, I have the same problem, can you please try to compile it on your system?
I have: no new line at end of file.

ReyBrujo
Moderator
January 2001
avatar

That is not an error, but a warning. Put a ENTER at the end of all your files.

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Ilyas Salman
Member #6,762
January 2006
avatar

I did what you said, without succes, then I saw that I forgot in input.c the ifndefs, so:

1#ifndef INPUT_C
2#define INPUT_C
3 
4#include <allegro.h>
5#include "input.h"
6 
7int user_wants_to_quit = FALSE;
8 
9void INPUT(VECTOR *sprite_position){
10 while (game_time > 0) {
11 if (key[KEY_LEFT])
12 sprite_position->x -= INCREMENT_X;
13 if (key[KEY_RIGHT])
14 sprite_position->x += INCREMENT_X;
15 if (key[KEY_UP])
16 sprite_position->y -= INCREMENT_Y;
17 if (key[KEY_DOWN])
18 sprite_position->y += INCREMENT_Y;
19 if (key[KEY_SPACE])
20 sprite_position->y += 0.30;
21 if (key[KEY_ESC])
22 user_wants_to_quit = TRUE;
23 --game_time;
24 }
25}
26END_OF_FUNCTION(INPUT)
27#endif

I also recompiled all (with and without the addition of ifndefs to input.c), I have: undefined reference to `INPUT(VECTOR*)'

ReyBrujo
Moderator
January 2001
avatar

You don't need the ifdef/endif in the C files, only in the headers (H files). As for the error, have you compiled the input.cpp too? The INPUT(VECTOR *) function is inside input.cpp, if you don't compile it, you will get that undefined error. And remove that END_OF_FUNCTION(INPUT).

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Ilyas Salman
Member #6,762
January 2006
avatar

I don't even have a input.cpp, only the main.cpp, how must it be written?
Thanks very very much.

ReyBrujo
Moderator
January 2001
avatar

Your input.cpp file is the one you posted here. Just add it to your project (I am guessing you are using MSVC6).

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Ilyas Salman
Member #6,762
January 2006
avatar

The input.c I changed to input.cpp, and it worked. Thanks!!
(I use codeblocks)

Go to: