第四章 样例
注:重复的例子没有列出
最快的图像平面块传送
将图像画到屏幕上有三种方式:1.创建一个图像平面并用SDL_BlitSurface传送到屏幕;2.在系统内存创建视频平面并调用SDL_UpdateRect;3.在显存创建视频平面并调用SDL_LockSurface。最好的方法是混合方式:
#include
1<stdio.h>
2 #include <stdlib.h>
3 #include "SDL.h"
4 #include "SDL_timer.h"
5
6 void ComplainAndExit(void)
7 {
8 fprintf(stderr, "Problem: %s\n", SDL_GetError());
9 exit(1);
10 }
11
12 int main(int argc, char *argv[])
13 {
14 SDL_PixelFormat fmt;
15 SDL_Surface *screen, *locked;
16 SDL_Surface *imagebmp, *image;
17 SDL_Rect dstrect;
18 int i;
19 Uint8 *buffer;
20
21 /* Initialize SDL */
22 if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
23 ComplainAndExit();
24 }
25 atexit(SDL_Quit);
26
27 /* Load a BMP image into a surface */
28 imagebmp = SDL_LoadBMP("image.bmp");
29 if ( imagebmp == NULL ) {
30 ComplainAndExit();
31 }
32
33 /* Set the video mode (640x480 at native depth) */
34 screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE|SDL_FULLSCREEN);
35 if ( screen == NULL ) {
36 ComplainAndExit();
37 }
38
39 /* Set the video colormap */
40 if ( imagebmp->format->palette != NULL ) {
41 SDL_SetColors(screen,
42 imagebmp->format->palette->colors, 0,
43 imagebmp->format->palette->ncolors);
44 }
45
46 /* Convert the image to the video format (maps colors) */
47 image = SDL_DisplayFormat(imagebmp);
48 SDL_FreeSurface(imagebmp);
49 if ( image == NULL ) {
50 ComplainAndExit();
51 }
52
53 /* Draw bands of color on the raw surface */
54 if ( SDL_MUSTLOCK(screen) ) {
55 if ( SDL_LockSurface(screen) < 0 )
56 ComplainAndExit();
57 }
58 buffer=(Uint8 *)screen->pixels;
59 for ( i=0; ih; ++i ) {
60 memset(buffer,(i*255)/screen->h,
61 screen->w*screen->format->BytesPerPixel);
62 buffer += screen->pitch;
63 }
64 if ( SDL_MUSTLOCK(screen) ) {
65 SDL_UnlockSurface(screen);
66 }
67
68 /* Blit the image to the center of the screen */
69 dstrect.x = (screen->w-image->w)/2;
70 dstrect.y = (screen->h-image->h)/2;
71 dstrect.w = image->w;
72 dstrect.h = image->h;
73 if ( SDL_BlitSurface(image, NULL, screen, &dstrect) < 0 ) {
74 SDL_FreeSurface(image);
75 ComplainAndExit();
76 }
77 SDL_FreeSurface(image);
78
79 /* Update the screen */
80 SDL_UpdateRects(screen, 1, &dstrect);
81
82 SDL_Delay(5000); /* Wait 5 seconds */
83 exit(0);
84 }
85
86
87### 过滤和处理事件
88
89
90 #include <stdio.h>
91 #include <stdlib.h>
92
93 #include "SDL.h"
94
95 /* This function may run in a separate event thread */
96 int FilterEvents(const SDL_Event *event) {
97 static int boycott = 1;
98
99 /* This quit event signals the closing of the window */
100 if ( (event->type == SDL_QUIT) && boycott ) {
101 printf("Quit event filtered out -- try again.\n");
102 boycott = 0;
103 return(0);
104 }
105 if ( event->type == SDL_MOUSEMOTION ) {
106 printf("Mouse moved to (%d,%d)\n",
107 event->motion.x, event->motion.y);
108 return(0); /* Drop it, we've handled it */
109 }
110 return(1);
111 }
112
113 int main(int argc, char *argv[])
114 {
115 SDL_Event event;
116
117 /* Initialize the SDL library (starts the event loop) */
118 if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
119 fprintf(stderr,
120 "Couldn't initialize SDL: %s\n", SDL_GetError());
121 exit(1);
122 }
123
124 /* Clean up on exit, exit on window close and interrupt */
125 atexit(SDL_Quit);
126
127 /* Ignore key events */
128 SDL_EventState(SDL_KEYDOWN, SDL_IGNORE);
129 SDL_EventState(SDL_KEYUP, SDL_IGNORE);
130
131 /* Filter quit and mouse motion events */
132 SDL_SetEventFilter(FilterEvents);
133
134 /* The mouse isn't much use unless we have a display for reference */
135 if ( SDL_SetVideoMode(640, 480, 8, 0) == NULL ) {
136 fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
137 SDL_GetError());
138 exit(1);
139 }
140
141 /* Loop waiting for ESC+Mouse_Button */
142 while ( SDL_WaitEvent(&event) >= 0 ) {
143 switch (event.type) {
144 case SDL_ACTIVEEVENT: {
145 if ( event.active.state & SDL_APPACTIVE ) {
146 if ( event.active.gain ) {
147 printf("App activated\n");
148 } else {
149 printf("App iconified\n");
150 }
151 }
152 }
153 break;
154
155 case SDL_MOUSEBUTTONDOWN: {
156 Uint8 *keys;
157
158 keys = SDL_GetKeyState(NULL);
159 if ( keys[SDLK_ESCAPE] == SDL_PRESSED ) {
160 printf("Bye bye...\n");
161 exit(0);
162 }
163 printf("Mouse button pressed\n");
164 }
165 break;
166
167 case SDL_QUIT: {
168 printf("Quit requested, quitting.\n");
169 exit(0);
170 }
171 break;
172 }
173 }
174 /* This should never happen */
175 printf("SDL_WaitEvent error: %s\n", SDL_GetError());
176 exit(1);
177 }
178
179
180### 打开音频设备
181
182
183 SDL_AudioSpec wanted;
184 extern void fill_audio(void *udata, Uint8 *stream, int len);
185
186 /* Set the audio format */
187 wanted.freq = 22050;
188 wanted.format = AUDIO_S16;
189 wanted.channels = 2; /* 1 = mono, 2 = stereo */
190 wanted.samples = 1024; /* Good low-latency value for callback */
191 wanted.callback = fill_audio;
192 wanted.userdata = NULL;
193
194 /* Open the audio device, forcing the desired format */
195 if ( SDL_OpenAudio(&wanted, NULL) < 0 ) {
196 fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
197 return(-1);
198 }
199 return(0);
200
201
202### 播放音频
203
204
205 static Uint8 *audio_chunk;
206 static Uint32 audio_len;
207 static Uint8 *audio_pos;
208
209 /* The audio function callback takes the following parameters:
210 stream: A pointer to the audio buffer to be filled
211 len: The length (in bytes) of the audio buffer
212 */
213 void fill_audio(void *udata, Uint8 *stream, int len)
214 {
215 /* Only play if we have data left */
216 if ( audio_len == 0 )
217 return;
218
219 /* Mix as much data as possible */
220 len = ( len > audio_len ? audio_len : len );
221 SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME)
222 audio_pos += len;
223 audio_len -= len;
224 }
225
226 /* Load the audio data ... */
227
228 ;;;;;
229
230 audio_pos = audio_chunk;
231
232 /* Let the callback function play the audio chunk */
233 SDL_PauseAudio(0);
234
235 /* Do some processing */
236
237 ;;;;;
238
239 /* Wait for sound to complete */
240 while ( audio_len > 0 ) {
241 SDL_Delay(100); /* Sleep 1/10 second */
242 }
243 SDL_CloseAudio();
244
245
246### 列出所有CDROM
247
248
249 #include "SDL.h"
250
251 /* Initialize SDL first */
252 if ( SDL_Init(SDL_INIT_CDROM) < 0 ) {
253 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
254 exit(1);
255 }
256 atexit(SDL_Quit);
257
258 /* Find out how many CD-ROM drives are connected to the system */
259 printf("Drives available: %d\n", SDL_CDNumDrives());
260 for ( i=0; i<sdl_cdnumdrives(); "couldn't="" ###="" %d:="" %s\n",="" (="" (status)="" )="" *cdrom;="" *status_str;="" ++i="" ;="" \"%s\"\n",="" break;="" case="" cd-rom="" cd_error:="" cd_paused:="" cd_playing:="" cd_stopped:="" cd_trayempty:="" cdrom="NULL" cdstatus="" char="" default="" drive:="" exit(2);="" fprintf(stderr,="" i,="" if="" open="" printf("drive="" sdl_cd="" sdl_cdname(i));="" sdl_geterror());="" status="" status:="" status;="" status_str="error state" status_str);="" switch="" {="" }="" 打开缺省cdrom驱动器="">= CD_PLAYING ) {
261 int m, s, f;
262 FRAMES_TO_MSF(cdrom->cur_frame, &m, &s, &f);
263 printf("Currently playing track %d, %d:%2.2d\n",
264 cdrom->track[cdrom->cur_track].id, m, s);
265 }
266
267
268### 列出CD上所有音轨
269
270
271 SDL_CD *cdrom; /* Assuming this has already been set.. */
272 int i;
273 int m, s, f;
274
275 SDL_CDStatus(cdrom);
276 printf("Drive tracks: %d\n", cdrom->numtracks);
277 for ( i=0; i<cdrom->numtracks; ++i ) {
278 FRAMES_TO_MSF(cdrom->track[i].length, &m, &s, &f);
279 if ( f > 0 )
280 ++s;
281 printf("\tTrack (index %d) %d: %d:%2.2d\n", i,
282 cdrom->track[i].id, m, s);
283 }
284
285
286### 播放CD
287
288
289 SDL_CD *cdrom; /* Assuming this has already been set.. */
290
291 // Play entire CD:
292 if ( CD_INDRIVE(SDL_CDStatus(cdrom)) )
293 SDL_CDPlayTracks(cdrom, 0, 0, 0, 0);
294
295 // Play last track:
296 if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) {
297 SDL_CDPlayTracks(cdrom, cdrom->numtracks-1, 0, 0, 0);
298 }
299
300 // Play first and second track and 10 seconds of third track:
301 if ( CD_INDRIVE(SDL_CDStatus(cdrom)) )
302 SDL_CDPlayTracks(cdrom, 0, 0, 2, 10);
303
304
305### 基于时间的游戏主循环
306
307
308 #define TICK_INTERVAL 30
309
310 Uint32 TimeLeft(void)
311 {
312 static Uint32 next_time = 0;
313 Uint32 now;
314
315 now = SDL_GetTicks();
316 if ( next_time <= now ) {
317 next_time = now+TICK_INTERVAL;
318 return(0);
319 }
320 return(next_time-now);
321 }
322
323
324 /* main game loop
325
326 while ( game_running ) {
327 UpdateGameState();
328 SDL_Delay(TimeLeft());
329 }</cdrom-></sdl_cdnumdrives();></stdlib.h></stdio.h></stdlib.h></stdio.h>