Logo Search packages:      
Sourcecode: scummvm version File versions  Download package

cursor.cpp

/* 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/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 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();
            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 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;
      }
}

// 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
      }
}

// 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));
}

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
            _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
      }
}

Generated by  Doxygen 1.6.0   Back to index