Source code to a Demo Program
From wiki.gp2x.org
Demo.C
Here's a heavily modified version of the SDL's standard demo program. The original version works fine for desktops, but the GP2X is a bit different.
The code itself is overly documented. I'll make the page into a pretty thing soon, but it seems like getting the information out is the first step.
// This little demo program displays an image on a GP2X, waits for a button press, and exits. // This is a modified version of the demo.c program that ships in the SDL's demo directory. // Modifications done by Charles Merriam, 1/2006, under the GNU LGPL, same as the SDL. #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include "SDL.h" // SDL stands for "Simple Direct-Media Layer" /* convenience function, for SDL_BlitSurface. */ 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. } /* Main program that executes. */ int /// return the error code. Usually zero means execution was OK else not 0 main(int argc, /// number of arguments char *argv[]) /// the argument strings. Argv[0] is the command name iteself. { SDL_Surface *screen; /// Graphical surface structure. SDL_Joystick *joystick; /// Joystick information structure, full of info I don't use in this program. SDL_Event event; // An event structure. // This is a big union. Specifically, the first 8 bytes are the type. The 'union' is either // the type (for the first 8 bytes) or some structure where the first 8 bytes // are still the type. It is just a style, and typographic convenience, that // it is not a structure of { unit 8 type, union data { keyboard.....} }. int done = 0; if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) // initialize the video subsystem and the joystick subsystem. Using a bitwise or to send multiple flags is // common. { return 1; /// oops, something failed. } screen = SDL_SetVideoMode(320, 240, 16, SDL_SWSURFACE); // Setting the video mode. This SDL call can only take certain parameters. // a 320x240 screen, so this won't look especially good on a TV which allows a higher resolution // 16 bits per pixel. // SDL_SWSURFACE : Create the Video Surface in System Memory. // This works. Double buffering does not currently work, and using the SDL_HWSURFACE // is tricky. if (!screen) // oops. Look { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); // Won't see the fprint on the graphical GP2X screen. return 1; } joystick = SDL_JoystickOpen(0); // initialize the joystick and buttons. Number '0' is the only one. if (!joystick) // should not happen { fprintf(stderr, "Couldn't open the joystick: %s\n", SDL_GetError()); return 1; } SDL_ShowCursor(SDL_DISABLE); // do not show cursor on the screen. SDL_Surface* bitmap = SDL_LoadBMP("/mnt/sd/image.bmp"); // load a BMP format. // BMP is an uncompressed simple bitmap of a specific color depth. // The file is the sd card, which was mounted like a normal linux file system. // Not that we don't check for errors in the demo code, and this is the only likely // spot for an error to occur. Figuring out which errors to check for is tricky. drawSprite(bitmap, screen, 0, 0, 0, 0, bitmap->w, bitmap->h); // draw it. SDL_Flip(screen); // Tell SDL to update the screen at some useful time. Note that without SDL_DOUBLEBUF, // this will just be the same as SDL_UpdateRect. // OK, now let's wait for a keypress. But it's complicated. // The event queue might not be empty on start-up. // When I launch this program from the GP2X main menus, I press down the B button. // Depending on my speed on the button, if the SDL and the image are in cache, and, // possibly, the phase of moon, the SDL may start up while while the B button is still down. // If this happens, SDL immediately adds a button down event for the B button. SDL_PollEvent(&event); // ignore any one event in the queue. // SDL_PollEvent will return immediately, and will return 1 if there is a pending event. // I don't care about the pending event, if any, so I can ignore the return value. while (!done) { SDL_WaitEvent(&event); // wait indefinitly for events. Through away error return value (1). // When this returns, some event happened. switch (event.type) // look at the 'type', or a uint8 at the beginning of the event union. { // OK, now these are rather silly. The GP2X has no keys to hit, and has no 'quit' method. // Instead, the GP2X has button events for the various buttons (A,B,X,Y,L,R,Start,Select,Volume), and // the joystick positions, and the center click down. /* case SDL_KEYDOWN: case SDL_QUIT: */ // These are the button events case SDL_JOYBUTTONDOWN: // and here we could see code like "if (event.jbutton.button == GP2X_BUTTON_X) .... //but any button will do. done = 1; break; } } SDL_Quit(); // Shut down the SDL library, freeing resources. // This is how to quit back to the menu. Just doing a return(0) will look like the GP2X hung. chdir("/usr/gp2x"); execl("/usr/gp2x/gp2xmenu", "/usr/gp2x/gp2xmenu", NULL); // execl will go run the other program INSTEAD of this one. return 0; // this line make the compiler happy, but the call to execl() above never returns } |