Mercurial > sdl-ios-xcode
annotate src/video/win32/SDL_gapirender.c @ 4897:c3eb55210a90
SDL_DestroyWindow is setting window->magic to NULL too early. -
window->magic is also checked in SDL_DestroyRenderer. All cleanup code
like freeing the renderer and textures is not executed.
The patch moves window_magic = NULL behind the SDL_DestroyRenderer call.
Kind regards,
André
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 27 Sep 2010 00:49:34 -0700 |
parents | e1664f94f026 |
children | aa8888658021 |
rev | line source |
---|---|
4569 | 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 ***************************************************************************/ | |
3168 | 24 |
25 #include "SDL_config.h" | |
26 | |
27 #if SDL_VIDEO_RENDER_GAPI | |
28 | |
29 #include "SDL_win32video.h" | |
4569 | 30 #include "SDL_win32window.h" |
3168 | 31 #include "../SDL_yuv_sw_c.h" |
32 | |
4569 | 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; | |
3168 | 44 |
4569 | 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; | |
3168 | 57 |
4569 | 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; | |
3168 | 67 }; |
68 | |
4569 | 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)(); | |
3168 | 77 |
4569 | 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 | |
3168 | 106 |
4569 | 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; | |
3168 | 122 |
4569 | 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; | |
3168 | 136 |
4569 | 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; | |
3168 | 147 |
148 | |
4569 | 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; }; | |
3168 | 202 |
4569 | 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_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 | |
3168 | 226 } |
4569 | 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_TEXTURESCALEMODE_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; | |
3168 | 277 } |
278 | |
4569 | 279 void WINCE_AddRenderDriver(_THIS) |
3168 | 280 { |
4569 | 281 HDC hdc; |
282 HMODULE render_gapi; | |
283 int render_raw, ii; | |
284 const char* preferably = SDL_getenv("SDL_VIDEO_RENDERER"); | |
3520
83518f8fcd61
Fixed calls to SDL_AddRenderDriver()
Sam Lantinga <slouken@libsdl.org>
parents:
3168
diff
changeset
|
285 |
4569 | 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); | |
3168 | 291 |
4569 | 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; | |
3168 | 295 |
4569 | 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); | |
3168 | 303 |
4569 | 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 } | |
3520
83518f8fcd61
Fixed calls to SDL_AddRenderDriver()
Sam Lantinga <slouken@libsdl.org>
parents:
3168
diff
changeset
|
321 } |
3168 | 322 } |
323 | |
4569 | 324 SDL_Renderer* WINCE_CreateRenderer(SDL_Window* window, Uint32 flags) |
3168 | 325 { |
4569 | 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; | |
3168 | 333 |
4569 | 334 if(!(window->flags & SDL_WINDOW_FULLSCREEN)) |
335 window->flags |= SDL_WINDOW_FULLSCREEN; | |
3168 | 336 |
4569 | 337 if(!SDL_PixelFormatEnumToMasks(displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) |
338 { | |
339 SDL_SetError("Unknown display format"); | |
3168 | 340 return NULL; |
341 } | |
342 | |
4569 | 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; | |
3168 | 352 } |
353 | |
4569 | 354 renderer = (SDL_Renderer*) SDL_calloc(1, sizeof(SDL_Renderer)); |
355 if(!renderer) | |
356 { | |
3168 | 357 SDL_OutOfMemory(); |
358 return NULL; | |
359 } | |
360 | |
4569 | 361 data = (WINCE_RenderData*) SDL_calloc(1, sizeof(WINCE_RenderData)); |
362 if(!data) | |
363 { | |
364 WINCE_DestroyRenderer(renderer); | |
3168 | 365 SDL_OutOfMemory(); |
366 return NULL; | |
367 } | |
368 | |
4569 | 369 // initialize internal engine |
370 if(!RAW_Init(data) && !GAPI_Init(data, windowdata->hwnd)) | |
3168 | 371 { |
4569 | 372 WINCE_DestroyRenderer(renderer); |
3168 | 373 return NULL; |
374 } | |
375 | |
376 | |
4569 | 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 | |
3168 | 382 |
4569 | 383 windowdata->videodata->render = data->gapi ? RENDER_GAPI : RENDER_RAW; |
384 windowdata->videodata->CoordTransform = WINCE_PointerCoordinateTransform; | |
3168 | 385 |
4569 | 386 window->display->device->MaximizeWindow = NULL; |
387 window->display->device->MinimizeWindow = NULL; | |
3168 | 388 |
4569 | 389 WINCE_SetupOrientation(data, window->w, window->h); |
3168 | 390 |
4569 | 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; | |
3168 | 397 |
4569 | 398 renderer->RenderCopy = WINCE_RenderCopy; |
399 renderer->DestroyRenderer = WINCE_DestroyRenderer; | |
3168 | 400 |
4569 | 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; | |
3168 | 406 |
4569 | 407 renderer->info = data->gapi ? GAPI_RenderDriver.info : RAW_RenderDriver.info; |
3168 | 408 |
3685
64ce267332c6
Switched from SDL_WindowID and SDL_TextureID to SDL_Window* and SDL_Texture* for code simplicity and improved performance.
Sam Lantinga <slouken@libsdl.org>
parents:
3612
diff
changeset
|
409 renderer->window = window; |
3168 | 410 renderer->driverdata = data; |
411 | |
412 return renderer; | |
413 } | |
414 | |
4569 | 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) | |
3168 | 499 { |
4569 | 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 { | |
3612
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
607 SDL_Unsupported(); |
3168 | 608 return -1; |
609 } | |
610 | |
4569 | 611 int WINCE_RenderDrawLines(SDL_Renderer* renderer, const SDL_Point* points, int count) |
3168 | 612 { |
3612
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
613 SDL_Unsupported(); |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
614 return -1; |
3168 | 615 } |
616 | |
4569 | 617 int WINCE_RenderDrawRects(SDL_Renderer* renderer, const SDL_Rect ** rects, int count) |
3168 | 618 { |
3612
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
619 SDL_Unsupported(); |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
620 return -1; |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
621 } |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
622 |
4569 | 623 int WINCE_RenderFillRects(SDL_Renderer* renderer, const SDL_Rect** rects, int count) |
3612
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
624 { |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
625 SDL_Unsupported(); |
3168 | 626 return -1; |
627 } | |
628 | |
4569 | 629 |
630 | |
631 void WINCE_SetupOrientation(WINCE_RenderData* data, int width, int height) | |
3168 | 632 { |
4569 | 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; | |
3168 | 655 |
4569 | 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"); | |
3168 | 684 |
4569 | 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 } | |
3168 | 744 } |
745 } | |
746 | |
4569 | 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) | |
3168 | 778 { |
4569 | 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 } | |
3168 | 805 |
4569 | 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; | |
3168 | 847 } |
848 | |
4569 | 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(); | |
3168 | 914 |
4569 | 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; | |
3168 | 966 } |
4569 | 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 } | |
3168 | 988 } |
989 | |
4569 | 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; | |
3168 | 1030 |
4569 | 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 } | |
3168 | 1055 |
4569 | 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; | |
3168 | 1066 |
4569 | 1067 case ORIENTATION_LEFT: |
1068 fb->offset = __abs(fb->ypitch * (fb->height - 1)); | |
1069 break; | |
3168 | 1070 |
4569 | 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; | |
3168 | 1081 } |
1082 | |
4569 | 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; | |
3168 | 1091 } |
4569 | 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; | |
3168 | 1109 } |
1110 | |
4569 | 1111 void FrameBufferRotate(FrameBufferInfo* dst, int orientation) |
3168 | 1112 { |
4569 | 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 } | |
3168 | 1175 } |
1176 | |
4569 | 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) | |
3168 | 1192 { |
4569 | 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 } | |
3168 | 1207 |
4569 | 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; | |
3168 | 1225 } |
1226 | |
4569 | 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)); | |
3168 | 1244 } |
1245 | |
4569 | 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; | |
3168 | 1259 |
4569 | 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 |