📄 sdl_cursor.c
字号:
pixels8[0] = SDL_MapRGB(screen->format, 255, 255, 255);
pixels8[1] = SDL_MapRGB(screen->format, 0, 0, 0);
palette_changed = 0;
}
dst = (Uint8 *)screen->pixels +
(SDL_cursor->area.y+area->y)*screen->pitch +
SDL_cursor->area.x;
dstskip = screen->pitch-area->w;
for ( h=area->h; h; h-- ) {
for ( w=area->w/8; w; w-- ) {
maskb = *mask++;
datab = *data++;
for ( i=0; i<8; ++i ) {
if ( maskb & 0x80 ) {
*dst = pixels8[datab>>7];
}
maskb <<= 1;
datab <<= 1;
dst++;
}
}
dst += dstskip;
}
}
break;
case 2: {
Uint16 *dst;
int dstskip;
dst = (Uint16 *)screen->pixels +
(SDL_cursor->area.y+area->y)*screen->pitch/2 +
SDL_cursor->area.x;
dstskip = (screen->pitch/2)-area->w;
for ( h=area->h; h; h-- ) {
for ( w=area->w/8; w; w-- ) {
maskb = *mask++;
datab = *data++;
for ( i=0; i<8; ++i ) {
if ( maskb & 0x80 ) {
*dst = pixels[datab>>7];
}
maskb <<= 1;
datab <<= 1;
dst++;
}
}
dst += dstskip;
}
}
break;
case 3: {
Uint8 *dst;
int dstskip;
dst = (Uint8 *)screen->pixels +
(SDL_cursor->area.y+area->y)*screen->pitch +
SDL_cursor->area.x*3;
dstskip = screen->pitch-area->w*3;
for ( h=area->h; h; h-- ) {
for ( w=area->w/8; w; w-- ) {
maskb = *mask++;
datab = *data++;
for ( i=0; i<8; ++i ) {
if ( maskb & 0x80 ) {
memset(dst,pixels[datab>>7],3);
}
maskb <<= 1;
datab <<= 1;
dst += 3;
}
}
dst += dstskip;
}
}
break;
case 4: {
Uint32 *dst;
int dstskip;
dst = (Uint32 *)screen->pixels +
(SDL_cursor->area.y+area->y)*screen->pitch/4 +
SDL_cursor->area.x;
dstskip = (screen->pitch/4)-area->w;
for ( h=area->h; h; h-- ) {
for ( w=area->w/8; w; w-- ) {
maskb = *mask++;
datab = *data++;
for ( i=0; i<8; ++i ) {
if ( maskb & 0x80 ) {
*dst = pixels[datab>>7];
}
maskb <<= 1;
datab <<= 1;
dst++;
}
}
dst += dstskip;
}
}
break;
}
}
static void SDL_DrawCursorSlow(SDL_Surface *screen, SDL_Rect *area)
{
const Uint32 pixels[2] = { 0xFFFFFF, 0x000000 };
int h;
int x, minx, maxx;
Uint8 *data, datab = 0;
Uint8 *mask, maskb = 0;
Uint8 *dst;
int dstbpp, dstskip;
data = SDL_cursor->data + area->y * SDL_cursor->area.w/8;
mask = SDL_cursor->mask + area->y * SDL_cursor->area.w/8;
dstbpp = screen->format->BytesPerPixel;
dst = (Uint8 *)screen->pixels +
(SDL_cursor->area.y+area->y)*screen->pitch +
SDL_cursor->area.x*dstbpp;
dstskip = screen->pitch-SDL_cursor->area.w*dstbpp;
minx = area->x;
maxx = area->x+area->w;
if ( screen->format->BytesPerPixel == 1 ) {
if ( palette_changed ) {
pixels8[0] = SDL_MapRGB(screen->format, 255, 255, 255);
pixels8[1] = SDL_MapRGB(screen->format, 0, 0, 0);
palette_changed = 0;
}
for ( h=area->h; h; h-- ) {
for ( x=0; x<SDL_cursor->area.w; ++x ) {
if ( (x%8) == 0 ) {
maskb = *mask++;
datab = *data++;
}
if ( (x >= minx) && (x < maxx) ) {
if ( maskb & 0x80 ) {
memset(dst, pixels8[datab>>7], dstbpp);
}
}
maskb <<= 1;
datab <<= 1;
dst += dstbpp;
}
dst += dstskip;
}
} else {
for ( h=area->h; h; h-- ) {
for ( x=0; x<SDL_cursor->area.w; ++x ) {
if ( (x%8) == 0 ) {
maskb = *mask++;
datab = *data++;
}
if ( (x >= minx) && (x < maxx) ) {
if ( maskb & 0x80 ) {
memset(dst, pixels[datab>>7], dstbpp);
}
}
maskb <<= 1;
datab <<= 1;
dst += dstbpp;
}
dst += dstskip;
}
}
}
/* This handles the ugly work of converting the saved cursor background from
the pixel format of the shadow surface to that of the video surface.
This is only necessary when blitting from a shadow surface of a different
pixel format than the video surface, and using a software rendered cursor.
*/
static void SDL_ConvertCursorSave(SDL_Surface *screen, int w, int h)
{
SDL_BlitInfo info;
SDL_loblit RunBlit;
/* Make sure we can steal the blit mapping */
if ( screen->map->dst != SDL_VideoSurface ) {
return;
}
/* Set up the blit information */
info.s_pixels = SDL_cursor->save[1];
info.s_width = w;
info.s_height = h;
info.s_skip = 0;
info.d_pixels = SDL_cursor->save[0];
info.d_width = w;
info.d_height = h;
info.d_skip = 0;
info.aux_data = screen->map->sw_data->aux_data;
info.src = screen->format;
info.table = screen->map->table;
info.dst = SDL_VideoSurface->format;
RunBlit = screen->map->sw_data->blit;
/* Run the actual software blit */
RunBlit(&info);
}
void SDL_DrawCursorNoLock(SDL_Surface *screen)
{
SDL_Rect area;
/* Get the mouse rectangle, clipped to the screen */
SDL_MouseRect(&area);
if ( (area.w == 0) || (area.h == 0) ) {
return;
}
/* Copy mouse background */
{ int w, h, screenbpp;
Uint8 *src, *dst;
/* Set up the copy pointers */
screenbpp = screen->format->BytesPerPixel;
if ( (screen == SDL_VideoSurface) ||
FORMAT_EQUAL(screen->format, SDL_VideoSurface->format) ) {
dst = SDL_cursor->save[0];
} else {
dst = SDL_cursor->save[1];
}
src = (Uint8 *)screen->pixels + area.y * screen->pitch +
area.x * screenbpp;
/* Perform the copy */
w = area.w*screenbpp;
h = area.h;
while ( h-- ) {
memcpy(dst, src, w);
dst += w;
src += screen->pitch;
}
}
/* Draw the mouse cursor */
area.x -= SDL_cursor->area.x;
area.y -= SDL_cursor->area.y;
if ( (area.x == 0) && (area.w == SDL_cursor->area.w) ) {
SDL_DrawCursorFast(screen, &area);
} else {
SDL_DrawCursorSlow(screen, &area);
}
}
void SDL_DrawCursor(SDL_Surface *screen)
{
/* Lock the screen if necessary */
if ( screen == NULL ) {
return;
}
if ( SDL_MUSTLOCK(screen) ) {
if ( SDL_LockSurface(screen) < 0 ) {
return;
}
}
SDL_DrawCursorNoLock(screen);
/* Unlock the screen and update if necessary */
if ( SDL_MUSTLOCK(screen) ) {
SDL_UnlockSurface(screen);
}
if ( (screen == SDL_VideoSurface) &&
((screen->flags & SDL_HWSURFACE) != SDL_HWSURFACE) ) {
SDL_VideoDevice *video = current_video;
SDL_VideoDevice *this = current_video;
SDL_Rect area;
SDL_MouseRect(&area);
/* This can be called before a video mode is set */
if ( video->UpdateRects ) {
video->UpdateRects(this, 1, &area);
}
}
}
void SDL_EraseCursorNoLock(SDL_Surface *screen)
{
SDL_Rect area;
/* Get the mouse rectangle, clipped to the screen */
SDL_MouseRect(&area);
if ( (area.w == 0) || (area.h == 0) ) {
return;
}
/* Copy mouse background */
{ int w, h, screenbpp;
Uint8 *src, *dst;
/* Set up the copy pointers */
screenbpp = screen->format->BytesPerPixel;
if ( (screen == SDL_VideoSurface) ||
FORMAT_EQUAL(screen->format, SDL_VideoSurface->format) ) {
src = SDL_cursor->save[0];
} else {
src = SDL_cursor->save[1];
}
dst = (Uint8 *)screen->pixels + area.y * screen->pitch +
area.x * screenbpp;
/* Perform the copy */
w = area.w*screenbpp;
h = area.h;
while ( h-- ) {
memcpy(dst, src, w);
src += w;
dst += screen->pitch;
}
/* Perform pixel conversion on cursor background */
if ( src > SDL_cursor->save[1] ) {
SDL_ConvertCursorSave(screen, area.w, area.h);
}
}
}
void SDL_EraseCursor(SDL_Surface *screen)
{
/* Lock the screen if necessary */
if ( screen == NULL ) {
return;
}
if ( SDL_MUSTLOCK(screen) ) {
if ( SDL_LockSurface(screen) < 0 ) {
return;
}
}
SDL_EraseCursorNoLock(screen);
/* Unlock the screen and update if necessary */
if ( SDL_MUSTLOCK(screen) ) {
SDL_UnlockSurface(screen);
}
if ( (screen == SDL_VideoSurface) &&
((screen->flags & SDL_HWSURFACE) != SDL_HWSURFACE) ) {
SDL_VideoDevice *video = current_video;
SDL_VideoDevice *this = current_video;
SDL_Rect area;
SDL_MouseRect(&area);
if ( video->UpdateRects ) {
video->UpdateRects(this, 1, &area);
}
}
}
/* Reset the cursor on video mode change
FIXME: Keep track of all cursors, and reset them all.
*/
void SDL_ResetCursor(void)
{
int savelen;
if ( SDL_cursor ) {
savelen = SDL_cursor->area.w*4*SDL_cursor->area.h;
SDL_cursor->area.x = 0;
SDL_cursor->area.y = 0;
memset(SDL_cursor->save[0], 0, savelen);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -