1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1994-2000 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
18 #if defined(TARGET_SDL)
20 inline void SDLInitVideoDisplay(void)
22 /* initialize SDL video */
23 if (SDL_Init(SDL_INIT_VIDEO) < 0)
24 Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
26 /* set default SDL depth */
27 video.default_depth = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
29 /* set exit function to automatically cleanup SDL stuff after exit() */
33 inline void SDLInitVideoBuffer(DrawBuffer *backbuffer, DrawWindow *window,
36 /* open SDL video output device (window or fullscreen mode) */
37 if (!SDLSetVideoMode(backbuffer, fullscreen))
38 Error(ERR_EXIT, "setting video mode failed");
40 /* set window and icon title */
41 SDL_WM_SetCaption(program.window_title, program.window_title);
43 /* SDL cannot directly draw to the visible video framebuffer like X11,
44 but always uses a backbuffer, which is then blitted to the visible
45 video framebuffer with 'SDL_UpdateRect' (or replaced with the current
46 visible video framebuffer with 'SDL_Flip', if the hardware supports
47 this). Therefore do not use an additional backbuffer for drawing, but
48 use a symbolic buffer (distinguishable from the SDL backbuffer) called
49 'window', which indicates that the SDL backbuffer should be updated to
50 the visible video framebuffer when attempting to blit to it.
52 For convenience, it seems to be a good idea to create this symbolic
53 buffer 'window' at the same size as the SDL backbuffer. Although it
54 should never be drawn to directly, it would do no harm nevertheless. */
56 /* create additional (symbolic) buffer for double-buffering */
57 *window = CreateBitmap(video.width, video.height, video.depth);
60 inline boolean SDLSetVideoMode(DrawBuffer *backbuffer, boolean fullscreen)
62 boolean success = TRUE;
63 int surface_flags = SDL_HWSURFACE | (fullscreen ? SDL_FULLSCREEN : 0);
65 if (fullscreen && !video.fullscreen_enabled && video.fullscreen_available)
67 /* switch display to fullscreen mode, if available */
68 DrawWindow window_old = *backbuffer;
69 DrawWindow window_new = CreateBitmapStruct();
71 if ((window_new->surface = SDL_SetVideoMode(video.width, video.height,
72 video.depth, surface_flags))
75 /* switching display to fullscreen mode failed */
76 Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError());
78 /* do not try it again */
79 video.fullscreen_available = FALSE;
85 FreeBitmap(window_old);
86 *backbuffer = window_new;
88 video.fullscreen_enabled = TRUE;
93 if ((!fullscreen && video.fullscreen_enabled) || !*backbuffer)
95 /* switch display to window mode */
96 DrawWindow window_old = *backbuffer;
97 DrawWindow window_new = CreateBitmapStruct();
99 if ((window_new->surface = SDL_SetVideoMode(video.width, video.height,
100 video.depth, surface_flags))
103 /* switching display to window mode failed -- should not happen */
104 Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError());
111 FreeBitmap(window_old);
112 *backbuffer = window_new;
114 video.fullscreen_enabled = FALSE;
122 inline void SDLCopyArea(Bitmap src_bitmap, Bitmap dst_bitmap,
123 int src_x, int src_y,
124 int width, int height,
125 int dst_x, int dst_y, int copy_mode)
127 Bitmap real_dst_bitmap = (dst_bitmap == window ? backbuffer : dst_bitmap);
128 SDL_Rect src_rect, dst_rect;
140 if (src_bitmap != backbuffer || dst_bitmap != window)
141 SDL_BlitSurface((copy_mode == SDLCOPYAREA_MASKED ?
142 src_bitmap->surface_masked : src_bitmap->surface),
143 &src_rect, real_dst_bitmap->surface, &dst_rect);
145 if (dst_bitmap == window)
146 SDL_UpdateRect(backbuffer->surface, dst_x, dst_y, width, height);
149 inline void SDLFillRectangle(Bitmap dst_bitmap, int x, int y,
150 int width, int height, unsigned int color)
152 Bitmap real_dst_bitmap = (dst_bitmap == window ? backbuffer : dst_bitmap);
154 unsigned int color_r = (color >> 16) && 0xff;
155 unsigned int color_g = (color >> 8) && 0xff;
156 unsigned int color_b = (color >> 0) && 0xff;
163 SDL_FillRect(real_dst_bitmap->surface, &rect,
164 SDL_MapRGB(real_dst_bitmap->surface->format,
165 color_r, color_g, color_b));
167 if (dst_bitmap == window)
168 SDL_UpdateRect(backbuffer->surface, x, y, width, height);
171 inline void SDLDrawSimpleLine(SDL_Surface *surface, int from_x, int from_y,
172 int to_x, int to_y, unsigned int color)
175 unsigned int color_r = (color >> 16) & 0xff;
176 unsigned int color_g = (color >> 8) & 0xff;
177 unsigned int color_b = (color >> 0) & 0xff;
180 swap_numbers(&from_x, &to_x);
183 swap_numbers(&from_y, &to_y);
187 rect.w = (to_x - from_x + 1);
188 rect.h = (to_y - from_y + 1);
190 SDL_FillRect(surface, &rect,
191 SDL_MapRGB(surface->format, color_r, color_g, color_b));
194 inline boolean SDLOpenAudio(void)
196 if (SDL_Init(SDL_INIT_AUDIO) < 0)
198 Error(ERR_WARN, "SDL_Init() failed: %s", SDL_GetError());
202 if (Mix_OpenAudio(22050, AUDIO_S16, 2, 512) < 0)
204 Error(ERR_WARN, "Mix_OpenAudio() failed: %s", SDL_GetError());
208 Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4);
209 Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4);
214 inline void SDLCloseAudio(void)
222 #endif /* TARGET_SDL */