📄 sdl_epocvideo.cpp
字号:
ConstructWindowL(_this); /* Initialise Epoc frame buffer */ TDisplayMode displayMode = Private->EPOC_WsScreen->DisplayMode();#if !defined(__WINS__) && !defined(TEST_BM_DRAW) TScreenInfoV01 screenInfo; TPckg<TScreenInfoV01> sInfo(screenInfo); UserSvr::ScreenInfo(sInfo); Private->EPOC_ScreenSize = screenInfo.iScreenSize; Private->EPOC_DisplayMode = displayMode; Private->EPOC_HasFrameBuffer = screenInfo.iScreenAddressValid; Private->EPOC_FrameBuffer = Private->EPOC_HasFrameBuffer ? (TUint8*) screenInfo.iScreenAddress : NULL; Private->EPOC_BytesPerPixel = ((GetBpp(displayMode)-1) / 8) + 1; Private->EPOC_BytesPerScanLine = screenInfo.iScreenSize.iWidth * Private->EPOC_BytesPerPixel; Private->EPOC_BytesPerScreen = Private->EPOC_BytesPerScanLine * Private->EPOC_ScreenSize.iHeight; SDL_TRACE1("Screen width %d", screenInfo.iScreenSize.iWidth); SDL_TRACE1("Screen height %d", screenInfo.iScreenSize.iHeight); SDL_TRACE1("Screen dmode %d", displayMode); SDL_TRACE1("Screen valid %d", screenInfo.iScreenAddressValid); SDL_TRACE1("bpp %d", Private->EPOC_BytesPerPixel); SDL_TRACE1("bpsl %d", Private->EPOC_BytesPerScanLine); SDL_TRACE1("bps %d", Private->EPOC_BytesPerScreen); /* It seems that in SA1100 machines for 8bpp displays there is a 512 palette table at the * beginning of the frame buffer. E.g. Series 7 and Netbook. * In 12 bpp machines the table has 16 entries. */ if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 8) { Private->EPOC_FrameBuffer += 512; } else { Private->EPOC_FrameBuffer += 32; } /*if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 12) Private->EPOC_FrameBuffer += 16 * 2; if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 16) Private->EPOC_FrameBuffer += 16 * 2; */#else /* defined __WINS__ */ /* Create bitmap, device and context for screen drawing */ Private->EPOC_ScreenSize = Private->EPOC_WsScreen->SizeInPixels(); Private->EPOC_Bitmap = new (ELeave) CWsBitmap(Private->EPOC_WsSession); Private->EPOC_Bitmap->Create(Private->EPOC_ScreenSize, displayMode); Private->EPOC_DisplayMode = displayMode; Private->EPOC_HasFrameBuffer = ETrue; Private->EPOC_FrameBuffer = NULL; /* Private->EPOC_Bitmap->DataAddress() can change any time */ Private->EPOC_BytesPerPixel = ((GetBpp(displayMode)-1) / 8) + 1; Private->EPOC_BytesPerScanLine = Private->EPOC_WsScreen->SizeInPixels().iWidth * Private->EPOC_BytesPerPixel;#endif /* __WINS__ */#ifndef SYMBIAN_CRYSTAL // Get draw device for updating the screen TScreenInfoV01 screenInfo2; Epoc_Runtime::GetScreenInfo(screenInfo2); TRAPD(status, Private->EPOC_DrawDevice = CFbsDrawDevice::NewScreenDeviceL(screenInfo2, displayMode)); User::LeaveIfError(status);#endif /* The "best" video format should be returned to caller. */ vformat->BitsPerPixel = /*!!GetBpp(displayMode) */ 8; vformat->BytesPerPixel = /*!!Private->EPOC_BytesPerPixel*/ 1; /* Activate events for me */ Private->EPOC_WsEventStatus = KRequestPending; Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus); SDL_TRACE("SDL:WsEventStatus"); User::WaitForRequest(Private->EPOC_WsEventStatus); //Markus: I added this and ... Private->EPOC_RedrawEventStatus = KRequestPending; Private->EPOC_WsSession.RedrawReady(&Private->EPOC_RedrawEventStatus); SDL_TRACE("SDL:RedrawEventStatus"); User::WaitForRequest(Private->EPOC_RedrawEventStatus); //...this, if not catches a stray event is risen //if there are active objects used, or confucing //actions with User::WaitForAnyRequest Private->EPOC_WsWindow.PointerFilter(EPointerFilterDrag, 0); Private->EPOC_ScreenOffset = TPoint(0, 0);#if defined(__WINS__) || defined(TEST_BM_DRAW) LockHeap(Private->EPOC_Bitmap); // Lock bitmap heap#endif SDL_TRACE("SDL:DrawBackground"); DrawBackground(_this); // Clear screen#if defined(__WINS__) || defined(TEST_BM_DRAW) UnlockHeap(Private->EPOC_Bitmap); // Unlock bitmap heap#endif //!! TODO: error handling //if (ret != KErrNone) // return(-1); //else return(0);}SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 /*flags*/){ if (format->BitsPerPixel == 12 || format->BitsPerPixel == 8) return Private->SDL_modelist; return NULL;}int EPOC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors){ if ((firstcolor+ncolors) > 256) return -1;// SDL_TRACE1("colors %d", (TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode))); if(TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode) == 4096) { // Set 12 bit palette for(int i = firstcolor; i < ncolors; i++) { // 4k value: 0000 rrrr gggg bbbb TUint32 color4K = (colors[i].r & 0x0000f0) << 4; color4K |= (colors[i].g & 0x0000f0); color4K |= (colors[i].b & 0x0000f0) >> 4; EPOC_HWPalette_256_to_Screen[i] = color4K; } } else if(TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode) == 65536) { for(int i = firstcolor; i < ncolors; i++) { // 64k-colour displays effectively support RGB values // with 5 bits allocated to red, 6 to green and 5 to blue // 64k value: rrrr rggg gggb bbbb TUint32 color64K = (colors[i].r & 0x0000f8) << 8; color64K |= (colors[i].g & 0x0000fc) << 3; color64K |= (colors[i].b & 0x0000f8) >> 3; EPOC_HWPalette_256_to_Screen[i] = color64K; } } else if(TDisplayModeUtils::NumDisplayModeColors(Private->EPOC_DisplayMode) == 16777216) { for(int i = firstcolor; i < ncolors; i++) { // 16M-colour //0000 0000 rrrr rrrr gggg gggg bbbb bbbb TUint32 color16M = colors[i].r << 16; color16M |= colors[i].g << 8; color16M |= colors[i].b; EPOC_HWPalette_256_to_Screen[i] = color16M; } } else { return -2; } return(0);}SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 /*flags*/){ SDL_TRACE("SDL:EPOC_SetVideoMode"); /* Check parameters */#ifdef SYMBIAN_CRYSTAL if (! (bpp == 8 || bpp == 12 || bpp == 16) && ( (width == 640 && height == 200) || (width == 640 && height == 400) || (width == 640 && height == 480) || (width == 320 && height == 200) || (width == 320 && height == 240) )) { SDL_SetError("Requested video mode is not supported"); return NULL; }#else // SYMBIAN_SERIES60 if (! (bpp == 8 || bpp == 12 || bpp == 16) && ( (width == 320 && height == 200) || (width == 320 && height == 240) || (width == 256 && height == 192) || (width == 176 && height == 208) || (width == 208 && height == 176) || // Rotated (width == 160 && height == 144) )) { SDL_SetError("Requested video mode is not supported"); return NULL; }#endif if (current && current->pixels) { free(current->pixels); current->pixels = NULL; } if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) { return(NULL); } /* Set up the new mode framebuffer */ if (bpp == 8) current->flags = (SDL_FULLSCREEN|SDL_SWSURFACE|SDL_PREALLOC|SDL_HWPALETTE); else // 12 bpp, 16 bpp current->flags = (SDL_FULLSCREEN|SDL_SWSURFACE|SDL_PREALLOC); current->w = width; current->h = height; int numBytesPerPixel = ((bpp-1)>>3) + 1; current->pitch = numBytesPerPixel * width; // Number of bytes in scanline current->pixels = malloc(width * height * numBytesPerPixel); memset(current->pixels, 0, width * height * numBytesPerPixel); /* Set the blit function */ _this->UpdateRects = EPOC_DirectUpdate; /* * Logic for getting suitable screen dimensions, offset, scaling and orientation */ int w = current->w; int h = current->h; // Rotate, if the screen does not fit horizontally and it is landscape screen/* if ((width>Private->EPOC_ScreenSize.iWidth) && (width>height)) { Private->EPOC_ScreenOrientation = CFbsBitGc::EGraphicsOrientationRotated270; w = current->h; h = current->w; }*/ // Get nearest stepwise scale values for width and height. The smallest supported scaled screen is 1/2. TInt scaleValue = 0; Private->EPOC_ScreenXScaleValue = 1; Private->EPOC_ScreenYScaleValue = 1; if (w > Private->EPOC_ScreenSize.iWidth) { // Find the biggest scale value that result the width that fits in the screen HW for (scaleValue = 2; scaleValue++;) { TInt scaledWidth = (w * (scaleValue-1))/scaleValue; if (scaledWidth > Private->EPOC_ScreenSize.iWidth) break; } Private->EPOC_ScreenXScaleValue = Max(2, scaleValue - 1); w = (w * (Private->EPOC_ScreenXScaleValue-1))/Private->EPOC_ScreenXScaleValue; } if (h > Private->EPOC_ScreenSize.iHeight) { // Find the biggest scale value that result the height that fits in the screen HW for (scaleValue = 2; scaleValue++;) { TInt scaledHeight = (h * (scaleValue-1))/scaleValue; if (scaledHeight > Private->EPOC_ScreenSize.iHeight) break; } Private->EPOC_ScreenYScaleValue = Max(2, scaleValue - 1); h = (h * (Private->EPOC_ScreenYScaleValue-1))/Private->EPOC_ScreenYScaleValue; } /* Centralize game window on device screen */ Private->EPOC_ScreenOffset.iX = (Private->EPOC_ScreenSize.iWidth - w) / 2; if (Private->EPOC_ScreenOffset.iX < 0) Private->EPOC_ScreenOffset.iX = 0; Private->EPOC_ScreenOffset.iY = (Private->EPOC_ScreenSize.iHeight - h) / 2; if (Private->EPOC_ScreenOffset.iY < 0) Private->EPOC_ScreenOffset.iY = 0; SDL_TRACE1("View width %d", w); SDL_TRACE1("View height %d", h); SDL_TRACE1("View bmode %d", bpp); SDL_TRACE1("View s %d", scaleValue); SDL_TRACE1("View x %d", Private->EPOC_ScreenOffset.iX); SDL_TRACE1("View y %d", Private->EPOC_ScreenOffset.iY); /* We're done */ return(current);}void RedrawWindowL(_THIS){#if defined(__WINS__) || defined(TEST_BM_DRAW) LockHeap(Private->EPOC_Bitmap); // Lock bitmap heap Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow);#endif int w = _this->screen->w; int h = _this->screen->h; if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) { w = _this->screen->h; h = _this->screen->w; } if ((w < Private->EPOC_ScreenSize.iWidth) || (h < Private->EPOC_ScreenSize.iHeight)) { DrawBackground(_this); } /* Tell the system that something has been drawn */ TRect rect = TRect(Private->EPOC_WsWindow.Size()); Private->EPOC_WsWindow.Invalidate(rect);#if defined(__WINS__) || defined(TEST_BM_DRAW) Private->EPOC_WsWindow.BeginRedraw(rect); Private->EPOC_WindowGc->BitBlt(TPoint(), Private->EPOC_Bitmap); Private->EPOC_WsWindow.EndRedraw(); Private->EPOC_WindowGc->Deactivate(); UnlockHeap(Private->EPOC_Bitmap);; // Unlock bitmap heap Private->EPOC_WsSession.Flush();#endif /* Draw current buffer */ SDL_Rect fullScreen; fullScreen.x = 0; fullScreen.y = 0; fullScreen.w = _this->screen->w; fullScreen.h = _this->screen->h; EPOC_DirectUpdate(_this, 1, &fullScreen);}void DrawBackground(_THIS){ /* Draw background */#if defined(__WINS__) || defined(TEST_BM_DRAW) //warning heap is not locked! - a function calling must ensure that it's ok TUint16* screenBuffer = (TUint16*)Private->EPOC_Bitmap->DataAddress();#else TUint16* screenBuffer = (TUint16*)Private->EPOC_FrameBuffer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -