src/video/SDL_surface.c
branchSDL-1.3
changeset 1683 396a35389351
parent 1682 7ae8018b2e5d
child 1720 a1ebb17f9c52
     1.1 --- a/src/video/SDL_surface.c	Fri Jun 16 06:00:31 2006 +0000
     1.2 +++ b/src/video/SDL_surface.c	Sat Jun 17 06:45:14 2006 +0000
     1.3 @@ -47,20 +47,21 @@
     1.4      /* Next time I write a library like SDL, I'll use int for size. :) */
     1.5      if (width >= 16384 || height >= 65536) {
     1.6          SDL_SetError("Width or height is too large");
     1.7 -        return (NULL);
     1.8 +        return NULL;
     1.9      }
    1.10  
    1.11      /* Allocate the surface */
    1.12      surface = (SDL_Surface *) SDL_malloc(sizeof(*surface));
    1.13      if (surface == NULL) {
    1.14          SDL_OutOfMemory();
    1.15 -        return (NULL);
    1.16 +        return NULL;
    1.17      }
    1.18 -    surface->flags = 0;
    1.19 +    SDL_zerop(surface);
    1.20 +
    1.21      surface->format = SDL_AllocFormat(depth, Rmask, Gmask, Bmask, Amask);
    1.22 -    if (surface->format == NULL) {
    1.23 -        SDL_free(surface);
    1.24 -        return (NULL);
    1.25 +    if (!surface->format) {
    1.26 +        SDL_FreeSurface(surface);
    1.27 +        return NULL;
    1.28      }
    1.29      if (Amask) {
    1.30          surface->flags |= SDL_SRCALPHA;
    1.31 @@ -68,16 +69,69 @@
    1.32      surface->w = width;
    1.33      surface->h = height;
    1.34      surface->pitch = SDL_CalculatePitch(surface);
    1.35 -    surface->pixels = NULL;
    1.36 -    surface->locked = 0;
    1.37 -    surface->map = NULL;
    1.38      SDL_SetClipRect(surface, NULL);
    1.39 -    SDL_FormatChanged(surface);
    1.40 +
    1.41 +    if (surface->format->BitsPerPixel <= 8) {
    1.42 +        SDL_Palette *palette =
    1.43 +            SDL_AllocPalette((1 << surface->format->BitsPerPixel));
    1.44 +        if (!palette) {
    1.45 +            SDL_FreeSurface(surface);
    1.46 +            return NULL;
    1.47 +        }
    1.48 +        if (Rmask || Bmask || Gmask) {
    1.49 +            const SDL_PixelFormat *format = surface->format;
    1.50 +
    1.51 +            /* create palette according to masks */
    1.52 +            int i;
    1.53 +            int Rm = 0, Gm = 0, Bm = 0;
    1.54 +            int Rw = 0, Gw = 0, Bw = 0;
    1.55 +
    1.56 +            if (Rmask) {
    1.57 +                Rw = 8 - format->Rloss;
    1.58 +                for (i = format->Rloss; i > 0; i -= Rw)
    1.59 +                    Rm |= 1 << i;
    1.60 +            }
    1.61 +            if (Gmask) {
    1.62 +                Gw = 8 - format->Gloss;
    1.63 +                for (i = format->Gloss; i > 0; i -= Gw)
    1.64 +                    Gm |= 1 << i;
    1.65 +            }
    1.66 +            if (Bmask) {
    1.67 +                Bw = 8 - format->Bloss;
    1.68 +                for (i = format->Bloss; i > 0; i -= Bw)
    1.69 +                    Bm |= 1 << i;
    1.70 +            }
    1.71 +            for (i = 0; i < palette->ncolors; ++i) {
    1.72 +                int r, g, b;
    1.73 +                r = (i & Rmask) >> format->Rshift;
    1.74 +                r = (r << format->Rloss) | ((r * Rm) >> Rw);
    1.75 +                palette->colors[i].r = r;
    1.76 +
    1.77 +                g = (i & Gmask) >> format->Gshift;
    1.78 +                g = (g << format->Gloss) | ((g * Gm) >> Gw);
    1.79 +                palette->colors[i].g = g;
    1.80 +
    1.81 +                b = (i & Bmask) >> format->Bshift;
    1.82 +                b = (b << format->Bloss) | ((b * Bm) >> Bw);
    1.83 +                palette->colors[i].b = b;
    1.84 +            }
    1.85 +        } else if (palette->ncolors == 2) {
    1.86 +            /* Create a black and white bitmap palette */
    1.87 +            palette->colors[0].r = 0xFF;
    1.88 +            palette->colors[0].g = 0xFF;
    1.89 +            palette->colors[0].b = 0xFF;
    1.90 +            palette->colors[1].r = 0x00;
    1.91 +            palette->colors[1].g = 0x00;
    1.92 +            palette->colors[1].b = 0x00;
    1.93 +        }
    1.94 +        SDL_SetSurfacePalette(surface, palette);
    1.95 +        SDL_FreePalette(palette);
    1.96 +    }
    1.97  
    1.98      /* Get the pixels */
    1.99      if (surface->w && surface->h) {
   1.100          surface->pixels = SDL_malloc(surface->h * surface->pitch);
   1.101 -        if (surface->pixels == NULL) {
   1.102 +        if (!surface->pixels) {
   1.103              SDL_FreeSurface(surface);
   1.104              SDL_OutOfMemory();
   1.105              return NULL;
   1.106 @@ -88,17 +142,18 @@
   1.107  
   1.108      /* Allocate an empty mapping */
   1.109      surface->map = SDL_AllocBlitMap();
   1.110 -    if (surface->map == NULL) {
   1.111 +    if (!surface->map) {
   1.112          SDL_FreeSurface(surface);
   1.113 -        return (NULL);
   1.114 +        return NULL;
   1.115      }
   1.116 +    SDL_FormatChanged(surface);
   1.117  
   1.118      /* The surface is ready to go */
   1.119      surface->refcount = 1;
   1.120  #ifdef CHECK_LEAKS
   1.121      ++surfaces_allocated;
   1.122  #endif
   1.123 -    return (surface);
   1.124 +    return surface;
   1.125  }
   1.126  
   1.127  /*
   1.128 @@ -157,47 +212,64 @@
   1.129              surface->flags |= SDL_HWSURFACE;
   1.130              surface->w = w;
   1.131              surface->h = h;
   1.132 -            surface->lock_data = (void *) textureID;
   1.133              SDL_SetClipRect(surface, NULL);
   1.134          }
   1.135      }
   1.136 +    if (surface) {
   1.137 +        surface->textureID = textureID;
   1.138 +    }
   1.139  
   1.140      return surface;
   1.141  }
   1.142  
   1.143 -/*
   1.144 - * Set the palette in a blittable surface
   1.145 - */
   1.146 -int
   1.147 -SDL_SetColors(SDL_Surface * surface, const SDL_Color * colors, int firstcolor,
   1.148 -              int ncolors)
   1.149 +static int
   1.150 +SDL_SurfacePaletteChanged(void *userdata, SDL_Palette * palette)
   1.151  {
   1.152 -    SDL_Palette *pal;
   1.153 -    int gotall;
   1.154 -    int palsize;
   1.155 +    SDL_Surface *surface = (SDL_Surface *) userdata;
   1.156  
   1.157 -    /* Verify the parameters */
   1.158 -    pal = surface->format->palette;
   1.159 -    if (!pal) {
   1.160 -        return 0;               /* not a palettized surface */
   1.161 -    }
   1.162 -    gotall = 1;
   1.163 -    palsize = 1 << surface->format->BitsPerPixel;
   1.164 -    if (ncolors > (palsize - firstcolor)) {
   1.165 -        ncolors = (palsize - firstcolor);
   1.166 -        gotall = 0;
   1.167 -    }
   1.168 -
   1.169 -    if (colors != (pal->colors + firstcolor)) {
   1.170 -        SDL_memcpy(pal->colors + firstcolor, colors,
   1.171 -                   ncolors * sizeof(*colors));
   1.172 +    if (surface->textureID) {
   1.173 +        if (SDL_SetTexturePalette
   1.174 +            (surface->textureID, palette->colors, 0, palette->ncolors) < 0) {
   1.175 +            SDL_GetTexturePalette(surface->textureID, palette->colors, 0,
   1.176 +                                  palette->ncolors);
   1.177 +            return -1;
   1.178 +        }
   1.179      }
   1.180      SDL_FormatChanged(surface);
   1.181  
   1.182 -    if (surface->flags & (SDL_SHADOW_SURFACE | SDL_SCREEN_SURFACE)) {
   1.183 -        gotall &= SDL_SetScreenColors(surface, colors, firstcolor, ncolors);
   1.184 +    return 0;
   1.185 +}
   1.186 +
   1.187 +int
   1.188 +SDL_SetSurfacePalette(SDL_Surface * surface, SDL_Palette * palette)
   1.189 +{
   1.190 +    if (!surface || !surface->format) {
   1.191 +        SDL_SetError("SDL_SetSurfacePalette() passed a NULL surface");
   1.192 +        return -1;
   1.193      }
   1.194 -    return gotall;
   1.195 +
   1.196 +    if (palette && palette->ncolors != (1 << surface->format->BitsPerPixel)) {
   1.197 +        SDL_SetError
   1.198 +            ("SDL_SetSurfacePalette() passed a palette that doesn't match the surface format");
   1.199 +        return -1;
   1.200 +    }
   1.201 +
   1.202 +    if (surface->format->palette == palette) {
   1.203 +        return 0;
   1.204 +    }
   1.205 +
   1.206 +    if (surface->format->palette) {
   1.207 +        SDL_DelPaletteWatch(surface->format->palette,
   1.208 +                            SDL_SurfacePaletteChanged, surface);
   1.209 +    }
   1.210 +
   1.211 +    surface->format->palette = palette;
   1.212 +
   1.213 +    if (surface->format->palette) {
   1.214 +        SDL_AddPaletteWatch(surface->format->palette,
   1.215 +                            SDL_SurfacePaletteChanged, surface);
   1.216 +    }
   1.217 +    return 0;
   1.218  }
   1.219  
   1.220  /*
   1.221 @@ -729,8 +801,8 @@
   1.222          /* Perform the lock */
   1.223          if (surface->flags & SDL_HWSURFACE) {
   1.224              if (SDL_LockTexture
   1.225 -                ((SDL_TextureID) surface->lock_data, NULL, 1,
   1.226 -                 &surface->pixels, &surface->pitch) < 0) {
   1.227 +                (surface->textureID, NULL, 1, &surface->pixels,
   1.228 +                 &surface->pitch) < 0) {
   1.229                  return (-1);
   1.230              }
   1.231          }
   1.232 @@ -760,13 +832,13 @@
   1.233  
   1.234      /* Unlock hardware or accelerated surfaces */
   1.235      if (surface->flags & SDL_HWSURFACE) {
   1.236 -        SDL_UnlockTexture((SDL_TextureID) surface->lock_data);
   1.237 -    } else {
   1.238 -        /* Update RLE encoded surface with new data */
   1.239 -        if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
   1.240 -            surface->flags &= ~SDL_RLEACCEL;    /* stop lying */
   1.241 -            SDL_RLESurface(surface);
   1.242 -        }
   1.243 +        SDL_UnlockTexture(surface->textureID);
   1.244 +    }
   1.245 +
   1.246 +    /* Update RLE encoded surface with new data */
   1.247 +    if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
   1.248 +        surface->flags &= ~SDL_RLEACCEL;        /* stop lying */
   1.249 +        SDL_RLESurface(surface);
   1.250      }
   1.251  }
   1.252  
   1.253 @@ -894,6 +966,7 @@
   1.254          SDL_UnRLESurface(surface, 0);
   1.255      }
   1.256      if (surface->format) {
   1.257 +        SDL_SetSurfacePalette(surface, NULL);
   1.258          SDL_FreeFormat(surface->format);
   1.259          surface->format = NULL;
   1.260      }
   1.261 @@ -902,8 +975,8 @@
   1.262          surface->map = NULL;
   1.263      }
   1.264      /* Should we destroy the texture too?
   1.265 -       if (surface->flags & SDL_HWSURFACE) {
   1.266 -       SDL_DestroyTexture((SDL_TextureID)surface->lock_data);
   1.267 +       if (surface->textureID) {
   1.268 +       SDL_DestroyTexture(surface->textureID);
   1.269         }
   1.270       */
   1.271      if (surface->pixels && ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC)) {