root / proj / src / sprite.c @ 207
History | View | Annotate | Download (3.92 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 | 207 | up20180642 | double theta, s, c;
|
48 | 192 | up20180642 | 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 | 207 | up20180642 | sprite_set_angle(ret, 0.0); |
58 | 192 | up20180642 | 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 | 207 | up20180642 | void (sprite_set_angle) (sprite_t *p, double angle ){ p->theta = angle; p->c = fm_cos(p->theta); p->s = fm_sin(p->theta); } |
68 | 190 | up20180642 | 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 | 190 | up20180642 | double dx = (x - p->x)/p->scale;
|
74 | double dy = (y - p->y)/p->scale;
|
||
75 | 207 | up20180642 | int16_t du = dx*p->c - dy*p->s + 0.5; |
76 | int16_t dv = dx*p->s + dy*p->c + 0.5; |
||
77 | 192 | up20180642 | *u = du + basic_sprite_get_u0(p->bsp); |
78 | *v = dv + basic_sprite_get_v0(p->bsp); |
||
79 | 160 | up20180642 | } |
80 | |||
81 | 190 | up20180642 | void (sprite_pic2src)(const sprite_t *p, int16_t u, int16_t v, int16_t *x, int16_t *y){ |
82 | 192 | up20180642 | int16_t du = u - basic_sprite_get_u0(p->bsp); |
83 | int16_t dv = v - basic_sprite_get_v0(p->bsp); |
||
84 | 207 | up20180642 | double dx = du*p->c + dv*p->s;
|
85 | double dy = -du*p->s + dv*p->c;
|
||
86 | 190 | up20180642 | *x = dx*p->scale + 0.5 + p->x; |
87 | *y = dy*p->scale + 0.5 + p->y; |
||
88 | } |
||
89 | |||
90 | 163 | up20180642 | void (sprite_draw)(const sprite_t *p){ |
91 | 192 | up20180642 | const uint16_t w = basic_sprite_get_w(p->bsp);
|
92 | const uint16_t h = basic_sprite_get_h(p->bsp);
|
||
93 | 190 | up20180642 | int16_t xmin, xmax, ymin, ymax; { |
94 | int16_t x, y; |
||
95 | 192 | up20180642 | sprite_pic2src(p, 0, 0, &x, &y); |
96 | 190 | up20180642 | xmin = x; xmax = x; ymin = y; ymax = y; |
97 | 192 | up20180642 | sprite_pic2src(p, w, 0, &x, &y);
|
98 | 190 | up20180642 | xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax); |
99 | 192 | up20180642 | sprite_pic2src(p, 0, h, &x, &y);
|
100 | 190 | up20180642 | xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax); |
101 | 192 | up20180642 | sprite_pic2src(p, w, h, &x, &y); |
102 | 190 | up20180642 | xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax); |
103 | xmin = max(xmin-2, 0); xmax = min(xmax+2, graph_get_XRes()); |
||
104 | ymin = max(ymin-2, 0); ymax = min(ymax+2, graph_get_YRes()); |
||
105 | } |
||
106 | 192 | up20180642 | const uint8_t *map = basic_sprite_get_map(p->bsp);
|
107 | 163 | up20180642 | int16_t u, v; |
108 | 190 | up20180642 | for(int16_t y = ymin; y < ymax; ++y){
|
109 | for(int16_t x = xmin; x < xmax; ++x){
|
||
110 | 163 | up20180642 | sprite_src2pic(p, x, y, &u, &v); |
111 | 192 | up20180642 | if(0 <= u && u < w && 0 <= v && v < h){ |
112 | uint32_t c = *(uint32_t*)(map + (v*w + u)*4);
|
||
113 | 207 | up20180642 | if(GET_ALP(c) < 0x7F) |
114 | graph_set_pixel(x, y, GET_COLOR(c)); |
||
115 | 152 | up20180642 | } |
116 | } |
||
117 | } |
||
118 | } |