bool keyPressedAutoRepeat(int key) { if (keyJustPressed(key)) { repeatStartTimer = 14; return true; } if (keyPressed(key) && repeatStartTimer == 0 && repeatTimer == 0) { repeatTimer = 2; return true; } return false; }
// Private function used for simple submenus void subMenuGenericUpdateFunc() { if (keyJustPressed(KEY_A) || keyJustPressed(KEY_B)) closeSubMenu(); }
// Called each vblank while the menu is on void updateMenu() { if (subMenuUpdateFunc != 0) { subMenuUpdateFunc(); return; } bool redraw = false; // Get input if (keyPressedAutoRepeat(KEY_UP)) { option--; if (option < -1) option = menuList[menu].numOptions-1; redraw = true; } else if (keyPressedAutoRepeat(KEY_DOWN)) { option++; if (option >= menuList[menu].numOptions) option = -1; redraw = true; } else if (keyPressedAutoRepeat(KEY_LEFT)) { if (option == -1) { menu--; if (menu < 0) menu = numMenus-1; } else if (menuList[menu].options[option].numValues != 0 && menuList[menu].options[option].enabled) { int selection = menuList[menu].options[option].selection-1; if (selection < 0) selection = menuList[menu].options[option].numValues-1; menuList[menu].options[option].selection = selection; menuList[menu].options[option].function(selection); } redraw = true; } else if (keyPressedAutoRepeat(KEY_RIGHT)) { if (option == -1) { menu++; if (menu >= numMenus) menu = 0; } else if (menuList[menu].options[option].numValues != 0 && menuList[menu].options[option].enabled) { int selection = menuList[menu].options[option].selection+1; if (selection >= menuList[menu].options[option].numValues) selection = 0; menuList[menu].options[option].selection = selection; menuList[menu].options[option].function(selection); } redraw = true; } else if (keyJustPressed(KEY_A)) { forceReleaseKey(KEY_A); if (option >= 0 && menuList[menu].options[option].numValues == 0 && menuList[menu].options[option].enabled) { menuList[menu].options[option].function(menuList[menu].options[option].selection); } redraw = true; } else if (keyJustPressed(KEY_B)) { forceReleaseKey(KEY_B); closeMenu(); updateScreens(); } else if (keyJustPressed(KEY_L)) { menu--; if (menu < 0) menu = numMenus-1; if (option >= menuList[menu].numOptions) option = menuList[menu].numOptions-1; redraw = true; } else if (keyJustPressed(KEY_R)) { menu++; if (menu >= numMenus) menu = 0; if (option >= menuList[menu].numOptions) option = menuList[menu].numOptions-1; redraw = true; } if (redraw && subMenuUpdateFunc == 0 && isMenuOn()) // The menu may have been closed by an option doAtVBlank(redrawMenu); }
/* * Prompts the user for a file to load. * Returns a pointer to a newly-allocated string. The caller is responsible * for free()ing it. */ char* startFileChooser() { char* retval; char cwd[256]; getcwd(cwd, 256); DIR* dp = opendir(cwd); struct dirent *entry; if (dp == NULL) { iprintf("Error opening directory.\n"); return 0; } while (true) { numFiles=0; std::vector<char*> filenames; std::vector<bool> directory; while ((entry = readdir(dp)) != NULL) { char* ext = strrchr(entry->d_name, '.')+1; if (entry->d_type & DT_DIR || strcmpi(ext, "cgb") == 0 || strcmpi(ext, "gbc") == 0 || strcmpi(ext, "gb") == 0 || strcmpi(ext, "sgb") == 0 || strcmpi(ext, "gbs") == 0) { if (!(strcmp(".", entry->d_name) == 0)) { directory.push_back(entry->d_type & DT_DIR); char *name = (char*)malloc(sizeof(char)*(strlen(entry->d_name)+1)); strcpy(name, entry->d_name); filenames.push_back(name); numFiles++; } } } quickSort(filenames, directory, nameSortFunction, 0, numFiles - 1); scrollY=0; updateScrollDown(); bool readDirectory = false; while (!readDirectory) { consoleClear(); for (int i=scrollY; i<scrollY+filesPerPage && i<numFiles; i++) { if (i == fileSelection) iprintf("* "); else if (i == scrollY && i != 0) iprintf("^ "); else if (i == scrollY+filesPerPage-1 && scrollY+filesPerPage-1 != numFiles-1) iprintf("v "); else iprintf(" "); char outBuffer[32]; int maxLen = 29; if (directory[i]) maxLen--; strncpy(outBuffer, filenames[i], maxLen); outBuffer[maxLen] = '\0'; if (directory[i]) iprintf("%s/\n", outBuffer); else iprintf("%s\n", outBuffer); } while (true) { swiWaitForVBlank(); readKeys(); if (keyJustPressed(KEY_A)) { if (directory[fileSelection]) { closedir(dp); dp = opendir(filenames[fileSelection]); chdir(filenames[fileSelection]); readDirectory = true; break; } else { // Copy the result to a new allocation, as the // filename would become unavailable when freed. retval = (char*) malloc(sizeof(char) * (strlen(filenames[fileSelection]) + 1)); strcpy(retval, filenames[fileSelection]); // free memory used for filenames in this dir for (int i=0; i<numFiles; i++) { free(filenames[i]); } goto end; } } else if (keyJustPressed(KEY_B)) { if (numFiles >= 1 && strcmp(filenames[0], "..") == 0) { closedir(dp); dp = opendir(".."); chdir(".."); readDirectory = true; break; } } else if (keyPressedAutoRepeat(KEY_UP)) { if (fileSelection > 0) { fileSelection--; updateScrollUp(); break; } } else if (keyPressedAutoRepeat(KEY_DOWN)) { if (fileSelection < numFiles-1) { fileSelection++; updateScrollDown(); break; } } else if (keyPressedAutoRepeat(KEY_RIGHT)) { fileSelection += filesPerPage/2; updateScrollDown(); break; } else if (keyPressedAutoRepeat(KEY_LEFT)) { fileSelection -= filesPerPage/2; updateScrollUp(); break; } } } // free memory used for filenames for (int i=0; i<numFiles; i++) { free(filenames[i]); } fileSelection = 0; } end: closedir(dp); consoleClear(); return retval; }
void updateKeyConfigChooser() { bool redraw = false; int& option = keyConfigChooser_option; KeyConfig* config = &keyConfigs[selectedKeyConfig]; if (keyJustPressed(KEY_B)) { loadKeyConfig(); closeSubMenu(); } else if (keyJustPressed(KEY_X)) { keyConfigs.push_back(KeyConfig(*config)); selectedKeyConfig = keyConfigs.size()-1; char name[32]; sprintf(name, "Custom %d", keyConfigs.size()-1); strcpy(keyConfigs.back().name, name); option = -1; redraw = true; } else if (keyJustPressed(KEY_Y)) { if (selectedKeyConfig != 0) /* can't erase the default */ { keyConfigs.erase(keyConfigs.begin() + selectedKeyConfig); if (selectedKeyConfig >= keyConfigs.size()) selectedKeyConfig = keyConfigs.size() - 1; redraw = true; } } else if (keyPressedAutoRepeat(KEY_DOWN)) { if (option == NUM_BINDABLE_BUTTONS-1) option = -1; #if defined(_3DS) else if(option == 11) //Skip nonexistant keys option = 14; else if(option == 15) option = 24; #endif else option++; redraw = true; } else if (keyPressedAutoRepeat(KEY_UP)) { if (option == -1) option = NUM_BINDABLE_BUTTONS-1; #if defined(_3DS) else if(option == 14) //Skip nonexistant keys option = 11; else if(option == 24) option = 15; #endif else option--; redraw = true; } else if (keyPressedAutoRepeat(KEY_LEFT)) { if (option == -1) { if (selectedKeyConfig == 0) selectedKeyConfig = keyConfigs.size()-1; else selectedKeyConfig--; } else { config->funcKeys[option]--; if (config->funcKeys[option] < 0) config->funcKeys[option] = NUM_FUNC_KEYS-1; } redraw = true; } else if (keyPressedAutoRepeat(KEY_RIGHT)) { if (option == -1) { selectedKeyConfig++; if (selectedKeyConfig >= keyConfigs.size()) selectedKeyConfig = 0; } else { config->funcKeys[option]++; if (config->funcKeys[option] >= NUM_FUNC_KEYS) config->funcKeys[option] = 0; } redraw = true; } if (redraw) doAtVBlank(redrawKeyConfigChooser); }