(20111222) 20:00

This commit is contained in:
2011-12-22 20:00:00 +01:00
parent 969064b44c
commit 123dfa03cd
22 changed files with 387 additions and 206 deletions

36
Anim.c
View File

@@ -60,6 +60,19 @@ int Anim_GetTime(Anim a){
} }
/////////////////////////////
// Anim_GetSize
//
// Gets the animation size.
void Anim_GetSize(Anim a,int *w,int *h){
Animation *anim=a;
int waux;
*w=anim->w;
Draw_GetSize(anim->img,&waux,h);
}
///////////////////////////// /////////////////////////////
// Anim_SetOffset // Anim_SetOffset
// Anim_GetOffset // Anim_GetOffset
@@ -132,6 +145,29 @@ void AnimPlay_Draw(AnimPlay *ani,int x,int y){
} }
/////////////////////////////
// AnimPlay_GetOffset
// AnimPlay_GetSize
//
//
void AnimPlay_GetOffset(AnimPlay *ani,int *x,int *y){
if(ani->anim){
Anim_GetOffset(ani->anim,x,y);
}else
if(ani->img){
Draw_GetOffset(ani->img,x,y);
}
}
void AnimPlay_GetSize(AnimPlay *ani,int *w,int *h){
if(ani->anim){
Anim_GetSize(ani->anim,w,h);
}else
if(ani->img){
Draw_GetSize(ani->img,w,h);
}
}
///////////////////////////// /////////////////////////////
// AnimPlay_IncTime // AnimPlay_IncTime
// //

16
Anim.h
View File

@@ -27,6 +27,13 @@ Anim Anim_LoadAnim(char *fichero,int frames,float fps);
int Anim_GetTime(Anim anim); int Anim_GetTime(Anim anim);
/////////////////////////////
// Anim_GetSize
//
// Gets the animation size.
void Anim_GetSize(Anim anim,int *w,int *h);
///////////////////////////// /////////////////////////////
// Anim_SetOffset // Anim_SetOffset
// Anim_GetOffset // Anim_GetOffset
@@ -77,6 +84,15 @@ void AnimPlay_SetAnim(AnimPlay *ap,Anim ani);
void AnimPlay_Draw(AnimPlay *ani,int x,int y); void AnimPlay_Draw(AnimPlay *ani,int x,int y);
/////////////////////////////
// AnimPlay_GetOffset
// AnimPlay_GetSize
//
//
void AnimPlay_GetOffset(AnimPlay *ani,int *x,int *y);
void AnimPlay_GetSize(AnimPlay *ani,int *w,int *h);
///////////////////////////// /////////////////////////////
// AnimPlay_IncTime // AnimPlay_IncTime
// //

66
Draw.c
View File

@@ -153,6 +153,8 @@ void Draw_Clean(
SDL_MapRGB(_screen->format, r, g, b)); SDL_MapRGB(_screen->format, r, g, b));
} }
//////////////////////////////////////////////// ////////////////////////////////////////////////
// DrawImage // // DrawImage //
/////////////// ///////////////
@@ -389,11 +391,12 @@ SDL_Surface *Draw_DefaultFontSurface(
8*256, 8, 32,0,0,0,0); 8*256, 8, 32,0,0,0,0);
surf->format->Amask=0xFF000000; surf->format->Amask=0xFF000000;
surf->format->Ashift=24; surf->format->Ashift=24;
SDL_SetAlpha(surf, SDL_SRCALPHA, 255);
// Draw the font // Draw the font
SDL_LockSurface(surf); SDL_LockSurface(surf);
color =SDL_MapRGBA(surf->format,r,g,b,a); color =SDL_MapRGBA(surf->format,r,g,b,a);
color2=SDL_MapRGBA(surf->format,r,g,b,0); color2=SDL_MapRGBA(surf->format,r,g,0,0);
for(c=0;c<256;c++){ for(c=0;c<256;c++){
for(y=0;y<8;y++){ for(y=0;y<8;y++){
for(x=0;x<8;x++){ for(x=0;x<8;x++){
@@ -431,12 +434,8 @@ DrawFnt Draw_DefaultFont(
font->surf = Draw_DefaultFontSurface(r,g,b,a); font->surf = Draw_DefaultFontSurface(r,g,b,a);
font->w=8; font->w=8;
font->h=8; font->h=8;
font->min=0;
font->surf->format->Amask=0xFF000000; font->max=128;
font->surf->format->Ashift=24;
SDL_SetAlpha(font->surf, SDL_SRCALPHA, 255);
return((DrawFnt)font); return((DrawFnt)font);
} }
@@ -446,43 +445,18 @@ DrawFnt Draw_DefaultFont(
// //
// Load a font from a file. // Load a font from a file.
DrawFnt Draw_LoadFont(char *fichero,int min,int max){ DrawFnt Draw_LoadFont(char *fichero,int min,int max){
/*DrawFont *font; DrawFont *font;
int x,y,c; int w,h;
Uint32 color,color2;
// Create the default font // Create the default font
font=malloc(sizeof(DrawFont)); font=malloc(sizeof(DrawFont));
font->surf = SDL_CreateRGBSurface(SDL_SWSURFACE, font->surf = Draw_LoadSurface(fichero);
8*256, 8, 32,0,0,0,0); font->w=font->surf->w/(max-min);
font->w=8; font->h=font->surf->h;
font->h=8; font->min=min;
font->surf->format->Amask=0xFF000000; font->max=max;
font->surf->format->Ashift=24;
SDL_SetAlpha(font->surf, SDL_SRCALPHA, 255);
// Draw the font return((DrawFnt)font);
SDL_LockSurface(font->surf);
color =SDL_MapRGBA(font->surf->format,r,g,b,a);
color2=SDL_MapRGBA(font->surf->format,r,g,b,0);
for(c=0;c<256;c++){
for(y=0;y<8;y++){
for(x=0;x<8;x++){
if(((fontdata_8x8[c*8+y]>>(7-x)) & 0x01)==1){
//Imagen_PutPixel(dest,c*8+x,y,color);
((Uint32 *)font->surf->pixels)[(c*8+x)+(8*256*y)]=
color;
}else{
//Imagen_PutPixel(dest,c*8+x,y,color2);
((Uint32 *)font->surf->pixels)[(c*8+x)+(8*256*y)]=
color2;
}
}
}
}
SDL_UnlockSurface(font->surf);
return((DrawFnt)font);*/
return(NULL);
} }
///////////////////////////// /////////////////////////////
@@ -505,11 +479,13 @@ void Draw_DrawText(DrawFnt f,char *text,int x,int y){
// Iterate the string // Iterate the string
ptr=text; ptr=text;
while(*ptr){ while(*ptr){
orig.x=(*ptr)*font->w; if((*ptr)<font->max){
dest.x=x; orig.x=((*ptr)-font->min)*font->w;
dest.y=y; dest.x=x;
// Blit every character dest.y=y;
SDL_BlitSurface(font->surf,&orig,_screen,&dest); // Blit every character
SDL_BlitSurface(font->surf,&orig,_screen,&dest);
}
x+=font->w; x+=font->w;
ptr++; ptr++;
} }

View File

@@ -42,6 +42,7 @@ Entity *Entity_New(){
AnimPlay_SetImg(&e->anim,NULL); AnimPlay_SetImg(&e->anim,NULL);
e->oncopy=NULL; e->oncopy=NULL;
e->ondelete=NULL;
e->proc=NULL; e->proc=NULL;
e->postproc=NULL; e->postproc=NULL;
e->collision=NULL; e->collision=NULL;
@@ -61,6 +62,9 @@ Entity *Entity_New(){
// //
// //
void Entity_Destroy(Entity *e){ void Entity_Destroy(Entity *e){
if(e->ondelete){
e->ondelete(e);
}
e->next=_free_entity; e->next=_free_entity;
_free_entity=e; _free_entity=e;
} }
@@ -91,6 +95,7 @@ Entity *Entity_Copy(Entity *e){
AnimPlay_Copy(&n->anim,&e->anim); AnimPlay_Copy(&n->anim,&e->anim);
n->oncopy=e->oncopy; n->oncopy=e->oncopy;
n->ondelete=e->ondelete;
n->proc=e->proc; n->proc=e->proc;
n->postproc=e->postproc; n->postproc=e->postproc;
n->collision=e->collision; n->collision=e->collision;
@@ -222,25 +227,17 @@ void Entity_CollisionResponse(
int Entity_Collide(Entity *b1,Entity *b2){ int Entity_Collide(Entity *b1,Entity *b2){
float t; float t;
vec2 n; vec2 n;
vec2 cir1[2]; vec2 vel;
Entity *b_aux; Entity *b_aux;
if(!(b1->flags&EntityFlag_Collision) || !(b2->flags&EntityFlag_Collision)) //if(!(b1->flags&EntityFlag_Collision) || !(b2->flags&EntityFlag_Collision))
// return(0);
// Test relative to b1
vec2_minus(vel,b1->vel,b2->vel);
if(vec2_dot(vel,vel)<=0.0f)
return(0); return(0);
if(Colision_CircleCircle(b1->pos,b1->radius,vel,b2->pos,b2->radius,&t,n)){
// FIX: Swap colision order based on moving object
if(vec2_dot(b1->vel,b1->vel)<vec2_dot(b2->vel,b2->vel)){
b_aux=b1;
b1=b2;
b2=b_aux;
}
// Prepare testing vectors
vec2_copy(cir1[0],b1->pos);
vec2_plus(cir1[1],b1->pos,b1->vel);
vec2_minus(cir1[1],cir1[1],b2->vel);
if(Colision_CircleCircle(cir1,b1->radius,b2->pos,b2->radius,&t,n)){
int response=1; int response=1;
// Check the collision methods // Check the collision methods
@@ -259,7 +256,11 @@ int Entity_Collide(Entity *b1,Entity *b2){
// Collision response // Collision response
if(response){ if(response){
Entity_CollisionResponse(b1,b2,t,n); if(vec2_dot(b1->vel,b1->vel)>vec2_dot(b2->vel,b2->vel)){
Entity_CollisionResponse(b1,b2,t,n);
}else{
Entity_CollisionResponse(b2,b1,t,n);
}
return(1); return(1);
}else{ }else{
return(0); return(0);
@@ -281,6 +282,14 @@ void Entity_Overlaps(Entity *b1,Entity *b2){
return; return;
vec2_minus(len,b1->pos,b2->pos); vec2_minus(len,b1->pos,b2->pos);
if(fabs(len[0])>b1->radius)
return;
if(fabs(len[1])>b1->radius)
return;
if(fabs(len[0])>b2->radius)
return;
if(fabs(len[1])>b2->radius)
return;
dist=sqrtf(vec2_dot(len,len)); dist=sqrtf(vec2_dot(len,len));
if(b1->radius>dist && b1->overlap){ if(b1->radius>dist && b1->overlap){

View File

@@ -33,6 +33,7 @@ typedef struct Tag_Entity {
AnimPlay anim; AnimPlay anim;
void (*oncopy)(struct Tag_Entity *ent); void (*oncopy)(struct Tag_Entity *ent);
void (*ondelete)(struct Tag_Entity *ent);
void (*proc)(struct Tag_Entity *ent,int ft); void (*proc)(struct Tag_Entity *ent,int ft);
void (*postproc)(struct Tag_Entity *ent,int ft); void (*postproc)(struct Tag_Entity *ent,int ft);
int (*collision)( int (*collision)(

View File

@@ -22,6 +22,7 @@ DrawImg img_player_up;
DrawImg img_player_left; DrawImg img_player_left;
DrawImg img_player_right; DrawImg img_player_right;
DrawImg img_savepoint; DrawImg img_savepoint;
Anim anim_savepoint_active;
DrawImg img_endpoint; DrawImg img_endpoint;
Anim anim_exitpoint; Anim anim_exitpoint;
DrawImg img_arrowshooter_up; DrawImg img_arrowshooter_up;
@@ -104,12 +105,12 @@ void player_proc(Entity *e,int ft){
} }
} }
vec2_scale(vel,vel,1.0f); vec2_scale(vel,vel,1);
Entity_AddVelLimit(e,vel,3.0f); Entity_AddVelLimit(e,vel,3.0f);
} }
// Scroll View
GameLib_GetPos(pos); GameLib_GetPos(pos);
GameLib_GetSize(size); GameLib_GetSize(size);
size[0]/=2; size[0]/=2;
@@ -139,36 +140,35 @@ void barrel_proc(Entity *e,int ft){
} }
} }
void destroy_postproc(Entity *e,int ft){
GameLib_DelEntity(e);
}
void hole_spiked_overlap(Entity *e1,Entity *e2){ void hole_spiked_overlap(Entity *e1,Entity *e2){
Entity *e; Entity *e;
if(e1->postproc)
return;
if(e2->type==Ent_Barrel){ if(e2->type==Ent_Barrel){
Entity *e; Entity *e;
e1->postproc=destroy_postproc; // Disable future overlaps
e2->postproc=destroy_postproc; e1->overlap=NULL;
GameLib_PlaySound(snd_fillhole,(int)e2->pos[0],(int)e2->pos[1]); // Remove the two entities
GameLib_DelEntity(e1);
GameLib_DelEntity(e2);
// "Fill the hole"
e=Entity_Copy(ent_hole_filled); e=Entity_Copy(ent_hole_filled);
vec2_copy(e->pos,e1->pos); vec2_copy(e->pos,e1->pos);
GameLib_AddEntity(e); GameLib_AddEntity(e);
GameLib_PlaySound(snd_fillhole,(int)e2->pos[0],(int)e2->pos[1]);
} }
if(e2->type==Ent_Player){ if(e2->type==Ent_Player){
// KILL the player // "Kill the player"
e=Entity_Copy(ent_player_broken); e=Entity_Copy(ent_player_broken);
vec2_copy(e->pos,e2->pos); vec2_copy(e->pos,e2->pos);
GameLib_AddEntity(e); GameLib_AddEntity(e);
GameLib_PlaySound(snd_burn,(int)e2->pos[0],(int)e2->pos[1]); GameLib_PlaySound(snd_burn,(int)e2->pos[0],(int)e2->pos[1]);
e2->postproc=destroy_postproc; GameLib_DelEntity(e2);
// HACK
game_level_reset=1; game_level_reset=1;
} }
} }
@@ -177,21 +177,18 @@ void hole_spiked_overlap(Entity *e1,Entity *e2){
void hole_lava_overlap(Entity *e1,Entity *e2){ void hole_lava_overlap(Entity *e1,Entity *e2){
Entity *e; Entity *e;
if(e2->type==Ent_Barrel && e1->postproc==NULL){ if(e2->type==Ent_Barrel){
e2->postproc=destroy_postproc; // "Burn the barrel"
GameLib_DelEntity(e2);
// Burning effect
e=Entity_Copy(ent_fire); e=Entity_Copy(ent_fire);
vec2_copy(e->pos,e2->pos); vec2_copy(e->pos,e2->pos);
GameLib_AddEntity(e); GameLib_AddEntity(e);
GameLib_PlaySound(snd_burn,(int)e2->pos[0],(int)e2->pos[1]); GameLib_PlaySound(snd_burn,(int)e2->pos[0],(int)e2->pos[1]);
} }
if(e2->type==Ent_Player && e1->postproc==NULL){ if(e2->type==Ent_Player){
// KILL the player (burned) // "Burn the player"
e2->postproc=destroy_postproc; GameLib_DelEntity(e2);
game_level_reset=1; game_level_reset=1;
// Burning effect
e=Entity_Copy(ent_fire); e=Entity_Copy(ent_fire);
vec2_copy(e->pos,e2->pos); vec2_copy(e->pos,e2->pos);
GameLib_AddEntity(e); GameLib_AddEntity(e);
@@ -216,11 +213,11 @@ int arrow_collision(Entity *e1,Entity *e2,float t,vec2 n){
e=Entity_Copy(ent_player_broken); e=Entity_Copy(ent_player_broken);
vec2_copy(e->pos,e2->pos); vec2_copy(e->pos,e2->pos);
GameLib_AddEntity(e); GameLib_AddEntity(e);
e2->postproc=destroy_postproc; GameLib_DelEntity(e2);
GameLib_PlaySound(snd_burn,(int)e2->pos[0],(int)e2->pos[1]); GameLib_PlaySound(snd_burn,(int)e2->pos[0],(int)e2->pos[1]);
game_level_reset=1; game_level_reset=1;
} }
e1->postproc=destroy_postproc; GameLib_DelEntity(e1);
GameLib_PlaySound(snd_arrowhit,(int)e1->pos[0],(int)e1->pos[1]); GameLib_PlaySound(snd_arrowhit,(int)e1->pos[0],(int)e1->pos[1]);
return(0); return(0);
@@ -245,6 +242,12 @@ void arrowshooter_proc(Entity *e,int ft){
} }
} }
Entity *_savepoint=NULL;
void savepoint_ondelete(Entity *e){
if(_savepoint==e){
_savepoint=NULL;
}
}
void savepoint_overlap(Entity *e1,Entity *e2){ void savepoint_overlap(Entity *e1,Entity *e2){
if(e2->type==Ent_Player){ if(e2->type==Ent_Player){
// Save the point // Save the point
@@ -252,6 +255,13 @@ void savepoint_overlap(Entity *e1,Entity *e2){
game_level_point=e1->A; game_level_point=e1->A;
GameLib_PlaySound(snd_savepoint,(int)e1->pos[0],(int)e1->pos[1]); GameLib_PlaySound(snd_savepoint,(int)e1->pos[0],(int)e1->pos[1]);
} }
if(e1!=_savepoint){
AnimPlay_SetAnim(&e1->anim,anim_savepoint_active);
if(_savepoint){
AnimPlay_SetImg(&_savepoint->anim,img_savepoint);
}
_savepoint=e1;
}
} }
} }
@@ -263,7 +273,7 @@ void exitpoint_overlap(Entity *e1,Entity *e2){
game_level_reset=2; game_level_reset=2;
// HACK: Delete the player // HACK: Delete the player
e2->postproc=destroy_postproc; GameLib_DelEntity(e2);
GameLib_PlaySound(snd_exitpoint,(int)e1->pos[0],(int)e1->pos[1]); GameLib_PlaySound(snd_exitpoint,(int)e1->pos[0],(int)e1->pos[1]);
} }
@@ -275,15 +285,15 @@ void endpoint_overlap(Entity *e1,Entity *e2){
game_level_reset=3; game_level_reset=3;
// HACK: Delete the player // HACK: Delete the player
e2->postproc=destroy_postproc; GameLib_DelEntity(e2);
GameLib_PlaySound(snd_exitpoint,(int)e1->pos[0],(int)e1->pos[1]); GameLib_PlaySound(snd_exitpoint,(int)e1->pos[0],(int)e1->pos[1]);
} }
} }
void fire_proc(Entity *e,int ft){ void timeoutent_proc(Entity *e,int ft){
if(e->A==0){ if(e->A==0){
e->postproc=destroy_postproc; GameLib_DelEntity(e);
}else{ }else{
e->A--; e->A--;
} }
@@ -333,6 +343,9 @@ void GameEnts_Init(){
img_savepoint=Draw_LoadImage("data/save_point.bmp"); img_savepoint=Draw_LoadImage("data/save_point.bmp");
Draw_SetOffset(img_savepoint,-16,-16); Draw_SetOffset(img_savepoint,-16,-16);
anim_savepoint_active=Anim_LoadAnim("data/save_point_active.bmp",2,5);
Anim_SetOffset(anim_savepoint_active,-16,-16);
anim_exitpoint=Anim_LoadAnim("data/exit_point.bmp",2,10); anim_exitpoint=Anim_LoadAnim("data/exit_point.bmp",2,10);
Anim_SetOffset(anim_exitpoint,-16,-48); Anim_SetOffset(anim_exitpoint,-16,-48);
@@ -397,6 +410,7 @@ void GameEnts_Init(){
ent_column=Entity_New(); ent_column=Entity_New();
ent_column->type=Ent_Column; ent_column->type=Ent_Column;
ent_column->flags=EntityFlag_Collision; ent_column->flags=EntityFlag_Collision;
//ent_column->flags=0;
ent_column->radius=12; ent_column->radius=12;
ent_column->mass=-1.0f; ent_column->mass=-1.0f;
AnimPlay_SetImg(&ent_column->anim,img_column); AnimPlay_SetImg(&ent_column->anim,img_column);
@@ -443,9 +457,11 @@ void GameEnts_Init(){
ent_arrow_up=Entity_New(); ent_arrow_up=Entity_New();
ent_arrow_up->type=Ent_Arrow; ent_arrow_up->type=Ent_Arrow;
ent_arrow_up->flags=EntityFlag_Collision; ent_arrow_up->flags=EntityFlag_Collision;
ent_arrow_up->radius=10; ent_arrow_up->radius=7;
ent_arrow_up->fric_static=0; ent_arrow_up->fric_static=0;
ent_arrow_up->collision=arrow_collision; ent_arrow_up->collision=arrow_collision;
ent_arrow_up->proc=timeoutent_proc;
ent_arrow_up->A=120;
AnimPlay_SetImg(&ent_arrow_up->anim,img_arrow_up); AnimPlay_SetImg(&ent_arrow_up->anim,img_arrow_up);
vec2_set(ent_arrow_up->vel,0,-4); vec2_set(ent_arrow_up->vel,0,-4);
ent_arrow_down=Entity_Copy(ent_arrow_up); ent_arrow_down=Entity_Copy(ent_arrow_up);
@@ -486,6 +502,7 @@ void GameEnts_Init(){
ent_savepoint_1->radius=16; ent_savepoint_1->radius=16;
AnimPlay_SetImg(&ent_savepoint_1->anim,img_savepoint); AnimPlay_SetImg(&ent_savepoint_1->anim,img_savepoint);
ent_savepoint_1->overlap=savepoint_overlap; ent_savepoint_1->overlap=savepoint_overlap;
ent_savepoint_1->ondelete=savepoint_ondelete;
ent_savepoint_1->A=1; ent_savepoint_1->A=1;
ent_savepoint_2=Entity_Copy(ent_savepoint_1); ent_savepoint_2=Entity_Copy(ent_savepoint_1);
ent_savepoint_2->A=2; ent_savepoint_2->A=2;
@@ -509,8 +526,8 @@ void GameEnts_Init(){
ent_fire->type=Ent_Effect; ent_fire->type=Ent_Effect;
ent_fire->flags=0; ent_fire->flags=0;
AnimPlay_SetAnim(&ent_fire->anim,anim_fire); AnimPlay_SetAnim(&ent_fire->anim,anim_fire);
ent_fire->proc=fire_proc; ent_fire->proc=timeoutent_proc;
ent_fire->A=30; ent_fire->A=60;
ent_player_broken=Entity_New(); ent_player_broken=Entity_New();
ent_player_broken->type=Ent_Effect; ent_player_broken->type=Ent_Effect;

197
GameLib.c
View File

@@ -15,8 +15,11 @@
// Globals // Globals
int _running; int _running;
Entity **_entity=NULL; Entity **_entity=NULL;
int *_entity_flag=NULL;
int _n_entities=0; int _n_entities=0;
int _n_entities_res=0; int _n_entities_res=0;
int _entities_lock=0;
int _entities_compactate=0;
void (*_gameproc)()=NULL; void (*_gameproc)()=NULL;
void (*_gamepostproc)()=NULL; void (*_gamepostproc)()=NULL;
int _ft; int _ft;
@@ -55,6 +58,7 @@ int GameLib_Init(int w,int h,char *title,int fps){
void GameLib_AddEntity(Entity *e){ void GameLib_AddEntity(Entity *e){
if(_n_entities>=_n_entities_res){ if(_n_entities>=_n_entities_res){
Entity **entity_aux; Entity **entity_aux;
int *entity_flag_aux;
int i; int i;
// Grow the array // Grow the array
@@ -63,15 +67,22 @@ void GameLib_AddEntity(Entity *e){
else else
_n_entities_res*=2; _n_entities_res*=2;
entity_aux=malloc(sizeof(Entity *)*_n_entities_res); entity_aux=malloc(sizeof(Entity *)*_n_entities_res);
for(i=0;i<_n_entities;i++) entity_flag_aux=malloc(sizeof(int)*_n_entities_res);
for(i=0;i<_n_entities;i++){
entity_aux[i]=_entity[i]; entity_aux[i]=_entity[i];
if(_entity) entity_flag_aux[i]=_entity_flag[i];
}
if(_entity){
free(_entity); free(_entity);
free(_entity_flag);
}
_entity=entity_aux; _entity=entity_aux;
_entity_flag=entity_flag_aux;
} }
// Add the entity // Add the entity
_entity[_n_entities]=e; _entity[_n_entities]=e;
_entity_flag[_n_entities]=1;
_n_entities++; _n_entities++;
} }
@@ -84,11 +95,17 @@ int GameLib_UnrefEntity(Entity *e){
int i; int i;
for(i=0;i<_n_entities;i++){ for(i=0;i<_n_entities;i++){
if(e==_entity[i]){ if(e==_entity[i]){
_entity[i]=NULL; if(_entities_lock){
return(1); _entity_flag[i]=-2;
}else{
_entity[i]=NULL;
_entity_flag[i]=0;
}
_entities_compactate=1;
return(i);
} }
} }
return(0); return(-1);
} }
@@ -97,52 +114,90 @@ int GameLib_UnrefEntity(Entity *e){
// //
// Adds an entity to the game. // Adds an entity to the game.
int GameLib_DelEntity(Entity *e){ int GameLib_DelEntity(Entity *e){
if(!GameLib_UnrefEntity(e)){ int i;
if((i=GameLib_UnrefEntity(e))==-1){
return(0); return(0);
} }
Entity_Destroy(e); if(_entities_lock){
// Delete latter
_entity[i]=e;
_entity_flag[i]=-1;
}else{
// Delete now
Entity_Destroy(e);
}
return(1); return(1);
} }
/////////////////////////////
// GameLib_Compactate
//
//
void GameLib_Compactate(){
int i,j;
j=0;
if(!_entities_compactate)
return;
for(i=0;i<_n_entities;i++){
if(!_entity[i] || _entity_flag[i]==-2)
continue;
if(_entity_flag[i]==-1){
Entity_Destroy(_entity[i]);
continue;
}
if(i>j){
_entity[j]=_entity[i];
_entity_flag[j]=_entity_flag[i];
}
j++;
}
_n_entities=j;
_entities_compactate=0;
_entities_lock=0;
}
///////////////////////////// /////////////////////////////
// GameLib_ProcLoop // GameLib_ProcLoop
// //
// Process the loop. // Process the loop.
long long t_proc;
long long t_col;
long long t_over;
long long t_postproc;
int f_count;
int GameLib_ProcLoop(){ int GameLib_ProcLoop(){
int i,j; int i,j;
int repeat,count; int repeat,count;
long long time;
// Launch the method
// Process
time=Time_GetTime();
GameLib_Compactate();_entities_lock=1;
if(_gameproc){ if(_gameproc){
_gameproc(); _gameproc();
} }
// Process entities
// vec2 grav;
// vec2_set(grav,0,1);
for(i=0;i<_n_entities;i++){ for(i=0;i<_n_entities;i++){
if(!_entity[i]) if(!_entity[i])
continue; continue;
Entity_Process(_entity[i],_ft); Entity_Process(_entity[i],_ft);
/*
if(_entity[i]->mass>0.0f){
vec2_plus(_entity[i]->vel,_entity[i]->vel,grav);
}
*/
} }
GameLib_Compactate();
t_proc+=Time_GetTime()-time;
// Process colisions between entities
// Colisions between entities
time=Time_GetTime();
GameLib_Compactate();_entities_lock=1;
count=0; count=0;
do{ do{
repeat=0; repeat=0;
for(i=0;i<_n_entities-1;i++){ for(i=0;i<_n_entities-1;i++){
if(!_entity[i])
continue;
if(!(_entity[i]->flags&EntityFlag_Collision)) if(!(_entity[i]->flags&EntityFlag_Collision))
continue; continue;
for(j=i+1;j<_n_entities;j++){ for(j=i+1;j<_n_entities;j++){
if(!_entity[j]) if(!(_entity[j]->flags&EntityFlag_Collision))
continue; continue;
if(Entity_Collide(_entity[i],_entity[j])){ if(Entity_Collide(_entity[i],_entity[j])){
repeat=1; repeat=1;
@@ -150,47 +205,39 @@ int GameLib_ProcLoop(){
} }
} }
count++; count++;
}while(repeat && count<20); }while(repeat && count<10);
// Stop remaining collisions // Stop remaining collisions
for(i=0;i<_n_entities-1;i++){ if(count==10){
if(!_entity[i]) for(i=0;i<_n_entities-1;i++){
continue; if(!(_entity[i]->flags&EntityFlag_Collision))
if(!(_entity[i]->flags&EntityFlag_Collision))
continue;
for(j=i+1;j<_n_entities;j++){
if(!_entity[j])
continue; continue;
if(Entity_Collide(_entity[i],_entity[j])){ for(j=i+1;j<_n_entities;j++){
vec2_set(_entity[i]->vel,0,0); if(!(_entity[j]->flags&EntityFlag_Collision))
vec2_set(_entity[j]->vel,0,0); continue;
if(Entity_Collide(_entity[i],_entity[j])){
vec2_set(_entity[i]->vel,0,0);
vec2_set(_entity[j]->vel,0,0);
}
} }
} }
} }
GameLib_Compactate();
t_col+=Time_GetTime()-time;
// Process Overlaps // Process Overlaps
time=Time_GetTime();
GameLib_Compactate();_entities_lock=1;
for(i=0;i<_n_entities-1;i++){ for(i=0;i<_n_entities-1;i++){
if(!_entity[i])
continue;
if(!(_entity[i]->flags&EntityFlag_Overlap)) if(!(_entity[i]->flags&EntityFlag_Overlap))
continue; continue;
for(j=i+1;j<_n_entities;j++){ for(j=i+1;j<_n_entities;j++){
if(!_entity[j]) if(!(_entity[j]->flags&EntityFlag_Overlap))
continue; continue;
Entity_Overlaps(_entity[i],_entity[j]); Entity_Overlaps(_entity[i],_entity[j]);
} }
} }
GameLib_Compactate();
// Compactate t_over+=Time_GetTime()-time;
j=0;
for(i=0;i<_n_entities;i++){
if(!_entity[i])
continue;
if(i>j)
_entity[j]=_entity[i];
j++;
}
_n_entities=j;
// Sort // Sort
int n,n2,swap; int n,n2,swap;
@@ -222,13 +269,15 @@ int GameLib_ProcLoop(){
n=n2; n=n2;
}while(n>0); }while(n>0);
// PostProcess and draw entities // PostProcess and draw entities
time=Time_GetTime();
GameLib_Compactate();_entities_lock=1;
for(i=0;i<_n_entities;i++){ for(i=0;i<_n_entities;i++){
Entity *e; Entity *e;
Entity_PostProcess(_entity[i],_ft); Entity_PostProcess(_entity[i],_ft);
if(!_entity[i])
continue;
// FIXME: This is a hack
e=_entity[i]; e=_entity[i];
if(e->pos[0]<(_game_pos[0]-128)) if(e->pos[0]<(_game_pos[0]-128))
continue; continue;
@@ -241,11 +290,13 @@ int GameLib_ProcLoop(){
Entity_Draw(e,-_game_pos[0],-_game_pos[1]); Entity_Draw(e,-_game_pos[0],-_game_pos[1]);
} }
// Launch the method
if(_gamepostproc){ if(_gamepostproc){
_gamepostproc(); _gamepostproc();
} }
GameLib_Compactate();
t_postproc+=Time_GetTime()-time;
f_count++;
return(_running); return(_running);
} }
@@ -263,7 +314,18 @@ void GameLib_Loop(
_gameproc=gameproc; _gameproc=gameproc;
_gamepostproc=gamepostproc; _gamepostproc=gamepostproc;
t_proc=0;
t_col=0;
t_over=0;
t_postproc=0;
f_count=0;
Draw_Loop(GameLib_ProcLoop); Draw_Loop(GameLib_ProcLoop);
printf("Profiling::::::::::::\n");
printf("t_proc........:%6lld\n",t_proc/f_count);
printf("t_col.........:%6lld\n",t_col/f_count);
printf("t_over........:%6lld\n",t_over/f_count);
printf("t_postprocdraw:%6lld\n",t_postproc/f_count);
} }
@@ -276,23 +338,30 @@ void GameLib_BreakLoop(){
} }
/////////////////////////////
// GameLib_GetPos
// GameLib_SetPos
// GameLib_SetPos
//
//
void GameLib_GetPos(int pos[2]){ void GameLib_GetPos(int pos[2]){
pos[0]=_game_pos[0]; pos[0]=_game_pos[0];
pos[1]=_game_pos[1]; pos[1]=_game_pos[1];
} }
void GameLib_SetPos(int pos[2]){ void GameLib_SetPos(int pos[2]){
_game_pos[0]=pos[0]; _game_pos[0]=pos[0];
_game_pos[1]=pos[1]; _game_pos[1]=pos[1];
} }
void GameLib_GetSize(int size[2]){ void GameLib_GetSize(int size[2]){
size[0]=_game_size[0]; size[0]=_game_size[0];
size[1]=_game_size[1]; size[1]=_game_size[1];
} }
/////////////////////////////
// GameLib_ForEachEn
//
// Deletes every entity.
void GameLib_DelEnts(){ void GameLib_DelEnts(){
int i; int i;
@@ -305,7 +374,10 @@ void GameLib_DelEnts(){
} }
/////////////////////////////
// GameLib_ForEachEn
//
// Iterates every entity.
void GameLib_ForEachEnt(int (*func)(Entity *ent)){ void GameLib_ForEachEnt(int (*func)(Entity *ent)){
int i; int i;
for(i=0;i<_n_entities;i++){ for(i=0;i<_n_entities;i++){
@@ -318,10 +390,15 @@ void GameLib_ForEachEnt(int (*func)(Entity *ent)){
} }
/////////////////////////////
// GameLib_PlaySound
//
//
void GameLib_PlaySound(AudioSnd snd,int x,int y){ void GameLib_PlaySound(AudioSnd snd,int x,int y){
float vleft,vright,vcen; float vleft,vright,vcen;
int r,cx,cy,off; int r,cx,cy,off;
// Get the screen context
cx=_game_pos[0]+_game_size[0]/2; cx=_game_pos[0]+_game_size[0]/2;
cy=_game_pos[1]+_game_size[1]/2; cy=_game_pos[1]+_game_size[1]/2;
if(_game_size[0]>_game_size[1]){ if(_game_size[0]>_game_size[1]){
@@ -332,26 +409,22 @@ void GameLib_PlaySound(AudioSnd snd,int x,int y){
r=r*1.2f; r=r*1.2f;
off=r/10.0f; off=r/10.0f;
vleft=vright=1.0f; // Calculate volumes
vcen=1.0f-(abs(y-cy)/(float)r); vcen=1.0f-(abs(y-cy)/(float)r);
vright=1.0f-(abs(x-(cx+off))/(float)r); vright=1.0f-(abs(x-(cx+off))/(float)r);
vleft=1.0f-(abs(x-(cx-off))/(float)r); vleft=1.0f-(abs(x-(cx-off))/(float)r);
vright*=vcen; vright*=vcen;
vleft*=vcen; vleft*=vcen;
// Clamp to 0
if(vleft<0.0f) if(vleft<0.0f)
vleft=0.0f; vleft=0.0f;
if(vright<0.0f) if(vright<0.0f)
vright=0.0f; vright=0.0f;
if(vleft<=0.0f && vright<=0.0f){ if(vleft<=0.0f && vright<=0.0f){
return; return;
} }
// PLAY!
Audio_PlaySound(snd,vleft,vright); Audio_PlaySound(snd,vleft,vright);
} }

View File

@@ -56,18 +56,36 @@ void GameLib_Loop(
void GameLib_BreakLoop(); void GameLib_BreakLoop();
/////////////////////////////
// GameLib_GetPos
// GameLib_SetPos
// GameLib_SetPos
//
//
void GameLib_GetPos(int pos[2]); void GameLib_GetPos(int pos[2]);
void GameLib_SetPos(int pos[2]); void GameLib_SetPos(int pos[2]);
void GameLib_GetSize(int size[2]); void GameLib_GetSize(int size[2]);
/////////////////////////////
// GameLib_ForEachEn
//
// Deletes every entity.
void GameLib_DelEnts(); void GameLib_DelEnts();
/////////////////////////////
// GameLib_ForEachEn
//
// Iterates every entity.
void GameLib_ForEachEnt(int (*func)(Entity *ent)); void GameLib_ForEachEnt(int (*func)(Entity *ent));
/////////////////////////////
// GameLib_PlaySound
//
// Play a sound position aware.
void GameLib_PlaySound(AudioSnd snd,int x,int y); void GameLib_PlaySound(AudioSnd snd,int x,int y);
#endif #endif

0
Makefile.common Executable file → Normal file
View File

View File

@@ -1,5 +1,5 @@
LIBS= -lSDL -lpthread -L/usr/X11R6/lib -L/usr/lib -lm LIBS= -lSDL -lpthread -L/usr/X11R6/lib -L/usr/lib -lm
CFLAGS= -Wall -g -I/usr/include/ -I/usr/include/SDL/ -I/usr/X11R6/include/ CFLAGS= -Wall -g -I/usr/include/ -I/usr/include/SDL/ -I/usr/X11R6/include/
CC=gcc CC=gcc
RM=rm -rf RM=rm -rf

61
Util.c
View File

@@ -30,7 +30,6 @@ int SolveQuadratic(float a,float b,float c,float *Rmin,float *Rmax){
return(1); return(1);
} }
///////////////////////////// /////////////////////////////
// Intersec_RayUnitCircle // Intersec_RayUnitCircle
// //
@@ -38,16 +37,21 @@ int SolveQuadratic(float a,float b,float c,float *Rmin,float *Rmax){
int Intersec_RayUnitCircle(vec2 orig,vec2 vel,vec2 center,float *t){ int Intersec_RayUnitCircle(vec2 orig,vec2 vel,vec2 center,float *t){
float a,b,c; float a,b,c;
float Rmin,Rmax; float Rmin,Rmax;
vec2 temp; vec2 distv;
float qlvel;
float qdistv;
// Check if the collision is even posible
qlvel=vec2_dot(vel,vel);
if(fabs(qlvel)<=0.0f)
return(0);
vec2_minus(distv,orig,center);
qdistv=vec2_dot(distv,distv);
// Solve as a unit circle // Solve as a unit circle
a=vec2_dot(vel,vel); a=qlvel;
if(fabs(a)<=0.0f){ b=2.0f*vec2_dot(distv,vel);
return(0); c=qdistv-1.0f;
}
vec2_minus(temp,orig,center);
b=2.0f*vec2_dot(temp,vel);
c=vec2_dot(temp,temp)-1.0f;
if(SolveQuadratic(a,b,c,&Rmin,&Rmax)){ if(SolveQuadratic(a,b,c,&Rmin,&Rmax)){
if(Rmin>=-0.0f && Rmin<Rmax && Rmin<=1.0f){ if(Rmin>=-0.0f && Rmin<Rmax && Rmin<=1.0f){
*t=Rmin; *t=Rmin;
@@ -67,25 +71,46 @@ int Intersec_RayUnitCircle(vec2 orig,vec2 vel,vec2 center,float *t){
// //
// Colision point of a circle against another circle. // Colision point of a circle against another circle.
int Colision_CircleCircle( int Colision_CircleCircle(
vec2 cir1[2],float rad1, vec2 cir1,float rad1,vec2 vel,
vec2 cir2,float rad2, vec2 cir2,float rad2,
float *t,vec2 n) float *t,vec2 n)
{ {
vec2 vel,orig,cen,temp; vec2 vel_a,orig_a,cen_a,temp;
float rads,invrads; float rads,invrads;
float maxx,minx;
float maxy,miny;
// Check if the collision is even posible
rads=rad1+rad2;
minx=cir1[0]-rads;
maxx=cir1[0]+rads;
if(vel[0]>0){
maxx+=vel[0];
}else{
minx+=vel[0];
}
if(cir2[0]<minx || cir2[0]>maxx)
return(0);
miny=cir1[1]-rads;
maxy=cir1[1]+rads;
if(vel[1]>0){
maxy+=vel[1];
}else{
miny+=vel[1];
}
if(cir2[1]<miny || cir2[1]>maxy)
return(0);
// Convert to a unit circle vs ray // Convert to a unit circle vs ray
rads=rad1+rad2; rads=rad1+rad2;
invrads=1.0f/rads; invrads=1.0f/rads;
vec2_minus(vel,cir1[1],cir1[0]); vec2_scale(vel_a,vel,invrads);
vec2_scale(vel,vel,invrads); vec2_scale(orig_a,cir1,invrads);
vec2_scale(orig,cir1[0],invrads); vec2_scale(cen_a,cir2,invrads);
vec2_scale(cen,cir2,invrads); if(Intersec_RayUnitCircle(orig_a,vel_a,cen_a,t)){
if(Intersec_RayUnitCircle(orig,vel,cen,t)){
// Calculate n // Calculate n
vec2_minus(vel,cir1[1],cir1[0]);
vec2_scale(temp,vel,*t); vec2_scale(temp,vel,*t);
vec2_plus(temp,cir1[0],temp); vec2_plus(temp,cir1,temp);
vec2_minus(temp,cir2,temp); vec2_minus(temp,cir2,temp);
vec2_scale(n,temp,1.0f/rads); vec2_scale(n,temp,1.0f/rads);
return(1); return(1);

4
Util.h
View File

@@ -31,14 +31,12 @@ typedef float vec2[2];
int Intersec_RayUnitCircle(vec2 orig,vec2 vel,vec2 center,float *t); int Intersec_RayUnitCircle(vec2 orig,vec2 vel,vec2 center,float *t);
///////////////////////////// /////////////////////////////
// Intersect_CircleCircle // Intersect_CircleCircle
// //
// Colision point of a circle against another circle. // Colision point of a circle against another circle.
int Colision_CircleCircle( int Colision_CircleCircle(
vec2 ca[2],float ra, vec2 cir1,float ra,vec2 vel,
vec2 cb,float rb, vec2 cb,float rb,
float *t,vec2 n); float *t,vec2 n);

View File

@@ -8,18 +8,19 @@
#.......# #.......#
#SSSSSS.# #SSSSSS.#
#.......# #.......#
#.B.LLLL# #.B.SSSS#
#SSSmmmm# #SSSmmmm#
#.......# ############ #.......# ############
#mmm.mmm# #....L.....# #mmm.mmm# #....L.....#
m.m #..S.L.S..<# m.m #..L.L.S..<#
m.m #..S.L.S...# m.m #..L.L.S...#
m.#######..S.L.S..<# m.#######..L.L.S..<#
m........2.S.L.S...# m........2.L.L.S...#
mmmmmmmmmSSS.L.S...# mmmmmmmmmmmL.L.S...#
m.>..L.S...# m.>L.L.S...#
m....L.S.B.######## m....L.S...#
m.>....S.B........# m.>..L.S...########
m.B....S..........#
mmmmmmmmmmmmmmmmm.# mmmmmmmmmmmmmmmmm.#
m.# m.#
m.# m.#

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

BIN
data/save_point_active.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

BIN
data/save_point_active.xcf Normal file

Binary file not shown.

41
main.c
View File

@@ -12,6 +12,7 @@
int play; int play;
int game_started=0;
int game_level=0; int game_level=0;
int game_level_point=1; int game_level_point=1;
int game_level_reset=0; int game_level_reset=0;
@@ -26,12 +27,17 @@ int ProcTitle(){
Draw_Clean(0,0,0); Draw_Clean(0,0,0);
Draw_DrawImg(img_logo,170,100); Draw_DrawImg(img_logo,170,100);
if(!game_started){
Draw_DrawText(font ,"Press [Space] to Start.",300,300); Draw_DrawText(font ,"Press [Space] to Start.",300,300);
}else{
Draw_DrawText(font ,"Press [Space] to Continue.",300,300);
}
Draw_DrawText(font ,"By Kableado (VAR)",200,440); Draw_DrawText(font ,"By Kableado (VAR)",200,440);
if(Input_AnyKey()){ if( Input_GetKey(InputKey_Jump)==InputKey_Pressed||
Input_GetKey(InputKey_Continue)==InputKey_Pressed)
{
play=1; play=1;
return(0); return(0);
} }
@@ -43,11 +49,14 @@ int ProcEnd(){
Draw_DrawImg(img_end,170,100); Draw_DrawImg(img_end,170,100);
Draw_DrawText(font ,"Congratulations you saved the kittie!",300,320); Draw_DrawText(font ,"Congratulations you saved the kittie!",250,320);
Draw_DrawText(font ,"Thanks for playing!",250,350);
Draw_DrawText(font ,"Thanks for playing!",100,440); Draw_DrawText(font ,"Press [Space] to Title.",300,400);
if(Input_AnyKey()){ if( Input_GetKey(InputKey_Jump)==InputKey_Pressed||
Input_GetKey(InputKey_Continue)==InputKey_Pressed)
{
return(0); return(0);
} }
return(1); return(1);
@@ -78,7 +87,7 @@ void PostProcGame(){
} }
if(game_level_reset){ if(game_level_reset){
if( Input_AnyKey()){ if(Input_AnyKey()){
if(GameMap_CreateLevel(game_level,game_level_point)){ if(GameMap_CreateLevel(game_level,game_level_point)){
if(game_level_reset==2){ if(game_level_reset==2){
int pos[2]={0,0}; int pos[2]={0,0};
@@ -107,19 +116,21 @@ int main(int argc,char *argv[]){
font=Draw_DefaultFont(255,255,255,255); font=Draw_DefaultFont(255,255,255,255);
font_shad=Draw_DefaultFont(0,0,0,127); font_shad=Draw_DefaultFont(0,0,0,127);
GameEnts_Init(); GameEnts_Init();
do{ do{
play=0; play=0;
Draw_Loop(ProcTitle); Draw_Loop(ProcTitle);
if(play==1){ if(play==1){
int pos[2]={0,0}; if(!game_started){
GameLib_SetPos(pos); int pos[2]={0,0};
GameLib_SetPos(pos);
game_level=0; game_level=3;
game_level_point=1; game_level_point=2;
game_level_reset=0; game_level_reset=0;
GameMap_CreateLevel(game_level,game_level_point);
GameMap_CreateLevel(game_level,game_level_point); }
game_started=1;
GameLib_Loop(ProcGame,PostProcGame); GameLib_Loop(ProcGame,PostProcGame);
} }
if(play==2){ if(play==2){

BIN
shot.bmp

Binary file not shown.

Before

Width:  |  Height:  |  Size: 900 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB