Index: proj/include/graph.h
===================================================================
--- proj/include/graph.h	(revision 191)
+++ proj/include/graph.h	(revision 192)
@@ -37,12 +37,4 @@
 /// DRAW
 int (graph_draw)(void);
 
-
-
-/// RECTANGLE
-
-
-int (graph_draw_hline)(uint16_t x, uint16_t y, uint16_t len, uint32_t color);
-int (graph_draw_rectangle)(uint16_t x, uint16_t y,uint16_t width, uint16_t height, uint32_t color);
-
 #endif /* end of include guard: GRAPH_H_INCLUDED */
Index: proj/include/proj_func.h
===================================================================
--- proj/include/proj_func.h	(revision 191)
+++ proj/include/proj_func.h	(revision 192)
@@ -1,7 +1,7 @@
 #ifndef PROJ_FUNC_H_INCLUDED
 #define PROJ_FUNC_H_INCLUDED
 
-#include "sprite.h"
+#include "ent.h"
 
 /**
  * @brief Cleans up all memory, unsubscribes interrupts.
@@ -15,7 +15,7 @@
 /**
  * @brief Updates movement variables.
  */
-void update_movement(sprite_t *p);
+void update_movement(ent_t *p);
 
 void update_mouse_position(struct packet *p);
 
@@ -30,7 +30,7 @@
  * @param
  * @return Angle
  */
-double get_mouse_angle(sprite_t *p);
+double get_mouse_angle(ent_t *p);
 
 /**
  * @brief Get horizontal movement direction.
Index: proj/include/sprite.h
===================================================================
--- proj/include/sprite.h	(revision 191)
+++ proj/include/sprite.h	(revision 192)
@@ -1,10 +1,28 @@
 #ifndef SPRITE_H_INCLUDED
 #define SPRITE_H_INCLUDED
 
+struct basic_sprite;
+typedef struct basic_sprite basic_sprite_t;
+
+basic_sprite_t* (basic_sprite_ctor)(const char **xpm, int16_t u0, int16_t v0);
+void            (basic_sprite_dtor)(basic_sprite_t *p);
+
+const uint8_t* (basic_sprite_get_map)(const basic_sprite_t *p);
+uint16_t       (basic_sprite_get_w)  (const basic_sprite_t *p);
+uint16_t       (basic_sprite_get_h)  (const basic_sprite_t *p);
+int16_t        (basic_sprite_get_u0) (const basic_sprite_t *p);
+int16_t        (basic_sprite_get_v0) (const basic_sprite_t *p);
+
 struct sprite;
 typedef struct sprite sprite_t;
 
-sprite_t* (sprite_ctor)(const char **xpm, int u0, int v0);
+sprite_t* (sprite_ctor)(const basic_sprite_t *bsp);
+/*
+ * /!\ WARNING: Entity destructor does not destruct the basic_sprite passed as
+ * constructor arguments, since it is assumed the same basic_sprite may be used to
+ * draw several sprites. It is thus YOUR responsibility to delete basic_sprite's.
+ * @param   p   Pointer to sprite_t to be destructed
+ */
 void      (sprite_dtor)(sprite_t *p);
 
 void (sprite_set_pos)   (sprite_t *p, int16_t x, int16_t y);
Index: proj/src/font.c
===================================================================
--- proj/src/font.c	(revision 191)
+++ proj/src/font.c	(revision 192)
@@ -72,13 +72,19 @@
         free(ret);
         return NULL;
     }
+    int good = false;
     char filepath[1024];
     for(size_t i = 0; i < ret->nchars; ++i){
         sprintf(filepath, "%s/ascii%03d.xpm2", s, i);
         char **xpm = xpm_load_xpm2(filepath);
         ret->glyphs[i] = glyph_ctor((const char**)xpm);
+        if(ret->glyphs[i] != NULL) good = true;
     }
-    return ret;
+    if(good) return ret;
+    else{
+        //font_dtor(ret);
+        return NULL;
+    }
 }
 void (font_dtor)(font_t *p){
     if(p == NULL) return;
Index: proj/src/graph.c
===================================================================
--- proj/src/graph.c	(revision 191)
+++ proj/src/graph.c	(revision 192)
@@ -301,18 +301,3 @@
     memcpy(video_mem, video_buf, graph_get_vram_size());
     return 0;
 }
-
-/// RECTANGLE
-int (graph_draw_hline)(uint16_t x, uint16_t y, uint16_t len, uint32_t color){
-    int r;
-    for (uint16_t i = 0; i < len; i++)
-        if ((r = graph_set_pixel(x + i, y, color))) return r;
-    return SUCCESS;
-}
-
-int (graph_draw_rectangle)(uint16_t x, uint16_t y,uint16_t width, uint16_t height, uint32_t color)	{
-    int r;
-    for (uint16_t i = 0; i < height; i++)
-        if ((r = graph_draw_hline(x, y + i, width, color))) return r;
-    return SUCCESS;
-}
Index: proj/src/proj.c
===================================================================
--- proj/src/proj.c	(revision 191)
+++ proj/src/proj.c	(revision 192)
@@ -17,16 +17,13 @@
 #include "sprite.h"
 #include "rectangle.h"
 #include "font.h"
+#include "ent.h"
 
-#ifdef DIOGO
-    #include "shooter.h"
-#endif
+#include "crosshair.h"
+#include "shooter.h"
+#include "pistol.h"
+#include "nothing.h"
 
-#ifdef TELMO
-    #include "crosshair.h"
-    #include "shooter.h"
-#endif
-
 int main(int argc, char* argv[]) {
 
     lcf_set_language("EN-US");
@@ -46,6 +43,9 @@
 
     int r;
 
+    font_t *consolas = font_ctor("/home/lcom/labs/proj/font/Consolas/xpm2");
+    if(consolas == NULL){ printf("Failed to load consolas\n"); return 1; }
+
     /// subscribe interrupts
     if (subscribe_all()) { return 1; }
 
@@ -56,9 +56,12 @@
         return 1;
     }
 
-    font_t *consolas = font_ctor("/home/lcom/labs/proj/font/xpm2");
-
     /// Load stuff
+    basic_sprite_t *bsp_crosshair = NULL;
+    basic_sprite_t *bsp_shooter   = NULL;
+    basic_sprite_t *bsp_pistol    = NULL;
+    basic_sprite_t *bsp_nothing   = NULL;
+    sprite_t       *sp_crosshair  = NULL;
     {
         graph_clear_screen();
         text_t *txt = text_ctor(consolas, "Loading...");
@@ -65,7 +68,15 @@
         text_draw(txt);
         text_dtor(txt);
         graph_draw();
+
+        bsp_crosshair = get_crosshair(); if(bsp_crosshair == NULL) printf("Failed to get crosshair\n");
+        bsp_shooter   = get_shooter  (); if(bsp_shooter   == NULL) printf("Failed to get shooter\n");
+        bsp_pistol    = get_pistol   (); if(bsp_pistol    == NULL) printf("Failed to get pistol\n");
+        bsp_nothing   = get_nothing  (); if(bsp_nothing   == NULL) printf("Failed to get nothing\n");
+
+        sp_crosshair = sprite_ctor(bsp_crosshair); if(sp_crosshair == NULL) printf("Failed to get crosshair sprite\n");
     }
+
     #ifdef DIOGO
         graph_clear_screen();
 
@@ -96,13 +107,19 @@
     #endif
 
     #ifdef TELMO
-        sprite_t *crosshair = get_crosshair();
-        sprite_t *shooter1 = get_shooter();
-        sprite_set_pos(shooter1, graph_get_XRes()/2, graph_get_YRes()/2);
-        sprite_set_scale(shooter1, 4);
+        ent_set_scale(2.0);
+
+        ent_t *shooter1 = ent_ctor(bsp_shooter, bsp_pistol); if(shooter1 == NULL) printf("Failed to get shooter1\n");
+        ent_set_pos(shooter1, 0, 0);
+        ent_set_origin(ent_get_x(shooter1)-ent_get_XLength()/2.0,
+                       ent_get_y(shooter1)-ent_get_YLength()/2.0);
+
+        ent_t *shooter2 = ent_ctor(bsp_shooter, bsp_nothing);
+        ent_set_pos(shooter2, -50, -50);
+
         graph_clear_screen();
-        sprite_draw(crosshair);
-        sprite_draw(shooter1);
+        ent_draw(shooter1);
+        sprite_draw(sp_crosshair);
         graph_draw();
     #endif
 
@@ -133,12 +150,16 @@
                                 uint32_t refresh_count_value = sys_hz() / REFRESH_RATE;
                                 if (no_interrupts % refresh_count_value == 0) {
                                     update_movement(shooter1);
-                                    sprite_set_pos(crosshair, get_mouse_X(), get_mouse_Y());
+                                    ent_set_origin(ent_get_x(shooter1)-ent_get_XLength()/2.0,
+                                                   ent_get_y(shooter1)-ent_get_YLength()/2.0);
+
+                                    sprite_set_pos(sp_crosshair, get_mouse_X(), get_mouse_Y());
                                     double angle = get_mouse_angle(shooter1);
-                                    sprite_set_angle(shooter1, angle - M_PI_2);
+                                    ent_set_angle(shooter1, angle - M_PI_2);
                                     graph_clear_screen();
-                                    sprite_draw(crosshair);
-                                    sprite_draw(shooter1);
+                                    ent_draw(shooter2);
+                                    ent_draw(shooter1);
+                                    sprite_draw(sp_crosshair);
                                     graph_draw();
                                 }
                             }
@@ -181,8 +202,15 @@
         #endif
     }
 
-    font_dtor(consolas);
+    #ifdef TELMO
+        ent_dtor(shooter1); shooter1 = NULL;
+    #endif
 
+    basic_sprite_dtor(bsp_crosshair); bsp_crosshair = NULL;
+    basic_sprite_dtor(bsp_shooter  ); bsp_shooter   = NULL;
+    sprite_dtor      (sp_crosshair ); sp_crosshair  = NULL;
+    font_dtor        (consolas     ); consolas      = NULL;
+
     // Unsubscribe interrupts
     if (unsubscribe_all()) {
         if (cleanup())
Index: proj/src/proj_func.c
===================================================================
--- proj/src/proj_func.c	(revision 191)
+++ proj/src/proj_func.c	(revision 192)
@@ -43,10 +43,9 @@
     hor_mov = d_pressed - a_pressed;
 }
 
-void update_movement(sprite_t *p) {
-
+void update_movement(ent_t *p) {
     static const int speed = 5;
-    sprite_set_pos(p, sprite_get_x(p) + speed * hor_mov, sprite_get_y(p) + speed * ver_mov);
+    ent_set_pos(p, ent_get_x(p) + speed * hor_mov, ent_get_y(p) + speed * ver_mov);
 }
 
 static int32_t mouse_x = 0, mouse_y = 0;
@@ -63,8 +62,8 @@
 
 int32_t get_mouse_Y(void) { return mouse_y; }
 
-double get_mouse_angle(sprite_t *p) {
-    return atan2(sprite_get_y(p) - mouse_y, mouse_x - sprite_get_x(p));
+double get_mouse_angle(ent_t *p) {
+    return atan2(ent_get_y_screen(p) - mouse_y, mouse_x - ent_get_x_screen(p));
 }
 
 int get_hor_movement(void) { return hor_mov; }
Index: proj/src/sprite.c
===================================================================
--- proj/src/sprite.c	(revision 191)
+++ proj/src/sprite.c	(revision 192)
@@ -7,17 +7,14 @@
 #include "fast_math.h"
 #include <math.h>
 
-struct sprite{
-    int16_t x, y;
+struct basic_sprite{
+    uint8_t *map;
     uint16_t w, h;
     int16_t u0, v0;
-    double theta;
-    double scale;
-    uint8_t *map;
 };
 
-sprite_t* (sprite_ctor)(const char **xpm, int u0, int v0){
-    sprite_t *ret = (sprite_t*)malloc(sizeof(sprite_t));
+basic_sprite_t* (basic_sprite_ctor)(const char **xpm, int16_t u0, int16_t v0){
+    basic_sprite_t *ret = malloc(sizeof(basic_sprite_t));
     if(ret == NULL) return NULL;
     enum xpm_image_type type = XPM_8_8_8_8;
     xpm_image_t img;
@@ -26,30 +23,51 @@
         free(ret);
         return NULL;
     }
-    ret->x = 0;
-    ret->y = 0;
     ret->w = img.width;
     ret->h = img.height;
     ret->u0 = u0;
-    ret->v0 = u0;
-    ret->theta = 0;
-    ret->scale = 1;
+    ret->v0 = v0;
     return ret;
 }
-void (sprite_dtor)(sprite_t *p){
+void (basic_sprite_dtor)(basic_sprite_t *p){
     if(p == NULL) return;
     free(p->map);
     free(p);
 }
 
+const uint8_t* (basic_sprite_get_map)(const basic_sprite_t *p){ return p->map; }
+uint16_t       (basic_sprite_get_w)  (const basic_sprite_t *p){ return p->w  ; }
+uint16_t       (basic_sprite_get_h)  (const basic_sprite_t *p){ return p->h  ; }
+int16_t        (basic_sprite_get_u0) (const basic_sprite_t *p){ return p->u0 ; }
+int16_t        (basic_sprite_get_v0) (const basic_sprite_t *p){ return p->v0 ; }
+
+struct sprite{
+    const basic_sprite_t *bsp;
+    int16_t x, y; //position in screen
+    double theta;
+    double scale;
+};
+
+sprite_t* (sprite_ctor)(const basic_sprite_t *bsp){
+    sprite_t *ret = malloc(sizeof(sprite_t));
+    if(ret == NULL) return NULL;
+    ret->bsp = bsp;
+    ret->x = 0;
+    ret->y = 0;
+    ret->theta = 0.0;
+    ret->scale = 1.0;
+    return ret;
+}
+void (sprite_dtor)(sprite_t *p){
+    if(p == NULL) return;
+    free(p);
+}
+
 void (sprite_set_pos)   (sprite_t *p, int16_t x , int16_t y ){ p->x = x; p->y = y; }
-void (sprite_set_center)(sprite_t *p, int16_t u0, int16_t v0){ p->u0 = u0; p->v0 = v0; }
 void (sprite_set_angle) (sprite_t *p, double angle          ){ p->theta = angle; }
 void (sprite_set_scale) (sprite_t *p, double scale          ){ p->scale = scale; }
 int16_t  (sprite_get_x)(const sprite_t *p){ return p->x; }
 int16_t  (sprite_get_y)(const sprite_t *p){ return p->y; }
-uint16_t (sprite_get_w)(const sprite_t *p){ return p->w; }
-uint16_t (sprite_get_h)(const sprite_t *p){ return p->h; }
 
 void (sprite_src2pic)(const sprite_t *p, int16_t x, int16_t y, int16_t *u, int16_t *v){
     double s = fm_sin(p->theta);
@@ -58,15 +76,15 @@
     double dy = (y - p->y)/p->scale;
     int16_t du = dx*c - dy*s + 0.5;
     int16_t dv = dx*s + dy*c + 0.5;
-    *u = du + p->u0;
-    *v = dv + p->v0;
+    *u = du + basic_sprite_get_u0(p->bsp);
+    *v = dv + basic_sprite_get_v0(p->bsp);
 }
 
 void (sprite_pic2src)(const sprite_t *p, int16_t u, int16_t v, int16_t *x, int16_t *y){
     double s = fm_sin(p->theta);
     double c = fm_cos(p->theta);
-    int16_t du = u - p->u0;
-    int16_t dv = v - p->v0;
+    int16_t du = u - basic_sprite_get_u0(p->bsp);
+    int16_t dv = v - basic_sprite_get_v0(p->bsp);
     double dx =  du*c + dv*s;
     double dy = -du*s + dv*c;
     *x = dx*p->scale + 0.5 + p->x;
@@ -74,28 +92,28 @@
 }
 
 void (sprite_draw)(const sprite_t *p){
+    const uint16_t w = basic_sprite_get_w(p->bsp);
+    const uint16_t h = basic_sprite_get_h(p->bsp);
     int16_t xmin, xmax, ymin, ymax; {
         int16_t x, y;
-        sprite_pic2src(p, 0   , 0   , &x, &y);
+        sprite_pic2src(p, 0, 0, &x, &y);
         xmin = x; xmax = x; ymin = y; ymax = y;
-        sprite_pic2src(p, p->w, 0   , &x, &y);
+        sprite_pic2src(p, w, 0, &x, &y);
         xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax);
-        sprite_pic2src(p, 0   , p->h, &x, &y);
+        sprite_pic2src(p, 0, h, &x, &y);
         xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax);
-        sprite_pic2src(p, p->w, p->h, &x, &y);
+        sprite_pic2src(p, w, h, &x, &y);
         xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax);
         xmin = max(xmin-2, 0); xmax = min(xmax+2, graph_get_XRes());
         ymin = max(ymin-2, 0); ymax = min(ymax+2, graph_get_YRes());
     }
+    const uint8_t *map = basic_sprite_get_map(p->bsp);
     int16_t u, v;
     for(int16_t y = ymin; y < ymax; ++y){
         for(int16_t x = xmin; x < xmax; ++x){
-    //const int16_t diag = p->scale*sqrt(p->w*p->w + p->h*p->h)+2;
-    //for(int16_t y = max(0,p->y-diag); y < min(p->y+diag,graph_get_YRes()); ++y){
-    //    for(int16_t x = max(0,p->x-diag); x < min(p->x+diag,graph_get_XRes()); ++x){
             sprite_src2pic(p, x, y, &u, &v);
-            if(0 <= u && u < p->w && 0 <= v && v < p->h){
-                uint32_t c = *(uint32_t*)(p->map + (v*p->w + u)*4);
+            if(0 <= u && u < w && 0 <= v && v < h){
+                uint32_t c = *(uint32_t*)(map + (v*w + u)*4);
                 graph_set_pixel_alpha(x, y, GET_COLOR(c), GET_ALP(c));
             }
         }
Index: proj/src/xpm_utils.c
===================================================================
--- proj/src/xpm_utils.c	(revision 191)
+++ proj/src/xpm_utils.c	(revision 192)
@@ -21,7 +21,7 @@
 char** xpm_load_xpm2(const char *fpath){
     FILE *f = fopen(fpath, "r");
     if(f == NULL) return NULL;
-    char *line_buf = malloc(1024*sizeof(char)); size_t len = 1024;
+    size_t len = 1024; char *line_buf = malloc(len*sizeof(char));
     int sz;
 
     char **ret = NULL;
Index: proj/xpm/crosshair.h
===================================================================
--- proj/xpm/crosshair.h	(revision 191)
+++ proj/xpm/crosshair.h	(revision 192)
@@ -1,6 +1,6 @@
 #include "crosshair.xpm"
 #include "sprite.h"
 
-sprite_t* get_crosshair(){
-    return sprite_ctor(crosshair_xpm, 16, 16);
+basic_sprite_t* get_crosshair(){
+    return basic_sprite_ctor(crosshair_xpm, 16, 16);
 }
Index: proj/xpm/shooter.h
===================================================================
--- proj/xpm/shooter.h	(revision 191)
+++ proj/xpm/shooter.h	(revision 192)
@@ -1,6 +1,11 @@
+#ifndef SHOOTER_H_INCLUDED
+#define SHOOTER_H_INCLUDED
+
 #include "shooter.xpm"
 #include "sprite.h"
 
-sprite_t* get_shooter(){
-    return sprite_ctor((const char **)shooter_xpm, 34, 34);
+basic_sprite_t* get_shooter(void){
+    return basic_sprite_ctor((const char **)shooter_xpm, 34, 34);
 }
+
+#endif //SHOOTER_H_INCLUDED
Index: proj/DR.mk
===================================================================
--- proj/DR.mk	(revision 191)
+++ proj/DR.mk	(revision 192)
@@ -2,7 +2,7 @@
 
 .PATH: ${.CURDIR}/src
 
-SRCS= proj.c graph.c sprite.c kbc.c keyboard.c mouse.c utils.c timer.c interrupts_func.c proj_func.c fast_math.c rectangle.c font.c xpm_utils.c
+SRCS= proj.c graph.c sprite.c kbc.c keyboard.c mouse.c utils.c timer.c interrupts_func.c proj_func.c fast_math.c rectangle.c font.c xpm_utils.c ent.c
 
 CPPFLAGS += -pedantic -I./include -I./bmp -I./xpm -D LCOM_MACRO -D DIOGO -D __LCOM_OPTIMIZED_
 
Index: proj/Makefile
===================================================================
--- proj/Makefile	(revision 191)
+++ proj/Makefile	(revision 192)
@@ -2,7 +2,7 @@
 
 .PATH: ${.CURDIR}/src
 
-SRCS= proj.c graph.c sprite.c kbc.c keyboard.c mouse.c utils.c timer.c interrupts_func.c proj_func.c fast_math.c rectangle.c font.c xpm_utils.c
+SRCS= proj.c graph.c sprite.c kbc.c keyboard.c mouse.c utils.c timer.c interrupts_func.c proj_func.c fast_math.c rectangle.c font.c xpm_utils.c ent.c
 
 CPPFLAGS += -pedantic -I./include -I./bmp -I./xpm -D LCOM_MACRO -D __LCOM_OPTIMIZED_
 
Index: proj/TB.mk
===================================================================
--- proj/TB.mk	(revision 191)
+++ proj/TB.mk	(revision 192)
@@ -2,7 +2,7 @@
 
 .PATH: ${.CURDIR}/src
 
-SRCS= proj.c graph.c sprite.c kbc.c keyboard.c mouse.c utils.c timer.c interrupts_func.c proj_func.c fast_math.c rectangle.c font.c xpm_utils.c
+SRCS= proj.c graph.c sprite.c kbc.c keyboard.c mouse.c utils.c timer.c interrupts_func.c proj_func.c fast_math.c rectangle.c font.c xpm_utils.c ent.c
 
 CPPFLAGS += -pedantic -I./include -I./bmp -I./xpm -D LCOM_MACRO -D TELMO #-D __LCOM_OPTIMIZED_
 
