test/testsprite.c
changeset 0 74212992fb08
child 107 01fcac5d146e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/test/testsprite.c	Thu Apr 26 16:45:43 2001 +0000
     1.3 @@ -0,0 +1,290 @@
     1.4 +
     1.5 +/* Simple program:  Move N sprites around on the screen as fast as possible */
     1.6 +
     1.7 +#include <stdio.h>
     1.8 +#include <stdlib.h>
     1.9 +#include <string.h>
    1.10 +#include <ctype.h>
    1.11 +#include <time.h>
    1.12 +
    1.13 +#include "SDL.h"
    1.14 +
    1.15 +#define NUM_SPRITES	100
    1.16 +#define MAX_SPEED 	1
    1.17 +
    1.18 +SDL_Surface *sprite;
    1.19 +int numsprites;
    1.20 +SDL_Rect *sprite_rects;
    1.21 +SDL_Rect *positions;
    1.22 +SDL_Rect *velocities;
    1.23 +int sprites_visible;
    1.24 +
    1.25 +int LoadSprite(SDL_Surface *screen, char *file)
    1.26 +{
    1.27 +	SDL_Surface *temp;
    1.28 +
    1.29 +	/* Load the sprite image */
    1.30 +	sprite = SDL_LoadBMP(file);
    1.31 +	if ( sprite == NULL ) {
    1.32 +		fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
    1.33 +		return(-1);
    1.34 +	}
    1.35 +
    1.36 +	/* Set transparent pixel as the pixel at (0,0) */
    1.37 +	if ( sprite->format->palette ) {
    1.38 +		SDL_SetColorKey(sprite, (SDL_SRCCOLORKEY|SDL_RLEACCEL),
    1.39 +						*(Uint8 *)sprite->pixels);
    1.40 +	}
    1.41 +
    1.42 +	/* Convert sprite to video format */
    1.43 +	temp = SDL_DisplayFormat(sprite);
    1.44 +	SDL_FreeSurface(sprite);
    1.45 +	if ( temp == NULL ) {
    1.46 +		fprintf(stderr, "Couldn't convert background: %s\n",
    1.47 +							SDL_GetError());
    1.48 +		return(-1);
    1.49 +	}
    1.50 +	sprite = temp;
    1.51 +
    1.52 +	/* We're ready to roll. :) */
    1.53 +	return(0);
    1.54 +}
    1.55 +
    1.56 +void MoveSprites(SDL_Surface *screen, Uint32 background)
    1.57 +{
    1.58 +	int i, nupdates;
    1.59 +	SDL_Rect area, *position, *velocity;
    1.60 +
    1.61 +	nupdates = 0;
    1.62 +	/* Erase all the sprites if necessary */
    1.63 +	if ( sprites_visible ) {
    1.64 +		SDL_FillRect(screen, NULL, background);
    1.65 +	}
    1.66 +
    1.67 +	/* Move the sprite, bounce at the wall, and draw */
    1.68 +	for ( i=0; i<numsprites; ++i ) {
    1.69 +		position = &positions[i];
    1.70 +		velocity = &velocities[i];
    1.71 +		position->x += velocity->x;
    1.72 +		if ( (position->x < 0) || (position->x >= screen->w) ) {
    1.73 +			velocity->x = -velocity->x;
    1.74 +			position->x += velocity->x;
    1.75 +		}
    1.76 +		position->y += velocity->y;
    1.77 +		if ( (position->y < 0) || (position->y >= screen->h) ) {
    1.78 +			velocity->y = -velocity->y;
    1.79 +			position->y += velocity->y;
    1.80 +		}
    1.81 +
    1.82 +		/* Blit the sprite onto the screen */
    1.83 +		area = *position;
    1.84 +		SDL_BlitSurface(sprite, NULL, screen, &area);
    1.85 +		sprite_rects[nupdates++] = area;
    1.86 +	}
    1.87 +
    1.88 +	/* Update the screen! */
    1.89 +	if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
    1.90 +		SDL_Flip(screen);
    1.91 +	} else {
    1.92 +		SDL_UpdateRects(screen, nupdates, sprite_rects);
    1.93 +	}
    1.94 +	sprites_visible = 1;
    1.95 +}
    1.96 +
    1.97 +/* This is a way of telling whether or not to use hardware surfaces */
    1.98 +Uint32 FastestFlags(Uint32 flags)
    1.99 +{
   1.100 +	const SDL_VideoInfo *info;
   1.101 +
   1.102 +	/* Hardware acceleration is only used in fullscreen mode */
   1.103 +	flags |= SDL_FULLSCREEN;
   1.104 +
   1.105 +	/* Check for various video capabilities */
   1.106 +	info = SDL_GetVideoInfo();
   1.107 +	if ( info->blit_hw_CC && info->blit_fill ) {
   1.108 +		/* We use accelerated colorkeying and color filling */
   1.109 +		flags |= SDL_HWSURFACE;
   1.110 +	}
   1.111 +	/* If we have enough video memory, and will use accelerated
   1.112 +	   blits directly to it, then use page flipping.
   1.113 +	 */
   1.114 +	if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
   1.115 +		/* Direct hardware blitting without double-buffering
   1.116 +		   causes really bad flickering.
   1.117 +		 */
   1.118 +		SDL_Surface *screen = SDL_GetVideoSurface();
   1.119 +		if ( info->video_mem > (screen->h*screen->pitch) ) {
   1.120 +			flags |= SDL_DOUBLEBUF;
   1.121 +		} else {
   1.122 +			flags &= ~SDL_HWSURFACE;
   1.123 +		}
   1.124 +	}
   1.125 +
   1.126 +	/* Return the flags */
   1.127 +	return(flags);
   1.128 +}
   1.129 +
   1.130 +int main(int argc, char *argv[])
   1.131 +{
   1.132 +	SDL_Surface *screen;
   1.133 +	Uint8 *mem;
   1.134 +	int width, height;
   1.135 +	Uint8  video_bpp;
   1.136 +	Uint32 videoflags;
   1.137 +	Uint32 background;
   1.138 +	int    i, done;
   1.139 +	SDL_Event event;
   1.140 +	Uint32 then, now, frames;
   1.141 +
   1.142 +	/* Initialize SDL */
   1.143 +	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
   1.144 +		fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
   1.145 +		exit(1);
   1.146 +	}
   1.147 +	atexit(SDL_Quit);
   1.148 +
   1.149 +	numsprites = NUM_SPRITES;
   1.150 +	videoflags = SDL_SWSURFACE|SDL_ANYFORMAT;
   1.151 +	width = 640;
   1.152 +	height = 480;
   1.153 +	video_bpp = 8;
   1.154 +	while ( argc > 1 ) {
   1.155 +		--argc;
   1.156 +		if ( strcmp(argv[argc-1], "-width") == 0 ) {
   1.157 +			width = atoi(argv[argc]);
   1.158 +			--argc;
   1.159 +		} else
   1.160 +		if ( strcmp(argv[argc-1], "-height") == 0 ) {
   1.161 +			height = atoi(argv[argc]);
   1.162 +			--argc;
   1.163 +		} else
   1.164 +		if ( strcmp(argv[argc-1], "-bpp") == 0 ) {
   1.165 +			video_bpp = atoi(argv[argc]);
   1.166 +			videoflags &= ~SDL_ANYFORMAT;
   1.167 +			--argc;
   1.168 +		} else
   1.169 +		if ( strcmp(argv[argc], "-fast") == 0 ) {
   1.170 +			videoflags = FastestFlags(videoflags);
   1.171 +		} else
   1.172 +		if ( strcmp(argv[argc], "-hw") == 0 ) {
   1.173 +			videoflags ^= SDL_HWSURFACE;
   1.174 +		} else
   1.175 +		if ( strcmp(argv[argc], "-flip") == 0 ) {
   1.176 +			videoflags ^= SDL_DOUBLEBUF;
   1.177 +		} else
   1.178 +		if ( strcmp(argv[argc], "-fullscreen") == 0 ) {
   1.179 +			videoflags ^= SDL_FULLSCREEN;
   1.180 +		} else
   1.181 +		if ( isdigit(argv[argc][0]) ) {
   1.182 +			numsprites = atoi(argv[argc]);
   1.183 +		} else {
   1.184 +			fprintf(stderr, 
   1.185 +	"Usage: %s [-bpp N] [-hw] [-flip] [-fast] [-fullscreen] [numsprites]\n",
   1.186 +								argv[0]);
   1.187 +			exit(1);
   1.188 +		}
   1.189 +	}
   1.190 +
   1.191 +	/* Set video mode */
   1.192 +	screen = SDL_SetVideoMode(width, height, video_bpp, videoflags);
   1.193 +	if ( ! screen ) {
   1.194 +		fprintf(stderr, "Couldn't set %dx%d video mode: %s\n",
   1.195 +					width, height, SDL_GetError());
   1.196 +		exit(2);
   1.197 +	}
   1.198 +
   1.199 +	/* Load the sprite */
   1.200 +	if ( LoadSprite(screen, "icon.bmp") < 0 ) {
   1.201 +		exit(1);
   1.202 +	}
   1.203 +
   1.204 +	/* Allocate memory for the sprite info */
   1.205 +	mem = (Uint8 *)malloc(4*sizeof(SDL_Rect)*numsprites);
   1.206 +	if ( mem == NULL ) {
   1.207 +		SDL_FreeSurface(sprite);
   1.208 +		fprintf(stderr, "Out of memory!\n");
   1.209 +		exit(2);
   1.210 +	}
   1.211 +	sprite_rects = (SDL_Rect *)mem;
   1.212 +	positions = sprite_rects;
   1.213 +	sprite_rects += numsprites;
   1.214 +	velocities = sprite_rects;
   1.215 +	sprite_rects += numsprites;
   1.216 +	srand(time(NULL));
   1.217 +	for ( i=0; i<numsprites; ++i ) {
   1.218 +		positions[i].x = rand()%screen->w;
   1.219 +		positions[i].y = rand()%screen->h;
   1.220 +		positions[i].w = sprite->w;
   1.221 +		positions[i].h = sprite->h;
   1.222 +		velocities[i].x = 0;
   1.223 +		velocities[i].y = 0;
   1.224 +		while ( ! velocities[i].x && ! velocities[i].y ) {
   1.225 +			velocities[i].x = (rand()%(MAX_SPEED*2+1))-MAX_SPEED;
   1.226 +			velocities[i].y = (rand()%(MAX_SPEED*2+1))-MAX_SPEED;
   1.227 +		}
   1.228 +	}
   1.229 +	background = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
   1.230 +
   1.231 +	/* Print out information about our surfaces */
   1.232 +	printf("Screen is at %d bits per pixel\n",screen->format->BitsPerPixel);
   1.233 +	if ( (screen->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
   1.234 +		printf("Screen is in video memory\n");
   1.235 +	} else {
   1.236 +		printf("Screen is in system memory\n");
   1.237 +	}
   1.238 +	if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
   1.239 +		printf("Screen has double-buffering enabled\n");
   1.240 +	}
   1.241 +	if ( (sprite->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
   1.242 +		printf("Sprite is in video memory\n");
   1.243 +	} else {
   1.244 +		printf("Sprite is in system memory\n");
   1.245 +	}
   1.246 +	/* Run a sample blit to trigger blit acceleration */
   1.247 +	{ SDL_Rect dst;
   1.248 +		dst.x = 0;
   1.249 +		dst.y = 0;
   1.250 +		dst.w = sprite->w;
   1.251 +		dst.h = sprite->h;
   1.252 +		SDL_BlitSurface(sprite, NULL, screen, &dst);
   1.253 +		SDL_FillRect(screen, &dst, background);
   1.254 +	}
   1.255 +	if ( (sprite->flags & SDL_HWACCEL) == SDL_HWACCEL ) {
   1.256 +		printf("Sprite blit uses hardware acceleration\n");
   1.257 +	}
   1.258 +	if ( (sprite->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) {
   1.259 +		printf("Sprite blit uses RLE acceleration\n");
   1.260 +	}
   1.261 +
   1.262 +	/* Loop, blitting sprites and waiting for a keystroke */
   1.263 +	frames = 0;
   1.264 +	then = SDL_GetTicks();
   1.265 +	done = 0;
   1.266 +	sprites_visible = 0;
   1.267 +	while ( !done ) {
   1.268 +		/* Check for events */
   1.269 +		++frames;
   1.270 +		while ( SDL_PollEvent(&event) ) {
   1.271 +			switch (event.type) {
   1.272 +				case SDL_KEYDOWN:
   1.273 +					/* Any keypress quits the app... */
   1.274 +				case SDL_QUIT:
   1.275 +					done = 1;
   1.276 +					break;
   1.277 +				default:
   1.278 +					break;
   1.279 +			}
   1.280 +		}
   1.281 +		MoveSprites(screen, background);
   1.282 +	}
   1.283 +	SDL_FreeSurface(sprite);
   1.284 +	free(mem);
   1.285 +
   1.286 +	/* Print out some timing information */
   1.287 +	now = SDL_GetTicks();
   1.288 +	if ( now > then ) {
   1.289 +		printf("%2.2f frames per second\n",
   1.290 +					((double)frames*1000)/(now-then));
   1.291 +	}
   1.292 +	return(0);
   1.293 +}