SDL Guide 中文译版(四)

类别:Delphi 点击:0 评论:0 推荐:
  第四章 样例

注:重复的例子没有列出

最快的图像平面块传送

将图像画到屏幕上有三种方式:1.创建一个图像平面并用SDL_BlitSurface传送到屏幕;2.在系统内存创建视频平面并调用SDL_UpdateRect;3.在显存创建视频平面并调用SDL_LockSurface。最好的方法是混合方式:

#include <stdio.h> #include <stdlib.h> #include "SDL.h" #include "SDL_timer.h" void ComplainAndExit(void) { fprintf(stderr, "Problem: %s\n", 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_VIDEO) < 0 ) { ComplainAndExit(); } atexit(SDL_Quit); /* Load a BMP image into a surface */ imagebmp = SDL_LoadBMP("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 <stdio.h> #include <stdlib.h> #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 loop) */ if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't initialize SDL: %s\n", 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: %s\n", 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 activated\n"); } else { printf("App iconified\n"); } } } 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 pressed\n"); } break; case SDL_QUIT: { printf("Quit requested, quitting.\n"); exit(0); } break; } } /* This should never happen */ printf("SDL_WaitEvent error: %s\n", 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: %s\n", 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_pos += 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: %s\n",SDL_GetError()); exit(1); } atexit(SDL_Quit); /* Find out how many CD-ROM drives are connected to the system */ printf("Drives available: %d\n", SDL_CDNumDrives()); for ( i=0; i<SDL_CDNumDrives(); ++i ) { printf("Drive %d: \"%s\"\n", i, SDL_CDName(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: %s\n", 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: %s\n", status_str); if ( status >= CD_PLAYING ) { int m, s, f; FRAMES_TO_MSF(cdrom->cur_frame, &m, &s, &f); printf("Currently playing track %d, %d:%2.2d\n", 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: %d\n", cdrom->numtracks); for ( i=0; i<cdrom->numtracks; ++i ) { FRAMES_TO_MSF(cdrom->track[i].length, &m, &s, &f); if ( f > 0 ) ++s; printf("\tTrack (index %d) %d: %d:%2.2d\n", 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()); }

本文地址:http://com.8s8s.com/it/it5460.htm