Skip to content
This repository has been archived by the owner on Nov 7, 2023. It is now read-only.

Commit

Permalink
fix most rendering inaccuracies
Browse files Browse the repository at this point in the history
  • Loading branch information
lemon32767 committed May 31, 2020
1 parent 9e625ff commit 00a8a29
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 36 deletions.
72 changes: 46 additions & 26 deletions celeste.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void Celeste_P8_set_call_func(callback_func_t func) {
static inline float P8sin(float x) {
return -sinf(x*6.2831853071796); //https://pico-8.fandom.com/wiki/Math
}
#define P8cos(x) -P8sin((x)+0.25) //cos(x) = sin(x+pi/2)
#define P8cos(x) (-P8sin((x)+0.25)) //cos(x) = sin(x+pi/2)
static inline float P8rnd(float max) {
return Celeste_P8_call(CELESTE_P8_RND, max).f;
}
Expand Down Expand Up @@ -102,7 +102,7 @@ static inline void P8map(int mx, int my, int tx, int ty, int mw, int mh, int mas
}


#define MAX_OBJECTS 16
#define MAX_OBJECTS 24
#define FRUIT_COUNT 30

// ~celeste~
Expand Down Expand Up @@ -299,7 +299,7 @@ typedef struct {
VEC dash_accel;
float spr_off;
bool was_on_ground;
HAIR hair[10]; //also player_spawn
HAIR hair[5]; //also player_spawn

//player_spawn
int state, delay;
Expand All @@ -321,7 +321,8 @@ typedef struct {
int sfx_delay;

//lifeup
int duration, flash;
int duration;
float flash;

//platform
float last, dir;
Expand All @@ -332,7 +333,7 @@ typedef struct {
VECI off2; //changed from off..

//big chest
PARTICLE particles[100];
PARTICLE particles[50];
int particle_count;

//flag
Expand Down Expand Up @@ -505,15 +506,22 @@ static void PLAYER_update(OBJ* this) {
if (pause_player) return;

int input = P8btn(k_right) ? 1 : (P8btn(k_left) ? -1 : 0);

/*LEMON: instead of calling kill_player() below, we call it at the end of this function.. */
/* this is because if we spawn smoke particles after doing kill_player they might spawn */
/* in the slot where the player was... and at the end of this function there is code that changes */
/* the spr property, to do player animation, but this would change the sprite of this smoke particle */

int do_kill_player = 0;

// spikes collide
if (spikes_at(this->x+this->hitbox.x,this->y+this->hitbox.y,this->hitbox.w,this->hitbox.h,this->spd.x,this->spd.y)) {
kill_player(this);
do_kill_player = 1;
}

// bottom death
if (this->y>128) {
kill_player(this);
do_kill_player = 1;
}

bool on_ground=OBJ_is_solid(this, 0,1);
Expand Down Expand Up @@ -557,7 +565,7 @@ static void PLAYER_update(OBJ* this) {
int maxrun=1;
float accel=0.6;
float deccel=0.15;
if (!on_ground) {
accel=0.4;
} else if (on_ice) {
Expand All @@ -572,7 +580,7 @@ static void PLAYER_update(OBJ* this) {
} else {
this->spd.x=appr(this->spd.x,input*maxrun,accel);
}
//facing
if (this->spd.x!=0) {
this->flip_x=(this->spd.x<0);
Expand Down Expand Up @@ -621,7 +629,7 @@ static void PLAYER_update(OBJ* this) {
}
}
}
// dash
float d_full=5;
float d_half=d_full*0.70710678118;
Expand Down Expand Up @@ -697,6 +705,7 @@ static void PLAYER_update(OBJ* this) {
// was on the ground
this->was_on_ground=on_ground;

if (do_kill_player) kill_player(this);
}
static void PLAYER_draw(OBJ* this) {
// clamp in screen
Expand Down Expand Up @@ -787,8 +796,9 @@ static void PLAYER_SPAWN_update(OBJ* this) {
this->delay-=1;
this->spr=6;
if (this->delay<0) {
destroy_object(this);
//destroy_object(this);
init_object(OBJ_PLAYER,this->x,this->y);
destroy_object(this); //LEMON: reordererd cus otherewise player object would not be drwn for the first frame (update wasnt being called since it overwrote this PLAYER_SPAWN slot)
}
}
}
Expand Down Expand Up @@ -821,13 +831,13 @@ static void SPRING_update(OBJ* this) {
hit->djump=max_djump;
this->delay=10;
init_object(OBJ_SMOKE,this->x,this->y);
// breakable below us
OBJ* below=OBJ_collide(this, OBJ_FALL_FLOOR,0,1);
if (below != NULL) {
break_fall_floor(below);
}
psfx(8);
}
} else if (this->delay>0) {
Expand Down Expand Up @@ -988,6 +998,7 @@ static void FLY_FRUIT_init(OBJ* this) {
this->sfx_delay=8;
}
static void FLY_FRUIT_update(OBJ* this) {
int do_destroy_object = 0; //LEMON: see PLAYER_update..
//fly away
if (this->fly) {
if (this->sfx_delay>0) {
Expand All @@ -999,7 +1010,7 @@ static void FLY_FRUIT_update(OBJ* this) {
}
this->spd.y=appr(this->spd.y,-3.5,0.25);
if (this->y<-16) {
destroy_object(this);
do_destroy_object = 1;
}
// wait
} else {
Expand All @@ -1017,8 +1028,9 @@ static void FLY_FRUIT_update(OBJ* this) {
P8sfx(13);
got_fruit[level_index()] = true;
init_object(OBJ_LIFEUP,this->x,this->y);
destroy_object(this);
do_destroy_object = 1;
}
if (do_destroy_object) destroy_object(this);
}
static void FLY_FRUIT_draw(OBJ* this) {
float off=0;
Expand Down Expand Up @@ -1053,7 +1065,7 @@ static void LIFEUP_update(OBJ* this) {
static void LIFEUP_draw(OBJ* this) {
this->flash+=0.5;

P8print("1000",this->x-2,this->y,7+this->flash%2);
P8print("1000",this->x-2,this->y,7+((int)this->flash)%2);
}

//fake_wall
Expand All @@ -1068,12 +1080,13 @@ static void FAKE_WALL_update(OBJ* this) {
hit->dash_time=-1;
sfx_timer=20;
P8sfx(16);
destroy_object(this);
//destroy_object(this);
init_object(OBJ_SMOKE,this->x,this->y);
init_object(OBJ_SMOKE,this->x+8,this->y);
init_object(OBJ_SMOKE,this->x,this->y+8);
init_object(OBJ_SMOKE,this->x+8,this->y+8);
init_object(OBJ_FRUIT,this->x+4,this->y+4);
destroy_object(this); //LEMON: moved here. see PLAYER_update
}
this->hitbox=(HITBOX){.x=0,.y=0,.w=16,.h=16};
}
Expand All @@ -1089,7 +1102,7 @@ static void FAKE_WALL_draw(OBJ* this) {
//if_not_fruit=true,
static void KEY_update(OBJ* this) {
int was=P8flr(this->spr);
this->spr=9+(P8sin(frames/30)+0.5)*1;
this->spr=9+(P8sin(frames/30.0)+0.5)*1;
int is=P8flr(this->spr);
if (is==10 && is!=was) {
this->flip_x=!this->flip_x;
Expand Down Expand Up @@ -1208,7 +1221,7 @@ static void BIG_CHEST_draw(OBJ* this) {
shake=5;
flash_bg=true;
if (this->timer<=45 && this->particle_count<50) {
this->particles[particle_count++] = (PARTICLE){
this->particles[this->particle_count++] = (PARTICLE){
.x=1+P8rnd(14),
.y=0,
.h=32+P8rnd(32),
Expand Down Expand Up @@ -1253,9 +1266,9 @@ static void ORB_draw(OBJ* this) {
}

P8spr(102,this->x,this->y, 1,1,false,false);
float off=frames/30;
float off=frames/30.0;
for (int i=0; i <= 7; i++) {
P8circfill(this->x+4+P8cos(off+i/8)*8,this->y+4+P8sin(off+i/8)*8,1,7);
P8circfill(this->x+4+P8cos(off+i/8.0)*8,this->y+4+P8sin(off+i/8.0)*8,1,7);
}
}

Expand Down Expand Up @@ -1320,7 +1333,7 @@ static void ROOM_TITLE_draw(OBJ* this) {
}
}
//print("//-",86,64-2,13)
draw_time(4,4);
}
}
Expand All @@ -1342,6 +1355,7 @@ static OBJ* init_object(OBJTYPE type, float x, float y) {
}
if (!obj) {
//no more free space for objects, give up
// printf("exhausted object memory..\n");
return NULL;
}
obj->active = true;
Expand Down Expand Up @@ -1563,7 +1577,7 @@ void Celeste_P8_draw() {
// clear screen
int bg_col = 0;
if (flash_bg) {
bg_col = frames/5;
bg_col = frames/5.0;
} else if (new_bg) {
bg_col=2;
}
Expand All @@ -1574,7 +1588,7 @@ void Celeste_P8_draw() {
CLOUD* c = &clouds[0];
while (!c->isLast) {
c->x += c->spd;
P8rectfill(c->x,c->y,c->x+c->w,c->y+4+(1-c->w/64)*12,new_bg ? 14 : 1);
P8rectfill(c->x,c->y,c->x+c->w,c->y+4+(1-c->w/64.0)*12,new_bg ? 14 : 1);
if (c->x > 128) {
c->x = -c->w;
c->y = P8rnd(128-8);
Expand Down Expand Up @@ -1667,9 +1681,8 @@ void Celeste_P8_draw() {
}

static void draw_object(OBJ* obj) {

if (OBJTYPE_prop(obj->type).draw !=NULL) {
OBJTYPE_prop(obj->type).draw(obj);
OBJTYPE_prop(obj->type).draw(obj);
} else if (obj->spr > 0) {
P8spr(obj->spr,obj->x,obj->y,1,1,obj->flip_x,obj->flip_y);
}
Expand Down Expand Up @@ -1749,3 +1762,10 @@ static bool spikes_at(int x,int y,int w,int h,float xspd,float yspd) {
}
return false;
}

//////////END/////////

void Celeste_P8__DEBUG(void) {
if (is_title()) start_game = true, start_game_flash=1;
else next_room();
}
10 changes: 6 additions & 4 deletions celeste.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ typedef union { float f; int i; } Celeste_P8_val;
typedef Celeste_P8_val (*callback_func_t) (CELESTE_P8_CALLBACK_TYPE calltype, ...);

extern void Celeste_P8_set_call_func(callback_func_t func);
extern void Celeste_P8_init();
extern void Celeste_P8_update();
extern void Celeste_P8_draw();
extern void Celeste_P8_init(void);
extern void Celeste_P8_update(void);
extern void Celeste_P8_draw(void);

extern void Celeste_P8__DEBUG(void); //debug functionality

typedef int Celeste_P8_bool_t;

#endif
#endif
32 changes: 26 additions & 6 deletions sdl12main.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ static const SDL_Color base_palette[16] = {
static SDL_Color palette[16];

static inline Uint32 getcolor(char idx) {
assert(idx >= 0 && idx < 16);
SDL_Color c = palette[(int)idx];
SDL_Color c = palette[idx%16];
return SDL_MapRGB(screen->format, c.r,c.g,c.b);
}

Expand Down Expand Up @@ -285,6 +284,9 @@ int main(int argc, char** argv) {
} else if (ev.key.keysym.sym == SDLK_f) {
SDL_WM_ToggleFullScreen(screen);
break;
} else if (0 && ev.key.keysym.sym == SDLK_5) {
Celeste_P8__DEBUG();
break;
}
//fallthrough
}
Expand Down Expand Up @@ -540,7 +542,20 @@ Celeste_P8_val pico8emu(CELESTE_P8_CALLBACK_TYPE call, ...) {
float cy = FLOAT_ARG() - camera_y;
float r = FLOAT_ARG();
int col = INT_ARG();
{

int realcolor = getcolor(col);

if (r <= 1) {
SDL_FillRect(screen, &(SDL_Rect){scale*(cx-1), scale*cy, scale*3, scale}, realcolor);
SDL_FillRect(screen, &(SDL_Rect){scale*cx, scale*(cy-1), scale, scale*3}, realcolor);
} else if (r <= 2) {
SDL_FillRect(screen, &(SDL_Rect){scale*(cx-2), scale*(cy-1), scale*5, scale*3}, realcolor);
SDL_FillRect(screen, &(SDL_Rect){scale*(cx-1), scale*(cy-2), scale*3, scale*5}, realcolor);
} else if (r <= 3) {
SDL_FillRect(screen, &(SDL_Rect){scale*(cx-3), scale*(cy-1), scale*7, scale*3}, realcolor);
SDL_FillRect(screen, &(SDL_Rect){scale*(cx-1), scale*(cy-3), scale*3, scale*7}, realcolor);
SDL_FillRect(screen, &(SDL_Rect){scale*(cx-2), scale*(cy-2), scale*5, scale*5}, realcolor);
} else { //i dont think the game uses this
int f = 1 - r; //used to track the progress of the drawn circle (since its semi-recursive)
int ddFx = 1; //step x
int ddFy = -2 * r; //step y
Expand Down Expand Up @@ -683,8 +698,8 @@ static void Xline(int x0, int y0, int x1, int y1, unsigned char color) {
Uint32 realcolor = getcolor(color);

#undef CLAMP
#define PLOT(x,y) do { \
SDL_FillRect(screen, &(SDL_Rect){x*scale,y*scale,scale,scale}, realcolor); \
#define PLOT(x,y) do { \
SDL_FillRect(screen, &(SDL_Rect){x*scale,y*scale,scale,scale}, realcolor); \
} while (0)
int sx, sy, dx, dy, err, e2;
dx = abs(x1 - x0);
Expand All @@ -694,7 +709,12 @@ static void Xline(int x0, int y0, int x1, int y1, unsigned char color) {
if (x0 < x1) sx = 1; else sx = -1;
if (y0 < y1) sy = 1; else sy = -1;
err = dx - dy;
while (x0 != x1 || y0 != y1) {
if (!dy && !dx) return;
else if (!dx) { //vertical line
for (int y = y0; y != y1; y += sy) PLOT(x0,y);
} else if (!dy) { //horizontal line
for (int x = x0; x != x1; x += sx) PLOT(x,y0);
} while (x0 != x1 || y0 != y1) {
PLOT(x0, y0);
e2 = 2 * err;
if (e2 > -dy) {
Expand Down

0 comments on commit 00a8a29

Please sign in to comment.