Last active
October 19, 2018 18:02
-
-
Save JettMonstersGoBoom/107b8d99fdb9063609b27cffb6042a11 to your computer and use it in GitHub Desktop.
Simple Entity type in C macros.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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