Talk:Writing an SDL Hello World
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)