Mercurial > sdl-ios-xcode
comparison src/render/software/SDL_render_sw.c @ 5198:bb45ecd958d8
Renamed files for consistency
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 05 Feb 2011 12:01:11 -0800 |
parents | src/render/software/SDL_renderer_sw.c@4d39eeaad00b |
children | 2178ffe17222 |
comparison
equal
deleted
inserted
replaced
5197:69f47f2c1856 | 5198:bb45ecd958d8 |
---|---|
1 /* | |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997-2010 Sam Lantinga | |
4 | |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Lesser General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2.1 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Lesser General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Lesser General Public | |
16 License along with this library; if not, write to the Free Software | |
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
18 | |
19 Sam Lantinga | |
20 slouken@libsdl.org | |
21 */ | |
22 #include "SDL_config.h" | |
23 | |
24 #include "../SDL_sysrender.h" | |
25 #include "../../video/SDL_pixels_c.h" | |
26 | |
27 #include "SDL_draw.h" | |
28 #include "SDL_blendfillrect.h" | |
29 #include "SDL_blendline.h" | |
30 #include "SDL_blendpoint.h" | |
31 #include "SDL_drawline.h" | |
32 #include "SDL_drawpoint.h" | |
33 | |
34 | |
35 /* SDL surface based renderer implementation */ | |
36 | |
37 static SDL_Renderer *SW_CreateRenderer(SDL_Window * window, Uint32 flags); | |
38 static void SW_WindowEvent(SDL_Renderer * renderer, | |
39 const SDL_WindowEvent *event); | |
40 static int SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); | |
41 static int SW_SetTextureColorMod(SDL_Renderer * renderer, | |
42 SDL_Texture * texture); | |
43 static int SW_SetTextureAlphaMod(SDL_Renderer * renderer, | |
44 SDL_Texture * texture); | |
45 static int SW_SetTextureBlendMode(SDL_Renderer * renderer, | |
46 SDL_Texture * texture); | |
47 static int SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, | |
48 const SDL_Rect * rect, const void *pixels, | |
49 int pitch); | |
50 static int SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, | |
51 const SDL_Rect * rect, void **pixels, int *pitch); | |
52 static void SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); | |
53 static int SW_RenderDrawPoints(SDL_Renderer * renderer, | |
54 const SDL_Point * points, int count); | |
55 static int SW_RenderDrawLines(SDL_Renderer * renderer, | |
56 const SDL_Point * points, int count); | |
57 static int SW_RenderFillRects(SDL_Renderer * renderer, | |
58 const SDL_Rect ** rects, int count); | |
59 static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, | |
60 const SDL_Rect * srcrect, const SDL_Rect * dstrect); | |
61 static int SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, | |
62 Uint32 format, void * pixels, int pitch); | |
63 static void SW_RenderPresent(SDL_Renderer * renderer); | |
64 static void SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture); | |
65 static void SW_DestroyRenderer(SDL_Renderer * renderer); | |
66 | |
67 | |
68 SDL_RenderDriver SW_RenderDriver = { | |
69 SW_CreateRenderer, | |
70 { | |
71 "software", | |
72 0, | |
73 8, | |
74 { | |
75 SDL_PIXELFORMAT_RGB555, | |
76 SDL_PIXELFORMAT_RGB565, | |
77 SDL_PIXELFORMAT_RGB888, | |
78 SDL_PIXELFORMAT_BGR888, | |
79 SDL_PIXELFORMAT_ARGB8888, | |
80 SDL_PIXELFORMAT_RGBA8888, | |
81 SDL_PIXELFORMAT_ABGR8888, | |
82 SDL_PIXELFORMAT_BGRA8888 | |
83 }, | |
84 0, | |
85 0} | |
86 }; | |
87 | |
88 typedef struct | |
89 { | |
90 SDL_bool updateSize; | |
91 SDL_Surface *surface; | |
92 } SW_RenderData; | |
93 | |
94 | |
95 SDL_Renderer * | |
96 SW_CreateRendererForSurface(SDL_Surface * surface) | |
97 { | |
98 SDL_Renderer *renderer; | |
99 SW_RenderData *data; | |
100 | |
101 if (!surface) { | |
102 SDL_SetError("Can't create renderer for NULL surface"); | |
103 return NULL; | |
104 } | |
105 | |
106 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); | |
107 if (!renderer) { | |
108 SDL_OutOfMemory(); | |
109 return NULL; | |
110 } | |
111 | |
112 data = (SW_RenderData *) SDL_calloc(1, sizeof(*data)); | |
113 if (!data) { | |
114 SW_DestroyRenderer(renderer); | |
115 SDL_OutOfMemory(); | |
116 return NULL; | |
117 } | |
118 data->surface = surface; | |
119 | |
120 renderer->WindowEvent = SW_WindowEvent; | |
121 renderer->CreateTexture = SW_CreateTexture; | |
122 renderer->SetTextureColorMod = SW_SetTextureColorMod; | |
123 renderer->SetTextureAlphaMod = SW_SetTextureAlphaMod; | |
124 renderer->SetTextureBlendMode = SW_SetTextureBlendMode; | |
125 renderer->UpdateTexture = SW_UpdateTexture; | |
126 renderer->LockTexture = SW_LockTexture; | |
127 renderer->UnlockTexture = SW_UnlockTexture; | |
128 renderer->DestroyTexture = SW_DestroyTexture; | |
129 renderer->RenderDrawPoints = SW_RenderDrawPoints; | |
130 renderer->RenderDrawLines = SW_RenderDrawLines; | |
131 renderer->RenderFillRects = SW_RenderFillRects; | |
132 renderer->RenderCopy = SW_RenderCopy; | |
133 renderer->RenderReadPixels = SW_RenderReadPixels; | |
134 renderer->RenderPresent = SW_RenderPresent; | |
135 renderer->DestroyRenderer = SW_DestroyRenderer; | |
136 renderer->info = SW_RenderDriver.info; | |
137 renderer->driverdata = data; | |
138 | |
139 return renderer; | |
140 } | |
141 | |
142 SDL_Renderer * | |
143 SW_CreateRenderer(SDL_Window * window, Uint32 flags) | |
144 { | |
145 SDL_Surface *surface; | |
146 | |
147 surface = SDL_GetWindowSurface(window); | |
148 if (!surface) { | |
149 return NULL; | |
150 } | |
151 return SW_CreateRendererForSurface(surface); | |
152 } | |
153 | |
154 static SDL_Surface * | |
155 SW_ActivateRenderer(SDL_Renderer * renderer) | |
156 { | |
157 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; | |
158 SDL_Window *window = renderer->window; | |
159 | |
160 if (data->updateSize) { | |
161 data->surface = SDL_GetWindowSurface(window); | |
162 data->updateSize = SDL_FALSE; | |
163 } | |
164 return data->surface; | |
165 } | |
166 | |
167 static void | |
168 SW_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) | |
169 { | |
170 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; | |
171 | |
172 if (event->event == SDL_WINDOWEVENT_RESIZED) { | |
173 data->updateSize = SDL_TRUE; | |
174 } | |
175 } | |
176 | |
177 static int | |
178 SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) | |
179 { | |
180 int bpp; | |
181 Uint32 Rmask, Gmask, Bmask, Amask; | |
182 | |
183 if (!SDL_PixelFormatEnumToMasks | |
184 (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { | |
185 SDL_SetError("Unknown texture format"); | |
186 return -1; | |
187 } | |
188 | |
189 texture->driverdata = | |
190 SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask, | |
191 Bmask, Amask); | |
192 SDL_SetSurfaceColorMod(texture->driverdata, texture->r, texture->g, | |
193 texture->b); | |
194 SDL_SetSurfaceAlphaMod(texture->driverdata, texture->a); | |
195 SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode); | |
196 | |
197 if (texture->access == SDL_TEXTUREACCESS_STATIC) { | |
198 SDL_SetSurfaceRLE(texture->driverdata, 1); | |
199 } | |
200 | |
201 if (!texture->driverdata) { | |
202 return -1; | |
203 } | |
204 return 0; | |
205 } | |
206 | |
207 static int | |
208 SW_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) | |
209 { | |
210 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | |
211 return SDL_SetSurfaceColorMod(surface, texture->r, texture->g, | |
212 texture->b); | |
213 } | |
214 | |
215 static int | |
216 SW_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture) | |
217 { | |
218 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | |
219 return SDL_SetSurfaceAlphaMod(surface, texture->a); | |
220 } | |
221 | |
222 static int | |
223 SW_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture) | |
224 { | |
225 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | |
226 return SDL_SetSurfaceBlendMode(surface, texture->blendMode); | |
227 } | |
228 | |
229 static int | |
230 SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, | |
231 const SDL_Rect * rect, const void *pixels, int pitch) | |
232 { | |
233 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | |
234 Uint8 *src, *dst; | |
235 int row; | |
236 size_t length; | |
237 | |
238 src = (Uint8 *) pixels; | |
239 dst = (Uint8 *) surface->pixels + | |
240 rect->y * surface->pitch + | |
241 rect->x * surface->format->BytesPerPixel; | |
242 length = rect->w * surface->format->BytesPerPixel; | |
243 for (row = 0; row < rect->h; ++row) { | |
244 SDL_memcpy(dst, src, length); | |
245 src += pitch; | |
246 dst += surface->pitch; | |
247 } | |
248 return 0; | |
249 } | |
250 | |
251 static int | |
252 SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, | |
253 const SDL_Rect * rect, void **pixels, int *pitch) | |
254 { | |
255 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | |
256 | |
257 *pixels = | |
258 (void *) ((Uint8 *) surface->pixels + rect->y * surface->pitch + | |
259 rect->x * surface->format->BytesPerPixel); | |
260 *pitch = surface->pitch; | |
261 return 0; | |
262 } | |
263 | |
264 static void | |
265 SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) | |
266 { | |
267 } | |
268 | |
269 static int | |
270 SW_RenderDrawPoints(SDL_Renderer * renderer, const SDL_Point * points, | |
271 int count) | |
272 { | |
273 SDL_Surface *surface = SW_ActivateRenderer(renderer); | |
274 | |
275 if (!surface) { | |
276 return -1; | |
277 } | |
278 | |
279 /* Draw the points! */ | |
280 if (renderer->blendMode == SDL_BLENDMODE_NONE) { | |
281 Uint32 color = SDL_MapRGBA(surface->format, | |
282 renderer->r, renderer->g, renderer->b, | |
283 renderer->a); | |
284 | |
285 return SDL_DrawPoints(surface, points, count, color); | |
286 } else { | |
287 return SDL_BlendPoints(surface, points, count, | |
288 renderer->blendMode, | |
289 renderer->r, renderer->g, renderer->b, | |
290 renderer->a); | |
291 } | |
292 } | |
293 | |
294 static int | |
295 SW_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, | |
296 int count) | |
297 { | |
298 SDL_Surface *surface = SW_ActivateRenderer(renderer); | |
299 | |
300 if (!surface) { | |
301 return -1; | |
302 } | |
303 | |
304 /* Draw the lines! */ | |
305 if (renderer->blendMode == SDL_BLENDMODE_NONE) { | |
306 Uint32 color = SDL_MapRGBA(surface->format, | |
307 renderer->r, renderer->g, renderer->b, | |
308 renderer->a); | |
309 | |
310 return SDL_DrawLines(surface, points, count, color); | |
311 } else { | |
312 return SDL_BlendLines(surface, points, count, | |
313 renderer->blendMode, | |
314 renderer->r, renderer->g, renderer->b, | |
315 renderer->a); | |
316 } | |
317 } | |
318 | |
319 static int | |
320 SW_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, | |
321 int count) | |
322 { | |
323 SDL_Surface *surface = SW_ActivateRenderer(renderer); | |
324 | |
325 if (!surface) { | |
326 return -1; | |
327 } | |
328 | |
329 if (renderer->blendMode == SDL_BLENDMODE_NONE) { | |
330 Uint32 color = SDL_MapRGBA(surface->format, | |
331 renderer->r, renderer->g, renderer->b, | |
332 renderer->a); | |
333 return SDL_FillRects(surface, rects, count, color); | |
334 } else { | |
335 return SDL_BlendFillRects(surface, rects, count, | |
336 renderer->blendMode, | |
337 renderer->r, renderer->g, renderer->b, | |
338 renderer->a); | |
339 } | |
340 } | |
341 | |
342 static int | |
343 SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, | |
344 const SDL_Rect * srcrect, const SDL_Rect * dstrect) | |
345 { | |
346 SDL_Surface *surface = SW_ActivateRenderer(renderer); | |
347 SDL_Surface *src = (SDL_Surface *) texture->driverdata; | |
348 SDL_Rect final_rect = *dstrect; | |
349 | |
350 if (!surface) { | |
351 return -1; | |
352 } | |
353 return SDL_BlitSurface(src, srcrect, surface, &final_rect); | |
354 } | |
355 | |
356 static int | |
357 SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, | |
358 Uint32 format, void * pixels, int pitch) | |
359 { | |
360 SDL_Surface *surface = SW_ActivateRenderer(renderer); | |
361 Uint32 src_format; | |
362 void *src_pixels; | |
363 | |
364 if (!surface) { | |
365 return -1; | |
366 } | |
367 | |
368 if (rect->x < 0 || rect->x+rect->w > surface->w || | |
369 rect->y < 0 || rect->y+rect->h > surface->h) { | |
370 SDL_SetError("Tried to read outside of surface bounds"); | |
371 return -1; | |
372 } | |
373 | |
374 src_format = SDL_MasksToPixelFormatEnum( | |
375 surface->format->BitsPerPixel, | |
376 surface->format->Rmask, surface->format->Gmask, | |
377 surface->format->Bmask, surface->format->Amask); | |
378 | |
379 src_pixels = (void*)((Uint8 *) surface->pixels + | |
380 rect->y * surface->pitch + | |
381 rect->x * surface->format->BytesPerPixel); | |
382 | |
383 return SDL_ConvertPixels(rect->w, rect->h, | |
384 src_format, src_pixels, surface->pitch, | |
385 format, pixels, pitch); | |
386 } | |
387 | |
388 static void | |
389 SW_RenderPresent(SDL_Renderer * renderer) | |
390 { | |
391 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; | |
392 SDL_Window *window = renderer->window; | |
393 | |
394 if (window) { | |
395 SDL_UpdateWindowSurface(window); | |
396 } | |
397 } | |
398 | |
399 static void | |
400 SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) | |
401 { | |
402 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | |
403 | |
404 SDL_FreeSurface(surface); | |
405 } | |
406 | |
407 static void | |
408 SW_DestroyRenderer(SDL_Renderer * renderer) | |
409 { | |
410 SW_RenderData *data = (SW_RenderData *) renderer->driverdata; | |
411 | |
412 if (data) { | |
413 SDL_free(data); | |
414 } | |
415 SDL_free(renderer); | |
416 } | |
417 | |
418 /* vi: set ts=4 sw=4 expandtab: */ |