酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

PSPでHOMEキー押下に対応させる

まともに説明書きがある所がなかったので試行錯誤を繰り返しているのですが、なかなか成功しません。HOMEキーを押下で中断画面が出て「このままお待ちください」と、いう画面でフリーズしているようです。

ネットで見つけたソースと同じ様にしているはずなのですが・・・APIのアドレスが間違っているというオチだろうか。Saltさんのブログでは

nem氏のPSPsoundのstartup.s を使ってたのだが、、、  STUB_FUNC 0x278C0DF5,sceKernelWaitThreadEnd  STUB_FUNC 0x9FA03CD3,sceKernelDeleteThreadこの2行(インデントが違うのですぐわかる)を削除する必要がありそうだ。なぜなのかは、よくわからんが、うまく終了できるようになった。

HOME で戻れない。。。

と、あるのでsceKernelWaitThreadEnd、sceKernelDeleteThreadの宣言を止めてみたのですが症状は変わりませんでした。

念のためhelloPSPのソースを改造したものを掲載しておきます。HOMEキーで中断出来ませんが・・・

startup.s の似たような文の下に追加しました

 STUB_START  "sceSuspendForUser",0x40000000,0x00020005 
 STUB_FUNC  0xEADB1BD7,"DisableSuspend" 
 STUB_FUNC  0x3AEE7261,"EnableSuspend" 
 STUB_END

 STUB_START "UtilsForUser",0x40010000,0x00040005 
 STUB_FUNC  0x91E4F6A7,sceKernelLibcClock 
 STUB_FUNC  0x27CC57F0,sceKernelLibcTime 
 STUB_FUNC  0x71EC4271,sceKernelLibcGettimeofday 
 STUB_FUNC  0x79D1C3FA,sceKernelDcacheWritebackAll 
 STUB_END

 STUB_START "LoadExecForUser",0x40010000,0x20005
 STUB_FUNC  0x5572A5F,sceKernelExitGame
 STUB_FUNC  0x4AC57943,SetExitCallback
 STUB_END 

 STUB_START "scePower",0x40010000,0x10005
 STUB_FUNC  0x4B7766E,PowerSetCallback
 STUB_END

 STUB_START "ThreadManForUser",0x40010000,0x000B0005
 STUB_FUNC  0x446D8DE6,sceKernelCreateThread
 STUB_FUNC  0xF475845D,sceKernelStartThread
 STUB_FUNC  0xAA73C935,sceKernelExitThread
 STUB_FUNC  0x9ACE131E,sceKernelSleepThread
 STUB_FUNC  0x55C20A00,sceKernelCreateEventFlag
 STUB_FUNC  0xEF9E4C70,sceKernelDeleteEventFlag
 STUB_FUNC  0x1FB15A32,sceKernelSetEventFlag
 STUB_FUNC  0x812346E4,sceKernelClearEventFlag
 STUB_FUNC  0x402FCF22,sceKernelWaitEventFlag
 STUB_FUNC  0x82826F70,KernelPollCallbacks
 STUB_FUNC  0xE81CAF8F,sceKernelCreateCallback
 STUB_FUNC  0x278C0DF5,sceKernelWaitThreadEnd
 STUB_FUNC  0x9FA03CD3,sceKernelDeleteThread
 STUB_END 

pg.h に下記の宣言を追加します

 #define POWER_CB_POWER 0x80000000
 #define POWER_CB_HOLDON   0x40000000
 #define POWER_CB_STANDBY  0x00080000
 #define POWER_CB_RESCOMP  0x00040000
 #define POWER_CB_RESUME   0x00020000
 #define POWER_CB_SUSPEND  0x00010000
 #define POWER_CB_EXT      0x00001000
 #define POWER_CB_BATLOW   0x00000100
 #define POWER_CB_BATTERY  0x00000080
 #define POWER_CB_BATTPOWER    0x0000007F

 int sceKernelCreateThread(const char* name, void *func, int initPriority, int stacksize, void *arg, int option);
 int sceKernelStartThread(int thid, int arg0, int arg1);
 int sceKernelSleepThread(void);
 int sceKernelRegisterExitCallback(int cbid);
 int sceKernelCreateCallback(const char *name, void *func);
 void sceKernelPollCallbacks(void);
 void sceKernelExitGame(void);

さらに、hellopsp.cを以下のようにします。

 /*
 Procedimiento que se llamara cuando la consola quiera salir del juego,
 por ejemplo cuando le damos al menu HOME y SALIR
 */
 int exit_callback(void)
 {
    sceKernelExitGame();
    return 0;
 }

 /*
 Procedimiento que se llamara cuando se apague la consola, se puede saber si es por
 falta de bateria o por que el usuario la apaga, pero como en nuestro caso nos da
 igual pues simplemente no hacemos nada.
 */
 void power_callback(int unknown, int pwrflags)
 {
    //void 
 }

 /*
 Este Thread crea los "CallBacks" necesarios para la salida y la bateria
 */
 int CallbackThread(void *arg)
 {
    int cbid;
    cbid = sceKernelCreateCallback("Exit Callback", exit_callback);
    SetExitCallback(cbid);
    cbid = sceKernelCreateCallback("Power Callback", power_callback);
    PowerSetCallback(0, cbid);
    KernelPollCallbacks();
 }

 /*
 Este procedimiento crea un thread apuntando hacia la funcion anterior "CallbackThread",
 a esta funcion hay que llamarla desde el "main" por ejemplo.
 */
 int SetupCallbacks(void)
 {
    int thid = 0;
    thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
    sceKernelStartThread(thid, 0, 0);
    return thid;
 }

 int xmain(void)
 {
    /* HOMEキー対応 */
    SetupCallbacks();
 //    sceKernelSleepThread();

    return 0;
 }