LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Blogs > MrCode
User Name
Password

Notices

This is the first "blog" of any kind I've ever had, so it's probably not the greatest...

Just a little snippet about me:

I'd like to consider myself relatively tech-savvy; obviously I use Linux (Arch to be precise; K.I.S.S. FTW), and I enjoy learning new things about computers in general (both software and hardware-related).

This blog is mostly just for whenever I feel like telling the world about my experiences with computers/Linux (or just life in general), or just posting for the hell of it.
Rate this Entry

My first (real) experimentation with SDL

Posted 04-20-2011 at 10:55 AM by MrCode
Updated 04-20-2011 at 02:00 PM by MrCode (stdlib.h include was unnecessary)

It's been a while since I've done any serious programming (if little demo/learning programs can be considered serious ), but I finally got around to doing some little SDL apps.

The code here is basically for learning purposes; it's not like I'm keeping hold of it with an iron grip…IOW, go ahead and use parts of it (or the whole of it) to learn from/use in your own programs/whatever. It's not like there's much here anyway.

The one whose source I'll post is a very simplistic painter's algorithm stacking/compositing/whatever-you-want-to-call-it demo (I called it compositing ). It's very slow, because it has to blit both images upon every refresh, but I don't know how to do proper stacked window management with SDL anyhow (i.e. only re-blitting the areas of the background surface that had been overwritten by the foreground surface), and this is really more of a pet project anyway. Besides, if you have a machine with a fast-enough CPU, you won't notice any slowdown…it runs just great for most images on my Intel Core i5 lappy.

I can't post the source for all of them because LQ won't let me (10k char limit ).

Code:
/* SDL_image blitting/compositing example.                *
 *                                                        *
 * Compile with:                                          *
 *                                                        *
 * gcc -lSDL -lSDL_image -o SDL_composite SDL_composite.c *
 *                                                        *
 * …on Linux and other UNIX-likes, else use whatever      *
 * compiler came with your system.  This should compile   *
 * on pretty much anything capable of running an OS and a *
 * windowing system, as long as it also has its own       *
 * implementation of the SDL libs.                        *
 *                                                        *
 * Note: You may need to change the SDL header #include   *
 * statements below to properly reflect the location of   *
 * your system's SDL header files.                        */

#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>

#define BPP 24

SDL_Surface* LoadImage(char* file);

int main(int argc,char** argv)
{
    if(argc == 3)
    {
        char quit = 0;    
    
        SDL_Surface* scr = NULL; //Display surface
        SDL_Surface *img1 = NULL, //Background surface
                    *img2 = NULL; //Foreground surface

        SDL_Rect draw; //Drawing rectangle for foreground surface

        SDL_Event ev; //Event structure

        /*Assuming everything went well with initialization…*/
        if(SDL_Init(SDL_INIT_VIDEO) == -1)
        {
            fprintf(stderr,"%s\n",SDL_GetError());
            return -1;
        }

        /*…go ahead and set the video mode, checking for screwups afterward*/
        scr = SDL_SetVideoMode(1,1,BPP,SDL_HWSURFACE | SDL_DOUBLEBUF);
        if(scr == NULL)
        {
            fprintf(stderr,"%s\n",SDL_GetError());
            return -1;
        }

        /*Load images*/
        img1 = LoadImage(argv[1]);
        if(img1 == NULL)
        {
            fprintf(stderr,"%s\n",SDL_GetError());
            return -1;
        }
    
        img2 = LoadImage(argv[2]);
        if(img2 == NULL)
        {
            fprintf(stderr,"%s\n",SDL_GetError());
            return -1;
        }
        
        /*Re-set screen video mode to width and height of background image*/
        scr = SDL_SetVideoMode(img1->w,img1->h,BPP,SDL_HWSURFACE |
                                                   SDL_DOUBLEBUF);

        SDL_WM_SetCaption("SDL Blitting/Compositing Demo",NULL);

        /*Set drawing rect position/dimensions*/
        draw.x = (img1->w / 2) - (img2->w / 2);
        draw.y = (img1->h / 2) - (img2->h / 2);
        
        draw.w = img2->w;
        draw.h = img2->h;

        /*Blit background first, then foreground on top*/
        SDL_BlitSurface(img1,NULL,scr,NULL);
        SDL_BlitSurface(img2,NULL,scr,&draw);

        /*Update screen*/
        SDL_Flip(scr);

        while(quit == 0)
        {
            /*While there are events in the queue*/
            while(SDL_PollEvent(&ev))
            {
                switch(ev.type)
                {
                    /*If the user hits the close button in the window*/
                    case SDL_QUIT:
                        quit = 1;
                    break;
                    case SDL_KEYDOWN:
                    {
                        /*If the user presses the escape key*/
                        if(ev.key.keysym.sym == SDLK_ESCAPE)
                            quit = 1;
                    } break;
                    /*If the cursor moves in the window*/
                    case SDL_MOUSEMOTION:
                    {
                        /*Set drawing rect position/dimensions*/
                        draw.x = ev.motion.x - (img2->w / 2);
                        draw.y = ev.motion.y - (img2->h / 2);

                        draw.w = img2->w;
                        draw.h = img2->h;

                        /*Blit background first, then foreground on top*/
                        SDL_BlitSurface(img1,NULL,scr,NULL);
                        SDL_BlitSurface(img2,NULL,scr,&draw);
                        
                        /*Update screen*/
                        SDL_Flip(scr);
                    } break;
                }
            }

            /* Delay for approx. 17 ms after each event poll *
             * for approx. 60 polling ticks/sec.             *
             * Without this, the program will poll for       *
             * events as often as it can, taking 100% CPU    *
             * time in the process.                          */
            SDL_Delay((int)1000/60);
        }

        /*Free surface pointers and quit*/
        SDL_FreeSurface(img1);
        SDL_FreeSurface(img2);
        SDL_Quit();
    }
    else
    {
        printf("Usage: ./SDL_composite <fg> <bg>\n");
        printf("SDL Example: composites <fg> onto <bg>.\n");
        printf("Also demonstrates event-based programming with SDL.\n");
        
        return 1;
    }
    
    return 0;
}

SDL_Surface* LoadImage(char* file)
{
    SDL_Surface* initImage = NULL;
    SDL_Surface* optImage  = NULL;

    initImage = IMG_Load(file);

    if(initImage != NULL)
    {
        optImage = SDL_DisplayFormat(initImage);

        SDL_FreeSurface(initImage);
    }

    return optImage;
}
…sorry if this seems pointless/dumb/whatever, but I mostly was just looking for an excuse to post to my LQ blog anyway; I'd been leaving it sit for a while after posting something kinda negative, and I didn't want to leave things hanging on a bad note.

Comments are obviously welcome, and to answer a question asked in a comment on my previous post: yes, I will respond to others' comments in this and all subsequent posts (should I make any more ) if I feel like it.
Views 2435 Comments 1
« Prev     Main     Next »
Total Comments 1

Comments

  1. Old Comment
    UPDATE: I made a proper stacker! It's much easier on the CPU.

    I'm trying to decide whether I should post it in this entry (not sure if LQ will let me ), put it in a new one, or just not bother posting it at all.
    Posted 04-21-2011 at 09:47 AM by MrCode MrCode is offline
 

  



All times are GMT -5. The time now is 01:57 PM.

Main Menu
Advertisement

My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration