test/testsprite.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 10 Dec 2003 12:35:56 +0000
changeset 753 b14fdadd8311
parent 663 8bedd6d61642
child 1151 be9c9c8f6d53
permissions -rw-r--r--
Date: Thu, 4 Dec 2003 07:48:40 +0200
From: "Mike Gorchak"
Subject: SDL/QNX6 new patch

Here in attachment my patch for the SDL/QNX6 again :) It contain non-crtitical/cosmetic fixes:

1. Fixed window centering at other than the first consoles.
2. Fixed window centering algorithm in case when window height or width are greater than the desktop resolution.
3. Fixed window positioning on other than the first consoles.
4. Fixed occasional input focus lost when switching to fullscreen.
5. Removed the Photon's default chroma color for the overlays, added RGB(12, 6, 12) color instead (very dark pink).
6. Added more checks to the YUV overlay code (fixed crashes during resolution mode switches).
7. Added support for Enter/Backspace keys in unicode mode (used by Maelstrom and by other games).
8. Fixed window restore/maximize function. It works, finally.
slouken@0
     1
/* Simple program:  Move N sprites around on the screen as fast as possible */
slouken@0
     2
slouken@0
     3
#include <stdio.h>
slouken@0
     4
#include <stdlib.h>
slouken@0
     5
#include <string.h>
slouken@0
     6
#include <ctype.h>
slouken@753
     7
#include <math.h>
slouken@0
     8
#include <time.h>
slouken@0
     9
slouken@0
    10
#include "SDL.h"
slouken@0
    11
slouken@587
    12
#define DEBUG_FLIP 1
slouken@587
    13
slouken@0
    14
#define NUM_SPRITES	100
slouken@0
    15
#define MAX_SPEED 	1
slouken@0
    16
slouken@0
    17
SDL_Surface *sprite;
slouken@0
    18
int numsprites;
slouken@0
    19
SDL_Rect *sprite_rects;
slouken@0
    20
SDL_Rect *positions;
slouken@0
    21
SDL_Rect *velocities;
slouken@0
    22
int sprites_visible;
slouken@288
    23
Uint16 sprite_w, sprite_h;
slouken@0
    24
slouken@0
    25
int LoadSprite(SDL_Surface *screen, char *file)
slouken@0
    26
{
slouken@0
    27
	SDL_Surface *temp;
slouken@0
    28
slouken@0
    29
	/* Load the sprite image */
slouken@0
    30
	sprite = SDL_LoadBMP(file);
slouken@0
    31
	if ( sprite == NULL ) {
slouken@0
    32
		fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
slouken@0
    33
		return(-1);
slouken@0
    34
	}
slouken@0
    35
slouken@0
    36
	/* Set transparent pixel as the pixel at (0,0) */
slouken@0
    37
	if ( sprite->format->palette ) {
slouken@0
    38
		SDL_SetColorKey(sprite, (SDL_SRCCOLORKEY|SDL_RLEACCEL),
slouken@0
    39
						*(Uint8 *)sprite->pixels);
slouken@0
    40
	}
slouken@0
    41
slouken@0
    42
	/* Convert sprite to video format */
slouken@0
    43
	temp = SDL_DisplayFormat(sprite);
slouken@0
    44
	SDL_FreeSurface(sprite);
slouken@0
    45
	if ( temp == NULL ) {
slouken@0
    46
		fprintf(stderr, "Couldn't convert background: %s\n",
slouken@0
    47
							SDL_GetError());
slouken@0
    48
		return(-1);
slouken@0
    49
	}
slouken@0
    50
	sprite = temp;
slouken@0
    51
slouken@0
    52
	/* We're ready to roll. :) */
slouken@0
    53
	return(0);
slouken@0
    54
}
slouken@0
    55
slouken@0
    56
void MoveSprites(SDL_Surface *screen, Uint32 background)
slouken@0
    57
{
slouken@0
    58
	int i, nupdates;
slouken@0
    59
	SDL_Rect area, *position, *velocity;
slouken@0
    60
slouken@0
    61
	nupdates = 0;
slouken@0
    62
	/* Erase all the sprites if necessary */
slouken@0
    63
	if ( sprites_visible ) {
slouken@0
    64
		SDL_FillRect(screen, NULL, background);
slouken@0
    65
	}
slouken@0
    66
slouken@0
    67
	/* Move the sprite, bounce at the wall, and draw */
slouken@0
    68
	for ( i=0; i<numsprites; ++i ) {
slouken@0
    69
		position = &positions[i];
slouken@0
    70
		velocity = &velocities[i];
slouken@0
    71
		position->x += velocity->x;
slouken@288
    72
		if ( (position->x < 0) || (position->x >= (screen->w - sprite_w)) ) {
slouken@0
    73
			velocity->x = -velocity->x;
slouken@0
    74
			position->x += velocity->x;
slouken@0
    75
		}
slouken@0
    76
		position->y += velocity->y;
slouken@288
    77
		if ( (position->y < 0) || (position->y >= (screen->h - sprite_w)) ) {
slouken@0
    78
			velocity->y = -velocity->y;
slouken@0
    79
			position->y += velocity->y;
slouken@0
    80
		}
slouken@0
    81
slouken@0
    82
		/* Blit the sprite onto the screen */
slouken@0
    83
		area = *position;
slouken@0
    84
		SDL_BlitSurface(sprite, NULL, screen, &area);
slouken@0
    85
		sprite_rects[nupdates++] = area;
slouken@0
    86
	}
slouken@0
    87
slouken@587
    88
#if DEBUG_FLIP
slouken@587
    89
    {
slouken@663
    90
	if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
slouken@663
    91
            static int t = 0;
slouken@663
    92
slouken@663
    93
            Uint32 color = SDL_MapRGB (screen->format, 255, 0, 0);
slouken@663
    94
            SDL_Rect r;
slouken@663
    95
            r.x = (sin((float)t * 2 * 3.1459) + 1.0) / 2.0 * (screen->w-20);
slouken@663
    96
            r.y = 0;
slouken@663
    97
            r.w = 20;
slouken@663
    98
            r.h = screen->h;
slouken@587
    99
        
slouken@663
   100
            SDL_FillRect (screen, &r, color);
slouken@663
   101
            t+=2;
slouken@663
   102
        }
slouken@587
   103
    }
slouken@587
   104
#endif
slouken@587
   105
    
slouken@0
   106
	/* Update the screen! */
slouken@0
   107
	if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
slouken@0
   108
		SDL_Flip(screen);
slouken@0
   109
	} else {
slouken@0
   110
		SDL_UpdateRects(screen, nupdates, sprite_rects);
slouken@0
   111
	}
slouken@0
   112
	sprites_visible = 1;
slouken@0
   113
}
slouken@0
   114
slouken@0
   115
/* This is a way of telling whether or not to use hardware surfaces */
slouken@107
   116
Uint32 FastestFlags(Uint32 flags, int width, int height, int bpp)
slouken@0
   117
{
slouken@0
   118
	const SDL_VideoInfo *info;
slouken@0
   119
slouken@0
   120
	/* Hardware acceleration is only used in fullscreen mode */
slouken@0
   121
	flags |= SDL_FULLSCREEN;
slouken@0
   122
slouken@0
   123
	/* Check for various video capabilities */
slouken@0
   124
	info = SDL_GetVideoInfo();
slouken@0
   125
	if ( info->blit_hw_CC && info->blit_fill ) {
slouken@0
   126
		/* We use accelerated colorkeying and color filling */
slouken@0
   127
		flags |= SDL_HWSURFACE;
slouken@0
   128
	}
slouken@0
   129
	/* If we have enough video memory, and will use accelerated
slouken@0
   130
	   blits directly to it, then use page flipping.
slouken@0
   131
	 */
slouken@0
   132
	if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
slouken@0
   133
		/* Direct hardware blitting without double-buffering
slouken@0
   134
		   causes really bad flickering.
slouken@0
   135
		 */
slouken@107
   136
		if ( info->video_mem*1024 > (height*width*bpp/8) ) {
slouken@0
   137
			flags |= SDL_DOUBLEBUF;
slouken@0
   138
		} else {
slouken@0
   139
			flags &= ~SDL_HWSURFACE;
slouken@0
   140
		}
slouken@0
   141
	}
slouken@0
   142
slouken@0
   143
	/* Return the flags */
slouken@0
   144
	return(flags);
slouken@0
   145
}
slouken@0
   146
slouken@0
   147
int main(int argc, char *argv[])
slouken@0
   148
{
slouken@0
   149
	SDL_Surface *screen;
slouken@0
   150
	Uint8 *mem;
slouken@0
   151
	int width, height;
slouken@0
   152
	Uint8  video_bpp;
slouken@0
   153
	Uint32 videoflags;
slouken@0
   154
	Uint32 background;
slouken@0
   155
	int    i, done;
slouken@0
   156
	SDL_Event event;
slouken@0
   157
	Uint32 then, now, frames;
slouken@0
   158
slouken@0
   159
	/* Initialize SDL */
slouken@0
   160
	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
slouken@0
   161
		fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
slouken@0
   162
		exit(1);
slouken@0
   163
	}
slouken@0
   164
	atexit(SDL_Quit);
slouken@0
   165
slouken@0
   166
	numsprites = NUM_SPRITES;
slouken@0
   167
	videoflags = SDL_SWSURFACE|SDL_ANYFORMAT;
slouken@0
   168
	width = 640;
slouken@0
   169
	height = 480;
slouken@0
   170
	video_bpp = 8;
slouken@0
   171
	while ( argc > 1 ) {
slouken@0
   172
		--argc;
slouken@0
   173
		if ( strcmp(argv[argc-1], "-width") == 0 ) {
slouken@0
   174
			width = atoi(argv[argc]);
slouken@0
   175
			--argc;
slouken@0
   176
		} else
slouken@0
   177
		if ( strcmp(argv[argc-1], "-height") == 0 ) {
slouken@0
   178
			height = atoi(argv[argc]);
slouken@0
   179
			--argc;
slouken@0
   180
		} else
slouken@0
   181
		if ( strcmp(argv[argc-1], "-bpp") == 0 ) {
slouken@0
   182
			video_bpp = atoi(argv[argc]);
slouken@0
   183
			videoflags &= ~SDL_ANYFORMAT;
slouken@0
   184
			--argc;
slouken@0
   185
		} else
slouken@0
   186
		if ( strcmp(argv[argc], "-fast") == 0 ) {
slouken@107
   187
			videoflags = FastestFlags(videoflags, width, height, video_bpp);
slouken@0
   188
		} else
slouken@0
   189
		if ( strcmp(argv[argc], "-hw") == 0 ) {
slouken@0
   190
			videoflags ^= SDL_HWSURFACE;
slouken@0
   191
		} else
slouken@0
   192
		if ( strcmp(argv[argc], "-flip") == 0 ) {
slouken@0
   193
			videoflags ^= SDL_DOUBLEBUF;
slouken@0
   194
		} else
slouken@0
   195
		if ( strcmp(argv[argc], "-fullscreen") == 0 ) {
slouken@0
   196
			videoflags ^= SDL_FULLSCREEN;
slouken@0
   197
		} else
slouken@0
   198
		if ( isdigit(argv[argc][0]) ) {
slouken@0
   199
			numsprites = atoi(argv[argc]);
slouken@0
   200
		} else {
slouken@0
   201
			fprintf(stderr, 
slouken@0
   202
	"Usage: %s [-bpp N] [-hw] [-flip] [-fast] [-fullscreen] [numsprites]\n",
slouken@0
   203
								argv[0]);
slouken@0
   204
			exit(1);
slouken@0
   205
		}
slouken@0
   206
	}
slouken@0
   207
slouken@0
   208
	/* Set video mode */
slouken@0
   209
	screen = SDL_SetVideoMode(width, height, video_bpp, videoflags);
slouken@0
   210
	if ( ! screen ) {
slouken@0
   211
		fprintf(stderr, "Couldn't set %dx%d video mode: %s\n",
slouken@0
   212
					width, height, SDL_GetError());
slouken@0
   213
		exit(2);
slouken@0
   214
	}
slouken@0
   215
slouken@0
   216
	/* Load the sprite */
slouken@0
   217
	if ( LoadSprite(screen, "icon.bmp") < 0 ) {
slouken@0
   218
		exit(1);
slouken@0
   219
	}
slouken@0
   220
slouken@0
   221
	/* Allocate memory for the sprite info */
slouken@0
   222
	mem = (Uint8 *)malloc(4*sizeof(SDL_Rect)*numsprites);
slouken@0
   223
	if ( mem == NULL ) {
slouken@0
   224
		SDL_FreeSurface(sprite);
slouken@0
   225
		fprintf(stderr, "Out of memory!\n");
slouken@0
   226
		exit(2);
slouken@0
   227
	}
slouken@0
   228
	sprite_rects = (SDL_Rect *)mem;
slouken@0
   229
	positions = sprite_rects;
slouken@0
   230
	sprite_rects += numsprites;
slouken@0
   231
	velocities = sprite_rects;
slouken@0
   232
	sprite_rects += numsprites;
slouken@288
   233
	sprite_w = sprite->w;
slouken@288
   234
	sprite_h = sprite->h;
slouken@0
   235
	srand(time(NULL));
slouken@0
   236
	for ( i=0; i<numsprites; ++i ) {
slouken@288
   237
		positions[i].x = rand()%(screen->w - sprite_w);
slouken@288
   238
		positions[i].y = rand()%(screen->h - sprite_h);
slouken@0
   239
		positions[i].w = sprite->w;
slouken@0
   240
		positions[i].h = sprite->h;
slouken@0
   241
		velocities[i].x = 0;
slouken@0
   242
		velocities[i].y = 0;
slouken@0
   243
		while ( ! velocities[i].x && ! velocities[i].y ) {
slouken@0
   244
			velocities[i].x = (rand()%(MAX_SPEED*2+1))-MAX_SPEED;
slouken@0
   245
			velocities[i].y = (rand()%(MAX_SPEED*2+1))-MAX_SPEED;
slouken@0
   246
		}
slouken@0
   247
	}
slouken@0
   248
	background = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
slouken@0
   249
slouken@0
   250
	/* Print out information about our surfaces */
slouken@0
   251
	printf("Screen is at %d bits per pixel\n",screen->format->BitsPerPixel);
slouken@0
   252
	if ( (screen->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
slouken@0
   253
		printf("Screen is in video memory\n");
slouken@0
   254
	} else {
slouken@0
   255
		printf("Screen is in system memory\n");
slouken@0
   256
	}
slouken@0
   257
	if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
slouken@0
   258
		printf("Screen has double-buffering enabled\n");
slouken@0
   259
	}
slouken@0
   260
	if ( (sprite->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
slouken@0
   261
		printf("Sprite is in video memory\n");
slouken@0
   262
	} else {
slouken@0
   263
		printf("Sprite is in system memory\n");
slouken@0
   264
	}
slouken@0
   265
	/* Run a sample blit to trigger blit acceleration */
slouken@0
   266
	{ SDL_Rect dst;
slouken@0
   267
		dst.x = 0;
slouken@0
   268
		dst.y = 0;
slouken@0
   269
		dst.w = sprite->w;
slouken@0
   270
		dst.h = sprite->h;
slouken@0
   271
		SDL_BlitSurface(sprite, NULL, screen, &dst);
slouken@0
   272
		SDL_FillRect(screen, &dst, background);
slouken@0
   273
	}
slouken@0
   274
	if ( (sprite->flags & SDL_HWACCEL) == SDL_HWACCEL ) {
slouken@0
   275
		printf("Sprite blit uses hardware acceleration\n");
slouken@0
   276
	}
slouken@0
   277
	if ( (sprite->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) {
slouken@0
   278
		printf("Sprite blit uses RLE acceleration\n");
slouken@0
   279
	}
slouken@0
   280
slouken@0
   281
	/* Loop, blitting sprites and waiting for a keystroke */
slouken@0
   282
	frames = 0;
slouken@0
   283
	then = SDL_GetTicks();
slouken@0
   284
	done = 0;
slouken@0
   285
	sprites_visible = 0;
slouken@0
   286
	while ( !done ) {
slouken@0
   287
		/* Check for events */
slouken@0
   288
		++frames;
slouken@0
   289
		while ( SDL_PollEvent(&event) ) {
slouken@0
   290
			switch (event.type) {
slouken@529
   291
				case SDL_MOUSEBUTTONDOWN:
slouken@529
   292
					SDL_WarpMouse(screen->w/2, screen->h/2);
slouken@529
   293
					break;
slouken@0
   294
				case SDL_KEYDOWN:
slouken@0
   295
					/* Any keypress quits the app... */
slouken@0
   296
				case SDL_QUIT:
slouken@0
   297
					done = 1;
slouken@0
   298
					break;
slouken@0
   299
				default:
slouken@0
   300
					break;
slouken@0
   301
			}
slouken@0
   302
		}
slouken@0
   303
		MoveSprites(screen, background);
slouken@0
   304
	}
slouken@0
   305
	SDL_FreeSurface(sprite);
slouken@0
   306
	free(mem);
slouken@0
   307
slouken@0
   308
	/* Print out some timing information */
slouken@0
   309
	now = SDL_GetTicks();
slouken@0
   310
	if ( now > then ) {
slouken@0
   311
		printf("%2.2f frames per second\n",
slouken@0
   312
					((double)frames*1000)/(now-then));
slouken@0
   313
	}
slouken@288
   314
	SDL_Quit();
slouken@0
   315
	return(0);
slouken@0
   316
}