comparison src/video/win32/SDL_gapirender.c @ 4569:e1664f94f026

Andrey A. I made a video driver GAPI/RAW for WinCE (SDL-1.3). RAW mode has a priority, and also, GAPI mode works with environment "SDL_VIDEO_RENDERER=gapi" and for RAW mode "SDL_VIDEO_RENDERER=raw". I checked the work on the screens of VGA, WVGA, QVGA, WQVGA, HVGA, + tested all modes with WindowsMobile Emulator. Also, correctly draws the pointer position and the scale of the pointer for VGA/WVGA modes, correctly draws top left position for DM orientation screen, and portrait/landscape/square geometry the screen also correct. Also, I added a small fix for GDI fullscreen mode. Patch for latest revision SDL-1.3 in an attachment. Also added small path for mingw32ce build.
author Sam Lantinga <slouken@libsdl.org>
date Tue, 27 Jul 2010 21:31:28 -0700
parents f7b03b6838cb
children aa8888658021
comparison
equal deleted inserted replaced
4568:25b9cd8bdc30 4569:e1664f94f026
1 /* 1 /***************************************************************************
2 SDL - Simple DirectMedia Layer 2 * Copyright (C) 2010 by Andrey Afletdinov <afletdinov@gmail.com> *
3 Copyright (C) 1997-2010 Sam Lantinga 3 * *
4 4 * WinCE RAW/GAPI video driver *
5 This library is free software; you can redistribute it and/or 5 * *
6 modify it under the terms of the GNU Lesser General Public 6 * Part of the SDL - (Simple DirectMedia Layer) *
7 License as published by the Free Software Foundation; either 7 * http://www.libsdl.org *
8 version 2.1 of the License, or (at your option) any later version. 8 * *
9 9 * This program is free software; you can redistribute it and/or modify *
10 This library is distributed in the hope that it will be useful, 10 * it under the terms of the GNU General Public License as published by *
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * the Free Software Foundation; either version 2 of the License, or *
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * (at your option) any later version. *
13 Lesser General Public License for more details. 13 * *
14 14 * This program is distributed in the hope that it will be useful, *
15 You should have received a copy of the GNU Lesser General Public 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 License along with this library; if not, write to the Free Software 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * GNU General Public License for more details. *
18 18 * *
19 Sam Lantinga 19 * You should have received a copy of the GNU General Public License *
20 slouken@libsdl.org 20 * along with this program; if not, write to the *
21 21 * Free Software Foundation, Inc., *
22 Stefan Klug 22 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23 klug.stefan@gmx.de 23 ***************************************************************************/
24 */ 24
25 #include "SDL_config.h" 25 #include "SDL_config.h"
26 26
27 #if SDL_VIDEO_RENDER_GAPI 27 #if SDL_VIDEO_RENDER_GAPI
28 28
29 #include "SDL_win32video.h" 29 #include "SDL_win32video.h"
30 //#include "../SDL_sysvideo.h" 30 #include "SDL_win32window.h"
31 #include "../SDL_yuv_sw_c.h" 31 #include "../SDL_yuv_sw_c.h"
32 #include "../SDL_renderer_sw.h" 32
33 33 // RawFrameBufferInfo
34 #include "SDL_gapirender_c.h" 34 typedef struct
35 35 {
36 #define GAPI_RENDERER_DEBUG 1 36 WORD wFormat;
37 37 WORD wBPP;
38 /* GAPI renderer implementation */ 38 VOID *pFramePointer;
39 39 int cxStride;
40 static SDL_Renderer *GAPI_CreateRenderer(SDL_Window * window, Uint32 flags); 40 int cyStride;
41 static int GAPI_RenderDrawPoints(SDL_Renderer * renderer, 41 int cxPixels;
42 const SDL_Point * points, int count); 42 int cyPixels;
43 static int GAPI_RenderDrawLines(SDL_Renderer * renderer, 43 } RawFrameBufferInfo;
44 const SDL_Point * points, int count); 44
45 static int GAPI_RenderDrawRects(SDL_Renderer * renderer, 45 // GXDeviceInfo
46 const SDL_Rect ** rects, int count); 46 typedef struct
47 static int GAPI_RenderFillRects(SDL_Renderer * renderer, 47 {
48 const SDL_Rect ** rects, int count); 48 long Version;
49 static int GAPI_RenderCopy(SDL_Renderer * renderer, 49 void* pvFrameBuffer;
50 SDL_Texture * texture, 50 unsigned long cbStride;
51 const SDL_Rect * srcrect, 51 unsigned long cxWidth;
52 const SDL_Rect * dstrect); 52 unsigned long cyHeight;
53 static void GAPI_RenderPresent(SDL_Renderer * renderer); 53 unsigned long cBPP;
54 static void GAPI_DestroyRenderer(SDL_Renderer * renderer); 54 unsigned long ffFormat;
55 55 char unknown[0x84 - 7 * 4];
56 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 //
57 SDL_RenderDriver GAPI_RenderDriver = { 206 SDL_RenderDriver GAPI_RenderDriver = {
58 GAPI_CreateRenderer, 207 WINCE_CreateRenderer,
59 { 208 {
60 "gapi", 209 GAPI_RENDER_NAME,
61 (SDL_RENDERER_SINGLEBUFFER), 210 (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD),
62 } 211 (SDL_TEXTUREMODULATE_NONE),
212 (SDL_BLENDMODE_NONE),
213 (SDL_TEXTURESCALEMODE_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 }
63 }; 227 };
64 228
65 static HMODULE g_hGapiLib = 0; 229 SDL_RenderDriver RAW_RenderDriver = {
66 230 WINCE_CreateRenderer,
67 // for testing with GapiEmu 231 {
68 #define USE_GAPI_EMU 0 232 RAW_RENDER_NAME,
69 #define EMULATE_AXIM_X30 0 233 (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTDISCARD),
70 234 (SDL_TEXTUREMODULATE_NONE),
71 #if 0 235 (SDL_BLENDMODE_NONE),
72 #define GAPI_LOG(...) printf(__VA_ARGS__) 236 (SDL_TEXTURESCALEMODE_NONE),
73 #else 237 7,
74 #define GAPI_LOG(...) 238 {
75 #endif 239 SDL_PIXELFORMAT_RGB555,
76 240 SDL_PIXELFORMAT_RGB565,
77 241 SDL_PIXELFORMAT_YV12,
78 #if USE_GAPI_EMU && !REPORT_VIDEO_INFO 242 SDL_PIXELFORMAT_IYUV,
79 #pragma message("Warning: Using GapiEmu in release build. I assume you'd like to set USE_GAPI_EMU to zero.") 243 SDL_PIXELFORMAT_YUY2,
80 #endif 244 SDL_PIXELFORMAT_UYVY,
81 245 SDL_PIXELFORMAT_YVYU
82 246 },
83 static void 247 0,
84 GAPI_SetError(const char *prefix, HRESULT result) 248 0
85 { 249 }
86 const char *error; 250 };
87 251
88 switch (result) { 252 int WINCE_Available(void)
89 default: 253 {
90 error = "UNKNOWN"; 254 const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER");
91 break; 255
92 } 256 // raw check
93 SDL_SetError("%s: %s", prefix, error); 257 RawFrameBufferInfo rfbi = { 0 };
94 } 258 HDC hdc = GetDC(NULL);
95 259 int render_raw = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi);
96 void 260 ReleaseDC(NULL, hdc);
97 GAPI_AddRenderDriver(_THIS) 261
98 { 262 if(render_raw != 0 && rfbi.cxPixels != 0 && rfbi.cyPixels != 0 &&
99 int i; 263 rfbi.pFramePointer != 0 && rfbi.cxStride != 0 && rfbi.cyStride != 0)
100 264 render_raw = 1;
101 /* TODO: should we check for support of GetRawFramebuffer here? 265
102 */ 266 if(preferably && 0 == SDL_strcasecmp(preferably, RAW_RENDER_NAME)) return 0 != render_raw;
103 #if USE_GAPI_EMU 267
104 g_hGapiLib = LoadLibrary(L"GAPI_Emu.dll"); 268 // gapi check
105 #else 269 HMODULE render_gapi = LoadLibrary(TEXT("\\Windows\\gx.dll"));
106 g_hGapiLib = LoadLibrary(L"\\Windows\\gx.dll"); 270 if(0 == render_gapi)
107 #endif 271 render_gapi = LoadLibrary(TEXT("gx.dll"));
108 272 FreeLibrary(render_gapi);
109 if (g_hGapiLib) { 273
110 #define LINK(name,import) gx.name = (PFN##name)GetProcAddress( g_hGapiLib, L##import ); 274 if(preferably && 0 == SDL_strcasecmp(preferably, GAPI_RENDER_NAME)) return 0 != render_gapi;
111 275
112 LINK(GXOpenDisplay, "?GXOpenDisplay@@YAHPAUHWND__@@K@Z") 276 return 0 != render_raw || 0 != render_gapi;
113 LINK(GXCloseDisplay, "?GXCloseDisplay@@YAHXZ") 277 }
114 LINK(GXBeginDraw, "?GXBeginDraw@@YAPAXXZ") 278
115 LINK(GXEndDraw, "?GXEndDraw@@YAHXZ") 279 void WINCE_AddRenderDriver(_THIS)
116 LINK(GXOpenInput, "?GXOpenInput@@YAHXZ") 280 {
117 LINK(GXCloseInput, "?GXCloseInput@@YAHXZ")
118 LINK(GXGetDisplayProperties,
119 "?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ")
120 LINK(GXGetDefaultKeys, "?GXGetDefaultKeys@@YA?AUGXKeyList@@H@Z")
121 LINK(GXSuspend, "?GXSuspend@@YAHXZ")
122 LINK(GXResume, "?GXResume@@YAHXZ")
123 LINK(GXSetViewport, "?GXSetViewport@@YAHKKKK@Z")
124 LINK(GXIsDisplayDRAMBuffer, "?GXIsDisplayDRAMBuffer@@YAHXZ")
125
126 /* wrong gapi.dll */
127 if (!gx.GXOpenDisplay) {
128 FreeLibrary(g_hGapiLib);
129 g_hGapiLib = 0;
130 }
131 #undef LINK
132 }
133
134 for (i = 0; i < _this->num_displays; ++i) {
135 SDL_AddRenderDriver(&_this->displays[i], &GAPI_RenderDriver);
136 }
137 }
138
139 typedef enum
140 {
141 USAGE_GX_FUNCS = 0x0001, /* enable to use GXOpen/GXClose/GXBeginDraw... */
142 USAGE_DATA_PTR_CONSTANT = 0x0002 /* the framebuffer is at a constant location, don't use values from GXBeginDraw() */
143 } GAPI_UsageFlags;
144
145
146
147 typedef struct
148 {
149 int w;
150 int h;
151 int xPitch; /* bytes to move to go to the next pixel */
152 int yPitch; /* bytes to move to go to the next line */
153 int offset; /* data offset, to add to the data returned from GetFramebuffer, before processing */
154
155 void *data;
156 Uint32 usageFlags; /* these flags contain options to define screen handling and to reliably workarounds */
157
158 Uint32 format; /* pixel format as defined in SDL_pixels.h */
159
160 } GAPI_RenderData;
161
162
163 static Uint32
164 GuessPixelFormatFromBpp(int bpp)
165 {
166 switch (bpp) {
167 case 15:
168 return SDL_PIXELFORMAT_RGB555;
169 case 16:
170 return SDL_PIXELFORMAT_RGB565;
171 default:
172 return SDL_PIXELFORMAT_UNKNOWN;
173 break;
174 }
175 }
176
177 static GAPI_RenderData *
178 FillRenderDataRawFramebuffer(SDL_Window * window)
179 {
180 RawFrameBufferInfo rbi;
181 GAPI_RenderData *renderdata;
182 HDC hdc; 281 HDC hdc;
183 282 HMODULE render_gapi;
184 //TODO should we use the hdc of the window? 283 int render_raw, ii;
284 const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER");
285
286 // raw check
287 RawFrameBufferInfo rfbi = { 0 };
185 hdc = GetDC(NULL); 288 hdc = GetDC(NULL);
186 int result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, 289 render_raw = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi);
187 sizeof(RawFrameBufferInfo),
188 (char *) &rbi);
189 ReleaseDC(NULL, hdc); 290 ReleaseDC(NULL, hdc);
190 291
191 if (!(result > 0)) { 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");
192 return NULL; 340 return NULL;
193 } 341 }
194 342
195 /* Asus A696 returns wrong results so we do a sanity check 343 switch(window->fullscreen_mode.format)
196 See: 344 {
197 http://groups.google.com/group/microsoft.public.smartphone.developer/browse_thread/thread/4fde5bddd477de81 345 case SDL_PIXELFORMAT_RGB555:
198 */ 346 case SDL_PIXELFORMAT_RGB565:
199 if (rbi.cxPixels <= 0 || 347 break;
200 rbi.cyPixels <= 0 || 348
201 rbi.cxStride == 0 || rbi.cyStride == 0 || rbi.pFramePointer == 0) { 349 default:
202 return NULL; 350 SDL_SetError("Support only 16 or 15 bpp");
203 } 351 return NULL;
204 352 }
205 353
206 renderdata = (GAPI_RenderData *) SDL_calloc(1, sizeof(*renderdata)); 354 renderer = (SDL_Renderer*) SDL_calloc(1, sizeof(SDL_Renderer));
207 if (!renderdata) { 355 if(!renderer)
356 {
208 SDL_OutOfMemory(); 357 SDL_OutOfMemory();
209 return NULL; 358 return NULL;
210 } 359 }
211 //Try to match the window size 360
212 //TODO add rotation support 361 data = (WINCE_RenderData*) SDL_calloc(1, sizeof(WINCE_RenderData));
213 if (rbi.cxPixels != window->w || rbi.cyPixels != window->h) { 362 if(!data)
214 SDL_free(renderdata); 363 {
215 return NULL; 364 WINCE_DestroyRenderer(renderer);
216 }
217 //Check that the display uses a known display format
218 switch (rbi.wFormat) {
219 case FORMAT_565:
220 renderdata->format = SDL_PIXELFORMAT_RGB565;
221 break;
222 case FORMAT_555:
223 renderdata->format = SDL_PIXELFORMAT_RGB555;
224 break;
225 default:
226 //TODO we should add support for other formats
227 SDL_free(renderdata);
228 return NULL;
229 }
230
231 renderdata->usageFlags = USAGE_DATA_PTR_CONSTANT;
232 renderdata->data = rbi.pFramePointer;
233 renderdata->w = rbi.cxPixels;
234 renderdata->h = rbi.cyPixels;
235 renderdata->xPitch = rbi.cxStride;
236 renderdata->yPitch = rbi.cyStride;
237
238 return renderdata;
239
240 }
241
242
243 static GAPI_RenderData *
244 FillRenderDataGAPI(SDL_Window * window)
245 {
246 GAPI_RenderData *renderdata;
247 struct GXDisplayProperties gxdp;
248 int tmp;
249
250 #ifdef _ARM_
251 WCHAR oemstr[100];
252 #endif
253
254 if (!g_hGapiLib) {
255 return NULL;
256 }
257
258 renderdata = (GAPI_RenderData *) SDL_calloc(1, sizeof(GAPI_RenderData));
259 if (!renderdata) {
260 SDL_OutOfMemory(); 365 SDL_OutOfMemory();
261 return NULL; 366 return NULL;
262 } 367 }
263 368
264 gxdp = gx.GXGetDisplayProperties(); 369 // initialize internal engine
265 renderdata->usageFlags = USAGE_GX_FUNCS; 370 if(!RAW_Init(data) && !GAPI_Init(data, windowdata->hwnd))
266 renderdata->w = gxdp.cxWidth; 371 {
267 renderdata->h = gxdp.cyHeight; 372 WINCE_DestroyRenderer(renderer);
268 renderdata->xPitch = gxdp.cbxPitch; 373 return NULL;
269 renderdata->yPitch = gxdp.cbyPitch; 374 }
270 375
271 //Check that the display uses a known display format 376
272 if (gxdp.ffFormat & kfDirect565) { 377 // set debug
273 renderdata->format = SDL_PIXELFORMAT_RGB565; 378 data->debug = SDL_getenv("DEBUG_VIDEO_GAPI") || SDL_getenv("GAPI_RENDERER_DEBUG") ? 1 : 0;
274 } else if (gxdp.ffFormat & kfDirect555) { 379 #if defined(DEBUG_VIDEO_GAPI) || defined(GAPI_RENDERER_DEBUG)
275 renderdata->format = SDL_PIXELFORMAT_RGB555; 380 data->debug = 1;
276 } else {
277 renderdata->format = SDL_PIXELFORMAT_UNKNOWN;
278 }
279
280 /* apply some device specific corrections */
281 #ifdef _ARM_
282 SystemParametersInfo(SPI_GETOEMINFO, sizeof(oemstr), oemstr, 0);
283
284 // buggy iPaq38xx
285 if ((oemstr[12] == 'H') && (oemstr[13] == '3')
286 && (oemstr[14] == '8')
287 && (gxdp.cbxPitch > 0)) {
288 renderdata->data = (void *) 0xac0755a0;
289 renderdata->xPitch = -640;
290 renderdata->yPitch = 2;
291 }
292 #if (EMULATE_AXIM_X30 == 0)
293 // buggy Dell Axim X30
294 if (_tcsncmp(oemstr, L"Dell Axim X30", 13) == 0)
295 #endif 381 #endif
296 { 382
297 GXDeviceInfo gxInfo = { 0 }; 383 windowdata->videodata->render = data->gapi ? RENDER_GAPI : RENDER_RAW;
298 HDC hdc = GetDC(NULL); 384 windowdata->videodata->CoordTransform = WINCE_PointerCoordinateTransform;
299 int result; 385
300 386 window->display->device->MaximizeWindow = NULL;
301 gxInfo.Version = 100; 387 window->display->device->MinimizeWindow = NULL;
302 result = 388
303 ExtEscape(hdc, GETGXINFO, 0, NULL, sizeof(gxInfo), 389 WINCE_SetupOrientation(data, window->w, window->h);
304 (char *) &gxInfo); 390
305 if (result > 0) { 391 renderer->CreateTexture = WINCE_CreateTexture;
306 renderdata->usageFlags = USAGE_DATA_PTR_CONSTANT; /* no more GAPI usage from now */ 392 renderer->DestroyTexture = WINCE_DestroyTexture;
307 renderdata->data = gxInfo.pvFrameBuffer; 393 renderer->QueryTexturePixels = WINCE_QueryTexturePixels;
308 this->hidden->needUpdate = 0; 394 renderer->UpdateTexture = WINCE_UpdateTexture;
309 renderdata->xPitch = 2; 395 renderer->LockTexture = WINCE_LockTexture;
310 renderdata->yPitch = 480; 396 renderer->UnlockTexture = WINCE_UnlockTexture;
311 renderdata->w = gxInfo.cxWidth; 397
312 renderdata->h = gxInfo.cyHeight; 398 renderer->RenderCopy = WINCE_RenderCopy;
313 399 renderer->DestroyRenderer = WINCE_DestroyRenderer;
314 //Check that the display uses a known display format 400
315 switch (rbi->wFormat) { 401 renderer->RenderPresent = WINCE_RenderPresent;
316 case FORMAT_565: 402 renderer->RenderDrawPoints = WINCE_RenderDrawPoints;
317 renderdata->format = SDL_PIXELFORMAT_RGB565; 403 renderer->RenderDrawLines = WINCE_RenderDrawLines;
318 break; 404 renderer->RenderDrawRects = WINCE_RenderDrawRects;
319 case FORMAT_555: 405 renderer->RenderFillRects = WINCE_RenderFillRects;
320 renderdata->format = SDL_PIXELFORMAT_RGB555; 406
321 break; 407 renderer->info = data->gapi ? GAPI_RenderDriver.info : RAW_RenderDriver.info;
322 default: 408
323 //TODO we should add support for other formats
324 SDL_free(renderdata);
325 return NULL;
326 }
327 }
328 }
329 #endif
330
331
332 if (renderdata->format == SDL_PIXELFORMAT_UNKNOWN) {
333 SDL_SetError("Gapi Pixelformat is unknown");
334 SDL_free(renderdata);
335 return NULL;
336 }
337
338 /* Gapi always returns values in standard orientation, so we manually apply
339 the current orientation
340 */
341
342 DEVMODE settings;
343 SDL_memset(&settings, 0, sizeof(DEVMODE));
344 settings.dmSize = sizeof(DEVMODE);
345
346 settings.dmFields = DM_DISPLAYORIENTATION;
347 ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL);
348
349 if (settings.dmDisplayOrientation == DMDO_90) {
350
351 tmp = renderdata->w;
352 renderdata->w = renderdata->h;
353 renderdata->h = tmp;
354
355 tmp = renderdata->xPitch;
356 renderdata->xPitch = -renderdata->yPitch;
357 renderdata->yPitch = tmp;
358
359 renderdata->offset = -renderdata->w * renderdata->xPitch;
360
361 } else if (settings.dmDisplayOrientation == DMDO_180) {
362
363 renderdata->xPitch = -renderdata->xPitch;
364 renderdata->yPitch = -renderdata->yPitch;
365
366 renderdata->offset = -renderdata->h * renderdata->yPitch
367 - renderdata->w * renderdata->xPitch;
368
369 } else if (settings.dmDisplayOrientation == DMDO_270) {
370
371 tmp = renderdata->w;
372 renderdata->w = renderdata->h;
373 renderdata->h = tmp;
374
375 tmp = renderdata->xPitch;
376 renderdata->xPitch = renderdata->yPitch;
377 renderdata->yPitch = -tmp;
378
379 renderdata->offset = -renderdata->h * renderdata->yPitch;
380
381 }
382
383 if (renderdata->w != window->w || renderdata->h != window->h) {
384 GAPI_LOG("GAPI open failed, wrong size %i %i %i %i\n", renderdata->w,
385 renderdata->h, renderdata->xPitch, renderdata->yPitch);
386 SDL_free(renderdata);
387 return NULL;
388 }
389
390 return renderdata;
391
392 }
393
394
395 /* This function does the whole encapsulation of Gapi/RAWFRAMEBUFFER
396 it should handle all the device dependent details and fill the device INDEPENDENT
397 RenderData structure.
398 */
399 GAPI_RenderData *
400 FillRenderData(SDL_Window * window)
401 {
402 /* We try to match the requested window to the modes available by GAPI and RAWFRAMEBUFFER.
403 First RAWFRAMEBUFFER is tried, as it is the most reliable one
404 Look here for detailed discussions:
405 http://pdaphonehome.com/forums/samsung-i700/28087-just-saw.html
406 http://blogs.msdn.com/windowsmobile/archive/2007/08/13/have-you-migrated-to-directdraw-yet.aspx
407 */
408
409 GAPI_RenderData *res;
410
411 res = FillRenderDataRawFramebuffer(window);
412 GAPI_LOG("FillRenderDataRawFramebuffer: %p\n", res);
413 if (res) {
414 return res;
415 }
416 //Now we try gapi
417 res = FillRenderDataGAPI(window);
418 GAPI_LOG("FillRenderDataGAPI: %p\n", res);
419
420 return res;
421 }
422
423 void *
424 GetFramebuffer()
425 {
426
427 }
428
429
430 SDL_Renderer *
431 GAPI_CreateRenderer(SDL_Window * window, Uint32 flags)
432 {
433 SDL_VideoDisplay *display = window->display;
434 SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
435 SDL_DisplayMode *displayMode = &display->current_mode;
436 SDL_Renderer *renderer;
437 GAPI_RenderData *data;
438 int i, n;
439 int bpp;
440 Uint32 Rmask, Gmask, Bmask, Amask;
441
442 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
443 SDL_SetError("Gapi supports only fullscreen windows");
444 return NULL;
445 }
446
447 if (!SDL_PixelFormatEnumToMasks
448 (displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
449 SDL_SetError("Unknown display format");
450 return NULL;
451 }
452
453 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
454 if (!renderer) {
455 SDL_OutOfMemory();
456 return NULL;
457 }
458
459 data = FillRenderData(window);
460 if (!data) {
461 GAPI_DestroyRenderer(renderer);
462 SDL_OutOfMemory();
463 return NULL;
464 }
465
466 renderer->RenderDrawPoints = GAPI_RenderDrawPoints;
467 renderer->RenderDrawLines = GAPI_RenderDrawLines;
468 renderer->RenderDrawRects = GAPI_RenderDrawRects;
469 renderer->RenderFillRects = GAPI_RenderFillRects;
470 renderer->RenderCopy = GAPI_RenderCopy;
471 renderer->RenderPresent = GAPI_RenderPresent;
472 renderer->DestroyRenderer = GAPI_DestroyRenderer;
473 renderer->info.name = GAPI_RenderDriver.info.name;
474 renderer->info.flags = 0;
475 renderer->window = window; 409 renderer->window = window;
476 renderer->driverdata = data; 410 renderer->driverdata = data;
477 411
478 /* Gapi provides only a framebuffer so lets use software implementation */ 412 return renderer;
479 Setup_SoftwareRenderer(renderer); 413 }
480 414
481 #ifdef GAPI_RENDERER_DEBUG 415 void WINCE_DestroyRenderer(SDL_Renderer* renderer)
482 printf("Created gapi renderer\n"); 416 {
483 printf("use GX functions: %i\n", data->usageFlags & USAGE_GX_FUNCS); 417 WINCE_RenderData *renderdata = (WINCE_RenderData*) renderer->driverdata;
484 printf("framebuffer is constant: %i\n", 418
485 data->usageFlags & USAGE_DATA_PTR_CONSTANT); 419 if(renderdata)
486 printf("w: %i h: %i\n", data->w, data->h); 420 {
487 printf("data ptr: %p\n", data->data); /* this can be 0 in case of GAPI usage */ 421 if(renderdata->gapi)
488 printf("xPitch: %i\n", data->xPitch); 422 GAPI_Quit(renderdata);
489 printf("yPitch: %i\n", data->yPitch); 423 else
490 printf("offset: %i\n", data->offset); 424 RAW_Quit(renderdata);
491 printf("format: %x\n", data->format); 425
492 #endif 426 SDL_free(renderdata);
493 427 }
494 if (data->usageFlags & USAGE_GX_FUNCS) { 428
495 if (gx.GXOpenDisplay(windowdata->hwnd, GX_FULLSCREEN) == 0) { 429 SDL_free(renderer);
496 GAPI_DestroyRenderer(renderer); 430 }
497 return NULL; 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;
498 } 456 }
499 } 457 SDL_Window* window = renderer->window;
500 458 SDL_VideoDisplay* display = window->display;
501 return renderer; 459 texturedata->format = display->current_mode.format;
502 } 460 }
503 461 else
504 static int 462 {
505 GAPI_RenderDrawPoints(SDL_Renderer * renderer, 463 texturedata->yuv = NULL;
506 const SDL_Point * points, int count) 464 texturedata->format = texture->format;
507 { 465 }
508 // TODO implement 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 {
509 SDL_Unsupported(); 607 SDL_Unsupported();
510 return -1; 608 return -1;
511 } 609 }
512 610
513 static int 611 int WINCE_RenderDrawLines(SDL_Renderer* renderer, const SDL_Point* points, int count)
514 GAPI_RenderDrawLines(SDL_Renderer * renderer, 612 {
515 const SDL_Point * points, int count)
516 {
517 // TODO implement
518 SDL_Unsupported(); 613 SDL_Unsupported();
519 return -1; 614 return -1;
520 } 615 }
521 616
522 static int 617 int WINCE_RenderDrawRects(SDL_Renderer* renderer, const SDL_Rect ** rects, int count)
523 GAPI_RenderDrawRects(SDL_Renderer * renderer, 618 {
524 const SDL_Rect ** rects, int count)
525 {
526 // TODO implement
527 SDL_Unsupported(); 619 SDL_Unsupported();
528 return -1; 620 return -1;
529 } 621 }
530 622
531 static int 623 int WINCE_RenderFillRects(SDL_Renderer* renderer, const SDL_Rect** rects, int count)
532 GAPI_RenderFillRects(SDL_Renderer * renderer, 624 {
533 const SDL_Rect ** rects, int count)
534 {
535 // TODO implement
536 SDL_Unsupported(); 625 SDL_Unsupported();
537 return -1; 626 return -1;
538 } 627 }
539 628
540 /* Video memory is very slow so lets optimize as much as possible */ 629
541 static void 630
542 updateLine16to16(char *src, int srcXPitch, int srcYPitch, 631 void WINCE_SetupOrientation(WINCE_RenderData* data, int width, int height)
543 char *dst, int dstXPitch, int dstYPitch, int width, 632 {
544 int height) 633 const float maxW1 = GetSystemMetrics(SM_CXSCREEN) > GetSystemMetrics(SM_CYSCREEN) ? GetSystemMetrics(SM_CXSCREEN) : GetSystemMetrics(SM_CYSCREEN);
545 { 634 const float maxW2 = data->fb.width > data->fb.height ? data->fb.width : data->fb.height;
546 char *srcLine, *dstLine; 635
547 char *srcPix, *dstPix; 636 // scale define
548 637 data->scale = maxW2 / maxW1;
549 int x, y; 638
550 639 // init fb values
551 //First dumb solution 640 FrameBufferInitialize(&data->fb);
552 if (srcXPitch == 2 && dstXPitch == 2) { 641
553 srcLine = src; 642 // orientation values
554 dstLine = dst; 643 data->userOrientation = ORIENTATION_UP;
555 y = height; 644 data->systemOrientation = WINCE_GetDMOrientation();
556 while (y--) { 645 data->hardwareGeometry = data->fb.width == data->fb.height ? GEOMETRY_SQUARE :
557 SDL_memcpy(dstLine, srcLine, width * sizeof(Uint16)); 646 (data->fb.width < data->fb.height ? GEOMETRY_PORTRAIT : GEOMETRY_LANDSCAPE);
558 srcLine += srcYPitch; 647
559 dstLine += dstYPitch; 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;
560 } 876 }
561 } else { 877
562 //printf("GAPI uses slow blit path %i, %i\n", dstXPitch, dstYPitch); 878 data->gapi->hGapiLib = LoadLibrary(TEXT("\\Windows\\gx.dll"));
563 srcLine = src; 879 if(0 == data->gapi->hGapiLib)
564 dstLine = dst; 880 {
565 y = height; 881 data->gapi->hGapiLib = LoadLibrary(TEXT("gx.dll"));
566 while (y--) { 882 if(0 == data->gapi->hGapiLib) return 0;
567 srcPix = srcLine; 883 }
568 dstPix = dstLine; 884
569 x = width; 885 // load gapi library
570 while (x--) { 886 #define LINK(type,name,import) name=(PFN##type)GetProcAddress(data->gapi->hGapiLib,TEXT(import))
571 *((Uint16 *) dstPix) = *((Uint16 *) srcPix); 887 LINK(GXOpenDisplay, data->gapi->GXOpenDisplay, "?GXOpenDisplay@@YAHPAUHWND__@@K@Z");
572 dstPix += dstXPitch; 888 LINK(GXCloseDisplay, data->gapi->GXCloseDisplay, "?GXCloseDisplay@@YAHXZ");
573 srcPix += srcXPitch; 889 LINK(GXBeginDraw, data->gapi->GXBeginDraw, "?GXBeginDraw@@YAPAXXZ");
574 } 890 LINK(GXEndDraw, data->gapi->GXEndDraw, "?GXEndDraw@@YAHXZ");
575 srcLine += srcYPitch; 891 LINK(GXGetDisplayProperties,data->gapi->GXGetDisplayProperties,"?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ");
576 dstLine += dstYPitch; 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;
577 } 966 }
578 } 967 else
579 } 968 {
580 969 data->flags |= FB_SKIP_OFFSET;
581 static int 970 data->pixels = data->gapi->GXBeginDraw();
582 GAPI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 971 data->gapi->GXEndDraw();
583 const SDL_Rect * srcrect, const SDL_Rect * dstrect) 972
584 { 973 if(data->debug)
585 GAPI_RenderData *data = (GAPI_RenderData *) renderer->driverdata; 974 {
586 int bpp; 975 printf("GAPI_Init\n");
587 int bytespp; 976 printf("use GXBeginDraw: %p\n", data->pixels);
588 int status; 977 printf("use skip offset\n");
589 Uint32 Rmask, Gmask, Bmask, Amask; 978 }
590 979 }
591 if (texture->format != data->format) { 980
592 SDL_SetError("Gapi got wrong texture"); 981 if(0 == data->format ||
593 return -1; 982 0 > WINCE_FixedGeometry(&data->fb, SDL_BYTESPERPIXEL(data->format), data->debug))
594 } 983 {
595 984 SDL_SetError("GAPI_Init: unknown hardware");
596 GAPI_LOG("GAPI_RenderCopy\n"); 985 GAPI_Quit(data);
597 986 return 0;
598 if (data->usageFlags & USAGE_GX_FUNCS) { 987 }
599 char *buffer; 988 }
600 buffer = gx.GXBeginDraw(); 989
601 if (!(data->usageFlags & USAGE_DATA_PTR_CONSTANT)) { 990 return data->gapi && data->pixels ? 1 : 0;
602 data->data = buffer; 991 }
603 } 992
604 } 993 void GAPI_Quit(WINCE_RenderData* data)
605 994 {
606 GAPI_LOG("GAPI_RenderCopy blit\n"); 995 if(data->gapi)
607 /* If our framebuffer has an xPitch which matches the pixelsize, we 996 {
608 can convert the framebuffer to a SDL_surface and blit there, 997 if(data->gapi->GXCloseDisplay) data->gapi->GXCloseDisplay();
609 otherwise, we have to use our own blitting routine 998 if(data->gapi->hGapiLib) FreeLibrary(data->gapi->hGapiLib);
610 */ 999
611 SDL_PixelFormatEnumToMasks(data->format, &bpp, &Rmask, &Gmask, &Bmask, 1000 SDL_free(data->gapi);
612 &Amask); 1001 data->gapi = NULL;
613 bytespp = bpp >> 3; 1002 }
614 if (data->xPitch == bytespp && 0) { 1003 }
615 SDL_Surface *screen = 1004
616 SDL_CreateRGBSurfaceFrom(data->data, data->w, data->h, 1005 int RAW_Init(WINCE_RenderData* data)
617 bpp, data->yPitch, Rmask, Gmask, Bmask, 1006 {
618 Amask); 1007 const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER");
619 status = 1008 if(preferably && 0 != SDL_strcasecmp(preferably, RAW_RENDER_NAME)) return 0;
620 SDL_UpperBlit((SDL_Surface *) texture->driverdata, srcrect, 1009
621 screen, dstrect); 1010 RawFrameBufferInfo rfbi = { 0 };
622 SDL_FreeSurface(screen); 1011 HDC hdc = GetDC(NULL);
623 } else { /* screen is rotated, we have to blit on our own */ 1012 int result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *) &rfbi);
624 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; 1013 ReleaseDC(NULL, hdc);
625 1014
626 char *src, *dst; 1015 //disable
627 src = surface->pixels; 1016 if(result == 0 || rfbi.pFramePointer == 0 ||
628 src += srcrect->y * surface->pitch + srcrect->x * 2; 1017 rfbi.cxPixels == 0 || rfbi.cyPixels == 0 ||
629 1018 rfbi.cxStride == 0 || rfbi.cyStride == 0) return 0;
630 dst = data->data + data->offset; 1019
631 dst += dstrect->y * data->yPitch + dstrect->x * data->xPitch; 1020 data->flags = FB_RAW_MODE;
632 1021
633 updateLine16to16(src, 2, surface->pitch, 1022 // fill FrameBufferInfo
634 dst, data->xPitch, data->yPitch, 1023 SDL_memset(&data->fb, 0, sizeof(FrameBufferInfo));
635 srcrect->w, srcrect->h); 1024
636 1025 data->fb.xpitch = rfbi.cxStride;
637 } 1026 data->fb.ypitch = rfbi.cyStride;
638 1027 data->fb.width = rfbi.cxPixels;
639 Uint32 ticks = SDL_GetTicks(); 1028 data->fb.height = rfbi.cyPixels;
640 if (data->usageFlags & USAGE_GX_FUNCS) { 1029 data->fb.offset = 0;
641 gx.GXEndDraw(); 1030
642 } 1031 if((FORMAT_565 & rfbi.wFormat) || 16 == rfbi.wBPP)
643 GAPI_LOG("GAPI_RenderCopy %i\n", SDL_GetTicks() - ticks); 1032 data->format = SDL_PIXELFORMAT_RGB565;
644 return status; 1033 else
645 } 1034 if((FORMAT_555 & rfbi.wFormat) || 15 == rfbi.wBPP)
646 1035 data->format = SDL_PIXELFORMAT_RGB555;
647 static void 1036 else
648 GAPI_RenderPresent(SDL_Renderer * renderer) 1037 data->format = 0;
649 { 1038
650 /* Nothing todo as we rendered directly to the screen on RenderCopy */ 1039 if(0 == data->format ||
651 } 1040 0 > WINCE_FixedGeometry(&data->fb, SDL_BYTESPERPIXEL(data->format), data->debug))
652 1041 {
653 static void 1042 SDL_SetError("RAW_Init: unknown hardware");
654 GAPI_DestroyRenderer(SDL_Renderer * renderer) 1043 RAW_Quit(data);
655 { 1044 return 0;
656 GAPI_RenderData *data = (GAPI_RenderData *) renderer->driverdata; 1045 }
657 1046
658 if (data->usageFlags & USAGE_GX_FUNCS) { 1047 data->pixels = rfbi.pFramePointer;
659 gx.GXCloseDisplay(); 1048
660 } 1049 return data->pixels ? 1 : 0;
661 1050 }
662 if (data) { 1051
663 SDL_free(data); 1052 void RAW_Quit(WINCE_RenderData* data)
664 } 1053 {
665 SDL_free(renderer); 1054 }
666 } 1055
667 1056 void FrameBufferInitialize(FrameBufferInfo* fb)
668 #endif /* SDL_VIDEO_RENDER_GAPI */ 1057 {
669 1058 int orientation = GetFrameBufferOrientation(fb);
670 /* vi: set ts=4 sw=4 expandtab: */ 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