1 /* Simple program: Move N sprites around on the screen as fast as possible */
12 #define NUM_SPRITES 100
17 SDL_Rect
*sprite_rects
;
22 Uint16 sprite_w
, sprite_h
;
24 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
25 static void quit(int rc
)
31 int LoadSprite(char *file
)
35 /* Load the sprite image */
36 sprite
= SDL_LoadBMP(file
);
37 if ( sprite
== NULL
) {
38 fprintf(stderr
, "Couldn't load %s: %s", file
, SDL_GetError());
42 /* Set transparent pixel as the pixel at (0,0) */
43 if ( sprite
->format
->palette
) {
44 SDL_SetColorKey(sprite
, (SDL_SRCCOLORKEY
|SDL_RLEACCEL
),
45 *(Uint8
*)sprite
->pixels
);
48 /* Convert sprite to video format */
49 temp
= SDL_DisplayFormat(sprite
);
50 SDL_FreeSurface(sprite
);
52 fprintf(stderr
, "Couldn't convert background: %s\n",
58 /* We're ready to roll. :) */
62 void MoveSprites(SDL_Surface
*screen
, Uint32 background
)
65 SDL_Rect area
, *position
, *velocity
;
68 /* Erase all the sprites if necessary */
69 if ( sprites_visible
) {
70 SDL_FillRect(screen
, NULL
, background
);
73 /* Move the sprite, bounce at the wall, and draw */
74 for ( i
=0; i
<numsprites
; ++i
) {
75 position
= &positions
[i
];
76 velocity
= &velocities
[i
];
77 position
->x
+= velocity
->x
;
78 if ( (position
->x
< 0) || (position
->x
>= (screen
->w
- sprite_w
)) ) {
79 velocity
->x
= -velocity
->x
;
80 position
->x
+= velocity
->x
;
82 position
->y
+= velocity
->y
;
83 if ( (position
->y
< 0) || (position
->y
>= (screen
->h
- sprite_w
)) ) {
84 velocity
->y
= -velocity
->y
;
85 position
->y
+= velocity
->y
;
88 /* Blit the sprite onto the screen */
90 SDL_BlitSurface(sprite
, NULL
, screen
, &area
);
91 sprite_rects
[nupdates
++] = area
;
95 if ( (screen
->flags
& SDL_DOUBLEBUF
) == SDL_DOUBLEBUF
) {
98 Uint32 color
= SDL_MapRGB (screen
->format
, 255, 0, 0);
100 r
.x
= (sin((float)t
* 2 * 3.1459) + 1.0) / 2.0 * (screen
->w
-20);
105 SDL_FillRect (screen
, &r
, color
);
110 /* Update the screen! */
111 if ( (screen
->flags
& SDL_DOUBLEBUF
) == SDL_DOUBLEBUF
) {
114 SDL_UpdateRects(screen
, nupdates
, sprite_rects
);
119 /* This is a way of telling whether or not to use hardware surfaces */
120 Uint32
FastestFlags(Uint32 flags
, int width
, int height
, int bpp
)
122 const SDL_VideoInfo
*info
;
124 /* Hardware acceleration is only used in fullscreen mode */
125 flags
|= SDL_FULLSCREEN
;
127 /* Check for various video capabilities */
128 info
= SDL_GetVideoInfo();
129 if ( info
->blit_hw_CC
&& info
->blit_fill
) {
130 /* We use accelerated colorkeying and color filling */
131 flags
|= SDL_HWSURFACE
;
133 /* If we have enough video memory, and will use accelerated
134 blits directly to it, then use page flipping.
136 if ( (flags
& SDL_HWSURFACE
) == SDL_HWSURFACE
) {
137 /* Direct hardware blitting without double-buffering
138 causes really bad flickering.
140 if ( info
->video_mem
*1024 > (height
*width
*bpp
/8) ) {
141 flags
|= SDL_DOUBLEBUF
;
143 flags
&= ~SDL_HWSURFACE
;
147 /* Return the flags */
151 int main(int argc
, char *argv
[])
161 Uint32 then
, now
, frames
;
164 if ( SDL_Init(SDL_INIT_VIDEO
) < 0 ) {
165 fprintf(stderr
, "Couldn't initialize SDL: %s\n",SDL_GetError());
169 numsprites
= NUM_SPRITES
;
170 videoflags
= SDL_SWSURFACE
|SDL_ANYFORMAT
;
177 if ( strcmp(argv
[argc
-1], "-width") == 0 ) {
178 width
= atoi(argv
[argc
]);
181 if ( strcmp(argv
[argc
-1], "-height") == 0 ) {
182 height
= atoi(argv
[argc
]);
185 if ( strcmp(argv
[argc
-1], "-bpp") == 0 ) {
186 video_bpp
= atoi(argv
[argc
]);
187 videoflags
&= ~SDL_ANYFORMAT
;
190 if ( strcmp(argv
[argc
], "-fast") == 0 ) {
191 videoflags
= FastestFlags(videoflags
, width
, height
, video_bpp
);
193 if ( strcmp(argv
[argc
], "-hw") == 0 ) {
194 videoflags
^= SDL_HWSURFACE
;
196 if ( strcmp(argv
[argc
], "-flip") == 0 ) {
197 videoflags
^= SDL_DOUBLEBUF
;
199 if ( strcmp(argv
[argc
], "-debugflip") == 0 ) {
202 if ( strcmp(argv
[argc
], "-fullscreen") == 0 ) {
203 videoflags
^= SDL_FULLSCREEN
;
205 if ( isdigit(argv
[argc
][0]) ) {
206 numsprites
= atoi(argv
[argc
]);
209 "Usage: %s [-bpp N] [-hw] [-flip] [-fast] [-fullscreen] [numsprites]\n",
216 screen
= SDL_SetVideoMode(width
, height
, video_bpp
, videoflags
);
218 fprintf(stderr
, "Couldn't set %dx%d video mode: %s\n",
219 width
, height
, SDL_GetError());
223 /* Load the sprite */
224 if ( LoadSprite("icon.bmp") < 0 ) {
228 /* Allocate memory for the sprite info */
229 mem
= (Uint8
*)malloc(4*sizeof(SDL_Rect
)*numsprites
);
231 SDL_FreeSurface(sprite
);
232 fprintf(stderr
, "Out of memory!\n");
235 sprite_rects
= (SDL_Rect
*)mem
;
236 positions
= sprite_rects
;
237 sprite_rects
+= numsprites
;
238 velocities
= sprite_rects
;
239 sprite_rects
+= numsprites
;
240 sprite_w
= sprite
->w
;
241 sprite_h
= sprite
->h
;
243 for ( i
=0; i
<numsprites
; ++i
) {
244 positions
[i
].x
= rand()%(screen
->w
- sprite_w
);
245 positions
[i
].y
= rand()%(screen
->h
- sprite_h
);
246 positions
[i
].w
= sprite
->w
;
247 positions
[i
].h
= sprite
->h
;
250 while ( ! velocities
[i
].x
&& ! velocities
[i
].y
) {
251 velocities
[i
].x
= (rand()%(MAX_SPEED
*2+1))-MAX_SPEED
;
252 velocities
[i
].y
= (rand()%(MAX_SPEED
*2+1))-MAX_SPEED
;
255 background
= SDL_MapRGB(screen
->format
, 0x00, 0x00, 0x00);
257 /* Print out information about our surfaces */
258 printf("Screen is at %d bits per pixel\n",screen
->format
->BitsPerPixel
);
259 if ( (screen
->flags
& SDL_HWSURFACE
) == SDL_HWSURFACE
) {
260 printf("Screen is in video memory\n");
262 printf("Screen is in system memory\n");
264 if ( (screen
->flags
& SDL_DOUBLEBUF
) == SDL_DOUBLEBUF
) {
265 printf("Screen has double-buffering enabled\n");
267 if ( (sprite
->flags
& SDL_HWSURFACE
) == SDL_HWSURFACE
) {
268 printf("Sprite is in video memory\n");
270 printf("Sprite is in system memory\n");
272 /* Run a sample blit to trigger blit acceleration */
278 SDL_BlitSurface(sprite
, NULL
, screen
, &dst
);
279 SDL_FillRect(screen
, &dst
, background
);
281 if ( (sprite
->flags
& SDL_HWACCEL
) == SDL_HWACCEL
) {
282 printf("Sprite blit uses hardware acceleration\n");
284 if ( (sprite
->flags
& SDL_RLEACCEL
) == SDL_RLEACCEL
) {
285 printf("Sprite blit uses RLE acceleration\n");
288 /* Loop, blitting sprites and waiting for a keystroke */
290 then
= SDL_GetTicks();
294 /* Check for events */
296 while ( SDL_PollEvent(&event
) ) {
297 switch (event
.type
) {
298 case SDL_MOUSEBUTTONDOWN
:
299 SDL_WarpMouse(screen
->w
/2, screen
->h
/2);
302 /* Any keypress quits the app... */
310 MoveSprites(screen
, background
);
312 SDL_FreeSurface(sprite
);
315 /* Print out some timing information */
316 now
= SDL_GetTicks();
318 printf("%2.2f frames per second\n",
319 ((double)frames
*1000)/(now
-then
));