How to divide a project?
Ilyas Salman

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

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

Hrvoje Ban
/* 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

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

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.

ReyBrujo

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//////////////////////////////////////////////////////

Michael Faerber
Paul Pridham

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

:P

Ilyas Salman

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

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

Oops! Sorry :)

Ilyas Salman

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

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

Ilyas Salman

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

After the VECTOR. Remember to link against Allegro libraries.

Ilyas Salman

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

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

Ilyas Salman

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

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

Ilyas Salman

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

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).

Ilyas Salman

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

ReyBrujo

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

Ilyas Salman

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

Thread #558270. Printed from Allegro.cc