1 /***********************************************************
2 * Artsoft Retro-Game Library *
3 *----------------------------------------------------------*
4 * (c) 1994-2002 Artsoft Entertainment *
6 * Detmolder Strasse 189 *
9 * e-mail: info@artsoft.org *
10 *----------------------------------------------------------*
12 ***********************************************************/
20 #if defined(TARGET_SDL)
22 /* ========================================================================= */
24 /* ========================================================================= */
26 /* functions from SGE library */
27 inline void sge_Line(SDL_Surface *, Sint16, Sint16, Sint16, Sint16, Uint32);
30 #define FULLSCREEN_BUG
33 /* stuff needed to work around SDL/Windows fullscreen drawing bug */
34 static int fullscreen_width;
35 static int fullscreen_height;
36 static int fullscreen_xoffset;
37 static int fullscreen_yoffset;
38 static int video_xoffset;
39 static int video_yoffset;
41 inline void SDLInitVideoDisplay(void)
43 /* initialize SDL video */
44 if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
45 Error(ERR_EXIT, "SDL_InitSubSystem() failed: %s", SDL_GetError());
47 /* set default SDL depth */
48 video.default_depth = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
51 inline void SDLInitVideoBuffer(DrawBuffer **backbuffer, DrawWindow **window,
56 static int screen_xy[][2] =
65 /* default: normal game window size */
66 fullscreen_width = video.width;
67 fullscreen_height = video.height;
68 fullscreen_xoffset = 0;
69 fullscreen_yoffset = 0;
72 for (i=0; screen_xy[i][0] != -1; i++)
74 if (video.width <= screen_xy[i][0] && video.height <= screen_xy[i][1])
76 fullscreen_width = screen_xy[i][0];
77 fullscreen_height = screen_xy[i][1];
82 fullscreen_xoffset = (fullscreen_width - video.width) / 2;
83 fullscreen_yoffset = (fullscreen_height - video.height) / 2;
86 /* open SDL video output device (window or fullscreen mode) */
87 if (!SDLSetVideoMode(backbuffer, fullscreen))
88 Error(ERR_EXIT, "setting video mode failed");
90 /* set window and icon title */
91 SDL_WM_SetCaption(program.window_title, program.window_title);
93 /* SDL cannot directly draw to the visible video framebuffer like X11,
94 but always uses a backbuffer, which is then blitted to the visible
95 video framebuffer with 'SDL_UpdateRect' (or replaced with the current
96 visible video framebuffer with 'SDL_Flip', if the hardware supports
97 this). Therefore do not use an additional backbuffer for drawing, but
98 use a symbolic buffer (distinguishable from the SDL backbuffer) called
99 'window', which indicates that the SDL backbuffer should be updated to
100 the visible video framebuffer when attempting to blit to it.
102 For convenience, it seems to be a good idea to create this symbolic
103 buffer 'window' at the same size as the SDL backbuffer. Although it
104 should never be drawn to directly, it would do no harm nevertheless. */
106 /* create additional (symbolic) buffer for double-buffering */
107 *window = CreateBitmap(video.width, video.height, video.depth);
110 inline boolean SDLSetVideoMode(DrawBuffer **backbuffer, boolean fullscreen)
112 boolean success = TRUE;
113 int surface_flags_fullscreen = SURFACE_FLAGS | SDL_FULLSCREEN;
114 int surface_flags_window = SURFACE_FLAGS;
115 SDL_Surface *new_surface = NULL;
117 if (*backbuffer == NULL)
118 *backbuffer = CreateBitmapStruct();
120 if (fullscreen && !video.fullscreen_enabled && video.fullscreen_available)
122 video_xoffset = fullscreen_xoffset;
123 video_yoffset = fullscreen_yoffset;
125 /* switch display to fullscreen mode, if available */
126 if ((new_surface = SDL_SetVideoMode(fullscreen_width, fullscreen_height,
127 video.depth, surface_flags_fullscreen))
130 /* switching display to fullscreen mode failed */
131 Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError());
133 /* do not try it again */
134 video.fullscreen_available = FALSE;
139 (*backbuffer)->surface = new_surface;
141 video.fullscreen_enabled = TRUE;
146 if ((!fullscreen && video.fullscreen_enabled) || new_surface == NULL)
151 /* switch display to window mode */
152 if ((new_surface = SDL_SetVideoMode(video.width, video.height,
153 video.depth, surface_flags_window))
156 /* switching display to window mode failed -- should not happen */
157 Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError());
163 (*backbuffer)->surface = new_surface;
165 video.fullscreen_enabled = FALSE;
173 inline void SDLCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap,
174 int src_x, int src_y,
175 int width, int height,
176 int dst_x, int dst_y, int copy_mode)
178 Bitmap *real_dst_bitmap = (dst_bitmap == window ? backbuffer : dst_bitmap);
179 SDL_Rect src_rect, dst_rect;
181 #ifdef FULLSCREEN_BUG
182 if (src_bitmap == backbuffer)
184 src_x += video_xoffset;
185 src_y += video_yoffset;
194 #ifdef FULLSCREEN_BUG
195 if (dst_bitmap == backbuffer || dst_bitmap == window)
197 dst_x += video_xoffset;
198 dst_y += video_yoffset;
207 if (src_bitmap != backbuffer || dst_bitmap != window)
208 SDL_BlitSurface((copy_mode == SDLCOPYAREA_MASKED ?
209 src_bitmap->surface_masked : src_bitmap->surface),
210 &src_rect, real_dst_bitmap->surface, &dst_rect);
212 if (dst_bitmap == window)
213 SDL_UpdateRect(backbuffer->surface, dst_x, dst_y, width, height);
216 inline void SDLFillRectangle(Bitmap *dst_bitmap, int x, int y,
217 int width, int height, unsigned int color)
219 Bitmap *real_dst_bitmap = (dst_bitmap == window ? backbuffer : dst_bitmap);
221 unsigned int color_r = (color >> 16) && 0xff;
222 unsigned int color_g = (color >> 8) && 0xff;
223 unsigned int color_b = (color >> 0) && 0xff;
225 #ifdef FULLSCREEN_BUG
226 if (dst_bitmap == backbuffer || dst_bitmap == window)
238 SDL_FillRect(real_dst_bitmap->surface, &rect,
239 SDL_MapRGB(real_dst_bitmap->surface->format,
240 color_r, color_g, color_b));
242 if (dst_bitmap == window)
243 SDL_UpdateRect(backbuffer->surface, x, y, width, height);
246 inline void SDLDrawSimpleLine(Bitmap *dst_bitmap, int from_x, int from_y,
247 int to_x, int to_y, unsigned int color)
249 SDL_Surface *surface = dst_bitmap->surface;
251 unsigned int color_r = (color >> 16) & 0xff;
252 unsigned int color_g = (color >> 8) & 0xff;
253 unsigned int color_b = (color >> 0) & 0xff;
256 swap_numbers(&from_x, &to_x);
259 swap_numbers(&from_y, &to_y);
263 rect.w = (to_x - from_x + 1);
264 rect.h = (to_y - from_y + 1);
266 #ifdef FULLSCREEN_BUG
267 if (dst_bitmap == backbuffer || dst_bitmap == window)
269 rect.x += video_xoffset;
270 rect.y += video_yoffset;
274 SDL_FillRect(surface, &rect,
275 SDL_MapRGB(surface->format, color_r, color_g, color_b));
278 inline void SDLDrawLine(Bitmap *dst_bitmap, int from_x, int from_y,
279 int to_x, int to_y, Uint32 color)
281 #ifdef FULLSCREEN_BUG
282 if (dst_bitmap == backbuffer || dst_bitmap == window)
284 from_x += video_xoffset;
285 from_y += video_yoffset;
286 to_x += video_xoffset;
287 to_y += video_yoffset;
291 sge_Line(dst_bitmap->surface, from_x, from_y, to_x, to_y, color);
295 inline void SDLDrawLines(SDL_Surface *surface, struct XY *points,
296 int num_points, Uint32 color)
301 for (i=0; i<num_points - 1; i++)
303 for (x=0; x<line_width; x++)
305 for (y=0; y<line_width; y++)
307 int dx = x - line_width / 2;
308 int dy = y - line_width / 2;
310 if ((x == 0 && y == 0) ||
311 (x == 0 && y == line_width - 1) ||
312 (x == line_width - 1 && y == 0) ||
313 (x == line_width - 1 && y == line_width - 1))
316 sge_Line(surface, points[i].x + dx, points[i].y + dy,
317 points[i+1].x + dx, points[i+1].y + dy, color);
324 inline Pixel SDLGetPixel(Bitmap *dst_bitmap, int x, int y)
326 SDL_Surface *surface = dst_bitmap->surface;
328 #ifdef FULLSCREEN_BUG
329 if (dst_bitmap == backbuffer || dst_bitmap == window)
336 switch (surface->format->BytesPerPixel)
338 case 1: /* assuming 8-bpp */
340 return *((Uint8 *)surface->pixels + y * surface->pitch + x);
344 case 2: /* probably 15-bpp or 16-bpp */
346 return *((Uint16 *)surface->pixels + y * surface->pitch / 2 + x);
350 case 3: /* slow 24-bpp mode; usually not used */
352 /* does this work? */
353 Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x * 3;
357 shift = surface->format->Rshift;
358 color |= *(pix + shift / 8) >> shift;
359 shift = surface->format->Gshift;
360 color |= *(pix + shift / 8) >> shift;
361 shift = surface->format->Bshift;
362 color |= *(pix + shift / 8) >> shift;
368 case 4: /* probably 32-bpp */
370 return *((Uint32 *)surface->pixels + y * surface->pitch / 4 + x);
379 /* ========================================================================= */
380 /* The following functions have been taken from the SGE library */
381 /* (SDL Graphics Extension Library) by Anders Lindström */
382 /* http://www.etek.chalmers.se/~e8cal1/sge/index.html */
383 /* ========================================================================= */
385 void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
387 if (x >= 0 && x <= surface->w - 1 && y >= 0 && y <= surface->h - 1)
389 switch (surface->format->BytesPerPixel)
394 *((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
400 /* Probably 15-bpp or 16-bpp */
401 *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
407 /* Slow 24-bpp mode, usually not used */
411 /* Gack - slow, but endian correct */
412 pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
413 shift = surface->format->Rshift;
414 *(pix+shift/8) = color>>shift;
415 shift = surface->format->Gshift;
416 *(pix+shift/8) = color>>shift;
417 shift = surface->format->Bshift;
418 *(pix+shift/8) = color>>shift;
424 /* Probably 32-bpp */
425 *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
432 void _PutPixelRGB(SDL_Surface *surface, Sint16 x, Sint16 y,
433 Uint8 R, Uint8 G, Uint8 B)
435 _PutPixel(surface, x, y, SDL_MapRGB(surface->format, R, G, B));
438 void _PutPixel8(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
440 *((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
443 void _PutPixel16(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
445 *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
448 void _PutPixel24(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
453 /* Gack - slow, but endian correct */
454 pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
455 shift = surface->format->Rshift;
456 *(pix+shift/8) = color>>shift;
457 shift = surface->format->Gshift;
458 *(pix+shift/8) = color>>shift;
459 shift = surface->format->Bshift;
460 *(pix+shift/8) = color>>shift;
463 void _PutPixel32(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
465 *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
468 void _PutPixelX(SDL_Surface *dest,Sint16 x,Sint16 y,Uint32 color)
470 switch (dest->format->BytesPerPixel)
473 *((Uint8 *)dest->pixels + y*dest->pitch + x) = color;
477 *((Uint16 *)dest->pixels + y*dest->pitch/2 + x) = color;
481 _PutPixel24(dest,x,y,color);
485 *((Uint32 *)dest->pixels + y*dest->pitch/4 + x) = color;
490 void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
492 if (SDL_MUSTLOCK(surface))
494 if (SDL_LockSurface(surface) < 0)
500 _PutPixel(surface, x, y, color);
502 if (SDL_MUSTLOCK(surface))
504 SDL_UnlockSurface(surface);
508 void sge_PutPixelRGB(SDL_Surface *surface, Sint16 x, Sint16 y,
509 Uint8 R, Uint8 G, Uint8 B)
511 sge_PutPixel(surface, x, y, SDL_MapRGB(surface->format, R, G, B));
514 Sint32 sge_CalcYPitch(SDL_Surface *dest, Sint16 y)
516 if (y >= 0 && y <= dest->h - 1)
518 switch (dest->format->BytesPerPixel)
521 return y*dest->pitch;
525 return y*dest->pitch/2;
529 return y*dest->pitch;
533 return y*dest->pitch/4;
541 void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch, Uint32 color)
543 if (x >= 0 && x <= surface->w - 1 && ypitch >= 0)
545 switch (surface->format->BytesPerPixel)
550 *((Uint8 *)surface->pixels + ypitch + x) = color;
556 /* Probably 15-bpp or 16-bpp */
557 *((Uint16 *)surface->pixels + ypitch + x) = color;
563 /* Slow 24-bpp mode, usually not used */
567 /* Gack - slow, but endian correct */
568 pix = (Uint8 *)surface->pixels + ypitch + x*3;
569 shift = surface->format->Rshift;
570 *(pix+shift/8) = color>>shift;
571 shift = surface->format->Gshift;
572 *(pix+shift/8) = color>>shift;
573 shift = surface->format->Bshift;
574 *(pix+shift/8) = color>>shift;
580 /* Probably 32-bpp */
581 *((Uint32 *)surface->pixels + ypitch + x) = color;
588 void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
593 if (SDL_MUSTLOCK(Surface))
595 if (SDL_LockSurface(Surface) < 0)
608 /* Do the clipping */
609 if (y < 0 || y > Surface->h - 1 || x1 > Surface->w - 1 || x2 < 0)
613 if (x2 > Surface->w - 1)
621 SDL_FillRect(Surface, &l, Color);
623 if (SDL_MUSTLOCK(Surface))
625 SDL_UnlockSurface(Surface);
629 void sge_HLineRGB(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
630 Uint8 R, Uint8 G, Uint8 B)
632 sge_HLine(Surface, x1, x2, y, SDL_MapRGB(Surface->format, R, G, B));
635 void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color)
646 /* Do the clipping */
647 if (y < 0 || y > Surface->h - 1 || x1 > Surface->w - 1 || x2 < 0)
651 if (x2 > Surface->w - 1)
659 SDL_FillRect(Surface, &l, Color);
662 void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
667 if (SDL_MUSTLOCK(Surface))
669 if (SDL_LockSurface(Surface) < 0)
682 /* Do the clipping */
683 if (x < 0 || x > Surface->w - 1 || y1 > Surface->h - 1 || y2 < 0)
687 if (y2 > Surface->h - 1)
695 SDL_FillRect(Surface, &l, Color);
697 if (SDL_MUSTLOCK(Surface))
699 SDL_UnlockSurface(Surface);
703 void sge_VLineRGB(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
704 Uint8 R, Uint8 G, Uint8 B)
706 sge_VLine(Surface, x, y1, y2, SDL_MapRGB(Surface->format, R, G, B));
709 void _VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color)
720 /* Do the clipping */
721 if (x < 0 || x > Surface->w - 1 || y1 > Surface->h - 1 || y2 < 0)
725 if (y2 > Surface->h - 1)
733 SDL_FillRect(Surface, &l, Color);
736 void sge_DoLine(SDL_Surface *Surface, Sint16 x1, Sint16 y1,
737 Sint16 x2, Sint16 y2, Uint32 Color,
738 void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y,
741 Sint16 dx, dy, sdx, sdy, x, y, px, py;
746 sdx = (dx < 0) ? -1 : 1;
747 sdy = (dy < 0) ? -1 : 1;
759 for (x = 0; x < dx; x++)
761 Callback(Surface, px, py, Color);
775 for (y = 0; y < dy; y++)
777 Callback(Surface, px, py, Color);
791 void sge_DoLineRGB(SDL_Surface *Surface, Sint16 X1, Sint16 Y1,
792 Sint16 X2, Sint16 Y2, Uint8 R, Uint8 G, Uint8 B,
793 void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y,
796 sge_DoLine(Surface, X1, Y1, X2, Y2,
797 SDL_MapRGB(Surface->format, R, G, B), Callback);
800 void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,
803 if (SDL_MUSTLOCK(Surface))
805 if (SDL_LockSurface(Surface) < 0)
810 sge_DoLine(Surface, x1, y1, x2, y2, Color, _PutPixel);
812 /* unlock the display */
813 if (SDL_MUSTLOCK(Surface))
815 SDL_UnlockSurface(Surface);
819 void sge_LineRGB(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2,
820 Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
822 sge_Line(Surface, x1, y1, x2, y2, SDL_MapRGB(Surface->format, R, G, B));
825 Bitmap *SDLLoadImage(char *filename)
827 Bitmap *new_bitmap = CreateBitmapStruct();
828 SDL_Surface *sdl_image_tmp;
830 /* load image to temporary surface */
831 if ((sdl_image_tmp = IMG_Load(filename)) == NULL)
833 SetError("IMG_Load(): %s", SDL_GetError());
837 /* create native non-transparent surface for current image */
838 if ((new_bitmap->surface = SDL_DisplayFormat(sdl_image_tmp)) == NULL)
840 SetError("SDL_DisplayFormat(): %s", SDL_GetError());
844 /* create native transparent surface for current image */
845 SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY,
846 SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
847 if ((new_bitmap->surface_masked = SDL_DisplayFormat(sdl_image_tmp)) == NULL)
849 SetError("SDL_DisplayFormat(): %s", SDL_GetError());
853 /* free temporary surface */
854 SDL_FreeSurface(sdl_image_tmp);
856 new_bitmap->width = new_bitmap->surface->w;
857 new_bitmap->height = new_bitmap->surface->h;
863 /* ========================================================================= */
864 /* audio functions */
865 /* ========================================================================= */
867 inline void SDLOpenAudio(void)
869 if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
871 Error(ERR_WARN, "SDL_InitSubSystem() failed: %s", SDL_GetError());
875 if (Mix_OpenAudio(DEFAULT_AUDIO_SAMPLE_RATE, MIX_DEFAULT_FORMAT,
876 AUDIO_NUM_CHANNELS_STEREO,
877 DEFAULT_AUDIO_FRAGMENT_SIZE) < 0)
879 Error(ERR_WARN, "Mix_OpenAudio() failed: %s", SDL_GetError());
883 audio.sound_available = TRUE;
884 audio.music_available = TRUE;
885 audio.loops_available = TRUE;
886 audio.sound_enabled = TRUE;
888 /* set number of available mixer channels */
889 audio.num_channels = Mix_AllocateChannels(NUM_MIXER_CHANNELS);
890 audio.music_channel = MUSIC_CHANNEL;
891 audio.first_sound_channel = FIRST_SOUND_CHANNEL;
893 Mixer_InitChannels();
896 inline void SDLCloseAudio(void)
902 SDL_QuitSubSystem(SDL_INIT_AUDIO);
906 /* ========================================================================= */
907 /* event functions */
908 /* ========================================================================= */
910 inline void SDLNextEvent(Event *event)
912 SDL_WaitEvent(event);
914 #ifdef FULLSCREEN_BUG
915 if (event->type == EVENT_BUTTONPRESS ||
916 event->type == EVENT_BUTTONRELEASE)
918 if (((ButtonEvent *)event)->x > video_xoffset)
919 ((ButtonEvent *)event)->x -= video_xoffset;
921 ((ButtonEvent *)event)->x = 0;
922 if (((ButtonEvent *)event)->y > video_yoffset)
923 ((ButtonEvent *)event)->y -= video_yoffset;
925 ((ButtonEvent *)event)->y = 0;
927 else if (event->type == EVENT_MOTIONNOTIFY)
929 if (((ButtonEvent *)event)->x > video_xoffset)
930 ((ButtonEvent *)event)->x -= video_xoffset;
932 ((ButtonEvent *)event)->x = 0;
933 if (((ButtonEvent *)event)->y > video_yoffset)
934 ((ButtonEvent *)event)->y -= video_yoffset;
936 ((ButtonEvent *)event)->y = 0;
942 /* ========================================================================= */
943 /* joystick functions */
944 /* ========================================================================= */
946 static SDL_Joystick *sdl_joystick[MAX_PLAYERS] = { NULL, NULL, NULL, NULL };
947 static int sdl_js_axis[MAX_PLAYERS][2] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
948 static int sdl_js_button[MAX_PLAYERS][2] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
950 static boolean SDLOpenJoystick(int nr)
952 if (nr < 0 || nr > MAX_PLAYERS)
955 return ((sdl_joystick[nr] = SDL_JoystickOpen(nr)) == NULL ? FALSE : TRUE);
958 static void SDLCloseJoystick(int nr)
960 if (nr < 0 || nr > MAX_PLAYERS)
963 SDL_JoystickClose(sdl_joystick[nr]);
966 static boolean SDLCheckJoystickOpened(int nr)
968 if (nr < 0 || nr > MAX_PLAYERS)
971 return (SDL_JoystickOpened(nr) ? TRUE : FALSE);
974 void HandleJoystickEvent(Event *event)
978 case SDL_JOYAXISMOTION:
979 if (event->jaxis.axis < 2)
980 sdl_js_axis[event->jaxis.which][event->jaxis.axis]= event->jaxis.value;
983 case SDL_JOYBUTTONDOWN:
984 if (event->jbutton.button < 2)
985 sdl_js_button[event->jbutton.which][event->jbutton.button] = TRUE;
988 case SDL_JOYBUTTONUP:
989 if (event->jbutton.button < 2)
990 sdl_js_button[event->jbutton.which][event->jbutton.button] = FALSE;
998 void SDLInitJoysticks()
1000 static boolean sdl_joystick_subsystem_initialized = FALSE;
1003 if (!sdl_joystick_subsystem_initialized)
1005 sdl_joystick_subsystem_initialized = TRUE;
1007 if (SDL_Init(SDL_INIT_JOYSTICK) < 0)
1009 Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
1014 for (i=0; i<MAX_PLAYERS; i++)
1016 char *device_name = setup.input[i].joy.device_name;
1017 int joystick_nr = getJoystickNrFromDeviceName(device_name);
1019 if (joystick_nr >= SDL_NumJoysticks())
1022 /* misuse joystick file descriptor variable to store joystick number */
1023 joystick.fd[i] = joystick_nr;
1025 /* this allows subsequent calls to 'InitJoysticks' for re-initialization */
1026 if (SDLCheckJoystickOpened(joystick_nr))
1027 SDLCloseJoystick(joystick_nr);
1029 if (!setup.input[i].use_joystick)
1032 if (!SDLOpenJoystick(joystick_nr))
1034 Error(ERR_WARN, "cannot open joystick %d", joystick_nr);
1038 joystick.status = JOYSTICK_ACTIVATED;
1042 boolean SDLReadJoystick(int nr, int *x, int *y, boolean *b1, boolean *b2)
1044 if (nr < 0 || nr >= MAX_PLAYERS)
1048 *x = sdl_js_axis[nr][0];
1050 *y = sdl_js_axis[nr][1];
1053 *b1 = sdl_js_button[nr][0];
1055 *b2 = sdl_js_button[nr][1];
1060 #endif /* TARGET_SDL */