Image

Imageexanode wrote in Imageru_cpp

Здравствуйте уважаемые члены и.. членки комьюнити. Есть у меня следующая прога (под катом), а в ней очень простая функция update(), какие у вас идеи по ее оптимизации и вообще оптимизации подобных функций?

UPD: Программка должна рисовать расширение теплопередачи от точки к точке, не обязательно точно, но сохраняя форму. При наличии постоянных дропов разных цветов получаются красивые взрывы.




#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <SDL/SDL.h>

#define WIDTH   160
#define HEIGHT  120

SDL_Surface *screen;
uint32_t pool[WIDTH+1][HEIGHT+1];

#define min(a,b) ((a) < (b) ? (a) : (b))

#define min2(a,b) (*(a) < *(b) ? (a) : (b))
#define min3(a,b,c) min2(min2((a),(b)),(c))
#define min9(a,b,c,d,e,f,g,h,i) min3(min3((a),(b),(c)), min3((d),(e),(f)), min3((g),(h),(i)))

void update() {
    int x, y;
    uint32_t *m;

    for(y = 1; y < HEIGHT; y++)
        for(x = 1; x < WIDTH; x++) {
        rep:
            m = min9(
                    &pool[x-1][y-1],   &pool[x][y-1],    &pool[x+1][y-1],
                    &pool[x-1][y],     &pool[x][y],    &pool[x+1][y],
                    &pool[x-1][y+1],   &pool[x][y],    &pool[x+1][y+1]
            );
            if(*m == pool[x][y]) continue;
            //printf("%d -> %d\n", pool[x][y], *m);
            ++*m;
            --pool[x][y];
            goto rep;
        }
}

void drop(int x, int y, uint32_t weight) {
    pool[x][y] = weight;
}



void resize(int w, int h) {
    assert(screen = SDL_SetVideoMode(w, h, 32,
        SDL_ANYFORMAT|SDL_HWSURFACE/*|SDL_DOUBLEBUF*/|SDL_VIDEORESIZE));
}


int main(int argc, char **argv) {
    int frames = 0;
    int done = 0;
    int x, y, i;

    assert(SDL_Init(SDL_INIT_VIDEO) >= 0);

    resize(160, 120);
    drop(WIDTH/2, HEIGHT/2, 255000);
    drop(1, 1, 2550000);
    drop(WIDTH-1, HEIGHT-1, 2550000);

    while(!done) { // main loop
        SDL_Event event;

        while(SDL_PollEvent(&event)) { // read system events
            switch(event.type) {
            case SDL_VIDEORESIZE:
                resize(event.resize.w, event.resize.h);
            break;
            case SDL_QUIT:
                done = 1;
            break;
            case SDL_KEYDOWN:
                if(event.key.keysym.sym == SDLK_ESCAPE) done = 1;
                //keys[event.key.keysym.sym] = 1;
            break;
            case SDL_KEYUP:
                //keys[event.key.keysym.sym] = 0;
            break;
            }
        }

        SDL_LockSurface(screen);
        update();
        for(y = i = 0; y < screen->h; y++)
            for(x = 0; x < screen->w; x++, i++) {
                int mx = (x*WIDTH + WIDTH-1)/screen->w;
                int my = (y*HEIGHT + HEIGHT-1)/screen->h;
                uint8_t *p = screen->pixels + y*screen->pitch + x*screen->format->BytesPerPixel;
                int r = min(pool[mx][my],255);
                int g = min(pool[mx][my]/255,255);
                int b = min((pool[mx][my]/255)/255,255);
                p[0] = r;
                p[1] = g;
                p[2] = b;
            }
        SDL_UnlockSurface(screen);
        SDL_Flip(screen);

        frames++;
    }

    SDL_Quit();
    return 0;
}