Ticket #9152: cleanup.diff

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

PSP Cleanup

Line 
1Index: configure
2===================================================================
3--- configure (revision 48355)
4+++ configure (working copy)
5@@ -1645,7 +1645,7 @@
6 # Enable 16bit support only for backends which support it
7 #
8 case $_backend in
9- dreamcast | samsungtv | sdl | wii)
10+ dreamcast | samsungtv | sdl | wii | psp)
11 if test "$_16bit" = auto ; then
12 _16bit=yes
13 else
14Index: backends/platform/psp/input.cpp
15===================================================================
16--- backends/platform/psp/input.cpp (revision 0)
17+++ backends/platform/psp/input.cpp (revision 0)
18@@ -0,0 +1,317 @@
19+/* ScummVM - Graphic Adventure Engine
20+ *
21+ * ScummVM is the legal property of its developers, whose names
22+ * are too numerous to list here. Please refer to the COPYRIGHT
23+ * file distributed with this source distribution.
24+ *
25+ * This program is free software; you can redistribute it and/or
26+ * modify it under the terms of the GNU General Public License
27+ * as published by the Free Software Foundation; either version 2
28+ * of the License, or (at your option) any later version.
29+
30+ * This program is distributed in the hope that it will be useful,
31+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33+ * GNU General Public License for more details.
34+
35+ * You should have received a copy of the GNU General Public License
36+ * along with this program; if not, write to the Free Software
37+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
38+ *
39+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
40+ * $Id: osys_psp.cpp 43618 2009-08-21 22:44:49Z joostp $
41+ *
42+ */
43+
44+// Todo: handle events that should fire because of shift going off
45+// 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.
46+
47+//#define __PSP_DEBUG_FUNCS__ /* Uncomment for debugging the stack */
48+//#define __PSP_DEBUG_PRINT__ /* Uncomment for debug prints */
49+
50+#include "backends/platform/psp/trace.h"
51+
52+#include "backends/platform/psp/input.h"
53+
54+// Defines for working with PSP buttons
55+#define CHANGED(x) (_buttonsChanged & (x))
56+#define PRESSED(x) ((_buttonsChanged & (x)) && (pad.Buttons & (x)))
57+#define UNPRESSED(x) ((_buttonsChanged & (x)) && !(pad.Buttons & (x)))
58+#define DOWN(x) (pad.Buttons & (x))
59+#define UP(x) (!(pad.Buttons & (x)))
60+#define PSP_DPAD (PSP_CTRL_DOWN|PSP_CTRL_UP|PSP_CTRL_LEFT|PSP_CTRL_RIGHT)
61+#define PSP_4BUTTONS (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE | PSP_CTRL_TRIANGLE | PSP_CTRL_SQUARE)
62+#define PSP_TRIGGERS (PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER)
63+
64+#define PAD_CHECK_TIME 40
65+
66+void InputHandler::init() {
67+ sceCtrlSetSamplingCycle(0); // set sampling to vsync. n = n usecs
68+ sceCtrlSetSamplingMode(1); // analog
69+}
70+
71+bool InputHandler::getAllInputs(Common::Event &event) {
72+ DEBUG_ENTER_FUNC();
73+
74+ uint32 time = g_system->getMillis(); // may not be necessary with read
75+ if (time - _lastPadCheckTime < PAD_CHECK_TIME) {
76+ DEBUG_EXIT_FUNC();
77+ return false;
78+ }
79+
80+ _lastPadCheckTime = time;
81+ SceCtrlData pad;
82+
83+ sceCtrlPeekBufferPositive(&pad, 1); // Peek ignores sleep. Read sleeps thread
84+
85+ bool haveEvent;
86+
87+ memset(&event, 0, sizeof(event));
88+
89+ if (_keyboard->isVisible())
90+ haveEvent = _keyboard->processInput(event, pad);
91+ else
92+ haveEvent = getEvent(event, pad);
93+
94+ if (haveEvent)
95+ {
96+ PSP_DEBUG_PRINT("Have event[%s]\n", haveEvent ? "true" : "false");
97+ PSP_DEBUG_PRINT("event.type[%d]\n", event.type);
98+ }
99+
100+ DEBUG_EXIT_FUNC();
101+
102+ return haveEvent;
103+}
104+
105+bool InputHandler::getEvent(Common::Event &event, SceCtrlData &pad) {
106+ DEBUG_ENTER_FUNC();
107+
108+ _buttonsChanged = pad.Buttons ^ _prevButtons;
109+ bool haveEvent = false;
110+
111+ // Collect events from different sources
112+ haveEvent = getDpadEvent(event, pad);
113+
114+ if (!haveEvent)
115+ haveEvent = getButtonEvent(event, pad);
116+
117+ if (!haveEvent)
118+ haveEvent = getNubEvent(event, pad);
119+
120+ _prevButtons = pad.Buttons;
121+
122+ DEBUG_EXIT_FUNC();
123+ return haveEvent;
124+}
125+
126+bool InputHandler::getDpadEvent(Common::Event &event, SceCtrlData &pad) {
127+ DEBUG_ENTER_FUNC();
128+
129+ int newDpadX = 0, newDpadY = 0;
130+ bool haveEvent = false;
131+
132+ if (DOWN(PSP_CTRL_UP)) {
133+ newDpadY++;
134+ if (DOWN(PSP_CTRL_RTRIGGER)) // Shifting causes diagonals
135+ newDpadX++;
136+ }
137+ if (DOWN(PSP_CTRL_RIGHT)) {
138+ newDpadX++;
139+ if (DOWN(PSP_CTRL_RTRIGGER))
140+ newDpadY--;
141+ }
142+ if (DOWN(PSP_CTRL_DOWN)) {
143+ newDpadY--;
144+ if (DOWN(PSP_CTRL_RTRIGGER))
145+ newDpadX--;
146+ }
147+ if (DOWN(PSP_CTRL_LEFT)) {
148+ newDpadX--;
149+ if (DOWN(PSP_CTRL_RTRIGGER))
150+ newDpadY++;
151+ }
152+
153+ if (newDpadX != _dpadX || newDpadY != _dpadY) {
154+ if (_dpadX == 0 && _dpadY == 0) { // We were in the middle so we pressed dpad
155+ event.type = Common::EVENT_KEYDOWN;
156+ event.kbd.keycode = translateDpad(newDpadX, newDpadY);
157+ event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0'; // Get ascii
158+ _dpadX = newDpadX;
159+ _dpadY = newDpadY;
160+ }
161+ else if (newDpadX == 0 && newDpadY == 0) {// We're now centered so we unpressed dpad
162+ event.type = Common::EVENT_KEYUP;
163+ event.kbd.keycode = translateDpad(_dpadX, _dpadY);
164+ event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0';
165+ _dpadX = newDpadX;
166+ _dpadY = newDpadY;
167+ } else { // we moved from one pressed dpad direction to another one
168+ event.type = Common::EVENT_KEYUP; // first release the last dpad direction
169+ event.kbd.keycode = translateDpad(_dpadX, _dpadY);
170+ event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0';
171+ _dpadX = 0; // so that we'll pick up a new dpad movement the next round
172+ _dpadY = 0;
173+ }
174+
175+ PSP_DEBUG_PRINT("Keypad event. DpadX[%d], DpadY[%d]\n", _dpadX, _dpadY);
176+ haveEvent = true;
177+ }
178+
179+ DEBUG_EXIT_FUNC();
180+ return haveEvent;
181+}
182+
183+inline Common::KeyCode InputHandler::translateDpad(int x, int y) {
184+ DEBUG_ENTER_FUNC();
185+ Common::KeyCode key;
186+
187+ if (x == -1) {
188+ if (y == -1)
189+ key = Common::KEYCODE_KP1;
190+ else if (y == 0)
191+ key = Common::KEYCODE_KP4;
192+ else /* y == 1 */
193+ key = Common::KEYCODE_KP7;
194+ } else if (x == 0) {
195+ if (y == -1)
196+ key = Common::KEYCODE_KP2;
197+ else /* y == 1 */
198+ key = Common::KEYCODE_KP8;
199+ } else {/* x == 1 */
200+ if (y == -1)
201+ key = Common::KEYCODE_KP3;
202+ else if (y == 0)
203+ key = Common::KEYCODE_KP6;
204+ else /* y == 1 */
205+ key = Common::KEYCODE_KP9;
206+ }
207+
208+ DEBUG_EXIT_FUNC();
209+ return key;
210+}
211+
212+
213+bool InputHandler::getButtonEvent(Common::Event &event, SceCtrlData &pad) {
214+ DEBUG_ENTER_FUNC();
215+ bool haveEvent = false;
216+
217+ if (PRESSED(PSP_CTRL_SELECT))
218+ _keyboard->setVisible(true);
219+
220+ else if (CHANGED(PSP_4BUTTONS | PSP_TRIGGERS | PSP_CTRL_START)) {
221+ if (CHANGED(PSP_CTRL_CROSS)) {
222+ event.type = DOWN(PSP_CTRL_CROSS) ? Common::EVENT_LBUTTONDOWN : Common::EVENT_LBUTTONUP;
223+ event.mouse.x = _cursor->getX(); // Could this have to do with SCI enter problem?
224+ event.mouse.y = _cursor->getY();
225+ PSP_DEBUG_PRINT("%s\n", event.type == Common::EVENT_LBUTTONDOWN ? "LButtonDown" : "LButtonUp");
226+ } else if (CHANGED(PSP_CTRL_CIRCLE)) {
227+ event.type = DOWN(PSP_CTRL_CIRCLE) ? Common::EVENT_RBUTTONDOWN : Common::EVENT_RBUTTONUP;
228+ event.mouse.x = _cursor->getX();
229+ event.mouse.y = _cursor->getY();
230+ PSP_DEBUG_PRINT("%s\n", event.type == Common::EVENT_LBUTTONDOWN ? "RButtonDown" : "RButtonUp");
231+ } else {
232+ //any of the other buttons.
233+ event.type = _buttonsChanged & pad.Buttons ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP;
234+ event.kbd.ascii = 0;
235+ event.kbd.flags = 0;
236+
237+ if (CHANGED(PSP_CTRL_LTRIGGER)) {
238+ event.kbd.keycode = Common::KEYCODE_ESCAPE;
239+ event.kbd.ascii = 27;
240+ } else if (CHANGED(PSP_CTRL_START)) {
241+ event.kbd.keycode = Common::KEYCODE_F5;
242+ event.kbd.ascii = Common::ASCII_F5;
243+ if (DOWN(PSP_CTRL_RTRIGGER)) {
244+ event.kbd.flags |= Common::KBD_CTRL; // Main menu to allow RTL
245+ }
246+ } else if (CHANGED(PSP_CTRL_SQUARE)) {
247+ event.kbd.keycode = Common::KEYCODE_PERIOD;
248+ event.kbd.ascii = '.';
249+ } else if (CHANGED(PSP_CTRL_TRIANGLE)) {
250+ event.kbd.keycode = Common::KEYCODE_RETURN;
251+ event.kbd.ascii = '\n';
252+ } else if (DOWN(PSP_CTRL_RTRIGGER)) { // An event
253+ event.kbd.flags |= Common::KBD_SHIFT;
254+ }
255+ PSP_DEBUG_PRINT("Ascii[%d]. Key %s.\n", event.kbd.ascii, event.type == Common::EVENT_KEYDOWN ? "down" : "up" );
256+ }
257+
258+ haveEvent = true;
259+ }
260+
261+ DEBUG_EXIT_FUNC();
262+ return haveEvent;
263+}
264+
265+bool InputHandler::getNubEvent(Common::Event &event, SceCtrlData &pad) {
266+ DEBUG_ENTER_FUNC();
267+
268+ bool haveEvent = false;
269+ int32 analogStepX = pad.Lx; // Goes up to 255.
270+ int32 analogStepY = pad.Ly;
271+
272+ int32 oldX = _cursor->getX();
273+ int32 oldY = _cursor->getY();
274+
275+ analogStepX = modifyNubAxisMotion(analogStepX);
276+ analogStepY = modifyNubAxisMotion(analogStepY);
277+
278+ if (analogStepX != 0 || analogStepY != 0) {
279+
280+ PSP_DEBUG_PRINT("raw x[%d], y[%d]\n", analogStepX, analogStepY);
281+
282+ // If no movement then this has no effect
283+ if (DOWN(PSP_CTRL_RTRIGGER)) {
284+ // Fine control mode for analog
285+ if (analogStepX != 0) {
286+ if (analogStepX > 0)
287+ _cursor->increaseXY(2, 0);
288+ else
289+ _cursor->increaseXY(-2, 0);
290+ }
291+
292+ if (analogStepY != 0) {
293+ if (analogStepY > 0)
294+ _cursor->increaseXY(0, 2);
295+ else
296+ _cursor->increaseXY(0, -2);
297+ }
298+ } else { // Regular speed movement
299+ _cursor->increaseXY(analogStepX, 0);
300+ _cursor->increaseXY(0, analogStepY);
301+ }
302+
303+ int32 newX = _cursor->getX();
304+ int32 newY = _cursor->getY();
305+
306+ if ((oldX != newX) || (oldY != newY)) {
307+ event.type = Common::EVENT_MOUSEMOVE;
308+ event.mouse.x = newX;
309+ event.mouse.y = newY;
310+ haveEvent = true;
311+
312+ PSP_DEBUG_PRINT("Nub event. X[%d], Y[%d]\n", newX, newY);
313+ }
314+ }
315+ DEBUG_EXIT_FUNC();
316+ return haveEvent;
317+}
318+
319+inline int32 InputHandler::modifyNubAxisMotion(int32 input) {
320+ DEBUG_ENTER_FUNC();
321+ const int MIN_NUB_MOTION = 23;
322+
323+ input -= 128; // Center on 0.
324+
325+ if (input < -MIN_NUB_MOTION - 1)
326+ input += MIN_NUB_MOTION + 1; // reduce the velocity
327+ else if (input > MIN_NUB_MOTION)
328+ input -= MIN_NUB_MOTION; // same
329+ else // between these points, dampen the response to 0
330+ input = 0;
331+
332+
333+ DEBUG_EXIT_FUNC();
334+ return input;
335+}
336\ No newline at end of file
337Index: backends/platform/psp/display_client.cpp
338===================================================================
339--- backends/platform/psp/display_client.cpp (revision 0)
340+++ backends/platform/psp/display_client.cpp (revision 0)
341@@ -0,0 +1,806 @@
342+/* ScummVM - Graphic Adventure Engine
343+ *
344+ * ScummVM is the legal property of its developers, whose names
345+ * are too numerous to list here. Please refer to the COPYRIGHT
346+ * file distributed with this source distribution.
347+ *
348+ * This program is free software; you can redistribute it and/or
349+ * modify it under the terms of the GNU General Public License
350+ * as published by the Free Software Foundation; either version 2
351+ * of the License, or (at your option) any later version.
352+
353+ * This program is distributed in the hope that it will be useful,
354+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
355+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
356+ * GNU General Public License for more details.
357+
358+ * You should have received a copy of the GNU General Public License
359+ * along with this program; if not, write to the Free Software
360+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
361+ *
362+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
363+ * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
364+ *
365+ */
366+
367+#include <pspgu.h>
368+#include <pspdisplay.h>
369+#include <psputils.h>
370+
371+#include "common/scummsys.h"
372+#include "backends/platform/psp/display_client.h"
373+#include "backends/platform/psp/display_manager.h"
374+#include "backends/platform/psp/memory.h"
375+
376+//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */
377+//#define __PSP_DEBUG_PRINT__
378+#include "backends/platform/psp/trace.h"
379+
380+#define PSP_BUFFER_WIDTH (512)
381+#define PSP_SCREEN_WIDTH 480
382+#define PSP_SCREEN_HEIGHT 272
383+#define PSP_FRAME_SIZE (PSP_BUFFER_WIDTH * PSP_SCREEN_HEIGHT)
384+
385+DisplayManager *GuRenderer::_displayManager = 0;
386+
387+
388+// class Palette ------------------------------------------------------------
389+//
390+void Palette::clear() {
391+ DEBUG_ENTER_FUNC();
392+
393+ if (_values && _numOfEntries)
394+ memset(_values, 0, getSizeInBytes());
395+
396+ PSP_DEBUG_PRINT("_values[%p]\n", _values);
397+
398+ DEBUG_EXIT_FUNC();
399+}
400+
401+// Used to clear the specific keycolor
402+//
403+void Palette::clearColor(uint32 color) {
404+ DEBUG_ENTER_FUNC();
405+
406+ assert(_values);
407+ assert(color < _numOfEntries);
408+
409+ PSP_DEBUG_PRINT("color[%d], numofEntries[%u], bpp[%u], values[%p]\n", color, _numOfEntries,
410+ _pixelFormat.bitsPerPixel, _values);
411+
412+ if (_numOfEntries <= 16)
413+ color &= 0xF;
414+ else if (_numOfEntries <= 256)
415+ color &= 0xFF;
416+
417+ switch (_pixelFormat.bitsPerPixel) {
418+ case 16: {
419+ uint16 *shortVal = (uint16 *)&_values[_pixelFormat.pixelsToBytes(color)];
420+ *shortVal = 0;
421+ }
422+ break;
423+ case 32: {
424+ uint32 *wordVal = (uint32 *)&_values[_pixelFormat.pixelsToBytes(color)];
425+ *wordVal = 0;
426+ }
427+ break;
428+ default:
429+ PSP_ERROR("Incorrect bits per pixel value[%u]\n", _pixelFormat.bitsPerPixel);
430+ }
431+
432+ DEBUG_EXIT_FUNC();
433+}
434+
435+// Set some of the palette to color values in array
436+// By default, ScummVm doesn't support alpha values in palettes
437+void Palette::setPartial(const byte *colors, uint32 start, uint32 num, bool supportsAlpha /* = false */) {
438+ DEBUG_ENTER_FUNC();
439+
440+ assert(_values);
441+ assert(_numOfEntries);
442+
443+ const byte *src = colors;
444+
445+ if (start + num > _numOfEntries) // Check boundary
446+ num = _numOfEntries - start;
447+
448+ if (_pixelFormat.bitsPerPixel == 16) {
449+ uint16 *palette = (uint16 *)_values;
450+ palette += start;
451+
452+ for (uint32 i = 0; i < num; ++i) {
453+ byte alphaVal = supportsAlpha ? src[3] : 0xFF;
454+ *palette = (uint16)_pixelFormat.rgbaToColor(src[0], src[1], src[2], alphaVal);
455+ src += 4;
456+ palette++;
457+ }
458+ }
459+ else if (_pixelFormat.bitsPerPixel == 32) {
460+ uint32 *palette = (uint32 *)_values;
461+ palette += start;
462+
463+ for (uint32 i = 0; i < num; ++i) {
464+ byte alphaVal = supportsAlpha ? src[3] : 0xFF;
465+ *palette = _pixelFormat.rgbaToColor(src[0], src[1], src[2], alphaVal);
466+ src += 4;
467+ palette++;
468+ }
469+ }
470+
471+ DEBUG_EXIT_FUNC();
472+}
473+
474+// Sets pixel format and number of entries by the buffer's pixel format */
475+void Palette::setPixelFormats(PSPPixelFormat::Type paletteType, PSPPixelFormat::Type bufferType, bool swapRedBlue /* = false */) {
476+ DEBUG_ENTER_FUNC();
477+
478+ if (paletteType == PSPPixelFormat::Type_Unknown)
479+ PSP_ERROR("Unknown paletteType[%u]\n", paletteType);
480+
481+ switch (bufferType) {
482+ case PSPPixelFormat::Type_Palette_8bit:
483+ _numOfEntries = 256;
484+ break;
485+ case PSPPixelFormat::Type_Palette_4bit:
486+ _numOfEntries = 16;
487+ break;
488+ case PSPPixelFormat::Type_Unknown:
489+ case PSPPixelFormat::Type_None:
490+ PSP_ERROR("Unhandled bufferType[%u]\n", bufferType);
491+ break;
492+ default: // No palette
493+ _numOfEntries = 0;
494+ break;
495+ }
496+
497+ _pixelFormat.set(paletteType, swapRedBlue);
498+
499+ DEBUG_EXIT_FUNC();
500+}
501+
502+bool Palette::allocate() {
503+ DEBUG_ENTER_FUNC();
504+ PSP_DEBUG_PRINT("_numOfEntries[%u]\n", _numOfEntries);
505+ PSP_DEBUG_PRINT("_pixelFormat: format[%u], bpp[%u]\n", _pixelFormat.format, _pixelFormat.bitsPerPixel);
506+
507+ if (_values) {
508+ free (CACHED(_values));
509+ _values = 0;
510+ }
511+
512+ // We allocate on 64bytes to get a cache line, and round up to 64bytes to get the full line
513+ uint32 amountInBytes = getSizeInBytes();
514+ if (amountInBytes < 64)
515+ amountInBytes = 64;
516+ _values = (byte *)memalign(64, amountInBytes);
517+
518+ // Use uncached memory
519+ GuRenderer::cacheInvalidate(_values, amountInBytes);
520+ _values = UNCACHED(_values);
521+
522+ if (!_values) {
523+ PSP_ERROR("Couldn't allocate palette.\n");
524+ DEBUG_EXIT_FUNC();
525+ return false;
526+ }
527+
528+ PSP_DEBUG_PRINT("_values[%p]\n", _values);
529+ clear();
530+
531+ DEBUG_EXIT_FUNC();
532+ return true;
533+}
534+
535+void Palette::deallocate() {
536+ DEBUG_ENTER_FUNC();
537+
538+ free (CACHED(_values));
539+ _values = 0;
540+ _numOfEntries = 0;
541+
542+ DEBUG_EXIT_FUNC();
543+}
544+
545+// Copy some of the palette to an array of colors
546+//
547+void Palette::getPartial(byte *colors, uint start, uint num) {
548+ DEBUG_ENTER_FUNC();
549+
550+ assert(_values);
551+ assert(_numOfEntries);
552+
553+ uint32 r, g, b, a;
554+
555+ if (start + num > _numOfEntries) // Check boundary
556+ num = _numOfEntries - start;
557+
558+ if (_pixelFormat.bitsPerPixel == 16) {
559+ uint16 *palette = (uint16 *)_values;
560+ palette += start;
561+
562+ for (uint32 i = start; i < start + num; i++) {
563+ _pixelFormat.colorToRgba(*palette, r, g, b, a);
564+
565+ *colors++ = (byte)r;
566+ *colors++ = (byte)g;
567+ *colors++ = (byte)b;
568+ *colors++ = (byte)a;
569+ palette++;
570+ }
571+ } else if (_pixelFormat.bitsPerPixel == 32) {
572+ uint32 *palette = (uint32 *)_values;
573+ palette += start;
574+
575+ for (uint32 i = start; i < start + num; i++) {
576+ _pixelFormat.colorToRgba(*palette, r, g, b, a);
577+
578+ *colors++ = (byte)r;
579+ *colors++ = (byte)g;
580+ *colors++ = (byte)b;
581+ *colors++ = (byte)a;
582+ palette++;
583+ }
584+ }
585+
586+ DEBUG_EXIT_FUNC();
587+}
588+
589+void Palette::setSingleColorRGBA(uint32 num, byte r, byte g, byte b, byte a) {
590+ // DEBUG_ENTER_FUNC();
591+ uint16 *shortValues;
592+ uint32 *wordValues;
593+
594+ assert (_values);
595+ assert (num < _numOfEntries);
596+
597+ switch (_pixelFormat.bitsPerPixel) {
598+ case 16:
599+ shortValues = (uint16 *)_values;
600+ shortValues[num] = _pixelFormat.rgbaToColor(r, g, b, a);
601+ break;
602+ case 32:
603+ wordValues = (uint32 *)_values;
604+ wordValues[num] = _pixelFormat.rgbaToColor(r, g, b, a);
605+ break;
606+ default:
607+ PSP_ERROR("Incorrect bitsPerPixel[%d]\n", _pixelFormat.bitsPerPixel);
608+ break;
609+ }
610+ // DEBUG_EXIT_FUNC();
611+}
612+
613+// Print to screen
614+void Palette::print(uint32 numToPrint /* = 0 */) {
615+ if (_numOfEntries > 0) {
616+ assert (_values);
617+
618+ if (numToPrint > _numOfEntries || numToPrint == 0)
619+ numToPrint = _numOfEntries;
620+
621+ PSP_INFO_PRINT("cursor palette:\n");
622+
623+ for (unsigned int i=0; i<numToPrint; i++) {
624+ byte *pcolor = &_values[_pixelFormat.pixelsToBytes(i)];
625+ uint32 color = _pixelFormat.getColorValueAt(pcolor);
626+
627+ PSP_INFO_PRINT("[%u=%x] ", i, color);
628+ }
629+
630+ PSP_INFO_PRINT("\n");
631+ }
632+}
633+
634+uint32 Palette::getRawColorAt(uint32 position) {
635+ byte *pcolor = &_values[_pixelFormat.pixelsToBytes(position)];
636+ uint32 color = _pixelFormat.getColorValueAt(pcolor);
637+ return color;
638+}
639+
640+uint32 Palette::getRGBAColorAt(uint32 position) {
641+ uint32 color = getRawColorAt(position);
642+ uint32 r, g, b, a;
643+ _pixelFormat.colorToRgba(color, r, g, b, a);
644+ return (a << 24 | b << 16 | g << 8 | r);
645+}
646+
647+// class Buffer ---------------------------------------------------
648+
649+void Buffer::setPixelFormat(PSPPixelFormat::Type type, bool swapRedBlue) {
650+ if (type == PSPPixelFormat::Type_None ||
651+ type == PSPPixelFormat::Type_Unknown)
652+ PSP_ERROR("Unhandled buffer format[%u]\n", type);
653+
654+ _pixelFormat.set(type, swapRedBlue);
655+}
656+
657+bool Buffer::hasPalette() {
658+ if (_pixelFormat.format == PSPPixelFormat::Type_Palette_8bit ||
659+ _pixelFormat.format == PSPPixelFormat::Type_Palette_4bit)
660+ return true;
661+
662+ return false;
663+}
664+
665+/* pitch is in bytes */
666+void Buffer::copyFromArray(const byte *buffer, int pitch) {
667+ DEBUG_ENTER_FUNC();
668+
669+ // We use sourceSize because outside, they won't know what the true size is
670+ copyFromRect(buffer, pitch, 0, 0, _sourceSize.width, _sourceSize.height);
671+
672+ DEBUG_EXIT_FUNC();
673+}
674+
675+/* pitch is in bytes */
676+void Buffer::copyFromRect(const byte *buf, uint32 pitch, int destX, int destY, uint32 recWidth, uint32 recHeight) {
677+ // Removed silly clipping code
678+ DEBUG_ENTER_FUNC();
679+ assert (_pixels);
680+
681+ if (recWidth > _sourceSize.width - destX) {
682+ recWidth = _sourceSize.width - destX;
683+ }
684+
685+ if (recHeight > _sourceSize.height - destY) {
686+ recHeight = _sourceSize.height - destY;
687+ }
688+
689+ if (recWidth <= 0 || recHeight <= 0) {
690+ DEBUG_EXIT_FUNC();
691+ return;
692+ }
693+
694+ byte *dst = _pixels + _pixelFormat.pixelsToBytes((destY * _width) + destX);
695+
696+ uint32 recWidthInBytes = _pixelFormat.pixelsToBytes(recWidth);
697+ uint32 realWidthInBytes = _pixelFormat.pixelsToBytes(_width);
698+
699+ if (pitch == realWidthInBytes && pitch == recWidthInBytes) {
700+ //memcpy(dst, buf, _pixelFormat.pixelsToBytes(recHeight * recWidth));
701+ Copier::copy(dst, buf, _pixelFormat.pixelsToBytes(recHeight * recWidth), &_pixelFormat);
702+ } else {
703+ do {
704+ //memcpy(dst, buf, recWidthInBytes);
705+ Copier::copy(dst, buf, recWidthInBytes, &_pixelFormat);
706+ buf += pitch;
707+ dst += realWidthInBytes;
708+ } while (--recHeight);
709+ }
710+
711+ DEBUG_EXIT_FUNC();
712+}
713+
714+/* pitch is in bytes */
715+void Buffer::copyToArray(byte *dst, int pitch) {
716+ DEBUG_ENTER_FUNC();
717+ assert (_pixels);
718+
719+ uint32 h = _height;
720+ byte *src = _pixels;
721+ uint32 sourceWidthInBytes = _pixelFormat.pixelsToBytes(_sourceSize.width);
722+ uint32 realWidthInBytes = _pixelFormat.pixelsToBytes(_width);
723+
724+ do {
725+ //memcpy(dst, src, sourceWidthInBytes);
726+ Copier::copy(dst, src, sourceWidthInBytes, &_pixelFormat);
727+ src += realWidthInBytes;
728+ dst += pitch;
729+ } while (--h);
730+
731+ DEBUG_EXIT_FUNC();
732+}
733+
734+/* We can size the buffer either by texture size (multiple of 2^n) or source size. The GU can
735+ really handle both, but is supposed to get only 2^n size buffers */
736+void Buffer::setSize(uint32 width, uint32 height, HowToSize textureOrSource/*=kSizeByTextureSize*/) {
737+ DEBUG_ENTER_FUNC();
738+ PSP_DEBUG_PRINT("w[%u], h[%u], %s\n", width, height, textureOrSource ? "size by source" : "size by texture");
739+
740+ _sourceSize.width = width;
741+ _sourceSize.height = height;
742+
743+ _textureSize.width = scaleUpToPowerOfTwo(width);
744+ _textureSize.height = scaleUpToPowerOfTwo(height);
745+
746+ if (textureOrSource == kSizeByTextureSize) {
747+ _width = _textureSize.width;
748+ _height = _textureSize.height;
749+ }
750+ else { /* kSizeBySourceSize */
751+ _width = _sourceSize.width;
752+ _height = _sourceSize.height;
753+ }
754+
755+ DEBUG_EXIT_FUNC();
756+}
757+
758+/* Scale a dimension (width/height) up to power of 2 for the texture */
759+uint32 Buffer::scaleUpToPowerOfTwo(uint32 size) {
760+
761+ uint32 textureDimension = 0;
762+ if (size <= 16)
763+ textureDimension = 16;
764+ else if (size <= 32)
765+ textureDimension = 32;
766+ else if (size <= 64)
767+ textureDimension = 64;
768+ else if (size <= 128)
769+ textureDimension = 128;
770+ else if (size <= 256)
771+ textureDimension = 256;
772+ else
773+ textureDimension = 512;
774+
775+ PSP_DEBUG_PRINT("power of 2 = %u\n", textureDimension);
776+
777+ return textureDimension;
778+}
779+
780+bool Buffer::allocate(bool inVram/*=false*/) {
781+ DEBUG_ENTER_FUNC();
782+
783+ PSP_DEBUG_PRINT("_width[%u], _height[%u]\n", _width, _height);
784+ PSP_DEBUG_PRINT("_pixelFormat: format[%u], bpp[%u]\n", _pixelFormat.format, _pixelFormat.bitsPerPixel);
785+
786+ if (_pixels) {
787+ if (VramAllocator::isAddressInVram(_pixels)) // Check if in VRAM
788+ VramAllocator::instance().deallocate(_pixels);
789+ else // not in VRAM
790+ free (CACHED(_pixels));
791+
792+ _pixels = 0;
793+ }
794+
795+ uint32 size = getSizeInBytes();
796+
797+ if (inVram) {
798+ _pixels = (byte *)VramAllocator::instance().allocate(size);
799+ }
800+
801+ if (!_pixels) { // Either we are not in vram or we didn't manage to allocate in vram
802+ // Align to 64 bytes. All normal buffer sizes are multiples of 64 anyway
803+ _pixels = (byte *)memalign(64, size);
804+ }
805+
806+ if (!_pixels) {
807+ PSP_ERROR("couldn't allocate buffer.\n");
808+ DEBUG_EXIT_FUNC();
809+ return false;
810+ }
811+
812+ // Use uncached memory
813+ GuRenderer::cacheInvalidate(_pixels, size);
814+ _pixels = UNCACHED(_pixels);
815+
816+ clear();
817+ DEBUG_EXIT_FUNC();
818+ return true;
819+}
820+
821+void Buffer::deallocate() {
822+ DEBUG_ENTER_FUNC();
823+
824+ if (!_pixels)
825+ return;
826+
827+ if (VramAllocator::isAddressInVram(_pixels)) // Check if in VRAM
828+ VramAllocator::instance().deallocate(_pixels);
829+ else
830+ free(CACHED(_pixels));
831+
832+ _pixels = 0;
833+
834+ DEBUG_EXIT_FUNC();
835+}
836+
837+void Buffer::clear() {
838+ DEBUG_ENTER_FUNC();
839+
840+ if (_pixels)
841+ memset(_pixels, 0, getSizeInBytes());
842+
843+ DEBUG_EXIT_FUNC();
844+}
845+
846+/* Convert 4 bit images to match weird PSP format */
847+void Buffer::flipNibbles() {
848+ DEBUG_ENTER_FUNC();
849+
850+ if (_pixelFormat.bitsPerPixel != 4)
851+ return;
852+
853+ assert(_pixels);
854+
855+ uint32 *dest = (uint32 *)_pixels;
856+
857+ for (uint32 i = 0; i < getSourceHeight(); i++) {
858+ for (uint32 j = 0; j < (getWidth() >> 3); j++) { // /8 because we do it in 32bit chunks
859+ uint32 val = *dest;
860+ *dest++ = ((val >> 4) & 0x0F0F0F0F) | ((val << 4) & 0xF0F0F0F0);
861+ }
862+ }
863+
864+ DEBUG_EXIT_FUNC();
865+}
866+
867+// Print buffer contents to screen (only source size is printed out)
868+void Buffer::print(uint32 mask, uint32 numToPrint /*=0*/) {
869+ assert(_pixels);
870+
871+ if (numToPrint > _sourceSize.width * _sourceSize.height || numToPrint == 0)
872+ numToPrint = _sourceSize.width * _sourceSize.height;
873+
874+ PSP_INFO_PRINT("buffer: \n");
875+ PSP_INFO_PRINT("width[%u], height[%u]\n\n", _sourceSize.width, _sourceSize.height);
876+
877+ for (unsigned int i=0; i < _sourceSize.height; i++) {
878+ for (unsigned int j=0; j < _sourceSize.width; j++) {
879+ if (numToPrint <= 0) // check if done
880+ break;
881+
882+ byte *pcolor = &_pixels[_pixelFormat.pixelsToBytes((i * _width) + j)];
883+ uint32 color = _pixelFormat.getColorValueAt(pcolor);
884+
885+ if (color != 0) PSP_INFO_PRINT("[%x] ", color);
886+ //PSP_INFO_PRINT("[%x] ", mask & color);
887+
888+ numToPrint--;
889+ }
890+ PSP_INFO_PRINT("\n");
891+ }
892+ PSP_INFO_PRINT("\n");
893+}
894+
895+// class GuRenderer -------------------------------------------------
896+//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */
897+//#define __PSP_DEBUG_PRINT__
898+
899+#include "backends/platform/psp/trace.h"
900+
901+
902+void GuRenderer::render() {
903+ DEBUG_ENTER_FUNC();
904+ PSP_DEBUG_PRINT("Buffer[%p] Palette[%p]\n", _buffer->getPixels(), _palette->getRawValues());
905+
906+ setMaxTextureOffsetByIndex(0, 0);
907+
908+ guProgramDrawBehavior();
909+
910+ if (_buffer->hasPalette())
911+ guLoadPalette();
912+
913+ guProgramTextureFormat();
914+ guLoadTexture();
915+
916+ Vertex *vertices = guGetVertices();
917+ fillVertices(vertices);
918+
919+ guDrawVertices(vertices);
920+
921+ if (_buffer->getSourceWidth() > 512) {
922+ setMaxTextureOffsetByIndex(1, 0);
923+
924+ guLoadTexture();
925+
926+ vertices = guGetVertices();
927+ fillVertices(vertices);
928+
929+ guDrawVertices(vertices);
930+ }
931+
932+ DEBUG_EXIT_FUNC();
933+}
934+
935+INLINE void GuRenderer::setMaxTextureOffsetByIndex(uint32 x, uint32 y) {
936+ DEBUG_ENTER_FUNC();
937+ const uint32 maxTextureSizeShift = 9; /* corresponds to 512 = max texture size*/
938+
939+ _maxTextureOffset.x = x << maxTextureSizeShift; /* x times 512 */
940+ _maxTextureOffset.y = y << maxTextureSizeShift; /* y times 512 */
941+ DEBUG_EXIT_FUNC();
942+}
943+
944+INLINE void GuRenderer::guProgramDrawBehavior() {
945+ DEBUG_ENTER_FUNC();
946+ PSP_DEBUG_PRINT("blending[%s] colorTest[%s] reverseAlpha[%s] keyColor[%u]\n", _blending ? "on" : "off", _colorTest ? "on" : "off", _alphaReverse ? "on" : "off", _keyColor);
947+
948+ if (_blending) {
949+ sceGuEnable(GU_BLEND);
950+
951+ if (_alphaReverse) // Reverse the alpha value (0 is 1)
952+ sceGuBlendFunc(GU_ADD, GU_ONE_MINUS_SRC_ALPHA, GU_SRC_ALPHA, 0, 0);
953+ else // Normal alpha values
954+ sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
955+
956+ } else
957+ sceGuDisable(GU_BLEND);
958+
959+ if (_colorTest) {
960+ sceGuEnable(GU_COLOR_TEST);
961+ sceGuColorFunc(GU_NOTEQUAL, _keyColor, 0x00ffffff);
962+ } else
963+ sceGuDisable(GU_COLOR_TEST);
964+
965+ DEBUG_EXIT_FUNC();
966+}
967+
968+INLINE void GuRenderer::guLoadPalette() {
969+ DEBUG_ENTER_FUNC();
970+
971+ uint32 mask;
972+
973+ if (_buffer->getBitsPerPixel() == 4)
974+ mask = 0x0F;
975+ else if (_buffer->getBitsPerPixel() == 8)
976+ mask = 0xFF;
977+ else
978+ assert(0); /* error */
979+
980+ PSP_DEBUG_PRINT("numOfEntries[%d]\n", _palette->getNumOfEntries());
981+ PSP_DEBUG_PRINT("bpp[%d], pixelformat[%d], mask[%x]\n", _buffer->getBitsPerPixel(), _palette->getPixelFormat(), mask);
982+
983+ sceGuClutMode(convertToGuPixelFormat(_palette->getPixelFormat()), 0, mask, 0);
984+ sceGuClutLoad(_palette->getNumOfEntries() >> 3, _palette->getRawValues());
985+
986+ DEBUG_EXIT_FUNC();
987+}
988+
989+INLINE void GuRenderer::guProgramTextureFormat() {
990+ DEBUG_ENTER_FUNC();
991+ PSP_DEBUG_PRINT("pixelFormat[%d]\n", _buffer->getPixelFormat());
992+
993+ sceGuTexMode(convertToGuPixelFormat(_buffer->getPixelFormat()), 0, 0, 0);
994+ DEBUG_EXIT_FUNC();
995+}
996+
997+INLINE uint32 GuRenderer::convertToGuPixelFormat(PSPPixelFormat::Type format) {
998+ DEBUG_ENTER_FUNC();
999+
1000+ uint32 guFormat = 0;
1001+
1002+ switch (format) {
1003+ case PSPPixelFormat::Type_4444:
1004+ guFormat = GU_PSM_4444;
1005+ break;
1006+ case PSPPixelFormat::Type_5551:
1007+ guFormat = GU_PSM_5551;
1008+ break;
1009+ case PSPPixelFormat::Type_5650:
1010+ guFormat = GU_PSM_5650;
1011+ break;
1012+ case PSPPixelFormat::Type_8888:
1013+ guFormat = GU_PSM_8888;
1014+ break;
1015+ case PSPPixelFormat::Type_Palette_8bit:
1016+ guFormat = GU_PSM_T8;
1017+ break;
1018+ case PSPPixelFormat::Type_Palette_4bit:
1019+ guFormat = GU_PSM_T4;
1020+ break;
1021+ default:
1022+ break;
1023+ }
1024+
1025+ PSP_DEBUG_PRINT("Pixelformat[%d], guFormat[%d]\n", format, guFormat);
1026+
1027+ DEBUG_EXIT_FUNC();
1028+ return guFormat;
1029+
1030+}
1031+
1032+INLINE void GuRenderer::guLoadTexture() {
1033+ DEBUG_ENTER_FUNC();
1034+
1035+ sceGuTexImage(0, _buffer->getTextureWidth(), _buffer->getTextureHeight(), _buffer->getWidth(), _buffer->getPixels() + _buffer->_pixelFormat.pixelsToBytes(_maxTextureOffset.x));
1036+
1037+ DEBUG_EXIT_FUNC();
1038+}
1039+
1040+INLINE Vertex *GuRenderer::guGetVertices() {
1041+ DEBUG_ENTER_FUNC();
1042+
1043+ Vertex *ret = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
1044+
1045+ DEBUG_EXIT_FUNC();
1046+ return ret;
1047+}
1048+
1049+// Fills the vertices. Most of the logic is here.
1050+void GuRenderer::fillVertices(Vertex *vertices) {
1051+ DEBUG_ENTER_FUNC();
1052+
1053+ uint32 outputWidth = _displayManager->getOutputWidth();
1054+ uint32 outputHeight = _displayManager->getOutputHeight();
1055+
1056+ float textureStartX, textureStartY, textureEndX, textureEndY;
1057+
1058+ // Texture adjustments for eliminating half-pixel artifacts from scaling
1059+ // Not necessary if we don't scale
1060+ float textureAdjustment = 0.0f;
1061+ if (_useGlobalScaler &&
1062+ (_displayManager->getScaleX() != 1.0f || _displayManager->getScaleX() != 1.0f))
1063+ textureAdjustment = 0.5f;
1064+
1065+ textureStartX = textureAdjustment + _offsetInBuffer.x; //debug
1066+ textureStartY = textureAdjustment + _offsetInBuffer.y;
1067+ // We subtract maxTextureOffset because our shifted texture starts at 512 and will go to 640
1068+ textureEndX = _offsetInBuffer.x + _drawSize.width - textureAdjustment - _maxTextureOffset.x;
1069+ textureEndY = _offsetInBuffer.y + _drawSize.height - textureAdjustment;
1070+
1071+ // For scaling to the final image size, calculate the gaps on both sides
1072+ uint32 gapX = _useGlobalScaler ? (PSP_SCREEN_WIDTH - outputWidth) >> 1 : 0;
1073+ uint32 gapY = _useGlobalScaler ? (PSP_SCREEN_HEIGHT - outputHeight) >> 1 : 0;
1074+
1075+ float imageStartX, imageStartY, imageEndX, imageEndY;
1076+
1077+ imageStartX = gapX + ( scaleSourceToOutputX(_maxTextureOffset.x) );
1078+ imageStartY = gapY;
1079+
1080+ imageStartX += scaleSourceToOutputX(_offsetOnScreen.x);
1081+ imageStartY += scaleSourceToOutputY(_offsetOnScreen.y);
1082+
1083+ if (_fullScreen) { // shortcut
1084+ imageEndX = PSP_SCREEN_WIDTH - gapX;
1085+ imageEndY = PSP_SCREEN_HEIGHT - gapY;
1086+ } else { /* !fullScreen */
1087+ imageEndX = imageStartX + scaleSourceToOutputX(_drawSize.width);
1088+ imageEndY = imageStartY + scaleSourceToOutputY(_drawSize.height);
1089+ }
1090+
1091+ vertices[0].u = textureStartX;
1092+ vertices[0].v = textureStartY;
1093+ vertices[1].u = textureEndX;
1094+ vertices[1].v = textureEndY;
1095+
1096+ vertices[0].x = imageStartX;
1097+ vertices[0].y = imageStartY;
1098+ vertices[0].z = 0;
1099+ vertices[1].x = imageEndX;
1100+ vertices[1].y = imageEndY;
1101+ vertices[1].z = 0;
1102+
1103+ PSP_DEBUG_PRINT("TextureStart: X[%f] Y[%f] TextureEnd: X[%.1f] Y[%.1f]\n", textureStartX, textureStartY, textureEndX, textureEndY);
1104+ PSP_DEBUG_PRINT("ImageStart: X[%f] Y[%f] ImageEnd: X[%.1f] Y[%.1f]\n", imageStartX, imageStartY, imageEndX, imageEndY);
1105+
1106+ DEBUG_EXIT_FUNC();
1107+}
1108+
1109+/* Scale the input X offset to appear in proper position on the screen */
1110+INLINE float GuRenderer::scaleSourceToOutputX(float offset) {
1111+ float result;
1112+
1113+ if (!_useGlobalScaler)
1114+ result = offset;
1115+ else if (!offset)
1116+ result = 0.0f;
1117+ else
1118+ result = offset * _displayManager->getScaleX();
1119+
1120+ return result;
1121+}
1122+
1123+/* Scale the input Y offset to appear in proper position on the screen */
1124+INLINE float GuRenderer::scaleSourceToOutputY(float offset) {
1125+ float result;
1126+
1127+ if (!_useGlobalScaler)
1128+ result = offset;
1129+ else if (!offset)
1130+ result = 0.0f;
1131+ else
1132+ result = offset * _displayManager->getScaleY();
1133+
1134+ return result;
1135+}
1136+
1137+INLINE void GuRenderer::guDrawVertices(Vertex *vertices) {
1138+ DEBUG_ENTER_FUNC();
1139+
1140+ sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
1141+ DEBUG_EXIT_FUNC();
1142+}
1143+
1144+void GuRenderer::cacheInvalidate(void *pointer, uint32 size) {
1145+ sceKernelDcacheWritebackInvalidateRange(pointer, size);
1146+}
1147+
1148Index: backends/platform/psp/trace.h
1149===================================================================
1150--- backends/platform/psp/trace.h (revision 48355)
1151+++ backends/platform/psp/trace.h (working copy)
1152@@ -29,25 +29,109 @@
1153
1154 #include <stdio.h>
1155 #include <psptypes.h>
1156-#include <pspkernel.h>
1157 #include <stdarg.h>
1158-#include <pspdebug.h>
1159
1160 // Use these defines for debugging
1161
1162-//#define __PSP_DEBUG__
1163-//#define __PSP_DEBUG_SUSPEND__
1164+//#define __PSP_PRINT_TO_FILE__
1165+//#define __PSP_PRINT_TO_FILE_AND_SCREEN__
1166+//#define __PSP_DEBUG_FUNCS__ /* can put this locally too */
1167+//#define __PSP_DEBUG_PRINT__
1168
1169-void PSPDebugTrace (const char *filename, const char *format, ...);
1170-void PSPDebugTrace (const char *format, ...);
1171+void PSPDebugTrace (bool alsoToScreen, const char *format, ...);
1172
1173-#ifdef __PSP_DEBUG_SUSPEND__
1174-#define PSPDebugSuspend(format,...) PSPDebugTrace(format, ## __VA_ARGS__)
1175-#else
1176-#define PSPDegbugSuspend(x)
1177-#define PSPDebugSuspend(format,...)
1178-#endif /* __PSP_DEBUG_SUSPEND__ */
1179+#ifndef TRACE_C
1180+extern int psp_debug_indent;
1181+#endif
1182
1183+#endif /* TRACE_H */
1184
1185-#endif // TRACE_H
1186+// From here on, we allow multiple definitions
1187+#undef __PSP_PRINT__
1188+#undef PSP_ERROR
1189+#undef PSP_ERROR_STATIC
1190+#undef __PSP_INDENT__
1191+#undef PSP_INFO_PRINT
1192+#undef PSP_INFO_PRINT_INDENT
1193+#undef PSP_DEBUG_PRINT
1194+#undef PSP_DEBUG_PRINT_FUNC
1195+#undef PSP_DEBUG_PRINT_SAMELN
1196+#undef PSP_DEBUG_DO
1197+#undef DEBUG_ENTER_FUNC
1198+#undef DEBUG_ENTER_FUNC_STATIC
1199+#undef DEBUG_EXIT_FUNC
1200+#undef DEBUG_EXIT_FUNC_STATIC
1201+#undef INLINE
1202
1203+/* Choose to print to file/screen/both */
1204+#ifdef __PSP_PRINT_TO_FILE__
1205+ #define __PSP_PRINT__(format,...) PSPDebugTrace(false, format, ## __VA_ARGS__)
1206+#elif defined __PSP_PRINT_TO_FILE_AND_SCREEN__
1207+ #define __PSP_PRINT__(format,...) PSPDebugTrace(true, format, ## __VA_ARGS__)
1208+#else /* default - print to screen */
1209+ #define __PSP_PRINT__(format,...) fprintf(stderr, format, ## __VA_ARGS__)
1210+#endif /* PSP_PRINT_TO_FILE/SCREEN */
1211+
1212+/* Error function */
1213+#define PSP_ERROR(format,...) __PSP_PRINT__("Error in %s::%s(): " format, getObjectName(), __FUNCTION__, ## __VA_ARGS__)
1214+
1215+#define PSP_ERROR_STATIC(format, ...) __PSP_PRINT__("Error in %s(): " format, __FUNCTION__, ## __VA_ARGS__)
1216+
1217+/* Do the indent */
1218+#define __PSP_INDENT__ for(int _i=psp_debug_indent; _i>0; _i--) \
1219+ __PSP_PRINT__( " ")
1220+
1221+/* always print */
1222+#define PSP_INFO_PRINT(format,...) __PSP_PRINT__(format, ## __VA_ARGS__)
1223+/* always print, with indent */
1224+#define PSP_INFO_PRINT_INDENT(format,...) { __PSP_INDENT__; \
1225+ __PSP_PRINT__(format, ## __VA_ARGS__); }
1226+
1227+#ifdef __PSP_DEBUG_PRINT__
1228+ /* printf with indents */
1229+ #define PSP_DEBUG_PRINT_SAMELN(format,...) __PSP_PRINT__(format, ## __VA_ARGS__)
1230+ #define PSP_DEBUG_PRINT(format,...) { __PSP_INDENT__; \
1231+ __PSP_PRINT__(format, ## __VA_ARGS__); }
1232+ #define PSP_DEBUG_PRINT_FUNC(format,...) { __PSP_INDENT__; \
1233+ __PSP_PRINT__("In %s::%s(): " format, getObjectName(), __FUNCTION__, ## __VA_ARGS__); }
1234+ #define PSP_DEBUG_DO(x) (x)
1235+
1236+#else /* no debug print */
1237+ #define PSP_DEBUG_PRINT_SAMELN(format,...)
1238+ #define PSP_DEBUG_PRINT(format,...)
1239+ #define PSP_DEBUG_PRINT_FUNC(format,...)
1240+ #define PSP_DEBUG_DO(x)
1241+#endif /* __PSP_DEBUG_PRINT__ */
1242+
1243+/* Debugging function calls */
1244+#ifdef __PSP_DEBUG_FUNCS__
1245+ #define DEBUG_ENTER_FUNC() PSP_INFO_PRINT_INDENT("++ %s::%s()\n", getObjectName(), __FUNCTION__); \
1246+ psp_debug_indent++
1247+
1248+ #define DEBUG_ENTER_FUNC_STATIC() PSP_INFO_PRINT_INDENT("++ %s()\n", __FUNCTION__); \
1249+ psp_debug_indent++
1250+
1251+ #define DEBUG_EXIT_FUNC() psp_debug_indent--; \
1252+ if (psp_debug_indent < 0) PSP_ERROR("debug indent < 0\n"); \
1253+ PSP_INFO_PRINT_INDENT("-- %s::%s()\n", getObjectName(), __FUNCTION__)
1254+
1255+ #define DEBUG_EXIT_FUNC_STATIC() psp_debug_indent--; \
1256+ if (psp_debug_indent < 0) PSP_ERROR_STATIC("debug indent < 0\n"); \
1257+ PSP_INFO_PRINT_INDENT("-- %s()\n", __FUNCTION__)
1258+
1259+ #define INLINE /* don't want to inline so we get function names properly */
1260+
1261+#else /* Don't debug function calls */
1262+ #define DEBUG_ENTER_FUNC()
1263+ #define DEBUG_ENTER_FUNC_STATIC()
1264+ #define DEBUG_EXIT_FUNC()
1265+ #define DEBUG_EXIT_FUNC_STATIC()
1266+ #define INLINE inline
1267+#endif /* __PSP_DEBUG_FUNCS__ */
1268+
1269+// Undef the main defines for next time
1270+#undef __PSP_PRINT_TO_FILE__
1271+#undef __PSP_PRINT_TO_FILE_AND_SCREEN__
1272+#undef __PSP_DEBUG_FUNCS__
1273+#undef __PSP_DEBUG_PRINT__
1274+
1275Index: backends/platform/psp/display_manager.h
1276===================================================================
1277--- backends/platform/psp/display_manager.h (revision 0)
1278+++ backends/platform/psp/display_manager.h (revision 0)
1279@@ -0,0 +1,117 @@
1280+/* ScummVM - Graphic Adventure Engine
1281+ *
1282+ * ScummVM is the legal property of its developers, whose names
1283+ * are too numerous to list here. Please refer to the COPYRIGHT
1284+ * file distributed with this source distribution.
1285+ *
1286+ * This program is free software; you can redistribute it and/or
1287+ * modify it under the terms of the GNU General Public License
1288+ * as published by the Free Software Foundation; either version 2
1289+ * of the License, or (at your option) any later version.
1290+
1291+ * This program is distributed in the hope that it will be useful,
1292+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1293+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1294+ * GNU General Public License for more details.
1295+
1296+ * You should have received a copy of the GNU General Public License
1297+ * along with this program; if not, write to the Free Software
1298+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1299+ *
1300+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
1301+ * $Id: osys_psp.cpp 47541 2010-01-25 01:39:44Z lordhoto $
1302+ *
1303+ */
1304+
1305+#ifndef PSP_DISPLAY_MAN_H
1306+#define PSP_DISPLAY_MAN_H
1307+
1308+/**
1309+ * Class used only by DisplayManager to start/stop GU rendering
1310+ */
1311+class MasterGuRenderer {
1312+public:
1313+ MasterGuRenderer() : _lastRenderTime(0) {}
1314+ const char *getObjectName() { return "MasterGuRenderer"; }
1315+ void guInit();
1316+ void guPreRender();
1317+ void guPostRender();
1318+ void guShutDown();
1319+private:
1320+ static uint32 _displayList[];
1321+ uint32 _lastRenderTime; // For measuring rendering
1322+ void guProgramDisplayBufferSizes();
1323+};
1324+
1325+class Screen;
1326+class Overlay;
1327+class Cursor;
1328+class PSPKeyboard;
1329+
1330+/**
1331+ * Class that manages all display clients
1332+ */
1333+class DisplayManager {
1334+public:
1335+ enum GraphicsModeID { ///> Possible output formats onscreen
1336+ CENTERED_320X200,
1337+ CENTERED_435X272,
1338+ STRETCHED_480X272,
1339+ CENTERED_362X272
1340+ };
1341+ DisplayManager() : _screen(0), _cursor(0), _overlay(0), _keyboard(0), _lastUpdateTime(0), _graphicsMode(0) {}
1342+ ~DisplayManager();
1343+
1344+ const char *getObjectName() { return "DisplayManager"; }
1345+
1346+ void init();
1347+ void renderAll();
1348+ bool setGraphicsMode(int mode);
1349+ bool setGraphicsMode(const char *name);
1350+ int getGraphicsMode() const { return _graphicsMode; }
1351+ uint32 getDefaultGraphicsMode() const { return STRETCHED_480X272; }
1352+ const OSystem::GraphicsMode* getSupportedGraphicsModes() const { return _supportedModes; }
1353+
1354+ // Setters
1355+ void setScreen(Screen *screen) { _screen = screen; }
1356+ void setCursor(Cursor *cursor) { _cursor = cursor; }
1357+ void setOverlay(Overlay *overlay) { _overlay = overlay; }
1358+ void setKeyboard(PSPKeyboard *keyboard) { _keyboard = keyboard; }
1359+ void setSizeAndPixelFormat(uint width, uint height, const Graphics::PixelFormat *format);
1360+
1361+ // Getters
1362+ float getScaleX() { return _displayParams.scaleX; }
1363+ float getScaleY() { return _displayParams.scaleY; }
1364+ uint32 getOutputWidth() { return _displayParams.screenOutput.width; }
1365+ uint32 getOutputHeight() { return _displayParams.screenOutput.height; }
1366+ uint32 getOutputBitsPerPixel() { return _displayParams.outputBitsPerPixel; }
1367+ Common::List<Graphics::PixelFormat> getSupportedPixelFormats();
1368+
1369+private:
1370+ struct GlobalDisplayParams {
1371+ Dimensions screenOutput;
1372+ Dimensions screenSource;
1373+ float scaleX;
1374+ float scaleY;
1375+ uint32 outputBitsPerPixel; // How many bits end up on-screen
1376+ GlobalDisplayParams() : scaleX(0.0f), scaleY(0.0f), outputBitsPerPixel(0) {}
1377+ };
1378+
1379+ // Pointers to DisplayClients
1380+ Screen *_screen;
1381+ Cursor *_cursor;
1382+ Overlay *_overlay;
1383+ PSPKeyboard *_keyboard;
1384+
1385+ MasterGuRenderer _masterGuRenderer;
1386+ uint32 _lastUpdateTime; // For limiting FPS
1387+ int _graphicsMode;
1388+ GlobalDisplayParams _displayParams;
1389+ static const OSystem::GraphicsMode _supportedModes[];
1390+
1391+ void calculateScaleParams(); // calculates scaling factor
1392+ bool isTimeToUpdate(); // should we update the screen now
1393+};
1394+
1395+
1396+#endif /* PSP_DISPLAY_MAN_H */
1397\ No newline at end of file
1398Index: backends/platform/psp/psp_main.cpp
1399===================================================================
1400--- backends/platform/psp/psp_main.cpp (revision 48355)
1401+++ backends/platform/psp/psp_main.cpp (working copy)
1402@@ -26,8 +26,10 @@
1403 #define USERSPACE_ONLY //don't use kernel mode features
1404
1405 #ifndef USERSPACE_ONLY
1406-#include <pspkernel.h>
1407-#include <pspdebug.h>
1408+ #include <pspkernel.h>
1409+ #include <pspdebug.h>
1410+#else
1411+ #include <pspuser.h>
1412 #endif
1413
1414 #include <psppower.h>
1415@@ -118,10 +120,10 @@
1416 cbid = sceKernelCreateCallback("Power Callback", (SceKernelCallbackFunction)power_callback, 0);
1417 if (cbid >= 0) {
1418 if (scePowerRegisterCallback(-1, cbid) < 0) {
1419- PSPDebugTrace("SetupCallbacks(): Couldn't register callback for power_callback\n");
1420+ PSP_ERROR_STATIC("Couldn't register callback for power_callback\n");
1421 }
1422 } else {
1423- PSPDebugTrace("SetupCallbacks(): Couldn't create a callback for power_callback\n");
1424+ PSP_ERROR_STATIC("Couldn't create a callback for power_callback\n");
1425 }
1426
1427 sceKernelSleepThreadCB();
1428Index: backends/platform/psp/memory.cpp
1429===================================================================
1430--- backends/platform/psp/memory.cpp (revision 0)
1431+++ backends/platform/psp/memory.cpp (revision 0)
1432@@ -0,0 +1,223 @@
1433+/* ScummVM - Graphic Adventure Engine
1434+ *
1435+ * ScummVM is the legal property of its developers, whose names
1436+ * are too numerous to list here. Please refer to the COPYRIGHT
1437+ * file distributed with this source distribution.
1438+ *
1439+ * This program is free software; you can redistribute it and/or
1440+ * modify it under the terms of the GNU General Public License
1441+ * as published by the Free Software Foundation; either version 2
1442+ * of the License, or (at your option) any later version.
1443+
1444+ * This program is distributed in the hope that it will be useful,
1445+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1446+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1447+ * GNU General Public License for more details.
1448+
1449+ * You should have received a copy of the GNU General Public License
1450+ * along with this program; if not, write to the Free Software
1451+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1452+ *
1453+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
1454+ * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
1455+ *
1456+ */
1457+
1458+#include "common/scummsys.h"
1459+#include "common/singleton.h"
1460+#include "common/list.h"
1461+#include "backends/platform/psp/psppixelformat.h"
1462+#include "backends/platform/psp/memory.h"
1463+
1464+// Class Copier --------------------------------------------------------------------------
1465+//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */
1466+//#define __PSP_DEBUG_PRINT__
1467+
1468+#include "backends/platform/psp/trace.h"
1469+
1470+void Copier::copy(byte *dst, const byte *src, uint32 bytes, PSPPixelFormat *format /* = NULL */) {
1471+ DEBUG_ENTER_FUNC_STATIC();
1472+
1473+ uint32 prefixDst = (((uint32)dst) & 0x3);
1474+ prefixDst = prefixDst ? 4 - prefixDst : 0; // prefix only if we have address % 4 != 0
1475+ uint32 prefixSrc = (((uint32)src) & 0x3);
1476+ prefixSrc = prefixSrc ? 4 - prefixSrc : 0; // prefix only if we have address % 4 != 0
1477+ uint32 *dst32, *src32;
1478+ bool swapRB = format ? format->swapRB : false; // take swap value from pixelformat if it's given
1479+#ifdef __PSP_DEBUG_PRINT__
1480+ uint32 debugBytes = bytes;
1481+ const byte *debugDst = dst, *debugSrc = src;
1482+#endif
1483+
1484+ //PSP_DEBUG_PRINT("dst[%p], src[%p], bytes[%d], swap[%s], prefixDst[%u], prefixSrc[%u]\n", dst, src, bytes, swapRB ? "true" : "false", prefixDst, prefixSrc);
1485+
1486+ if (prefixDst || prefixSrc) { // we're not aligned to word boundaries
1487+ 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
1488+ PSP_DEBUG_PRINT("misaligned copy of %u bytes from %p to %p\n", bytes, src, dst);
1489+ if ((prefixDst & 1) || (prefixSrc & 1))
1490+ copy8(dst, src, bytes); // no swap is possible on 8 bit
1491+ else
1492+ copy16((uint16 *)dst, (uint16 *)src, bytes, format);
1493+
1494+ DEBUG_EXIT_FUNC_STATIC();
1495+ return;
1496+ }
1497+
1498+ // Do the prefix: the part to get us aligned
1499+ if (prefixDst & 1) { // byte
1500+ copy8(dst, src, prefixDst); // no swap available
1501+ } else { // short
1502+ copy16((uint16 *)dst, (uint16 *)src, prefixDst, format);
1503+ }
1504+ if (bytes > prefixDst) // check that we can afford to subtract from bytes
1505+ bytes -= prefixDst;
1506+ else {
1507+ DEBUG_EXIT_FUNC_STATIC();
1508+ return;
1509+ }
1510+ dst32 = (uint32 *)(dst + prefixDst);
1511+ src32 = (uint32 *)(src + prefixSrc);
1512+ } else { // We're aligned to word boundaries
1513+ dst32 = (uint32 *)dst;
1514+ src32 = (uint32 *)src;
1515+ }
1516+
1517+ uint32 words = bytes >> 2;
1518+ uint32 remainingBytes = bytes & 0x3;
1519+
1520+ if (swapRB) { // need to swap
1521+ for (; words > 0; words--) {
1522+ *dst32 = format->swapRedBlue32(*src32);
1523+ dst32++;
1524+ src32++;
1525+ }
1526+ } else { // no swapping
1527+ for (; words > 0; words--) {
1528+ *dst32 = *src32;
1529+ dst32++;
1530+ src32++;
1531+ }
1532+ }
1533+
1534+ // Do any remaining bytes
1535+ if (remainingBytes) {
1536+ if (remainingBytes & 1) // we have bytes left
1537+ copy8((byte *)dst32, (byte *)src32, remainingBytes);
1538+ else // 16bits left
1539+ copy16((uint16*)dst32, (uint16 *)src32, remainingBytes, format);
1540+ }
1541+
1542+ // debug
1543+#ifdef __PSP_DEBUG_PRINT__
1544+ bool mismatch = false;
1545+
1546+ for (uint32 i=0; i<debugBytes; i++) {
1547+ if (debugDst[i] != debugSrc[i]) {
1548+ if (mismatch == false) {
1549+ PSP_DEBUG_PRINT_SAMELN("mismatch in copy:\n");
1550+ PSP_DEBUG_PRINT("dst[%p], src[%p], bytes[%u], swap[%s], prefixDst[%u], prefixSrc[%u]\n", debugDst, debugSrc, debugBytes, swapRB ? "true" : "false", prefixDst, prefixSrc);
1551+ mismatch = true;
1552+ }
1553+ PSP_DEBUG_PRINT_SAMELN("%x!=%x ", debugSrc[i], debugDst[i]);
1554+ }
1555+ }
1556+ if (mismatch)
1557+ PSP_DEBUG_PRINT("\n");
1558+#endif
1559+
1560+ DEBUG_EXIT_FUNC_STATIC();
1561+}
1562+
1563+inline void Copier::copy8(byte *dst, const byte *src, uint32 bytes) {
1564+ for (; bytes > 0; bytes--) {
1565+ *dst = *src;
1566+ dst++;
1567+ src++;
1568+ }
1569+}
1570+
1571+inline void Copier::copy16(uint16 *dst, const uint16 *src, uint32 bytes, PSPPixelFormat *format /* = NULL */) {
1572+ uint32 shorts = bytes >> 1;
1573+ bool swapRB = format ? format->swapRB : false;
1574+
1575+ if (swapRB) {
1576+ for (; shorts > 0 ; shorts--) {
1577+ *dst = format->swapRedBlue16(*src);
1578+ dst++;
1579+ src++;
1580+ }
1581+ } else {
1582+ for (; shorts > 0 ; shorts--) {
1583+ *dst = *src;
1584+ dst++;
1585+ src++;
1586+ }
1587+ }
1588+}
1589+
1590+
1591+// Class VramAllocator -----------------------------------
1592+
1593+DECLARE_SINGLETON(VramAllocator)
1594+
1595+//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */
1596+//#define __PSP_DEBUG_PRINT__
1597+
1598+#include "backends/platform/psp/trace.h"
1599+
1600+
1601+void *VramAllocator::allocate(int32 size, bool smallAllocation /* = false */) {
1602+ DEBUG_ENTER_FUNC();
1603+ assert (size > 0);
1604+
1605+ byte *lastAddress = smallAllocation ? (byte *)VRAM_SMALL_ADDRESS : (byte *)VRAM_START_ADDRESS;
1606+ Common::List<Allocation>::iterator i;
1607+
1608+ // Find a block that fits, starting from the beginning
1609+ for (i = _allocList.begin(); i != _allocList.end(); ++i) {
1610+ byte *currAddress = (*i).address;
1611+
1612+ if (currAddress - lastAddress >= size) // We found a match
1613+ break;
1614+
1615+ if ((*i).getEnd() > lastAddress)
1616+ lastAddress = (byte *)(*i).getEnd();
1617+ }
1618+
1619+ if (lastAddress + size > (byte *)VRAM_END_ADDRESS) {
1620+ PSP_DEBUG_PRINT("No space for allocation of %d bytes. %d bytes already allocated.\n",
1621+ size, _bytesAllocated);
1622+ return NULL;
1623+ }
1624+
1625+ _allocList.insert(i, Allocation(lastAddress, size));
1626+ _bytesAllocated += size;
1627+
1628+ PSP_DEBUG_PRINT("Allocated in VRAM, size %u at %p.\n", size, lastAddress);
1629+ PSP_DEBUG_PRINT("Total allocated %u, remaining %u.\n", _bytesAllocated, (2 * 1024 * 1024) - _bytesAllocated);
1630+
1631+ DEBUG_EXIT_FUNC();
1632+ return lastAddress;
1633+}
1634+
1635+// Deallocate a block from VRAM
1636+void VramAllocator::deallocate(void *address) {
1637+ DEBUG_ENTER_FUNC();
1638+ address = (byte *)CACHED(address); // Make sure all addresses are the same
1639+
1640+ Common::List<Allocation>::iterator i;
1641+
1642+ // Find the Allocator to deallocate
1643+ for (i = _allocList.begin(); i != _allocList.end(); ++i) {
1644+ if ((*i).address == address) {
1645+ _bytesAllocated -= (*i).size;
1646+ _allocList.erase(i);
1647+ PSP_DEBUG_PRINT("Deallocated address[%p], size[%u]\n", (*i).address, (*i).size);
1648+ DEBUG_EXIT_FUNC();
1649+ return;
1650+ }
1651+ }
1652+
1653+ PSP_DEBUG_PRINT("Address[%p] not allocated.\n", address);
1654+ DEBUG_EXIT_FUNC();
1655+}
1656Index: backends/platform/psp/module.mk
1657===================================================================
1658--- backends/platform/psp/module.mk (revision 48355)
1659+++ backends/platform/psp/module.mk (working copy)
1660@@ -1,9 +1,15 @@
1661 MODULE := backends/platform/psp
1662
1663-MODULE_OBJS := \
1664- powerman.o \
1665+MODULE_OBJS := powerman.o \
1666 psp_main.o \
1667 osys_psp.o \
1668+ psppixelformat.o \
1669+ memory.o \
1670+ display_manager.o \
1671+ display_client.o \
1672+ default_display_client.o \
1673+ input.o \
1674+ cursor.o \
1675 trace.o \
1676 psploader.o \
1677 pspkeyboard.o
1678Index: backends/platform/psp/default_display_client.h
1679===================================================================
1680--- backends/platform/psp/default_display_client.h (revision 0)
1681+++ backends/platform/psp/default_display_client.h (revision 0)
1682@@ -0,0 +1,111 @@
1683+/* ScummVM - Graphic Adventure Engine
1684+ *
1685+ * ScummVM is the legal property of its developers, whose names
1686+ * are too numerous to list here. Please refer to the COPYRIGHT
1687+ * file distributed with this source distribution.
1688+ *
1689+ * This program is free software; you can redistribute it and/or
1690+ * modify it under the terms of the GNU General Public License
1691+ * as published by the Free Software Foundation; either version 2
1692+ * of the License, or (at your option) any later version.
1693+
1694+ * This program is distributed in the hope that it will be useful,
1695+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1696+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1697+ * GNU General Public License for more details.
1698+
1699+ * You should have received a copy of the GNU General Public License
1700+ * along with this program; if not, write to the Free Software
1701+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1702+ *
1703+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/trace.h $
1704+ * $Id: trace.h 44276 2009-09-23 16:11:23Z joostp $
1705+ *
1706+ */
1707+
1708+#ifndef PSP_DEF_DISPLAY_CLIENT_H
1709+#define PSP_DEF_DISPLAY_CLIENT_H
1710+
1711+/**
1712+ * Default display client that is useful for most purposes.
1713+ */
1714+class DefaultDisplayClient : public DisplayClient {
1715+public:
1716+ DefaultDisplayClient() : _visible(false), _dirty(true) {}
1717+ const char *getObjectName() { return "DefaultDisplayClient"; }
1718+
1719+ bool isVisible() { return _visible; }
1720+ void setVisible(bool v) { _visible = v; setDirty(); }
1721+ Buffer &buffer() { return _buffer; }
1722+ Palette &palette() { return _palette; }
1723+ void init();
1724+ bool allocate(bool bufferInVram = false, bool paletteInVram = false);
1725+ void deallocate();
1726+ void clearBuffer();
1727+ void clearPalette();
1728+ void render() { _renderer.render(); }
1729+ uint32 getWidth() { return _buffer.getSourceWidth(); }
1730+ uint32 getHeight() { return _buffer.getSourceHeight(); }
1731+ void setPartialPalette(const byte *colors, uint start, uint num) { setDirty(); return _palette.setPartial(colors, start, num); }
1732+ void getPartialPalette(byte *colors, uint start, uint num) {
1733+ return _palette.getPartial(colors, start, num);
1734+ }
1735+ void copyFromRect(const byte *buf, int pitch, int destX, int destY, int recWidth, int recHeight);
1736+ void copyToArray(byte *dst, int pitch);
1737+ void setDirty() { _dirty = true; }
1738+ void setClean() { _dirty = false; }
1739+ bool isDirty() { return _dirty; }
1740+
1741+protected:
1742+ Buffer _buffer;
1743+ Palette _palette;
1744+ GuRenderer _renderer;
1745+ bool _visible;
1746+ bool _dirty;
1747+};
1748+
1749+/**
1750+ * Screen overlay class.
1751+ */
1752+class Overlay : public DefaultDisplayClient {
1753+public:
1754+ Overlay() {}
1755+ ~Overlay() { }
1756+
1757+ const char *getObjectName() { return "Overlay"; }
1758+ void init();
1759+ bool allocate();
1760+ void setBytesPerPixel(uint32 size);
1761+ void setSize(uint32 width, uint32 height);
1762+ void copyToArray(OverlayColor *buf, int pitch);
1763+ void copyFromRect(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
1764+};
1765+
1766+/**
1767+ * Screen class.
1768+ */
1769+class Screen : public DefaultDisplayClient {
1770+public:
1771+ Screen() : _shakePos(0) {
1772+ memset(&_pixelFormat, 0, sizeof(_pixelFormat));
1773+ memset(&_frameBuffer, 0, sizeof(_frameBuffer));
1774+ }
1775+ ~Screen() {}
1776+ const char *getObjectName() { return "Screen"; }
1777+
1778+ void init();
1779+ bool allocate();
1780+ void setShakePos(int pos);
1781+ void setScummvmPixelFormat(const Graphics::PixelFormat *format);
1782+ const Graphics::PixelFormat &getScummvmPixelFormat() const { return _pixelFormat; }
1783+ Graphics::Surface *lockAndGetForEditing();
1784+ void unlock() { setDirty(); } // set dirty here because of changes
1785+ void setSize(uint32 width, uint32 height);
1786+
1787+private:
1788+ uint32 _shakePos;
1789+ Graphics::PixelFormat _pixelFormat;
1790+ Graphics::Surface _frameBuffer;
1791+};
1792+
1793+#endif /* PSP_DEF_DISPLAY_CLIENT_H */
1794\ No newline at end of file
1795Index: backends/platform/psp/cursor.cpp
1796===================================================================
1797--- backends/platform/psp/cursor.cpp (revision 0)
1798+++ backends/platform/psp/cursor.cpp (revision 0)
1799@@ -0,0 +1,363 @@
1800+/* ScummVM - Graphic Adventure Engine
1801+ *
1802+ * ScummVM is the legal property of its developers, whose names
1803+ * are too numerous to list here. Please refer to the COPYRIGHT
1804+ * file distributed with this source distribution.
1805+ *
1806+ * This program is free software; you can redistribute it and/or
1807+ * modify it under the terms of the GNU General Public License
1808+ * as published by the Free Software Foundation; either version 2
1809+ * of the License, or (at your option) any later version.
1810+
1811+ * This program is distributed in the hope that it will be useful,
1812+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1813+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1814+ * GNU General Public License for more details.
1815+
1816+ * You should have received a copy of the GNU General Public License
1817+ * along with this program; if not, write to the Free Software
1818+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1819+ *
1820+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.h $
1821+ * $Id: osys_psp.h 46120 2009-11-24 10:33:30Z Bluddy $
1822+ *
1823+ */
1824+
1825+#include "common/scummsys.h"
1826+#include "backends/platform/psp/display_client.h"
1827+#include "backends/platform/psp/default_display_client.h"
1828+#include "backends/platform/psp/cursor.h"
1829+
1830+//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */
1831+//#define __PSP_DEBUG_PRINT__
1832+
1833+#include "backends/platform/psp/trace.h"
1834+
1835+void Cursor::init() {
1836+ DEBUG_ENTER_FUNC();
1837+
1838+ _renderer.setBuffer(&_buffer); // We do this explicitly
1839+ _renderer.setPalette(&_screenPalette); // because we want to choose screenpalette by default
1840+ _renderer.setUseGlobalScaler(true);
1841+ setRendererModePalettized(true); // Assume we start in 8bit mode
1842+
1843+ // Default modes
1844+ _palette.setPixelFormats(PSPPixelFormat::Type_5551, PSPPixelFormat::Type_Palette_8bit); // default
1845+ _screenPalette.setPixelFormats(PSPPixelFormat::Type_5551, PSPPixelFormat::Type_Palette_8bit);
1846+ _buffer.setPixelFormat(PSPPixelFormat::Type_5551);
1847+
1848+ DEBUG_EXIT_FUNC();
1849+}
1850+
1851+void Cursor::deallocate() {
1852+ DEBUG_ENTER_FUNC();
1853+
1854+ _buffer.deallocate();
1855+ _palette.deallocate();
1856+ _screenPalette.deallocate();
1857+
1858+ DEBUG_EXIT_FUNC();
1859+}
1860+
1861+void Cursor::setCursorPalette(const byte *colors, uint start, uint num) {
1862+ DEBUG_ENTER_FUNC();
1863+
1864+ if (!_palette.isAllocated()) {
1865+ _palette.allocate();
1866+ }
1867+
1868+ // Workaround: This is wrong, but we seem to not be getting setScreenPalette
1869+ if (!_screenPalette.isAllocated()) {
1870+ _screenPalette.allocate();
1871+ }
1872+
1873+ _palette.setPartial(colors, start, num);
1874+ setDirty();
1875+
1876+ DEBUG_EXIT_FUNC();
1877+}
1878+
1879+void Cursor::setScreenPalette(const byte *colors, uint start, uint num) {
1880+ DEBUG_ENTER_FUNC();
1881+
1882+ if (!_screenPalette.isAllocated()) {
1883+ _screenPalette.allocate();
1884+ }
1885+
1886+ _screenPalette.setPartial(colors, start, num);
1887+ setDirty();
1888+
1889+ DEBUG_EXIT_FUNC();
1890+}
1891+
1892+void Cursor::setKeyColor(uint32 color) {
1893+ DEBUG_ENTER_FUNC();
1894+ PSP_DEBUG_PRINT("new color[%u], old color[%u]\n", color, _keyColor);
1895+
1896+ _keyColor = color;
1897+
1898+ DEBUG_EXIT_FUNC();
1899+}
1900+
1901+void Cursor::clearKeyColor() {
1902+ DEBUG_ENTER_FUNC();
1903+ PSP_DEBUG_PRINT("keyColor[%d]\n", _keyColor);
1904+
1905+ // We need 2 mechanisms: one for palettized and one for 16 bit
1906+ if (_buffer.hasPalette()) {
1907+ if (_screenPalette.isAllocated())
1908+ _screenPalette.clearColor(_keyColor); // set keycolor to 0
1909+ if (_palette.isAllocated())
1910+ _palette.clearColor(_keyColor); // Do we need both?
1911+ } else { // 16bit
1912+ _renderer.setKeyColor(_keyColor);
1913+ }
1914+ setDirty();
1915+
1916+ DEBUG_EXIT_FUNC();
1917+}
1918+
1919+void Cursor::enableCursorPalette(bool enable) {
1920+ DEBUG_ENTER_FUNC();
1921+ PSP_DEBUG_PRINT("enable[%s]\n", enable ? "true" : "false");
1922+
1923+ _useCursorPalette = enable;
1924+ if (enable)
1925+ _renderer.setPalette(&_palette); // very important that we do this switch
1926+ else
1927+ _renderer.setPalette(&_screenPalette);
1928+
1929+ setDirty();
1930+ DEBUG_EXIT_FUNC();
1931+}
1932+
1933+inline void Cursor::setSize(uint32 width, uint32 height) {
1934+ DEBUG_ENTER_FUNC();
1935+ PSP_DEBUG_PRINT("width[%u], height[%u]\n", width, height);
1936+
1937+ _buffer.setSize(width, height, Buffer::kSizeByTextureSize); // we'll use texture size for mouse
1938+ _renderer.setDrawWholeBuffer(); // We need to let the renderer know how much to draw
1939+
1940+ DEBUG_EXIT_FUNC();
1941+}
1942+
1943+void Cursor::copyFromArray(const byte *array) {
1944+ DEBUG_ENTER_FUNC();
1945+
1946+ if (!_buffer.isAllocated()) {
1947+ _buffer.allocate();
1948+ }
1949+
1950+ _buffer.copyFromArray(array, _buffer.getSourceWidthInBytes()); // pitch is source width
1951+ setDirty();
1952+
1953+ // debug
1954+ //PSP_DEBUG_DO(_buffer.print(0xF));
1955+
1956+ DEBUG_EXIT_FUNC();
1957+
1958+}
1959+
1960+void Cursor::setHotspot(int32 x, int32 y) {
1961+ DEBUG_ENTER_FUNC();
1962+
1963+ _hotspotX = x;
1964+ _hotspotY = y;
1965+ updateRendererOffset(); // Important
1966+
1967+ PSP_DEBUG_PRINT("hotspotX[%d], hotspotY[%d]\n", x, y);
1968+ DEBUG_EXIT_FUNC();
1969+}
1970+
1971+// Returns true if change in x or y
1972+bool Cursor::increaseXY(int32 incX, int32 incY) {
1973+ DEBUG_ENTER_FUNC();
1974+
1975+ int32 oldX = _x, oldY = _y;
1976+
1977+ // adjust for differences in X and Y
1978+ adjustXYForScreenSize(incX, incY);
1979+
1980+ _x += incX;
1981+ _y += incY;
1982+
1983+ // Clamp mouse
1984+ if (_x < 0)
1985+ _x = 0;
1986+ if (_y < 0)
1987+ _y = 0;
1988+ if (_x >= (int)_mouseLimitWidth)
1989+ _x = (int)_mouseLimitWidth - 1;
1990+ if (_y >= (int)_mouseLimitHeight)
1991+ _y = (int)_mouseLimitHeight - 1;
1992+
1993+ PSP_DEBUG_PRINT("X[%d], Y[%d]\n", _x, _y);
1994+
1995+ if (oldX != _x || oldY != _y) {
1996+ updateRendererOffset();
1997+ setDirty();
1998+ DEBUG_EXIT_FUNC();
1999+ return true;
2000+ }
2001+
2002+ DEBUG_EXIT_FUNC();
2003+ return false;
2004+}
2005+
2006+// Set limits on the movement of the cursor ie. screen size
2007+void Cursor::setLimits(uint32 width, uint32 height) {
2008+ #define PSP_SCREEN_WIDTH 480
2009+ #define PSP_SCREEN_HEIGHT 272
2010+ DEBUG_ENTER_FUNC();
2011+
2012+ PSP_DEBUG_PRINT("width[%u], height[%u]\n", width, height);
2013+ _mouseLimitWidth = width;
2014+ _mouseLimitHeight = height;
2015+
2016+ DEBUG_EXIT_FUNC();
2017+}
2018+
2019+// Adjust X,Y movement for the screen size to keep it consistent
2020+INLINE void Cursor::adjustXYForScreenSize(int32 &x, int32 &y) {
2021+ DEBUG_ENTER_FUNC();
2022+ // We have our speed calibrated for the y axis at 480x272. The idea is to adjust this for other
2023+ // resolutions and for x, which is wider.
2024+ int32 newX = x, newY = y;
2025+
2026+ // adjust width movement to match height (usually around 1.5)
2027+ if (_mouseLimitWidth >= _mouseLimitHeight + (_mouseLimitHeight >> 1))
2028+ newX = newX + (newX >> 1);
2029+
2030+ if (_mouseLimitWidth >= 600) { // multiply by 2
2031+ newX <<= 2;
2032+ newY <<= 2;
2033+ } else if (_mouseLimitWidth >= 480) { // multiply by 1.5
2034+ newX = newX + (newX >> 1);
2035+ newY = newY + (newY >> 1);
2036+ }
2037+
2038+ // Divide all movements by 8
2039+ newX >>= 3;
2040+ newY >>= 3;
2041+
2042+ // Make sure we didn't destroy minimum movement
2043+ if (!((x && !newX) || (y && !newY))) {
2044+ x = newX;
2045+ y = newY;
2046+ }
2047+
2048+ DEBUG_EXIT_FUNC();
2049+}
2050+
2051+// This is only called when we have a new screen
2052+void Cursor::setScreenPaletteScummvmPixelFormat(const Graphics::PixelFormat *format) {
2053+ DEBUG_ENTER_FUNC();
2054+
2055+ uint32 oldPaletteSize = 0;
2056+ if (_screenPalette.isAllocated())
2057+ oldPaletteSize = _screenPalette.getSizeInBytes();
2058+
2059+ PSPPixelFormat::Type bufferType = PSPPixelFormat::Type_Unknown;
2060+ PSPPixelFormat::Type paletteType = PSPPixelFormat::Type_Unknown;
2061+ bool swapRedBlue = false;
2062+
2063+ // Convert Scummvm Pixel Format to PSPPixelFormat
2064+ PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType, swapRedBlue);
2065+
2066+ if (paletteType == PSPPixelFormat::Type_None) {
2067+ //_screenPalette.deallocate(); // leave palette for default CLUT8
2068+ setRendererModePalettized(false); // use 16-bit mechanism
2069+ } else { // We have a palette
2070+ _screenPalette.setPixelFormats(paletteType, bufferType);
2071+ setRendererModePalettized(true); // use palettized mechanism
2072+ }
2073+
2074+ if (paletteType == PSPPixelFormat::Type_None) {
2075+ setRendererModePalettized(false); // use 16-bit mechanism
2076+ } else { // we have a palette
2077+ _palette.setPixelFormats(paletteType, bufferType);
2078+ setRendererModePalettized(true); // use palettized mechanism
2079+ }
2080+
2081+ DEBUG_EXIT_FUNC();
2082+}
2083+
2084+// This is called many many times
2085+void Cursor::setSizeAndScummvmPixelFormat(uint32 width, uint32 height, const Graphics::PixelFormat *format) {
2086+ DEBUG_ENTER_FUNC();
2087+
2088+ PSP_DEBUG_PRINT("useCursorPalette[%s]\n", _useCursorPalette ? "true" : "false");
2089+
2090+ uint32 oldBufferSize = 0, oldPaletteSize = 0;
2091+
2092+ if (_buffer.isAllocated())
2093+ oldBufferSize = _buffer.getSizeInBytes();
2094+
2095+ if (_palette.isAllocated())
2096+ oldPaletteSize = _palette.getSizeInBytes();
2097+
2098+ setSize(width, height);
2099+
2100+ PSPPixelFormat::Type bufferType = PSPPixelFormat::Type_Unknown;
2101+ PSPPixelFormat::Type paletteType = PSPPixelFormat::Type_Unknown;
2102+ bool swapRedBlue = false;
2103+
2104+ PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferType, paletteType, swapRedBlue);
2105+ PSP_DEBUG_PRINT("bufferType[%u], paletteType[%u]\n", bufferType, paletteType);
2106+
2107+ // Check if we need to set new pixel format
2108+ if (_buffer.getPixelFormat() != bufferType) {
2109+ PSP_DEBUG_PRINT("new buffer pixel format[%u] is different from [%u]. Setting it.\n", bufferType, _buffer.getPixelFormat());
2110+ _buffer.setPixelFormat(bufferType);
2111+ }
2112+
2113+ // Check if we need to reallocate
2114+ if (_buffer.getSizeInBytes() != oldBufferSize) {
2115+ _buffer.allocate();
2116+ PSP_DEBUG_PRINT("reallocating buffer. new size: width[%u], height[%u]\n", width, height);
2117+ }
2118+
2119+ PSP_DEBUG_PRINT("palette pixel format[%u]\n", paletteType);
2120+
2121+ if (paletteType == PSPPixelFormat::Type_None) {
2122+ setRendererModePalettized(false); // use palettized mechanism
2123+ } else { // We have a palette
2124+ _palette.setPixelFormats(paletteType, bufferType);
2125+ setRendererModePalettized(true); // use palettized mechanism
2126+ }
2127+
2128+ // debug
2129+ // PSP_DEBUG_DO(_palette.print(10));
2130+ // PSP_DEBUG_DO(_screenPalette.print(10));
2131+
2132+ DEBUG_EXIT_FUNC();
2133+}
2134+
2135+void Cursor::setXY(int x, int y) {
2136+ DEBUG_ENTER_FUNC();
2137+
2138+ _x = x;
2139+ _y = y;
2140+ updateRendererOffset(); // Very important to let renderer know things changed
2141+ setDirty();
2142+
2143+ DEBUG_EXIT_FUNC();
2144+}
2145+
2146+INLINE void Cursor::updateRendererOffset() {
2147+ DEBUG_ENTER_FUNC();
2148+ _renderer.setOffsetOnScreen(_x - _hotspotX, _y - _hotspotY);
2149+ DEBUG_EXIT_FUNC();
2150+}
2151+
2152+INLINE void Cursor::setRendererModePalettized(bool palettized) {
2153+ if (palettized) { // We have a palette. Use blending
2154+ _renderer.setAlphaBlending(true);
2155+ _renderer.setAlphaReverse(false);
2156+ _renderer.setColorTest(false);
2157+ } else { // 16 bits, no palette
2158+ _renderer.setAlphaBlending(true);
2159+ _renderer.setAlphaReverse(true); // We can't change all alpha values, so just reverse
2160+ _renderer.setColorTest(true); // Color test to make our key color transparent
2161+ }
2162+}
2163Index: backends/platform/psp/psppixelformat.cpp
2164===================================================================
2165--- backends/platform/psp/psppixelformat.cpp (revision 0)
2166+++ backends/platform/psp/psppixelformat.cpp (revision 0)
2167@@ -0,0 +1,168 @@
2168+/* ScummVM - Graphic Adventure Engine
2169+ *
2170+ * ScummVM is the legal property of its developers, whose names
2171+ * are too numerous to list here. Please refer to the COPYRIGHT
2172+ * file distributed with this source distribution.
2173+ *
2174+ * This program is free software; you can redistribute it and/or
2175+ * modify it under the terms of the GNU General Public License
2176+ * as published by the Free Software Foundation; either version 2
2177+ * of the License, or (at your option) any later version.
2178+
2179+ * This program is distributed in the hope that it will be useful,
2180+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2181+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2182+ * GNU General Public License for more details.
2183+
2184+ * You should have received a copy of the GNU General Public License
2185+ * along with this program; if not, write to the Free Software
2186+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
2187+ *
2188+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
2189+ * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
2190+ *
2191+ */
2192+
2193+#include "common/scummsys.h"
2194+#include "backends/platform/psp/psppixelformat.h"
2195+
2196+//#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */
2197+//#define __PSP_DEBUG_PRINT__ /* For debug printouts */
2198+
2199+#include "backends/platform/psp/trace.h"
2200+
2201+// class PSPPixelFormat --------------------------------------
2202+
2203+void PSPPixelFormat::set(Type type, bool swap /* = false */) {
2204+ DEBUG_ENTER_FUNC();
2205+ PSP_DEBUG_PRINT("type = %d\n", type);
2206+
2207+ format = type;
2208+ swapRB = swap;
2209+
2210+ switch (type) {
2211+ case Type_4444:
2212+ case Type_5551:
2213+ case Type_5650:
2214+ bitsPerPixel = 16;
2215+ break;
2216+ case Type_8888:
2217+ bitsPerPixel = 32;
2218+ break;
2219+ case Type_Palette_8bit:
2220+ bitsPerPixel = 8;
2221+ break;
2222+ case Type_Palette_4bit:
2223+ bitsPerPixel = 4;
2224+ break;
2225+ case Type_None:
2226+ bitsPerPixel = 0;
2227+ break;
2228+ default: // This is an error, but let's continue anyway
2229+ PSP_ERROR("Unhandled value of pixel type[%d]\n", type);
2230+ bitsPerPixel = 16;
2231+ break;
2232+ }
2233+
2234+ PSP_DEBUG_PRINT("bitsPerPixel[%u]\n", bitsPerPixel);
2235+ DEBUG_EXIT_FUNC();
2236+}
2237+
2238+// Convert from ScummVM general PixelFormat to our pixel format
2239+// For buffer and palette.
2240+void PSPPixelFormat::convertFromScummvmPixelFormat(const Graphics::PixelFormat *pf,
2241+ PSPPixelFormat::Type &bufferType,
2242+ PSPPixelFormat::Type &paletteType,
2243+ bool &swapRedBlue) {
2244+ swapRedBlue = false; // no red-blue swap by default
2245+ PSPPixelFormat::Type *target = 0; // which one we'll be filling
2246+
2247+ if (!pf) { // Default, pf is NULL
2248+ bufferType = Type_Palette_8bit;
2249+ paletteType = Type_5551;
2250+ } else { // We have a pf
2251+ if (pf->bytesPerPixel == 1) {
2252+ bufferType = Type_Palette_8bit;
2253+ target = &paletteType; // The type describes the palette
2254+ } else if (pf->bytesPerPixel == 2) {
2255+ paletteType = Type_None;
2256+ target = &bufferType; // The type describes the buffer
2257+ } else {
2258+ PSP_ERROR_STATIC("Unknown bpp[%u] in pixeltype. Reverting to 8bpp\n", pf->bytesPerPixel);
2259+ bufferType = Type_Palette_8bit;
2260+ target = &paletteType; // The type describes the palette
2261+ }
2262+
2263+ // Find out the exact type of the target
2264+ if (pf->rLoss == 3 && pf->bLoss == 3) {
2265+ if (pf->gLoss == 3)
2266+ *target = Type_5551;
2267+ else
2268+ *target = Type_5650;
2269+ } else if (pf->rLoss == 4 && pf->gLoss == 4 && pf->bLoss == 4) {
2270+ *target = Type_4444;
2271+ } else if (pf->gLoss == 0 && pf->gShift == 8) {
2272+ *target = Type_8888;
2273+ } else if ((pf->gLoss == 0 && pf->gShift == 0) ||
2274+ (pf->gLoss == 8 && pf->gShift == 0)) { // Default CLUT8 can have weird values
2275+ *target = Type_5551;
2276+ } else {
2277+ PSP_ERROR_STATIC("Unknown Scummvm pixel format.\n");
2278+ PSP_ERROR_STATIC("\trLoss[%d], gLoss[%d], bLoss[%d], aLoss[%d]\n\trShift[%d], gShift[%d], bShift[%d], aShift[%d]\n",
2279+ pf->rLoss, pf->gLoss, pf->bLoss, pf->aLoss,
2280+ pf->rShift, pf->gShift, pf->bShift, pf->aShift);
2281+ *target = Type_Unknown;
2282+ }
2283+
2284+ if (pf->rShift != 0) {// We allow backend swap of red and blue
2285+ swapRedBlue = true;
2286+ PSP_DEBUG_PRINT("detected red/blue swap\n");
2287+ }
2288+ }
2289+}
2290+
2291+Graphics::PixelFormat PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type type) {
2292+ Graphics::PixelFormat pf;
2293+
2294+ switch(type) {
2295+ case Type_4444:
2296+ pf.bytesPerPixel = 2;
2297+ pf.aLoss = 4; pf.rLoss = 4; pf.gLoss = 4; pf.bLoss = 4;
2298+ pf.aShift = 12; pf.rShift = 0; pf.gShift = 4; pf.bShift = 8;
2299+ break;
2300+ case Type_5551:
2301+ pf.bytesPerPixel = 2;
2302+ pf.aLoss = 7; pf.rLoss = 3; pf.gLoss = 3; pf.bLoss = 3;
2303+ pf.aShift = 15; pf.rShift = 0; pf.gShift = 5; pf.bShift = 10;
2304+ break;
2305+ case Type_5650:
2306+ pf.bytesPerPixel = 2;
2307+ pf.aLoss = 8; pf.rLoss = 3; pf.gLoss = 2; pf.bLoss = 3;
2308+ pf.aShift = 0; pf.rShift = 0; pf.gShift = 5; pf.bShift = 11;
2309+ break;
2310+ case Type_8888:
2311+ pf.bytesPerPixel = 4;
2312+ pf.aLoss = 0; pf.rLoss = 0; pf.gLoss = 0; pf.bLoss = 0;
2313+ pf.aShift = 24; pf.rShift = 0; pf.gShift = 8; pf.bShift = 16;
2314+ break;
2315+ default:
2316+ PSP_ERROR_STATIC("Unhandled PSPPixelFormat[%u]\n", type);
2317+ break;
2318+ }
2319+
2320+ return pf;
2321+}
2322+
2323+uint32 PSPPixelFormat::convertTo32BitColor(uint32 color) {
2324+ DEBUG_ENTER_FUNC();
2325+ uint32 r,g,b,a, output;
2326+
2327+ colorToRgba(color, r, g, b, a);
2328+ output = ((b << 16) | (g << 8) | (r << 0) | (a << 24));
2329+ PSP_DEBUG_PRINT_FUNC("input color[%x], output[%x]\n", color, output);
2330+
2331+ DEBUG_EXIT_FUNC();
2332+ return output;
2333+}
2334+
2335+
2336Index: backends/platform/psp/pspkeyboard.cpp
2337===================================================================
2338--- backends/platform/psp/pspkeyboard.cpp (revision 48355)
2339+++ backends/platform/psp/pspkeyboard.cpp (working copy)
2340@@ -23,17 +23,20 @@
2341 *
2342 */
2343
2344-//#define PSP_KB_SHELL /* Need a hack to properly load the keyboard from the PSP shell */
2345+#define PSP_KB_SHELL /* Need a hack to properly load the keyboard from the PSP shell */
2346+
2347 #ifdef PSP_KB_SHELL
2348-#define PSP_KB_SHELL_PATH "ms0:/psp/game4xx/scummvm-1.0.0rc1/" /* path to kbd.zip */
2349+ #define PSP_KB_SHELL_PATH "ms0:/psp/game4xx/scummvm-solid/" /* path to kbd.zip */
2350 #endif
2351-//#define PSP_KB_DEBUG
2352
2353+//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */
2354+//#define __PSP_DEBUG_PRINT__
2355+
2356+#include "backends/platform/psp/trace.h"
2357 #include <malloc.h>
2358 #include "pspkernel.h"
2359-#include <pspgu.h>
2360 #include "png.h"
2361-#include "pspkeyboard.h"
2362+#include "backends/platform/psp/pspkeyboard.h"
2363 #include "common/keyboard.h"
2364 #include "common/fs.h"
2365 #include "common/unzip.h"
2366@@ -94,314 +97,145 @@
2367 file->read(data, length);
2368 }
2369
2370+// Array with file names
2371+const char *PSPKeyboard::_guiStrings[] = {
2372+ "keys4.png", "keys_s4.png",
2373+ "keys_c4.png", "keys_s_c4.png",
2374+ "nums4.png", "nums_s4.png",
2375+ "syms4.png", "syms_s4.png"
2376+};
2377+
2378 // Constructor
2379 PSPKeyboard::PSPKeyboard() {
2380+ DEBUG_ENTER_FUNC();
2381+
2382 _init = false; // we're not initialized yet
2383 _prevButtons = 0; // Reset previous buttons
2384- _dirty = true; // keyboard needs redrawing
2385- _mode = 0; // charset selected. (0 - letters, 1 - uppercase 2 - numbers 3 - symbols)
2386+ _dirty = false; // keyboard needs redrawing
2387+ _mode = 0; // charset selected. (0: letters, 1: uppercase 2: numbers 3: symbols)
2388 _oldCursor = kCenter; // Center cursor by default
2389- _moved_x = 20; // Default starting location
2390- _moved_y = 50;
2391+ _movedX = 20; // Default starting location
2392+ _movedY = 50;
2393 _moved = false; // Keyboard wasn't moved recently
2394 _state = kInvisible; // We start invisible
2395 _lastState = kInvisible;
2396+
2397+ // Constant renderer settings
2398+ _renderer.setAlphaBlending(true);
2399+ _renderer.setColorTest(false);
2400+ _renderer.setUseGlobalScaler(false);
2401+
2402+ DEBUG_EXIT_FUNC();
2403 }
2404
2405 // Destructor
2406 PSPKeyboard::~PSPKeyboard() {
2407- if (!_init) return;
2408+ DEBUG_ENTER_FUNC();
2409+
2410+ if (!_init) {
2411+ DEBUG_EXIT_FUNC();
2412+ return;
2413+ }
2414
2415- int a;
2416- for (a = 0; a < guiStringsSize; a++) {
2417- free(_keyTextures[a].texture);
2418- free(_keyTextures[a].palette);
2419- _keyTextures[a].texture = NULL;
2420- _keyTextures[a].palette = NULL;
2421+ for (int i = 0; i < guiStringsSize; i++) {
2422+ _buffers[i].deallocate();
2423+ _palettes[i].deallocate();
2424 }
2425 _init = false;
2426+
2427+ DEBUG_EXIT_FUNC();
2428 }
2429
2430-// Array with file names
2431-const char *PSPKeyboard::_guiStrings[] = {
2432- "keys4.png", "keys_s4.png",
2433- "keys_c4.png", "keys_s_c4.png",
2434- "nums4.png", "nums_s4.png",
2435- "syms4.png", "syms_s4.png"
2436-};
2437-
2438-// Defines for working with PSP buttons
2439-#define CHANGED(x) (buttonsChanged & (x))
2440-#define PRESSED(x) ((buttonsChanged & (x)) && (pad.Buttons & (x)))
2441-#define UNPRESSED(x) ((buttonsChanged & (x)) && !(pad.Buttons & (x)))
2442-#define DOWN(x) (pad.Buttons & (x))
2443-#define UP(x) (!(pad.Buttons & (x)))
2444-#define PSP_DPAD (PSP_CTRL_DOWN|PSP_CTRL_UP|PSP_CTRL_LEFT|PSP_CTRL_RIGHT)
2445-#define PSP_4BUTTONS (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE | PSP_CTRL_TRIANGLE | PSP_CTRL_SQUARE)
2446-
2447-/*
2448- * Attempts to read a character from the controller
2449- * Uses the state machine.
2450- */
2451-bool PSPKeyboard::processInput(Common::Event &event, SceCtrlData &pad, bool &usedInput) {
2452- usedInput = false; // Assume we don't use an input
2453- bool haveEvent = false; // Whether we have an event for the event manager to process
2454- event.kbd.flags = 0;
2455- unsigned int keyDown;
2456- uint32 buttonsChanged = _prevButtons ^ pad.Buttons;
2457-
2458- if (!_init) // In case we never had init
2459- goto END;
2460-
2461- if (PRESSED(PSP_CTRL_SELECT)) {
2462+void PSPKeyboard::setVisible(bool val) {
2463+ if (val && _state == kInvisible && _init) { // Check also that were loaded correctly
2464 _lastState = _state;
2465- _state = kMove; // Check for move or visible state
2466- usedInput = true;
2467- goto END;
2468+ _state = kMove;
2469 }
2470-
2471- if (_state == kInvisible) // Return if we're invisible
2472- goto END;
2473-
2474- if (DOWN(PSP_DPAD | PSP_4BUTTONS | PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_START))
2475- usedInput = true; // for now, we neutralize all button inputs
2476-
2477- // Check for moving the keyboard onscreen
2478- if (_state == kMove) {
2479- if (UNPRESSED(PSP_CTRL_SELECT)) {
2480- _state = (_lastState == kInvisible) ? kDefault : kInvisible; // Back to previous state
2481- _dirty = true;
2482-
2483- if (_moved) { // We moved the keyboard. Keep the keyboard onscreen
2484- _state = kDefault;
2485- _moved = false; // reset moved flag
2486- }
2487- }
2488- else if (DOWN(PSP_DPAD)) {
2489- _moved = true;
2490- _dirty = true;
2491-
2492- if (DOWN(PSP_CTRL_DOWN))
2493- increaseKeyboardLocationY(5);
2494- else if (DOWN(PSP_CTRL_UP))
2495- increaseKeyboardLocationY(-5);
2496- else if (DOWN(PSP_CTRL_LEFT))
2497- increaseKeyboardLocationX(-5);
2498- else /* DOWN(PSP_CTRL_RIGHT) */
2499- increaseKeyboardLocationX(5);
2500- }
2501- usedInput = true; // We used up the input (select was held down)
2502- goto END;
2503+ else if ( !val && _state != kInvisible) {
2504+ _lastState = _state;
2505+ _state = kInvisible;
2506 }
2507-
2508-
2509- // Handle 4 buttons + 2 triggers
2510- if (_state == kDefault || _state == kCornersSelected) {
2511- unsigned int changed;
2512-
2513- if (_state == kDefault) { // Handle default state
2514- changed = CHANGED(PSP_4BUTTONS); // We only care about the 4 buttons
2515- if (PRESSED(PSP_CTRL_LTRIGGER)) { // Don't say we used up the input
2516- _state = kLTriggerDown;
2517- goto END;
2518- }
2519- else if (PRESSED(PSP_CTRL_RTRIGGER)) { // Don't say we used up the input
2520- _state = kRTriggerDown;
2521- goto END;
2522- }
2523-
2524- if (DOWN(PSP_4BUTTONS))
2525- usedInput = true; // Make sure these button presses don't get through
2526- } else { /* _state == kCornersSelected */
2527- // We care about 4 buttons + triggers (for letter selection)
2528- changed = CHANGED(PSP_4BUTTONS | PSP_CTRL_RTRIGGER | PSP_CTRL_LTRIGGER);
2529-
2530- if (DOWN(PSP_4BUTTONS | PSP_CTRL_RTRIGGER | PSP_CTRL_LTRIGGER))
2531- usedInput = true; // Make sure these button presses don't get through
2532- }
2533-
2534- if (changed) { //pressing a char select button -- both states
2535-
2536- int innerChoice;
2537-
2538- if (UNPRESSED(PSP_CTRL_TRIANGLE)) {
2539- innerChoice = 0;
2540- event.type = Common::EVENT_KEYUP; // We give priority to key_up
2541- } else if (UNPRESSED(PSP_CTRL_CIRCLE)) {
2542- innerChoice = 1;
2543- event.type = Common::EVENT_KEYUP; // We give priority to key_up
2544- } else if (UNPRESSED(PSP_CTRL_CROSS)) {
2545- innerChoice = 2;
2546- event.type = Common::EVENT_KEYUP; // We give priority to key_up
2547- } else if (UNPRESSED(PSP_CTRL_SQUARE)) {
2548- innerChoice = 3;
2549- event.type = Common::EVENT_KEYUP; // We give priority to key_up
2550- } else if (UNPRESSED(PSP_CTRL_LTRIGGER) && _state == kCornersSelected) {
2551- innerChoice = 4;
2552- event.type = Common::EVENT_KEYUP; // We give priority to key_up
2553- } else if (UNPRESSED(PSP_CTRL_RTRIGGER) && _state == kCornersSelected) {
2554- innerChoice = 5;
2555- event.type = Common::EVENT_KEYUP; // We give priority to key_up
2556- } else if (PRESSED(PSP_CTRL_TRIANGLE)) {
2557- innerChoice = 0;
2558- event.type = Common::EVENT_KEYDOWN;
2559- } else if (PRESSED(PSP_CTRL_CIRCLE)) {
2560- innerChoice = 1;
2561- event.type = Common::EVENT_KEYDOWN;
2562- } else if (PRESSED(PSP_CTRL_CROSS)) {
2563- innerChoice = 2;
2564- event.type = Common::EVENT_KEYDOWN;
2565- } else if (PRESSED(PSP_CTRL_SQUARE)) {
2566- innerChoice = 3;
2567- event.type = Common::EVENT_KEYDOWN;
2568- } else if (PRESSED(PSP_CTRL_LTRIGGER) && _state == kCornersSelected) {
2569- innerChoice = 4;
2570- event.type = Common::EVENT_KEYDOWN; // We give priority to key_up
2571- } else /* (UNPRESSED(PSP_CTRL_RTRIGGER)) && _state == kCornersSelected */ {
2572- innerChoice = 5;
2573- event.type = Common::EVENT_KEYDOWN; // We give priority to key_up
2574- }
2575-
2576- #define IS_UPPERCASE(x) ((x) >= (unsigned short)'A' && (x) <= (unsigned short)'Z')
2577- #define TO_LOWER(x) ((x) += 'a'-'A')
2578-
2579- //Now grab the value out of the array
2580- short choice = _modeChar[_mode][_oldCursor][innerChoice];
2581-
2582- event.kbd.ascii = choice <= 255 ? choice : 0;
2583-
2584- // Handle upper-case which is missing in Common::KeyCode
2585- if (IS_UPPERCASE(choice)) {
2586- event.kbd.keycode = (Common::KeyCode) TO_LOWER(choice);
2587- event.kbd.flags = Common::KBD_SHIFT;
2588- } else
2589- event.kbd.keycode = (Common::KeyCode) choice;
2590-
2591- haveEvent = (choice != Common::KEYCODE_INVALID) ? true : false; // We have an event/don't if it's invalid
2592- usedInput = true;
2593- }
2594- }
2595-
2596- // Check for movement of cursor
2597- if (_state == kDefault || _state == kCornersSelected) {
2598- // Check if a dependent button is down
2599- if (_state == kDefault)
2600- keyDown = DOWN(PSP_4BUTTONS);
2601- else /* if (_state == kCornersSelected) */
2602- keyDown = DOWN(PSP_4BUTTONS | PSP_CTRL_RTRIGGER | PSP_CTRL_LTRIGGER);
2603-
2604- Cursor cursor = _oldCursor;
2605-
2606- // Find where the cursor is pointing
2607- if (keyDown == false) { // Don't allow movement if a nub-dependent key is down
2608- cursor = kCenter;
2609- _state = kDefault;
2610-
2611- if (DOWN(PSP_DPAD)) {
2612- _state = kCornersSelected;
2613- usedInput = true; // Make sure the pressed d-pad is used up
2614-
2615- if (DOWN(PSP_CTRL_UP))
2616- cursor = kUp;
2617- else if (DOWN(PSP_CTRL_RIGHT))
2618- cursor = kRight;
2619- else if (DOWN(PSP_CTRL_DOWN))
2620- cursor = kDown;
2621- else if (DOWN(PSP_CTRL_LEFT))
2622- cursor = kLeft;
2623- }
2624- }
2625-
2626- if (cursor != _oldCursor) { //If we've moved, update dirty and return
2627- _dirty = true;
2628- _oldCursor = cursor;
2629- usedInput = true; // We 'used up' the input
2630- //goto END; // We didn't find an event
2631- }
2632- }
2633-
2634- // Deal with trigger states
2635- if (_state == kRTriggerDown) {
2636- usedInput = true;
2637-
2638- if (UNPRESSED(PSP_CTRL_RTRIGGER)) {
2639- _dirty = true;
2640-
2641- if(_mode > 1)
2642- _mode = 0;
2643- else
2644- _mode = (_mode == 0) ? 1 : 0;
2645-
2646- usedInput = true;
2647- _state = kDefault;
2648-
2649- goto END;
2650- }
2651- } else if (_state == kLTriggerDown) {
2652- usedInput = true;
2653-
2654- if (UNPRESSED(PSP_CTRL_LTRIGGER)) {
2655- _dirty = true;
2656-
2657- if(_mode < 2)
2658- _mode = 2;
2659- else
2660- _mode = (_mode == 2) ? 3 : 2;
2661-
2662- usedInput = true;
2663- _state = kDefault;
2664-
2665- goto END;
2666- }
2667- }
2668-
2669- // Handle start button: enter plus make keyboard invisible
2670- if (CHANGED(PSP_CTRL_START)) {
2671- event.kbd.ascii = '\n';
2672- event.kbd.keycode = Common::KEYCODE_RETURN;
2673- event.type = DOWN(PSP_CTRL_START) ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP;
2674- usedInput = true; // Don't let start get through
2675- haveEvent = true;
2676- if (UP(PSP_CTRL_START))
2677- _state = kInvisible; // Make us invisible if unpressed
2678- }
2679-
2680-END:
2681- _prevButtons = pad.Buttons;
2682- return haveEvent;
2683+ setDirty();
2684 }
2685
2686-
2687 /* move the position the keyboard is currently drawn at */
2688 void PSPKeyboard::moveTo(const int newX, const int newY) {
2689- _moved_x = newX;
2690- _moved_y = newY;
2691+ DEBUG_ENTER_FUNC();
2692+
2693+ _movedX = newX;
2694+ _movedY = newY;
2695+ setDirty();
2696+
2697+ DEBUG_EXIT_FUNC();
2698 }
2699
2700 /* move the position the keyboard is currently drawn at */
2701 void PSPKeyboard::increaseKeyboardLocationX(int amount) {
2702- int newX = _moved_x + amount;
2703+ DEBUG_ENTER_FUNC();
2704+
2705+ int newX = _movedX + amount;
2706
2707- if (newX > PSP_SCREEN_WIDTH - 5 || newX < 0 - 140) // clamp
2708+ if (newX > PSP_SCREEN_WIDTH - 5 || newX < 0 - 140) { // clamp
2709+ DEBUG_EXIT_FUNC();
2710 return;
2711- _moved_x = newX;
2712+ }
2713+ _movedX = newX;
2714+ setDirty();
2715+
2716+ DEBUG_EXIT_FUNC();
2717 }
2718
2719 /* move the position the keyboard is currently drawn at */
2720 void PSPKeyboard::increaseKeyboardLocationY(int amount) {
2721- int newY = _moved_y + amount;
2722+ DEBUG_ENTER_FUNC();
2723+
2724+ int newY = _movedY + amount;
2725
2726- if (newY > PSP_SCREEN_HEIGHT - 5 || newY < 0 - 140) // clamp
2727+ if (newY > PSP_SCREEN_HEIGHT - 5 || newY < 0 - 140) { // clamp
2728+ DEBUG_EXIT_FUNC();
2729 return;
2730- _moved_y = newY;
2731+ }
2732+ _movedY = newY;
2733+ setDirty();
2734+
2735+ DEBUG_EXIT_FUNC();
2736 }
2737
2738 /* draw the keyboard at the current position */
2739 void PSPKeyboard::render() {
2740- _dirty = false;
2741+ DEBUG_ENTER_FUNC();
2742+
2743+ unsigned int currentBuffer = _mode<<1;
2744+
2745+ // Draw the background letters
2746+ // Set renderer to current buffer & palette
2747+ _renderer.setBuffer(&_buffers[currentBuffer]);
2748+ _renderer.setPalette(&_palettes[currentBuffer]);
2749+ _renderer.setOffsetOnScreen(_movedX, _movedY);
2750+ _renderer.setOffsetInBuffer(0, 0);
2751+ _renderer.setDrawWholeBuffer();
2752+ _renderer.render();
2753+
2754+ // Get X and Y coordinates for the orange block
2755 int x, y;
2756+ convertCursorToXY(_oldCursor, x, y);
2757+
2758+ const int OrangeBlockSize = 64;
2759+ const int GrayBlockSize = 43;
2760+
2761+ // Draw the current Highlighted Selector (orange block)
2762+ _renderer.setBuffer(&_buffers[currentBuffer + 1]);
2763+ _renderer.setPalette(&_palettes[currentBuffer + 1]);
2764+ _renderer.setOffsetOnScreen(_movedX + (x * GrayBlockSize), _movedY + (y * GrayBlockSize));
2765+ _renderer.setOffsetInBuffer(x * OrangeBlockSize, y * OrangeBlockSize);
2766+ _renderer.setDrawSize(OrangeBlockSize, OrangeBlockSize);
2767+ _renderer.render();
2768+
2769+ DEBUG_EXIT_FUNC();
2770+}
2771
2772- switch(_oldCursor) {
2773+inline void PSPKeyboard::convertCursorToXY(CursorDirections cur, int &x, int &y) {
2774+ switch(cur) {
2775 case kUp:
2776 x = 1;
2777 y = 0;
2778@@ -423,76 +257,17 @@
2779 y = 1;
2780 break;
2781 }
2782-
2783- // Draw the background letters
2784- surface_draw_offset(&_keyTextures[_mode<<1], 0, 0, 0, 0,
2785- _keyTextures[_mode<<1].texture_width,
2786- _keyTextures[_mode<<1].texture_height);
2787-
2788- // Draw the current Highlighted Selector (orange bit)
2789- surface_draw_offset(&_keyTextures[(_mode<<1) + 1],
2790- //Offset from the current draw position to render at
2791- x * 43, y * 43,
2792- //internal offset of the image
2793- x * 64, y * 64,
2794- //size to render (always the same)
2795- 64, 64);
2796 }
2797
2798-
2799-// Render the given surface at the current screen position offset by screenX, screenY
2800-// the surface will be internally offset by offsetX,offsetY. And the size of it to be drawn will be intWidth,intHeight
2801-void PSPKeyboard::surface_draw_offset(struct gu_surface* surface, int screenX, int screenY, int offsetX, int offsetY, int intWidth, int intHeight) {
2802- sceGuAlphaFunc( GU_GREATER, 0, 0xff );
2803- sceGuEnable( GU_ALPHA_TEST );
2804- sceGuTexFunc(GU_TFX_BLEND,GU_TCC_RGBA);
2805- sceGuTexEnvColor(0xFF000000);
2806- sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 );
2807- sceGuEnable(GU_BLEND);
2808- if (surface->paletteSize == 256) { // 8-bit
2809- sceGuClutMode(GU_PSM_8888, 0, 0xFF, 0);
2810- sceGuClutLoad(32, surface->palette); // upload 32*8 entries (256)
2811- sceGuTexMode(GU_PSM_T8, 0, 0, 0); // 8-bit image
2812- } else if (surface->paletteSize == 16) { // 4-bit
2813- sceGuClutMode(GU_PSM_8888, 0, 0x0F, 0);
2814- sceGuClutLoad(2, surface->palette); // upload 2*8 entries (16)
2815- sceGuTexMode(GU_PSM_T4, 0, 0, 0); // 4-bit image
2816- } else { // 32-bit
2817- sceGuTexMode(GU_PSM_8888,0,0,GU_FALSE);
2818- }
2819- sceGuTexImage(0,surface->surface_width, surface->surface_height,surface->surface_width, surface->texture);
2820- sceGuTexFunc(GU_TFX_MODULATE,GU_TCC_RGBA);
2821-
2822- Vertex* c_vertices = (Vertex*)sceGuGetMemory(2 * sizeof(Vertex));
2823-
2824- c_vertices[0].u = offsetX;
2825- c_vertices[0].v = offsetY;
2826- c_vertices[0].x = _moved_x + screenX;
2827- c_vertices[0].y = _moved_y + screenY;
2828- c_vertices[0].z = 0;
2829- c_vertices[0].color = 0xFFFFFFFF;
2830-
2831- c_vertices[1].u = offsetX + intWidth;
2832- c_vertices[1].v = offsetY + intHeight;
2833- c_vertices[1].x = _moved_x + screenX + intWidth;
2834- c_vertices[1].y = _moved_y + screenY + intHeight;
2835- c_vertices[1].z = 0;
2836- c_vertices[1].color = 0xFFFFFFFF;
2837-
2838- sceGuDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_COLOR_8888|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,0,c_vertices);
2839-
2840- sceGuDisable( GU_BLEND );
2841- sceGuDisable( GU_ALPHA_TEST );
2842-}
2843-
2844-/* load all the guibits that make up the OSK */
2845+/* load the keyboard into memory */
2846 bool PSPKeyboard::load() {
2847- unsigned char *temp_texture = NULL;
2848- uint32 *temp_palette = NULL;
2849- int a;
2850+ DEBUG_ENTER_FUNC();
2851
2852- if (_init)
2853+ if (_init) {
2854+ PSP_DEBUG_PRINT("keyboard already loaded into memory\n");
2855+ DEBUG_EXIT_FUNC();
2856 return true;
2857+ }
2858
2859 // For the shell, we must use a hack
2860 #ifdef PSP_KB_SHELL
2861@@ -500,221 +275,131 @@
2862 #else /* normal mode */
2863 Common::FSNode node("."); // Look in current directory
2864 #endif
2865-#ifdef PSP_KB_DEBUG
2866- fprintf(stderr, "path = %s\n", node.getPath().c_str());
2867-#endif
2868+ PSP_DEBUG_PRINT("path[%s]\n", node.getPath().c_str());
2869
2870 Common::Archive *fileArchive = NULL;
2871 Common::Archive *zipArchive = NULL;
2872 Common::SeekableReadStream * file = 0;
2873
2874 if (node.getChild("kbd").exists() && node.getChild("kbd").isDirectory()) {
2875-#ifdef PSP_KB_DEBUG
2876- fprintf(stderr, "found directory ./kbd\n");
2877-#endif
2878+ PSP_DEBUG_PRINT("found directory ./kbd\n");
2879 fileArchive = new Common::FSDirectory(node.getChild("kbd"));
2880 }
2881 if (node.getChild("kbd.zip").exists()) {
2882-#ifdef PSP_KB_DEBUG
2883- fprintf(stderr, "found kbd.zip\n");
2884-#endif
2885+ PSP_DEBUG_PRINT("found kbd.zip\n");
2886 zipArchive = Common::makeZipArchive(node.getChild("kbd.zip"));
2887 }
2888
2889- // Loop through different png images
2890- for (a = 0; a < guiStringsSize; a++) {
2891+ int i;
2892+
2893+ // Loop through all png images
2894+ for (i = 0; i < guiStringsSize; i++) {
2895 uint32 height = 0, width = 0, paletteSize = 0;
2896
2897-#ifdef PSP_KB_DEBUG
2898- fprintf(stderr, "load(): Opening %s.\n", _guiStrings[a]);
2899-#endif
2900+ PSP_DEBUG_PRINT("Opening %s.\n", _guiStrings[i]);
2901
2902 // Look for the file in the kbd directory
2903- if (fileArchive && fileArchive->hasFile(_guiStrings[a])) {
2904+ if (fileArchive && fileArchive->hasFile(_guiStrings[i])) {
2905+ PSP_DEBUG_PRINT("found it in kbd directory.\n");
2906
2907-#ifdef PSP_KB_DEBUG
2908- fprintf(stderr, "load(): found it in kbd directory.\n");
2909-#endif
2910-
2911- file = fileArchive->createReadStreamForMember(_guiStrings[a]);
2912+ file = fileArchive->createReadStreamForMember(_guiStrings[i]);
2913 if (!file) {
2914- fprintf(stderr, "load(): Can't open kbd/%s for keyboard. No keyboard will load.\n", _guiStrings[a]);
2915+ PSP_ERROR("Can't open kbd/%s for keyboard. No keyboard will load.\n", _guiStrings[i]);
2916 goto ERROR;
2917 }
2918 }
2919 // We didn't find it. Look for it in the zip file
2920- else if (zipArchive && zipArchive->hasFile(_guiStrings[a])) {
2921+ else if (zipArchive && zipArchive->hasFile(_guiStrings[i])) {
2922+ PSP_DEBUG_PRINT("found it in kbd.zip.\n");
2923
2924-#ifdef PSP_KB_DEBUG
2925- fprintf(stderr, "load(): found it in kbd.zip.\n");
2926-#endif
2927-
2928- file = zipArchive->createReadStreamForMember(_guiStrings[a]);
2929+ file = zipArchive->createReadStreamForMember(_guiStrings[i]);
2930 if (!file) {
2931- fprintf(stderr, "Can't open %s in kbd.zip for keyboard. No keyboard will load.\n", _guiStrings[a]);
2932+ PSP_ERROR("Can't open %s in kbd.zip for keyboard. No keyboard will load.\n", _guiStrings[i]);
2933 goto ERROR;
2934 }
2935 } else { // Couldn't find the file
2936- fprintf(stderr, "load(): Can't find %s for keyboard. No keyboard will load.\n", _guiStrings[a]);
2937+ PSP_ERROR("Can't find %s for keyboard. No keyboard will load.\n", _guiStrings[i]);
2938 goto ERROR;
2939 }
2940
2941- if (get_png_image_size(file, &width, &height, &paletteSize) == 0) { // Check image size and palette size
2942+ if (getPngImageSize(file, &width, &height, &paletteSize) == 0) { // Check image size and palette size
2943 // Allocate memory for image
2944-#ifdef PSP_KB_DEBUG
2945- fprintf(stderr, "load(): width=%d, height=%d, paletteSize=%d\n", width, height, paletteSize);
2946-#endif
2947-
2948+ PSP_DEBUG_PRINT("width[%d], height[%d], paletteSize[%d]\n", width, height, paletteSize);
2949+ _buffers[i].setSize(width, height, Buffer::kSizeByTextureSize);
2950+
2951 if (paletteSize) { // 8 or 4-bit image
2952- uint32 textureSize = 0;
2953-
2954 if (paletteSize <= 16) { // 4 bit
2955- paletteSize = 16;
2956- textureSize = (width * height)>>1;
2957+ _buffers[i].setPixelFormat(PSPPixelFormat::Type_Palette_4bit);
2958+ _palettes[i].setPixelFormats(PSPPixelFormat::Type_4444, PSPPixelFormat::Type_Palette_4bit);
2959+ paletteSize = 16;
2960 } else if (paletteSize <= 256){ // 8-bit image
2961 paletteSize = 256;
2962- textureSize = width * height;
2963+ _buffers[i].setPixelFormat(PSPPixelFormat::Type_Palette_8bit);
2964+ _palettes[i].setPixelFormats(PSPPixelFormat::Type_4444, PSPPixelFormat::Type_Palette_8bit);
2965 } else {
2966- fprintf(stderr, "Error: palette of %d too big!\n", paletteSize);
2967+ PSP_ERROR("palette of %d too big!\n", paletteSize);
2968 goto ERROR;
2969 }
2970-#ifdef PSP_KB_DEBUG
2971- fprintf(stderr, "load(): allocating %d bytes for texture and %d for palette\n", textureSize, paletteSize*4);
2972-#endif
2973- temp_texture = (u8 *)malloc(textureSize);
2974- temp_palette = (uint32 *)memalign(16, paletteSize<<2);
2975- memset(temp_palette, 0, paletteSize<<2); // Set to 0 since we might only fill some of it
2976+
2977 } else { // 32-bit image
2978- temp_texture = (unsigned char *)malloc((width * height)<<2);
2979+ _buffers[i].setPixelFormat(PSPPixelFormat::Type_8888);
2980 }
2981+
2982+ _buffers[i].allocate();
2983+ _palettes[i].allocate();
2984
2985 // Try to load the image
2986 file->seek(0); // Go back to start
2987
2988- if (load_png_image(file, temp_texture, temp_palette) != 0)
2989+ if (loadPngImage(file, _buffers[i], _palettes[i]) != 0)
2990 goto ERROR;
2991 else { // Success
2992-#ifdef PSP_KB_DEBUG
2993- fprintf(stderr, "Managed to load the image.\n");
2994-#endif
2995- // we need to store the texture in an image of width and heights of 2^n sizes
2996- _keyTextures[a].texture_width = width; // original size
2997- _keyTextures[a].texture_height = height;
2998- _keyTextures[a].surface_width = convert_pow2(width); // converted size
2999- _keyTextures[a].surface_height = convert_pow2(height);
3000- _keyTextures[a].palette = temp_palette;
3001- _keyTextures[a].paletteSize = paletteSize;
3002+ PSP_DEBUG_PRINT("Managed to load the image\n");
3003
3004- uint32 size;
3005-
3006- if (paletteSize == 16) // 4 bit
3007- size = (_keyTextures[a].surface_width * _keyTextures[a].surface_height)>>1;
3008- else if (paletteSize == 256) // 8-bit
3009- size = _keyTextures[a].surface_width * _keyTextures[a].surface_height;
3010- else // 32 bit
3011- size = (_keyTextures[a].surface_width * _keyTextures[a].surface_height)<<2;
3012-
3013-#ifdef PSP_KB_DEBUG
3014- fprintf(stderr, "load(): perm texture width=%d, height=%d, size=%d\n", _keyTextures[a].surface_width, _keyTextures[a].surface_height, size);
3015-#endif
3016- _keyTextures[a].texture = (unsigned char *)memalign(16, size); // Allocate memory
3017-
3018- block_copy(&_keyTextures[a], temp_texture); // Copy temp texture to permanent texture
3019-
3020 if (paletteSize == 16) // 4-bit
3021- flipNibbles(&_keyTextures[a]);
3022+ _buffers[i].flipNibbles();
3023
3024- free(temp_texture);
3025-
3026 delete file;
3027 }
3028 }
3029- else
3030+ else {
3031+ PSP_ERROR("couldn't obtain PNG image size\n");
3032 goto ERROR;
3033+ }
3034 } /* for loop */
3035+
3036 _init = true;
3037
3038 delete fileArchive;
3039 delete zipArchive;
3040
3041+ DEBUG_EXIT_FUNC();
3042 return true;
3043
3044 ERROR:
3045
3046- // Error .. Couldn't get png info from one of the needed files
3047- free(temp_texture);
3048 delete file;
3049 delete fileArchive;
3050 delete zipArchive;
3051
3052- for (int b = 0; b < a; b++) {
3053- free(_keyTextures[b].texture);
3054- free(_keyTextures[b].palette);
3055- _keyTextures[b].texture = NULL;
3056+ for (int j = 0; j < i; j++) {
3057+ _buffers[j].deallocate();
3058+ _palettes[j].deallocate();
3059 }
3060 _init = false;
3061+
3062+ DEBUG_EXIT_FUNC();
3063 return false;
3064 }
3065
3066-// Copy texture from regular size image to power of 2 size image
3067-//
3068-void PSPKeyboard::block_copy(gu_surface* surface, u8 *texture) {
3069- u32 stride = 0, width = 0;
3070-
3071- switch(surface->paletteSize) {
3072- case 16: // 4-bit
3073- width = surface->texture_width >> 1;
3074- stride = (surface->surface_width - surface->texture_width)>>1;
3075- break;
3076- case 256: // 8-bit
3077- width = surface->texture_width;
3078- stride = surface->surface_width - surface->texture_width;
3079- break;
3080- case 0: // 32-bit
3081- width = surface->texture_width << 2;
3082- stride = (surface->surface_width - surface->texture_width)<<2;
3083- break;
3084- default:
3085- fprintf(stderr, "Error in block_copy: bad value in paletteSize = %d\n", surface->paletteSize);
3086- return;
3087- }
3088-
3089- u8 *src = texture;
3090- u8 *dest = surface->texture;
3091-
3092- for (unsigned int y = 0; y < surface->texture_height; y++) {
3093- memcpy(dest, src, width);
3094- dest += width;
3095- src += width;
3096-
3097- // skip at the end of each line
3098- if (stride > 0) {
3099- dest += stride;
3100- }
3101- }
3102-}
3103-
3104-// Convert 4 bit images to match weird PSP format
3105-//
3106-void PSPKeyboard::flipNibbles(gu_surface* surface) {
3107- u32 *dest = (u32 *)surface->texture;
3108-
3109- for (u32 y = 0; y < surface->texture_height; y++) {
3110- for (u32 x = 0; x < (surface->surface_width >> 3); x++) {
3111- u32 val = *dest;
3112- *dest++ = ((val >> 4) & 0x0F0F0F0F) | ((val << 4) & 0xF0F0F0F0);
3113- }
3114- }
3115-
3116-}
3117-
3118-
3119 static void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg) {
3120 // ignore PNG warnings
3121 }
3122
3123 /* Get the width and height of a png image */
3124-int PSPKeyboard::get_png_image_size(Common::SeekableReadStream *file, uint32 *png_width, uint32 *png_height, u32 *paletteSize) {
3125+int PSPKeyboard::getPngImageSize(Common::SeekableReadStream *file, uint32 *png_width, uint32 *png_height, u32 *paletteSize) {
3126+ DEBUG_ENTER_FUNC();
3127+
3128 png_structp png_ptr;
3129 png_infop info_ptr;
3130 unsigned int sig_read = 0;
3131@@ -723,12 +408,14 @@
3132
3133 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
3134 if (png_ptr == NULL) {
3135+ DEBUG_EXIT_FUNC();
3136 return -1;
3137 }
3138 png_set_error_fn(png_ptr, (png_voidp) NULL, (png_error_ptr) NULL, user_warning_fn);
3139 info_ptr = png_create_info_struct(png_ptr);
3140 if (info_ptr == NULL) {
3141 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
3142+ DEBUG_EXIT_FUNC();
3143 return -1;
3144 }
3145 // Set the png lib to use our read function
3146@@ -746,22 +433,27 @@
3147
3148 *png_width = width;
3149 *png_height = height;
3150+
3151+ DEBUG_EXIT_FUNC();
3152 return 0;
3153 }
3154
3155 // Load a texture from a png image
3156 //
3157-int PSPKeyboard::load_png_image(Common::SeekableReadStream *file, unsigned char *ImageBuffer, uint32 *palette) {
3158+int PSPKeyboard::loadPngImage(Common::SeekableReadStream *file, Buffer &buffer, Palette &palette) {
3159+ DEBUG_ENTER_FUNC();
3160+
3161 png_structp png_ptr;
3162 png_infop info_ptr;
3163 unsigned int sig_read = 0;
3164 png_uint_32 width, height;
3165 int bit_depth, color_type, interlace_type;
3166- size_t x, y;
3167+ size_t y;
3168
3169 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
3170 if (png_ptr == NULL) {
3171- fprintf(stderr, "load_png_image(): Error: couldn't create read struct to load keyboard.\n");
3172+ PSP_ERROR("Couldn't create read struct to load keyboard\n");
3173+ DEBUG_EXIT_FUNC();
3174 return -1;
3175 }
3176 // Use dummy error function
3177@@ -769,11 +461,13 @@
3178
3179 info_ptr = png_create_info_struct(png_ptr);
3180 if (info_ptr == NULL) {
3181+ PSP_ERROR("Couldn't create info struct to load keyboard\n");
3182 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
3183+ DEBUG_EXIT_FUNC();
3184 return -1;
3185 }
3186
3187- // Set the png lib to use our read function
3188+ // Set the png lib to use our customized read function
3189 png_set_read_fn(png_ptr, (void *)file, pngReadStreamRead);
3190
3191 png_set_sig_bytes(png_ptr, sig_read);
3192@@ -784,71 +478,280 @@
3193 png_set_strip_16(png_ptr);
3194
3195 if (color_type == PNG_COLOR_TYPE_PALETTE) {
3196- // We copy the palette
3197- uint32 *dstPal = palette;
3198+ // Copy the palette
3199 png_colorp srcPal = info_ptr->palette;
3200 for(int i=0; i < info_ptr->num_palette; i++) {
3201 unsigned char alphaVal = (i < info_ptr->num_trans) ? info_ptr->trans[i] : 0xFF; // Load alpha if it's there
3202- *dstPal++ = GU_ARGB(alphaVal, srcPal->red, srcPal->green, srcPal->blue);
3203+ palette.setSingleColorRGBA(i, srcPal->red, srcPal->green, srcPal->blue, alphaVal);
3204 srcPal++;
3205 }
3206-
3207- unsigned char *line = (unsigned char*) malloc(info_ptr->rowbytes);
3208- if (!line) {
3209- png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
3210- return -1;
3211- }
3212-
3213- for (y = 0; y < height; y++) {
3214- png_read_row(png_ptr, line, png_bytep_NULL);
3215- memcpy(&ImageBuffer[y * info_ptr->rowbytes], line, info_ptr->rowbytes);
3216- }
3217-
3218- free(line);
3219 } else { // Not a palettized image
3220+ // Round up grayscale images
3221 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
3222 // Convert trans channel to alpha for 32 bits
3223 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
3224+ // Filler for alpha?
3225 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
3226+ }
3227
3228- u32* line = (u32*) malloc(width<<2);
3229- if (!line) {
3230- png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
3231- return -1;
3232- }
3233+ unsigned char *line = (unsigned char*) malloc(info_ptr->rowbytes);
3234+ if (!line) {
3235+ png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
3236+ PSP_ERROR("Couldn't allocate line\n");
3237+ DEBUG_EXIT_FUNC();
3238+ return -1;
3239+ }
3240
3241- u32* Image = (u32 *)ImageBuffer;
3242- for (y = 0; y < height; y++) {
3243- png_read_row(png_ptr, (u8*) line, png_bytep_NULL);
3244- for (x = 0; x < width; x++) {
3245- Image[y*width + x] = line[x];
3246- }
3247- }
3248-
3249- free(line);
3250+ for (y = 0; y < height; y++) {
3251+ png_read_row(png_ptr, line, png_bytep_NULL);
3252+ buffer.copyFromRect(line, info_ptr->rowbytes, 0, y, width, 1); // Copy into buffer
3253+ //memcpy(buffer.getPixels()[y * buffer.getWidthInBytes()], line, info_ptr->rowbytes);
3254 }
3255
3256+ free(line);
3257+
3258 png_read_end(png_ptr, info_ptr);
3259 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
3260
3261+ DEBUG_EXIT_FUNC();
3262 return 0;
3263 }
3264
3265-// Function to get the lowest power of 2 higher than our image size
3266-//
3267-uint32 PSPKeyboard::convert_pow2(uint32 size) {
3268- uint32 pow_counter = 0;
3269+// Defines for working with PSP buttons
3270+#define CHANGED(x) (_buttonsChanged & (x))
3271+#define PRESSED(x) ((_buttonsChanged & (x)) && (pad.Buttons & (x)))
3272+#define UNPRESSED(x) ((_buttonsChanged & (x)) && !(pad.Buttons & (x)))
3273+#define DOWN(x) (pad.Buttons & (x))
3274+#define UP(x) (!(pad.Buttons & (x)))
3275+#define PSP_DPAD (PSP_CTRL_DOWN|PSP_CTRL_UP|PSP_CTRL_LEFT|PSP_CTRL_RIGHT)
3276+#define PSP_4BUTTONS (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE | PSP_CTRL_TRIANGLE | PSP_CTRL_SQUARE)
3277
3278- for (; pow_counter < 32; pow_counter++) {
3279- // Find the first value which is higher
3280- if ((size >> pow_counter) == 0) {
3281- // take already good values into account
3282- if (((uint32) 1 << pow_counter) != size)
3283- return ((uint32)1 << pow_counter);
3284- else
3285- return ((uint32)1 << (pow_counter-1));
3286+/*
3287+ * Attempts to read a character from the controller
3288+ * Uses the state machine.
3289+ * returns whether we have an event
3290+ */
3291+bool PSPKeyboard::processInput(Common::Event &event, SceCtrlData &pad) {
3292+ DEBUG_ENTER_FUNC();
3293+
3294+ bool haveEvent = false; // Whether we have an event for the event manager to process
3295+ event.kbd.flags = 0;
3296+
3297+ _buttonsChanged = _prevButtons ^ pad.Buttons;
3298+
3299+ if (!_init) // In case we never had init
3300+ return false;
3301+ if (_state == kInvisible) // Return if we're invisible
3302+ return false;
3303+ if (_state != kMove && PRESSED(PSP_CTRL_SELECT)) {
3304+ _lastState = _state;
3305+ _state = kMove; // Check for move or visible state
3306+ }
3307+ else if (CHANGED(PSP_CTRL_START)) { // Handle start button: enter, make KB invisible
3308+ event.kbd.ascii = '\n';
3309+ event.kbd.keycode = Common::KEYCODE_RETURN;
3310+ event.type = DOWN(PSP_CTRL_START) ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP;
3311+ haveEvent = true;
3312+ _dirty = true;
3313+ if (UP(PSP_CTRL_START))
3314+ _state = kInvisible; // Make us invisible if unpressed
3315+ }
3316+ // Check for being in state of moving the keyboard onscreen or pressing select
3317+ else if (_state == kMove)
3318+ handleMoveState(pad);
3319+ else if (_state == kDefault)
3320+ haveEvent = handleDefaultState(event, pad);
3321+ else if (_state == kCornersSelected)
3322+ haveEvent = handleCornersSelectedState(event, pad);
3323+ else if (_state == kRTriggerDown)
3324+ handleRTriggerDownState(pad); // Deal with trigger states
3325+ else if (_state == kLTriggerDown)
3326+ handleLTriggerDownState(pad); // Deal with trigger states
3327+
3328+ _prevButtons = pad.Buttons;
3329+
3330+ DEBUG_EXIT_FUNC();
3331+ return haveEvent;
3332+}
3333+
3334+void PSPKeyboard::handleMoveState(SceCtrlData &pad) {
3335+ DEBUG_ENTER_FUNC();
3336+ if (UNPRESSED(PSP_CTRL_SELECT)) {
3337+ // Toggle between visible and invisible
3338+ _state = (_lastState == kInvisible) ? kDefault : kInvisible;
3339+ _dirty = true;
3340+
3341+ if (_moved) { // We moved the keyboard. Keep the keyboard onscreen anyway
3342+ _state = kDefault;
3343+ _moved = false; // reset moved flag
3344 }
3345+ } else if (DOWN(PSP_DPAD)) { // How we move the KB onscreen
3346+ _moved = true;
3347+ _dirty = true;
3348+
3349+ if (DOWN(PSP_CTRL_DOWN))
3350+ increaseKeyboardLocationY(5);
3351+ else if (DOWN(PSP_CTRL_UP))
3352+ increaseKeyboardLocationY(-5);
3353+ else if (DOWN(PSP_CTRL_LEFT))
3354+ increaseKeyboardLocationX(-5);
3355+ else /* DOWN(PSP_CTRL_RIGHT) */
3356+ increaseKeyboardLocationX(5);
3357 }
3358- return 0;
3359+ DEBUG_EXIT_FUNC();
3360 }
3361
3362+bool PSPKeyboard::handleDefaultState(Common::Event &event, SceCtrlData &pad) {
3363+ DEBUG_ENTER_FUNC();
3364+ bool haveEvent = false;
3365+
3366+ if (PRESSED(PSP_CTRL_LTRIGGER)) // Don't say we used up the input
3367+ _state = kLTriggerDown;
3368+ else if (PRESSED(PSP_CTRL_RTRIGGER)) // Don't say we used up the input
3369+ _state = kRTriggerDown;
3370+ else if (CHANGED(PSP_4BUTTONS)) // We only care about the 4 buttons
3371+ haveEvent = getInputChoice(event, pad);
3372+ else if (!DOWN(PSP_4BUTTONS)) // Must be up to move cursor
3373+ getCursorMovement(pad);
3374+
3375+ DEBUG_EXIT_FUNC();
3376+ return haveEvent;
3377+}
3378+
3379+bool PSPKeyboard::handleCornersSelectedState(Common::Event &event, SceCtrlData &pad) {
3380+ DEBUG_ENTER_FUNC();
3381+ // We care about 4 buttons + triggers (for letter selection)
3382+ bool haveEvent = false;
3383+
3384+ if (CHANGED(PSP_4BUTTONS | PSP_CTRL_RTRIGGER | PSP_CTRL_LTRIGGER))
3385+ haveEvent = getInputChoice(event, pad);
3386+ if (!DOWN(PSP_4BUTTONS | PSP_CTRL_RTRIGGER | PSP_CTRL_LTRIGGER)) // Must be up to move cursor
3387+ getCursorMovement(pad)
3388+
3389+ DEBUG_EXIT_FUNC();
3390+ return haveEvent;
3391+}
3392+
3393+bool PSPKeyboard::getInputChoice(Common::Event &event, SceCtrlData &pad) {
3394+ DEBUG_ENTER_FUNC();
3395+ int innerChoice;
3396+ bool haveEvent = false;
3397+
3398+ if (UNPRESSED(PSP_CTRL_TRIANGLE)) {
3399+ innerChoice = 0;
3400+ event.type = Common::EVENT_KEYUP; // We give priority to key_up
3401+ } else if (UNPRESSED(PSP_CTRL_CIRCLE)) {
3402+ innerChoice = 1;
3403+ event.type = Common::EVENT_KEYUP; // We give priority to key_up
3404+ } else if (UNPRESSED(PSP_CTRL_CROSS)) {
3405+ innerChoice = 2;
3406+ event.type = Common::EVENT_KEYUP; // We give priority to key_up
3407+ } else if (UNPRESSED(PSP_CTRL_SQUARE)) {
3408+ innerChoice = 3;
3409+ event.type = Common::EVENT_KEYUP; // We give priority to key_up
3410+ } else if (UNPRESSED(PSP_CTRL_LTRIGGER) && _state == kCornersSelected) {
3411+ innerChoice = 4;
3412+ event.type = Common::EVENT_KEYUP; // We give priority to key_up
3413+ } else if (UNPRESSED(PSP_CTRL_RTRIGGER) && _state == kCornersSelected) {
3414+ innerChoice = 5;
3415+ event.type = Common::EVENT_KEYUP; // We give priority to key_up
3416+ } else if (PRESSED(PSP_CTRL_TRIANGLE)) {
3417+ innerChoice = 0;
3418+ event.type = Common::EVENT_KEYDOWN;
3419+ } else if (PRESSED(PSP_CTRL_CIRCLE)) {
3420+ innerChoice = 1;
3421+ event.type = Common::EVENT_KEYDOWN;
3422+ } else if (PRESSED(PSP_CTRL_CROSS)) {
3423+ innerChoice = 2;
3424+ event.type = Common::EVENT_KEYDOWN;
3425+ } else if (PRESSED(PSP_CTRL_SQUARE)) {
3426+ innerChoice = 3;
3427+ event.type = Common::EVENT_KEYDOWN;
3428+ } else if (PRESSED(PSP_CTRL_LTRIGGER) && _state == kCornersSelected) {
3429+ innerChoice = 4;
3430+ event.type = Common::EVENT_KEYDOWN; // We give priority to key_up
3431+ } else /* (PRESSED(PSP_CTRL_RTRIGGER)) && _state == kCornersSelected */ {
3432+ innerChoice = 5;
3433+ event.type = Common::EVENT_KEYDOWN; // We give priority to key_up
3434+ }
3435+
3436+ #define IS_UPPERCASE(x) ((x) >= (unsigned short)'A' && (x) <= (unsigned short)'Z')
3437+ #define TO_LOWER(x) ((x) += 'a'-'A')
3438+
3439+ //Now grab the value out of the array
3440+ short choice = _modeChar[_mode][_oldCursor][innerChoice];
3441+
3442+ event.kbd.ascii = choice <= 255 ? choice : 0;
3443+
3444+ // Handle upper-case which is missing in Common::KeyCode
3445+ if (IS_UPPERCASE(choice)) {
3446+ event.kbd.keycode = (Common::KeyCode) TO_LOWER(choice);
3447+ event.kbd.flags = Common::KBD_SHIFT;
3448+ } else
3449+ event.kbd.keycode = (Common::KeyCode) choice;
3450+
3451+ haveEvent = (choice != Common::KEYCODE_INVALID) ? true : false; // We have an event/don't if it's invalid
3452+
3453+ DEBUG_EXIT_FUNC();
3454+ return haveEvent;
3455+}
3456+
3457+void PSPKeyboard::getCursorMovement(SceCtrlData &pad) {
3458+ DEBUG_ENTER_FUNC();
3459+ CursorDirections cursor;
3460+
3461+ // Find where the cursor is pointing
3462+ cursor = kCenter;
3463+ _state = kDefault;
3464+
3465+ if (DOWN(PSP_DPAD)) {
3466+ _state = kCornersSelected;
3467+
3468+ if (DOWN(PSP_CTRL_UP))
3469+ cursor = kUp;
3470+ else if (DOWN(PSP_CTRL_RIGHT))
3471+ cursor = kRight;
3472+ else if (DOWN(PSP_CTRL_DOWN))
3473+ cursor = kDown;
3474+ else if (DOWN(PSP_CTRL_LEFT))
3475+ cursor = kLeft;
3476+ }
3477+
3478+ if (cursor != _oldCursor) { //If we've moved, update dirty and return
3479+ _dirty = true;
3480+ _oldCursor = cursor;
3481+ }
3482+ DEBUG_EXIT_FUNC();
3483+}
3484+
3485+void PSPKeyboard::handleLTriggerDownState(SceCtrlData &pad) {
3486+ DEBUG_ENTER_FUNC();
3487+ if (UNPRESSED(PSP_CTRL_LTRIGGER)) {
3488+ _dirty = true;
3489+
3490+ if(_mode < 2)
3491+ _mode = 2;
3492+ else
3493+ _mode = (_mode == 2) ? 3 : 2;
3494+
3495+ _state = kDefault;
3496+ }
3497+ DEBUG_EXIT_FUNC();
3498+}
3499+
3500+void PSPKeyboard::handleRTriggerDownState(SceCtrlData &pad) {
3501+ DEBUG_ENTER_FUNC();
3502+ if (UNPRESSED(PSP_CTRL_RTRIGGER)) {
3503+ _dirty = true;
3504+
3505+ if(_mode > 1)
3506+ _mode = 0;
3507+ else
3508+ _mode = (_mode == 0) ? 1 : 0;
3509+
3510+ _state = kDefault;
3511+ }
3512+ DEBUG_EXIT_FUNC();
3513+}
3514+
3515+
3516Index: backends/platform/psp/osys_psp.h
3517===================================================================
3518--- backends/platform/psp/osys_psp.h (revision 48355)
3519+++ backends/platform/psp/osys_psp.h (working copy)
3520@@ -32,139 +32,125 @@
3521 #include "sound/mixer_intern.h"
3522 #include "backends/base-backend.h"
3523 #include "backends/fs/psp/psp-fs-factory.h"
3524+#include "backends/platform/psp/display_client.h"
3525+#include "backends/platform/psp/default_display_client.h"
3526+#include "backends/platform/psp/cursor.h"
3527 #include "backends/platform/psp/pspkeyboard.h"
3528+#include "backends/platform/psp/display_manager.h"
3529+#include "backends/platform/psp/input.h"
3530
3531 #include <SDL.h>
3532
3533-#include <pspctrl.h>
3534-
3535-enum GraphicModeID {
3536- CENTERED_320X200,
3537- CENTERED_435X272,
3538- STRETCHED_480X272,
3539- CENTERED_362X272
3540-};
3541-
3542 class OSystem_PSP : public BaseBackend {
3543-public:
3544- static const OSystem::GraphicsMode s_supportedGraphicsModes[];
3545- static OSystem *instance();
3546-
3547-protected:
3548- struct Vertex {
3549- float u,v;
3550- float x,y,z;
3551- };
3552-
3553- uint16 _screenWidth;
3554- uint16 _screenHeight;
3555- uint16 _overlayWidth;
3556- uint16 _overlayHeight;
3557- byte *_offscreen;
3558- OverlayColor *_overlayBuffer;
3559- uint16 _palette[256];
3560- bool _overlayVisible;
3561- uint32 _shakePos;
3562- uint32 _lastScreenUpdate;
3563-
3564- Graphics::Surface _framebuffer;
3565-
3566- bool _mouseVisible;
3567- int _mouseX, _mouseY;
3568- int _dpadX, _dpadY;
3569- int _mouseWidth, _mouseHeight;
3570- int _mouseHotspotX, _mouseHotspotY;
3571- byte _mouseKeyColour;
3572- byte *_mouseBuf;
3573- bool _cursorPaletteDisabled;
3574-
3575- int _graphicMode;
3576- unsigned short* _clut;
3577- PSPKeyboard *_keyboard;
3578-
3579- uint32 _prevButtons;
3580- uint32 _lastPadCheck;
3581- uint32 _padAccel;
3582-
3583- SceCtrlData pad;
3584-
3585+private:
3586+
3587 Common::SaveFileManager *_savefile;
3588 Audio::MixerImpl *_mixer;
3589 Common::TimerManager *_timer;
3590
3591- Common::KeyCode getDpadEvent(int x, int y);
3592+ // All needed sub-members
3593+ Screen _screen;
3594+ Overlay _overlay;
3595+ Cursor _cursor;
3596+ DisplayManager _displayManager;
3597+ PSPKeyboard _keyboard;
3598+ InputHandler _inputHandler;
3599
3600+ void initSDL();
3601+
3602 public:
3603- OSystem_PSP();
3604- virtual ~OSystem_PSP();
3605+ OSystem_PSP() : _savefile(0), _mixer(0), _timer(0) {}
3606+ ~OSystem_PSP();
3607
3608- virtual void initBackend();
3609+ static OSystem *instance();
3610
3611- virtual bool hasFeature(Feature f);
3612- virtual void setFeatureState(Feature f, bool enable);
3613- virtual bool getFeatureState(Feature f);
3614-
3615- virtual const GraphicsMode *getSupportedGraphicsModes() const;
3616- virtual int getDefaultGraphicsMode() const;
3617- virtual bool setGraphicsMode(int mode);
3618+ const char *getObjectName() const; // For debugging
3619+
3620+ void initBackend();
3621+
3622+ // Feature related
3623+ bool hasFeature(Feature f);
3624+ void setFeatureState(Feature f, bool enable);
3625+ bool getFeatureState(Feature f);
3626+
3627+ // Graphics related
3628+ const GraphicsMode *getSupportedGraphicsModes() const;
3629+ int getDefaultGraphicsMode() const;
3630+ bool setGraphicsMode(int mode);
3631 bool setGraphicsMode(const char *name);
3632- virtual int getGraphicsMode() const;
3633+ int getGraphicsMode() const;
3634+#ifdef USE_RGB_COLOR
3635+ virtual Graphics::PixelFormat getScreenFormat() const;
3636+ virtual Common::List<Graphics::PixelFormat> getSupportedFormats();
3637+#endif
3638+
3639+ // Screen size
3640+ void initSize(uint width, uint height, const Graphics::PixelFormat *format);
3641+ int16 getWidth();
3642+ int16 getHeight();
3643+
3644+ // Palette related
3645+ void setPalette(const byte *colors, uint start, uint num);
3646+ void grabPalette(byte *colors, uint start, uint num);
3647+ void setCursorPalette(const byte *colors, uint start, uint num);
3648+ void disableCursorPalette(bool disable);
3649+
3650+ // Screen related
3651+ void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h);
3652+ Graphics::Surface *lockScreen();
3653+ void unlockScreen();
3654+ void updateScreen();
3655+ void setShakePos(int shakeOffset);
3656+
3657+ // Overlay related
3658+ void showOverlay();
3659+ void hideOverlay();
3660+ void clearOverlay();
3661+ void grabOverlay(OverlayColor *buf, int pitch);
3662+ void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
3663+ int16 getOverlayHeight();
3664+ int16 getOverlayWidth();
3665+ Graphics::PixelFormat getOverlayFormat() const { return Graphics::createPixelFormat<4444>(); }
3666+
3667+ // Mouse related
3668+ bool showMouse(bool visible);
3669+ void warpMouse(int x, int y);
3670+ void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format);
3671
3672- virtual void initSize(uint width, uint height, const Graphics::PixelFormat *format);
3673- virtual int16 getWidth();
3674- virtual int16 getHeight();
3675+ // Events and input
3676+ bool pollEvent(Common::Event &event);
3677+ bool processInput(Common::Event &event);
3678
3679- virtual void setPalette(const byte *colors, uint start, uint num);
3680- virtual void grabPalette(byte *colors, uint start, uint num);
3681- virtual void setCursorPalette(const byte *colors, uint start, uint num);
3682- virtual void disableCursorPalette(bool disable);
3683- virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h);
3684- virtual Graphics::Surface *lockScreen();
3685- virtual void unlockScreen();
3686- virtual void updateScreen();
3687- virtual void setShakePos(int shakeOffset);
3688+ // Time
3689+ uint32 getMillis();
3690+ void delayMillis(uint msecs);
3691
3692- virtual void showOverlay();
3693- virtual void hideOverlay();
3694- virtual void clearOverlay();
3695- virtual void grabOverlay(OverlayColor *buf, int pitch);
3696- virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
3697- virtual int16 getOverlayHeight();
3698- virtual int16 getOverlayWidth();
3699- virtual Graphics::PixelFormat getOverlayFormat() const { return Graphics::createPixelFormat<4444>(); }
3700-
3701- virtual bool showMouse(bool visible);
3702- virtual void warpMouse(int x, int y);
3703- virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format);
3704-
3705- virtual bool pollEvent(Common::Event &event);
3706- virtual bool processInput(Common::Event &event);
3707-
3708- virtual uint32 getMillis();
3709- virtual void delayMillis(uint msecs);
3710-
3711+ // Timer
3712 typedef int (*TimerProc)(int interval);
3713- virtual void setTimerCallback(TimerProc callback, int interval);
3714+ void setTimerCallback(TimerProc callback, int interval);
3715+ Common::TimerManager *getTimerManager() { return _timer; }
3716
3717- virtual MutexRef createMutex(void);
3718- virtual void lockMutex(MutexRef mutex);
3719- virtual void unlockMutex(MutexRef mutex);
3720- virtual void deleteMutex(MutexRef mutex);
3721+ // Mutex
3722+ MutexRef createMutex(void);
3723+ void lockMutex(MutexRef mutex);
3724+ void unlockMutex(MutexRef mutex);
3725+ void deleteMutex(MutexRef mutex);
3726
3727+ // Sound
3728 static void mixCallback(void *sys, byte *samples, int len);
3729- virtual void setupMixer(void);
3730-
3731- Common::SaveFileManager *getSavefileManager() { return _savefile; }
3732+ void setupMixer(void);
3733 Audio::Mixer *getMixer() { return _mixer; }
3734- Common::TimerManager *getTimerManager() { return _timer; }
3735+
3736+ // Misc
3737+ Common::SaveFileManager *getSavefileManager() { return _savefile; }
3738 FilesystemFactory *getFilesystemFactory() { return &PSPFilesystemFactory::instance(); }
3739 void getTimeAndDate(TimeDate &t) const;
3740
3741- virtual void quit();
3742+ void quit();
3743
3744- virtual Common::SeekableReadStream *createConfigReadStream();
3745- virtual Common::WriteStream *createConfigWriteStream();
3746+ Common::SeekableReadStream *createConfigReadStream();
3747+ Common::WriteStream *createConfigWriteStream();
3748+
3749 };
3750
3751-
3752 #endif /* OSYS_PSP_H */
3753Index: backends/platform/psp/powerman.cpp
3754===================================================================
3755--- backends/platform/psp/powerman.cpp (revision 48355)
3756+++ backends/platform/psp/powerman.cpp (working copy)
3757@@ -23,24 +23,23 @@
3758 *
3759 */
3760
3761+//#define __PSP_DEBUG_FUNCS__ /* can put this locally too */
3762+//#define __PSP_DEBUG_PRINT__
3763+#include "backends/platform/psp/trace.h"
3764+
3765 #include <psppower.h>
3766 #include <pspthreadman.h>
3767
3768-#include "./powerman.h"
3769-#include "./trace.h"
3770+#include "backends/platform/psp/powerman.h"
3771 #include "engine.h"
3772
3773 DECLARE_SINGLETON(PowerManager)
3774
3775-#ifdef __PSP_DEBUG_SUSPEND__
3776-void PowerManager::debugPM() {
3777- PSPDebugTrace("PM status is %d. Listcount is %d. CriticalCount is %d. ThreadId is %x. Error = %d\n", _PMStatus, _listCounter,
3778- _criticalCounter, sceKernelGetThreadId(), _error);
3779+// Function to debug the Power Manager (we have no output to screen)
3780+inline void PowerManager::debugPM() {
3781+ PSP_DEBUG_PRINT("PM status[%d]. Listcount[%d]. CriticalCount[%d]. ThreadId[%x]. Error[%d]\n",
3782+ _PMStatus, _listCounter, _criticalCounter, sceKernelGetThreadId(), _error);
3783 }
3784-#else
3785- #define debugPM()
3786- #define PMStatusSet(x)
3787-#endif /* __PSP_DEBUG_SUSPEND__ */
3788
3789
3790 /*******************************************
3791@@ -49,7 +48,8 @@
3792 *
3793 ********************************************/
3794 PowerManager::PowerManager() {
3795-
3796+ DEBUG_ENTER_FUNC();
3797+
3798 _flagMutex = NULL; /* Init mutex handle */
3799 _listMutex = NULL; /* Init mutex handle */
3800 _condSuspendable = NULL; /* Init condition variable */
3801@@ -57,33 +57,34 @@
3802
3803 _condSuspendable = SDL_CreateCond();
3804 if (_condSuspendable <= 0) {
3805- PSPDebugSuspend("PowerManager::PowerManager(): Couldn't create condSuspendable\n");
3806+ PSP_ERROR("Couldn't create Suspendable condition variable\n");
3807 }
3808
3809 _condPM = SDL_CreateCond();
3810 if (_condPM <= 0) {
3811- PSPDebugSuspend("PowerManager::PowerManager(): Couldn't create condPM\n");
3812+ PSP_ERROR("Couldn't create PM condition variable\n");
3813 }
3814
3815 _flagMutex = SDL_CreateMutex();
3816 if (_flagMutex <= 0) {
3817- PSPDebugSuspend("PowerManager::PowerManager(): Couldn't create flagMutex\n");
3818+ PSP_ERROR("Couldn't create flag Mutex\n");
3819 }
3820
3821 _listMutex = SDL_CreateMutex();
3822 if (_listMutex <= 0) {
3823- PSPDebugSuspend("PowerManager::PowerManager(): Couldn't create listMutex\n");
3824+ PSP_ERROR("Couldn't create list Mutex\n");
3825 }
3826
3827 _suspendFlag = false;
3828- _criticalCounter = 0;
3829- _pauseFlag = 0; _pauseFlagOld = 0; _pauseClientState = 0;
3830-
3831-#ifdef __PSP_DEBUG_SUSPEND__
3832+ _criticalCounter = 0; // How many are in the critical section
3833+ _pauseFlag = 0;
3834+ _pauseFlagOld = 0;
3835+ _pauseClientState = 0;
3836 _listCounter = 0;
3837 PMStatusSet(kInitDone);
3838 _error = 0;
3839-#endif
3840+
3841+ DEBUG_EXIT_FUNC();
3842 }
3843
3844 /*******************************************
3845@@ -92,26 +93,24 @@
3846 *
3847 ********************************************/
3848 int PowerManager::registerSuspend(Suspendable *item) {
3849+ DEBUG_ENTER_FUNC();
3850 // Register in list
3851- PSPDebugSuspend("In registerSuspend\n");
3852 debugPM();
3853
3854 if (SDL_mutexP(_listMutex) != 0) {
3855- PSPDebugTrace("PowerManager::registerSuspend(): Couldn't lock _listMutex %d\n", _listMutex);
3856+ PSP_ERROR("Couldn't lock _listMutex[%p]\n", _listMutex);
3857 }
3858
3859 _suspendList.push_front(item);
3860-#ifdef __PSP_DEBUG_SUSPEND__
3861 _listCounter++;
3862-#endif
3863
3864 if (SDL_mutexV(_listMutex) != 0) {
3865- PSPDebugTrace("PowerManager::registerSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
3866+ PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex);
3867 }
3868-
3869- PSPDebugSuspend("Out of registerSuspend\n");
3870+
3871 debugPM();
3872
3873+ DEBUG_EXIT_FUNC();
3874 return 0;
3875 }
3876
3877@@ -121,27 +120,25 @@
3878 *
3879 ********************************************/
3880 int PowerManager::unregisterSuspend(Suspendable *item) {
3881-
3882- PSPDebugSuspend("In unregisterSuspend\n");
3883+ DEBUG_ENTER_FUNC();
3884 debugPM();
3885
3886 // Unregister from stream list
3887 if (SDL_mutexP(_listMutex) != 0) {
3888- PSPDebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
3889+ PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex);
3890 }
3891
3892 _suspendList.remove(item);
3893-#ifdef __PSP_DEBUG_SUSPEND__
3894 _listCounter--;
3895-#endif
3896
3897 if (SDL_mutexV(_listMutex) != 0) {
3898- PSPDebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
3899+ PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex);
3900 }
3901
3902- PSPDebugSuspend("Out of unregisterSuspend\n");
3903+ PSP_DEBUG_PRINT("Out of unregisterSuspend\n");
3904 debugPM();
3905
3906+ DEBUG_EXIT_FUNC();
3907 return 0;
3908 }
3909
3910@@ -151,10 +148,9 @@
3911 *
3912 ********************************************/
3913 PowerManager::~PowerManager() {
3914-
3915-#ifdef __PSP_DEBUG_SUSPEND__
3916+ DEBUG_ENTER_FUNC();
3917+
3918 PMStatusSet(kDestroyPM);
3919-#endif
3920
3921 SDL_DestroyCond(_condSuspendable);
3922 _condSuspendable = 0;
3923@@ -167,6 +163,8 @@
3924
3925 SDL_DestroyMutex(_listMutex);
3926 _listMutex = 0;
3927+
3928+ DEBUG_EXIT_FUNC();
3929 }
3930
3931 /*******************************************
3932@@ -184,14 +182,14 @@
3933
3934 if ((pause != _pauseFlagOld) && g_engine) { // Check to see if we have an engine
3935 if (pause && _pauseClientState == PowerManager::Unpaused) {
3936- _pauseClientState = PowerManager::Pausing; // Tell PM we're in the middle of pausing
3937+ _pauseClientState = PowerManager::Pausing; // Tell PM we're in the middle of pausing
3938 g_engine->pauseEngine(true);
3939- PSPDebugSuspend("Pausing engine in PowerManager::pollPauseEngine()\n");
3940+ PSP_DEBUG_PRINT_FUNC("Pausing engine\n");
3941 _pauseClientState = PowerManager::Paused; // Tell PM we're done pausing
3942 }
3943 else if (!pause && _pauseClientState == PowerManager::Paused) {
3944 g_engine->pauseEngine(false);
3945- PSPDebugSuspend("Unpausing for resume in PowerManager::pollPauseEngine()\n");
3946+ PSP_DEBUG_PRINT_FUNC("Unpausing for resume\n");
3947 _pauseClientState = PowerManager::Unpaused; // Tell PM we're in the middle of pausing
3948 }
3949
3950@@ -205,7 +203,7 @@
3951 * Use this for small critical sections where you can easily restore the previous state.
3952 *
3953 ********************************************/
3954- int PowerManager::blockOnSuspend() {
3955+int PowerManager::blockOnSuspend() {
3956 return beginCriticalSection(true);
3957 }
3958
3959@@ -216,26 +214,28 @@
3960 * Make sure to call endCriticalSection or the PSP won't suspend.
3961 ********************************************/
3962
3963- int PowerManager::beginCriticalSection(bool justBlock) {
3964+int PowerManager::beginCriticalSection(bool justBlock) {
3965+ DEBUG_ENTER_FUNC();
3966+
3967 int ret = NotBlocked;
3968
3969 if (SDL_mutexP(_flagMutex) != 0) {
3970- PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't lock flagMutex %d\n", _flagMutex);
3971+ PSP_ERROR("PowerManager::blockOnSuspend(): Couldn't lock flagMutex[%p]\n", _flagMutex);
3972 ret = Error;
3973 }
3974
3975 // Check the access flag
3976 if (_suspendFlag == true) {
3977- PSPDebugSuspend("We're being blocked!\n");
3978+ PSP_DEBUG_PRINT("We're being blocked!\n");
3979 debugPM();
3980 ret = Blocked;
3981
3982 // If it's true, we wait for a signal to continue
3983 if (SDL_CondWait(_condSuspendable, _flagMutex) != 0) {
3984- PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't wait on cond %d\n", _condSuspendable);
3985+ PSP_DEBUG_PRINT("PowerManager::blockOnSuspend(): Couldn't wait on cond[%p]\n", _condSuspendable);
3986 }
3987
3988- PSPDebugSuspend("We got blocked!!\n");
3989+ PSP_DEBUG_PRINT("We got blocked!!\n");
3990 debugPM();
3991 }
3992
3993@@ -244,18 +244,20 @@
3994 _criticalCounter++;
3995
3996 if (SDL_mutexV(_flagMutex) != 0) {
3997- PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't unlock flagMutex %d\n", _flagMutex);
3998+ PSP_ERROR("PowerManager::blockOnSuspend(): Couldn't unlock flagMutex[%p]\n", _flagMutex);
3999 ret = Error;
4000 }
4001
4002+ DEBUG_EXIT_FUNC();
4003 return ret;
4004 }
4005
4006 int PowerManager::endCriticalSection() {
4007+ DEBUG_ENTER_FUNC();
4008 int ret = 0;
4009
4010 if (SDL_mutexP(_flagMutex) != 0) {
4011- PSPDebugTrace("PowerManager::endCriticalSection(): Couldn't lock flagMutex %d\n", _flagMutex);
4012+ PSP_ERROR("PowerManager::endCriticalSection(): Couldn't lock flagMutex[%p]\n", _flagMutex);
4013 ret = Error;
4014 }
4015
4016@@ -264,26 +266,27 @@
4017
4018 if (_criticalCounter <= 0) {
4019 if (_suspendFlag == true) { // If the PM is sleeping, this flag must be set
4020- PSPDebugSuspend("Unblocked thread waking up the PM.\n");
4021+ PSP_DEBUG_PRINT("Unblocked thread waking up the PM.\n");
4022 debugPM();
4023
4024 SDL_CondBroadcast(_condPM);
4025
4026- PSPDebugSuspend("Woke up the PM\n");
4027+ PSP_DEBUG_PRINT("Woke up the PM\n");
4028 debugPM();
4029 }
4030
4031 if (_criticalCounter < 0) { // Check for bad usage of critical sections
4032- PSPDebugTrace("PowerManager::endCriticalSection(): Error! Critical counter is %d\n", _criticalCounter);
4033+ PSP_ERROR("Critical counter[%d]\n", _criticalCounter);
4034 debugPM();
4035 }
4036 }
4037
4038 if (SDL_mutexV(_flagMutex) != 0) {
4039- PSPDebugTrace("PowerManager::endCriticalSection(): Couldn't unlock flagMutex %d\n", _flagMutex);
4040+ PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex);
4041 ret = Error;
4042 }
4043
4044+ DEBUG_EXIT_FUNC();
4045 return ret;
4046 }
4047
4048@@ -293,6 +296,7 @@
4049 *
4050 ********************************************/
4051 int PowerManager::suspend() {
4052+ DEBUG_ENTER_FUNC();
4053 int ret = 0;
4054
4055 if (_pauseFlag) return ret; // Very important - make sure we only suspend once
4056@@ -325,7 +329,7 @@
4057 // Now we set the suspend flag to true to cause reading threads to block
4058
4059 if (SDL_mutexP(_flagMutex) != 0) {
4060- PSPDebugTrace("PowerManager::suspend(): Couldn't lock flagMutex %d\n", _flagMutex);
4061+ PSP_ERROR("Couldn't lock flagMutex[%p]\n", _flagMutex);
4062 _error = Error;
4063 ret = Error;
4064 }
4065@@ -342,7 +346,7 @@
4066 }
4067
4068 if (SDL_mutexV(_flagMutex) != 0) {
4069- PSPDebugTrace("PowerManager::suspend(): Couldn't unlock flagMutex %d\n", _flagMutex);
4070+ PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex);
4071 _error = Error;
4072 ret = Error;
4073 }
4074@@ -351,22 +355,22 @@
4075
4076 // Loop over list, calling suspend()
4077 if (SDL_mutexP(_listMutex) != 0) {
4078- PSPDebugTrace("PowerManager::suspend(): Couldn't lock listMutex %d\n", _listMutex);
4079+ PSP_ERROR("Couldn't lock listMutex[%p]\n", _listMutex);
4080 _error = Error;
4081 ret = Error;
4082 }
4083 PMStatusSet(kIteratingListSuspend);
4084 // Iterate
4085- Common::List<Suspendable *>::iterator i = _suspendList.begin();
4086+ Common::List<Suspendable *>::iterator i;
4087
4088- for (; i != _suspendList.end(); ++i) {
4089+ for (i = _suspendList.begin(); i != _suspendList.end(); ++i) {
4090 (*i)->suspend();
4091 }
4092
4093 PMStatusSet(kDoneIteratingListSuspend);
4094
4095 if (SDL_mutexV(_listMutex) != 0) {
4096- PSPDebugTrace("PowerManager::suspend(): Couldn't unlock listMutex %d\n", _listMutex);
4097+ PSP_ERROR("Couldn't unlock listMutex[%p]\n", _listMutex);
4098 _error = Error;
4099 ret = Error;
4100 }
4101@@ -374,6 +378,7 @@
4102
4103 scePowerUnlock(0); // Allow the PSP to go to sleep now
4104
4105+ DEBUG_EXIT_FUNC();
4106 return ret;
4107 }
4108
4109@@ -383,6 +388,7 @@
4110 *
4111 ********************************************/
4112 int PowerManager::resume() {
4113+ DEBUG_ENTER_FUNC();
4114 int ret = 0;
4115
4116 // Make sure we can't get another suspend
4117@@ -394,7 +400,7 @@
4118
4119 // First we notify our Suspendables. Loop over list, calling resume()
4120 if (SDL_mutexP(_listMutex) != 0) {
4121- PSPDebugTrace("PowerManager::resume(): Couldn't lock listMutex %d\n", _listMutex);
4122+ PSP_ERROR("Couldn't lock listMutex[%p]\n", _listMutex);
4123 _error = Error;
4124 ret = Error;
4125 }
4126@@ -409,7 +415,7 @@
4127 PMStatusSet(kDoneIteratingListResume);
4128
4129 if (SDL_mutexV(_listMutex) != 0) {
4130- PSPDebugTrace("PowerManager::resume(): Couldn't unlock listMutex %d\n", _listMutex);
4131+ PSP_ERROR("Couldn't unlock listMutex[%p]\n", _listMutex);
4132 _error = Error;
4133 ret = Error;
4134 }
4135@@ -418,7 +424,7 @@
4136
4137 // Now we set the suspend flag to false
4138 if (SDL_mutexP(_flagMutex) != 0) {
4139- PSPDebugTrace("PowerManager::resume(): Couldn't lock flagMutex %d\n", _flagMutex);
4140+ PSP_ERROR("Couldn't lock flagMutex %p\n", _flagMutex);
4141 _error = Error;
4142 ret = Error;
4143 }
4144@@ -430,14 +436,14 @@
4145
4146 // Signal the other threads to wake up
4147 if (SDL_CondBroadcast(_condSuspendable) != 0) {
4148- PSPDebugTrace("PowerManager::resume(): Couldn't broadcast condition %d\n", _condSuspendable);
4149+ PSP_ERROR("Couldn't broadcast condition[%p]\n", _condSuspendable);
4150 _error = Error;
4151 ret = Error;
4152 }
4153 PMStatusSet(kDoneSignallingSuspendedThreadsResume);
4154
4155 if (SDL_mutexV(_flagMutex) != 0) {
4156- PSPDebugTrace("PowerManager::resume(): Couldn't unlock flagMutex %d\n", _flagMutex);
4157+ PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex);
4158 _error = Error;
4159 ret = Error;
4160 }
4161@@ -447,5 +453,6 @@
4162
4163 scePowerUnlock(0); // Allow new suspends
4164
4165+ DEBUG_EXIT_FUNC();
4166 return ret;
4167 }
4168Index: backends/platform/psp/Makefile
4169===================================================================
4170--- backends/platform/psp/Makefile (revision 48355)
4171+++ backends/platform/psp/Makefile (working copy)
4172@@ -66,7 +66,7 @@
4173 #CC = psp-gcc
4174 CXX = psp-g++
4175 CXXFLAGS = -O3 -Wall -Wno-multichar -fno-exceptions -fno-rtti
4176-DEFINES = -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL
4177+DEFINES = -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL -DUSE_RGB_COLOR
4178 LDFLAGS :=
4179 INCDIR := $(srcdir) . $(srcdir)/engines/ $(PSPSDK)/include
4180 INCLUDES := $(addprefix -I, $(INCDIR))
4181@@ -133,6 +133,13 @@
4182 OBJS := powerman.o \
4183 psp_main.o \
4184 osys_psp.o \
4185+ psppixelformat.o \
4186+ memory.o \
4187+ display_manager.o \
4188+ display_client.o \
4189+ default_display_client.o \
4190+ input.o \
4191+ cursor.o \
4192 trace.o \
4193 psploader.o \
4194 pspkeyboard.o
4195Index: backends/platform/psp/trace.cpp
4196===================================================================
4197--- backends/platform/psp/trace.cpp (revision 48355)
4198+++ backends/platform/psp/trace.cpp (working copy)
4199@@ -23,47 +23,33 @@
4200 *
4201 */
4202
4203+#define TRACE_C
4204+#include <pspkernel.h>
4205+#include <pspdebug.h>
4206+#include "backends/platform/psp/trace.h"
4207
4208-#include "./trace.h"
4209
4210+int psp_debug_indent = 0;
4211
4212-
4213-void PSPDebugTrace (const char *format, ...) {
4214-#ifdef __PSP_DEBUG__
4215+void PSPDebugTrace (bool alsoToScreen, const char *format, ...) {
4216 va_list opt;
4217- char buff[2048];
4218- int bufsz, fd;
4219+ char buffer[2048];
4220+ int bufsz;
4221+ FILE *fd = 0;
4222
4223 va_start(opt, format);
4224- bufsz = vsnprintf( buff, (size_t) sizeof(buff), format, opt);
4225+ bufsz = vsnprintf( buffer, (size_t) sizeof(buffer), format, opt);
4226 va_end(opt);
4227
4228- fd = sceIoOpen("MS0:/DTRACE.TXT", PSP_O_RDWR | PSP_O_CREAT | PSP_O_APPEND, 0777);
4229-
4230- if (fd <= 0)
4231+ //fd = fopen("MS0:/SCUMMTRACE.TXT", "ab");
4232+ fd = fopen("SCUMMTRACE.TXT", "ab");
4233+
4234+ if (fd == 0)
4235 return;
4236
4237- sceIoWrite(fd, (const void*)buff, bufsz);
4238- sceIoClose(fd);
4239-#endif /* __PSP_DEBUG__ */
4240-}
4241-
4242-void PSPDebugTrace (const char * filename, const char *format, ...) {
4243-#ifdef __PSP_DEBUG__
4244- va_list opt;
4245- char buff[2048];
4246- int bufsz, fd;
4247-
4248- va_start(opt, format);
4249- bufsz = vsnprintf( buff, (size_t) sizeof(buff), format, opt);
4250- va_end(opt);
4251-
4252- fd = sceIoOpen(filename, PSP_O_RDWR | PSP_O_CREAT | PSP_O_APPEND, 0777);
4253-
4254- if (fd <= 0)
4255- return;
4256-
4257- sceIoWrite(fd, (const void*)buff, bufsz);
4258- sceIoClose(fd);
4259-#endif /* __PSP_DEBUG__ */
4260-}
4261+ fwrite(buffer, 1, bufsz, fd);
4262+ fclose(fd);
4263+
4264+ if (alsoToScreen)
4265+ fprintf(stderr, buffer);
4266+}
4267\ No newline at end of file
4268Index: backends/platform/psp/display_manager.cpp
4269===================================================================
4270--- backends/platform/psp/display_manager.cpp (revision 0)
4271+++ backends/platform/psp/display_manager.cpp (revision 0)
4272@@ -0,0 +1,336 @@
4273+/* ScummVM - Graphic Adventure Engine
4274+ *
4275+ * ScummVM is the legal property of its developers, whose names
4276+ * are too numerous to list here. Please refer to the COPYRIGHT
4277+ * file distributed with this source distribution.
4278+ *
4279+ * This program is free software; you can redistribute it and/or
4280+ * modify it under the terms of the GNU General Public License
4281+ * as published by the Free Software Foundation; either version 2
4282+ * of the License, or (at your option) any later version.
4283+
4284+ * This program is distributed in the hope that it will be useful,
4285+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4286+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4287+ * GNU General Public License for more details.
4288+
4289+ * You should have received a copy of the GNU General Public License
4290+ * along with this program; if not, write to the Free Software
4291+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
4292+ *
4293+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
4294+ * $Id: osys_psp.cpp 47541 2010-01-25 01:39:44Z lordhoto $
4295+ *
4296+ */
4297+
4298+//#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */
4299+//#define __PSP_DEBUG_PRINT__ /* For debug printouts */
4300+
4301+//#define ENABLE_RENDER_MEASURE
4302+
4303+#include "backends/platform/psp/trace.h"
4304+
4305+#include <pspgu.h>
4306+#include <pspdisplay.h>
4307+
4308+#include "common/scummsys.h"
4309+#include "backends/base-backend.h"
4310+#include "backends/platform/psp/display_client.h"
4311+#include "backends/platform/psp/default_display_client.h"
4312+#include "backends/platform/psp/cursor.h"
4313+#include "backends/platform/psp/pspkeyboard.h"
4314+#include "backends/platform/psp/display_manager.h"
4315+
4316+#define PSP_BUFFER_WIDTH (512)
4317+#define PSP_SCREEN_WIDTH 480
4318+#define PSP_SCREEN_HEIGHT 272
4319+#define PSP_FRAME_SIZE (PSP_BUFFER_WIDTH * PSP_SCREEN_HEIGHT)
4320+
4321+uint32 __attribute__((aligned(16))) MasterGuRenderer::_displayList[2048];
4322+
4323+ const OSystem::GraphicsMode DisplayManager::_supportedModes[] = {
4324+ { "320x200 (centered)", "320x200 16-bit centered", CENTERED_320X200 },
4325+ { "435x272 (best-fit, centered)", "435x272 16-bit centered", CENTERED_435X272 },
4326+ { "480x272 (full screen)", "480x272 16-bit stretched", STRETCHED_480X272 },
4327+ { "362x272 (4:3, centered)", "362x272 16-bit centered", CENTERED_362X272 },
4328+ {0, 0, 0}
4329+};
4330+
4331+
4332+// Class MasterGuRenderer ----------------------------------------------
4333+
4334+void MasterGuRenderer::guInit() {
4335+ DEBUG_ENTER_FUNC();
4336+
4337+ sceGuInit();
4338+ sceGuStart(0, _displayList);
4339+
4340+ guProgramDisplayBufferSizes();
4341+
4342+ sceGuOffset(2048 - (PSP_SCREEN_WIDTH/2), 2048 - (PSP_SCREEN_HEIGHT/2));
4343+ sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
4344+ sceGuDepthRange(0xC350, 0x2710);
4345+ sceGuDisable(GU_DEPTH_TEST); // We'll use depth buffer area
4346+ sceGuDepthMask(GU_TRUE); // Prevent writes to depth buffer
4347+ sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
4348+ sceGuEnable(GU_SCISSOR_TEST);
4349+ sceGuFrontFace(GU_CW);
4350+ sceGuEnable(GU_TEXTURE_2D);
4351+
4352+ sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
4353+ sceGuFinish();
4354+ sceGuSync(0,0);
4355+
4356+ sceDisplayWaitVblankStart();
4357+ sceGuDisplay(1);
4358+
4359+ DEBUG_EXIT_FUNC();
4360+}
4361+
4362+void MasterGuRenderer::guProgramDisplayBufferSizes() {
4363+ DEBUG_ENTER_FUNC();
4364+
4365+ PSP_DEBUG_PRINT("Outputbits[%u]\n", GuRenderer::_displayManager->getOutputBitsPerPixel());
4366+
4367+ switch (GuRenderer::_displayManager->getOutputBitsPerPixel()) {
4368+ case 16:
4369+ sceGuDrawBuffer(GU_PSM_4444, (void *)0, PSP_BUFFER_WIDTH);
4370+ sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, (void*)(PSP_FRAME_SIZE * sizeof(uint16)), PSP_BUFFER_WIDTH);
4371+ sceGuDepthBuffer((void*)(PSP_FRAME_SIZE * sizeof(uint16) * 2), PSP_BUFFER_WIDTH);
4372+ VramAllocator::instance().allocate(PSP_FRAME_SIZE * sizeof(uint16) * 2);
4373+ break;
4374+ case 32:
4375+ sceGuDrawBuffer(GU_PSM_8888, (void *)0, PSP_BUFFER_WIDTH);
4376+ sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, (void*)(PSP_FRAME_SIZE * sizeof(uint32)), PSP_BUFFER_WIDTH);
4377+ sceGuDepthBuffer((void*)(PSP_FRAME_SIZE * sizeof(uint32) * 2), PSP_BUFFER_WIDTH);
4378+ VramAllocator::instance().allocate(PSP_FRAME_SIZE * sizeof(uint32) * 2);
4379+ break;
4380+ }
4381+
4382+ DEBUG_EXIT_FUNC();
4383+}
4384+
4385+// These are GU commands that should always stay the same
4386+INLINE void MasterGuRenderer::guPreRender() {
4387+ DEBUG_ENTER_FUNC();
4388+
4389+#ifdef ENABLE_RENDER_MEASURE
4390+ _lastRenderTime = g_system->getMillis();
4391+#endif /* ENABLE_RENDER_MEASURE */
4392+
4393+ sceGuStart(0, _displayList);
4394+
4395+ sceGuClearColor(0xFF000000);
4396+ sceGuClear(GU_COLOR_BUFFER_BIT);
4397+
4398+ sceGuAmbientColor(0xFFFFFFFF);
4399+ sceGuColor(0xFFFFFFFF);
4400+ sceGuTexOffset(0,0);
4401+ sceGuTexFilter(GU_LINEAR, GU_LINEAR);
4402+
4403+ sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); // Also good enough for all purposes
4404+ sceGuAlphaFunc(GU_GREATER, 0, 0xFF); // Also good enough for all purposes
4405+
4406+ DEBUG_EXIT_FUNC();
4407+}
4408+
4409+INLINE void MasterGuRenderer::guPostRender() {
4410+ DEBUG_ENTER_FUNC();
4411+
4412+ sceGuFinish();
4413+ sceGuSync(0,0);
4414+
4415+#ifdef ENABLE_RENDER_MEASURE
4416+ uint32 now = g_system->getMillis();
4417+ PSP_INFO_PRINT("Render took %d milliseconds\n", now - _lastRenderTime);
4418+#endif /* ENABLE_RENDER_MEASURE */
4419+
4420+ sceDisplayWaitVblankStart();
4421+ sceGuSwapBuffers();
4422+
4423+ DEBUG_EXIT_FUNC();
4424+}
4425+
4426+void MasterGuRenderer::guShutDown() {
4427+ sceGuTerm();
4428+}
4429+
4430+
4431+// Class DisplayManager -----------------------------------------------------
4432+
4433+DisplayManager::~DisplayManager() {
4434+ _masterGuRenderer.guShutDown();
4435+}
4436+
4437+void DisplayManager::init() {
4438+ DEBUG_ENTER_FUNC();
4439+
4440+ _displayParams.outputBitsPerPixel = 32; // can be changed to produce 16-bit output
4441+
4442+ GuRenderer::setDisplayManager(this);
4443+ _screen->init();
4444+ _overlay->init();
4445+ _cursor->init();
4446+
4447+ _masterGuRenderer.guInit(); // start up the renderer
4448+
4449+ DEBUG_EXIT_FUNC();
4450+}
4451+
4452+void DisplayManager::setSizeAndPixelFormat(uint width, uint height, const Graphics::PixelFormat *format) {
4453+
4454+ DEBUG_ENTER_FUNC();
4455+ PSP_DEBUG_PRINT("w[%u], h[%u], pformat[%p]\n", width, height, format);
4456+
4457+ _overlay->deallocate();
4458+ _screen->deallocate();
4459+
4460+ _screen->setScummvmPixelFormat(format);
4461+ _screen->setSize(width, height);
4462+ _screen->allocate();
4463+
4464+ _cursor->setScreenPaletteScummvmPixelFormat(format);
4465+
4466+ _overlay->setBytesPerPixel(sizeof(OverlayColor));
4467+ _overlay->setSize(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
4468+ _overlay->allocate();
4469+
4470+ _displayParams.screenSource.width = width;
4471+ _displayParams.screenSource.height = height;
4472+ calculateScaleParams();
4473+
4474+ DEBUG_EXIT_FUNC();
4475+}
4476+
4477+bool DisplayManager::setGraphicsMode(const char *name) {
4478+ DEBUG_ENTER_FUNC();
4479+
4480+ int i = 0;
4481+
4482+ while (_supportedModes[i].name) {
4483+ if (!strcmpi(_supportedModes[i].name, name)) {
4484+ setGraphicsMode(_supportedModes[i].id);
4485+ DEBUG_EXIT_FUNC();
4486+ return true;
4487+ }
4488+ i++;
4489+ }
4490+
4491+ DEBUG_EXIT_FUNC();
4492+ return false;
4493+}
4494+
4495+bool DisplayManager::setGraphicsMode(int mode) {
4496+ DEBUG_ENTER_FUNC();
4497+
4498+ _graphicsMode = mode;
4499+
4500+ switch (_graphicsMode) {
4501+ case CENTERED_320X200:
4502+ _displayParams.screenOutput.width = 320;
4503+ _displayParams.screenOutput.height = 200;
4504+ break;
4505+ case CENTERED_435X272:
4506+ _displayParams.screenOutput.width = 435;
4507+ _displayParams.screenOutput.height = 272;
4508+ break;
4509+ case STRETCHED_480X272:
4510+ _displayParams.screenOutput.width = 480;
4511+ _displayParams.screenOutput.height = 272;
4512+ break;
4513+ case CENTERED_362X272:
4514+ _displayParams.screenOutput.width = 362;
4515+ _displayParams.screenOutput.height = 272;
4516+ break;
4517+ default:
4518+ PSP_ERROR("Unsupported graphics mode[%d].\n", _graphicsMode);
4519+ }
4520+
4521+ calculateScaleParams();
4522+
4523+ DEBUG_EXIT_FUNC();
4524+ return true;
4525+}
4526+
4527+void DisplayManager::calculateScaleParams() {
4528+ if (_displayParams.screenOutput.width && _displayParams.screenSource.width &&
4529+ _displayParams.screenOutput.height && _displayParams.screenSource.height) {
4530+ _displayParams.scaleX = ((float)_displayParams.screenOutput.width) / _displayParams.screenSource.width;
4531+ _displayParams.scaleY = ((float)_displayParams.screenOutput.height) / _displayParams.screenSource.height;
4532+ }
4533+}
4534+
4535+void DisplayManager::renderAll() {
4536+ DEBUG_ENTER_FUNC();
4537+
4538+ if (!isTimeToUpdate()) {
4539+ DEBUG_EXIT_FUNC();
4540+ return;
4541+ }
4542+
4543+ if (!_screen->isDirty() &&
4544+ (!_overlay->isDirty()) &&
4545+ (!_cursor->isDirty()) &&
4546+ (!_keyboard->isDirty())) {
4547+ PSP_DEBUG_PRINT("Nothing dirty\n");
4548+ DEBUG_EXIT_FUNC();
4549+ return;
4550+ }
4551+
4552+ PSP_DEBUG_PRINT("screen[%s], overlay[%s], cursor[%s], keyboard[%s]\n",
4553+ _screen->isDirty() ? "true" : "false",
4554+ _overlay->isDirty() ? "true" : "false",
4555+ _cursor->isDirty() ? "true" : "false",
4556+ _keyboard->isDirty() ? "true" : "false"
4557+ );
4558+
4559+ _masterGuRenderer.guPreRender(); // Set up rendering
4560+
4561+ _screen->render();
4562+
4563+ _screen->setClean(); // clean out dirty bit
4564+
4565+ if (_overlay->isVisible())
4566+ _overlay->render();
4567+
4568+ _overlay->setClean();
4569+
4570+ if (_cursor->isVisible())
4571+ _cursor->render();
4572+
4573+ _cursor->setClean();
4574+
4575+ if (_keyboard->isVisible())
4576+ _keyboard->render();
4577+
4578+ _keyboard->setClean();
4579+
4580+ _masterGuRenderer.guPostRender();
4581+
4582+ DEBUG_EXIT_FUNC();
4583+}
4584+
4585+inline bool DisplayManager::isTimeToUpdate() {
4586+
4587+#define MAX_FPS 30
4588+
4589+ uint32 now = g_system->getMillis();
4590+ if (now - _lastUpdateTime < (1000 / MAX_FPS))
4591+ return false;
4592+
4593+ _lastUpdateTime = now;
4594+ return true;
4595+}
4596+
4597+Common::List<Graphics::PixelFormat> DisplayManager::getSupportedPixelFormats() {
4598+ Common::List<Graphics::PixelFormat> list;
4599+
4600+ // In order of preference
4601+ list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_5650));
4602+ list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_5551));
4603+ list.push_back(PSPPixelFormat::convertToScummvmPixelFormat(PSPPixelFormat::Type_4444));
4604+ list.push_back(Graphics::PixelFormat::createFormatCLUT8());
4605+
4606+ return list;
4607+}
4608+
4609Index: backends/platform/psp/input.h
4610===================================================================
4611--- backends/platform/psp/input.h (revision 0)
4612+++ backends/platform/psp/input.h (revision 0)
4613@@ -0,0 +1,64 @@
4614+/* ScummVM - Graphic Adventure Engine
4615+ *
4616+ * ScummVM is the legal property of its developers, whose names
4617+ * are too numerous to list here. Please refer to the COPYRIGHT
4618+ * file distributed with this source distribution.
4619+ *
4620+ * This program is free software; you can redistribute it and/or
4621+ * modify it under the terms of the GNU General Public License
4622+ * as published by the Free Software Foundation; either version 2
4623+ * of the License, or (at your option) any later version.
4624+
4625+ * This program is distributed in the hope that it will be useful,
4626+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4627+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4628+ * GNU General Public License for more details.
4629+
4630+ * You should have received a copy of the GNU General Public License
4631+ * along with this program; if not, write to the Free Software
4632+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
4633+ *
4634+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
4635+ * $Id: osys_psp.cpp 43618 2009-08-21 22:44:49Z joostp $
4636+ *
4637+ */
4638+
4639+#ifndef PSP_INPUT_H
4640+#define PSP_INPUT_H
4641+
4642+#include "common/scummsys.h"
4643+#include "common/events.h"
4644+#include "backends/platform/psp/display_client.h"
4645+#include "backends/platform/psp/default_display_client.h"
4646+#include "backends/platform/psp/pspkeyboard.h"
4647+#include "backends/platform/psp/cursor.h"
4648+#include <pspctrl.h>
4649+
4650+class InputHandler {
4651+public:
4652+ InputHandler() : _cursor(0), _keyboard(0), _prevButtons(0), _lastPadCheckTime(0), _buttonsChanged(0), _dpadX(0), _dpadY(0) {}
4653+ const char *getObjectName() { return "InputHandler"; }
4654+
4655+ void init();
4656+ bool getAllInputs(Common::Event &event);
4657+ void setKeyboard(PSPKeyboard *keyboard) { _keyboard = keyboard; }
4658+ void setCursor(Cursor *cursor) { _cursor = cursor; }
4659+
4660+private:
4661+ Cursor *_cursor;
4662+ PSPKeyboard *_keyboard;
4663+ uint32 _prevButtons;
4664+ uint32 _lastPadCheckTime;
4665+ uint32 _buttonsChanged;
4666+ int32 _dpadX, _dpadY;
4667+ int32 _accelX, _accelY;
4668+
4669+ bool getEvent(Common::Event &event, SceCtrlData &pad);
4670+ bool getDpadEvent(Common::Event &event, SceCtrlData &pad);
4671+ bool getButtonEvent(Common::Event &event, SceCtrlData &pad);
4672+ bool getNubEvent(Common::Event &event, SceCtrlData &pad);
4673+ int32 modifyNubAxisMotion(int32 input);
4674+ Common::KeyCode translateDpad(int x, int y);
4675+};
4676+
4677+#endif /* PSP_INPUT_H */
4678Index: backends/platform/psp/default_display_client.cpp
4679===================================================================
4680--- backends/platform/psp/default_display_client.cpp (revision 0)
4681+++ backends/platform/psp/default_display_client.cpp (revision 0)
4682@@ -0,0 +1,238 @@
4683+/* ScummVM - Graphic Adventure Engine
4684+ *
4685+ * ScummVM is the legal property of its developers, whose names
4686+ * are too numerous to list here. Please refer to the COPYRIGHT
4687+ * file distributed with this source distribution.
4688+ *
4689+ * This program is free software; you can redistribute it and/or
4690+ * modify it under the terms of the GNU General Public License
4691+ * as published by the Free Software Foundation; either version 2
4692+ * of the License, or (at your option) any later version.
4693+
4694+ * This program is distributed in the hope that it will be useful,
4695+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4696+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4697+ * GNU General Public License for more details.
4698+
4699+ * You should have received a copy of the GNU General Public License
4700+ * along with this program; if not, write to the Free Software
4701+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
4702+ *
4703+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.h $
4704+ * $Id: osys_psp.h 46120 2009-11-24 10:33:30Z Bluddy $
4705+ *
4706+ */
4707+
4708+#include "common/scummsys.h"
4709+#include "backends/platform/psp/display_client.h"
4710+#include "backends/platform/psp/default_display_client.h"
4711+
4712+//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */
4713+//#define __PSP_DEBUG_PRINT__
4714+
4715+#include "backends/platform/psp/trace.h"
4716+
4717+// Class DefaultDisplayClient ---------------------------------------------
4718+
4719+bool DefaultDisplayClient::allocate(bool bufferInVram /* = false */, bool paletteInVram /* = false */) {
4720+ DEBUG_ENTER_FUNC();
4721+
4722+ if (!_buffer.allocate(bufferInVram)) {
4723+ PSP_ERROR("Couldn't allocate buffer.\n");
4724+ DEBUG_EXIT_FUNC();
4725+ return false;
4726+ }
4727+
4728+ if (_buffer.hasPalette())
4729+ {
4730+ PSP_DEBUG_PRINT("_palette[%p]\n", &_palette);
4731+
4732+ if (!_palette.allocate()) {
4733+ PSP_ERROR("Couldn't allocate pallette.\n");
4734+ DEBUG_EXIT_FUNC();
4735+ return false;
4736+ }
4737+ }
4738+
4739+ DEBUG_EXIT_FUNC();
4740+ return true;
4741+}
4742+
4743+void DefaultDisplayClient::deallocate() {
4744+ _buffer.deallocate();
4745+ if (_buffer.hasPalette())
4746+ _palette.deallocate();
4747+}
4748+
4749+
4750+void DefaultDisplayClient::clearBuffer() {
4751+ DEBUG_ENTER_FUNC();
4752+ _buffer.clear();
4753+ setDirty();
4754+ DEBUG_EXIT_FUNC();
4755+}
4756+
4757+inline void DefaultDisplayClient::clearPalette() {
4758+ DEBUG_ENTER_FUNC();
4759+ _palette.clear();
4760+ setDirty();
4761+ DEBUG_EXIT_FUNC();
4762+}
4763+
4764+void DefaultDisplayClient::init() {
4765+ DEBUG_ENTER_FUNC();
4766+ _renderer.setBuffer(&_buffer);
4767+ _renderer.setPalette(&_palette);
4768+ DEBUG_EXIT_FUNC();
4769+}
4770+
4771+void DefaultDisplayClient::copyFromRect(const byte *buf, int pitch, int destX, int destY, int recWidth, int recHeight) {
4772+ DEBUG_ENTER_FUNC();
4773+ _buffer.copyFromRect(buf, pitch, destX, destY, recWidth, recHeight);
4774+ setDirty();
4775+ DEBUG_EXIT_FUNC();
4776+}
4777+
4778+void DefaultDisplayClient::copyToArray(byte *dst, int pitch) {
4779+ DEBUG_ENTER_FUNC();
4780+ _buffer.copyToArray(dst, pitch);
4781+ DEBUG_EXIT_FUNC();
4782+}
4783+
4784+// Class Overlay -------------------------------------------------------
4785+
4786+void Overlay::init() {
4787+ DEBUG_ENTER_FUNC();
4788+
4789+ DefaultDisplayClient::init();
4790+ _renderer.setAlphaBlending(true);
4791+ _renderer.setColorTest(false);
4792+ _renderer.setUseGlobalScaler(false);
4793+ _renderer.setFullScreen(true); // speeds up render slightly
4794+
4795+ DEBUG_EXIT_FUNC();
4796+}
4797+
4798+void Overlay::setBytesPerPixel(uint32 size) {
4799+ DEBUG_ENTER_FUNC();
4800+
4801+ switch (size) {
4802+ case 1:
4803+ _buffer.setPixelFormat(PSPPixelFormat::Type_Palette_8bit);
4804+ _palette.setPixelFormats(PSPPixelFormat::Type_4444, PSPPixelFormat::Type_Palette_8bit);
4805+ break;
4806+ case 2:
4807+ _buffer.setPixelFormat(PSPPixelFormat::Type_4444);
4808+ break;
4809+ case 4:
4810+ _buffer.setPixelFormat(PSPPixelFormat::Type_8888);
4811+ break;
4812+ }
4813+
4814+ DEBUG_EXIT_FUNC();
4815+}
4816+
4817+void Overlay::setSize(uint32 width, uint32 height) {
4818+ DEBUG_ENTER_FUNC();
4819+ _buffer.setSize(width, height, Buffer::kSizeBySourceSize);
4820+ _renderer.setDrawWholeBuffer(); // We need to let the renderer know how much to draw
4821+ DEBUG_EXIT_FUNC();
4822+}
4823+
4824+void Overlay::copyToArray(OverlayColor *buf, int pitch) {
4825+ DEBUG_ENTER_FUNC();
4826+ _buffer.copyToArray((byte *)buf, pitch * sizeof(OverlayColor)); // Change to bytes
4827+ DEBUG_EXIT_FUNC();
4828+}
4829+
4830+void Overlay::copyFromRect(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
4831+ DEBUG_ENTER_FUNC();
4832+
4833+ _buffer.copyFromRect((byte *)buf, pitch * sizeof(OverlayColor), x, y, w, h); // Change to bytes
4834+ // debug
4835+ //_buffer.print(0xFF);
4836+ setDirty();
4837+ DEBUG_EXIT_FUNC();
4838+}
4839+
4840+bool Overlay::allocate() {
4841+ DEBUG_ENTER_FUNC();
4842+
4843+ bool ret = DefaultDisplayClient::allocate(true, false); // buffer in VRAM
4844+
4845+ DEBUG_EXIT_FUNC();
4846+ return ret;
4847+}
4848+
4849+// Class Screen -----------------------------------------------------------
4850+
4851+void Screen::init() {
4852+ DEBUG_ENTER_FUNC();
4853+
4854+ DefaultDisplayClient::init();
4855+ _renderer.setAlphaBlending(false);
4856+ _renderer.setColorTest(false);
4857+ _renderer.setUseGlobalScaler(true);
4858+ _renderer.setFullScreen(true);
4859+
4860+ DEBUG_EXIT_FUNC();
4861+}
4862+
4863+void Screen::setShakePos(int pos) {
4864+ _shakePos = pos;
4865+ _renderer.setOffsetOnScreen(0, pos);
4866+ setDirty();
4867+}
4868+
4869+void Screen::setSize(uint32 width, uint32 height) {
4870+ DEBUG_ENTER_FUNC();
4871+
4872+ _buffer.setSize(width, height, Buffer::kSizeBySourceSize);
4873+ _renderer.setDrawWholeBuffer(); // We need to let the renderer know how much to draw
4874+
4875+ DEBUG_EXIT_FUNC();
4876+}
4877+
4878+void Screen::setScummvmPixelFormat(const Graphics::PixelFormat *format) {
4879+ DEBUG_ENTER_FUNC();
4880+ PSP_DEBUG_PRINT("format[%p], _buffer[%p], _palette[%p]\n", format, &_buffer, &_palette);
4881+
4882+ if (!format) {
4883+ bzero(&_pixelFormat, sizeof(_pixelFormat));
4884+ _pixelFormat.bytesPerPixel = 1; // default
4885+ } else {
4886+ _pixelFormat = *format;
4887+ }
4888+
4889+ PSPPixelFormat::Type bufferFormat, paletteFormat;
4890+ bool swapRedBlue = false;
4891+
4892+ PSPPixelFormat::convertFromScummvmPixelFormat(format, bufferFormat, paletteFormat, swapRedBlue);
4893+ _buffer.setPixelFormat(bufferFormat, swapRedBlue);
4894+ _palette.setPixelFormats(paletteFormat, bufferFormat, swapRedBlue);
4895+
4896+ DEBUG_EXIT_FUNC();
4897+}
4898+
4899+Graphics::Surface *Screen::lockAndGetForEditing() {
4900+ DEBUG_ENTER_FUNC();
4901+
4902+ _frameBuffer.pixels = _buffer.getPixels();
4903+ _frameBuffer.w = _buffer.getSourceWidth();
4904+ _frameBuffer.h = _buffer.getSourceHeight();
4905+ _frameBuffer.pitch = _buffer.getBytesPerPixel() * _buffer.getWidth();
4906+ _frameBuffer.bytesPerPixel = _buffer.getBytesPerPixel();
4907+ // We'll set to dirty once we unlock the screen
4908+
4909+ DEBUG_EXIT_FUNC();
4910+
4911+ return &_frameBuffer;
4912+}
4913+
4914+bool Screen::allocate() {
4915+ DEBUG_ENTER_FUNC();
4916+
4917+ return DefaultDisplayClient::allocate(true, false); // buffer in VRAM
4918+
4919+ DEBUG_EXIT_FUNC();
4920+}
4921Index: backends/platform/psp/display_client.h
4922===================================================================
4923--- backends/platform/psp/display_client.h (revision 0)
4924+++ backends/platform/psp/display_client.h (revision 0)
4925@@ -0,0 +1,243 @@
4926+/* ScummVM - Graphic Adventure Engine
4927+ *
4928+ * ScummVM is the legal property of its developers, whose names
4929+ * are too numerous to list here. Please refer to the COPYRIGHT
4930+ * file distributed with this source distribution.
4931+ *
4932+ * This program is free software; you can redistribute it and/or
4933+ * modify it under the terms of the GNU General Public License
4934+ * as published by the Free Software Foundation; either version 2
4935+ * of the License, or (at your option) any later version.
4936+
4937+ * This program is distributed in the hope that it will be useful,
4938+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4939+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4940+ * GNU General Public License for more details.
4941+
4942+ * You should have received a copy of the GNU General Public License
4943+ * along with this program; if not, write to the Free Software
4944+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
4945+ *
4946+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
4947+ * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
4948+ *
4949+ */
4950+
4951+#ifndef PSP_GRAPHICS_H
4952+#define PSP_GRAPHICS_H
4953+
4954+#include "common/singleton.h"
4955+#include "graphics/surface.h"
4956+#include "common/system.h"
4957+#include "backends/platform/psp/psppixelformat.h"
4958+#include "backends/platform/psp/memory.h"
4959+
4960+#define MAX_TEXTURE_SIZE 512
4961+
4962+class DisplayManager;
4963+class GuRenderer;
4964+
4965+/**
4966+ * Interface to inherit for all display clients
4967+ * We deliberately avoid virtual functions for speed.
4968+ */
4969+class DisplayClient { // Abstract class
4970+public:
4971+ DisplayClient() {}
4972+ bool isVisible() { return true; }
4973+ bool isDirty() { return true; }
4974+ void setClean() {}
4975+ void render() {}
4976+ virtual ~DisplayClient() {}
4977+};
4978+
4979+/**
4980+ * Vertex used for GU rendering
4981+ */
4982+struct Vertex {
4983+ float u,v;
4984+ float x,y,z;
4985+};
4986+
4987+struct Point {
4988+ int x;
4989+ int y;
4990+ Point() : x(0), y(0) {}
4991+};
4992+
4993+/**
4994+ * Dimensions struct for simplification
4995+ */
4996+struct Dimensions {
4997+ uint32 width;
4998+ uint32 height;
4999+ Dimensions() : width(0), height(0) {}
5000+};
5001+
5002+/**
5003+ * Universal PSP Palette class
5004+ * Use this in any class that wishes to draw to the PSP screen.
5005+ * Use together with GuRenderer
5006+ */
5007+class Palette {
5008+public:
5009+ Palette() : _values(0), _numOfEntries(0) {}
5010+ virtual ~Palette() { deallocate(); }
5011+ const char *getObjectName() { return "Palette";}
5012+ bool allocate();
5013+ void deallocate();
5014+ void clear();
5015+ void setPixelFormats(PSPPixelFormat::Type paletteType, PSPPixelFormat::Type bufferType, bool swapRedBlue = false);
5016+ void setNumOfEntries(uint32 num) { _numOfEntries = num; }
5017+ uint32 getNumOfEntries() { return _numOfEntries; }
5018+ uint32 getSizeInBytes() { return _pixelFormat.pixelsToBytes(_numOfEntries); }
5019+ void set(byte *values) { setPartial(values, 0, _numOfEntries); }
5020+ void setPartial(const byte *colors, uint start, uint num, bool supportsAlpha = false);
5021+ void getPartial(byte *colors, uint start, uint num);
5022+ uint32 getRawColorAt(uint32 position);
5023+ uint32 getRGBAColorAt(uint32 position);
5024+ void setSingleColorRGBA(uint32 num, byte r, byte g, byte b, byte a);
5025+ void clearColor(uint32 color);
5026+ byte *getRawValues() { return _values; }
5027+ bool isAllocated() { return (_values != 0); }
5028+ PSPPixelFormat::Type getPixelFormat() { return _pixelFormat.format; }
5029+ void print(uint32 numToPrint = 0); // print to screen
5030+
5031+protected:
5032+ byte *_values; ///< array of palette data
5033+ uint32 _numOfEntries; ///< number of palette entries
5034+ PSPPixelFormat _pixelFormat; ///< pixel format of the palette data
5035+};
5036+
5037+/**
5038+ * Universal PSP buffer/texture object
5039+ * Use this in any class that wishes to draw to the PSP screen.
5040+ * Use together with GuRenderer
5041+ */
5042+class Buffer {
5043+public:
5044+ enum HowToSize {
5045+ kSizeByTextureSize, // buffer size is determined by power of 2 roundup for texture
5046+ kSizeBySourceSize // buffer size is determined by source size
5047+ };
5048+
5049+ Buffer() : _pixels(0), _width(0), _height(0) {}
5050+ virtual ~Buffer() { deallocate(); }
5051+ const char *getObjectName() { return "Buffer"; }
5052+
5053+ // setters
5054+ void setSize(uint32 width, uint32 height, HowToSize textureOrSource=kSizeByTextureSize);
5055+ void setBitsPerPixel(uint32 bits) { _pixelFormat.bitsPerPixel = bits; }
5056+ void setBytesPerPixel(uint32 bytes) { setBitsPerPixel(bytes << 3); }
5057+ void setPixelFormat(PSPPixelFormat::Type type, bool swapRedBlue = false);
5058+
5059+ // getters
5060+ uint32 getWidth() { return _width; }
5061+ uint32 getWidthInBytes() { return _pixelFormat.pixelsToBytes(getWidth()); }
5062+ uint32 getHeight() { return _height; }
5063+ uint32 getSourceWidth() { return _sourceSize.width; }
5064+ uint32 getSourceWidthInBytes() { return _pixelFormat.pixelsToBytes(_sourceSize.width); }
5065+ uint32 getSourceHeight() { return _sourceSize.height; }
5066+ uint32 getTextureWidth() { return _textureSize.width; }
5067+ uint32 getTextureHeight() { return _textureSize.height; }
5068+ PSPPixelFormat::Type getPixelFormat() { return _pixelFormat.format; }
5069+ uint32 getBitsPerPixel() { return _pixelFormat.bitsPerPixel; }
5070+ uint32 getBytesPerPixel() { return getBitsPerPixel() >> 3; } /* won't work for 4-bit */
5071+ byte *getPixels() { return _pixels; }
5072+ uint32 getSizeInBytes() { return _pixelFormat.pixelsToBytes(_width * _height); }
5073+
5074+ bool hasPalette();
5075+ void copyFromArray(const byte *buffer, int pitch);
5076+ void copyFromRect(const byte *buf, uint32 pitch, int destX, int destY, uint32 recWidth, uint32 recHeight);
5077+ void copyToArray(byte *dst, int pitch);
5078+ bool allocate(bool inVram = false);
5079+ void deallocate();
5080+ bool isAllocated() { return (_pixels != 0) ; }
5081+ void clear();
5082+ void flipNibbles(); // To handle peculiarities of PSP's 4 bit textures
5083+ static uint32 scaleUpToPowerOfTwo(uint32 size);
5084+ void print(uint32 mask, uint32 numToPrint = 0);
5085+
5086+protected:
5087+ friend class GuRenderer;
5088+ byte *_pixels;
5089+ uint32 _width; ///< True allocated width
5090+ uint32 _height; ///< True allocated height
5091+ Dimensions _textureSize; ///< Size rounded up to power of 2. Used for drawing
5092+ Dimensions _sourceSize; ///< Original size of the buffer
5093+ PSPPixelFormat _pixelFormat; ///< Format of the buffer
5094+};
5095+
5096+/**
5097+ * Universal rendering class for PSP
5098+ * Use this if you want to draw to the screen.
5099+ * Needs to be supplied with a Buffer and a Palette
5100+ */
5101+class GuRenderer {
5102+public:
5103+ // Constructors
5104+ GuRenderer() : _useGlobalScaler(false), _buffer(0), _palette(0), _blending(false), _alphaReverse(false), _colorTest(false), _keyColor(0), _fullScreen(false) {}
5105+ GuRenderer(Buffer *buffer, Palette *palette) : _useGlobalScaler(false), _buffer(buffer), _palette(palette), _blending(false), _alphaReverse(false), _colorTest(false), _keyColor(0), _fullScreen(false) {}
5106+ static void setDisplayManager(DisplayManager *dm) { _displayManager = dm; } // Called by the Display Manager
5107+ const char *getObjectName() { return "GuRenderer"; }
5108+
5109+ // Setters
5110+ void setDrawSize(uint32 width, uint32 height) { // How big of an area to draw
5111+ _drawSize.width = width;
5112+ _drawSize.height = height;
5113+ }
5114+ void setDrawWholeBuffer() { // Draw the full size of the current buffer
5115+ assert(_buffer);
5116+ _drawSize.width = _buffer->getSourceWidth();
5117+ _drawSize.height = _buffer->getSourceHeight();
5118+ }
5119+ void setBuffer(Buffer *buffer) { _buffer = buffer; }
5120+ void setPalette(Palette *palette) { _palette = palette; }
5121+ void setMaxTextureOffsetByIndex(uint32 x, uint32 y); // For drawing multiple textures
5122+ void setOffsetOnScreen(uint32 x, uint32 y) { _offsetOnScreen.x = x; _offsetOnScreen.y = y; }
5123+ void setOffsetInBuffer(uint32 x, uint32 y) { _offsetInBuffer.x = x; _offsetInBuffer.y = y; }
5124+ void setColorTest(bool value) { _colorTest = value; }
5125+ void setKeyColor(uint32 value) { _keyColor = _buffer->_pixelFormat.convertTo32BitColor(value); }
5126+ void setAlphaBlending(bool value) { _blending = value; }
5127+ void setAlphaReverse(bool value) { _alphaReverse = value; }
5128+ void setFullScreen(bool value) { _fullScreen = value; } // Shortcut for rendering
5129+ void setUseGlobalScaler(bool value) { _useGlobalScaler = value; } // Scale to screen
5130+
5131+ static void cacheInvalidate(void *pointer, uint32 size);
5132+
5133+ void render(); // Default rendering function. This should be good enough for most purposes
5134+
5135+protected:
5136+ // Gu functions
5137+ void fillVertices(Vertex *vertices); // Fill in vertices with coordinates
5138+ void guProgramDrawBehavior();
5139+ Vertex *guGetVertices();
5140+ void guLoadTexture();
5141+ void guLoadPalette();
5142+ void guProgramTextureFormat();
5143+ void guProgramTextureBitDepth();
5144+ void guDrawVertices(Vertex *vertices);
5145+
5146+ uint32 convertToGuPixelFormat(PSPPixelFormat::Type format);
5147+ float scaleSourceToOutputX(float offset);
5148+ float scaleSourceToOutputY(float offset);
5149+
5150+ friend class MasterGuRenderer;
5151+ Point _maxTextureOffset; ///> For rendering textures > 512 pixels
5152+ Point _offsetOnScreen; ///> Where on screen to draw
5153+ Point _offsetInBuffer; ///> Where in the texture to draw
5154+ bool _useGlobalScaler; ///> Scale to the output size on screen
5155+ Buffer *_buffer;
5156+ Palette *_palette;
5157+ static DisplayManager *_displayManager;
5158+ Dimensions _drawSize; ///> Actual size to draw out of the Buffer
5159+ bool _blending;
5160+ bool _alphaReverse; ///> 0 counts as full alpha
5161+ bool _colorTest;
5162+ uint32 _keyColor; ///> Color to test against for color test. in 32 bits.
5163+ bool _fullScreen; ///> Speeds up for fullscreen rendering
5164+};
5165+
5166+#endif /* PSP_SCREEN_H */
5167Index: backends/platform/psp/memory.h
5168===================================================================
5169--- backends/platform/psp/memory.h (revision 0)
5170+++ backends/platform/psp/memory.h (revision 0)
5171@@ -0,0 +1,81 @@
5172+
5173+/* ScummVM - Graphic Adventure Engine
5174+ *
5175+ * ScummVM is the legal property of its developers, whose names
5176+ * are too numerous to list here. Please refer to the COPYRIGHT
5177+ * file distributed with this source distribution.
5178+ *
5179+ * This program is free software; you can redistribute it and/or
5180+ * modify it under the terms of the GNU General Public License
5181+ * as published by the Free Software Foundation; either version 2
5182+ * of the License, or (at your option) any later version.
5183+
5184+ * This program is distributed in the hope that it will be useful,
5185+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5186+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5187+ * GNU General Public License for more details.
5188+
5189+ * You should have received a copy of the GNU General Public License
5190+ * along with this program; if not, write to the Free Software
5191+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
5192+ *
5193+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
5194+ * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
5195+ *
5196+ */
5197+
5198+#ifndef PSP_MEMORY_H
5199+#define PSP_MEMORY_H
5200+
5201+#define UNCACHED(x) ((byte *)(((uint32)(x)) | 0x40000000)) /* make an uncached access */
5202+#define CACHED(x) ((byte *)(((uint32)(x)) & 0xBFFFFFFF)) /* make an uncached access into a cached one */
5203+
5204+/**
5205+ * Class that does memory copying and swapping if needed
5206+ */
5207+class Copier {
5208+public:
5209+ static void copy(byte *dst, const byte *src, uint32 bytes, PSPPixelFormat *format = NULL);
5210+ static void copy8(byte *dst, const byte *src, uint32 bytes);
5211+ static void copy16(uint16 *dst, const uint16 *src, uint32 bytes, PSPPixelFormat *format = NULL);
5212+};
5213+
5214+/**
5215+ * Class that allocates memory in the VRAM
5216+ */
5217+class VramAllocator : public Common::Singleton<VramAllocator> {
5218+public:
5219+ VramAllocator() : _bytesAllocated(0) {}
5220+ const char *getObjectName() { return "VramAllocator"; }
5221+ void *allocate(int32 size, bool smallAllocation = false); // smallAllocation e.g. palettes
5222+ void deallocate(void *pointer);
5223+
5224+ static inline bool isAddressInVram(void *address) {
5225+ if ((uint32)(CACHED(address)) >= VRAM_START_ADDRESS && (uint32)(CACHED(address)) < VRAM_END_ADDRESS)
5226+ return true;
5227+ return false;
5228+}
5229+
5230+
5231+private:
5232+ /**
5233+ * Used to allocate in VRAM
5234+ */
5235+ struct Allocation {
5236+ byte *address;
5237+ uint32 size;
5238+ void *getEnd() { return address + size; }
5239+ Allocation(void *Address, uint32 Size) : address((byte *)Address), size(Size) {}
5240+ Allocation() : address(0), size(0) {}
5241+ };
5242+
5243+ enum {
5244+ VRAM_START_ADDRESS = 0x04000000,
5245+ VRAM_END_ADDRESS = 0x04200000,
5246+ VRAM_SMALL_ADDRESS = VRAM_END_ADDRESS - (4*1024) // 4K in the end for small allocations
5247+ };
5248+ Common::List <Allocation> _allocList; // List of allocations
5249+ uint32 _bytesAllocated;
5250+};
5251+
5252+#endif /* PSP_MEMORY_H */
5253Index: backends/platform/psp/osys_psp.cpp
5254===================================================================
5255--- backends/platform/psp/osys_psp.cpp (revision 48355)
5256+++ backends/platform/psp/osys_psp.cpp (working copy)
5257@@ -23,6 +23,7 @@
5258 *
5259 */
5260
5261+#include <pspuser.h>
5262 #include <pspgu.h>
5263 #include <pspdisplay.h>
5264
5265@@ -33,128 +34,77 @@
5266 #include "common/events.h"
5267 #include "common/scummsys.h"
5268
5269-#include "osys_psp.h"
5270-#include "trace.h"
5271-#include "powerman.h"
5272+#include "backends/platform/psp/osys_psp.h"
5273+#include "backends/platform/psp/powerman.h"
5274
5275 #include "backends/saves/psp/psp-saves.h"
5276 #include "backends/timer/default/default-timer.h"
5277 #include "graphics/surface.h"
5278 #include "sound/mixer_intern.h"
5279
5280-#include "backends/platform/psp/pspkeyboard.h"
5281+//#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */
5282+//#define __PSP_DEBUG_PRINT__ /* For debug printouts */
5283
5284+#include "backends/platform/psp/trace.h"
5285
5286+
5287 #define SAMPLES_PER_SEC 44100
5288
5289-#define PIXEL_SIZE (4)
5290-#define BUF_WIDTH (512)
5291-#define PSP_SCREEN_WIDTH 480
5292-#define PSP_SCREEN_HEIGHT 272
5293-#define PSP_FRAME_SIZE (BUF_WIDTH * PSP_SCREEN_HEIGHT * PIXEL_SIZE)
5294-#define MOUSE_SIZE 128
5295-#define KBD_DATA_SIZE 130560
5296-
5297-#define MAX_FPS 30
5298-
5299-unsigned int __attribute__((aligned(16))) displayList[2048];
5300-unsigned short __attribute__((aligned(16))) clut256[256];
5301-unsigned short __attribute__((aligned(16))) mouseClut[256];
5302-unsigned short __attribute__((aligned(16))) cursorPalette[256];
5303-unsigned int __attribute__((aligned(16))) mouseBuf256[MOUSE_SIZE*MOUSE_SIZE];
5304-
5305-
5306-unsigned long RGBToColour(unsigned long r, unsigned long g, unsigned long b) {
5307- return (((b >> 3) << 10) | ((g >> 3) << 5) | ((r >> 3) << 0)) | 0x8000;
5308-}
5309-
5310 static int timer_handler(int t) {
5311 DefaultTimerManager *tm = (DefaultTimerManager *)g_system->getTimerManager();
5312 tm->handler();
5313 return t;
5314 }
5315
5316-const OSystem::GraphicsMode OSystem_PSP::s_supportedGraphicsModes[] = {
5317- { "320x200 (centered)", "320x200 16-bit centered", CENTERED_320X200 },
5318- { "435x272 (best-fit, centered)", "435x272 16-bit centered", CENTERED_435X272 },
5319- { "480x272 (full screen)", "480x272 16-bit stretched", STRETCHED_480X272 },
5320- { "362x272 (4:3, centered)", "362x272 16-bit centered", CENTERED_362X272 },
5321- {0, 0, 0}
5322-};
5323+const char *OSystem_PSP::getObjectName() const {
5324+ return "OSystem_PSP";
5325+}
5326
5327+void OSystem_PSP::initSDL() {
5328+ SDL_Init(SDL_INIT_AUDIO | SDL_INIT_TIMER);
5329+}
5330
5331-OSystem_PSP::OSystem_PSP() : _screenWidth(0), _screenHeight(0), _overlayWidth(0), _overlayHeight(0),
5332- _offscreen(0), _overlayBuffer(0), _overlayVisible(false), _shakePos(0), _lastScreenUpdate(0),
5333- _mouseBuf(0), _prevButtons(0), _lastPadCheck(0), _mixer(0) {
5334- memset(_palette, 0, sizeof(_palette));
5335+OSystem_PSP::~OSystem_PSP() {}
5336
5337- _cursorPaletteDisabled = true;
5338+#define PSP_SCREEN_WIDTH 480
5339+#define PSP_SCREEN_HEIGHT 272
5340
5341- //init SDL
5342- uint32 sdlFlags = SDL_INIT_AUDIO | SDL_INIT_TIMER;
5343- SDL_Init(sdlFlags);
5344+void OSystem_PSP::initBackend() {
5345+ DEBUG_ENTER_FUNC();
5346
5347- _clut = clut256;
5348- _mouseBuf = (byte *)mouseBuf256;
5349- _graphicMode = STRETCHED_480X272;
5350+ _cursor.enableCursorPalette(false);
5351+ _cursor.setXY(PSP_SCREEN_WIDTH >> 1, PSP_SCREEN_HEIGHT >> 1); // Mouse in the middle of the screen
5352+
5353+ // Set pointers for display manager
5354+ _displayManager.setCursor(&_cursor);
5355+ _displayManager.setScreen(&_screen);
5356+ _displayManager.setOverlay(&_overlay);
5357+ _displayManager.setKeyboard(&_keyboard);
5358+ _displayManager.init();
5359
5360- _mouseX = PSP_SCREEN_WIDTH >> 1; // Mouse in the middle of the screen
5361- _mouseY = PSP_SCREEN_HEIGHT >> 1;
5362- _dpadX = _dpadY = 0;
5363+ // Set pointers for input handler
5364+ _inputHandler.setCursor(&_cursor);
5365+ _inputHandler.setKeyboard(&_keyboard);
5366+ _inputHandler.init();
5367
5368+ initSDL();
5369
5370- // Init GU
5371- sceGuInit();
5372- sceGuStart(0, displayList);
5373- sceGuDrawBuffer(GU_PSM_8888, (void *)0, BUF_WIDTH);
5374- sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, (void*)PSP_FRAME_SIZE, BUF_WIDTH);
5375- sceGuDepthBuffer((void*)(PSP_FRAME_SIZE * 2), BUF_WIDTH);
5376- sceGuOffset(2048 - (PSP_SCREEN_WIDTH/2), 2048 - (PSP_SCREEN_HEIGHT/2));
5377- sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
5378- sceGuDepthRange(0xC350, 0x2710);
5379- sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
5380- sceGuEnable(GU_SCISSOR_TEST);
5381- sceGuFrontFace(GU_CW);
5382- sceGuEnable(GU_TEXTURE_2D);
5383- sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT);
5384- sceGuFinish();
5385- sceGuSync(0,0);
5386-
5387- sceDisplayWaitVblankStart();
5388- sceGuDisplay(1);
5389-
5390-}
5391-
5392-OSystem_PSP::~OSystem_PSP() {
5393-
5394- free(_offscreen);
5395- free(_overlayBuffer);
5396- free(_mouseBuf);
5397- delete _keyboard;
5398-
5399- _offscreen = 0;
5400- _overlayBuffer = 0;
5401- _mouseBuf = 0;
5402- sceGuTerm();
5403-}
5404-
5405-
5406-void OSystem_PSP::initBackend() {
5407 _savefile = new PSPSaveFileManager;
5408
5409 _timer = new DefaultTimerManager();
5410
5411- _keyboard = new PSPKeyboard();
5412- _keyboard->load();
5413-
5414+ PSP_DEBUG_PRINT("calling keyboard.load()\n");
5415+ _keyboard.load(); // Load virtual keyboard files into memory
5416+
5417 setTimerCallback(&timer_handler, 10);
5418
5419 setupMixer();
5420
5421 OSystem::initBackend();
5422+
5423+ DEBUG_EXIT_FUNC();
5424 }
5425
5426-
5427 bool OSystem_PSP::hasFeature(Feature f) {
5428 return (f == kFeatureOverlaySupportsAlpha || f == kFeatureCursorHasPalette);
5429 }
5430@@ -167,735 +117,253 @@
5431 }
5432
5433 const OSystem::GraphicsMode* OSystem_PSP::getSupportedGraphicsModes() const {
5434- return s_supportedGraphicsModes;
5435+ return _displayManager.getSupportedGraphicsModes();
5436 }
5437
5438-
5439 int OSystem_PSP::getDefaultGraphicsMode() const {
5440- return STRETCHED_480X272;
5441+ DEBUG_ENTER_FUNC();
5442+
5443+ int ret = _displayManager.getDefaultGraphicsMode();
5444+
5445+ DEBUG_EXIT_FUNC();
5446+ return ret;
5447 }
5448
5449 bool OSystem_PSP::setGraphicsMode(int mode) {
5450- _graphicMode = mode;
5451- return true;
5452+ DEBUG_ENTER_FUNC();
5453+
5454+ int ret = _displayManager.setGraphicsMode(mode);
5455+
5456+ DEBUG_EXIT_FUNC();
5457+ return ret;
5458 }
5459
5460 bool OSystem_PSP::setGraphicsMode(const char *name) {
5461- int i = 0;
5462-
5463- while (s_supportedGraphicsModes[i].name) {
5464- if (!strcmpi(s_supportedGraphicsModes[i].name, name)) {
5465- _graphicMode = s_supportedGraphicsModes[i].id;
5466- return true;
5467- }
5468- i++;
5469- }
5470-
5471- return false;
5472+ DEBUG_ENTER_FUNC();
5473+
5474+ int ret = _displayManager.setGraphicsMode(name);
5475+
5476+ DEBUG_EXIT_FUNC();
5477+ return ret;
5478 }
5479
5480 int OSystem_PSP::getGraphicsMode() const {
5481- return _graphicMode;
5482+ DEBUG_ENTER_FUNC();
5483+
5484+ int ret = _displayManager.getGraphicsMode();
5485+
5486+ DEBUG_EXIT_FUNC();
5487+ return ret;
5488 }
5489
5490-void OSystem_PSP::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
5491- PSPDebugTrace("initSize\n");
5492+#ifdef USE_RGB_COLOR
5493
5494- _screenWidth = width;
5495- _screenHeight = height;
5496+Graphics::PixelFormat OSystem_PSP::getScreenFormat() const {
5497+ return _screen.getScummvmPixelFormat();
5498+}
5499
5500- const int scrBufSize = _screenWidth * _screenHeight * (format ? format->bytesPerPixel : 4);
5501+Common::List<Graphics::PixelFormat> OSystem_PSP::getSupportedFormats() {
5502+ return _displayManager.getSupportedPixelFormats();
5503+}
5504
5505- _overlayWidth = PSP_SCREEN_WIDTH; //width;
5506- _overlayHeight = PSP_SCREEN_HEIGHT; //height;
5507+#endif
5508
5509- free(_overlayBuffer);
5510- _overlayBuffer = (OverlayColor *)memalign(16, _overlayWidth * _overlayHeight * sizeof(OverlayColor));
5511+void OSystem_PSP::initSize(uint width, uint height, const Graphics::PixelFormat *format) {
5512+ DEBUG_ENTER_FUNC();
5513+
5514+ _displayManager.setSizeAndPixelFormat(width, height, format);
5515
5516- free(_offscreen);
5517- _offscreen = (byte *)memalign(16, scrBufSize);
5518- bzero(_offscreen, scrBufSize);
5519+ _cursor.setVisible(false);
5520+ _cursor.setLimits(_screen.getWidth(), _screen.getHeight());
5521
5522- clearOverlay();
5523- memset(_palette, 0xFFFF, 256 * sizeof(unsigned short));
5524-
5525- _mouseVisible = false;
5526- sceKernelDcacheWritebackAll();
5527+ DEBUG_EXIT_FUNC();
5528 }
5529
5530 int16 OSystem_PSP::getWidth() {
5531- return _screenWidth;
5532+ DEBUG_ENTER_FUNC();
5533+
5534+ int16 ret = (int16)_screen.getWidth();
5535+
5536+ DEBUG_EXIT_FUNC();
5537+ return ret;
5538 }
5539
5540 int16 OSystem_PSP::getHeight() {
5541- return _screenHeight;
5542+ DEBUG_ENTER_FUNC();
5543+
5544+ int16 ret = (int16)_screen.getHeight();
5545+
5546+ DEBUG_EXIT_FUNC();
5547+ return ret;
5548 }
5549
5550 void OSystem_PSP::setPalette(const byte *colors, uint start, uint num) {
5551- const byte *b = colors;
5552+ DEBUG_ENTER_FUNC();
5553+
5554+ _screen.setPartialPalette(colors, start, num);
5555+ _cursor.setScreenPalette(colors, start, num);
5556+ _cursor.clearKeyColor();
5557
5558- for (uint i = 0; i < num; ++i) {
5559- _palette[start + i] = RGBToColour(b[0], b[1], b[2]);
5560- b += 4;
5561- }
5562-
5563- //copy to CLUT
5564- memcpy(_clut, _palette, 256 * sizeof(unsigned short));
5565-
5566- //force update of mouse CLUT as well, as it may have been set up before this palette was set
5567- memcpy(mouseClut, _palette, 256 * sizeof(unsigned short));
5568- mouseClut[_mouseKeyColour] = 0;
5569-
5570- sceKernelDcacheWritebackAll();
5571+ DEBUG_EXIT_FUNC();
5572 }
5573
5574 void OSystem_PSP::setCursorPalette(const byte *colors, uint start, uint num) {
5575- const byte *b = colors;
5576+ DEBUG_ENTER_FUNC();
5577
5578- for (uint i = 0; i < num; ++i) {
5579- cursorPalette[start + i] = RGBToColour(b[0], b[1], b[2]);
5580- b += 4;
5581- }
5582+ _cursor.setCursorPalette(colors, start, num);
5583+ _cursor.enableCursorPalette(true);
5584+ _cursor.clearKeyColor(); // Do we need this?
5585
5586- cursorPalette[0] = 0;
5587-
5588- _cursorPaletteDisabled = false;
5589-
5590- sceKernelDcacheWritebackAll();
5591+ DEBUG_EXIT_FUNC();
5592 }
5593
5594 void OSystem_PSP::disableCursorPalette(bool disable) {
5595- _cursorPaletteDisabled = disable;
5596+ DEBUG_ENTER_FUNC();
5597+
5598+ _cursor.enableCursorPalette(!disable);
5599+
5600+ DEBUG_EXIT_FUNC();
5601 }
5602
5603 void OSystem_PSP::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
5604- //Clip the coordinates
5605- if (x < 0) {
5606- w += x;
5607- buf -= x;
5608- x = 0;
5609- }
5610+ DEBUG_ENTER_FUNC();
5611
5612- if (y < 0) {
5613- h += y;
5614- buf -= y * pitch;
5615- y = 0;
5616- }
5617+ _screen.copyFromRect(buf, pitch, x, y, w, h);
5618
5619- if (w > _screenWidth - x) {
5620- w = _screenWidth - x;
5621- }
5622-
5623- if (h > _screenHeight - y) {
5624- h = _screenHeight - y;
5625- }
5626-
5627- if (w <= 0 || h <= 0)
5628- return;
5629-
5630-
5631- byte *dst = _offscreen + y * _screenWidth + x;
5632-
5633- if (_screenWidth == pitch && pitch == w) {
5634- memcpy(dst, buf, h * w);
5635- } else {
5636- do {
5637- memcpy(dst, buf, w);
5638- buf += pitch;
5639- dst += _screenWidth;
5640- } while (--h);
5641- }
5642- sceKernelDcacheWritebackAll();
5643-
5644+ DEBUG_EXIT_FUNC();
5645 }
5646
5647 Graphics::Surface *OSystem_PSP::lockScreen() {
5648- _framebuffer.pixels = _offscreen;
5649- _framebuffer.w = _screenWidth;
5650- _framebuffer.h = _screenHeight;
5651- _framebuffer.pitch = _screenWidth;
5652- _framebuffer.bytesPerPixel = 1;
5653+ DEBUG_ENTER_FUNC();
5654
5655- return &_framebuffer;
5656+ Graphics::Surface *ret = _screen.lockAndGetForEditing();
5657+
5658+ DEBUG_EXIT_FUNC();
5659+ return ret;
5660 }
5661
5662 void OSystem_PSP::unlockScreen() {
5663- // The screen is always completely update anyway, so we don't have to force a full update here.
5664- sceKernelDcacheWritebackAll();
5665+ DEBUG_ENTER_FUNC();
5666+ // The screen is always completely updated anyway, so we don't have to force a full update here.
5667+ _screen.unlock();
5668+
5669+ DEBUG_EXIT_FUNC();
5670 }
5671
5672 void OSystem_PSP::updateScreen() {
5673- u32 now = getMillis();
5674- if (now - _lastScreenUpdate < 1000 / MAX_FPS)
5675- return;
5676+ DEBUG_ENTER_FUNC();
5677
5678- _lastScreenUpdate = now;
5679-
5680- sceGuStart(0, displayList);
5681-
5682- sceGuClearColor(0xFF000000);
5683- sceGuClear(GU_COLOR_BUFFER_BIT);
5684-
5685- sceGuClutMode(GU_PSM_5551, 0, 0xFF, 0);
5686- sceGuClutLoad(32, clut256); // upload 32*8 entries (256)
5687- sceGuTexMode(GU_PSM_T8, 0, 0, 0); // 8-bit image
5688- if (_screenWidth == 320)
5689- sceGuTexImage(0, 512, 256, _screenWidth, _offscreen);
5690- else
5691- sceGuTexImage(0, 512, 512, _screenWidth, _offscreen);
5692- sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGB);
5693- sceGuTexFilter(GU_LINEAR, GU_LINEAR);
5694- sceGuTexOffset(0,0);
5695- sceGuAmbientColor(0xFFFFFFFF);
5696- sceGuColor(0xFFFFFFFF);
5697-
5698- Vertex *vertices = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
5699- vertices[0].u = 0.5f;
5700- vertices[0].v = 0.5f;
5701- vertices[1].u = _screenWidth - 0.5f;
5702- vertices[1].v = _screenHeight - 0.5f;
5703-
5704- switch (_graphicMode) {
5705- case CENTERED_320X200:
5706- vertices[0].x = (PSP_SCREEN_WIDTH - 320) / 2;
5707- vertices[0].y = (PSP_SCREEN_HEIGHT - 200) / 2;
5708- vertices[0].z = 0;
5709- vertices[1].x = PSP_SCREEN_WIDTH - (PSP_SCREEN_WIDTH - 320) / 2;
5710- vertices[1].y = PSP_SCREEN_HEIGHT - (PSP_SCREEN_HEIGHT - 200) / 2;
5711- vertices[1].z = 0;
5712- break;
5713- case CENTERED_435X272:
5714- vertices[0].x = (PSP_SCREEN_WIDTH - 435) / 2;
5715- vertices[0].y = 0; vertices[0].z = 0;
5716- vertices[1].x = PSP_SCREEN_WIDTH - (PSP_SCREEN_WIDTH - 435) / 2;
5717- vertices[1].y = PSP_SCREEN_HEIGHT;
5718- vertices[1].z = 0;
5719- break;
5720- case STRETCHED_480X272:
5721- vertices[0].x = 0;
5722- vertices[0].y = 0;
5723- vertices[0].z = 0;
5724- vertices[1].x = PSP_SCREEN_WIDTH;
5725- vertices[1].y = PSP_SCREEN_HEIGHT;
5726- vertices[1].z = 0;
5727- break;
5728- case CENTERED_362X272:
5729- vertices[0].x = (PSP_SCREEN_WIDTH - 362) / 2;
5730- vertices[0].y = 0;
5731- vertices[0].z = 0;
5732- vertices[1].x = PSP_SCREEN_WIDTH - (PSP_SCREEN_WIDTH - 362) / 2;
5733- vertices[1].y = PSP_SCREEN_HEIGHT;
5734- vertices[1].z = 0;
5735- break;
5736- }
5737-
5738- if (_shakePos) {
5739- vertices[0].y += _shakePos;
5740- vertices[1].y += _shakePos;
5741- }
5742-
5743- sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
5744- if (_screenWidth == 640) {
5745- // 2nd draw
5746- Vertex *vertices2 = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
5747- sceGuTexImage(0, 512, 512, _screenWidth, _offscreen+512);
5748- vertices2[0].u = 512 + 0.5f;
5749- vertices2[0].v = vertices[0].v;
5750- vertices2[1].u = vertices[1].u;
5751- vertices2[1].v = _screenHeight - 0.5f;
5752- vertices2[0].x = vertices[0].x + (vertices[1].x - vertices[0].x) * 511 / 640;
5753- vertices2[0].y = 0;
5754- vertices2[0].z = 0;
5755- vertices2[1].x = vertices[1].x;
5756- vertices2[1].y = vertices[1].y;
5757- vertices2[1].z = 0;
5758- sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices2);
5759- }
5760-
5761-
5762- // draw overlay
5763- if (_overlayVisible) {
5764- Vertex *vertOverlay = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
5765- vertOverlay[0].x = 0;
5766- vertOverlay[0].y = 0;
5767- vertOverlay[0].z = 0;
5768- vertOverlay[1].x = PSP_SCREEN_WIDTH;
5769- vertOverlay[1].y = PSP_SCREEN_HEIGHT;
5770- vertOverlay[1].z = 0;
5771- vertOverlay[0].u = 0.5f;
5772- vertOverlay[0].v = 0.5f;
5773- vertOverlay[1].u = _overlayWidth - 0.5f;
5774- vertOverlay[1].v = _overlayHeight - 0.5f;
5775- sceGuTexMode(GU_PSM_4444, 0, 0, 0); // 16-bit image
5776- sceGuDisable(GU_ALPHA_TEST);
5777- sceGuEnable(GU_BLEND);
5778-
5779- //sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
5780- sceGuBlendFunc(GU_ADD, GU_FIX, GU_ONE_MINUS_SRC_ALPHA, 0xFFFFFFFF, 0);
5781-
5782- if (_overlayWidth > 320)
5783- sceGuTexImage(0, 512, 512, _overlayWidth, _overlayBuffer);
5784- else
5785- sceGuTexImage(0, 512, 256, _overlayWidth, _overlayBuffer);
5786-
5787- sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
5788- sceGuDrawArray(GU_SPRITES,GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D,2,0,vertOverlay);
5789- // need to render twice for textures > 512
5790- if ( _overlayWidth > 512) {
5791- Vertex *vertOverlay2 = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
5792- sceGuTexImage(0, 512, 512, _overlayWidth, _overlayBuffer + 512);
5793- vertOverlay2[0].u = 512 + 0.5f;
5794- vertOverlay2[0].v = vertOverlay[0].v;
5795- vertOverlay2[1].u = vertOverlay[1].u;
5796- vertOverlay2[1].v = _overlayHeight - 0.5f;
5797- vertOverlay2[0].x = PSP_SCREEN_WIDTH * 512 / 640;
5798- vertOverlay2[0].y = 0;
5799- vertOverlay2[0].z = 0;
5800- vertOverlay2[1].x = PSP_SCREEN_WIDTH;
5801- vertOverlay2[1].y = PSP_SCREEN_HEIGHT;
5802- vertOverlay2[1].z = 0;
5803- sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertOverlay2);
5804- }
5805- sceGuDisable(GU_BLEND);
5806- }
5807-
5808- // draw mouse
5809- if (_mouseVisible) {
5810- sceGuTexMode(GU_PSM_T8, 0, 0, 0); // 8-bit image
5811- sceGuClutMode(GU_PSM_5551, 0, 0xFF, 0);
5812- sceGuClutLoad(32, _cursorPaletteDisabled ? mouseClut : cursorPalette); // upload 32*8 entries (256)
5813- sceGuAlphaFunc(GU_GREATER, 0, 0xFF);
5814- sceGuEnable(GU_ALPHA_TEST);
5815- sceGuTexImage(0, MOUSE_SIZE, MOUSE_SIZE, MOUSE_SIZE, _mouseBuf);
5816- sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
5817-
5818- Vertex *vertMouse = (Vertex *)sceGuGetMemory(2 * sizeof(Vertex));
5819- vertMouse[0].u = 0.5f;
5820- vertMouse[0].v = 0.5f;
5821- vertMouse[1].u = _mouseWidth - 0.5f;
5822- vertMouse[1].v = _mouseHeight - 0.5f;
5823-
5824- //adjust cursor position
5825- int mX = _mouseX - _mouseHotspotX;
5826- int mY = _mouseY - _mouseHotspotY;
5827-
5828- if (_overlayVisible) {
5829- float scalex, scaley;
5830-
5831- scalex = (float)PSP_SCREEN_WIDTH /_overlayWidth;
5832- scaley = (float)PSP_SCREEN_HEIGHT /_overlayHeight;
5833-
5834- vertMouse[0].x = mX * scalex;
5835- vertMouse[0].y = mY * scaley;
5836- vertMouse[0].z = 0;
5837- vertMouse[1].x = vertMouse[0].x + _mouseWidth * scalex;
5838- vertMouse[1].y = vertMouse[0].y + _mouseHeight * scaley;
5839- vertMouse[1].z = 0;
5840- } else
5841- switch (_graphicMode) {
5842- case CENTERED_320X200:
5843- vertMouse[0].x = (PSP_SCREEN_WIDTH - 320) / 2 + mX;
5844- vertMouse[0].y = (PSP_SCREEN_HEIGHT - 200) / 2 + mY;
5845- vertMouse[0].z = 0;
5846- vertMouse[1].x = vertMouse[0].x + _mouseWidth;
5847- vertMouse[1].y = vertMouse[0].y + _mouseHeight;
5848- vertMouse[1].z = 0;
5849- break;
5850- case CENTERED_435X272:
5851- {
5852- float scalex, scaley;
5853-
5854- scalex = 435.0f / _screenWidth;
5855- scaley = 272.0f / _screenHeight;
5856-
5857- vertMouse[0].x = (PSP_SCREEN_WIDTH - 435) / 2 + mX * scalex;
5858- vertMouse[0].y = mY * scaley;
5859- vertMouse[0].z = 0;
5860- vertMouse[1].x = vertMouse[0].x + _mouseWidth * scalex;
5861- vertMouse[1].y = vertMouse[0].y + _mouseHeight * scaley;
5862- vertMouse[1].z = 0;
5863- }
5864- break;
5865- case CENTERED_362X272:
5866- {
5867- float scalex, scaley;
5868-
5869- scalex = 362.0f / _screenWidth;
5870- scaley = 272.0f / _screenHeight;
5871-
5872- vertMouse[0].x = (PSP_SCREEN_WIDTH - 362) / 2 + mX * scalex;
5873- vertMouse[0].y = mY * scaley;
5874- vertMouse[0].z = 0;
5875- vertMouse[1].x = vertMouse[0].x + _mouseWidth * scalex;
5876- vertMouse[1].y = vertMouse[0].y + _mouseHeight * scaley;
5877- vertMouse[1].z = 0;
5878- }
5879- break;
5880- case STRETCHED_480X272:
5881- {
5882- float scalex, scaley;
5883-
5884- scalex = (float)PSP_SCREEN_WIDTH / _screenWidth;
5885- scaley = (float)PSP_SCREEN_HEIGHT / _screenHeight;
5886-
5887- vertMouse[0].x = mX * scalex;
5888- vertMouse[0].y = mY * scaley;
5889- vertMouse[0].z = 0;
5890- vertMouse[1].x = vertMouse[0].x + _mouseWidth * scalex;
5891- vertMouse[1].y = vertMouse[0].y + _mouseHeight * scaley;
5892- vertMouse[1].z = 0;
5893- }
5894- break;
5895- }
5896- sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertMouse);
5897- }
5898-
5899- if (_keyboard->isVisible()) {
5900- _keyboard->render();
5901- }
5902-
5903- sceGuFinish();
5904- sceGuSync(0,0);
5905-
5906- sceDisplayWaitVblankStart();
5907- sceGuSwapBuffers();
5908+ _displayManager.renderAll();
5909+
5910+ DEBUG_EXIT_FUNC();
5911 }
5912
5913 void OSystem_PSP::setShakePos(int shakeOffset) {
5914- _shakePos = shakeOffset;
5915+ DEBUG_ENTER_FUNC();
5916+
5917+ _screen.setShakePos(shakeOffset);
5918+
5919+ DEBUG_EXIT_FUNC();
5920 }
5921
5922 void OSystem_PSP::showOverlay() {
5923- _overlayVisible = true;
5924+ DEBUG_ENTER_FUNC();
5925+
5926+ _overlay.setVisible(true);
5927+ _cursor.setLimits(_overlay.getWidth(), _overlay.getHeight());
5928+ _cursor.useGlobalScaler(false); // mouse with overlay is 1:1
5929+
5930+ DEBUG_EXIT_FUNC();
5931 }
5932
5933 void OSystem_PSP::hideOverlay() {
5934- PSPDebugTrace("OSystem_PSP::hideOverlay called\n");
5935- _overlayVisible = false;
5936+ DEBUG_ENTER_FUNC();
5937+
5938+ _overlay.setVisible(false);
5939+ _cursor.setLimits(_screen.getWidth(), _screen.getHeight());
5940+ _cursor.useGlobalScaler(true); // mouse needs to be scaled with screen
5941+
5942+ DEBUG_EXIT_FUNC();
5943 }
5944
5945 void OSystem_PSP::clearOverlay() {
5946- PSPDebugTrace("clearOverlay\n");
5947+ DEBUG_ENTER_FUNC();
5948
5949- bzero(_overlayBuffer, _overlayWidth * _overlayHeight * sizeof(OverlayColor));
5950- sceKernelDcacheWritebackAll();
5951+ _overlay.clearBuffer();
5952+
5953+ DEBUG_EXIT_FUNC();
5954 }
5955
5956 void OSystem_PSP::grabOverlay(OverlayColor *buf, int pitch) {
5957- int h = _overlayHeight;
5958- OverlayColor *src = _overlayBuffer;
5959+ DEBUG_ENTER_FUNC();
5960
5961- do {
5962- memcpy(buf, src, _overlayWidth * sizeof(OverlayColor));
5963- src += _overlayWidth;
5964- buf += pitch;
5965- } while (--h);
5966+ _overlay.copyToArray(buf, pitch);
5967+
5968+ DEBUG_EXIT_FUNC();
5969 }
5970
5971 void OSystem_PSP::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
5972- PSPDebugTrace("copyRectToOverlay\n");
5973+ DEBUG_ENTER_FUNC();
5974
5975- //Clip the coordinates
5976- if (x < 0) {
5977- w += x;
5978- buf -= x;
5979- x = 0;
5980- }
5981+ _overlay.copyFromRect(buf, pitch, x, y, w, h);
5982
5983- if (y < 0) {
5984- h += y;
5985- buf -= y * pitch;
5986- y = 0;
5987- }
5988-
5989- if (w > _overlayWidth - x) {
5990- w = _overlayWidth - x;
5991- }
5992-
5993- if (h > _overlayHeight - y) {
5994- h = _overlayHeight - y;
5995- }
5996-
5997- if (w <= 0 || h <= 0)
5998- return;
5999-
6000-
6001- OverlayColor *dst = _overlayBuffer + (y * _overlayWidth + x);
6002-
6003- if (_overlayWidth == pitch && pitch == w) {
6004- memcpy(dst, buf, h * w * sizeof(OverlayColor));
6005- } else {
6006- do {
6007- memcpy(dst, buf, w * sizeof(OverlayColor));
6008- buf += pitch;
6009- dst += _overlayWidth;
6010- } while (--h);
6011- }
6012- sceKernelDcacheWritebackAll();
6013+ DEBUG_EXIT_FUNC();
6014 }
6015
6016 int16 OSystem_PSP::getOverlayWidth() {
6017- return _overlayWidth;
6018+ return (int16) _overlay.getWidth();
6019 }
6020
6021 int16 OSystem_PSP::getOverlayHeight() {
6022- return _overlayHeight;
6023+ return (int16) _overlay.getHeight();
6024 }
6025
6026-
6027 void OSystem_PSP::grabPalette(byte *colors, uint start, uint num) {
6028- uint i;
6029- uint16 color;
6030+ DEBUG_ENTER_FUNC();
6031
6032- for (i = start; i < start + num; i++) {
6033- color = _palette[i];
6034- *colors++ = ((color & 0x1F) << 3);
6035- *colors++ = (((color >> 5) & 0x1F) << 3);
6036- *colors++ = (((color >> 10) & 0x1F) << 3);
6037- *colors++ = (color & 0x8000 ? 255 : 0);
6038- }
6039+ _screen.getPartialPalette(colors, start, num);
6040+
6041+ DEBUG_EXIT_FUNC();
6042 }
6043
6044-bool OSystem_PSP::showMouse(bool visible) {
6045- bool last = _mouseVisible;
6046- _mouseVisible = visible;
6047+bool OSystem_PSP::showMouse(bool v) {
6048+ DEBUG_ENTER_FUNC();
6049+
6050+ PSP_DEBUG_PRINT("%s\n", v ? "true" : "false");
6051+ bool last = _cursor.isVisible();
6052+ _cursor.setVisible(v);
6053+
6054+ DEBUG_EXIT_FUNC();
6055+
6056 return last;
6057 }
6058
6059 void OSystem_PSP::warpMouse(int x, int y) {
6060- //assert(x > 0 && x < _screenWidth);
6061- //assert(y > 0 && y < _screenHeight);
6062- _mouseX = x;
6063- _mouseY = y;
6064+ DEBUG_ENTER_FUNC();
6065+
6066+ _cursor.setXY(x,y);
6067+
6068+ DEBUG_EXIT_FUNC();
6069 }
6070
6071 void OSystem_PSP::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) {
6072- //TODO: handle cursorTargetScale
6073- _mouseWidth = w;
6074- _mouseHeight = h;
6075+ DEBUG_ENTER_FUNC();
6076
6077- _mouseHotspotX = hotspotX;
6078- _mouseHotspotY = hotspotY;
6079-
6080- _mouseKeyColour = keycolor & 0xFF;
6081-
6082- memcpy(mouseClut, _palette, 256 * sizeof(unsigned short));
6083- mouseClut[_mouseKeyColour] = 0;
6084-
6085- for (unsigned int i = 0; i < h; i++)
6086- memcpy(_mouseBuf + i * MOUSE_SIZE, buf + i * w, w);
6087-
6088- sceKernelDcacheWritebackAll();
6089-}
6090-
6091-#define PAD_CHECK_TIME 40
6092-#define PAD_DIR_MASK (PSP_CTRL_UP | PSP_CTRL_DOWN | PSP_CTRL_LEFT | PSP_CTRL_RIGHT)
6093-
6094-bool OSystem_PSP::processInput(Common::Event &event) {
6095- s8 analogStepAmountX = 0;
6096- s8 analogStepAmountY = 0;
6097-
6098- sceCtrlSetSamplingCycle(0);
6099- sceCtrlSetSamplingMode(1);
6100- sceCtrlReadBufferPositive(&pad, 1);
6101-
6102- bool usedInput, haveEvent;
6103-
6104- haveEvent = _keyboard->processInput(event, pad, usedInput);
6105-
6106- if (usedInput) // Check if the keyboard used up the input
6107- return haveEvent;
6108-
6109- uint32 buttonsChanged = pad.Buttons ^ _prevButtons;
6110-
6111- int newDpadX = 0, newDpadY = 0;
6112- event.kbd.ascii = 0;
6113- event.kbd.flags = 0;
6114-
6115- if (pad.Buttons & PSP_CTRL_UP) {
6116- newDpadY += 1;
6117- if (pad.Buttons & PSP_CTRL_RTRIGGER)
6118- newDpadX += 1;
6119+ 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);
6120+ if (format) {
6121+ 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);
6122 }
6123- if (pad.Buttons & PSP_CTRL_RIGHT) {
6124- newDpadX += 1;
6125- if (pad.Buttons & PSP_CTRL_RTRIGGER)
6126- newDpadY -= 1;
6127- }
6128- if (pad.Buttons & PSP_CTRL_DOWN) {
6129- newDpadY -= 1;
6130- if (pad.Buttons & PSP_CTRL_RTRIGGER)
6131- newDpadX -= 1;
6132- }
6133- if (pad.Buttons & PSP_CTRL_LEFT) {
6134- newDpadX -= 1;
6135- if (pad.Buttons & PSP_CTRL_RTRIGGER)
6136- newDpadY += 1;
6137- }
6138- //fprintf(stderr, "x=%d, y=%d, oldx=%d, oldy=%d\n", newDpadX, newDpadY, _dpadX, _dpadY);
6139- if (newDpadX != _dpadX || newDpadY != _dpadY) {
6140- if (_dpadX == 0 && _dpadY == 0) {// We pressed dpad
6141- event.type = Common::EVENT_KEYDOWN;
6142- event.kbd.keycode = getDpadEvent(newDpadX, newDpadY);
6143- event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0';
6144- _dpadX = newDpadX;
6145- _dpadY = newDpadY;
6146- }
6147- else if (newDpadX == 0 && newDpadY == 0) {// We unpressed dpad
6148- event.type = Common::EVENT_KEYUP;
6149- event.kbd.keycode = getDpadEvent(_dpadX, _dpadY);
6150- event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0';
6151- _dpadX = newDpadX;
6152- _dpadY = newDpadY;
6153- } else { // we moved from one pressed dpad to another one
6154- event.type = Common::EVENT_KEYUP; // first release the last dpad direction
6155- event.kbd.keycode = getDpadEvent(_dpadX, _dpadY);
6156- event.kbd.ascii = event.kbd.keycode - Common::KEYCODE_KP0 + '0';
6157- _dpadX = 0; // so that we'll pick up a new dpad movement
6158- _dpadY = 0;
6159- }
6160-
6161- _prevButtons = pad.Buttons;
6162- return true;
6163-
6164- } else if (buttonsChanged & (PSP_CTRL_CROSS | PSP_CTRL_CIRCLE | PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_START |
6165- PSP_CTRL_SELECT | PSP_CTRL_SQUARE | PSP_CTRL_TRIANGLE)) {
6166- if (buttonsChanged & PSP_CTRL_CROSS) {
6167- event.type = (pad.Buttons & PSP_CTRL_CROSS) ? Common::EVENT_LBUTTONDOWN : Common::EVENT_LBUTTONUP;
6168- } else if (buttonsChanged & PSP_CTRL_CIRCLE) {
6169- event.type = (pad.Buttons & PSP_CTRL_CIRCLE) ? Common::EVENT_RBUTTONDOWN : Common::EVENT_RBUTTONUP;
6170- } else {
6171- //any of the other buttons.
6172- event.type = buttonsChanged & pad.Buttons ? Common::EVENT_KEYDOWN : Common::EVENT_KEYUP;
6173-
6174- if (buttonsChanged & PSP_CTRL_LTRIGGER) {
6175- event.kbd.keycode = Common::KEYCODE_ESCAPE;
6176- event.kbd.ascii = 27;
6177- } else if (buttonsChanged & PSP_CTRL_START) {
6178- event.kbd.keycode = Common::KEYCODE_F5;
6179- event.kbd.ascii = Common::ASCII_F5;
6180- if (pad.Buttons & PSP_CTRL_RTRIGGER) {
6181- event.kbd.flags = Common::KBD_CTRL; // Main menu to allow RTL
6182- }
6183-/* } else if (buttonsChanged & PSP_CTRL_SELECT) {
6184- event.kbd.keycode = Common::KEYCODE_0;
6185- event.kbd.ascii = '0';
6186-*/ } else if (buttonsChanged & PSP_CTRL_SQUARE) {
6187- event.kbd.keycode = Common::KEYCODE_PERIOD;
6188- event.kbd.ascii = '.';
6189- } else if (buttonsChanged & PSP_CTRL_TRIANGLE) {
6190- event.kbd.keycode = Common::KEYCODE_RETURN;
6191- event.kbd.ascii = 13;
6192- } else if (pad.Buttons & PSP_CTRL_RTRIGGER) {
6193- event.kbd.flags |= Common::KBD_SHIFT;
6194- }
6195-
6196- }
6197-
6198- event.mouse.x = _mouseX;
6199- event.mouse.y = _mouseY;
6200- _prevButtons = pad.Buttons;
6201- return true;
6202- }
6203-
6204- uint32 time = getMillis();
6205- if (time - _lastPadCheck > PAD_CHECK_TIME) {
6206- _lastPadCheck = time;
6207- int16 newX = _mouseX;
6208- int16 newY = _mouseY;
6209-
6210- if (pad.Lx < 100) {
6211- analogStepAmountX = pad.Lx - 100;
6212- } else if (pad.Lx > 155) {
6213- analogStepAmountX = pad.Lx - 155;
6214- }
6215-
6216- if (pad.Ly < 100) {
6217- analogStepAmountY = pad.Ly - 100;
6218- } else if (pad.Ly > 155) {
6219- analogStepAmountY = pad.Ly - 155;
6220- }
6221-
6222- if (analogStepAmountX != 0 || analogStepAmountY != 0) {
6223-
6224- _prevButtons = pad.Buttons;
6225-
6226- // If no movement then this has no effect
6227- if (pad.Buttons & PSP_CTRL_RTRIGGER) {
6228- // Fine control mode for analog
6229- if (analogStepAmountX != 0) {
6230- if (analogStepAmountX > 0)
6231- newX += 1;
6232- else
6233- newX -= 1;
6234- }
6235-
6236- if (analogStepAmountY != 0) {
6237- if (analogStepAmountY > 0)
6238- newY += 1;
6239- else
6240- newY -= 1;
6241- }
6242- } else {
6243- newX += analogStepAmountX >> ((_screenWidth == 640) ? 2 : 3);
6244- newY += analogStepAmountY >> ((_screenWidth == 640) ? 2 : 3);
6245- }
6246-
6247- if (newX < 0)
6248- newX = 0;
6249- if (newY < 0)
6250- newY = 0;
6251- if (_overlayVisible) {
6252- if (newX >= _overlayWidth)
6253- newX = _overlayWidth - 1;
6254- if (newY >= _overlayHeight)
6255- newY = _overlayHeight - 1;
6256- } else {
6257- if (newX >= _screenWidth)
6258- newX = _screenWidth - 1;
6259- if (newY >= _screenHeight)
6260- newY = _screenHeight - 1;
6261- }
6262-
6263- if ((_mouseX != newX) || (_mouseY != newY)) {
6264- event.type = Common::EVENT_MOUSEMOVE;
6265- event.mouse.x = _mouseX = newX;
6266- event.mouse.y = _mouseY = newY;
6267- return true;
6268- }
6269- }
6270- }
6271-
6272- return false;
6273+
6274+ _cursor.setKeyColor(keycolor);
6275+ _cursor.setCursorTargetScale(cursorTargetScale);
6276+ _cursor.setSizeAndScummvmPixelFormat(w, h, format);
6277+ _cursor.setHotspot(hotspotX, hotspotY);
6278+ _cursor.clearKeyColor();
6279+ _cursor.copyFromArray(buf);
6280+
6281+ DEBUG_EXIT_FUNC();
6282 }
6283
6284-inline Common::KeyCode OSystem_PSP::getDpadEvent(int x, int y) {
6285- Common::KeyCode key;
6286-
6287- if (x == -1) {
6288- if (y == -1)
6289- key = Common::KEYCODE_KP1;
6290- else if (y == 0)
6291- key = Common::KEYCODE_KP4;
6292- else /* y == 1 */
6293- key = Common::KEYCODE_KP7;
6294- } else if (x == 0) {
6295- if (y == -1)
6296- key = Common::KEYCODE_KP2;
6297- else /* y == 1 */
6298- key = Common::KEYCODE_KP8;
6299- } else {/* x == 1 */
6300- if (y == -1)
6301- key = Common::KEYCODE_KP3;
6302- else if (y == 0)
6303- key = Common::KEYCODE_KP6;
6304- else /* y == 1 */
6305- key = Common::KEYCODE_KP9;
6306- }
6307-
6308- return key;
6309-}
6310-
6311 bool OSystem_PSP::pollEvent(Common::Event &event) {
6312
6313 // If we're polling for events, we should check for pausing the engine
6314@@ -905,8 +373,7 @@
6315
6316 PowerMan.pollPauseEngine();
6317
6318- return processInput(event);
6319-
6320+ return _inputHandler.getAllInputs(event);
6321 }
6322
6323
6324@@ -997,7 +464,6 @@
6325 void OSystem_PSP::quit() {
6326 SDL_CloseAudio();
6327 SDL_Quit();
6328- sceGuTerm();
6329 sceKernelExitGame();
6330 }
6331
6332@@ -1023,3 +489,5 @@
6333 Common::FSNode file(PSP_CONFIG_FILE);
6334 return file.createWriteStream();
6335 }
6336+
6337+
6338Index: backends/platform/psp/README.PSP.in
6339===================================================================
6340--- backends/platform/psp/README.PSP.in (revision 48355)
6341+++ backends/platform/psp/README.PSP.in (working copy)
6342@@ -16,12 +16,12 @@
6343 Right trigger - Modifier key (see below for uses)
6344 Analog - Mouse movement
6345 Right trigger + Analog - Fine control mouse
6346-Directionals - Mouse movement
6347+Directionals - Arrow keys
6348 Triangle - Enter
6349 Cross - Mouse button 1
6350 Circle - Mouse button 2
6351 Square - '.' (skip dialogue in some games)
6352-Start - F5
6353+Start - F5 (Main Menu)
6354 Right trigger + Start - Return-To-Launcher menu
6355
6356 Virtual Keyboard
6357Index: backends/platform/psp/cursor.h
6358===================================================================
6359--- backends/platform/psp/cursor.h (revision 0)
6360+++ backends/platform/psp/cursor.h (revision 0)
6361@@ -0,0 +1,82 @@
6362+/* ScummVM - Graphic Adventure Engine
6363+ *
6364+ * ScummVM is the legal property of its developers, whose names
6365+ * are too numerous to list here. Please refer to the COPYRIGHT
6366+ * file distributed with this source distribution.
6367+ *
6368+ * This program is free software; you can redistribute it and/or
6369+ * modify it under the terms of the GNU General Public License
6370+ * as published by the Free Software Foundation; either version 2
6371+ * of the License, or (at your option) any later version.
6372+
6373+ * This program is distributed in the hope that it will be useful,
6374+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6375+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6376+ * GNU General Public License for more details.
6377+
6378+ * You should have received a copy of the GNU General Public License
6379+ * along with this program; if not, write to the Free Software
6380+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
6381+ *
6382+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.h $
6383+ * $Id: osys_psp.h 46120 2009-11-24 10:33:30Z Bluddy $
6384+ *
6385+ */
6386+
6387+#ifndef MOUSE_H
6388+#define MOUSE_H
6389+
6390+class Cursor : public DefaultDisplayClient {
6391+private:
6392+ int _hotspotX, _hotspotY;
6393+ uint32 _keyColor;
6394+ int _cursorTargetScale;
6395+ bool _useCursorPalette;
6396+ bool _hasCursorPalette;
6397+ uint32 _mouseLimitWidth;
6398+ uint32 _mouseLimitHeight;
6399+ int32 _x, _y;
6400+ Palette _screenPalette; // separate palette for screen. default 'palette' is cursor palette.
6401+
6402+ void updateRendererOffset();
6403+
6404+public:
6405+ Cursor() : _hotspotX(0), _hotspotY(0), _keyColor(0), _cursorTargetScale(0),
6406+ _useCursorPalette(false), _hasCursorPalette(false), _mouseLimitWidth(0),
6407+ _mouseLimitHeight(0), _x(0), _y(0) { }
6408+ virtual ~Cursor() { deallocate(); }
6409+ const char *getObjectName() { return "Cursor"; }
6410+
6411+ void setKeyColor(uint32 color);
6412+ void setCursorTargetScale(int scale) { _cursorTargetScale = scale; }
6413+ void setScreenPalette(const byte *colors, uint start, uint num);
6414+ void copyFromArray(const byte *array);
6415+ Palette &palette() { return _palette; }
6416+ Buffer &buffer() { return _buffer; }
6417+ void setCursorPalette(const byte *colors, uint start, uint num);
6418+ void enableCursorPalette(bool enable);
6419+ void setLimits(uint32 width, uint32 height);
6420+ void setXY(int x, int y);
6421+ int32 getX() { return _x; }
6422+ int32 getY() { return _y; }
6423+ bool increaseXY(int32 incX, int32 incY); // returns true if there's a change in x or y
6424+ void adjustXYForScreenSize(int32 &x, int32 &y);
6425+ void init();
6426+ void setHotspot(int32 x, int32 y);
6427+ void setScreenPaletteScummvmPixelFormat(const Graphics::PixelFormat *format);
6428+ void setSizeAndScummvmPixelFormat(uint32 widht, uint32 height, const Graphics::PixelFormat *format);
6429+ void clearKeyColor();
6430+ void useGlobalScaler(bool val) { _renderer.setUseGlobalScaler(val); }
6431+ bool allocate();
6432+ void deallocate();
6433+
6434+private:
6435+ void setSize(uint32 width, uint32 height);
6436+ void getPixelFormatsFromScummvmPixelFormat(const Graphics::PixelFormat *format,
6437+ PSPPixelFormat::Type &bufferFormat,
6438+ PSPPixelFormat::Type &paletteFormat,
6439+ uint32 &numOfEntries);
6440+ void setRendererModePalettized(bool palettized);
6441+};
6442+
6443+#endif /* MOUSE_H */
6444Index: backends/platform/psp/psppixelformat.h
6445===================================================================
6446--- backends/platform/psp/psppixelformat.h (revision 0)
6447+++ backends/platform/psp/psppixelformat.h (revision 0)
6448@@ -0,0 +1,224 @@
6449+/* ScummVM - Graphic Adventure Engine
6450+ *
6451+ * ScummVM is the legal property of its developers, whose names
6452+ * are too numerous to list here. Please refer to the COPYRIGHT
6453+ * file distributed with this source distribution.
6454+ *
6455+ * This program is free software; you can redistribute it and/or
6456+ * modify it under the terms of the GNU General Public License
6457+ * as published by the Free Software Foundation; either version 2
6458+ * of the License, or (at your option) any later version.
6459+
6460+ * This program is distributed in the hope that it will be useful,
6461+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6462+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6463+ * GNU General Public License for more details.
6464+
6465+ * You should have received a copy of the GNU General Public License
6466+ * along with this program; if not, write to the Free Software
6467+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
6468+ *
6469+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
6470+ * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
6471+ *
6472+ */
6473+
6474+#ifndef PSP_PIXEL_FORMAT_H
6475+#define PSP_PIXEL_FORMAT_H
6476+
6477+#include "graphics/pixelformat.h"
6478+#include "backends/platform/psp/trace.h"
6479+
6480+/**
6481+ * Specialized PixelFormat class
6482+ * Supports only those formats which the PSP allows, including 4 bit palettes.
6483+ * Also provides accurate color conversion (needed for color masking)
6484+ * As well as swapping of red and blue channels (needed by HE games, for example)
6485+ */
6486+struct PSPPixelFormat{
6487+ enum Type {
6488+ Type_None,
6489+ Type_4444,
6490+ Type_5551,
6491+ Type_5650,
6492+ Type_8888,
6493+ Type_Palette_8bit,
6494+ Type_Palette_4bit,
6495+ Type_Unknown
6496+ };
6497+
6498+ Type format;
6499+ uint32 bitsPerPixel; ///< Must match bpp of selected type
6500+ bool swapRB; ///< Swap red and blue values when reading and writing
6501+
6502+ PSPPixelFormat() : format(Type_Unknown), bitsPerPixel(0), swapRB(false) {}
6503+ const char *getObjectName() { return "PSPPixelFormat"; }
6504+ void set(Type type, bool swap = false);
6505+ static void convertFromScummvmPixelFormat(const Graphics::PixelFormat *pf,
6506+ PSPPixelFormat::Type &bufferType,
6507+ PSPPixelFormat::Type &paletteType,
6508+ bool &swapRedBlue);
6509+ static Graphics::PixelFormat convertToScummvmPixelFormat(PSPPixelFormat::Type type);
6510+ uint32 convertTo32BitColor(uint32 color);
6511+
6512+ inline uint32 rgbaToColor(uint32 r, uint32 g, uint32 b, uint32 a) {
6513+ uint32 color;
6514+
6515+ switch(format) {
6516+ case Type_4444:
6517+ color = (((b >> 4) << 8) | ((g >> 4) << 4) | ((r >> 4) << 0) | ((a >> 4) << 12));
6518+ break;
6519+ case Type_5551:
6520+ color = (((b >> 3) << 10) | ((g >> 3) << 5) | ((r >> 3) << 0) | ((a >> 7) << 15));
6521+ break;
6522+ case Type_5650:
6523+ color = (((b >> 3) << 11) | ((g >> 2) << 5) | ((r >> 3) << 0));
6524+ break;
6525+ case Type_8888:
6526+ color = (((b >> 0) << 16) | ((g >> 0) << 8) | ((r >> 0) << 0) | ((a >> 0) << 24));
6527+ break;
6528+ default:
6529+ color = 0;
6530+ break;
6531+ }
6532+ return color;
6533+ }
6534+
6535+ inline void colorToRgba(uint32 color, uint32 &r, uint32 &g, uint32 &b, uint32 &a) {
6536+ switch(format) {
6537+ case Type_4444:
6538+ a = (color >> 12) & 0xF; // Interpolate to get true colors
6539+ b = (color >> 8) & 0xF;
6540+ g = (color >> 4) & 0xF;
6541+ r = (color >> 0) & 0xF;
6542+ a = a << 4 | a;
6543+ b = b << 4 | b;
6544+ g = g << 4 | g;
6545+ r = r << 4 | r;
6546+ break;
6547+ case Type_5551:
6548+ a = (color >> 15) ? 0xFF : 0;
6549+ b = (color >> 10) & 0x1F;
6550+ g = (color >> 5) & 0x1F;
6551+ r = (color >> 0) & 0x1F;
6552+ b = b << 3 | b >> 2;
6553+ g = g << 3 | g >> 2;
6554+ r = r << 3 | r >> 2;
6555+ break;
6556+ case Type_5650:
6557+ a = 0xFF;
6558+ b = (color >> 11) & 0x1F;
6559+ g = (color >> 5) & 0x3F;
6560+ r = (color >> 0) & 0x1F;
6561+ b = b << 3 | b >> 2;
6562+ g = g << 2 | g >> 4;
6563+ r = r << 3 | r >> 2;
6564+ break;
6565+ case Type_8888:
6566+ a = (color >> 24) & 0xFF;
6567+ b = (color >> 16) & 0xFF;
6568+ g = (color >> 8) & 0xFF;
6569+ r = (color >> 0) & 0xFF;
6570+ break;
6571+ default:
6572+ a = b = g = r = 0;
6573+ break;
6574+ }
6575+ }
6576+
6577+
6578+ inline uint32 pixelsToBytes(uint32 pixels) {
6579+ switch (bitsPerPixel) {
6580+ case 4:
6581+ pixels >>= 1;
6582+ break;
6583+ case 16:
6584+ pixels <<= 1;
6585+ break;
6586+ case 32:
6587+ pixels <<= 2;
6588+ break;
6589+ case 8:
6590+ break;
6591+ default:
6592+ PSP_ERROR_STATIC("Incorrect bitsPerPixel value[%u]. pixels[%u]\n", bitsPerPixel, pixels);
6593+ break;
6594+ }
6595+ return pixels;
6596+ }
6597+
6598+ inline uint16 swapRedBlue16(uint16 color) {
6599+ uint16 output;
6600+
6601+ switch (format) {
6602+ case Type_4444:
6603+ output = (color & 0xf0f0) | ((color & 0x000f)<<8) | ((color & 0x0f00)>>8);
6604+ break;
6605+ case Type_5551:
6606+ output = (color & 0x83e0) | ((color & 0x001f)<<10) | ((color & 0x7c00)>>10);
6607+ break;
6608+ case Type_5650:
6609+ output = (color & 0x07e0) | ((color & 0x001f)<<11) | ((color & 0xf800)>>11);
6610+ break;
6611+ default:
6612+ PSP_ERROR_STATIC("invalid format[%u] for swapping\n", format);
6613+ output = 0;
6614+ break;
6615+ }
6616+ return output;
6617+ }
6618+
6619+ inline uint32 swapRedBlue32(uint32 color) {
6620+ uint32 output;
6621+
6622+ switch (format) {
6623+ case Type_4444:
6624+ output = (color & 0xf0f0f0f0) |
6625+ ((color & 0x000f000f)<<8) | ((color & 0x0f000f00)>>8);
6626+ break;
6627+ case Type_5551:
6628+ output = (color & 0x83e083e0) |
6629+ ((color & 0x001f001f)<<10) | ((color & 0x7c007c00)>>10);
6630+ break;
6631+ case Type_5650:
6632+ output = (color & 0x07e007e0) |
6633+ ((color & 0x001f001f)<<11) | ((color & 0xf800f800)>>11);
6634+ break;
6635+ case Type_8888:
6636+ output = (color & 0xff00ff00) |
6637+ ((color & 0x000000ff)<<16) | ((color & 0x00ff0000)>>16);
6638+ break;
6639+ default:
6640+ PSP_ERROR_STATIC("invalid format[%u] for swapping\n", format);
6641+ output = 0;
6642+ break;
6643+ }
6644+
6645+ return output;
6646+ }
6647+
6648+ // Return whatever color we point at
6649+ inline uint32 getColorValueAt(byte *pointer) {
6650+ uint32 result;
6651+
6652+ switch (bitsPerPixel) {
6653+ case 4: // We can't distinguish a 4 bit color with a pointer
6654+ case 8:
6655+ result = (uint32)*pointer;
6656+ break;
6657+ case 16:
6658+ result = (uint32)*(uint16 *)pointer;
6659+ break;
6660+ case 32:
6661+ result = *(uint32 *)pointer;
6662+ break;
6663+ default:
6664+ result = 0;
6665+ PSP_ERROR("Incorrect bitsPerPixel value[%u].\n", bitsPerPixel);
6666+ break;
6667+ }
6668+ return result;
6669+ }
6670+};
6671+
6672+#endif /* PSP_PIXEL_FORMAT_H */
6673\ No newline at end of file
6674Index: backends/platform/psp/pspkeyboard.h
6675===================================================================
6676--- backends/platform/psp/pspkeyboard.h (revision 48355)
6677+++ backends/platform/psp/pspkeyboard.h (working copy)
6678@@ -28,13 +28,14 @@
6679
6680 #include "common/events.h"
6681 #include "common/stream.h"
6682+#include "backends/platform/psp/display_client.h"
6683 #include <pspctrl.h>
6684
6685 //number of modes
6686 #define MODE_COUNT 4
6687 #define guiStringsSize 8 /* size of guistrings array */
6688
6689-class PSPKeyboard {
6690+class PSPKeyboard : public DisplayClient {
6691
6692 private:
6693 enum State {
6694@@ -49,67 +50,64 @@
6695 public:
6696 PSPKeyboard();
6697 ~PSPKeyboard();
6698+ const char *getObjectName() const { return "PSPKeyboard"; }
6699+
6700 bool load(); // Load keyboard into memory
6701 bool isInit() { return _init; } // Check for initialization
6702 bool isDirty() { return _dirty; } // Check if needs redrawing
6703+ void setDirty() { _dirty = true; }
6704+ void setClean() { _dirty = false; }
6705 bool isVisible() { return _state != kInvisible; } // Check if visible
6706- bool processInput(Common::Event &event, SceCtrlData &pad, bool &usedInput); // Process input
6707+ void setVisible(bool val);
6708+ bool processInput(Common::Event &event, SceCtrlData &pad); // Process input
6709 void moveTo(const int newX, const int newY); // Move keyboard
6710 void render(); // Draw the keyboard onscreen
6711
6712 private:
6713- struct gu_surface {
6714- u32 surface_width;
6715- u32 surface_height;
6716- u32 texture_width;
6717- u32 texture_height;
6718- u8 *texture;
6719- u32 *palette;
6720- u32 paletteSize;
6721+ enum CursorDirections {
6722+ kUp = 0,
6723+ kRight,
6724+ kDown,
6725+ kLeft,
6726+ kCenter
6727 };
6728
6729+ Buffer _buffers[guiStringsSize];
6730+ Palette _palettes[guiStringsSize];
6731+ GuRenderer _renderer;
6732
6733-// structures used for drawing the keyboard
6734- struct Vertex {
6735- float u, v;
6736- unsigned int color;
6737- float x,y,z;
6738- };
6739-
6740- void surface_draw_offset(struct gu_surface* surface,
6741- int screenX, int screenY, int offsetX, int offsetY, int intWidth, int intHeight);
6742- void block_copy(gu_surface* surface, u8 *texture);
6743- int load_png_image(Common::SeekableReadStream *, unsigned char *ImageBuffer, uint32 *palette);
6744- int get_png_image_size(Common::SeekableReadStream *, uint32 *png_width, uint32 *png_height, u32 *paletteSize);
6745+ int loadPngImage(Common::SeekableReadStream *file, Buffer &buffer, Palette &palette);
6746+ int getPngImageSize(Common::SeekableReadStream *, uint32 *png_width, uint32 *png_height, u32 *paletteSize);
6747 uint32 convert_pow2(uint32 size);
6748- void flipNibbles(gu_surface* surface); // Convert to PSP 4-bit format
6749 void increaseKeyboardLocationX(int amount); // Move keyboard onscreen
6750 void increaseKeyboardLocationY(int amount);
6751+ void convertCursorToXY(CursorDirections cur, int &x, int &y);
6752
6753+ void handleMoveState(SceCtrlData &pad);
6754+ bool handleDefaultState(Common::Event &event, SceCtrlData &pad);
6755+ bool handleCornersSelectedState(Common::Event &event, SceCtrlData &pad);
6756+ bool getInputChoice(Common::Event &event, SceCtrlData &pad);
6757+ void getCursorMovement(SceCtrlData &pad);
6758+ void handleRTriggerDownState(SceCtrlData &pad);
6759+ void handleLTriggerDownState(SceCtrlData &pad);
6760+
6761 static short _modeChar[MODE_COUNT][5][6];
6762 static const char *_guiStrings[];
6763 bool _init;
6764- unsigned int _prevButtons; // A bit pattern.
6765+ uint32 _prevButtons; // A bit pattern.
6766+ uint32 _buttonsChanged;
6767+
6768 bool _dirty; // keyboard needs redrawing
6769 int _mode; // charset selected. (0 - letters or 1 - numbers)
6770- int _moved_x; // location we've moved the KB to onscreen
6771- int _moved_y;
6772+ int _movedX; // location we've moved the KB to onscreen
6773+ int _movedY;
6774 bool _moved; // whether the keyboard was moved
6775- gu_surface _keyTextures[guiStringsSize];
6776-
6777+
6778 State _state; // State of keyboard Keyboard state machine
6779 State _lastState;
6780
6781- enum Cursor {
6782- kUp = 0,
6783- kRight,
6784- kDown,
6785- kLeft,
6786- kCenter
6787- };
6788+ CursorDirections _oldCursor; // Point to place of last cursor
6789
6790- Cursor _oldCursor; // Point to place of last cursor
6791-
6792 };
6793
6794 #endif /* PSPKEYBOARD_H */
6795\ No newline at end of file
6796Index: backends/platform/psp/powerman.h
6797===================================================================
6798--- backends/platform/psp/powerman.h (revision 48355)
6799+++ backends/platform/psp/powerman.h (working copy)
6800@@ -52,6 +52,7 @@
6801 class PowerManager: public Common::Singleton<PowerManager> {
6802
6803 public:
6804+ const char *getObjectName() const { return "PowerManager"; }
6805 int blockOnSuspend(); /* block if suspending */
6806 int beginCriticalSection(bool justBlock = false); /* Use a critical section to block (if suspend was already pressed) */
6807 int endCriticalSection(); /* and to prevent the PSP from suspending in a particular section */
6808@@ -118,7 +119,6 @@
6809 kDoneSignallingSuspendedThreadsResume,
6810 kDoneResume
6811 };
6812-#ifdef __PSP_DEBUG_SUSPEND__
6813
6814 volatile int _listCounter; /* How many people are in the list - just for debugging */
6815
6816@@ -129,8 +129,6 @@
6817 public:
6818 int getPMStatus() { return _PMStatus; }
6819
6820-#endif /* __PSP_DEBUG_SUSPEND__ */
6821-
6822 };
6823
6824 // For easy access
6825Index: backends/fs/psp/psp-stream.h
6826===================================================================
6827--- backends/fs/psp/psp-stream.h (revision 48355)
6828+++ backends/fs/psp/psp-stream.h (working copy)
6829@@ -49,13 +49,14 @@
6830 int _errorSuspend;
6831 mutable int _errorSource;
6832
6833-#ifdef __PSP_DEBUG_SUSPEND__
6834+ // Error checking
6835 int _errorPos;
6836 void * _errorHandle;
6837 int _suspendCount;
6838-#endif /* __PSP_DEBUG_SUSPEND__ */
6839
6840 public:
6841+
6842+ const char *getObjectName() const { return "PSPIoStream"; }
6843 /**
6844 * Given a path, invoke fopen on that path and wrap the result in a
6845 * PSPIoStream instance.
6846Index: backends/fs/psp/psp-fs-factory.h
6847===================================================================
6848--- backends/fs/psp/psp-fs-factory.h (revision 48355)
6849+++ backends/fs/psp/psp-fs-factory.h (working copy)
6850@@ -35,6 +35,7 @@
6851 */
6852 class PSPFilesystemFactory : public FilesystemFactory, public Common::Singleton<PSPFilesystemFactory> {
6853 public:
6854+ const char *getObjectName() const { return "PSPFilesystemFactory"; }
6855 virtual AbstractFSNode *makeRootFileNode() const;
6856 virtual AbstractFSNode *makeCurrentDirectoryFileNode() const;
6857 virtual AbstractFSNode *makeFileNodePath(const Common::String &path) const;
6858Index: backends/fs/psp/psp-fs.cpp
6859===================================================================
6860--- backends/fs/psp/psp-fs.cpp (revision 48355)
6861+++ backends/fs/psp/psp-fs.cpp (working copy)
6862@@ -35,6 +35,9 @@
6863
6864 #define ROOT_PATH "ms0:/"
6865
6866+//#define __PSP_PRINT_TO_FILE__
6867+//#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */
6868+//#define __PSP_DEBUG_PRINT__ /* For debug printouts */
6869 #include "backends/platform/psp/trace.h"
6870
6871 /**
6872@@ -63,6 +66,7 @@
6873 */
6874 PSPFilesystemNode(const Common::String &p, bool verify = true);
6875
6876+ const char *getObjectName() const { return "PSPFileSystemNode"; }
6877 virtual bool exists() const;
6878 virtual Common::String getDisplayName() const { return _displayName; }
6879 virtual Common::String getName() const { return _displayName; }
6880@@ -87,6 +91,7 @@
6881 }
6882
6883 PSPFilesystemNode::PSPFilesystemNode(const Common::String &p, bool verify) {
6884+ DEBUG_ENTER_FUNC();
6885 assert(p.size() > 0);
6886
6887 _path = p;
6888@@ -94,54 +99,70 @@
6889 _isValid = true;
6890 _isDirectory = true;
6891
6892+ PSP_DEBUG_PRINT_FUNC("path [%s]\n", _path.c_str());
6893+
6894 if (verify) {
6895 struct stat st;
6896 if (PowerMan.beginCriticalSection()==PowerManager::Blocked)
6897- PSPDebugSuspend("Suspended in PSPFilesystemNode::PSPFilesystemNode\n");
6898+ PSP_DEBUG_PRINT_FUNC("Suspended\n");
6899 _isValid = (0 == stat(_path.c_str(), &st));
6900 PowerMan.endCriticalSection();
6901 _isDirectory = S_ISDIR(st.st_mode);
6902 }
6903+ DEBUG_EXIT_FUNC();
6904 }
6905
6906 bool PSPFilesystemNode::exists() const {
6907+ DEBUG_ENTER_FUNC();
6908 int ret = 0;
6909
6910 if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
6911- PSPDebugSuspend("Suspended in PSPFilesystemNode::exists()\n"); // Make sure to block in case of suspend
6912+ PSP_DEBUG_PRINT_FUNC("Suspended\n"); // Make sure to block in case of suspend
6913
6914+ PSP_DEBUG_PRINT_FUNC("path [%s]\n", _path.c_str());
6915+
6916 ret = access(_path.c_str(), F_OK);
6917 PowerMan.endCriticalSection();
6918
6919- return ret == 0;
6920+ DEBUG_EXIT_FUNC();
6921+ return (ret == 0);
6922 }
6923
6924 bool PSPFilesystemNode::isReadable() const {
6925+ DEBUG_ENTER_FUNC();
6926 int ret = 0;
6927
6928 if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
6929- PSPDebugSuspend("Suspended in PSPFilesystemNode::isReadable()\n"); // Make sure to block in case of suspend
6930+ PSP_DEBUG_PRINT_FUNC("Suspended\n"); // Make sure to block in case of suspend
6931
6932+ PSP_DEBUG_PRINT_FUNC("path [%s]\n", _path.c_str());
6933+
6934 ret = access(_path.c_str(), R_OK);
6935 PowerMan.endCriticalSection();
6936
6937- return ret == 0;
6938+ DEBUG_EXIT_FUNC();
6939+ return (ret == 0);
6940 }
6941
6942 bool PSPFilesystemNode::isWritable() const {
6943+ DEBUG_ENTER_FUNC();
6944 int ret = 0;
6945
6946 if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
6947- PSPDebugSuspend("Suspended in PSPFilesystemNode::isWritable()\n"); // Make sure to block in case of suspend
6948+ PSP_DEBUG_PRINT_FUNC("Suspended\n"); // Make sure to block in case of suspend
6949
6950+ PSP_DEBUG_PRINT_FUNC("path [%s]\n", _path.c_str());
6951+
6952 ret = access(_path.c_str(), W_OK);
6953 PowerMan.endCriticalSection();
6954
6955+ DEBUG_EXIT_FUNC();
6956 return ret == 0;
6957 }
6958
6959
6960 AbstractFSNode *PSPFilesystemNode::getChild(const Common::String &n) const {
6961+ DEBUG_ENTER_FUNC();
6962 // FIXME: Pretty lame implementation! We do no error checking to speak
6963 // of, do not check if this is a special node, etc.
6964 assert(_isDirectory);
6965@@ -151,10 +172,16 @@
6966 newPath += '/';
6967 newPath += n;
6968
6969- return new PSPFilesystemNode(newPath, true);
6970+ PSP_DEBUG_PRINT_FUNC("child [%s]\n", newPath.c_str());
6971+
6972+ AbstractFSNode *node = new PSPFilesystemNode(newPath, true);
6973+
6974+ DEBUG_EXIT_FUNC();
6975+ return node;
6976 }
6977
6978 bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const {
6979+ DEBUG_ENTER_FUNC();
6980 assert(_isDirectory);
6981
6982 //TODO: honor the hidden flag
6983@@ -162,8 +189,10 @@
6984 bool ret = true;
6985
6986 if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
6987- PSPDebugSuspend("Suspended in PSPFilesystemNode::getChildren\n"); // Make sure to block in case of suspend
6988+ PSP_DEBUG_PRINT_FUNC("Suspended\n"); // Make sure to block in case of suspend
6989
6990+ PSP_DEBUG_PRINT_FUNC("Current path[%s]\n", _path.c_str());
6991+
6992 int dfd = sceIoDopen(_path.c_str());
6993 if (dfd > 0) {
6994 SceIoDirent dir;
6995@@ -186,7 +215,9 @@
6996
6997 entry._path = newPath;
6998 entry._isDirectory = dir.d_stat.st_attr & FIO_SO_IFDIR;
6999-
7000+
7001+ PSP_DEBUG_PRINT_FUNC("Child[%s], %s\n", entry._path.c_str(), entry._isDirectory ? "dir" : "file");
7002+
7003 // Honor the chosen mode
7004 if ((mode == Common::FSNode::kListFilesOnly && entry._isDirectory) ||
7005 (mode == Common::FSNode::kListDirectoriesOnly && !entry._isDirectory))
7006@@ -202,17 +233,24 @@
7007 }
7008
7009 PowerMan.endCriticalSection();
7010+
7011+ DEBUG_EXIT_FUNC();
7012 return ret;
7013 }
7014
7015 AbstractFSNode *PSPFilesystemNode::getParent() const {
7016+ DEBUG_ENTER_FUNC();
7017 if (_path == ROOT_PATH)
7018 return 0;
7019
7020+ PSP_DEBUG_PRINT_FUNC("current[%s]\n", _path.c_str());
7021+
7022 const char *start = _path.c_str();
7023 const char *end = lastPathComponent(_path, '/');
7024
7025- return new PSPFilesystemNode(Common::String(start, end - start), false);
7026+ AbstractFSNode *node = new PSPFilesystemNode(Common::String(start, end - start), false);
7027+ DEBUG_EXIT_FUNC();
7028+ return node;
7029 }
7030
7031 Common::SeekableReadStream *PSPFilesystemNode::createReadStream() {
7032Index: backends/fs/psp/psp-stream.cpp
7033===================================================================
7034--- backends/fs/psp/psp-stream.cpp (revision 48355)
7035+++ backends/fs/psp/psp-stream.cpp (working copy)
7036@@ -27,15 +27,20 @@
7037 #include <SDL/SDL_thread.h>
7038 #include <SDL/SDL_mutex.h>
7039
7040-#include "backends/platform/psp/trace.h"
7041 #include "backends/platform/psp/powerman.h"
7042 #include "backends/fs/psp/psp-stream.h"
7043
7044 #include <errno.h>
7045
7046+//#define __PSP_PRINT_TO_FILE__
7047+//#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */
7048+//#define __PSP_DEBUG_PRINT__ /* For debug printouts */
7049+#include "backends/platform/psp/trace.h"
7050+
7051 PSPIoStream::PSPIoStream(const Common::String &path, bool writeMode)
7052 : StdioStream((void *)1), _path(path), _writeMode(writeMode) {
7053-
7054+ DEBUG_ENTER_FUNC();
7055+
7056 assert(!path.empty());
7057
7058 _handle = (void *)0; // Need to do this since base class asserts not 0.
7059@@ -43,34 +48,40 @@
7060 _feof = false;
7061 _pos = 0;
7062
7063-#ifdef __PSP_DEBUG_SUSPEND__
7064+ /* for error checking */
7065 _errorSuspend = 0;
7066 _errorSource = 0;
7067 _errorPos = 0;
7068 _errorHandle = 0;
7069 _suspendCount = 0;
7070-#endif
7071+
7072+ DEBUG_EXIT_FUNC();
7073 }
7074
7075 PSPIoStream::~PSPIoStream() {
7076+ DEBUG_ENTER_FUNC();
7077+
7078 if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
7079- PSPDebugSuspend("Suspended in PSPIoStream::~PSPIoStream()\n");
7080+ PSP_DEBUG_PRINT_FUNC("Suspended\n");
7081
7082 PowerMan.unregisterSuspend(this); // Unregister with powermanager to be suspended
7083- // Must do this before fclose() or resume() will reopen.
7084+ // Must do this before fclose() or resume() will reopen.
7085
7086 fclose((FILE *)_handle); // We don't need a critical section(?). Worst case, the handle gets closed on its own
7087
7088 PowerMan.endCriticalSection();
7089+
7090+ DEBUG_EXIT_FUNC();
7091 }
7092
7093-// Function to open the file pointed to by the path.
7094-//
7095-//
7096+/* Function to open the file pointed to by the path.
7097+ *
7098+ */
7099 void *PSPIoStream::open() {
7100+ DEBUG_ENTER_FUNC();
7101 if (PowerMan.beginCriticalSection() == PowerManager::Blocked) {
7102 // No need to open. Just return the _handle resume() already opened.
7103- PSPDebugSuspend("Suspended in PSPIoStream::open\n");
7104+ PSP_DEBUG_PRINT_FUNC("Suspended\n");
7105 }
7106
7107 _handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb"); // open
7108@@ -79,20 +90,22 @@
7109
7110 PowerMan.endCriticalSection();
7111
7112+ DEBUG_EXIT_FUNC();
7113 return _handle;
7114 }
7115
7116 bool PSPIoStream::err() const {
7117+ DEBUG_ENTER_FUNC();
7118 if (_ferror)
7119- PSPDebugSuspend("In PSPIoStream::err - mem_ferror=%d, source=%d, suspend error=%d, pos=%d, _errorPos=%d, _errorHandle=%p, suspendCount=%d _handle\n",
7120+ PSP_ERROR("mem_ferror[%d], source[%d], suspend error[%d], pos[%d], _errorPos[%d], _errorHandle[%p], suspendCount[%d]\n",
7121 _ferror, _errorSource, _errorSuspend, _pos, _errorPos, _errorHandle, _suspendCount);
7122
7123+ DEBUG_EXIT_FUNC();
7124 return _ferror;
7125 }
7126
7127 void PSPIoStream::clearErr() {
7128 _ferror = false; // Remove regular error bit
7129-
7130 }
7131
7132 bool PSPIoStream::eos() const {
7133@@ -105,45 +118,43 @@
7134
7135
7136 int32 PSPIoStream::size() const {
7137+ DEBUG_ENTER_FUNC();
7138 if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
7139- PSPDebugSuspend("Suspended in PSPIoStream::size()\n");
7140+ PSP_DEBUG_PRINT_FUNC("Suspended\n");
7141
7142 fseek((FILE *)_handle, 0, SEEK_END);
7143 int32 length = ftell((FILE *)_handle);
7144 fseek((FILE *)_handle, _pos, SEEK_SET);
7145
7146 if (_pos < 0 || length < 0) { // Check for errors
7147- PSPDebugSuspend("In PSPIoStream::size(). encountered an error!\n");
7148+ _errorSource = 2;
7149+ PSP_ERROR("pos[%d] or length[%d] < 0!\n", _pos, length);
7150 _ferror = true;
7151 length = -1; // If our oldPos is bad, we want length to be bad too to signal
7152 clearerr((FILE *)_handle);
7153-
7154-#ifdef __PSP_DEBUG_SUSPEND__
7155- _errorSource = 2;
7156-#endif
7157 }
7158
7159 PowerMan.endCriticalSection();
7160
7161+ DEBUG_EXIT_FUNC();
7162 return length;
7163 }
7164
7165 bool PSPIoStream::seek(int32 offs, int whence) {
7166+ DEBUG_ENTER_FUNC();
7167+
7168 // Check if we can access the file
7169 if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
7170- PSPDebugSuspend("Suspended in PSPIoStream::seek()\n");
7171+ PSP_DEBUG_PRINT_FUNC("Suspended\n");
7172
7173 int ret = fseek((FILE *)_handle, offs, whence);
7174
7175 if (ret != 0) {
7176 _ferror = true;
7177- PSPDebugSuspend("In PSPIoStream::seek(). encountered an error!\n");
7178+ PSP_ERROR("fseek returned with [%d], non-zero\n", ret);
7179 clearerr((FILE *)_handle);
7180 _feof = feof((FILE *)_handle);
7181-
7182-#ifdef __PSP_DEBUG_SUSPEND__
7183 _errorSource = 3;
7184-#endif
7185 }
7186 else { // everything ok
7187 _feof = false; // Reset eof flag since we know it was ok
7188@@ -153,13 +164,17 @@
7189
7190 PowerMan.endCriticalSection();
7191
7192- return ret == 0;
7193+ DEBUG_EXIT_FUNC();
7194+ return (ret == 0);
7195 }
7196
7197 uint32 PSPIoStream::read(void *ptr, uint32 len) {
7198+ DEBUG_ENTER_FUNC();
7199 // Check if we can access the file
7200 if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
7201- PSPDebugSuspend("Suspended in PSPIoStream::read()\n");
7202+ PSP_DEBUG_PRINT_FUNC("Suspended\n");
7203+
7204+ PSP_DEBUG_PRINT_FUNC("filename[%s], len[%d]\n", _path.c_str(), len);
7205
7206 size_t ret = fread((byte *)ptr, 1, len, (FILE *)_handle);
7207
7208@@ -171,24 +186,25 @@
7209 _ferror = true;
7210 clearerr((FILE *)_handle);
7211 _pos = ftell((FILE *)_handle); // Update our position
7212- PSPDebugSuspend("In PSPIoStream::read(). encountered an error!\n");
7213-
7214-#ifdef __PSP_DEBUG_SUSPEND__
7215 _errorSource = 4;
7216-#endif
7217+ PSP_ERROR("fread returned ret[%d] instead of len[%d]\n", ret, len);
7218 }
7219 }
7220
7221 PowerMan.endCriticalSection();
7222
7223+ DEBUG_EXIT_FUNC();
7224 return ret;
7225 }
7226
7227 uint32 PSPIoStream::write(const void *ptr, uint32 len) {
7228+ DEBUG_ENTER_FUNC();
7229 // Check if we can access the file
7230 if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
7231- PSPDebugSuspend("Suspended in PSPIoStream::read()\n");
7232+ PSP_DEBUG_PRINT_FUNC("Suspended\n");
7233
7234+ PSP_DEBUG_PRINT_FUNC("filename[%s], len[%d]\n", _path.c_str(), len);
7235+
7236 size_t ret = fwrite(ptr, 1, len, (FILE *)_handle);
7237
7238 _pos += ret;
7239@@ -197,73 +213,73 @@
7240 _ferror = true;
7241 clearerr((FILE *)_handle);
7242 _pos = ftell((FILE *)_handle); // Update pos
7243- PSPDebugTrace("In PSPIoStream::write(). encountered an error!\n");
7244-
7245-#ifdef __PSP_DEBUG_SUSPEND__
7246 _errorSource = 5;
7247-#endif
7248+ PSP_ERROR("fwrite returned[%d] instead of len[%d]\n", ret, len);
7249 }
7250
7251 PowerMan.endCriticalSection();
7252
7253+ DEBUG_EXIT_FUNC();
7254 return ret;
7255 }
7256
7257 bool PSPIoStream::flush() {
7258+ DEBUG_ENTER_FUNC();
7259 // Enter critical section
7260 if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
7261- PSPDebugSuspend("Suspended in PSPIoStream::read()\n");
7262+ PSP_DEBUG_PRINT_FUNC("Suspended\n");
7263
7264 int ret = fflush((FILE *)_handle);
7265
7266 if (ret != 0) {
7267 _ferror = true;
7268 clearerr((FILE *)_handle);
7269- PSPDebugSuspend("In PSPIoStream::flush(). encountered an error!\n");
7270-
7271-#ifdef __PSP_DEBUG_SUSPEND__
7272 _errorSource = 6;
7273-#endif
7274+ PSP_ERROR("fflush returned ret[%u]\n", ret);
7275 }
7276
7277 PowerMan.endCriticalSection();
7278
7279- return ret == 0;
7280+ DEBUG_EXIT_FUNC();
7281+ return (ret == 0);
7282 }
7283
7284 // For the PSP, since we're building in suspend support, we moved opening
7285 // the actual file to an open function since we need an actual PSPIoStream object to suspend.
7286 //
7287 PSPIoStream *PSPIoStream::makeFromPath(const Common::String &path, bool writeMode) {
7288+ DEBUG_ENTER_FUNC_STATIC();
7289 PSPIoStream *stream = new PSPIoStream(path, writeMode);
7290
7291- if (stream->open() > 0) {
7292- return stream;
7293- } else {
7294+ if (stream->open() <= 0) {
7295 delete stream;
7296- return 0;
7297+ stream = 0;
7298 }
7299+
7300+ DEBUG_EXIT_FUNC_STATIC();
7301+ return stream;
7302 }
7303
7304 /*
7305 * Function to suspend the IO stream (called by PowerManager)
7306+ * we can have no output here
7307 */
7308 int PSPIoStream::suspend() {
7309-#ifdef __PSP_DEBUG_SUSPEND__
7310+ DEBUG_ENTER_FUNC();
7311 _suspendCount++;
7312
7313- if (_handle > 0 && _pos < 0) {
7314+ if (_handle > 0 && _pos < 0) { /* check for error */
7315 _errorSuspend = SuspendError;
7316 _errorPos = _pos;
7317 _errorHandle = _handle;
7318 }
7319-#endif /* __PSP_DEBUG_SUSPEND__ */
7320
7321 if (_handle > 0) {
7322 fclose((FILE *)_handle); // close our file descriptor
7323 _handle = (void *)0xFFFFFFFF; // Set handle to non-null invalid value so makeFromPath doesn't return error
7324 }
7325
7326+ DEBUG_EXIT_FUNC();
7327 return 0;
7328 }
7329
7330@@ -271,31 +287,27 @@
7331 * Function to resume the IO stream (called by Power Manager)
7332 */
7333 int PSPIoStream::resume() {
7334+ DEBUG_ENTER_FUNC();
7335 int ret = 0;
7336-#ifdef __PSP_DEBUG_SUSPEND__
7337 _suspendCount--;
7338-#endif
7339
7340 // We reopen our file descriptor
7341 _handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb");
7342 if (_handle <= 0) {
7343- PSPDebugSuspend("PSPIoStream::resume(): Couldn't reopen file %s\n", _path.c_str());
7344+ PSP_ERROR("Couldn't reopen file %s\n", _path.c_str());
7345 }
7346
7347 // Resume our previous position
7348 if (_handle > 0 && _pos > 0) {
7349 ret = fseek((FILE *)_handle, _pos, SEEK_SET);
7350
7351-#ifdef __PSP_DEBUG_SUSPEND__
7352 if (ret != 0) { // Check for problem
7353 _errorSuspend = ResumeError;
7354 _errorPos = _pos;
7355 _errorHandle = _handle;
7356 }
7357-#endif
7358-
7359 }
7360-
7361+ DEBUG_EXIT_FUNC();
7362 return ret;
7363 }
7364