diff options
Diffstat (limited to 'backends/platform/psp/cursor.cpp')
-rw-r--r-- | backends/platform/psp/cursor.cpp | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/backends/platform/psp/cursor.cpp b/backends/platform/psp/cursor.cpp new file mode 100644 index 0000000000..b6b9a70458 --- /dev/null +++ b/backends/platform/psp/cursor.cpp @@ -0,0 +1,365 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.h $ + * $Id: osys_psp.h 46120 2009-11-24 10:33:30Z Bluddy $ + * + */ + +#include "common/scummsys.h" +#include "backends/platform/psp/display_client.h" +#include "backends/platform/psp/default_display_client.h" +#include "backends/platform/psp/cursor.h" + +//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */ +//#define __PSP_DEBUG_PRINT__ + +#include "backends/platform/psp/trace.h" + +void Cursor::init() { + DEBUG_ENTER_FUNC(); + + _renderer.setBuffer(&_buffer); // We do this explicitly + _renderer.setPalette(&_screenPalette); // because we want to choose screenpalette by default + _renderer.setUseGlobalScaler(true); + setRendererModePalettized(true); // Assume we start in 8bit mode + + // Default modes + _palette.setPixelFormats(PSPPixelFormat::Type_5551, PSPPixelFormat::Type_Palette_8bit); // default + _screenPalette.setPixelFormats(PSPPixelFormat::Type_5551, PSPPixelFormat::Type_Palette_8bit); + _buffer.setPixelFormat(PSPPixelFormat::Type_5551); + + DEBUG_EXIT_FUNC(); +} + +void Cursor::deallocate() { + DEBUG_ENTER_FUNC(); + + _buffer.deallocate(); + _palette.deallocate(); + _screenPalette.deallocate(); + + DEBUG_EXIT_FUNC(); +} + +void Cursor::setCursorPalette(const byte *colors, uint start, uint num) { + DEBUG_ENTER_FUNC(); + + if (!_palette.isAllocated()) { + _palette.allocate(); + } + + // Workaround: This is wrong, but we seem to not be getting setScreenPalette + if (!_screenPalette.isAllocated()) { + _screenPalette.allocate(); + } + + _palette.setPartial(colors, start, num); + setDirty(); + + DEBUG_EXIT_FUNC(); +} + +void Cursor::setScreenPalette(const byte *colors, uint start, uint num) { + DEBUG_ENTER_FUNC(); + + if (!_screenPalette.isAllocated()) { + _screenPalette.allocate(); + } + + _screenPalette.setPartial(colors, start, num); + setDirty(); + + DEBUG_EXIT_FUNC(); +} + +void Cursor::setKeyColor(uint32 color) { + DEBUG_ENTER_FUNC(); + PSP_DEBUG_PRINT("new color[%u], old color[%u]\n", color, _keyColor); + + // If it's a different color, undo the last keycolor + if (_buffer.hasPalette() && color != _keyColor) { + if (_screenPalette.isAllocated()) + _screenPalette.setColorPositionAlpha(_keyColor, true); + if (_palette.isAllocated()) + _palette.setColorPositionAlpha(_keyColor, true); + } + // Don't need anything special for 16-bit + _keyColor = color; + + DEBUG_EXIT_FUNC(); +} + +void Cursor::clearKeyColor() { + DEBUG_ENTER_FUNC(); + PSP_DEBUG_PRINT("keyColor[%d]\n", _keyColor); + + // We need 2 mechanisms: one for palettized and one for 16 bit + if (_buffer.hasPalette()) { + if (_screenPalette.isAllocated()) + _screenPalette.setColorPositionAlpha(_keyColor, false); // set keycolor to 0 + if (_palette.isAllocated()) + _palette.setColorPositionAlpha(_keyColor, false); + } else { // 16bit + _renderer.setKeyColor(_keyColor); + } + setDirty(); + + DEBUG_EXIT_FUNC(); +} + +void Cursor::enableCursorPalette(bool enable) { + DEBUG_ENTER_FUNC(); + PSP_DEBUG_PRINT("enable[%s]\n", enable ? "true" : "false"); + + _useCursorPalette = enable; + if (enable) + _renderer.setPalette(&_palette); // very important that we do this switch + else + _renderer.setPalette(&_screenPalette); + + setDirty(); + DEBUG_EXIT_FUNC(); +} + +inline void Cursor::setSize(uint32 width, uint32 height) { + DEBUG_ENTER_FUNC(); + PSP_DEBUG_PRINT("width[%u], height[%u]\n", width, height); + + _buffer.setSize(width, height, Buffer::kSizeByTextureSize); // we'll use texture size for mouse + _renderer.setDrawWholeBuffer(); // We need to let the renderer know how much to draw + + DEBUG_EXIT_FUNC(); +} + +void Cursor::copyFromArray(const byte *array) { + DEBUG_ENTER_FUNC(); + + if (!_buffer.isAllocated()) { + _buffer.allocate(); + } + + _buffer.copyFromArray(array, _buffer.getSourceWidthInBytes()); // pitch is source width + setDirty(); + + // debug + //PSP_DEBUG_DO(_buffer.print(0xF)); + + DEBUG_EXIT_FUNC(); + +} + +void Cursor::setHotspot(int32 x, int32 y) { + DEBUG_ENTER_FUNC(); + + _hotspotX = x; + _hotspotY = y; + updateRendererOffset(); // Important + + PSP_DEBUG_PRINT("hotspotX[%d], hotspotY[%d]\n", x, y); + DEBUG_EXIT_FUNC(); +} + +// Returns true if change in x or y +bool Cursor::increaseXY(int32 incX, int32 incY) { + DEBUG_ENTER_FUNC(); + + int32 oldX = _x, oldY = _y; + + // adjust for differences in X and Y + adjustXYForScreenSize(incX, incY); + + _x += incX; + _y += incY; + + // Clamp mouse + if (_x < 0) + _x = 0; + if (_y < 0) + _y = 0; + if (_x >= (int)_mouseLimitWidth) + _x = (int)_mouseLimitWidth - 1; + if (_y >= (int)_mouseLimitHeight) + _y = (int)_mouseLimitHeight - 1; + + PSP_DEBUG_PRINT("X[%d], Y[%d]\n", _x, _y); + + if (oldX != _x || oldY != _y) { + updateRendererOffset(); + setDirty(); + DEBUG_EXIT_FUNC(); + return true; + } + + DEBUG_EXIT_FUNC(); + return false; +} + +// Set limits on the movement of the cursor ie. screen size +void Cursor::setLimits(uint32 width, uint32 height) { + #define PSP_SCREEN_WIDTH 480 + #define PSP_SCREEN_HEIGHT 272 + DEBUG_ENTER_FUNC(); + + PSP_DEBUG_PRINT("width[%u], height[%u]\n", width, height); + _mouseLimitWidth = width; + _mouseLimitHeight = height; + + DEBUG_EXIT_FUNC(); +} + +// Adjust X,Y movement for the screen size to keep it consistent +inline void Cursor::adjustXYForScreenSize(int32 &x, int32 &y) { + DEBUG_ENTER_FUNC(); + // We have our speed calibrated for the y axis at 480x272. The idea is to adjust this for other + // resolutions and for x, which is wider. + int32 newX = x, newY = y; + + // adjust width movement to match height (usually around 1.5) + if (_mouseLimitWidth >= _mouseLimitHeight + (_mouseLimitHeight >> 1)) + newX = newX + (newX >> 1); + + if (_mouseLimitWidth >= 600) { // multiply by 2 + newX <<= 1; + newY <<= 1; + } else if (_mouseLimitWidth >= 480) { // multiply by 1.5 + newX = newX + (newX >> 1); + newY = newY + (newY >> 1); + } + + // Divide all movements by 8 + newX >>= 3; + newY >>= 3; + + // Make sure we didn't destroy minimum movement + if (!((x && !newX) || (y && !newY))) { + x = newX; + y = newY; + } + + DEBUG_EXIT_FUNC(); +} + +// This is only called when we have a new screen +void Cursor::setScreenPaletteScummvmPixelFormat(const Graphics::PixelFormat *format) { + DEBUG_ENTER_FUNC(); + + uint32 oldPaletteSize = 0; + if (_screenPalette.isAllocated()) + oldPaletteSize = _screenPalette.getSizeInBytes(); + + PSPPixelFormat::Type bufferType = PSPPixelFormat::Type_Unknown; + PSPPixelFormat::Type paletteType = PSPPixelFormat::Type_Unknown; + bool swapRedBlue = false; + + // Convert Scummvm Pixel Format to PSPPixelFormat + PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType, swapRedBlue); + + if (paletteType == PSPPixelFormat::Type_None) { + //_screenPalette.deallocate(); // leave palette for default CLUT8 + setRendererModePalettized(false); // use 16-bit mechanism + } else { // We have a palette + _screenPalette.setPixelFormats(paletteType, bufferType); + _palette.setPixelFormats(paletteType, bufferType); + setRendererModePalettized(true); // use palettized mechanism + } + + DEBUG_EXIT_FUNC(); +} + +// This is called many many times +void Cursor::setSizeAndScummvmPixelFormat(uint32 width, uint32 height, const Graphics::PixelFormat *format) { + DEBUG_ENTER_FUNC(); + + PSP_DEBUG_PRINT("useCursorPalette[%s]\n", _useCursorPalette ? "true" : "false"); + + uint32 oldBufferSize = 0, oldPaletteSize = 0; + + if (_buffer.isAllocated()) + oldBufferSize = _buffer.getSizeInBytes(); + + if (_palette.isAllocated()) + oldPaletteSize = _palette.getSizeInBytes(); + + setSize(width, height); + + PSPPixelFormat::Type bufferType = PSPPixelFormat::Type_Unknown; + PSPPixelFormat::Type paletteType = PSPPixelFormat::Type_Unknown; + bool swapRedBlue = false; + + PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType, swapRedBlue); + PSP_DEBUG_PRINT("bufferType[%u], paletteType[%u]\n", bufferType, paletteType); + + // Check if we need to set new pixel format + if (_buffer.getPixelFormat() != bufferType) { + PSP_DEBUG_PRINT("new buffer pixel format[%u] is different from [%u]. Setting it.\n", bufferType, _buffer.getPixelFormat()); + _buffer.setPixelFormat(bufferType); + } + + // Check if we need to reallocate + if (_buffer.getSizeInBytes() != oldBufferSize) { + _buffer.allocate(); + PSP_DEBUG_PRINT("reallocating buffer. new size: width[%u], height[%u]\n", width, height); + } + + PSP_DEBUG_PRINT("palette pixel format[%u]\n", paletteType); + + if (paletteType == PSPPixelFormat::Type_None) { + setRendererModePalettized(false); // use palettized mechanism + } else { // We have a palette + _palette.setPixelFormats(paletteType, bufferType); + setRendererModePalettized(true); // use palettized mechanism + } + + // debug + // PSP_DEBUG_DO(_palette.print(10)); + // PSP_DEBUG_DO(_screenPalette.print(10)); + + DEBUG_EXIT_FUNC(); +} + +void Cursor::setXY(int x, int y) { + DEBUG_ENTER_FUNC(); + + _x = x; + _y = y; + updateRendererOffset(); // Very important to let renderer know things changed + setDirty(); + + DEBUG_EXIT_FUNC(); +} + +inline void Cursor::updateRendererOffset() { + DEBUG_ENTER_FUNC(); + _renderer.setOffsetOnScreen(_x - _hotspotX, _y - _hotspotY); + DEBUG_EXIT_FUNC(); +} + +inline void Cursor::setRendererModePalettized(bool palettized) { + if (palettized) { // We have a palette. Use blending + _renderer.setAlphaBlending(true); + _renderer.setAlphaReverse(false); + _renderer.setColorTest(false); + } else { // 16 bits, no palette + _renderer.setAlphaBlending(true); + _renderer.setAlphaReverse(true); // We can't change all alpha values, so just reverse + _renderer.setColorTest(true); // Color test to make our key color transparent + } +} |