gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > compilation problem with globals and includes

#10141 - RaBBi - Wed Aug 27, 2003 10:21 pm

hi !

I tried for the first time to clean my code by playing with .h, .c and extern :P

After many bugs, I got a "hopefull" last error message :

Code:

sprites.h:6: parse error before '*' token


I pass a pointer on structure as a param to a function.

When all my code was in main.C, it worked.
But now that I use .h includes, it doesn't.

Here come prototype and function :

Code:

(in sprites.h)
void random_move  (TSprite *T_sprite, u16 direction, unsigned char* bitmap, unsigned char* vitesse);

(in sprites.c)
 typedef struct TSprite
{
    u8 ObjNo;
    s16 X, Y;
    s8  SpeedX, SpeedY;
    bool inMotion;
    u16 direction;
    u8 compteur_pas;
    u8 limite_pas;
    u8 AnimCnt;
    u32 frames;
}TSprite;

#define SPRITES_MAX  2

TSprite g_SprObj[SPRITES_MAX];

/*********************************************************************************
 * random_move(sprite_no, direction, *bitmap, *vitesse)
 *
 * D?place un sprite de mani?re al&atoire en process parall?le
 ********************************************************************************/
void random_move(TSprite *T_sprite, u16 direction, unsigned char* bitmap, unsigned char* vitesse)
{
    u16 sprite_Y = MY_OBJ_GET_Y_VALUE(T_sprite->ObjNo);
    u16 sprite_X = MY_OBJ_GET_X_VALUE(T_sprite->ObjNo);
    u16 rand_direction = 0;
    u16 opp_rand_direction = 0;

    if (T_sprite->compteur_pas == 0)
    {
        do {
        rand_direction = (int)((double)rand() / ((double)RAND_MAX + 1) * 4);
        opp_rand_direction = (rand_direction ^ 2);
        if (opp_rand_direction > 3) opp_rand_direction=0;

        rand_direction = rand_direction*3*1024;
        opp_rand_direction = opp_rand_direction*3*1024;
        } while ((rand_direction == (T_sprite->direction)) || (opp_rand_direction == (T_sprite->direction)));

        T_sprite->direction = rand_direction;

        //ham_DrawText(0, 1, "%4d", rand_direction);

        //ham_DrawText(0, 2, "%4d", opp_rand_direction);
        //T_sprite->compteur_pas = (int)((double)rand() / ((double)RAND_MAX + 1) * T_sprite->limite_pas);
        T_sprite->compteur_pas = 50;
    }

    if (T_sprite->compteur_pas != 0)
    {

        //if(g_NewFrame)
        //{

            // On n'update l'animation que toutes les 5 frames,
            if(!(T_sprite->frames%(vitesse[0])))
            {
                // charge le nouveau graph du sprite
                //ham_UpdateObjGfx(sprite_no,(void*)&eikishi_Bitmap[g_DirectionAnim+1024*(g_AnimCnt%3)]);
                ham_UpdateObjGfx(T_sprite->ObjNo,(void*)&bitmap[T_sprite->direction+1024*(T_sprite->AnimCnt%3)]);

                // mise ? jour de la position du perso
                T_sprite->AnimCnt++;
            }

            if(!(T_sprite->frames%(vitesse[1])))
            {
                switch(T_sprite->direction)
                {
                    //haut
                    case ANIM_HAUT:
                    sprite_Y--;
                    break;
                    //bas
                    case ANIM_BAS:
                    sprite_Y++;
                    break;
                    //gauche
                    case ANIM_GAUCHE:
                    sprite_X--;
                    break;
                    //droite
                    case ANIM_DROITE:
                    sprite_X++;
                    break;
                }

                redrawHero(T_sprite->ObjNo,sprite_X,sprite_Y);
                T_sprite->compteur_pas--;

                //RE-INIT du compteur de pas
                if (T_sprite->compteur_pas==0)
                {
                    //T_sprite->compteur_pas=T_sprite->limite_pas;
                }
            }
                     // Incr?mente le compteur de frames
            //g_NewFrame=0;       // Mise ? z?ro du bool?en Nouvelle Frame
            T_sprite->frames++;
        //}
    }
}



And of course, I don't know where this error come from.

So while I'm reading some C books, can someone guide me ? ^^

Thanks in advance ^^
_________________
Sorry for my poor english, but it would be worst for you to understand me if I speak in my native language, French ^^

#10144 - tepples - Thu Aug 28, 2003 12:48 am

First of all, you should put struct declarations and typedefs into your .h files before the function prototypes.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#10145 - RaBBi - Thu Aug 28, 2003 1:03 am

Ok, I do this tepples and it's worst now...

In fact, first I declared all my variables and my struct/typedef in .h but It doesn't compile, so I put all but not prototypes in .c.


What I have to put in .h files exactly ?

EDIT:
Ok I put off my struct typedef in a .h file that I include when I need, it's ok for that.

But now when I compile, I get this result :

Code:

globals.o(.data+0x0): multiple definition of `g_Frames'
main.o(.data+0x0): first defined here
globals.o(.data+0x4): multiple definition of `g_NewFrame'
main.o(.data+0x4): first defined here
globals.o(.data+0x5): multiple definition of `fin_intro'
main.o(.data+0x5): first defined here
globals.o(.data+0x6): multiple definition of `delay'
main.o(.data+0x6): first defined here
globals.o(.data+0x8): multiple definition of `test'
main.o(.data+0x8): first defined here
gamestruct.o(.rodata+0xcd00): multiple definition of `eikishi_Palette'
sprites.o(.rodata+0x0): first defined here
gamestruct.o(.rodata+0xcf00): multiple definition of `eikishi_Bitmap'
sprites.o(.rodata+0x200): first defined here
gamestruct.o(.rodata+0xff00): multiple definition of `fonts_Palette'
main.o(.rodata+0x9800): first defined here
gamestruct.o(.rodata+0x10100): multiple definition of `BMP_Font_Tiles'
main.o(.rodata+0x9a00): first defined here
gamestruct.o(.rodata+0x11780): multiple definition of `lettersData'
main.o(.rodata+0xb080): first defined here
gamestruct.o(.rodata+0x12d40): multiple definition of `lettersPalette'
main.o(.rodata+0xc640): first defined here


I think I don"t have a GOOD use of the "extern" term and the graphics includes...

In fact, I need the same gfx includes in several .c files...

Can someone guide me to find a source of good information about all these points ? (extern, includes, headers...)
Thank you
_________________
Sorry for my poor english, but it would be worst for you to understand me if I speak in my native language, French ^^

#10154 - RaBBi - Thu Aug 28, 2003 11:48 am

hmm...

I'm always in trouble with this...

I put all my variables/struc/Defines in a single file "typedefs.h" that I included in all my project files.

And I still have the same result : "multiple definition of ..."

I add this to the typedefs.h :

Code:

#if defined(TYPEDEFS_H)
/* fichier TYPEDEFS.H d?j? inclus */

#else

#define TYPEDEFS_H

.... my declarations ....

#endif


but nothing changes...

Does someone have a really good structure of a project that use global/extern variables and multiple headers to send me ?

Thank you
_________________
Sorry for my poor english, but it would be worst for you to understand me if I speak in my native language, French ^^

#10159 - RaBBi - Thu Aug 28, 2003 2:01 pm

hello !

Moderator can delete this topic >> I solved my problem ^^
_________________
Sorry for my poor english, but it would be worst for you to understand me if I speak in my native language, French ^^

#10164 - iuiz - Thu Aug 28, 2003 7:36 pm

It wouldn't help other Persons with the same Problem, if it it deleted.

#10173 - Omega81 - Thu Aug 28, 2003 10:59 pm

I am curious to know how you solved it.
_________________
Keep it real, keep it Free, Keep it GNU

#10174 - tepples - Thu Aug 28, 2003 11:14 pm

Keyword: 'extern'.

If you want a global variable to be accessible from multiple source files, declare it with 'extern' in the header file and without 'extern' in exactly one source file. Otherwise, if you don't need other source files to see a global variable, make it module-private by declaring it with 'static'.
Code:
/* Example */

/* === from music_engine.h === */
/* the public interface */
extern int music_position;
extern int music_volume;

int init_song(/*...*/);
int play_song(/*...*/);
int play_sample(/*...*/);
int mix_audio(/*...*/);

/* === from music_engine.c === */
int music_position;
int music_volume;

static unsigned char *module_data_ptr[8];
static int cur_instrument[8];

int init_song(/*...*/)
{ /*... */ }

int play_song(/*...*/)
{ /*... */ }

int play_sample(/*...*/)
{ /*... */ }

int mix_audio(/*...*/)
{ /*... */ }

_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#10256 - RaBBi - Sun Aug 31, 2003 9:13 pm

yes tepples it was exatly what I did.

no "extern" in source file
"extern" in other modules that use this variable.

But at the time I write this post, I have to do this too :

- globals variables are in a file that is not included in the others modules that could use some of the globals variables

- Types and Defines are in another file that is included in all the modules which need them.

Am I right with this way?

For the moment it works perfectly (even the pointers on structures) and since I can develop my engine with several files included ^^
_________________
Sorry for my poor english, but it would be worst for you to understand me if I speak in my native language, French ^^

#10287 - RaBBi - Mon Sep 01, 2003 5:31 pm

I got new problems about structures.

In a file called "backgrounds.c" I included a file called "typedefs.h".
In this header, there are typedef structs and DEFINES.
And one like this :

Code:

typedef struct TMap
{
    u16 MapNo;
    unsigned short MapPalette;          //palette de la map par d?faut
    unsigned char MapTiles;             //raw en tiles de la map
    unsigned short MapMap;              //map de la map
    s16 tilesX, tilesY;                 //tailles en tiles (1 tiles = 8x8)
    map_fragment_info_ptr MapFragment;  //Fragment ? charger de la map
    bool inScroll;                      //si en scroll
    u16 scroll_direction;               //direction du scroll
}TMap;

#define MAPS_MAX 255;



And in "backgrounds.c" I initialize like that :

Code:

TMap g_Maps[MAPS_MAX];       // tableau des Maps
g_Maps[0].MapNo=0;
g_Maps[0].MapPalette=ciel2_Palette;
g_Maps[0].MapTiles=ciel2_Tiles;
g_Maps[0].MapMap=ciel2_Map;
g_Maps[0].tilesX=32;
g_Maps[0].tilesY=32;
g_Maps[0].inScroll=FALSE;
g_Maps[0].scroll_direction=0;


And when I compile, HaM says to me :

Code:

backgrounds.c:X: parse error before '.' token

(with X is line number when I taped g_Maps[0].something)


Anyone has an idea about my mistake?

Thank you ^^
_________________
Sorry for my poor english, but it would be worst for you to understand me if I speak in my native language, French ^^

#10290 - tepples - Mon Sep 01, 2003 7:28 pm

RaBBi wrote:
Code:
#define MAPS_MAX 255;

You usually shouldn't use a ; after a #define'd macro. Instead:
Code:
#define MAPS_MAX 255

_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#10297 - RaBBi - Mon Sep 01, 2003 10:01 pm

yes but....i did this mistake only HERE lol

otherwise it's ok now, i solved my problem in using initialisation in a fonction
In fact, in a fonction, the "." syntax works.

I learn every day to make clean code and that's another example ^^
Anyway, thank you for reading.
_________________
Sorry for my poor english, but it would be worst for you to understand me if I speak in my native language, French ^^