diff --git a/assets-fx/fxconv-metadata.txt b/assets-fx/fxconv-metadata.txt index d6d7d33..2766769 100644 --- a/assets-fx/fxconv-metadata.txt +++ b/assets-fx/fxconv-metadata.txt @@ -1,3 +1,4 @@ sprite.png: type: bopti-image name: sprite_tst + profile: gray_alpha diff --git a/assets-fx/sprite.png b/assets-fx/sprite.png index 3dbb8a7..d934f88 100644 Binary files a/assets-fx/sprite.png and b/assets-fx/sprite.png differ diff --git a/src/config.h b/src/config.h index 7ffaef0..1af00fe 100644 --- a/src/config.h +++ b/src/config.h @@ -6,6 +6,8 @@ #define viewport_w 128 #define viewport_h 64 #define max_dist fix(32) +//Max sprites to attempt to render +#define max_sprites 16 #define TSIZE 32 diff --git a/src/main.c b/src/main.c index 12bdf16..6063f28 100644 --- a/src/main.c +++ b/src/main.c @@ -112,7 +112,9 @@ int main(){ goto c3d_abort; dupdate(); - dclear(C_WHITE); + dclear(0); + dprint(0,0,3,"%d",image_layer_count(sprite_tst.profile)); + dupdate();getkey(); #if debug EngineTimers timers; @@ -124,6 +126,8 @@ int main(){ .tex = 4 }; + add_sprite(&tsprite); + while (!exit_game) { prof_t frame = prof_make(); prof_enter(frame); @@ -143,7 +147,7 @@ int main(){ &game ); - project_sprite(tex_index, &tsprite, &game.player); + draw_sprites(tex_index, &game.player); if (disp_frame_time == 1) dprint( 0, 0, C_BLACK, "%d ms", frame_time); diff --git a/src/moteur.c b/src/moteur.c index 396f15f..560cea5 100644 --- a/src/moteur.c +++ b/src/moteur.c @@ -7,14 +7,13 @@ #include #include +#include #include #include #include #include "fixed.h" -#include "gint/display-cg.h" -#include "gint/display-fx.h" #include "moteur.h" #include "map.h" #include "game.h" @@ -23,7 +22,6 @@ // moteur.c : // ici se trouvent tout ce qui concerne les graphismes, mouvement et collisions // -// //1D zbuf for sprites fixed_t zbuf[viewport_w]; @@ -107,22 +105,6 @@ void load_map(){ //Fonction fournie par le grand Lephé :D inline int __attribute__((always_inline)) get_pixel(bopti_image_t const *img, int u, int v) -{ - int layers = 2; - int columns = (img->width + 31) >> 5; - - uint32_t const *layer_ptr = (void *)img->data; - layer_ptr += (v * columns + (u >> 5)) * layers; - - uint32_t mask = 0x80000000u >> (u & 31); - - int light = (layer_ptr[0] & mask) != 0; - int dark = (layer_ptr[1] & mask) != 0; - return (dark << 1) + light; -} - -inline int __attribute__((always_inline)) - get_pixel_alpha(bopti_image_t const *img, int u, int v) { int layers = image_layer_count(img->profile); int columns = (img->width + 31) >> 5; @@ -134,7 +116,11 @@ inline int __attribute__((always_inline)) int light = (layer_ptr[0] & mask) != 0; int dark = (layer_ptr[1] & mask) != 0; - return (dark << 1) + light; + int alpha = 0; + if(layers > 2){ + alpha = !(layer_ptr[2] & mask); + } + return (alpha << 2) + (dark << 1) + light; } uint32_t *light, *dark; @@ -169,6 +155,9 @@ inline void __attribute__((always_inline)) light[offset] |= mask; dark [offset] |= mask; break; + case C_NONE: + break; + default: break; } } diff --git a/src/moteur.h b/src/moteur.h index 9d85339..093a582 100644 --- a/src/moteur.h +++ b/src/moteur.h @@ -16,6 +16,8 @@ typedef struct { } EngineTimers; +int get_pixel(bopti_image_t const *tex, int u, int v); + void dscale_bopti(bopti_image_t *tex, fixed_t scale_x, fixed_t scale_y, int x, int y); diff --git a/src/sprites.c b/src/sprites.c index b1c6349..6c8b157 100644 --- a/src/sprites.c +++ b/src/sprites.c @@ -2,12 +2,15 @@ #include #include +#include +#include #include "game.h" #include "sprites.h" #include "moteur.h" #include "config.h" #include "fixed.h" +#include "utils.h" extern fixed_t zbuf[viewport_w]; @@ -16,15 +19,17 @@ int spritec; Sprite *sprite_index[SINDEX_S]; void add_sprite(Sprite *sprite){ - + if(spritec >= SINDEX_S) + return; + sprite_index[spritec++] = sprite; } -void remove_sprite(Sprite *sprite){ - +void clear_sprites(){ + spritec = 0; } -void draw_sprites(){ - +void remove_sprite(GUNUSED Sprite *sprite){ + //TODO } //Lodev's sprite projection, translated @@ -72,7 +77,6 @@ void project_sprite(bopti_image_t *tex_index[], Sprite *sprite, RcActor *player) fixed_t sprite_size = fdiv(fix(sprite_w), fix(TSIZE)); for(int x = sprite_pos_x; x < sprite_end_x; x++){ - //TODO : Zbuffer if(ty < 0 || x < 0 || ty > zbuf[x]) continue; if(x > viewport_w) @@ -80,7 +84,39 @@ void project_sprite(bopti_image_t *tex_index[], Sprite *sprite, RcActor *player) int tex_x = ffloor((x-sprite_pos_x) * fdiv(fix(TSIZE), fix(sprite_w))); tex_x %= TSIZE; - //dline(x, sprite_pos_y, x, sprite_pos_y+sprite_w,2); draw_stripe(tex_index[4], 0, sprite_pos_y, sprite_size, tex_x, x); } } + +struct SpriteDist{ + fixed_t dist; + int id; +}; + +int sprite_cmpfnc(const void *p1, const void *p2){ + return ((struct SpriteDist*)p2)->dist - ((struct SpriteDist*)p1)->dist; +} + +void draw_sprites(bopti_image_t *tex_index[], RcActor *player){ + struct SpriteDist dists[SINDEX_S]; + memset(dists, 0, sizeof(struct SpriteDist)*SINDEX_S); + for(int i = 0; i < spritec; i++){ + Sprite *spr = sprite_index[i]; + fixed_t d = player->pos.x - spr->pos.x; + d = fmul(d,d); + d += fmul(player->pos.y - spr->pos.y,player->pos.y - spr->pos.y); + dists[i].dist = d; + dists[i].id = i; + } + + qsort(dists, SINDEX_S, sizeof(struct SpriteDist), &sprite_cmpfnc); + + int msprite = min(spritec,max_sprites); + for(int i = msprite; i > 0; i--){ + struct SpriteDist *sd = &dists[i]; + Sprite *spr = sprite_index[sd->id]; + if(sd->dist > max_dist) + continue; + project_sprite(tex_index, spr, player); + } +} diff --git a/src/sprites.h b/src/sprites.h index 44e9e56..aed5543 100644 --- a/src/sprites.h +++ b/src/sprites.h @@ -14,6 +14,12 @@ typedef struct { int tex; } Sprite; -void project_sprite(bopti_image_t *tex_index[], Sprite *sprite, RcActor *player); +//Adds the sprite reference to the internal sprite index +// /!\ This sprite reference may be used at every call of draw_sprites +void add_sprite(Sprite *sprite); + +void clear_sprites(); + +void draw_sprites(bopti_image_t *tex_index[], RcActor *player); #endif diff --git a/src/utils.h b/src/utils.h index ebf556e..e17cfd8 100644 --- a/src/utils.h +++ b/src/utils.h @@ -5,5 +5,6 @@ #include +#define min(x, xmin) (x > xmin ? xmin:x) #endif