static void *removalCallback (void *arg) { while(devsleep > 0) { if(!rThreadRun) LWP_SuspendThread(removalThread); usleep(THREAD_SLEEP); devsleep -= THREAD_SLEEP; } while (1) { switch(sdMounted) //some kind of SD is mounted { #ifdef HW_RVL case FRONTSD: //check which one, if removed, set as unmounted if(!frontsd->isInserted()) { sdNeedsUnmount=sdMounted; sdMounted=0; } break; #endif /* //Polling EXI is bad with locks, so lets not do it. case CARD_A: //check which one, if removed, set as unmounted if(!carda->isInserted()) { sdNeedsUnmount=sdMounted; sdMounted=0; } break; case CARD_B: //check which one, if removed, set as unmounted if(!cardb->isInserted()) { sdNeedsUnmount=sdMounted; sdMounted=0; } break; */ } #ifdef HW_RVL if(usbMounted) // check if the device was removed if(!usb->isInserted()) { usbMounted = 0; usbNeedsUnmount=1; } #endif devsleep = 1000*1000; // 1 sec while(devsleep > 0) { if(!rThreadRun) LWP_SuspendThread(removalThread); usleep(THREAD_SLEEP); devsleep -= THREAD_SLEEP; } } return NULL; }
void * GuiImageAsync::GuiImageAsyncThread(void *arg) { while(!CloseThread) { if(ThreadSleep) LWP_SuspendThread(Thread); while(!List.empty() && !CloseThread) { LWP_MutexLock(ListLock); InUse = List.front(); List.erase(List.begin()); LWP_MutexUnlock(ListLock); if (!InUse) continue; InUse->imgData = InUse->callback(InUse->arg); if (InUse->imgData && InUse->imgData->GetImage()) { InUse->width = InUse->imgData->GetWidth(); InUse->height = InUse->imgData->GetHeight(); InUse->image = InUse->imgData->GetImage(); } InUse = NULL; } ThreadSleep = true; } return NULL; }
/********************************************************************************* * Networkthread for background network initialize and update check with idle prio *********************************************************************************/ static void * networkinitcallback(void *arg) { while (1) { if (!checkincomming && networkHalt) LWP_SuspendThread(networkthread); Initialize_Network(); if (networkinitialized == true && updatechecked == false) { if (CheckUpdate() > 0) updateavailable = true; //suspend thread updatechecked = true; networkHalt = true; } if (checkincomming) NetworkWait(); usleep(100000); } return NULL; }
void ExitCleanup() { LWP_SuspendThread (devicethread); UnmountAllFAT(); CloseShare(); #ifdef HW_RVL DI_Close(); #endif }
static void * parsecallback (void *arg) { while(1) { while(ParseDirEntries()) usleep(THREAD_SLEEP); LWP_SuspendThread(parsethread); } return NULL; }
// Init the GC/Wii net interface (wifi/bba/etc) static void* init_network(void *args) { char ip[16]; int res = 0, netsleep = 1*1000*1000; while(netsleep > 0) { if(netInitHalted) { LWP_SuspendThread(initnetthread); } usleep(100); netsleep -= 100; } while(1) { if(!net_initialized) { netInitPending = 1; res = if_config(ip, NULL, NULL, true, 5); if(res >= 0) { net_initialized = 1; } else { net_initialized = 0; } netInitPending = 0; } netsleep = 1000*1000; // 1 sec while(netsleep > 0) { if(netInitHalted) { LWP_SuspendThread(initnetthread); } usleep(100); netsleep -= 100; } } return NULL; }
/**************************************************************************** * UpdateGUI * * Primary thread to allow GUI to respond to state changes, and draws GUI ***************************************************************************/ static void * UpdateGUI(void *arg) { u8 i; while (!ExitRequested) { if (guiHalt) { LWP_SuspendThread(guithread); continue; } UpdatePads(); mainWindow->Draw(); if (Settings.tooltips && Theme::ShowTooltips && mainWindow->GetState() != STATE_DISABLED) mainWindow->DrawTooltip(); // Pointer modifies wpad data struct for easy implementation of "virtual pointer" with PAD-Sticks // That is why it has to be called right before updating other gui elements with the triggers i = 4; while(i--) pointer[i]->Draw(&userInput[i]); for (i = 0; i < 4; i++) mainWindow->Update(&userInput[i]); Menu_Render(); if (bgMusic) bgMusic->UpdateState(); } for (i = 5; i < 255; i += 10) { mainWindow->Draw(); Menu_DrawRectangle(0, 0, screenwidth, screenheight, (GXColor) { 0, 0, 0, i }, 1); Menu_Render(); } mainWindow->RemoveAll(); ShutoffRumble(); return NULL; }
static void * UpdateGUI (void *arg) { int i; while(1) { if(guiHalt) { LWP_SuspendThread(guithread); } else { UpdatePads(); mainWindow->Draw(); #ifdef HW_RVL for(i=3; i >= 0; i--) // so that player 1's cursor appears on top! { if(userInput[i].wpad->ir.valid) Menu_DrawImg(userInput[i].wpad->ir.x-48, userInput[i].wpad->ir.y-48, 96, 96, pointer[i]->GetImage(), userInput[i].wpad->ir.angle, 1, 1, 255); DoRumble(i); } #endif Menu_Render(); for(i=0; i < 4; i++) mainWindow->Update(&userInput[i]); if(ExitRequested) { for(i = 0; i < 255; i += 15) { mainWindow->Draw(); Menu_DrawRectangle(0,0,screenwidth,screenheight,(GXColor){0, 0, 0, i},1); Menu_Render(); } ExitApp(); } } } return NULL; }
static void * devicecallback (void *arg) { while (1) { if(isMounted[DEVICE_SD]) { if(!sd->isInserted()) // check if the device was removed { unmountRequired[DEVICE_SD] = true; isMounted[DEVICE_SD] = false; } } if(isMounted[DEVICE_USB]) { if(!usb->isInserted()) // check if the device was removed { unmountRequired[DEVICE_USB] = true; isMounted[DEVICE_USB] = false; } } if(isMounted[DEVICE_DVD]) { if(!dvd->isInserted()) // check if the device was removed { unmountRequired[DEVICE_DVD] = true; isMounted[DEVICE_DVD] = false; } } devsleep = 1000*1000; // 1 sec while(devsleep > 0) { if(deviceHalt) LWP_SuspendThread(devicethread); usleep(THREAD_SLEEP); devsleep -= THREAD_SLEEP; } // UpdateCheck(); } return NULL; }
bool DownloadUpdate() { bool result = false; if(strlen(updateURL) > 0) { // stop checking if devices were removed/inserted // since we're saving a file LWP_SuspendThread (devicethread); FILE * hfile; char updateFile[50]; sprintf(updateFile, "sd:/%s Update.zip", APPNAME); hfile = fopen (updateFile, "wb"); if (hfile > 0) { int retval; retval = http_request(updateURL, hfile, NULL, (1024*1024*5)); fclose (hfile); } bool unzipResult = unzipArchive(updateFile, (char *)"sd:/"); remove(updateFile); // delete update file if(unzipResult) { result = true; WaitPrompt("Update successful!"); } else { result = false; WaitPrompt("Update failed!"); } updateFound = false; // updating is finished (successful or not!) // go back to checking if devices were inserted/removed LWP_ResumeThread (devicethread); } return result; }
void * ThreadedTask::ThreadCallback(void *arg) { ThreadedTask * myInstance = (ThreadedTask *) arg; while(!myInstance->ExitRequested) { LWP_SuspendThread(myInstance->Thread); while(!myInstance->CallbackList.empty()) { if(myInstance->CallbackList[0].first) myInstance->CallbackList[0].first->Execute(myInstance->ArgList[0]); else if(myInstance->CallbackList[0].second) myInstance->CallbackList[0].second(myInstance->ArgList[0]); myInstance->CallbackList.erase(myInstance->CallbackList.begin()); myInstance->ArgList.erase(myInstance->ArgList.begin()); } } return NULL; }
void *DiHandler::ThreadMain( void *arg ) { enum State { St_Init, St_Reset, St_WaitForDisc, St_CheckDiscType, St_OpenPartition, St_WaitForDiscEject, // some error happened, dont do anything until the current disc is ejected St_Idle }; State state = St_Init; u32 coverState = 0; while( !threadExit ) { usleep( 1000 ); if( threadSleep ) LWP_SuspendThread( thread ); if( state == St_Init ) { if( WDVD_Init() ) { instance->ErrorHappened( E_Init, true ); threadExit = true; } state = St_Reset; continue; } else if( state == St_Reset ) { if( WDVD_Reset() ) { instance->ErrorHappened( E_Init, false ); continue; } state = St_WaitForDisc; } // check for disc u32 cover = 0; if( WDVD_GetCoverStatus( &cover ) ) { gprintf( "WDVD_GetCoverStatus() failed\n" ); WDVD_Close(); state = St_Init; continue; } // check if disc status is changed if( cover != coverState ) { //gprintf( "cover status: %08x %08x\n", cover, coverState ); if( cover & 2 )// disc is present and wasnt before { //gprintf( "disc inserted\n" ); instance->StartingToReadDisc(); WDVD_Reset(); state = St_CheckDiscType; } else if( coverState & 2 )// disc was present before isnt is gone now { instance->DiscEjected(); //gprintf( "disc ejected\n" ); state = St_WaitForDisc; } coverState = cover; } if( !( cover & 2 ) )// if theres no disc inserted, then loop { continue; } if( state == St_WaitForDiscEject ) { continue; } else if( state == St_CheckDiscType ) { s32 ret = WDVD_ReadDiskId( (void*)0x80000000 ); if( ret < 0 ) { gprintf("WDVD_ReadDiskId(): %d\n", ret ); instance->ErrorHappened( E_DVD_ReadError, false ); //state = St_WaitForDiscEject; WDVD_Close(); state = St_Init; //coverState = 0; continue; } // check disc type if( *(u32*)( 0x80000018 ) == 0x5d1c9ea3 ) { //gprintf( "disc is wii\n" ); state = St_OpenPartition; //instance->DiscInserted( T_Wii ); } else if( *(u32*)( 0x8000001c ) == 0xc2339f3d ) { //gprintf( "disc is gamecube\n" ); instance->DiscInserted( T_GC ); state = St_Idle; } else { //gprintf( "disc is unknown\n" ); instance->DiscInserted( T_Unknown ); state = St_WaitForDiscEject; //hexdump( (void*)0x80000000, 0x20 ); } } else if( state == St_OpenPartition ) { if( WDVD_OpenDataPartition() < 0 ) { instance->ErrorHappened( E_OpenPartition, false ); state = St_WaitForDiscEject; continue; } //gprintf( "partition is open\n" ); // search for the opening.bnr s32 ret; FST_INFO fst_info __attribute(( aligned( 32 ) )); //find FST inside partition ret = WDVD_Read( (u8*)&fst_info, sizeof( FST_INFO ), 0x420LL ); if( ret < 0 ) { gprintf("WDVD_Read( fst_info ): %d\n", ret ); instance->ErrorHappened( E_DVD_ReadError, false ); state = St_WaitForDiscEject; WDVD_ClosePartition(); continue; } fst_info.fst_offset <<= 2; fst_info.fst_size <<= 2; //gprintf( "%s %i\n", __FILE__, __LINE__ ); fst_buffer = (u8*)memalign( 32, RU( fst_info.fst_size, 0x40 ) ); if( !fst_buffer ) { instance->ErrorHappened( E_NoMem, true ); threadExit = true; WDVD_ClosePartition(); continue; } //gprintf( "%s %i\n", __FILE__, __LINE__ ); //gprintf( " %p %08x %08x\n", fst_buffer, fst_info.fst_size, fst_info.fst_offset ); //read fst into memory ret = WDVD_Read( fst_buffer, fst_info.fst_size, fst_info.fst_offset ); if( ret < 0 ) { gprintf("WDVD_Read( fst_buffer ): %d\n", ret ); instance->ErrorHappened( E_DVD_ReadError, false ); state = St_WaitForDiscEject; WDVD_ClosePartition(); continue; } //gprintf( "%s %i\n", __FILE__, __LINE__ ); //set the pointers fst = (FST_ENTRY *)fst_buffer; u32 name_table_offset = fst->filelen * 0xC; name_table = (char *)( fst_buffer + name_table_offset ); //gprintf( "%s %i\n", __FILE__, __LINE__ ); // find the opening.bnr int fd = EntryFromPath( "/opening.bnr", 0 ); if( fd < 2 ) { instance->ErrorHappened( E_NoOpeningBnr, false ); instance->DiscInserted( T_Wii ); FREE( fst ); name_table = NULL; state = St_Idle; WDVD_ClosePartition(); continue; } //gprintf( "%s %i\n", __FILE__, __LINE__ ); u32 len = fst[ fd ].filelen; u8 *buf = (u8*)memalign( 32, RU( len, 0x40 ) ); if( !buf ) { instance->ErrorHappened( E_NoMem, true ); threadExit = true; FREE( fst ); name_table = NULL; WDVD_ClosePartition(); continue; } //gprintf( "%s %i\n", __FILE__, __LINE__ ); ret = WDVD_Read( buf, len, (u64)( fst[ fd ].fileoffset ) << 2 ); if( ret < 0 ) { gprintf("WDVD_Read( opening.bnr ): %d\n", ret ); instance->ErrorHappened( E_DVD_ReadError, false ); state = St_WaitForDiscEject; FREE( fst ); name_table = NULL; free( buf ); WDVD_ClosePartition(); continue; } //gprintf( "%s %i\n", __FILE__, __LINE__ ); // done with these FREE( fst ); name_table = NULL; WDVD_ClosePartition(); //gprintf( "%s %i\n", __FILE__, __LINE__ ); bool rec = false; // got the opening.bnr. send it to whoever cares instance->OpeningBnrReady( buf, len, rec ); if( !rec ) { gprintf( "nobody got the banner. freeing it\n" ); free( buf ); } instance->DiscInserted( T_Wii ); //gprintf( "%s %i\n", __FILE__, __LINE__ ); state = St_Idle; } } return NULL; }
static void * PressKeys (void *arg) { SDL_Event event; int shift; u16 i; memset(shiftkey, 0, sizeof(shiftkey)); shiftkey[33] = 49; shiftkey[34] = 39; shiftkey[35] = 51; shiftkey[36] = 52; shiftkey[37] = 53; shiftkey[38] = 55; shiftkey[40] = 57; shiftkey[41] = 48; shiftkey[42] = 56; shiftkey[58] = 59; shiftkey[60] = 44; shiftkey[62] = 46; shiftkey[63] = 47; shiftkey[64] = 50; shiftkey[94] = 54; shiftkey[95] = 45; shiftkey[126] = 96; while(1) { LWP_SuspendThread(keythread); usleep(1200); for(i=0; i<strlen(dosboxCommand); i++) { shift=0; if((dosboxCommand[i] >= 65 && dosboxCommand[i] <= 90)) { dosboxCommand[i] += 32; shift = 1; } else if(dosboxCommand[i] > 0 && dosboxCommand[i] < 130 && shiftkey[(int)dosboxCommand[i]] > 0) { dosboxCommand[i] = shiftkey[(int)dosboxCommand[i]]; shift = 1; } if(shift) { event.type = SDL_KEYDOWN; event.key.keysym.sym = SDLK_LSHIFT; MAPPER_CheckEvent(&event); usleep(600); } // hack to allow mappings of SDL keys > 127 int keyoffset = 0; if(dosboxCommand[i] >= 14 && dosboxCommand[i] <= 25) keyoffset = 268; // F1-F12 (282-293) event.type = SDL_KEYDOWN; event.key.keysym.sym = (SDLKey)((int)dosboxCommand[i]+keyoffset); MAPPER_CheckEvent(&event); usleep(600); event.type = SDL_KEYUP; event.key.keysym.sym = (SDLKey)((int)dosboxCommand[i]+keyoffset); MAPPER_CheckEvent(&event); usleep(600); if(shift) { event.type = SDL_KEYUP; event.key.keysym.sym = SDLK_LSHIFT; MAPPER_CheckEvent(&event); usleep(600); } } dosboxCommand[0] = 0; } return NULL; }
void DiHandler::Sleep() { threadSleep = true; LWP_SuspendThread( thread ); }
int main(int argc, char *argv[]) { #ifdef HW_DOL ipl_set_config(6); // disable Qoob modchip #endif #ifdef WII_DVD DI_Init(); // first #endif int selectedMenu = -1; InitDeviceThread(); InitGCVideo (); ResetVideo_Menu (); // change to menu video mode // Controllers PAD_Init(); #ifdef HW_RVL WPAD_Init(); // read wiimote accelerometer and IR data WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR); WPAD_SetVRes(WPAD_CHAN_ALL,640,480); // Wii Power/Reset buttons WPAD_SetPowerButtonCallback((WPADShutdownCallback)ShutdownCB); SYS_SetPowerCallback(ShutdownCB); SYS_SetResetCallback(ResetCB); #endif // Initialise FreeType if (FT_Init ()) { printf ("Cannot initialise font subsystem!\n"); while (1); } InitialiseAudio(); // Initialize libFAT for SD and USB MountAllFAT(); // Initialize DVD subsystem (GameCube only) #ifdef HW_DOL DVD_Init (); #endif // allocate memory to store rom nesrom = (unsigned char *)malloc(1024*1024*3); // 3 MB should be plenty /*** Minimal Emulation Loop ***/ if ( !FCEUI_Initialize() ) { WaitPrompt("Unable to initialize FCE Ultra\n"); ExitToLoader(); } FCEUI_SetGameGenie(0); // 0 - OFF, 1 - ON memset(FDSBIOS, 0, sizeof(FDSBIOS)); // clear FDS BIOS memory cleanSFMDATA(); // clear state data // Set defaults DefaultSettings(); // store path app was loaded from sprintf(appPath, "fceugx"); if(argc > 0 && argv[0] != NULL) CreateAppPath(argv[0]); // Load preferences if(!LoadPrefs()) { WaitPrompt("Preferences reset - check settings!"); selectedMenu = 1; // change to preferences menu } FCEUI_SetSoundQuality(1); // 0 - low, 1 - high, 2 - high (alt.) FCEUI_SetVidSystem(GCSettings.timing); // causes a small 'pop' in the audio while (1) // main loop { #ifdef HW_RVL if(ShutdownRequested) ShutdownWii(); #endif // go back to checking if devices were inserted/removed // since we're entering the menu LWP_ResumeThread (devicethread); MainMenu(selectedMenu); selectedMenu = 2; // return to game menu from now on // stop checking if devices were removed/inserted // since we're starting emulation again LWP_SuspendThread (devicethread); ResetVideo_Emu(); setFrameTimer(); // set frametimer method before emulation SetPalette(); static int fskipc=0; while(1) // emulation loop { uint8 *gfx; int32 *sound; int32 ssize; #ifdef FRAMESKIP fskipc=(fskipc+1)%(frameskip+1); #endif FCEUI_Emulate(&gfx, &sound, &ssize, fskipc); if(!fskipc) { xbsave = gfx; FCEUD_Update(gfx, sound, ssize); } if(ResetRequested) { PowerNES(); // reset game ResetRequested = 0; } if(ConfigRequested) { ResetVideo_Menu(); if (GCSettings.AutoSave == 1) { SaveRAM(GCSettings.SaveMethod, SILENT); } else if (GCSettings.AutoSave == 2) { SaveState(GCSettings.SaveMethod, SILENT); } else if(GCSettings.AutoSave == 3) { SaveRAM(GCSettings.SaveMethod, SILENT); SaveState(GCSettings.SaveMethod, SILENT); } // save zoom level SavePrefs(SILENT); ConfigRequested = 0; break; // leave emulation loop } } } }
static void * netcb (void *arg) { s32 res=-1; int retry; int wait; static bool prevInit = false; while(netHalt != 2) { retry = 5; while (retry>0 && (netHalt != 2)) { if(prevInit) { int i; net_deinit(); for(i=0; i < 400 && (netHalt != 2); i++) // 10 seconds to try to reset { res = net_get_status(); if(res != -EBUSY) // trying to init net so we can't kill the net { usleep(2000); net_wc24cleanup(); //kill the net prevInit=false; // net_wc24cleanup is called only once usleep(20000); break; } usleep(20000); } } usleep(2000); res = net_init_async(NULL, NULL); if(res != 0) { sleep(1); retry--; continue; } res = net_get_status(); wait = 400; // only wait 8 sec while (res == -EBUSY && wait > 0 && (netHalt != 2)) { usleep(20000); res = net_get_status(); wait--; } if(res==0) break; retry--; usleep(2000); } if (res == 0) { struct in_addr hostip; hostip.s_addr = net_gethostip(); if (hostip.s_addr) { strcpy(wiiIP, inet_ntoa(hostip)); networkInit = true; prevInit = true; } } if(netHalt != 2) LWP_SuspendThread(networkthread); } return NULL; }
static void * UpdateGUI (void *arg) { int i; while(1) { if(guiHalt) { LWP_SuspendThread(guithread); } else { UpdatePads(); mainWindow->Draw(); #ifdef HW_RVL // for(i=3; i >= 0; i--) // so that player 1's cursor appears on top! // { if(userInput[0].wpad->ir.valid) Menu_DrawImg(userInput[0].wpad->ir.x-48, userInput[0].wpad->ir.y-48, 96, 96, pointer->GetImage(), userInput[0].wpad->ir.angle, 1, 1, 255); // } #endif Menu_Render(); // for(i=0; i < 4; i++) mainWindow->Update(&userInput[0]); if(ExitRequested) { for(i = 0; i < 255; i += 15) { mainWindow->Draw(); GXColor Color = (GXColor) {0, 0, 0, i}; Menu_DrawRectangle(0,0,screenwidth,screenheight,&Color,false,true); Menu_Render(); } if (boothomebrew) { LoadHomebrew(Settings.forwarder_path.c_str()); string startingAppName = Settings.forwarder_path; if((signed)startingAppName.rfind("/") != -1) startingAppName.erase(startingAppName.rfind("/")); startingAppName.erase(0, startingAppName.rfind("/") +1); if(IOS_GetVersion() != GetAppIOS(startingAppName)) addAppIos(Settings.startingAppName, SelectedIOS()); } if (!goneek2o) ExitApp(); } // sd check if(Settings.device == "sd1") check_sd(); // usb check else if(Settings.device == "usb1") check_usb(); // sd und usb check else if(Settings.device == "sd_usb") { check_sd(); check_usb(); } else if(Settings.device == "dvd") check_dvd(); #ifndef VWII else if(Settings.device == "gca") check_gca(); else if(Settings.device == "gcb") check_gcb(); #endif else if(Settings.device == "all") { check_sd(); check_usb(); check_dvd(); #ifndef VWII check_gca(); check_gcb(); #endif } // screenshoot if(WPAD_ButtonsDown(0) & WPAD_BUTTON_1 && WPAD_ButtonsDown(0) & WPAD_BUTTON_2) Screenshot(); } } return NULL; }