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.
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
/* 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()
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();
//////////////////////////////////////////////////////
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.
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 | |
5 | int user_wants_to_quit = FALSE; |
6 | |
7 | void 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 | |
5 | volatile int game_time; |
6 | volatile int sec_counter; |
7 | |
8 | int init_timer(void); |
9 | void game_timer(void) { |
10 | game_time++; |
11 | } |
12 | END_OF_FUNCTION(game_timer); |
13 | |
14 | void game_sec_timer(void) { |
15 | sec_counter++; |
16 | } |
17 | END_OF_FUNCTION(game_sec_timer); |
18 | |
19 | int 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 | |
37 | int 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 | } |
94 | END_OF_MAIN(); |
95 | ////////////////////////////////////////////////////// |
You know, your life would be so much easier if you just used STL and OpenLayer.
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?
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);
Oops! Sorry
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 | |
5 | volatile int game_time; |
6 | volatile int sec_counter; |
7 | |
8 | int init_timer(void); |
9 | void game_timer(void) { |
10 | game_time++; |
11 | } |
12 | END_OF_FUNCTION(game_timer); |
13 | |
14 | void game_sec_timer(void) { |
15 | sec_counter++; |
16 | } |
17 | END_OF_FUNCTION(game_sec_timer); |
18 | |
19 | int 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 | |
37 | int 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 | } |
94 | END_OF_MAIN(); |
1 | // input.c |
2 | #include <allegro.h> |
3 | #include "input.h" |
4 | |
5 | int user_wants_to_quit = FALSE; |
6 | |
7 | void 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
Add void INPUT(VECTOR *); to input.h.
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.
After the VECTOR. Remember to link against Allegro libraries.
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 | |
10 | typedef struct{ |
11 | |
12 | double x,y; |
13 | }VECTOR; |
14 | void INPUT(VECTOR *); |
15 | |
16 | extern int user_wants_to_quit; |
17 | extern volatile int game_time; |
18 | #endif |
Don't forget to do a full recompile after you (only) change a header file.
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.
That is not an error, but a warning. Put a ENTER at the end of all your files.
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 | |
7 | int user_wants_to_quit = FALSE; |
8 | |
9 | void 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 | } |
26 | END_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*)'
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).
I don't even have a input.cpp, only the main.cpp, how must it be written?
Thanks very very much.
Your input.cpp file is the one you posted here. Just add it to your project (I am guessing you are using MSVC6).
The input.c I changed to input.cpp, and it worked. Thanks!!
(I use codeblocks)