aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/psp/cursor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backends/platform/psp/cursor.cpp')
-rw-r--r--backends/platform/psp/cursor.cpp365
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
+ }
+}