comparison src/video/windows/SDL_gapirender.c @ 5062:e8916fe9cfc8

Fixed bug #925 Changed "win32" to "windows"
author Sam Lantinga <slouken@libsdl.org>
date Thu, 20 Jan 2011 18:04:05 -0800
parents src/video/win32/SDL_gapirender.c@aa8888658021
children c2539ff054c8
comparison
equal deleted inserted replaced
5061:9e9940eae455 5062:e8916fe9cfc8
1 /***************************************************************************
2 * Copyright (C) 2010 by Andrey Afletdinov <afletdinov@gmail.com> *
3 * *
4 * WinCE RAW/GAPI video driver *
5 * *
6 * Part of the SDL - (Simple DirectMedia Layer) *
7 * http://www.libsdl.org *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the *
21 * Free Software Foundation, Inc., *
22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23 ***************************************************************************/
24
25 #include "SDL_config.h"
26
27 #if SDL_VIDEO_RENDER_GAPI
28
29 #include "SDL_windowsvideo.h"
30 #include "SDL_windowswindow.h"
31 #include "../SDL_yuv_sw_c.h"
32
33 // RawFrameBufferInfo
34 typedef struct
35 {
36 WORD wFormat;
37 WORD wBPP;
38 VOID *pFramePointer;
39 int cxStride;
40 int cyStride;
41 int cxPixels;
42 int cyPixels;
43 } RawFrameBufferInfo;
44
45 // GXDeviceInfo
46 typedef struct
47 {
48 long Version;
49 void* pvFrameBuffer;
50 unsigned long cbStride;
51 unsigned long cxWidth;
52 unsigned long cyHeight;
53 unsigned long cBPP;
54 unsigned long ffFormat;
55 char unknown[0x84 - 7 * 4];
56 } GXDeviceInfo;
57
58 // wince: GXDisplayProperties
59 struct GXDisplayProperties
60 {
61 DWORD cxWidth;
62 DWORD cyHeight;
63 long cbxPitch;
64 long cbyPitch;
65 long cBPP;
66 DWORD ffFormat;
67 };
68
69 // gx.dll
70 typedef int (*PFNGXOpenDisplay)(HWND hWnd, DWORD dwFlags);
71 typedef int (*PFNGXCloseDisplay)();
72 typedef void* (*PFNGXBeginDraw)();
73 typedef int (*PFNGXEndDraw)();
74 typedef struct GXDisplayProperties (*PFNGXGetDisplayProperties)();
75 typedef int (*PFNGXSuspend)();
76 typedef int (*PFNGXResume)();
77
78 typedef struct
79 {
80 // gx.dll
81 HMODULE hGapiLib;
82 PFNGXOpenDisplay GXOpenDisplay;
83 PFNGXCloseDisplay GXCloseDisplay;
84 PFNGXBeginDraw GXBeginDraw;
85 PFNGXEndDraw GXEndDraw;
86 PFNGXGetDisplayProperties GXGetDisplayProperties;
87 PFNGXSuspend GXSuspend;
88 PFNGXResume GXResume;
89 } GapiInfo;
90
91 //#ifndef DM_DISPLAYORIENTATION
92 //#define DM_DISPLAYORIENTATION 0x00800000L
93 //#endif
94
95 #define FORMAT_565 1
96 #define FORMAT_555 2
97 #define FORMAT_OTHER 3
98
99 #define GETRAWFRAMEBUFFER 0x00020001
100 #define GETGXINFO 0x00020000
101
102 #define kfPalette 0x10
103 #define kfDirect 0x20
104 #define kfDirect555 0x40
105 #define kfDirect565 0x80
106
107 #define GX_FULLSCREEN 0x01
108
109 enum ScreenOrientation { ORIENTATION_UNKNOWN = -1, ORIENTATION_UP = DMDO_0, ORIENTATION_DOWN = DMDO_180, ORIENTATION_LEFT = DMDO_270, ORIENTATION_RIGHT = DMDO_90 };
110 enum ScreenGeometry { GEOMETRY_UNKNOWN, GEOMETRY_PORTRAIT, GEOMETRY_LANDSCAPE, GEOMETRY_SQUARE };
111 enum FrameBufferFlags { FB_SKIP_OFFSET = 0x0001, FB_RAW_MODE = 0x0002, FB_SUSPENDED = 0x0004 };
112
113 // private framebuffer info
114 typedef struct
115 {
116 int width;
117 int height;
118 int xpitch;
119 int ypitch;
120 int offset;
121 } FrameBufferInfo;
122
123 // private display data
124 typedef struct
125 {
126 unsigned char* pixels; // video memory
127 int format; // video format
128 FrameBufferInfo fb; // framebuffer geometry
129 GapiInfo* gapi; // GAPI module
130 int userOrientation;
131 int systemOrientation;
132 int hardwareGeometry;
133 int flags; // fb flags
134 float scale; // scale pointer position
135 int debug;
136
137 } WINCE_RenderData;
138
139 typedef struct
140 {
141 SDL_SW_YUVTexture *yuv;
142 Uint32 format;
143 void *pixels;
144 int pitch;
145
146 } WINCE_TextureData;
147
148
149 // system func
150 SDL_Renderer* WINCE_CreateRenderer(SDL_Window* window, Uint32 flags);
151 void WINCE_DestroyRenderer(SDL_Renderer* renderer);
152
153 int WINCE_CreateTexture(SDL_Renderer* renderer, SDL_Texture* texture);
154 void WINCE_DestroyTexture(SDL_Renderer* renderer, SDL_Texture* texture);
155 int WINCE_QueryTexturePixels(SDL_Renderer* renderer, SDL_Texture* texture, void** pixels, int* pitch);
156 int WINCE_UpdateTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, const void* pixels, int pitch);
157 int WINCE_LockTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, int dirty, void** pixels, int* pitch);
158 void WINCE_UnlockTexture(SDL_Renderer* renderer, SDL_Texture* texture);
159
160 int WINCE_Available(void);
161 void WINCE_SetupOrientation(WINCE_RenderData* data, int width, int height);
162
163 int WINCE_RenderCopy(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* srect, const SDL_Rect* drect);
164 void WINCE_ShowWindow(_THIS, SDL_Window* window, int visible);
165
166 void WINCE_RenderPresent(SDL_Renderer* renderer);
167 int WINCE_RenderDrawPoints(SDL_Renderer* renderer, const SDL_Point* points, int count);
168 int WINCE_RenderDrawLines(SDL_Renderer* renderer, const SDL_Point* points, int count);
169 int WINCE_RenderDrawRects(SDL_Renderer* renderer, const SDL_Rect ** rects, int count);
170 int WINCE_RenderFillRects(SDL_Renderer* renderer, const SDL_Rect** rects, int count);
171
172 void WINCE_PointerCoordinateTransform(SDL_Window* window, POINT* pt);
173 void WINCE_DumpVideoInfo(WINCE_RenderData* data);
174 void WINCE_PortraitTransform(WINCE_RenderData* data, int width, int height);
175 void WINCE_LandscapeTransform(WINCE_RenderData* data, int width, int height);
176 void WINCE_SquareTransform(WINCE_RenderData* data, int width, int height);
177 int WINCE_FixedGeometry(FrameBufferInfo* fb, int bpp, int debug);
178 int WINCE_GetDMOrientation(void);
179 int WINCE_SetDMOrientation(int orientation);
180 void WINCE_UpdateYUVTextureData(SDL_Texture* texture);
181
182 // gapi engine specific
183 int GAPI_Init(WINCE_RenderData* data, HWND hwnd);
184 void GAPI_Quit(WINCE_RenderData* data);
185
186 // raw engine specific
187 int RAW_Init(WINCE_RenderData* data);
188 void RAW_Quit(WINCE_RenderData* data);
189
190 // tools
191 void FrameBufferRotate(FrameBufferInfo* src, int orientation);
192 int GetFrameBufferOrientation(const FrameBufferInfo* src);
193 void PointerRotate(POINT* pt, const FrameBufferInfo* fb, int orientation);
194 void FrameBufferInitialize(FrameBufferInfo* fb);
195 void FrameBufferDumpInfo(const FrameBufferInfo* fb, const char*);
196 const char* GetOrientationName(int orientation);
197 void UpdateLine16to16(const FrameBufferInfo* fb, const Uint16* src, Uint16* dst, Uint16 width);
198
199 // stdlib
200 inline int __abs(int x){ return x < 0 ? -x : x; };
201 inline void __swap(int* a, int* b){ int t = *a; *a = *b; *b = t; };
202
203 #define GAPI_RENDER_NAME "gapi"
204 #define RAW_RENDER_NAME "raw"
205 //
206 SDL_RenderDriver GAPI_RenderDriver = {
207 WINCE_CreateRenderer,
208 {
209 GAPI_RENDER_NAME,
210 (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD),
211 (SDL_TEXTUREMODULATE_NONE),
212 (SDL_BLENDMODE_NONE),
213 (SDL_SCALEMODE_NONE),
214 7,
215 {
216 SDL_PIXELFORMAT_RGB555,
217 SDL_PIXELFORMAT_RGB565,
218 SDL_PIXELFORMAT_YV12,
219 SDL_PIXELFORMAT_IYUV,
220 SDL_PIXELFORMAT_YUY2,
221 SDL_PIXELFORMAT_UYVY,
222 SDL_PIXELFORMAT_YVYU
223 },
224 0,
225 0
226 }
227 };
228
229 SDL_RenderDriver RAW_RenderDriver = {
230 WINCE_CreateRenderer,
231 {
232 RAW_RENDER_NAME,
233 (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD),
234 (SDL_TEXTUREMODULATE_NONE),
235 (SDL_BLENDMODE_NONE),
236 (SDL_SCALEMODE_NONE),
237 7,
238 {
239 SDL_PIXELFORMAT_RGB555,
240 SDL_PIXELFORMAT_RGB565,
241 SDL_PIXELFORMAT_YV12,
242 SDL_PIXELFORMAT_IYUV,
243 SDL_PIXELFORMAT_YUY2,
244 SDL_PIXELFORMAT_UYVY,
245 SDL_PIXELFORMAT_YVYU
246 },
247 0,
248 0
249 }
250 };
251
252 int WINCE_Available(void)
253 {
254 const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER");
255
256 // raw check
257 RawFrameBufferInfo rfbi = { 0 };
258 HDC hdc = GetDC(NULL);
259 int render_raw = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi);
260 ReleaseDC(NULL, hdc);
261
262 if(render_raw != 0 && rfbi.cxPixels != 0 && rfbi.cyPixels != 0 &&
263 rfbi.pFramePointer != 0 && rfbi.cxStride != 0 && rfbi.cyStride != 0)
264 render_raw = 1;
265
266 if(preferably && 0 == SDL_strcasecmp(preferably, RAW_RENDER_NAME)) return 0 != render_raw;
267
268 // gapi check
269 HMODULE render_gapi = LoadLibrary(TEXT("\\Windows\\gx.dll"));
270 if(0 == render_gapi)
271 render_gapi = LoadLibrary(TEXT("gx.dll"));
272 FreeLibrary(render_gapi);
273
274 if(preferably && 0 == SDL_strcasecmp(preferably, GAPI_RENDER_NAME)) return 0 != render_gapi;
275
276 return 0 != render_raw || 0 != render_gapi;
277 }
278
279 void WINCE_AddRenderDriver(_THIS)
280 {
281 HDC hdc;
282 HMODULE render_gapi;
283 int render_raw, ii;
284 const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER");
285
286 // raw check
287 RawFrameBufferInfo rfbi = { 0 };
288 hdc = GetDC(NULL);
289 render_raw = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi);
290 ReleaseDC(NULL, hdc);
291
292 if(render_raw != 0 && rfbi.cxPixels != 0 && rfbi.cyPixels != 0 &&
293 rfbi.pFramePointer != 0 && rfbi.cxStride != 0 && rfbi.cyStride != 0)
294 render_raw = 1;
295
296 // gapi check
297 render_gapi = LoadLibrary(TEXT("\\Windows\\gx.dll"));
298 if(0 == render_gapi)
299 render_gapi = LoadLibrary(TEXT("gx.dll"));
300
301 if(render_gapi)
302 FreeLibrary(render_gapi);
303
304 for(ii = 0; ii < _this->num_displays; ++ii)
305 {
306 if(preferably)
307 {
308 if(0 == SDL_strcasecmp(preferably, RAW_RENDER_NAME) && render_raw)
309 SDL_AddRenderDriver(&_this->displays[ii], &RAW_RenderDriver);
310 else
311 if(0 == SDL_strcasecmp(preferably, GAPI_RENDER_NAME) && render_gapi)
312 SDL_AddRenderDriver(&_this->displays[ii], &GAPI_RenderDriver);
313 }
314 else
315 {
316 if(render_raw)
317 SDL_AddRenderDriver(&_this->displays[ii], &RAW_RenderDriver);
318 if(render_gapi)
319 SDL_AddRenderDriver(&_this->displays[ii], &GAPI_RenderDriver);
320 }
321 }
322 }
323
324 SDL_Renderer* WINCE_CreateRenderer(SDL_Window* window, Uint32 flags)
325 {
326 SDL_VideoDisplay* display = window->display;
327 SDL_DisplayMode* displayMode = &display->current_mode;
328 SDL_WindowData* windowdata = (SDL_WindowData *) window->driverdata;
329 SDL_Renderer* renderer;
330 WINCE_RenderData* data;
331 int bpp;
332 Uint32 Rmask, Gmask, Bmask, Amask;
333
334 if(!(window->flags & SDL_WINDOW_FULLSCREEN))
335 window->flags |= SDL_WINDOW_FULLSCREEN;
336
337 if(!SDL_PixelFormatEnumToMasks(displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask))
338 {
339 SDL_SetError("Unknown display format");
340 return NULL;
341 }
342
343 switch(window->fullscreen_mode.format)
344 {
345 case SDL_PIXELFORMAT_RGB555:
346 case SDL_PIXELFORMAT_RGB565:
347 break;
348
349 default:
350 SDL_SetError("Support only 16 or 15 bpp");
351 return NULL;
352 }
353
354 renderer = (SDL_Renderer*) SDL_calloc(1, sizeof(SDL_Renderer));
355 if(!renderer)
356 {
357 SDL_OutOfMemory();
358 return NULL;
359 }
360
361 data = (WINCE_RenderData*) SDL_calloc(1, sizeof(WINCE_RenderData));
362 if(!data)
363 {
364 WINCE_DestroyRenderer(renderer);
365 SDL_OutOfMemory();
366 return NULL;
367 }
368
369 // initialize internal engine
370 if(!RAW_Init(data) && !GAPI_Init(data, windowdata->hwnd))
371 {
372 WINCE_DestroyRenderer(renderer);
373 return NULL;
374 }
375
376
377 // set debug
378 data->debug = SDL_getenv("DEBUG_VIDEO_GAPI") || SDL_getenv("GAPI_RENDERER_DEBUG") ? 1 : 0;
379 #if defined(DEBUG_VIDEO_GAPI) || defined(GAPI_RENDERER_DEBUG)
380 data->debug = 1;
381 #endif
382
383 windowdata->videodata->render = data->gapi ? RENDER_GAPI : RENDER_RAW;
384 windowdata->videodata->CoordTransform = WINCE_PointerCoordinateTransform;
385
386 window->display->device->MaximizeWindow = NULL;
387 window->display->device->MinimizeWindow = NULL;
388
389 WINCE_SetupOrientation(data, window->w, window->h);
390
391 renderer->CreateTexture = WINCE_CreateTexture;
392 renderer->DestroyTexture = WINCE_DestroyTexture;
393 renderer->QueryTexturePixels = WINCE_QueryTexturePixels;
394 renderer->UpdateTexture = WINCE_UpdateTexture;
395 renderer->LockTexture = WINCE_LockTexture;
396 renderer->UnlockTexture = WINCE_UnlockTexture;
397
398 renderer->RenderCopy = WINCE_RenderCopy;
399 renderer->DestroyRenderer = WINCE_DestroyRenderer;
400
401 renderer->RenderPresent = WINCE_RenderPresent;
402 renderer->RenderDrawPoints = WINCE_RenderDrawPoints;
403 renderer->RenderDrawLines = WINCE_RenderDrawLines;
404 renderer->RenderDrawRects = WINCE_RenderDrawRects;
405 renderer->RenderFillRects = WINCE_RenderFillRects;
406
407 renderer->info = data->gapi ? GAPI_RenderDriver.info : RAW_RenderDriver.info;
408
409 renderer->window = window;
410 renderer->driverdata = data;
411
412 return renderer;
413 }
414
415 void WINCE_DestroyRenderer(SDL_Renderer* renderer)
416 {
417 WINCE_RenderData *renderdata = (WINCE_RenderData*) renderer->driverdata;
418
419 if(renderdata)
420 {
421 if(renderdata->gapi)
422 GAPI_Quit(renderdata);
423 else
424 RAW_Quit(renderdata);
425
426 SDL_free(renderdata);
427 }
428
429 SDL_free(renderer);
430 }
431
432 int WINCE_CreateTexture(SDL_Renderer* renderer, SDL_Texture* texture)
433 {
434 WINCE_TextureData* texturedata = (WINCE_TextureData*) SDL_calloc(1, sizeof(WINCE_TextureData));
435 if(NULL == texturedata)
436 {
437 SDL_OutOfMemory();
438 return -1;
439 }
440
441 texturedata->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
442 texturedata->pixels = SDL_malloc(texture->h * texturedata->pitch);
443 if(NULL == texturedata->pixels)
444 {
445 SDL_OutOfMemory();
446 return -1;
447 }
448
449 if(SDL_ISPIXELFORMAT_FOURCC(texture->format))
450 {
451 texturedata->yuv = SDL_SW_CreateYUVTexture(texture->format, texture->w, texture->h);
452 if(NULL == texturedata->yuv)
453 {
454 SDL_OutOfMemory();
455 return -1;
456 }
457 SDL_Window* window = renderer->window;
458 SDL_VideoDisplay* display = window->display;
459 texturedata->format = display->current_mode.format;
460 }
461 else
462 {
463 texturedata->yuv = NULL;
464 texturedata->format = texture->format;
465 }
466
467 texture->driverdata = texturedata;
468
469 return 0;
470 }
471
472 void WINCE_DestroyTexture(SDL_Renderer* renderer, SDL_Texture* texture)
473 {
474 WINCE_TextureData *texturedata = (WINCE_TextureData*) texture->driverdata;
475
476 if(texturedata)
477 {
478 if(texturedata->yuv) SDL_SW_DestroyYUVTexture(texturedata->yuv);
479 if(texturedata->pixels) SDL_free(texturedata->pixels);
480 SDL_free(texturedata);
481 texture->driverdata = NULL;
482 }
483 }
484
485 int WINCE_QueryTexturePixels(SDL_Renderer* renderer, SDL_Texture* texture, void** pixels, int* pitch)
486 {
487 WINCE_TextureData* texturedata = (WINCE_TextureData*) texture->driverdata;
488
489 if(texturedata->yuv)
490 return SDL_SW_QueryYUVTexturePixels(texturedata->yuv, pixels, pitch);
491
492 *pixels = texturedata->pixels;
493 *pitch = texturedata->pitch;
494
495 return 0;
496 }
497
498 int WINCE_UpdateTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, const void* pixels, int pitch)
499 {
500 WINCE_TextureData* texturedata = (WINCE_TextureData*) texture->driverdata;
501
502 if(texturedata->yuv)
503 {
504 if(SDL_SW_UpdateYUVTexture(texturedata->yuv, rect, pixels, pitch) < 0)
505 return -1;
506 WINCE_UpdateYUVTextureData(texture);
507 return 0;
508 }
509
510 if(0 < rect->w && 0 < rect->h)
511 {
512 const unsigned char *src = ((const unsigned char*) pixels);
513 unsigned char *dst = ((unsigned char*) texturedata->pixels) +
514 rect->y * texturedata->pitch +
515 rect->x * SDL_BYTESPERPIXEL(texture->format);
516 int length = rect->w * SDL_BYTESPERPIXEL(texture->format);
517 int height = rect->h;
518
519 while(height--)
520 {
521 SDL_memcpy(dst, src, length);
522 dst += texturedata->pitch;
523 src += pitch;
524 }
525 }
526
527 return 0;
528 }
529
530 int WINCE_LockTexture(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* rect, int dirty, void** pixels, int* pitch)
531 {
532 WINCE_TextureData *texturedata = (WINCE_TextureData*) texture->driverdata;
533
534 if(texturedata->yuv)
535 return SDL_SW_LockYUVTexture(texturedata->yuv, rect, dirty, pixels, pitch);
536
537 *pixels = (void *) ((unsigned char*) texturedata->pixels +
538 rect->y * texturedata->pitch +
539 rect->x * SDL_BYTESPERPIXEL(texture->format));
540 *pitch = texturedata->pitch;
541 }
542
543 void WINCE_UnlockTexture(SDL_Renderer* renderer, SDL_Texture* texture)
544 {
545 WINCE_TextureData *texturedata = (WINCE_TextureData*) texture->driverdata;
546
547 if(texturedata->yuv)
548 {
549 SDL_SW_UnlockYUVTexture(texturedata->yuv);
550 WINCE_UpdateYUVTextureData(texture);
551 }
552 }
553
554 int WINCE_RenderCopy(SDL_Renderer* renderer, SDL_Texture* texture, const SDL_Rect* srect, const SDL_Rect* drect)
555 {
556 WINCE_RenderData* dstdata = (WINCE_RenderData*) renderer->driverdata;
557 WINCE_TextureData* srcdata = (WINCE_TextureData*) texture->driverdata;
558
559 if((dstdata->flags & FB_SUSPENDED) ||
560 0 >= srect->w || 0 >= srect->h) return;
561
562 // lock gapi
563 if(dstdata->gapi) dstdata->gapi->GXBeginDraw();
564
565 const unsigned char *src = ((const unsigned char*) srcdata->pixels);
566 unsigned char *dst = dstdata->pixels + (dstdata->flags & FB_SKIP_OFFSET ? 0 : dstdata->fb.offset) +
567 drect->y * dstdata->fb.ypitch +
568 drect->x * dstdata->fb.xpitch;
569 if(srcdata->yuv)
570 {
571 return SDL_SW_CopyYUVToRGB(srcdata->yuv,
572 srect, srcdata->format,
573 drect->w, drect->h, dst,
574 dstdata->fb.ypitch);
575 }
576 else
577 {
578 int height = drect->h;
579 int length = drect->w * SDL_BYTESPERPIXEL(texture->format); // in bytes
580
581 while(height--)
582 {
583 switch(SDL_BYTESPERPIXEL(texture->format))
584 {
585 case 2: UpdateLine16to16(&dstdata->fb, (Uint16*) src, (Uint16*) dst, length >> 1); break;
586
587 default: break;
588 }
589
590 dst += dstdata->fb.ypitch;
591 src += srcdata->pitch;
592 }
593 }
594
595 // unlock gapi
596 if(dstdata->gapi) dstdata->gapi->GXEndDraw();
597
598 return 0;
599 }
600
601 void WINCE_RenderPresent(SDL_Renderer* renderer)
602 {
603 }
604
605 int WINCE_RenderDrawPoints(SDL_Renderer* renderer, const SDL_Point* points, int count)
606 {
607 SDL_Unsupported();
608 return -1;
609 }
610
611 int WINCE_RenderDrawLines(SDL_Renderer* renderer, const SDL_Point* points, int count)
612 {
613 SDL_Unsupported();
614 return -1;
615 }
616
617 int WINCE_RenderDrawRects(SDL_Renderer* renderer, const SDL_Rect ** rects, int count)
618 {
619 SDL_Unsupported();
620 return -1;
621 }
622
623 int WINCE_RenderFillRects(SDL_Renderer* renderer, const SDL_Rect** rects, int count)
624 {
625 SDL_Unsupported();
626 return -1;
627 }
628
629
630
631 void WINCE_SetupOrientation(WINCE_RenderData* data, int width, int height)
632 {
633 const float maxW1 = GetSystemMetrics(SM_CXSCREEN) > GetSystemMetrics(SM_CYSCREEN) ? GetSystemMetrics(SM_CXSCREEN) : GetSystemMetrics(SM_CYSCREEN);
634 const float maxW2 = data->fb.width > data->fb.height ? data->fb.width : data->fb.height;
635
636 // scale define
637 data->scale = maxW2 / maxW1;
638
639 // init fb values
640 FrameBufferInitialize(&data->fb);
641
642 // orientation values
643 data->userOrientation = ORIENTATION_UP;
644 data->systemOrientation = WINCE_GetDMOrientation();
645 data->hardwareGeometry = data->fb.width == data->fb.height ? GEOMETRY_SQUARE :
646 (data->fb.width < data->fb.height ? GEOMETRY_PORTRAIT : GEOMETRY_LANDSCAPE);
647
648 if(data->debug)
649 WINCE_DumpVideoInfo(data);
650
651 if(data->systemOrientation == ORIENTATION_UNKNOWN)
652 data->systemOrientation == ORIENTATION_UP;
653
654 data->userOrientation = ORIENTATION_UP;
655
656 switch(data->hardwareGeometry)
657 {
658 case GEOMETRY_PORTRAIT: WINCE_PortraitTransform(data, width, height); break;
659 case GEOMETRY_LANDSCAPE: WINCE_LandscapeTransform(data, width, height); break;
660 case GEOMETRY_SQUARE: WINCE_SquareTransform(data, width, height); break;
661 default: break;
662 }
663
664 // debug
665 if(data->debug)
666 {
667 printf("\n");
668 printf("user video width: %d\n", width);
669 printf("user video height: %d\n", height);
670 FrameBufferDumpInfo(&data->fb, "user");
671 }
672 }
673
674 void WINCE_DumpVideoInfo(WINCE_RenderData* data)
675 {
676 // get oem info
677 WCHAR oemInfo[48];
678 SDL_memset(oemInfo, 0, sizeof(oemInfo));
679 SystemParametersInfo(SPI_GETOEMINFO, sizeof(oemInfo) - sizeof(WCHAR), oemInfo, 0);
680
681 printf("hardware oem: ");
682 wprintf(oemInfo);
683 printf("\n");
684
685 printf("video driver mode: %s\n", (data->flags & FB_RAW_MODE ? RAW_RENDER_NAME : GAPI_RENDER_NAME));
686 printf("GetSystemMetrics(SM_CXSCREEN): %d\n", GetSystemMetrics(SM_CXSCREEN));
687 printf("GetSystemMetrics(SM_CYSCREEN): %d\n", GetSystemMetrics(SM_CYSCREEN));
688 printf("scale coord: %f\n", data->scale);
689
690 FrameBufferDumpInfo(&data->fb, "hardware");
691
692 printf("display format: %p\n", data->format);
693 printf("display bits per pixel: %d\n", SDL_BITSPERPIXEL(data->format));
694 printf("display bytes per pixel: %d\n", SDL_BYTESPERPIXEL(data->format));
695 printf("display memory: %p\n", data->pixels);
696 printf("system orientation: %d, %s\n", data->systemOrientation, GetOrientationName(data->systemOrientation));
697 printf("hardware geometry: %d\n", data->hardwareGeometry);
698 }
699
700 void WINCE_ShowWindow(_THIS, SDL_Window* window, int visible)
701 {
702 SDL_WindowData* windowdata = (SDL_WindowData*) window->driverdata;
703 SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
704 SDL_Renderer* renderer = (SDL_Renderer*) window->renderer;
705
706 if(visible)
707 {
708 if(window->flags & SDL_WINDOW_FULLSCREEN)
709 {
710 if(videodata->SHFullScreen)
711 videodata->SHFullScreen(windowdata->hwnd, SHFS_HIDETASKBAR | SHFS_HIDESTARTICON | SHFS_HIDESIPBUTTON);
712 ShowWindow(FindWindow(TEXT("HHTaskBar"), NULL), SW_HIDE);
713 }
714
715 ShowWindow(windowdata->hwnd, SW_SHOW);
716 SetForegroundWindow(windowdata->hwnd);
717
718 if(renderer &&
719 (videodata->render == RENDER_GAPI || videodata->render == RENDER_RAW))
720 {
721 WINCE_RenderData* renderdata = (WINCE_RenderData*) renderer->driverdata;
722 renderdata->flags &= ~FB_SUSPENDED;
723 if(renderdata->gapi) renderdata->gapi->GXResume();
724 }
725 }
726 else
727 {
728 if(renderer &&
729 (videodata->render == RENDER_GAPI || videodata->render == RENDER_RAW))
730 {
731 WINCE_RenderData* renderdata = (WINCE_RenderData*) renderer->driverdata;
732 if(renderdata->gapi) renderdata->gapi->GXSuspend();
733 renderdata->flags |= FB_SUSPENDED;
734 }
735
736 ShowWindow(windowdata->hwnd, SW_HIDE);
737
738 if(window->flags & SDL_WINDOW_FULLSCREEN)
739 {
740 if(videodata->SHFullScreen)
741 videodata->SHFullScreen(windowdata->hwnd, SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON | SHFS_SHOWSIPBUTTON);
742 ShowWindow(FindWindow(TEXT("HHTaskBar"), NULL), SW_SHOW);
743 }
744 }
745 }
746
747
748 void WINCE_PointerCoordinateTransform(SDL_Window* window, POINT* pt)
749 {
750 WINCE_RenderData* data = (WINCE_RenderData*) window->renderer->driverdata;
751
752 pt->x *= data->scale;
753 pt->y *= data->scale;
754
755 PointerRotate(pt, &data->fb, data->userOrientation);
756 }
757
758 void WINCE_PortraitTransform(WINCE_RenderData* data, int width, int height)
759 {
760 if(data->systemOrientation != ORIENTATION_UP)
761 FrameBufferRotate(&data->fb, data->systemOrientation);
762
763 if(data->fb.width != width || data->fb.height != height)
764 switch(data->systemOrientation)
765 {
766 case ORIENTATION_UP:
767 case ORIENTATION_LEFT: data->userOrientation = ORIENTATION_RIGHT; break;
768 case ORIENTATION_RIGHT:
769 case ORIENTATION_DOWN: data->userOrientation = ORIENTATION_LEFT; break;
770 default: break;
771 }
772
773 if(data->userOrientation != ORIENTATION_UP)
774 FrameBufferRotate(&data->fb, data->userOrientation);
775 }
776
777 void WINCE_LandscapeTransform(WINCE_RenderData* data, int width, int height)
778 {
779 switch(data->systemOrientation)
780 {
781 case ORIENTATION_UP: FrameBufferRotate(&data->fb, ORIENTATION_LEFT); break;
782 case ORIENTATION_LEFT:FrameBufferRotate(&data->fb, ORIENTATION_DOWN); break;
783 case ORIENTATION_DOWN:FrameBufferRotate(&data->fb, ORIENTATION_RIGHT); break;
784 default: break;
785 }
786
787 if(data->fb.width != width || data->fb.height != height)
788 switch(data->systemOrientation)
789 {
790 case ORIENTATION_UP:
791 case ORIENTATION_LEFT: data->userOrientation = ORIENTATION_RIGHT; break;
792 case ORIENTATION_RIGHT:
793 case ORIENTATION_DOWN: data->userOrientation = ORIENTATION_LEFT; break;
794 default: break;
795 }
796
797 if(data->userOrientation != ORIENTATION_UP)
798 FrameBufferRotate(&data->fb, data->userOrientation);
799 }
800
801 void WINCE_SquareTransform(WINCE_RenderData* data, int width, int height)
802 {
803 WINCE_PortraitTransform(data, width, height);
804 }
805
806 int WINCE_FixedGeometry(FrameBufferInfo* fb, int bpp, int debug)
807 {
808 // check square
809 if(GetSystemMetrics(SM_CXSCREEN) == GetSystemMetrics(SM_CYSCREEN) &&
810 fb->width != fb->height)
811 {
812 if(fb->width < fb->height)
813 fb->height = fb->width;
814 else
815 if(fb->height < fb->width)
816 fb->width = fb->height;
817 }
818
819 // check width
820 if(__abs(fb->xpitch) == bpp &&
821 fb->width != __abs(fb->ypitch) / bpp)
822 {
823 if(fb->height == __abs(fb->ypitch) / bpp)
824 {
825 __swap(&fb->width, &fb->height);
826
827 if(debug)
828 printf("WINCE_FixedGeometry: width: %d, height: %d\n", fb->width, fb->height);
829 }
830 else
831 return -1;
832 }
833 else
834 // check height
835 if(__abs(fb->ypitch) == bpp &&
836 fb->height != __abs(fb->xpitch) / bpp)
837 {
838 if(fb->width == __abs(fb->xpitch) / bpp)
839 {
840 __swap(&fb->width, &fb->height);
841
842 if(debug)
843 printf("WINCE_FixedGeometry: width: %d, height: %d\n", fb->width, fb->height);
844 }
845 else
846 return -1;
847 }
848
849 return 0;
850 }
851
852 void WINCE_UpdateYUVTextureData(SDL_Texture* texture)
853 {
854 WINCE_TextureData* texturedata = (WINCE_TextureData*) texture->driverdata;
855 SDL_Rect rect;
856
857 rect.x = 0;
858 rect.y = 0;
859 rect.w = texture->w;
860 rect.h = texture->h;
861 SDL_SW_CopyYUVToRGB(texturedata->yuv, &rect, texturedata->format, texture->w, texture->h, texturedata->pixels, texturedata->pitch);
862 }
863
864 int GAPI_Init(WINCE_RenderData* data, HWND hwnd)
865 {
866 if(NULL == data->gapi)
867 {
868 const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER");
869 if(preferably && 0 != SDL_strcasecmp(preferably, GAPI_RENDER_NAME)) return 0;
870
871 data->gapi = (GapiInfo *) SDL_calloc(1, sizeof(GapiInfo));
872 if(NULL == data->gapi)
873 {
874 SDL_OutOfMemory();
875 return 0;
876 }
877
878 data->gapi->hGapiLib = LoadLibrary(TEXT("\\Windows\\gx.dll"));
879 if(0 == data->gapi->hGapiLib)
880 {
881 data->gapi->hGapiLib = LoadLibrary(TEXT("gx.dll"));
882 if(0 == data->gapi->hGapiLib) return 0;
883 }
884
885 // load gapi library
886 #define LINK(type,name,import) name=(PFN##type)GetProcAddress(data->gapi->hGapiLib,TEXT(import))
887 LINK(GXOpenDisplay, data->gapi->GXOpenDisplay, "?GXOpenDisplay@@YAHPAUHWND__@@K@Z");
888 LINK(GXCloseDisplay, data->gapi->GXCloseDisplay, "?GXCloseDisplay@@YAHXZ");
889 LINK(GXBeginDraw, data->gapi->GXBeginDraw, "?GXBeginDraw@@YAPAXXZ");
890 LINK(GXEndDraw, data->gapi->GXEndDraw, "?GXEndDraw@@YAHXZ");
891 LINK(GXGetDisplayProperties,data->gapi->GXGetDisplayProperties,"?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ");
892 LINK(GXSuspend, data->gapi->GXSuspend, "?GXSuspend@@YAHXZ");
893 LINK(GXResume, data->gapi->GXResume, "?GXResume@@YAHXZ");
894 #undef LINK
895
896 int enable = data->gapi->GXGetDisplayProperties && data->gapi->GXCloseDisplay && data->gapi->GXOpenDisplay &&
897 data->gapi->GXBeginDraw && data->gapi->GXEndDraw && data->gapi->GXSuspend && data->gapi->GXResume;
898
899 if(!enable)
900 {
901 SDL_SetError("GAPI_Init: error gx.dll: internal error");
902 GAPI_Quit(data);
903 return 0;
904 }
905
906 if(0 == data->gapi->GXOpenDisplay(hwnd, GX_FULLSCREEN))
907 {
908 SDL_SetError("GAPI_Init: couldn't initialize GAPI");
909 GAPI_Quit(data);
910 return 0;
911 }
912
913 struct GXDisplayProperties gxProperties = data->gapi->GXGetDisplayProperties();
914
915 // fill FrameBufferInfo
916 data->fb.xpitch = gxProperties.cbxPitch;
917 data->fb.ypitch = gxProperties.cbyPitch;
918 data->fb.width = gxProperties.cxWidth;
919 data->fb.height = gxProperties.cyHeight;
920 data->fb.offset = 0;
921
922 if((gxProperties.ffFormat & kfDirect565) || 16 == gxProperties.cBPP)
923 data->format = SDL_PIXELFORMAT_RGB565;
924 else
925 if((gxProperties.ffFormat & kfDirect555) || 15 == gxProperties.cBPP)
926 data->format = SDL_PIXELFORMAT_RGB555;
927 else
928 data->format = 0;
929
930 // get pixels
931 GXDeviceInfo gxInfo = { 0 };
932 HDC hdc = GetDC(NULL);
933
934 gxInfo.Version = 100;
935 int result = ExtEscape(hdc, GETGXINFO, 0, NULL, sizeof(gxInfo), (char *) &gxInfo);
936 ReleaseDC(NULL, hdc);
937
938 if(result > 0)
939 {
940 // more debug
941 if(data->debug)
942 {
943 printf("GXDeviceInfo.pvFrameBuffer: %p\n", gxInfo.pvFrameBuffer);
944 printf("GXDeviceInfo.cxWidth: %d\n", gxInfo.cxWidth);
945 printf("GXDeviceInfo.cyHeight: %d\n", gxInfo.cyHeight);
946 printf("GXDeviceInfo.cbStride: %d\n", gxInfo.cbStride);
947 printf("GXDeviceInfo.cBPP: %d\n", gxInfo.cBPP);
948 printf("GXDeviceInfo.ffFormat: 0x%x\n", gxInfo.ffFormat);
949
950 printf("GXDeviceInfo.unk:\n");
951 int ii; for(ii = 0; ii < sizeof(gxInfo.unknown); ++ii)
952 printf("0x%02hhX,", gxInfo.unknown[ii]);
953 printf("\n");
954 }
955
956 if(gxInfo.ffFormat && gxInfo.ffFormat != gxProperties.ffFormat)
957 {
958 if((gxInfo.ffFormat & kfDirect565) || 16 == gxInfo.cBPP)
959 data->format = SDL_PIXELFORMAT_RGB565;
960 else
961 if((gxInfo.ffFormat & kfDirect555) || 15 == gxInfo.cBPP)
962 data->format = SDL_PIXELFORMAT_RGB555;
963 }
964
965 data->pixels = gxInfo.pvFrameBuffer;
966 }
967 else
968 {
969 data->flags |= FB_SKIP_OFFSET;
970 data->pixels = data->gapi->GXBeginDraw();
971 data->gapi->GXEndDraw();
972
973 if(data->debug)
974 {
975 printf("GAPI_Init\n");
976 printf("use GXBeginDraw: %p\n", data->pixels);
977 printf("use skip offset\n");
978 }
979 }
980
981 if(0 == data->format ||
982 0 > WINCE_FixedGeometry(&data->fb, SDL_BYTESPERPIXEL(data->format), data->debug))
983 {
984 SDL_SetError("GAPI_Init: unknown hardware");
985 GAPI_Quit(data);
986 return 0;
987 }
988 }
989
990 return data->gapi && data->pixels ? 1 : 0;
991 }
992
993 void GAPI_Quit(WINCE_RenderData* data)
994 {
995 if(data->gapi)
996 {
997 if(data->gapi->GXCloseDisplay) data->gapi->GXCloseDisplay();
998 if(data->gapi->hGapiLib) FreeLibrary(data->gapi->hGapiLib);
999
1000 SDL_free(data->gapi);
1001 data->gapi = NULL;
1002 }
1003 }
1004
1005 int RAW_Init(WINCE_RenderData* data)
1006 {
1007 const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER");
1008 if(preferably && 0 != SDL_strcasecmp(preferably, RAW_RENDER_NAME)) return 0;
1009
1010 RawFrameBufferInfo rfbi = { 0 };
1011 HDC hdc = GetDC(NULL);
1012 int result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi);
1013 ReleaseDC(NULL, hdc);
1014
1015 //disable
1016 if(result == 0 || rfbi.pFramePointer == 0 ||
1017 rfbi.cxPixels == 0 || rfbi.cyPixels == 0 ||
1018 rfbi.cxStride == 0 || rfbi.cyStride == 0) return 0;
1019
1020 data->flags = FB_RAW_MODE;
1021
1022 // fill FrameBufferInfo
1023 SDL_memset(&data->fb, 0, sizeof(FrameBufferInfo));
1024
1025 data->fb.xpitch = rfbi.cxStride;
1026 data->fb.ypitch = rfbi.cyStride;
1027 data->fb.width = rfbi.cxPixels;
1028 data->fb.height = rfbi.cyPixels;
1029 data->fb.offset = 0;
1030
1031 if((FORMAT_565 & rfbi.wFormat) || 16 == rfbi.wBPP)
1032 data->format = SDL_PIXELFORMAT_RGB565;
1033 else
1034 if((FORMAT_555 & rfbi.wFormat) || 15 == rfbi.wBPP)
1035 data->format = SDL_PIXELFORMAT_RGB555;
1036 else
1037 data->format = 0;
1038
1039 if(0 == data->format ||
1040 0 > WINCE_FixedGeometry(&data->fb, SDL_BYTESPERPIXEL(data->format), data->debug))
1041 {
1042 SDL_SetError("RAW_Init: unknown hardware");
1043 RAW_Quit(data);
1044 return 0;
1045 }
1046
1047 data->pixels = rfbi.pFramePointer;
1048
1049 return data->pixels ? 1 : 0;
1050 }
1051
1052 void RAW_Quit(WINCE_RenderData* data)
1053 {
1054 }
1055
1056 void FrameBufferInitialize(FrameBufferInfo* fb)
1057 {
1058 int orientation = GetFrameBufferOrientation(fb);
1059
1060 // set correct start offset
1061 switch(orientation)
1062 {
1063 case ORIENTATION_UP:
1064 fb->offset = 0;
1065 break;
1066
1067 case ORIENTATION_LEFT:
1068 fb->offset = __abs(fb->ypitch * (fb->height - 1));
1069 break;
1070
1071 case ORIENTATION_RIGHT:
1072 fb->offset = __abs(fb->xpitch * (fb->width - 1));
1073 break;
1074
1075 case ORIENTATION_DOWN:
1076 fb->offset = __abs(fb->xpitch * (fb->width - 1) +
1077 fb->ypitch * (fb->height - 1));
1078 break;
1079
1080 default: break;
1081 }
1082
1083 //if(orientation != ORIENTATION_UP)
1084 switch(orientation)
1085 {
1086 case ORIENTATION_LEFT: FrameBufferRotate(fb, ORIENTATION_RIGHT); break;
1087 case ORIENTATION_RIGHT:FrameBufferRotate(fb, ORIENTATION_LEFT); break;
1088 case ORIENTATION_DOWN: FrameBufferRotate(fb, ORIENTATION_DOWN); break;
1089
1090 default: break;
1091 }
1092 }
1093
1094 int GetFrameBufferOrientation(const FrameBufferInfo* src)
1095 {
1096 if(src->xpitch > 0 && src->ypitch > 0)
1097 return ORIENTATION_UP;
1098 else
1099 if(src->xpitch > 0 && src->ypitch < 0)
1100 return ORIENTATION_LEFT;
1101 else
1102 if(src->xpitch < 0 && src->ypitch > 0)
1103 return ORIENTATION_RIGHT;
1104 else
1105 if(src->xpitch < 0 && src->ypitch < 0)
1106 return ORIENTATION_DOWN;
1107
1108 return ORIENTATION_UNKNOWN;
1109 }
1110
1111 void FrameBufferRotate(FrameBufferInfo* dst, int orientation)
1112 {
1113 FrameBufferInfo src;
1114 // copy dst -> src
1115 SDL_memcpy(&src, dst, sizeof(FrameBufferInfo));
1116
1117 switch(orientation)
1118 {
1119 case ORIENTATION_LEFT:
1120 dst->width = src.height;
1121 dst->height = src.width;
1122 dst->xpitch = src.ypitch;
1123 dst->ypitch = -src.xpitch;
1124 dst->offset = src.offset + src.xpitch * (src.width - 1);
1125 break;
1126
1127 case ORIENTATION_RIGHT:
1128 dst->width = src.height;
1129 dst->height = src.width;
1130 dst->xpitch = -src.ypitch;
1131 dst->ypitch = src.xpitch;
1132 dst->offset = src.offset + src.ypitch * (src.height - 1);
1133 break;
1134
1135 case ORIENTATION_DOWN:
1136 FrameBufferRotate(dst, ORIENTATION_LEFT);
1137 FrameBufferRotate(dst, ORIENTATION_LEFT);
1138 break;
1139
1140 default:
1141 break;
1142 }
1143 }
1144
1145 void PointerRotate(POINT* pt, const FrameBufferInfo* fb, int orientation)
1146 {
1147 switch(orientation)
1148 {
1149 case ORIENTATION_UP:
1150 break;
1151
1152 case ORIENTATION_LEFT:
1153 {
1154 int temp = pt->y;
1155 pt->y = fb->height - pt->x;
1156 pt->x = temp;
1157 }
1158 break;
1159
1160 case ORIENTATION_RIGHT:
1161 {
1162 int temp = pt->x;
1163 pt->x = fb->width - pt->y;
1164 pt->y = temp;
1165 }
1166 break;
1167
1168 case ORIENTATION_DOWN:
1169 pt->x = fb->width - pt->x;
1170 pt->y = fb->height - pt->y;
1171 break;
1172
1173 default: break;
1174 }
1175 }
1176
1177 const char* GetOrientationName(int orientation)
1178 {
1179 switch(orientation)
1180 {
1181 case ORIENTATION_UP: return "UP";
1182 case ORIENTATION_DOWN: return "DOWN";
1183 case ORIENTATION_LEFT: return "LEFT";
1184 case ORIENTATION_RIGHT: return "RIGHT";
1185 default: break;
1186 }
1187
1188 return "UNKNOWN";
1189 }
1190
1191 int WINCE_GetDMOrientation(void)
1192 {
1193 DEVMODE sDevMode = {0};
1194 sDevMode.dmSize = sizeof(DEVMODE);
1195 sDevMode.dmFields = DM_DISPLAYORIENTATION;
1196
1197 // DMDO_0, DMDO_90, DMDO_180, DMDO_270
1198 if(DISP_CHANGE_BADMODE != ChangeDisplaySettingsEx(NULL, &sDevMode, 0, CDS_TEST, NULL))
1199 switch(sDevMode.dmDisplayOrientation)
1200 {
1201 case DMDO_0: return DMDO_0;
1202 case DMDO_90: return DMDO_90;
1203 case DMDO_180: return DMDO_180;
1204 case DMDO_270: return DMDO_270;
1205 default: break;
1206 }
1207
1208 SDL_SetError("WINCE_GetDMOrientation: ChangeDisplaySettingsEx return BADMODE");
1209 return -1;
1210 }
1211
1212 int WINCE_SetDMOrientation(int orientation)
1213 {
1214 DEVMODE sDevMode = {0};
1215 sDevMode.dmSize = sizeof(DEVMODE);
1216 sDevMode.dmFields = DM_DISPLAYORIENTATION;
1217
1218 switch(orientation)
1219 {
1220 case DMDO_0: sDevMode.dmDisplayOrientation = DMDO_0; break;
1221 case DMDO_90: sDevMode.dmDisplayOrientation = DMDO_90; break;
1222 case DMDO_180: sDevMode.dmDisplayOrientation = DMDO_180; break;
1223 case DMDO_270: sDevMode.dmDisplayOrientation = DMDO_270; break;
1224 default: return 0;
1225 }
1226
1227 if(DISP_CHANGE_BADMODE != ChangeDisplaySettingsEx(NULL, &sDevMode, 0, CDS_RESET, NULL))
1228 return 1;
1229
1230 SDL_SetError("WINCE_SetDMOrientation: ChangeDisplaySettingsEx return BADMODE");
1231 return -1;
1232 }
1233
1234 void FrameBufferDumpInfo(const FrameBufferInfo* fb, const char* name)
1235 {
1236 printf("%s fb.width: %d\n", name, fb->width);
1237 printf("%s fb.height: %d\n", name, fb->height);
1238 printf("%s fb.xpitch: %d\n", name, fb->xpitch);
1239 printf("%s fb.ypitch: %d\n", name, fb->ypitch);
1240 printf("%s fb.offset: %d\n", name, fb->offset);
1241
1242 int orientation = GetFrameBufferOrientation(fb);
1243 printf("%s fb.orientation: %d, %s\n", name, orientation, GetOrientationName(orientation));
1244 }
1245
1246 void UpdateLine16to16(const FrameBufferInfo* fb, const Uint16* src, Uint16* dst, Uint16 width)
1247 {
1248 if(2 == fb->xpitch)
1249 {
1250 switch(width)
1251 {
1252 case 1:
1253 *dst = *src;
1254 break;
1255
1256 case 2:
1257 *((Uint32*) dst) = *((Uint32*) src);
1258 break;
1259
1260 default:
1261 SDL_memcpy(dst, src, width * 2);
1262 break;
1263 }
1264 }
1265 else
1266 if(-2 == fb->xpitch)
1267 {
1268 while(width--)
1269 *dst-- = *src++;
1270 }
1271 else
1272 {
1273 while(width--)
1274 {
1275 *dst = *src++;
1276 dst += fb->xpitch / 2;
1277 }
1278 }
1279 }
1280
1281 #endif // SDL_VIDEO_RENDER_GAPI