src/SDL12_compat.c
changeset 39 354ef2d7f999
parent 38 3f4404bfd179
child 40 9f165553c592
     1.1 --- a/src/SDL12_compat.c	Mon Jul 21 04:08:00 2014 -0400
     1.2 +++ b/src/SDL12_compat.c	Sat Jul 26 00:54:42 2014 -0400
     1.3 @@ -359,6 +359,16 @@
     1.4      SDL12_GL_MAX_ATTRIBUTE
     1.5  } SDL12_GLattr;
     1.6  
     1.7 +
     1.8 +typedef struct
     1.9 +{
    1.10 +    Uint32 format;
    1.11 +    SDL_Rect *modeslist;
    1.12 +    SDL_Rect **modes;  /* ptrs to each item in modeslist, for SDL_ListModes() */
    1.13 +} VideoModeList;
    1.14 +
    1.15 +static VideoModeList *VideoModes = NULL;
    1.16 +static int VideoModesCount = 0;
    1.17  static SDL12_VideoInfo VideoInfo;
    1.18  static SDL_Window *VideoWindow20 = NULL;
    1.19  static SDL12_Surface *WindowSurface = NULL;
    1.20 @@ -483,6 +493,115 @@
    1.21      }
    1.22  }
    1.23  
    1.24 +/* This sets up VideoModes and VideoModesCount. You end up with arrays by pixel
    1.25 +    format, each with a value that 1.2's SDL_ListModes() can return. */
    1.26 +static int
    1.27 +Init12VidModes(void)
    1.28 +{
    1.29 +    const int total = SDL20_GetNumDisplayModes(VideoDisplayIndex);
    1.30 +    VideoModeList *vmode = NULL;
    1.31 +    int num_modes = 0;
    1.32 +    void *ptr = NULL;
    1.33 +    int i, j;
    1.34 +
    1.35 +    SDL_assert(VideoModes == NULL);
    1.36 +    SDL_assert(VideoModesCount == 0);
    1.37 +
    1.38 +    for (i = 0; i < total; ++i) {
    1.39 +        SDL_DisplayMode mode;
    1.40 +
    1.41 +        if (SDL20_GetDisplayMode(VideoDisplayIndex, i, &mode) == -1) {
    1.42 +            continue;
    1.43 +        } else if (!mode.w || !mode.h) {
    1.44 +            SDL_assert(0 && "Can this actually happen?");
    1.45 +            continue;
    1.46 +        }
    1.47 +
    1.48 +        if (!vmode || (mode.format != vmode->format)) {  // SDL20_GetDisplayMode() sorts on bpp first. We know when to change arrays.
    1.49 +            if (VideoModesCount > 0) {
    1.50 +                VideoModes[VideoModesCount-1].modes[num_modes] = NULL;
    1.51 +            }
    1.52 +            ptr = (VideoModeList *) SDL20_realloc(VideoModes, sizeof (VideoModeList) * (VideoModesCount+1));
    1.53 +            if (!ptr) {
    1.54 +                return SDL20_OutOfMemory();
    1.55 +            }
    1.56 +            VideoModes = (VideoModeList *) ptr;
    1.57 +            vmode = &VideoModes[VideoModesCount];
    1.58 +            vmode->format = mode.format;
    1.59 +            vmode->modeslist = NULL;
    1.60 +            vmode->modes = NULL;
    1.61 +            VideoModesCount++;
    1.62 +            num_modes = 0;
    1.63 +        }
    1.64 +
    1.65 +        /* make sure we don't have this one already (with a different refresh rate, etc). */
    1.66 +        for (j = 0; j < num_modes; j++) {
    1.67 +            if ((vmode->modeslist[j].w == mode.w) && (vmode->modeslist[j].h == mode.h)) {
    1.68 +                break;
    1.69 +            }
    1.70 +        }
    1.71 +
    1.72 +        if (j < num_modes) {
    1.73 +            continue;  /* already have this one. */
    1.74 +        }
    1.75 +
    1.76 +        ptr = SDL20_realloc(vmode->modes, sizeof (SDL_Rect *) * (num_modes + 2));
    1.77 +        if (ptr == NULL) {
    1.78 +            return SDL20_OutOfMemory();
    1.79 +        }
    1.80 +        vmode->modes = (SDL_Rect **) ptr;
    1.81 +
    1.82 +        ptr = SDL20_realloc(vmode->modeslist, sizeof (SDL_Rect) * (num_modes + 1));
    1.83 +        if (ptr == NULL) {
    1.84 +            return SDL20_OutOfMemory();
    1.85 +        }
    1.86 +        vmode->modeslist = (SDL_Rect *) ptr;
    1.87 +
    1.88 +        vmode->modeslist[num_modes].x = 0;
    1.89 +        vmode->modeslist[num_modes].y = 0;
    1.90 +        vmode->modeslist[num_modes].w = mode.w;
    1.91 +        vmode->modeslist[num_modes].h = mode.h;
    1.92 +
    1.93 +        vmode->modes[num_modes] = &vmode->modeslist[num_modes];
    1.94 +
    1.95 +        num_modes++;
    1.96 +    }
    1.97 +
    1.98 +    if (VideoModesCount > 0) {
    1.99 +        VideoModes[VideoModesCount-1].modes[num_modes] = NULL;
   1.100 +    }
   1.101 +
   1.102 +    return 0;
   1.103 +}
   1.104 +
   1.105 +static int
   1.106 +Init12Video(void)
   1.107 +{
   1.108 +    int i;
   1.109 +
   1.110 +    for (i = 0; i < SDL12_MAXEVENTS-1; i++)
   1.111 +        EventQueuePool[i].next = &EventQueuePool[i+1];
   1.112 +    EventQueuePool[SDL12_MAXEVENTS-1].next = NULL;
   1.113 +
   1.114 +    EventQueueHead = EventQueueTail = NULL;
   1.115 +    EventQueueAvailable = EventQueuePool;
   1.116 +
   1.117 +    SDL_memset(EventStates, SDL_ENABLE, sizeof (EventStates)); /* on by default */
   1.118 +    EventStates[SDL12_SYSWMEVENT] = SDL_IGNORE;  /* off by default. */
   1.119 +
   1.120 +    SDL20_SetEventFilter(EventFilter20to12, NULL);
   1.121 +
   1.122 +    VideoDisplayIndex = GetVideoDisplay();
   1.123 +    SwapInterval = 0;
   1.124 +
   1.125 +    if (Init12VidModes() == -1) {
   1.126 +        return -1;
   1.127 +    }
   1.128 +
   1.129 +    return 0;
   1.130 +}
   1.131 +
   1.132 +
   1.133  DECLSPEC int SDLCALL
   1.134  SDL_InitSubSystem(Uint32 sdl12flags)
   1.135  {
   1.136 @@ -507,19 +626,10 @@
   1.137      // !!! FIXME: do something about SDL12_INIT_EVENTTHREAD
   1.138  
   1.139      rc = SDL20_Init(sdl20flags);
   1.140 -    if ((rc == 0) && (sdl20flags & SDL_INIT_VIDEO))
   1.141 -    {
   1.142 -        int i;
   1.143 -        for (i = 0; i < SDL12_MAXEVENTS-1; i++)
   1.144 -            EventQueuePool[i].next = &EventQueuePool[i+1];
   1.145 -        EventQueuePool[SDL12_MAXEVENTS-1].next = NULL;
   1.146 -        EventQueueHead = EventQueueTail = NULL;
   1.147 -        EventQueueAvailable = EventQueuePool;
   1.148 -        SDL_memset(EventStates, SDL_ENABLE, sizeof (EventStates)); /* on by default */
   1.149 -        EventStates[SDL12_SYSWMEVENT] = SDL_IGNORE;  /* off by default. */
   1.150 -        SDL20_SetEventFilter(EventFilter20to12, NULL);
   1.151 -        VideoDisplayIndex = GetVideoDisplay();
   1.152 -        SwapInterval = 0;
   1.153 +    if ((rc == 0) && (sdl20flags & SDL_INIT_VIDEO)) {
   1.154 +        if (Init12Video() == -1) {
   1.155 +            return -1;  /* !!! FIXME: should we deinit other subsystems? */
   1.156 +        }
   1.157      }
   1.158  
   1.159      return rc;
   1.160 @@ -582,6 +692,27 @@
   1.161      return InitFlags20to12(SDL20_WasInit(sdl20flags)) | extraflags;
   1.162  }
   1.163  
   1.164 +static void
   1.165 +Quit12Video(void)
   1.166 +{
   1.167 +    int i;
   1.168 +
   1.169 +    for (i = 0; i < VideoModesCount; i++) {
   1.170 +        SDL20_free(VideoModes[i].modeslist);
   1.171 +        SDL20_free(VideoModes[i].modes);
   1.172 +    }
   1.173 +    SDL20_free(VideoModes);
   1.174 +
   1.175 +    SDL20_FreeFormat(VideoInfo.vfmt);
   1.176 +    SDL20_zero(VideoInfo);
   1.177 +
   1.178 +    EventFilter12 = NULL;
   1.179 +    EventQueueAvailable = EventQueueHead = EventQueueTail = NULL;
   1.180 +    CurrentCursor = NULL;
   1.181 +    VideoModes = NULL;
   1.182 +    VideoModesCount = 0;
   1.183 +}
   1.184 +
   1.185  DECLSPEC void SDLCALL
   1.186  SDL_QuitSubSystem(Uint32 sdl12flags)
   1.187  {
   1.188 @@ -594,11 +725,7 @@
   1.189  
   1.190      // !!! FIXME: reset a bunch of other global variables too.
   1.191      if (sdl12flags & SDL12_INIT_VIDEO) {
   1.192 -        EventFilter12 = NULL;
   1.193 -        EventQueueAvailable = EventQueueHead = EventQueueTail = NULL;
   1.194 -        CurrentCursor = NULL;
   1.195 -        SDL20_FreeFormat(VideoInfo.vfmt);
   1.196 -        SDL20_zero(VideoInfo);
   1.197 +        Quit12Video();
   1.198      }
   1.199  
   1.200      // !!! FIXME: do something about SDL12_INIT_EVENTTHREAD
   1.201 @@ -1251,6 +1378,8 @@
   1.202  {
   1.203      SDL_DisplayMode mode;
   1.204  
   1.205 +    // !!! FIXME: calculate this in Init12Video(), then this just does: return VideoInfo.vfmt ? &VideoInfo : NULL;
   1.206 +
   1.207      if (!VideoInfo.vfmt && SDL20_GetDesktopDisplayMode(VideoDisplayIndex, &mode) == 0) {
   1.208          VideoInfo.vfmt = SDL20_AllocFormat(mode.format);
   1.209          VideoInfo.current_w = mode.w;
   1.210 @@ -1293,72 +1422,41 @@
   1.211      return actual_bpp;
   1.212  }
   1.213  
   1.214 -#if SANITY_CHECK_THIS_CODE
   1.215  DECLSPEC SDL_Rect ** SDLCALL
   1.216 -SDL_ListModes(const SDL12_PixelFormat *format, Uint32 flags)
   1.217 +SDL_ListModes(const SDL12_PixelFormat *format12, Uint32 flags)
   1.218  {
   1.219 -    int i, nmodes;
   1.220 -    SDL_Rect **modes;
   1.221 +    Uint32 fmt;
   1.222 +    int i;
   1.223  
   1.224      if (!SDL20_WasInit(SDL_INIT_VIDEO)) {
   1.225          return NULL;
   1.226      }
   1.227  
   1.228 +    if ((!format12) && (!VideoInfo.vfmt)) {
   1.229 +        SDL20_SetError("No pixel format specified");
   1.230 +        return NULL;
   1.231 +    }
   1.232 +
   1.233      if (!(flags & SDL12_FULLSCREEN)) {
   1.234 -        return (SDL_Rect **) (-1);
   1.235 +        return (SDL_Rect **) (-1);  /* any resolution is fine. */
   1.236      }
   1.237  
   1.238 -    if (!format) {
   1.239 -        format = VideoInfo.vfmt;
   1.240 +    if (format12) {
   1.241 +        fmt = SDL20_MasksToPixelFormatEnum(format12->BitsPerPixel, format12->Rmask, format12->Gmask, format12->Bmask, format12->Amask);
   1.242 +    } else {
   1.243 +        fmt = VideoInfo.vfmt->format;
   1.244      }
   1.245  
   1.246 -    /* !!! FIXME: Memory leak */
   1.247 -    nmodes = 0;
   1.248 -    modes = NULL;
   1.249 -    for (i = 0; i < SDL20_GetNumDisplayModes(VideoDisplayIndex); ++i) {
   1.250 -        SDL_DisplayMode mode;
   1.251 -        int bpp;
   1.252 -
   1.253 -        SDL20_GetDisplayMode(VideoDisplayIndex, i, &mode);
   1.254 -        if (!mode.w || !mode.h) {
   1.255 -            return (SDL_Rect **) (-1);
   1.256 +    for (i = 0; i < VideoModesCount; i++) {
   1.257 +        VideoModeList *modes = &VideoModes[i];
   1.258 +        if (modes->format == fmt) {
   1.259 +            return modes->modes;
   1.260          }
   1.261 -        
   1.262 -        /* Copied from src/video/SDL_pixels.c:SDL_PixelFormatEnumToMasks */
   1.263 -        if (SDL_BYTESPERPIXEL(mode.format) <= 2) {
   1.264 -            bpp = SDL_BITSPERPIXEL(mode.format);
   1.265 -        } else {
   1.266 -            bpp = SDL_BYTESPERPIXEL(mode.format) * 8;
   1.267 -        }
   1.268 -
   1.269 -        if (bpp != format->BitsPerPixel) {
   1.270 -            continue;
   1.271 -        }
   1.272 -        if (nmodes > 0 && modes[nmodes - 1]->w == mode.w
   1.273 -            && modes[nmodes - 1]->h == mode.h) {
   1.274 -            continue;
   1.275 -        }
   1.276 -
   1.277 -        modes = SDL20_realloc(modes, (nmodes + 2) * sizeof(*modes));
   1.278 -        if (!modes) {
   1.279 -            return NULL;
   1.280 -        }
   1.281 -        modes[nmodes] = (SDL_Rect *) SDL20_malloc(sizeof(SDL_Rect));
   1.282 -        if (!modes[nmodes]) {
   1.283 -            return NULL;
   1.284 -        }
   1.285 -        modes[nmodes]->x = 0;
   1.286 -        modes[nmodes]->y = 0;
   1.287 -        modes[nmodes]->w = mode.w;
   1.288 -        modes[nmodes]->h = mode.h;
   1.289 -        ++nmodes;
   1.290      }
   1.291 -    if (modes) {
   1.292 -        modes[nmodes] = NULL;
   1.293 -    }
   1.294 -    return modes;
   1.295 +
   1.296 +    SDL20_SetError("No modes support requested pixel format");
   1.297 +    return NULL;
   1.298  }
   1.299 -#endif
   1.300  
   1.301  DECLSPEC void SDLCALL
   1.302  SDL_FreeCursor(SDL12_Cursor *cursor12)