Ticket #9152: cleanup.4.diff
File cleanup.4.diff, 219.1 KB (added by , 15 years ago) |
---|
-
configure
1647 1647 # Enable 16bit support only for backends which support it 1648 1648 # 1649 1649 case $_backend in 1650 dreamcast | samsungtv | sdl | wii )1650 dreamcast | samsungtv | sdl | wii | psp) 1651 1651 if test "$_16bit" = auto ; then 1652 1652 _16bit=yes 1653 1653 else -
backends/platform/psp/psploader.h
135 135 } 136 136 137 137 #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 48 void InputHandler::init() { 49 sceCtrlSetSamplingCycle(0); // set sampling to vsync. n = n usecs 50 sceCtrlSetSamplingMode(1); // analog 51 } 52 53 bool 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 87 bool 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 108 bool 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 165 inline 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 195 bool 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 247 bool 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 301 inline 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 44 DisplayManager *GuRenderer::_displayManager = 0; 45 46 47 // class Palette ------------------------------------------------------------ 48 // 49 void 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 // 62 void 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 96 void 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 */ 134 void 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 161 bool 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 194 void 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 // 206 void 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 248 void 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 273 void 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 293 uint32 Palette::getRawColorAt(uint32 position) { 294 byte *pcolor = &_values[_pixelFormat.pixelsToBytes(position)]; 295 uint32 color = _pixelFormat.getColorValueAt(pcolor); 296 return color; 297 } 298 299 uint32 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 308 void 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 316 bool 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 */ 325 void 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 */ 335 void 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 */ 374 void 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 */ 395 void 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 */ 418 uint32 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 439 bool 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 480 void 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 496 void 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 */ 506 void 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) 527 void 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 561 void 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 594 INLINE 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 603 INLINE 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 627 INLINE 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 648 INLINE 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 656 INLINE 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 691 INLINE 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 699 INLINE 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. 709 void 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 */ 769 INLINE 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 */ 783 INLINE 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 796 INLINE 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 803 void GuRenderer::cacheInvalidate(void *pointer, uint32 size) { 804 sceKernelDcacheWritebackInvalidateRange(pointer, size); 805 } -
backends/platform/psp/trace.h
+
29 29 30 30 #include <stdio.h> 31 31 #include <psptypes.h> 32 #include <pspkernel.h>33 32 #include <stdarg.h> 34 #include <pspdebug.h>35 33 36 34 // Use these defines for debugging 37 35 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__ 40 40 41 void PSPDebugTrace (const char *filename, const char *format, ...); 42 void PSPDebugTrace (const char *format, ...); 41 void PSPDebugTrace (bool alsoToScreen, const char *format, ...); 43 42 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 44 extern int psp_debug_indent; 45 #endif 50 46 47 #endif /* TRACE_H */ 51 48 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 53 62 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 */ 32 class MasterGuRenderer { 33 public: 34 MasterGuRenderer() : _lastRenderTime(0) {} 35 void guInit(); 36 void guPreRender(); 37 void guPostRender(); 38 void guShutDown(); 39 private: 40 static uint32 _displayList[]; 41 uint32 _lastRenderTime; // For measuring rendering 42 void guProgramDisplayBufferSizes(); 43 }; 44 45 class Screen; 46 class Overlay; 47 class Cursor; 48 class PSPKeyboard; 49 50 /** 51 * Class that manages all display clients 52 */ 53 class DisplayManager { 54 public: 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 87 private: 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
26 26 #define USERSPACE_ONLY //don't use kernel mode features 27 27 28 28 #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> 31 33 #endif 32 34 33 35 #include <psppower.h> … … 118 120 cbid = sceKernelCreateCallback("Power Callback", (SceKernelCallbackFunction)power_callback, 0); 119 121 if (cbid >= 0) { 120 122 if (scePowerRegisterCallback(-1, cbid) < 0) { 121 PSP DebugTrace("SetupCallbacks():Couldn't register callback for power_callback\n");123 PSP_ERROR("Couldn't register callback for power_callback\n"); 122 124 } 123 125 } else { 124 PSP DebugTrace("SetupCallbacks():Couldn't create a callback for power_callback\n");126 PSP_ERROR("Couldn't create a callback for power_callback\n"); 125 127 } 126 128 127 129 sceKernelSleepThreadCB(); … … 167 169 168 170 return res; 169 171 } 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 38 void 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 110 test: 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 132 inline 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 140 inline 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 165 DECLARE_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 173 void *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 208 void 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
1 1 MODULE := backends/platform/psp 2 2 3 MODULE_OBJS := \ 4 powerman.o \ 3 MODULE_OBJS := powerman.o \ 5 4 psp_main.o \ 6 5 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 \ 7 13 trace.o \ 8 14 psploader.o \ 9 15 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 */ 32 class DefaultDisplayClient : public DisplayClient { 33 public: 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 58 protected: 59 Buffer _buffer; 60 Palette _palette; 61 GuRenderer _renderer; 62 bool _visible; 63 bool _dirty; 64 }; 65 66 /** 67 * Screen overlay class. 68 */ 69 class Overlay : public DefaultDisplayClient { 70 public: 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 */ 85 class Screen : public DefaultDisplayClient { 86 public: 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 102 private: 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 36 void 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 52 void Cursor::deallocate() { 53 DEBUG_ENTER_FUNC(); 54 55 _buffer.deallocate(); 56 _palette.deallocate(); 57 _screenPalette.deallocate(); 58 59 DEBUG_EXIT_FUNC(); 60 } 61 62 void 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 80 void 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 93 void 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 110 void 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 128 void 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 142 inline 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 152 void 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 169 void 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 181 bool 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 216 void 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 229 INLINE 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 261 void 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 288 void 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 338 void 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 349 INLINE void Cursor::updateRendererOffset() { 350 DEBUG_ENTER_FUNC(); 351 _renderer.setOffsetOnScreen(_x - _hotspotX, _y - _hotspotY); 352 DEBUG_EXIT_FUNC(); 353 } 354 355 INLINE 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 36 void 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. 73 void 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 124 Graphics::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 156 uint32 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
+ +
24 24 */ 25 25 26 26 //#define PSP_KB_SHELL /* Need a hack to properly load the keyboard from the PSP shell */ 27 27 28 #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 */ 29 30 #endif 30 //#define PSP_KB_DEBUG31 31 32 //#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */ 33 //#define __PSP_DEBUG_PRINT__ 34 35 #include "backends/platform/psp/trace.h" 32 36 #include <malloc.h> 33 37 #include "pspkernel.h" 34 #include <pspgu.h>35 38 #include "png.h" 36 #include " pspkeyboard.h"39 #include "backends/platform/psp/pspkeyboard.h" 37 40 #include "common/keyboard.h" 38 41 #include "common/fs.h" 39 42 #include "common/unzip.h" … … 94 97 file->read(data, length); 95 98 } 96 99 100 // Array with file names 101 const 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 97 108 // Constructor 98 109 PSPKeyboard::PSPKeyboard() { 110 DEBUG_ENTER_FUNC(); 111 99 112 _init = false; // we're not initialized yet 100 113 _prevButtons = 0; // Reset previous buttons 101 _dirty = true; // keyboard needs redrawing102 _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) 103 116 _oldCursor = kCenter; // Center cursor by default 104 _moved _x= 20; // Default starting location105 _moved _y= 50;117 _movedX = 20; // Default starting location 118 _movedY = 50; 106 119 _moved = false; // Keyboard wasn't moved recently 107 120 _state = kInvisible; // We start invisible 108 121 _lastState = kInvisible; 122 123 // Constant renderer settings 124 _renderer.setAlphaBlending(true); 125 _renderer.setColorTest(false); 126 _renderer.setUseGlobalScaler(false); 127 128 DEBUG_EXIT_FUNC(); 109 129 } 110 130 111 131 // Destructor 112 132 PSPKeyboard::~PSPKeyboard() { 113 if (!_init) return; 133 DEBUG_ENTER_FUNC(); 134 135 if (!_init) { 136 DEBUG_EXIT_FUNC(); 137 return; 138 } 114 139 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(); 121 143 } 122 144 _init = false; 145 146 DEBUG_EXIT_FUNC(); 123 147 } 124 148 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)) { 149 void PSPKeyboard::setVisible(bool val) { 150 if (val && _state == kInvisible && _init) { // Check also that were loaded correctly 157 151 _lastState = _state; 158 _state = kMove; // Check for move or visible state 159 usedInput = true; 160 goto END; 152 _state = kMove; 161 153 } 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; 195 157 } 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(); 372 159 } 373 160 374 375 161 /* move the position the keyboard is currently drawn at */ 376 162 void 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(); 379 170 } 380 171 381 172 /* move the position the keyboard is currently drawn at */ 382 173 void PSPKeyboard::increaseKeyboardLocationX(int amount) { 383 int newX = _moved_x + amount; 174 DEBUG_ENTER_FUNC(); 175 176 int newX = _movedX + amount; 384 177 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(); 386 180 return; 387 _moved_x = newX; 181 } 182 _movedX = newX; 183 setDirty(); 184 185 DEBUG_EXIT_FUNC(); 388 186 } 389 187 390 188 /* move the position the keyboard is currently drawn at */ 391 189 void PSPKeyboard::increaseKeyboardLocationY(int amount) { 392 int newY = _moved_y + amount; 190 DEBUG_ENTER_FUNC(); 191 192 int newY = _movedY + amount; 393 193 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(); 395 196 return; 396 _moved_y = newY; 197 } 198 _movedY = newY; 199 setDirty(); 200 201 DEBUG_EXIT_FUNC(); 397 202 } 398 203 399 204 /* draw the keyboard at the current position */ 400 205 void 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 402 220 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 } 403 236 404 switch(_oldCursor) { 237 inline void PSPKeyboard::convertCursorToXY(CursorDirections cur, int &x, int &y) { 238 switch(cur) { 405 239 case kUp: 406 240 x = 1; 407 241 y = 0; … … 423 257 y = 1; 424 258 break; 425 259 } 426 427 // Draw the background letters428 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 at435 x * 43, y * 43,436 //internal offset of the image437 x * 64, y * 64,438 //size to render (always the same)439 64, 64);440 260 } 441 261 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 */ 489 263 bool PSPKeyboard::load() { 490 unsigned char *temp_texture = NULL; 491 uint32 *temp_palette = NULL; 492 int a; 264 DEBUG_ENTER_FUNC(); 493 265 494 if (_init) 266 if (_init) { 267 PSP_DEBUG_PRINT("keyboard already loaded into memory\n"); 268 DEBUG_EXIT_FUNC(); 495 269 return true; 270 } 496 271 497 272 // For the shell, we must use a hack 498 273 #ifdef PSP_KB_SHELL … … 500 275 #else /* normal mode */ 501 276 Common::FSNode node("."); // Look in current directory 502 277 #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()); 506 279 507 280 Common::Archive *fileArchive = NULL; 508 281 Common::Archive *zipArchive = NULL; 509 282 Common::SeekableReadStream * file = 0; 510 283 511 284 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"); 515 286 fileArchive = new Common::FSDirectory(node.getChild("kbd")); 516 287 } 517 288 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"); 521 290 zipArchive = Common::makeZipArchive(node.getChild("kbd.zip")); 522 291 } 523 292 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++) { 526 297 uint32 height = 0, width = 0, paletteSize = 0; 527 298 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]); 531 300 532 301 // 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"); 534 304 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]); 540 306 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]); 542 308 goto ERROR; 543 309 } 544 310 } 545 311 // 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"); 547 314 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]); 553 316 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]); 555 318 goto ERROR; 556 319 } 557 320 } 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]); 559 322 goto ERROR; 560 323 } 561 324 562 if (get _png_image_size(file, &width, &height, &paletteSize) == 0) { // Check image size and palette size325 if (getPngImageSize(file, &width, &height, &paletteSize) == 0) { // Check image size and palette size 563 326 // 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 568 330 if (paletteSize) { // 8 or 4-bit image 569 uint32 textureSize = 0;570 571 331 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; 574 335 } else if (paletteSize <= 256){ // 8-bit image 575 336 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); 577 339 } else { 578 fprintf(stderr, "Error:palette of %d too big!\n", paletteSize);340 PSP_ERROR("palette of %d too big!\n", paletteSize); 579 341 goto ERROR; 580 342 } 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 587 344 } else { // 32-bit image 588 temp_texture = (unsigned char *)malloc((width * height)<<2);345 _buffers[i].setPixelFormat(PSPPixelFormat::Type_8888); 589 346 } 347 348 _buffers[i].allocate(); 349 _palettes[i].allocate(); 590 350 591 351 // Try to load the image 592 352 file->seek(0); // Go back to start 593 353 594 if (load _png_image(file, temp_texture, temp_palette) != 0)354 if (loadPngImage(file, _buffers[i], _palettes[i]) != 0) 595 355 goto ERROR; 596 356 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"); 607 358 608 uint32 size;609 610 if (paletteSize == 16) // 4 bit611 size = (_keyTextures[a].surface_width * _keyTextures[a].surface_height)>>1;612 else if (paletteSize == 256) // 8-bit613 size = _keyTextures[a].surface_width * _keyTextures[a].surface_height;614 else // 32 bit615 size = (_keyTextures[a].surface_width * _keyTextures[a].surface_height)<<2;616 617 #ifdef PSP_KB_DEBUG618 fprintf(stderr, "load(): perm texture width=%d, height=%d, size=%d\n", _keyTextures[a].surface_width, _keyTextures[a].surface_height, size);619 #endif620 _keyTextures[a].texture = (unsigned char *)memalign(16, size); // Allocate memory621 622 block_copy(&_keyTextures[a], temp_texture); // Copy temp texture to permanent texture623 624 359 if (paletteSize == 16) // 4-bit 625 flipNibbles(&_keyTextures[a]);360 _buffers[i].flipNibbles(); 626 361 627 free(temp_texture);628 629 362 delete file; 630 363 } 631 364 } 632 else 365 else { 366 PSP_ERROR("couldn't obtain PNG image size\n"); 633 367 goto ERROR; 368 } 634 369 } /* for loop */ 370 635 371 _init = true; 636 372 637 373 delete fileArchive; 638 374 delete zipArchive; 639 375 376 DEBUG_EXIT_FUNC(); 640 377 return true; 641 378 642 379 ERROR: 643 380 644 // Error .. Couldn't get png info from one of the needed files645 free(temp_texture);646 381 delete file; 647 382 delete fileArchive; 648 383 delete zipArchive; 649 384 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(); 654 388 } 655 389 _init = false; 390 391 DEBUG_EXIT_FUNC(); 656 392 return false; 657 393 } 658 394 659 // Copy texture from regular size image to power of 2 size image660 //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-bit666 width = surface->texture_width >> 1;667 stride = (surface->surface_width - surface->texture_width)>>1;668 break;669 case 256: // 8-bit670 width = surface->texture_width;671 stride = surface->surface_width - surface->texture_width;672 break;673 case 0: // 32-bit674 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 line691 if (stride > 0) {692 dest += stride;693 }694 }695 }696 697 // Convert 4 bit images to match weird PSP format698 //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 712 395 static void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg) { 713 396 // ignore PNG warnings 714 397 } 715 398 716 399 /* 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) { 400 int PSPKeyboard::getPngImageSize(Common::SeekableReadStream *file, uint32 *png_width, uint32 *png_height, u32 *paletteSize) { 401 DEBUG_ENTER_FUNC(); 402 718 403 png_structp png_ptr; 719 404 png_infop info_ptr; 720 405 unsigned int sig_read = 0; … … 723 408 724 409 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 725 410 if (png_ptr == NULL) { 411 DEBUG_EXIT_FUNC(); 726 412 return -1; 727 413 } 728 414 png_set_error_fn(png_ptr, (png_voidp) NULL, (png_error_ptr) NULL, user_warning_fn); 729 415 info_ptr = png_create_info_struct(png_ptr); 730 416 if (info_ptr == NULL) { 731 417 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); 418 DEBUG_EXIT_FUNC(); 732 419 return -1; 733 420 } 734 421 // Set the png lib to use our read function … … 746 433 747 434 *png_width = width; 748 435 *png_height = height; 436 437 DEBUG_EXIT_FUNC(); 749 438 return 0; 750 439 } 751 440 752 441 // Load a texture from a png image 753 442 // 754 int PSPKeyboard::load_png_image(Common::SeekableReadStream *file, unsigned char *ImageBuffer, uint32 *palette) { 443 int PSPKeyboard::loadPngImage(Common::SeekableReadStream *file, Buffer &buffer, Palette &palette) { 444 DEBUG_ENTER_FUNC(); 445 755 446 png_structp png_ptr; 756 447 png_infop info_ptr; 757 448 unsigned int sig_read = 0; 758 449 png_uint_32 width, height; 759 450 int bit_depth, color_type, interlace_type; 760 size_t x,y;451 size_t y; 761 452 762 453 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 763 454 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(); 765 457 return -1; 766 458 } 767 459 // Use dummy error function … … 769 461 770 462 info_ptr = png_create_info_struct(png_ptr); 771 463 if (info_ptr == NULL) { 464 PSP_ERROR("Couldn't create info struct to load keyboard\n"); 772 465 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); 466 DEBUG_EXIT_FUNC(); 773 467 return -1; 774 468 } 775 469 776 // Set the png lib to use our read function470 // Set the png lib to use our customized read function 777 471 png_set_read_fn(png_ptr, (void *)file, pngReadStreamRead); 778 472 779 473 png_set_sig_bytes(png_ptr, sig_read); … … 784 478 png_set_strip_16(png_ptr); 785 479 786 480 if (color_type == PNG_COLOR_TYPE_PALETTE) { 787 // We copy the palette 788 uint32 *dstPal = palette; 481 // Copy the palette 789 482 png_colorp srcPal = info_ptr->palette; 790 483 for(int i=0; i < info_ptr->num_palette; i++) { 791 484 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); 793 486 srcPal++; 794 487 } 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);808 488 } else { // Not a palettized image 489 // Round up grayscale images 809 490 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr); 810 491 // Convert trans channel to alpha for 32 bits 811 492 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); 493 // Filler for alpha? 812 494 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); 495 } 813 496 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 } 819 504 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); 829 509 } 830 510 511 free(line); 512 831 513 png_read_end(png_ptr, info_ptr); 832 514 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); 833 515 516 DEBUG_EXIT_FUNC(); 834 517 return 0; 835 518 } 836 519 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) 841 528 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 */ 534 bool 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 577 void PSPKeyboard::handleMoveState(SceCtrlData &pad) { 578 DEBUG_ENTER_FUNC(); 579 if (UP(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 850 587 } 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); 851 600 } 852 return 0;601 DEBUG_EXIT_FUNC(); 853 602 } 854 603 604 bool 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 621 bool 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 635 bool 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 699 void 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 727 void 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 742 void 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
32 32 #include "sound/mixer_intern.h" 33 33 #include "backends/base-backend.h" 34 34 #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" 35 38 #include "backends/platform/psp/pspkeyboard.h" 39 #include "backends/platform/psp/display_manager.h" 40 #include "backends/platform/psp/input.h" 36 41 37 42 #include <SDL.h> 38 43 39 #include <pspctrl.h>40 41 enum GraphicModeID {42 CENTERED_320X200,43 CENTERED_435X272,44 STRETCHED_480X272,45 CENTERED_362X27246 };47 48 44 class 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 45 private: 46 91 47 Common::SaveFileManager *_savefile; 92 48 Audio::MixerImpl *_mixer; 93 49 Common::TimerManager *_timer; 94 50 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; 96 58 59 void initSDL(); 60 97 61 public: 98 OSystem_PSP() ;99 virtual~OSystem_PSP();62 OSystem_PSP() : _savefile(0), _mixer(0), _timer(0) {} 63 ~OSystem_PSP(); 100 64 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); 110 78 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); 112 117 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); 116 121 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); 126 125 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 146 127 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; } 148 130 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); 153 136 137 // Sound 154 138 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); 158 140 Audio::Mixer *getMixer() { return _mixer; } 159 Common::TimerManager *getTimerManager() { return _timer; } 141 142 // Misc 143 Common::SaveFileManager *getSavefileManager() { return _savefile; } 160 144 FilesystemFactory *getFilesystemFactory() { return &PSPFilesystemFactory::instance(); } 161 145 void getTimeAndDate(TimeDate &t) const; 162 146 163 v irtual void quit();147 void quit(); 164 148 165 virtual Common::SeekableReadStream *createConfigReadStream(); 166 virtual Common::WriteStream *createConfigWriteStream(); 149 Common::SeekableReadStream *createConfigReadStream(); 150 Common::WriteStream *createConfigWriteStream(); 151 167 152 }; 168 153 169 170 154 #endif /* OSYS_PSP_H */ -
backends/platform/psp/powerman.cpp
23 23 * 24 24 */ 25 25 26 //#define __PSP_DEBUG_FUNCS__ /* can put this locally too */ 27 //#define __PSP_DEBUG_PRINT__ 28 #include "backends/platform/psp/trace.h" 29 26 30 #include <psppower.h> 27 31 #include <pspthreadman.h> 28 32 29 #include "./powerman.h" 30 #include "./trace.h" 33 #include "backends/platform/psp/powerman.h" 31 34 #include "engine.h" 32 35 33 36 DECLARE_SINGLETON(PowerManager) 34 37 35 #ifdef __PSP_DEBUG_SUSPEND__ 36 void PowerManager::debugPM() {37 PSP DebugTrace("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) 39 inline 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); 39 42 } 40 #else41 #define debugPM()42 #define PMStatusSet(x)43 #endif /* __PSP_DEBUG_SUSPEND__ */44 43 45 44 46 45 /******************************************* … … 49 48 * 50 49 ********************************************/ 51 50 PowerManager::PowerManager() { 52 51 DEBUG_ENTER_FUNC(); 52 53 53 _flagMutex = NULL; /* Init mutex handle */ 54 54 _listMutex = NULL; /* Init mutex handle */ 55 55 _condSuspendable = NULL; /* Init condition variable */ … … 57 57 58 58 _condSuspendable = SDL_CreateCond(); 59 59 if (_condSuspendable <= 0) { 60 PSP DebugSuspend("PowerManager::PowerManager(): Couldn't create condSuspendable\n");60 PSP_ERROR("Couldn't create Suspendable condition variable\n"); 61 61 } 62 62 63 63 _condPM = SDL_CreateCond(); 64 64 if (_condPM <= 0) { 65 PSP DebugSuspend("PowerManager::PowerManager(): Couldn't create condPM\n");65 PSP_ERROR("Couldn't create PM condition variable\n"); 66 66 } 67 67 68 68 _flagMutex = SDL_CreateMutex(); 69 69 if (_flagMutex <= 0) { 70 PSP DebugSuspend("PowerManager::PowerManager(): Couldn't create flagMutex\n");70 PSP_ERROR("Couldn't create flag Mutex\n"); 71 71 } 72 72 73 73 _listMutex = SDL_CreateMutex(); 74 74 if (_listMutex <= 0) { 75 PSP DebugSuspend("PowerManager::PowerManager(): Couldn't create listMutex\n");75 PSP_ERROR("Couldn't create list Mutex\n"); 76 76 } 77 77 78 78 _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; 83 83 _listCounter = 0; 84 84 PMStatusSet(kInitDone); 85 85 _error = 0; 86 #endif 86 87 DEBUG_EXIT_FUNC(); 87 88 } 88 89 89 90 /******************************************* … … 92 93 * 93 94 ********************************************/ 94 95 int PowerManager::registerSuspend(Suspendable *item) { 96 DEBUG_ENTER_FUNC(); 95 97 // Register in list 96 PSPDebugSuspend("In registerSuspend\n");97 98 debugPM(); 98 99 99 100 if (SDL_mutexP(_listMutex) != 0) { 100 PSP DebugTrace("PowerManager::registerSuspend(): Couldn't lock _listMutex %d\n", _listMutex);101 PSP_ERROR("Couldn't lock _listMutex[%p]\n", _listMutex); 101 102 } 102 103 103 104 _suspendList.push_front(item); 104 #ifdef __PSP_DEBUG_SUSPEND__105 105 _listCounter++; 106 #endif107 106 108 107 if (SDL_mutexV(_listMutex) != 0) { 109 PSP DebugTrace("PowerManager::registerSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);108 PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex); 110 109 } 111 112 PSPDebugSuspend("Out of registerSuspend\n"); 110 113 111 debugPM(); 114 112 113 DEBUG_EXIT_FUNC(); 115 114 return 0; 116 115 } 117 116 … … 121 120 * 122 121 ********************************************/ 123 122 int PowerManager::unregisterSuspend(Suspendable *item) { 124 125 PSPDebugSuspend("In unregisterSuspend\n"); 123 DEBUG_ENTER_FUNC(); 126 124 debugPM(); 127 125 128 126 // Unregister from stream list 129 127 if (SDL_mutexP(_listMutex) != 0) { 130 PSP DebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);128 PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex); 131 129 } 132 130 133 131 _suspendList.remove(item); 134 #ifdef __PSP_DEBUG_SUSPEND__135 132 _listCounter--; 136 #endif137 133 138 134 if (SDL_mutexV(_listMutex) != 0) { 139 PSP DebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);135 PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex); 140 136 } 141 137 142 PSP DebugSuspend("Out of unregisterSuspend\n");138 PSP_DEBUG_PRINT("Out of unregisterSuspend\n"); 143 139 debugPM(); 144 140 141 DEBUG_EXIT_FUNC(); 145 142 return 0; 146 143 } 147 144 … … 151 148 * 152 149 ********************************************/ 153 150 PowerManager::~PowerManager() { 154 155 #ifdef __PSP_DEBUG_SUSPEND__ 151 DEBUG_ENTER_FUNC(); 152 156 153 PMStatusSet(kDestroyPM); 157 #endif158 154 159 155 SDL_DestroyCond(_condSuspendable); 160 156 _condSuspendable = 0; … … 167 163 168 164 SDL_DestroyMutex(_listMutex); 169 165 _listMutex = 0; 166 167 DEBUG_EXIT_FUNC(); 170 168 } 171 169 172 170 /******************************************* … … 184 182 185 183 if ((pause != _pauseFlagOld) && g_engine) { // Check to see if we have an engine 186 184 if (pause && _pauseClientState == PowerManager::Unpaused) { 187 _pauseClientState = PowerManager::Pausing; // Tell PM we're in the middle of pausing185 _pauseClientState = PowerManager::Pausing; // Tell PM we're in the middle of pausing 188 186 g_engine->pauseEngine(true); 189 PSP DebugSuspend("Pausing engine in PowerManager::pollPauseEngine()\n");187 PSP_DEBUG_PRINT_FUNC("Pausing engine\n"); 190 188 _pauseClientState = PowerManager::Paused; // Tell PM we're done pausing 191 189 } 192 190 else if (!pause && _pauseClientState == PowerManager::Paused) { 193 191 g_engine->pauseEngine(false); 194 PSP DebugSuspend("Unpausing for resume in PowerManager::pollPauseEngine()\n");192 PSP_DEBUG_PRINT_FUNC("Unpausing for resume\n"); 195 193 _pauseClientState = PowerManager::Unpaused; // Tell PM we're in the middle of pausing 196 194 } 197 195 … … 205 203 * Use this for small critical sections where you can easily restore the previous state. 206 204 * 207 205 ********************************************/ 208 206 int PowerManager::blockOnSuspend() { 209 207 return beginCriticalSection(true); 210 208 } 211 209 … … 216 214 * Make sure to call endCriticalSection or the PSP won't suspend. 217 215 ********************************************/ 218 216 219 int PowerManager::beginCriticalSection(bool justBlock) { 217 int PowerManager::beginCriticalSection(bool justBlock) { 218 DEBUG_ENTER_FUNC(); 219 220 220 int ret = NotBlocked; 221 221 222 222 if (SDL_mutexP(_flagMutex) != 0) { 223 PSP DebugTrace("PowerManager::blockOnSuspend(): Couldn't lock flagMutex %d\n", _flagMutex);223 PSP_ERROR("PowerManager::blockOnSuspend(): Couldn't lock flagMutex[%p]\n", _flagMutex); 224 224 ret = Error; 225 225 } 226 226 227 227 // Check the access flag 228 228 if (_suspendFlag == true) { 229 PSP DebugSuspend("We're being blocked!\n");229 PSP_DEBUG_PRINT("We're being blocked!\n"); 230 230 debugPM(); 231 231 ret = Blocked; 232 232 233 233 // If it's true, we wait for a signal to continue 234 234 if (SDL_CondWait(_condSuspendable, _flagMutex) != 0) { 235 PSP DebugTrace("PowerManager::blockOnSuspend(): Couldn't wait on cond %d\n", _condSuspendable);235 PSP_DEBUG_PRINT("PowerManager::blockOnSuspend(): Couldn't wait on cond[%p]\n", _condSuspendable); 236 236 } 237 237 238 PSP DebugSuspend("We got blocked!!\n");238 PSP_DEBUG_PRINT("We got blocked!!\n"); 239 239 debugPM(); 240 240 } 241 241 … … 244 244 _criticalCounter++; 245 245 246 246 if (SDL_mutexV(_flagMutex) != 0) { 247 PSP DebugTrace("PowerManager::blockOnSuspend(): Couldn't unlock flagMutex %d\n", _flagMutex);247 PSP_ERROR("PowerManager::blockOnSuspend(): Couldn't unlock flagMutex[%p]\n", _flagMutex); 248 248 ret = Error; 249 249 } 250 250 251 DEBUG_EXIT_FUNC(); 251 252 return ret; 252 253 } 253 254 254 255 int PowerManager::endCriticalSection() { 256 DEBUG_ENTER_FUNC(); 255 257 int ret = 0; 256 258 257 259 if (SDL_mutexP(_flagMutex) != 0) { 258 PSP DebugTrace("PowerManager::endCriticalSection(): Couldn't lock flagMutex %d\n", _flagMutex);260 PSP_ERROR("PowerManager::endCriticalSection(): Couldn't lock flagMutex[%p]\n", _flagMutex); 259 261 ret = Error; 260 262 } 261 263 … … 264 266 265 267 if (_criticalCounter <= 0) { 266 268 if (_suspendFlag == true) { // If the PM is sleeping, this flag must be set 267 PSP DebugSuspend("Unblocked thread waking up the PM.\n");269 PSP_DEBUG_PRINT("Unblocked thread waking up the PM.\n"); 268 270 debugPM(); 269 271 270 272 SDL_CondBroadcast(_condPM); 271 273 272 PSP DebugSuspend("Woke up the PM\n");274 PSP_DEBUG_PRINT("Woke up the PM\n"); 273 275 debugPM(); 274 276 } 275 277 276 278 if (_criticalCounter < 0) { // Check for bad usage of critical sections 277 PSP DebugTrace("PowerManager::endCriticalSection(): Error! Critical counter is %d\n", _criticalCounter);279 PSP_ERROR("Critical counter[%d]\n", _criticalCounter); 278 280 debugPM(); 279 281 } 280 282 } 281 283 282 284 if (SDL_mutexV(_flagMutex) != 0) { 283 PSP DebugTrace("PowerManager::endCriticalSection(): Couldn't unlock flagMutex %d\n", _flagMutex);285 PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex); 284 286 ret = Error; 285 287 } 286 288 289 DEBUG_EXIT_FUNC(); 287 290 return ret; 288 291 } 289 292 … … 293 296 * 294 297 ********************************************/ 295 298 int PowerManager::suspend() { 299 DEBUG_ENTER_FUNC(); 296 300 int ret = 0; 297 301 298 302 if (_pauseFlag) return ret; // Very important - make sure we only suspend once … … 325 329 // Now we set the suspend flag to true to cause reading threads to block 326 330 327 331 if (SDL_mutexP(_flagMutex) != 0) { 328 PSP DebugTrace("PowerManager::suspend(): Couldn't lock flagMutex %d\n", _flagMutex);332 PSP_ERROR("Couldn't lock flagMutex[%p]\n", _flagMutex); 329 333 _error = Error; 330 334 ret = Error; 331 335 } … … 342 346 } 343 347 344 348 if (SDL_mutexV(_flagMutex) != 0) { 345 PSP DebugTrace("PowerManager::suspend(): Couldn't unlock flagMutex %d\n", _flagMutex);349 PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex); 346 350 _error = Error; 347 351 ret = Error; 348 352 } … … 351 355 352 356 // Loop over list, calling suspend() 353 357 if (SDL_mutexP(_listMutex) != 0) { 354 PSP DebugTrace("PowerManager::suspend(): Couldn't lock listMutex %d\n", _listMutex);358 PSP_ERROR("Couldn't lock listMutex[%p]\n", _listMutex); 355 359 _error = Error; 356 360 ret = Error; 357 361 } 358 362 PMStatusSet(kIteratingListSuspend); 359 363 // Iterate 360 Common::List<Suspendable *>::iterator i = _suspendList.begin();364 Common::List<Suspendable *>::iterator i; 361 365 362 for ( ; i != _suspendList.end(); ++i) {366 for (i = _suspendList.begin(); i != _suspendList.end(); ++i) { 363 367 (*i)->suspend(); 364 368 } 365 369 366 370 PMStatusSet(kDoneIteratingListSuspend); 367 371 368 372 if (SDL_mutexV(_listMutex) != 0) { 369 PSP DebugTrace("PowerManager::suspend(): Couldn't unlock listMutex %d\n", _listMutex);373 PSP_ERROR("Couldn't unlock listMutex[%p]\n", _listMutex); 370 374 _error = Error; 371 375 ret = Error; 372 376 } … … 374 378 375 379 scePowerUnlock(0); // Allow the PSP to go to sleep now 376 380 381 DEBUG_EXIT_FUNC(); 377 382 return ret; 378 383 } 379 384 … … 383 388 * 384 389 ********************************************/ 385 390 int PowerManager::resume() { 391 DEBUG_ENTER_FUNC(); 386 392 int ret = 0; 387 393 388 394 // Make sure we can't get another suspend … … 394 400 395 401 // First we notify our Suspendables. Loop over list, calling resume() 396 402 if (SDL_mutexP(_listMutex) != 0) { 397 PSP DebugTrace("PowerManager::resume(): Couldn't lock listMutex %d\n", _listMutex);403 PSP_ERROR("Couldn't lock listMutex[%p]\n", _listMutex); 398 404 _error = Error; 399 405 ret = Error; 400 406 } … … 409 415 PMStatusSet(kDoneIteratingListResume); 410 416 411 417 if (SDL_mutexV(_listMutex) != 0) { 412 PSP DebugTrace("PowerManager::resume(): Couldn't unlock listMutex %d\n", _listMutex);418 PSP_ERROR("Couldn't unlock listMutex[%p]\n", _listMutex); 413 419 _error = Error; 414 420 ret = Error; 415 421 } … … 418 424 419 425 // Now we set the suspend flag to false 420 426 if (SDL_mutexP(_flagMutex) != 0) { 421 PSP DebugTrace("PowerManager::resume(): Couldn't lock flagMutex %d\n", _flagMutex);427 PSP_ERROR("Couldn't lock flagMutex %p\n", _flagMutex); 422 428 _error = Error; 423 429 ret = Error; 424 430 } … … 430 436 431 437 // Signal the other threads to wake up 432 438 if (SDL_CondBroadcast(_condSuspendable) != 0) { 433 PSP DebugTrace("PowerManager::resume(): Couldn't broadcast condition %d\n", _condSuspendable);439 PSP_ERROR("Couldn't broadcast condition[%p]\n", _condSuspendable); 434 440 _error = Error; 435 441 ret = Error; 436 442 } 437 443 PMStatusSet(kDoneSignallingSuspendedThreadsResume); 438 444 439 445 if (SDL_mutexV(_flagMutex) != 0) { 440 PSP DebugTrace("PowerManager::resume(): Couldn't unlock flagMutex %d\n", _flagMutex);446 PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex); 441 447 _error = Error; 442 448 ret = Error; 443 449 } … … 447 453 448 454 scePowerUnlock(0); // Allow new suspends 449 455 456 DEBUG_EXIT_FUNC(); 450 457 return ret; 451 458 } -
backends/platform/psp/Makefile
66 66 #CC = psp-gcc 67 67 CXX = psp-g++ 68 68 CXXFLAGS = -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 69 DEFINES = -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL -DUSE_RGB_COLOR 70 70 LDFLAGS := 71 71 INCDIR := $(srcdir) . $(srcdir)/engines/ $(PSPSDK)/include 72 72 INCLUDES := $(addprefix -I, $(INCDIR)) … … 133 133 OBJS := powerman.o \ 134 134 psp_main.o \ 135 135 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 \ 136 143 trace.o \ 137 144 psploader.o \ 138 145 pspkeyboard.o -
backends/platform/psp/trace.cpp
23 23 * 24 24 */ 25 25 26 #define TRACE_C 27 #include <pspkernel.h> 28 #include <pspdebug.h> 29 #include "backends/platform/psp/trace.h" 26 30 27 #include "./trace.h"28 31 32 int psp_debug_indent = 0; 29 33 30 31 void PSPDebugTrace (const char *format, ...) { 32 #ifdef __PSP_DEBUG__ 34 void PSPDebugTrace (bool alsoToScreen, const char *format, ...) { 33 35 va_list opt; 34 char buff[2048]; 35 int bufsz, fd; 36 char buffer[2048]; 37 int bufsz; 38 FILE *fd = 0; 36 39 37 40 va_start(opt, format); 38 bufsz = vsnprintf( buff , (size_t) sizeof(buff), format, opt);41 bufsz = vsnprintf( buffer, (size_t) sizeof(buffer), format, opt); 39 42 va_end(opt); 40 43 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) 44 48 return; 45 49 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); 49 55 } 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 49 uint32 __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 62 void 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 90 void 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 114 INLINE 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 137 INLINE 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 154 void MasterGuRenderer::guShutDown() { 155 sceGuTerm(); 156 } 157 158 159 // Class DisplayManager ----------------------------------------------------- 160 161 DisplayManager::~DisplayManager() { 162 _masterGuRenderer.guShutDown(); 163 } 164 165 void 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 180 void 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 205 bool 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 223 bool 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 255 void 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 263 void 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 313 inline 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 325 Common::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 37 class InputHandler { 38 public: 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 46 private: 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 37 bool 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 61 void DefaultDisplayClient::deallocate() { 62 _buffer.deallocate(); 63 if (_buffer.hasPalette()) 64 _palette.deallocate(); 65 } 66 67 68 void DefaultDisplayClient::clearBuffer() { 69 DEBUG_ENTER_FUNC(); 70 _buffer.clear(); 71 setDirty(); 72 DEBUG_EXIT_FUNC(); 73 } 74 75 inline void DefaultDisplayClient::clearPalette() { 76 DEBUG_ENTER_FUNC(); 77 _palette.clear(); 78 setDirty(); 79 DEBUG_EXIT_FUNC(); 80 } 81 82 void DefaultDisplayClient::init() { 83 DEBUG_ENTER_FUNC(); 84 _renderer.setBuffer(&_buffer); 85 _renderer.setPalette(&_palette); 86 DEBUG_EXIT_FUNC(); 87 } 88 89 void 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 96 void 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 104 void 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 116 void 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 135 void 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 142 void 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 148 void 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 158 bool 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 169 void 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 181 void Screen::setShakePos(int pos) { 182 _shakePos = pos; 183 _renderer.setOffsetOnScreen(0, pos); 184 setDirty(); 185 } 186 187 void 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 196 void 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 217 Graphics::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 232 bool 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 37 class DisplayManager; 38 class GuRenderer; 39 40 /** 41 * Interface to inherit for all display clients 42 * We deliberately avoid virtual functions for speed. 43 */ 44 class DisplayClient { // Abstract class 45 public: 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 */ 57 struct Vertex { 58 float u,v; 59 float x,y,z; 60 }; 61 62 struct Point { 63 int x; 64 int y; 65 Point() : x(0), y(0) {} 66 }; 67 68 /** 69 * Dimensions struct for simplification 70 */ 71 struct 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 */ 82 class Palette { 83 public: 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 105 protected: 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 */ 116 class Buffer { 117 public: 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 159 protected: 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 */ 174 class GuRenderer { 175 public: 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 207 protected: 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 */ 36 class Copier { 37 public: 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 */ 46 class VramAllocator : public Common::Singleton<VramAllocator> { 47 public: 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 59 private: 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
23 23 * 24 24 */ 25 25 26 #include <pspuser.h> 26 27 #include <pspgu.h> 27 28 #include <pspdisplay.h> 28 29 … … 33 34 #include "common/events.h" 34 35 #include "common/scummsys.h" 35 36 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" 39 39 40 40 #include "backends/saves/psp/psp-saves.h" 41 41 #include "backends/timer/default/default-timer.h" 42 42 #include "graphics/surface.h" 43 43 #include "sound/mixer_intern.h" 44 44 45 #include "backends/platform/psp/pspkeyboard.h" 45 //#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */ 46 //#define __PSP_DEBUG_PRINT__ /* For debug printouts */ 46 47 48 #include "backends/platform/psp/trace.h" 47 49 50 48 51 #define SAMPLES_PER_SEC 44100 49 52 50 #define PIXEL_SIZE (4)51 #define BUF_WIDTH (512)52 #define PSP_SCREEN_WIDTH 48053 #define PSP_SCREEN_HEIGHT 27254 #define PSP_FRAME_SIZE (BUF_WIDTH * PSP_SCREEN_HEIGHT * PIXEL_SIZE)55 #define MOUSE_SIZE 12856 #define KBD_DATA_SIZE 13056057 58 #define MAX_FPS 3059 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 71 53 static int timer_handler(int t) { 72 54 DefaultTimerManager *tm = (DefaultTimerManager *)g_system->getTimerManager(); 73 55 tm->handler(); 74 56 return t; 75 57 } 76 58 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 }; 59 void OSystem_PSP::initSDL() { 60 SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER); 61 } 84 62 63 OSystem_PSP::~OSystem_PSP() {} 85 64 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 90 67 91 _cursorPaletteDisabled = true; 68 void OSystem_PSP::initBackend() { 69 DEBUG_ENTER_FUNC(); 92 70 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(); 96 80 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(); 100 85 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(); 104 87 105 106 // Init GU107 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() {143 88 _savefile = new PSPSaveFileManager; 144 89 145 90 _timer = new DefaultTimerManager(); 146 91 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 150 95 setTimerCallback(&timer_handler, 10); 151 96 152 97 setupMixer(); 153 98 154 99 OSystem::initBackend(); 100 101 DEBUG_EXIT_FUNC(); 155 102 } 156 103 157 158 104 bool OSystem_PSP::hasFeature(Feature f) { 159 105 return (f == kFeatureOverlaySupportsAlpha || f == kFeatureCursorHasPalette); 160 106 } … … 167 113 } 168 114 169 115 const OSystem::GraphicsMode* OSystem_PSP::getSupportedGraphicsModes() const { 170 return s_supportedGraphicsModes;116 return _displayManager.getSupportedGraphicsModes(); 171 117 } 172 118 173 174 119 int 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; 176 126 } 177 127 178 128 bool 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; 181 135 } 182 136 183 137 bool 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; 195 144 } 196 145 197 146 int 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; 199 153 } 200 154 201 void OSystem_PSP::initSize(uint width, uint height, const Graphics::PixelFormat *format) { 202 PSPDebugTrace("initSize\n"); 155 #ifdef USE_RGB_COLOR 203 156 204 _screenWidth = width; 205 _screenHeight = height; 157 Graphics::PixelFormat OSystem_PSP::getScreenFormat() const { 158 return _screen.getScummvmPixelFormat(); 159 } 206 160 207 const int scrBufSize = _screenWidth * _screenHeight * (format ? format->bytesPerPixel : 4); 161 Common::List<Graphics::PixelFormat> OSystem_PSP::getSupportedFormats() { 162 return _displayManager.getSupportedPixelFormats(); 163 } 208 164 209 _overlayWidth = PSP_SCREEN_WIDTH; //width; 210 _overlayHeight = PSP_SCREEN_HEIGHT; //height; 165 #endif 211 166 212 free(_overlayBuffer); 213 _overlayBuffer = (OverlayColor *)memalign(16, _overlayWidth * _overlayHeight * sizeof(OverlayColor)); 167 void OSystem_PSP::initSize(uint width, uint height, const Graphics::PixelFormat *format) { 168 DEBUG_ENTER_FUNC(); 169 170 _displayManager.setSizeAndPixelFormat(width, height, format); 214 171 215 free(_offscreen); 216 _offscreen = (byte *)memalign(16, scrBufSize); 217 bzero(_offscreen, scrBufSize); 172 _cursor.setVisible(false); 173 _cursor.setLimits(_screen.getWidth(), _screen.getHeight()); 218 174 219 clearOverlay(); 220 memset(_palette, 0xFFFF, 256 * sizeof(unsigned short)); 221 222 _mouseVisible = false; 223 sceKernelDcacheWritebackAll(); 175 DEBUG_EXIT_FUNC(); 224 176 } 225 177 226 178 int16 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; 228 185 } 229 186 230 187 int16 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; 232 194 } 233 195 234 196 void 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(); 236 202 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(); 250 204 } 251 205 252 206 void OSystem_PSP::setCursorPalette(const byte *colors, uint start, uint num) { 253 const byte *b = colors;207 DEBUG_ENTER_FUNC(); 254 208 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? 259 212 260 cursorPalette[0] = 0; 261 262 _cursorPaletteDisabled = false; 263 264 sceKernelDcacheWritebackAll(); 213 DEBUG_EXIT_FUNC(); 265 214 } 266 215 267 216 void OSystem_PSP::disableCursorPalette(bool disable) { 268 _cursorPaletteDisabled = disable; 217 DEBUG_ENTER_FUNC(); 218 219 _cursor.enableCursorPalette(!disable); 220 221 DEBUG_EXIT_FUNC(); 269 222 } 270 223 271 224 void 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(); 278 226 279 if (y < 0) { 280 h += y; 281 buf -= y * pitch; 282 y = 0; 283 } 227 _screen.copyFromRect(buf, pitch, x, y, w, h); 284 228 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(); 310 230 } 311 231 312 232 Graphics::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(); 318 234 319 return &_framebuffer; 235 Graphics::Surface *ret = _screen.lockAndGetForEditing(); 236 237 DEBUG_EXIT_FUNC(); 238 return ret; 320 239 } 321 240 322 241 void 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(); 325 247 } 326 248 327 249 void OSystem_PSP::updateScreen() { 328 u32 now = getMillis(); 329 if (now - _lastScreenUpdate < 1000 / MAX_FPS) 330 return; 250 DEBUG_ENTER_FUNC(); 331 251 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(); 562 255 } 563 256 564 257 void OSystem_PSP::setShakePos(int shakeOffset) { 565 _shakePos = shakeOffset; 258 DEBUG_ENTER_FUNC(); 259 260 _screen.setShakePos(shakeOffset); 261 262 DEBUG_EXIT_FUNC(); 566 263 } 567 264 568 265 void 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(); 570 273 } 571 274 572 275 void 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(); 575 283 } 576 284 577 285 void OSystem_PSP::clearOverlay() { 578 PSPDebugTrace("clearOverlay\n");286 DEBUG_ENTER_FUNC(); 579 287 580 bzero(_overlayBuffer, _overlayWidth * _overlayHeight * sizeof(OverlayColor)); 581 sceKernelDcacheWritebackAll(); 288 _overlay.clearBuffer(); 289 290 DEBUG_EXIT_FUNC(); 582 291 } 583 292 584 293 void OSystem_PSP::grabOverlay(OverlayColor *buf, int pitch) { 585 int h = _overlayHeight; 586 OverlayColor *src = _overlayBuffer; 294 DEBUG_ENTER_FUNC(); 587 295 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(); 593 299 } 594 300 595 301 void OSystem_PSP::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) { 596 PSPDebugTrace("copyRectToOverlay\n");302 DEBUG_ENTER_FUNC(); 597 303 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); 604 305 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(); 635 307 } 636 308 637 309 int16 OSystem_PSP::getOverlayWidth() { 638 return _overlayWidth;310 return (int16) _overlay.getWidth(); 639 311 } 640 312 641 313 int16 OSystem_PSP::getOverlayHeight() { 642 return _overlayHeight;314 return (int16) _overlay.getHeight(); 643 315 } 644 316 645 646 317 void OSystem_PSP::grabPalette(byte *colors, uint start, uint num) { 647 uint i; 648 uint16 color; 318 DEBUG_ENTER_FUNC(); 649 319 650 for (i = start; i < start + num; i++) { 651 color = _palette[i]; 652 *colors++ = ((color & 0x1F) << 3); 653 *colors++ = (((color >> 5) & 0x1F) << 3); 654 *colors++ = (((color >> 10) & 0x1F) << 3); 655 *colors++ = (color & 0x8000 ? 255 : 0); 656 } 320 _screen.getPartialPalette(colors, start, num); 321 322 DEBUG_EXIT_FUNC(); 657 323 } 658 324 659 bool OSystem_PSP::showMouse(bool visible) { 660 bool last = _mouseVisible; 661 _mouseVisible = visible; 325 bool OSystem_PSP::showMouse(bool v) { 326 DEBUG_ENTER_FUNC(); 327 328 PSP_DEBUG_PRINT("%s\n", v ? "true" : "false"); 329 bool last = _cursor.isVisible(); 330 _cursor.setVisible(v); 331 332 DEBUG_EXIT_FUNC(); 333 662 334 return last; 663 335 } 664 336 665 337 void OSystem_PSP::warpMouse(int x, int y) { 666 //assert(x > 0 && x < _screenWidth); 667 //assert(y > 0 && y < _screenHeight); 668 _mouseX = x; 669 _mouseY = y; 338 DEBUG_ENTER_FUNC(); 339 340 _cursor.setXY(x,y); 341 342 DEBUG_EXIT_FUNC(); 670 343 } 671 344 672 345 void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { 673 //TODO: handle cursorTargetScale 674 _mouseWidth = w; 675 _mouseHeight = h; 346 DEBUG_ENTER_FUNC(); 676 347 677 _mouseHotspotX = hotspotX; 678 _mouseHotspotY = hotspotY; 679 680 _mouseKeyColour = keycolor & 0xFF; 681 682 memcpy(mouseClut, _palette, 256 * sizeof(unsigned short)); 683 mouseClut[_mouseKeyColour] = 0; 684 685 for (unsigned int i = 0; i < h; i++) 686 memcpy(_mouseBuf + i * MOUSE_SIZE, buf + i * w, w); 687 688 sceKernelDcacheWritebackAll(); 689 } 690 691 #define PAD_CHECK_TIME 40 692 #define PAD_DIR_MASK (PSP_CTRL_UP | PSP_CTRL_DOWN | PSP_CTRL_LEFT | PSP_CTRL_RIGHT) 693 694 bool OSystem_PSP::processInput(Common::Event &event) { 695 s8 analogStepAmountX = 0; 696 s8 analogStepAmountY = 0; 697 698 sceCtrlSetSamplingCycle(0); 699 sceCtrlSetSamplingMode(1); 700 sceCtrlReadBufferPositive(&pad, 1); 701 702 bool usedInput, haveEvent; 703 704 haveEvent = _keyboard->processInput(event, pad, usedInput); 705 706 if (usedInput) // Check if the keyboard used up the input 707 return haveEvent; 708 709 uint32 buttonsChanged = pad.Buttons ^ _prevButtons; 710 711 int newDpadX = 0, newDpadY = 0; 712 event.kbd.ascii = 0; 713 event.kbd.flags = 0; 714 715 if (pad.Buttons & PSP_CTRL_UP) { 716 newDpadY += 1; 717 if (pad.Buttons & PSP_CTRL_RTRIGGER) 718 newDpadX += 1; 348 PSP_DEBUG_PRINT("pbuf[%p], w[%u], h[%u], hotspot:X[%d], Y[%d], keycolor[%d], scale[%d], pformat[%p]\n", buf, w, h, hotspotX, hotspotY, keycolor, cursorTargetScale, format); 349 if (format) { 350 PSP_DEBUG_PRINT("format: bpp[%d], rLoss[%d], gLoss[%d], bLoss[%d], aLoss[%d], rShift[%d], gShift[%d], bShift[%d], aShift[%d]\n", format->bytesPerPixel, format->rLoss, format->gLoss, format->bLoss, format->aLoss, format->rShift, format->gShift, format->bShift, format->aShift); 719 351 } 720 if (pad.Buttons & PSP_CTRL_RIGHT) { 721 newDpadX += 1; 722 if (pad.Buttons & PSP_CTRL_RTRIGGER) 723 newDpadY -= 1; 724 } 725 if (pad.Buttons & PSP_CTRL_DOWN) { 726 newDpadY -= 1; 727 if (pad.Buttons & PSP_CTRL_RTRIGGER) 728 newDpadX -= 1; 729 } 730 if (pad.Buttons & PSP_CTRL_LEFT) { 731 newDpadX -= 1; 732 if (pad.Buttons & PSP_CTRL_RTRIGGER) 733 newDpadY += 1; 734 } 735 //fprintf(stderr, "x=%d, y=%d, oldx=%d, oldy=%d\n", newDpadX, newDpadY, _dpadX, _dpadY); 736 if (newDpadX != _dpadX || newDpadY != _dpadY) { 737 if (_dpadX == 0 && _dpadY == 0) {// We pressed dpad 738 event.type = Common::EVENT_KEYDOWN; 739 event.kbd.keycode = getDpadEvent(newDpadX, newDpadY); 740 event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0'; 741 _dpadX = newDpadX; 742 _dpadY = newDpadY; 743 } 744 else if (newDpadX == 0 && newDpadY == 0) {// We unpressed dpad 745 event.type = Common::EVENT_KEYUP; 746 event.kbd.keycode = getDpadEvent(_dpadX, _dpadY); 747 event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0'; 748 _dpadX = newDpadX; 749 _dpadY = newDpadY; 750 } else { // we moved from one pressed dpad to another one 751 event.type = Common::EVENT_KEYUP; // first release the last dpad direction 752 event.kbd.keycode = getDpadEvent(_dpadX, _dpadY); 753 event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0'; 754 _dpadX = 0; // so that we'll pick up a new dpad movement 755 _dpadY = 0; 756 } 757 758 _prevButtons = pad.Buttons; 759 return true; 760 761 } else if (buttonsChanged & (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE | PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_START | 762 PSP_CTRL_SELECT | PSP_CTRL_SQUARE | PSP_CTRL_TRIANGLE)) { 763 if (buttonsChanged & PSP_CTRL_CROSS) { 764 event.type = (pad.Buttons & PSP_CTRL_CROSS) ? Common::EVENT_LBUTTONDOWN : Common::EVENT_LBUTTONUP; 765 } else if (buttonsChanged & PSP_CTRL_CIRCLE) { 766 event.type = (pad.Buttons & PSP_CTRL_CIRCLE) ? Common::EVENT_RBUTTONDOWN : Common::EVENT_RBUTTONUP; 767 } else { 768 //any of the other buttons. 769 event.type = buttonsChanged & pad.Buttons ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP; 770 771 if (buttonsChanged & PSP_CTRL_LTRIGGER) { 772 event.kbd.keycode = Common::KEYCODE_ESCAPE; 773 event.kbd.ascii = 27; 774 } else if (buttonsChanged & PSP_CTRL_START) { 775 event.kbd.keycode = Common::KEYCODE_F5; 776 event.kbd.ascii = Common::ASCII_F5; 777 if (pad.Buttons & PSP_CTRL_RTRIGGER) { 778 event.kbd.flags = Common::KBD_CTRL; // Main menu to allow RTL 779 } 780 /* } else if (buttonsChanged & PSP_CTRL_SELECT) { 781 event.kbd.keycode = Common::KEYCODE_0; 782 event.kbd.ascii = '0'; 783 */ } else if (buttonsChanged & PSP_CTRL_SQUARE) { 784 event.kbd.keycode = Common::KEYCODE_PERIOD; 785 event.kbd.ascii = '.'; 786 } else if (buttonsChanged & PSP_CTRL_TRIANGLE) { 787 event.kbd.keycode = Common::KEYCODE_RETURN; 788 event.kbd.ascii = 13; 789 } else if (pad.Buttons & PSP_CTRL_RTRIGGER) { 790 event.kbd.flags |= Common::KBD_SHIFT; 791 } 792 793 } 794 795 event.mouse.x = _mouseX; 796 event.mouse.y = _mouseY; 797 _prevButtons = pad.Buttons; 798 return true; 799 } 800 801 uint32 time = getMillis(); 802 if (time - _lastPadCheck > PAD_CHECK_TIME) { 803 _lastPadCheck = time; 804 int16 newX = _mouseX; 805 int16 newY = _mouseY; 806 807 if (pad.Lx < 100) { 808 analogStepAmountX = pad.Lx - 100; 809 } else if (pad.Lx > 155) { 810 analogStepAmountX = pad.Lx - 155; 811 } 812 813 if (pad.Ly < 100) { 814 analogStepAmountY = pad.Ly - 100; 815 } else if (pad.Ly > 155) { 816 analogStepAmountY = pad.Ly - 155; 817 } 818 819 if (analogStepAmountX != 0 || analogStepAmountY != 0) { 820 821 _prevButtons = pad.Buttons; 822 823 // If no movement then this has no effect 824 if (pad.Buttons & PSP_CTRL_RTRIGGER) { 825 // Fine control mode for analog 826 if (analogStepAmountX != 0) { 827 if (analogStepAmountX > 0) 828 newX += 1; 829 else 830 newX -= 1; 831 } 832 833 if (analogStepAmountY != 0) { 834 if (analogStepAmountY > 0) 835 newY += 1; 836 else 837 newY -= 1; 838 } 839 } else { 840 newX += analogStepAmountX >> ((_screenWidth == 640) ? 2 : 3); 841 newY += analogStepAmountY >> ((_screenWidth == 640) ? 2 : 3); 842 } 843 844 if (newX < 0) 845 newX = 0; 846 if (newY < 0) 847 newY = 0; 848 if (_overlayVisible) { 849 if (newX >= _overlayWidth) 850 newX = _overlayWidth - 1; 851 if (newY >= _overlayHeight) 852 newY = _overlayHeight - 1; 853 } else { 854 if (newX >= _screenWidth) 855 newX = _screenWidth - 1; 856 if (newY >= _screenHeight) 857 newY = _screenHeight - 1; 858 } 859 860 if ((_mouseX != newX) || (_mouseY != newY)) { 861 event.type = Common::EVENT_MOUSEMOVE; 862 event.mouse.x = _mouseX = newX; 863 event.mouse.y = _mouseY = newY; 864 return true; 865 } 866 } 867 } 868 869 return false; 352 353 _cursor.setKeyColor(keycolor); 354 _cursor.setCursorTargetScale(cursorTargetScale); 355 _cursor.setSizeAndScummvmPixelFormat(w, h, format); 356 _cursor.setHotspot(hotspotX, hotspotY); 357 _cursor.clearKeyColor(); 358 _cursor.copyFromArray(buf); 359 360 DEBUG_EXIT_FUNC(); 870 361 } 871 362 872 inline Common::KeyCode OSystem_PSP::getDpadEvent(int x, int y) {873 Common::KeyCode key;874 875 if (x == -1) {876 if (y == -1)877 key = Common::KEYCODE_KP1;878 else if (y == 0)879 key = Common::KEYCODE_KP4;880 else /* y == 1 */881 key = Common::KEYCODE_KP7;882 } else if (x == 0) {883 if (y == -1)884 key = Common::KEYCODE_KP2;885 else /* y == 1 */886 key = Common::KEYCODE_KP8;887 } else {/* x == 1 */888 if (y == -1)889 key = Common::KEYCODE_KP3;890 else if (y == 0)891 key = Common::KEYCODE_KP6;892 else /* y == 1 */893 key = Common::KEYCODE_KP9;894 }895 896 return key;897 }898 899 363 bool OSystem_PSP::pollEvent(Common::Event &event) { 900 364 901 365 // If we're polling for events, we should check for pausing the engine … … 905 369 906 370 PowerMan.pollPauseEngine(); 907 371 908 return processInput(event); 909 372 return _inputHandler.getAllInputs(event); 910 373 } 911 374 912 375 … … 997 460 void OSystem_PSP::quit() { 998 461 SDL_CloseAudio(); 999 462 SDL_Quit(); 1000 sceGuTerm();1001 463 sceKernelExitGame(); 1002 464 } 1003 465 -
backends/platform/psp/README.PSP.in
16 16 Right trigger - Modifier key (see below for uses) 17 17 Analog - Mouse movement 18 18 Right trigger + Analog - Fine control mouse 19 Directionals - Mouse movement 19 Directions - Arrow keys 20 Directions + Right Trigger - Diagonal arrow keys 20 21 Triangle - Enter 21 22 Cross - Mouse button 1 22 23 Circle - Mouse button 2 23 24 Square - '.' (skip dialogue in some games) 24 Start - F5 25 Start - F5 (Main Menu) 25 26 Right trigger + Start - Return-To-Launcher menu 26 27 27 28 Virtual Keyboard -
backends/platform/psp/cursor.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.h $ 22 * $Id: osys_psp.h 46120 2009-11-24 10:33:30Z Bluddy $ 23 * 24 */ 25 26 #ifndef MOUSE_H 27 #define MOUSE_H 28 29 class Cursor : public DefaultDisplayClient { 30 private: 31 int _hotspotX, _hotspotY; 32 uint32 _keyColor; 33 int _cursorTargetScale; 34 bool _useCursorPalette; 35 bool _hasCursorPalette; 36 uint32 _mouseLimitWidth; 37 uint32 _mouseLimitHeight; 38 int32 _x, _y; 39 Palette _screenPalette; // separate palette for screen. default 'palette' is cursor palette. 40 41 void updateRendererOffset(); 42 43 public: 44 Cursor() : _hotspotX(0), _hotspotY(0), _keyColor(0), _cursorTargetScale(0), 45 _useCursorPalette(false), _hasCursorPalette(false), _mouseLimitWidth(0), 46 _mouseLimitHeight(0), _x(0), _y(0) { } 47 virtual ~Cursor() { deallocate(); } 48 49 void setKeyColor(uint32 color); 50 void setCursorTargetScale(int scale) { _cursorTargetScale = scale; } 51 void setScreenPalette(const byte *colors, uint start, uint num); 52 void copyFromArray(const byte *array); 53 Palette &palette() { return _palette; } 54 Buffer &buffer() { return _buffer; } 55 void setCursorPalette(const byte *colors, uint start, uint num); 56 void enableCursorPalette(bool enable); 57 void setLimits(uint32 width, uint32 height); 58 void setXY(int x, int y); 59 int32 getX() { return _x; } 60 int32 getY() { return _y; } 61 bool increaseXY(int32 incX, int32 incY); // returns true if there's a change in x or y 62 void adjustXYForScreenSize(int32 &x, int32 &y); 63 void init(); 64 void setHotspot(int32 x, int32 y); 65 void setScreenPaletteScummvmPixelFormat(const Graphics::PixelFormat *format); 66 void setSizeAndScummvmPixelFormat(uint32 widht, uint32 height, const Graphics::PixelFormat *format); 67 void clearKeyColor(); 68 void useGlobalScaler(bool val) { _renderer.setUseGlobalScaler(val); } 69 bool allocate(); 70 void deallocate(); 71 72 private: 73 void setSize(uint32 width, uint32 height); 74 void getPixelFormatsFromScummvmPixelFormat(const Graphics::PixelFormat *format, 75 PSPPixelFormat::Type &bufferFormat, 76 PSPPixelFormat::Type &paletteFormat, 77 uint32 &numOfEntries); 78 void setRendererModePalettized(bool palettized); 79 }; 80 81 #endif /* MOUSE_H */ -
backends/platform/psp/psppixelformat.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_PIXEL_FORMAT_H 27 #define PSP_PIXEL_FORMAT_H 28 29 #include "graphics/pixelformat.h" 30 #include "backends/platform/psp/trace.h" 31 32 /** 33 * Specialized PixelFormat class 34 * Supports only those formats which the PSP allows, including 4 bit palettes. 35 * Also provides accurate color conversion (needed for color masking) 36 * As well as swapping of red and blue channels (needed by HE games, for example) 37 */ 38 struct PSPPixelFormat{ 39 enum Type { 40 Type_None, 41 Type_4444, 42 Type_5551, 43 Type_5650, 44 Type_8888, 45 Type_Palette_8bit, 46 Type_Palette_4bit, 47 Type_Unknown 48 }; 49 50 Type format; 51 uint32 bitsPerPixel; ///< Must match bpp of selected type 52 bool swapRB; ///< Swap red and blue values when reading and writing 53 54 PSPPixelFormat() : format(Type_Unknown), bitsPerPixel(0), swapRB(false) {} 55 void set(Type type, bool swap = false); 56 static void convertFromScummvmPixelFormat(const Graphics::PixelFormat *pf, 57 PSPPixelFormat::Type &bufferType, 58 PSPPixelFormat::Type &paletteType, 59 bool &swapRedBlue); 60 static Graphics::PixelFormat convertToScummvmPixelFormat(PSPPixelFormat::Type type); 61 uint32 convertTo32BitColor(uint32 color); 62 63 inline uint32 rgbaToColor(uint32 r, uint32 g, uint32 b, uint32 a) { 64 uint32 color; 65 66 switch(format) { 67 case Type_4444: 68 color = (((b >> 4) << 8) | ((g >> 4) << 4) | ((r >> 4) << 0) | ((a >> 4) << 12)); 69 break; 70 case Type_5551: 71 color = (((b >> 3) << 10) | ((g >> 3) << 5) | ((r >> 3) << 0) | ((a >> 7) << 15)); 72 break; 73 case Type_5650: 74 color = (((b >> 3) << 11) | ((g >> 2) << 5) | ((r >> 3) << 0)); 75 break; 76 case Type_8888: 77 color = (((b >> 0) << 16) | ((g >> 0) << 8) | ((r >> 0) << 0) | ((a >> 0) << 24)); 78 break; 79 default: 80 color = 0; 81 break; 82 } 83 return color; 84 } 85 86 inline void colorToRgba(uint32 color, uint32 &r, uint32 &g, uint32 &b, uint32 &a) { 87 switch(format) { 88 case Type_4444: 89 a = (color >> 12) & 0xF; // Interpolate to get true colors 90 b = (color >> 8) & 0xF; 91 g = (color >> 4) & 0xF; 92 r = (color >> 0) & 0xF; 93 a = a << 4 | a; 94 b = b << 4 | b; 95 g = g << 4 | g; 96 r = r << 4 | r; 97 break; 98 case Type_5551: 99 a = (color >> 15) ? 0xFF : 0; 100 b = (color >> 10) & 0x1F; 101 g = (color >> 5) & 0x1F; 102 r = (color >> 0) & 0x1F; 103 b = b << 3 | b >> 2; 104 g = g << 3 | g >> 2; 105 r = r << 3 | r >> 2; 106 break; 107 case Type_5650: 108 a = 0xFF; 109 b = (color >> 11) & 0x1F; 110 g = (color >> 5) & 0x3F; 111 r = (color >> 0) & 0x1F; 112 b = b << 3 | b >> 2; 113 g = g << 2 | g >> 4; 114 r = r << 3 | r >> 2; 115 break; 116 case Type_8888: 117 a = (color >> 24) & 0xFF; 118 b = (color >> 16) & 0xFF; 119 g = (color >> 8) & 0xFF; 120 r = (color >> 0) & 0xFF; 121 break; 122 default: 123 a = b = g = r = 0; 124 break; 125 } 126 } 127 128 inline uint32 setColorAlpha(uint32 color, byte alpha) { 129 switch(format) { 130 case Type_4444: 131 color = (color & 0x0FFF) | (((uint32)alpha >> 4) << 12); 132 break; 133 case Type_5551: 134 color = (color & 0x7FFF) | (((uint32)alpha >> 7) << 15); 135 break; 136 case Type_8888: 137 color = (color & 0x00FFFFFF) | ((uint32)alpha << 24); 138 break; 139 case Type_5650: 140 default: 141 break; 142 } 143 return color; 144 } 145 146 inline uint32 pixelsToBytes(uint32 pixels) { 147 switch (bitsPerPixel) { 148 case 4: 149 pixels >>= 1; 150 break; 151 case 16: 152 pixels <<= 1; 153 break; 154 case 32: 155 pixels <<= 2; 156 break; 157 case 8: 158 break; 159 default: 160 PSP_ERROR("Incorrect bitsPerPixel value[%u]. pixels[%u]\n", bitsPerPixel, pixels); 161 break; 162 } 163 return pixels; 164 } 165 166 inline uint16 swapRedBlue16(uint16 color) { 167 uint16 output; 168 169 switch (format) { 170 case Type_4444: 171 output = (color & 0xf0f0) | ((color & 0x000f)<<8) | ((color & 0x0f00)>>8); 172 break; 173 case Type_5551: 174 output = (color & 0x83e0) | ((color & 0x001f)<<10) | ((color & 0x7c00)>>10); 175 break; 176 case Type_5650: 177 output = (color & 0x07e0) | ((color & 0x001f)<<11) | ((color & 0xf800)>>11); 178 break; 179 default: 180 PSP_ERROR("invalid format[%u] for swapping\n", format); 181 output = 0; 182 break; 183 } 184 return output; 185 } 186 187 inline uint32 swapRedBlue32(uint32 color) { 188 uint32 output; 189 190 switch (format) { 191 case Type_4444: 192 output = (color & 0xf0f0f0f0) | 193 ((color & 0x000f000f)<<8) | ((color & 0x0f000f00)>>8); 194 break; 195 case Type_5551: 196 output = (color & 0x83e083e0) | 197 ((color & 0x001f001f)<<10) | ((color & 0x7c007c00)>>10); 198 break; 199 case Type_5650: 200 output = (color & 0x07e007e0) | 201 ((color & 0x001f001f)<<11) | ((color & 0xf800f800)>>11); 202 break; 203 case Type_8888: 204 output = (color & 0xff00ff00) | 205 ((color & 0x000000ff)<<16) | ((color & 0x00ff0000)>>16); 206 break; 207 default: 208 PSP_ERROR("invalid format[%u] for swapping\n", format); 209 output = 0; 210 break; 211 } 212 213 return output; 214 } 215 216 // Return whatever color we point at 217 inline uint32 getColorValueAt(byte *pointer) { 218 uint32 result; 219 220 switch (bitsPerPixel) { 221 case 4: // We can't distinguish a 4 bit color with a pointer 222 case 8: 223 result = (uint32)*pointer; 224 break; 225 case 16: 226 result = (uint32)*(uint16 *)pointer; 227 break; 228 case 32: 229 result = *(uint32 *)pointer; 230 break; 231 default: 232 result = 0; 233 PSP_ERROR("Incorrect bitsPerPixel value[%u].\n", bitsPerPixel); 234 break; 235 } 236 return result; 237 } 238 }; 239 240 #endif /* PSP_PIXEL_FORMAT_H */ -
backends/platform/psp/pspkeyboard.h
28 28 29 29 #include "common/events.h" 30 30 #include "common/stream.h" 31 #include "backends/platform/psp/display_client.h" 31 32 #include <pspctrl.h> 32 33 33 34 //number of modes 34 35 #define MODE_COUNT 4 35 36 #define guiStringsSize 8 /* size of guistrings array */ 36 37 37 class PSPKeyboard {38 class PSPKeyboard : public DisplayClient { 38 39 39 40 private: 40 41 enum State { … … 49 50 public: 50 51 PSPKeyboard(); 51 52 ~PSPKeyboard(); 53 52 54 bool load(); // Load keyboard into memory 53 55 bool isInit() { return _init; } // Check for initialization 54 56 bool isDirty() { return _dirty; } // Check if needs redrawing 57 void setDirty() { _dirty = true; } 58 void setClean() { _dirty = false; } 55 59 bool isVisible() { return _state != kInvisible; } // Check if visible 56 bool processInput(Common::Event &event, SceCtrlData &pad, bool &usedInput); // Process input 60 void setVisible(bool val); 61 bool processInput(Common::Event &event, SceCtrlData &pad); // Process input 57 62 void moveTo(const int newX, const int newY); // Move keyboard 58 63 void render(); // Draw the keyboard onscreen 59 64 60 65 private: 61 struct gu_surface { 62 u32 surface_width; 63 u32 surface_height; 64 u32 texture_width; 65 u32 texture_height; 66 u8 *texture; 67 u32 *palette; 68 u32 paletteSize; 66 enum CursorDirections { 67 kUp = 0, 68 kRight, 69 kDown, 70 kLeft, 71 kCenter 69 72 }; 70 73 74 Buffer _buffers[guiStringsSize]; 75 Palette _palettes[guiStringsSize]; 76 GuRenderer _renderer; 71 77 72 // structures used for drawing the keyboard 73 struct Vertex { 74 float u, v; 75 unsigned int color; 76 float x,y,z; 77 }; 78 79 void surface_draw_offset(struct gu_surface* surface, 80 int screenX, int screenY, int offsetX, int offsetY, int intWidth, int intHeight); 81 void block_copy(gu_surface* surface, u8 *texture); 82 int load_png_image(Common::SeekableReadStream *, unsigned char *ImageBuffer, uint32 *palette); 83 int get_png_image_size(Common::SeekableReadStream *, uint32 *png_width, uint32 *png_height, u32 *paletteSize); 78 int loadPngImage(Common::SeekableReadStream *file, Buffer &buffer, Palette &palette); 79 int getPngImageSize(Common::SeekableReadStream *, uint32 *png_width, uint32 *png_height, u32 *paletteSize); 84 80 uint32 convert_pow2(uint32 size); 85 void flipNibbles(gu_surface* surface); // Convert to PSP 4-bit format86 81 void increaseKeyboardLocationX(int amount); // Move keyboard onscreen 87 82 void increaseKeyboardLocationY(int amount); 83 void convertCursorToXY(CursorDirections cur, int &x, int &y); 88 84 85 void handleMoveState(SceCtrlData &pad); 86 bool handleDefaultState(Common::Event &event, SceCtrlData &pad); 87 bool handleCornersSelectedState(Common::Event &event, SceCtrlData &pad); 88 bool getInputChoice(Common::Event &event, SceCtrlData &pad); 89 void getCursorMovement(SceCtrlData &pad); 90 void handleRTriggerDownState(SceCtrlData &pad); 91 void handleLTriggerDownState(SceCtrlData &pad); 92 89 93 static short _modeChar[MODE_COUNT][5][6]; 90 94 static const char *_guiStrings[]; 91 95 bool _init; 92 unsigned int _prevButtons; // A bit pattern. 96 uint32 _prevButtons; // A bit pattern. 97 uint32 _buttonsChanged; 98 93 99 bool _dirty; // keyboard needs redrawing 94 100 int _mode; // charset selected. (0 - letters or 1 - numbers) 95 int _moved _x; // location we've moved the KB to onscreen96 int _moved _y;101 int _movedX; // location we've moved the KB to onscreen 102 int _movedY; 97 103 bool _moved; // whether the keyboard was moved 98 gu_surface _keyTextures[guiStringsSize]; 99 104 100 105 State _state; // State of keyboard Keyboard state machine 101 106 State _lastState; 102 107 103 enum Cursor { 104 kUp = 0, 105 kRight, 106 kDown, 107 kLeft, 108 kCenter 109 }; 108 CursorDirections _oldCursor; // Point to place of last cursor 110 109 111 Cursor _oldCursor; // Point to place of last cursor112 113 110 }; 114 111 115 #endif /* PSPKEYBOARD_H */ 116 No newline at end of file 112 #endif /* PSPKEYBOARD_H */ -
backends/platform/psp/portdefs.h
50 50 //#define printf pspDebugScreenPrintf 51 51 52 52 #endif /* PORTDEFS_H */ 53 54 -
backends/platform/psp/powerman.h
118 118 kDoneSignallingSuspendedThreadsResume, 119 119 kDoneResume 120 120 }; 121 #ifdef __PSP_DEBUG_SUSPEND__122 121 123 122 volatile int _listCounter; /* How many people are in the list - just for debugging */ 124 123 … … 129 128 public: 130 129 int getPMStatus() { return _PMStatus; } 131 130 132 #endif /* __PSP_DEBUG_SUSPEND__ */133 134 131 }; 135 132 136 133 // For easy access 137 134 #define PowerMan PowerManager::instance() 138 135 139 136 #endif /* POWERMAN_H */ -
backends/fs/psp/psp-stream.h
49 49 int _errorSuspend; 50 50 mutable int _errorSource; 51 51 52 #ifdef __PSP_DEBUG_SUSPEND__ 52 // Error checking 53 53 int _errorPos; 54 54 void * _errorHandle; 55 55 int _suspendCount; 56 #endif /* __PSP_DEBUG_SUSPEND__ */57 56 58 57 public: 58 59 const char *getObjectName() const { return "PSPIoStream"; } 59 60 /** 60 61 * Given a path, invoke fopen on that path and wrap the result in a 61 62 * PSPIoStream instance. -
backends/fs/psp/psp-fs-factory.h
35 35 */ 36 36 class PSPFilesystemFactory : public FilesystemFactory, public Common::Singleton<PSPFilesystemFactory> { 37 37 public: 38 const char *getObjectName() const { return "PSPFilesystemFactory"; } 38 39 virtual AbstractFSNode *makeRootFileNode() const; 39 40 virtual AbstractFSNode *makeCurrentDirectoryFileNode() const; 40 41 virtual AbstractFSNode *makeFileNodePath(const Common::String &path) const; -
backends/fs/psp/psp-fs.cpp
35 35 36 36 #define ROOT_PATH "ms0:/" 37 37 38 //#define __PSP_PRINT_TO_FILE__ 39 //#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */ 40 //#define __PSP_DEBUG_PRINT__ /* For debug printouts */ 38 41 #include "backends/platform/psp/trace.h" 39 42 40 43 /** … … 63 66 */ 64 67 PSPFilesystemNode(const Common::String &p, bool verify = true); 65 68 69 const char *getObjectName() const { return "PSPFileSystemNode"; } 66 70 virtual bool exists() const; 67 71 virtual Common::String getDisplayName() const { return _displayName; } 68 72 virtual Common::String getName() const { return _displayName; } … … 87 91 } 88 92 89 93 PSPFilesystemNode::PSPFilesystemNode(const Common::String &p, bool verify) { 94 DEBUG_ENTER_FUNC(); 90 95 assert(p.size() > 0); 91 96 92 97 _path = p; … … 94 99 _isValid = true; 95 100 _isDirectory = true; 96 101 102 PSP_DEBUG_PRINT_FUNC("path [%s]\n", _path.c_str()); 103 97 104 if (verify) { 98 105 struct stat st; 99 106 if (PowerMan.beginCriticalSection()==PowerManager::Blocked) 100 PSP DebugSuspend("Suspended in PSPFilesystemNode::PSPFilesystemNode\n");107 PSP_DEBUG_PRINT_FUNC("Suspended\n"); 101 108 _isValid = (0 == stat(_path.c_str(), &st)); 102 109 PowerMan.endCriticalSection(); 103 110 _isDirectory = S_ISDIR(st.st_mode); 104 111 } 112 DEBUG_EXIT_FUNC(); 105 113 } 106 114 107 115 bool PSPFilesystemNode::exists() const { 116 DEBUG_ENTER_FUNC(); 108 117 int ret = 0; 109 118 110 119 if (PowerMan.beginCriticalSection() == PowerManager::Blocked) 111 PSP DebugSuspend("Suspended in PSPFilesystemNode::exists()\n"); // Make sure to block in case of suspend120 PSP_DEBUG_PRINT_FUNC("Suspended\n"); // Make sure to block in case of suspend 112 121 122 PSP_DEBUG_PRINT_FUNC("path [%s]\n", _path.c_str()); 123 113 124 ret = access(_path.c_str(), F_OK); 114 125 PowerMan.endCriticalSection(); 115 126 116 return ret == 0; 127 DEBUG_EXIT_FUNC(); 128 return (ret == 0); 117 129 } 118 130 119 131 bool PSPFilesystemNode::isReadable() const { 132 DEBUG_ENTER_FUNC(); 120 133 int ret = 0; 121 134 122 135 if (PowerMan.beginCriticalSection() == PowerManager::Blocked) 123 PSPDebugSuspend("Suspended in PSPFilesystemNode::isReadable()\n"); // Make sure to block in case of suspend136 PSP_DEBUG_PRINT_FUNC("Suspended\n"); // Make sure to block in case of suspend 124 137 138 PSP_DEBUG_PRINT_FUNC("path [%s]\n", _path.c_str()); 139 125 140 ret = access(_path.c_str(), R_OK); 126 141 PowerMan.endCriticalSection(); 127 142 128 return ret == 0; 143 DEBUG_EXIT_FUNC(); 144 return (ret == 0); 129 145 } 130 146 131 147 bool PSPFilesystemNode::isWritable() const { 148 DEBUG_ENTER_FUNC(); 132 149 int ret = 0; 133 150 134 151 if (PowerMan.beginCriticalSection() == PowerManager::Blocked) 135 PSP DebugSuspend("Suspended in PSPFilesystemNode::isWritable()\n"); // Make sure to block in case of suspend152 PSP_DEBUG_PRINT_FUNC("Suspended\n"); // Make sure to block in case of suspend 136 153 154 PSP_DEBUG_PRINT_FUNC("path [%s]\n", _path.c_str()); 155 137 156 ret = access(_path.c_str(), W_OK); 138 157 PowerMan.endCriticalSection(); 139 158 159 DEBUG_EXIT_FUNC(); 140 160 return ret == 0; 141 161 } 142 162 143 163 144 164 AbstractFSNode *PSPFilesystemNode::getChild(const Common::String &n) const { 165 DEBUG_ENTER_FUNC(); 145 166 // FIXME: Pretty lame implementation! We do no error checking to speak 146 167 // of, do not check if this is a special node, etc. 147 168 assert(_isDirectory); … … 151 172 newPath += '/'; 152 173 newPath += n; 153 174 154 return new PSPFilesystemNode(newPath, true); 175 PSP_DEBUG_PRINT_FUNC("child [%s]\n", newPath.c_str()); 176 177 AbstractFSNode *node = new PSPFilesystemNode(newPath, true); 178 179 DEBUG_EXIT_FUNC(); 180 return node; 155 181 } 156 182 157 183 bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const { 184 DEBUG_ENTER_FUNC(); 158 185 assert(_isDirectory); 159 186 160 187 //TODO: honor the hidden flag … … 162 189 bool ret = true; 163 190 164 191 if (PowerMan.beginCriticalSection() == PowerManager::Blocked) 165 PSP DebugSuspend("Suspended in PSPFilesystemNode::getChildren\n"); // Make sure to block in case of suspend192 PSP_DEBUG_PRINT_FUNC("Suspended\n"); // Make sure to block in case of suspend 166 193 194 PSP_DEBUG_PRINT_FUNC("Current path[%s]\n", _path.c_str()); 195 167 196 int dfd = sceIoDopen(_path.c_str()); 168 197 if (dfd > 0) { 169 198 SceIoDirent dir; … … 186 215 187 216 entry._path = newPath; 188 217 entry._isDirectory = dir.d_stat.st_attr & FIO_SO_IFDIR; 189 218 219 PSP_DEBUG_PRINT_FUNC("Child[%s], %s\n", entry._path.c_str(), entry._isDirectory ? "dir" : "file"); 220 190 221 // Honor the chosen mode 191 222 if ((mode == Common::FSNode::kListFilesOnly && entry._isDirectory) || 192 223 (mode == Common::FSNode::kListDirectoriesOnly && !entry._isDirectory)) … … 202 233 } 203 234 204 235 PowerMan.endCriticalSection(); 236 237 DEBUG_EXIT_FUNC(); 205 238 return ret; 206 239 } 207 240 208 241 AbstractFSNode *PSPFilesystemNode::getParent() const { 242 DEBUG_ENTER_FUNC(); 209 243 if (_path == ROOT_PATH) 210 244 return 0; 211 245 246 PSP_DEBUG_PRINT_FUNC("current[%s]\n", _path.c_str()); 247 212 248 const char *start = _path.c_str(); 213 249 const char *end = lastPathComponent(_path, '/'); 214 250 215 return new PSPFilesystemNode(Common::String(start, end - start), false); 251 AbstractFSNode *node = new PSPFilesystemNode(Common::String(start, end - start), false); 252 DEBUG_EXIT_FUNC(); 253 return node; 216 254 } 217 255 218 256 Common::SeekableReadStream *PSPFilesystemNode::createReadStream() { -
backends/fs/psp/psp-stream.cpp
27 27 #include <SDL/SDL_thread.h> 28 28 #include <SDL/SDL_mutex.h> 29 29 30 #include "backends/platform/psp/trace.h"31 30 #include "backends/platform/psp/powerman.h" 32 31 #include "backends/fs/psp/psp-stream.h" 33 32 34 33 #include <errno.h> 35 34 35 //#define __PSP_PRINT_TO_FILE__ 36 //#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */ 37 //#define __PSP_DEBUG_PRINT__ /* For debug printouts */ 38 #include "backends/platform/psp/trace.h" 39 36 40 PSPIoStream::PSPIoStream(const Common::String &path, bool writeMode) 37 41 : StdioStream((void *)1), _path(path), _writeMode(writeMode) { 38 42 DEBUG_ENTER_FUNC(); 43 39 44 assert(!path.empty()); 40 45 41 46 _handle = (void *)0; // Need to do this since base class asserts not 0. … … 43 48 _feof = false; 44 49 _pos = 0; 45 50 46 #ifdef __PSP_DEBUG_SUSPEND__ 51 /* for error checking */ 47 52 _errorSuspend = 0; 48 53 _errorSource = 0; 49 54 _errorPos = 0; 50 55 _errorHandle = 0; 51 56 _suspendCount = 0; 52 #endif 57 58 DEBUG_EXIT_FUNC(); 53 59 } 54 60 55 61 PSPIoStream::~PSPIoStream() { 62 DEBUG_ENTER_FUNC(); 63 56 64 if (PowerMan.beginCriticalSection() == PowerManager::Blocked) 57 PSP DebugSuspend("Suspended in PSPIoStream::~PSPIoStream()\n");65 PSP_DEBUG_PRINT_FUNC("Suspended\n"); 58 66 59 67 PowerMan.unregisterSuspend(this); // Unregister with powermanager to be suspended 60 // Must do this before fclose() or resume() will reopen.68 // Must do this before fclose() or resume() will reopen. 61 69 62 70 fclose((FILE *)_handle); // We don't need a critical section(?). Worst case, the handle gets closed on its own 63 71 64 72 PowerMan.endCriticalSection(); 73 74 DEBUG_EXIT_FUNC(); 65 75 } 66 76 67 / /Function to open the file pointed to by the path.68 // 69 //77 /* Function to open the file pointed to by the path. 78 * 79 */ 70 80 void *PSPIoStream::open() { 81 DEBUG_ENTER_FUNC(); 71 82 if (PowerMan.beginCriticalSection() == PowerManager::Blocked) { 72 83 // No need to open. Just return the _handle resume() already opened. 73 PSP DebugSuspend("Suspended in PSPIoStream::open\n");84 PSP_DEBUG_PRINT_FUNC("Suspended\n"); 74 85 } 75 86 76 87 _handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb"); // open … … 79 90 80 91 PowerMan.endCriticalSection(); 81 92 93 DEBUG_EXIT_FUNC(); 82 94 return _handle; 83 95 } 84 96 85 97 bool PSPIoStream::err() const { 98 DEBUG_ENTER_FUNC(); 86 99 if (_ferror) 87 PSP DebugSuspend("In PSPIoStream::err - mem_ferror=%d, source=%d, suspend error=%d, pos=%d, _errorPos=%d, _errorHandle=%p, suspendCount=%d _handle\n",100 PSP_ERROR("mem_ferror[%d], source[%d], suspend error[%d], pos[%d], _errorPos[%d], _errorHandle[%p], suspendCount[%d]\n", 88 101 _ferror, _errorSource, _errorSuspend, _pos, _errorPos, _errorHandle, _suspendCount); 89 102 103 DEBUG_EXIT_FUNC(); 90 104 return _ferror; 91 105 } 92 106 93 107 void PSPIoStream::clearErr() { 94 108 _ferror = false; // Remove regular error bit 95 96 109 } 97 110 98 111 bool PSPIoStream::eos() const { … … 105 118 106 119 107 120 int32 PSPIoStream::size() const { 121 DEBUG_ENTER_FUNC(); 108 122 if (PowerMan.beginCriticalSection() == PowerManager::Blocked) 109 PSP DebugSuspend("Suspended in PSPIoStream::size()\n");123 PSP_DEBUG_PRINT_FUNC("Suspended\n"); 110 124 111 125 fseek((FILE *)_handle, 0, SEEK_END); 112 126 int32 length = ftell((FILE *)_handle); 113 127 fseek((FILE *)_handle, _pos, SEEK_SET); 114 128 115 129 if (_pos < 0 || length < 0) { // Check for errors 116 PSPDebugSuspend("In PSPIoStream::size(). encountered an error!\n"); 130 _errorSource = 2; 131 PSP_ERROR("pos[%d] or length[%d] < 0!\n", _pos, length); 117 132 _ferror = true; 118 133 length = -1; // If our oldPos is bad, we want length to be bad too to signal 119 134 clearerr((FILE *)_handle); 120 121 #ifdef __PSP_DEBUG_SUSPEND__122 _errorSource = 2;123 #endif124 135 } 125 136 126 137 PowerMan.endCriticalSection(); 127 138 139 DEBUG_EXIT_FUNC(); 128 140 return length; 129 141 } 130 142 131 143 bool PSPIoStream::seek(int32 offs, int whence) { 144 DEBUG_ENTER_FUNC(); 145 132 146 // Check if we can access the file 133 147 if (PowerMan.beginCriticalSection() == PowerManager::Blocked) 134 PSP DebugSuspend("Suspended in PSPIoStream::seek()\n");148 PSP_DEBUG_PRINT_FUNC("Suspended\n"); 135 149 136 150 int ret = fseek((FILE *)_handle, offs, whence); 137 151 138 152 if (ret != 0) { 139 153 _ferror = true; 140 PSP DebugSuspend("In PSPIoStream::seek(). encountered an error!\n");154 PSP_ERROR("fseek returned with [%d], non-zero\n", ret); 141 155 clearerr((FILE *)_handle); 142 156 _feof = feof((FILE *)_handle); 143 144 #ifdef __PSP_DEBUG_SUSPEND__145 157 _errorSource = 3; 146 #endif147 158 } 148 159 else { // everything ok 149 160 _feof = false; // Reset eof flag since we know it was ok … … 153 164 154 165 PowerMan.endCriticalSection(); 155 166 156 return ret == 0; 167 DEBUG_EXIT_FUNC(); 168 return (ret == 0); 157 169 } 158 170 159 171 uint32 PSPIoStream::read(void *ptr, uint32 len) { 172 DEBUG_ENTER_FUNC(); 160 173 // Check if we can access the file 161 174 if (PowerMan.beginCriticalSection() == PowerManager::Blocked) 162 PSPDebugSuspend("Suspended in PSPIoStream::read()\n"); 175 PSP_DEBUG_PRINT_FUNC("Suspended\n"); 176 177 PSP_DEBUG_PRINT_FUNC("filename[%s], len[%d]\n", _path.c_str(), len); 163 178 164 179 size_t ret = fread((byte *)ptr, 1, len, (FILE *)_handle); 165 180 … … 171 186 _ferror = true; 172 187 clearerr((FILE *)_handle); 173 188 _pos = ftell((FILE *)_handle); // Update our position 174 PSPDebugSuspend("In PSPIoStream::read(). encountered an error!\n");175 176 #ifdef __PSP_DEBUG_SUSPEND__177 189 _errorSource = 4; 178 #endif 190 PSP_ERROR("fread returned ret[%d] instead of len[%d]\n", ret, len); 179 191 } 180 192 } 181 193 182 194 PowerMan.endCriticalSection(); 183 195 196 DEBUG_EXIT_FUNC(); 184 197 return ret; 185 198 } 186 199 187 200 uint32 PSPIoStream::write(const void *ptr, uint32 len) { 201 DEBUG_ENTER_FUNC(); 188 202 // Check if we can access the file 189 203 if (PowerMan.beginCriticalSection() == PowerManager::Blocked) 190 PSP DebugSuspend("Suspended in PSPIoStream::read()\n");204 PSP_DEBUG_PRINT_FUNC("Suspended\n"); 191 205 206 PSP_DEBUG_PRINT_FUNC("filename[%s], len[%d]\n", _path.c_str(), len); 207 192 208 size_t ret = fwrite(ptr, 1, len, (FILE *)_handle); 193 209 194 210 _pos += ret; … … 197 213 _ferror = true; 198 214 clearerr((FILE *)_handle); 199 215 _pos = ftell((FILE *)_handle); // Update pos 200 PSPDebugTrace("In PSPIoStream::write(). encountered an error!\n");201 202 #ifdef __PSP_DEBUG_SUSPEND__203 216 _errorSource = 5; 204 #endif 217 PSP_ERROR("fwrite returned[%d] instead of len[%d]\n", ret, len); 205 218 } 206 219 207 220 PowerMan.endCriticalSection(); 208 221 222 DEBUG_EXIT_FUNC(); 209 223 return ret; 210 224 } 211 225 212 226 bool PSPIoStream::flush() { 227 DEBUG_ENTER_FUNC(); 213 228 // Enter critical section 214 229 if (PowerMan.beginCriticalSection() == PowerManager::Blocked) 215 PSP DebugSuspend("Suspended in PSPIoStream::read()\n");230 PSP_DEBUG_PRINT_FUNC("Suspended\n"); 216 231 217 232 int ret = fflush((FILE *)_handle); 218 233 219 234 if (ret != 0) { 220 235 _ferror = true; 221 236 clearerr((FILE *)_handle); 222 PSPDebugSuspend("In PSPIoStream::flush(). encountered an error!\n");223 224 #ifdef __PSP_DEBUG_SUSPEND__225 237 _errorSource = 6; 226 #endif 238 PSP_ERROR("fflush returned ret[%u]\n", ret); 227 239 } 228 240 229 241 PowerMan.endCriticalSection(); 230 242 231 return ret == 0; 243 DEBUG_EXIT_FUNC(); 244 return (ret == 0); 232 245 } 233 246 234 247 // For the PSP, since we're building in suspend support, we moved opening 235 248 // the actual file to an open function since we need an actual PSPIoStream object to suspend. 236 249 // 237 250 PSPIoStream *PSPIoStream::makeFromPath(const Common::String &path, bool writeMode) { 251 DEBUG_ENTER_FUNC(); 238 252 PSPIoStream *stream = new PSPIoStream(path, writeMode); 239 253 240 if (stream->open() > 0) { 241 return stream; 242 } else { 254 if (stream->open() <= 0) { 243 255 delete stream; 244 return0;256 stream = 0; 245 257 } 258 259 DEBUG_EXIT_FUNC(); 260 return stream; 246 261 } 247 262 248 263 /* 249 264 * Function to suspend the IO stream (called by PowerManager) 265 * we can have no output here 250 266 */ 251 267 int PSPIoStream::suspend() { 252 #ifdef __PSP_DEBUG_SUSPEND__ 268 DEBUG_ENTER_FUNC(); 253 269 _suspendCount++; 254 270 255 if (_handle > 0 && _pos < 0) { 271 if (_handle > 0 && _pos < 0) { /* check for error */ 256 272 _errorSuspend = SuspendError; 257 273 _errorPos = _pos; 258 274 _errorHandle = _handle; 259 275 } 260 #endif /* __PSP_DEBUG_SUSPEND__ */261 276 262 277 if (_handle > 0) { 263 278 fclose((FILE *)_handle); // close our file descriptor 264 279 _handle = (void *)0xFFFFFFFF; // Set handle to non-null invalid value so makeFromPath doesn't return error 265 280 } 266 281 282 DEBUG_EXIT_FUNC(); 267 283 return 0; 268 284 } 269 285 … … 271 287 * Function to resume the IO stream (called by Power Manager) 272 288 */ 273 289 int PSPIoStream::resume() { 290 DEBUG_ENTER_FUNC(); 274 291 int ret = 0; 275 #ifdef __PSP_DEBUG_SUSPEND__276 292 _suspendCount--; 277 #endif278 293 279 294 // We reopen our file descriptor 280 295 _handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb"); 281 296 if (_handle <= 0) { 282 PSP DebugSuspend("PSPIoStream::resume():Couldn't reopen file %s\n", _path.c_str());297 PSP_ERROR("Couldn't reopen file %s\n", _path.c_str()); 283 298 } 284 299 285 300 // Resume our previous position 286 301 if (_handle > 0 && _pos > 0) { 287 302 ret = fseek((FILE *)_handle, _pos, SEEK_SET); 288 303 289 #ifdef __PSP_DEBUG_SUSPEND__290 304 if (ret != 0) { // Check for problem 291 305 _errorSuspend = ResumeError; 292 306 _errorPos = _pos; 293 307 _errorHandle = _handle; 294 308 } 295 #endif296 297 309 } 298 310 DEBUG_EXIT_FUNC(); 299 311 return ret; 300 312 } 301 313