19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Simple program:  Test bitmap blits */
39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <stdio.h>
59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <stdlib.h>
69682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <string.h>
79682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
89682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "SDL.h"
99682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "picture.xbm"
109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic void quit(int rc)
139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	SDL_Quit();
159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	exit(rc);
169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse HallSDL_Surface *LoadXBM(SDL_Surface *screen, int w, int h, Uint8 *bits)
199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	SDL_Surface *bitmap;
219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	Uint8 *line;
229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Allocate the bitmap */
249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 1, 0, 0, 0, 0);
259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	if ( bitmap == NULL ) {
269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		fprintf(stderr, "Couldn't allocate bitmap: %s\n",
279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall						SDL_GetError());
289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		return(NULL);
299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	}
309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Copy the pixels */
329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	line = (Uint8 *)bitmap->pixels;
339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	w = (w+7)/8;
349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	while ( h-- ) {
359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		memcpy(line, bits, w);
369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		/* X11 Bitmap images have the bits reversed */
379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		{ int i, j; Uint8 *buf, byte;
389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			for ( buf=line, i=0; i<w; ++i, ++buf ) {
399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				byte = *buf;
409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				*buf = 0;
419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				for ( j=7; j>=0; --j ) {
429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					*buf |= (byte&0x01)<<j;
439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					byte >>= 1;
449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				}
459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			}
469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		}
479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		line += bitmap->pitch;
489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		bits += w;
499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	}
509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	return(bitmap);
519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint main(int argc, char *argv[])
549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	SDL_Surface *screen;
569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	SDL_Surface *bitmap;
579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	Uint8  video_bpp;
589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	Uint32 videoflags;
599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	Uint8 *buffer;
609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	int i, k, done;
619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	SDL_Event event;
629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	Uint16 *buffer16;
639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        Uint16 color;
649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        Uint8  gradient;
659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	SDL_Color palette[256];
669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Initialize SDL */
699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		return(1);
729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	}
739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	video_bpp = 0;
759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	videoflags = SDL_SWSURFACE;
769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	while ( argc > 1 ) {
779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		--argc;
789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		if ( strcmp(argv[argc-1], "-bpp") == 0 ) {
799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			video_bpp = atoi(argv[argc]);
809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			--argc;
819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		} else
829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		if ( strcmp(argv[argc], "-warp") == 0 ) {
839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			videoflags |= SDL_HWPALETTE;
849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		} else
859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		if ( strcmp(argv[argc], "-hw") == 0 ) {
869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			videoflags |= SDL_HWSURFACE;
879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		} else
889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		if ( strcmp(argv[argc], "-fullscreen") == 0 ) {
899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			videoflags |= SDL_FULLSCREEN;
909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		} else {
919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			fprintf(stderr,
929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			"Usage: %s [-bpp N] [-warp] [-hw] [-fullscreen]\n",
939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall								argv[0]);
949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			quit(1);
959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		}
969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	}
979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Set 640x480 video mode */
999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	if ( (screen=SDL_SetVideoMode(640,480,video_bpp,videoflags)) == NULL ) {
1009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n",
1019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall						video_bpp, SDL_GetError());
1029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		quit(2);
1039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	}
1049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	if (video_bpp==8) {
1069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		/* Set a gray colormap, reverse order from white to black */
1079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		for ( i=0; i<256; ++i ) {
1089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			palette[i].r = 255-i;
1099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			palette[i].g = 255-i;
1109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			palette[i].b = 255-i;
1119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		}
1129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		SDL_SetColors(screen, palette, 0, 256);
1139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	}
1149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Set the surface pixels and refresh! */
1169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	if ( SDL_LockSurface(screen) < 0 ) {
1179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		fprintf(stderr, "Couldn't lock the display surface: %s\n",
1189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall							SDL_GetError());
1199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		quit(2);
1209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	}
1219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	buffer=(Uint8 *)screen->pixels;
1229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	if (screen->format->BytesPerPixel!=2) {
1239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        	for ( i=0; i<screen->h; ++i ) {
1249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        		memset(buffer,(i*255)/screen->h, screen->pitch);
1259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        		buffer += screen->pitch;
1269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        	}
1279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        }
1289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        else
1299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        {
1309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		for ( i=0; i<screen->h; ++i ) {
1319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			gradient=((i*255)/screen->h);
1329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall                        color = SDL_MapRGB(screen->format, gradient, gradient, gradient);
1339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall                        buffer16=(Uint16*)buffer;
1349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall                        for (k=0; k<screen->w; k++)
1359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall                        {
1369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall                            *(buffer16+k)=color;
1379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall                        }
1389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			buffer += screen->pitch;
1399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		}
1409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        }
1419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	SDL_UnlockSurface(screen);
1429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	SDL_UpdateRect(screen, 0, 0, 0, 0);
1439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Load the bitmap */
1459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	bitmap = LoadXBM(screen, picture_width, picture_height,
1469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					(Uint8 *)picture_bits);
1479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	if ( bitmap == NULL ) {
1489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		quit(1);
1499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	}
1509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	/* Wait for a keystroke */
1529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	done = 0;
1539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	while ( !done ) {
1549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		/* Check for events */
1559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		while ( SDL_PollEvent(&event) ) {
1569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			switch (event.type) {
1579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				case SDL_MOUSEBUTTONDOWN: {
1589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					SDL_Rect dst;
1599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
1609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					dst.x = event.button.x - bitmap->w/2;
1619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					dst.y = event.button.y - bitmap->h/2;
1629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					dst.w = bitmap->w;
1639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					dst.h = bitmap->h;
1649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					SDL_BlitSurface(bitmap, NULL,
1659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall								screen, &dst);
1669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					SDL_UpdateRects(screen,1,&dst);
1679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					}
1689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					break;
1699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				case SDL_KEYDOWN:
1709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					/* Any key press quits the app... */
1719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					done = 1;
1729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					break;
1739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				case SDL_QUIT:
1749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					done = 1;
1759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					break;
1769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall				default:
1779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall					break;
1789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall			}
1799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall		}
1809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	}
1819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	SDL_FreeSurface(bitmap);
1829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	SDL_Quit();
1839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall	return(0);
1849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall}
185