3168
|
1 /*
|
|
2 SDL - Simple DirectMedia Layer
|
|
3 Copyright (C) 1997-2009 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 Stefan Klug
|
|
23 klug.stefan@gmx.de
|
|
24 */
|
|
25 #include "SDL_config.h"
|
|
26
|
|
27 #if SDL_VIDEO_RENDER_DDRAW
|
|
28
|
|
29 #include "SDL_win32video.h"
|
|
30 #include "../SDL_yuv_sw_c.h"
|
|
31
|
|
32 #if 0
|
|
33 #define DDRAW_LOG(...) printf(__VA_ARGS__)
|
|
34 #else
|
|
35 #define DDRAW_LOG(...)
|
|
36 #endif
|
|
37
|
|
38
|
|
39 /* DirectDraw renderer implementation */
|
|
40
|
|
41 static SDL_Renderer *DDRAW_CreateRenderer(SDL_Window * window, Uint32 flags);
|
|
42 static int DDRAW_DisplayModeChanged(SDL_Renderer * renderer);
|
|
43 static int DDRAW_CreateTexture(SDL_Renderer * renderer,
|
|
44 SDL_Texture * texture);
|
|
45 static int DDRAW_QueryTexturePixels(SDL_Renderer * renderer,
|
|
46 SDL_Texture * texture, void **pixels,
|
|
47 int *pitch);
|
|
48 static int DDRAW_SetTextureColorMod(SDL_Renderer * renderer,
|
|
49 SDL_Texture * texture);
|
|
50 static int DDRAW_SetTextureAlphaMod(SDL_Renderer * renderer,
|
|
51 SDL_Texture * texture);
|
|
52 static int DDRAW_SetTextureBlendMode(SDL_Renderer * renderer,
|
|
53 SDL_Texture * texture);
|
|
54 static int DDRAW_SetTextureScaleMode(SDL_Renderer * renderer,
|
|
55 SDL_Texture * texture);
|
|
56 static int DDRAW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
57 const SDL_Rect * rect, const void *pixels,
|
|
58 int pitch);
|
|
59 static int DDRAW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
60 const SDL_Rect * rect, int markDirty,
|
|
61 void **pixels, int *pitch);
|
|
62 static void DDRAW_UnlockTexture(SDL_Renderer * renderer,
|
|
63 SDL_Texture * texture);
|
|
64 static void DDRAW_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
65 int numrects, const SDL_Rect * rects);
|
|
66 static int DDRAW_RenderPoint(SDL_Renderer * renderer, int x, int y);
|
|
67 static int DDRAW_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2,
|
|
68 int y2);
|
|
69 static int DDRAW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect);
|
|
70 static int DDRAW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
71 const SDL_Rect * srcrect,
|
|
72 const SDL_Rect * dstrect);
|
|
73 static void DDRAW_RenderPresent(SDL_Renderer * renderer);
|
|
74 static void DDRAW_DestroyTexture(SDL_Renderer * renderer,
|
|
75 SDL_Texture * texture);
|
|
76 static void DDRAW_DestroyRenderer(SDL_Renderer * renderer);
|
|
77
|
|
78
|
|
79 SDL_RenderDriver DDRAW_RenderDriver = {
|
|
80 DDRAW_CreateRenderer,
|
|
81 {
|
|
82 "ddraw",
|
|
83 (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
|
|
84 SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
|
|
85 SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_ACCELERATED),
|
|
86 (SDL_TEXTUREMODULATE_NONE),
|
|
87 (SDL_BLENDMODE_NONE),
|
|
88 (SDL_TEXTURESCALEMODE_NONE),
|
|
89 0,
|
|
90 {0},
|
|
91 0,
|
|
92 0}
|
|
93 };
|
|
94
|
|
95 typedef struct
|
|
96 {
|
|
97 IDirectDraw *ddraw;
|
|
98 IDirectDrawSurface *primary;
|
|
99 } DDRAW_RenderData;
|
|
100
|
|
101 typedef struct
|
|
102 {
|
|
103 RECT lock;
|
|
104 IDirectDrawSurface *surface;
|
|
105 } DDRAW_TextureData;
|
|
106
|
|
107
|
|
108 static void
|
|
109 DDRAW_SetError(const char *prefix, HRESULT result)
|
|
110 {
|
|
111 const char *error;
|
|
112
|
|
113 switch (result) {
|
|
114 case DDERR_CANTCREATEDC:
|
|
115 error = "CANTCREATEDC";
|
|
116 break;
|
|
117 case DDERR_CANTLOCKSURFACE:
|
|
118 error = "CANTLOCKSURFACE";
|
|
119 break;
|
|
120 case DDERR_CLIPPERISUSINGHWND:
|
|
121 error = "CLIPPERISUSINGHWND";
|
|
122 break;
|
|
123 case DDERR_COLORKEYNOTSET:
|
|
124 error = "COLORKEYNOTSET";
|
|
125 break;
|
|
126 case DDERR_CURRENTLYNOTAVAIL:
|
|
127 error = "CURRENTLYNOTAVAIL";
|
|
128 break;
|
|
129 case DDERR_DCALREADYCREATED:
|
|
130 error = "DCALREADYCREATED";
|
|
131 break;
|
|
132 case DDERR_DEVICEDOESNTOWNSURFACE:
|
|
133 error = "DEVICEDOESNTOWNSURFACE";
|
|
134 break;
|
|
135 case DDERR_DIRECTDRAWALREADYCREATED:
|
|
136 error = "DIRECTDRAWALREADYCREATED";
|
|
137 break;
|
|
138 case DDERR_EXCLUSIVEMODEALREADYSET:
|
|
139 error = "EXCLUSIVEMODEALREADYSET";
|
|
140 break;
|
|
141 case DDERR_GENERIC:
|
|
142 error = "GENERIC";
|
|
143 break;
|
|
144 case DDERR_HEIGHTALIGN:
|
|
145 error = "HEIGHTALIGN";
|
|
146 break;
|
|
147 case DDERR_IMPLICITLYCREATED:
|
|
148 error = "IMPLICITLYCREATED";
|
|
149 break;
|
|
150 case DDERR_INCOMPATIBLEPRIMARY:
|
|
151 error = "INCOMPATIBLEPRIMARY";
|
|
152 break;
|
|
153 case DDERR_INVALIDCAPS:
|
|
154 error = "INVALIDCAPS";
|
|
155 break;
|
|
156 case DDERR_INVALIDCLIPLIST:
|
|
157 error = "INVALIDCLIPLIST";
|
|
158 break;
|
|
159 case DDERR_INVALIDMODE:
|
|
160 error = "INVALIDMODE";
|
|
161 break;
|
|
162 case DDERR_INVALIDOBJECT:
|
|
163 error = "INVALIDOBJECT";
|
|
164 break;
|
|
165 case DDERR_INVALIDPARAMS:
|
|
166 error = "INVALIDPARAMS";
|
|
167 break;
|
|
168 case DDERR_INVALIDPIXELFORMAT:
|
|
169 error = "INVALIDPIXELFORMAT";
|
|
170 break;
|
|
171 case DDERR_INVALIDPOSITION:
|
|
172 error = "INVALIDPOSITION";
|
|
173 break;
|
|
174 case DDERR_INVALIDRECT:
|
|
175 error = "INVALIDRECT";
|
|
176 break;
|
|
177 case DDERR_LOCKEDSURFACES:
|
|
178 error = "LOCKEDSURFACES";
|
|
179 break;
|
|
180 case DDERR_MOREDATA:
|
|
181 error = "MOREDATA";
|
|
182 break;
|
|
183 case DDERR_NOALPHAHW:
|
|
184 error = "NOALPHAHW";
|
|
185 break;
|
|
186 case DDERR_NOBLTHW:
|
|
187 error = "NOBLTHW";
|
|
188 break;
|
|
189 case DDERR_NOCLIPLIST:
|
|
190 error = "NOCLIPLIST";
|
|
191 break;
|
|
192 case DDERR_NOCLIPPERATTACHED:
|
|
193 error = "NOCLIPPERATTACHED";
|
|
194 break;
|
|
195 case DDERR_NOCOLORCONVHW:
|
|
196 error = "NOCOLORCONVHW";
|
|
197 break;
|
|
198 case DDERR_NOCOLORKEYHW:
|
|
199 error = "NOCOLORKEYHW";
|
|
200 break;
|
|
201 case DDERR_NOCOOPERATIVELEVELSET:
|
|
202 error = "NOCOOPERATIVELEVELSET";
|
|
203 break;
|
|
204 case DDERR_NODC:
|
|
205 error = "NODC";
|
|
206 break;
|
|
207 case DDERR_NOFLIPHW:
|
|
208 error = "NOFLIPHW";
|
|
209 break;
|
|
210 case DDERR_NOOVERLAYDEST:
|
|
211 error = "NOOVERLAYDEST";
|
|
212 break;
|
|
213 case DDERR_NOOVERLAYHW:
|
|
214 error = "NOOVERLAYHW";
|
|
215 break;
|
|
216 case DDERR_NOPALETTEATTACHED:
|
|
217 error = "NOPALETTEATTACHED";
|
|
218 break;
|
|
219 case DDERR_NOPALETTEHW:
|
|
220 error = "NOPALETTEHW";
|
|
221 break;
|
|
222 case DDERR_NORASTEROPHW:
|
|
223 error = "NORASTEROPHW";
|
|
224 break;
|
|
225 case DDERR_NOSTRETCHHW:
|
|
226 error = "NOSTRETCHHW";
|
|
227 break;
|
|
228 case DDERR_NOTAOVERLAYSURFACE:
|
|
229 error = "NOTAOVERLAYSURFACE";
|
|
230 break;
|
|
231 case DDERR_NOTFLIPPABLE:
|
|
232 error = "NOTFLIPPABLE";
|
|
233 break;
|
|
234 case DDERR_NOTFOUND:
|
|
235 error = "NOTFOUND";
|
|
236 break;
|
|
237 case DDERR_NOTLOCKED:
|
|
238 error = "NOTLOCKED";
|
|
239 break;
|
|
240 case DDERR_NOTPALETTIZED:
|
|
241 error = "NOTPALETTIZED";
|
|
242 break;
|
|
243 case DDERR_NOVSYNCHW:
|
|
244 error = "NOVSYNCHW";
|
|
245 break;
|
|
246 case DDERR_NOZOVERLAYHW:
|
|
247 error = "NOZOVERLAYHW";
|
|
248 break;
|
|
249 case DDERR_OUTOFCAPS:
|
|
250 error = "OUTOFCAPS";
|
|
251 break;
|
|
252 case DDERR_OUTOFMEMORY:
|
|
253 error = "OUTOFMEMORY";
|
|
254 break;
|
|
255 case DDERR_OUTOFVIDEOMEMORY:
|
|
256 error = "OUTOFVIDEOMEMORY";
|
|
257 break;
|
|
258 case DDERR_OVERLAPPINGRECTS:
|
|
259 error = "OVERLAPPINGRECTS";
|
|
260 break;
|
|
261 case DDERR_OVERLAYNOTVISIBLE:
|
|
262 error = "OVERLAYNOTVISIBLE";
|
|
263 break;
|
|
264 case DDERR_PALETTEBUSY:
|
|
265 error = "PALETTEBUSY";
|
|
266 break;
|
|
267 case DDERR_PRIMARYSURFACEALREADYEXISTS:
|
|
268 error = "PRIMARYSURFACEALREADYEXISTS";
|
|
269 break;
|
|
270 case DDERR_REGIONTOOSMALL:
|
|
271 error = "REGIONTOOSMALL";
|
|
272 break;
|
|
273 case DDERR_SURFACEBUSY:
|
|
274 error = "SURFACEBUSY";
|
|
275 break;
|
|
276 case DDERR_SURFACELOST:
|
|
277 error = "SURFACELOST";
|
|
278 break;
|
|
279 case DDERR_TOOBIGHEIGHT:
|
|
280 error = "TOOBIGHEIGHT";
|
|
281 break;
|
|
282 case DDERR_TOOBIGSIZE:
|
|
283 error = "TOOBIGSIZE";
|
|
284 break;
|
|
285 case DDERR_TOOBIGWIDTH:
|
|
286 error = "TOOBIGWIDTH";
|
|
287 break;
|
|
288 case DDERR_UNSUPPORTED:
|
|
289 error = "UNSUPPORTED";
|
|
290 break;
|
|
291 case DDERR_UNSUPPORTEDFORMAT:
|
|
292 error = "UNSUPPORTEDFORMAT";
|
|
293 break;
|
|
294 case DDERR_VERTICALBLANKINPROGRESS:
|
|
295 error = "VERTICALBLANKINPROGRESS";
|
|
296 break;
|
|
297 case DDERR_VIDEONOTACTIVE:
|
|
298 error = "VIDEONOTACTIVE";
|
|
299 break;
|
|
300 case DDERR_WASSTILLDRAWING:
|
|
301 error = "WASSTILLDRAWING";
|
|
302 break;
|
|
303 case DDERR_WRONGMODE:
|
|
304 error = "WRONGMODE";
|
|
305 break;
|
|
306 default:
|
|
307 error = "UNKNOWN";
|
|
308 break;
|
|
309 }
|
|
310 SDL_SetError("%s: %s", prefix, error);
|
|
311 }
|
|
312
|
|
313 static SDL_bool
|
|
314 PixelFormatToDDPIXELFORMAT(Uint32 format, LPDDPIXELFORMAT dst)
|
|
315 {
|
|
316 SDL_zerop(dst);
|
|
317 dst->dwSize = sizeof(*dst);
|
|
318
|
|
319 if (SDL_ISPIXELFORMAT_FOURCC(format)) {
|
|
320 dst->dwFlags = DDPF_FOURCC;
|
|
321 dst->dwFourCC = format;
|
|
322 } else if (SDL_ISPIXELFORMAT_INDEXED(format)) {
|
|
323 SDL_SetError("Indexed pixelformats are not supported.");
|
|
324 return SDL_FALSE;
|
|
325 } else {
|
|
326 int bpp;
|
|
327 Uint32 Rmask, Gmask, Bmask, Amask;
|
|
328 if (!SDL_PixelFormatEnumToMasks
|
|
329 (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
|
|
330 SDL_SetError("pixelformat not supported");
|
|
331 return SDL_FALSE;
|
|
332 }
|
|
333
|
|
334 if (!Rmask && !Gmask && !Bmask) {
|
|
335 dst->dwFlags = DDPF_ALPHA;
|
|
336 dst->dwAlphaBitDepth = bpp;
|
|
337 } else {
|
|
338 dst->dwFlags = DDPF_RGB;
|
|
339 dst->dwRGBBitCount = bpp;
|
|
340 dst->dwRBitMask = Rmask;
|
|
341 dst->dwGBitMask = Gmask;
|
|
342 dst->dwBBitMask = Bmask;
|
|
343
|
|
344 if (Amask) {
|
|
345 dst->dwFlags |= DDPF_ALPHAPIXELS;
|
|
346 dst->dwRGBAlphaBitMask = Amask;
|
|
347 }
|
|
348 }
|
|
349 }
|
|
350
|
|
351 return SDL_TRUE;
|
|
352 }
|
|
353
|
|
354 static SDL_bool
|
|
355 DDRAW_IsTextureFormatAvailable(IDirectDraw * ddraw, Uint32 display_format,
|
|
356 Uint32 texture_format)
|
|
357 {
|
|
358 int bpp;
|
|
359 Uint32 Rmask, Gmask, Bmask, Amask;
|
|
360
|
|
361 if (SDL_ISPIXELFORMAT_FOURCC(texture_format)) {
|
|
362 //TODO I don't expect DDRAW to support all 4CC formats, but I don't know which ones
|
|
363 return SDL_TRUE;
|
|
364 }
|
|
365 //These are only basic checks
|
|
366 if (SDL_ISPIXELFORMAT_INDEXED(texture_format)) {
|
|
367 return SDL_FALSE;
|
|
368 }
|
|
369
|
|
370 if (!SDL_PixelFormatEnumToMasks
|
|
371 (texture_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
|
|
372 return SDL_FALSE;
|
|
373 }
|
|
374
|
|
375 switch (bpp) {
|
|
376 case 4:
|
|
377 case 8:
|
|
378 case 16:
|
|
379 case 24:
|
|
380 case 32:
|
|
381 break;
|
|
382 default:
|
|
383 return SDL_FALSE;
|
|
384 }
|
|
385
|
|
386 return SDL_TRUE;
|
|
387 }
|
|
388
|
|
389 void
|
|
390 DDRAW_AddRenderDriver(_THIS)
|
|
391 {
|
|
392 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
|
393 SDL_RendererInfo *info = &DDRAW_RenderDriver.info;
|
|
394 SDL_DisplayMode *mode = &SDL_CurrentDisplay.desktop_mode;
|
|
395
|
|
396 if (data->ddraw) {
|
|
397 int i;
|
|
398 int formats[] = {
|
|
399 SDL_PIXELFORMAT_INDEX8,
|
|
400 SDL_PIXELFORMAT_RGB332,
|
|
401 SDL_PIXELFORMAT_RGB444,
|
|
402 SDL_PIXELFORMAT_RGB555,
|
|
403 SDL_PIXELFORMAT_ARGB4444,
|
|
404 SDL_PIXELFORMAT_ARGB1555,
|
|
405 SDL_PIXELFORMAT_RGB565,
|
|
406 SDL_PIXELFORMAT_RGB888,
|
|
407 SDL_PIXELFORMAT_ARGB8888,
|
|
408 SDL_PIXELFORMAT_ARGB2101010,
|
|
409 };
|
|
410
|
|
411 for (i = 0; i < SDL_arraysize(formats); ++i) {
|
|
412 if (DDRAW_IsTextureFormatAvailable
|
|
413 (data->ddraw, mode->format, formats[i])) {
|
|
414 info->texture_formats[info->num_texture_formats++] =
|
|
415 formats[i];
|
|
416 }
|
|
417 }
|
|
418
|
|
419 //TODO the fourcc formats should get fetched from IDirectDraw::GetFourCCCodes
|
|
420 info->texture_formats[info->num_texture_formats++] =
|
|
421 SDL_PIXELFORMAT_YV12;
|
|
422 info->texture_formats[info->num_texture_formats++] =
|
|
423 SDL_PIXELFORMAT_IYUV;
|
|
424 info->texture_formats[info->num_texture_formats++] =
|
|
425 SDL_PIXELFORMAT_YUY2;
|
|
426 info->texture_formats[info->num_texture_formats++] =
|
|
427 SDL_PIXELFORMAT_UYVY;
|
|
428 info->texture_formats[info->num_texture_formats++] =
|
|
429 SDL_PIXELFORMAT_YVYU;
|
|
430
|
|
431 SDL_AddRenderDriver(0, &DDRAW_RenderDriver);
|
|
432 }
|
|
433 }
|
|
434
|
|
435 SDL_Renderer *
|
|
436 DDRAW_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|
437 {
|
|
438 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
|
|
439 SDL_VideoData *videodata = (SDL_VideoData *) display->device->driverdata;
|
|
440 SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
|
|
441 SDL_Renderer *renderer;
|
|
442 DDRAW_RenderData *data;
|
|
443 HRESULT result;
|
|
444 DDSURFACEDESC ddsd;
|
|
445
|
|
446 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
|
|
447 if (!renderer) {
|
|
448 SDL_OutOfMemory();
|
|
449 return NULL;
|
|
450 }
|
|
451
|
|
452 data = (DDRAW_RenderData *) SDL_calloc(1, sizeof(*data));
|
|
453 if (!data) {
|
|
454 DDRAW_DestroyRenderer(renderer);
|
|
455 SDL_OutOfMemory();
|
|
456 return NULL;
|
|
457 }
|
|
458 data->ddraw = videodata->ddraw;
|
|
459
|
|
460 renderer->DisplayModeChanged = DDRAW_DisplayModeChanged;
|
|
461 renderer->CreateTexture = DDRAW_CreateTexture;
|
|
462 renderer->QueryTexturePixels = DDRAW_QueryTexturePixels;
|
|
463
|
|
464 renderer->SetTextureColorMod = DDRAW_SetTextureColorMod;
|
|
465 renderer->SetTextureAlphaMod = DDRAW_SetTextureAlphaMod;
|
|
466 renderer->SetTextureBlendMode = DDRAW_SetTextureBlendMode;
|
|
467 renderer->SetTextureScaleMode = DDRAW_SetTextureScaleMode;
|
|
468 renderer->UpdateTexture = DDRAW_UpdateTexture;
|
|
469 renderer->LockTexture = DDRAW_LockTexture;
|
|
470 renderer->UnlockTexture = DDRAW_UnlockTexture;
|
|
471 renderer->DirtyTexture = DDRAW_DirtyTexture;
|
|
472 renderer->RenderPoint = DDRAW_RenderPoint;
|
|
473 renderer->RenderLine = DDRAW_RenderLine;
|
|
474 renderer->RenderFill = DDRAW_RenderFill;
|
|
475 renderer->RenderCopy = DDRAW_RenderCopy;
|
|
476 renderer->RenderPresent = DDRAW_RenderPresent;
|
|
477 renderer->DestroyTexture = DDRAW_DestroyTexture;
|
|
478 renderer->DestroyRenderer = DDRAW_DestroyRenderer;
|
|
479 renderer->info = DDRAW_RenderDriver.info;
|
|
480 renderer->window = window->id;
|
|
481 renderer->driverdata = data;
|
|
482
|
|
483 renderer->info.flags = SDL_RENDERER_ACCELERATED;
|
|
484
|
|
485 SDL_zero(ddsd);
|
|
486 ddsd.dwSize = sizeof(ddsd);
|
|
487 ddsd.dwFlags = DDSD_CAPS;
|
|
488
|
|
489 if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
|
490 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
|
491 } else {
|
|
492 //TODO handle non fullscreen
|
|
493 SDL_SetError("DirectDraw renderer has only fullscreen implemented");
|
|
494 DDRAW_DestroyRenderer(renderer);
|
|
495 return NULL;
|
|
496 }
|
|
497
|
|
498 if (flags & SDL_RENDERER_PRESENTFLIP2) {
|
|
499 ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT;
|
|
500 ddsd.dwBackBufferCount = 2;
|
|
501 } else if (flags & SDL_RENDERER_PRESENTFLIP3) {
|
|
502 ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT;
|
|
503 ddsd.dwBackBufferCount = 3;
|
|
504 } else if (flags & SDL_RENDERER_PRESENTCOPY) {
|
|
505 //TODO what is the best approximation to this mode
|
|
506 } else {
|
|
507
|
|
508 }
|
|
509
|
|
510 if (flags & SDL_RENDERER_PRESENTVSYNC) {
|
|
511 SDL_SetError("DirectDraw renderer with v-sync is not implemented");
|
|
512 DDRAW_DestroyRenderer(renderer);
|
|
513 return NULL;
|
|
514 }
|
|
515
|
|
516 result =
|
|
517 data->ddraw->lpVtbl->SetCooperativeLevel(data->ddraw,
|
|
518 windowdata->hwnd,
|
|
519 DDSCL_NORMAL);
|
|
520 if (result != DD_OK) {
|
|
521 DDRAW_SetError("CreateDevice()", result);
|
|
522 DDRAW_DestroyRenderer(renderer);
|
|
523 return NULL;
|
|
524 }
|
|
525
|
|
526 result =
|
|
527 data->ddraw->lpVtbl->CreateSurface(data->ddraw, &ddsd, &data->primary,
|
|
528 NULL);
|
|
529 if (result != DD_OK) {
|
|
530 DDRAW_SetError("CreateDevice()", result);
|
|
531 DDRAW_DestroyRenderer(renderer);
|
|
532 return NULL;
|
|
533 }
|
|
534
|
|
535 return renderer;
|
|
536 }
|
|
537
|
|
538 static int
|
|
539 DDRAW_Reset(SDL_Renderer * renderer)
|
|
540 {
|
|
541 //TODO implement
|
|
542 /*D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
|
|
543 HRESULT result;
|
|
544
|
|
545 result = IDirect3DDevice9_Reset(data->device, &data->pparams);
|
|
546 if (FAILED(result)) {
|
|
547 if (result == D3DERR_DEVICELOST) {
|
|
548 /* Don't worry about it, we'll reset later... *
|
|
549 return 0;
|
|
550 } else {
|
|
551 D3D_SetError("Reset()", result);
|
|
552 return -1;
|
|
553 }
|
|
554 }
|
|
555 IDirect3DDevice9_SetVertexShader(data->device, NULL);
|
|
556 IDirect3DDevice9_SetFVF(data->device,
|
|
557 D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
|
558 IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
|
|
559 D3DCULL_NONE);
|
|
560 IDirect3DDevice9_SetRenderState(data->device, D3DRS_LIGHTING, FALSE); */
|
|
561 return 0;
|
|
562 }
|
|
563
|
|
564 static int
|
|
565 DDRAW_DisplayModeChanged(SDL_Renderer * renderer)
|
|
566 {
|
|
567 //TODO implement
|
|
568 /*D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata;
|
|
569 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
|
|
570 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
|
|
571
|
|
572 data->pparams.BackBufferWidth = window->w;
|
|
573 data->pparams.BackBufferHeight = window->h;
|
|
574 if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
|
575 data->pparams.BackBufferFormat =
|
|
576 PixelFormatToD3DFMT(display->fullscreen_mode.format);
|
|
577 } else {
|
|
578 data->pparams.BackBufferFormat = D3DFMT_UNKNOWN;
|
|
579 }
|
|
580 return D3D_Reset(renderer); */
|
|
581 return 0;
|
|
582 }
|
|
583
|
|
584 static int
|
|
585 DDRAW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|
586 {
|
|
587 DDRAW_RenderData *renderdata = (DDRAW_RenderData *) renderer->driverdata;
|
|
588 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
|
|
589 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
|
|
590 Uint32 display_format = display->current_mode.format;
|
|
591 DDRAW_TextureData *data;
|
|
592 DDSURFACEDESC ddsd;
|
|
593 HRESULT result;
|
|
594
|
|
595 data = (DDRAW_TextureData *) SDL_calloc(1, sizeof(*data));
|
|
596 if (!data) {
|
|
597 SDL_OutOfMemory();
|
|
598 return -1;
|
|
599 }
|
|
600
|
|
601 SDL_zero(ddsd);
|
|
602 ddsd.dwSize = sizeof(ddsd);
|
|
603 ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_HEIGHT | DDSD_WIDTH;
|
|
604 ddsd.dwWidth = texture->w;
|
|
605 ddsd.dwHeight = texture->h;
|
|
606
|
|
607
|
|
608 if (!PixelFormatToDDPIXELFORMAT(texture->format, &ddsd.ddpfPixelFormat)) {
|
|
609 SDL_free(data);
|
|
610 return -1;
|
|
611 }
|
|
612
|
|
613 texture->driverdata = data;
|
|
614
|
|
615 result =
|
|
616 renderdata->ddraw->lpVtbl->CreateSurface(renderdata->ddraw, &ddsd,
|
|
617 &data->surface, NULL);
|
|
618 if (result != DD_OK) {
|
|
619 SDL_free(data);
|
|
620 DDRAW_SetError("CreateTexture", result);
|
|
621 return -1;
|
|
622 }
|
|
623
|
|
624 return 0;
|
|
625 }
|
|
626
|
|
627 static int
|
|
628 DDRAW_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
629 void **pixels, int *pitch)
|
|
630 {
|
|
631 //TODO implement
|
|
632 SDL_SetError("QueryTexturePixels is not implemented");
|
|
633 return -1;
|
|
634 }
|
|
635
|
|
636 static int
|
|
637 DDRAW_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
|
|
638 {
|
|
639 return 0;
|
|
640 }
|
|
641
|
|
642 static int
|
|
643 DDRAW_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
|
|
644 {
|
|
645 return 0;
|
|
646 }
|
|
647
|
|
648 static int
|
|
649 DDRAW_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
|
|
650 {
|
|
651 switch (texture->blendMode) {
|
|
652 case SDL_BLENDMODE_NONE:
|
|
653 return 0;
|
|
654 default:
|
|
655 SDL_Unsupported();
|
|
656 texture->blendMode = SDL_BLENDMODE_NONE;
|
|
657 return -1;
|
|
658 }
|
|
659 }
|
|
660
|
|
661 static int
|
|
662 DDRAW_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
|
|
663 {
|
|
664 switch (texture->scaleMode) {
|
|
665 case SDL_TEXTURESCALEMODE_NONE:
|
|
666 default:
|
|
667 SDL_Unsupported();
|
|
668 texture->scaleMode = SDL_TEXTURESCALEMODE_NONE;
|
|
669 return -1;
|
|
670 }
|
|
671 return 0;
|
|
672 }
|
|
673
|
|
674 static int
|
|
675 DDRAW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
676 const SDL_Rect * rect, const void *pixels, int pitch)
|
|
677 {
|
|
678 DDRAW_TextureData *data = (DDRAW_TextureData *) texture->driverdata;
|
|
679
|
|
680 //TODO implement
|
|
681 SDL_SetError("UpdateTexture is not implemented");
|
|
682 return 0;
|
|
683 }
|
|
684
|
|
685 static int
|
|
686 DDRAW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
687 const SDL_Rect * rect, int markDirty, void **pixels,
|
|
688 int *pitch)
|
|
689 {
|
|
690 DDRAW_TextureData *data = (DDRAW_TextureData *) texture->driverdata;
|
|
691 HRESULT result;
|
|
692 DDSURFACEDESC ddsd;
|
|
693
|
|
694 SDL_zero(ddsd);
|
|
695 ddsd.dwSize = sizeof(ddsd);
|
|
696
|
|
697 /**
|
|
698 * On a Axim x51v locking a subrect returns the startaddress of the whole surface,
|
|
699 * wheras on my ASUS MyPal 696 the startaddress of the locked area is returned,
|
|
700 * thats why I always lock the whole surface and calculate the pixels pointer by hand.
|
|
701 * This shouldn't be a speed problem, as multiple locks aren't available on DDraw Mobile
|
|
702 * see http://msdn.microsoft.com/en-us/library/ms858221.aspx
|
|
703 */
|
|
704
|
|
705 result = data->surface->lpVtbl->Lock(data->surface, NULL, &ddsd, 0, NULL);
|
|
706 if (result != DD_OK) {
|
|
707 DDRAW_SetError("LockRect()", result);
|
|
708 return -1;
|
|
709 }
|
|
710
|
|
711 *pixels = ddsd.lpSurface + rect->y * ddsd.lPitch + rect->x * ddsd.lXPitch;
|
|
712 *pitch = ddsd.lPitch;
|
|
713 return 0;
|
|
714 }
|
|
715
|
|
716 static void
|
|
717 DDRAW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|
718 {
|
|
719 DDRAW_TextureData *data = (DDRAW_TextureData *) texture->driverdata;
|
|
720
|
|
721 data->surface->lpVtbl->Unlock(data->surface, NULL);
|
|
722 }
|
|
723
|
|
724 static void
|
|
725 DDRAW_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
726 int numrects, const SDL_Rect * rects)
|
|
727 {
|
|
728 }
|
|
729
|
|
730 static void
|
|
731 DDRAW_SetBlendMode(DDRAW_RenderData * data, int blendMode)
|
|
732 {
|
|
733 switch (blendMode) {
|
|
734
|
|
735 }
|
|
736 }
|
|
737
|
|
738 static int
|
|
739 DDRAW_RenderPoint(SDL_Renderer * renderer, int x, int y)
|
|
740 {
|
|
741 return -1;
|
|
742 }
|
|
743
|
|
744 static int
|
|
745 DDRAW_RenderLine(SDL_Renderer * renderer, int x1, int y1, int x2, int y2)
|
|
746 {
|
|
747 return -1;
|
|
748 }
|
|
749
|
|
750 static int
|
|
751 DDRAW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect)
|
|
752 {
|
|
753 return -1;
|
|
754 }
|
|
755
|
|
756 static int
|
|
757 DDRAW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
758 const SDL_Rect * srcrect, const SDL_Rect * dstrect)
|
|
759 {
|
|
760 DDRAW_RenderData *data = (DDRAW_RenderData *) renderer->driverdata;
|
|
761 DDRAW_TextureData *texturedata =
|
|
762 (DDRAW_TextureData *) texture->driverdata;
|
|
763 HRESULT result;
|
|
764 RECT srcr;
|
|
765 RECT dstr;
|
|
766 DDBLTFX bltfx;
|
|
767
|
|
768 srcr.left = srcrect->x;
|
|
769 srcr.top = srcrect->y;
|
|
770 srcr.right = srcrect->x + srcrect->w;
|
|
771 srcr.bottom = srcrect->y + srcrect->h;
|
|
772
|
|
773 dstr.left = dstrect->x;
|
|
774 dstr.top = dstrect->y;
|
|
775 dstr.right = dstrect->x + dstrect->w;
|
|
776 dstr.bottom = dstrect->y + dstrect->h;
|
|
777
|
|
778 SDL_zero(bltfx);
|
|
779 bltfx.dwSize = sizeof(bltfx);
|
|
780 bltfx.dwROP = SRCCOPY;
|
|
781
|
|
782 data->primary->lpVtbl->Blt(data->primary, &dstr, texturedata->surface,
|
|
783 &srcr, DDBLT_ROP, &bltfx);
|
|
784
|
|
785 return 0;
|
|
786 }
|
|
787
|
|
788 static void
|
|
789 DDRAW_RenderPresent(SDL_Renderer * renderer)
|
|
790 {
|
|
791 DDRAW_RenderData *data = (DDRAW_RenderData *) renderer->driverdata;
|
|
792 HRESULT result;
|
|
793
|
|
794 return;
|
|
795
|
|
796 result =
|
|
797 data->primary->lpVtbl->Flip(data->primary, NULL, DDFLIP_INTERVAL1);
|
|
798 if (result != DD_OK) {
|
|
799 DDRAW_SetError("Present()", result);
|
|
800 }
|
|
801 }
|
|
802
|
|
803 static void
|
|
804 DDRAW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|
805 {
|
|
806 DDRAW_TextureData *data = (DDRAW_TextureData *) texture->driverdata;
|
|
807
|
|
808 if (!data) {
|
|
809 return;
|
|
810 }
|
|
811
|
|
812 data->surface->lpVtbl->Release(data->surface);
|
|
813 SDL_free(data);
|
|
814 texture->driverdata = NULL;
|
|
815 }
|
|
816
|
|
817 static void
|
|
818 DDRAW_DestroyRenderer(SDL_Renderer * renderer)
|
|
819 {
|
|
820 DDRAW_RenderData *data = (DDRAW_RenderData *) renderer->driverdata;
|
|
821
|
|
822 if (data) {
|
|
823 data->primary->lpVtbl->Release(data->primary);
|
|
824 SDL_free(data);
|
|
825 }
|
|
826 SDL_free(renderer);
|
|
827 }
|
|
828
|
|
829 #endif /* SDL_VIDEO_RENDER_DDRAW */
|
|
830
|
|
831 /* vi: set ts=4 sw=4 expandtab: */
|