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)