Ticket #9063: suspend.2.patch

File suspend.2.patch, 30.9 KB (added by bluddy, 11 years ago)

Worked out some bugs. Good to go hopefully.

  • backends/platform/psp/psp_main.cpp

     
    3131#include <pspdebug.h>
    3232#endif
    3333
     34#include <psppower.h>
     35
    3436#include <common/system.h>
    3537#include <engines/engine.h>
    3638#include <base/main.h>
    3739#include <base/plugins.h>
     40#include "backends/platform/psp/powerman.h"
    3841
     42
    3943#include "osys_psp_gu.h"
    4044#include "./trace.h"
    4145
     
    9195#endif
    9296
    9397/* Exit callback */
    94 SceKernelCallbackFunction exit_callback(int /*arg1*/, int /*arg2*/, void * /*common*/) {
     98int exit_callback(void) {
    9599        sceKernelExitGame();
    96100        return 0;
    97101}
    98102
     103/* Function for handling suspend/resume */
     104void power_callback(int , int powerinfo) {
     105
     106        if(powerinfo & PSP_POWER_CB_POWER_SWITCH || powerinfo & PSP_POWER_CB_SUSPENDING) {
     107                PowerMan.suspend();
     108        }
     109        else if(powerinfo & PSP_POWER_CB_RESUME_COMPLETE) {
     110                PowerMan.resume();
     111        }
     112}
     113
    99114/* Callback thread */
    100115int CallbackThread(SceSize /*size*/, void *arg) {
    101116        int cbid;
    102117
    103118        cbid = sceKernelCreateCallback("Exit Callback", (SceKernelCallbackFunction)exit_callback, NULL);
    104119        sceKernelRegisterExitCallback(cbid);
     120        /* Set up callbacks for PSPIoStream */
    105121
     122        cbid = sceKernelCreateCallback("Power Callback", (SceKernelCallbackFunction)power_callback, 0);
     123        if (cbid >= 0) {
     124                if(scePowerRegisterCallback(-1, cbid) < 0) {
     125                        PSPDebugTrace("SetupCallbacks(): Couldn't register callback for power_callback\n");
     126                }
     127        }
     128        else {
     129                PSPDebugTrace("SetupCallbacks(): Couldn't create a callback for power_callback\n");
     130        }
     131
    106132        sceKernelSleepThreadCB();
    107133        return 0;
    108134}
     
    119145
    120146#undef main
    121147int main(void) {
     148
     149        PowerManager::instance();       // Setup power manager
     150
    122151        SetupCallbacks();
    123152
    124153        static const char *argv[] = { "scummvm", NULL };
     
    131160
    132161        g_system->quit();       // TODO: Consider removing / replacing this!
    133162
     163        PowerManager::destroy();        // get rid of PowerManager
     164
    134165        sceKernelSleepThread();
    135166
    136167        return res;
  • backends/platform/psp/psp.spec

     
    11%rename lib     old_lib
    22*lib:
    3 %(old_lib) -lpspdebug -lpspgu -lpspctrl -lpspge -lpspdisplay -lpsphprm -lpspsdk -lpsprtc -lpspaudio -lc -lpspuser -lpsputility -lpspkernel -lpspnet_inet -lz -lstdc++ -lc -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpsputility -lpspsdk -lpspuser
     3%(old_lib) -lpspdebug -lpspgu -lpspctrl -lpspge -lpspdisplay -lpsphprm -lpspsdk -lpsprtc -lpspaudio -lc -lpspuser -lpsputility -lpspkernel -lpspnet_inet -lz -lstdc++ -lc -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpsputility -lpspuser -lpsppower
  • backends/platform/psp/osys_psp.cpp

     
    430430                        } else if (buttonsChanged & PSP_CTRL_START) {
    431431                                event.kbd.keycode = Common::KEYCODE_F5;
    432432                                event.kbd.ascii = Common::ASCII_F5;
     433                                event.kbd.flags = Common::KBD_CTRL;     // Main menu to allow RTL
    433434/*                      } else if (buttonsChanged & PSP_CTRL_SELECT) {
    434435                                event.kbd.keycode = Common::KEYCODE_0;
    435436                                event.kbd.ascii = '0';
  • backends/platform/psp/osys_psp.h

     
    2323 *
    2424 */
    2525
     26#ifndef OSYS_PSP_H
     27#define OSYS_PSP_H
     28
    2629#include "common/scummsys.h"
    2730#include "graphics/surface.h"
    2831#include "graphics/colormasks.h"
     
    144147        virtual Common::WriteStream *createConfigWriteStream();
    145148};
    146149
     150
     151#endif /* OSYS_PSP_H */
  • backends/platform/psp/powerman.cpp

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-0-13-1/backends/platform/psp/psp_main.cpp $
     22 * $Id: psp_main.cpp 34827 2008-10-19 21:06:26Z fingolfin $
     23 *
     24 */
     25
     26#include "./powerman.h"
     27
     28DECLARE_SINGLETON(PowerManager);
     29
     30 /*******************************************
     31*
     32*       Constructor
     33*
     34********************************************/
     35 PowerManager::PowerManager() {
     36        _flagMutex = NULL;                                      /* Init mutex handle */
     37        _listMutex = NULL;                                      /* Init mutex handle */
     38        _condSuspendable = NULL;                        /* Init condition variable */
     39        _condPM = NULL;
     40       
     41        _condSuspendable = SDL_CreateCond();
     42        if(_condSuspendable <= 0) {
     43                PSPDebugTrace("PowerManager::PowerManager(): Couldn't create condSuspendable\n");
     44        }
     45       
     46        _condPM = SDL_CreateCond();
     47        if(_condPM <= 0) {
     48                PSPDebugTrace("PowerManager::PowerManager(): Couldn't create condPM\n");
     49        }
     50
     51        _flagMutex = SDL_CreateMutex();
     52        if(_flagMutex <= 0) {
     53                PSPDebugTrace("PowerManager::PowerManager(): Couldn't create flagMutex\n");
     54        }
     55
     56        _listMutex = SDL_CreateMutex();
     57        if(_listMutex <= 0) {
     58                PSPDebugTrace("PowerManager::PowerManager(): Couldn't create listMutex\n");
     59        }
     60
     61        _suspendFlag = false;
     62        _criticalCounter = 0;
     63
     64 }
     65 
     66/*******************************************
     67*
     68*       Function to register to be notified when suspend/resume time comes
     69*
     70********************************************/
     71int PowerManager::registerSuspend(Suspendable *item) {
     72        // Register in list
     73        PSPDebugTrace("In registerSuspend\n");
     74
     75        if(SDL_mutexP(_listMutex) != 0) {
     76                PSPDebugTrace("PowerManager::registerSuspend(): Couldn't lock _listMutex %d\n", _listMutex);
     77        }
     78
     79        _suspendList.push_front(item);
     80
     81        if(SDL_mutexV(_listMutex) != 0) {
     82                PSPDebugTrace("PowerManager::registerSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
     83        }
     84
     85        PSPDebugTrace("Out of registerSuspend\n");
     86
     87        return 0;
     88}
     89
     90/*******************************************
     91*
     92*       Function to unregister to be notified when suspend/resume time comes
     93*
     94********************************************/ 
     95 int PowerManager::unregisterSuspend(Suspendable *item) {
     96
     97        PSPDebugTrace("In unregisterSuspend\n");
     98
     99         // Unregister from stream list
     100        if(SDL_mutexP(_listMutex) != 0) {
     101                PSPDebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
     102        }
     103
     104        _suspendList.remove(item);
     105
     106        if(SDL_mutexV(_listMutex) != 0) {
     107                PSPDebugTrace("PowerManager::unregisterSuspend(): Couldn't unlock _listMutex %d\n", _listMutex);
     108        }
     109
     110        PSPDebugTrace("Out of unregisterSuspend\n");
     111
     112        return 0;
     113 }
     114 
     115 /*******************************************
     116*
     117*       Destructor
     118*
     119********************************************/
     120 PowerManager::~PowerManager() {
     121
     122        SDL_DestroyCond(_condSuspendable);
     123        _condSuspendable = 0;
     124       
     125        SDL_DestroyCond(_condPM);
     126        _condPM = 0;
     127
     128        SDL_DestroyMutex(_flagMutex);
     129        _flagMutex = 0;
     130
     131        SDL_DestroyMutex(_listMutex);
     132        _listMutex = 0;
     133 }
     134 
     135 
     136 /*******************************************
     137*
     138*       Function to be called by threads wanting to block on the PSP entering suspend
     139*
     140********************************************/ 
     141 int PowerManager::blockOnSuspend()  {
     142
     143        return beginCriticalSection(true);
     144}
     145
     146 /*
     147  * Function to block on a suspend, then start a non-suspendable critical section
     148  */
     149int PowerManager::beginCriticalSection(bool justBlock) {
     150        int ret = PowerManager::NotBlocked;
     151
     152        if(SDL_mutexP(_flagMutex) != 0) {
     153                PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't lock flagMutex %d\n", _flagMutex);
     154                ret = PowerManager::Error;
     155        }
     156
     157        // Check the access flag
     158        if(_suspendFlag==true) {
     159                PSPDebugTrace("Blocking!!!!!!!!!!!!!!!!!!!!!!\n");
     160                ret = PowerManager::Blocked;
     161
     162                // If it's true, we wait for a signal to continue
     163                if(SDL_CondWait(_condSuspendable, _flagMutex) != 0) {
     164                        PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't wait on cond %d\n", _condSuspendable);
     165                }
     166
     167                PSPDebugTrace("We got blocked!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
     168        }
     169       
     170        // Now put the pm to sleep
     171        if(justBlock == false)
     172                _criticalCounter++;
     173
     174        if(SDL_mutexV(_flagMutex) != 0) {
     175                PSPDebugTrace("PowerManager::blockOnSuspend(): Couldn't unlock flagMutex %d\n", _flagMutex);
     176                ret = PowerManager::Error;
     177        }
     178
     179        return ret;
     180}
     181
     182int PowerManager::endCriticalSection() {
     183        int ret = 0;
     184
     185        if(SDL_mutexP(_flagMutex) != 0) {
     186                PSPDebugTrace("PowerManager::endCriticalSection(): Couldn't lock flagMutex %d\n", _flagMutex);
     187                ret = PowerManager::Error;
     188        }
     189
     190        // We're done with our critical section
     191        _criticalCounter--;
     192       
     193        if(_criticalCounter <= 0) {
     194                if(_suspendFlag == true) PSPDebugTrace("Waking up the PM and suspendFlag is true\n");
     195
     196                SDL_CondBroadcast(_condPM);
     197
     198                if(_criticalCounter < 0) {
     199                        PSPDebugTrace("PowerManager::endCriticalSection(): Error! Critical counter is %d\n", _criticalCounter);
     200                }
     201        }
     202
     203        if(SDL_mutexV(_flagMutex) != 0) {
     204                PSPDebugTrace("PowerManager::endCriticalSection(): Couldn't unlock flagMutex %d\n", _flagMutex);
     205                ret = PowerManager::Error;
     206        }
     207
     208        return ret;
     209}
     210
     211 /*******************************************
     212*
     213*       Callback function to be called to put every Suspendable to suspend
     214*
     215********************************************/ 
     216int PowerManager::suspend() {
     217
     218        int ret = 0;
     219
     220        // First we set the suspend flag to true
     221        if(SDL_mutexP(_flagMutex) != 0) {
     222                PSPDebugTrace("PowerManager::suspend(): Couldn't lock flagMutex %d\n", _flagMutex);
     223                ret = -1;
     224        }
     225
     226        _suspendFlag = true;
     227       
     228        if(_criticalCounter > 0)
     229                SDL_CondWait(_condPM, _flagMutex);
     230
     231        if(SDL_mutexV(_flagMutex) != 0) {
     232                PSPDebugTrace("PowerManager::suspend(): Couldn't unlock flagMutex %d\n", _flagMutex);
     233                ret = -1;
     234        }
     235
     236        // Loop over list, calling suspend()
     237        if(SDL_mutexP(_listMutex) != 0) {
     238                PSPDebugTrace("PowerManager::suspend(): Couldn't lock listMutex %d\n", _listMutex);
     239                ret = -1;
     240        }
     241
     242        Common::List<Suspendable *>::iterator i = _suspendList.begin();
     243
     244        for(; i != _suspendList.end(); i++) {
     245                (*i)->suspend();
     246        }
     247
     248        if(SDL_mutexV(_listMutex) != 0) {
     249                PSPDebugTrace("PowerManager::suspend(): Couldn't unlock listMutex %d\n", _listMutex);
     250                ret = -1;
     251        }
     252
     253        return ret;
     254}
     255
     256 /*******************************************
     257*
     258*       Callback function to resume every Suspendable
     259*
     260********************************************/ 
     261int PowerManager::resume() {
     262
     263        int ret = 0;
     264
     265        // First we notify our Suspendables. Loop over list, calling resume()
     266        if(SDL_mutexP(_listMutex) != 0) {
     267                PSPDebugTrace("PowerManager::resume(): Couldn't lock listMutex %d\n", _listMutex);
     268                ret = -1;
     269        }
     270
     271        Common::List<Suspendable *>::iterator i = _suspendList.begin();
     272
     273        for(; i != _suspendList.end(); i++) {
     274                (*i)->resume();
     275        }
     276
     277        if(SDL_mutexV(_listMutex) != 0) {
     278                PSPDebugTrace("PowerManager::resume(): Couldn't unlock listMutex %d\n", _listMutex);
     279                ret = -1;
     280        }
     281
     282        // Now we set the suspend flag to false
     283        if(SDL_mutexP(_flagMutex) != 0) {
     284                PSPDebugTrace("PowerManager::resume(): Couldn't lock flagMutex %d\n", _flagMutex);
     285                ret = -1;
     286        }
     287        _suspendFlag = false;
     288
     289        // Signal the other threads to wake up
     290        if(SDL_CondBroadcast(_condSuspendable) != 0) {
     291                PSPDebugTrace("PowerManager::resume(): Couldn't broadcast condition %d\n", _condSuspendable);
     292                ret = -1;
     293        }
     294
     295        if(SDL_mutexV(_flagMutex) != 0) {
     296                PSPDebugTrace("PowerManager::resume(): Couldn't unlock flagMutex %d\n", _flagMutex);
     297                ret = -1;
     298        }
     299
     300        return ret;
     301}
  • backends/platform/psp/Makefile

    Property changes on: backends/platform/psp/powerman.cpp
    ___________________________________________________________________
    Added: svn:executable
       + *
    
     
    7575CXXFLAGS+= -DUSE_VORBIS -DUSE_TREMOR
    7676LIBS    += -lvorbisidec
    7777
    78 LIBS    += `$(PSPBIN)/sdl-config --libs` -lz -lstdc++ -lc -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpsputility -lpspsdk -lpspuser
     78LIBS    += `$(PSPBIN)/sdl-config --libs` -lz -lstdc++ -lc -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpsputility -lpspuser -lpsppower
    7979
    8080CXXFLAGS := $(CXXFLAGS) -fno-exceptions -fno-rtti
    8181
    8282TARGET = scummvm-psp
    83 OBJS := psp_main.o \
     83OBJS := powerman.o \
     84        psp_main.o \
    8485        osys_psp.o \
    8586        osys_psp_gu.o \
    8687        kbd_ss_c.o \
  • backends/platform/psp/powerman.h

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-0-13-1/backends/platform/psp/psp_main.cpp $
     22 * $Id: psp_main.cpp 34827 2008-10-19 21:06:26Z fingolfin $
     23 *
     24 */
     25
     26#ifndef POWERMAN_H
     27#define POWERMAN_H
     28 
     29#include <SDL/SDL_thread.h>
     30#include <SDL/SDL_mutex.h>
     31#include "common/singleton.h"
     32#include "common/list.h"
     33 
     34 /*
     35  *  Implement this class (interface) if you want to use PowerManager's suspend callback functionality
     36  *
     37  */
     38 class Suspendable {
     39 public:
     40        virtual int suspend() = 0;
     41        virtual int resume() = 0;
     42 };
     43 
     44 /******************************************************************************************************
     45 *
     46 *  This class will call a Suspendable when the PSP goes to suspend/resumes. It also provides the ability to block
     47 *  a thread when the PSP is going to suspend/suspending, and to wake it up when the PSP is resumed.
     48 *      This ability is very useful for managing the PSPIoStream class, but may be found useful by other classes as well.
     49 *
     50 *******************************************************************************************************/
     51 class PowerManager: public Common::Singleton<PowerManager> {
     52private:
     53        friend class Common::Singleton<PowerManager>;
     54        PowerManager();
     55        ~PowerManager();
     56
     57        Common::List<Suspendable *> _suspendList;               /* list to register in */
     58
     59        bool _suspendFlag;                                                              /* protected variable */
     60        SDL_mutex *_flagMutex;                                                  /* mutex to access access flag */
     61        SDL_mutex *_listMutex;                                                  /* mutex to access Suspendable list */
     62        SDL_cond *_condSuspendable;                                             /* signal to synchronize accessing threads */
     63        SDL_cond *_condPM;                                                              /* signal to wake up the PM from a critical section */
     64        int _criticalCounter;                                                   /* Counter of how many threads are in a critical section */
     65
     66public:
     67        int blockOnSuspend();                                                           /* block if suspending */
     68        int beginCriticalSection(bool justBlock = false);       /* Use a critical section to block (if suspend was already pressed) */
     69        int endCriticalSection();                                                       /* and to prevent the PSP from suspending in a particular section */
     70        int registerSuspend(Suspendable *item);                 /* register to be called to suspend/resume */
     71        int unregisterSuspend(Suspendable *item);               /* remove from suspend/resume list */
     72        int suspend();                                                                  /* callback to have all items in list suspend */
     73        int resume();                                                                   /* callback to have all items in list resume */
     74       
     75        enum {
     76                Error = -1,
     77                NotBlocked = 0,
     78                Blocked = 1             
     79        };
     80               
     81 };
     82 
     83 // For easy access
     84#define PowerMan        PowerManager::instance()
     85
     86 #endif /* POWERMAN_H */
  • backends/fs/psp/psp-stream.h

    Property changes on: backends/platform/psp/powerman.h
    ___________________________________________________________________
    Added: svn:executable
       + *
    
     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net:443/svnroot/scummvm/scummvm/trunk/backends/fs/stdiostream.h $
     22 * $Id: stdiostream.h 34549 2008-09-14 22:28:53Z wjpalenstijn $
     23 *
     24 */
     25
     26#ifndef PSPSTREAM_H_
     27#define PSPSTREAM_H_
     28
     29#include "backends/fs/stdiostream.h"
     30#include "backends/platform/psp/powerman.h"
     31#include "common/list.h"
     32
     33/*
     34 *  Class to handle special suspend/resume needs of PSP IO Streams
     35 */
     36class PSPIoStream : public StdioStream, public Suspendable {
     37protected:
     38        Common::String _path;                   /* Need to maintain for reopening after suspend */
     39        bool _writeMode;                                /* "" */
     40        unsigned int _pos;                              /* "" */
     41
     42public:
     43        /**
     44         * Given a path, invoke fopen on that path and wrap the result in a
     45         * PSPIoStream instance.
     46         */
     47        static PSPIoStream *makeFromPath(const Common::String &path, bool writeMode);
     48
     49        PSPIoStream(const Common::String &path, bool writeMode);
     50        virtual ~PSPIoStream();
     51
     52        void * open();          // open the file pointed to by the file path
     53
     54        bool err() const;
     55        void clearErr();
     56        bool eos() const;
     57
     58        virtual uint32 write(const void *dataPtr, uint32 dataSize);
     59        virtual bool flush();
     60
     61        virtual int32 pos() const;
     62        virtual int32 size() const;
     63        virtual bool seek(int32 offs, int whence = SEEK_SET);
     64        virtual uint32 read(void *dataPtr, uint32 dataSize);
     65
     66        int suspend();          /* Suspendable interface (power manager) */
     67        int resume();           /* " " */
     68};
     69
     70#endif /* PSPSTREAM_H_ */
  • backends/fs/psp/psp-fs.cpp

    Property changes on: backends/fs/psp/psp-stream.h
    ___________________________________________________________________
    Added: svn:executable
       + *
    
     
    2626
    2727#include "engines/engine.h"
    2828#include "backends/fs/abstract-fs.h"
    29 #include "backends/fs/stdiostream.h"
     29#include "backends/fs/psp/psp-stream.h"
     30#include "backends/platform/psp/powerman.h"
    3031
    3132#include <sys/stat.h>
    3233#include <unistd.h>
     
    3536
    3637#define ROOT_PATH       "ms0:/"
    3738
     39#include "backends/platform/psp/trace.h"
     40
     41
    3842/**
    3943 * Implementation of the ScummVM file system API based on PSPSDK API.
    4044 *
     
    6165         */
    6266        PSPFilesystemNode(const Common::String &p, bool verify = true);
    6367
    64         virtual bool exists() const { return access(_path.c_str(), F_OK) == 0; }
     68        virtual bool exists() const;
    6569        virtual Common::String getDisplayName() const { return _displayName; }
    6670        virtual Common::String getName() const { return _displayName; }
    6771        virtual Common::String getPath() const { return _path; }
    6872        virtual bool isDirectory() const { return _isDirectory; }
    69         virtual bool isReadable() const { return access(_path.c_str(), R_OK) == 0; }
    70         virtual bool isWritable() const { return access(_path.c_str(), W_OK) == 0; }
     73        virtual bool isReadable() const;
     74        virtual bool isWritable() const;
    7175
    7276        virtual AbstractFSNode *getChild(const Common::String &n) const;
    7377        virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const;
     
    9498
    9599        if (verify) {
    96100                struct stat st;
     101                PowerMan.beginCriticalSection();
    97102                _isValid = (0 == stat(_path.c_str(), &st));
     103                PowerMan.endCriticalSection();
    98104                _isDirectory = S_ISDIR(st.st_mode);
    99105        }
    100106}
    101107
     108bool PSPFilesystemNode::exists() const {
     109        int ret = 0;
     110
     111        PowerMan.beginCriticalSection();        // Make sure to block in case of suspend
     112
     113        ret = access(_path.c_str(), F_OK);
     114
     115        PowerMan.endCriticalSection();
     116        return ret == 0;
     117}
     118
     119bool PSPFilesystemNode::isReadable() const {
     120
     121        int ret = 0;
     122
     123        PowerMan.beginCriticalSection();        // Make sure to block in case of suspend
     124
     125        ret = access(_path.c_str(), R_OK);
     126
     127        PowerMan.endCriticalSection();
     128       
     129        return ret == 0;
     130}
     131
     132bool PSPFilesystemNode::isWritable() const {
     133
     134        int ret = 0;
     135
     136        PowerMan.beginCriticalSection();        // Make sure to block in case of suspend
     137
     138        ret = access(_path.c_str(), W_OK);
     139
     140        PowerMan.endCriticalSection();
     141       
     142        return ret == 0;
     143}
     144
     145
    102146AbstractFSNode *PSPFilesystemNode::getChild(const Common::String &n) const {
    103147        // FIXME: Pretty lame implementation! We do no error checking to speak
    104148        // of, do not check if this is a special node, etc.
     
    117161
    118162        //TODO: honor the hidden flag
    119163
     164        bool ret = true;
     165
     166        PowerMan.beginCriticalSection();        // Make sure to block in case of suspend
     167       
    120168        int dfd  = sceIoDopen(_path.c_str());
    121169        if (dfd > 0) {
    122170                SceIoDirent dir;
     
    149197                }
    150198
    151199                sceIoDclose(dfd);
    152                 return true;
    153         } else {
    154                 return false;
     200                ret = true;
    155201        }
     202        else {  // dfd <= 0
     203                ret = false;
     204        }
     205        PowerMan.endCriticalSection();
     206        return ret;
    156207}
    157208
    158209AbstractFSNode *PSPFilesystemNode::getParent() const {
     
    166217}
    167218
    168219Common::SeekableReadStream *PSPFilesystemNode::createReadStream() {
    169         return StdioStream::makeFromPath(getPath().c_str(), false);
     220        return PSPIoStream::makeFromPath(getPath(), false);
    170221}
    171222
    172223Common::WriteStream *PSPFilesystemNode::createWriteStream() {
    173         return StdioStream::makeFromPath(getPath().c_str(), true);
     224        return PSPIoStream::makeFromPath(getPath(), true);
    174225}
    175226
    176227#endif //#ifdef __PSP__
  • backends/fs/psp/psp-stream.cpp

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL: https://scummvm.svn.sourceforge.net:443/svnroot/scummvm/scummvm/trunk/backends/fs/stdiostream.cpp $
     22 * $Id: stdiostream.cpp 39143 2009-03-06 00:26:48Z sunmax $
     23 *
     24 */
     25#ifdef __PSP__
     26
     27#include "backends/fs/psp/psp-stream.h"
     28#include "backends/platform/psp/trace.h"
     29#include <errno.h>
     30
     31PSPIoStream::PSPIoStream(const Common::String &path, bool writeMode)
     32: StdioStream((void *)1), _path(path), _writeMode(writeMode) {
     33
     34        assert(!path.empty());
     35
     36        _handle = (void *)0;            // Need to do this since base class asserts not 0.
     37
     38        PowerMan.registerSuspend(this);  // Register with the powermanager to be suspended
     39
     40}
     41
     42PSPIoStream::~PSPIoStream() {
     43
     44        PowerMan.unregisterSuspend(this); // Unregister with powermanager to be suspended
     45                                                                 // Must do this before fclose() or resume() will reopen.
     46
     47        fclose((FILE *)_handle);
     48}
     49
     50// Function to open the file pointed to by the path.
     51//
     52//
     53void * PSPIoStream::open() {
     54
     55        if(PowerMan.beginCriticalSection()==PowerManager::Blocked) {
     56                // No need to open. Just return the _handle resume() already opened.
     57                PSPDebugTrace("Suspended in PSPIoStream::open\n");
     58        }
     59        else {
     60                _handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb");       // open
     61        }
     62       
     63        PowerMan.endCriticalSection();
     64
     65        return _handle;
     66}
     67
     68bool PSPIoStream::err() const {
     69
     70        bool ret;
     71
     72        if(PowerMan.beginCriticalSection() == PowerManager::Blocked)
     73                PSPDebugTrace("Suspended in PSPIoStream::err()\n");
     74
     75        ret = ferror((FILE *)_handle) != 0;
     76
     77        PowerMan.endCriticalSection();
     78
     79        return ret;
     80}
     81
     82void PSPIoStream::clearErr() {
     83
     84        if(PowerMan.beginCriticalSection() == PowerManager::Blocked)
     85                PSPDebugTrace("Suspended in PSPIoStream::clearErr()\n");
     86
     87        clearerr((FILE *)_handle);
     88
     89        PowerMan.endCriticalSection();
     90}
     91
     92bool PSPIoStream::eos() const {
     93
     94        bool ret;
     95
     96        if(PowerMan.beginCriticalSection() == PowerManager::Blocked)
     97                PSPDebugTrace("Suspended in PSPIoStream::eos()\n");
     98
     99        ret = feof((FILE *)_handle) != 0;
     100
     101        PowerMan.endCriticalSection();
     102
     103        return ret;
     104}
     105
     106int32 PSPIoStream::pos() const {
     107
     108        int32 ret;
     109
     110        if(PowerMan.beginCriticalSection() == PowerManager::Blocked)
     111                PSPDebugTrace("Suspended in PSPIoStream::pos()\n");
     112
     113        ret = ftell((FILE *)_handle);
     114
     115        PowerMan.endCriticalSection();
     116
     117        return ret;
     118}
     119
     120
     121int32 PSPIoStream::size() const {
     122
     123        if(PowerMan.beginCriticalSection() == PowerManager::Blocked)
     124                PSPDebugTrace("Suspended in PSPIoStream::size()\n");
     125
     126        int32 oldPos = ftell((FILE *)_handle);
     127        fseek((FILE *)_handle, 0, SEEK_END);
     128        int32 length = ftell((FILE *)_handle);
     129        fseek((FILE *)_handle, oldPos, SEEK_SET);
     130
     131        PowerMan.endCriticalSection();
     132
     133        return length;
     134}
     135
     136bool PSPIoStream::seek(int32 offs, int whence) {
     137
     138        int ret = 0;
     139
     140        // Check if we can access the file
     141        if(PowerMan.beginCriticalSection() == PowerManager::Blocked)
     142                PSPDebugTrace("Suspended in PSPIoStream::seek()\n");
     143
     144        ret = fseek((FILE *)_handle, offs, whence);
     145
     146        PowerMan.endCriticalSection();
     147
     148        return ret == 0;
     149}
     150
     151uint32 PSPIoStream::read(void *ptr, uint32 len) {
     152
     153        int ret = 0;
     154
     155        // Check if we can access the file
     156        if(PowerMan.beginCriticalSection() == PowerManager::Blocked)
     157                PSPDebugTrace("Suspended in PSPIoStream::read()\n");
     158
     159        ret = fread((byte *)ptr, 1, len, (FILE *)_handle);
     160       
     161        PowerMan.endCriticalSection();
     162       
     163        return ret;
     164}
     165
     166uint32 PSPIoStream::write(const void *ptr, uint32 len) {
     167
     168        int ret = 0;
     169
     170        // Check if we can access the file
     171        if(PowerMan.beginCriticalSection() == PowerManager::Blocked)
     172                PSPDebugTrace("Suspended in PSPIoStream::read()\n");
     173
     174        ret = fwrite(ptr, 1, len, (FILE *)_handle);
     175
     176        PowerMan.endCriticalSection();
     177
     178        return ret;
     179}
     180
     181bool PSPIoStream::flush() {
     182
     183        int ret = 0;
     184
     185        // Check if we can access the file
     186        if(PowerMan.beginCriticalSection() == PowerManager::Blocked)
     187                PSPDebugTrace("Suspended in PSPIoStream::read()\n");
     188
     189        ret = fflush((FILE *)_handle);
     190
     191        PowerMan.endCriticalSection();
     192
     193        return ret == 0;
     194}
     195
     196// For the PSP, since we're building in suspend support, we moved opening
     197// the actual file to an open function since we need an actual PSPIoStream object to suspend.
     198//
     199PSPIoStream *PSPIoStream::makeFromPath(const Common::String &path, bool writeMode) {
     200
     201        PSPIoStream *stream = new PSPIoStream(path, writeMode);
     202
     203        if(stream->open() > 0)
     204                return stream;
     205        else {
     206                delete stream;
     207                return 0;
     208        }
     209}
     210
     211/*
     212 *  Function to suspend the IO stream (called by PowerManager)
     213 */
     214int PSPIoStream::suspend() {
     215
     216        if(_handle > 0) {
     217                _pos = ftell((FILE *)_handle);  // Save our position
     218                fclose((FILE *)_handle);                // close our file descriptor
     219                _handle = 0;                                    // Set handle to null
     220        }
     221
     222        return 0;
     223}
     224
     225/*
     226 *  Function to resume the IO stream (called by Power Manager)
     227 */
     228int PSPIoStream::resume() {
     229        int ret = 0;
     230
     231        // We reopen our file descriptor
     232        _handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb");
     233        if(_handle<=0) {
     234                PSPDebugTrace("PSPIoStream::resume(): Couldn't reopen file %s\n", _path.c_str());
     235                ret = -1;;
     236        }
     237
     238        // Resume our previous position
     239        if(_handle > 0) fseek((FILE *)_handle, _pos, SEEK_SET);
     240
     241        return ret;
     242}
     243
     244#endif /* __PSP__ */
  • backends/fs/psp/psp-fs-factory.cpp

    Property changes on: backends/fs/psp/psp-stream.cpp
    ___________________________________________________________________
    Added: svn:executable
       + *
    
     
    3434
    3535AbstractFSNode *PSPFilesystemFactory::makeCurrentDirectoryFileNode() const {
    3636        char buf[MAXPATHLEN];
    37         return getcwd(buf, MAXPATHLEN) ? new PSPFilesystemNode(buf) : NULL;
     37        char * ret = 0;
     38
     39        PowerMan.beginCriticalSection();
     40        ret = getcwd(buf, MAXPATHLEN);
     41        PowerMan.endCriticalSection();
     42
     43        return (ret ? new PSPFilesystemNode(buf) : NULL);
    3844}
    3945
    4046AbstractFSNode *PSPFilesystemFactory::makeFileNodePath(const Common::String &path) const {
  • backends/module.mk

     
    1111        fs/posix/posix-fs-factory.o \
    1212        fs/ps2/ps2-fs-factory.o \
    1313        fs/psp/psp-fs-factory.o \
     14        fs/psp/psp-stream.o \
    1415        fs/symbian/symbian-fs-factory.o \
    1516        fs/windows/windows-fs-factory.o \
    1617        fs/wii/wii-fs-factory.o \