root / proj / src / sprite.c @ 197
History | View | Annotate | Download (3.93 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 | 192 | up20180642 | struct basic_sprite{
|
11 | uint8_t *map; |
||
12 | 163 | up20180642 | uint16_t w, h; |
13 | int16_t u0, v0; |
||
14 | 152 | up20180642 | }; |
15 | |||
16 | 192 | up20180642 | basic_sprite_t* (basic_sprite_ctor)(const char **xpm, int16_t u0, int16_t v0){ |
17 | basic_sprite_t *ret = malloc(sizeof(basic_sprite_t));
|
||
18 | 152 | up20180642 | if(ret == NULL) return NULL; |
19 | 160 | up20180642 | enum xpm_image_type type = XPM_8_8_8_8;
|
20 | 152 | up20180642 | xpm_image_t img; |
21 | 162 | up20180642 | ret->map = xpm_load((xpm_map_t)xpm, type, &img); |
22 | 152 | up20180642 | if(ret->map == NULL){ |
23 | free(ret); |
||
24 | return NULL; |
||
25 | } |
||
26 | ret->w = img.width; |
||
27 | ret->h = img.height; |
||
28 | 162 | up20180642 | ret->u0 = u0; |
29 | 192 | up20180642 | ret->v0 = v0; |
30 | 152 | up20180642 | return ret;
|
31 | } |
||
32 | 192 | up20180642 | void (basic_sprite_dtor)(basic_sprite_t *p){
|
33 | 152 | up20180642 | if(p == NULL) return; |
34 | 178 | up20180642 | free(p->map); |
35 | 152 | up20180642 | free(p); |
36 | } |
||
37 | |||
38 | 192 | up20180642 | const uint8_t* (basic_sprite_get_map)(const basic_sprite_t *p){ return p->map; } |
39 | uint16_t (basic_sprite_get_w) (const basic_sprite_t *p){ return p->w ; } |
||
40 | uint16_t (basic_sprite_get_h) (const basic_sprite_t *p){ return p->h ; } |
||
41 | int16_t (basic_sprite_get_u0) (const basic_sprite_t *p){ return p->u0 ; } |
||
42 | int16_t (basic_sprite_get_v0) (const basic_sprite_t *p){ return p->v0 ; } |
||
43 | |||
44 | struct sprite{
|
||
45 | const basic_sprite_t *bsp;
|
||
46 | int16_t x, y; //position in screen
|
||
47 | double theta;
|
||
48 | double scale;
|
||
49 | }; |
||
50 | |||
51 | sprite_t* (sprite_ctor)(const basic_sprite_t *bsp){
|
||
52 | sprite_t *ret = malloc(sizeof(sprite_t));
|
||
53 | if(ret == NULL) return NULL; |
||
54 | ret->bsp = bsp; |
||
55 | ret->x = 0;
|
||
56 | ret->y = 0;
|
||
57 | ret->theta = 0.0; |
||
58 | ret->scale = 1.0; |
||
59 | return ret;
|
||
60 | } |
||
61 | void (sprite_dtor)(sprite_t *p){
|
||
62 | if(p == NULL) return; |
||
63 | free(p); |
||
64 | } |
||
65 | |||
66 | 190 | up20180642 | void (sprite_set_pos) (sprite_t *p, int16_t x , int16_t y ){ p->x = x; p->y = y; }
|
67 | void (sprite_set_angle) (sprite_t *p, double angle ){ p->theta = angle; } |
||
68 | void (sprite_set_scale) (sprite_t *p, double scale ){ p->scale = scale; } |
||
69 | 178 | up20180642 | int16_t (sprite_get_x)(const sprite_t *p){ return p->x; } |
70 | int16_t (sprite_get_y)(const sprite_t *p){ return p->y; } |
||
71 | 152 | up20180642 | |
72 | 163 | up20180642 | void (sprite_src2pic)(const sprite_t *p, int16_t x, int16_t y, int16_t *u, int16_t *v){ |
73 | 168 | up20180642 | double s = fm_sin(p->theta);
|
74 | double c = fm_cos(p->theta);
|
||
75 | 190 | up20180642 | double dx = (x - p->x)/p->scale;
|
76 | double dy = (y - p->y)/p->scale;
|
||
77 | int16_t du = dx*c - dy*s + 0.5; |
||
78 | int16_t dv = dx*s + dy*c + 0.5; |
||
79 | 192 | up20180642 | *u = du + basic_sprite_get_u0(p->bsp); |
80 | *v = dv + basic_sprite_get_v0(p->bsp); |
||
81 | 160 | up20180642 | } |
82 | |||
83 | 190 | up20180642 | void (sprite_pic2src)(const sprite_t *p, int16_t u, int16_t v, int16_t *x, int16_t *y){ |
84 | double s = fm_sin(p->theta);
|
||
85 | double c = fm_cos(p->theta);
|
||
86 | 192 | up20180642 | int16_t du = u - basic_sprite_get_u0(p->bsp); |
87 | int16_t dv = v - basic_sprite_get_v0(p->bsp); |
||
88 | 190 | up20180642 | double dx = du*c + dv*s;
|
89 | double dy = -du*s + dv*c;
|
||
90 | *x = dx*p->scale + 0.5 + p->x; |
||
91 | *y = dy*p->scale + 0.5 + p->y; |
||
92 | } |
||
93 | |||
94 | 163 | up20180642 | void (sprite_draw)(const sprite_t *p){ |
95 | 192 | up20180642 | const uint16_t w = basic_sprite_get_w(p->bsp);
|
96 | const uint16_t h = basic_sprite_get_h(p->bsp);
|
||
97 | 190 | up20180642 | int16_t xmin, xmax, ymin, ymax; { |
98 | int16_t x, y; |
||
99 | 192 | up20180642 | sprite_pic2src(p, 0, 0, &x, &y); |
100 | 190 | up20180642 | xmin = x; xmax = x; ymin = y; ymax = y; |
101 | 192 | up20180642 | sprite_pic2src(p, w, 0, &x, &y);
|
102 | 190 | up20180642 | xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax); |
103 | 192 | up20180642 | sprite_pic2src(p, 0, h, &x, &y);
|
104 | 190 | up20180642 | xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax); |
105 | 192 | up20180642 | sprite_pic2src(p, w, h, &x, &y); |
106 | 190 | up20180642 | xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax); |
107 | xmin = max(xmin-2, 0); xmax = min(xmax+2, graph_get_XRes()); |
||
108 | ymin = max(ymin-2, 0); ymax = min(ymax+2, graph_get_YRes()); |
||
109 | } |
||
110 | 192 | up20180642 | const uint8_t *map = basic_sprite_get_map(p->bsp);
|
111 | 163 | up20180642 | int16_t u, v; |
112 | 190 | up20180642 | for(int16_t y = ymin; y < ymax; ++y){
|
113 | for(int16_t x = xmin; x < xmax; ++x){
|
||
114 | 163 | up20180642 | sprite_src2pic(p, x, y, &u, &v); |
115 | 192 | up20180642 | if(0 <= u && u < w && 0 <= v && v < h){ |
116 | uint32_t c = *(uint32_t*)(map + (v*w + u)*4);
|
||
117 | 189 | up20180655 | graph_set_pixel_alpha(x, y, GET_COLOR(c), GET_ALP(c)); |
118 | 152 | up20180642 | } |
119 | } |
||
120 | } |
||
121 | } |