original 1.0.1 release
[xwelltris.git] / src / image / sublib / SDL_surface.c
blob9b25e3c192bda0fcbb76b0778263269f4a4f028c
2 #include "SDL.h"
5 /*
6 * Calculate the pad-aligned scanline width of a surface
7 */
8 Uint16 SDL_CalculatePitch(SDL_Surface *surface)
10 Uint16 pitch;
12 /* Surface should be 4-byte aligned for speed */
13 pitch = surface->w*surface->format->BytesPerPixel;
14 switch (surface->format->BitsPerPixel)
16 case 1:
17 pitch = (pitch+7)/8;
18 break;
19 case 4:
20 pitch = (pitch+1)/2;
21 break;
22 default:
23 break;
25 pitch = (pitch + 3) & ~3; /* 4-byte aligning */
26 return(pitch);
30 * Free a previously allocated format structure
32 void SDL_FreeFormat(SDL_PixelFormat *format)
34 if ( format )
36 if ( format->palette )
38 if ( format->palette->colors )
40 free(format->palette->colors);
42 free(format->palette);
44 free(format);
48 /* Helper functions */
50 * Allocate a pixel format structure and fill it according to the given info.
52 SDL_PixelFormat *SDL_AllocFormat(int bpp,
53 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
55 SDL_PixelFormat *format;
56 Uint32 mask;
58 /* Allocate an empty pixel format structure */
59 format = (SDL_PixelFormat*)malloc(sizeof(*format));
60 if ( format == NULL ) {
61 SDL_OutOfMemory();
62 return(NULL);
64 memset(format, 0, sizeof(*format));
65 format->alpha = SDL_ALPHA_OPAQUE;
67 /* Set up the format */
68 format->BitsPerPixel = bpp;
69 format->BytesPerPixel = (bpp+7)/8;
70 switch (bpp) {
71 case 1:
72 /* Create the 2 color black-white palette */
73 format->palette = (SDL_Palette *)malloc(
74 sizeof(SDL_Palette));
75 if ( format->palette == NULL ) {
76 SDL_FreeFormat(format);
77 SDL_OutOfMemory();
78 return(NULL);
80 (format->palette)->ncolors = 2;
81 (format->palette)->colors = (SDL_Color *)malloc(
82 (format->palette)->ncolors*sizeof(SDL_Color));
83 if ( (format->palette)->colors == NULL ) {
84 SDL_FreeFormat(format);
85 SDL_OutOfMemory();
86 return(NULL);
88 format->palette->colors[0].r = 0xFF;
89 format->palette->colors[0].g = 0xFF;
90 format->palette->colors[0].b = 0xFF;
91 format->palette->colors[1].r = 0x00;
92 format->palette->colors[1].g = 0x00;
93 format->palette->colors[1].b = 0x00;
94 format->Rloss = 8;
95 format->Gloss = 8;
96 format->Bloss = 8;
97 format->Aloss = 8;
98 format->Rshift = 0;
99 format->Gshift = 0;
100 format->Bshift = 0;
101 format->Ashift = 0;
102 format->Rmask = 0;
103 format->Gmask = 0;
104 format->Bmask = 0;
105 format->Amask = 0;
106 break;
108 case 4:
109 /* Create the 16 color VGA palette */
110 format->palette = (SDL_Palette *)malloc(
111 sizeof(SDL_Palette));
112 if ( format->palette == NULL ) {
113 SDL_FreeFormat(format);
114 SDL_OutOfMemory();
115 return(NULL);
117 (format->palette)->ncolors = 16;
118 (format->palette)->colors = (SDL_Color *)malloc(
119 (format->palette)->ncolors*sizeof(SDL_Color));
120 if ( (format->palette)->colors == NULL ) {
121 SDL_FreeFormat(format);
122 SDL_OutOfMemory();
123 return(NULL);
125 /* Punt for now, will this ever be used? */
126 memset((format->palette)->colors, 0,
127 (format->palette)->ncolors*sizeof(SDL_Color));
129 /* Palettized formats have no mask info */
130 format->Rloss = 8;
131 format->Gloss = 8;
132 format->Bloss = 8;
133 format->Aloss = 8;
134 format->Rshift = 0;
135 format->Gshift = 0;
136 format->Bshift = 0;
137 format->Ashift = 0;
138 format->Rmask = 0;
139 format->Gmask = 0;
140 format->Bmask = 0;
141 format->Amask = 0;
142 break;
144 case 8:
145 /* Create an empty 256 color palette */
146 format->palette = (SDL_Palette *)malloc(
147 sizeof(SDL_Palette));
148 if ( format->palette == NULL ) {
149 SDL_FreeFormat(format);
150 SDL_OutOfMemory();
151 return(NULL);
153 (format->palette)->ncolors = 256;
154 (format->palette)->colors = (SDL_Color *)malloc(
155 (format->palette)->ncolors*sizeof(SDL_Color));
156 if ( (format->palette)->colors == NULL ) {
157 SDL_FreeFormat(format);
158 SDL_OutOfMemory();
159 return(NULL);
161 memset((format->palette)->colors, 0,
162 (format->palette)->ncolors*sizeof(SDL_Color));
164 /* Palettized formats have no mask info */
165 format->Rloss = 8;
166 format->Gloss = 8;
167 format->Bloss = 8;
168 format->Aloss = 8;
169 format->Rshift = 0;
170 format->Gshift = 0;
171 format->Bshift = 0;
172 format->Ashift = 0;
173 format->Rmask = 0;
174 format->Gmask = 0;
175 format->Bmask = 0;
176 format->Amask = 0;
177 break;
179 default:
180 /* No palette, just packed pixel info */
181 format->palette = NULL;
182 format->Rshift = 0;
183 format->Rloss = 8;
184 if ( Rmask ) {
185 for ( mask = Rmask; !(mask&0x01); mask >>= 1 )
186 ++format->Rshift;
187 for ( ; (mask&0x01); mask >>= 1 )
188 --format->Rloss;
190 format->Gshift = 0;
191 format->Gloss = 8;
192 if ( Gmask ) {
193 for ( mask = Gmask; !(mask&0x01); mask >>= 1 )
194 ++format->Gshift;
195 for ( ; (mask&0x01); mask >>= 1 )
196 --format->Gloss;
198 format->Bshift = 0;
199 format->Bloss = 8;
200 if ( Bmask ) {
201 for ( mask = Bmask; !(mask&0x01); mask >>= 1 )
202 ++format->Bshift;
203 for ( ; (mask&0x01); mask >>= 1 )
204 --format->Bloss;
206 format->Ashift = 0;
207 format->Aloss = 8;
208 if ( Amask ) {
209 for ( mask = Amask; !(mask&0x01); mask >>= 1 )
210 ++format->Ashift;
211 for ( ; (mask&0x01); mask >>= 1 )
212 --format->Aloss;
214 format->Rmask = Rmask;
215 format->Gmask = Gmask;
216 format->Bmask = Bmask;
217 format->Amask = Amask;
218 break;
220 /* Calculate some standard bitmasks, if necessary
221 * Note: This could conflict with an alpha mask, if given.
223 if ( (bpp > 8) && !format->Rmask && !format->Gmask && !format->Bmask ) {
224 /* R-G-B */
225 if ( bpp > 24 )
226 bpp = 24;
227 format->Rloss = 8-(bpp/3);
228 format->Gloss = 8-(bpp/3)-(bpp%3);
229 format->Bloss = 8-(bpp/3);
230 format->Rshift = ((bpp/3)+(bpp%3))+(bpp/3);
231 format->Gshift = (bpp/3);
232 format->Bshift = 0;
233 format->Rmask = ((0xFF>>format->Rloss)<<format->Rshift);
234 format->Gmask = ((0xFF>>format->Gloss)<<format->Gshift);
235 format->Bmask = ((0xFF>>format->Bloss)<<format->Bshift);
237 return(format);
241 * Free a surface created by the above function.
243 void SDL_FreeSurface (SDL_Surface *surface)
245 /* Free anything that's not NULL, and not the screen surface */
246 if (surface == NULL)
248 return;
250 if ( --surface->refcount > 0 ) {
251 return;
253 if ( surface->format )
255 SDL_FreeFormat(surface->format);
256 surface->format = NULL;
258 if ( surface->pixels &&
259 ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC) )
261 free(surface->pixels);
263 free(surface);
268 /* Public routines */
270 * Create an empty RGB surface of the appropriate depth
272 SDL_Surface * SDL_CreateRGBSurface (Uint32 flags,
273 int width, int height, int depth,
274 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
276 SDL_Surface *surface;
278 flags &= ~SDL_HWSURFACE;
280 /* Allocate the surface */
281 surface = (SDL_Surface *)malloc(sizeof(*surface));
282 if ( surface == NULL )
284 return(NULL);
286 surface->flags = SDL_SWSURFACE;
288 surface->format = SDL_AllocFormat(depth, Rmask, Gmask, Bmask, Amask);
290 if ( surface->format == NULL )
292 free(surface);
293 return(NULL);
295 if ( Amask )
297 surface->flags |= SDL_SRCALPHA;
299 surface->w = width;
300 surface->h = height;
301 surface->pitch = SDL_CalculatePitch(surface);
302 surface->pixels = NULL;
303 surface->offset = 0;
304 // surface->hwdata = NULL;
305 // surface->locked = 0;
306 // surface->map = NULL;
307 surface->format_version = 0;
309 if ( surface->w && surface->h )
311 surface->pixels = (void*)malloc(surface->h*surface->pitch);
312 if ( surface->pixels == NULL )
314 SDL_FreeSurface(surface);
315 return(NULL);
317 /* This is important for bitmaps */
318 memset(surface->pixels, 0, surface->h*surface->pitch);
321 /* The surface is ready to go */
322 surface->refcount = 1;
323 return(surface);
326 int SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key)
328 return 0;