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
}
|