Mercurial > sdl-ios-xcode
comparison src/video/fbcon/SDL_fbvideo.c @ 4256:ba587a51f899 SDL-1.2
Vitaly Minko to slouken
Hi all,
I wrote a patch, which allows user to rotate the screen in case of fbcon driver.
The rotation angle is controlled by SDL_VIDEO_FBCON_ROTATION environment variable and possible values are:
not set - Not rotating, no shadow.
"NONE" - Not rotating, but still using shadow.
"CW" - Rotating screen clockwise.
"UD" - Rotating screen upside down.
"CCW" - Rotating screen counter clockwise.
The patch is based on wscons driver, written by Staffan Ulfberg.
I tested it on
Device: Sharp Zaurus SL-C1000
SDL version: 1.2.13
Kernel version: 2.6.24.4
Best regards,
Vitaly.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 28 Sep 2009 06:23:22 +0000 |
parents | bec67d0b6645 |
children | ca02f877d055 |
comparison
equal
deleted
inserted
replaced
4255:5a203e2b0162 | 4256:ba587a51f899 |
---|---|
124 { 1280, 1024, 9369, 224, 32, 32, 4, 136, 4, 0, 0 }, /* 60 Hz */ | 124 { 1280, 1024, 9369, 224, 32, 32, 4, 136, 4, 0, 0 }, /* 60 Hz */ |
125 { 1408, 1056, 8214, 256, 40, 32, 5, 144, 5, 0, 0 }, /* 60 Hz */ | 125 { 1408, 1056, 8214, 256, 40, 32, 5, 144, 5, 0, 0 }, /* 60 Hz */ |
126 { 1600, 1200,/*?*/0, 272, 48, 32, 5, 152, 5, 0, 0 }, /* 60 Hz */ | 126 { 1600, 1200,/*?*/0, 272, 48, 32, 5, 152, 5, 0, 0 }, /* 60 Hz */ |
127 #endif | 127 #endif |
128 }; | 128 }; |
129 enum { | |
130 FBCON_ROTATE_NONE = 0, | |
131 FBCON_ROTATE_CCW = 90, | |
132 FBCON_ROTATE_UD = 180, | |
133 FBCON_ROTATE_CW = 270 | |
134 }; | |
135 | |
136 #define min(a,b) ((a)<(b)?(a):(b)) | |
129 | 137 |
130 /* Initialization/Query functions */ | 138 /* Initialization/Query functions */ |
131 static int FB_VideoInit(_THIS, SDL_PixelFormat *vformat); | 139 static int FB_VideoInit(_THIS, SDL_PixelFormat *vformat); |
132 static SDL_Rect **FB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); | 140 static SDL_Rect **FB_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); |
133 static SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); | 141 static SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); |
150 | 158 |
151 /* Internal palette functions */ | 159 /* Internal palette functions */ |
152 static void FB_SavePalette(_THIS, struct fb_fix_screeninfo *finfo, | 160 static void FB_SavePalette(_THIS, struct fb_fix_screeninfo *finfo, |
153 struct fb_var_screeninfo *vinfo); | 161 struct fb_var_screeninfo *vinfo); |
154 static void FB_RestorePalette(_THIS); | 162 static void FB_RestorePalette(_THIS); |
163 | |
164 /* Shadow buffer functions */ | |
165 static FB_bitBlit FB_blit16; | |
166 static FB_bitBlit FB_blit16blocked; | |
155 | 167 |
156 static int SDL_getpagesize(void) | 168 static int SDL_getpagesize(void) |
157 { | 169 { |
158 #ifdef HAVE_GETPAGESIZE | 170 #ifdef HAVE_GETPAGESIZE |
159 return getpagesize(); | 171 return getpagesize(); |
489 int i, j; | 501 int i, j; |
490 int current_index; | 502 int current_index; |
491 unsigned int current_w; | 503 unsigned int current_w; |
492 unsigned int current_h; | 504 unsigned int current_h; |
493 const char *SDL_fbdev; | 505 const char *SDL_fbdev; |
506 const char *rotation; | |
494 FILE *modesdb; | 507 FILE *modesdb; |
495 | 508 |
496 /* Initialize the library */ | 509 /* Initialize the library */ |
497 SDL_fbdev = SDL_getenv("SDL_FBDEV"); | 510 SDL_fbdev = SDL_getenv("SDL_FBDEV"); |
498 if ( SDL_fbdev == NULL ) { | 511 if ( SDL_fbdev == NULL ) { |
617 /* Hmm, failed to memory map I/O registers */ | 630 /* Hmm, failed to memory map I/O registers */ |
618 mapped_io = NULL; | 631 mapped_io = NULL; |
619 } | 632 } |
620 } | 633 } |
621 | 634 |
635 rotate = FBCON_ROTATE_NONE; | |
636 rotation = SDL_getenv("SDL_VIDEO_FBCON_ROTATION"); | |
637 if (rotation != NULL) { | |
638 if (SDL_strlen(rotation) == 0) { | |
639 shadow_fb = 0; | |
640 rotate = FBCON_ROTATE_NONE; | |
641 #ifdef FBCON_DEBUG | |
642 printf("Not rotating, no shadow\n"); | |
643 #endif | |
644 } else if (!SDL_strcmp(rotation, "NONE")) { | |
645 shadow_fb = 1; | |
646 rotate = FBCON_ROTATE_NONE; | |
647 #ifdef FBCON_DEBUG | |
648 printf("Not rotating, but still using shadow\n"); | |
649 #endif | |
650 } else if (!SDL_strcmp(rotation, "CW")) { | |
651 shadow_fb = 1; | |
652 rotate = FBCON_ROTATE_CW; | |
653 #ifdef FBCON_DEBUG | |
654 printf("Rotating screen clockwise\n"); | |
655 #endif | |
656 } else if (!SDL_strcmp(rotation, "CCW")) { | |
657 shadow_fb = 1; | |
658 rotate = FBCON_ROTATE_CCW; | |
659 #ifdef FBCON_DEBUG | |
660 printf("Rotating screen counter clockwise\n"); | |
661 #endif | |
662 } else if (!SDL_strcmp(rotation, "UD")) { | |
663 shadow_fb = 1; | |
664 rotate = FBCON_ROTATE_UD; | |
665 #ifdef FBCON_DEBUG | |
666 printf("Rotating screen upside down\n"); | |
667 #endif | |
668 } else { | |
669 SDL_SetError("\"%s\" is not a valid value for " | |
670 "SDL_VIDEO_FBCON_ROTATION", rotation); | |
671 return(-1); | |
672 } | |
673 } | |
674 | |
675 if (rotate == FBCON_ROTATE_CW || rotate == FBCON_ROTATE_CCW) { | |
676 current_w = vinfo.yres; | |
677 current_h = vinfo.xres; | |
678 } else { | |
679 current_w = vinfo.xres; | |
680 current_h = vinfo.yres; | |
681 } | |
682 | |
622 /* Query for the list of available video modes */ | 683 /* Query for the list of available video modes */ |
623 current_w = vinfo.xres; | |
624 current_h = vinfo.yres; | |
625 current_index = ((vinfo.bits_per_pixel+7)/8)-1; | 684 current_index = ((vinfo.bits_per_pixel+7)/8)-1; |
626 modesdb = fopen(FB_MODES_DB, "r"); | 685 modesdb = fopen(FB_MODES_DB, "r"); |
627 for ( i=0; i<NUM_MODELISTS; ++i ) { | 686 for ( i=0; i<NUM_MODELISTS; ++i ) { |
628 SDL_nummodes[i] = 0; | 687 SDL_nummodes[i] = 0; |
629 SDL_modelist[i] = NULL; | 688 SDL_modelist[i] = NULL; |
633 } else if(modesdb) { | 692 } else if(modesdb) { |
634 while ( read_fbmodes_mode(modesdb, &vinfo) ) { | 693 while ( read_fbmodes_mode(modesdb, &vinfo) ) { |
635 for ( i=0; i<NUM_MODELISTS; ++i ) { | 694 for ( i=0; i<NUM_MODELISTS; ++i ) { |
636 unsigned int w, h; | 695 unsigned int w, h; |
637 | 696 |
697 if (rotate == FBCON_ROTATE_CW || rotate == FBCON_ROTATE_CCW) { | |
698 w = vinfo.yres; | |
699 h = vinfo.xres; | |
700 } else { | |
701 w = vinfo.xres; | |
702 h = vinfo.yres; | |
703 } | |
638 /* See if we are querying for the current mode */ | 704 /* See if we are querying for the current mode */ |
639 w = vinfo.xres; | |
640 h = vinfo.yres; | |
641 if ( i == current_index ) { | 705 if ( i == current_index ) { |
642 if ( (current_w > w) || (current_h > h) ) { | 706 if ( (current_w > w) || (current_h > h) ) { |
643 /* Only check once */ | 707 /* Only check once */ |
644 FB_AddMode(this, i, current_w, current_h, 0); | 708 FB_AddMode(this, i, current_w, current_h, 0); |
645 current_index = -1; | 709 current_index = -1; |
655 } else { | 719 } else { |
656 for ( i=0; i<NUM_MODELISTS; ++i ) { | 720 for ( i=0; i<NUM_MODELISTS; ++i ) { |
657 for ( j=0; j<(sizeof(checkres)/sizeof(checkres[0])); ++j ) { | 721 for ( j=0; j<(sizeof(checkres)/sizeof(checkres[0])); ++j ) { |
658 unsigned int w, h; | 722 unsigned int w, h; |
659 | 723 |
724 if (rotate == FBCON_ROTATE_CW || rotate == FBCON_ROTATE_CCW) { | |
725 w = checkres[j].h; | |
726 h = checkres[j].w; | |
727 } else { | |
728 w = checkres[j].w; | |
729 h = checkres[j].h; | |
730 } | |
660 /* See if we are querying for the current mode */ | 731 /* See if we are querying for the current mode */ |
661 w = checkres[j].w; | |
662 h = checkres[j].h; | |
663 if ( i == current_index ) { | 732 if ( i == current_index ) { |
664 if ( (current_w > w) || (current_h > h) ) { | 733 if ( (current_w > w) || (current_h > h) ) { |
665 /* Only check once */ | 734 /* Only check once */ |
666 FB_AddMode(this, i, current_w, current_h, 0); | 735 FB_AddMode(this, i, current_w, current_h, 0); |
667 current_index = -1; | 736 current_index = -1; |
672 } | 741 } |
673 } | 742 } |
674 } | 743 } |
675 } | 744 } |
676 | 745 |
677 /* Fill in our hardware acceleration capabilities */ | |
678 this->info.current_w = current_w; | 746 this->info.current_w = current_w; |
679 this->info.current_h = current_h; | 747 this->info.current_h = current_h; |
680 this->info.wm_available = 0; | 748 this->info.wm_available = 0; |
681 this->info.hw_available = 1; | 749 this->info.hw_available = !shadow_fb; |
682 this->info.video_mem = finfo.smem_len/1024; | 750 this->info.video_mem = shadow_fb ? 0 : finfo.smem_len/1024; |
751 /* Fill in our hardware acceleration capabilities */ | |
683 if ( mapped_io ) { | 752 if ( mapped_io ) { |
684 switch (finfo.accel) { | 753 switch (finfo.accel) { |
685 case FB_ACCEL_MATROX_MGA2064W: | 754 case FB_ACCEL_MATROX_MGA2064W: |
686 case FB_ACCEL_MATROX_MGA1064SG: | 755 case FB_ACCEL_MATROX_MGA1064SG: |
687 case FB_ACCEL_MATROX_MGA2164W: | 756 case FB_ACCEL_MATROX_MGA2164W: |
711 #ifdef FBACCEL_DEBUG | 780 #ifdef FBACCEL_DEBUG |
712 printf("Unknown hardware accelerator.\n"); | 781 printf("Unknown hardware accelerator.\n"); |
713 #endif | 782 #endif |
714 break; | 783 break; |
715 } | 784 } |
785 } | |
786 | |
787 if (shadow_fb) { | |
788 shadow_mem = (char *)SDL_malloc(mapped_memlen); | |
789 if (shadow_mem == NULL) { | |
790 SDL_SetError("No memory for shadow"); | |
791 return (-1); | |
792 } | |
716 } | 793 } |
717 | 794 |
718 /* Enable mouse and keyboard support */ | 795 /* Enable mouse and keyboard support */ |
719 if ( FB_OpenKeyboard(this) < 0 ) { | 796 if ( FB_OpenKeyboard(this) < 0 ) { |
720 FB_VideoQuit(this); | 797 FB_VideoQuit(this); |
945 } | 1022 } |
946 #ifdef FBCON_DEBUG | 1023 #ifdef FBCON_DEBUG |
947 fprintf(stderr, "Printing original vinfo:\n"); | 1024 fprintf(stderr, "Printing original vinfo:\n"); |
948 print_vinfo(&vinfo); | 1025 print_vinfo(&vinfo); |
949 #endif | 1026 #endif |
1027 /* Do not use double buffering with shadow buffer */ | |
1028 if (shadow_fb) { | |
1029 flags &= ~SDL_DOUBLEBUF; | |
1030 } | |
1031 | |
950 if ( (vinfo.xres != width) || (vinfo.yres != height) || | 1032 if ( (vinfo.xres != width) || (vinfo.yres != height) || |
951 (vinfo.bits_per_pixel != bpp) || (flags & SDL_DOUBLEBUF) ) { | 1033 (vinfo.bits_per_pixel != bpp) || (flags & SDL_DOUBLEBUF) ) { |
952 vinfo.activate = FB_ACTIVATE_NOW; | 1034 vinfo.activate = FB_ACTIVATE_NOW; |
953 vinfo.accel_flags = 0; | 1035 vinfo.accel_flags = 0; |
954 vinfo.bits_per_pixel = bpp; | 1036 vinfo.bits_per_pixel = bpp; |
971 } | 1053 } |
972 #ifdef FBCON_DEBUG | 1054 #ifdef FBCON_DEBUG |
973 fprintf(stderr, "Printing wanted vinfo:\n"); | 1055 fprintf(stderr, "Printing wanted vinfo:\n"); |
974 print_vinfo(&vinfo); | 1056 print_vinfo(&vinfo); |
975 #endif | 1057 #endif |
976 if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) { | 1058 if ( !shadow_fb && |
1059 ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) { | |
977 vinfo.yres_virtual = height; | 1060 vinfo.yres_virtual = height; |
978 if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) { | 1061 if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) { |
979 SDL_SetError("Couldn't set console screen info"); | 1062 SDL_SetError("Couldn't set console screen info"); |
980 return(NULL); | 1063 return(NULL); |
981 } | 1064 } |
1027 } | 1110 } |
1028 | 1111 |
1029 /* Save hardware palette, if needed */ | 1112 /* Save hardware palette, if needed */ |
1030 FB_SavePalette(this, &finfo, &vinfo); | 1113 FB_SavePalette(this, &finfo, &vinfo); |
1031 | 1114 |
1115 if (shadow_fb) { | |
1116 if (vinfo.bits_per_pixel == 16) { | |
1117 blitFunc = (rotate == FBCON_ROTATE_NONE || | |
1118 rotate == FBCON_ROTATE_UD) ? | |
1119 FB_blit16 : FB_blit16blocked; | |
1120 } else { | |
1121 fprintf(stderr, "Init vinfo:\n"); | |
1122 print_vinfo(&vinfo); | |
1123 SDL_SetError("Using software buffer, but no blitter " | |
1124 "function is available for %d bpp.", | |
1125 vinfo.bits_per_pixel); | |
1126 return(NULL); | |
1127 } | |
1128 } | |
1129 | |
1032 /* Set up the new mode framebuffer */ | 1130 /* Set up the new mode framebuffer */ |
1033 current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE); | 1131 current->flags &= SDL_FULLSCREEN; |
1132 if (shadow_fb) { | |
1133 current->flags |= SDL_SWSURFACE; | |
1134 } else { | |
1135 current->flags |= SDL_HWSURFACE; | |
1136 } | |
1034 current->w = vinfo.xres; | 1137 current->w = vinfo.xres; |
1035 current->h = vinfo.yres; | 1138 current->h = vinfo.yres; |
1036 current->pitch = finfo.line_length; | 1139 if (shadow_fb) { |
1037 current->pixels = mapped_mem+mapped_offset; | 1140 current->pitch = current->w * ((vinfo.bits_per_pixel + 7) / 8); |
1141 current->pixels = shadow_mem; | |
1142 physlinebytes = finfo.line_length; | |
1143 } else { | |
1144 current->pitch = finfo.line_length; | |
1145 current->pixels = mapped_mem+mapped_offset; | |
1146 } | |
1038 | 1147 |
1039 /* Set up the information for hardware surfaces */ | 1148 /* Set up the information for hardware surfaces */ |
1040 surfaces_mem = (char *)current->pixels + | 1149 surfaces_mem = (char *)current->pixels + |
1041 vinfo.yres_virtual*current->pitch; | 1150 vinfo.yres_virtual*current->pitch; |
1042 surfaces_len = (mapped_memlen-(surfaces_mem-mapped_mem)); | 1151 surfaces_len = (shadow_fb) ? |
1152 0 : (mapped_memlen-(surfaces_mem-mapped_mem)); | |
1153 | |
1043 FB_FreeHWSurfaces(this); | 1154 FB_FreeHWSurfaces(this); |
1044 FB_InitHWSurfaces(this, current, surfaces_mem, surfaces_len); | 1155 FB_InitHWSurfaces(this, current, surfaces_mem, surfaces_len); |
1045 | 1156 |
1046 /* Let the application know we have a hardware palette */ | 1157 /* Let the application know we have a hardware palette */ |
1047 switch (finfo.visual) { | 1158 switch (finfo.visual) { |
1048 case FB_VISUAL_PSEUDOCOLOR: | 1159 case FB_VISUAL_PSEUDOCOLOR: |
1049 current->flags |= SDL_HWPALETTE; | 1160 current->flags |= SDL_HWPALETTE; |
1050 break; | 1161 break; |
1051 default: | 1162 default: |
1052 break; | 1163 break; |
1053 } | 1164 } |
1054 | 1165 |
1055 /* Update for double-buffering, if we can */ | 1166 /* Update for double-buffering, if we can */ |
1056 if ( flags & SDL_DOUBLEBUF ) { | 1167 if ( flags & SDL_DOUBLEBUF ) { |
1057 if ( vinfo.yres_virtual == (height*2) ) { | 1168 if ( vinfo.yres_virtual == (height*2) ) { |
1058 current->flags |= SDL_DOUBLEBUF; | 1169 current->flags |= SDL_DOUBLEBUF; |
1059 flip_page = 0; | 1170 flip_page = 0; |
1060 flip_address[0] = (char *)current->pixels; | 1171 flip_address[0] = (char *)current->pixels; |
1061 flip_address[1] = (char *)current->pixels+ | 1172 flip_address[1] = (char *)current->pixels+ |
1062 current->h*current->pitch; | 1173 current->h*current->pitch; |
1063 this->screen = current; | 1174 this->screen = current; |
1064 FB_FlipHWSurface(this, current); | 1175 FB_FlipHWSurface(this, current); |
1065 this->screen = NULL; | 1176 this->screen = NULL; |
1066 } | 1177 } |
1067 } | 1178 } |
1327 | 1438 |
1328 surface->pixels = flip_address[flip_page]; | 1439 surface->pixels = flip_address[flip_page]; |
1329 return(0); | 1440 return(0); |
1330 } | 1441 } |
1331 | 1442 |
1443 static void FB_blit16(Uint8 *byte_src_pos, int src_right_delta, int src_down_delta, | |
1444 Uint8 *byte_dst_pos, int dst_linebytes, int width, int height) | |
1445 { | |
1446 int w; | |
1447 Uint16 *src_pos = (Uint16 *)byte_src_pos; | |
1448 Uint16 *dst_pos = (Uint16 *)byte_dst_pos; | |
1449 | |
1450 while (height) { | |
1451 Uint16 *src = src_pos; | |
1452 Uint16 *dst = dst_pos; | |
1453 for (w = width; w != 0; w--) { | |
1454 *dst = *src; | |
1455 src += src_right_delta; | |
1456 dst++; | |
1457 } | |
1458 dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes); | |
1459 src_pos += src_down_delta; | |
1460 height--; | |
1461 } | |
1462 } | |
1463 | |
1464 #define BLOCKSIZE_W 32 | |
1465 #define BLOCKSIZE_H 32 | |
1466 | |
1467 static void FB_blit16blocked(Uint8 *byte_src_pos, int src_right_delta, int src_down_delta, | |
1468 Uint8 *byte_dst_pos, int dst_linebytes, int width, int height) | |
1469 { | |
1470 int w; | |
1471 Uint16 *src_pos = (Uint16 *)byte_src_pos; | |
1472 Uint16 *dst_pos = (Uint16 *)byte_dst_pos; | |
1473 | |
1474 while (height > 0) { | |
1475 Uint16 *src = src_pos; | |
1476 Uint16 *dst = dst_pos; | |
1477 for (w = width; w > 0; w -= BLOCKSIZE_W) { | |
1478 FB_blit16((Uint8 *)src, | |
1479 src_right_delta, | |
1480 src_down_delta, | |
1481 (Uint8 *)dst, | |
1482 dst_linebytes, | |
1483 min(w, BLOCKSIZE_W), | |
1484 min(height, BLOCKSIZE_H)); | |
1485 src += src_right_delta * BLOCKSIZE_W; | |
1486 dst += BLOCKSIZE_W; | |
1487 } | |
1488 dst_pos = (Uint16 *)((Uint8 *)dst_pos + dst_linebytes * BLOCKSIZE_H); | |
1489 src_pos += src_down_delta * BLOCKSIZE_H; | |
1490 height -= BLOCKSIZE_H; | |
1491 } | |
1492 } | |
1493 | |
1332 static void FB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) | 1494 static void FB_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) |
1333 { | 1495 { |
1334 /* The application is already updating the visible video memory */ | 1496 int width = cache_vinfo.xres; |
1335 return; | 1497 int height = cache_vinfo.yres; |
1498 int bytes_per_pixel = (cache_vinfo.bits_per_pixel + 7) / 8; | |
1499 int i; | |
1500 | |
1501 if (!shadow_fb) { | |
1502 /* The application is already updating the visible video memory */ | |
1503 return; | |
1504 } | |
1505 | |
1506 if (cache_vinfo.bits_per_pixel != 16) { | |
1507 SDL_SetError("Shadow copy only implemented for 16 bpp"); | |
1508 return; | |
1509 } | |
1510 | |
1511 for (i = 0; i < numrects; i++) { | |
1512 int x1, y1, x2, y2; | |
1513 int scr_x1, scr_y1, scr_x2, scr_y2; | |
1514 int sha_x1, sha_y1; | |
1515 int shadow_right_delta; /* Address change when moving right in dest */ | |
1516 int shadow_down_delta; /* Address change when moving down in dest */ | |
1517 char *src_start; | |
1518 char *dst_start; | |
1519 | |
1520 x1 = rects[i].x; | |
1521 y1 = rects[i].y; | |
1522 x2 = x1 + rects[i].w; | |
1523 y2 = y1 + rects[i].h; | |
1524 | |
1525 if (x1 < 0) { | |
1526 x1 = 0; | |
1527 } else if (x1 > width) { | |
1528 x1 = width; | |
1529 } | |
1530 if (x2 < 0) { | |
1531 x2 = 0; | |
1532 } else if (x2 > width) { | |
1533 x2 = width; | |
1534 } | |
1535 if (y1 < 0) { | |
1536 y1 = 0; | |
1537 } else if (y1 > height) { | |
1538 y1 = height; | |
1539 } | |
1540 if (y2 < 0) { | |
1541 y2 = 0; | |
1542 } else if (y2 > height) { | |
1543 y2 = height; | |
1544 } | |
1545 if (x2 <= x1 || y2 <= y1) { | |
1546 continue; | |
1547 } | |
1548 | |
1549 switch (rotate) { | |
1550 case FBCON_ROTATE_NONE: | |
1551 sha_x1 = scr_x1 = x1; | |
1552 sha_y1 = scr_y1 = y1; | |
1553 scr_x2 = x2; | |
1554 scr_y2 = y2; | |
1555 shadow_right_delta = 1; | |
1556 shadow_down_delta = width; | |
1557 break; | |
1558 case FBCON_ROTATE_CCW: | |
1559 scr_x1 = y1; | |
1560 scr_y1 = width - x2; | |
1561 scr_x2 = y2; | |
1562 scr_y2 = width - x1; | |
1563 sha_x1 = x2 - 1; | |
1564 sha_y1 = y1; | |
1565 shadow_right_delta = width; | |
1566 shadow_down_delta = -1; | |
1567 break; | |
1568 case FBCON_ROTATE_UD: | |
1569 scr_x1 = width - x2; | |
1570 scr_y1 = height - y2; | |
1571 scr_x2 = width - x1; | |
1572 scr_y2 = height - y1; | |
1573 sha_x1 = x2 - 1; | |
1574 sha_y1 = y2 - 1; | |
1575 shadow_right_delta = -1; | |
1576 shadow_down_delta = -width; | |
1577 break; | |
1578 case FBCON_ROTATE_CW: | |
1579 scr_x1 = height - y2; | |
1580 scr_y1 = x1; | |
1581 scr_x2 = height - y1; | |
1582 scr_y2 = x2; | |
1583 sha_x1 = x1; | |
1584 sha_y1 = y2 - 1; | |
1585 shadow_right_delta = -width; | |
1586 shadow_down_delta = 1; | |
1587 break; | |
1588 default: | |
1589 SDL_SetError("Unknown rotation"); | |
1590 return; | |
1591 } | |
1592 | |
1593 src_start = shadow_mem + | |
1594 (sha_y1 * width + sha_x1) * bytes_per_pixel; | |
1595 dst_start = mapped_mem + mapped_offset + scr_y1 * physlinebytes + | |
1596 scr_x1 * bytes_per_pixel; | |
1597 | |
1598 blitFunc((Uint8 *) src_start, | |
1599 shadow_right_delta, | |
1600 shadow_down_delta, | |
1601 (Uint8 *) dst_start, | |
1602 physlinebytes, | |
1603 scr_x2 - scr_x1, | |
1604 scr_y2 - scr_y1); | |
1605 } | |
1336 } | 1606 } |
1337 | 1607 |
1338 #ifdef VGA16_FBCON_SUPPORT | 1608 #ifdef VGA16_FBCON_SUPPORT |
1339 /* Code adapted with thanks from the XFree86 VGA16 driver! :) */ | 1609 /* Code adapted with thanks from the XFree86 VGA16 driver! :) */ |
1340 #define writeGr(index, value) \ | 1610 #define writeGr(index, value) \ |