static int SubThread(SceSize args, void *argp) { int error, numWaitThreads; SceKernelMbxInfo info; /* For simplicily, we statically allocate some messages */ static MyMessage one = { {0}, "One" }; static MyMessage two = { {0}, "Two" }; static MyMessage three = { {0}, "Three" }; sceKernelDelayThread(100000); printf("SUB: started\n"); sceKernelDelayThread(1000000); /* Send a message */ printf("SUB: Posting 1\n"); sceKernelSendMbx(myMessagebox, &one.header); /* Send another message after some delay, to demonstrate the timeout feature */ sceKernelDelayThread(1000000); printf("SUB: Posting 2\n"); sceKernelSendMbx(myMessagebox, &two.header); /* Again, send another message after some delay, this time to demonstrate the polling feature */ sceKernelDelayThread(1000000); printf("SUB: Posting 3\n"); sceKernelSendMbx(myMessagebox, &three.header); /* Wait for the main task to start blocking again, and then check the messagebox status */ sceKernelDelayThread(1000000); printf("SUB: Checking messagebox status\n"); info.size = sizeof(info); error = sceKernelReferMbxStatus(myMessagebox, &info); if(error < 0) printf("SUB: ERROR %08x\n", error); else printf("SUB: status ok, name=\"%s\", attr=%d, numWaitThreads=%d, " "numMessages=%d, firstMessage=%p\n", info.name, info.attr, info.numWaitThreads, info.numMessages, info.firstMessage); /* Finally, cancel the main tasks receive operation */ printf("SUB: Cancelling receive\n"); error = sceKernelCancelReceiveMbx(myMessagebox, &numWaitThreads); sceKernelDelayThread(100000); if(error < 0) printf("SUB: ERROR %08x\n", error); else printf("SUB: cancellation ok, %d threads were waiting\n", numWaitThreads); printf("SUB: Exiting\n"); return 0; }
int main(int argc, char *argv[]) { SceCtrlData pad; int oldButtons = 0; #define SECOND 1000000 #define REPEAT_START (1 * SECOND) #define REPEAT_DELAY (SECOND / 5) struct timeval repeatStart; struct timeval repeatDelay; int result; int msgCount = 0; repeatStart.tv_sec = 0; repeatStart.tv_usec = 0; repeatDelay.tv_sec = 0; repeatDelay.tv_usec = 0; printHeader(); int receiveThreadId = sceKernelCreateThread("ReceiveMbx", receiveMbxThread, 0x50, 0x1000, 0, 0); sceKernelStartThread(receiveThreadId, 0, 0); while (!done) { sceCtrlReadBufferPositive(&pad, 1); int buttonDown = (oldButtons ^ pad.Buttons) & pad.Buttons; if (pad.Buttons == oldButtons) { struct timeval now; gettimeofday(&now, NULL); if (repeatStart.tv_sec == 0) { repeatStart.tv_sec = now.tv_sec; repeatStart.tv_usec = now.tv_usec; repeatDelay.tv_sec = 0; repeatDelay.tv_usec = 0; } else { long usec = (now.tv_sec - repeatStart.tv_sec) * SECOND; usec += (now.tv_usec - repeatStart.tv_usec); if (usec >= REPEAT_START) { if (repeatDelay.tv_sec != 0) { usec = (now.tv_sec - repeatDelay.tv_sec) * SECOND; usec += (now.tv_usec - repeatDelay.tv_usec); if (usec >= REPEAT_DELAY) { repeatDelay.tv_sec = 0; } } if (repeatDelay.tv_sec == 0) { buttonDown = pad.Buttons; repeatDelay.tv_sec = now.tv_sec; repeatDelay.tv_usec = now.tv_usec; } } } } else { repeatStart.tv_sec = 0; } if (buttonDown & PSP_CTRL_CROSS) { printHeader(); mbxId = sceKernelCreateMbx("Mbx", 0, NULL); pspDebugScreenPrintf("sceKernelCreateMbx = 0x%08X\n", mbxId); printMbxStatus(mbxId); } if (buttonDown & PSP_CTRL_CIRCLE) { printHeader(); msgCount++; MyMessage *msg = malloc(sizeof(MyMessage)); msg->header.next = (void *) 0x12345678; msg->header.msgPriority = 1; msg->header.dummy[0] = 2; msg->header.dummy[1] = 3; msg->header.dummy[2] = 4; sprintf(msg->text, "Hello %d", msgCount); result = sceKernelSendMbx(mbxId, msg); pspDebugScreenPrintf("sceKernelSendMbx msg=0x%08X, msgCount=%d: 0x%08X\n", (int) msg, msgCount, result); printMbxStatus(mbxId); } if (buttonDown & PSP_CTRL_SQUARE) { printHeader(); printMbxStatus(mbxId); } if (buttonDown & PSP_CTRL_LEFT) { sceKernelWakeupThread(receiveThreadId); printHeader(); } if (buttonDown & PSP_CTRL_TRIANGLE) { done = 1; } oldButtons = pad.Buttons; } sceGuTerm(); sceKernelExitGame(); return 0; }