ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

cursorman.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "graphics/cursorman.h"
00024 
00025 #include "common/system.h"
00026 #include "common/stack.h"
00027 
00028 namespace Common {
00029 DECLARE_SINGLETON(Graphics::CursorManager);
00030 }
00031 
00032 namespace Graphics {
00033 
00034 CursorManager::~CursorManager() {
00035     for (Common::Stack<Cursor *>::size_type i = 0; i < _cursorStack.size(); ++i)
00036         delete _cursorStack[i];
00037     _cursorStack.clear();
00038     for (Common::Stack<Palette *>::size_type i = 0; i < _cursorPaletteStack.size(); ++i)
00039         delete _cursorPaletteStack[i];
00040     _cursorPaletteStack.clear();
00041 }
00042 
00043 bool CursorManager::isVisible() {
00044     if (_cursorStack.empty())
00045         return false;
00046     return _cursorStack.top()->_visible;
00047 }
00048 
00049 bool CursorManager::showMouse(bool visible) {
00050     if (_cursorStack.empty())
00051         return false;
00052     if (_locked) {
00053         return false;
00054     }
00055 
00056     _cursorStack.top()->_visible = visible;
00057 
00058     // Should work, even if there's just a dummy cursor on the stack.
00059     return g_system->showMouse(visible);
00060 }
00061 
00062 void CursorManager::pushCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
00063     Cursor *cur = new Cursor(buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
00064 
00065     cur->_visible = isVisible();
00066     _cursorStack.push(cur);
00067 
00068     g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
00069 }
00070 
00071 void CursorManager::popCursor() {
00072     if (_cursorStack.empty())
00073         return;
00074 
00075     Cursor *cur = _cursorStack.pop();
00076     delete cur;
00077 
00078     if (!_cursorStack.empty()) {
00079         cur = _cursorStack.top();
00080         g_system->setMouseCursor(cur->_data, cur->_width, cur->_height, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_dontScale, &cur->_format);
00081     } else {
00082         g_system->setMouseCursor(nullptr, 0, 0, 0, 0, 0);
00083     }
00084 
00085     g_system->showMouse(isVisible());
00086 }
00087 
00088 
00089 void CursorManager::popAllCursors() {
00090     while (!_cursorStack.empty()) {
00091         Cursor *cur = _cursorStack.pop();
00092         delete cur;
00093     }
00094 
00095     if (g_system->hasFeature(OSystem::kFeatureCursorPalette)) {
00096         while (!_cursorPaletteStack.empty()) {
00097             Palette *pal = _cursorPaletteStack.pop();
00098             delete pal;
00099         }
00100     }
00101 
00102     g_system->setMouseCursor(nullptr, 0, 0, 0, 0, 0);
00103     g_system->showMouse(isVisible());
00104 }
00105 
00106 void CursorManager::replaceCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
00107 
00108     if (_cursorStack.empty()) {
00109         pushCursor(buf, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
00110         return;
00111     }
00112 
00113     Cursor *cur = _cursorStack.top();
00114 
00115 #ifdef USE_RGB_COLOR
00116     uint size;
00117     if (!format)
00118         size = w * h;
00119     else
00120         size = w * h * format->bytesPerPixel;
00121 #else
00122     uint size = w * h;
00123 #endif
00124 
00125     if (cur->_size < size) {
00126         delete[] cur->_data;
00127         cur->_data = new byte[size];
00128         cur->_size = size;
00129     }
00130 
00131     if (buf && cur->_data)
00132         memcpy(cur->_data, buf, size);
00133 
00134     cur->_width = w;
00135     cur->_height = h;
00136     cur->_hotspotX = hotspotX;
00137     cur->_hotspotY = hotspotY;
00138     cur->_keycolor = keycolor;
00139     cur->_dontScale = dontScale;
00140 #ifdef USE_RGB_COLOR
00141     if (format)
00142         cur->_format = *format;
00143     else
00144         cur->_format = Graphics::PixelFormat::createFormatCLUT8();
00145 #endif
00146 
00147     g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, dontScale, format);
00148 }
00149 
00150 bool CursorManager::supportsCursorPalettes() {
00151     return g_system->hasFeature(OSystem::kFeatureCursorPalette);
00152 }
00153 
00154 void CursorManager::disableCursorPalette(bool disable) {
00155     if (!g_system->hasFeature(OSystem::kFeatureCursorPalette))
00156         return;
00157 
00158     if (_cursorPaletteStack.empty())
00159         return;
00160 
00161     Palette *pal = _cursorPaletteStack.top();
00162     pal->_disabled = disable;
00163 
00164     g_system->setFeatureState(OSystem::kFeatureCursorPalette, !disable);
00165 }
00166 
00167 void CursorManager::pushCursorPalette(const byte *colors, uint start, uint num) {
00168     if (!g_system->hasFeature(OSystem::kFeatureCursorPalette))
00169         return;
00170 
00171     Palette *pal = new Palette(colors, start, num);
00172     _cursorPaletteStack.push(pal);
00173 
00174     if (num)
00175         g_system->setCursorPalette(colors, start, num);
00176     else
00177         g_system->setFeatureState(OSystem::kFeatureCursorPalette, false);
00178 }
00179 
00180 void CursorManager::popCursorPalette() {
00181     if (!g_system->hasFeature(OSystem::kFeatureCursorPalette))
00182         return;
00183 
00184     if (_cursorPaletteStack.empty())
00185         return;
00186 
00187     Palette *pal = _cursorPaletteStack.pop();
00188     delete pal;
00189 
00190     if (_cursorPaletteStack.empty()) {
00191         g_system->setFeatureState(OSystem::kFeatureCursorPalette, false);
00192         return;
00193     }
00194 
00195     pal = _cursorPaletteStack.top();
00196 
00197     if (pal->_num && !pal->_disabled)
00198         g_system->setCursorPalette(pal->_data, pal->_start, pal->_num);
00199     else
00200         g_system->setFeatureState(OSystem::kFeatureCursorPalette, false);
00201 }
00202 
00203 void CursorManager::replaceCursorPalette(const byte *colors, uint start, uint num) {
00204     if (!g_system->hasFeature(OSystem::kFeatureCursorPalette))
00205         return;
00206 
00207     if (_cursorPaletteStack.empty()) {
00208         pushCursorPalette(colors, start, num);
00209         return;
00210     }
00211 
00212     Palette *pal = _cursorPaletteStack.top();
00213     uint size = 3 * num;
00214 
00215     if (pal->_size < size) {
00216         // Could not re-use the old buffer. Create a new one.
00217         delete[] pal->_data;
00218         pal->_data = new byte[size];
00219         pal->_size = size;
00220     }
00221 
00222     pal->_start = start;
00223     pal->_num = num;
00224 
00225     if (num) {
00226         memcpy(pal->_data, colors, size);
00227         g_system->setCursorPalette(pal->_data, pal->_start, pal->_num);
00228     } else {
00229         g_system->setFeatureState(OSystem::kFeatureCursorPalette, false);
00230     }
00231 }
00232 
00233 void CursorManager::lock(bool locked) {
00234     _locked = locked;
00235 }
00236 
00237 CursorManager::Cursor::Cursor(const void *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
00238 #ifdef USE_RGB_COLOR
00239     if (!format)
00240         _format = Graphics::PixelFormat::createFormatCLUT8();
00241      else
00242         _format = *format;
00243     _size = w * h * _format.bytesPerPixel;
00244     _keycolor = keycolor & ((1 << (_format.bytesPerPixel << 3)) - 1);
00245 #else
00246     _format = Graphics::PixelFormat::createFormatCLUT8();
00247     _size = w * h;
00248     _keycolor = keycolor & 0xFF;
00249 #endif
00250     _data = new byte[_size];
00251     if (data && _data)
00252         memcpy(_data, data, _size);
00253     _width = w;
00254     _height = h;
00255     _hotspotX = hotspotX;
00256     _hotspotY = hotspotY;
00257     _dontScale = dontScale;
00258     _visible = false;
00259 }
00260 
00261 CursorManager::Cursor::~Cursor() {
00262     delete[] _data;
00263 }
00264 
00265 CursorManager::Palette::Palette(const byte *colors, uint start, uint num) {
00266     _start = start;
00267     _num = num;
00268     _size = 3 * num;
00269 
00270     if (num) {
00271         _data = new byte[_size];
00272         memcpy(_data, colors, _size);
00273     } else {
00274         _data = NULL;
00275     }
00276 
00277     _disabled = false;
00278 }
00279 
00280 CursorManager::Palette::~Palette() {
00281     delete[] _data;
00282 }
00283 
00284 } // End of namespace Graphics


Generated on Sat Jul 13 2019 05:01:14 for ResidualVM by doxygen 1.7.1
curved edge   curved edge