Mercurial > sdl-ios-xcode
annotate src/video/windows/SDL_gapirender.c @ 5067:61d53410eb41
Fixed bug #859
CREATE_SUBDIRS helps a lot if browsing HTML documentation in a file browser.
ALWAYS_DETAILED_SEC makes sure everything has at least the automatic
documentation like function prototype and source references.
STRIP_FROM_PATH allows you to include only the relevant portions of the files'
paths, cleaning up both the file list and directory tree, though you need to
change the path listed here to match wherever you put SDL.
ALIASES avoids some warnings generated by
C:\source\svn.libsdl.org\trunk\SDL\src\joystick\darwin\10.3.9-FIX\IOHIDLib.h.
It seems Apple uses a few commands which are not normally supported by Doxygen.
BUILTIN_STL_SUPPORT adds support for parsing code which makes use of the
standard template library. There isn't a lot of C++ in SDL (some in bwindow at
least), but this still seems like a good idea.
TYPEDEF_HIDES_STRUCT means that for code like this:
typedef struct A {int B;} C;
C is documented as a structure containing B instead of a typedef mapped to A.
EXTRACT_ALL, EXTRACT_PRIVATE, EXTRACT_STATIC, EXTRACT_LOCAL_METHODS,
EXTRACT_ANON_NSPACES and INTERNAL_DOCS make sure that _everything_ is
documented.
CASE_SENSE_NAMES = NO avoids potential conflicts when building documentation on
case insensitive file systems like NTFS and FAT32.
WARN_NO_PARAMDOC lets you know when you have documented some, but not all, of
the parameters of a function. This is useful when you're working on adding
such documentation since it makes partially documented functions easier to
spot.
WARN_LOGFILE writes warnings to a seperate file instead of mixing them in with
stdout. When not running in quiet mode, these warnings can be hard to spot
without this flag.
I added *.h.in and *.h.default to FILE_PATTERNS to generate documentation for
config.h.in and config.h.default.
RECURSIVE tells doxygen to look not only in the input directory, but also in
subfolders.
EXCLUDE avoids documenting things like test programs, examples and templates
which need to be documented separately.
I've used EXCLUDE_PATTERNS to exclude non-source subdirectories that often find
their way into source folders (such as obj or .svn).
EXAMPLE_PATH lists directories doxygen will search to find included example
code. So far, SDL doesn't really use this feature, but I've listed some likely
locations.
SOURCE_BROWSER adds syntax highlighted source code to the HTML output.
USE_HTAGS is nice, but not available on Windows.
INLINE_SOURCES adds the body of a function to it's documentation so you can
quickly see exactly what it does.
ALPHABETICAL_INDEX generates an alphabetical list of all structures, functions,
etc., which makes it much easier to find what you're looking for.
IGNORE_PREFIX skips the SDL_ prefix when deciding which index page to place an
item on so you don't have everything show up under "S".
HTML_DYNAMIC_SECTIONS hides the includes/included by diagrams by default and
adds JavaScript to allow the user to show and hide them by clicking a link.
ENUM_VALUES_PER_LINE = 1 makes enums easier to read by placing each value on
it's own line.
GENERATE_TREEVIEW produces a two frame index page with a navigation tree on the
left.
I have LaTeX and man pages turned off to speed up doxygen, you may want to turn
them back on yourself.
I added _WIN32=1 to PREDEFINED to cause SDL to output documentation related to
Win32 builds of SDL. Normally, doxygen gets confused since there are multiple
definitions for various structures and formats that vary by platform. Without
this doxygen can produce broken documentation or, if you're lucky, output
documentation only for the dummy drivers, which isn't very useful. You need to
pick a platform.
GENERATE_TAGFILE produces a file which can be used to link other doxygen
documentation to the SDL documentation.
CLASS_DIAGRAMS turns on class diagrams even when dot is not available.
HAVE_DOT tells doxygen to try to use dot to generate diagrams.
TEMPLATE_RELATIONS and INCLUDE_GRAPH add additional diagrams to the
documentation.
DOT_MULTI_TARGETS speeds up dot.
OUTPUT_DIRECTORY, INPUT and other paths reflect the fact that this Doxyfile is
intended to process src as well as include and is being run from a separate
subdirectory. Doxygen produces several temporary files while it's running and
if interrupted, can leave those files behind. It's easier to clean up if there
aren't a hundred or so files in the same folder. I typically run doxygen in
SDL/doxy and set the output directory to '.'. Since doxygen puts it's output
in subfolders by type, this keeps things pretty well organised. You could use
'../doc' instead and get the same results.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 21 Jan 2011 12:57:01 -0800 |
parents | e8916fe9cfc8 |
children | c2539ff054c8 |
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 | |
5062 | 29 #include "SDL_windowsvideo.h" |
30 #include "SDL_windowswindow.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), | |
4929
aa8888658021
Use the enumerated type for blend and scale mode instead of int
Sam Lantinga <slouken@libsdl.org>
parents:
4569
diff
changeset
|
213 (SDL_SCALEMODE_NONE), |
4569 | 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), | |
4929
aa8888658021
Use the enumerated type for blend and scale mode instead of int
Sam Lantinga <slouken@libsdl.org>
parents:
4569
diff
changeset
|
236 (SDL_SCALEMODE_NONE), |
4569 | 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 |