X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fsdl.c;h=6e4b781b0df5a63cbdfa5ffb73ebaf448e5f1605;hb=228a5718ede5ee00512ed2e333b3cee47baa124c;hp=f3846da7491d6862b55416414cab925328575252;hpb=4cc378525f493292a995869afcf0c45f1f38f951;p=rocksndiamonds.git diff --git a/src/sdl.c b/src/sdl.c index f3846da7..6e4b781b 100644 --- a/src/sdl.c +++ b/src/sdl.c @@ -12,11 +12,108 @@ * sdl.c * ***********************************************************/ -#ifdef USE_SDL_LIBRARY +#ifdef TARGET_SDL #include "main.h" #include "misc.h" +inline void SDLInitBufferedDisplay(DrawBuffer *backbuffer, DrawWindow *window) +{ + /* initialize SDL video */ + if (SDL_Init(SDL_INIT_VIDEO) < 0) + Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError()); + + /* automatically cleanup SDL stuff after exit() */ + atexit(SDL_Quit); + + /* open SDL video output device (window or fullscreen mode) */ + if (!SDLSetVideoMode(backbuffer)) + Error(ERR_EXIT, "setting video mode failed"); + + /* set window and icon title */ + SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING); + + /* create additional buffer for double-buffering */ + pix[PIX_DB_BACK] = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH); + + /* SDL cannot directly draw to the visible video framebuffer like X11, + but always uses a backbuffer, which is then blitted to the visible + video framebuffer with 'SDL_UpdateRect' (or replaced with the current + visible video framebuffer with 'SDL_Flip', if the hardware supports + this). Therefore do not use an additional backbuffer for drawing, but + use a symbolic buffer (distinguishable from the SDL backbuffer) called + 'window', which indicates that the SDL backbuffer should be updated to + the visible video framebuffer when attempting to blit to it. + + For convenience, it seems to be a good idea to create this symbolic + buffer 'window' at the same size as the SDL backbuffer. Although it + should never be drawn to directly, it would do no harm nevertheless. */ + + *window = pix[PIX_DB_BACK]; /* 'window' is only symbolic buffer */ + pix[PIX_DB_BACK] = *backbuffer; /* 'backbuffer' is SDL screen buffer */ +} + +inline boolean SDLSetVideoMode(DrawBuffer *backbuffer) +{ + boolean success = TRUE; + + if (setup.fullscreen && !fullscreen_enabled && fullscreen_available) + { + /* switch display to fullscreen mode, if available */ + DrawWindow window_old = *backbuffer; + DrawWindow window_new; + + if ((window_new = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, WIN_SDL_DEPTH, + SDL_HWSURFACE|SDL_FULLSCREEN)) + == NULL) + { + /* switching display to fullscreen mode failed */ + Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError()); + + /* do not try it again */ + fullscreen_available = FALSE; + success = FALSE; + } + else + { + if (window_old) + SDL_FreeSurface(window_old); + *backbuffer = window_new; + + fullscreen_enabled = TRUE; + success = TRUE; + } + } + + if ((!setup.fullscreen && fullscreen_enabled) || !*backbuffer) + { + /* switch display to window mode */ + DrawWindow window_old = *backbuffer; + DrawWindow window_new; + + if ((window_new = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, WIN_SDL_DEPTH, + SDL_HWSURFACE)) + == NULL) + { + /* switching display to window mode failed -- should not happen */ + Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError()); + + success = FALSE; + } + else + { + if (window_old) + SDL_FreeSurface(window_old); + *backbuffer = window_new; + + fullscreen_enabled = FALSE; + success = TRUE; + } + } + + return success; +} + inline void SDLCopyArea(SDL_Surface *src_surface, SDL_Surface *dst_surface, int src_x, int src_y, int width, int height, @@ -86,4 +183,32 @@ inline void SDLDrawSimpleLine(SDL_Surface *surface, int from_x, int from_y, SDL_MapRGB(surface->format, color_r, color_g, color_b)); } -#endif /* USE_SDL_LIBRARY */ +inline boolean SDLOpenAudio(void) +{ + if (SDL_Init(SDL_INIT_AUDIO) < 0) + { + Error(ERR_WARN, "SDL_Init() failed: %s", SDL_GetError()); + return FALSE; + } + + if (Mix_OpenAudio(22050, AUDIO_S16, 2, 512) < 0) + { + Error(ERR_WARN, "Mix_OpenAudio() failed: %s", SDL_GetError()); + return FALSE; + } + + Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4); + Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4); + + return TRUE; +} + +inline void SDLCloseAudio(void) +{ + Mix_HaltMusic(); + Mix_HaltChannel(-1); + + Mix_CloseAudio(); +} + +#endif /* TARGET_SDL */