Subject: Flag Revision 2.

From: Shlomi Fish <[email-masked]>
Date: Fri, 8 Feb 2002 23:57:28 +0200 (IST)

It's included below. Much better and more optimized, and pretty much
finalized. There's quite a lot of duplicate code around, and it only works
with 8-bit displays.

Strangely enough, rendering a bigger flag is slower than a smaller one,
but maybe the Screen, X-Windows, etc. has something to do with it. I'm
pretty sure my code is fast enough so there won't be a difference in the
refresh rate.

Enjoy, and happy fluttering!

Regards,

	Shlomi Fish

/***************************************/

#include <stdio.h>
#include <math.h>
#include <signal.h>

#include <SDL.h>

#define PI 3.14159265358

#if 0
/* This putpixel definition was ripped from the SDL doc project */

/*
 * Set the pixel at (x, y) to the given value
 * NOTE: The surface must be locked before calling this!
 */
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
    int bpp = surface->format->BytesPerPixel;
    /* Here p is the address to the pixel we want to set */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
        *p = pixel;
        break;

    case 2:
        *(Uint16 *)p = pixel;
        break;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
            p[0] = (pixel >> 16) & 0xff;
            p[1] = (pixel >> 8) & 0xff;
            p[2] = pixel & 0xff;
        } else {
            p[0] = pixel & 0xff;
            p[1] = (pixel >> 8) & 0xff;
            p[2] = (pixel >> 16) & 0xff;
        }
        break;

    case 4:
        *(Uint32 *)p = pixel;
        break;
    }
}

#else
#define putpixel(surface, x, y, pixel)  \
    {   \
        *(Uint8 *)(surface->pixels + (y) * surface->pitch + x) = pixel; \
    }
#endif

/*
 * Linus Torvalds would kill me if he saw this, but who is John Galt?
 * (at least not Linus, I hope)
 * */
#define min(a,b) (((a)<(b))?(a):(b))
#define max(a,b) (((a)>(b))?(a):(b))

int mycont = 1;

void my_stop_program(int signal_number)
{
    mycont = 0;
}

#define LOG2_DEGREES_RANGE 9
#define DEGREES_RANGE (1 << (LOG2_DEGREES_RANGE))
#define DEG_MOD(x) ((x)&(DEGREES_RANGE-1))

int main(int argc, char * argv[])
{
    int x_num_points = 20;
    int y_num_points = 10;
    int x_x_offset = 20;
    int x_y_offset = 0;
    int y_x_offset = 3;
    int y_y_offset = 10;
    double y_amplitude = 10.0;
    int y_amp_delta = 50;
    int x_amp_delta = 20;
    /* This is so it won't get out of the end of the screen */
    int y_abs_offset = 20;
    int x_abs_offset = 10;
    int sin_lookup[DEGREES_RANGE];

    int x,y,t, prev_t;
    int prev_y_height;
    int this_y_height;
    int x_pos, y_pos;

    int y_acc_degree, y_x_acc_degree;
    int prev_y_acc_degree, prev_y_x_acc_degree;
    int y_acc_y_pos, y_acc_x_pos;

    Uint8 black, white;

    SDL_Surface *screen;
    SDL_Rect * rects;
    SDL_Rect * the_rect;

    int a;

    for(a=0 ; a < DEGREES_RANGE  ;a++)
    {
        sin_lookup[a] = (int)(sin((2*PI/DEGREES_RANGE)*a)*y_amplitude);
    }

    /* Initialize the SDL library */
    if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
        fprintf(stderr,
                "Couldn't initialize SDL: %s\n", SDL_GetError());
        exit(1);
    }

    /* Clean up on exit */
    atexit(SDL_Quit);

    signal(SIGQUIT, my_stop_program);
    signal(SIGINT, my_stop_program);

    /*
     * Initialize the display in a 640x480 8-bit palettized mode,
     * requesting a software surface
     */
    screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);
    if ( screen == NULL ) {
        fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
                        SDL_GetError());
        exit(1);
    }

    black = (Uint8)SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
    white = (Uint8)SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF);
    rects = (SDL_Rect *)malloc(sizeof(rects[0]) * x_num_points*y_num_points*2);
    for(a=0;a<x_num_points*y_num_points*2;a++)
    {
        rects[a].w = rects[a].h = 1;
    }

    printf("%i\n", SDL_MUSTLOCK(screen));

    prev_t = 0;
    for(t=1 ; mycont ; t = ((t+1)&(DEGREES_RANGE-1)))
    {
        the_rect = rects;

        y_acc_degree = t;
        prev_y_acc_degree = prev_t;
        y_acc_y_pos = y_abs_offset;
        y_acc_x_pos = x_abs_offset;
        for(y=0;y<y_num_points;y++)
        {
            y_x_acc_degree = y_acc_degree;
            prev_y_x_acc_degree = prev_y_acc_degree;

            x_pos = y_acc_x_pos;
            y_pos = y_acc_y_pos;
            for(x=0;x<x_num_points;x++)
            {
                prev_y_height =
                    y_pos +
                    sin_lookup[prev_y_x_acc_degree]
                    ;
                this_y_height =
                    y_pos +
                    sin_lookup[y_x_acc_degree]
                    ;

                the_rect->x = x_pos;
                the_rect->y = prev_y_height;
                the_rect++;
                the_rect->x = x_pos;
                the_rect->y = this_y_height;
                the_rect++;

                /* I don't need to lock the screen, so I'm omitting it */

                putpixel(
                    screen,
                    x_pos,
                    prev_y_height,
                    black
                    );

                putpixel(
                    screen,
                    x_pos,
                    this_y_height,
                    white
                    );

                y_x_acc_degree = DEG_MOD(y_x_acc_degree+x_amp_delta);
                prev_y_x_acc_degree = DEG_MOD(prev_y_x_acc_degree+x_amp_delta);
                x_pos += x_x_offset;
                y_pos += x_y_offset;
            }
            y_acc_degree = DEG_MOD(y_acc_degree+y_amp_delta);
            prev_y_acc_degree = DEG_MOD(prev_y_acc_degree+y_amp_delta);
            y_acc_y_pos += y_y_offset;
            y_acc_x_pos += y_x_offset;
        }

        SDL_UpdateRects(screen, x_num_points*y_num_points*2, rects);

        prev_t = t;
    }

    return 0;
}
/****************************/

----------------------------------------------------------------------
Shlomi Fish        [email-masked]
Home Page:         http://t2.technion.ac.il/~shlomif/
Home E-mail:       [email-masked]

"Let's suppose you have a table with 2^n cups..."
"Wait a second - is n a natural number?"