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.

Coding > function pointers

#172515 - mog123 - Wed Feb 10, 2010 4:46 pm

Did anyone try doing any function pointers to get some sort of hermetisation and has some code they could share? Implementing something like this would be a great help in designing games for the GBA. I've never done any function pointers and am also curious can the GBA handle it.

#172517 - elhobbs - Wed Feb 10, 2010 5:14 pm

can the gba handle function pointers? why do you think it couldn't? maybe I am missing something...

#172520 - mog123 - Wed Feb 10, 2010 5:18 pm

In memory terms.

#172521 - elhobbs - Wed Feb 10, 2010 5:20 pm

a function pointer is just a memory address - so on the gba it would be 4 bytes.

#172522 - mog123 - Wed Feb 10, 2010 5:24 pm

Ok, and the function is stored on the ROM. I get it. Thanks.

#172526 - gauauu - Wed Feb 10, 2010 9:30 pm

There shouldn't be any issue using function pointers. A simple example from my game:

Code:

//EnemyUpdateFunction is a pointer to a function that updates an
//enemy.  Each enemy type would have its own update function
typedef int(*EnemyUpdateFunction)(Enemy *, int );

typedef struct
{
   int startHP;
        //...omitting a bunch of other members
   EnemyUpdateFunction updateFunction;

} EnemyType;

//now define a particular enemy type
const EnemyType enemy_bat_def =
{
   1,            //hp
         //omitting stuff.....
   enemyBatFunc   //updateFunction

};


int enemyBatFunc(Enemy * enemy, int param)
{
   //update the bat here
}




Code:

//and then to call a particular enemy's update function
enemy->enemyType->updateFunction(newEnemy, ENEMY_INIT);

#172527 - kusma - Thu Feb 11, 2010 12:30 am

mog123 wrote:
Ok, and the function is stored on the ROM. I get it. Thanks.

No.

Function pointers works fine on the GBA, just like on any other platform.

#172528 - dantheman - Thu Feb 11, 2010 2:25 am

During my "learning C for engineers" class in which we programmed for the GBA, our linked list "library" used a lot of function pointers. For instance, we had a generic function that would parse the entire list and took in a function pointer deciding what to do with that list (print it to the screen, add items together, remove from the head of the list, etc). Took a while to wrap my mind around it, but it's certainly doable on the GBA.

#172529 - brave_orakio - Thu Feb 11, 2010 4:08 am

I use it extensively in my demo. I use it in both player and AI controlled objects on screen. I put a function pointer in the structure I used for objects and let it point to the proper function depending on the action of the object on screen.
_________________
help me

#172534 - mog123 - Thu Feb 11, 2010 5:38 pm

I've been trying out function pointers and PN seems to giving me errors;

Here's a code snippet:

Code:


typedef struct _METHODS_{
   void (*animate_player);
} METHODS;

typedef struct _PLAYER_{
   //variables
   METHODS *Methods;
   u8 Action;
   u8 Frame;
} PLAYER;


void animate_player(PLAYER *Player, int x, int y)
{
//code
}
PLAYER *Player = (PLAYER*)malloc(sizeof(PLAYER));

Player->Methods->animate_player=animate_player;
Player->Methods->animate_player(Player,x,y);


Can't seem to get this to work. Any ideas?
PN error:
Quote:
error: called object 'Player->Methods->animate_player' is not a function

#172535 - kusma - Thu Feb 11, 2010 6:09 pm

mog123 wrote:
I've been trying out function pointers and PN seems to giving me errors;

Here's a code snippet:

Code:


typedef struct _METHODS_{
   void (*animate_player);
} METHODS;

typedef struct _PLAYER_{
   //variables
   METHODS *Methods;
   u8 Action;
   u8 Frame;
} PLAYER;


void animate_player(PLAYER *Player, int x, int y)
{
//code
}
PLAYER *Player = (PLAYER*)malloc(sizeof(PLAYER));

Player->Methods->animate_player=animate_player;
Player->Methods->animate_player(Player,x,y);


Can't seem to get this to work. Any ideas?
PN error:
Quote:
error: called object 'Player->Methods->animate_player' is not a function

The animate_player member in the METHODS-struct must list it's parameters, or the compiler won't be able to generate the function-call. Something like this:
Code:
typedef struct _METHODS_{
   void (*animate_player)(PLAYER *Player, int x, int y);
} METHODS;

#172536 - mog123 - Thu Feb 11, 2010 6:24 pm

I actually tried that the first time and got this:

Quote:

error: expected ')' before '*' token
warning: no semicolon at end of struct or union


Then I just shortened the parameters to (PLAYER) and it compiled, worked, but PN gave me:

Quote:
warning: parameter names (without types) in function declaration


Last edited by mog123 on Thu Feb 11, 2010 6:25 pm; edited 1 time in total

#172537 - elwing - Thu Feb 11, 2010 6:24 pm

mog123 wrote:
I've been trying out function pointers and PN seems to giving me errors;

Here's a code snippet:

Code:


typedef struct _METHODS_{
   void (*animate_player);
} METHODS;

typedef struct _PLAYER_{
   //variables
   METHODS *Methods;
   u8 Action;
   u8 Frame;
} PLAYER;


void animate_player(PLAYER *Player, int x, int y)
{
//code
}
PLAYER *Player = (PLAYER*)malloc(sizeof(PLAYER));

Player->Methods->animate_player=animate_player;
Player->Methods->animate_player(Player,x,y);


Can't seem to get this to work. Any ideas?
PN error:
Quote:
error: called object 'Player->Methods->animate_player' is not a function


it seems to me that not only you're trying to access an invalid pointer, but you're also trying to use a pointer of function as a function...

isn't something like that better?
Code:

typedef void(*ANIMATE_PLAYER)(PLAYER*, int, int);

typedef struct _PLAYER_{
   //variables
   ANIMATE_PLAYER animate_player;
   u8 Action;
   u8 Frame;
} PLAYER;

void animate_player(PLAYER *Player, int x, int y)
{
//code
}

PLAYER *Player = (PLAYER*)malloc(sizeof(PLAYER));

Player->animate_player=&animate_player;
(*Player->animate_player)(Player,x,y);



haven't tested hope i didn't made a pointer error...


Last edited by elwing on Thu Feb 11, 2010 6:34 pm; edited 1 time in total

#172539 - mog123 - Thu Feb 11, 2010 6:32 pm

Ok, fixed it, no warnings:

struct _PLAYER_;
typedef struct _PLAYER_ PLAYER;

typedef struct _METHODS_{
void (*animate_player)(PLAYER*,int,int);
} METHODS;

struct _PLAYER_{
//variables
METHODS *Methods;
u8 Action;
u8 Frame;
};

#172629 - mog123 - Sun Feb 21, 2010 2:40 pm

Another thing that's bugging me. Do I need to assign the function to hte function pointer everytime I need to use it?

Everything works when I do something like this(in a loop):
Code:
Player->Methods->Animate=Animate;
Player->Methods->Animate(Player);


But when I move the upper line outside the loop, the function doesn't work. Is that how it's supposed to be?


edit: fixed this.
_________________
Check out my GBA game in development : 忍物語