Revision 306
finally solved problem of lag
proj/libs/graph/src/graph.c | ||
---|---|---|
357 | 357 |
struct sprite{ |
358 | 358 |
const basic_sprite_t *bsp; |
359 | 359 |
int16_t x, y; //position in screen |
360 |
double theta, s, c; |
|
361 |
double scale; |
|
360 |
int16_t su0, sv0; |
|
361 |
float theta, s, c; |
|
362 |
float scale; |
|
363 |
uint8_t *sbuf; |
|
362 | 364 |
}; |
363 | 365 |
sprite_t* (sprite_ctor)(const basic_sprite_t *bsp){ |
364 | 366 |
sprite_t *ret = malloc(sizeof(sprite_t)); |
365 | 367 |
if(ret == NULL) return NULL; |
366 | 368 |
ret->bsp = bsp; |
369 |
ret->sbuf = NULL; |
|
367 | 370 |
ret->x = 0; |
368 | 371 |
ret->y = 0; |
369 | 372 |
sprite_set_angle(ret, 0.0); |
370 |
ret->scale = 1.0;
|
|
373 |
sprite_set_scale(ret, 1.0);
|
|
371 | 374 |
return ret; |
372 | 375 |
} |
373 | 376 |
void (sprite_dtor)(sprite_t *p){ |
374 | 377 |
if(p == NULL) return; |
378 |
free(p->sbuf); |
|
375 | 379 |
free(p); |
376 | 380 |
} |
377 | 381 |
void (sprite_set_pos) (sprite_t *p, int16_t x , int16_t y ){ p->x = x; p->y = y; } |
378 | 382 |
void (sprite_set_angle) (sprite_t *p, double angle ){ p->theta = angle; p->c = fm_cos(p->theta); p->s = fm_sin(p->theta); } |
379 |
void (sprite_set_scale) (sprite_t *p, double scale ){ p->scale = scale; } |
|
383 |
void (sprite_set_scale) (sprite_t *p, double scale ){ |
|
384 |
if(p->scale == scale) return; |
|
385 |
p->scale = scale; |
|
386 |
|
|
387 |
p->su0 = p->bsp->u0*p->scale; |
|
388 |
p->sv0 = p->bsp->u0*p->scale; |
|
389 |
|
|
390 |
const uint16_t W = basic_sprite_get_w(p->bsp), |
|
391 |
H = basic_sprite_get_h(p->bsp); |
|
392 |
uint16_t sW = W*scale, sH = H*scale; |
|
393 |
p->sbuf = realloc(p->sbuf, sW*sH*4); |
|
394 |
const uint8_t *map = basic_sprite_get_map(p->bsp); |
|
395 |
for(uint16_t sx = 0; sx < sW; ++sx){ |
|
396 |
for(uint16_t sy = 0; sy < sH; ++sy){ |
|
397 |
uint16_t x = sx/scale, y = sy/scale; |
|
398 |
if(x > W || y > H) continue; |
|
399 |
memcpy(p->sbuf+4*(sx+sy*sW), map+4*(x+y*W), 4); |
|
400 |
} |
|
401 |
} |
|
402 |
} |
|
380 | 403 |
int16_t (sprite_get_x)(const sprite_t *p){ return p->x; } |
381 | 404 |
int16_t (sprite_get_y)(const sprite_t *p){ return p->y; } |
382 | 405 |
double (sprite_get_angle)(const sprite_t *p){ return p->theta; } |
383 | 406 |
uint16_t (sprite_get_w)(const sprite_t *p){ return basic_sprite_get_w(p->bsp); } |
384 | 407 |
uint16_t (sprite_get_h)(const sprite_t *p){ return basic_sprite_get_h(p->bsp); } |
385 |
void (sprite_src2pic)(const sprite_t *p, int16_t x, int16_t y, int16_t *u, int16_t *v){ |
|
386 |
double dx = (x - p->x)/p->scale; |
|
387 |
double dy = (y - p->y)/p->scale; |
|
388 |
int16_t du = dx*p->c - dy*p->s - 0.5; |
|
389 |
int16_t dv = dx*p->s + dy*p->c - 0.5; |
|
390 |
*u = du + basic_sprite_get_u0(p->bsp); |
|
391 |
*v = dv + basic_sprite_get_v0(p->bsp); |
|
408 |
void (sprite_src2sbuf)(const sprite_t *p, int16_t x, int16_t y, int16_t *u, int16_t *v){ |
|
409 |
if(p->theta == 0.0){ |
|
410 |
*u = x - p->x + p->su0; |
|
411 |
*v = y - p->y + p->sv0; |
|
412 |
}else{ |
|
413 |
float dx = x - p->x; |
|
414 |
float dy = y - p->y; |
|
415 |
int16_t du = dx*p->c - dy*p->s - 0.5f; |
|
416 |
int16_t dv = dx*p->s + dy*p->c - 0.5f; |
|
417 |
*u = du + p->su0; |
|
418 |
*v = dv + p->sv0; |
|
419 |
} |
|
392 | 420 |
} |
393 |
void (sprite_pic2src)(const sprite_t *p, int16_t u, int16_t v, int16_t *x, int16_t *y){
|
|
394 |
int16_t du = u - basic_sprite_get_u0(p->bsp);
|
|
395 |
int16_t dv = v - basic_sprite_get_v0(p->bsp);
|
|
421 |
void (sprite_sbuf2src)(const sprite_t *p, int16_t u, int16_t v, int16_t *x, int16_t *y){
|
|
422 |
int16_t du = u - p->su0;
|
|
423 |
int16_t dv = v - p->sv0;
|
|
396 | 424 |
double dx = du*p->c + dv*p->s; |
397 | 425 |
double dy = -du*p->s + dv*p->c; |
398 |
*x = dx*p->scale + 0.5 + p->x;
|
|
399 |
*y = dy*p->scale + 0.5 + p->y;
|
|
426 |
*x = dx + 0.5 + p->x; |
|
427 |
*y = dy + 0.5 + p->y; |
|
400 | 428 |
} |
429 |
|
|
401 | 430 |
void (sprite_draw)(const sprite_t *p){ |
402 |
const uint16_t w = basic_sprite_get_w(p->bsp);
|
|
403 |
const uint16_t h = basic_sprite_get_h(p->bsp);
|
|
431 |
const uint16_t sw = p->scale*basic_sprite_get_w(p->bsp);
|
|
432 |
const uint16_t sh = p->scale*basic_sprite_get_h(p->bsp);
|
|
404 | 433 |
int16_t xmin, xmax, ymin, ymax; { |
405 | 434 |
int16_t x, y; |
406 |
sprite_pic2src(p, 0, 0, &x, &y);
|
|
435 |
sprite_sbuf2src(p, 0 , 0 , &x, &y);
|
|
407 | 436 |
xmin = x; xmax = x; ymin = y; ymax = y; |
408 |
sprite_pic2src(p, w, 0, &x, &y);
|
|
437 |
sprite_sbuf2src(p, sw, 0 , &x, &y);
|
|
409 | 438 |
xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax); |
410 |
sprite_pic2src(p, 0, h, &x, &y);
|
|
439 |
sprite_sbuf2src(p, 0 , sh, &x, &y);
|
|
411 | 440 |
xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax); |
412 |
sprite_pic2src(p, w, h, &x, &y);
|
|
441 |
sprite_sbuf2src(p, sw, sh, &x, &y);
|
|
413 | 442 |
xmin = min(x, xmin); xmax = max(x, xmax); ymin = min(y, ymin); ymax = max(y, ymax); |
414 |
xmin = max(xmin-(int16_t)p->scale-2, 0); xmax = min(xmax+(int16_t)p->scale+2, graph_get_XRes());
|
|
415 |
ymin = max(ymin-(int16_t)p->scale-2, 0); ymax = min(ymax+(int16_t)p->scale+2, graph_get_YRes());
|
|
443 |
xmin = max(xmin-2, 0); xmax = min(xmax+2, graph_get_XRes());
|
|
444 |
ymin = max(ymin-2, 0); ymax = min(ymax+2, graph_get_YRes());
|
|
416 | 445 |
} |
417 |
const uint8_t *map = basic_sprite_get_map(p->bsp); |
|
418 | 446 |
const uint16_t bytes_pixel = 3/*graph_get_bytes_pixel()*/; |
419 | 447 |
for(int16_t u, v, y = ymin; y < ymax; ++y){ |
420 | 448 |
uint8_t *place = video_buf + (xmin + y*graph_get_XRes())*bytes_pixel; |
421 | 449 |
for(int16_t x = xmin; x < xmax; ++x, place += bytes_pixel){ |
422 |
sprite_src2pic(p, x, y, &u, &v); |
|
423 |
if(0 <= u && u < w && 0 <= v && v < h){ |
|
424 |
const uint8_t *c_p = map+(v*w+u)*4; |
|
425 |
if(*(c_p+3) < ALPHA_THRESHOLD) //alpha |
|
450 |
sprite_src2sbuf(p, x, y, &u, &v); |
|
451 |
//u = x; v = y; |
|
452 |
if(0 <= u && u < sw && 0 <= v && v < sh){ |
|
453 |
const uint8_t *c_p = p->sbuf+(v*sw+u)*4; |
|
454 |
if(*(c_p+3) < ALPHA_THRESHOLD){ //alpha |
|
426 | 455 |
memcpy(place, c_p, bytes_pixel); |
456 |
} |
|
427 | 457 |
} |
428 | 458 |
} |
429 | 459 |
} |
Also available in: Unified diff