Project

General

Profile

Revision 306

finally solved problem of lag

View differences:

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