Creating callbacks (aka The curious tale of the home button)

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

Moderators: cheriff, TyRaNiD

Post Reply
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Creating callbacks (aka The curious tale of the home button)

Post by TyRaNiD »

To stop people asking this post contains sample code to make the home button work and then exit back to the browser. As an aside I will add some power callback stuff for interest.

First off to get the sceKernelExitGame function working you need to setup your main function in a thread, if you are using nem's source for hellopsp you will need to change the _start: function in startup.s. Here is an example.

Code: Select all

		.ent _start
		.weak _start

_start:
		addiu 	$sp, 0x10
		sw		$ra, 0($sp)	
		sw		$s0, 4($sp)
		sw		$s1, 8($sp)

		move	$s0, $a0				# Save args
		move	$s1, $a1

		la  	$a0, _main_thread_name	# Main thread setup
		la		$a1, xmain
		li		$a2, 0x20				# Priority
		li		$a3, 0x40000			# Stack size
		lui		$t0, 0x8000				# Attributes
		jal		sceKernelCreateThread
		move	$t1, $0

		move	$a0, $v0				# Start thread
		move	$a1, $s0
		jal		sceKernelStartThread
		move	$a2, $s1

		lw		$ra, 0($sp)
		lw		$s0, 4($sp)
		lw		$s1, 8($sp)
		move	$v0, $0
		jr 		$ra
		addiu	$sp, 0x10

_main_thread_name:
		.asciiz	"user_main"
NOTE: This code does not setup the gp register so if using nem's code you need to either a) set it up somewhere else or b) pass the -G0 flag to the compiler in order to eliminate the gp register usage (my personal preference :P)

The home button will generate a callback whenever it is pressed, but only if one is registered. If one is not registered it will do nothing at all so to do this we call sceKernelCreateCallback to make a new callback and then pass it to SetExitCallback. So...

Code: Select all

int exit_callback(void)
{
// Cleanup the games resources etc (if required)

// Exit game
	sceKernelExitGame();

	return 0;
}

#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
void power_callback(int unknown, int pwrflags)
{
	// Combine pwrflags and the above defined masks
}

// Thread to create the callbacks and then begin polling
int CallbackThread(void *arg)
{
	int cbid;

	cbid = sceKernelCreateCallback("Exit Callback", exit_callback);
	sceKernelRegisterExitCallback(cbid);
	cbid = sceKernelCreateCallback("Power Callback", power_callback);
	scePowerRegisterCallback(0, cbid);

	KernelPollCallbacks();
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void)
{
	int thid = 0;

	thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
	if(thid >= 0)
	{
		sceKernelStartThread(thid, 0, 0);
	}

	return thid;
}
So there we go, now when you press the home button the "Do you want to exit the game?" message should appear. Choose yes and you'll be back to the browser in time. And as an added bonus you can monitor power events :)

Before you ask the functions used in here are all listed in http://forums.ps2dev.org/viewtopic.php?t=1594
blackdroid
Posts: 564
Joined: Sat Jan 17, 2004 10:22 am
Location: Sweden
Contact:

Post by blackdroid »

/me puts on the cheerleader uniform and shouts go tyranid!

( see this is dev, and im not slandering or putting locks on, I can play nice ;)
Kung VU
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

Some people seem to have trouble with this code (god knows why ? ;) so here is a link to a very simple example with source. Thx to weak for hosting it.

http://www.fraglab.at/files/exit_pspsrc.zip
subbie
Posts: 122
Joined: Thu May 05, 2005 4:14 am

Post by subbie »

Thanks!!

I can't wait to use this tomorrow. :) You have made running homebrew stuff easier.
Smiths
Posts: 30
Joined: Sun May 15, 2005 10:01 am

Post by Smiths »

Thanks tons for it, already every homebrewer is throwing it in their projects, great work!
Erant
Posts: 33
Joined: Fri May 13, 2005 6:19 am

Post by Erant »

It looks great, and I know it works, because I've seen it in action on other homebrew ventures. But it doesn't work for me! I'm guessing this is due to the fact that I'm using the PSPDev toolchain, and not the PS2Dev toolchain. I'm getting the following errors trying to compile your crt0.S:

crt0.S:20: Error: illegal operands `sw $s0,4($sp)'
crt0.S:21: Error: illegal operands `sw $s1,8($sp)'
crt0.S:23: Error: illegal operands `move $s0,$a0'
crt0.S:24: Error: illegal operands `move $s1,$a1'
crt0.S:26: Error: illegal operands `la $a0,_main_thread_name'
crt0.S:27: Error: illegal operands `la $a1,xmain'
crt0.S:28: Error: illegal operands `li $a2,0x20'
crt0.S:29: Error: illegal operands `li $a3,0x40000'
crt0.S:30: Error: illegal operands `lui $t0,0x8000'
crt0.S:32: Error: illegal operands `move $t1,$0'
crt0.S:34: Error: illegal operands `move $a0,$v0'
crt0.S:35: Error: illegal operands `move $a1,$s0'
crt0.S:37: Error: illegal operands `move $a2,$s1'
crt0.S:40: Error: illegal operands `lw $s0,4($sp)'
crt0.S:41: Error: illegal operands `lw $s1,8($sp)'
crt0.S:42: Error: illegal operands `move $v0,$0'

The code itself compiles fine, as does your code example, and using my original crt0.S even runs, but doesn't give me the exit...
Live free, prosper, and under my rule.
weak
Posts: 114
Joined: Thu Jan 13, 2005 8:31 pm
Location: Vienna, Austria

Post by weak »

this has been discussed here

but since you're like the 20th person asking for it, here's a startup.s you can use with the toolchain.
HexDump
Posts: 70
Joined: Tue Jun 07, 2005 9:18 pm

Post by HexDump »

a dumb question, couldn´t you pool for buttons your self instead of using callbacks? Why everyone does use callbacks? simplicity?.


Thanks in advance,
HexDump.
mu5
Posts: 3
Joined: Thu Jul 14, 2005 12:34 am

Post by mu5 »

TyRaNiD wrote:Some people seem to have trouble with this code (god knows why ? ;) so here is a link to a very simple example with source. Thx to weak for hosting it.

http://www.fraglab.at/files/exit_pspsrc.zip
Newbie Question : I tried to compile this with the PSPSDK - its says im missing startup.o and main.o - Do I need to use GCC to create these? cheers
User avatar
Agoln
Posts: 326
Joined: Wed Jun 08, 2005 3:14 am
Location: Fort Wayne, IN

Post by Agoln »

mu5 wrote:Newbie Question : I tried to compile this with the PSPSDK - its says im missing startup.o and main.o - Do I need to use GCC to create these? cheers
Don't use that, use the samples in the SDK for information. Look under the samples/kernel directory. If you do not have that directory, then you should update the SDK.
Lego of my Ago!
mu5
Posts: 3
Joined: Thu Jul 14, 2005 12:34 am

Post by mu5 »

Im trying to get the exit example running on the PSPSDK (Win32). I had a look at the makefile and it was using ee-gcc, so I have changed that to psp-gcc to try and get it to compile.

Now im getting the same error as listed above..

crt0.S:20: Error: illegal operands `sw $s0,4($sp)'
crt0.S:21: Error: illegal operands `sw $s1,8($sp)'
crt0.S:23: Error: illegal operands `move $s0,$a0' etc

OK - so i need to include regdef.h, right?

I had a look, and all my 'regdef.h' files under my PSPSDK directory are all 1k in size!!! (and have a warning saying they wont compile anyway!)

Can anyone tell me what newlib is? And why i wouldnt have it in the SDK?

Also, I have no kernel directory under my samples directory.

Thanks for the help :)
User avatar
Agoln
Posts: 326
Joined: Wed Jun 08, 2005 3:14 am
Location: Fort Wayne, IN

Post by Agoln »

There are working I/O and exit samples in the current SDK, please get a copy of subversion, checkout the SDK and get crackin with that.

Make sure that you have cygwin installed too.

http://wiki.pspdev.org/psp:programming_faq
Lego of my Ago!
Post Reply