Skip to content

Instantly share code, notes, and snippets.

@JettMonstersGoBoom
Last active October 19, 2018 18:02
Show Gist options
  • Save JettMonstersGoBoom/107b8d99fdb9063609b27cffb6042a11 to your computer and use it in GitHub Desktop.
Save JettMonstersGoBoom/107b8d99fdb9063609b27cffb6042a11 to your computer and use it in GitHub Desktop.
Simple Entity type in C macros.
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#pragma pack(1)
typedef struct
{
int32_t x, y;
} Vect2D_s32;
typedef struct _ent_t
{
Vect2D_s32 position;
Vect2D_s32 acceleration;
struct _ent_t *next, *prev;
void (*update)();
} Entity;
typedef struct
{
uint32_t startFrame : 10; // the base frame
uint32_t frameCount : 5; // how many frames are there ?
uint32_t delay : 5; // delay
uint16_t noloop : 1; // set this if we want to not loop
} Animation;
typedef struct
{
Animation *anim; // ptr to animation
uint16_t timer : 5; // individual info , timer
uint16_t frameInd : 5; // current frame inside the scope
uint16_t ended : 1; // set this flag when we hit the end
uint16_t frame; // the actual frame ( base->startFrame + frameInd )
} Entity_Animation;
typedef struct
{
Entity super;
Entity_Animation animation;
int health;
} Player;
// Animation
// tick down timer, when timer = 0 next frame or loop or stop
#define anim_update(_anim) ({ \
register Entity_Animation *anim = (Entity_Animation *)_anim; \
register Animation *base = anim->anim; \
anim->ended = 0; \
if (anim->timer == 0) \
{ \
anim->frameInd++; \
if (anim->frameInd > base->frameCount) \
{ \
if (base->noloop == 0) \
{ \
anim->frameInd = 0; \
} \
else \
{ \
anim->frameInd-- \
}; \
anim->ended = 1; \
} \
anim->timer = base->delay; \
anim->frame = base->startFrame + anim->frameInd; \
} \
else \
{ \
anim->timer--; \
} \
})
typedef struct
{
Entity super;
int life;
} Particle;
// Add to list
#define list_add(list, obj) ({ \
((Entity *)obj)->next = list; \
((Entity *)obj)->prev = NULL; \
if (list != NULL) \
list->prev = obj; \
list = (Entity *)obj; \
})
// Remove from list
#define list_del(list, obj) ({ \
if (((Entity *)obj)->next) \
((Entity *)obj)->next->prev = ((Entity *)obj)->prev; \
if (((Entity *)obj)->prev) \
((Entity *)obj)->prev->next = ((Entity *)obj)->next; \
else \
list = ((Entity *)obj)->next; \
})
// for loop from this list
#define list_for(_list) for (self = _list; self != NULL; self = self->next)
// entity move
#define ent_move(obj) ({ \
((Entity *)obj)->position.x += ((Entity *)obj)->acceleration.x; \
((Entity *)obj)->position.y += ((Entity *)obj)->acceleration.y; \
})
// set all properties
#define ent_set_all(obj, _x, _y, _ax, _ay, _update) ({ \
((Entity *)obj)->position.x = _x; \
((Entity *)obj)->position.y = _y; \
((Entity *)obj)->acceleration.x = _ax; \
((Entity *)obj)->acceleration.y = _ay; \
((Entity *)obj)->update = _update; \
})
// set just X & Y
#define ent_set_xy(obj, _x, _y) ({ \
((Entity *)obj)->position.x = _x; \
((Entity *)obj)->position.y = _y; \
})
// set just acceleration
#define ent_set_acceleration(obj, _x, _y) ({ \
((Entity *)obj)->acceleration.x = _x; \
((Entity *)obj)->acceleration.y = _y; \
})
// set the update function
#define ent_set_update(obj, _update) ({ \
((Entity *)obj)->update = _update; \
})
// apply force to acceleration ( doesn't move )
#define ent_apply_force(obj, _x, _y) ({ \
((Entity *)obj)->acceleration.x += _x; \
((Entity *)obj)->acceleration.y += _y; \
})
// debugging
#define ent_print(obj) ({ \
printf("x=%x y=%x vx=%x vy=%x prev=%x next=%x update=%x\n", \
((Entity *)obj)->position.x, \
((Entity *)obj)->position.y, \
((Entity *)obj)->acceleration.x, \
((Entity *)obj)->acceleration.y, \
((Entity *)obj)->prev, \
((Entity *)obj)->next, \
((Entity *)obj)->update); \
})
// test data
Animation hero_walk = {32, 5, 7, 0};
Animation hero_run = {65, 31, 1, 1}; // never loop test
Player heroes[2];
Particle prts[16];
Entity *list = NULL;
register Entity *self asm("r12");
void Hero()
{
register Player *player = (Player *)self;
ent_move(self);
ent_apply_force(self, 0, 1);
// player->animation.anim = &hero_walk;
player->health++;
anim_update((Entity_Animation *)&player->animation);
// Animate(&player->animation);
if (player->animation.ended == 1)
{
printf("health = %d\n", player->health);
}
printf("end trigger %d\n", player->animation.frame);
ent_print(self);
}
void main()
{
self = (Entity *)&heroes[0];
heroes[0].health = 100;
heroes[1].health = 10;
heroes[0].animation.anim = &hero_run;
heroes[1].animation.anim = &hero_walk;
printf("try list_add\n");
list_add(list, (Entity *)&prts[0]);
list_add(list, (Entity *)&prts[1]);
list_add(list, (Entity *)&heroes[1]);
list_add(list, (Entity *)&prts[2]);
list_add(list, (Entity *)&heroes[0]);
printf("try ent_set_all\n");
ent_set_all(&heroes[0], 0, 1, 2, 3, Hero);
ent_set_all(&heroes[1], 0, 1, 2, 3, Hero);
//
printf("self = first ent in list\n");
ent_print(self);
ent_apply_force(self, 3, 3);
ent_print(self);
ent_set_acceleration(self, 3, 3);
ent_print(self);
ent_move(self);
ent_print(self);
self = self->next;
printf("self = next\n");
ent_print(self);
ent_apply_force(self, 3, 3);
ent_print(self);
ent_set_acceleration(self, 3, 3);
ent_print(self);
ent_move(self);
ent_print(self);
printf("try for print\n");
list_for(list)
ent_print(self);
printf("try delete\n");
list_del(list, &prts[1]);
list_del(list, &prts[2]);
printf("try for print\n");
list_for(list)
ent_print(self);
list_del(list, &prts[0]);
printf("try for\n");
for (int q = 0; q < 100; q++)
{
list_for(list)
{
if (self->update != NULL)
self->update();
}
}
/*
ent_init( (Entity*)&heroes[0] , 0 , 1, 2, 3);
ent_print( (Entity*)&heroes[0] );
ent_applyForce( (Entity*)&heroes[0], 3,3);
ent_print( (Entity*)&heroes[0] );
ent_setForce( (Entity*)&heroes[0], 3,3);
ent_print( (Entity*)&heroes[0] );
ent_move( (Entity*)&heroes[0] );
ent_print( (Entity*)&heroes[0] );
// gbapal("ruff16.pal.bin");
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment