Mercurial > sdl-ios-xcode
comparison src/video/symbian/EKA2/SDL_epocvideo.cpp @ 3975:e85e65aec22f SDL-1.2
Added S60 port.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sun, 24 Jun 2007 18:26:35 +0000 |
parents | |
children | a1b03ba2fcd0 |
comparison
equal
deleted
inserted
replaced
3974:42578e98a295 | 3975:e85e65aec22f |
---|---|
1 /* | |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga | |
4 | |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
20 slouken@devolution.com | |
21 */ | |
22 | |
23 /* | |
24 SDL_epocvideo.cpp | |
25 Epoc based SDL video driver implementation | |
26 | |
27 Markus Mertama | |
28 */ | |
29 | |
30 | |
31 | |
32 #include "epoc_sdl.h" | |
33 | |
34 #include <stdlib.h> | |
35 #include <stdio.h> | |
36 #include <string.h> | |
37 | |
38 extern "C" { | |
39 #include "SDL_error.h" | |
40 #include "SDL_timer.h" | |
41 #include "SDL_video.h" | |
42 #undef NULL | |
43 #include "SDL_pixels_c.h" | |
44 #include "SDL.h" | |
45 #include "SDL_mouse.h" | |
46 } | |
47 | |
48 #include "SDL_epocvideo.h" | |
49 #include "SDL_epocevents_c.h" | |
50 | |
51 | |
52 | |
53 #include <coedef.h> | |
54 #include <flogger.h> | |
55 | |
56 #include <eikenv.h> | |
57 #include <eikappui.h> | |
58 #include <eikapp.h> | |
59 #include "sdlepocapi.h" | |
60 | |
61 | |
62 //////////////////////////////////////////////////////////////// | |
63 | |
64 | |
65 | |
66 | |
67 _LIT(KLibName, "SDL"); | |
68 | |
69 void RDebug_Print_b(char* error_str, void* param) | |
70 { | |
71 TBuf8<128> error8((TUint8*)error_str); | |
72 TBuf<128> error; | |
73 error.Copy(error8); | |
74 | |
75 #ifndef TRACE_TO_FILE | |
76 if (param) //!! Do not work if the parameter is really 0!! | |
77 RDebug::Print(error, param); | |
78 else | |
79 RDebug::Print(error); | |
80 #else | |
81 if (param) //!! Do not work if the parameter is really 0!! | |
82 RFileLogger::WriteFormat(KLibName, _L("SDL.txt"), EFileLoggingModeAppend, error, param); | |
83 else | |
84 RFileLogger::Write(KLibName, _L("SDL.txt"), EFileLoggingModeAppend, error); | |
85 #endif | |
86 | |
87 } | |
88 | |
89 extern "C" void RDebug_Print(char* error_str, void* param) | |
90 { | |
91 RDebug_Print_b(error_str, param); | |
92 } | |
93 | |
94 /* | |
95 int Debug_AvailMem2() | |
96 { | |
97 //User::CompressAllHeaps(); | |
98 TMemoryInfoV1Buf membuf; | |
99 User::LeaveIfError(UserHal::MemoryInfo(membuf)); | |
100 TMemoryInfoV1 minfo = membuf(); | |
101 return(minfo.iFreeRamInBytes); | |
102 } | |
103 | |
104 extern "C" int Debug_AvailMem() | |
105 { | |
106 return(Debug_AvailMem2()); | |
107 } | |
108 | |
109 */ | |
110 | |
111 extern "C" { | |
112 | |
113 /* Initialization/Query functions */ | |
114 | |
115 static int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat); | |
116 static SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | |
117 static SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | |
118 static int EPOC_SetColors(_THIS, int firstcolor, int ncolors, | |
119 SDL_Color *colors); | |
120 static void EPOC_VideoQuit(_THIS); | |
121 | |
122 /* Hardware surface functions */ | |
123 | |
124 static int EPOC_AllocHWSurface(_THIS, SDL_Surface *surface); | |
125 static int EPOC_LockHWSurface(_THIS, SDL_Surface *surface); | |
126 static int EPOC_FlipHWSurface(_THIS, SDL_Surface *surface); | |
127 static void EPOC_UnlockHWSurface(_THIS, SDL_Surface *surface); | |
128 static void EPOC_FreeHWSurface(_THIS, SDL_Surface *surface); | |
129 static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects); | |
130 | |
131 static int EPOC_Available(void); | |
132 static SDL_VideoDevice *EPOC_CreateDevice(int devindex); | |
133 | |
134 void DrawBackground(_THIS); | |
135 void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer); | |
136 void DirectDrawRotated(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer); | |
137 | |
138 /* Mouse functions */ | |
139 | |
140 static WMcursor *EPOC_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); | |
141 static void EPOC_FreeWMCursor(_THIS, WMcursor *cursor); | |
142 static int EPOC_ShowWMCursor(_THIS, WMcursor *cursor); | |
143 } | |
144 | |
145 | |
146 extern "C" | |
147 { | |
148 struct WMcursor | |
149 { | |
150 }; | |
151 } | |
152 | |
153 /* Epoc video driver bootstrap functions */ | |
154 | |
155 | |
156 static int EPOC_Available(void) | |
157 { | |
158 return 1; /* Always available */ | |
159 } | |
160 | |
161 static void EPOC_DeleteDevice(SDL_VideoDevice *device) | |
162 { | |
163 User::Free(device->hidden); | |
164 User::Free(device); | |
165 } | |
166 | |
167 static SDL_VideoDevice *EPOC_CreateDevice(int /*devindex*/) | |
168 { | |
169 SDL_VideoDevice *device; | |
170 | |
171 SDL_TRACE("SDL:EPOC_CreateDevice"); | |
172 | |
173 /* Allocate all variables that we free on delete */ | |
174 device = static_cast<SDL_VideoDevice*>(User::Alloc(sizeof(SDL_VideoDevice))); | |
175 if ( device ) | |
176 { | |
177 Mem::FillZ(device, (sizeof *device)); | |
178 device->hidden = static_cast<struct SDL_PrivateVideoData*> | |
179 (User::Alloc((sizeof *device->hidden))); | |
180 } | |
181 if ( (device == NULL) || (device->hidden == NULL) ) | |
182 { | |
183 SDL_OutOfMemory(); | |
184 if ( device ) { | |
185 User::Free(device); | |
186 } | |
187 return(0); | |
188 } | |
189 Mem::FillZ(device->hidden, (sizeof *device->hidden)); | |
190 | |
191 /* Set the function pointers */ | |
192 device->VideoInit = EPOC_VideoInit; | |
193 device->ListModes = EPOC_ListModes; | |
194 device->SetVideoMode = EPOC_SetVideoMode; | |
195 device->SetColors = EPOC_SetColors; | |
196 device->UpdateRects = NULL; | |
197 device->VideoQuit = EPOC_VideoQuit; | |
198 device->AllocHWSurface = EPOC_AllocHWSurface; | |
199 device->CheckHWBlit = NULL; | |
200 device->FillHWRect = NULL; | |
201 device->SetHWColorKey = NULL; | |
202 device->SetHWAlpha = NULL; | |
203 device->LockHWSurface = EPOC_LockHWSurface; | |
204 device->UnlockHWSurface = EPOC_UnlockHWSurface; | |
205 device->FlipHWSurface = EPOC_FlipHWSurface; | |
206 device->FreeHWSurface = EPOC_FreeHWSurface; | |
207 device->SetIcon = NULL; | |
208 device->SetCaption = NULL; | |
209 device->GetWMInfo = NULL; | |
210 device->FreeWMCursor = EPOC_FreeWMCursor; | |
211 device->CreateWMCursor = EPOC_CreateWMCursor; | |
212 device->ShowWMCursor = EPOC_ShowWMCursor; | |
213 device->WarpWMCursor = NULL; | |
214 device->InitOSKeymap = EPOC_InitOSKeymap; | |
215 device->PumpEvents = EPOC_PumpEvents; | |
216 device->free = EPOC_DeleteDevice; | |
217 | |
218 return device; | |
219 } | |
220 | |
221 | |
222 VideoBootStrap EPOC_bootstrap = { | |
223 "epoc\0\0\0", "EPOC system", | |
224 EPOC_Available, EPOC_CreateDevice | |
225 }; | |
226 | |
227 | |
228 | |
229 void DisableKeyBlocking(_THIS) | |
230 { | |
231 EpocSdlEnv::Request(EpocSdlEnv::EDisableKeyBlocking); | |
232 } | |
233 | |
234 void ConstructWindowL(_THIS) | |
235 { | |
236 SDL_TRACE("SDL:ConstructWindowL"); | |
237 DisableKeyBlocking(_this); //disable key blocking | |
238 } | |
239 | |
240 | |
241 int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat) | |
242 { | |
243 /* Construct Epoc window */ | |
244 | |
245 ConstructWindowL(_this); | |
246 | |
247 /* Initialise Epoc frame buffer */ | |
248 | |
249 | |
250 const TDisplayMode displayMode = EpocSdlEnv::DisplayMode(); | |
251 | |
252 /* The "best" video format should be returned to caller. */ | |
253 | |
254 vformat->BitsPerPixel = TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode); | |
255 vformat->BytesPerPixel = TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode) / 8; | |
256 | |
257 | |
258 //?? Private->iWindow->PointerFilter(EPointerFilterDrag, 0); | |
259 | |
260 Private->iScreenPos = TPoint(0, 0); | |
261 | |
262 Private->iRect.x = Private->iScreenPos.iX; | |
263 Private->iRect.y = Private->iScreenPos.iY; | |
264 | |
265 const TSize sz = EpocSdlEnv::WindowSize(); | |
266 | |
267 Private->iRect.w = sz.iWidth; | |
268 Private->iRect.h = sz.iHeight; | |
269 Private->iRectPtr = &Private->iRect; | |
270 | |
271 return(0); | |
272 } | |
273 | |
274 | |
275 SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | |
276 { | |
277 if(flags & SDL_HWSURFACE) | |
278 { | |
279 if(format->BytesPerPixel != 4) //in HW only full color is supported | |
280 return NULL; | |
281 } | |
282 if(flags & SDL_FULLSCREEN) | |
283 { | |
284 return &Private->iRectPtr; | |
285 } | |
286 return (SDL_Rect **)(-1); //everythingisok, unless too small shoes | |
287 } | |
288 | |
289 | |
290 int EPOC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) | |
291 { | |
292 if ((firstcolor+ncolors) > 256) | |
293 return -1; | |
294 TUint32 palette[256]; | |
295 const TDisplayMode mode = EpocSdlEnv::DisplayMode(); | |
296 if(TDisplayModeUtils::NumDisplayModeColors(mode) == 4096) | |
297 { | |
298 // Set 12 bit palette | |
299 for(int i = firstcolor; i < ncolors; i++) | |
300 { | |
301 // 4k value: 0000 rrrr gggg bbbb | |
302 TUint32 color4K = (colors[i].r & 0x0000f0) << 4; | |
303 color4K |= (colors[i].g & 0x0000f0); | |
304 color4K |= (colors[i].b & 0x0000f0) >> 4; | |
305 palette[i] = color4K; | |
306 } | |
307 } | |
308 else if(TDisplayModeUtils::NumDisplayModeColors(mode) == 65536) | |
309 { | |
310 for(int i = firstcolor; i < ncolors; i++) | |
311 { | |
312 // 64k-colour displays effectively support RGB values | |
313 // with 5 bits allocated to red, 6 to green and 5 to blue | |
314 // 64k value: rrrr rggg gggb bbbb | |
315 TUint32 color64K = (colors[i].r & 0x0000f8) << 8; | |
316 color64K |= (colors[i].g & 0x0000fc) << 3; | |
317 color64K |= (colors[i].b & 0x0000f8) >> 3; | |
318 palette[i] = color64K; | |
319 } | |
320 } | |
321 else if(TDisplayModeUtils::NumDisplayModeColors(mode) == 16777216) | |
322 { | |
323 for(int i = firstcolor; i < ncolors; i++) | |
324 { | |
325 // 16M-colour | |
326 //0000 0000 rrrr rrrr gggg gggg bbbb bbbb | |
327 TUint32 color16M = colors[i].r << 16; | |
328 color16M |= colors[i].g << 8; | |
329 color16M |= colors[i].b; | |
330 palette[i] = color16M; | |
331 } | |
332 } | |
333 else | |
334 { | |
335 return -2; | |
336 } | |
337 if(EpocSdlEnv::SetPalette(firstcolor, ncolors, palette) == KErrNone) | |
338 return 0; | |
339 return -1; | |
340 } | |
341 | |
342 | |
343 /* | |
344 void AllocHWSurfaceL(CFbsBitmap*& aBitmap, const TDisplayMode& aMode, const TSize& aSize) | |
345 { | |
346 aBitmap = new (ELeave) CFbsBitmap(); | |
347 if(KErrNone != aBitmap->CreateHardwareBitmap(aSize, aMode, | |
348 EpocSdlEnv::EikonEnv().EikAppUi()->Application()->AppDllUid())) | |
349 //...if it fails - should we use wsbitmaps??? | |
350 {//the good reason to use hw bitmaps is that they wont need lock heap | |
351 PANIC_IF_ERROR(aBitmap->Create(aSize, aMode)); | |
352 } | |
353 } | |
354 | |
355 int CreateSurfaceL(_THIS, SDL_Surface* surface) | |
356 { | |
357 __ASSERT_ALWAYS(Private->iFrame == NULL, PANIC(KErrAlreadyExists)); | |
358 ; | |
359 TInt dmode = EColorLast; | |
360 | |
361 TDisplayMode displayMode; | |
362 EpocSdlEnv::GetDiplayMode(displayMode); | |
363 | |
364 if( | |
365 TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode) | |
366 == surface->format->BitsPerPixel) | |
367 { | |
368 dmode = displayMode; | |
369 } | |
370 else | |
371 { | |
372 --dmode; | |
373 while(TDisplayModeUtils::IsDisplayModeColor(TDisplayMode(dmode)) && | |
374 TDisplayModeUtils::NumDisplayModeBitsPerPixel(TDisplayMode(dmode)) != | |
375 surface->format->BitsPerPixel) | |
376 --dmode; | |
377 } | |
378 | |
379 __ASSERT_ALWAYS(TDisplayModeUtils::IsDisplayModeColor(TDisplayMode(dmode)), PANIC(KErrNotSupported)); | |
380 TRAPD(err, AllocHWSurfaceL(Private->iFrame, TDisplayMode(dmode), TSize(surface->w, surface->h))); | |
381 return err == KErrNone ? 0 : -1; | |
382 } | |
383 */ | |
384 | |
385 TDisplayMode GetDisplayMode(TInt aBitsPerPixel) | |
386 { | |
387 const TDisplayMode displayMode = EpocSdlEnv::DisplayMode(); | |
388 TInt dmode = EColorLast; | |
389 if( | |
390 TDisplayModeUtils::NumDisplayModeBitsPerPixel(displayMode) | |
391 == aBitsPerPixel) | |
392 { | |
393 dmode = displayMode; | |
394 } | |
395 else | |
396 { | |
397 --dmode; | |
398 while(TDisplayModeUtils::IsDisplayModeColor(TDisplayMode(dmode)) && | |
399 TDisplayModeUtils::NumDisplayModeBitsPerPixel(TDisplayMode(dmode)) != | |
400 aBitsPerPixel) | |
401 --dmode; | |
402 } | |
403 return TDisplayMode(dmode); | |
404 } | |
405 | |
406 SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current, | |
407 int width, int height, int bpp, Uint32 flags) | |
408 { | |
409 const TSize screenSize = EpocSdlEnv::WindowSize(TSize(width, height)); | |
410 if(width > screenSize.iWidth || height > screenSize.iHeight) | |
411 { | |
412 if(flags & SDL_FULLSCREEN) | |
413 { | |
414 width = screenSize.iWidth; | |
415 height = screenSize.iHeight; | |
416 } | |
417 else | |
418 return NULL; | |
419 } | |
420 | |
421 if(current && current->pixels) | |
422 { | |
423 // free(current->pixels); | |
424 current->pixels = NULL; | |
425 } | |
426 | |
427 if(!SDL_ReallocFormat(current, bpp, 0, 0, 0, 0)) | |
428 { | |
429 return(NULL); | |
430 } | |
431 | |
432 current->flags = 0; | |
433 if(width == screenSize.iWidth && height == screenSize.iHeight) | |
434 current->flags |= SDL_FULLSCREEN; | |
435 | |
436 const int numBytesPerPixel = ((bpp-1)>>3) + 1; | |
437 current->pitch = numBytesPerPixel * width; // Number of bytes in scanline | |
438 | |
439 /* Set up the new mode framebuffer */ | |
440 current->flags |= SDL_PREALLOC; | |
441 | |
442 if(bpp <= 8) | |
443 current->flags |= SDL_HWPALETTE; | |
444 | |
445 User::Free(Private->iSwSurface); | |
446 current->pixels = NULL; | |
447 Private->iSwSurface = NULL; | |
448 | |
449 if(flags & SDL_HWSURFACE) | |
450 { | |
451 current->flags |= SDL_HWSURFACE; | |
452 // current->pixels = NULL; | |
453 // Private->iSwSurface = NULL; | |
454 } | |
455 else | |
456 { | |
457 current->flags |= SDL_SWSURFACE; | |
458 const TInt surfacesize = width * height * numBytesPerPixel; | |
459 Private->iSwSurfaceSize = TSize(width, height); | |
460 delete Private->iSwSurface; | |
461 Private->iSwSurface = NULL; | |
462 current->pixels = (TUint8*) User::AllocL(surfacesize); | |
463 Private->iSwSurface = (TUint8*) current->pixels; | |
464 const TInt err = EpocSdlEnv::AllocSwSurface | |
465 (TSize(width, height), GetDisplayMode(current->format->BitsPerPixel)); | |
466 if(err != KErrNone) | |
467 return NULL; | |
468 } | |
469 | |
470 current->w = width; | |
471 current->h = height; | |
472 | |
473 | |
474 | |
475 /* Set the blit function */ | |
476 _this->UpdateRects = EPOC_DirectUpdate; | |
477 | |
478 /* | |
479 * Logic for getting suitable screen dimensions, offset, scaling and orientation | |
480 */ | |
481 | |
482 | |
483 /* Centralize game window on device screen */ | |
484 | |
485 | |
486 Private->iScreenPos.iX = Max(0, (screenSize.iWidth - width) / 2); | |
487 Private->iScreenPos.iY = Max(0, (screenSize.iHeight - height) / 2); | |
488 | |
489 // delete (Private->iFrame); | |
490 // Private->iFrame = NULL; | |
491 | |
492 // TRAPD(err, CreateSurfaceL(_this, current)); | |
493 // PANIC_IF_ERROR(err); | |
494 | |
495 SDL_TRACE1("View width %d", width); | |
496 SDL_TRACE1("View height %d", height); | |
497 SDL_TRACE1("View bmode %d", bpp); | |
498 SDL_TRACE1("View x %d", Private->iScreenPos.iX); | |
499 SDL_TRACE1("View y %d", Private->iScreenPos.iY); | |
500 | |
501 EpocSdlEnv::LockPalette(EFalse); | |
502 /* We're done */ | |
503 return(current); | |
504 } | |
505 | |
506 | |
507 | |
508 static int EPOC_AllocHWSurface(_THIS, SDL_Surface* surface) | |
509 { | |
510 return KErrNone == EpocSdlEnv::AllocHwSurface(TSize(surface->w, surface->h), GetDisplayMode(surface->format->BitsPerPixel)); | |
511 } | |
512 | |
513 static void EPOC_FreeHWSurface(_THIS, SDL_Surface* /*surface*/) | |
514 { | |
515 } | |
516 | |
517 static int EPOC_LockHWSurface(_THIS, SDL_Surface* surface) | |
518 { | |
519 if(EpocSdlEnv::IsDsaAvailable()) | |
520 { | |
521 TUint8* address = EpocSdlEnv::LockHwSurface(); | |
522 if(address != NULL) | |
523 { | |
524 surface->pixels = address; | |
525 return 1; | |
526 } | |
527 } | |
528 return 0; | |
529 } | |
530 static void EPOC_UnlockHWSurface(_THIS, SDL_Surface* /*surface*/) | |
531 { | |
532 EpocSdlEnv::UnlockHwSurface(); | |
533 } | |
534 | |
535 static int EPOC_FlipHWSurface(_THIS, SDL_Surface* /*surface*/) | |
536 { | |
537 return(0); | |
538 } | |
539 | |
540 static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) | |
541 { | |
542 if(EpocSdlEnv::IsDsaAvailable()) | |
543 { | |
544 if(Private->iSwSurface) | |
545 { | |
546 const TRect target(Private->iScreenPos, Private->iSwSurfaceSize); | |
547 for(TInt i = 0; i < numrects ;i++) | |
548 { | |
549 const TRect rect(TPoint(rects[i].x, rects[i].y), | |
550 TSize(rects[i].w, rects[i].h)); | |
551 if(!EpocSdlEnv::AddUpdateRect(Private->iSwSurface, rect, target)) | |
552 return; //not succesful | |
553 } | |
554 EpocSdlEnv::UpdateSwSurface(); | |
555 } | |
556 SDL_PauseAudio(0); | |
557 } | |
558 else | |
559 { | |
560 SDL_PauseAudio(1); | |
561 EpocSdlEnv::WaitDsaAvailable(); | |
562 } | |
563 } | |
564 | |
565 | |
566 /* Note: If we are terminated, this could be called in the middle of | |
567 another SDL video routine -- notably UpdateRects. | |
568 */ | |
569 void EPOC_VideoQuit(_THIS) | |
570 { | |
571 // delete Private->iFrame; | |
572 // Private->iFrame = NULL; | |
573 User::Free(Private->iSwSurface); | |
574 Private->iSwSurface = NULL; | |
575 EpocSdlEnv::FreeSurface(); | |
576 } | |
577 | |
578 | |
579 | |
580 | |
581 WMcursor *EPOC_CreateWMCursor(_THIS, Uint8* /*data*/, Uint8* /*mask*/, int /*w*/, int /*h*/, int /*hot_x*/, int /*hot_y*/) | |
582 { | |
583 return (WMcursor*) 1; //hii! prevents SDL to view a std cursor | |
584 } | |
585 | |
586 void EPOC_FreeWMCursor(_THIS, WMcursor* /*cursor*/) | |
587 { | |
588 } | |
589 | |
590 int EPOC_ShowWMCursor(_THIS, WMcursor *cursor) | |
591 { | |
592 return true; | |
593 } | |
594 |