📄 sdl_gapivideo.c
字号:
} } return 1;}/* Video memory is very slow so lets optimize as much as possible */static int updateLine16to16(_THIS, PIXEL *srcPointer, PIXEL *destPointer, int width, int height, int lines){ PIXEL *line1, *line2; int step = gapi->dstPixelStep / 2; if( step == 1 ) /* optimized blitting on most devices */ { SDL_memcpy(destPointer, srcPointer, width * sizeof(PIXEL)); return 1; } else { if( (gapi->gapiOrientation != SDL_ORIENTATION_UP) && (gapi->userOrientation == SDL_ORIENTATION_UP )) // iPaq 3660/3800 and user orientation up { // to prevent data misalignment copy only one line if( ((((unsigned)destPointer & 3) != 0) && (gapi->gapiOrientation == SDL_ORIENTATION_LEFT)) || ((((unsigned)destPointer & 3) == 0) && (gapi->gapiOrientation != SDL_ORIENTATION_LEFT)) || (lines == 1) ) { while(width--) { *destPointer = *srcPointer++; destPointer += step; } return 1; } /* read two lines at the same time, write DWORD */ line1 = srcPointer; line2 = srcPointer + SDL_VideoSurface->pitch / 2; if( gapi->gapiOrientation == SDL_ORIENTATION_LEFT ) while(width--) // iPaq 3800 { *(DWORD*)destPointer =(*line2++ << 16) | *line1++; destPointer += step; } else { destPointer += gapi->gxProperties.cbyPitch / 2; while(width--) // iPaq 3660 { *(DWORD*)destPointer =(*line1++ << 16) | *line2++; destPointer += step; } } return 2; } else { // iPaq 3800 and user orientation landscape if( gapi->gapiOrientation == SDL_ORIENTATION_LEFT ) { int w1; // to prevent data misalignment copy only one pixel if( (((unsigned)destPointer & 3) == 0) && (width > 0)) { *destPointer-- = *srcPointer++; width--; } destPointer--; w1 = width / 2; while(w1--) { DWORD p = *(DWORD*)srcPointer; *((DWORD*)destPointer) = (p << 16) | (p >> 16); destPointer -= 2; srcPointer += 2; } if( width & 1 ) // copy the last pixel { destPointer++; *destPointer = *srcPointer; } return 1; } // modern iPaqs and user orientation landscape // read two pixels, write DWORD line1 = srcPointer; line2 = srcPointer + SDL_VideoSurface->pitch / 2; if( (((unsigned)destPointer & 3) != 0) || (lines == 1) ) { while(width--) { *destPointer = *srcPointer++; destPointer += step; } return 1; } while(width--) { *(DWORD*)destPointer =(*line2++ << 16) | *line1++; destPointer -= gapi->gxProperties.cbyPitch / 2; } return 2; } }}// Color component masks for 565#define REDMASK (31<<11)#define GREENMASK (63<<5)#define BLUEMASK (31)static int updateLine16to4(_THIS, PIXEL *srcPointer, unsigned char *destPointer, int width, int height, int lines, int yNibble, int xNibble){ PIXEL *line1, *line2; int step = gapi->dstPixelStep; if( gapi->userOrientation == SDL_ORIENTATION_UP ) { if( yNibble ) // copy bottom half of a line { while(width--) { PIXEL c1 = *srcPointer++; c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); *destPointer = (*destPointer & 0x0F) | ((~(c1 >> 3) << 4)); destPointer += step; } return 1; } // either 1 pixel picture or tail, anyway this is the last line if( lines == 1 ) { while(width--) { PIXEL c1 = *srcPointer++; c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); *destPointer = (*destPointer & 0xF0) | ((~(c1 >> 3) & 0xF)); destPointer += step; } return 1; } line1 = srcPointer; line2 = srcPointer + SDL_VideoSurface->pitch / 2; while(width--) { PIXEL c1 = *line1++; PIXEL c2 = *line2++; c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); c2 = ((c2 & REDMASK) >> 11) + ((c2 & GREENMASK) >> 5) + (c2 & BLUEMASK); *destPointer = ~((c1 >> 3) + ((c2 >> 3) << 4)); destPointer += step; } return 2; } else { int w1; w1 = width / 2; if( xNibble ) { // copy one pixel PIXEL c1 = *srcPointer++; c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); *destPointer = (*destPointer & 0xF0) | ((~(c1 >> 3) & 0xF)); destPointer++; } while(w1--) { PIXEL c1 = *srcPointer; PIXEL c2 = *(srcPointer + 1); c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); c2 = ((c2 & REDMASK) >> 11) + ((c2 & GREENMASK) >> 5) + (c2 & BLUEMASK); *destPointer++ = ~((c2 >> 3) + ((c1 >> 3) << 4)); srcPointer += 2; } // copy tail if( (width & 1) && !xNibble ) { PIXEL c1 = *srcPointer; c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); *destPointer = (*destPointer & 0x0F) | ((~(c1 >> 3) << 4)); } return 1; }}static void GAPI_UpdateRectsMono(_THIS, int numrects, SDL_Rect *rects){ int i, height; int linesProcessed; int xNibble, yNibble; for (i=0; i<numrects; i++) { unsigned char *destPointer; unsigned char *srcPointer; if( gapi->userOrientation == SDL_ORIENTATION_UP ) destPointer = (unsigned char*) gapi->videoMem + gapi->startOffset - rects[i].y * gapi->gxProperties.cBPP / 8 + rects[i].x * gapi->dstPixelStep; else destPointer = (unsigned char*) gapi->videoMem + gapi->startOffset + rects[i].x * gapi->gxProperties.cBPP / 8 + rects[i].y * gapi->dstLineStep; srcPointer = ((unsigned char*) SDL_VideoSurface->pixels) + rects[i].y * SDL_VideoSurface->pitch + rects[i].x * 2; yNibble = rects[i].y & 1; // TODO: only for 4 bpp xNibble = rects[i].x & 1; height = rects[i].h; while (height > 0) { switch(gapi->gxProperties.cBPP) { case 2: // TODO case 4: linesProcessed = updateLine16to4(this, (PIXEL*) srcPointer, destPointer, rects[i].w, rects[i].h, height, yNibble, xNibble); yNibble = 0; } height -= linesProcessed; if( gapi->userOrientation == SDL_ORIENTATION_UP ) destPointer--; // always fill 1 byte else destPointer += gapi->dstLineStep; srcPointer += SDL_VideoSurface->pitch * linesProcessed; // pitch in bytes } }}static void GAPI_UpdateRectsColor(_THIS, int numrects, SDL_Rect *rects){ int i, height; int bytesPerPixel = (gapi->gxProperties.cBPP + 1) / 8; int linesProcessed; for (i=0; i<numrects; i++) { unsigned char *destPointer = (unsigned char*) gapi->videoMem + gapi->startOffset + rects[i].y * gapi->dstLineStep + rects[i].x * gapi->dstPixelStep; unsigned char *srcPointer = ((unsigned char*) SDL_VideoSurface->pixels) + rects[i].y * SDL_VideoSurface->pitch + rects[i].x * bytesPerPixel; height = rects[i].h;// fprintf(stderr, "Starting rect %dx%d, dst=0x%x, w = %d, h = %d\n", rects[i].w, rects[i].h,destPointer,rects[i].w,rects[i].h);// fflush(stderr); linesProcessed = height; while (height > 0) { switch(bytesPerPixel) { case 1: linesProcessed = updateLine8to8(this, srcPointer, (unsigned char *) destPointer, rects[i].w, rects[i].h, height); break; case 2:#pragma warning(disable: 4133) linesProcessed = updateLine16to16(this, (PIXEL*) srcPointer, destPointer, rects[i].w, rects[i].h, height); break; } height -= linesProcessed; destPointer += gapi->dstLineStep * linesProcessed; srcPointer += SDL_VideoSurface->pitch * linesProcessed; // pitch in bytes }// fprintf(stderr, "End of rect\n");// fflush(stderr); }}static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects){ // we do not want to corrupt video memory if( gapi->suspended ) return; if( gapi->needUpdate ) gapi->videoMem = gapi->gxFunc.GXBeginDraw(); if( gapi->gxProperties.cBPP < 8 ) GAPI_UpdateRectsMono(this, numrects, rects); else GAPI_UpdateRectsColor(this, numrects, rects); if( gapi->needUpdate ) gapi->gxFunc.GXEndDraw();}/* Note: If we are terminated, this could be called in the middle of another SDL video routine -- notably UpdateRects.*/void GAPI_VideoQuit(_THIS){ int i, j; /* Destroy the window and everything associated with it */ if ( SDL_Window ) { if ((g_hGapiLib != 0) && this && this->hidden && this->hidden->gxFunc.GXCloseDisplay && !this->hidden->useVga) this->hidden->gxFunc.GXCloseDisplay(); if (this->screen->pixels != NULL) { SDL_free(this->screen->pixels); this->screen->pixels = NULL; } if ( screen_icn ) { DestroyIcon(screen_icn); screen_icn = NULL; } DIB_DestroyWindow(this); SDL_UnregisterApp(); SDL_Window = NULL;#if defined(_WIN32_WCE)// Unload wince aygshell library to prevent leak if( aygshell ) { FreeLibrary(aygshell); aygshell = NULL; }#endif /* Free video mode lists */ for ( i=0; i<NUM_MODELISTS; ++i ) { if ( gapi->SDL_modelist[i] != NULL ) { for ( j=0; gapi->SDL_modelist[i][j]; ++j ) SDL_free(gapi->SDL_modelist[i][j]); SDL_free(gapi->SDL_modelist[i]); gapi->SDL_modelist[i] = NULL; } } }}static void GAPI_RealizePalette(_THIS){ OutputDebugString(TEXT("GAPI_RealizePalette NOT IMPLEMENTED !\r\n"));}static void GAPI_PaletteChanged(_THIS, HWND window){ OutputDebugString(TEXT("GAPI_PaletteChanged NOT IMPLEMENTED !\r\n"));}static void GAPI_WinPAINT(_THIS, HDC hdc){ // draw current offscreen buffer on hdc int bpp = 16; // we always use either 8 or 16 bpp internally HGDIOBJ prevObject; unsigned short *bitmapData; HBITMAP hb; HDC srcDC; // Create a DIB BYTE buffer[sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD)] = {0}; BITMAPINFO* pBMI = (BITMAPINFO*)buffer; BITMAPINFOHEADER* pHeader = &pBMI->bmiHeader; DWORD* pColors = (DWORD*)&pBMI->bmiColors; // CreateDIBSection does not support 332 pixel format on wce if( gapi->gxProperties.cBPP == 8 ) return; // DIB Header pHeader->biSize = sizeof(BITMAPINFOHEADER); pHeader->biWidth = this->hidden->w; pHeader->biHeight = -this->hidden->h; pHeader->biPlanes = 1; pHeader->biBitCount = bpp; pHeader->biCompression = BI_RGB; pHeader->biSizeImage = (this->hidden->w * this->hidden->h * bpp) / 8; // Color masks if( bpp == 16 ) { pColors[0] = REDMASK; pColors[1] = GREENMASK; pColors[2] = BLUEMASK; pHeader->biCompression = BI_BITFIELDS; } // Create the DIB hb = CreateDIBSection( 0, pBMI, DIB_RGB_COLORS, (void**)&bitmapData, 0, 0 ); // copy data // FIXME: prevent misalignment, but I've never seen non aligned width of screen memcpy(bitmapData, this->hidden->buffer, pHeader->biSizeImage); srcDC = CreateCompatibleDC(hdc); prevObject = SelectObject(srcDC, hb); BitBlt(hdc, 0, 0, this->hidden->w, this->hidden->h, srcDC, 0, 0, SRCCOPY); SelectObject(srcDC, prevObject); DeleteObject(hb); DeleteDC(srcDC);}int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) { GAPI_CreatePalette(ncolors, colors); return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -