mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-09 19:32:11 +00:00
328 lines
9.6 KiB
C++
328 lines
9.6 KiB
C++
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "common/scummsys.h"
|
|
#include "backends/platform/psp/psppixelformat.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);
|
|
}
|
|
|
|
void Cursor::deallocate() {
|
|
DEBUG_ENTER_FUNC();
|
|
|
|
_buffer.deallocate();
|
|
_palette.deallocate();
|
|
_screenPalette.deallocate();
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
void Cursor::setScreenPalette(const byte *colors, uint start, uint num) {
|
|
DEBUG_ENTER_FUNC();
|
|
|
|
if (!_screenPalette.isAllocated()) {
|
|
_screenPalette.allocate();
|
|
}
|
|
|
|
_screenPalette.setPartial(colors, start, num);
|
|
setDirty();
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
// 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 screen resolution
|
|
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();
|
|
return true;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
// 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
|
|
int32 newX = x, newY = y;
|
|
|
|
if (_mouseLimitWidth >= 600) { // multiply by 2
|
|
newX *= 2;
|
|
newY *= 2;
|
|
} else if (_mouseLimitWidth >= 480) { // multiply by 1.5
|
|
newX = newX + (newX / 2);
|
|
newY = newY + (newY / 2);
|
|
}
|
|
}
|
|
|
|
// This is only called when we have a new screen
|
|
void Cursor::setScreenPaletteScummvmPixelFormat(const Graphics::PixelFormat *format) {
|
|
DEBUG_ENTER_FUNC();
|
|
|
|
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
|
|
}
|
|
}
|
|
|
|
// 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;
|
|
|
|
if (_buffer.isAllocated())
|
|
oldBufferSize = _buffer.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 non-palettized mechanism
|
|
if (format) {
|
|
if (format->aBits() == 0)
|
|
_fakeAlpha = true; // we are treating e.g. 555 as 5551
|
|
else
|
|
_fakeAlpha = false; // we have a genuine alpha channel
|
|
}
|
|
} 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));
|
|
}
|
|
|
|
void Cursor::setXY(int x, int y) {
|
|
DEBUG_ENTER_FUNC();
|
|
|
|
_x = x;
|
|
_y = y;
|
|
updateRendererOffset(); // Very important to let renderer know things changed
|
|
setDirty();
|
|
}
|
|
|
|
inline void Cursor::updateRendererOffset() {
|
|
DEBUG_ENTER_FUNC();
|
|
_renderer.setOffsetOnScreen(_x - _hotspotX, _y - _hotspotY);
|
|
}
|
|
|
|
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
|
|
// Color test is an easy way for the hardware to make our keycolor
|
|
// transparent.
|
|
_renderer.setColorTest(true);
|
|
|
|
// Alpha blending is not strictly required, but makes the cursor look
|
|
// much better
|
|
_renderer.setAlphaBlending(true);
|
|
|
|
// Pixel formats without alpha (5650) are considered to have their alpha set.
|
|
// Since pixel formats like 555 are treated as 5551 on PSP, we reverse
|
|
// the alpha format for them so that 0 alpha is 1.
|
|
if (_buffer.getPixelFormat() != PSPPixelFormat::Type_5650 && _fakeAlpha)
|
|
_renderer.setAlphaReverse(true);
|
|
else
|
|
_renderer.setAlphaReverse(false);
|
|
}
|
|
}
|