Mercurial > sdl-ios-xcode
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 |