So I got this Gp2x Wiz from (http://gp2xstore.com) its a handheld game system that uses Linux for its operating system. Its pretty cool the only thing Is the screen is so small. The SDL Library's that exist on the internet only support 320x240 or 240x320 16 bit. This made it a hassle to port one of my games to the device.
After many crashes I realized that the game I was trying to port's main surface size was 640x480. I had a few choices I could recode all the graphics to use smaller graphics, or I could write a function to 'shrink' the game to the display. I choose the latter and wrote a small function to resize the main surface. I just changed the surface pointer from SDL_SetVideoMode to a new surface created in memory. Then ran the function and had it plot the pixels to the real front surface which was 320x240. It took several segmentation faults before I finally got it working.
I decided to post this code incase anyone else is having the same problem as me. You can download it
here. Included is a small demo that uses the surface resizing function. The example uses a little library for fonts called
SDL_mxf. Here is the code for the resize function called
CopySurface. A few helper functions are also there,
CreateSurface to create the offscreen surface,
SDL_GetX,
SDL_GetY for calculating the positions of the pixels, and
InitPoints for storing the values to speed it up a little bit.
-
Jared Bruni
SDL_Surface *CreateSurface(size_t w, size_t h)
{
SDL_Surface *surface;
static int rmask, gmask, bmask, amask;
rmask = 0xF800;
gmask = 0x07E0;
bmask = 0x001f;
amask = 0;
surface = SDL_CreateRGBSurface(SDL_SWSURFACE , w, h, 16, rmask, gmask,bmask, amask);
return surface;
}
typedef struct _Point {
int x, y;
} Point;
Point points[640][480];
int SDL_GetX(int w ,int x, int nw) {
float xp = (float)x * (float)w / (float)nw;
return (int)xp;
}
int SDL_GetY(int h, int y, int nh) {
float yp = (float)y * (float)h / (float)nh;
return (int)yp;
}
void InitPoints() {
int i;
for(i = 0; i < 640; i++) {
for(int z = 0; z < 480; z++) {
points[i][z].x = SDL_GetX(640, i, 320);
points[i][z].y = SDL_GetY(480, z, 240);
}
}
}
void CopySurface(SDL_Surface *from, SDL_Surface *to) {
Uint16 *buffer, *buffer_to, color;
if(SDL_MUSTLOCK(from))
SDL_LockSurface(from);
if(SDL_MUSTLOCK(to))
SDL_LockSurface(to);
buffer = (Uint16*)from->pixels;
buffer_to = (Uint16*)to->pixels;
color = 0;
for(int x = 0; x < to->w-1; x++) {
for(int y = 0; y < to->h-1; y++) {
int cx,cy;
cx = points[x][y].x;
cy = points[x][y].y;
color = *(buffer+(cy*from->pitch/2)+cx);
*(buffer_to+(y*to->pitch/2)+x) = color;
}
}
if(SDL_MUSTLOCK(from))
SDL_UnlockSurface(from);
if(SDL_MUSTLOCK(to))
SDL_UnlockSurface(to);
}