Project

General

Profile

Statistics
| Revision:

root / proj / src / sprite.c @ 191

History | View | Annotate | Download (3.42 KB)

1 152 up20180642
#include <lcom/lcf.h>
2
3
#include "sprite.h"
4
5 166 up20180642
#include "graph.h"
6 163 up20180642
#include "utils.h"
7 168 up20180642
#include "fast_math.h"
8 160 up20180642
#include <math.h>
9 152 up20180642
10
struct sprite{
11 163 up20180642
    int16_t x, y;
12
    uint16_t w, h;
13
    int16_t u0, v0;
14 182 up20180642
    double theta;
15 190 up20180642
    double scale;
16 152 up20180642
    uint8_t *map;
17
};
18
19 163 up20180642
sprite_t* (sprite_ctor)(const char **xpm, int u0, int v0){
20 152 up20180642
    sprite_t *ret = (sprite_t*)malloc(sizeof(sprite_t));
21
    if(ret == NULL) return NULL;
22 160 up20180642
    enum xpm_image_type type = XPM_8_8_8_8;
23 152 up20180642
    xpm_image_t img;
24 162 up20180642
    ret->map = xpm_load((xpm_map_t)xpm, type, &img);
25 152 up20180642
    if(ret->map == NULL){
26
        free(ret);
27
        return NULL;
28
    }
29 159 up20180642
    ret->x = 0;
30
    ret->y = 0;
31 152 up20180642
    ret->w = img.width;
32
    ret->h = img.height;
33 162 up20180642
    ret->u0 = u0;
34
    ret->v0 = u0;
35 160 up20180642
    ret->theta = 0;
36 190 up20180642
    ret->scale = 1;
37 152 up20180642
    return ret;
38
}
39 163 up20180642
void (sprite_dtor)(sprite_t *p){
40 152 up20180642
    if(p == NULL) return;
41 178 up20180642
    free(p->map);
42 152 up20180642
    free(p);
43
}
44
45 190 up20180642
void (sprite_set_pos)   (sprite_t *p, int16_t x , int16_t y ){ p->x = x; p->y = y; }
46 163 up20180642
void (sprite_set_center)(sprite_t *p, int16_t u0, int16_t v0){ p->u0 = u0; p->v0 = v0; }
47 190 up20180642
void (sprite_set_angle) (sprite_t *p, double angle          ){ p->theta = angle; }
48
void (sprite_set_scale) (sprite_t *p, double scale          ){ p->scale = scale; }
49 178 up20180642
int16_t  (sprite_get_x)(const sprite_t *p){ return p->x; }
50
int16_t  (sprite_get_y)(const sprite_t *p){ return p->y; }
51
uint16_t (sprite_get_w)(const sprite_t *p){ return p->w; }
52
uint16_t (sprite_get_h)(const sprite_t *p){ return p->h; }
53 152 up20180642
54 163 up20180642
void (sprite_src2pic)(const sprite_t *p, int16_t x, int16_t y, int16_t *u, int16_t *v){
55 168 up20180642
    double s = fm_sin(p->theta);
56
    double c = fm_cos(p->theta);
57 190 up20180642
    double dx = (x - p->x)/p->scale;
58
    double dy = (y - p->y)/p->scale;
59
    int16_t du = dx*c - dy*s + 0.5;
60
    int16_t dv = dx*s + dy*c + 0.5;
61
    *u = du + p->u0;
62
    *v = dv + p->v0;
63 160 up20180642
}
64
65 190 up20180642
void (sprite_pic2src)(const sprite_t *p, int16_t u, int16_t v, int16_t *x, int16_t *y){
66
    double s = fm_sin(p->theta);
67
    double c = fm_cos(p->theta);
68
    int16_t du = u - p->u0;
69
    int16_t dv = v - p->v0;
70
    double dx =  du*c + dv*s;
71
    double dy = -du*s + dv*c;
72
    *x = dx*p->scale + 0.5 + p->x;
73
    *y = dy*p->scale + 0.5 + p->y;
74
}
75
76 163 up20180642
void (sprite_draw)(const sprite_t *p){
77 190 up20180642
    int16_t xmin, xmax, ymin, ymax; {
78
        int16_t x, y;
79
        sprite_pic2src(p, 0   , 0   , &x, &y);
80
        xmin = x; xmax = x; ymin = y; ymax = y;
81
        sprite_pic2src(p, p->w, 0   , &x, &y);
82
        xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax);
83
        sprite_pic2src(p, 0   , p->h, &x, &y);
84
        xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax);
85
        sprite_pic2src(p, p->w, p->h, &x, &y);
86
        xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax);
87
        xmin = max(xmin-2, 0); xmax = min(xmax+2, graph_get_XRes());
88
        ymin = max(ymin-2, 0); ymax = min(ymax+2, graph_get_YRes());
89
    }
90 163 up20180642
    int16_t u, v;
91 190 up20180642
    for(int16_t y = ymin; y < ymax; ++y){
92
        for(int16_t x = xmin; x < xmax; ++x){
93
    //const int16_t diag = p->scale*sqrt(p->w*p->w + p->h*p->h)+2;
94
    //for(int16_t y = max(0,p->y-diag); y < min(p->y+diag,graph_get_YRes()); ++y){
95
    //    for(int16_t x = max(0,p->x-diag); x < min(p->x+diag,graph_get_XRes()); ++x){
96 163 up20180642
            sprite_src2pic(p, x, y, &u, &v);
97
            if(0 <= u && u < p->w && 0 <= v && v < p->h){
98 183 up20180642
                uint32_t c = *(uint32_t*)(p->map + (v*p->w + u)*4);
99 189 up20180655
                graph_set_pixel_alpha(x, y, GET_COLOR(c), GET_ALP(c));
100 152 up20180642
            }
101
        }
102
    }
103
}