/* lights.c - Bouncing Lights 0.7 (using TinySGGL with SDL) Author Jani Kniivilä compile with: gcc -o lights lights.c -lSDL -lpthread -ltSGGL */ #include #include #include #define WIDTH 640 /* width */ #define HEIGHT 480 /* and height of the screen */ #define N_FLARES 16 /* amount of flares to draw simultaneously on screen */ gfx_image_t *flares[N_FLARES]; gfx_image_t *output; /* where to draw everything */ SDL_Surface *surface; /* screen surface */ gfx_image_t *background; /* contains the background image */ gfx_image_t *o_flares[3]; /* 0 - Red, 1 - Green, 2 - Blue */ const float my_pi = 3.141593; int fx_init() { int i, j; gfx_color_t color1, color2, color3; /* * Initialize SDL and open proper graphics mode/window */ if (SDL_Init(SDL_INIT_VIDEO) < 0) return -1; atexit(SDL_Quit); surface = SDL_SetVideoMode(WIDTH, HEIGHT, 16, SDL_SWSURFACE); if (!surface) return -2; /* * Create a "link" to SDL */ output = gfx_create_null_image(WIDTH, HEIGHT); /* create an image without pixel-data */ if (!output) return -3; output->data = (Uint16 *) surface->pixels; /* redirect the pixels to "screen" */ /* * Create background */ background = gfx_create_image(WIDTH, HEIGHT); if (!background) return -4; for (j = 0; j < background->height; j++) { for (i = 0; i < background->width; i++) { gfx_set_color(&color1, (i^j)&0x7f, (i|j)&0x3f, (i^j)&0x3f); background->data[i+j*WIDTH] = (Uint16) color1.value; } } /* * Create flares */ o_flares[0] = gfx_create_empty_image(64, 64); if (!o_flares[0]) return -5; o_flares[1] = gfx_create_empty_image(64, 64); if (!o_flares[1]) return -6; o_flares[2] = gfx_create_empty_image(64, 64); if (!o_flares[2]) return -7; gfx_set_color(&color1, 8, 0, 0); /* red */ gfx_set_color(&color2, 0, 8, 0); /* green */ gfx_set_color(&color3, 0, 0, 8); /* blue */ for (i = 0; i < 31; i++) { gfx_addfcircle(32, 32, 31 - i, &color1, o_flares[0]); gfx_addfcircle(32, 32, 31 - i, &color2, o_flares[1]); gfx_addfcircle(32, 32, 31 - i, &color3, o_flares[2]); } for (i = 0; i < N_FLARES; i++) { flares[i] = o_flares[i % 3]; } return 0; } void fx_shutdown() { gfx_dispose_image(background); gfx_dispose_image(o_flares[0]); gfx_dispose_image(o_flares[1]); gfx_dispose_image(o_flares[2]); free(output); /* must not use gfx_dispose_image() on this one */ } int fx_draw_frame() { int xp, yp, i; unsigned int size; static float angle = 0; if (SDL_MUSTLOCK(surface)) SDL_LockSurface(surface); gfx_copy(output, background); for (i = 0; i < N_FLARES; i++) { size = 3.2 * 64 + cos(angle*2.4 + (3*i*M_PI / N_FLARES)) * 64; xp = output->mid_x - (size>>1) + (int)(cos(angle + i*M_PI / N_FLARES) * 120); yp = output->mid_y - (size>>1) + (int)(sin(angle + 3*i*M_PI / N_FLARES) * 120); gfx_slow_add_scaled_image(xp, yp, flares[i], size, size, output); } if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface); SDL_Flip(surface); angle += my_pi / (1.1*N_FLARES); return 0; } int main() { SDL_Event event; int done = 0; if (fx_init()) return -1; while (!done) { fx_draw_frame(); while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: case SDL_KEYDOWN: case SDL_MOUSEBUTTONDOWN: done = 1; } } } fx_shutdown(); return 0; }