Skip to content

Instantly share code, notes, and snippets.

@kristopolous
Created February 26, 2013 19:14
Show Gist options
  • Save kristopolous/5041185 to your computer and use it in GitHub Desktop.
Save kristopolous/5041185 to your computer and use it in GitHub Desktop.
video
#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);
}
@kristopolous
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment