Ticket #8353: mouse.v5.diff
File mouse.v5.diff, 26.4 KB (added by , 20 years ago) |
---|
-
backends/sdl/graphics.cpp
RCS file: /cvsroot/scummvm/scummvm/backends/sdl/graphics.cpp,v retrieving revision 1.24 diff -u -r1.24 graphics.cpp
42 42 {0, 0, 0} 43 43 }; 44 44 45 // Table of relative scalers magnitudes 46 // [definedScale-1][_scaleFactor-1] 47 static ScalerProc *scalersMagn[3][3] = { 48 { Normal1x, AdvMame2x, AdvMame3x }, 49 { Normal1x, Normal1x, Normal1o5x }, 50 { Normal1x, Normal1x, Normal1x } 51 }; 52 53 static int cursorStretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY); 54 45 55 const OSystem::GraphicsMode *OSystem_SDL::getSupportedGraphicsModes() const { 46 56 return s_supportedGraphicsModes; 47 57 } … … 367 377 SDL_FreeSurface(old_screen); 368 378 SDL_FreeSurface(old_tmpscreen); 369 379 380 // Update cursor to new scale 381 blitCursor(); 382 370 383 // Blit everything to the screen 371 384 internUpdateScreen(); 372 385 … … 399 412 _forceFull = true; 400 413 } 401 414 402 // Make sure the mouse is drawn, if it should be drawn.403 drawMouse();404 405 415 // Check whether the palette was changed in the meantime and update the 406 416 // screen surface accordingly. 407 417 if (_paletteDirtyEnd != 0) { … … 434 444 } 435 445 #endif 436 446 447 undrawMouse(); 448 437 449 // Force a full redraw if requested 438 450 if (_forceFull) { 439 451 _numDirtyRects = 1; … … 527 539 SDL_BlitSurface(_osdSurface, 0, _hwscreen, 0); 528 540 } 529 541 #endif 530 542 drawMouse(); 543 531 544 // Finally, blit all our changes to the screen 532 545 SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList); 546 } else { 547 drawMouse(); 548 if (_numDirtyRects) 549 SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList); 533 550 } 534 551 535 552 _numDirtyRects = 0; … … 562 579 assert(_hwscreen != 0); 563 580 _fullscreen ^= true; 564 581 565 undrawMouse();566 567 582 #if defined(MACOSX) && !SDL_VERSION_ATLEAST(1, 2, 6) 568 583 // On OS X, SDL_WM_ToggleFullScreen is currently not implemented. Worse, 569 584 // before SDL 1.2.6 it always returned -1 (which would indicate a … … 672 687 addDirtyRect(x, y, w, h); 673 688 } 674 689 675 /* FIXME: undraw mouse only if the draw rect intersects with the mouse rect */676 undrawMouse();677 678 690 // Try to lock the screen surface 679 691 if (SDL_LockSurface(_screen) == -1) 680 692 error("SDL_LockSurface failed: %s", SDL_GetError()); … … 696 708 } 697 709 698 710 699 void OSystem_SDL::addDirtyRect(int x, int y, int w, int h ) {711 void OSystem_SDL::addDirtyRect(int x, int y, int w, int h, bool mouseRect) { 700 712 if (_forceFull) 701 713 return; 702 714 715 if (mouseRect) { 716 SDL_Rect *r = &_dirtyRectList[_numDirtyRects++]; 717 r->x = x; 718 r->y = y; 719 r->w = w; 720 r->h = h; 721 return; 722 } 723 703 724 if (_numDirtyRects == NUM_DIRTY_RECT) 704 725 _forceFull = true; 705 726 else { … … 846 867 847 868 if (start + num > _paletteDirtyEnd) 848 869 _paletteDirtyEnd = start + num; 870 871 // Some games blink cursors with palette 872 if (!_overlayVisible && !_cursorHasOwnPalette) 873 blitCursor(); 874 } 875 876 void OSystem_SDL::setCursorPalette(const byte *colors, uint start, uint num) { 877 const byte *b = colors; 878 uint i; 879 SDL_Color *base = _cursorPalette + start; 880 for (i = 0; i < num; i++) { 881 base[i].r = b[0]; 882 base[i].g = b[1]; 883 base[i].b = b[2]; 884 b += 4; 885 } 886 887 _cursorHasOwnPalette = true; 888 889 if (!_overlayVisible) 890 blitCursor(); 849 891 } 850 892 851 893 void OSystem_SDL::setShakePos(int shake_pos) { … … 862 904 void OSystem_SDL::showOverlay() { 863 905 assert (_transactionMode == kTransactionNone); 864 906 865 // hide the mouse866 undrawMouse();867 868 907 _overlayVisible = true; 869 908 clearOverlay(); 870 909 } … … 872 911 void OSystem_SDL::hideOverlay() { 873 912 assert (_transactionMode == kTransactionNone); 874 913 875 // hide the mouse876 undrawMouse();877 878 914 _overlayVisible = false; 879 915 _forceFull = true; 880 916 } … … 887 923 888 924 Common::StackLock lock(_graphicsMutex); // Lock the mutex until this function ends 889 925 890 // hide the mouse891 undrawMouse();892 893 926 // Clear the overlay by making the game screen "look through" everywhere. 894 927 SDL_Rect src, dst; 895 928 src.x = src.y = 0; … … 911 944 if (_tmpscreen == NULL) 912 945 return; 913 946 914 // hide the mouse915 undrawMouse();916 917 947 if (SDL_LockSurface(_tmpscreen) == -1) 918 948 error("SDL_LockSurface failed: %s", SDL_GetError()); 919 949 … … 964 994 _cksumValid = false; 965 995 addDirtyRect(x, y, w, h); 966 996 967 /* FIXME: undraw mouse only if the draw rect intersects with the mouse rect */968 undrawMouse();969 970 997 if (SDL_LockSurface(_tmpscreen) == -1) 971 998 error("SDL_LockSurface failed: %s", SDL_GetError()); 972 999 … … 1000 1027 bool last = _mouseVisible; 1001 1028 _mouseVisible = visible; 1002 1029 1003 if (visible) 1004 drawMouse(); 1005 else 1006 undrawMouse(); 1030 updateScreen(); 1007 1031 1008 1032 return last; 1009 1033 } 1010 1034 1011 1035 void OSystem_SDL::setMousePos(int x, int y) { 1012 1036 if (x != _mouseCurState.x || y != _mouseCurState.y) { 1013 undrawMouse();1014 1037 _mouseCurState.x = x; 1015 1038 _mouseCurState.y = y; 1016 1039 updateScreen(); … … 1032 1055 } 1033 1056 } 1034 1057 1035 void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor) { 1036 1037 undrawMouse(); 1038 1039 assert(w <= MAX_MOUSE_W); 1040 assert(h <= MAX_MOUSE_H); 1041 _mouseCurState.w = w; 1042 _mouseCurState.h = h; 1043 1058 void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale) { 1044 1059 _mouseHotspotX = hotspot_x; 1045 1060 _mouseHotspotY = hotspot_y; 1046 1061 1047 1062 _mouseKeyColor = keycolor; 1048 1063 1064 _cursorTargetScale = cursorTargetScale; 1065 1066 if (_mouseCurState.w != (int)w || _mouseCurState.h != (int)h) { 1067 _mouseCurState.w = w; 1068 _mouseCurState.h = h; 1069 1070 if (_mouseOrigSurface) 1071 SDL_FreeSurface(_mouseOrigSurface); 1072 1073 // Allocate bigger surface because AdvMame2x adds black pixel at [0,0] 1074 _mouseOrigSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, 1075 _mouseCurState.w + 2, 1076 _mouseCurState.h + 2, 1077 16, 1078 _hwscreen->format->Rmask, 1079 _hwscreen->format->Gmask, 1080 _hwscreen->format->Bmask, 1081 _hwscreen->format->Amask); 1082 1083 if (_mouseOrigSurface == NULL) 1084 error("allocating _mouseOrigSurface failed"); 1085 SDL_SetColorKey(_mouseOrigSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kMouseColorKey); 1086 } 1087 1049 1088 free(_mouseData); 1050 1089 1051 1090 _mouseData = (byte *)malloc(w * h); 1052 1091 memcpy(_mouseData, buf, w * h); 1092 blitCursor(); 1053 1093 } 1054 1094 1055 void OSystem_SDL::toggleMouseGrab() { 1056 if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) 1057 SDL_WM_GrabInput(SDL_GRAB_ON); 1058 else 1059 SDL_WM_GrabInput(SDL_GRAB_OFF); 1060 } 1061 1062 void OSystem_SDL::drawMouse() { 1063 if (_mouseDrawn || !_mouseVisible || !_mouseData) 1064 return; 1065 1066 int x = _mouseCurState.x - _mouseHotspotX; 1067 int y = _mouseCurState.y - _mouseHotspotY; 1068 int w = _mouseCurState.w; 1069 int h = _mouseCurState.h; 1095 void OSystem_SDL::blitCursor() { 1096 byte *dstPtr; 1097 const byte *srcPtr = _mouseData; 1070 1098 byte color; 1071 const byte *src = _mouseData; // Image representing the mouse 1072 1073 // clip the mouse rect, and addjust the src pointer accordingly 1074 if (x < 0) { 1075 w += x; 1076 src -= x; 1077 x = 0; 1078 } 1079 if (y < 0) { 1080 h += y; 1081 src -= y * _mouseCurState.w; 1082 y = 0; 1099 int w, h; 1100 1101 if (!_mouseOrigSurface) 1102 return; 1103 1104 w = _mouseCurState.w; 1105 h = _mouseCurState.h; 1106 1107 SDL_LockSurface(_mouseOrigSurface); 1108 1109 // Make whole surface transparent 1110 for (int i = 0; i < h + 2; i++) { 1111 dstPtr = (byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch * i; 1112 for (int j = 0; j < w + 2; j++) { 1113 *(uint16 *)dstPtr = kMouseColorKey; 1114 dstPtr += 2; 1115 } 1083 1116 } 1084 1117 1085 if (w > _screenWidth - x) 1086 w = _screenWidth - x; 1087 if (h > _screenHeight - y) 1088 h = _screenHeight - y; 1089 1090 // Quick check to see if anything has to be drawn at all 1091 if (w <= 0 || h <= 0) 1092 return; 1093 1094 // Draw the mouse cursor; backup the covered area in "bak" 1095 if (SDL_LockSurface(_overlayVisible ? _tmpscreen : _screen) == -1) 1096 error("SDL_LockSurface failed: %s", SDL_GetError()); 1097 1098 // Mark as dirty 1099 addDirtyRect(x, y, w, h); 1100 1101 if (!_overlayVisible) { 1102 byte *bak = _mouseBackup; // Surface used to backup the area obscured by the mouse 1103 byte *dst; // Surface we are drawing into 1104 1105 dst = (byte *)_screen->pixels + y * _screenWidth + x; 1106 while (h > 0) { 1107 int width = w; 1108 while (width > 0) { 1109 *bak++ = *dst; 1110 color = *src++; 1111 if (color != _mouseKeyColor) // transparent, don't draw 1112 *dst = color; 1113 dst++; 1114 width--; 1118 // Draw from [1,1] since AdvMame2x adds artefact at 0,0 1119 dstPtr = (byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch + 2; 1120 1121 for (int i = 0; i < h; i++) { 1122 for (int j = 0; j < w; j++) { 1123 color = *srcPtr; 1124 if (color != _mouseKeyColor) { // transparent, don't draw 1125 if (_cursorHasOwnPalette && !_overlayVisible) 1126 *(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format, 1127 _cursorPalette[color].r, _cursorPalette[color].g, 1128 _cursorPalette[color].b); 1129 else 1130 *(uint16 *)dstPtr = SDL_MapRGB(_mouseOrigSurface->format, 1131 _currentPalette[color].r, _currentPalette[color].g, 1132 _currentPalette[color].b); 1115 1133 } 1116 src += _mouseCurState.w - w; 1117 bak += MAX_MOUSE_W - w; 1118 dst += _screenWidth - w; 1119 h--; 1134 dstPtr += 2; 1135 srcPtr++; 1120 1136 } 1121 1137 dstPtr += _mouseOrigSurface->pitch - w * 2; 1138 } 1139 1140 int hW, hH, hH1; 1141 1142 if (_cursorTargetScale >= _scaleFactor) { 1143 hW = w; 1144 hH = hH1 = h; 1122 1145 } else { 1123 uint16 *bak = (uint16 *)_mouseBackup; // Surface used to backup the area obscured by the mouse 1124 byte *dst; // Surface we are drawing into 1125 1126 dst = (byte *)_tmpscreen->pixels + (y + 1) * _tmpscreen->pitch + (x + 1) * 2; 1127 while (h > 0) { 1128 int width = w; 1129 while (width > 0) { 1130 *bak++ = *(uint16 *)dst; 1131 color = *src++; 1132 if (color != 0xFF) // 0xFF = transparent, don't draw 1133 *(uint16 *)dst = RGBToColor(_currentPalette[color].r, _currentPalette[color].g, _currentPalette[color].b); 1134 dst += 2; 1135 width--; 1136 } 1137 src += _mouseCurState.w - w; 1138 bak += MAX_MOUSE_W - w; 1139 dst += _tmpscreen->pitch - w * 2; 1140 h--; 1141 } 1146 hW = w * _scaleFactor / _cursorTargetScale; 1147 hH = hH1 = h * _scaleFactor / _cursorTargetScale; 1148 } 1149 1150 if (_adjustAspectRatio) { 1151 hH = real2Aspect(hH - 1) + 1; 1152 } 1153 1154 if (_mouseCurState.hW != hW || _mouseCurState.hH != hH) { 1155 _mouseCurState.hW = hW; 1156 _mouseCurState.hH = hH; 1157 1158 if (_mouseSurface) 1159 SDL_FreeSurface(_mouseSurface); 1160 1161 _mouseSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, 1162 _mouseCurState.hW, 1163 _mouseCurState.hH, 1164 16, 1165 _hwscreen->format->Rmask, 1166 _hwscreen->format->Gmask, 1167 _hwscreen->format->Bmask, 1168 _hwscreen->format->Amask); 1169 1170 if (_mouseSurface == NULL) 1171 error("allocating _mouseSurface failed"); 1172 1173 SDL_SetColorKey(_mouseSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kMouseColorKey); 1174 } 1175 1176 SDL_LockSurface(_mouseSurface); 1177 (scalersMagn[_cursorTargetScale-1][_scaleFactor-1])((byte *)_mouseOrigSurface->pixels + _mouseOrigSurface->pitch + 2, 1178 _mouseOrigSurface->pitch, (byte *)_mouseSurface->pixels, _mouseSurface->pitch, 1179 _mouseCurState.w, _mouseCurState.h); 1180 1181 if (_adjustAspectRatio) 1182 cursorStretch200To240((uint8 *)_mouseSurface->pixels, _mouseSurface->pitch, hW, hH1, 0, 0, 0); 1183 1184 SDL_UnlockSurface(_mouseSurface); 1185 SDL_UnlockSurface(_mouseOrigSurface); 1186 } 1187 1188 // Basically it is kVeryFastAndUglyAspectMode of stretch200To240 from 1189 // common/scale/aspect.cpp 1190 static int cursorStretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY) { 1191 int maxDstY = real2Aspect(origSrcY + height - 1); 1192 int y; 1193 const uint8 *startSrcPtr = buf + srcX * 2 + (srcY - origSrcY) * pitch; 1194 uint8 *dstPtr = buf + srcX * 2 + maxDstY * pitch; 1195 1196 for (y = maxDstY; y >= srcY; y--) { 1197 const uint8 *srcPtr = startSrcPtr + aspect2Real(y) * pitch; 1198 1199 if (srcPtr == dstPtr) 1200 break; 1201 memcpy(dstPtr, srcPtr, width * 2); 1202 dstPtr -= pitch; 1142 1203 } 1143 1204 1144 SDL_UnlockSurface(_overlayVisible ? _tmpscreen : _screen); 1205 return 1 + maxDstY - srcY; 1206 } 1145 1207 1146 // Finally, set the flag to indicate the mouse has been drawn 1147 _mouseDrawn = true; 1208 void OSystem_SDL::toggleMouseGrab() { 1209 if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) 1210 SDL_WM_GrabInput(SDL_GRAB_ON); 1211 else 1212 SDL_WM_GrabInput(SDL_GRAB_OFF); 1148 1213 } 1149 1214 1150 1215 void OSystem_SDL::undrawMouse() { 1151 assert (_transactionMode == kTransactionNone || _transactionMode == kTransactionCommit); 1152 1153 if (!_mouseDrawn) 1154 return; 1155 _mouseDrawn = false; 1156 1157 int old_mouse_x = _mouseCurState.x - _mouseHotspotX; 1158 int old_mouse_y = _mouseCurState.y - _mouseHotspotY; 1159 int old_mouse_w = _mouseCurState.w; 1160 int old_mouse_h = _mouseCurState.h; 1161 1162 // clip the mouse rect, and addjust the src pointer accordingly 1163 if (old_mouse_x < 0) { 1164 old_mouse_w += old_mouse_x; 1165 old_mouse_x = 0; 1166 } 1167 if (old_mouse_y < 0) { 1168 old_mouse_h += old_mouse_y; 1169 old_mouse_y = 0; 1170 } 1171 1172 if (old_mouse_w > _screenWidth - old_mouse_x) 1173 old_mouse_w = _screenWidth - old_mouse_x; 1174 if (old_mouse_h > _screenHeight - old_mouse_y) 1175 old_mouse_h = _screenHeight - old_mouse_y; 1176 1177 // Quick check to see if anything has to be drawn at all 1178 if (old_mouse_w <= 0 || old_mouse_h <= 0) 1179 return; 1216 if (_mouseBackup.w) { 1217 if (_adjustAspectRatio) 1218 addDirtyRect(_mouseBackup.x, aspect2Real(_mouseBackup.y), _mouseBackup.w, 1219 _mouseBackup.h); 1220 else 1221 addDirtyRect(_mouseBackup.x, _mouseBackup.y, _mouseBackup.w, 1222 _mouseBackup.h); 1223 } 1224 } 1180 1225 1181 if (SDL_LockSurface(_overlayVisible ? _tmpscreen : _screen) == -1) 1182 error("SDL_LockSurface failed: %s", SDL_GetError()); 1226 void OSystem_SDL::drawMouse() { 1227 if (!_mouseVisible) { 1228 _mouseBackup.x = _mouseBackup.y = _mouseBackup.w = _mouseBackup.h = 0; 1229 return; 1230 } 1231 1232 SDL_Rect src, dst; 1233 bool scale; 1183 1234 1184 int x, y; 1185 if (!_overlayVisible) { 1186 byte *dst, *bak = _mouseBackup; 1187 1188 // No need to do clipping here, since drawMouse() did that already 1189 dst = (byte *)_screen->pixels + old_mouse_y * _screenWidth + old_mouse_x; 1190 for (y = 0; y < old_mouse_h; ++y, bak += MAX_MOUSE_W, dst += _screenWidth) { 1191 for (x = 0; x < old_mouse_w; ++x) { 1192 dst[x] = bak[x]; 1193 } 1194 } 1195 1196 } else { 1235 scale = (_scaleFactor > _cursorTargetScale); 1197 1236 1198 byte *dst; 1199 uint16 *bak = (uint16 *)_mouseBackup; 1200 1201 // No need to do clipping here, since drawMouse() did that already 1202 dst = (byte *)_tmpscreen->pixels + (old_mouse_y + 1) * _tmpscreen->pitch + (old_mouse_x + 1) * 2; 1203 for (y = 0; y < old_mouse_h; ++y, bak += MAX_MOUSE_W, dst += _tmpscreen->pitch) { 1204 for (x = 0; x < old_mouse_w; ++x) { 1205 *((uint16 *)dst + x) = bak[x]; 1206 } 1207 } 1208 } 1237 dst.x = _mouseCurState.x - _mouseHotspotX / _cursorTargetScale; 1238 dst.y = _mouseCurState.y - _mouseHotspotY / _cursorTargetScale; 1209 1239 1210 addDirtyRect(old_mouse_x, old_mouse_y, old_mouse_w, old_mouse_h); 1240 dst.w = _mouseCurState.hW; 1241 dst.h = _mouseCurState.hH; 1242 src.x = src.y = 0; 1211 1243 1212 SDL_UnlockSurface(_overlayVisible ? _tmpscreen : _screen); 1244 // clip the mouse rect, and adjust the src pointer accordingly 1245 int dx, dy; 1246 1247 dx = dst.x; dy = dst.y; 1248 dx = scale ? dst.x * _scaleFactor / _cursorTargetScale : dst.x; 1249 dy = scale ? dst.y * _scaleFactor / _cursorTargetScale : dst.y; 1250 if (_adjustAspectRatio) 1251 dy = real2Aspect(dy); 1252 1253 if (dst.x < 0) { 1254 dst.w += dx; 1255 src.x -= dx; 1256 dst.x = 0; 1257 } 1258 if (dst.y < 0) { 1259 dst.h += dy; 1260 src.y -= dy; 1261 dst.y = 0; 1262 } 1263 1264 // Quick check to see if anything has to be drawn at all 1265 if (dst.w <= 0 || dst.h <= 0) 1266 return; 1267 1268 src.w = dst.w; 1269 src.h = dst.h; 1270 1271 if (_adjustAspectRatio) 1272 dst.y = real2Aspect(dst.y); 1273 1274 _mouseBackup.x = dst.x; 1275 _mouseBackup.y = dst.y; 1276 _mouseBackup.w = dst.w; 1277 _mouseBackup.h = dst.h; 1278 1279 dst.x *= _scaleFactor; 1280 dst.y *= _scaleFactor; 1281 1282 if (SDL_BlitSurface(_mouseSurface, &src, _hwscreen, &dst) != 0) 1283 error("SDL_BlitSurface failed: %s", SDL_GetError()); 1284 1285 addDirtyRect(dst.x, dst.y, dst.w, dst.h, true); 1213 1286 } 1214 1287 1215 1216 1288 #pragma mark - 1217 1289 #pragma mark --- Mouse --- 1218 1290 #pragma mark - -
backends/sdl/sdl-common.h
RCS file: /cvsroot/scummvm/scummvm/backends/sdl/sdl-common.h,v retrieving revision 1.71 diff -u -r1.71 sdl-common.h
82 82 virtual void warpMouse(int x, int y); // overloaded by CE backend 83 83 84 84 // Set the bitmap that's used when drawing the cursor. 85 void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor); 85 void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale); 86 87 // Set colors of cursor palette 88 void setCursorPalette(const byte *colors, uint start, uint num); 86 89 87 90 // Shaking is used in SCUMM. Set current shake position. 88 91 void setShakePos(int shake_pos); … … 258 261 }; 259 262 260 263 struct MousePos { 261 int16 x, y, w, h; 264 int16 x, y, w, h, hW, hH; 265 MousePos() : x(0), y(0), w(0), h(0), hW(0), hH(0) {} 262 266 }; 263 267 264 268 // mouse … … 266 270 bool _mouseVisible; 267 271 bool _mouseDrawn; 268 272 byte *_mouseData; 269 byte *_mouseBackup;273 SDL_Rect _mouseBackup; 270 274 MousePos _mouseCurState; 271 275 int16 _mouseHotspotX; 272 276 int16 _mouseHotspotY; 273 277 byte _mouseKeyColor; 278 int _cursorTargetScale; 279 bool _cursorHasOwnPalette; 280 SDL_Surface *_mouseOrigSurface; 281 SDL_Surface *_mouseSurface; 282 enum { 283 kMouseColorKey = 1 284 }; 274 285 275 286 // joystick 276 287 SDL_Joystick *_joystick; … … 283 294 SDL_Color *_currentPalette; 284 295 uint _paletteDirtyStart, _paletteDirtyEnd; 285 296 297 // Cursor palette data 298 SDL_Color *_cursorPalette; 299 286 300 /** 287 301 * Mutex which prevents multiple threads from interfering with each other 288 302 * when accessing the screen. … … 293 307 void addDirtyRgnAuto(const byte *buf); 294 308 void makeChecksums(const byte *buf); 295 309 296 virtual void addDirtyRect(int x, int y, int w, int h ); // overloaded by CE backend310 virtual void addDirtyRect(int x, int y, int w, int h, bool mouseRect = false); // overloaded by CE backend 297 311 298 312 virtual void drawMouse(); // overloaded by CE backend 299 313 virtual void undrawMouse(); // overloaded by CE backend 314 void blitCursor(); 300 315 301 316 /** Set the position of the virtual mouse cursor. */ 302 317 void setMousePos(int x, int y); -
backends/sdl/sdl.cpp
RCS file: /cvsroot/scummvm/scummvm/backends/sdl/sdl.cpp,v retrieving revision 1.78 diff -u -r1.78 sdl.cpp
100 100 _tmpscreen(0), _overlayVisible(false), 101 101 _samplesPerSec(0), 102 102 _cdrom(0), _scalerProc(0), _modeChanged(false), _dirtyChecksums(0), 103 _mouseVisible(false), _mouseDrawn(false), _mouseData(0), 104 _mouseHotspotX(0), _mouseHotspotY(0), 103 _mouseVisible(false), _mouseDrawn(false), _mouseData(0), _mouseSurface(0), 104 _mouseOrigSurface(0), _mouseHotspotX(0), _mouseHotspotY(0), _cursorTargetScale(1), 105 _cursorHasOwnPalette(false), 105 106 _joystick(0), 106 107 _currentShakePos(0), _newShakePos(0), 107 108 _paletteDirtyStart(0), _paletteDirtyEnd(0), … … 109 110 110 111 // allocate palette storage 111 112 _currentPalette = (SDL_Color *)calloc(sizeof(SDL_Color), 256); 113 _cursorPalette = (SDL_Color *)calloc(sizeof(SDL_Color), 256); 112 114 113 // allocate the dirty rect storage 114 _mouseBackup = (byte *)malloc(MAX_MOUSE_W * MAX_MOUSE_H * MAX_SCALING * 2); 115 _mouseBackup.x = _mouseBackup.y = _mouseBackup.w = _mouseBackup.h = 0; 115 116 116 117 // reset mouse state 117 118 memset(&_km, 0, sizeof(_km)); … … 123 124 OSystem_SDL::~OSystem_SDL() { 124 125 free(_dirtyChecksums); 125 126 free(_currentPalette); 126 free(_ mouseBackup);127 free(_cursorPalette); 127 128 free(_mouseData); 128 129 } 129 130 … … 147 148 return 148 149 (f == kFeatureFullscreenMode) || 149 150 (f == kFeatureAspectRatioCorrection) || 150 (f == kFeatureAutoComputeDirtyRects); 151 (f == kFeatureAutoComputeDirtyRects) || 152 (f == kFeatureCursorHasPalette); 151 153 } 152 154 153 155 void OSystem_SDL::setFeatureState(Feature f, bool enable) { -
common/scaler.cpp
RCS file: /cvsroot/scummvm/scummvm/common/scaler.cpp,v retrieving revision 1.64 diff -u -r1.64 scaler.cpp
169 169 } 170 170 } 171 171 172 #define INTERPOLATE INTERPOLATE<bitFormat> 173 #define Q_INTERPOLATE Q_INTERPOLATE<bitFormat> 174 175 /** 176 * Trivial nearest-neighbour 1.5x scaler. 177 */ 178 template<int bitFormat> 179 void Normal1o5xTemplate(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, 180 int width, int height) { 181 uint8 *r; 182 const uint32 dstPitch2 = dstPitch * 2; 183 const uint32 dstPitch3 = dstPitch * 3; 184 const uint32 srcPitch2 = srcPitch * 2; 185 186 assert(((int)dstPtr & 1) == 0); 187 while (height) { 188 r = dstPtr; 189 for (int i = 0; i < width; i += 2, r += 6) { 190 uint16 color0 = *(((const uint16 *)srcPtr) + i); 191 uint16 color1 = *(((const uint16 *)srcPtr) + i + 1); 192 uint16 color2 = *(((const uint16 *)(srcPtr + srcPitch)) + i); 193 uint16 color3 = *(((const uint16 *)(srcPtr + srcPitch)) + i + 1); 194 195 *(uint16 *)(r + 0) = color0; 196 *(uint16 *)(r + 2) = INTERPOLATE(color0, color1); 197 *(uint16 *)(r + 4) = color1; 198 *(uint16 *)(r + 0 + dstPitch) = INTERPOLATE(color0, color2); 199 *(uint16 *)(r + 2 + dstPitch) = Q_INTERPOLATE(color0, color1, color2, color3); 200 *(uint16 *)(r + 4 + dstPitch) = INTERPOLATE(color1, color3); 201 *(uint16 *)(r + 0 + dstPitch2) = color2; 202 *(uint16 *)(r + 2 + dstPitch2) = INTERPOLATE(color2, color3); 203 *(uint16 *)(r + 4 + dstPitch2) = color3; 204 } 205 srcPtr += srcPitch2; 206 dstPtr += dstPitch3; 207 height -= 2; 208 } 209 } 210 MAKE_WRAPPER(Normal1o5x) 211 172 212 /** 173 213 * The Scale2x filter, also known as AdvMame2x. 174 214 * See also http://scale2x.sourceforge.net -
common/scaler.h
RCS file: /cvsroot/scummvm/scummvm/common/scaler.h,v retrieving revision 1.27 diff -u -r1.27 scaler.h
41 41 DECLARE_SCALER(Normal1x); 42 42 DECLARE_SCALER(Normal2x); 43 43 DECLARE_SCALER(Normal3x); 44 DECLARE_SCALER(Normal1o5x); 44 45 DECLARE_SCALER(TV2x); 45 46 DECLARE_SCALER(DotMatrix); 46 47 DECLARE_SCALER(HQ2x); -
common/system.h
RCS file: /cvsroot/scummvm/scummvm/common/system.h,v retrieving revision 1.86 diff -u -r1.86 system.h
96 96 * Implementing this is purely optional, and no harm should arise 97 97 * when not doing so (except for decreased speed in said frontends). 98 98 */ 99 kFeatureAutoComputeDirtyRects 99 kFeatureAutoComputeDirtyRects, 100 101 /** 102 * This flags determines either cursor can have its own palette or not 103 * It is currently used only by some Macintosh versions of Humongous 104 * Entertainment games. If backend doesn't implement this feature then 105 * engine switches to b/w version of cursors. 106 */ 107 kFeatureCursorHasPalette 100 108 }; 101 109 102 110 /** … … 274 282 virtual void setPalette(const byte *colors, uint start, uint num) = 0; 275 283 276 284 /** 285 * Replace the specified range of cursor the palette with new colors. 286 * The palette entries from 'start' till (start+num-1) will be replaced - so 287 * a full palette update is accomplished via start=0, num=256. 288 * 289 * Backends which implement it should have kFeatureCursorHasPalette flag set 290 * 291 * @see setPalette 292 * @see kFeatureCursorHasPalette 293 */ 294 virtual void setCursorPalette(const byte *colors, uint start, uint num) {}; 295 296 /** 277 297 * Blit a bitmap to the virtual screen. 278 298 * The real screen will not immediately be updated to reflect the changes. 279 299 * Client code has to to call updateScreen to ensure any changes are … … 365 385 /** 366 386 * Set the bitmap used for drawing the cursor. 367 387 * 368 * @param buf the pixmap data to be used (8bit/pixel) 369 * @param w width of the mouse cursor 370 * @param h height of the mouse cursor 371 * @param hotspotX horizontal offset from the left side to the hotspot 372 * @param hotspotY vertical offset from the top side to the hotspot 373 * @param keycolor transparency color index 388 * @param buf the pixmap data to be used (8bit/pixel) 389 * @param w width of the mouse cursor 390 * @param h height of the mouse cursor 391 * @param hotspotX horizontal offset from the left side to the hotspot 392 * @param hotspotY vertical offset from the top side to the hotspot 393 * @param keycolor transparency color index 394 * @param cursorTargetScale scale factor which cursor is designed for 374 395 */ 375 virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255 ) = 0;396 virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int cursorTargetScale = 1) = 0; 376 397 377 398 //@} 378 399 -
scumm/cursor.cpp
RCS file: /cvsroot/scummvm/scummvm/scumm/cursor.cpp,v retrieving revision 2.27 diff -u -r2.27 cursor.cpp
107 107 108 108 void ScummEngine::updateCursor() { 109 109 _system->setMouseCursor(_grabbedCursor, _cursor.width, _cursor.height, 110 _cursor.hotspotX, _cursor.hotspotY); 110 _cursor.hotspotX, _cursor.hotspotY, 255, 111 (_heversion == 70 ? 2 : 1)); 111 112 } 112 113 113 114 void ScummEngine_v6::grabCursor(int x, int y, int w, int h) { -
scumm/resource_v7he.cpp
RCS file: /cvsroot/scummvm/scummvm/scumm/resource_v7he.cpp,v retrieving revision 1.19 diff -u -r1.19 resource_v7he.cpp
1532 1532 *hotspot_x = dis.readUint16BE(); 1533 1533 *w = *h = 16; 1534 1534 1535 // FIXME 1536 // Color cursors use their own palette. 1537 // So we can't use it for now and use B/W version 1538 return; 1535 // Use b/w cursor on backends which don't support cursor palettes 1536 if (!_vm->_system->hasFeature(OSystem::kFeatureCursorHasPalette)) 1537 return; 1539 1538 1540 1539 dis.readUint32BE(); // reserved 1541 1540 dis.readUint32BE(); // cursorID … … 1600 1599 palette[c * 4 + 3] = 0; 1601 1600 } 1602 1601 1603 // TODO: Here we should set separate cursor palette. 1604 // It requires cursor to be rendered on a different surface at 1605 // least in SDL backend. 1606 // HACK: now set global palett just to see if colors are correct. 1607 // this affects subtitles colors 1608 _vm->_system->setPalette(palette, 0, ctSize); 1602 _vm->_system->setCursorPalette(palette, 0, ctSize); 1609 1603 1610 1604 numBytes = 1611 1605 (iconBounds[2] - iconBounds[0]) *