SDL Guide 中文譯版(四) (轉)

worldblog發表於2007-12-15
SDL Guide 中文譯版(四) (轉)[@more@] 

第四章 樣例

注:重複的例子沒有列出

最快的影像平面塊傳送

將影像畫到螢幕上有三種方式:1.建立一個影像平面並用SDL_BlitSurface傳送到螢幕;2.在建立影片平面並SDL_UpdateRect;3.在視訊記憶體建立影片平面並呼叫SDL_LockSurface。最好的方法是混合方式:

#include #include #include "SDL.h" #include "SDL_timer.h" void ComplainAndExit(void) { fprintf(stderr, "Problem: %sn", SDL_GetError()); exit(1); } int main(int argc, char *argv[]) { SDL_PixelFormat fmt; SDL_Surface *screen, *locked; SDL_Surface *imagebmp, *image; SDL_Rect dstrect; int i; Uint8 *buffer; /* Initialize SDL */ if ( SDL_Init(SDL_INIT_VO) < 0 ) { ComplainAndExit(); } atexit(SDL_Quit); /* Load a BMP image into a surface */ imagebmp = SDL_LoaMP("image.bmp"); if ( imagebmp == NULL ) { ComplainAndExit(); } /* Set the video mode (640x480 at native depth) */ screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE|SDL_FULLSCREEN); if ( screen == NULL ) { ComplainAndExit(); } /* Set the video colormap */ if ( imagebmp->format->palette != NULL ) { SDL_SetColors(screen, imagebmp->format->palette->colors, 0, imagebmp->format->palette->ncolors); } /* Convert the image to the video format (maps colors) */ image = SDL_DisplayFormat(imagebmp); SDL_FreeSurface(imagebmp); if ( image == NULL ) { ComplainAndExit(); } /* Draw bands of color on the raw surface */ if ( SDL_MUSTLOCK(screen) ) { if ( SDL_LockSurface(screen) < 0 ) ComplainAndExit(); } buffer=(Uint8 *)screen->pixels; for ( i=0; ih; ++i ) { memset(buffer,(i*255)/screen->h, screen->w*screen->format->BytesPerPixel); buffer += screen->pitch; } if ( SDL_MUSTLOCK(screen) ) { SDL_UnlockSurface(screen); } /* Blit the image to the center of the screen */ dstrect.x = (screen->w-image->w)/2; dstrect.y = (screen->h-image->h)/2; dstrect.w = image->w; dstrect.h = image->h; if ( SDL_BlitSurface(image, NULL, screen, &dstrect) < 0 ) { SDL_FreeSurface(image); ComplainAndExit(); } SDL_FreeSurface(image); /* Update the screen */ SDL_UpdateRects(screen, 1, &dstrect); SDL_Delay(5000); /* Wait 5 seconds */ exit(0); }


過濾和處理事件

#include #include #include "SDL.h" /* This function may run in a separate event thread */ int FilterEvents(const SDL_Event *event) { static int boycott = 1; /* This quit event signals the closing of the window */ if ( (event->type == SDL_QUIT) && boycott ) { printf("Quit event filtered out -- try again.n"); boycott = 0; return(0); } if ( event->type == SDL_MOUSEMOTION ) { printf("Mouse moved to (%d,%d)n", event->motion.x, event->motion.y); return(0); /* Drop it, we've handled it */ } return(1); } int main(int argc, char *argv[]) { SDL_Event event; /* Initialize the SDL library (starts the event l) */ if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't initialize SDL: %sn", SDL_GetError()); exit(1); } /* Clean up on exit, exit on window close and interrupt */ atexit(SDL_Quit); /* Ignore key events */ SDL_EventState(SDL_KEYDOWN, SDL_IGNORE); SDL_EventState(SDL_KEYUP, SDL_IGNORE); /* Filter quit and mouse motion events */ SDL_SetEventFilter(FilterEvents); /* The mouse isn't much use unless we have a display for reference */ if ( SDL_SetVideoMode(640, 480, 8, 0) == NULL ) { fprintf(stderr, "Couldn't set 640x480x8 video mode: %sn", SDL_GetError()); exit(1); } /* Loop waiting for ESC+Mouse_Button */ while ( SDL_WaitEvent(&event) >= 0 ) { switch (event.type) { case SDL_ACTIVEEVENT: { if ( event.active.state & SDL_APPACTIVE ) { if ( event.active.gain ) { printf("App activatedn"); } else { printf("App iconifiedn"); } } } break; case SDL_MOUSEBUTTONDOWN: { Uint8 *keys; keys = SDL_GetKeyState(NULL); if ( keys[SDLK_ESCAPE] == SDL_PRESSED ) { printf("Bye bye...n"); exit(0); } printf("Mouse button pressedn"); } break; case SDL_QUIT: { printf("Quit requested, quitting.n"); exit(0); } break; } } /* This should never happen */ printf("SDL_WaitEvent error: %sn", SDL_GetError()); exit(1); }


開啟裝置

SDL_AudioSpec wanted; extern void fill_audio(void *udata, Uint8 *stream, int len); /* Set the audio format */ wanted.freq = 22050; wanted.format = AUDIO_S16; wanted.channels = 2; /* 1 = mono, 2 = stereo */ wanted.samples = 1024; /* Good low-latency value for callback */ wanted.callback = fill_audio; wanted.userdata = NULL; /* Open the audio device, forcing the desired format */ if ( SDL_OpenAudio(&wanted, NULL) < 0 ) { fprintf(stderr, "Couldn't open audio: %sn", SDL_GetError()); return(-1); } return(0);


音訊

static Uint8 *audio_chunk; static Uint32 audio_len; static Uint8 *audio_pos; /* The audio function callback takes the following parameters: stream: A pointer to the audio buffer to be filled len: The length (in bytes) of the audio buffer */ void fill_audio(void *udata, Uint8 *stream, int len) { /* Only play if we have data left */ if ( audio_len == 0 ) return; /* Mix as much data as possible */ len = ( len > audio_len ? audio_len : len ); SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME) audio_p+= len; audio_len -= len; } /* Load the audio data ... */ ;;;;; audio_pos = audio_chunk; /* Let the callback function play the audio chunk */ SDL_PauseAudio(0); /* Do some processing */ ;;;;; /* Wait for sound to complete */ while ( audio_len > 0 ) { SDL_Delay(100); /* Sleep 1/10 second */ } SDL_CloseAudio();


列出所有CDROM

#include "SDL.h" /* Initialize SDL first */ if ( SDL_Init(SDL_INIT_CDROM) < 0 ) { fprintf(stderr, "Couldn't initialize SDL: %sn",SDL_GetError()); exit(1); } atexit(SDL_Quit); /* Find out how many CD-ROM drives are connected to the system */ printf("Drives available: %dn", SDL_CDNumDrives()); for ( i=0; i

開啟預設CDROM器

SDL_CD *cdrom; CDstatus status; char *status_str; cdrom = SDL_CDOpen(0); if ( cdrom == NULL ) { fprintf(stderr, "Couldn't open default CD-ROM drive: %sn", SDL_GetError()); exit(2); } status = SDL_CDStatus(cdrom); switch (status) { case CD_TRAYEMPTY: status_str = "tray empty"; break; case CD_STOPPED: status_str = "stopped"; break; case CD_PLAYING: status_str = "playing"; break; case CD_PAUSED: status_str = "paused"; break; case CD_ERROR: status_str = "error state"; break; } printf("Drive status: %sn", status_str); if ( status >= CD_PLAYING ) { int m, s, f; FRAMES_TO_M(cdrom->cur_frame, &m, &s, &f); printf("Currently playing track %d, %d:%2.2dn", cdrom->track[cdrom->cur_track].id, m, s); }


列出CD上所有音軌

SDL_CD *cdrom; /* Assuming this has already been set.. */ int i; int m, s, f; SDL_CDStatus(cdrom); printf("Drive tracks: %dn", cdrom->numtracks); for ( i=0; inumtracks; ++i ) { FRAMES_TO_MSF(cdrom->track[i].length, &m, &s, &f); if ( f > 0 ) ++s; printf("tTrack (index %d) %d: %d:%2.2dn", i, cdrom->track[i].id, m, s); }


播放CD

SDL_CD *cdrom; /* Assuming this has already been set.. */ // Play entire CD: if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) SDL_CDPlayTracks(cdrom, 0, 0, 0, 0); // Play last track: if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) { SDL_CDPlayTracks(cdrom, cdrom->numtracks-1, 0, 0, 0); } // Play first and second track and 10 seconds of third track: if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) SDL_CDPlayTracks(cdrom, 0, 0, 2, 10);


基於時間的遊戲主迴圈

#define TICK_INTERVAL 30 Uint32 TimeLeft(void) { static Uint32 next_time = 0; Uint32 now; now = SDL_GetTicks(); if ( next_time <= now ) { next_time = now+TICK_INTERVAL; return(0); } return(next_time-now); } /* main game loop while ( game_running ) { UpdateGameState(); SDL_Delay(TimeLeft()); }


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993821/,如需轉載,請註明出處,否則將追究法律責任。

相關文章