// Checks if devices are available, prints name of device being detected for slow init devices void populateDeviceAvailability() { if(PAD_ButtonsHeld(0) & PAD_BUTTON_B) { deviceHandler_setAllDevicesAvailable(); return; } uiDrawObj_t *msgBox = DrawPublish(DrawProgressBar(true, 0, "Detecting devices ...\nThis can be skipped by holding B next time")); int i; for(i = 0; i < MAX_DEVICES; i++) { if(allDevices[i] != NULL && !deviceHandler_getDeviceAvailable(allDevices[i])) { print_gecko("Checking device availability for device %s\r\n", allDevices[i]->deviceName); deviceHandler_setDeviceAvailable(allDevices[i], allDevices[i]->test()); } if(PAD_ButtonsHeld(0) & PAD_BUTTON_B) { deviceHandler_setAllDevicesAvailable(); break; } } DrawDispose(msgBox); }
void main_loop() { while(PAD_ButtonsHeld(0) & PAD_BUTTON_A) { VIDEO_WaitVSync (); } // We don't care if a subsequent device is "default" if(needsDeviceChange) { free_files(); if(deviceHandler_deinit) { deviceHandler_deinit(deviceHandler_initial); } if (forceSlot) { deviceHandler_FAT_deinit(&initial_SD1); } curDevice = -1; needsDeviceChange = 0; deviceHandler_initial = NULL; needsRefresh = 1; curMenuLocation = ON_FILLIST; select_device(0); if (curDevice == WKF) { trySlotB(); } curMenuLocation = ON_OPTIONS; } if(deviceHandler_initial) { // If the user selected a device, make sure it's ready before we browse the filesystem deviceHandler_deinit( deviceHandler_initial ); sdgecko_setSpeed(EXI_SPEED32MHZ); if(!deviceHandler_init( deviceHandler_initial )) { if(((deviceHandler_initial->name[0] == 's')&&(deviceHandler_initial->name[1] == 'd'))||(deviceHandler_initial->name[0] == 'i')) { print_gecko("SD/IDE-EXI Device Failed to initialize @ 32MHz!\r\nTrying again once @ 16MHz...\r\n"); sdgecko_setSpeed(EXI_SPEED16MHZ); if(!deviceHandler_init(deviceHandler_initial)) { // Try the alternate slot for SDGecko or IDE-EXI if(deviceHandler_initial->name[0] == 's') deviceHandler_initial = (deviceHandler_initial == &initial_SD0) ? &initial_SD1:&initial_SD0; else deviceHandler_initial = (deviceHandler_initial == &initial_IDE0) ? &initial_IDE1:&initial_IDE0; memcpy(&curFile, deviceHandler_initial, sizeof(file_handle)); } print_gecko("Trying alternate slot @ 32MHz...\r\n"); sdgecko_setSpeed(EXI_SPEED32MHZ); if(!deviceHandler_init( deviceHandler_initial )) { print_gecko("Alternate slot failed once @ 16MHz... \r\n"); sdgecko_setSpeed(EXI_SPEED16MHZ); if(!deviceHandler_init( deviceHandler_initial )) { print_gecko("Both slots failed twice\r\n"); needsDeviceChange = 1; return; } } } } if(curDevice==SD_CARD || curDevice==WKF || curDevice==IDEEXI) { load_config(forceSlot); } } else { curMenuLocation=ON_OPTIONS; } // If a previously undetected device has been successfully init'd, mark it as available from now on if(!deviceHandler_getDeviceAvailable(curDevice)) { deviceHandler_setDeviceAvailable(curDevice, 1); } while(1) { if(deviceHandler_initial && needsRefresh) { curMenuLocation=ON_OPTIONS; free_files(); curSelection=0; files=0; curMenuSelection=0; // Read the directory/device TOC if(allFiles){ free(allFiles); allFiles = NULL; } print_gecko("Reading directory: %s\r\n",curFile.name); files = deviceHandler_readDir(&curFile, &allFiles, -1); memcpy(&curDir, &curFile, sizeof(file_handle)); sortFiles(allFiles, files); print_gecko("Found %i entries\r\n",files); if(files<1) { deviceHandler_deinit(deviceHandler_initial); needsDeviceChange=1; break;} needsRefresh = 0; curMenuLocation=ON_FILLIST; } while(PAD_ButtonsHeld(0) & PAD_BUTTON_A) { VIDEO_WaitVSync (); } drawFiles(&allFiles, files); u16 btns = PAD_ButtonsHeld(0); if(curMenuLocation==ON_OPTIONS) { if(btns & PAD_BUTTON_LEFT){ curMenuSelection = (--curMenuSelection < 0) ? (MENU_MAX-1) : curMenuSelection;} else if(btns & PAD_BUTTON_RIGHT){curMenuSelection = (curMenuSelection + 1) % MENU_MAX; } } if(deviceHandler_initial && ((btns & PAD_BUTTON_B)||(curMenuLocation==ON_FILLIST))) { while(PAD_ButtonsHeld(0) & PAD_BUTTON_B){ VIDEO_WaitVSync (); } curMenuLocation=ON_FILLIST; renderFileBrowser(&allFiles, files); } else if(btns & PAD_BUTTON_A) { //handle menu event switch(curMenuSelection) { case 0: // Device change needsDeviceChange = 1; //Change from SD->DVD or vice versa break; case 1: // Settings show_settings(NULL, NULL); break; case 2: // Credits show_info(); break; case 3: if(deviceHandler_initial) { memcpy(&curFile, deviceHandler_initial, sizeof(file_handle)); if(curDevice == WKF) { wkfReinit(); deviceHandler_deinit(deviceHandler_initial); } } needsRefresh=1; break; case 4: __libogc_exit(0); break; } } while (!(!(PAD_ButtonsHeld(0) & PAD_BUTTON_B) && !(PAD_ButtonsHeld(0) & PAD_BUTTON_A) && !(PAD_ButtonsHeld(0) & PAD_BUTTON_RIGHT) && !(PAD_ButtonsHeld(0) & PAD_BUTTON_LEFT))) { VIDEO_WaitVSync(); } if(needsDeviceChange) { break; } } }
/**************************************************************************** * Main ****************************************************************************/ int main () { // Setup defaults (if no config is found) memset(&swissSettings, 0 , sizeof(SwissSettings)); // Register all devices supported (order matters for boot devices) int i = 0; for(i = 0; i < MAX_DEVICES; i++) allDevices[i] = NULL; i = 0; allDevices[i++] = &__device_wkf; allDevices[i++] = &__device_wode; allDevices[i++] = &__device_sd_a; allDevices[i++] = &__device_sd_b; allDevices[i++] = &__device_card_a; allDevices[i++] = &__device_card_b; allDevices[i++] = &__device_dvd; allDevices[i++] = &__device_ide_a; allDevices[i++] = &__device_ide_b; allDevices[i++] = &__device_qoob; allDevices[i++] = &__device_smb; allDevices[i++] = &__device_sys; allDevices[i++] = &__device_usbgecko; allDevices[i++] = &__device_ftp; allDevices[i++] = &__device_fsp; allDevices[i++] = NULL; // Set current devices devices[DEVICE_CUR] = NULL; devices[DEVICE_DEST] = NULL; devices[DEVICE_TEMP] = NULL; devices[DEVICE_CONFIG] = NULL; devices[DEVICE_PATCHES] = NULL; Initialise(); // Sane defaults refreshSRAM(&swissSettings); swissSettings.debugUSB = 0; swissSettings.gameVMode = 0; // Auto video mode swissSettings.exiSpeed = 1; // 32MHz swissSettings.uiVMode = 0; // Auto UI mode swissSettings.aveCompat = 1; swissSettings.enableFileManagement = 0; needsDeviceChange = 1; needsRefresh = 1; //debugging stuff if(swissSettings.debugUSB) { if(usb_isgeckoalive(1)) { usb_flush(1); } print_gecko("Arena Size: %iKb\r\n",(SYS_GetArena1Hi()-SYS_GetArena1Lo())/1024); print_gecko("DVD Drive Present? %s\r\n",swissSettings.hasDVDDrive?"Yes":"No"); print_gecko("GIT Commit: %s\r\n", GITREVISION); print_gecko("GIT Revision: %s\r\n", GITVERSION); } // Go through all devices with FEAT_BOOT_DEVICE feature and set it as current if one is available for(i = 0; i < MAX_DEVICES; i++) { if(allDevices[i] != NULL && (allDevices[i]->features & FEAT_BOOT_DEVICE)) { print_gecko("Testing device %s\r\n", allDevices[i]->deviceName); if(allDevices[i]->test()) { deviceHandler_setDeviceAvailable(allDevices[i], true); devices[DEVICE_CUR] = allDevices[i]; break; } } } if(devices[DEVICE_CUR] != NULL) { print_gecko("Detected %s\r\n", devices[DEVICE_CUR]->deviceName); if(devices[DEVICE_CUR]->init(devices[DEVICE_CUR]->initial)) { if(devices[DEVICE_CUR]->features & FEAT_AUTOLOAD_DOL) { load_auto_dol(); } memcpy(&curFile, devices[DEVICE_CUR]->initial, sizeof(file_handle)); needsDeviceChange = 0; } } // Scan here since some devices would already be initialised (faster) populateDeviceAvailability(); // If there's no default config device, set it to the first writable device available if(swissSettings.configDeviceId == DEVICE_ID_UNK) { for(int i = 0; i < MAX_DEVICES; i++) { if(allDevices[i] != NULL && (allDevices[i]->features & FEAT_WRITE) && deviceHandler_getDeviceAvailable(allDevices[i])) { swissSettings.configDeviceId = allDevices[i]->deviceUniqueId; print_gecko("No default config device found, using [%s]\r\n", allDevices[i]->deviceName); syssramex* sramex = __SYS_LockSramEx(); sramex->__padding0 = swissSettings.configDeviceId; __SYS_UnlockSramEx(1); while(!__SYS_SyncSram()); break; } } } // Try to open up the config .ini in case it hasn't been opened already if(config_init()) { // TODO notification area this print_gecko("Loaded %i entries from the config file\r\n",config_get_count()); } if(swissSettings.initNetworkAtStart) { // Start up the BBA if it exists uiDrawObj_t *msgBox = DrawPublish(DrawProgressBar(true, 0, "Initialising Network")); init_network(); init_httpd_thread(); DrawDispose(msgBox); } // DVD Motor off setting; Always stop the drive if we only started it to read the ID out if((swissSettings.stopMotor && swissSettings.hasDVDDrive) || (swissSettings.hasDVDDrive == 2)) { dvd_motor_off(); } // Swiss video mode force GXRModeObj *forcedMode = getVideoModeFromSwissSetting(swissSettings.uiVMode); if((forcedMode != NULL) && (forcedMode != getVideoMode())) { setVideoMode(forcedMode); } while(1) { menu_loop(); } return 0; }