5245
|
1 /* Simple program: Move N sprites around on the screen as fast as possible */
|
|
2
|
|
3 #include <stdlib.h>
|
|
4 #include <stdio.h>
|
|
5 #include <time.h>
|
|
6
|
|
7 #include "SDL.h"
|
|
8 #include "common.h"
|
|
9
|
|
10 #define WINDOW_WIDTH 640
|
|
11 #define WINDOW_HEIGHT 480
|
|
12
|
|
13 static CommonState *state;
|
|
14
|
|
15 typedef struct {
|
|
16 SDL_Window *window;
|
|
17 SDL_Renderer *renderer;
|
|
18 SDL_Texture *background;
|
|
19 SDL_Texture *sprite;
|
|
20 SDL_Rect sprite_rect;
|
|
21 int scale_direction;
|
|
22 } DrawState;
|
|
23
|
|
24 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
|
|
25 static void
|
|
26 quit(int rc)
|
|
27 {
|
|
28 CommonQuit(state);
|
|
29 exit(rc);
|
|
30 }
|
|
31
|
|
32 SDL_Texture *
|
|
33 LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent)
|
|
34 {
|
|
35 SDL_Surface *temp;
|
|
36 SDL_Texture *texture;
|
|
37
|
|
38 /* Load the sprite image */
|
|
39 temp = SDL_LoadBMP(file);
|
|
40 if (temp == NULL) {
|
|
41 fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
|
|
42 return NULL;
|
|
43 }
|
|
44
|
|
45 /* Set transparent pixel as the pixel at (0,0) */
|
|
46 if (transparent) {
|
|
47 if (temp->format->palette) {
|
|
48 SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels);
|
|
49 } else {
|
|
50 switch (temp->format->BitsPerPixel) {
|
|
51 case 15:
|
|
52 SDL_SetColorKey(temp, SDL_TRUE,
|
|
53 (*(Uint16 *) temp->pixels) & 0x00007FFF);
|
|
54 break;
|
|
55 case 16:
|
|
56 SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels);
|
|
57 break;
|
|
58 case 24:
|
|
59 SDL_SetColorKey(temp, SDL_TRUE,
|
|
60 (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
|
|
61 break;
|
|
62 case 32:
|
|
63 SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels);
|
|
64 break;
|
|
65 }
|
|
66 }
|
|
67 }
|
|
68
|
|
69 /* Create textures from the image */
|
|
70 texture = SDL_CreateTextureFromSurface(renderer, temp);
|
|
71 if (!texture) {
|
|
72 fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
|
|
73 SDL_FreeSurface(temp);
|
|
74 return NULL;
|
|
75 }
|
|
76 SDL_FreeSurface(temp);
|
|
77
|
|
78 /* We're ready to roll. :) */
|
|
79 return texture;
|
|
80 }
|
|
81
|
|
82 void
|
|
83 Draw(DrawState *s)
|
|
84 {
|
|
85 int w, h;
|
|
86 SDL_Rect rect;
|
|
87
|
|
88 SDL_GetWindowSize(s->window, &w, &h);
|
|
89
|
|
90 /* Draw the background */
|
|
91 SDL_RenderCopy(s->renderer, s->background, NULL, NULL);
|
|
92
|
|
93 /* Scale and draw the sprite */
|
|
94 s->sprite_rect.w += s->scale_direction;
|
|
95 s->sprite_rect.h += s->scale_direction;
|
|
96 if (s->scale_direction > 0) {
|
|
97 if (s->sprite_rect.w >= w || s->sprite_rect.h >= h) {
|
|
98 s->scale_direction = -1;
|
|
99 }
|
|
100 } else {
|
|
101 if (s->sprite_rect.w <= 1 || s->sprite_rect.h <= 1) {
|
|
102 s->scale_direction = 1;
|
|
103 }
|
|
104 }
|
|
105 s->sprite_rect.x = (w - s->sprite_rect.w) / 2;
|
|
106 s->sprite_rect.y = (h - s->sprite_rect.h) / 2;
|
|
107
|
|
108 SDL_RenderCopy(s->renderer, s->sprite, NULL, &s->sprite_rect);
|
|
109
|
|
110 /* Update the screen! */
|
|
111 SDL_RenderPresent(s->renderer);
|
|
112 }
|
|
113
|
|
114 int
|
|
115 main(int argc, char *argv[])
|
|
116 {
|
|
117 DrawState *drawstates;
|
|
118 int i, done;
|
|
119 SDL_Event event;
|
|
120 int frames;
|
|
121 Uint32 then, now;
|
|
122
|
|
123 /* Initialize test framework */
|
|
124 state = CommonCreateState(argv, SDL_INIT_VIDEO);
|
|
125 if (!state) {
|
|
126 return 1;
|
|
127 }
|
|
128 for (i = 1; i < argc;) {
|
|
129 int consumed;
|
|
130
|
|
131 consumed = CommonArg(state, i);
|
|
132 if (consumed == 0) {
|
|
133 fprintf(stderr, "Usage: %s %s\n", argv[0], CommonUsage(state));
|
|
134 return 1;
|
|
135 }
|
|
136 i += consumed;
|
|
137 }
|
|
138 if (!CommonInit(state)) {
|
|
139 quit(2);
|
|
140 }
|
|
141
|
|
142 drawstates = SDL_stack_alloc(DrawState, state->num_windows);
|
|
143 for (i = 0; i < state->num_windows; ++i) {
|
|
144 DrawState *drawstate = &drawstates[i];
|
|
145
|
|
146 drawstate->window = state->windows[i];
|
|
147 drawstate->renderer = state->renderers[i];
|
|
148 drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE);
|
|
149 drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE);
|
|
150 if (!drawstate->sprite || !drawstate->background) {
|
|
151 quit(2);
|
|
152 }
|
|
153 SDL_QueryTexture(drawstate->sprite, NULL, NULL,
|
|
154 &drawstate->sprite_rect.w, &drawstate->sprite_rect.h);
|
|
155 drawstate->scale_direction = 1;
|
|
156 }
|
|
157
|
|
158 /* Main render loop */
|
|
159 frames = 0;
|
|
160 then = SDL_GetTicks();
|
|
161 done = 0;
|
|
162 while (!done) {
|
|
163 /* Check for events */
|
|
164 ++frames;
|
|
165 while (SDL_PollEvent(&event)) {
|
|
166 CommonEvent(state, &event, &done);
|
|
167 }
|
|
168 for (i = 0; i < state->num_windows; ++i) {
|
|
169 Draw(&drawstates[i]);
|
|
170 }
|
|
171 }
|
|
172
|
|
173 /* Print out some timing information */
|
|
174 now = SDL_GetTicks();
|
|
175 if (now > then) {
|
|
176 double fps = ((double) frames * 1000) / (now - then);
|
|
177 printf("%2.2f frames per second\n", fps);
|
|
178 }
|
|
179
|
|
180 SDL_stack_free(drawstate);
|
|
181
|
|
182 quit(0);
|
|
183 return 0;
|
|
184 }
|
|
185
|
|
186 /* vi: set ts=4 sw=4 expandtab: */
|