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 void CursorManager::replaceCursor(const Graphics::Cursor *cursor) {
00151     replaceCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(), cursor->getHotspotX(),
00152                   cursor->getHotspotY(), cursor->getKeyColor());
00153 
00154     if (cursor->getPalette())
00155         replaceCursorPalette(cursor->getPalette(), cursor->getPaletteStartIndex(), cursor->getPaletteCount());
00156 }
00157 
00158 bool CursorManager::supportsCursorPalettes() {
00159     return g_system->hasFeature(OSystem::kFeatureCursorPalette);
00160 }
00161 
00162 void CursorManager::disableCursorPalette(bool disable) {
00163     if (!g_system->hasFeature(OSystem::kFeatureCursorPalette))
00164         return;
00165 
00166     if (_cursorPaletteStack.empty())
00167         return;
00168 
00169     Palette *pal = _cursorPaletteStack.top();
00170     pal->_disabled = disable;
00171 
00172     g_system->setFeatureState(OSystem::kFeatureCursorPalette, !disable);
00173 }
00174 
00175 void CursorManager::pushCursorPalette(const byte *colors, uint start, uint num) {
00176     if (!g_system->hasFeature(OSystem::kFeatureCursorPalette))
00177         return;
00178 
00179     Palette *pal = new Palette(colors, start, num);
00180     _cursorPaletteStack.push(pal);
00181 
00182     if (num)
00183         g_system->setCursorPalette(colors, start, num);
00184     else
00185         g_system->setFeatureState(OSystem::kFeatureCursorPalette, false);
00186 }
00187 
00188 void CursorManager::popCursorPalette() {
00189     if (!g_system->hasFeature(OSystem::kFeatureCursorPalette))
00190         return;
00191 
00192     if (_cursorPaletteStack.empty())
00193         return;
00194 
00195     Palette *pal = _cursorPaletteStack.pop();
00196     delete pal;
00197 
00198     if (_cursorPaletteStack.empty()) {
00199         g_system->setFeatureState(OSystem::kFeatureCursorPalette, false);
00200         return;
00201     }
00202 
00203     pal = _cursorPaletteStack.top();
00204 
00205     if (pal->_num && !pal->_disabled)
00206         g_system->setCursorPalette(pal->_data, pal->_start, pal->_num);
00207     else
00208         g_system->setFeatureState(OSystem::kFeatureCursorPalette, false);
00209 }
00210 
00211 void CursorManager::replaceCursorPalette(const byte *colors, uint start, uint num) {
00212     if (!g_system->hasFeature(OSystem::kFeatureCursorPalette))
00213         return;
00214 
00215     if (_cursorPaletteStack.empty()) {
00216         pushCursorPalette(colors, start, num);
00217         return;
00218     }
00219 
00220     Palette *pal = _cursorPaletteStack.top();
00221     uint size = 3 * num;
00222 
00223     if (pal->_size < size) {
00224         // Could not re-use the old buffer. Create a new one.
00225         delete[] pal->_data;
00226         pal->_data = new byte[size];
00227         pal->_size = size;
00228     }
00229 
00230     pal->_start = start;
00231     pal->_num = num;
00232 
00233     if (num) {
00234         memcpy(pal->_data, colors, size);
00235         g_system->setCursorPalette(pal->_data, pal->_start, pal->_num);
00236     } else {
00237         g_system->setFeatureState(OSystem::kFeatureCursorPalette, false);
00238     }
00239 }
00240 
00241 void CursorManager::lock(bool locked) {
00242     _locked = locked;
00243 }
00244 
00245 CursorManager::Cursor::Cursor(const void *data, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
00246 #ifdef USE_RGB_COLOR
00247     if (!format)
00248         _format = Graphics::PixelFormat::createFormatCLUT8();
00249      else
00250         _format = *format;
00251     _size = w * h * _format.bytesPerPixel;
00252     _keycolor = keycolor & ((1 << (_format.bytesPerPixel << 3)) - 1);
00253 #else
00254     _format = Graphics::PixelFormat::createFormatCLUT8();
00255     _size = w * h;
00256     _keycolor = keycolor & 0xFF;
00257 #endif
00258     _data = new byte[_size];
00259     if (data && _data)
00260         memcpy(_data, data, _size);
00261     _width = w;
00262     _height = h;
00263     _hotspotX = hotspotX;
00264     _hotspotY = hotspotY;
00265     _dontScale = dontScale;
00266     _visible = false;
00267 }
00268 
00269 CursorManager::Cursor::~Cursor() {
00270     delete[] _data;
00271 }
00272 
00273 CursorManager::Palette::Palette(const byte *colors, uint start, uint num) {
00274     _start = start;
00275     _num = num;
00276     _size = 3 * num;
00277 
00278     if (num) {
00279         _data = new byte[_size];
00280         memcpy(_data, colors, _size);
00281     } else {
00282         _data = NULL;
00283     }
00284 
00285     _disabled = false;
00286 }
00287 
00288 CursorManager::Palette::~Palette() {
00289     delete[] _data;
00290 }
00291 
00292 } // End of namespace Graphics


Generated on Sat Jun 27 2020 05:00:51 for ResidualVM by doxygen 1.7.1
curved edge   curved edge