Need help troubleshooting a simple prx

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Holmz
Posts: 5
Joined: Wed Feb 14, 2007 6:06 am
Location: Las Vegas, NV

Need help troubleshooting a simple prx

Post by Holmz »

I wrote a simple prx to change wallpapers with a simple button press but it has two very serious issues that I can't seem to get around on my own:
1.a. If I use sceCtrlReadBufferPositive then the vsh won't respond to anything until I hit the button it's looking for and then it only works while the code is being executed (I know the code is being executed because the memory stick is being accessed)
1.b. I looked around and saw a suggestion to use sceCtrlPeekBufferPositive but when I use that the code won't execute, vsh works fine but the code is never triggered.

2. When the code is executed the wallpaper isn't automatically refreshed, you can see that the wallpaper has indeed changed if you go to Settings->Theme Settings->Theme and switch between Use and Do Not Use or by coldbooting the psp. I know there has to be some syscall that will refresh it and it's probably in the sceDisplay library but I have no idea which one it might be.

I'm running 3.10 OE-A' in 1.50 Kernel mode, here's the code, any nudge in the right direction would be appreciated.

Code: Select all

//  Wallpaper Changer .prx
//  by S. Holmes Started 01.23.07
//

#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspctrl.h>
#include <stdio.h>
#include <stdlib.h>
#include <pspdebug.h>
#include <pspiofilemgr.h>
#include <pspctrl.h>
#include <string.h>
#include <time.h>

PSP_MODULE_INFO&#40;"WallpaperChanger", 0, 1, 1&#41;;

#define printf pspDebugScreenPrintf
#define Screen PSP_CTRL_SCREEN
#define Square PSP_CTRL_SQUARE
#define LTrig PSP_CTRL_LTRIGGER
#define WPDir "ms0&#58;/PSP/PHOTO/Wallpapers"
#define MAXPATH 262
#define ActualWP "flash1&#58;/vsh/theme/wallpaper.bmp"

//    The following counts the number of wallpapers in 
//    your wallpaper directory, code comes from the 
//    mp3.c file from the open source irsmp3 project
//    thank you to whoever wrote that.  Modified so it 
//    only uses ms0&#58;/PSP/PHOTO/Wallpapers and does not
//    use/look for subdirs, also currently only looks 
//    for .jpg's 

int nCountWallPapers&#40;&#41; &#123;
    int nFileDir;
    int WPCount = 0;
    SceIoDirent d_dir;
    memset&#40;&d_dir, 0, sizeof&#40;SceIoDirent&#41;&#41;;
    nFileDir = sceIoDopen&#40;WPDir&#41;;
    
    if &#40;nFileDir >= 0&#41;
    &#123;
        while &#40;&#40;sceIoDread&#40;nFileDir, &d_dir&#41; > 0&#41;&#41;
        &#123;
                if &#40;&#40;d_dir.d_stat.st_attr & FIO_SO_IFDIR&#41; == 0&#41; //not a directory
                &#123;
                     if &#40;!stricmp&#40;d_dir.d_name+strlen&#40;d_dir.d_name&#41;-4, ".jpg"&#41;&#41;  //if it is a jpg
                     &#123;
                                          WPCount++;
                     &#125;
                &#125;
        &#125;
        sceIoDclose&#40;nFileDir&#41;;
    &#125;
    return WPCount;
&#125;
//    This code also taken from mp3.c but altered to fit my needs.
char* szGetWPName&#40;&#41; 
&#123;
    int nFileDir;
    SceIoDirent d_dir;
    int nCount = -1;
    int nRWP;
    char szWallName&#91;MAXPATH&#93;;    //compiler complains about this being uninitialized but 
                         //it's the only way I got this to work
   
    srand&#40;time&#40;0&#41;&#41;;
    
    nRWP = rand&#40;&#41; % nCountWallPapers&#40;&#41;;
    memset&#40;&d_dir, 0, sizeof&#40;SceIoDirent&#41;&#41;;
    nFileDir = sceIoDopen&#40;WPDir&#41;;
    
    if &#40;nFileDir >= 0&#41;
    &#123;
        while &#40;&#40;sceIoDread&#40;nFileDir, &d_dir&#41; > 0&#41;&#41;
        &#123;
                if &#40;&#40;d_dir.d_stat.st_attr & FIO_SO_IFDIR&#41; == 0&#41; //not a directory
                &#123;
                     if &#40;!stricmp&#40;d_dir.d_name+strlen&#40;d_dir.d_name&#41;-4, ".jpg"&#41;&#41;
                     &#123;
                         if &#40;nCount == nRWP&#41;
                         &#123;
                             sprintf&#40;szWallName, "%s/", WPDir&#41;;
                             strcat&#40;szWallName, d_dir.d_name&#41;;
                             nCount = -1;
                             break;
                         &#125;
                         nCount++;
                     &#125;
                &#125;
        &#125;
    &#125;
    return szWallName; //compiler complains about this too but it's the only
                       //way I can get this to work
&#125;

void ChangeWP&#40;&#41;
&#123;
            char* szNewWall = szGetWPName&#40;&#41;;
            
            int c;
            FILE* fSource;
            FILE* fDest;
            
            fSource = fopen&#40;szNewWall, "rb"&#41;;
            fDest = fopen&#40;ActualWP, "wb"&#41;;
            
            while &#40;&#40;c = getc&#40;fSource&#41;&#41; != EOF&#41;
            &#123;
                        fputc&#40;c, fDest&#41;;
            &#125;
            
            fclose&#40;fSource&#41;;
            fclose&#40;fDest&#41;;
&#125;
            
//    The meat!
int main&#40;void&#41; &#123;
    SceCtrlData pad;

    while&#40;1&#41; 
    &#123;
        sceCtrlReadBufferPositive&#40;&pad, 1&#41;;
        if&#40;pad.Buttons & Square&#41;
        &#123;
                 ChangeWP&#40;&#41;;  
                    
        &#125;
    &#125;

    return 0;
    
&#125;
Edit:More info, TyRaNiD's building prxes in pspsdk post said that if your application is simple and user mode only there was no need for an exports, so mine doesn't have one, also here is the Makefile if it sheds any light on the situation.

Code: Select all

TARGET = WPC
OBJS = main.o

BUILD_PRX = 1

CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = WPC

PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak 
Insert_witty_name
Posts: 376
Joined: Wed May 10, 2006 11:31 pm

Post by Insert_witty_name »

For your first point sceCtrlPeekBufferPositive() is what you need, try adding a small delay to your while loop.

sceKernelDelayThread(100); or similar.
Anissian
Posts: 16
Joined: Fri Jan 26, 2007 8:40 pm

Post by Anissian »

It's a bit late here and I am a sleepy, but.. aren't you returning the address of an array allocated in the stack? (char szWallName[MAXPATH]; ... return szWallName)... that's a source of crashes, and it will not always work.

Possible fixes:

* declare it static as in static char szWallName[MAXPATH];

* or use malloc/free (or equivalent if Kernel mode), leaving the responsability of freeing to the caller.

* change the prototype to
int /*error codes*/ function (char* outputname, int len) or similar.

If I am missing something, I'll quickly edit/Delete the post :o)
Holmz
Posts: 5
Joined: Wed Feb 14, 2007 6:06 am
Location: Las Vegas, NV

Re:Answers...

Post by Holmz »

First of all, thanks for your time and input, I appreciate it.

Anissian, the compiler warned me about returning an address but I wasn't sure how to get around it, declaring it static worked like a charm.

Insert_witty_name, I've tried various delays even before I made my initial post and again after your post but nothing seems to work, sceCtrlPeekBufferPositive() just will not call ChangeWP() for me. After your post I changed my PSP_MODULE_INFO to ("WallPaperChanger, 0x1000, 1, 1) so the prx could use that Kernel call but that didn't work either. I tried using a delay with sceCtrlReadBufferPositive() and that acts just like the Peek without the delay - the vsh works just fine but the ChangeWP() function is never being called.

I'm stumped.

Again, thanks for your time and help.
ufoz
Posts: 86
Joined: Thu Nov 10, 2005 2:36 am
Location: Tokyo
Contact:

Post by ufoz »

I dunno about compiling issues, but you're flashing a jpg file to wallpaper.bmp? That's just not gonna work like that. You need to convert the image format.
Holmz
Posts: 5
Joined: Wed Feb 14, 2007 6:06 am
Location: Las Vegas, NV

Re:Converting...

Post by Holmz »

ufoz wrote:I dunno about compiling issues, but you're flashing a jpg file to wallpaper.bmp? That's just not gonna work like that. You need to convert the image format.
That's what I thought but I don't know much about image formats and in my tests everything worked fine. I even wrote a console program that did the same thing (copies a file and renames it) with no problems, it worked when I had this code in eboot.pbp form.
Cy-4AH
Posts: 44
Joined: Wed Jan 31, 2007 9:58 pm
Location: Belarus

Post by Cy-4AH »

Insert_witty_name wrote:For your first point sceCtrlPeekBufferPositive() is what you need, try adding a small delay to your while loop.

sceKernelDelayThread(100); or similar.
I don't know how this code differ from using sceCtrlReadBufferPositive with sceCtrlSetSemplingCycle.
IMHO sceCtrlPeek... functions must be called in programm once (not just in checking cycle) or in handler of interruption caused by Pad.
I think such thing exist and it will be better for battery live than just loops everywhere in code.
For example in windows, we use handlers of messages from buttons and main thread sleep when there is no messages. If anyone know how catch events or messages or interrupts from Pad?
adrahil
Posts: 274
Joined: Thu Mar 16, 2006 1:55 am

Post by adrahil »

ReadBuffer reads the key state and doesn't leave it for other apps.
PeekBuffer just looks at it.
Take the analogy if a daily newspaper. The psp has a newspaper delivered to it. PeekBuffer will take the paper, read it, and put it back on the table for others to read. ReadBuffer will take it and keep it or throw directly away without letting the others see it.
Post Reply