Ticket #9152: cleanup.3.diff

File cleanup.3.diff, 219.1 KB (added by bluddy, 11 years ago)

Cleanup ver 3

  • configure

     
    16471647# Enable 16bit support only for backends which support it
    16481648#
    16491649case $_backend in
    1650         dreamcast | samsungtv | sdl | wii)
     1650        dreamcast | samsungtv | sdl | wii | psp)
    16511651                if test "$_16bit" = auto ; then
    16521652                        _16bit=yes
    16531653                else
  • backends/platform/psp/psploader.h

     
    135135}
    136136
    137137#endif /* PSPLOADER_H */
    138 
  • backends/platform/psp/input.cpp

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
     22 * $Id: osys_psp.cpp 43618 2009-08-21 22:44:49Z joostp $
     23 *
     24 */
     25
     26// Todo: handle events that should fire because of shift going off
     27// Solution: handle shift on a button-by-button basis, only allowing it when the button is up. Also a inputmap-wide button. At buttonup, shiftstate is inspected per button.
     28 
     29//#define __PSP_DEBUG_FUNCS__   /* Uncomment for debugging the stack */
     30//#define __PSP_DEBUG_PRINT__ /* Uncomment for debug prints */
     31 
     32#include "backends/platform/psp/trace.h"
     33
     34#include "backends/platform/psp/input.h"
     35
     36// Defines for working with PSP buttons
     37#define CHANGED(x)       (_buttonsChanged & (x))
     38#define PRESSED(x)   ((_buttonsChanged & (x)) && (pad.Buttons & (x)))
     39#define UNPRESSED(x) ((_buttonsChanged & (x)) && !(pad.Buttons & (x)))
     40#define DOWN(x)          (pad.Buttons & (x))
     41#define UP(x)            (!(pad.Buttons & (x)))
     42#define PSP_DPAD         (PSP_CTRL_DOWN|PSP_CTRL_UP|PSP_CTRL_LEFT|PSP_CTRL_RIGHT)
     43#define PSP_4BUTTONS (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE | PSP_CTRL_TRIANGLE | PSP_CTRL_SQUARE)
     44#define PSP_TRIGGERS (PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER)
     45
     46#define PAD_CHECK_TIME  53
     47
     48void InputHandler::init() {
     49        sceCtrlSetSamplingCycle(0);     // set sampling to vsync. n = n usecs
     50        sceCtrlSetSamplingMode(1);  // analog
     51}
     52
     53bool InputHandler::getAllInputs(Common::Event &event) {
     54        DEBUG_ENTER_FUNC();
     55       
     56        uint32 time = g_system->getMillis();    // may not be necessary with read
     57        if (time - _lastPadCheckTime < PAD_CHECK_TIME) {
     58                DEBUG_EXIT_FUNC();
     59                return false;
     60        }
     61
     62        _lastPadCheckTime = time;
     63        SceCtrlData pad;
     64
     65        sceCtrlPeekBufferPositive(&pad, 1);     // Peek ignores sleep. Read sleeps thread
     66
     67        bool haveEvent;
     68
     69        memset(&event, 0, sizeof(event));
     70
     71        if (_keyboard->isVisible())
     72                haveEvent = _keyboard->processInput(event, pad);
     73        else
     74                haveEvent = getEvent(event, pad);
     75
     76        if (haveEvent)
     77        {       
     78                PSP_DEBUG_PRINT("Have event[%s]\n", haveEvent ? "true" : "false");
     79                PSP_DEBUG_PRINT("event.type[%d]\n", event.type);
     80        }       
     81
     82        DEBUG_EXIT_FUNC();
     83       
     84        return haveEvent;
     85}
     86
     87bool InputHandler::getEvent(Common::Event &event, SceCtrlData &pad) {
     88        DEBUG_ENTER_FUNC();
     89
     90        _buttonsChanged = pad.Buttons ^ _prevButtons;
     91        bool haveEvent = false;
     92
     93        // Collect events from different sources
     94        haveEvent = getDpadEvent(event, pad);
     95               
     96        if (!haveEvent)
     97                haveEvent = getButtonEvent(event, pad);
     98               
     99        if (!haveEvent)
     100                haveEvent = getNubEvent(event, pad);           
     101
     102        _prevButtons = pad.Buttons;
     103       
     104        DEBUG_EXIT_FUNC();
     105        return haveEvent;
     106}
     107
     108bool InputHandler::getDpadEvent(Common::Event &event, SceCtrlData &pad) {
     109        DEBUG_ENTER_FUNC();
     110       
     111        int newDpadX = 0, newDpadY = 0;
     112        bool haveEvent = false;
     113
     114        if (DOWN(PSP_CTRL_UP)) {
     115                newDpadY++;
     116                if (DOWN(PSP_CTRL_RTRIGGER))    // Shifting causes diagonals
     117                        newDpadX++;
     118        }
     119        if (DOWN(PSP_CTRL_RIGHT)) {
     120                newDpadX++;
     121                if (DOWN(PSP_CTRL_RTRIGGER))
     122                        newDpadY--;
     123        }
     124        if (DOWN(PSP_CTRL_DOWN)) {
     125                newDpadY--;
     126                if (DOWN(PSP_CTRL_RTRIGGER))
     127                        newDpadX--;
     128        }
     129        if (DOWN(PSP_CTRL_LEFT)) {
     130                newDpadX--;
     131                if (DOWN(PSP_CTRL_RTRIGGER))
     132                        newDpadY++;
     133        }
     134       
     135        if (newDpadX != _dpadX || newDpadY != _dpadY) {
     136                if (_dpadX == 0 && _dpadY == 0) {               // We were in the middle so we pressed dpad
     137                        event.type = Common::EVENT_KEYDOWN;
     138                        event.kbd.keycode = translateDpad(newDpadX, newDpadY);
     139                        event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0';        // Get ascii
     140                        _dpadX = newDpadX;
     141                        _dpadY = newDpadY;
     142                }
     143                else if (newDpadX == 0 && newDpadY == 0) {// We're now centered so we unpressed dpad
     144                        event.type = Common::EVENT_KEYUP;
     145                        event.kbd.keycode = translateDpad(_dpadX, _dpadY);
     146                        event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0';
     147                        _dpadX = newDpadX;
     148                        _dpadY = newDpadY;
     149                } else {        // we moved from one pressed dpad direction to another one
     150                        event.type = Common::EVENT_KEYUP;       // first release the last dpad direction
     151                        event.kbd.keycode = translateDpad(_dpadX, _dpadY);
     152                        event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0';
     153                        _dpadX = 0; // so that we'll pick up a new dpad movement the next round
     154                        _dpadY = 0;
     155                }
     156               
     157                PSP_DEBUG_PRINT("Keypad event. DpadX[%d], DpadY[%d]\n", _dpadX, _dpadY);
     158                haveEvent = true;
     159        }
     160
     161        DEBUG_EXIT_FUNC();
     162        return haveEvent;
     163}
     164
     165inline Common::KeyCode InputHandler::translateDpad(int x, int y) {
     166        DEBUG_ENTER_FUNC();
     167        Common::KeyCode key;
     168
     169        if (x == -1) {
     170                if (y == -1)
     171                        key = Common::KEYCODE_KP1;
     172                else if (y == 0)
     173                        key = Common::KEYCODE_KP4;
     174                else /* y == 1 */
     175                        key = Common::KEYCODE_KP7;
     176        } else if (x == 0) {
     177                if (y == -1)
     178                        key = Common::KEYCODE_KP2;
     179                else /* y == 1 */
     180                        key = Common::KEYCODE_KP8;
     181        } else {/* x == 1 */
     182                if (y == -1)
     183                        key = Common::KEYCODE_KP3;
     184                else if (y == 0)
     185                        key = Common::KEYCODE_KP6;
     186                else /* y == 1 */
     187                        key = Common::KEYCODE_KP9;
     188        }
     189
     190        DEBUG_EXIT_FUNC();
     191        return key;
     192}
     193
     194
     195bool InputHandler::getButtonEvent(Common::Event &event, SceCtrlData &pad) {
     196        DEBUG_ENTER_FUNC();
     197        bool haveEvent = false;
     198
     199        if (PRESSED(PSP_CTRL_SELECT))
     200                _keyboard->setVisible(true);
     201
     202        else if (CHANGED(PSP_4BUTTONS | PSP_TRIGGERS | PSP_CTRL_START)) {
     203                if (CHANGED(PSP_CTRL_CROSS)) {
     204                        event.type = DOWN(PSP_CTRL_CROSS) ? Common::EVENT_LBUTTONDOWN : Common::EVENT_LBUTTONUP;
     205                        event.mouse.x = _cursor->getX();        // Could this have to do with SCI enter problem?
     206                        event.mouse.y = _cursor->getY();
     207                        PSP_DEBUG_PRINT("%s\n", event.type == Common::EVENT_LBUTTONDOWN ? "LButtonDown" : "LButtonUp");
     208                } else if (CHANGED(PSP_CTRL_CIRCLE)) {
     209                        event.type = DOWN(PSP_CTRL_CIRCLE) ? Common::EVENT_RBUTTONDOWN : Common::EVENT_RBUTTONUP;
     210                        event.mouse.x = _cursor->getX();
     211                        event.mouse.y = _cursor->getY();
     212                        PSP_DEBUG_PRINT("%s\n", event.type == Common::EVENT_LBUTTONDOWN ? "RButtonDown" : "RButtonUp");
     213                } else {
     214                        //any of the other buttons.
     215                        event.type = _buttonsChanged & pad.Buttons ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP;
     216                        event.kbd.ascii = 0;
     217                        event.kbd.flags = 0;
     218
     219                        if (CHANGED(PSP_CTRL_LTRIGGER)) {
     220                                event.kbd.keycode = Common::KEYCODE_ESCAPE;
     221                                event.kbd.ascii = 27;
     222                        } else if (CHANGED(PSP_CTRL_START)) {
     223                                event.kbd.keycode = Common::KEYCODE_F5;
     224                                event.kbd.ascii = Common::ASCII_F5;
     225                                if (DOWN(PSP_CTRL_RTRIGGER)) {
     226                                        event.kbd.flags |= Common::KBD_CTRL;    // Main menu to allow RTL
     227                                }
     228                        } else if (CHANGED(PSP_CTRL_SQUARE)) {
     229                                event.kbd.keycode = Common::KEYCODE_PERIOD;
     230                                event.kbd.ascii = '.';
     231                        } else if (CHANGED(PSP_CTRL_TRIANGLE)) {
     232                                event.kbd.keycode = Common::KEYCODE_RETURN;
     233                                event.kbd.ascii = '\r';
     234                        } else if (DOWN(PSP_CTRL_RTRIGGER)) {                   // An event
     235                                event.kbd.flags |= Common::KBD_SHIFT;
     236                        }
     237                        PSP_DEBUG_PRINT("Ascii[%d]. Key %s.\n", event.kbd.ascii, event.type == Common::EVENT_KEYDOWN ? "down" : "up" );
     238                }
     239               
     240                haveEvent = true;
     241        }
     242       
     243        DEBUG_EXIT_FUNC();
     244        return haveEvent;
     245}
     246
     247bool InputHandler::getNubEvent(Common::Event &event, SceCtrlData &pad) {
     248        DEBUG_ENTER_FUNC();
     249
     250        bool haveEvent = false;
     251        int32 analogStepX = pad.Lx;             // Goes up to 255.
     252        int32 analogStepY = pad.Ly;
     253
     254        int32 oldX = _cursor->getX();
     255        int32 oldY = _cursor->getY();
     256
     257        analogStepX = modifyNubAxisMotion(analogStepX);
     258        analogStepY = modifyNubAxisMotion(analogStepY);
     259       
     260        if (analogStepX != 0 || analogStepY != 0) {
     261       
     262                PSP_DEBUG_PRINT("raw x[%d], y[%d]\n", analogStepX, analogStepY);
     263               
     264                // If no movement then this has no effect
     265                if (DOWN(PSP_CTRL_RTRIGGER)) {
     266                        // Fine control mode for analog
     267                                if (analogStepX != 0) {
     268                                        if (analogStepX > 0)
     269                                                _cursor->increaseXY(2, 0);
     270                                        else
     271                                                _cursor->increaseXY(-2, 0);
     272                                }
     273
     274                                if (analogStepY != 0) {
     275                                        if (analogStepY > 0)
     276                                                _cursor->increaseXY(0, 2);
     277                                        else
     278                                                _cursor->increaseXY(0, -2);
     279                                }
     280                } else {        // Regular speed movement
     281                        _cursor->increaseXY(analogStepX, 0);
     282                        _cursor->increaseXY(0, analogStepY);
     283                }
     284
     285                int32 newX = _cursor->getX();
     286                int32 newY = _cursor->getY();
     287
     288                if ((oldX != newX) || (oldY != newY)) {
     289                        event.type = Common::EVENT_MOUSEMOVE;
     290                        event.mouse.x = newX;
     291                        event.mouse.y = newY;
     292                        haveEvent = true;
     293                       
     294                        PSP_DEBUG_PRINT("Nub event. X[%d], Y[%d]\n", newX, newY);
     295                }
     296        }
     297        DEBUG_EXIT_FUNC();
     298        return haveEvent;
     299}
     300
     301inline int32 InputHandler::modifyNubAxisMotion(int32 input) {
     302        DEBUG_ENTER_FUNC();
     303        const int MIN_NUB_MOTION = 30;
     304       
     305        input -= 128;   // Center on 0.
     306       
     307        if (input < -MIN_NUB_MOTION - 1)
     308                input += MIN_NUB_MOTION + 1;    // reduce the velocity
     309        else if (input > MIN_NUB_MOTION)
     310                input -= MIN_NUB_MOTION;        // same
     311        else                            // between these points, dampen the response to 0       
     312                input = 0;
     313       
     314       
     315        DEBUG_EXIT_FUNC();
     316        return input;   
     317}
  • backends/platform/psp/display_client.cpp

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
     22 * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
     23 *
     24 */
     25
     26#include <pspgu.h>
     27#include <pspdisplay.h>
     28#include <psputils.h>
     29
     30#include "common/scummsys.h"
     31#include "backends/platform/psp/display_client.h"
     32#include "backends/platform/psp/display_manager.h"
     33#include "backends/platform/psp/memory.h"
     34
     35//#define __PSP_DEBUG_FUNCS__   /* For debugging the stack */
     36//#define __PSP_DEBUG_PRINT__
     37#include "backends/platform/psp/trace.h"
     38
     39#define PSP_BUFFER_WIDTH (512)
     40#define PSP_SCREEN_WIDTH        480
     41#define PSP_SCREEN_HEIGHT       272
     42#define PSP_FRAME_SIZE (PSP_BUFFER_WIDTH * PSP_SCREEN_HEIGHT)
     43
     44DisplayManager *GuRenderer::_displayManager = 0;
     45
     46
     47// class Palette ------------------------------------------------------------
     48//
     49void Palette::clear() {
     50        DEBUG_ENTER_FUNC();
     51
     52        if (_values && _numOfEntries)
     53                memset(_values, 0, getSizeInBytes());
     54               
     55        PSP_DEBUG_PRINT("_values[%p]\n", _values);
     56               
     57        DEBUG_EXIT_FUNC();
     58}
     59
     60// Used to clear the specific keycolor
     61//
     62void Palette::setColorPositionAlpha(uint32 position, bool alpha) {
     63        DEBUG_ENTER_FUNC();
     64       
     65        assert(_values);
     66        assert(position < _numOfEntries);
     67       
     68        PSP_DEBUG_PRINT("position[%d], numofEntries[%u], bpp[%u], values[%p]\n", position, _numOfEntries,
     69                        _pixelFormat.bitsPerPixel, _values);
     70
     71        if (_numOfEntries <= 16)
     72                position &= 0xF;
     73        else if (_numOfEntries <= 256)
     74                position &= 0xFF;
     75       
     76        switch (_pixelFormat.bitsPerPixel) {
     77        case 16: {             
     78                uint16 *shortVal = (uint16 *)&_values[_pixelFormat.pixelsToBytes(position)];
     79                *shortVal = _pixelFormat.setColorAlpha((uint32)*shortVal, alpha ? 255 : 0);
     80                }
     81                break;
     82        case 32: {
     83                uint32 *wordVal = (uint32 *)&_values[_pixelFormat.pixelsToBytes(position)];
     84                *wordVal = _pixelFormat.setColorAlpha((uint32)*wordVal, alpha ? 255 : 0);
     85                }
     86                break;
     87        default:
     88                PSP_ERROR("Incorrect bits per pixel value[%u]\n", _pixelFormat.bitsPerPixel);
     89        }
     90               
     91        DEBUG_EXIT_FUNC();
     92}
     93
     94//      Set some of the palette to color values in array
     95//      By default, ScummVm doesn't support alpha values in palettes
     96void Palette::setPartial(const byte *colors, uint32 start, uint32 num, bool supportsAlpha /* = false */) {
     97        DEBUG_ENTER_FUNC();
     98
     99        assert(_values);
     100        assert(_numOfEntries);
     101       
     102        const byte *src = colors;
     103       
     104        if (start + num > _numOfEntries)        // Check boundary
     105                num = _numOfEntries - start;
     106
     107        if (_pixelFormat.bitsPerPixel == 16) {
     108                uint16 *palette = (uint16 *)_values;
     109                palette += start;
     110               
     111                for (uint32 i = 0; i < num; ++i) {
     112                        byte alphaVal = supportsAlpha ? src[3] : 0xFF;
     113                        *palette = (uint16)_pixelFormat.rgbaToColor(src[0], src[1], src[2], alphaVal);
     114                        src += 4;       
     115                        palette++;
     116                }
     117        }
     118        else if (_pixelFormat.bitsPerPixel == 32) {
     119                uint32 *palette = (uint32 *)_values;
     120                palette += start;
     121               
     122                for (uint32 i = 0; i < num; ++i) {
     123                        byte alphaVal = supportsAlpha ? src[3] : 0xFF;
     124                        *palette = _pixelFormat.rgbaToColor(src[0], src[1], src[2], alphaVal);
     125                        src += 4;       
     126                        palette++;
     127                }
     128        }
     129       
     130        DEBUG_EXIT_FUNC();
     131}
     132
     133// Sets pixel format and number of entries by the buffer's pixel format */
     134void Palette::setPixelFormats(PSPPixelFormat::Type paletteType, PSPPixelFormat::Type bufferType, bool swapRedBlue /* = false */) {
     135        DEBUG_ENTER_FUNC();
     136       
     137        if (paletteType == PSPPixelFormat::Type_Unknown)
     138                PSP_ERROR("Unknown paletteType[%u]\n", paletteType);
     139
     140        switch (bufferType) {
     141        case PSPPixelFormat::Type_Palette_8bit:
     142                _numOfEntries = 256;
     143                break;
     144        case PSPPixelFormat::Type_Palette_4bit:
     145                _numOfEntries = 16;
     146                break;
     147        case PSPPixelFormat::Type_Unknown:
     148        case PSPPixelFormat::Type_None:
     149                PSP_ERROR("Unhandled bufferType[%u]\n", bufferType);
     150                break;
     151        default:                // No palette
     152                _numOfEntries = 0;
     153                break;
     154        }
     155       
     156        _pixelFormat.set(paletteType, swapRedBlue);
     157       
     158        DEBUG_EXIT_FUNC();
     159}
     160
     161bool Palette::allocate() {
     162        DEBUG_ENTER_FUNC();
     163        PSP_DEBUG_PRINT("_numOfEntries[%u]\n", _numOfEntries);
     164        PSP_DEBUG_PRINT("_pixelFormat: format[%u], bpp[%u]\n", _pixelFormat.format, _pixelFormat.bitsPerPixel);
     165
     166        if (_values) {
     167                free (CACHED(_values));
     168                _values = 0;
     169        }
     170
     171        // We allocate on 64bytes to get a cache line, and round up to 64bytes to get the full line
     172        uint32 amountInBytes = getSizeInBytes();
     173        if (amountInBytes < 64)
     174                amountInBytes = 64;
     175        _values = (byte *)memalign(64, amountInBytes);
     176
     177        // Use uncached memory
     178        GuRenderer::cacheInvalidate(_values, amountInBytes);
     179        _values = UNCACHED(_values);
     180       
     181        if (!_values) {
     182                PSP_ERROR("Couldn't allocate palette.\n");
     183                DEBUG_EXIT_FUNC();
     184                return false;
     185        }
     186       
     187        PSP_DEBUG_PRINT("_values[%p]\n", _values);
     188        clear();
     189       
     190        DEBUG_EXIT_FUNC();
     191        return true;
     192}
     193
     194void Palette::deallocate() {
     195        DEBUG_ENTER_FUNC();
     196       
     197        free (CACHED(_values));
     198        _values = 0;
     199        _numOfEntries = 0;
     200       
     201        DEBUG_EXIT_FUNC();
     202}
     203
     204// Copy some of the palette to an array of colors
     205//
     206void Palette::getPartial(byte *colors, uint start, uint num) {
     207        DEBUG_ENTER_FUNC();
     208
     209        assert(_values);
     210        assert(_numOfEntries);
     211       
     212        uint32 r, g, b, a;
     213
     214        if (start + num > _numOfEntries)        // Check boundary
     215                num = _numOfEntries - start;
     216       
     217        if (_pixelFormat.bitsPerPixel == 16) { 
     218                uint16 *palette = (uint16 *)_values;
     219                palette += start;
     220               
     221                for (uint32 i = start; i < start + num; i++) {
     222                        _pixelFormat.colorToRgba(*palette, r, g, b, a);
     223                       
     224                        *colors++ = (byte)r;
     225                        *colors++ = (byte)g;
     226                        *colors++ = (byte)b;
     227                        *colors++ = (byte)a;
     228                        palette++;
     229                }
     230        } else if (_pixelFormat.bitsPerPixel == 32) {   
     231                uint32 *palette = (uint32 *)_values;
     232                palette += start;
     233               
     234                for (uint32 i = start; i < start + num; i++) {
     235                        _pixelFormat.colorToRgba(*palette, r, g, b, a);
     236                       
     237                        *colors++ = (byte)r;
     238                        *colors++ = (byte)g;
     239                        *colors++ = (byte)b;
     240                        *colors++ = (byte)a;
     241                        palette++;
     242                }
     243        }
     244       
     245        DEBUG_EXIT_FUNC();
     246}
     247
     248void Palette::setSingleColorRGBA(uint32 num, byte r, byte g, byte b, byte a) { 
     249        // DEBUG_ENTER_FUNC();
     250        uint16 *shortValues;
     251        uint32 *wordValues;
     252       
     253        assert (_values);
     254        assert (num < _numOfEntries);
     255       
     256        switch (_pixelFormat.bitsPerPixel) {
     257        case 16:
     258                shortValues = (uint16 *)_values;
     259                shortValues[num] = _pixelFormat.rgbaToColor(r, g, b, a);
     260                break;
     261        case 32:
     262                wordValues = (uint32 *)_values;
     263                wordValues[num] = _pixelFormat.rgbaToColor(r, g, b, a);         
     264                break;
     265        default:
     266                PSP_ERROR("Incorrect bitsPerPixel[%d]\n", _pixelFormat.bitsPerPixel);
     267                break;
     268        }
     269        // DEBUG_EXIT_FUNC();
     270}
     271
     272// Print to screen
     273void Palette::print(uint32 numToPrint /* = 0 */) {
     274        if (_numOfEntries > 0) {
     275                assert (_values);
     276               
     277                if (numToPrint > _numOfEntries || numToPrint == 0)
     278                        numToPrint = _numOfEntries;
     279               
     280                PSP_INFO_PRINT("cursor palette:\n");
     281               
     282                for (unsigned int i=0; i<numToPrint; i++) {
     283                        byte *pcolor = &_values[_pixelFormat.pixelsToBytes(i)];
     284                        uint32 color = _pixelFormat.getColorValueAt(pcolor);
     285                       
     286                        PSP_INFO_PRINT("[%u=%x] ", i, color);
     287                }
     288       
     289                PSP_INFO_PRINT("\n");
     290        }
     291}
     292
     293uint32 Palette::getRawColorAt(uint32 position) {
     294        byte *pcolor = &_values[_pixelFormat.pixelsToBytes(position)];
     295        uint32 color = _pixelFormat.getColorValueAt(pcolor);
     296        return color;
     297}
     298
     299uint32 Palette::getRGBAColorAt(uint32 position) {
     300        uint32 color = getRawColorAt(position);
     301        uint32 r, g, b, a;
     302        _pixelFormat.colorToRgba(color, r, g, b, a);
     303        return (a << 24 | b << 16 | g << 8 |  r);
     304}
     305
     306// class Buffer ---------------------------------------------------
     307
     308void Buffer::setPixelFormat(PSPPixelFormat::Type type, bool swapRedBlue) {
     309        if (type == PSPPixelFormat::Type_None ||
     310                type == PSPPixelFormat::Type_Unknown)
     311                PSP_ERROR("Unhandled buffer format[%u]\n", type);
     312               
     313        _pixelFormat.set(type, swapRedBlue);
     314}
     315
     316bool Buffer::hasPalette() {
     317        if (_pixelFormat.format == PSPPixelFormat::Type_Palette_8bit ||
     318                _pixelFormat.format == PSPPixelFormat::Type_Palette_4bit)
     319                return true;
     320
     321        return false;
     322}
     323
     324/* pitch is in bytes */
     325void Buffer::copyFromArray(const byte *buffer, int pitch) {
     326        DEBUG_ENTER_FUNC();
     327       
     328        // We use sourceSize because outside, they won't know what the true size is
     329        copyFromRect(buffer, pitch, 0, 0, _sourceSize.width, _sourceSize.height);
     330       
     331        DEBUG_EXIT_FUNC();
     332}
     333
     334/* pitch is in bytes */
     335void Buffer::copyFromRect(const byte *buf, uint32 pitch, int destX, int destY, uint32 recWidth, uint32 recHeight) {
     336        // Removed silly clipping code
     337        DEBUG_ENTER_FUNC();
     338        assert (_pixels);
     339       
     340        if (recWidth > _sourceSize.width - destX) {
     341                recWidth = _sourceSize.width - destX;
     342        }
     343
     344        if (recHeight > _sourceSize.height - destY) {
     345                recHeight = _sourceSize.height - destY;
     346        }
     347
     348        if (recWidth <= 0 || recHeight <= 0) {
     349                DEBUG_EXIT_FUNC();
     350                return;
     351        }
     352
     353        byte *dst = _pixels + _pixelFormat.pixelsToBytes((destY * _width) + destX);
     354       
     355        uint32 recWidthInBytes = _pixelFormat.pixelsToBytes(recWidth);
     356        uint32 realWidthInBytes = _pixelFormat.pixelsToBytes(_width);
     357
     358        if (pitch == realWidthInBytes && pitch == recWidthInBytes) {
     359                //memcpy(dst, buf, _pixelFormat.pixelsToBytes(recHeight * recWidth));
     360                Copier::copy(dst, buf, _pixelFormat.pixelsToBytes(recHeight * recWidth), &_pixelFormat);
     361        } else {
     362                do {
     363                        //memcpy(dst, buf, recWidthInBytes);
     364                        Copier::copy(dst, buf, recWidthInBytes, &_pixelFormat);
     365                        buf += pitch;
     366                        dst += realWidthInBytes;
     367                } while (--recHeight);
     368        }
     369       
     370        DEBUG_EXIT_FUNC();
     371}
     372
     373/* pitch is in bytes */
     374void Buffer::copyToArray(byte *dst, int pitch) {
     375        DEBUG_ENTER_FUNC();
     376        assert (_pixels);
     377       
     378        uint32 h = _height;
     379        byte *src = _pixels;
     380        uint32 sourceWidthInBytes = _pixelFormat.pixelsToBytes(_sourceSize.width);
     381        uint32 realWidthInBytes = _pixelFormat.pixelsToBytes(_width);
     382
     383        do {
     384                //memcpy(dst, src, sourceWidthInBytes);
     385                Copier::copy(dst, src, sourceWidthInBytes, &_pixelFormat);
     386                src += realWidthInBytes;
     387                dst += pitch;
     388        } while (--h);
     389       
     390        DEBUG_EXIT_FUNC();
     391}
     392
     393/* We can size the buffer either by texture size (multiple of 2^n) or source size. The GU can
     394        really handle both, but is supposed to get only 2^n size buffers */
     395void Buffer::setSize(uint32 width, uint32 height, HowToSize textureOrSource/*=kSizeByTextureSize*/) {
     396        DEBUG_ENTER_FUNC();
     397        PSP_DEBUG_PRINT("w[%u], h[%u], %s\n", width, height, textureOrSource ? "size by source" : "size by texture");
     398       
     399        _sourceSize.width = width;
     400        _sourceSize.height = height;
     401
     402        _textureSize.width = scaleUpToPowerOfTwo(width);
     403        _textureSize.height = scaleUpToPowerOfTwo(height);
     404
     405        if (textureOrSource == kSizeByTextureSize) {
     406                _width = _textureSize.width;
     407                _height = _textureSize.height;
     408        }
     409        else { /* kSizeBySourceSize */
     410                _width = _sourceSize.width;
     411                _height = _sourceSize.height;
     412        }
     413       
     414        DEBUG_EXIT_FUNC();
     415}
     416
     417/* Scale a dimension (width/height) up to power of 2 for the texture */
     418uint32 Buffer::scaleUpToPowerOfTwo(uint32 size) {
     419       
     420        uint32 textureDimension = 0;
     421        if (size <= 16)
     422                textureDimension = 16;
     423        else if (size <= 32)
     424                textureDimension = 32;
     425        else if (size <= 64)
     426                textureDimension = 64;
     427        else if (size <= 128)
     428                textureDimension = 128;
     429        else if (size <= 256)
     430                textureDimension = 256;
     431        else
     432                textureDimension = 512;
     433       
     434        PSP_DEBUG_PRINT("power of 2 = %u\n", textureDimension);
     435
     436        return textureDimension;
     437}
     438
     439bool Buffer::allocate(bool inVram/*=false*/) {
     440        DEBUG_ENTER_FUNC();
     441       
     442        PSP_DEBUG_PRINT("_width[%u], _height[%u]\n", _width, _height);
     443        PSP_DEBUG_PRINT("_pixelFormat: format[%u], bpp[%u]\n", _pixelFormat.format, _pixelFormat.bitsPerPixel);
     444
     445        if (_pixels) {
     446                if (VramAllocator::isAddressInVram(_pixels))    // Check if in VRAM
     447                        VramAllocator::instance().deallocate(_pixels);
     448                else    // not in VRAM
     449                        free (CACHED(_pixels));
     450                       
     451                _pixels = 0;   
     452        }
     453
     454        uint32 size = getSizeInBytes();
     455       
     456        if (inVram) {
     457                _pixels = (byte *)VramAllocator::instance().allocate(size);
     458        }
     459       
     460        if (!_pixels) { // Either we are not in vram or we didn't manage to allocate in vram
     461                // Align to 64 bytes. All normal buffer sizes are multiples of 64 anyway
     462                _pixels = (byte *)memalign(64, size);
     463        }
     464
     465        if (!_pixels) {
     466                PSP_ERROR("couldn't allocate buffer.\n");
     467                DEBUG_EXIT_FUNC();
     468                return false;
     469        }
     470       
     471        // Use uncached memory
     472        GuRenderer::cacheInvalidate(_pixels, size);
     473        _pixels = UNCACHED(_pixels);
     474
     475        clear();
     476        DEBUG_EXIT_FUNC();
     477        return true;
     478}
     479
     480void Buffer::deallocate() {
     481        DEBUG_ENTER_FUNC();
     482
     483        if (!_pixels)
     484                return;
     485               
     486        if (VramAllocator::isAddressInVram(_pixels))    // Check if in VRAM
     487                VramAllocator::instance().deallocate(_pixels);
     488        else
     489                free(CACHED(_pixels));
     490               
     491        _pixels = 0;
     492       
     493        DEBUG_EXIT_FUNC();
     494}
     495
     496void Buffer::clear() {
     497        DEBUG_ENTER_FUNC();
     498       
     499        if (_pixels)
     500                memset(_pixels, 0, getSizeInBytes());
     501               
     502        DEBUG_EXIT_FUNC();
     503}
     504
     505/* Convert 4 bit images to match weird PSP format */
     506void Buffer::flipNibbles() {
     507        DEBUG_ENTER_FUNC();
     508       
     509        if (_pixelFormat.bitsPerPixel != 4)
     510                return;
     511               
     512        assert(_pixels);       
     513       
     514        uint32 *dest = (uint32 *)_pixels;
     515
     516        for (uint32 i = 0; i < getSourceHeight(); i++) {
     517                for (uint32 j = 0; j < (getWidth() >> 3); j++) {        // /8 because we do it in 32bit chunks
     518                        uint32 val = *dest;
     519                        *dest++ = ((val >> 4) & 0x0F0F0F0F) | ((val << 4) & 0xF0F0F0F0);
     520                }
     521        }
     522
     523        DEBUG_EXIT_FUNC();
     524}
     525
     526// Print buffer contents to screen (only source size is printed out)
     527void Buffer::print(uint32 mask, uint32 numToPrint /*=0*/) {
     528        assert(_pixels);
     529       
     530        if (numToPrint > _sourceSize.width * _sourceSize.height || numToPrint == 0)
     531                numToPrint = _sourceSize.width * _sourceSize.height;
     532       
     533        PSP_INFO_PRINT("buffer: \n");
     534        PSP_INFO_PRINT("width[%u], height[%u]\n\n", _sourceSize.width, _sourceSize.height);
     535       
     536        for (unsigned int i=0; i < _sourceSize.height; i++) {
     537                for (unsigned int j=0; j < _sourceSize.width; j++) {
     538                        if (numToPrint <= 0)    // check if done
     539                                break;
     540                               
     541                        byte *pcolor = &_pixels[_pixelFormat.pixelsToBytes((i * _width) + j)];
     542                        uint32 color = _pixelFormat.getColorValueAt(pcolor);
     543 
     544                        //if (color != 0) PSP_INFO_PRINT("[%x] ", color);
     545                        PSP_INFO_PRINT("[%x] ", mask & color);
     546                               
     547                        numToPrint--;
     548                }
     549                PSP_INFO_PRINT("\n");
     550        }
     551        PSP_INFO_PRINT("\n");
     552}
     553
     554// class GuRenderer -------------------------------------------------
     555//#define __PSP_DEBUG_FUNCS__   /* For debugging the stack */
     556//#define __PSP_DEBUG_PRINT__
     557
     558#include "backends/platform/psp/trace.h"
     559
     560
     561void GuRenderer::render() {
     562        DEBUG_ENTER_FUNC();
     563        PSP_DEBUG_PRINT("Buffer[%p] Palette[%p]\n", _buffer->getPixels(), _palette->getRawValues());
     564
     565        setMaxTextureOffsetByIndex(0, 0);
     566       
     567        guProgramDrawBehavior();
     568       
     569        if (_buffer->hasPalette())
     570                guLoadPalette();
     571       
     572        guProgramTextureFormat();
     573        guLoadTexture();
     574       
     575        Vertex *vertices = guGetVertices();     
     576        fillVertices(vertices);
     577
     578        guDrawVertices(vertices);
     579
     580        if (_buffer->getSourceWidth() > 512) {
     581                setMaxTextureOffsetByIndex(1, 0);
     582
     583                guLoadTexture();
     584               
     585                vertices = guGetVertices();
     586                fillVertices(vertices);
     587
     588                guDrawVertices(vertices);
     589        }
     590       
     591        DEBUG_EXIT_FUNC();
     592}
     593
     594INLINE void GuRenderer::setMaxTextureOffsetByIndex(uint32 x, uint32 y) {
     595        DEBUG_ENTER_FUNC();
     596        const uint32 maxTextureSizeShift = 9; /* corresponds to 512 = max texture size*/
     597
     598        _maxTextureOffset.x = x << maxTextureSizeShift; /* x times 512 */
     599        _maxTextureOffset.y = y << maxTextureSizeShift; /* y times 512 */
     600        DEBUG_EXIT_FUNC();
     601}
     602
     603INLINE void GuRenderer::guProgramDrawBehavior() {
     604        DEBUG_ENTER_FUNC();
     605        PSP_DEBUG_PRINT("blending[%s] colorTest[%s] reverseAlpha[%s] keyColor[%u]\n", _blending ? "on" : "off", _colorTest ? "on" : "off", _alphaReverse ? "on" : "off", _keyColor);
     606       
     607        if (_blending) {
     608                sceGuEnable(GU_BLEND);
     609
     610                if (_alphaReverse)      // Reverse the alpha value (0 is 1)
     611                        sceGuBlendFunc(GU_ADD, GU_ONE_MINUS_SRC_ALPHA, GU_SRC_ALPHA, 0, 0);
     612                else    // Normal alpha values
     613                        sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);             
     614
     615        } else
     616                sceGuDisable(GU_BLEND);
     617       
     618        if (_colorTest) {
     619                sceGuEnable(GU_COLOR_TEST);
     620                sceGuColorFunc(GU_NOTEQUAL, _keyColor, 0x00ffffff);
     621        } else
     622                sceGuDisable(GU_COLOR_TEST);
     623
     624        DEBUG_EXIT_FUNC();
     625}
     626
     627INLINE void GuRenderer::guLoadPalette() {
     628        DEBUG_ENTER_FUNC();
     629       
     630        uint32 mask;
     631       
     632        if (_buffer->getBitsPerPixel() == 4)
     633                mask = 0x0F;
     634        else if (_buffer->getBitsPerPixel() == 8)
     635                mask = 0xFF;
     636        else
     637                assert(0);      /* error */
     638
     639        PSP_DEBUG_PRINT("numOfEntries[%d]\n", _palette->getNumOfEntries());
     640        PSP_DEBUG_PRINT("bpp[%d], pixelformat[%d], mask[%x]\n", _buffer->getBitsPerPixel(), _palette->getPixelFormat(), mask);
     641               
     642        sceGuClutMode(convertToGuPixelFormat(_palette->getPixelFormat()), 0, mask, 0);
     643        sceGuClutLoad(_palette->getNumOfEntries() >> 3, _palette->getRawValues());
     644       
     645        DEBUG_EXIT_FUNC();
     646}
     647
     648INLINE void GuRenderer::guProgramTextureFormat() {
     649        DEBUG_ENTER_FUNC();
     650        PSP_DEBUG_PRINT("pixelFormat[%d]\n", _buffer->getPixelFormat());
     651       
     652        sceGuTexMode(convertToGuPixelFormat(_buffer->getPixelFormat()), 0, 0, 0);
     653        DEBUG_EXIT_FUNC();
     654}
     655
     656INLINE uint32 GuRenderer::convertToGuPixelFormat(PSPPixelFormat::Type format) {
     657                DEBUG_ENTER_FUNC();
     658               
     659                uint32 guFormat = 0;
     660               
     661                switch (format) {
     662                case PSPPixelFormat::Type_4444:
     663                        guFormat = GU_PSM_4444;
     664                        break;
     665                case PSPPixelFormat::Type_5551:
     666                        guFormat = GU_PSM_5551;
     667                        break;
     668                case PSPPixelFormat::Type_5650:
     669                        guFormat = GU_PSM_5650;
     670                        break;
     671                case PSPPixelFormat::Type_8888:
     672                        guFormat = GU_PSM_8888;
     673                        break;
     674                case PSPPixelFormat::Type_Palette_8bit:
     675                        guFormat = GU_PSM_T8;
     676                        break;
     677                case PSPPixelFormat::Type_Palette_4bit:
     678                        guFormat = GU_PSM_T4;
     679                        break;
     680                default:
     681                        break;                 
     682        }
     683       
     684        PSP_DEBUG_PRINT("Pixelformat[%d], guFormat[%d]\n", format, guFormat);
     685       
     686        DEBUG_EXIT_FUNC();
     687        return guFormat;
     688       
     689}
     690
     691INLINE void GuRenderer::guLoadTexture() {
     692        DEBUG_ENTER_FUNC();
     693       
     694        sceGuTexImage(0, _buffer->getTextureWidth(), _buffer->getTextureHeight(), _buffer->getWidth(), _buffer->getPixels() + _buffer->_pixelFormat.pixelsToBytes(_maxTextureOffset.x));
     695       
     696        DEBUG_EXIT_FUNC();
     697}
     698
     699INLINE Vertex *GuRenderer::guGetVertices() {
     700        DEBUG_ENTER_FUNC();
     701       
     702        Vertex *ret = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
     703       
     704        DEBUG_EXIT_FUNC();
     705        return ret;
     706}
     707
     708// Fills the vertices. Most of the logic is here.
     709void GuRenderer::fillVertices(Vertex *vertices) {
     710        DEBUG_ENTER_FUNC();
     711       
     712        uint32 outputWidth = _displayManager->getOutputWidth();
     713        uint32 outputHeight = _displayManager->getOutputHeight();
     714
     715        float textureStartX, textureStartY, textureEndX, textureEndY;
     716       
     717        // Texture adjustments for eliminating half-pixel artifacts from scaling
     718        // Not necessary if we don't scale
     719        float textureAdjustment = 0.0f;
     720        if (_useGlobalScaler &&
     721           (_displayManager->getScaleX() != 1.0f || _displayManager->getScaleX() != 1.0f))
     722                        textureAdjustment = 0.5f;
     723       
     724        textureStartX = textureAdjustment + _offsetInBuffer.x; //debug
     725        textureStartY = textureAdjustment + _offsetInBuffer.y;
     726        // We subtract maxTextureOffset because our shifted texture starts at 512 and will go to 640
     727        textureEndX = _offsetInBuffer.x + _drawSize.width - textureAdjustment - _maxTextureOffset.x;
     728        textureEndY = _offsetInBuffer.y + _drawSize.height - textureAdjustment;
     729
     730        // For scaling to the final image size, calculate the gaps on both sides
     731        uint32 gapX = _useGlobalScaler ? (PSP_SCREEN_WIDTH - outputWidth) >> 1 : 0;
     732        uint32 gapY = _useGlobalScaler ? (PSP_SCREEN_HEIGHT - outputHeight) >> 1 : 0;
     733       
     734        float imageStartX, imageStartY, imageEndX, imageEndY;
     735
     736        imageStartX = gapX + ( scaleSourceToOutputX(_maxTextureOffset.x) );
     737        imageStartY = gapY;
     738
     739        imageStartX += scaleSourceToOutputX(_offsetOnScreen.x);
     740        imageStartY += scaleSourceToOutputY(_offsetOnScreen.y);
     741       
     742        if (_fullScreen) { // shortcut
     743                imageEndX = PSP_SCREEN_WIDTH - gapX;
     744                imageEndY = PSP_SCREEN_HEIGHT - gapY;
     745        } else { /* !fullScreen */
     746                imageEndX = imageStartX + scaleSourceToOutputX(_drawSize.width);
     747                imageEndY = imageStartY + scaleSourceToOutputY(_drawSize.height);
     748        }
     749
     750        vertices[0].u = textureStartX;
     751        vertices[0].v = textureStartY;
     752        vertices[1].u = textureEndX;
     753        vertices[1].v = textureEndY;
     754       
     755        vertices[0].x = imageStartX;
     756        vertices[0].y = imageStartY;
     757        vertices[0].z = 0;
     758        vertices[1].x = imageEndX;
     759        vertices[1].y = imageEndY;
     760        vertices[1].z = 0;
     761       
     762        PSP_DEBUG_PRINT("TextureStart: X[%f] Y[%f] TextureEnd: X[%.1f] Y[%.1f]\n", textureStartX, textureStartY, textureEndX, textureEndY);
     763        PSP_DEBUG_PRINT("ImageStart:   X[%f] Y[%f] ImageEnd:   X[%.1f] Y[%.1f]\n", imageStartX, imageStartY, imageEndX, imageEndY);
     764       
     765        DEBUG_EXIT_FUNC();
     766}
     767
     768/* Scale the input X offset to appear in proper position on the screen */
     769INLINE float GuRenderer::scaleSourceToOutputX(float offset) {
     770        float result;
     771       
     772        if (!_useGlobalScaler)
     773                result = offset;
     774        else if (!offset)
     775                result = 0.0f; 
     776        else
     777                result = offset * _displayManager->getScaleX();
     778       
     779        return result;
     780}
     781
     782/* Scale the input Y offset to appear in proper position on the screen */
     783INLINE float GuRenderer::scaleSourceToOutputY(float offset) {
     784        float result;
     785       
     786        if (!_useGlobalScaler)
     787                result = offset;
     788        else if (!offset)
     789                result = 0.0f;
     790        else
     791                result = offset * _displayManager->getScaleY();
     792               
     793        return result;
     794}
     795
     796INLINE void GuRenderer::guDrawVertices(Vertex *vertices) {
     797        DEBUG_ENTER_FUNC();
     798       
     799        sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
     800        DEBUG_EXIT_FUNC();
     801}
     802
     803void GuRenderer::cacheInvalidate(void *pointer, uint32 size) {
     804        sceKernelDcacheWritebackInvalidateRange(pointer, size);
     805}
  • backends/platform/psp/trace.h

    +
     
    2929
    3030#include <stdio.h>
    3131#include <psptypes.h>
    32 #include <pspkernel.h>
    3332#include <stdarg.h>
    34 #include <pspdebug.h>
    3533
    3634// Use these defines for debugging
    3735
    38 //#define __PSP_DEBUG__
    39 //#define __PSP_DEBUG_SUSPEND__
     36//#define __PSP_PRINT_TO_FILE__
     37//#define __PSP_PRINT_TO_FILE_AND_SCREEN__
     38//#define __PSP_DEBUG_FUNCS__   /* can put this locally too */
     39//#define __PSP_DEBUG_PRINT__
    4040
    41 void PSPDebugTrace (const char *filename, const char *format, ...);
    42 void PSPDebugTrace (const char *format, ...);
     41void PSPDebugTrace (bool alsoToScreen, const char *format, ...);
    4342
    44 #ifdef __PSP_DEBUG_SUSPEND__
    45 #define PSPDebugSuspend(format,...)             PSPDebugTrace(format, ## __VA_ARGS__)
    46 #else
    47 #define PSPDegbugSuspend(x)
    48 #define PSPDebugSuspend(format,...)
    49 #endif /* __PSP_DEBUG_SUSPEND__ */
     43#ifndef TRACE_C
     44extern int psp_debug_indent;
     45#endif
    5046
     47#endif /* TRACE_H */
    5148
    52 #endif // TRACE_H
     49// From here on, we allow multiple definitions
     50#undef __PSP_PRINT__
     51#undef PSP_ERROR
     52#undef __PSP_INDENT__
     53#undef PSP_INFO_PRINT
     54#undef PSP_INFO_PRINT_INDENT
     55#undef PSP_DEBUG_PRINT
     56#undef PSP_DEBUG_PRINT_FUNC
     57#undef PSP_DEBUG_PRINT_SAMELN
     58#undef PSP_DEBUG_DO
     59#undef DEBUG_ENTER_FUNC
     60#undef DEBUG_EXIT_FUNC
     61#undef INLINE
    5362
     63/* Choose to print to file/screen/both */
     64#ifdef __PSP_PRINT_TO_FILE__
     65        #define __PSP_PRINT__(format,...)                       PSPDebugTrace(false, format, ## __VA_ARGS__)
     66#elif defined __PSP_PRINT_TO_FILE_AND_SCREEN__
     67        #define __PSP_PRINT__(format,...)                       PSPDebugTrace(true, format, ## __VA_ARGS__)
     68#else /* default - print to screen */
     69        #define __PSP_PRINT__(format,...)                       fprintf(stderr, format, ## __VA_ARGS__)
     70#endif /* PSP_PRINT_TO_FILE/SCREEN */
     71       
     72/* Error function */
     73#define PSP_ERROR(format,...)                                   __PSP_PRINT__("Error in %s: " format, __PRETTY_FUNCTION__, ## __VA_ARGS__)
     74
     75/* Do the indent */
     76#define __PSP_INDENT__                                                  for(int _i=psp_debug_indent; _i>0; _i--) \
     77                                                                                                        __PSP_PRINT__( "   ")
     78
     79/* always print */
     80#define PSP_INFO_PRINT(format,...)                              __PSP_PRINT__(format, ## __VA_ARGS__)
     81/* always print, with indent */
     82#define PSP_INFO_PRINT_INDENT(format,...)               { __PSP_INDENT__; \
     83                                                                                                __PSP_PRINT__(format, ## __VA_ARGS__); }
     84
     85#ifdef __PSP_DEBUG_PRINT__
     86        /* printf with indents */
     87        #define PSP_DEBUG_PRINT_SAMELN(format,...)      __PSP_PRINT__(format, ## __VA_ARGS__)
     88        #define PSP_DEBUG_PRINT(format,...)                     { __PSP_INDENT__; \
     89                                                                                                __PSP_PRINT__(format, ## __VA_ARGS__); }
     90        #define PSP_DEBUG_PRINT_FUNC(format,...)        { __PSP_INDENT__; \
     91                                                                                                __PSP_PRINT__("In %s: " format, __PRETTY_FUNCTION__, ## __VA_ARGS__); }
     92        #define PSP_DEBUG_DO(x)                                         (x)                                             
     93
     94#else   /* no debug print */
     95        #define PSP_DEBUG_PRINT_SAMELN(format,...)
     96        #define PSP_DEBUG_PRINT(format,...)     
     97        #define PSP_DEBUG_PRINT_FUNC(format,...)
     98        #define PSP_DEBUG_DO(x)
     99#endif /* __PSP_DEBUG_PRINT__ */
     100
     101/* Debugging function calls */
     102#ifdef __PSP_DEBUG_FUNCS__
     103        #define DEBUG_ENTER_FUNC()                                      PSP_INFO_PRINT_INDENT("++ %s\n", __PRETTY_FUNCTION__); \
     104                                                                                                psp_debug_indent++
     105                                                       
     106        #define DEBUG_EXIT_FUNC()                                       psp_debug_indent--; \
     107                                                                                                if (psp_debug_indent < 0) PSP_ERROR("debug indent < 0\n"); \
     108                                                                                                PSP_INFO_PRINT_INDENT("-- %s\n", __PRETTY_FUNCTION__)
     109
     110        #define INLINE                  /* don't want to inline so we get function names properly */
     111                                                       
     112#else /* Don't debug function calls */
     113        #define DEBUG_ENTER_FUNC()
     114        #define DEBUG_EXIT_FUNC()
     115        #define INLINE                                          inline
     116#endif /* __PSP_DEBUG_FUNCS__ */
     117
     118// Undef the main defines for next time
     119#undef __PSP_PRINT_TO_FILE__
     120#undef __PSP_PRINT_TO_FILE_AND_SCREEN__
     121#undef __PSP_DEBUG_FUNCS__
     122#undef __PSP_DEBUG_PRINT__
  • backends/platform/psp/display_manager.h

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
     22 * $Id: osys_psp.cpp 47541 2010-01-25 01:39:44Z lordhoto $
     23 *
     24 */
     25
     26#ifndef PSP_DISPLAY_MAN_H
     27#define PSP_DISPLAY_MAN_H
     28
     29/**
     30 *      Class used only by DisplayManager to start/stop GU rendering
     31 */
     32class MasterGuRenderer {
     33public:
     34        MasterGuRenderer() : _lastRenderTime(0) {}
     35        void guInit();
     36        void guPreRender();
     37        void guPostRender();
     38        void guShutDown();
     39private:
     40        static uint32 _displayList[];
     41        uint32 _lastRenderTime;                                 // For measuring rendering
     42        void guProgramDisplayBufferSizes();
     43};
     44
     45class Screen;
     46class Overlay;
     47class Cursor;
     48class PSPKeyboard;
     49
     50/**
     51 *      Class that manages all display clients
     52 */
     53class DisplayManager {
     54public:
     55        enum GraphicsModeID {                   ///> Possible output formats onscreen
     56                CENTERED_320X200,
     57                CENTERED_435X272,
     58                STRETCHED_480X272,
     59                CENTERED_362X272
     60        };
     61        DisplayManager() : _screen(0), _cursor(0), _overlay(0), _keyboard(0), _lastUpdateTime(0), _graphicsMode(0) {}
     62        ~DisplayManager();
     63       
     64        void init();
     65        void renderAll();
     66        bool setGraphicsMode(int mode);
     67        bool setGraphicsMode(const char *name);
     68        int getGraphicsMode() const { return _graphicsMode; }
     69    uint32 getDefaultGraphicsMode() const { return STRETCHED_480X272; }
     70        const OSystem::GraphicsMode* getSupportedGraphicsModes() const { return _supportedModes; }
     71
     72        // Setters
     73        void setScreen(Screen *screen) { _screen = screen; }
     74        void setCursor(Cursor *cursor) { _cursor = cursor; }
     75        void setOverlay(Overlay *overlay) { _overlay = overlay; }
     76        void setKeyboard(PSPKeyboard *keyboard) { _keyboard = keyboard; }
     77        void setSizeAndPixelFormat(uint width, uint height, const Graphics::PixelFormat *format);
     78
     79        // Getters
     80        float getScaleX() { return _displayParams.scaleX; }
     81        float getScaleY() { return _displayParams.scaleY; }
     82        uint32 getOutputWidth() { return _displayParams.screenOutput.width; }
     83        uint32 getOutputHeight() { return _displayParams.screenOutput.height; }
     84        uint32 getOutputBitsPerPixel() { return _displayParams.outputBitsPerPixel; }
     85        Common::List<Graphics::PixelFormat> getSupportedPixelFormats();
     86
     87private:
     88        struct GlobalDisplayParams {
     89                Dimensions screenOutput;
     90                Dimensions screenSource;
     91                float scaleX;
     92                float scaleY;
     93                uint32 outputBitsPerPixel;              // How many bits end up on-screen
     94                GlobalDisplayParams() : scaleX(0.0f), scaleY(0.0f), outputBitsPerPixel(0) {}
     95        };
     96
     97        // Pointers to DisplayClients
     98        Screen *_screen;
     99        Cursor *_cursor;
     100        Overlay *_overlay;
     101        PSPKeyboard *_keyboard;
     102       
     103        MasterGuRenderer _masterGuRenderer;
     104        uint32 _lastUpdateTime;                                 // For limiting FPS
     105        int _graphicsMode;
     106        GlobalDisplayParams _displayParams;
     107        static const OSystem::GraphicsMode _supportedModes[];
     108       
     109        void calculateScaleParams();    // calculates scaling factor
     110        bool isTimeToUpdate();                  // should we update the screen now     
     111};
     112
     113
     114#endif /* PSP_DISPLAY_MAN_H */
  • backends/platform/psp/psp_main.cpp

     
    2626#define USERSPACE_ONLY  //don't use kernel mode features
    2727
    2828#ifndef USERSPACE_ONLY
    29 #include <pspkernel.h>
    30 #include <pspdebug.h>
     29        #include <pspkernel.h>
     30        #include <pspdebug.h>
     31#else
     32        #include <pspuser.h>
    3133#endif
    3234
    3335#include <psppower.h>
     
    118120        cbid = sceKernelCreateCallback("Power Callback", (SceKernelCallbackFunction)power_callback, 0);
    119121        if (cbid >= 0) {
    120122                if (scePowerRegisterCallback(-1, cbid) < 0) {
    121                         PSPDebugTrace("SetupCallbacks(): Couldn't register callback for power_callback\n");
     123                        PSP_ERROR("Couldn't register callback for power_callback\n");
    122124                }
    123125        } else {
    124                 PSPDebugTrace("SetupCallbacks(): Couldn't create a callback for power_callback\n");
     126                PSP_ERROR("Couldn't create a callback for power_callback\n");
    125127        }
    126128
    127129        sceKernelSleepThreadCB();
     
    167169
    168170        return res;
    169171}
    170 
  • backends/platform/psp/memory.cpp

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
     22 * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
     23 *
     24 */
     25
     26#include "common/scummsys.h"
     27#include "common/singleton.h"
     28#include "common/list.h"
     29#include "backends/platform/psp/psppixelformat.h"
     30#include "backends/platform/psp/memory.h"
     31 
     32// Class Copier --------------------------------------------------------------------------
     33//#define __PSP_DEBUG_FUNCS__   /* For debugging the stack */
     34//#define __PSP_DEBUG_PRINT__
     35
     36#include "backends/platform/psp/trace.h"
     37
     38void Copier::copy(byte *dst, const byte *src, uint32 bytes, PSPPixelFormat *format /* = NULL */) {
     39        DEBUG_ENTER_FUNC();
     40       
     41        uint32 prefixDst = (((uint32)dst) & 0x3);
     42        prefixDst = prefixDst ? 4 - prefixDst : 0;      // prefix only if we have address % 4 != 0
     43        uint32 prefixSrc = (((uint32)src) & 0x3);
     44        prefixSrc = prefixSrc ? 4 - prefixSrc : 0;  // prefix only if we have address % 4 != 0
     45        uint32 *dst32, *src32;
     46        bool swapRB = format ? format->swapRB : false;  // take swap value from pixelformat if it's given
     47#ifdef __PSP_DEBUG_PRINT__
     48        uint32 debugBytes = bytes;
     49        const byte *debugDst = dst, *debugSrc = src;
     50#endif 
     51        uint32 words, remainingBytes;
     52       
     53        //PSP_DEBUG_PRINT("dst[%p], src[%p], bytes[%d], swap[%s], prefixDst[%u], prefixSrc[%u]\n", dst, src, bytes, swapRB ? "true" : "false", prefixDst, prefixSrc);
     54       
     55        if (prefixDst || prefixSrc) {                   // we're not aligned to word boundaries
     56                if (prefixDst != prefixSrc) {           // worst case: we can never be aligned. this mode is highly inefficient. try to get engines not to use this mode too much
     57                        PSP_DEBUG_PRINT("misaligned copy of %u bytes from %p to %p\n", bytes, src, dst);
     58                        if ((prefixDst & 1) || (prefixSrc & 1))
     59                                copy8(dst, src, bytes); // no swap is possible on 8 bit
     60                        else
     61                                copy16((uint16 *)dst, (uint16 *)src, bytes, format);
     62                               
     63                        goto test;     
     64                }
     65               
     66                // Do the prefix: the part to get us aligned
     67                if (prefixDst & 1) {                    // byte
     68                        copy8(dst, src, prefixDst);     // no swap available
     69                } else {                                                // short
     70                        copy16((uint16 *)dst, (uint16 *)src, prefixDst, format);
     71                }
     72                if (bytes > prefixDst)  // check that we can afford to subtract from bytes
     73                        bytes -= prefixDst;
     74                else {
     75                        DEBUG_EXIT_FUNC();     
     76                        return;
     77                }
     78                dst32 = (uint32 *)(dst + prefixDst);
     79                src32 = (uint32 *)(src + prefixSrc);
     80        } else { // We're aligned to word boundaries
     81                dst32 = (uint32 *)dst;
     82                src32 = (uint32 *)src;
     83        }       
     84       
     85        words = bytes >> 2;
     86        remainingBytes = bytes & 0x3;
     87       
     88        if (swapRB) {   // need to swap
     89                for (; words > 0; words--) {
     90                        *dst32 = format->swapRedBlue32(*src32);
     91                        dst32++;
     92                        src32++;
     93                }
     94        } else { // no swapping
     95                for (; words > 0; words--) {
     96                        *dst32 = *src32;
     97                        dst32++;
     98                        src32++;
     99                }
     100        }
     101
     102        // Do any remaining bytes
     103        if (remainingBytes) {
     104                if (remainingBytes & 1) // we have bytes left
     105                        copy8((byte *)dst32, (byte *)src32, remainingBytes);
     106                else // 16bits left
     107                        copy16((uint16*)dst32, (uint16 *)src32, remainingBytes, format);
     108        }
     109
     110test:   
     111        // debug
     112#ifdef __PSP_DEBUG_PRINT__
     113        bool mismatch = false;
     114
     115        for (uint32 i=0; i<debugBytes; i++) {
     116                if (debugDst[i] != debugSrc[i]) {
     117                        if (mismatch == false) {
     118                                PSP_DEBUG_PRINT_SAMELN("mismatch in copy:\n");
     119                                PSP_DEBUG_PRINT("dst[%p], src[%p], bytes[%u], swap[%s], prefixDst[%u], prefixSrc[%u]\n", debugDst, debugSrc, debugBytes, swapRB ? "true" : "false", prefixDst, prefixSrc);
     120                                mismatch = true;
     121                        }
     122                        PSP_DEBUG_PRINT_SAMELN("%x!=%x ", debugSrc[i], debugDst[i]);
     123                }
     124        }
     125        if (mismatch)
     126                PSP_DEBUG_PRINT("\n");
     127#endif
     128
     129        DEBUG_EXIT_FUNC();
     130}
     131
     132inline void Copier::copy8(byte *dst, const byte *src, uint32 bytes) {
     133        for (; bytes > 0; bytes--) {
     134                *dst = *src;
     135                dst++;
     136                src++;
     137        }       
     138}
     139
     140inline void Copier::copy16(uint16 *dst, const uint16 *src, uint32 bytes, PSPPixelFormat *format /* = NULL */) {
     141        uint32 shorts = bytes >> 1;
     142        uint32 remainingBytes = bytes & 1;
     143        bool swapRB = format ? format->swapRB : false;
     144
     145        if (swapRB) {
     146                for (; shorts > 0 ; shorts--) {
     147                        *dst = format->swapRedBlue16(*src);
     148                        dst++;
     149                        src++;
     150                }       
     151        } else {
     152                for (; shorts > 0 ; shorts--) {
     153                        *dst = *src;
     154                        dst++;
     155                        src++;
     156                }
     157        }
     158        if (remainingBytes)
     159                *(byte *)dst = *(byte *)src;
     160}
     161 
     162 
     163// Class VramAllocator -----------------------------------
     164
     165DECLARE_SINGLETON(VramAllocator)
     166
     167//#define __PSP_DEBUG_FUNCS__   /* For debugging the stack */
     168//#define __PSP_DEBUG_PRINT__
     169
     170#include "backends/platform/psp/trace.h"
     171
     172
     173void *VramAllocator::allocate(int32 size, bool smallAllocation /* = false */) {
     174        DEBUG_ENTER_FUNC();
     175        assert (size > 0);
     176       
     177        byte *lastAddress = smallAllocation ? (byte *)VRAM_SMALL_ADDRESS : (byte *)VRAM_START_ADDRESS;
     178        Common::List<Allocation>::iterator i;
     179
     180        // Find a block that fits, starting from the beginning
     181        for (i = _allocList.begin(); i != _allocList.end(); ++i) {
     182                byte *currAddress = (*i).address;
     183               
     184                if (currAddress - lastAddress >= size) // We found a match
     185                        break;
     186               
     187                if ((*i).getEnd() > lastAddress)
     188                        lastAddress = (byte *)(*i).getEnd();
     189        }
     190
     191        if (lastAddress + size > (byte *)VRAM_END_ADDRESS) {
     192                PSP_DEBUG_PRINT("No space for allocation of %d bytes. %d bytes already allocated.\n",
     193                                                size, _bytesAllocated);
     194                return NULL;
     195        }
     196
     197        _allocList.insert(i, Allocation(lastAddress, size));
     198        _bytesAllocated += size;
     199       
     200        PSP_DEBUG_PRINT("Allocated in VRAM, size %u at %p.\n", size, lastAddress);
     201        PSP_DEBUG_PRINT("Total allocated %u, remaining %u.\n", _bytesAllocated, (2 * 1024 * 1024) - _bytesAllocated);
     202       
     203        DEBUG_EXIT_FUNC();
     204        return lastAddress;
     205}
     206
     207// Deallocate a block from VRAM
     208void VramAllocator::deallocate(void *address) {
     209        DEBUG_ENTER_FUNC();
     210        address = (byte *)CACHED(address);      // Make sure all addresses are the same
     211       
     212        Common::List<Allocation>::iterator i;
     213       
     214        // Find the Allocator to deallocate
     215        for (i = _allocList.begin(); i != _allocList.end(); ++i) {
     216                if ((*i).address == address) {
     217                        _bytesAllocated -= (*i).size;
     218                        _allocList.erase(i);
     219                        PSP_DEBUG_PRINT("Deallocated address[%p], size[%u]\n", (*i).address, (*i).size);
     220                        DEBUG_EXIT_FUNC();
     221                        return;
     222                }
     223        }       
     224       
     225        PSP_DEBUG_PRINT("Address[%p] not allocated.\n", address);
     226        DEBUG_EXIT_FUNC();
     227}               
  • backends/platform/psp/module.mk

     
    11MODULE := backends/platform/psp
    22
    3 MODULE_OBJS := \
    4         powerman.o \
     3MODULE_OBJS := powerman.o \
    54        psp_main.o \
    65        osys_psp.o \
     6        psppixelformat.o \
     7        memory.o \
     8        display_manager.o \
     9        display_client.o \
     10        default_display_client.o \
     11        input.o \
     12        cursor.o \
    713        trace.o \
    814        psploader.o \
    915        pspkeyboard.o
  • backends/platform/psp/default_display_client.h

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/trace.h $
     22 * $Id: trace.h 44276 2009-09-23 16:11:23Z joostp $
     23 *
     24 */
     25
     26#ifndef PSP_DEF_DISPLAY_CLIENT_H
     27#define PSP_DEF_DISPLAY_CLIENT_H
     28
     29/**
     30 *      Default display client that is useful for most purposes.
     31 */
     32class DefaultDisplayClient : public DisplayClient {
     33public:
     34        DefaultDisplayClient() : _visible(false), _dirty(true) {}
     35       
     36        bool isVisible() { return _visible; }
     37        void setVisible(bool v) { _visible = v; setDirty(); }
     38        Buffer &buffer() { return _buffer; }
     39        Palette &palette() { return _palette; }
     40        void init();
     41        bool allocate(bool bufferInVram = false, bool paletteInVram = false);
     42        void deallocate();
     43        void clearBuffer();
     44        void clearPalette();
     45        void render() { _renderer.render(); }
     46        uint32 getWidth() { return _buffer.getSourceWidth(); }
     47        uint32 getHeight() { return _buffer.getSourceHeight(); }
     48        void setPartialPalette(const byte *colors, uint start, uint num) { setDirty(); return _palette.setPartial(colors, start, num); }
     49        void getPartialPalette(byte *colors, uint start, uint num) {
     50                return _palette.getPartial(colors, start, num);
     51        }
     52        void copyFromRect(const byte *buf, int pitch, int destX, int destY, int recWidth, int recHeight);
     53        void copyToArray(byte *dst, int pitch);
     54        void setDirty() { _dirty = true; }
     55        void setClean() { _dirty = false; }
     56        bool isDirty() { return _dirty; }
     57
     58protected:
     59        Buffer _buffer;
     60        Palette _palette;
     61        GuRenderer _renderer;
     62        bool _visible;
     63        bool _dirty;
     64};
     65
     66/**
     67 *      Screen overlay class.
     68 */
     69class Overlay : public DefaultDisplayClient {
     70public:
     71        Overlay() {}
     72        ~Overlay() { }
     73       
     74        void init();
     75        bool allocate();
     76        void setBytesPerPixel(uint32 size);
     77        void setSize(uint32 width, uint32 height);
     78        void copyToArray(OverlayColor *buf, int pitch);
     79        void copyFromRect(const OverlayColor *buf, int pitch, int x, int y, int w, int h);     
     80};
     81
     82/**
     83 *      Screen class.
     84 */
     85class Screen : public DefaultDisplayClient {
     86public:
     87        Screen() : _shakePos(0) {
     88                memset(&_pixelFormat, 0, sizeof(_pixelFormat));
     89                memset(&_frameBuffer, 0, sizeof(_frameBuffer));
     90        }
     91        ~Screen() {}
     92       
     93        void init();
     94        bool allocate();
     95        void setShakePos(int pos);
     96        void setScummvmPixelFormat(const Graphics::PixelFormat *format);
     97        const Graphics::PixelFormat &getScummvmPixelFormat() const { return _pixelFormat; }
     98        Graphics::Surface *lockAndGetForEditing();
     99        void unlock() { setDirty(); } // set dirty here because of changes
     100        void setSize(uint32 width, uint32 height);     
     101       
     102private:
     103        uint32 _shakePos;
     104        Graphics::PixelFormat _pixelFormat;
     105        Graphics::Surface _frameBuffer;
     106};
     107
     108#endif /* PSP_DEF_DISPLAY_CLIENT_H */
  • backends/platform/psp/cursor.cpp

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.h $
     22 * $Id: osys_psp.h 46120 2009-11-24 10:33:30Z Bluddy $
     23 *
     24 */
     25
     26#include "common/scummsys.h"
     27#include "backends/platform/psp/display_client.h"
     28#include "backends/platform/psp/default_display_client.h"
     29#include "backends/platform/psp/cursor.h"
     30
     31//#define __PSP_DEBUG_FUNCS__   /* For debugging the stack */
     32//#define __PSP_DEBUG_PRINT__
     33
     34#include "backends/platform/psp/trace.h"
     35 
     36void Cursor::init() {
     37        DEBUG_ENTER_FUNC();
     38       
     39        _renderer.setBuffer(&_buffer);                  // We do this explicitly
     40        _renderer.setPalette(&_screenPalette);  // because we want to choose screenpalette by default
     41        _renderer.setUseGlobalScaler(true);
     42        setRendererModePalettized(true);                // Assume we start in 8bit mode
     43       
     44        // Default modes
     45        _palette.setPixelFormats(PSPPixelFormat::Type_5551, PSPPixelFormat::Type_Palette_8bit); // default
     46        _screenPalette.setPixelFormats(PSPPixelFormat::Type_5551, PSPPixelFormat::Type_Palette_8bit);
     47        _buffer.setPixelFormat(PSPPixelFormat::Type_5551);
     48       
     49        DEBUG_EXIT_FUNC();
     50}
     51
     52void Cursor::deallocate() {
     53        DEBUG_ENTER_FUNC();
     54       
     55        _buffer.deallocate();
     56        _palette.deallocate();
     57        _screenPalette.deallocate();
     58       
     59        DEBUG_EXIT_FUNC();
     60}
     61
     62void Cursor::setCursorPalette(const byte *colors, uint start, uint num) {
     63        DEBUG_ENTER_FUNC();
     64
     65        if (!_palette.isAllocated()) {
     66                _palette.allocate();
     67        }
     68       
     69        // Workaround: This is wrong, but we seem to not be getting setScreenPalette
     70        if (!_screenPalette.isAllocated()) {
     71                _screenPalette.allocate();
     72        }       
     73       
     74        _palette.setPartial(colors, start, num);
     75        setDirty();
     76       
     77        DEBUG_EXIT_FUNC();
     78}       
     79
     80void Cursor::setScreenPalette(const byte *colors, uint start, uint num) {
     81        DEBUG_ENTER_FUNC();
     82
     83        if (!_screenPalette.isAllocated()) {
     84                _screenPalette.allocate();
     85        }
     86       
     87        _screenPalette.setPartial(colors, start, num);
     88        setDirty();
     89       
     90        DEBUG_EXIT_FUNC();
     91}
     92
     93void Cursor::setKeyColor(uint32 color) {
     94        DEBUG_ENTER_FUNC();
     95        PSP_DEBUG_PRINT("new color[%u], old color[%u]\n", color, _keyColor);
     96       
     97        // If it's a different color, undo the last keycolor
     98        if (_buffer.hasPalette() && color != _keyColor) {
     99                if (_screenPalette.isAllocated())
     100                        _screenPalette.setColorPositionAlpha(_keyColor, true);
     101                if (_palette.isAllocated())
     102                        _palette.setColorPositionAlpha(_keyColor, true);
     103        }
     104        // Don't need anything special for 16-bit
     105        _keyColor = color;
     106       
     107        DEBUG_EXIT_FUNC();
     108}
     109
     110void Cursor::clearKeyColor() {
     111        DEBUG_ENTER_FUNC();
     112        PSP_DEBUG_PRINT("keyColor[%d]\n", _keyColor);
     113
     114        // We need 2 mechanisms: one for palettized and one for 16 bit
     115        if (_buffer.hasPalette()) {
     116                if (_screenPalette.isAllocated())
     117                        _screenPalette.setColorPositionAlpha(_keyColor, false);         // set keycolor to 0   
     118                if (_palette.isAllocated())
     119                        _palette.setColorPositionAlpha(_keyColor, false);       
     120        } else {        // 16bit
     121                _renderer.setKeyColor(_keyColor);
     122        }
     123        setDirty();
     124       
     125        DEBUG_EXIT_FUNC();
     126}
     127
     128void Cursor::enableCursorPalette(bool enable) {
     129        DEBUG_ENTER_FUNC();
     130        PSP_DEBUG_PRINT("enable[%s]\n", enable ? "true" : "false");
     131       
     132        _useCursorPalette = enable;
     133        if (enable)
     134                _renderer.setPalette(&_palette);        // very important that we do this switch
     135        else
     136                _renderer.setPalette(&_screenPalette);
     137       
     138        setDirty();
     139        DEBUG_EXIT_FUNC();             
     140}
     141
     142inline void Cursor::setSize(uint32 width, uint32 height) {
     143        DEBUG_ENTER_FUNC();
     144        PSP_DEBUG_PRINT("width[%u], height[%u]\n", width, height);
     145
     146        _buffer.setSize(width, height, Buffer::kSizeByTextureSize);     // we'll use texture size for mouse
     147        _renderer.setDrawWholeBuffer();         // We need to let the renderer know how much to draw
     148       
     149        DEBUG_EXIT_FUNC();
     150}
     151
     152void Cursor::copyFromArray(const byte *array) {
     153        DEBUG_ENTER_FUNC();
     154       
     155        if (!_buffer.isAllocated())     {
     156                _buffer.allocate();
     157        }
     158
     159        _buffer.copyFromArray(array, _buffer.getSourceWidthInBytes());  // pitch is source width
     160        setDirty();
     161       
     162        // debug       
     163        //PSP_DEBUG_DO(_buffer.print(0xF));
     164
     165        DEBUG_EXIT_FUNC();
     166
     167}
     168
     169void Cursor::setHotspot(int32 x, int32 y) {
     170        DEBUG_ENTER_FUNC();
     171
     172        _hotspotX = x;
     173        _hotspotY = y;
     174        updateRendererOffset(); // Important
     175
     176        PSP_DEBUG_PRINT("hotspotX[%d], hotspotY[%d]\n", x, y);
     177        DEBUG_EXIT_FUNC();
     178}
     179
     180// Returns true if change in x or y
     181bool Cursor::increaseXY(int32 incX, int32 incY) {
     182        DEBUG_ENTER_FUNC();     
     183
     184        int32 oldX = _x, oldY = _y;
     185
     186        // adjust for differences in X and Y
     187        adjustXYForScreenSize(incX, incY);
     188       
     189        _x += incX;
     190        _y += incY;
     191       
     192        // Clamp mouse
     193        if (_x < 0)
     194                _x = 0;
     195        if (_y < 0)
     196                _y = 0;
     197        if (_x >= (int)_mouseLimitWidth)
     198                _x = (int)_mouseLimitWidth - 1;
     199        if (_y >= (int)_mouseLimitHeight)
     200                _y = (int)_mouseLimitHeight - 1;
     201       
     202        PSP_DEBUG_PRINT("X[%d], Y[%d]\n", _x, _y);
     203       
     204        if (oldX != _x || oldY != _y) {
     205                updateRendererOffset();
     206                setDirty();
     207                DEBUG_EXIT_FUNC();
     208                return true;
     209        }
     210       
     211        DEBUG_EXIT_FUNC();
     212        return false;
     213}
     214
     215// Set limits on the movement of the cursor ie. screen size
     216void Cursor::setLimits(uint32 width, uint32 height) {
     217        #define PSP_SCREEN_WIDTH 480
     218        #define PSP_SCREEN_HEIGHT 272
     219        DEBUG_ENTER_FUNC();
     220       
     221        PSP_DEBUG_PRINT("width[%u], height[%u]\n", width, height);
     222        _mouseLimitWidth = width;
     223        _mouseLimitHeight = height;
     224       
     225        DEBUG_EXIT_FUNC();
     226}
     227       
     228// Adjust X,Y movement for the screen size to keep it consistent       
     229INLINE void Cursor::adjustXYForScreenSize(int32 &x, int32 &y) {
     230        DEBUG_ENTER_FUNC();
     231        // We have our speed calibrated for the y axis at 480x272. The idea is to adjust this for other
     232        // resolutions and for x, which is wider.
     233        int32 newX = x, newY = y;
     234       
     235        // adjust width movement to match height (usually around 1.5)
     236        if (_mouseLimitWidth >= _mouseLimitHeight + (_mouseLimitHeight >> 1))
     237                newX = newX + (newX >> 1);
     238       
     239        if (_mouseLimitWidth >= 600) {  // multiply by 2
     240                newX <<= 1;
     241                newY <<= 1;
     242        } else if (_mouseLimitWidth >= 480) {   // multiply by 1.5
     243                newX = newX + (newX >> 1);
     244                newY = newY + (newY >> 1);
     245        }
     246       
     247        // Divide all movements by 8
     248        newX >>= 3;
     249        newY >>= 3;
     250       
     251        // Make sure we didn't destroy minimum movement
     252        if (!((x && !newX) || (y && !newY))) { 
     253                x = newX;
     254                y = newY;
     255        }
     256       
     257        DEBUG_EXIT_FUNC();
     258}
     259
     260// This is only called when we have a new screen
     261void Cursor::setScreenPaletteScummvmPixelFormat(const Graphics::PixelFormat *format) {
     262        DEBUG_ENTER_FUNC();
     263
     264        uint32 oldPaletteSize = 0;
     265        if (_screenPalette.isAllocated())
     266                oldPaletteSize = _screenPalette.getSizeInBytes();
     267       
     268        PSPPixelFormat::Type bufferType = PSPPixelFormat::Type_Unknown;
     269        PSPPixelFormat::Type paletteType = PSPPixelFormat::Type_Unknown;
     270        bool swapRedBlue = false;
     271       
     272        // Convert Scummvm Pixel Format to PSPPixelFormat
     273        PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType, swapRedBlue);
     274       
     275        if (paletteType == PSPPixelFormat::Type_None) {
     276                //_screenPalette.deallocate();          // leave palette for default CLUT8
     277                setRendererModePalettized(false);       // use 16-bit mechanism
     278        } else {        // We have a palette
     279                _screenPalette.setPixelFormats(paletteType, bufferType);       
     280                _palette.setPixelFormats(paletteType, bufferType);             
     281                setRendererModePalettized(true);        // use palettized mechanism
     282        }
     283       
     284        DEBUG_EXIT_FUNC();
     285}
     286
     287// This is called many many times
     288void Cursor::setSizeAndScummvmPixelFormat(uint32 width, uint32 height, const Graphics::PixelFormat *format) {
     289        DEBUG_ENTER_FUNC();
     290       
     291        PSP_DEBUG_PRINT("useCursorPalette[%s]\n", _useCursorPalette ? "true" : "false");
     292       
     293        uint32 oldBufferSize = 0, oldPaletteSize = 0;
     294       
     295        if (_buffer.isAllocated())
     296                oldBufferSize = _buffer.getSizeInBytes();
     297               
     298        if (_palette.isAllocated())
     299                oldPaletteSize = _palette.getSizeInBytes();
     300       
     301        setSize(width, height);
     302       
     303        PSPPixelFormat::Type bufferType = PSPPixelFormat::Type_Unknown;
     304        PSPPixelFormat::Type paletteType = PSPPixelFormat::Type_Unknown;
     305        bool swapRedBlue = false;
     306       
     307        PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType, swapRedBlue);
     308        PSP_DEBUG_PRINT("bufferType[%u], paletteType[%u]\n", bufferType, paletteType);
     309       
     310        // Check if we need to set new pixel format
     311        if (_buffer.getPixelFormat() != bufferType) {
     312                PSP_DEBUG_PRINT("new buffer pixel format[%u] is different from [%u]. Setting it.\n", bufferType, _buffer.getPixelFormat());
     313                _buffer.setPixelFormat(bufferType);
     314        }
     315       
     316        // Check if we need to reallocate
     317        if (_buffer.getSizeInBytes() != oldBufferSize) {
     318                _buffer.allocate();
     319                PSP_DEBUG_PRINT("reallocating buffer. new size: width[%u], height[%u]\n", width, height);
     320        }
     321
     322        PSP_DEBUG_PRINT("palette pixel format[%u]\n", paletteType);
     323               
     324        if (paletteType == PSPPixelFormat::Type_None) {
     325                setRendererModePalettized(false);       // use palettized mechanism
     326        } else {        // We have a palette
     327                _palette.setPixelFormats(paletteType, bufferType);             
     328                setRendererModePalettized(true);        // use palettized mechanism
     329        }       
     330
     331        // debug
     332        // PSP_DEBUG_DO(_palette.print(10));
     333        // PSP_DEBUG_DO(_screenPalette.print(10));
     334       
     335        DEBUG_EXIT_FUNC();
     336}
     337
     338void Cursor::setXY(int x, int y) {
     339        DEBUG_ENTER_FUNC();
     340       
     341    _x = x;
     342        _y = y;
     343        updateRendererOffset(); // Very important to let renderer know things changed
     344        setDirty();
     345       
     346        DEBUG_EXIT_FUNC();
     347}
     348
     349INLINE void Cursor::updateRendererOffset() {
     350        DEBUG_ENTER_FUNC();
     351        _renderer.setOffsetOnScreen(_x - _hotspotX, _y - _hotspotY);
     352        DEBUG_EXIT_FUNC();
     353}
     354
     355INLINE void Cursor::setRendererModePalettized(bool palettized) {
     356        if (palettized) {       // We have a palette. Use blending
     357                _renderer.setAlphaBlending(true);
     358                _renderer.setAlphaReverse(false);
     359                _renderer.setColorTest(false);
     360        } else {                        // 16 bits, no palette
     361                _renderer.setAlphaBlending(true);
     362                _renderer.setAlphaReverse(true); // We can't change all alpha values, so just reverse
     363                _renderer.setColorTest(true);   // Color test to make our key color transparent
     364        }
     365}
  • backends/platform/psp/psppixelformat.cpp

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
     22 * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
     23 *
     24 */
     25
     26#include "common/scummsys.h"
     27#include "backends/platform/psp/psppixelformat.h"
     28
     29//#define __PSP_DEBUG_FUNCS__   /* For debugging function calls */
     30//#define __PSP_DEBUG_PRINT__   /* For debug printouts */
     31
     32#include "backends/platform/psp/trace.h"
     33
     34// class PSPPixelFormat --------------------------------------
     35
     36void PSPPixelFormat::set(Type type, bool swap /* = false */) {
     37        DEBUG_ENTER_FUNC();
     38        PSP_DEBUG_PRINT("type = %d\n", type);
     39       
     40        format = type;
     41        swapRB = swap;
     42       
     43        switch (type) {
     44        case Type_4444:
     45        case Type_5551:
     46        case Type_5650:
     47                bitsPerPixel = 16;
     48                break;
     49        case Type_8888:
     50                bitsPerPixel = 32;
     51                break;
     52        case Type_Palette_8bit:
     53                bitsPerPixel = 8;
     54                break;
     55        case Type_Palette_4bit:
     56                bitsPerPixel = 4;
     57                break;
     58        case Type_None:
     59                bitsPerPixel = 0;
     60                break;
     61        default:        // This is an error, but let's continue anyway
     62                PSP_ERROR("Unhandled value of pixel type[%d]\n", type);
     63                bitsPerPixel = 16;
     64                break;
     65        }
     66
     67        PSP_DEBUG_PRINT("bitsPerPixel[%u]\n", bitsPerPixel);
     68        DEBUG_EXIT_FUNC();
     69}
     70
     71// Convert from ScummVM general PixelFormat to our pixel format
     72// For buffer and palette.
     73void PSPPixelFormat::convertFromScummvmPixelFormat(const Graphics::PixelFormat *pf,
     74                                                                                                PSPPixelFormat::Type &bufferType,
     75                                                                                                PSPPixelFormat::Type &paletteType,
     76                                                                                                bool &swapRedBlue) {
     77        swapRedBlue = false;     // no red-blue swap by default
     78        PSPPixelFormat::Type *target = 0;       // which one we'll be filling
     79       
     80        if (!pf) {      // Default, pf is NULL
     81                bufferType = Type_Palette_8bit;
     82                paletteType = Type_5551;
     83        } else {        // We have a pf
     84                if (pf->bytesPerPixel == 1) {
     85                        bufferType = Type_Palette_8bit;
     86                        target = &paletteType;  // The type describes the palette
     87                } else if (pf->bytesPerPixel == 2) {
     88                        paletteType = Type_None;
     89                        target = &bufferType;   // The type describes the buffer
     90                } else {
     91                        PSP_ERROR("Unknown bpp[%u] in pixeltype. Reverting to 8bpp\n", pf->bytesPerPixel);
     92                        bufferType = Type_Palette_8bit;
     93                        target = &paletteType;  // The type describes the palette
     94                }
     95       
     96                // Find out the exact type of the target
     97                if (pf->rLoss == 3 && pf->bLoss == 3) {
     98                        if (pf->gLoss == 3)
     99                                *target = Type_5551;
     100                        else
     101                                *target = Type_5650;
     102                } else if (pf->rLoss == 4 && pf->gLoss == 4 && pf->bLoss == 4) {
     103                        *target = Type_4444;
     104                } else if (pf->gLoss == 0 && pf->gShift == 8) {
     105                        *target = Type_8888;
     106                } else if ((pf->gLoss == 0 && pf->gShift == 0) ||
     107                                   (pf->gLoss == 8 && pf->gShift == 0)) {       // Default CLUT8 can have weird values
     108                        *target = Type_5551;
     109                } else {
     110                        PSP_ERROR("Unknown Scummvm pixel format.\n");
     111                        PSP_ERROR("\trLoss[%d], gLoss[%d], bLoss[%d], aLoss[%d]\n\trShift[%d], gShift[%d], bShift[%d], aShift[%d]\n",
     112                        pf->rLoss, pf->gLoss, pf->bLoss, pf->aLoss,
     113                        pf->rShift, pf->gShift, pf->bShift, pf->aShift);               
     114                        *target = Type_Unknown;
     115                }
     116
     117                if (pf->rShift != 0)    {// We allow backend swap of red and blue
     118                        swapRedBlue = true;
     119                        PSP_DEBUG_PRINT("detected red/blue swap\n");
     120                }
     121        }
     122}
     123
     124Graphics::PixelFormat PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type type) {
     125        Graphics::PixelFormat pf;
     126       
     127        switch(type) {
     128        case Type_4444:
     129                pf.bytesPerPixel = 2;
     130                pf.aLoss = 4;    pf.rLoss = 4;   pf.gLoss = 4;   pf.bLoss = 4;
     131                pf.aShift = 12; pf.rShift = 0;  pf.gShift = 4;  pf.bShift = 8;
     132                break;
     133        case Type_5551:
     134                pf.bytesPerPixel = 2;
     135                pf.aLoss = 7;    pf.rLoss = 3;    pf.gLoss = 3;    pf.bLoss = 3;
     136                pf.aShift = 15; pf.rShift = 0;   pf.gShift = 5;   pf.bShift = 10;
     137                break;
     138        case Type_5650:
     139                pf.bytesPerPixel = 2;
     140                pf.aLoss = 8;     pf.rLoss = 3;    pf.gLoss = 2;    pf.bLoss = 3;
     141                pf.aShift = 0;   pf.rShift = 0;   pf.gShift = 5;   pf.bShift = 11;
     142                break;
     143        case Type_8888:
     144                pf.bytesPerPixel = 4;
     145                pf.aLoss = 0;     pf.rLoss = 0;    pf.gLoss = 0;    pf.bLoss = 0;
     146                pf.aShift = 24;  pf.rShift = 0;   pf.gShift = 8;   pf.bShift = 16;
     147                break;
     148        default:
     149                PSP_ERROR("Unhandled PSPPixelFormat[%u]\n", type);
     150                break;
     151        }
     152       
     153        return pf;
     154}
     155
     156uint32 PSPPixelFormat::convertTo32BitColor(uint32 color) {
     157        DEBUG_ENTER_FUNC();
     158        uint32 r,g,b,a, output;
     159       
     160        colorToRgba(color, r, g, b, a);
     161        output = ((b << 16) | (g << 8) | (r << 0) | (a << 24));
     162        PSP_DEBUG_PRINT_FUNC("input color[%x], output[%x]\n", color, output);
     163       
     164        DEBUG_EXIT_FUNC();
     165        return output;
     166}
  • backends/platform/psp/pspkeyboard.cpp

    +
    +
     
    2424 */
    2525
    2626//#define PSP_KB_SHELL  /* Need a hack to properly load the keyboard from the PSP shell */
     27
    2728#ifdef PSP_KB_SHELL
    28 #define PSP_KB_SHELL_PATH       "ms0:/psp/game4xx/scummvm-1.0.0rc1/"    /* path to kbd.zip */
     29        #define PSP_KB_SHELL_PATH       "ms0:/psp/game4xx/scummvm-solid/"       /* path to kbd.zip */
    2930#endif
    30 //#define PSP_KB_DEBUG
    3131
     32//#define __PSP_DEBUG_FUNCS__   /* For debugging the stack */
     33//#define __PSP_DEBUG_PRINT__
     34
     35#include "backends/platform/psp/trace.h"
    3236#include <malloc.h>
    3337#include "pspkernel.h"
    34 #include <pspgu.h>
    3538#include "png.h"
    36 #include "pspkeyboard.h"
     39#include "backends/platform/psp/pspkeyboard.h"
    3740#include "common/keyboard.h"
    3841#include "common/fs.h"
    3942#include "common/unzip.h"
     
    9497        file->read(data, length);
    9598}
    9699
     100// Array with file names
     101const char *PSPKeyboard::_guiStrings[] = {
     102        "keys4.png", "keys_s4.png",
     103        "keys_c4.png", "keys_s_c4.png",
     104        "nums4.png", "nums_s4.png",
     105        "syms4.png", "syms_s4.png"
     106};
     107
    97108// Constructor
    98109PSPKeyboard::PSPKeyboard() {
     110        DEBUG_ENTER_FUNC();
     111       
    99112        _init = false;                  // we're not initialized yet
    100113        _prevButtons = 0;               // Reset previous buttons
    101         _dirty = true;          // keyboard needs redrawing
    102         _mode = 0;              // charset selected. (0 - letters, 1 - uppercase 2 - numbers 3 - symbols)
     114        _dirty = false;         // keyboard needs redrawing
     115        _mode = 0;              // charset selected. (0: letters, 1: uppercase 2: numbers 3: symbols)
    103116        _oldCursor = kCenter;   // Center cursor by default
    104         _moved_x = 20;                  // Default starting location
    105         _moved_y = 50;
     117        _movedX = 20;                   // Default starting location
     118        _movedY = 50;
    106119        _moved = false;                 // Keyboard wasn't moved recently
    107120        _state = kInvisible;    // We start invisible
    108121        _lastState = kInvisible;
     122       
     123        // Constant renderer settings
     124        _renderer.setAlphaBlending(true);
     125        _renderer.setColorTest(false);
     126        _renderer.setUseGlobalScaler(false);   
     127       
     128        DEBUG_EXIT_FUNC();
    109129}
    110130
    111131// Destructor
    112132PSPKeyboard::~PSPKeyboard() {
    113         if (!_init) return;
     133        DEBUG_ENTER_FUNC();
     134       
     135        if (!_init) {
     136                DEBUG_EXIT_FUNC();
     137                return;
     138        }
    114139
    115         int a;
    116         for (a = 0; a < guiStringsSize; a++) {
    117                 free(_keyTextures[a].texture);
    118                 free(_keyTextures[a].palette);
    119                 _keyTextures[a].texture = NULL;
    120                 _keyTextures[a].palette = NULL;
     140        for (int i = 0; i < guiStringsSize; i++) {
     141                _buffers[i].deallocate();
     142                _palettes[i].deallocate();
    121143        }
    122144        _init = false;
     145       
     146        DEBUG_EXIT_FUNC();
    123147}
    124148
    125 // Array with file names
    126 const char *PSPKeyboard::_guiStrings[] = {
    127         "keys4.png", "keys_s4.png",
    128         "keys_c4.png", "keys_s_c4.png",
    129         "nums4.png", "nums_s4.png",
    130         "syms4.png", "syms_s4.png"
    131 };
    132 
    133 // Defines for working with PSP buttons
    134 #define CHANGED(x)       (buttonsChanged & (x))
    135 #define PRESSED(x)   ((buttonsChanged & (x)) && (pad.Buttons & (x)))
    136 #define UNPRESSED(x) ((buttonsChanged & (x)) && !(pad.Buttons & (x)))
    137 #define DOWN(x)          (pad.Buttons & (x))
    138 #define UP(x)            (!(pad.Buttons & (x)))
    139 #define PSP_DPAD         (PSP_CTRL_DOWN|PSP_CTRL_UP|PSP_CTRL_LEFT|PSP_CTRL_RIGHT)
    140 #define PSP_4BUTTONS (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE | PSP_CTRL_TRIANGLE | PSP_CTRL_SQUARE)
    141 
    142 /*
    143  *  Attempts to read a character from the controller
    144  *  Uses the state machine.
    145  */
    146 bool PSPKeyboard::processInput(Common::Event &event, SceCtrlData &pad, bool &usedInput) {
    147         usedInput = false;                      // Assume we don't use an input
    148         bool haveEvent = false;         // Whether we have an event for the event manager to process
    149         event.kbd.flags = 0;
    150         unsigned int keyDown;
    151         uint32 buttonsChanged = _prevButtons ^ pad.Buttons;
    152 
    153         if (!_init)                                     // In case we never had init
    154                 goto END;
    155 
    156         if (PRESSED(PSP_CTRL_SELECT)) {
     149void PSPKeyboard::setVisible(bool val) {
     150        if (val && _state == kInvisible && _init) {     // Check also that were loaded correctly
    157151                _lastState = _state;
    158                 _state = kMove;                 // Check for move or visible state
    159                 usedInput = true;
    160                 goto END;
     152                _state = kMove;
    161153        }
    162 
    163         if (_state == kInvisible)       // Return if we're invisible
    164                 goto END;
    165 
    166         if (DOWN(PSP_DPAD | PSP_4BUTTONS | PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_START))
    167                 usedInput = true;               // for now, we neutralize all button inputs
    168 
    169         // Check for moving the keyboard onscreen
    170         if (_state == kMove) {
    171                 if (UNPRESSED(PSP_CTRL_SELECT)) {
    172                         _state = (_lastState == kInvisible) ? kDefault : kInvisible;                    // Back to previous state
    173                         _dirty = true;
    174 
    175                         if (_moved) {                           // We moved the keyboard. Keep the keyboard onscreen
    176                                 _state = kDefault;
    177                                 _moved = false;                 // reset moved flag
    178                         }
    179                 }
    180                 else if (DOWN(PSP_DPAD)) {
    181                         _moved = true;
    182                         _dirty = true;
    183 
    184                         if (DOWN(PSP_CTRL_DOWN))
    185                                 increaseKeyboardLocationY(5);
    186                         else if (DOWN(PSP_CTRL_UP))
    187                                 increaseKeyboardLocationY(-5);
    188                         else if (DOWN(PSP_CTRL_LEFT))
    189                                 increaseKeyboardLocationX(-5);
    190                         else  /* DOWN(PSP_CTRL_RIGHT) */
    191                                 increaseKeyboardLocationX(5);
    192                 }
    193                 usedInput = true;       // We used up the input (select was held down)
    194                 goto END;
     154        else if ( !val && _state != kInvisible) {
     155                _lastState = _state;
     156                _state = kInvisible;
    195157        }
    196 
    197 
    198         // Handle 4 buttons + 2 triggers
    199         if (_state == kDefault || _state == kCornersSelected) {
    200                 unsigned int changed;
    201 
    202                 if (_state == kDefault) {       // Handle default state
    203                         changed = CHANGED(PSP_4BUTTONS);                        // We only care about the 4 buttons
    204                         if (PRESSED(PSP_CTRL_LTRIGGER)) {                       // Don't say we used up the input
    205                                 _state = kLTriggerDown;
    206                                 goto END;
    207                         }
    208                         else if (PRESSED(PSP_CTRL_RTRIGGER)) {          // Don't say we used up the input
    209                                 _state = kRTriggerDown;
    210                                 goto END;
    211                         }
    212 
    213                         if (DOWN(PSP_4BUTTONS))
    214                                 usedInput = true;                                               // Make sure these button presses don't get through
    215                 } else { /* _state == kCornersSelected */
    216                         // We care about 4 buttons + triggers (for letter selection)
    217                         changed = CHANGED(PSP_4BUTTONS | PSP_CTRL_RTRIGGER | PSP_CTRL_LTRIGGER);
    218 
    219                         if (DOWN(PSP_4BUTTONS | PSP_CTRL_RTRIGGER | PSP_CTRL_LTRIGGER))
    220                                 usedInput = true;       // Make sure these button presses don't get through
    221                 }
    222 
    223                 if (changed) { //pressing a char select button -- both states
    224 
    225                         int innerChoice;
    226 
    227                         if (UNPRESSED(PSP_CTRL_TRIANGLE)) {
    228                                 innerChoice = 0;
    229                                 event.type = Common::EVENT_KEYUP;                       // We give priority to key_up
    230                         } else if (UNPRESSED(PSP_CTRL_CIRCLE)) {
    231                                 innerChoice = 1;
    232                                 event.type = Common::EVENT_KEYUP;                       // We give priority to key_up
    233                         } else if (UNPRESSED(PSP_CTRL_CROSS)) {
    234                                 innerChoice = 2;
    235                                 event.type = Common::EVENT_KEYUP;                       // We give priority to key_up
    236                         } else if (UNPRESSED(PSP_CTRL_SQUARE)) {
    237                                 innerChoice = 3;
    238                                 event.type = Common::EVENT_KEYUP;                       // We give priority to key_up
    239                         } else if (UNPRESSED(PSP_CTRL_LTRIGGER) && _state == kCornersSelected) {
    240                                 innerChoice = 4;
    241                                 event.type = Common::EVENT_KEYUP;                       // We give priority to key_up
    242                         } else if (UNPRESSED(PSP_CTRL_RTRIGGER) && _state == kCornersSelected) {
    243                                 innerChoice = 5;
    244                                 event.type = Common::EVENT_KEYUP;                       // We give priority to key_up
    245                         } else if (PRESSED(PSP_CTRL_TRIANGLE)) {
    246                                 innerChoice = 0;
    247                                 event.type = Common::EVENT_KEYDOWN;
    248                         } else if (PRESSED(PSP_CTRL_CIRCLE)) {
    249                                 innerChoice = 1;
    250                                 event.type = Common::EVENT_KEYDOWN;
    251                         } else if (PRESSED(PSP_CTRL_CROSS)) {
    252                                 innerChoice = 2;
    253                                 event.type = Common::EVENT_KEYDOWN;
    254                         } else if (PRESSED(PSP_CTRL_SQUARE)) {
    255                                 innerChoice = 3;
    256                                 event.type = Common::EVENT_KEYDOWN;
    257                         } else if (PRESSED(PSP_CTRL_LTRIGGER) && _state == kCornersSelected) {
    258                                 innerChoice = 4;
    259                                 event.type = Common::EVENT_KEYDOWN;                     // We give priority to key_up
    260                         } else  /* (UNPRESSED(PSP_CTRL_RTRIGGER)) && _state == kCornersSelected */ {
    261                                 innerChoice = 5;
    262                                 event.type = Common::EVENT_KEYDOWN;                     // We give priority to key_up
    263                         }
    264 
    265                         #define IS_UPPERCASE(x) ((x) >= (unsigned short)'A' && (x) <= (unsigned short)'Z')
    266                         #define TO_LOWER(x)             ((x) += 'a'-'A')
    267 
    268                         //Now grab the value out of the array
    269                         short choice = _modeChar[_mode][_oldCursor][innerChoice];
    270 
    271                         event.kbd.ascii = choice <= 255 ? choice : 0;
    272 
    273                         // Handle upper-case which is missing in Common::KeyCode
    274                         if (IS_UPPERCASE(choice)) {
    275                                 event.kbd.keycode = (Common::KeyCode) TO_LOWER(choice);
    276                                 event.kbd.flags = Common::KBD_SHIFT;
    277                         } else
    278                                 event.kbd.keycode = (Common::KeyCode) choice;
    279 
    280                         haveEvent = (choice != Common::KEYCODE_INVALID) ? true : false; // We have an event/don't if it's invalid
    281                         usedInput = true;
    282                 }
    283         }
    284 
    285         // Check for movement of cursor
    286         if (_state == kDefault || _state == kCornersSelected) {
    287                 // Check if a dependent button is down
    288                 if (_state == kDefault)
    289                         keyDown = DOWN(PSP_4BUTTONS);
    290                 else /* if (_state == kCornersSelected) */
    291                         keyDown = DOWN(PSP_4BUTTONS | PSP_CTRL_RTRIGGER | PSP_CTRL_LTRIGGER);
    292 
    293                 Cursor cursor = _oldCursor;
    294 
    295                 // Find where the cursor is pointing
    296                 if (keyDown == false) { // Don't allow movement if a nub-dependent key is down
    297                         cursor = kCenter;
    298                         _state = kDefault;
    299 
    300                         if (DOWN(PSP_DPAD)) {
    301                                 _state = kCornersSelected;
    302                                 usedInput = true;       // Make sure the pressed d-pad is used up
    303 
    304                                 if (DOWN(PSP_CTRL_UP))
    305                                         cursor = kUp;
    306                                 else if (DOWN(PSP_CTRL_RIGHT))
    307                                         cursor = kRight;
    308                                 else if (DOWN(PSP_CTRL_DOWN))
    309                                         cursor = kDown;
    310                                 else if (DOWN(PSP_CTRL_LEFT))
    311                                         cursor = kLeft;
    312                         }
    313                 }
    314 
    315                 if (cursor != _oldCursor) { //If we've moved, update dirty and return
    316                         _dirty = true;
    317                         _oldCursor = cursor;
    318                         usedInput = true;               // We 'used up' the input
    319                         //goto END;                             // We didn't find an event
    320                 }
    321         }
    322 
    323         // Deal with trigger states
    324         if (_state == kRTriggerDown) {
    325                 usedInput = true;
    326 
    327                 if (UNPRESSED(PSP_CTRL_RTRIGGER)) {
    328                         _dirty = true;
    329 
    330                         if(_mode > 1)
    331                                 _mode = 0;
    332                         else
    333                                 _mode = (_mode == 0) ? 1 : 0;
    334 
    335                         usedInput = true;
    336                         _state = kDefault;
    337 
    338                         goto END;
    339                 }
    340         } else if (_state == kLTriggerDown) {
    341                 usedInput = true;
    342 
    343                 if (UNPRESSED(PSP_CTRL_LTRIGGER)) {
    344                         _dirty = true;
    345 
    346                         if(_mode < 2)
    347                                 _mode = 2;
    348                         else
    349                                 _mode = (_mode == 2) ? 3 : 2;
    350 
    351                         usedInput = true;
    352                         _state = kDefault;
    353 
    354                         goto END;
    355                 }
    356         }
    357 
    358         // Handle start button: enter plus make keyboard invisible
    359         if (CHANGED(PSP_CTRL_START)) {
    360                 event.kbd.ascii = '\n';
    361                 event.kbd.keycode = Common::KEYCODE_RETURN;
    362                 event.type = DOWN(PSP_CTRL_START) ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP;
    363                 usedInput = true;                                       // Don't let start get through
    364                 haveEvent = true;
    365                 if (UP(PSP_CTRL_START))
    366                         _state = kInvisible;                    // Make us invisible if unpressed
    367         }
    368 
    369 END:
    370         _prevButtons = pad.Buttons;
    371         return haveEvent;
     158        setDirty();
    372159}
    373160
    374 
    375161/* move the position the keyboard is currently drawn at */
    376162void PSPKeyboard::moveTo(const int newX, const int newY) {
    377         _moved_x = newX;
    378         _moved_y = newY;
     163        DEBUG_ENTER_FUNC();
     164       
     165        _movedX = newX;
     166        _movedY = newY;
     167        setDirty();
     168       
     169        DEBUG_EXIT_FUNC();
    379170}
    380171
    381172/* move the position the keyboard is currently drawn at */
    382173void PSPKeyboard::increaseKeyboardLocationX(int amount) {
    383         int newX = _moved_x + amount;
     174        DEBUG_ENTER_FUNC();
     175       
     176        int newX = _movedX + amount;
    384177
    385         if (newX > PSP_SCREEN_WIDTH - 5 || newX < 0 - 140)      // clamp
     178        if (newX > PSP_SCREEN_WIDTH - 5 || newX < 0 - 140) {    // clamp
     179                DEBUG_EXIT_FUNC();
    386180                return;
    387         _moved_x = newX;
     181        }       
     182        _movedX = newX;
     183        setDirty();
     184       
     185        DEBUG_EXIT_FUNC();
    388186}
    389187
    390188/* move the position the keyboard is currently drawn at */
    391189void PSPKeyboard::increaseKeyboardLocationY(int amount) {
    392         int newY = _moved_y + amount;
     190        DEBUG_ENTER_FUNC();
     191       
     192        int newY = _movedY + amount;
    393193
    394         if (newY > PSP_SCREEN_HEIGHT - 5 || newY < 0 - 140)     // clamp
     194        if (newY > PSP_SCREEN_HEIGHT - 5 || newY < 0 - 140)     { // clamp
     195                DEBUG_EXIT_FUNC();
    395196                return;
    396         _moved_y = newY;
     197        }
     198        _movedY = newY;
     199        setDirty();
     200       
     201        DEBUG_EXIT_FUNC();
    397202}
    398203
    399204/* draw the keyboard at the current position */
    400205void PSPKeyboard::render() {
    401         _dirty = false;
     206        DEBUG_ENTER_FUNC();
     207
     208        unsigned int currentBuffer = _mode<<1;
     209       
     210        // Draw the background letters
     211        // Set renderer to current buffer & palette
     212        _renderer.setBuffer(&_buffers[currentBuffer]);
     213        _renderer.setPalette(&_palettes[currentBuffer]);
     214        _renderer.setOffsetOnScreen(_movedX, _movedY);
     215        _renderer.setOffsetInBuffer(0, 0);
     216        _renderer.setDrawWholeBuffer();
     217        _renderer.render();
     218       
     219        // Get X and Y coordinates for the orange block
    402220        int x, y;
     221        convertCursorToXY(_oldCursor, x, y);
     222       
     223        const int OrangeBlockSize = 64;
     224        const int GrayBlockSize = 43;
     225       
     226        // Draw the current Highlighted Selector (orange block)
     227        _renderer.setBuffer(&_buffers[currentBuffer + 1]);
     228        _renderer.setPalette(&_palettes[currentBuffer + 1]);
     229        _renderer.setOffsetOnScreen(_movedX + (x * GrayBlockSize), _movedY + (y * GrayBlockSize));
     230        _renderer.setOffsetInBuffer(x * OrangeBlockSize, y * OrangeBlockSize);
     231        _renderer.setDrawSize(OrangeBlockSize, OrangeBlockSize);
     232        _renderer.render();
     233       
     234        DEBUG_EXIT_FUNC();             
     235}
    403236
    404         switch(_oldCursor) {
     237inline void PSPKeyboard::convertCursorToXY(CursorDirections cur, int &x, int &y) {
     238        switch(cur) {
    405239        case kUp:
    406240                x = 1;
    407241                y = 0;
     
    423257                y = 1;
    424258                break;
    425259        }
    426 
    427         // Draw the background letters
    428         surface_draw_offset(&_keyTextures[_mode<<1], 0, 0, 0, 0,
    429                         _keyTextures[_mode<<1].texture_width,
    430                         _keyTextures[_mode<<1].texture_height);
    431 
    432         // Draw the current Highlighted Selector (orange bit)
    433         surface_draw_offset(&_keyTextures[(_mode<<1) + 1],
    434                         //Offset from the current draw position to render at
    435                         x * 43, y * 43,
    436                         //internal offset of the image
    437                         x * 64, y * 64,
    438                         //size to render (always the same)
    439                         64, 64);
    440260}
    441261
    442 
    443 //  Render the given surface at the current screen position offset by screenX, screenY
    444 //  the surface will be internally offset by offsetX,offsetY. And the size of it to be drawn will be intWidth,intHeight
    445 void PSPKeyboard::surface_draw_offset(struct gu_surface* surface, int screenX, int screenY, int offsetX, int offsetY, int intWidth, int intHeight) {
    446         sceGuAlphaFunc( GU_GREATER, 0, 0xff );
    447         sceGuEnable( GU_ALPHA_TEST );
    448         sceGuTexFunc(GU_TFX_BLEND,GU_TCC_RGBA);
    449         sceGuTexEnvColor(0xFF000000);
    450         sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 );
    451         sceGuEnable(GU_BLEND);
    452         if (surface->paletteSize == 256) {      // 8-bit
    453                 sceGuClutMode(GU_PSM_8888, 0, 0xFF, 0);
    454                 sceGuClutLoad(32, surface->palette); // upload 32*8 entries (256)
    455                 sceGuTexMode(GU_PSM_T8, 0, 0, 0);   // 8-bit image
    456         } else if (surface->paletteSize == 16) {        // 4-bit
    457                 sceGuClutMode(GU_PSM_8888, 0, 0x0F, 0);
    458                 sceGuClutLoad(2, surface->palette); // upload 2*8 entries (16)
    459                 sceGuTexMode(GU_PSM_T4, 0, 0, 0);   // 4-bit image
    460         } else {        // 32-bit
    461                 sceGuTexMode(GU_PSM_8888,0,0,GU_FALSE);
    462         }
    463         sceGuTexImage(0,surface->surface_width, surface->surface_height,surface->surface_width, surface->texture);
    464         sceGuTexFunc(GU_TFX_MODULATE,GU_TCC_RGBA);
    465 
    466         Vertex* c_vertices = (Vertex*)sceGuGetMemory(2 * sizeof(Vertex));
    467 
    468         c_vertices[0].u                 = offsetX;
    469         c_vertices[0].v                 = offsetY;
    470         c_vertices[0].x                 = _moved_x + screenX;
    471         c_vertices[0].y                 = _moved_y + screenY;
    472         c_vertices[0].z                 = 0;
    473         c_vertices[0].color     = 0xFFFFFFFF;
    474 
    475         c_vertices[1].u                 = offsetX + intWidth;
    476         c_vertices[1].v                 = offsetY + intHeight;
    477         c_vertices[1].x                 = _moved_x + screenX + intWidth;
    478         c_vertices[1].y                 = _moved_y + screenY + intHeight;
    479         c_vertices[1].z                 = 0;
    480         c_vertices[1].color     = 0xFFFFFFFF;
    481 
    482         sceGuDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,0,c_vertices);
    483 
    484         sceGuDisable( GU_BLEND );
    485         sceGuDisable( GU_ALPHA_TEST );
    486 }
    487 
    488 /* load all the guibits that make up the OSK */
     262/* load the keyboard into memory */
    489263bool PSPKeyboard::load() {
    490         unsigned char *temp_texture = NULL;
    491         uint32 *temp_palette = NULL;
    492         int a;
     264        DEBUG_ENTER_FUNC();
    493265
    494         if (_init)
     266        if (_init) {
     267                PSP_DEBUG_PRINT("keyboard already loaded into memory\n");
     268                DEBUG_EXIT_FUNC();
    495269                return true;
     270        }
    496271
    497272        // For the shell, we must use a hack
    498273#ifdef PSP_KB_SHELL
     
    500275#else /* normal mode */
    501276        Common::FSNode node(".");                               // Look in current directory
    502277#endif
    503 #ifdef PSP_KB_DEBUG
    504         fprintf(stderr, "path = %s\n", node.getPath().c_str());
    505 #endif
     278        PSP_DEBUG_PRINT("path[%s]\n", node.getPath().c_str());
    506279
    507280        Common::Archive *fileArchive = NULL;
    508281        Common::Archive *zipArchive = NULL;
    509282        Common::SeekableReadStream * file = 0;
    510283
    511284        if (node.getChild("kbd").exists() && node.getChild("kbd").isDirectory()) {
    512 #ifdef PSP_KB_DEBUG
    513                 fprintf(stderr, "found directory ./kbd\n");
    514 #endif
     285                PSP_DEBUG_PRINT("found directory ./kbd\n");
    515286                fileArchive = new Common::FSDirectory(node.getChild("kbd"));
    516287        }
    517288        if (node.getChild("kbd.zip").exists()) {
    518 #ifdef PSP_KB_DEBUG
    519                 fprintf(stderr, "found kbd.zip\n");
    520 #endif
     289                PSP_DEBUG_PRINT("found kbd.zip\n");
    521290                zipArchive  = Common::makeZipArchive(node.getChild("kbd.zip"));
    522291        }
    523292
    524         // Loop through different png images
    525         for (a = 0; a < guiStringsSize; a++) {
     293        int i;
     294       
     295        // Loop through all png images
     296        for (i = 0; i < guiStringsSize; i++) {
    526297                uint32 height = 0, width = 0, paletteSize = 0;
    527298
    528 #ifdef PSP_KB_DEBUG
    529                 fprintf(stderr, "load(): Opening %s.\n", _guiStrings[a]);
    530 #endif
     299                PSP_DEBUG_PRINT("Opening %s.\n", _guiStrings[i]);
    531300
    532301                // Look for the file in the kbd directory
    533                 if (fileArchive && fileArchive->hasFile(_guiStrings[a])) {
     302                if (fileArchive && fileArchive->hasFile(_guiStrings[i])) {
     303                        PSP_DEBUG_PRINT("found it in kbd directory.\n");
    534304
    535 #ifdef PSP_KB_DEBUG
    536                         fprintf(stderr, "load(): found it in kbd directory.\n");
    537 #endif
    538 
    539                         file = fileArchive->createReadStreamForMember(_guiStrings[a]);
     305                        file = fileArchive->createReadStreamForMember(_guiStrings[i]);
    540306                        if (!file) {
    541                                 fprintf(stderr, "load(): Can't open kbd/%s for keyboard. No keyboard will load.\n", _guiStrings[a]);
     307                                PSP_ERROR("Can't open kbd/%s for keyboard. No keyboard will load.\n", _guiStrings[i]);
    542308                                goto ERROR;
    543309                        }
    544310                }
    545311                // We didn't find it. Look for it in the zip file
    546                 else if (zipArchive && zipArchive->hasFile(_guiStrings[a])) {
     312                else if (zipArchive && zipArchive->hasFile(_guiStrings[i])) {
     313                        PSP_DEBUG_PRINT("found it in kbd.zip.\n");
    547314
    548 #ifdef PSP_KB_DEBUG
    549                         fprintf(stderr, "load(): found it in kbd.zip.\n");
    550 #endif
    551 
    552                         file = zipArchive->createReadStreamForMember(_guiStrings[a]);
     315                        file = zipArchive->createReadStreamForMember(_guiStrings[i]);
    553316                        if (!file) {
    554                                 fprintf(stderr, "Can't open %s in kbd.zip for keyboard. No keyboard will load.\n", _guiStrings[a]);
     317                                PSP_ERROR("Can't open %s in kbd.zip for keyboard. No keyboard will load.\n", _guiStrings[i]);
    555318                                goto ERROR;
    556319                        }
    557320                } else {        // Couldn't find the file
    558                         fprintf(stderr, "load(): Can't find %s for keyboard. No keyboard will load.\n", _guiStrings[a]);
     321                        PSP_ERROR("Can't find %s for keyboard. No keyboard will load.\n", _guiStrings[i]);
    559322                        goto ERROR;
    560323                }
    561324
    562                 if (get_png_image_size(file, &width, &height, &paletteSize) == 0) { // Check image size and palette size
     325                if (getPngImageSize(file, &width, &height, &paletteSize) == 0) { // Check image size and palette size
    563326                        // Allocate memory for image
    564 #ifdef PSP_KB_DEBUG
    565                         fprintf(stderr, "load(): width=%d, height=%d, paletteSize=%d\n", width, height, paletteSize);
    566 #endif
    567 
     327                        PSP_DEBUG_PRINT("width[%d], height[%d], paletteSize[%d]\n", width, height, paletteSize);
     328                        _buffers[i].setSize(width, height, Buffer::kSizeByTextureSize);
     329                       
    568330                        if (paletteSize) {      // 8 or 4-bit image
    569                                 uint32 textureSize = 0;
    570 
    571331                                if (paletteSize <= 16) { // 4 bit
    572                                         paletteSize = 16;
    573                                         textureSize = (width * height)>>1;
     332                                        _buffers[i].setPixelFormat(PSPPixelFormat::Type_Palette_4bit);
     333                                        _palettes[i].setPixelFormats(PSPPixelFormat::Type_4444, PSPPixelFormat::Type_Palette_4bit);
     334                                        paletteSize = 16;                                       
    574335                                } else if (paletteSize <= 256){                 // 8-bit image
    575336                                        paletteSize = 256;
    576                                         textureSize = width * height;
     337                                        _buffers[i].setPixelFormat(PSPPixelFormat::Type_Palette_8bit);
     338                                        _palettes[i].setPixelFormats(PSPPixelFormat::Type_4444, PSPPixelFormat::Type_Palette_8bit);
    577339                                } else {
    578                                         fprintf(stderr, "Error: palette of %d too big!\n", paletteSize);
     340                                        PSP_ERROR("palette of %d too big!\n", paletteSize);
    579341                                        goto ERROR;
    580342                                }
    581 #ifdef PSP_KB_DEBUG
    582                                 fprintf(stderr, "load(): allocating %d bytes for texture and %d for palette\n", textureSize, paletteSize*4);
    583 #endif
    584                                 temp_texture = (u8 *)malloc(textureSize);
    585                                 temp_palette = (uint32 *)memalign(16, paletteSize<<2);
    586                                 memset(temp_palette, 0, paletteSize<<2);        // Set to 0 since we might only fill some of it
     343                               
    587344                        } else {                                // 32-bit image
    588                                 temp_texture = (unsigned char *)malloc((width * height)<<2);
     345                                _buffers[i].setPixelFormat(PSPPixelFormat::Type_8888);
    589346                        }
     347                       
     348                        _buffers[i].allocate();
     349                        _palettes[i].allocate();
    590350
    591351                        // Try to load the image
    592352                        file->seek(0);  // Go back to start
    593353
    594                         if (load_png_image(file, temp_texture, temp_palette) != 0)
     354                        if (loadPngImage(file, _buffers[i], _palettes[i]) != 0)
    595355                                goto ERROR;
    596356                        else {  // Success
    597 #ifdef PSP_KB_DEBUG
    598                                 fprintf(stderr, "Managed to load the image.\n");
    599 #endif
    600                                 // we need to store the texture in an image of width and heights of 2^n sizes
    601                                 _keyTextures[a].texture_width   = width;                                                // original size
    602                                 _keyTextures[a].texture_height  = height;
    603                                 _keyTextures[a].surface_width   = convert_pow2(width);          // converted size
    604                                 _keyTextures[a].surface_height  = convert_pow2(height);
    605                                 _keyTextures[a].palette                 = temp_palette;
    606                                 _keyTextures[a].paletteSize     = paletteSize;
     357                                PSP_DEBUG_PRINT("Managed to load the image\n");
    607358
    608                                 uint32 size;
    609 
    610                                 if (paletteSize == 16)                  // 4 bit
    611                                         size = (_keyTextures[a].surface_width * _keyTextures[a].surface_height)>>1;
    612                                 else if (paletteSize == 256)    // 8-bit
    613                                         size = _keyTextures[a].surface_width * _keyTextures[a].surface_height;
    614                                 else                                                    // 32 bit
    615                                         size = (_keyTextures[a].surface_width * _keyTextures[a].surface_height)<<2;
    616 
    617 #ifdef PSP_KB_DEBUG
    618                                 fprintf(stderr, "load(): perm texture width=%d, height=%d, size=%d\n", _keyTextures[a].surface_width, _keyTextures[a].surface_height, size);
    619 #endif
    620                                 _keyTextures[a].texture = (unsigned char *)memalign(16, size);  // Allocate memory
    621 
    622                                 block_copy(&_keyTextures[a], temp_texture);                     // Copy temp texture to permanent texture
    623 
    624359                                if (paletteSize == 16)          // 4-bit
    625                                         flipNibbles(&_keyTextures[a]);
     360                                        _buffers[i].flipNibbles();
    626361
    627                                 free(temp_texture);
    628 
    629362                                delete file;
    630363                        }
    631364                }
    632                 else
     365                else {
     366                        PSP_ERROR("couldn't obtain PNG image size\n");
    633367                        goto ERROR;
     368                }
    634369        } /* for loop */
     370       
    635371        _init = true;
    636372
    637373        delete fileArchive;
    638374        delete zipArchive;
    639375
     376        DEBUG_EXIT_FUNC();
    640377        return true;
    641378
    642379ERROR:
    643380
    644         // Error .. Couldn't get png info from one of the needed files
    645         free(temp_texture);
    646381        delete file;
    647382        delete fileArchive;
    648383        delete zipArchive;
    649384
    650         for (int b = 0; b < a; b++) {
    651                 free(_keyTextures[b].texture);
    652                 free(_keyTextures[b].palette);
    653                 _keyTextures[b].texture = NULL;
     385        for (int j = 0; j < i; j++) {
     386                _buffers[j].deallocate();
     387                _palettes[j].deallocate();
    654388        }
    655389        _init = false;
     390       
     391        DEBUG_EXIT_FUNC();
    656392        return false;
    657393}
    658394
    659 // Copy texture from regular size image to power of 2 size image
    660 //
    661 void PSPKeyboard::block_copy(gu_surface* surface, u8 *texture) {
    662         u32 stride = 0, width = 0;
    663 
    664         switch(surface->paletteSize) {
    665         case 16:        // 4-bit
    666                 width = surface->texture_width >> 1;
    667                 stride = (surface->surface_width - surface->texture_width)>>1;
    668                 break;
    669         case 256:       // 8-bit
    670                 width = surface->texture_width;
    671                 stride = surface->surface_width - surface->texture_width;
    672                 break;
    673         case 0:         // 32-bit
    674                 width = surface->texture_width << 2;
    675                 stride = (surface->surface_width - surface->texture_width)<<2;
    676                 break;
    677         default:
    678                 fprintf(stderr, "Error in block_copy: bad value in paletteSize = %d\n", surface->paletteSize);
    679                 return;
    680         }
    681 
    682         u8 *src  = texture;
    683         u8 *dest = surface->texture;
    684 
    685         for (unsigned int y = 0; y < surface->texture_height; y++) {
    686                 memcpy(dest, src, width);
    687                 dest += width;
    688                 src += width;
    689 
    690                 // skip at the end of each line
    691                 if (stride > 0) {
    692                         dest += stride;
    693                 }
    694         }
    695 }
    696 
    697 // Convert 4 bit images to match weird PSP format
    698 //
    699 void PSPKeyboard::flipNibbles(gu_surface* surface) {
    700         u32 *dest = (u32 *)surface->texture;
    701 
    702         for (u32 y = 0; y < surface->texture_height; y++) {
    703                 for (u32 x = 0; x < (surface->surface_width >> 3); x++) {
    704                         u32 val = *dest;
    705                         *dest++ = ((val >> 4) & 0x0F0F0F0F) | ((val << 4) & 0xF0F0F0F0);
    706                 }
    707         }
    708 
    709 }
    710 
    711 
    712395static void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg) {
    713396        // ignore PNG warnings
    714397}
    715398
    716399/* Get the width and height of a png image */
    717 int PSPKeyboard::get_png_image_size(Common::SeekableReadStream *file, uint32 *png_width, uint32 *png_height, u32 *paletteSize) {
     400int PSPKeyboard::getPngImageSize(Common::SeekableReadStream *file, uint32 *png_width, uint32 *png_height, u32 *paletteSize) {
     401        DEBUG_ENTER_FUNC();
     402       
    718403        png_structp png_ptr;
    719404        png_infop info_ptr;
    720405        unsigned int sig_read = 0;
     
    723408
    724409        png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    725410        if (png_ptr == NULL) {
     411                DEBUG_EXIT_FUNC();
    726412                return -1;
    727413        }
    728414        png_set_error_fn(png_ptr, (png_voidp) NULL, (png_error_ptr) NULL, user_warning_fn);
    729415        info_ptr = png_create_info_struct(png_ptr);
    730416        if (info_ptr == NULL) {
    731417                png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
     418                DEBUG_EXIT_FUNC();
    732419                return -1;
    733420        }
    734421        // Set the png lib to use our read function
     
    746433
    747434        *png_width = width;
    748435        *png_height = height;
     436       
     437        DEBUG_EXIT_FUNC();
    749438        return 0;
    750439}
    751440
    752441// Load a texture from a png image
    753442//
    754 int PSPKeyboard::load_png_image(Common::SeekableReadStream *file, unsigned char *ImageBuffer, uint32 *palette) {
     443int PSPKeyboard::loadPngImage(Common::SeekableReadStream *file, Buffer &buffer, Palette &palette) {
     444        DEBUG_ENTER_FUNC();
     445       
    755446        png_structp png_ptr;
    756447        png_infop info_ptr;
    757448        unsigned int sig_read = 0;
    758449        png_uint_32 width, height;
    759450        int bit_depth, color_type, interlace_type;
    760         size_t x, y;
     451        size_t y;
    761452
    762453        png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    763454        if (png_ptr == NULL) {
    764                 fprintf(stderr, "load_png_image(): Error: couldn't create read struct to load keyboard.\n");
     455                PSP_ERROR("Couldn't create read struct to load keyboard\n");
     456                DEBUG_EXIT_FUNC();
    765457                return -1;
    766458        }
    767459        // Use dummy error function
     
    769461
    770462        info_ptr = png_create_info_struct(png_ptr);
    771463        if (info_ptr == NULL) {
     464                PSP_ERROR("Couldn't create info struct to load keyboard\n");
    772465                png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
     466                DEBUG_EXIT_FUNC();
    773467                return -1;
    774468        }
    775469
    776         // Set the png lib to use our read function
     470        // Set the png lib to use our customized read function
    777471        png_set_read_fn(png_ptr, (void *)file, pngReadStreamRead);
    778472
    779473        png_set_sig_bytes(png_ptr, sig_read);
     
    784478        png_set_strip_16(png_ptr);
    785479
    786480        if (color_type == PNG_COLOR_TYPE_PALETTE) {
    787                 // We copy the palette
    788                 uint32 *dstPal = palette;
     481                // Copy the palette
    789482                png_colorp srcPal = info_ptr->palette;
    790483                for(int i=0; i < info_ptr->num_palette; i++) {
    791484                        unsigned char alphaVal = (i < info_ptr->num_trans) ? info_ptr->trans[i] : 0xFF; // Load alpha if it's there
    792                         *dstPal++ = GU_ARGB(alphaVal, srcPal->red, srcPal->green, srcPal->blue);
     485                        palette.setSingleColorRGBA(i, srcPal->red, srcPal->green, srcPal->blue, alphaVal);
    793486                        srcPal++;
    794487                }
    795 
    796                 unsigned char *line = (unsigned char*) malloc(info_ptr->rowbytes);
    797                 if (!line) {
    798                         png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
    799                         return -1;
    800                 }
    801 
    802                 for (y = 0; y < height; y++) {
    803                         png_read_row(png_ptr, line, png_bytep_NULL);
    804                         memcpy(&ImageBuffer[y * info_ptr->rowbytes], line, info_ptr->rowbytes);
    805                 }
    806 
    807                 free(line);
    808488        } else {        // Not a palettized image
     489                // Round up grayscale images
    809490                if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
    810491                // Convert trans channel to alpha for 32 bits
    811492                if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
     493                // Filler for alpha?
    812494                png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
     495        }       
    813496
    814                 u32* line = (u32*) malloc(width<<2);
    815                 if (!line) {
    816                         png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
    817                         return -1;
    818                 }
     497        unsigned char *line = (unsigned char*) malloc(info_ptr->rowbytes);
     498        if (!line) {
     499                png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
     500                PSP_ERROR("Couldn't allocate line\n");
     501                DEBUG_EXIT_FUNC();
     502                return -1;
     503        }
    819504
    820                 u32* Image = (u32 *)ImageBuffer;
    821                 for (y = 0; y < height; y++) {
    822                         png_read_row(png_ptr, (u8*) line, png_bytep_NULL);
    823                         for (x = 0; x < width; x++) {
    824                                 Image[y*width + x] = line[x];
    825                         }
    826                 }
    827 
    828                 free(line);
     505        for (y = 0; y < height; y++) {
     506                png_read_row(png_ptr, line, png_bytep_NULL);
     507                buffer.copyFromRect(line, info_ptr->rowbytes, 0, y, width, 1);  // Copy into buffer
     508                //memcpy(buffer.getPixels()[y * buffer.getWidthInBytes()], line, info_ptr->rowbytes);
    829509        }
    830510
     511        free(line);
     512       
    831513        png_read_end(png_ptr, info_ptr);
    832514        png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
    833515
     516        DEBUG_EXIT_FUNC();
    834517        return 0;
    835518}
    836519
    837 // Function to get the lowest power of 2 higher than our image size
    838 //
    839 uint32 PSPKeyboard::convert_pow2(uint32 size) {
    840         uint32 pow_counter = 0;
     520// Defines for working with PSP buttons
     521#define CHANGED(x)       (_buttonsChanged & (x))
     522#define PRESSED(x)   ((_buttonsChanged & (x)) && (pad.Buttons & (x)))
     523#define UNPRESSED(x) ((_buttonsChanged & (x)) && !(pad.Buttons & (x)))
     524#define DOWN(x)          (pad.Buttons & (x))
     525#define UP(x)            (!(pad.Buttons & (x)))
     526#define PSP_DPAD         (PSP_CTRL_DOWN|PSP_CTRL_UP|PSP_CTRL_LEFT|PSP_CTRL_RIGHT)
     527#define PSP_4BUTTONS (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE | PSP_CTRL_TRIANGLE | PSP_CTRL_SQUARE)
    841528
    842         for (; pow_counter < 32; pow_counter++) {
    843                 // Find the first value which is higher
    844                 if ((size >> pow_counter) == 0) {
    845                         // take already good values into account
    846                         if (((uint32) 1 << pow_counter) != size)
    847                                 return ((uint32)1 << pow_counter);
    848                         else
    849                                 return ((uint32)1 << (pow_counter-1));
     529/*
     530 *  Attempts to read a character from the controller
     531 *  Uses the state machine.
     532 *  returns whether we have an event
     533 */
     534bool PSPKeyboard::processInput(Common::Event &event, SceCtrlData &pad) {
     535        DEBUG_ENTER_FUNC();
     536       
     537        bool haveEvent = false;         // Whether we have an event for the event manager to process
     538        event.kbd.flags = 0;
     539       
     540        _buttonsChanged = _prevButtons ^ pad.Buttons;
     541
     542        if (!_init)                                     // In case we never had init
     543                return false;
     544        if (_state == kInvisible)       // Return if we're invisible
     545                return false;   
     546        if (_state != kMove && PRESSED(PSP_CTRL_SELECT)) {
     547                _lastState = _state;
     548                _state = kMove;                 // Check for move or visible state
     549        }
     550        else if (CHANGED(PSP_CTRL_START)) {             // Handle start button: enter, make KB invisible
     551                event.kbd.ascii = '\r';
     552                event.kbd.keycode = Common::KEYCODE_RETURN;
     553                event.type = DOWN(PSP_CTRL_START) ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP;
     554                haveEvent = true;
     555                _dirty = true;
     556                if (UP(PSP_CTRL_START))
     557                        _state = kInvisible;                    // Make us invisible if unpressed
     558        }       
     559        // Check for being in state of moving the keyboard onscreen or pressing select
     560        else if (_state == kMove)
     561                handleMoveState(pad);
     562        else if (_state == kDefault)
     563                haveEvent = handleDefaultState(event, pad);
     564        else if (_state == kCornersSelected)
     565                haveEvent = handleCornersSelectedState(event, pad);
     566        else if (_state == kRTriggerDown)
     567                handleRTriggerDownState(pad);   // Deal with trigger states
     568        else if (_state == kLTriggerDown)
     569                handleLTriggerDownState(pad);   // Deal with trigger states
     570
     571        _prevButtons = pad.Buttons;
     572       
     573        DEBUG_EXIT_FUNC();
     574        return haveEvent;
     575}
     576
     577void PSPKeyboard::handleMoveState(SceCtrlData &pad) {
     578        DEBUG_ENTER_FUNC();
     579        if (UNPRESSED(PSP_CTRL_SELECT)) {
     580                // Toggle between visible and invisible
     581                _state = (_lastState == kInvisible) ? kDefault : kInvisible;           
     582                _dirty = true;
     583
     584                if (_moved) {                                   // We moved the keyboard. Keep the keyboard onscreen anyway
     585                        _state = kDefault;
     586                        _moved = false;                         // reset moved flag
    850587                }
     588        } else if (DOWN(PSP_DPAD)) {            // How we move the KB onscreen
     589                _moved = true;
     590                _dirty = true;
     591
     592                if (DOWN(PSP_CTRL_DOWN))
     593                        increaseKeyboardLocationY(5);
     594                else if (DOWN(PSP_CTRL_UP))
     595                        increaseKeyboardLocationY(-5);
     596                else if (DOWN(PSP_CTRL_LEFT))
     597                        increaseKeyboardLocationX(-5);
     598                else  /* DOWN(PSP_CTRL_RIGHT) */
     599                        increaseKeyboardLocationX(5);
    851600        }
    852         return 0;
     601        DEBUG_EXIT_FUNC();     
    853602}
    854603
     604bool PSPKeyboard::handleDefaultState(Common::Event &event, SceCtrlData &pad) {
     605        DEBUG_ENTER_FUNC();
     606        bool haveEvent = false;
     607       
     608        if (PRESSED(PSP_CTRL_LTRIGGER))                         // Don't say we used up the input
     609                _state = kLTriggerDown;         
     610        else if (PRESSED(PSP_CTRL_RTRIGGER))    // Don't say we used up the input
     611                _state = kRTriggerDown;         
     612        else if (CHANGED(PSP_4BUTTONS))                 // We only care about the 4 buttons
     613                haveEvent = getInputChoice(event, pad);
     614        else if (!DOWN(PSP_4BUTTONS))                           // Must be up to move cursor
     615                getCursorMovement(pad);
     616       
     617        DEBUG_EXIT_FUNC();
     618        return haveEvent;
     619}
     620
     621bool PSPKeyboard::handleCornersSelectedState(Common::Event &event, SceCtrlData &pad) {
     622        DEBUG_ENTER_FUNC();
     623        // We care about 4 buttons + triggers (for letter selection)
     624        bool haveEvent = false;
     625       
     626        if (CHANGED(PSP_4BUTTONS | PSP_CTRL_RTRIGGER | PSP_CTRL_LTRIGGER))
     627                haveEvent = getInputChoice(event, pad);
     628        if (!DOWN(PSP_4BUTTONS | PSP_CTRL_RTRIGGER | PSP_CTRL_LTRIGGER)) // Must be up to move cursor
     629                getCursorMovement(pad)
     630       
     631        DEBUG_EXIT_FUNC();     
     632        return haveEvent;
     633}
     634
     635bool PSPKeyboard::getInputChoice(Common::Event &event, SceCtrlData &pad) {
     636        DEBUG_ENTER_FUNC();
     637        int innerChoice;
     638        bool haveEvent = false;
     639
     640        if (UNPRESSED(PSP_CTRL_TRIANGLE)) {
     641                innerChoice = 0;
     642                event.type = Common::EVENT_KEYUP;                       // We give priority to key_up
     643        } else if (UNPRESSED(PSP_CTRL_CIRCLE)) {
     644                innerChoice = 1;
     645                event.type = Common::EVENT_KEYUP;                       // We give priority to key_up
     646        } else if (UNPRESSED(PSP_CTRL_CROSS)) {
     647                innerChoice = 2;
     648                event.type = Common::EVENT_KEYUP;                       // We give priority to key_up
     649        } else if (UNPRESSED(PSP_CTRL_SQUARE)) {
     650                innerChoice = 3;
     651                event.type = Common::EVENT_KEYUP;                       // We give priority to key_up
     652        } else if (UNPRESSED(PSP_CTRL_LTRIGGER) && _state == kCornersSelected) {
     653                innerChoice = 4;
     654                event.type = Common::EVENT_KEYUP;                       // We give priority to key_up
     655        } else if (UNPRESSED(PSP_CTRL_RTRIGGER) && _state == kCornersSelected) {
     656                innerChoice = 5;
     657                event.type = Common::EVENT_KEYUP;                       // We give priority to key_up
     658        } else if (PRESSED(PSP_CTRL_TRIANGLE)) {
     659                innerChoice = 0;
     660                event.type = Common::EVENT_KEYDOWN;
     661        } else if (PRESSED(PSP_CTRL_CIRCLE)) {
     662                innerChoice = 1;
     663                event.type = Common::EVENT_KEYDOWN;
     664        } else if (PRESSED(PSP_CTRL_CROSS)) {
     665                innerChoice = 2;
     666                event.type = Common::EVENT_KEYDOWN;
     667        } else if (PRESSED(PSP_CTRL_SQUARE)) {
     668                innerChoice = 3;
     669                event.type = Common::EVENT_KEYDOWN;
     670        } else if (PRESSED(PSP_CTRL_LTRIGGER) && _state == kCornersSelected) {
     671                innerChoice = 4;
     672                event.type = Common::EVENT_KEYDOWN;                     // We give priority to key_up
     673        } else  /* (PRESSED(PSP_CTRL_RTRIGGER)) && _state == kCornersSelected */ {
     674                innerChoice = 5;
     675                event.type = Common::EVENT_KEYDOWN;                     // We give priority to key_up
     676        }
     677
     678        #define IS_UPPERCASE(x) ((x) >= (unsigned short)'A' && (x) <= (unsigned short)'Z')
     679        #define TO_LOWER(x)             ((x) += 'a'-'A')
     680
     681        //Now grab the value out of the array
     682        short choice = _modeChar[_mode][_oldCursor][innerChoice];
     683
     684        event.kbd.ascii = choice <= 255 ? choice : 0;
     685
     686        // Handle upper-case which is missing in Common::KeyCode
     687        if (IS_UPPERCASE(choice)) {
     688                event.kbd.keycode = (Common::KeyCode) TO_LOWER(choice);
     689                event.kbd.flags = Common::KBD_SHIFT;
     690        } else
     691                event.kbd.keycode = (Common::KeyCode) choice;
     692
     693        haveEvent = (choice != Common::KEYCODE_INVALID) ? true : false; // We have an event/don't if it's invalid
     694
     695        DEBUG_EXIT_FUNC();
     696        return haveEvent;
     697}
     698
     699void PSPKeyboard::getCursorMovement(SceCtrlData &pad) {
     700        DEBUG_ENTER_FUNC();
     701        CursorDirections cursor;
     702       
     703        // Find where the cursor is pointing
     704        cursor = kCenter;
     705        _state = kDefault;
     706
     707        if (DOWN(PSP_DPAD)) {
     708                _state = kCornersSelected;                     
     709
     710                if (DOWN(PSP_CTRL_UP))
     711                        cursor = kUp;
     712                else if (DOWN(PSP_CTRL_RIGHT))
     713                        cursor = kRight;
     714                else if (DOWN(PSP_CTRL_DOWN))
     715                        cursor = kDown;
     716                else if (DOWN(PSP_CTRL_LEFT))
     717                        cursor = kLeft;
     718        }
     719       
     720        if (cursor != _oldCursor) { //If we've moved, update dirty and return
     721                _dirty = true;
     722                _oldCursor = cursor;
     723        }
     724        DEBUG_EXIT_FUNC();
     725}
     726
     727void PSPKeyboard::handleLTriggerDownState(SceCtrlData &pad) {
     728        DEBUG_ENTER_FUNC();
     729        if (UNPRESSED(PSP_CTRL_LTRIGGER)) {
     730                _dirty = true;
     731
     732                if(_mode < 2)
     733                        _mode = 2;
     734                else
     735                        _mode = (_mode == 2) ? 3 : 2;
     736
     737                _state = kDefault;
     738        }
     739        DEBUG_EXIT_FUNC();
     740}
     741
     742void PSPKeyboard::handleRTriggerDownState(SceCtrlData &pad) {
     743        DEBUG_ENTER_FUNC();
     744        if (UNPRESSED(PSP_CTRL_RTRIGGER)) {
     745                _dirty = true;
     746
     747                if(_mode > 1)
     748                        _mode = 0;
     749                else
     750                        _mode = (_mode == 0) ? 1 : 0;
     751
     752                _state = kDefault;
     753        }
     754        DEBUG_EXIT_FUNC();
     755}
  • backends/platform/psp/osys_psp.h

     
    3232#include "sound/mixer_intern.h"
    3333#include "backends/base-backend.h"
    3434#include "backends/fs/psp/psp-fs-factory.h"
     35#include "backends/platform/psp/display_client.h"
     36#include "backends/platform/psp/default_display_client.h"
     37#include "backends/platform/psp/cursor.h"
    3538#include "backends/platform/psp/pspkeyboard.h"
     39#include "backends/platform/psp/display_manager.h"
     40#include "backends/platform/psp/input.h"
    3641
    3742#include <SDL.h>
    3843
    39 #include <pspctrl.h>
    40 
    41 enum GraphicModeID {
    42         CENTERED_320X200,
    43         CENTERED_435X272,
    44         STRETCHED_480X272,
    45         CENTERED_362X272
    46 };
    47 
    4844class OSystem_PSP : public BaseBackend {
    49 public:
    50         static const OSystem::GraphicsMode s_supportedGraphicsModes[];
    51         static OSystem *instance();
    52 
    53 protected:
    54         struct Vertex {
    55                 float u,v;
    56                 float x,y,z;
    57         };
    58 
    59         uint16  _screenWidth;
    60         uint16  _screenHeight;
    61         uint16  _overlayWidth;
    62         uint16  _overlayHeight;
    63         byte    *_offscreen;
    64         OverlayColor  *_overlayBuffer;
    65         uint16  _palette[256];
    66         bool    _overlayVisible;
    67         uint32  _shakePos;
    68         uint32  _lastScreenUpdate;
    69 
    70         Graphics::Surface _framebuffer;
    71 
    72         bool    _mouseVisible;
    73         int     _mouseX, _mouseY;
    74         int _dpadX, _dpadY;
    75         int     _mouseWidth, _mouseHeight;
    76         int     _mouseHotspotX, _mouseHotspotY;
    77         byte    _mouseKeyColour;
    78         byte    *_mouseBuf;
    79         bool    _cursorPaletteDisabled;
    80 
    81         int _graphicMode;
    82         unsigned short* _clut;
    83         PSPKeyboard *_keyboard;
    84 
    85         uint32  _prevButtons;
    86         uint32  _lastPadCheck;
    87         uint32  _padAccel;
    88 
    89         SceCtrlData pad;
    90 
     45private:
     46       
    9147        Common::SaveFileManager *_savefile;
    9248        Audio::MixerImpl *_mixer;
    9349        Common::TimerManager *_timer;
    9450
    95         Common::KeyCode getDpadEvent(int x, int y);
     51        // All needed sub-members
     52        Screen _screen;
     53        Overlay _overlay;
     54        Cursor _cursor;
     55        DisplayManager _displayManager;
     56        PSPKeyboard _keyboard;
     57        InputHandler _inputHandler;
    9658
     59        void initSDL();
     60
    9761public:
    98         OSystem_PSP();
    99         virtual ~OSystem_PSP();
     62        OSystem_PSP() : _savefile(0), _mixer(0), _timer(0) {}
     63        ~OSystem_PSP();
    10064
    101         virtual void initBackend();
    102 
    103         virtual bool hasFeature(Feature f);
    104         virtual void setFeatureState(Feature f, bool enable);
    105         virtual bool getFeatureState(Feature f);
    106 
    107         virtual const GraphicsMode *getSupportedGraphicsModes() const;
    108         virtual int getDefaultGraphicsMode() const;
    109         virtual bool setGraphicsMode(int mode);
     65        static OSystem *instance();
     66       
     67        void initBackend();
     68       
     69        // Feature related
     70        bool hasFeature(Feature f);
     71        void setFeatureState(Feature f, bool enable);
     72        bool getFeatureState(Feature f);
     73       
     74        // Graphics related
     75        const GraphicsMode *getSupportedGraphicsModes() const;
     76        int getDefaultGraphicsMode() const;
     77        bool setGraphicsMode(int mode);
    11078        bool setGraphicsMode(const char *name);
    111         virtual int getGraphicsMode() const;
     79        int getGraphicsMode() const;
     80#ifdef USE_RGB_COLOR
     81        virtual Graphics::PixelFormat getScreenFormat() const;
     82        virtual Common::List<Graphics::PixelFormat> getSupportedFormats();
     83#endif
     84       
     85        // Screen size
     86        void initSize(uint width, uint height, const Graphics::PixelFormat *format);
     87        int16 getWidth();
     88        int16 getHeight();
     89       
     90        // Palette related
     91        void setPalette(const byte *colors, uint start, uint num);
     92        void grabPalette(byte *colors, uint start, uint num);
     93        void setCursorPalette(const byte *colors, uint start, uint num);
     94        void disableCursorPalette(bool disable);
     95       
     96        // Screen related
     97        void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h);
     98        Graphics::Surface *lockScreen();
     99        void unlockScreen();
     100        void updateScreen();
     101        void setShakePos(int shakeOffset);
     102       
     103        // Overlay related
     104        void showOverlay();
     105        void hideOverlay();
     106        void clearOverlay();
     107        void grabOverlay(OverlayColor *buf, int pitch);
     108        void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
     109        int16 getOverlayHeight();
     110        int16 getOverlayWidth();
     111        Graphics::PixelFormat getOverlayFormat() const { return Graphics::createPixelFormat<4444>(); }
     112       
     113        // Mouse related
     114        bool showMouse(bool visible);
     115        void warpMouse(int x, int y);
     116        void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format);
    112117
    113         virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format);
    114         virtual int16 getWidth();
    115         virtual int16 getHeight();
     118        // Events and input
     119        bool pollEvent(Common::Event &event);
     120        bool processInput(Common::Event &event);
    116121
    117         virtual void setPalette(const byte *colors, uint start, uint num);
    118         virtual void grabPalette(byte *colors, uint start, uint num);
    119         virtual void setCursorPalette(const byte *colors, uint start, uint num);
    120         virtual void disableCursorPalette(bool disable);
    121         virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h);
    122         virtual Graphics::Surface *lockScreen();
    123         virtual void unlockScreen();
    124         virtual void updateScreen();
    125         virtual void setShakePos(int shakeOffset);
     122        // Time
     123        uint32 getMillis();
     124        void delayMillis(uint msecs);
    126125
    127         virtual void showOverlay();
    128         virtual void hideOverlay();
    129         virtual void clearOverlay();
    130         virtual void grabOverlay(OverlayColor *buf, int pitch);
    131         virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
    132         virtual int16 getOverlayHeight();
    133         virtual int16 getOverlayWidth();
    134         virtual Graphics::PixelFormat getOverlayFormat() const { return Graphics::createPixelFormat<4444>(); }
    135 
    136         virtual bool showMouse(bool visible);
    137         virtual void warpMouse(int x, int y);
    138         virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format);
    139 
    140         virtual bool pollEvent(Common::Event &event);
    141         virtual bool processInput(Common::Event &event);
    142 
    143         virtual uint32 getMillis();
    144         virtual void delayMillis(uint msecs);
    145 
     126        // Timer
    146127        typedef int (*TimerProc)(int interval);
    147         virtual void setTimerCallback(TimerProc callback, int interval);
     128        void setTimerCallback(TimerProc callback, int interval);
     129        Common::TimerManager *getTimerManager() { return _timer; }
    148130
    149         virtual MutexRef createMutex(void);
    150         virtual void lockMutex(MutexRef mutex);
    151         virtual void unlockMutex(MutexRef mutex);
    152         virtual void deleteMutex(MutexRef mutex);
     131        // Mutex
     132        MutexRef createMutex(void);
     133        void lockMutex(MutexRef mutex);
     134        void unlockMutex(MutexRef mutex);
     135        void deleteMutex(MutexRef mutex);
    153136
     137        // Sound
    154138        static void mixCallback(void *sys, byte *samples, int len);
    155         virtual void setupMixer(void);
    156 
    157         Common::SaveFileManager *getSavefileManager() { return _savefile; }
     139        void setupMixer(void);
    158140        Audio::Mixer *getMixer() { return _mixer; }
    159         Common::TimerManager *getTimerManager() { return _timer; }
     141       
     142        // Misc
     143        Common::SaveFileManager *getSavefileManager() { return _savefile; }
    160144        FilesystemFactory *getFilesystemFactory() { return &PSPFilesystemFactory::instance(); }
    161145        void getTimeAndDate(TimeDate &t) const;
    162146
    163         virtual void quit();
     147        void quit();
    164148
    165         virtual Common::SeekableReadStream *createConfigReadStream();
    166         virtual Common::WriteStream *createConfigWriteStream();
     149        Common::SeekableReadStream *createConfigReadStream();
     150        Common::WriteStream *createConfigWriteStream();
     151
    167152};
    168153
    169 
    170154#endif /* OSYS_PSP_H */
  • backends/platform/psp/powerman.cpp

     
    2323 *
    2424 */
    2525
     26//#define __PSP_DEBUG_FUNCS__   /* can put this locally too */
     27//#define __PSP_DEBUG_PRINT__
     28#include "backends/platform/psp/trace.h"
     29 
    2630#include <psppower.h>
    2731#include <pspthreadman.h>
    2832
    29 #include "./powerman.h"
    30 #include "./trace.h"
     33#include "backends/platform/psp/powerman.h"
    3134#include "engine.h"
    3235
    3336DECLARE_SINGLETON(PowerManager)
    3437
    35 #ifdef __PSP_DEBUG_SUSPEND__
    36 void PowerManager::debugPM() {
    37         PSPDebugTrace("PM status is %d. Listcount is %d. CriticalCount is %d. ThreadId is %x. Error = %d\n", _PMStatus, _listCounter,
    38                 _criticalCounter, sceKernelGetThreadId(), _error);
     38// Function to debug the Power Manager (we have no output to screen)
     39inline void PowerManager::debugPM() {
     40        PSP_DEBUG_PRINT("PM status[%d]. Listcount[%d]. CriticalCount[%d]. ThreadId[%x]. Error[%d]\n",
     41                                        _PMStatus, _listCounter, _criticalCounter, sceKernelGetThreadId(), _error);
    3942}
    40 #else
    41         #define debugPM()
    42         #define PMStatusSet(x)
    43 #endif /* __PSP_DEBUG_SUSPEND__ */
    4443
    4544
    4645 /*******************************************
     
    4948*
    5049********************************************/
    5150PowerManager::PowerManager() {
    52 
     51        DEBUG_ENTER_FUNC();
     52       
    5353        _flagMutex = NULL;                                      /* Init mutex handle */
    5454        _listMutex = NULL;                                      /* Init mutex handle */
    5555        _condSuspendable = NULL;                        /* Init condition variable */
     
    5757
    5858        _condSuspendable = SDL_CreateCond();
    5959        if (_condSuspendable <= 0) {
    60                 PSPDebugSuspend("PowerManager::PowerManager(): Couldn't create condSuspendable\n");
     60                PSP_ERROR("Couldn't create Suspendable condition variable\n");
    6161        }
    6262
    6363        _condPM = SDL_CreateCond();
    6464        if (_condPM <= 0) {
    65                 PSPDebugSuspend("PowerManager::PowerManager(): Couldn't create condPM\n");
     65                PSP_ERROR("Couldn't create PM condition variable\n");
    6666        }
    6767
    6868        _flagMutex = SDL_CreateMutex();
    6969        if (_flagMutex <= 0) {
    70                 PSPDebugSuspend("PowerManager::PowerManager(): Couldn't create flagMutex\n");
     70                PSP_ERROR("Couldn't create flag Mutex\n");
    7171        }
    7272
    7373        _listMutex = SDL_CreateMutex();
    7474        if (_listMutex <= 0) {
    75                 PSPDebugSuspend("PowerManager::PowerManager(): Couldn't create listMutex\n");
     75                PSP_ERROR("Couldn't create list Mutex\n");
    7676        }
    7777
    7878        _suspendFlag = false;
    79         _criticalCounter = 0;
    80         _pauseFlag = 0; _pauseFlagOld = 0; _pauseClientState = 0;
    81 
    82 #ifdef __PSP_DEBUG_SUSPEND__
     79        _criticalCounter = 0;   // How many are in the critical section
     80        _pauseFlag = 0;
     81        _pauseFlagOld = 0;
     82        _pauseClientState = 0;
    8383        _listCounter = 0;
    8484        PMStatusSet(kInitDone);
    8585        _error = 0;
    86 #endif
     86
     87        DEBUG_EXIT_FUNC();
    8788 }
    8889
    8990/*******************************************
     
    9293*
    9394********************************************/
    9495int PowerManager::registerSuspend(Suspendable *item) {
     96        DEBUG_ENTER_FUNC();
    9597        // Register in list
    96         PSPDebugSuspend("In registerSuspend\n");
    9798        debugPM();
    9899
    99100        if (SDL_mutexP(_listMutex) != 0) {
    100                 PSPDebugTrace("PowerManager::registerSuspend(): Couldn't lock _listMutex %d\n", _listMutex);
     101                PSP_ERROR("Couldn't lock _listMutex[%p]\n", _listMutex);
    101102        }
    102103
    103104        _suspendList.push_front(item);
    104 #ifdef __PSP_DEBUG_SUSPEND__
    105105        _listCounter++;
    106 #endif
    107106
    108107        if (SDL_mutexV(_listMutex) != 0) {
    109                 PSPDebugTrace("PowerManager::registerSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
     108                PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex);
    110109        }
    111 
    112         PSPDebugSuspend("Out of registerSuspend\n");
     110       
    113111        debugPM();
    114112
     113        DEBUG_EXIT_FUNC();
    115114        return 0;
    116115}
    117116
     
    121120*
    122121********************************************/
    123122int PowerManager::unregisterSuspend(Suspendable *item) {
    124 
    125         PSPDebugSuspend("In unregisterSuspend\n");
     123        DEBUG_ENTER_FUNC();
    126124        debugPM();
    127125
    128126         // Unregister from stream list
    129127        if (SDL_mutexP(_listMutex) != 0) {
    130                 PSPDebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
     128                PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex);
    131129        }
    132130
    133131        _suspendList.remove(item);
    134 #ifdef __PSP_DEBUG_SUSPEND__
    135132        _listCounter--;
    136 #endif
    137133
    138134        if (SDL_mutexV(_listMutex) != 0) {
    139                 PSPDebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
     135                PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex);
    140136        }
    141137
    142         PSPDebugSuspend("Out of unregisterSuspend\n");
     138        PSP_DEBUG_PRINT("Out of unregisterSuspend\n");
    143139        debugPM();
    144140
     141        DEBUG_EXIT_FUNC();
    145142        return 0;
    146143 }
    147144
     
    151148*
    152149********************************************/
    153150 PowerManager::~PowerManager() {
    154 
    155 #ifdef __PSP_DEBUG_SUSPEND__
     151        DEBUG_ENTER_FUNC();
     152 
    156153        PMStatusSet(kDestroyPM);
    157 #endif
    158154
    159155        SDL_DestroyCond(_condSuspendable);
    160156        _condSuspendable = 0;
     
    167163
    168164        SDL_DestroyMutex(_listMutex);
    169165        _listMutex = 0;
     166       
     167        DEBUG_EXIT_FUNC();
    170168 }
    171169
    172170/*******************************************
     
    184182
    185183        if ((pause != _pauseFlagOld) && g_engine) { // Check to see if we have an engine
    186184                if (pause && _pauseClientState == PowerManager::Unpaused) {
    187                         _pauseClientState = PowerManager::Pausing;      // Tell PM we're in the middle of pausing
     185                        _pauseClientState = PowerManager::Pausing;              // Tell PM we're in the middle of pausing
    188186                        g_engine->pauseEngine(true);
    189                         PSPDebugSuspend("Pausing engine in PowerManager::pollPauseEngine()\n");
     187                        PSP_DEBUG_PRINT_FUNC("Pausing engine\n");
    190188                        _pauseClientState = PowerManager::Paused;               // Tell PM we're done pausing
    191189                }
    192190                else if (!pause && _pauseClientState == PowerManager::Paused) {
    193191                        g_engine->pauseEngine(false);
    194                         PSPDebugSuspend("Unpausing for resume in PowerManager::pollPauseEngine()\n");
     192                        PSP_DEBUG_PRINT_FUNC("Unpausing for resume\n");
    195193                        _pauseClientState = PowerManager::Unpaused;     // Tell PM we're in the middle of pausing
    196194                }
    197195
     
    205203*   Use this for small critical sections where you can easily restore the previous state.
    206204*
    207205********************************************/
    208  int PowerManager::blockOnSuspend()  {
     206int PowerManager::blockOnSuspend()  {
    209207        return beginCriticalSection(true);
    210208}
    211209
     
    216214*       Make sure to call endCriticalSection or the PSP won't suspend.
    217215********************************************/
    218216
    219   int PowerManager::beginCriticalSection(bool justBlock) {
     217int PowerManager::beginCriticalSection(bool justBlock) {
     218        DEBUG_ENTER_FUNC();
     219       
    220220        int ret = NotBlocked;
    221221
    222222        if (SDL_mutexP(_flagMutex) != 0) {
    223                 PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't lock flagMutex %d\n", _flagMutex);
     223                PSP_ERROR("PowerManager::blockOnSuspend(): Couldn't lock flagMutex[%p]\n", _flagMutex);
    224224                ret = Error;
    225225        }
    226226
    227227        // Check the access flag
    228228        if (_suspendFlag == true) {
    229                 PSPDebugSuspend("We're being blocked!\n");
     229                PSP_DEBUG_PRINT("We're being blocked!\n");
    230230                debugPM();
    231231                ret = Blocked;
    232232
    233233                // If it's true, we wait for a signal to continue
    234234                if (SDL_CondWait(_condSuspendable, _flagMutex) != 0) {
    235                         PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't wait on cond %d\n", _condSuspendable);
     235                        PSP_DEBUG_PRINT("PowerManager::blockOnSuspend(): Couldn't wait on cond[%p]\n", _condSuspendable);
    236236                }
    237237
    238                 PSPDebugSuspend("We got blocked!!\n");
     238                PSP_DEBUG_PRINT("We got blocked!!\n");
    239239                debugPM();
    240240        }
    241241
     
    244244                _criticalCounter++;
    245245
    246246        if (SDL_mutexV(_flagMutex) != 0) {
    247                 PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't unlock flagMutex %d\n", _flagMutex);
     247                PSP_ERROR("PowerManager::blockOnSuspend(): Couldn't unlock flagMutex[%p]\n", _flagMutex);
    248248                ret = Error;
    249249        }
    250250
     251        DEBUG_EXIT_FUNC();
    251252        return ret;
    252253}
    253254
    254255int PowerManager::endCriticalSection() {
     256        DEBUG_ENTER_FUNC();
    255257        int ret = 0;
    256258
    257259        if (SDL_mutexP(_flagMutex) != 0) {
    258                 PSPDebugTrace("PowerManager::endCriticalSection(): Couldn't lock flagMutex %d\n", _flagMutex);
     260                PSP_ERROR("PowerManager::endCriticalSection(): Couldn't lock flagMutex[%p]\n", _flagMutex);
    259261                ret = Error;
    260262        }
    261263
     
    264266
    265267        if (_criticalCounter <= 0) {
    266268                if (_suspendFlag == true) {     // If the PM is sleeping, this flag must be set
    267                         PSPDebugSuspend("Unblocked thread waking up the PM.\n");
     269                        PSP_DEBUG_PRINT("Unblocked thread waking up the PM.\n");
    268270                        debugPM();
    269271
    270272                        SDL_CondBroadcast(_condPM);
    271273
    272                         PSPDebugSuspend("Woke up the PM\n");
     274                        PSP_DEBUG_PRINT("Woke up the PM\n");
    273275                        debugPM();
    274276                }
    275277
    276278                if (_criticalCounter < 0) {     // Check for bad usage of critical sections
    277                         PSPDebugTrace("PowerManager::endCriticalSection(): Error! Critical counter is %d\n", _criticalCounter);
     279                        PSP_ERROR("Critical counter[%d]\n", _criticalCounter);
    278280                        debugPM();
    279281                }
    280282        }
    281283
    282284        if (SDL_mutexV(_flagMutex) != 0) {
    283                 PSPDebugTrace("PowerManager::endCriticalSection(): Couldn't unlock flagMutex %d\n", _flagMutex);
     285                PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex);
    284286                ret = Error;
    285287        }
    286288
     289        DEBUG_EXIT_FUNC();
    287290        return ret;
    288291}
    289292
     
    293296*
    294297********************************************/
    295298int PowerManager::suspend() {
     299        DEBUG_ENTER_FUNC();
    296300        int ret = 0;
    297301
    298302        if (_pauseFlag) return ret;     // Very important - make sure we only suspend once
     
    325329        // Now we set the suspend flag to true to cause reading threads to block
    326330
    327331        if (SDL_mutexP(_flagMutex) != 0) {
    328                 PSPDebugTrace("PowerManager::suspend(): Couldn't lock flagMutex %d\n", _flagMutex);
     332                PSP_ERROR("Couldn't lock flagMutex[%p]\n", _flagMutex);
    329333                _error = Error;
    330334                ret = Error;
    331335        }
     
    342346        }
    343347
    344348        if (SDL_mutexV(_flagMutex) != 0) {
    345                 PSPDebugTrace("PowerManager::suspend(): Couldn't unlock flagMutex %d\n", _flagMutex);
     349                PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex);
    346350                _error = Error;
    347351                ret = Error;
    348352        }
     
    351355
    352356        // Loop over list, calling suspend()
    353357        if (SDL_mutexP(_listMutex) != 0) {
    354                 PSPDebugTrace("PowerManager::suspend(): Couldn't lock listMutex %d\n", _listMutex);
     358                PSP_ERROR("Couldn't lock listMutex[%p]\n", _listMutex);
    355359                _error = Error;
    356360                ret = Error;
    357361        }
    358362        PMStatusSet(kIteratingListSuspend);
    359363        // Iterate
    360         Common::List<Suspendable *>::iterator i = _suspendList.begin();
     364        Common::List<Suspendable *>::iterator i;
    361365
    362         for (; i != _suspendList.end(); ++i) {
     366        for (i = _suspendList.begin(); i != _suspendList.end(); ++i) {
    363367                (*i)->suspend();
    364368        }
    365369
    366370        PMStatusSet(kDoneIteratingListSuspend);
    367371
    368372        if (SDL_mutexV(_listMutex) != 0) {
    369                 PSPDebugTrace("PowerManager::suspend(): Couldn't unlock listMutex %d\n", _listMutex);
     373                PSP_ERROR("Couldn't unlock listMutex[%p]\n", _listMutex);
    370374                _error = Error;
    371375                ret = Error;
    372376        }
     
    374378
    375379        scePowerUnlock(0);                              // Allow the PSP to go to sleep now
    376380
     381        DEBUG_EXIT_FUNC();
    377382        return ret;
    378383}
    379384
     
    383388*
    384389********************************************/
    385390int PowerManager::resume() {
     391        DEBUG_ENTER_FUNC();
    386392        int ret = 0;
    387393
    388394        // Make sure we can't get another suspend
     
    394400
    395401        // First we notify our Suspendables. Loop over list, calling resume()
    396402        if (SDL_mutexP(_listMutex) != 0) {
    397                 PSPDebugTrace("PowerManager::resume(): Couldn't lock listMutex %d\n", _listMutex);
     403                PSP_ERROR("Couldn't lock listMutex[%p]\n", _listMutex);
    398404                _error = Error;
    399405                ret = Error;
    400406        }
     
    409415        PMStatusSet(kDoneIteratingListResume);
    410416
    411417        if (SDL_mutexV(_listMutex) != 0) {
    412                 PSPDebugTrace("PowerManager::resume(): Couldn't unlock listMutex %d\n", _listMutex);
     418                PSP_ERROR("Couldn't unlock listMutex[%p]\n", _listMutex);
    413419                _error = Error;
    414420                ret = Error;
    415421        }
     
    418424
    419425        // Now we set the suspend flag to false
    420426        if (SDL_mutexP(_flagMutex) != 0) {
    421                 PSPDebugTrace("PowerManager::resume(): Couldn't lock flagMutex %d\n", _flagMutex);
     427                PSP_ERROR("Couldn't lock flagMutex %p\n", _flagMutex);
    422428                _error = Error;
    423429                ret = Error;
    424430        }
     
    430436
    431437        // Signal the other threads to wake up
    432438        if (SDL_CondBroadcast(_condSuspendable) != 0) {
    433                 PSPDebugTrace("PowerManager::resume(): Couldn't broadcast condition %d\n", _condSuspendable);
     439                PSP_ERROR("Couldn't broadcast condition[%p]\n", _condSuspendable);
    434440                _error = Error;
    435441                ret = Error;
    436442        }
    437443        PMStatusSet(kDoneSignallingSuspendedThreadsResume);
    438444
    439445        if (SDL_mutexV(_flagMutex) != 0) {
    440                 PSPDebugTrace("PowerManager::resume(): Couldn't unlock flagMutex %d\n", _flagMutex);
     446                PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex);
    441447                _error = Error;
    442448                ret = Error;
    443449        }
     
    447453
    448454        scePowerUnlock(0);      // Allow new suspends
    449455
     456        DEBUG_EXIT_FUNC();
    450457        return ret;
    451458}
  • backends/platform/psp/Makefile

     
    6666#CC      = psp-gcc
    6767CXX      = psp-g++
    6868CXXFLAGS = -O3 -Wall -Wno-multichar -fno-exceptions -fno-rtti
    69 DEFINES  = -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL
     69DEFINES  = -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL -DUSE_RGB_COLOR
    7070LDFLAGS  :=
    7171INCDIR   := $(srcdir) . $(srcdir)/engines/ $(PSPSDK)/include
    7272INCLUDES := $(addprefix -I, $(INCDIR))
     
    133133OBJS := powerman.o \
    134134        psp_main.o \
    135135        osys_psp.o \
     136        psppixelformat.o \
     137        memory.o \
     138        display_manager.o \
     139        display_client.o \
     140        default_display_client.o \
     141        input.o \
     142        cursor.o \
    136143        trace.o \
    137144        psploader.o \
    138145        pspkeyboard.o
  • backends/platform/psp/trace.cpp

     
    2323 *
    2424 */
    2525
     26#define TRACE_C
     27#include <pspkernel.h>
     28#include <pspdebug.h>
     29#include "backends/platform/psp/trace.h"
    2630
    27 #include "./trace.h"
    2831
     32int psp_debug_indent = 0;
    2933
    30 
    31 void PSPDebugTrace (const char *format, ...) {
    32 #ifdef __PSP_DEBUG__
     34void PSPDebugTrace (bool alsoToScreen, const char *format, ...) {
    3335        va_list opt;
    34         char            buff[2048];
    35         int                     bufsz, fd;
     36        char            buffer[2048];
     37        int                     bufsz;
     38        FILE *fd = 0;
    3639
    3740        va_start(opt, format);
    38         bufsz = vsnprintf( buff, (size_t) sizeof(buff), format, opt);
     41        bufsz = vsnprintf( buffer, (size_t) sizeof(buffer), format, opt);
    3942        va_end(opt);
    4043
    41         fd = sceIoOpen("MS0:/DTRACE.TXT", PSP_O_RDWR | PSP_O_CREAT | PSP_O_APPEND, 0777);
    42 
    43         if (fd <= 0)
     44        //fd = fopen("MS0:/SCUMMTRACE.TXT", "ab");
     45        fd = fopen("SCUMMTRACE.TXT", "ab");
     46       
     47        if (fd == 0)
    4448                return;
    4549
    46         sceIoWrite(fd, (const void*)buff, bufsz);
    47         sceIoClose(fd);
    48 #endif /* __PSP_DEBUG__ */
     50        fwrite(buffer, 1, bufsz, fd);
     51        fclose(fd);
     52       
     53        if (alsoToScreen)
     54                fprintf(stderr, buffer);
    4955}
    50 
    51 void PSPDebugTrace (const char * filename, const char *format, ...) {
    52 #ifdef __PSP_DEBUG__
    53         va_list opt;
    54         char            buff[2048];
    55         int                     bufsz, fd;
    56 
    57         va_start(opt, format);
    58         bufsz = vsnprintf( buff, (size_t) sizeof(buff), format, opt);
    59         va_end(opt);
    60 
    61         fd = sceIoOpen(filename, PSP_O_RDWR | PSP_O_CREAT | PSP_O_APPEND, 0777);
    62 
    63         if (fd <= 0)
    64                 return;
    65 
    66         sceIoWrite(fd, (const void*)buff, bufsz);
    67         sceIoClose(fd);
    68 #endif /* __PSP_DEBUG__ */
    69 }
  • backends/platform/psp/display_manager.cpp

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
     22 * $Id: osys_psp.cpp 47541 2010-01-25 01:39:44Z lordhoto $
     23 *
     24 */
     25
     26//#define __PSP_DEBUG_FUNCS__   /* For debugging function calls */
     27//#define __PSP_DEBUG_PRINT__   /* For debug printouts */
     28
     29//#define ENABLE_RENDER_MEASURE
     30
     31#include "backends/platform/psp/trace.h"
     32
     33#include <pspgu.h>
     34#include <pspdisplay.h>
     35
     36#include "common/scummsys.h"
     37#include "backends/base-backend.h"
     38#include "backends/platform/psp/display_client.h"
     39#include "backends/platform/psp/default_display_client.h"
     40#include "backends/platform/psp/cursor.h"
     41#include "backends/platform/psp/pspkeyboard.h"
     42#include "backends/platform/psp/display_manager.h"
     43
     44#define PSP_BUFFER_WIDTH (512)
     45#define PSP_SCREEN_WIDTH        480
     46#define PSP_SCREEN_HEIGHT       272
     47#define PSP_FRAME_SIZE (PSP_BUFFER_WIDTH * PSP_SCREEN_HEIGHT)
     48
     49uint32 __attribute__((aligned(16))) MasterGuRenderer::_displayList[2048];
     50
     51 const OSystem::GraphicsMode DisplayManager::_supportedModes[] = {
     52        { "320x200 (centered)", "320x200 16-bit centered", CENTERED_320X200 },
     53        { "435x272 (best-fit, centered)", "435x272 16-bit centered", CENTERED_435X272 },
     54        { "480x272 (full screen)", "480x272 16-bit stretched", STRETCHED_480X272 },
     55        { "362x272 (4:3, centered)", "362x272 16-bit centered", CENTERED_362X272 },
     56        {0, 0, 0}
     57};
     58
     59
     60// Class MasterGuRenderer ----------------------------------------------
     61
     62void MasterGuRenderer::guInit() {
     63        DEBUG_ENTER_FUNC();
     64       
     65        sceGuInit();
     66        sceGuStart(0, _displayList);
     67       
     68        guProgramDisplayBufferSizes();
     69       
     70        sceGuOffset(2048 - (PSP_SCREEN_WIDTH/2), 2048 - (PSP_SCREEN_HEIGHT/2));
     71        sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
     72        sceGuDepthRange(0xC350, 0x2710);
     73        sceGuDisable(GU_DEPTH_TEST);    // We'll use depth buffer area
     74        sceGuDepthMask(GU_TRUE);                // Prevent writes to depth buffer
     75        sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
     76        sceGuEnable(GU_SCISSOR_TEST);
     77        sceGuFrontFace(GU_CW);
     78        sceGuEnable(GU_TEXTURE_2D);
     79
     80        sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
     81        sceGuFinish();
     82        sceGuSync(0,0);
     83
     84        sceDisplayWaitVblankStart();
     85        sceGuDisplay(1);
     86       
     87        DEBUG_EXIT_FUNC();
     88}
     89
     90void MasterGuRenderer::guProgramDisplayBufferSizes() {
     91        DEBUG_ENTER_FUNC();
     92
     93        PSP_DEBUG_PRINT("Outputbits[%u]\n", GuRenderer::_displayManager->getOutputBitsPerPixel());
     94       
     95        switch (GuRenderer::_displayManager->getOutputBitsPerPixel()) {
     96        case 16:
     97                sceGuDrawBuffer(GU_PSM_4444, (void *)0, PSP_BUFFER_WIDTH);
     98                sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, (void*)(PSP_FRAME_SIZE * sizeof(uint16)), PSP_BUFFER_WIDTH);
     99                sceGuDepthBuffer((void*)(PSP_FRAME_SIZE * sizeof(uint16) * 2), PSP_BUFFER_WIDTH);
     100                VramAllocator::instance().allocate(PSP_FRAME_SIZE * sizeof(uint16) * 2);
     101                break;
     102        case 32:
     103                sceGuDrawBuffer(GU_PSM_8888, (void *)0, PSP_BUFFER_WIDTH);
     104                sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, (void*)(PSP_FRAME_SIZE * sizeof(uint32)), PSP_BUFFER_WIDTH);
     105                sceGuDepthBuffer((void*)(PSP_FRAME_SIZE * sizeof(uint32) * 2), PSP_BUFFER_WIDTH);
     106                VramAllocator::instance().allocate(PSP_FRAME_SIZE * sizeof(uint32) * 2);
     107                break;
     108        }
     109       
     110        DEBUG_EXIT_FUNC();
     111}
     112
     113// These are GU commands that should always stay the same
     114INLINE void MasterGuRenderer::guPreRender() {
     115        DEBUG_ENTER_FUNC();
     116
     117#ifdef ENABLE_RENDER_MEASURE
     118        _lastRenderTime = g_system->getMillis();
     119#endif /* ENABLE_RENDER_MEASURE */     
     120       
     121        sceGuStart(0, _displayList);
     122
     123        sceGuClearColor(0xFF000000);
     124        sceGuClear(GU_COLOR_BUFFER_BIT);
     125       
     126        sceGuAmbientColor(0xFFFFFFFF);
     127        sceGuColor(0xFFFFFFFF);
     128        sceGuTexOffset(0,0);
     129        sceGuTexFilter(GU_LINEAR, GU_LINEAR);
     130       
     131        sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); // Also good enough for all purposes
     132        sceGuAlphaFunc(GU_GREATER, 0, 0xFF);       // Also good enough for all purposes
     133       
     134        DEBUG_EXIT_FUNC();
     135}
     136
     137INLINE void MasterGuRenderer::guPostRender() {
     138        DEBUG_ENTER_FUNC();
     139       
     140        sceGuFinish();
     141        sceGuSync(0,0);
     142
     143#ifdef ENABLE_RENDER_MEASURE
     144        uint32 now = g_system->getMillis();
     145        PSP_INFO_PRINT("Render took %d milliseconds\n", now - _lastRenderTime);
     146#endif /* ENABLE_RENDER_MEASURE */
     147       
     148        sceDisplayWaitVblankStart();
     149        sceGuSwapBuffers();
     150       
     151        DEBUG_EXIT_FUNC();
     152}
     153
     154void MasterGuRenderer::guShutDown() {
     155        sceGuTerm();
     156}
     157
     158
     159// Class DisplayManager -----------------------------------------------------
     160
     161DisplayManager::~DisplayManager() {
     162        _masterGuRenderer.guShutDown();
     163}
     164
     165void DisplayManager::init() {
     166        DEBUG_ENTER_FUNC();
     167       
     168        _displayParams.outputBitsPerPixel = 32; // can be changed to produce 16-bit output
     169       
     170        GuRenderer::setDisplayManager(this);
     171        _screen->init();
     172        _overlay->init();
     173        _cursor->init();
     174       
     175        _masterGuRenderer.guInit();                             // start up the renderer
     176       
     177        DEBUG_EXIT_FUNC();
     178}
     179
     180void DisplayManager::setSizeAndPixelFormat(uint width, uint height, const Graphics::PixelFormat *format) {
     181
     182        DEBUG_ENTER_FUNC();
     183        PSP_DEBUG_PRINT("w[%u], h[%u], pformat[%p]\n", width, height, format);
     184
     185        _overlay->deallocate();
     186        _screen->deallocate();
     187       
     188        _screen->setScummvmPixelFormat(format);
     189        _screen->setSize(width, height);
     190        _screen->allocate();
     191       
     192        _cursor->setScreenPaletteScummvmPixelFormat(format);
     193
     194        _overlay->setBytesPerPixel(sizeof(OverlayColor));
     195        _overlay->setSize(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
     196        _overlay->allocate();
     197       
     198        _displayParams.screenSource.width = width;
     199        _displayParams.screenSource.height = height;
     200        calculateScaleParams();
     201       
     202        DEBUG_EXIT_FUNC();
     203}
     204
     205bool DisplayManager::setGraphicsMode(const char *name) {
     206        DEBUG_ENTER_FUNC();
     207
     208        int i = 0;
     209
     210        while (_supportedModes[i].name) {
     211                if (!strcmpi(_supportedModes[i].name, name)) {
     212                        setGraphicsMode(_supportedModes[i].id);
     213                        DEBUG_EXIT_FUNC();
     214                        return true;
     215                }
     216                i++;
     217        }
     218
     219        DEBUG_EXIT_FUNC();
     220        return false;
     221}
     222
     223bool DisplayManager::setGraphicsMode(int mode) {
     224        DEBUG_ENTER_FUNC();
     225
     226        _graphicsMode = mode;
     227
     228        switch (_graphicsMode) {
     229        case CENTERED_320X200:
     230                _displayParams.screenOutput.width = 320;
     231                _displayParams.screenOutput.height = 200;
     232                break;
     233        case CENTERED_435X272:
     234                _displayParams.screenOutput.width = 435;
     235                _displayParams.screenOutput.height = 272;
     236                break;
     237        case STRETCHED_480X272:
     238                _displayParams.screenOutput.width = 480;
     239                _displayParams.screenOutput.height = 272;
     240                break;
     241        case CENTERED_362X272:
     242                _displayParams.screenOutput.width = 362;
     243                _displayParams.screenOutput.height = 272;
     244                break;
     245        default:
     246                PSP_ERROR("Unsupported graphics mode[%d].\n", _graphicsMode);
     247        }
     248       
     249        calculateScaleParams();
     250       
     251        DEBUG_EXIT_FUNC();
     252        return true;
     253}
     254
     255void DisplayManager::calculateScaleParams() {
     256        if (_displayParams.screenOutput.width && _displayParams.screenSource.width &&
     257            _displayParams.screenOutput.height && _displayParams.screenSource.height) {
     258                _displayParams.scaleX = ((float)_displayParams.screenOutput.width) / _displayParams.screenSource.width;
     259                _displayParams.scaleY = ((float)_displayParams.screenOutput.height) / _displayParams.screenSource.height;
     260        }
     261}
     262
     263void DisplayManager::renderAll() {
     264        DEBUG_ENTER_FUNC();
     265
     266        if (!isTimeToUpdate()) {
     267                DEBUG_EXIT_FUNC();
     268                return;
     269        }
     270
     271        if (!_screen->isDirty() &&
     272                (!_overlay->isDirty()) &&
     273                (!_cursor->isDirty()) &&
     274                (!_keyboard->isDirty())) {
     275                PSP_DEBUG_PRINT("Nothing dirty\n");
     276                DEBUG_EXIT_FUNC();
     277                return;
     278        }
     279       
     280        PSP_DEBUG_PRINT("screen[%s], overlay[%s], cursor[%s], keyboard[%s]\n",
     281                _screen->isDirty() ? "true" : "false",
     282                _overlay->isDirty() ? "true" : "false",
     283                _cursor->isDirty() ? "true" : "false",
     284                _keyboard->isDirty() ? "true" : "false"
     285                );
     286
     287        _masterGuRenderer.guPreRender();        // Set up rendering
     288
     289        _screen->render();
     290       
     291        _screen->setClean();                            // clean out dirty bit
     292
     293        if (_overlay->isVisible())
     294                _overlay->render();
     295               
     296        _overlay->setClean();
     297               
     298        if (_cursor->isVisible())
     299                _cursor->render();
     300               
     301        _cursor->setClean();
     302
     303        if (_keyboard->isVisible())
     304                _keyboard->render();
     305               
     306        _keyboard->setClean();
     307               
     308        _masterGuRenderer.guPostRender();
     309
     310        DEBUG_EXIT_FUNC();
     311}
     312
     313inline bool DisplayManager::isTimeToUpdate() {
     314
     315#define MAX_FPS 30
     316
     317        uint32 now = g_system->getMillis();
     318        if (now - _lastUpdateTime < (1000 / MAX_FPS))
     319                return false;
     320
     321        _lastUpdateTime = now;
     322        return true;
     323}
     324       
     325Common::List<Graphics::PixelFormat> DisplayManager::getSupportedPixelFormats() {
     326        Common::List<Graphics::PixelFormat> list;
     327       
     328        // In order of preference
     329        list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_5650));
     330        list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_5551));
     331        list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_4444));
     332        list.push_back(Graphics::PixelFormat::createFormatCLUT8());
     333       
     334        return list;
     335}
     336
  • backends/platform/psp/input.h

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
     22 * $Id: osys_psp.cpp 43618 2009-08-21 22:44:49Z joostp $
     23 *
     24 */
     25
     26#ifndef PSP_INPUT_H
     27#define PSP_INPUT_H
     28
     29#include "common/scummsys.h"
     30#include "common/events.h"
     31#include "backends/platform/psp/display_client.h"
     32#include "backends/platform/psp/default_display_client.h"
     33#include "backends/platform/psp/pspkeyboard.h"
     34#include "backends/platform/psp/cursor.h"
     35#include <pspctrl.h>
     36
     37class InputHandler {
     38public:
     39        InputHandler() : _cursor(0), _keyboard(0), _prevButtons(0), _lastPadCheckTime(0), _buttonsChanged(0), _dpadX(0), _dpadY(0) {}
     40       
     41        void init();
     42        bool getAllInputs(Common::Event &event);
     43        void setKeyboard(PSPKeyboard *keyboard) { _keyboard = keyboard; }
     44        void setCursor(Cursor *cursor) { _cursor = cursor; }
     45
     46private:
     47        Cursor *_cursor;
     48        PSPKeyboard *_keyboard;
     49        uint32  _prevButtons;
     50        uint32  _lastPadCheckTime;
     51        uint32 _buttonsChanged;
     52        int32 _dpadX, _dpadY;
     53        int32 _accelX, _accelY;
     54       
     55        bool getEvent(Common::Event &event, SceCtrlData &pad);
     56        bool getDpadEvent(Common::Event &event, SceCtrlData &pad);
     57        bool getButtonEvent(Common::Event &event, SceCtrlData &pad);
     58        bool getNubEvent(Common::Event &event, SceCtrlData &pad);       
     59        int32 modifyNubAxisMotion(int32 input);
     60        Common::KeyCode translateDpad(int x, int y);
     61};
     62
     63#endif /* PSP_INPUT_H */
  • backends/platform/psp/default_display_client.cpp

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.h $
     22 * $Id: osys_psp.h 46120 2009-11-24 10:33:30Z Bluddy $
     23 *
     24 */
     25
     26#include "common/scummsys.h"
     27#include "backends/platform/psp/display_client.h"
     28#include "backends/platform/psp/default_display_client.h"
     29
     30//#define __PSP_DEBUG_FUNCS__   /* For debugging the stack */
     31//#define __PSP_DEBUG_PRINT__
     32
     33#include "backends/platform/psp/trace.h"
     34
     35// Class DefaultDisplayClient ---------------------------------------------
     36
     37bool DefaultDisplayClient::allocate(bool bufferInVram /* = false */, bool paletteInVram /* = false */) {
     38        DEBUG_ENTER_FUNC();
     39       
     40        if (!_buffer.allocate(bufferInVram)) {
     41                        PSP_ERROR("Couldn't allocate buffer.\n");
     42                        DEBUG_EXIT_FUNC();
     43                        return false;
     44                }
     45
     46        if (_buffer.hasPalette())
     47        {
     48                PSP_DEBUG_PRINT("_palette[%p]\n", &_palette);
     49
     50                if (!_palette.allocate()) {
     51                        PSP_ERROR("Couldn't allocate pallette.\n");
     52                        DEBUG_EXIT_FUNC();
     53                        return false;
     54                }
     55        }
     56       
     57        DEBUG_EXIT_FUNC();
     58        return true;
     59}
     60
     61void DefaultDisplayClient::deallocate() {
     62        _buffer.deallocate();
     63        if (_buffer.hasPalette())
     64                _palette.deallocate();
     65}
     66
     67
     68void DefaultDisplayClient::clearBuffer() {
     69        DEBUG_ENTER_FUNC();
     70        _buffer.clear();
     71        setDirty();
     72        DEBUG_EXIT_FUNC();
     73}
     74
     75inline void DefaultDisplayClient::clearPalette() {
     76        DEBUG_ENTER_FUNC();
     77        _palette.clear();
     78        setDirty();
     79        DEBUG_EXIT_FUNC();
     80}
     81
     82void DefaultDisplayClient::init() {
     83        DEBUG_ENTER_FUNC();
     84        _renderer.setBuffer(&_buffer);
     85        _renderer.setPalette(&_palette);
     86        DEBUG_EXIT_FUNC();
     87}
     88
     89void DefaultDisplayClient::copyFromRect(const byte *buf, int pitch, int destX, int destY, int recWidth, int recHeight) {
     90        DEBUG_ENTER_FUNC();
     91        _buffer.copyFromRect(buf, pitch, destX, destY, recWidth, recHeight);
     92        setDirty();
     93        DEBUG_EXIT_FUNC();
     94}
     95
     96void DefaultDisplayClient::copyToArray(byte *dst, int pitch) {
     97        DEBUG_ENTER_FUNC();
     98        _buffer.copyToArray(dst, pitch);
     99        DEBUG_EXIT_FUNC();
     100}
     101
     102// Class Overlay -------------------------------------------------------
     103
     104void Overlay::init() {
     105        DEBUG_ENTER_FUNC();
     106
     107        DefaultDisplayClient::init();
     108        _renderer.setAlphaBlending(true);
     109        _renderer.setColorTest(false);
     110        _renderer.setUseGlobalScaler(false);
     111        _renderer.setFullScreen(true);  // speeds up render slightly
     112
     113        DEBUG_EXIT_FUNC();
     114}
     115
     116void Overlay::setBytesPerPixel(uint32 size) {
     117        DEBUG_ENTER_FUNC();
     118       
     119        switch (size) {
     120        case 1:
     121                _buffer.setPixelFormat(PSPPixelFormat::Type_Palette_8bit);
     122                _palette.setPixelFormats(PSPPixelFormat::Type_4444, PSPPixelFormat::Type_Palette_8bit);
     123                break;
     124        case 2:
     125                _buffer.setPixelFormat(PSPPixelFormat::Type_4444);
     126                break;
     127        case 4:
     128                _buffer.setPixelFormat(PSPPixelFormat::Type_8888);
     129                break;
     130        }
     131       
     132        DEBUG_EXIT_FUNC();
     133}
     134
     135void Overlay::setSize(uint32 width, uint32 height) {
     136        DEBUG_ENTER_FUNC();
     137        _buffer.setSize(width, height, Buffer::kSizeBySourceSize);
     138        _renderer.setDrawWholeBuffer(); // We need to let the renderer know how much to draw
     139        DEBUG_EXIT_FUNC();
     140}
     141
     142void Overlay::copyToArray(OverlayColor *buf, int pitch) {
     143        DEBUG_ENTER_FUNC();
     144        _buffer.copyToArray((byte *)buf, pitch * sizeof(OverlayColor)); // Change to bytes
     145        DEBUG_EXIT_FUNC();
     146}
     147
     148void Overlay::copyFromRect(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
     149        DEBUG_ENTER_FUNC();
     150       
     151        _buffer.copyFromRect((byte *)buf, pitch * sizeof(OverlayColor), x, y, w, h);    // Change to bytes
     152        // debug
     153        //_buffer.print(0xFF);
     154        setDirty();
     155        DEBUG_EXIT_FUNC();
     156}
     157
     158bool Overlay::allocate() {
     159        DEBUG_ENTER_FUNC();
     160       
     161        bool ret = DefaultDisplayClient::allocate(true, false); // buffer in VRAM
     162       
     163        DEBUG_EXIT_FUNC();
     164        return ret;
     165}
     166
     167// Class Screen -----------------------------------------------------------
     168
     169void Screen::init() {
     170        DEBUG_ENTER_FUNC();
     171
     172        DefaultDisplayClient::init();
     173        _renderer.setAlphaBlending(false);
     174        _renderer.setColorTest(false);
     175        _renderer.setUseGlobalScaler(true);
     176        _renderer.setFullScreen(true);
     177
     178        DEBUG_EXIT_FUNC();
     179}
     180
     181void Screen::setShakePos(int pos) {
     182        _shakePos = pos;
     183        _renderer.setOffsetOnScreen(0, pos);
     184        setDirty();
     185}
     186
     187void Screen::setSize(uint32 width, uint32 height) {
     188        DEBUG_ENTER_FUNC();
     189
     190        _buffer.setSize(width, height, Buffer::kSizeBySourceSize);
     191        _renderer.setDrawWholeBuffer(); // We need to let the renderer know how much to draw
     192       
     193        DEBUG_EXIT_FUNC();
     194}
     195
     196void Screen::setScummvmPixelFormat(const Graphics::PixelFormat *format) {
     197        DEBUG_ENTER_FUNC();
     198        PSP_DEBUG_PRINT("format[%p], _buffer[%p], _palette[%p]\n", format, &_buffer, &_palette);
     199
     200        if (!format) {
     201                bzero(&_pixelFormat, sizeof(_pixelFormat));
     202                _pixelFormat.bytesPerPixel = 1; // default
     203        } else {
     204                _pixelFormat = *format;
     205        }
     206       
     207        PSPPixelFormat::Type bufferFormat, paletteFormat;
     208        bool swapRedBlue = false;
     209       
     210        PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferFormat, paletteFormat, swapRedBlue);
     211        _buffer.setPixelFormat(bufferFormat, swapRedBlue);
     212        _palette.setPixelFormats(paletteFormat, bufferFormat, swapRedBlue);
     213       
     214        DEBUG_EXIT_FUNC();
     215}
     216
     217Graphics::Surface *Screen::lockAndGetForEditing() {
     218        DEBUG_ENTER_FUNC();
     219       
     220        _frameBuffer.pixels = _buffer.getPixels();
     221        _frameBuffer.w = _buffer.getSourceWidth();
     222        _frameBuffer.h = _buffer.getSourceHeight();
     223        _frameBuffer.pitch = _buffer.getBytesPerPixel() * _buffer.getWidth();
     224        _frameBuffer.bytesPerPixel = _buffer.getBytesPerPixel();
     225        // We'll set to dirty once we unlock the screen
     226       
     227        DEBUG_EXIT_FUNC();
     228       
     229        return &_frameBuffer;
     230}
     231
     232bool Screen::allocate() {
     233        DEBUG_ENTER_FUNC();
     234       
     235        return DefaultDisplayClient::allocate(true, false);     // buffer in VRAM
     236       
     237        DEBUG_EXIT_FUNC();
     238}
  • backends/platform/psp/display_client.h

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
     22 * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
     23 *
     24 */
     25 
     26#ifndef PSP_GRAPHICS_H
     27#define PSP_GRAPHICS_H
     28
     29#include "common/singleton.h"
     30#include "graphics/surface.h"
     31#include "common/system.h"
     32#include "backends/platform/psp/psppixelformat.h"
     33#include "backends/platform/psp/memory.h"
     34 
     35#define MAX_TEXTURE_SIZE 512
     36
     37class DisplayManager;
     38class GuRenderer;
     39
     40/**
     41 *      Interface to inherit for all display clients
     42 *      We deliberately avoid virtual functions for speed.
     43 */
     44class DisplayClient {                           // Abstract class
     45public:
     46        DisplayClient() {}
     47        bool isVisible() { return true; }
     48        bool isDirty() { return true; }
     49        void setClean() {}
     50        void render() {}
     51        virtual ~DisplayClient() {}
     52};
     53 
     54/**
     55 * Vertex used for GU rendering
     56 */
     57struct Vertex {
     58        float u,v;
     59        float x,y,z;
     60};
     61
     62struct Point {
     63        int x;
     64        int y;
     65        Point() : x(0), y(0) {}
     66};
     67
     68/**
     69 * Dimensions struct for simplification
     70 */
     71struct Dimensions {
     72        uint32 width;
     73        uint32 height;
     74        Dimensions() : width(0), height(0) {}
     75};
     76
     77/**
     78 *      Universal PSP Palette class
     79 *      Use this in any class that wishes to draw to the PSP screen.
     80 *      Use together with GuRenderer
     81 */
     82class Palette {
     83public:
     84        Palette() : _values(0), _numOfEntries(0) {}
     85        virtual ~Palette() { deallocate(); }
     86        bool allocate();
     87        void deallocate();
     88        void clear();
     89        void setPixelFormats(PSPPixelFormat::Type paletteType, PSPPixelFormat::Type bufferType, bool swapRedBlue = false);
     90        void setNumOfEntries(uint32 num) {      _numOfEntries = num; }
     91        uint32 getNumOfEntries() { return _numOfEntries; }
     92        uint32 getSizeInBytes() { return _pixelFormat.pixelsToBytes(_numOfEntries); }
     93        void set(byte *values) { setPartial(values, 0, _numOfEntries); }
     94        void setPartial(const byte *colors, uint start, uint num, bool supportsAlpha = false);
     95        void getPartial(byte *colors, uint start, uint num);
     96        uint32 getRawColorAt(uint32 position);
     97        uint32 getRGBAColorAt(uint32 position);
     98        void setSingleColorRGBA(uint32 num, byte r, byte g, byte b, byte a);
     99        void setColorPositionAlpha(uint32 position, bool alpha);
     100        byte *getRawValues() { return _values; }
     101        bool isAllocated() { return (_values != 0); }
     102        PSPPixelFormat::Type getPixelFormat() { return _pixelFormat.format; }
     103        void print(uint32 numToPrint = 0);                                      // print to screen
     104       
     105protected:
     106        byte *_values;                                  ///< array of palette data
     107        uint32 _numOfEntries;                   ///< number of palette entries
     108        PSPPixelFormat _pixelFormat;    ///< pixel format of the palette data
     109};
     110
     111/**
     112 *      Universal PSP buffer/texture object
     113 *      Use this in any class that wishes to draw to the PSP screen.
     114 *      Use together with GuRenderer
     115 */
     116class Buffer {
     117public:
     118        enum HowToSize {
     119                kSizeByTextureSize,     // buffer size is determined by power of 2 roundup for texture
     120                kSizeBySourceSize       // buffer size is determined by source size
     121        };
     122
     123        Buffer() : _pixels(0), _width(0), _height(0)  {}
     124        virtual ~Buffer() { deallocate(); }
     125       
     126        // setters
     127        void setSize(uint32 width, uint32 height, HowToSize textureOrSource=kSizeByTextureSize);
     128        void setBitsPerPixel(uint32 bits) { _pixelFormat.bitsPerPixel = bits; }
     129        void setBytesPerPixel(uint32 bytes) { setBitsPerPixel(bytes << 3); }
     130        void setPixelFormat(PSPPixelFormat::Type type, bool swapRedBlue = false);
     131
     132        // getters
     133        uint32 getWidth() { return _width; }
     134        uint32 getWidthInBytes() { return _pixelFormat.pixelsToBytes(getWidth()); }
     135        uint32 getHeight() { return _height; }
     136        uint32 getSourceWidth() { return _sourceSize.width; }
     137        uint32 getSourceWidthInBytes() { return _pixelFormat.pixelsToBytes(_sourceSize.width); }
     138        uint32 getSourceHeight() { return _sourceSize.height; }
     139        uint32 getTextureWidth() { return _textureSize.width; }
     140        uint32 getTextureHeight() { return _textureSize.height; }
     141        PSPPixelFormat::Type getPixelFormat() { return _pixelFormat.format; }
     142        uint32 getBitsPerPixel() { return _pixelFormat.bitsPerPixel; }
     143        uint32 getBytesPerPixel() { return getBitsPerPixel() >> 3; } /* won't work for 4-bit */
     144        byte *getPixels() { return _pixels; }
     145        uint32 getSizeInBytes() { return _pixelFormat.pixelsToBytes(_width * _height); }
     146       
     147        bool hasPalette();
     148        void copyFromArray(const byte *buffer, int pitch);
     149        void copyFromRect(const byte *buf, uint32 pitch, int destX, int destY, uint32 recWidth, uint32 recHeight);
     150        void copyToArray(byte *dst, int pitch);
     151        bool allocate(bool inVram = false);
     152        void deallocate();
     153        bool isAllocated() { return (_pixels != 0) ; }
     154        void clear();
     155        void flipNibbles();             // To handle peculiarities of PSP's 4 bit textures
     156        static uint32 scaleUpToPowerOfTwo(uint32 size);
     157        void print(uint32 mask, uint32 numToPrint = 0);
     158       
     159protected:
     160        friend class GuRenderer;
     161        byte *_pixels;
     162        uint32 _width;                                  ///< True allocated width
     163        uint32 _height;                                 ///< True allocated height
     164        Dimensions _textureSize;                ///< Size rounded up to power of 2. Used for drawing
     165        Dimensions _sourceSize;                 ///< Original size of the buffer
     166        PSPPixelFormat _pixelFormat;    ///< Format of the buffer       
     167};
     168
     169/**
     170 *      Universal rendering class for PSP
     171 *      Use this if you want to draw to the screen.
     172 *      Needs to be supplied with a Buffer and a Palette
     173 */
     174class GuRenderer {
     175public:
     176        // Constructors
     177        GuRenderer() : _useGlobalScaler(false), _buffer(0), _palette(0), _blending(false), _alphaReverse(false), _colorTest(false), _keyColor(0), _fullScreen(false) {}
     178        GuRenderer(Buffer *buffer, Palette *palette) : _useGlobalScaler(false), _buffer(buffer), _palette(palette), _blending(false), _alphaReverse(false), _colorTest(false), _keyColor(0), _fullScreen(false) {}
     179        static void setDisplayManager(DisplayManager *dm) { _displayManager = dm; } // Called by the Display Manager
     180       
     181        // Setters
     182        void setDrawSize(uint32 width, uint32 height) { // How big of an area to draw
     183                        _drawSize.width = width;
     184                        _drawSize.height = height;
     185        }
     186        void setDrawWholeBuffer() {                                             // Draw the full size of the current buffer
     187                assert(_buffer);
     188                _drawSize.width = _buffer->getSourceWidth();
     189                _drawSize.height = _buffer->getSourceHeight();
     190        }
     191    void setBuffer(Buffer *buffer) { _buffer = buffer; }
     192    void setPalette(Palette *palette) { _palette = palette; }
     193        void setMaxTextureOffsetByIndex(uint32 x, uint32 y);    // For drawing multiple textures
     194        void setOffsetOnScreen(uint32 x, uint32 y) { _offsetOnScreen.x = x; _offsetOnScreen.y = y; }
     195        void setOffsetInBuffer(uint32 x, uint32 y) { _offsetInBuffer.x = x; _offsetInBuffer.y = y; }
     196        void setColorTest(bool value) { _colorTest = value; }
     197        void setKeyColor(uint32 value) { _keyColor = _buffer->_pixelFormat.convertTo32BitColor(value); }
     198        void setAlphaBlending(bool value) { _blending = value; }
     199        void setAlphaReverse(bool value) { _alphaReverse = value; }
     200        void setFullScreen(bool value) { _fullScreen = value; }         // Shortcut for rendering
     201        void setUseGlobalScaler(bool value) { _useGlobalScaler = value; }       // Scale to screen
     202       
     203        static void cacheInvalidate(void *pointer, uint32 size);
     204       
     205        void render();                                                  // Default rendering function. This should be good enough for most purposes
     206
     207protected:
     208        // Gu functions
     209        void fillVertices(Vertex *vertices);    // Fill in vertices with coordinates
     210        void guProgramDrawBehavior();
     211        Vertex *guGetVertices();
     212        void guLoadTexture();   
     213        void guLoadPalette();
     214        void guProgramTextureFormat();
     215        void guProgramTextureBitDepth();
     216        void guDrawVertices(Vertex *vertices);
     217
     218        uint32 convertToGuPixelFormat(PSPPixelFormat::Type format);
     219        float scaleSourceToOutputX(float offset);
     220        float scaleSourceToOutputY(float offset);
     221       
     222        friend class MasterGuRenderer;
     223        Point _maxTextureOffset;                ///> For rendering textures > 512 pixels
     224        Point _offsetOnScreen;                  ///> Where on screen to draw
     225        Point _offsetInBuffer;                  ///> Where in the texture to draw
     226        bool _useGlobalScaler;                  ///> Scale to the output size on screen
     227        Buffer *_buffer;
     228        Palette *_palette;
     229        static DisplayManager *_displayManager;
     230        Dimensions _drawSize;                   ///> Actual size to draw out of the Buffer
     231        bool _blending;
     232        bool _alphaReverse;                             ///> 0 counts as full alpha
     233        bool _colorTest;
     234        uint32 _keyColor;                               ///> Color to test against for color test. in 32 bits.
     235        bool _fullScreen;                               ///> Speeds up for fullscreen rendering
     236};
     237
     238#endif /* PSP_SCREEN_H */
  • backends/platform/psp/memory.h

     
     1
     2/* ScummVM - Graphic Adventure Engine
     3 *
     4 * ScummVM is the legal property of its developers, whose names
     5 * are too numerous to list here. Please refer to the COPYRIGHT
     6 * file distributed with this source distribution.
     7 *
     8 * This program is free software; you can redistribute it and/or
     9 * modify it under the terms of the GNU General Public License
     10 * as published by the Free Software Foundation; either version 2
     11 * of the License, or (at your option) any later version.
     12
     13 * This program is distributed in the hope that it will be useful,
     14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 * GNU General Public License for more details.
     17
     18 * You should have received a copy of the GNU General Public License
     19 * along with this program; if not, write to the Free Software
     20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     21 *
     22 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
     23 * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
     24 *
     25 */
     26
     27#ifndef PSP_MEMORY_H
     28#define PSP_MEMORY_H
     29
     30#define UNCACHED(x)             ((byte *)(((uint32)(x)) | 0x40000000))  /* make an uncached access */
     31#define CACHED(x)               ((byte *)(((uint32)(x)) & 0xBFFFFFFF))  /* make an uncached access into a cached one */
     32 
     33/**
     34 *      Class that does memory copying and swapping if needed
     35 */
     36class Copier {
     37public:
     38        static void copy(byte *dst, const byte *src, uint32 bytes, PSPPixelFormat *format = NULL);
     39        static void copy8(byte *dst, const byte *src, uint32 bytes);
     40        static void copy16(uint16 *dst, const uint16 *src, uint32 bytes, PSPPixelFormat *format = NULL);
     41};
     42
     43/**
     44 *      Class that allocates memory in the VRAM
     45 */
     46class VramAllocator : public Common::Singleton<VramAllocator> {
     47public:
     48        VramAllocator() : _bytesAllocated(0) {}
     49        void *allocate(int32 size, bool smallAllocation = false);       // smallAllocation e.g. palettes
     50        void deallocate(void *pointer);
     51
     52        static inline bool isAddressInVram(void *address) {
     53        if ((uint32)(CACHED(address)) >= VRAM_START_ADDRESS && (uint32)(CACHED(address)) < VRAM_END_ADDRESS)
     54                return true;
     55        return false;
     56}
     57
     58
     59private:
     60        /**
     61         *      Used to allocate in VRAM
     62         */
     63        struct Allocation {
     64                byte *address;
     65                uint32 size;
     66                void *getEnd() { return address + size; }
     67                Allocation(void *Address, uint32 Size) : address((byte *)Address), size(Size) {}
     68                Allocation() : address(0), size(0) {}
     69        };
     70
     71        enum {
     72                VRAM_START_ADDRESS = 0x04000000,
     73                VRAM_END_ADDRESS   = 0x04200000,
     74                VRAM_SMALL_ADDRESS = VRAM_END_ADDRESS - (4*1024)        // 4K in the end for small allocations
     75        };
     76        Common::List <Allocation> _allocList;           // List of allocations
     77        uint32 _bytesAllocated;
     78};
     79 
     80#endif /* PSP_MEMORY_H */
  • backends/platform/psp/osys_psp.cpp

     
    2323 *
    2424 */
    2525
     26#include <pspuser.h>
    2627#include <pspgu.h>
    2728#include <pspdisplay.h>
    2829
     
    3334#include "common/events.h"
    3435#include "common/scummsys.h"
    3536
    36 #include "osys_psp.h"
    37 #include "trace.h"
    38 #include "powerman.h"
     37#include "backends/platform/psp/osys_psp.h"
     38#include "backends/platform/psp/powerman.h"
    3939
    4040#include "backends/saves/psp/psp-saves.h"
    4141#include "backends/timer/default/default-timer.h"
    4242#include "graphics/surface.h"
    4343#include "sound/mixer_intern.h"
    4444
    45 #include "backends/platform/psp/pspkeyboard.h"
     45//#define __PSP_DEBUG_FUNCS__   /* For debugging function calls */
     46//#define __PSP_DEBUG_PRINT__   /* For debug printouts */
    4647
     48#include "backends/platform/psp/trace.h"
    4749
     50
    4851#define SAMPLES_PER_SEC 44100
    4952
    50 #define PIXEL_SIZE (4)
    51 #define BUF_WIDTH (512)
    52 #define PSP_SCREEN_WIDTH        480
    53 #define PSP_SCREEN_HEIGHT       272
    54 #define PSP_FRAME_SIZE (BUF_WIDTH * PSP_SCREEN_HEIGHT * PIXEL_SIZE)
    55 #define MOUSE_SIZE      128
    56 #define KBD_DATA_SIZE   130560
    57 
    58 #define MAX_FPS 30
    59 
    60 unsigned int __attribute__((aligned(16))) displayList[2048];
    61 unsigned short __attribute__((aligned(16))) clut256[256];
    62 unsigned short __attribute__((aligned(16))) mouseClut[256];
    63 unsigned short __attribute__((aligned(16))) cursorPalette[256];
    64 unsigned int __attribute__((aligned(16))) mouseBuf256[MOUSE_SIZE*MOUSE_SIZE];
    65 
    66 
    67 unsigned long RGBToColour(unsigned long r, unsigned long g, unsigned long b) {
    68         return (((b >> 3) << 10) | ((g >> 3) << 5) | ((r >> 3) << 0)) | 0x8000;
    69 }
    70 
    7153static int timer_handler(int t) {
    7254        DefaultTimerManager *tm = (DefaultTimerManager *)g_system->getTimerManager();
    7355        tm->handler();
    7456        return t;
    7557}
    7658
    77 const OSystem::GraphicsMode OSystem_PSP::s_supportedGraphicsModes[] = {
    78         { "320x200 (centered)", "320x200 16-bit centered", CENTERED_320X200 },
    79         { "435x272 (best-fit, centered)", "435x272 16-bit centered", CENTERED_435X272 },
    80         { "480x272 (full screen)", "480x272 16-bit stretched", STRETCHED_480X272 },
    81         { "362x272 (4:3, centered)", "362x272 16-bit centered", CENTERED_362X272 },
    82         {0, 0, 0}
    83 };
     59void OSystem_PSP::initSDL() {
     60        SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER);
     61}
    8462
     63OSystem_PSP::~OSystem_PSP() {}
    8564
    86 OSystem_PSP::OSystem_PSP() : _screenWidth(0), _screenHeight(0), _overlayWidth(0), _overlayHeight(0),
    87                 _offscreen(0), _overlayBuffer(0), _overlayVisible(false), _shakePos(0), _lastScreenUpdate(0),
    88                 _mouseBuf(0), _prevButtons(0), _lastPadCheck(0), _mixer(0) {
    89         memset(_palette, 0, sizeof(_palette));
     65#define PSP_SCREEN_WIDTH 480
     66#define PSP_SCREEN_HEIGHT 272
    9067
    91         _cursorPaletteDisabled = true;
     68void OSystem_PSP::initBackend() {
     69        DEBUG_ENTER_FUNC();
    9270
    93         //init SDL
    94         uint32  sdlFlags = SDL_INIT_AUDIO | SDL_INIT_TIMER;
    95         SDL_Init(sdlFlags);
     71        _cursor.enableCursorPalette(false);
     72        _cursor.setXY(PSP_SCREEN_WIDTH >> 1, PSP_SCREEN_HEIGHT >> 1);   // Mouse in the middle of the screen
     73       
     74        // Set pointers for display manager
     75        _displayManager.setCursor(&_cursor);
     76        _displayManager.setScreen(&_screen);
     77        _displayManager.setOverlay(&_overlay);
     78        _displayManager.setKeyboard(&_keyboard);
     79        _displayManager.init();
    9680
    97         _clut = clut256;
    98         _mouseBuf = (byte *)mouseBuf256;
    99         _graphicMode = STRETCHED_480X272;
     81        // Set pointers for input handler
     82        _inputHandler.setCursor(&_cursor);
     83        _inputHandler.setKeyboard(&_keyboard);
     84        _inputHandler.init();
    10085
    101         _mouseX = PSP_SCREEN_WIDTH >> 1;        // Mouse in the middle of the screen
    102         _mouseY = PSP_SCREEN_HEIGHT >> 1;
    103         _dpadX = _dpadY = 0;
     86        initSDL();             
    10487
    105 
    106         // Init GU
    107         sceGuInit();
    108         sceGuStart(0, displayList);
    109         sceGuDrawBuffer(GU_PSM_8888, (void *)0, BUF_WIDTH);
    110         sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, (void*)PSP_FRAME_SIZE, BUF_WIDTH);
    111         sceGuDepthBuffer((void*)(PSP_FRAME_SIZE * 2), BUF_WIDTH);
    112         sceGuOffset(2048 - (PSP_SCREEN_WIDTH/2), 2048 - (PSP_SCREEN_HEIGHT/2));
    113         sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
    114         sceGuDepthRange(0xC350, 0x2710);
    115         sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
    116         sceGuEnable(GU_SCISSOR_TEST);
    117         sceGuFrontFace(GU_CW);
    118         sceGuEnable(GU_TEXTURE_2D);
    119         sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
    120         sceGuFinish();
    121         sceGuSync(0,0);
    122 
    123         sceDisplayWaitVblankStart();
    124         sceGuDisplay(1);
    125 
    126 }
    127 
    128 OSystem_PSP::~OSystem_PSP() {
    129 
    130         free(_offscreen);
    131         free(_overlayBuffer);
    132         free(_mouseBuf);
    133         delete _keyboard;
    134 
    135         _offscreen = 0;
    136         _overlayBuffer = 0;
    137         _mouseBuf = 0;
    138          sceGuTerm();
    139 }
    140 
    141 
    142 void OSystem_PSP::initBackend() {
    14388        _savefile = new PSPSaveFileManager;
    14489
    14590        _timer = new DefaultTimerManager();
    14691
    147         _keyboard = new PSPKeyboard();
    148         _keyboard->load();
    149 
     92        PSP_DEBUG_PRINT("calling keyboard.load()\n");
     93        _keyboard.load();       // Load virtual keyboard files into memory
     94       
    15095        setTimerCallback(&timer_handler, 10);
    15196
    15297        setupMixer();
    15398
    15499        OSystem::initBackend();
     100       
     101        DEBUG_EXIT_FUNC();
    155102}
    156103
    157 
    158104bool OSystem_PSP::hasFeature(Feature f) {
    159105        return (f == kFeatureOverlaySupportsAlpha || f == kFeatureCursorHasPalette);
    160106}
     
    167113}
    168114
    169115const OSystem::GraphicsMode* OSystem_PSP::getSupportedGraphicsModes() const {
    170         return s_supportedGraphicsModes;
     116        return _displayManager.getSupportedGraphicsModes();
    171117}
    172118
    173 
    174119int OSystem_PSP::getDefaultGraphicsMode() const {
    175         return STRETCHED_480X272;
     120        DEBUG_ENTER_FUNC();
     121
     122        int ret = _displayManager.getDefaultGraphicsMode();
     123
     124        DEBUG_EXIT_FUNC();
     125        return ret;
    176126}
    177127
    178128bool OSystem_PSP::setGraphicsMode(int mode) {
    179         _graphicMode = mode;
    180         return true;
     129        DEBUG_ENTER_FUNC();
     130       
     131        int ret = _displayManager.setGraphicsMode(mode);
     132       
     133        DEBUG_EXIT_FUNC();
     134        return ret;
    181135}
    182136
    183137bool OSystem_PSP::setGraphicsMode(const char *name) {
    184         int i = 0;
    185 
    186         while (s_supportedGraphicsModes[i].name) {
    187                 if (!strcmpi(s_supportedGraphicsModes[i].name, name)) {
    188                         _graphicMode = s_supportedGraphicsModes[i].id;
    189                         return true;
    190                 }
    191                 i++;
    192         }
    193 
    194         return false;
     138        DEBUG_ENTER_FUNC();
     139       
     140        int ret = _displayManager.setGraphicsMode(name);
     141       
     142        DEBUG_EXIT_FUNC();
     143        return ret;
    195144}
    196145
    197146int OSystem_PSP::getGraphicsMode() const {
    198         return _graphicMode;
     147        DEBUG_ENTER_FUNC();
     148       
     149        int ret = _displayManager.getGraphicsMode();
     150       
     151        DEBUG_EXIT_FUNC();
     152        return ret;
    199153}
    200154
    201 void OSystem_PSP::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
    202         PSPDebugTrace("initSize\n");
     155#ifdef USE_RGB_COLOR
    203156
    204         _screenWidth = width;
    205         _screenHeight = height;
     157Graphics::PixelFormat OSystem_PSP::getScreenFormat() const {
     158        return _screen.getScummvmPixelFormat();
     159}
    206160
    207         const int scrBufSize = _screenWidth * _screenHeight * (format ? format->bytesPerPixel : 4);
     161Common::List<Graphics::PixelFormat> OSystem_PSP::getSupportedFormats() {
     162        return _displayManager.getSupportedPixelFormats();
     163}
    208164
    209         _overlayWidth = PSP_SCREEN_WIDTH;       //width;
    210         _overlayHeight = PSP_SCREEN_HEIGHT;     //height;
     165#endif
    211166
    212         free(_overlayBuffer);
    213         _overlayBuffer = (OverlayColor *)memalign(16, _overlayWidth * _overlayHeight * sizeof(OverlayColor));
     167void OSystem_PSP::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
     168        DEBUG_ENTER_FUNC();
     169       
     170        _displayManager.setSizeAndPixelFormat(width, height, format);
    214171
    215         free(_offscreen);
    216         _offscreen = (byte *)memalign(16, scrBufSize);
    217         bzero(_offscreen, scrBufSize);
     172        _cursor.setVisible(false);
     173        _cursor.setLimits(_screen.getWidth(), _screen.getHeight());
    218174
    219         clearOverlay();
    220         memset(_palette, 0xFFFF, 256 * sizeof(unsigned short));
    221 
    222         _mouseVisible = false;
    223         sceKernelDcacheWritebackAll();
     175        DEBUG_EXIT_FUNC();
    224176}
    225177
    226178int16 OSystem_PSP::getWidth() {
    227         return _screenWidth;
     179        DEBUG_ENTER_FUNC();
     180
     181        int16 ret = (int16)_screen.getWidth();
     182       
     183        DEBUG_EXIT_FUNC();
     184        return ret;
    228185}
    229186
    230187int16 OSystem_PSP::getHeight() {
    231         return _screenHeight;
     188        DEBUG_ENTER_FUNC();
     189
     190        int16 ret = (int16)_screen.getHeight();
     191       
     192        DEBUG_EXIT_FUNC();
     193        return ret;
    232194}
    233195
    234196void OSystem_PSP::setPalette(const byte *colors, uint start, uint num) {
    235         const byte *b = colors;
     197        DEBUG_ENTER_FUNC();
     198       
     199        _screen.setPartialPalette(colors, start, num);
     200        _cursor.setScreenPalette(colors, start, num);
     201        _cursor.clearKeyColor();
    236202
    237         for (uint i = 0; i < num; ++i) {
    238                 _palette[start + i] = RGBToColour(b[0], b[1], b[2]);
    239                 b += 4;
    240         }
    241 
    242         //copy to CLUT
    243         memcpy(_clut, _palette, 256 * sizeof(unsigned short));
    244 
    245         //force update of mouse CLUT as well, as it may have been set up before this palette was set
    246         memcpy(mouseClut, _palette, 256 * sizeof(unsigned short));
    247         mouseClut[_mouseKeyColour] = 0;
    248 
    249         sceKernelDcacheWritebackAll();
     203        DEBUG_EXIT_FUNC();
    250204}
    251205
    252206void OSystem_PSP::setCursorPalette(const byte *colors, uint start, uint num) {
    253         const byte *b = colors;
     207        DEBUG_ENTER_FUNC();
    254208
    255         for (uint i = 0; i < num; ++i) {
    256                 cursorPalette[start + i] = RGBToColour(b[0], b[1], b[2]);
    257                 b += 4;
    258         }
     209        _cursor.setCursorPalette(colors, start, num);
     210        _cursor.enableCursorPalette(true);
     211        _cursor.clearKeyColor();        // Do we need this?
    259212
    260         cursorPalette[0] = 0;
    261 
    262         _cursorPaletteDisabled = false;
    263 
    264         sceKernelDcacheWritebackAll();
     213        DEBUG_EXIT_FUNC();
    265214}
    266215
    267216void OSystem_PSP::disableCursorPalette(bool disable) {
    268         _cursorPaletteDisabled = disable;
     217        DEBUG_ENTER_FUNC();
     218
     219        _cursor.enableCursorPalette(!disable);
     220       
     221        DEBUG_EXIT_FUNC();
    269222}
    270223
    271224void OSystem_PSP::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
    272         //Clip the coordinates
    273         if (x < 0) {
    274                 w += x;
    275                 buf -= x;
    276                 x = 0;
    277         }
     225        DEBUG_ENTER_FUNC();
    278226
    279         if (y < 0) {
    280                 h += y;
    281                 buf -= y * pitch;
    282                 y = 0;
    283         }
     227        _screen.copyFromRect(buf, pitch, x, y, w, h);
    284228
    285         if (w > _screenWidth - x) {
    286                 w = _screenWidth - x;
    287         }
    288 
    289         if (h > _screenHeight - y) {
    290                 h = _screenHeight - y;
    291         }
    292 
    293         if (w <= 0 || h <= 0)
    294                 return;
    295 
    296 
    297         byte *dst = _offscreen + y * _screenWidth + x;
    298 
    299         if (_screenWidth == pitch && pitch == w) {
    300                 memcpy(dst, buf, h * w);
    301         } else {
    302                 do {
    303                         memcpy(dst, buf, w);
    304                         buf += pitch;
    305                         dst += _screenWidth;
    306                 } while (--h);
    307         }
    308         sceKernelDcacheWritebackAll();
    309 
     229        DEBUG_EXIT_FUNC();
    310230}
    311231
    312232Graphics::Surface *OSystem_PSP::lockScreen() {
    313         _framebuffer.pixels = _offscreen;
    314         _framebuffer.w = _screenWidth;
    315         _framebuffer.h = _screenHeight;
    316         _framebuffer.pitch = _screenWidth;
    317         _framebuffer.bytesPerPixel = 1;
     233        DEBUG_ENTER_FUNC();
    318234
    319         return &_framebuffer;
     235        Graphics::Surface *ret = _screen.lockAndGetForEditing();       
     236       
     237        DEBUG_EXIT_FUNC();
     238        return ret;
    320239}
    321240
    322241void OSystem_PSP::unlockScreen() {
    323         // The screen is always completely update anyway, so we don't have to force a full update here.
    324         sceKernelDcacheWritebackAll();
     242        DEBUG_ENTER_FUNC();
     243        // The screen is always completely updated anyway, so we don't have to force a full update here.
     244        _screen.unlock();
     245       
     246        DEBUG_EXIT_FUNC();
    325247}
    326248
    327249void OSystem_PSP::updateScreen() {
    328         u32 now = getMillis();
    329         if (now - _lastScreenUpdate < 1000 / MAX_FPS)
    330                 return;
     250        DEBUG_ENTER_FUNC();
    331251
    332         _lastScreenUpdate = now;
    333 
    334         sceGuStart(0, displayList);
    335 
    336         sceGuClearColor(0xFF000000);
    337         sceGuClear(GU_COLOR_BUFFER_BIT);
    338 
    339         sceGuClutMode(GU_PSM_5551, 0, 0xFF, 0);
    340         sceGuClutLoad(32, clut256); // upload 32*8 entries (256)
    341         sceGuTexMode(GU_PSM_T8, 0, 0, 0); // 8-bit image
    342         if (_screenWidth == 320)
    343                 sceGuTexImage(0, 512, 256, _screenWidth, _offscreen);
    344         else
    345                 sceGuTexImage(0, 512, 512, _screenWidth, _offscreen);
    346         sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
    347         sceGuTexFilter(GU_LINEAR, GU_LINEAR);
    348         sceGuTexOffset(0,0);
    349         sceGuAmbientColor(0xFFFFFFFF);
    350         sceGuColor(0xFFFFFFFF);
    351 
    352         Vertex *vertices = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
    353         vertices[0].u = 0.5f;
    354         vertices[0].v = 0.5f;
    355         vertices[1].u = _screenWidth - 0.5f;
    356         vertices[1].v = _screenHeight - 0.5f;
    357 
    358         switch (_graphicMode) {
    359                 case CENTERED_320X200:
    360                         vertices[0].x = (PSP_SCREEN_WIDTH - 320) / 2;
    361                         vertices[0].y = (PSP_SCREEN_HEIGHT - 200) / 2;
    362                         vertices[0].z = 0;
    363                         vertices[1].x = PSP_SCREEN_WIDTH - (PSP_SCREEN_WIDTH - 320) / 2;
    364                         vertices[1].y = PSP_SCREEN_HEIGHT - (PSP_SCREEN_HEIGHT - 200) / 2;
    365                         vertices[1].z = 0;
    366                 break;
    367                 case CENTERED_435X272:
    368                         vertices[0].x = (PSP_SCREEN_WIDTH - 435) / 2;
    369                         vertices[0].y = 0; vertices[0].z = 0;
    370                         vertices[1].x = PSP_SCREEN_WIDTH - (PSP_SCREEN_WIDTH - 435) / 2;
    371                         vertices[1].y = PSP_SCREEN_HEIGHT;
    372                         vertices[1].z = 0;
    373                 break;
    374                 case STRETCHED_480X272:
    375                         vertices[0].x = 0;
    376                         vertices[0].y = 0;
    377                         vertices[0].z = 0;
    378                         vertices[1].x = PSP_SCREEN_WIDTH;
    379                         vertices[1].y = PSP_SCREEN_HEIGHT;
    380                         vertices[1].z = 0;
    381                 break;
    382                 case CENTERED_362X272:
    383                         vertices[0].x = (PSP_SCREEN_WIDTH - 362) / 2;
    384                         vertices[0].y = 0;
    385                         vertices[0].z = 0;
    386                         vertices[1].x = PSP_SCREEN_WIDTH - (PSP_SCREEN_WIDTH - 362) / 2;
    387                         vertices[1].y = PSP_SCREEN_HEIGHT;
    388                         vertices[1].z = 0;
    389                 break;
    390         }
    391 
    392         if (_shakePos) {
    393                 vertices[0].y += _shakePos;
    394                 vertices[1].y += _shakePos;
    395         }
    396 
    397         sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
    398         if (_screenWidth == 640) {
    399                 // 2nd draw
    400                 Vertex *vertices2 = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
    401                 sceGuTexImage(0, 512, 512, _screenWidth, _offscreen+512);
    402                 vertices2[0].u = 512 + 0.5f;
    403                 vertices2[0].v = vertices[0].v;
    404                 vertices2[1].u = vertices[1].u;
    405                 vertices2[1].v = _screenHeight - 0.5f;
    406                 vertices2[0].x = vertices[0].x + (vertices[1].x - vertices[0].x) * 511 / 640;
    407                 vertices2[0].y = 0;
    408                 vertices2[0].z = 0;
    409                 vertices2[1].x = vertices[1].x;
    410                 vertices2[1].y = vertices[1].y;
    411                 vertices2[1].z = 0;
    412                 sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices2);
    413         }
    414 
    415 
    416         // draw overlay
    417         if (_overlayVisible) {
    418                 Vertex *vertOverlay = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
    419                 vertOverlay[0].x = 0;
    420                 vertOverlay[0].y = 0;
    421                 vertOverlay[0].z = 0;
    422                 vertOverlay[1].x = PSP_SCREEN_WIDTH;
    423                 vertOverlay[1].y = PSP_SCREEN_HEIGHT;
    424                 vertOverlay[1].z = 0;
    425                 vertOverlay[0].u = 0.5f;
    426                 vertOverlay[0].v = 0.5f;
    427                 vertOverlay[1].u = _overlayWidth - 0.5f;
    428                 vertOverlay[1].v = _overlayHeight - 0.5f;
    429                 sceGuTexMode(GU_PSM_4444, 0, 0, 0); // 16-bit image
    430                 sceGuDisable(GU_ALPHA_TEST);
    431                 sceGuEnable(GU_BLEND);
    432 
    433                 //sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
    434                 sceGuBlendFunc(GU_ADD, GU_FIX, GU_ONE_MINUS_SRC_ALPHA, 0xFFFFFFFF, 0);
    435 
    436                 if (_overlayWidth > 320)
    437                         sceGuTexImage(0, 512, 512, _overlayWidth, _overlayBuffer);
    438                 else
    439                         sceGuTexImage(0, 512, 256, _overlayWidth, _overlayBuffer);
    440 
    441                 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
    442                 sceGuDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,0,vertOverlay);
    443                 // need to render twice for textures > 512
    444                 if ( _overlayWidth > 512) {
    445                         Vertex *vertOverlay2 = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
    446                         sceGuTexImage(0, 512, 512, _overlayWidth, _overlayBuffer + 512);
    447                         vertOverlay2[0].u = 512 + 0.5f;
    448                         vertOverlay2[0].v = vertOverlay[0].v;
    449                         vertOverlay2[1].u = vertOverlay[1].u;
    450                         vertOverlay2[1].v = _overlayHeight - 0.5f;
    451                         vertOverlay2[0].x = PSP_SCREEN_WIDTH * 512 / 640;
    452                         vertOverlay2[0].y = 0;
    453                         vertOverlay2[0].z = 0;
    454                         vertOverlay2[1].x = PSP_SCREEN_WIDTH;
    455                         vertOverlay2[1].y = PSP_SCREEN_HEIGHT;
    456                         vertOverlay2[1].z = 0;
    457                         sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertOverlay2);
    458                 }
    459                 sceGuDisable(GU_BLEND);
    460         }
    461 
    462         // draw mouse
    463         if (_mouseVisible) {
    464                 sceGuTexMode(GU_PSM_T8, 0, 0, 0); // 8-bit image
    465                 sceGuClutMode(GU_PSM_5551, 0, 0xFF, 0);
    466                 sceGuClutLoad(32, _cursorPaletteDisabled ? mouseClut : cursorPalette); // upload 32*8 entries (256)
    467                 sceGuAlphaFunc(GU_GREATER, 0, 0xFF);
    468                 sceGuEnable(GU_ALPHA_TEST);
    469                 sceGuTexImage(0, MOUSE_SIZE, MOUSE_SIZE, MOUSE_SIZE, _mouseBuf);
    470                 sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
    471 
    472                 Vertex *vertMouse = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
    473                 vertMouse[0].u = 0.5f;
    474                 vertMouse[0].v = 0.5f;
    475                 vertMouse[1].u = _mouseWidth - 0.5f;
    476                 vertMouse[1].v = _mouseHeight - 0.5f;
    477 
    478                 //adjust cursor position
    479                 int mX = _mouseX - _mouseHotspotX;
    480                 int mY = _mouseY - _mouseHotspotY;
    481 
    482                 if (_overlayVisible) {
    483                         float scalex, scaley;
    484 
    485                         scalex = (float)PSP_SCREEN_WIDTH /_overlayWidth;
    486                         scaley = (float)PSP_SCREEN_HEIGHT /_overlayHeight;
    487 
    488                         vertMouse[0].x = mX * scalex;
    489                         vertMouse[0].y = mY * scaley;
    490                         vertMouse[0].z = 0;
    491                         vertMouse[1].x = vertMouse[0].x + _mouseWidth * scalex;
    492                         vertMouse[1].y = vertMouse[0].y + _mouseHeight * scaley;
    493                         vertMouse[1].z = 0;
    494                 } else
    495                         switch (_graphicMode) {
    496                         case CENTERED_320X200:
    497                                 vertMouse[0].x = (PSP_SCREEN_WIDTH - 320) / 2 + mX;
    498                                 vertMouse[0].y = (PSP_SCREEN_HEIGHT - 200) / 2 + mY;
    499                                 vertMouse[0].z = 0;
    500                                 vertMouse[1].x = vertMouse[0].x + _mouseWidth;
    501                                 vertMouse[1].y = vertMouse[0].y + _mouseHeight;
    502                                 vertMouse[1].z = 0;
    503                         break;
    504                         case CENTERED_435X272:
    505                         {
    506                                 float scalex, scaley;
    507 
    508                                 scalex = 435.0f / _screenWidth;
    509                                 scaley = 272.0f / _screenHeight;
    510 
    511                                 vertMouse[0].x = (PSP_SCREEN_WIDTH - 435) / 2 + mX * scalex;
    512                                 vertMouse[0].y = mY * scaley;
    513                                 vertMouse[0].z = 0;
    514                                 vertMouse[1].x = vertMouse[0].x + _mouseWidth * scalex;
    515                                 vertMouse[1].y = vertMouse[0].y + _mouseHeight * scaley;
    516                                 vertMouse[1].z = 0;
    517                         }
    518                         break;
    519                         case CENTERED_362X272:
    520                         {
    521                                 float scalex, scaley;
    522 
    523                                 scalex = 362.0f / _screenWidth;
    524                                 scaley = 272.0f / _screenHeight;
    525 
    526                                 vertMouse[0].x = (PSP_SCREEN_WIDTH - 362) / 2 + mX * scalex;
    527                                 vertMouse[0].y = mY * scaley;
    528                                 vertMouse[0].z = 0;
    529                                 vertMouse[1].x = vertMouse[0].x + _mouseWidth * scalex;
    530                                 vertMouse[1].y = vertMouse[0].y + _mouseHeight * scaley;
    531                                 vertMouse[1].z = 0;
    532                         }
    533                         break;
    534                         case STRETCHED_480X272:
    535                         {
    536                                 float scalex, scaley;
    537 
    538                                 scalex = (float)PSP_SCREEN_WIDTH / _screenWidth;
    539                                 scaley = (float)PSP_SCREEN_HEIGHT / _screenHeight;
    540 
    541                                 vertMouse[0].x = mX * scalex;
    542                                 vertMouse[0].y = mY * scaley;
    543                                 vertMouse[0].z = 0;
    544                                 vertMouse[1].x = vertMouse[0].x + _mouseWidth * scalex;
    545                                 vertMouse[1].y = vertMouse[0].y + _mouseHeight * scaley;
    546                                 vertMouse[1].z = 0;
    547                         }
    548                         break;
    549                 }
    550                 sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertMouse);
    551         }
    552 
    553         if (_keyboard->isVisible()) {
    554                 _keyboard->render();
    555         }
    556 
    557         sceGuFinish();
    558         sceGuSync(0,0);
    559 
    560         sceDisplayWaitVblankStart();
    561         sceGuSwapBuffers();
     252        _displayManager.renderAll();
     253       
     254        DEBUG_EXIT_FUNC();
    562255}
    563256
    564257void OSystem_PSP::setShakePos(int shakeOffset) {
    565         _shakePos = shakeOffset;
     258        DEBUG_ENTER_FUNC();     
     259
     260        _screen.setShakePos(shakeOffset);
     261       
     262        DEBUG_EXIT_FUNC();     
    566263}
    567264
    568265void OSystem_PSP::showOverlay() {
    569         _overlayVisible = true;
     266        DEBUG_ENTER_FUNC();
     267
     268        _overlay.setVisible(true);
     269        _cursor.setLimits(_overlay.getWidth(), _overlay.getHeight());
     270        _cursor.useGlobalScaler(false); // mouse with overlay is 1:1
     271       
     272        DEBUG_EXIT_FUNC();
    570273}
    571274
    572275void OSystem_PSP::hideOverlay() {
    573         PSPDebugTrace("OSystem_PSP::hideOverlay called\n");
    574         _overlayVisible = false;
     276        DEBUG_ENTER_FUNC();
     277
     278        _overlay.setVisible(false);
     279        _cursor.setLimits(_screen.getWidth(), _screen.getHeight());
     280        _cursor.useGlobalScaler(true);  // mouse needs to be scaled with screen
     281       
     282        DEBUG_EXIT_FUNC();
    575283}
    576284
    577285void OSystem_PSP::clearOverlay() {
    578         PSPDebugTrace("clearOverlay\n");
     286        DEBUG_ENTER_FUNC();
    579287
    580         bzero(_overlayBuffer, _overlayWidth * _overlayHeight * sizeof(OverlayColor));
    581         sceKernelDcacheWritebackAll();
     288        _overlay.clearBuffer();
     289
     290        DEBUG_EXIT_FUNC();
    582291}
    583292
    584293void OSystem_PSP::grabOverlay(OverlayColor *buf, int pitch) {
    585         int h = _overlayHeight;
    586         OverlayColor *src = _overlayBuffer;
     294        DEBUG_ENTER_FUNC();
    587295
    588         do {
    589                 memcpy(buf, src, _overlayWidth * sizeof(OverlayColor));
    590                 src += _overlayWidth;
    591                 buf += pitch;
    592         } while (--h);
     296        _overlay.copyToArray(buf, pitch);
     297
     298        DEBUG_EXIT_FUNC();
    593299}
    594300
    595301void OSystem_PSP::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
    596         PSPDebugTrace("copyRectToOverlay\n");
     302        DEBUG_ENTER_FUNC();
    597303
    598         //Clip the coordinates
    599         if (x < 0) {
    600                 w += x;
    601                 buf -= x;
    602                 x = 0;
    603         }
     304        _overlay.copyFromRect(buf, pitch, x, y, w, h);
    604305
    605         if (y < 0) {
    606                 h += y;
    607                 buf -= y * pitch;
    608                 y = 0;
    609         }
    610 
    611         if (w > _overlayWidth - x) {
    612                 w = _overlayWidth - x;
    613         }
    614 
    615         if (h > _overlayHeight - y) {
    616                 h = _overlayHeight - y;
    617         }
    618 
    619         if (w <= 0 || h <= 0)
    620                 return;
    621 
    622 
    623         OverlayColor *dst = _overlayBuffer + (y * _overlayWidth + x);
    624 
    625         if (_overlayWidth == pitch && pitch == w) {
    626                 memcpy(dst, buf, h * w * sizeof(OverlayColor));
    627         } else {
    628                 do {
    629                         memcpy(dst, buf, w * sizeof(OverlayColor));
    630                         buf += pitch;
    631                         dst += _overlayWidth;
    632                 } while (--h);
    633         }
    634         sceKernelDcacheWritebackAll();
     306        DEBUG_EXIT_FUNC();
    635307}
    636308
    637309int16 OSystem_PSP::getOverlayWidth() {
    638         return _overlayWidth;
     310        return (int16) _overlay.getWidth();
    639311}
    640312
    641313int16 OSystem_PSP::getOverlayHeight() {
    642         return _overlayHeight;
     314        return (int16) _overlay.getHeight();
    643315}
    644316
    645 
    646317void OSystem_PSP::grabPalette(byte *colors, uint start, uint num) {
    647         uint i;
    648         uint16 color;
     318        DEBUG_ENTER_FUNC();
    649319
    650         for (i = start; i < start + num; i++) {
    651                 color = _palette[i];
    652                 *colors++ = ((color & 0x1F) << 3);
    653 &nbs