void testControllerTimmings() { u64 tick0, tick1; int n; SceCtrlData pad_data; SceCtrlLatch latch; // Test sceCtrlReadBufferPositive sceRtcGetCurrentTick(&tick0); for (n = 0; n < 5; n++) sceCtrlReadBufferPositive(&pad_data, 1); sceRtcGetCurrentTick(&tick1); printf("%d\n", (tick1 - tick0 > 5000)); // Test sceCtrlReadLatch sceRtcGetCurrentTick(&tick0); for (n = 0; n < 5; n++) sceCtrlReadLatch(&latch); sceRtcGetCurrentTick(&tick1); printf("%d\n", (tick1 - tick0 > 5000)); // Test sceCtrlPeekBufferPositive sceRtcGetCurrentTick(&tick0); for (n = 0; n < 5; n++) sceCtrlPeekBufferPositive(&pad_data, 1); sceRtcGetCurrentTick(&tick1); printf("%d\n", (tick1 - tick0 < 5000)); // Test sceCtrlPeekLatch /* sceRtcGetCurrentTick(&tick0); for (n = 0; n < 5; n++) sceCtrlPeekLatch(&pad_data, 1); sceRtcGetCurrentTick(&tick1); printf("%d\n", (tick1 - tick0 < 5000)); */ }
void testCycleLatch(int cycle) { SceCtrlLatch latch; // Ignore it this time, to reset it. sceCtrlReadLatch(&latch); sceDisplayWaitVblank(); sceCtrlSetSamplingCycle(cycle); int vcountBefore = sceDisplayGetVcount(); sceKernelDelayThread(166666); int vcountAfter = sceDisplayGetVcount(); int after = sceCtrlReadLatch(&latch); // Keeping it approximate because timing is hard to get millisecond accurate. schedf("%d cycle: %dx\n", cycle, (after + 5) / (vcountAfter - vcountBefore)); }
int main(int argc, char *argv[]) { int result, data; SceCtrlData pad_data[128]; SceCtrlLatch latch; schedulingLogPos = schedulingLog; SceUID thread = sceKernelCreateThread("preempt", &testThread, sceKernelGetThreadCurrentPriority() - 1, 0x500, 0, NULL); sceKernelStartThread(thread, 0, 0); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlSetSamplingMode 1\n"); didPreempt = 0; result = sceCtrlSetSamplingMode(1); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlSetSamplingMode 1: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlSetSamplingMode 0\n"); didPreempt = 0; result = sceCtrlSetSamplingMode(0); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlSetSamplingMode 0: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlSetSamplingCycle 0\n"); didPreempt = 0; result = sceCtrlSetSamplingCycle(0); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlSetSamplingCycle 0: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlGetSamplingMode\n"); didPreempt = 0; result = sceCtrlGetSamplingMode(&data); schedulingLogPos += sprintf(schedulingLogPos, "VALUE: %08x\n", data); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlGetSamplingMode: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlReadBufferPositive 1\n"); didPreempt = 0; result = sceCtrlReadBufferPositive(&pad_data[0], 1); outputPadData(result, &pad_data[0]); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlReadBufferPositive 1: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlReadBufferPositive 64\n"); didPreempt = 0; result = sceCtrlReadBufferPositive(&pad_data[0], 64); outputPadData(result, &pad_data[0]); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlReadBufferPositive 64: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlPeekBufferPositive 64\n"); didPreempt = 0; result = sceCtrlPeekBufferPositive(&pad_data[0], 64); outputPadData(result, &pad_data[0]); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlPeekBufferPositive 64: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlReadBufferPositive 96\n"); didPreempt = 0; result = sceCtrlReadBufferPositive(&pad_data[0], 96); outputPadData(result, &pad_data[0]); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlReadBufferPositive 96: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlPeekLatch\n"); didPreempt = 0; result = sceCtrlPeekLatch(&latch); // Result is # of reads, which won't match headless. result = result >= 1 ? 1 : 0; outputLatchData(result, &latch); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlPeekLatch: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlReadLatch\n"); didPreempt = 0; result = sceCtrlReadLatch(&latch); // Result is # of reads, which won't match headless. result = result >= 1 ? 1 : 0; outputLatchData(result, &latch); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlReadLatch: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); schedulingLogPos += sprintf(schedulingLogPos, "BEFORE sceCtrlPeekLatch\n"); didPreempt = 0; result = sceCtrlPeekLatch(&latch); outputLatchData(result, &latch); schedulingLogPos += sprintf(schedulingLogPos, "AFTER sceCtrlPeekLatch: %08x preempt:%d\n", result, didPreempt); sceKernelDelayThread(300); sceKernelTerminateDeleteThread(thread); sceKernelDelayThread(300); printf("%s", schedulingLog); return 0; }
void setPassword() { Config cfg; char input[11]; int len; #ifndef DEBUG footer_changemode = loadImageFromMemory(images[FOOTER_CHANGEMODE].data, images[FOOTER_CHANGEMODE].hdr.size); #endif while(1) { #ifdef DEBUG printf("\nEnter new password: "******"\nConfirm password: "******"\nPassword changed."); #else int temp; blitImageToScreen(0, 0, images[BACKGROUND].hdr.w, images[BACKGROUND].hdr.h, background, images[BACKGROUND].hdr.x, images[BACKGROUND].hdr.y); blitAlphaImageToScreen(0, 0, images[FOOTER_CHANGEMODE].hdr.w, images[FOOTER_CHANGEMODE].hdr.h, footer_changemode, images[FOOTER_CHANGEMODE].hdr.x, images[FOOTER_CHANGEMODE].hdr.y); blitAlphaImageToScreen(0, 0, images[TITLE_CONFIRMPASSWORD].hdr.w, images[TITLE_CONFIRMPASSWORD].hdr.h, title_confirmpassword, images[TITLE_CONFIRMPASSWORD].hdr.x, images[TITLE_CONFIRMPASSWORD].hdr.y); freeImage(title_confirmpassword); msg_passwordchanged = loadImageFromMemory(images[MSG_PASSWORDCHANGED].data, images[MSG_PASSWORDCHANGED].hdr.size); blitAlphaImageToScreen(0, 0, images[MSG_PASSWORDCHANGED].hdr.w, images[MSG_PASSWORDCHANGED].hdr.h, msg_passwordchanged, images[MSG_PASSWORDCHANGED].hdr.x, images[MSG_PASSWORDCHANGED].hdr.y); freeImage(msg_passwordchanged); for(temp = 0; temp < len; temp++) { blitAlphaImageToScreen(0, 0, images[MASK].hdr.w, images[MASK].hdr.h, mask, images[MASK].hdr.x+(temp*images[MASK].hdr.w), images[MASK].hdr.y); } sceDisplayWaitVblankStart(); flipScreen(); #endif sceKernelDelayThread(3000*1000); #ifdef DEBUG printf("\n\nPress X to require password only at reboot.\n\nPress O to require password always at XMB."); #else blitImageToScreen(0, 0, images[BACKGROUND].hdr.w, images[BACKGROUND].hdr.h, background, images[BACKGROUND].hdr.x, images[BACKGROUND].hdr.y); blitAlphaImageToScreen(0, 0, images[FOOTER_CHANGEMODE].hdr.w, images[FOOTER_CHANGEMODE].hdr.h, footer_changemode, images[FOOTER_CHANGEMODE].hdr.x, images[FOOTER_CHANGEMODE].hdr.y); title_requirepassword = loadImageFromMemory(images[TITLE_REQUIREPASSWORD].data, images[TITLE_REQUIREPASSWORD].hdr.size); blitAlphaImageToScreen(0, 0, images[TITLE_REQUIREPASSWORD].hdr.w, images[TITLE_REQUIREPASSWORD].hdr.h, title_requirepassword, images[TITLE_REQUIREPASSWORD].hdr.x, images[TITLE_REQUIREPASSWORD].hdr.y); freeImage(title_requirepassword); buttons = loadImageFromMemory(images[BUTTONS].data, images[BUTTONS].hdr.size); blitAlphaImageToScreen(0, 0, images[BUTTONS].hdr.w, images[BUTTONS].hdr.h, buttons, images[BUTTONS].hdr.x, images[BUTTONS].hdr.y); freeImage(buttons); sceDisplayWaitVblankStart(); flipScreen(); #endif SceCtrlLatch latch; sceCtrlSetSamplingCycle(0); sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); int skipped=0; while(1) { sceCtrlReadLatch(&latch); if(!skipped) { skipped=1; continue; } if (latch.uiMake & PSP_CTRL_CROSS) { cfg.onlyBoot = 1; break; } if (latch.uiMake & PSP_CTRL_CIRCLE) { cfg.onlyBoot = 0; break; } sceKernelDelayThread(10*1000); } sceKernelDelayThread(2000*1000); break; } else { #ifdef DEBUG printf("\nPasswords do not match."); #else int temp; blitImageToScreen(0, 0, images[BACKGROUND].hdr.w, images[BACKGROUND].hdr.h, background, images[BACKGROUND].hdr.x, images[BACKGROUND].hdr.y); blitAlphaImageToScreen(0, 0, images[FOOTER_CHANGEMODE].hdr.w, images[FOOTER_CHANGEMODE].hdr.h, footer_changemode, images[FOOTER_CHANGEMODE].hdr.x, images[FOOTER_CHANGEMODE].hdr.y); blitAlphaImageToScreen(0, 0, images[TITLE_CONFIRMPASSWORD].hdr.w, images[TITLE_CONFIRMPASSWORD].hdr.h, title_confirmpassword, images[TITLE_CONFIRMPASSWORD].hdr.x, images[TITLE_CONFIRMPASSWORD].hdr.y); freeImage(title_confirmpassword); msg_notmatch = loadImageFromMemory(images[MSG_NOTMATCH].data, images[MSG_NOTMATCH].hdr.size); blitAlphaImageToScreen(0, 0, images[MSG_NOTMATCH].hdr.w, images[MSG_NOTMATCH].hdr.h, msg_notmatch, images[MSG_NOTMATCH].hdr.x, images[MSG_NOTMATCH].hdr.y); freeImage(msg_notmatch); for(temp = 0; temp < len; temp++) { blitAlphaImageToScreen(0, 0, images[MASK].hdr.w, images[MASK].hdr.h, mask, images[MASK].hdr.x+(temp*images[MASK].hdr.w), images[MASK].hdr.y); } sceDisplayWaitVblankStart(); flipScreen(); #endif sceKernelDelayThread(3000*1000); } } #ifndef DEBUG freeImage(footer_changemode); #endif int result; result = sceIoUnassign("flash0:"); if(result < 0) { #ifdef DEBUG printf("\nError in unassign flash0."); #endif } else { result = sceIoAssign("flash0:", "lflash0:0,0", "flashfat0:", IOASSIGN_RDWR, NULL, 0); if(result < 0) { #ifdef DEBUG printf("\nError in assigning flash0 for write."); #endif } else { SceUID fp; fp = sceIoOpen("flash0:/buttons.ini", PSP_O_WRONLY|PSP_O_TRUNC|PSP_O_CREAT, 0777); if(fp < 0) { #ifdef DEBUG printf("\nError writing flash0:/buttons.ini."); #endif } else { sceIoWrite(fp, &cfg, sizeof(cfg)); sceIoClose(fp); #ifdef DEBUG printf("\nPassword written successfully."); #endif } } } }
int getInput(char* input) { int pos=0; int temp; int skipped=0; SceCtrlLatch latch; sceCtrlSetSamplingCycle(0); sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); while(1) { sceCtrlReadLatch(&latch); temp=pos; if(!skipped) { skipped=1; continue; } if ((latch.uiMake & PSP_CTRL_SELECT) && selectEnabled) { input[pos] = '\0'; return -1; } if (latch.uiMake & PSP_CTRL_START) { break; } if (pos >=10) { sceKernelDelayThread(10*1000); continue; } if (latch.uiMake & PSP_CTRL_TRIANGLE) { input[pos++] = 1; } if (latch.uiMake & PSP_CTRL_CROSS) { input[pos++] = 2; } if (latch.uiMake & PSP_CTRL_SQUARE) { input[pos++] = 3; } if (latch.uiMake & PSP_CTRL_CIRCLE) { input[pos++] = 4; } if (latch.uiMake & PSP_CTRL_UP) { input[pos++] = 5; } if (latch.uiMake & PSP_CTRL_DOWN) { input[pos++] = 6; } if (latch.uiMake & PSP_CTRL_LEFT) { input[pos++] = 7; } if (latch.uiMake & PSP_CTRL_RIGHT) { input[pos++] = 8; } if (latch.uiMake & PSP_CTRL_LTRIGGER) { input[pos++] = 9; } if (latch.uiMake & PSP_CTRL_RTRIGGER) { input[pos++] = 10; } if(pos>10) { pos=10; } #ifdef DEBUG if (pos > temp) { printf("*"); } #else blitImageToScreen(0, 0, images[BACKGROUND].hdr.w, images[BACKGROUND].hdr.h, background, images[BACKGROUND].hdr.x, images[BACKGROUND].hdr.y); blitAlphaImageToScreen(0, 0, images[footerindex].hdr.w, images[footerindex].hdr.h, *footer, images[footerindex].hdr.x, images[footerindex].hdr.y); blitAlphaImageToScreen(0, 0, images[titleindex].hdr.w, images[titleindex].hdr.h, *title, images[titleindex].hdr.x, images[titleindex].hdr.y); for (temp = 0; temp < pos; temp++) { blitAlphaImageToScreen(0, 0, images[MASK].hdr.w, images[MASK].hdr.h, mask, images[MASK].hdr.x+(temp*images[MASK].hdr.w), images[MASK].hdr.y); } sceDisplayWaitVblankStart(); flipScreen(); #endif sceKernelDelayThread(10*1000); } input[pos] = '\0'; return pos; }
void ui_msg_dialog (UI * ui, const char * msg) { pspUtilityMsgDialogParams params; unsigned int swap_count = 0; SceCtrlLatch latch; memset (¶ms, 0, sizeof (params)); params.base.size = sizeof (params); params.base.language = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; params.base.buttonSwap = PSP_UTILITY_ACCEPT_CROSS; /* Thread priorities */ params.base.graphicsThread = 17; params.base.accessThread = 19; params.base.fontThread = 18; params.base.soundThread = 16; params.mode = PSP_UTILITY_MSGDIALOG_MODE_TEXT; params.options = PSP_UTILITY_MSGDIALOG_OPTION_TEXT; snprintf (params.message, 512, msg); sceUtilityMsgDialogInitStart (¶ms); while (running) { int done = 0; /* directly use GU to avoid flickering with SDL */ sceGuStart (GU_DIRECT, list); sceGuClearColor (0xff554433); sceGuClearDepth (0); sceGuClear (GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); sceGuFinish (); sceGuSync (0,0); switch (sceUtilityMsgDialogGetStatus ()) { case PSP_UTILITY_DIALOG_NONE: break; case PSP_UTILITY_DIALOG_VISIBLE: sceUtilityMsgDialogUpdate (1); break; case PSP_UTILITY_DIALOG_QUIT: sceUtilityMsgDialogShutdownStart (); break; case PSP_UTILITY_DIALOG_FINISHED: done = 1; break; default: break; } sceDisplayWaitVblankStart (); sceGuSwapBuffers (); swap_count++; if (done) break; } /* hack for SDL compatibility. * if it end up on an odd buffer, SDL won't be displayed. * ie SDL will display in an hidden buffer */ if (swap_count & 1) sceGuSwapBuffers (); /* message dialog seems to causes strange latch behavior, next read * of latch will contains all button pressed during dialog. * read one to reset it */ sceCtrlReadLatch (&latch); }
/* configuration dialog return 0 when connected * 1 when cancelled (ie back) */ int ui_network_dialog_run (UI * ui) { pspUtilityNetconfData conf; struct pspUtilityNetconfAdhoc adhoc_params; unsigned int swap_count = 0; SceCtrlLatch latch; memset(&conf, 0, sizeof (conf)); memset(&adhoc_params, 0, sizeof (adhoc_params)); conf.base.size = sizeof (conf); conf.base.language = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; conf.base.buttonSwap = PSP_UTILITY_ACCEPT_CROSS; /* Thread priorities */ conf.base.graphicsThread = 17; conf.base.accessThread = 19; conf.base.fontThread = 18; conf.base.soundThread = 16; conf.action = PSP_NETCONF_ACTION_CONNECTAP; conf.adhocparam = &adhoc_params; sceUtilityNetconfInitStart (&conf); while (running) { int done = 0; /* directly use GU to avoid flickering with SDL */ sceGuStart (GU_DIRECT, list); sceGuClearColor (0xff554433); sceGuClearDepth (0); sceGuClear (GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); sceGuFinish (); sceGuSync (0,0); switch (sceUtilityNetconfGetStatus ()) { case PSP_UTILITY_DIALOG_NONE: break; case PSP_UTILITY_DIALOG_VISIBLE: sceUtilityNetconfUpdate (1); break; case PSP_UTILITY_DIALOG_QUIT: sceUtilityNetconfShutdownStart (); break; case PSP_UTILITY_DIALOG_FINISHED: done = 1; break; default: break; } sceDisplayWaitVblankStart (); sceGuSwapBuffers (); swap_count++; if (done) break; } /* hack for SDL compatibility. * if it end up on an odd buffer, SDL won't be displayed. * ie SDL will display in an hidden buffer */ if (swap_count & 1) sceGuSwapBuffers (); /* message dialog seems to causes strange latch behavior, next read * of latch will contains all button pressed during dialog. * read one to reset it */ sceCtrlReadLatch (&latch); return conf.base.result; }
int ui_flight_run (UI * ui, Drone * drone) { int ret = 0; int is_flying = 0; while (running) { SceCtrlData pad; SceCtrlLatch latch; int yaw = 0; int pitch = 0; int roll = 0; int gaz = 0; if (!drone->connected) { ui_msg_dialog (ui, "Connection to drone lost"); ret = FLIGHT_UI_MAIN_MENU; break; } ui_flight_update (ui, drone); sceCtrlReadBufferPositive (&pad, 1); sceCtrlReadLatch (&latch); is_flying = (drone->state == DRONE_STATE_TAKING_OFF) || (drone->state == DRONE_STATE_FLYING); /* Check triangle and circle transition */ if (EVENT_BUTTON_DOWN (&latch, PSP_CTRL_TRIANGLE)) { if (is_flying) drone_landing (drone); else drone_takeoff (drone); } if (EVENT_BUTTON_DOWN (&latch, PSP_CTRL_CIRCLE)) { drone_emergency (drone); is_flying = 0; } if (EVENT_BUTTON_DOWN (&latch, PSP_CTRL_SELECT)) { switch (ui->setting_select_binding) { case SELECT_BIND_TAKE_PICTURE: drone_take_picture (drone); break; case SELECT_BIND_FLIP_FRONT: drone_do_flip (drone, DRONE_FLIP_FRONT); break; case SELECT_BIND_FLIP_BACK: drone_do_flip (drone, DRONE_FLIP_BACK); break; case SELECT_BIND_FLIP_RIGHT: drone_do_flip (drone, DRONE_FLIP_RIGHT); break; case SELECT_BIND_FLIP_LEFT: drone_do_flip (drone, DRONE_FLIP_LEFT); break; default: break; } } if (EVENT_BUTTON_DOWN (&latch, PSP_CTRL_START)) { if (ui_flight_main_menu (ui, drone) == FLIGHT_MAIN_MENU_QUIT) { ret = FLIGHT_UI_MAIN_MENU; break; } } /* Send flight control */ if (pad.Buttons != 0) { if (pad.Buttons & PSP_CTRL_CROSS) gaz += ui->setting_gaz; if (pad.Buttons & PSP_CTRL_SQUARE) gaz -= ui->setting_gaz; if (pad.Buttons & PSP_CTRL_LTRIGGER) yaw -= ui->setting_yaw; if (pad.Buttons & PSP_CTRL_RTRIGGER) yaw += ui->setting_yaw; if (pad.Buttons & PSP_CTRL_UP) pitch += ui->setting_pitch; if (pad.Buttons & PSP_CTRL_DOWN) pitch -= ui->setting_pitch; if (pad.Buttons & PSP_CTRL_LEFT) roll -= ui->setting_roll; if (pad.Buttons & PSP_CTRL_RIGHT) roll += ui->setting_roll; } if (gaz || yaw || pitch || roll) drone_flight_control (drone, gaz, yaw, pitch, roll); sceDisplayWaitVblankStart (); SDL_Flip (ui->screen); } return ret; }