Frame draw interpolation between process frames.

This commit is contained in:
2013-04-15 23:59:35 +02:00
committed by Valeriano A.R
parent 11f5aad3ab
commit 87642abf43
7 changed files with 85 additions and 61 deletions

View File

@@ -71,7 +71,6 @@ int Draw_Init(int width,int height,char *title,int pfps,int fps){
SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute (SDL_GL_STENCIL_SIZE, 8);
SDL_GL_SetAttribute (SDL_GL_SWAP_CONTROL, 0);
SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
@@ -137,19 +136,21 @@ int Draw_Init(int width,int height,char *title,int pfps,int fps){
}
/////////////////////////////
// Draw_Loop
//
// Loops updating the game window.
void Draw_Loop(int (*proc)(),void (*draw)()){
void Draw_Loop(int (*proc)(),void (*draw)(float f)){
int done=0;
SDL_Event event;
Uint8* keys;
long long time,time2,timed;
long long t_frame=0;
long long newTime,accTime;
long long procTime1,procTime2,drawTime1,drawTime2,waitTime;
float frameFactor=0.0f;
t_frame=proc_t_frame;
time=Time_GetTime();
accTime=proc_t_frame;
procTime1=drawTime1=Time_GetTime();
while(!done){
// Update screen
@@ -177,39 +178,38 @@ void Draw_Loop(int (*proc)(),void (*draw)()){
// Sound Frame
Audio_Frame();
// Process and draw
// Process
if(proc){
while(t_frame>=proc_t_frame && !done){
if(accTime>100000){
accTime=100000;
}
while(accTime>=proc_t_frame && !done){
Input_Frame();
if(!proc()){
done=1;
}
t_frame-=proc_t_frame;
accTime-=proc_t_frame;
}
}
// Draw
if(draw){
draw();
frameFactor=(float)accTime/(float)proc_t_frame;
draw(frameFactor);
Draw_Flush();
}
// Measure time
time2=Time_GetTime();
timed=time2-time;
if(timed<draw_t_frame){
Time_Pause(draw_t_frame-timed);
time2=Time_GetTime();
t_frame+=time2-time;
}else{
t_frame+=timed;
}
time=time2;
// Wait to round draw_t_frame
drawTime2=Time_GetTime();
waitTime=draw_t_frame-(drawTime2-drawTime1);
Time_Pause(waitTime);
drawTime2=Time_GetTime();
drawTime1=drawTime2;
// FIX: Limit process frame rate
if(t_frame>50000){
t_frame=50000;
}
// Update time
procTime2=Time_GetTime();
accTime+=procTime2-procTime1;
procTime1=procTime2;
}
}

View File

@@ -15,7 +15,7 @@ int Draw_Init(int width,int height,char *title,int pfps,int fps);
// Draw_Loop
//
// Loops updating the game window.
void Draw_Loop(int (*proc)(),void (*draw)());
void Draw_Loop(int (*proc)(),void (*draw)(float f));
/////////////////////////////

View File

@@ -30,6 +30,7 @@ Entity *Entity_New(){
e->base=NULL;
e->type=0;
vec2_set(e->pos0,0.0f,0.0f);
vec2_set(e->pos,0.0f,0.0f);
e->flags=EntityFlag_Collision|EntityFlag_Overlap;
e->zorder=1;
@@ -146,9 +147,15 @@ Entity *Entity_Copy(Entity *e){
// Entity_Draw
//
//
void Entity_Draw(Entity *e,int x,int y){
void Entity_Draw(Entity *e,int x,int y,float f){
vec2 fPos;
Draw_SetColor(e->color[0],e->color[1],e->color[2],e->color[3]);
AnimPlay_Draw(&e->anim,e->pos[0]+x,e->pos[1]+y);
if(e->flags&EntityFlag_UpdatedPos){
vec2_interpol(fPos,e->pos0,e->pos,f);
AnimPlay_Draw(&e->anim,fPos[0]+x,fPos[1]+y);
}else{
AnimPlay_Draw(&e->anim,e->pos[0]+x,e->pos[1]+y);
}
}
@@ -202,6 +209,8 @@ void Entity_Process(Entity *b,int ft){
void Entity_PostProcess(Entity *e,int ft){
float qlen,len;
vec2_copy(e->pos0,e->pos);
// Determine if there is movement
qlen=vec2_dot(e->vel,e->vel);
if(qlen>0.0f){

View File

@@ -26,6 +26,7 @@ typedef struct Tag_Entity {
int type;
vec2 oldpos;
vec2 pos0;
vec2 pos;
int flags;
int zorder;
@@ -96,7 +97,7 @@ Entity *Entity_Copy(Entity *e);
// Entity_Draw
//
//
void Entity_Draw(Entity *e,int x,int y);
void Entity_Draw(Entity *e,int x,int y,float f);
/////////////////////////////
// Entity_IsVisible

View File

@@ -23,11 +23,12 @@ int _entities_lock=0;
int _entities_compactate=0;
void (*_gameproc)()=NULL;
void (*_gamepostproc)()=NULL;
void (*_gamepredraw)()=NULL;
void (*_gamedraw)()=NULL;
void (*_gamepredraw)(float f)=NULL;
void (*_gamedraw)(float f)=NULL;
int _ft;
int _game_size[2];
int _game_pos[2];
int _game_pos0[2];
int _game_pos1[2];
long long t_proc;
long long t_col;
@@ -55,8 +56,10 @@ int GameLib_Init(int w,int h,char *title,int pfps,int fps){
_game_size[0]=w;
_game_size[1]=h;
_game_pos[0]=0;
_game_pos[1]=0;
_game_pos0[0]=0;
_game_pos0[1]=0;
_game_pos1[0]=0;
_game_pos1[1]=0;
_ft=1000/fps;
@@ -177,6 +180,7 @@ void GameLib_Compactate(){
_entities_lock=0;
}
/////////////////////////////
// GameLib_ProcLoop
//
@@ -186,6 +190,9 @@ int GameLib_ProcLoop(){
int repeat,count;
long long time;
// Step the gamePosition
_game_pos0[0]=_game_pos1[0];
_game_pos0[0]=_game_pos1[0];
// Process
time=Time_GetTime();
@@ -201,7 +208,6 @@ int GameLib_ProcLoop(){
GameLib_Compactate();
t_proc+=Time_GetTime()-time;
// Colisions between entities
time=Time_GetTime();
GameLib_Compactate();_entities_lock=1;
@@ -221,6 +227,7 @@ int GameLib_ProcLoop(){
}
count++;
}while(repeat && count<10);
// Stop remaining collisions
if(count==10){
for(i=0;i<_n_entities;i++){
@@ -284,7 +291,6 @@ int GameLib_ProcLoop(){
n=n2;
}while(n>0);
// PostProcess
time=Time_GetTime();
GameLib_Compactate();_entities_lock=1;
@@ -310,20 +316,19 @@ int GameLib_ProcLoop(){
// GameLib_DrawLoop
//
//
void GameLib_DrawLoop(){
void GameLib_DrawLoop(float f){
long long time;
int i;
int game_pos[2];
game_pos[0]=_game_pos0[0]+f*(_game_pos1[0]-_game_pos0[0]);
game_pos[1]=_game_pos0[1]+f*(_game_pos1[1]-_game_pos0[1]);
time=Time_GetTime();
// Update Lights
//GameLib_UpdateIlumination();
// Predibujado
if(_gamepredraw){
_gamepredraw();
_gamepredraw(f);
}else{
// Limpiar pantalla
Draw_Clean(0,0,0);
@@ -336,7 +341,7 @@ void GameLib_DrawLoop(){
// Check visivility
if(!Entity_IsVisible(e,
_game_pos[0],_game_pos[1],
game_pos[0],game_pos[1],
_game_size[0],_game_size[1]))
{
continue;
@@ -348,15 +353,14 @@ void GameLib_DrawLoop(){
e->flags&=~EntityFlag_UpdateLight;
}
Entity_Draw(e,-_game_pos[0],-_game_pos[1]);
Entity_Draw(e,-game_pos[0],-game_pos[1],f);
}
Draw_SetColor(1,1,1,1);
if(_gamedraw){
_gamedraw();
_gamedraw(f);
}
GameLib_Compactate();
t_draw+=Time_GetTime()-time;
fdraw_count++;
@@ -370,8 +374,8 @@ void GameLib_DrawLoop(){
void GameLib_Loop(
void (*gameproc)(),
void (*gamepostproc)(),
void (*gamepredraw)(),
void (*gamedraw)())
void (*gamepredraw)(float f),
void (*gamedraw)(float f))
{
_running=1;
@@ -411,16 +415,23 @@ void GameLib_BreakLoop(){
/////////////////////////////
// GameLib_GetPos
// GameLib_SetPos
// GameLib_UpdatePos
// GameLib_SetPos
//
//
void GameLib_GetPos(int pos[2]){
pos[0]=_game_pos[0];
pos[1]=_game_pos[1];
pos[0]=_game_pos1[0];
pos[1]=_game_pos1[1];
}
void GameLib_SetPos(int pos[2]){
_game_pos[0]=pos[0];
_game_pos[1]=pos[1];
_game_pos0[0]=pos[0];
_game_pos0[1]=pos[1];
_game_pos1[0]=pos[0];
_game_pos1[1]=pos[1];
}
void GameLib_UpdatePos(int pos[2]){
_game_pos1[0]=pos[0];
_game_pos1[1]=pos[1];
}
void GameLib_GetSize(int size[2]){
size[0]=_game_size[0];
@@ -441,10 +452,10 @@ void GameLib_MoveToPos(vec2 pos,float f){
GameLib_MoveToPosV(pos,f);
}
void GameLib_MoveToPosH(vec2 pos,float f){
_game_pos[0]=_game_pos[0]+(pos[0]-(_game_pos[0]+(_game_size[0]/2.0f)))*f;
_game_pos1[0]=_game_pos1[0]+(pos[0]-(_game_pos1[0]+(_game_size[0]/2.0f)))*f;
}
void GameLib_MoveToPosV(vec2 pos,float f){
_game_pos[1]=_game_pos[1]+(pos[1]-(_game_pos[1]+(_game_size[1]/2.0f)))*f;
_game_pos1[1]=_game_pos1[1]+(pos[1]-(_game_pos1[1]+(_game_size[1]/2.0f)))*f;
}
@@ -491,8 +502,8 @@ void GameLib_PlaySound(AudioSnd snd,int x,int y){
int r,cx,cy,off;
// Get the screen context
cx=_game_pos[0]+_game_size[0]/2;
cy=_game_pos[1]+_game_size[1]/2;
cx=_game_pos1[0]+_game_size[0]/2;
cy=_game_pos1[1]+_game_size[1]/2;
if(_game_size[0]>_game_size[1]){
r=_game_size[0]/2;
}else{

View File

@@ -47,8 +47,8 @@ int GameLib_DelEntity(Entity *e);
void GameLib_Loop(
void (*gameproc)(),
void (*gamepostproc)(),
void (*gamepredraw)(),
void (*gamedraw)());
void (*gamepredraw)(float f),
void (*gamedraw)(float f));
/////////////////////////////

View File

@@ -26,6 +26,9 @@ typedef float vec2[2];
#define vec2_perp(v,n) (v)[0]=-(n)[1];(v)[1]=(n)[0];
#define vec2_scaleadd(v,v1,v2,s) (v)[0]=(v2)[0]*(s)+(v1)[0];(v)[1]=(v2)[1]*(s)+(v1)[1];
float vec2_norm(vec2 v);
#define vec2_interpol(v,v1,v2,f) \
(v)[0]=(v1)[0]-f*((v1)[0]-(v2)[0]);\
(v)[1]=(v1)[1]-f*((v1)[1]-(v2)[1]);
/////////////////////////////