Created
February 26, 2013 19:14
-
-
Save kristopolous/5041185 to your computer and use it in GitHub Desktop.
video
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<ppm.h> | |
#include<math.h> | |
#include<string.h> | |
typedef float mask; | |
#define HEIGHT 512 | |
#define WIDTH 512 | |
#define PI 3.14159265 | |
typedef struct | |
{ | |
int offset_x, | |
offset_y, | |
height, | |
width; | |
mask *alpha; | |
pixel *data; | |
pixel *old; | |
float scale; | |
} sprite; | |
typedef sprite background; | |
static unsigned char rgb = 0; | |
#define CAP(x) ((int)(x)) | |
#define CHECK_X(_sprite, x) ((CAP(x) > _sprite->width) ? _sprite->width :\ | |
CAP(x) < 0 ? 0 : CAP(x)) | |
#define CHECK_Y(_sprite, y) ((CAP(y) > _sprite->height) ? _sprite->height :\ | |
CAP(y) < 0 ? 0 : CAP(y)) | |
#define OFFSET(_sprite, x, y) (_sprite->width * CHECK_Y(_sprite, y) + CHECK_X(_sprite, x)) | |
#define TRANSLATE(_sprite, x, y) ((_sprite->data + OFFSET(_sprite, x, y))[0]) | |
#define TRANSLATE_OLD(_sprite, x, y) ((_sprite->old + OFFSET(_sprite, x, y))[0]) | |
#define TRANSLATE_ALPHA(_sprite, x, y) ((_sprite->alpha + OFFSET(_sprite, x, y))[0]) | |
#define DBG(message) { printf("%d %s : %s\n", __LINE__, __FILE__, message); fflush(0);} | |
void freeSprite(sprite*toFree) | |
{ | |
free(toFree->alpha); | |
free(toFree->data); | |
free(toFree->old); | |
free(toFree); | |
} | |
sprite* initSprite(int height, int width) | |
{ | |
sprite *toReturn = (sprite*)malloc(sizeof(sprite)); | |
toReturn->offset_x = 0; | |
toReturn->offset_y = 0; | |
toReturn->height = height; | |
toReturn->width = width; | |
toReturn->scale = 3.0; | |
toReturn->alpha = (mask*) malloc(sizeof(mask) * height * width); | |
toReturn->data = (pixel*) malloc(sizeof(pixel) * height * width); | |
toReturn->old = (pixel*) malloc(sizeof(pixel) * height * width * toReturn->scale * toReturn->scale); | |
memset(toReturn->alpha, 0, sizeof(mask) * height * width); | |
memset(toReturn->data, 0, sizeof(pixel) * height * width); | |
memset(toReturn->old, 0, sizeof(pixel) * height * width); | |
return toReturn; | |
} | |
int moveSprite(sprite*toMove, int x, int y) | |
{ | |
toMove->offset_x = x; | |
toMove->offset_y = y; | |
return 1; | |
} | |
int circle(sprite* toplace, pixel*start, pixel*end, float alpha) | |
{ | |
float i; | |
pixel *ref; | |
unsigned char j; | |
int radius = toplace->height/2; | |
float step = 0; | |
int rmul_r = (int)(end->r - start->r) / radius, | |
rmul_g = (int)(end->g - start->g) / radius, | |
rmul_b = (int)(end->b - start->b) / radius; | |
for(j = 0; j < radius; j++) | |
{ | |
step = 6.28318531 / radius / 3.141529 / 4; | |
for(i = 0; i < 6.28318531; i+= step) | |
{ | |
ref = &TRANSLATE(toplace, radius + cos(i) * j, radius + sin(i) * j); | |
ref->r = (start->r + rmul_r * j) * alpha; | |
ref->g = (start->g + rmul_g * j) * alpha; | |
ref->b = (start->b + rmul_b * j) * alpha; | |
TRANSLATE_ALPHA(toplace, radius + cos(i) * j, radius + sin(i) * j) = alpha; | |
} | |
} | |
} | |
void bitBlit_pre(background *bg, sprite*fg) | |
{ | |
mask invAlpha; | |
pixel *ptmp, *pfg; | |
int iy, | |
ix, | |
noscalex, | |
noscaley; | |
/* | |
for(iy = fg->offset_y; iy < fg->offset_y + (fg->height * fg->scale); iy++) | |
{ | |
memcpy(&TRANSLATE_OLD(fg, 0, iy - fg->offset_y), &TRANSLATE(bg, fg->offset_x, iy), sizeof(pixel) * (fg->width + 1) * fg->scale); | |
} | |
*/ | |
for(iy = 0; iy < (fg->height * fg->scale); iy++) | |
{ | |
noscaley = iy / fg->scale; | |
for(ix = 0; ix < (fg->width * fg->scale); ix++) | |
{ | |
noscalex = ix / fg->scale; | |
invAlpha = 1 - TRANSLATE_ALPHA(fg, noscalex, noscaley); | |
ptmp = &TRANSLATE(bg, fg->offset_x + ix, fg->offset_y + iy); | |
pfg = &TRANSLATE(fg, noscalex, noscaley); | |
ptmp->r = (ptmp->r * invAlpha) + pfg->r; | |
ptmp->g = (ptmp->g * invAlpha) + pfg->g; | |
ptmp->b = (ptmp->b * invAlpha) + pfg->b; | |
} | |
} | |
} | |
void bitBlit_post(background *bg, sprite*fg) | |
{ | |
int iy; | |
for(iy = fg->offset_y; iy < fg->offset_y + (fg->height * fg->scale); iy++) | |
{ | |
memcpy(&TRANSLATE(bg, fg->offset_x, iy), &TRANSLATE_OLD(fg, 0, iy - fg->offset_y), (fg->width + 1) * sizeof(pixel) * fg->scale); | |
} | |
} | |
int main() | |
{ | |
int col; | |
int centerx = WIDTH / 2, | |
centery = HEIGHT / 2; | |
float circ; | |
unsigned char r_grey; | |
FILE* file; | |
int fnum = 0; | |
char fname[80]; | |
pixel red = {255, 0, 0}, | |
black = {0, 0, 0}, | |
white = {255, 255, 255}, | |
grey = {128, 128, 128}, | |
green = {0, 255, 0}, | |
teal = {0, 255, 255}, | |
blue = {0, 0, 255}; | |
DBG("init sprite"); | |
sprite *background = initSprite(HEIGHT, WIDTH); | |
sprite *screwit = initSprite(HEIGHT, WIDTH); | |
sprite *blueCircle = initSprite(24, 24); | |
sprite *greenCircle = initSprite(32, 32); | |
sprite *redCircle = initSprite(64, 64); | |
srand(time(0)); | |
DBG("fill background"); | |
for(col=0;col<(HEIGHT * WIDTH);col++) | |
{ | |
r_grey = rand(); | |
r_grey /= 16; | |
r_grey += 127; | |
background->data[col].r = r_grey; | |
background->data[col].g = r_grey; | |
background->data[col].b = r_grey; | |
} | |
memcpy(screwit->data, background->data, HEIGHT * WIDTH * sizeof(pixel)); | |
DBG("create circle"); | |
circle(blueCircle, &white, &blue, 0.8); | |
circle(greenCircle, &teal, &green, 0.8); | |
circle(redCircle, &red, &blue, 0.8); | |
DBG("write files"); | |
for(circ = 0; circ < (8 * PI); circ += 0.0290888209) | |
{ | |
blueCircle->scale = (sin(circ + PI) / 3) + 1; | |
redCircle->scale = (sin(circ) / 2 + 1); | |
greenCircle->scale = (sin(circ * 4) / 3 + 1); | |
moveSprite(blueCircle, | |
centery + sin(circ + PI) * centery / 2, | |
centerx + cos(circ + PI) * centerx / 2); | |
moveSprite(greenCircle, | |
centery + sin(circ) * centery / 2, | |
centerx + cos(circ) * centerx / 2); | |
moveSprite(redCircle, | |
centery + sin(circ * 2) * centery / 6, | |
centerx + cos(circ * 2) * centerx / 6); | |
bitBlit_pre(background, blueCircle); | |
bitBlit_pre(background, greenCircle); | |
bitBlit_pre(background, redCircle); | |
sprintf(fname, "file%d.ppm", fnum++); | |
file = fopen(fname, "w"); | |
ppm_writeppminit(file, HEIGHT, WIDTH, 255, 0); | |
for(col = 0; col < HEIGHT; col++) | |
{ | |
ppm_writeppmrow(file, background->data + col * WIDTH, WIDTH, 255,0); | |
} | |
fclose(file); | |
printf("%d ", fnum); | |
fflush(0); | |
memcpy(background->data, screwit->data, HEIGHT * WIDTH * sizeof(pixel)); | |
/* bitBlit_post(background, redCircle); | |
bitBlit_post(background, greenCircle); | |
bitBlit_post(background, blueCircle);*/ | |
} | |
freeSprite(background); | |
freeSprite(blueCircle); | |
freeSprite(greenCircle); | |
freeSprite(redCircle); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
video here: http://www.youtube.com/watch?v=ATNsPMyV3RA