Page 1 of 3

Menu API and cascading menus

Posted: Sat Nov 27, 2010 8:00 am
by JJS
Since the current discussion is all over the place here and here, I thought it would be good to have a thread dedicated to it.


The main problem at the moment is that people want to run one menu from another and this is not possible right now. The question aside whether this is usefull feature, I think there is an easy solution for the problem.

It should be possible to unify the way the menu and a homebrew is run by always putting the menu API in argv[1]. If the structure gets modified by a game, it obviously was a menu and wants to run another game. If not it was a regular homebrew and the default menu should be reloaded. I don't think putting this in argv[1] will break any homebrew game as it is normally impossible to give arguments (except argv[0] obviously) to a PSP game.

While doing the change we could also remove the testing code for the sceIo* functions since it is obsolete after the parsing of p5 module stubs.

Re: Menu API and cascading menus

Posted: Sat Nov 27, 2010 3:54 pm
by m0skit0
Why not having dedicated functions from HBL that menu and homebrews alike can call? Since it's HBL who resolves the imports, we can easily hook those imports to make the homebrew/menu call whatever function HBL wants to export. This way a menu can call hblLoadMenu() and load another menu, or hblLoadExec() to load a homebrew. This way even a homebrew can load a menu (whatever this can be used for :lol: ).

Another idea would be to treat menus and homebrews all alike, and using sceKernelLoadExec() to switch between homebrews. For example the menu is loaded like any common homebrew, not a special one. It calls sceKernelLoadExec() on a homebrew, HBL catches this, kills and unloads the current homebrew (a menu) then loads another homebrew (the one selected from the menu). To get back to the menu, it would suffice to remember the path of the homebrew which acts as menu.

Re: Menu API and cascading menus

Posted: Sun Nov 28, 2010 3:27 pm
by Nymphaea
I think one way to do this is to simplify the loop used to run the menu, instead of running the menu then an eboot alternating like it does now, to just load what is put into hb_filename(or the menu if it hasn't changed), like so:

Code: Select all

    loadGlobalConfig();
    char filename[512]; //Why was this inside the loop before? o.0
    while (!exit)
    {
        int initial_free_ram = sceKernelTotalFreeMemSize();
        strcpy(filename, g->hb_filename);
        //Load default config
        loadGlobalConfig();
        LOGSTR0("Config Loaded OK\n");
        //Run menu if filename is unchanged
        if(strcmp(filename,hb_filename) == 0) {
            run_menu();
            LOGSTR0("Default Menu Started OK\n");
        //Run filename otherwise
        } else {
            LOGSTR1("Eboot is: %s\n", (u32)filename);
            //run homebrew
            run_eboot(filename);
            LOGSTR0("Eboot Started OK\n");
        }
        wait_for_eboot_end();
        cleanup(num_lib);
        ramcheck(initial_free_ram);
        if (strcmp("quit", g->hb_filename) == 0 || g->exit_callback_called)
            exit = 1;
    }
Please note I haven't tested this, and it needs tweaks in other places.(like making all eboots have argv[1] :P) Might also be somewhat outdated, haven't updated my HBL source in a while :P

Another thing that would be interesting, since it's possible peoples menu's could screw up/etc, we could have an argv[2] with error messages, such as if an improper filename is attempted, or the last homebrew tried doing something improperly, and the menu could report these when starting. Sounds more like something for a debug version, but would be useful for people making homebrew with HBL though. Could probably also put a pointer into an argument, which could be a struct of pointers to HBL functions, or expand the current structure, though that could break older menus(maybe not if everything is just added to the end of the struct? o.0)

I kind of like m0skit0's second idea though, that removes the need of the loop and menu API completely, and the sceKernelExitGame() could just be made to load the menu.

Re: Menu API and cascading menus

Posted: Mon Nov 29, 2010 5:30 am
by wololo
I'd be happy if we could keep backwards compatibility with the previous API for menus though, although I won't fight too hard for it.
If needed, I will update wMenu, but I'd love to be sure that major alternatives like vMenu get updated as well...

Re: Menu API and cascading menus

Posted: Tue Dec 14, 2010 4:43 pm
by JJS
I would like to get this into the code, so I quickly cobbled together some kind of api.

These would be the files needed by the homebrew/menu:


hblapi.h

Code: Select all

#ifndef HBL_API
#define HBL_API

// Sets the next homebrew that will be loaded after the current one exits
void hblSetNextHomebrew(char* path);

// Request HBL to return to the XMB after the current homebrew exits
void hblRequestQuitToXmb();

// Get the credits string, the size of the char buffer is specified in max_size
unsigned int hblGetCreditsString(char* credits, unsigned int max_size);

// Get the version string, the size of the char buffer is specified in max_size
unsigned int hblGetVersionName(char* version, unsigned int max_size);

// Get the HBL version/revision
unsigned int hblGetVersion();

#endif
hblapi.S

Code: Select all

	.set noreorder

#include "pspstub.s"

	STUB_START "hblapi",0x40090000,0x00050005
	STUB_FUNC  0xD42C21E8,hblSetNextHomebrew
	STUB_FUNC  0x4587B4CA,hblRequestQuitToXmb
	STUB_FUNC  0x1425C3CF,hblGetCreditsString
	STUB_FUNC  0x0FC815F2,hblGetVersionName
	STUB_FUNC  0xE079D8B9,hblGetVersion
	STUB_END

Implementation in HBL would be quite trivial and all function resolving can be easily done in hook.c.

Re: Menu API and cascading menus

Posted: Tue Dec 14, 2010 4:47 pm
by m0skit0
Nice. What about the NIDs? You SHA1'd the function names or how did you do it?

Re: Menu API and cascading menus

Posted: Tue Dec 14, 2010 5:14 pm
by FrEdDy
m0skit0 wrote:Nice. What about the NIDs? You SHA1'd the function names or how did you do it?
psp-build-exports maybe

Re: Menu API and cascading menus

Posted: Tue Dec 14, 2010 5:16 pm
by JJS
I just used PSPLinks "tonid" command. So they are the SHA1 of the function name, I think that is the logical choice for the NIDs.

Re: Menu API and cascading menus

Posted: Tue Dec 14, 2010 5:25 pm
by FrEdDy
JJS wrote:I just used PSPLinks "tonid" command. So they are the SHA1 of the function name, I think that is the logical choice for the NIDs.
why not using "normal" procedure? :?: Am I missing something here?

I normally write an exports file and then just

Code: Select all

psp-build-exports -s myexportfile.exp
And there's the stub file

Re: Menu API and cascading menus

Posted: Tue Dec 14, 2010 5:44 pm
by JJS
Yes, I could have done that. No special reason for the manual way despite the fact that didn't want to bother with writing the export file. And yes, I know that it would have been probably faster but I just didn't do it.

Anyway, are there comments about the API itself?

Edit: I noticed that a way to get the default path is missing. How about "void hblGetHomebrewPath(char* path)".

Edit2: And "void hblSetHomebrewPath(char* path)" so that it will be possible to return to the folder you started your last homebrew from if the menu implements this.