Ticket #9063: suspend.patch

File suspend.patch, 24.4 KB (added by bluddy, 15 years ago)

Patch to allow suspend/resume on PSP

Line 
1diff -NrcB trunkorig/backends/fs/psp/psp-fs.cpp trunk/backends/fs/psp/psp-fs.cpp
2*** trunkorig/backends/fs/psp/psp-fs.cpp Mon Aug 3 00:12:40 2009
3--- trunk/backends/fs/psp/psp-fs.cpp Sun Aug 2 23:21:48 2009
4***************
5*** 26,32 ****
6
7 #include "engines/engine.h"
8 #include "backends/fs/abstract-fs.h"
9! #include "backends/fs/stdiostream.h"
10
11 #include <sys/stat.h>
12 #include <unistd.h>
13--- 26,32 ----
14
15 #include "engines/engine.h"
16 #include "backends/fs/abstract-fs.h"
17! #include "backends/fs/psp/psp-stream.h"
18
19 #include <sys/stat.h>
20 #include <unistd.h>
21***************
22*** 35,40 ****
23--- 35,41 ----
24
25 #define ROOT_PATH "ms0:/"
26
27+ #include "backends/platform/psp/trace.h"
28 /**
29 * Implementation of the ScummVM file system API based on PSPSDK API.
30 *
31***************
32*** 166,176 ****
33 }
34
35 Common::SeekableReadStream *PSPFilesystemNode::createReadStream() {
36! return StdioStream::makeFromPath(getPath().c_str(), false);
37 }
38
39 Common::WriteStream *PSPFilesystemNode::createWriteStream() {
40! return StdioStream::makeFromPath(getPath().c_str(), true);
41 }
42
43 #endif //#ifdef __PSP__
44--- 167,177 ----
45 }
46
47 Common::SeekableReadStream *PSPFilesystemNode::createReadStream() {
48! return PSPIoStream::makeFromPath(getPath(), false);
49 }
50
51 Common::WriteStream *PSPFilesystemNode::createWriteStream() {
52! return PSPIoStream::makeFromPath(getPath(), true);
53 }
54
55 #endif //#ifdef __PSP__
56diff -NrcB trunkorig/backends/fs/psp/psp-stream.cpp trunk/backends/fs/psp/psp-stream.cpp
57*** trunkorig/backends/fs/psp/psp-stream.cpp Thu Jan 1 02:00:00 1970
58--- trunk/backends/fs/psp/psp-stream.cpp Sun Aug 2 22:18:08 2009
59***************
60*** 0 ****
61--- 1,190 ----
62+ /* ScummVM - Graphic Adventure Engine
63+ *
64+ * ScummVM is the legal property of its developers, whose names
65+ * are too numerous to list here. Please refer to the COPYRIGHT
66+ * file distributed with this source distribution.
67+ *
68+ * This program is free software; you can redistribute it and/or
69+ * modify it under the terms of the GNU General Public License
70+ * as published by the Free Software Foundation; either version 2
71+ * of the License, or (at your option) any later version.
72+
73+ * This program is distributed in the hope that it will be useful,
74+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
75+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
76+ * GNU General Public License for more details.
77+
78+ * You should have received a copy of the GNU General Public License
79+ * along with this program; if not, write to the Free Software
80+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
81+ *
82+ * $URL: https://scummvm.svn.sourceforge.net:443/svnroot/scummvm/scummvm/trunk/backends/fs/stdiostream.cpp $
83+ * $Id: stdiostream.cpp 39143 2009-03-06 00:26:48Z sunmax $
84+ *
85+ */
86+ #ifdef __PSP__
87+
88+ #include "backends/fs/psp/psp-stream.h"
89+ #include "backends/platform/psp/trace.h"
90+ #include <errno.h>
91+
92+ /* For static variable */
93+ PowerManager *PSPIoStream::pm = 0;
94+
95+ PSPIoStream::PSPIoStream(void *handle, const Common::String &path, bool writeMode)
96+ : StdioStream(handle), _path(path), _writeMode(writeMode) {
97+
98+ assert(!path.empty());
99+
100+ if(pm == 0) pm = &(PowerManager::instance());
101+
102+ pm->registerSuspend(this);
103+ }
104+
105+ PSPIoStream::~PSPIoStream() {
106+
107+ pm->unregisterSuspend(this);
108+
109+ fclose((FILE *)_handle);
110+ }
111+
112+ bool PSPIoStream::err() const {
113+
114+ pm->blockOnSuspend();
115+ return ferror((FILE *)_handle) != 0;
116+ }
117+
118+ void PSPIoStream::clearErr() {
119+
120+ pm->blockOnSuspend();
121+ clearerr((FILE *)_handle);
122+ }
123+
124+ bool PSPIoStream::eos() const {
125+
126+ pm->blockOnSuspend();
127+ return feof((FILE *)_handle) != 0;
128+ }
129+
130+ int32 PSPIoStream::pos() const {
131+
132+ pm->blockOnSuspend();
133+ return ftell((FILE *)_handle);
134+ }
135+
136+ int32 PSPIoStream::size() const {
137+
138+ pm->blockOnSuspend();
139+
140+ int32 oldPos = ftell((FILE *)_handle);
141+ fseek((FILE *)_handle, 0, SEEK_END);
142+ int32 length = ftell((FILE *)_handle);
143+ fseek((FILE *)_handle, oldPos, SEEK_SET);
144+
145+ return length;
146+ }
147+
148+ bool PSPIoStream::seek(int32 offs, int whence) {
149+
150+ int ret = 0;
151+
152+ // Check if we can access the file
153+ pm->blockOnSuspend();
154+
155+ // Act. If we fail, maybe it was because of a suspend
156+ if((ret = fseek((FILE *)_handle, offs, whence)) != 0 && (pm->blockOnSuspend() == PowerManager::Blocked))
157+ {
158+ ret = fseek((FILE *)_handle, offs, whence);
159+ }
160+ return ret==0;
161+ }
162+
163+ uint32 PSPIoStream::read(void *ptr, uint32 len) {
164+
165+ int ret = 0;
166+ pm->blockOnSuspend();
167+
168+ // Act. If we fail, maybe it was because of a suspend
169+ ret = fread((byte *)ptr, 1, len, (FILE *)_handle);
170+ if(ferror((FILE *)_handle) && pm->blockOnSuspend() == PowerManager::Blocked)
171+ {
172+ clearerr((FILE *)_handle);
173+ fseek((FILE *)_handle, -ret, SEEK_CUR);
174+ ret = fread((byte *)ptr, 1, len, (FILE *)_handle);
175+ }
176+ return ret;
177+
178+ }
179+
180+ uint32 PSPIoStream::write(const void *ptr, uint32 len) {
181+
182+ int ret = 0;
183+
184+ pm->blockOnSuspend();
185+
186+ // Act. If we fail, maybe it was because of a suspend
187+ ret = fwrite(ptr, 1, len, (FILE *)_handle);
188+ if(ferror((FILE *)_handle) && (pm->blockOnSuspend() == PowerManager::Blocked))
189+ {
190+ clearerr((FILE *)_handle);
191+ fseek((FILE *)_handle, -ret, SEEK_CUR);
192+ ret = fwrite(ptr, 1, len, (FILE *)_handle);
193+ }
194+ return ret;
195+ }
196+
197+ bool PSPIoStream::flush() {
198+
199+ int ret = 0;
200+
201+ pm->blockOnSuspend();
202+
203+ // Act. If we fail, maybe it was because of a suspend
204+ if((ret = fflush((FILE *)_handle)) != 0 && pm->blockOnSuspend() == PowerManager::Blocked)
205+ {
206+ ret = fflush((FILE *)_handle);
207+ }
208+ return ret == 0;
209+ }
210+
211+ PSPIoStream *PSPIoStream::makeFromPath(const Common::String &path, bool writeMode) {
212+
213+ FILE *handle = fopen(path.c_str(), writeMode ? "wb" : "rb");
214+
215+ if (handle)
216+ return new PSPIoStream(handle, path, writeMode);
217+ return 0;
218+ }
219+
220+
221+ int PSPIoStream::suspend() {
222+
223+ // Save our position
224+ _pos = ftell((FILE *)_handle);
225+
226+ // close our file descriptor
227+ fclose((FILE *)_handle);
228+
229+ return 0;
230+ }
231+
232+ int PSPIoStream::resume() {
233+ int ret = 0;
234+
235+ // We reopen our file descriptor
236+ _handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb");
237+ if(_handle<=0)
238+ {
239+ PSPDebugTrace("PSPIoStream::resume(): Couldn't reopen file %s\n", _path.c_str());
240+ ret = -1;;
241+ }
242+
243+ // Resume our previous position
244+ fseek((FILE *)_handle, _pos, SEEK_SET);
245+
246+ return ret;
247+ }
248+
249+
250+
251+ #endif /* __PSP__ */
252diff -NrcB trunkorig/backends/fs/psp/psp-stream.h trunk/backends/fs/psp/psp-stream.h
253*** trunkorig/backends/fs/psp/psp-stream.h Thu Jan 1 02:00:00 1970
254--- trunk/backends/fs/psp/psp-stream.h Sun Aug 2 21:55:51 2009
255***************
256*** 0 ****
257--- 1,69 ----
258+ /* ScummVM - Graphic Adventure Engine
259+ *
260+ * ScummVM is the legal property of its developers, whose names
261+ * are too numerous to list here. Please refer to the COPYRIGHT
262+ * file distributed with this source distribution.
263+ *
264+ * This program is free software; you can redistribute it and/or
265+ * modify it under the terms of the GNU General Public License
266+ * as published by the Free Software Foundation; either version 2
267+ * of the License, or (at your option) any later version.
268+
269+ * This program is distributed in the hope that it will be useful,
270+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
271+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
272+ * GNU General Public License for more details.
273+
274+ * You should have received a copy of the GNU General Public License
275+ * along with this program; if not, write to the Free Software
276+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
277+ *
278+ * $URL: https://scummvm.svn.sourceforge.net:443/svnroot/scummvm/scummvm/trunk/backends/fs/stdiostream.h $
279+ * $Id: stdiostream.h 34549 2008-09-14 22:28:53Z wjpalenstijn $
280+ *
281+ */
282+
283+ #ifndef PSPSTREAM_H_
284+ #define PSPSTREAM_H_
285+
286+ #include "backends/fs/stdiostream.h"
287+ #include "backends/platform/psp/powerman.h"
288+ #include "common/list.h"
289+
290+
291+ class PSPIoStream : public StdioStream, public Suspendable {
292+ protected:
293+ /** File handle to the actual file. */
294+ Common::String _path; /* Need to maintain for reopening after suspend */
295+ bool _writeMode; /* "" */
296+ unsigned int _pos; /* "" */
297+ static PowerManager *pm;
298+
299+
300+ public:
301+ /**
302+ * Given a path, invoke fopen on that path and wrap the result in a
303+ * StdioStream instance.
304+ */
305+ static PSPIoStream *makeFromPath(const Common::String &path, bool writeMode);
306+
307+ PSPIoStream(void *handle, const Common::String &path, bool writeMode);
308+ virtual ~PSPIoStream();
309+
310+ bool err() const;
311+ void clearErr();
312+ bool eos() const;
313+
314+ virtual uint32 write(const void *dataPtr, uint32 dataSize);
315+ virtual bool flush();
316+
317+ virtual int32 pos() const;
318+ virtual int32 size() const;
319+ virtual bool seek(int32 offs, int whence = SEEK_SET);
320+ virtual uint32 read(void *dataPtr, uint32 dataSize);
321+
322+ int suspend(); /* Suspendable interface */
323+ int resume(); /* " " */
324+ };
325+
326+ #endif /* PSPSTREAM_H_ */
327diff -NrcB trunkorig/backends/module.mk trunk/backends/module.mk
328*** trunkorig/backends/module.mk Mon Aug 3 00:12:46 2009
329--- trunk/backends/module.mk Sun Aug 2 22:56:20 2009
330***************
331*** 11,16 ****
332--- 11,17 ----
333 fs/posix/posix-fs-factory.o \
334 fs/ps2/ps2-fs-factory.o \
335 fs/psp/psp-fs-factory.o \
336+ fs/psp/psp-stream.o \
337 fs/symbian/symbian-fs-factory.o \
338 fs/windows/windows-fs-factory.o \
339 fs/wii/wii-fs-factory.o \
340diff -NrcB trunkorig/backends/platform/psp/Makefile trunk/backends/platform/psp/Makefile
341*** trunkorig/backends/platform/psp/Makefile Mon Aug 3 00:11:47 2009
342--- trunk/backends/platform/psp/Makefile Sun Aug 2 23:26:38 2009
343***************
344*** 75,86 ****
345 CXXFLAGS+= -DUSE_VORBIS -DUSE_TREMOR
346 LIBS += -lvorbisidec
347
348! LIBS += `$(PSPBIN)/sdl-config --libs` -lz -lstdc++ -lc -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpsputility -lpspsdk -lpspuser
349
350 CXXFLAGS := $(CXXFLAGS) -fno-exceptions -fno-rtti
351
352 TARGET = scummvm-psp
353! OBJS := psp_main.o \
354 osys_psp.o \
355 osys_psp_gu.o \
356 kbd_ss_c.o \
357--- 75,87 ----
358 CXXFLAGS+= -DUSE_VORBIS -DUSE_TREMOR
359 LIBS += -lvorbisidec
360
361! LIBS += `$(PSPBIN)/sdl-config --libs` -lz -lstdc++ -lc -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpsputility -lpspuser -lpsppower
362
363 CXXFLAGS := $(CXXFLAGS) -fno-exceptions -fno-rtti
364
365 TARGET = scummvm-psp
366! OBJS := powerman.o \
367! psp_main.o \
368 osys_psp.o \
369 osys_psp_gu.o \
370 kbd_ss_c.o \
371diff -NrcB trunkorig/backends/platform/psp/powerman.cpp trunk/backends/platform/psp/powerman.cpp
372*** trunkorig/backends/platform/psp/powerman.cpp Thu Jan 1 02:00:00 1970
373--- trunk/backends/platform/psp/powerman.cpp Sun Aug 2 22:13:29 2009
374***************
375*** 0 ****
376--- 1,256 ----
377+ /* ScummVM - Graphic Adventure Engine
378+ *
379+ * ScummVM is the legal property of its developers, whose names
380+ * are too numerous to list here. Please refer to the COPYRIGHT
381+ * file distributed with this source distribution.
382+ *
383+ * This program is free software; you can redistribute it and/or
384+ * modify it under the terms of the GNU General Public License
385+ * as published by the Free Software Foundation; either version 2
386+ * of the License, or (at your option) any later version.
387+
388+ * This program is distributed in the hope that it will be useful,
389+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
390+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
391+ * GNU General Public License for more details.
392+
393+ * You should have received a copy of the GNU General Public License
394+ * along with this program; if not, write to the Free Software
395+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
396+ *
397+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-0-13-1/backends/platform/psp/psp_main.cpp $
398+ * $Id: psp_main.cpp 34827 2008-10-19 21:06:26Z fingolfin $
399+ *
400+ */
401+
402+ #include "./powerman.h"
403+
404+ DECLARE_SINGLETON(PowerManager);
405+
406+ /*******************************************
407+ *
408+ * Constructor
409+ *
410+ ********************************************/
411+ PowerManager::PowerManager() {
412+ _flagMutex = NULL; /* Init mutex handle */
413+ _listMutex = NULL; /* Init mutex handle */
414+ _cond = NULL; /* Init condition variable */
415+
416+ _cond = SDL_CreateCond();
417+ if(_cond <= 0)
418+ {
419+ PSPDebugTrace("PowerManager::PowerManager(): Couldn't create cond\n");
420+ }
421+
422+ _flagMutex = SDL_CreateMutex();
423+ if(_flagMutex <= 0)
424+ {
425+ PSPDebugTrace("PowerManager::PowerManager(): Couldn't create flagMutex\n");
426+ }
427+
428+ _listMutex = SDL_CreateMutex();
429+ if(_listMutex <= 0)
430+ {
431+ PSPDebugTrace("PowerManager::PowerManager(): Couldn't create listMutex\n");
432+ }
433+
434+ _suspendFlag = false;
435+
436+ }
437+
438+ /*******************************************
439+ *
440+ * Function to register to be notified when suspend/resume time comes
441+ *
442+ ********************************************/
443+ int PowerManager::registerSuspend(Suspendable *item) {
444+ // Register in list
445+ if(SDL_mutexP(_listMutex) != 0)
446+ {
447+ PSPDebugTrace("PowerManager::registerSuspend(): Couldn't lock _listMutex %d\n", _listMutex);
448+ }
449+
450+ _suspendList.push_front(item);
451+
452+ if(SDL_mutexV(_listMutex) != 0)
453+ {
454+ PSPDebugTrace("PowerManager::registerSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
455+ }
456+
457+ return 0;
458+ }
459+
460+ /*******************************************
461+ *
462+ * Function to unregister to be notified when suspend/resume time comes
463+ *
464+ ********************************************/
465+ int PowerManager::unregisterSuspend(Suspendable *item) {
466+ // Unregister from stream list
467+ if(SDL_mutexP(_listMutex) != 0)
468+ {
469+ PSPDebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
470+ }
471+
472+ _suspendList.remove(item);
473+
474+ if(SDL_mutexV(_listMutex) != 0)
475+ {
476+ PSPDebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
477+ }
478+
479+ return 0;
480+
481+ }
482+
483+ /*******************************************
484+ *
485+ * Destructor
486+ *
487+ ********************************************/
488+ PowerManager::~PowerManager() {
489+
490+ SDL_DestroyCond(_cond);
491+ _cond = 0;
492+
493+ SDL_DestroyMutex(_flagMutex);
494+ _flagMutex = 0;
495+
496+ SDL_DestroyMutex(_listMutex);
497+ _listMutex = 0;
498+ }
499+
500+
501+ /*******************************************
502+ *
503+ * Function to be called by threads wanting to block on the PSP entering suspend
504+ *
505+ ********************************************/
506+ int PowerManager::blockOnSuspend() const {
507+
508+ int ret = PowerManager::NotBlocked;
509+
510+ if(SDL_mutexP(_flagMutex) != 0)
511+ {
512+ PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't lock flagMutex %d\n", _flagMutex);
513+ ret = PowerManager::Error;
514+ }
515+
516+ // Check the access flag
517+ if(_suspendFlag==true)
518+ {
519+ ret = PowerManager::Blocked;
520+
521+ // If it's true, we wait for a signal to continue
522+ if(SDL_CondWait(_cond, _flagMutex) != 0)
523+ {
524+ PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't wait on cond %d\n", _cond);
525+ }
526+ }
527+
528+ if(SDL_mutexV(_flagMutex) != 0)
529+ {
530+ PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't unlock flagMutex %d\n", _flagMutex);
531+ ret = PowerManager::Error;
532+ }
533+
534+ return ret;
535+ }
536+
537+ /*******************************************
538+ *
539+ * Callback function to be called to put every Suspendable to suspend
540+ *
541+ ********************************************/
542+ int PowerManager::suspend() {
543+
544+ int ret = 0;
545+
546+ // First we set the suspend flag to true
547+ if(SDL_mutexP(_flagMutex) != 0)
548+ {
549+ PSPDebugTrace("PowerManager::suspend(): Couldn't lock flagMutex %d\n", _flagMutex);
550+ ret = -1;
551+ }
552+
553+ _suspendFlag = true;
554+
555+ if(SDL_mutexV(_flagMutex) != 0)
556+ {
557+ PSPDebugTrace("PowerManager::suspend(): Couldn't unlock flagMutex %d\n", _flagMutex);
558+ ret = -1;
559+ }
560+
561+ // Loop over list, calling suspend()
562+ if(SDL_mutexP(_listMutex) != 0)
563+ {
564+ PSPDebugTrace("PowerManager::suspend(): Couldn't lock listMutex %d\n", _listMutex);
565+ ret = -1;
566+ }
567+
568+ Common::List<Suspendable *>::iterator i = _suspendList.begin();
569+
570+ for(; i != _suspendList.end(); i++)
571+ {
572+ (*i)->suspend();
573+ }
574+
575+ if(SDL_mutexV(_listMutex) != 0)
576+ {
577+ PSPDebugTrace("PowerManager::suspend(): Couldn't unlock listMutex %d\n", _listMutex);
578+ ret = -1;
579+ }
580+
581+ return ret;
582+ }
583+
584+ /*******************************************
585+ *
586+ * Callback function to resume every Suspendable
587+ *
588+ ********************************************/
589+ int PowerManager::resume() {
590+
591+ int ret = 0;
592+
593+ // First we notify our Suspendables. Loop over list, calling resume()
594+ if(SDL_mutexP(_listMutex) != 0)
595+ {
596+ PSPDebugTrace("PowerManager::resume(): Couldn't lock listMutex %d\n", _listMutex);
597+ ret = -1;
598+ }
599+
600+ Common::List<Suspendable *>::iterator i = _suspendList.begin();
601+
602+ for(; i != _suspendList.end(); i++)
603+ {
604+ (*i)->resume();
605+ }
606+
607+ if(SDL_mutexV(_listMutex) != 0)
608+ {
609+ PSPDebugTrace("PowerManager::resume(): Couldn't unlock listMutex %d\n", _listMutex);
610+ ret = -1;
611+ }
612+
613+ // Now we set the suspend flag to false
614+ if(SDL_mutexP(_flagMutex) != 0) {
615+ PSPDebugTrace("PowerManager::resume(): Couldn't lock flagMutex %d\n", _flagMutex);
616+ ret = -1;
617+ }
618+ _suspendFlag = false;
619+
620+ // Signal the other threads to wake up
621+ if(SDL_CondBroadcast(_cond) != 0) {
622+ PSPDebugTrace("PowerManager::resume(): Couldn't broadcast condition %d\n", _cond);
623+ ret = -1;
624+ }
625+
626+ if(SDL_mutexV(_flagMutex) != 0) {
627+ PSPDebugTrace("PowerManager::resume(): Couldn't unlock flagMutex %d\n", _flagMutex);
628+ ret = -1;
629+ }
630+
631+ return ret;
632+ }
633diff -NrcB trunkorig/backends/platform/psp/powerman.h trunk/backends/platform/psp/powerman.h
634*** trunkorig/backends/platform/psp/powerman.h Thu Jan 1 02:00:00 1970
635--- trunk/backends/platform/psp/powerman.h Sun Aug 2 21:55:08 2009
636***************
637*** 0 ****
638--- 1,79 ----
639+ /* ScummVM - Graphic Adventure Engine
640+ *
641+ * ScummVM is the legal property of its developers, whose names
642+ * are too numerous to list here. Please refer to the COPYRIGHT
643+ * file distributed with this source distribution.
644+ *
645+ * This program is free software; you can redistribute it and/or
646+ * modify it under the terms of the GNU General Public License
647+ * as published by the Free Software Foundation; either version 2
648+ * of the License, or (at your option) any later version.
649+
650+ * This program is distributed in the hope that it will be useful,
651+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
652+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
653+ * GNU General Public License for more details.
654+
655+ * You should have received a copy of the GNU General Public License
656+ * along with this program; if not, write to the Free Software
657+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
658+ *
659+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-0-13-1/backends/platform/psp/psp_main.cpp $
660+ * $Id: psp_main.cpp 34827 2008-10-19 21:06:26Z fingolfin $
661+ *
662+ */
663+
664+ #ifndef POWERMAN_H
665+ #define POWERMAN_H
666+
667+ #include <SDL/SDL_thread.h>
668+ #include <SDL/SDL_mutex.h>
669+ #include "common/singleton.h"
670+ #include "common/list.h"
671+
672+ /* Implement this class (interface) if you want to use PowerManager's suspend callback functionality */
673+ class Suspendable
674+ {
675+ public:
676+ virtual int suspend() = 0;
677+ virtual int resume() = 0;
678+ };
679+
680+ /******************************************************************************************************
681+ *
682+ * This class will call a Suspendable when the PSP goes to suspend/resumes. It also provides the ability to block
683+ * a thread when the PSP is going to suspend/suspending, and to wake it up when the PSP is resumed.
684+ * This ability is very useful for managing the PSPIoStream class, but may be found useful by other classes as well.
685+ *
686+ *******************************************************************************************************/
687+ class PowerManager: public Common::Singleton<PowerManager>
688+ {
689+ private:
690+ friend class Common::Singleton<PowerManager>;
691+ PowerManager();
692+ ~PowerManager();
693+
694+ Common::List<Suspendable *> _suspendList; /* list to register in */
695+
696+ bool _suspendFlag; /* protected variable */
697+ SDL_mutex *_flagMutex; /* mutex to access access flag */
698+ SDL_mutex *_listMutex; /* mutex to access Suspendable list */
699+ SDL_cond *_cond; /* signal to synchronize accessing threads */
700+
701+ public:
702+ int blockOnSuspend() const; /* block if suspending */
703+ int registerSuspend(Suspendable *item); /* register to be called to suspend/resume */
704+ int unregisterSuspend(Suspendable *item); /* remove from suspend/resume list */
705+ int suspend(); /* callback to have all items in list suspend */
706+ int resume(); /* callback to have all items in list resume */
707+
708+ enum
709+ {
710+ Error = -1,
711+ NotBlocked = 0,
712+ Blocked = 1
713+ };
714+
715+ };
716+
717+ #endif /* POWERMAN_H */
718diff -NrcB trunkorig/backends/platform/psp/psp_main.cpp trunk/backends/platform/psp/psp_main.cpp
719*** trunkorig/backends/platform/psp/psp_main.cpp Mon Aug 3 00:11:47 2009
720--- trunk/backends/platform/psp/psp_main.cpp Sun Aug 2 23:01:06 2009
721***************
722*** 18,25 ****
723 * along with this program; if not, write to the Free Software
724 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
725 *
726! * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/psp_main.cpp $
727! * $Id: psp_main.cpp 40204 2009-04-29 15:54:35Z joostp $
728 *
729 */
730
731--- 18,25 ----
732 * along with this program; if not, write to the Free Software
733 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
734 *
735! * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-0-13-1/backends/platform/psp/psp_main.cpp $
736! * $Id: psp_main.cpp 34827 2008-10-19 21:06:26Z fingolfin $
737 *
738 */
739
740***************
741*** 31,40 ****
742--- 31,44 ----
743 #include <pspdebug.h>
744 #endif
745
746+ #include <psppower.h>
747+
748 #include <common/system.h>
749 #include <engines/engine.h>
750 #include <base/main.h>
751 #include <base/plugins.h>
752+ #include "backends/platform/psp/powerman.h"
753+
754
755 #include "osys_psp_gu.h"
756 #include "./trace.h"
757***************
758*** 91,107 ****
759 #endif
760
761 /* Exit callback */
762! SceKernelCallbackFunction exit_callback(int /*arg1*/, int /*arg2*/, void * /*common*/) {
763 sceKernelExitGame();
764 return 0;
765 }
766
767 /* Callback thread */
768 int CallbackThread(SceSize /*size*/, void *arg) {
769 int cbid;
770
771 cbid = sceKernelCreateCallback("Exit Callback", (SceKernelCallbackFunction)exit_callback, NULL);
772 sceKernelRegisterExitCallback(cbid);
773
774 sceKernelSleepThreadCB();
775 return 0;
776--- 96,139 ----
777 #endif
778
779 /* Exit callback */
780! int exit_callback(void) {
781 sceKernelExitGame();
782 return 0;
783 }
784
785+ /* Function for handling suspend/resume */
786+ void power_callback(int , int powerinfo)
787+ {
788+ PowerManager *pm = &(PowerManager::instance());
789+
790+ if(powerinfo & PSP_POWER_CB_POWER_SWITCH || powerinfo & PSP_POWER_CB_SUSPENDING)
791+ {
792+ pm->suspend();
793+
794+ }
795+ else if(powerinfo & PSP_POWER_CB_RESUME_COMPLETE)
796+ {
797+ pm->resume();
798+ }
799+ }
800+
801 /* Callback thread */
802 int CallbackThread(SceSize /*size*/, void *arg) {
803 int cbid;
804
805 cbid = sceKernelCreateCallback("Exit Callback", (SceKernelCallbackFunction)exit_callback, NULL);
806 sceKernelRegisterExitCallback(cbid);
807+ /* Set up callbacks for PSPIoStream */
808+
809+ cbid = sceKernelCreateCallback("Power Callback", (SceKernelCallbackFunction)power_callback, 0);
810+ if (cbid >= 0) {
811+ if(scePowerRegisterCallback(-1, cbid) < 0) {
812+ PSPDebugTrace("SetupCallbacks(): Couldn't register callback for power_callback\n");
813+ }
814+ }
815+ else {
816+ PSPDebugTrace("SetupCallbacks(): Couldn't create a callback for power_callback\n");
817+ }
818
819 sceKernelSleepThreadCB();
820 return 0;
821***************
822*** 119,124 ****
823--- 153,161 ----
824
825 #undef main
826 int main(void) {
827+
828+ PowerManager::instance(); // Setup power manager
829+
830 SetupCallbacks();
831
832 static const char *argv[] = { "scummvm", NULL };
833***************
834*** 131,136 ****
835--- 168,175 ----
836
837 g_system->quit(); // TODO: Consider removing / replacing this!
838
839+ PowerManager::destroy(); // get rid of PowerManager
840+
841 sceKernelSleepThread();
842
843 return res;