view test/testbitmap.c @ 1554:0ca607a5d173

Fixed bug #84 Date: Sun, 23 Oct 2005 16:39:03 +0200 From: "A. Schmid" <sahib@phreaker.net> Subject: [SDL] no software surfaces with svgalib driver? Hi, I noticed that the SDL (1.2.9) svgalib driver only makes use of linear addressable (framebuffer) video modes. On older systems (like one of mine), linear addressable modes are often not available. Especially for cards with VESA VBE < 2.0 the svgalib vesa driver is unusable, since VESA only supports framebuffering for VBE 2.0 and later. The changes necessary to add support for software surfaces seem to be relatively small. I only had to hack src/video/svga/SDL_svgavideo.c (see attached patch). The code worked fine for me, but it is no more than a proof of concept and should be reviewed (probably has a memory leak when switching modes). It also uses the vgagl library (included in the svgalib package) and needs to be linked against it. -Alex
author Sam Lantinga <slouken@libsdl.org>
date Sun, 19 Mar 2006 12:04:40 +0000
parents be9c9c8f6d53
children 782fd950bd46 c121d94672cb
line wrap: on
line source


/* Simple program:  Test bitmap blits */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "SDL.h"
#include "picture.xbm"

/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void quit(int rc)
{
	SDL_Quit();
	exit(rc);
}

SDL_Surface *LoadXBM(SDL_Surface *screen, int w, int h, Uint8 *bits)
{
	SDL_Surface *bitmap;
	Uint8 *line;

	/* Allocate the bitmap */
	bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 1, 0, 0, 0, 0);
	if ( bitmap == NULL ) {
		fprintf(stderr, "Couldn't allocate bitmap: %s\n",
						SDL_GetError());
		return(NULL);
	}

	/* Copy the pixels */
	line = (Uint8 *)bitmap->pixels;
	w = (w+7)/8;
	while ( h-- ) {
		memcpy(line, bits, w);
		/* X11 Bitmap images have the bits reversed */
		{ int i, j; Uint8 *buf, byte;
			for ( buf=line, i=0; i<w; ++i, ++buf ) {
				byte = *buf;
				*buf = 0;
				for ( j=7; j>=0; --j ) {
					*buf |= (byte&0x01)<<j;
					byte >>= 1;
				}
			}
		}
		line += bitmap->pitch;
		bits += w;
	}
	return(bitmap);
}

int main(int argc, char *argv[])
{
	SDL_Surface *screen;
	SDL_Surface *bitmap;
	Uint8  video_bpp;
	Uint32 videoflags;
	Uint8 *buffer;
	int i, k, done;
	SDL_Event event;
	Uint16 *buffer16;
        Uint16 color;
        Uint8  gradient;
	SDL_Color palette[256];


	/* Initialize SDL */
	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
		fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
		return(1);
	}

	video_bpp = 0;
	videoflags = SDL_SWSURFACE;
	while ( argc > 1 ) {
		--argc;
		if ( strcmp(argv[argc-1], "-bpp") == 0 ) {
			video_bpp = atoi(argv[argc]);
			--argc;
		} else
		if ( strcmp(argv[argc], "-warp") == 0 ) {
			videoflags |= SDL_HWPALETTE;
		} else
		if ( strcmp(argv[argc], "-hw") == 0 ) {
			videoflags |= SDL_HWSURFACE;
		} else
		if ( strcmp(argv[argc], "-fullscreen") == 0 ) {
			videoflags |= SDL_FULLSCREEN;
		} else {
			fprintf(stderr,
			"Usage: %s [-bpp N] [-warp] [-hw] [-fullscreen]\n",
								argv[0]);
			quit(1);
		}
	}

	/* Set 640x480 video mode */
	if ( (screen=SDL_SetVideoMode(640,480,video_bpp,videoflags)) == NULL ) {
		fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n",
						video_bpp, SDL_GetError());
		quit(2);
	}

	if (video_bpp==8) {
		/* Set a gray colormap, reverse order from white to black */
		for ( i=0; i<256; ++i ) {
			palette[i].r = 255-i;
			palette[i].g = 255-i;
			palette[i].b = 255-i;
		}
		SDL_SetColors(screen, palette, 0, 256);
	}

	/* Set the surface pixels and refresh! */
	if ( SDL_LockSurface(screen) < 0 ) {
		fprintf(stderr, "Couldn't lock the display surface: %s\n",
							SDL_GetError());
		quit(2);
	}
	buffer=(Uint8 *)screen->pixels;
	if (screen->format->BytesPerPixel!=2) {
        	for ( i=0; i<screen->h; ++i ) {
        		memset(buffer,(i*255)/screen->h, screen->pitch);
        		buffer += screen->pitch;
        	}
        }
        else
        {
		for ( i=0; i<screen->h; ++i ) {
			gradient=((i*255)/screen->h);
                        color = SDL_MapRGB(screen->format, gradient, gradient, gradient);
                        buffer16=(Uint16*)buffer;
                        for (k=0; k<screen->w; k++)
                        {
                            *(buffer16+k)=color;
                        }
			buffer += screen->pitch;
		}
        }
	SDL_UnlockSurface(screen);
	SDL_UpdateRect(screen, 0, 0, 0, 0);

	/* Load the bitmap */
	bitmap = LoadXBM(screen, picture_width, picture_height,
					(Uint8 *)picture_bits);
	if ( bitmap == NULL ) {
		quit(1);
	}

	/* Wait for a keystroke */
	done = 0;
	while ( !done ) {
		/* Check for events */
		while ( SDL_PollEvent(&event) ) {
			switch (event.type) {
				case SDL_MOUSEBUTTONDOWN: {
					SDL_Rect dst;

					dst.x = event.button.x - bitmap->w/2;
					dst.y = event.button.y - bitmap->h/2;
					dst.w = bitmap->w;
					dst.h = bitmap->h;
					SDL_BlitSurface(bitmap, NULL,
								screen, &dst);
					SDL_UpdateRects(screen,1,&dst);
					}
					break;
				case SDL_KEYDOWN:
					/* Any key press quits the app... */
					done = 1;
					break;
				case SDL_QUIT:
					done = 1;
					break;
				default:
					break;
			}
		}
	}
	SDL_FreeSurface(bitmap);
	SDL_Quit();
	return(0);
}