Talk:Writing an SDL Hello World

From wiki.gp2x.org

Note: The current putpixel stuff is taken directly from the SDL tutorial: http://www.libsdl.org/cgi/docwiki.cgi/Pixel_20Access (no_skill)

Talk on the old Version

is this correct???

bufp=(Uint8 *)screen->pixels+(SCREEN_WIDTH*10)+10;

i keep thinking that the correct way is multiply Y coord by PITCH

|<------------pitch---------->|

|<----xres---->|<wasted>|

perhaps this image is more explicative: http://sol.gfxile.net/gp/pitch.gif

void putpixel(int x, int y, int color)
{
  unsigned int *ptr = (unsigned int*)screen->pixels;
  int lineoffset = y * (screen->pitch / 4);
  ptr[lineoffset + x] = color;
}

Yes, pitch is the memory usage for each line in bytes, which MAY be more than the memory needed. Note that the code implementation have the following assumption:

  • The 'ptr' is point to a memory video buffer which is accessible pixel by pixel
  • The function will not update the screen immediately, you need to use other way to update the whole screen after updated all pixels, such as flip().
  • The correct calculation for lineoffset would be:
   int lineoffset = y * (screen->pitch / screen->format.BytesPerPixel);
See here: http://www.libsdl.org/cgi/docwiki.cgi/Pixel_20Access
Additionally I'd add an example on how to blit an image as that might be way more interesting.
no_skill

The Hello Pixel example was using surface->pixel (and friends) when it should have been using screen->pixel; I guess no-one'd tried compiling that example yet...

Talk on compiling the code

would it be easier with a make file? i'm having trouble getting helloPixel.c to compile:

http://www.gp32x.com/board/index.php?s=&showtopic=32079&view=findpost&p=456551

what is the -lSDL option?

--You want to put -lSDL in your command line when you link the binary, this tells the linker to use the SDL library. Jonathan Holland 09:16, 17 December 2006 (PST)

Actual Hello World Code

I wrote this up yesterday as a test program to run on the GP2X. Since SDL doesn't have a high level font system your typical Hello world program ends up being quite the project, but here it is if anyone cares Jonathan Holland 09:16, 17 December 2006 (PST)

  #include <stdio.h>
  #include <stdlib.h>
  #include <fcntl.h>
  #include <string.h>
  #include "SDL.h"
  
  // Function Prototypes

  void drawSprite(SDL_Surface* imageSurface, SDL_Surface* screenSurface, int srcX, int srcY, int dstX, int dstY, int width, int height);
  
  void drawcharacter(int x, int y, int character);
  
  void drawstring(int x, int y, char *s);
  
  int clean_program_shutdown (void);


  SDL_Surface *gFont;               // The bitmap that contains the font
  SDL_Surface *temp;                // Temporary bitmap for occasional use
  SDL_Surface *screen;              // Graphical surface structure

  int main (int argc, char *argv[]) 
 {
   
    SDL_Joystick *joystick;       // Joystick structure
    
    SDL_Event event;              // The event structure, used by the message handler
    
    bool still_running = true;    // Simple flag to tell if the program needs to die
    
    // Initilize SDL, if it fails, exit to shell
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) clean_program_shutdown();
	
 // Set the screen mode
    screen = SDL_SetVideoMode(320,240,16,SDL_SWSURFACE);
	
	if (!screen) // Failed to set screen mode
    {
       SDL_Quit(); // Free up SDL resources
       clean_program_shutdown(); // Back to shell
    }

    // Initilize Joystick    
    joystick = SDL_JoystickOpen(0);
    
    SDL_ShowCursor(SDL_DISABLE);  // do not show cursor on the screen.
    
    // Load Font
    
    // This uses the BMP from Sol's tutorial, you can get it at:
    // http://sol.gfxile.net/gp/font.bmp

    temp = SDL_LoadBMP("font.bmp");
    gFont = SDL_ConvertSurface(temp, screen->format, SDL_SWSURFACE);
    SDL_FreeSurface(temp);
    
    // Ignore the first event in the event queue as it is most likely left over from 
    // launching the application.
    SDL_PollEvent(&event);  

    // Unlock screen if needed
    if (SDL_MUSTLOCK(screen)) 
    SDL_UnlockSurface(screen);
        
    // Draw Hello World        
    drawstring(65,110,"Hello World!");

    // Display to screen
    SDL_Flip (screen);

    // Main Event loop
    
    while (still_running == true)
    {
          SDL_WaitEvent(&event);  // wait indefinitly for events. 

		switch (event.type)  //Check to see what happened
		{
			
			// All we care about is joystick button presses, so we ignore all other messages
			
			case SDL_JOYBUTTONDOWN:
                 // We don't care what button, any button kills it.
				still_running = false;
			break;				
		}
    }
          
    
    SDL_Quit();
    clean_program_shutdown();
    return 0;
 }

     // Really Ugly text routines. Originally I borrowed Sol's routines from his tutorial, 
     // but they didn't work properly, so I rewrote them quickly.

   void drawstring (int x, int y, char *s)
     {

     int length = strlen(s);                       // Get length of the string
     int iCount;                                   // Loop index counter
     for (iCount = 0;iCount <= length; iCount++)   // Loop the length of the string
         {
          drawcharacter(x,y,s[iCount]);            // Draw the character
          x += gFont->w;                           // Increase the offset over 16 pixels
         }
     }

   void drawcharacter(int x, int y, int character)
  {
  
  character -= 33; // our font does not have the first 33 characters.

  drawSprite(gFont,screen,0,character* 16,x,y,16,16);  // Copy the letter from the font bitmap to the screen

  }

  // Stolen Drawsprite routine from SDL tutorials

  void drawSprite(SDL_Surface* imageSurface, SDL_Surface* screenSurface, int srcX, int srcY, int dstX, int dstY, int width, int height)
  {
	// just for annoyance later, note the SDL uses signed ints for x and y but unsigned for width and height.
	// shouldn't matter until resolution gets much better
	SDL_Rect srcRect;
	srcRect.x = srcX;
	srcRect.y = srcY;
	srcRect.w = width;
	srcRect.h = height;

	SDL_Rect dstRect;  
	dstRect.x = dstX;
	dstRect.y = dstY;
	dstRect.w = width;  // This is actually ignored by SDL_BlitSurface.
	dstRect.h = height; // This is actually ignored by SDL_BlitSurface.
   
	SDL_BlitSurface(imageSurface, &srcRect, screenSurface, &dstRect);
		// fast blit from source to destination.  
		// ignores the -1 or -2  possible error codes.
   }

  // The Gp2x will hang on your typical return 0 as the launch shell does not auto reload. 
  // This function should be the last thing called by your program, it relaunches the
  // Gp2x shell. Do not forget to put a return 0 in your main function to keep the compiler happy.

  int clean_program_shutdown(void) 
 {
    // Change Directory and launch the Gp2x shell.
	chdir("/usr/gp2x");

	execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL);

	return 0;  
 }

I'd put it on the article page, but the purpose of Hello World is to be a simple program for a beginner, the font routines etc make this program not so easy to understand from a beginners perspective, despite the very simple output.

Jonathan Holland 09:16, 17 December 2006 (PST)

Personal tools