/************************************************************************* WinMain() Windows entry point *************************************************************************/ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { SetupWindow(); MSG msg; int exitCode; CTimer timer; timer.Init(); while (true) { if(PeekMessage(&msg, g_hwnd, NULL, NULL, PM_REMOVE)) { if (msg.message == WM_QUIT) // do we receive a WM_QUIT message? { exitCode = msg.wParam; break; // if so, time to quit the application } else { TranslateMessage(&msg); // translate and dispatch to event queue DispatchMessage(&msg); } } // don't update the scene if the app is minimized if (g_isActive) { // update the scene every time through the loop GameMain(timer.GetElapsedSeconds()); DisplayFPS(&timer); // switch the front and back buffers to display the updated scene SwapBuffers(g_hdc); } else { timer.GetElapsedSeconds(); } } KillWindow(); return exitCode; }
//************************************************************************************* // //************************************************************************************* void IDisplayListDebugger::Run() { // // Enter the debug menu as soon as select is newly pressed // SceCtrlData pad; SPspPadState pad_state; pad_state.OldButtons = 0; sceCtrlPeekBufferPositive(&pad, 1); pad_state.OldButtons = pad.Buttons; bool menu_button_pressed( false ); u64 freq; NTiming::GetPreciseFrequency( &freq ); float freq_inv = 1.0f / f32( freq ); gRendererPSP->SetRecordCombinerStates( true ); CTimer timer; typedef std::vector< CDebugMenuOption * > DebugMenuOptionVector; DebugMenuOptionVector menu_options; u32 total_instruction_count = gNumInstructionsExecuted; u32 instruction_limit = gNumInstructionsExecuted; menu_options.push_back( new CCombinerExplorerDebugMenuOption ); menu_options.push_back( new CBlendDebugMenuOption ); menu_options.push_back( new CTextureExplorerDebugMenuOption ); menu_options.push_back( new CDisplayListLengthDebugMenuOption(total_instruction_count, &instruction_limit) ); menu_options.push_back( new CDecalOffsetDebugMenuOption ); u32 highlighted_option( 0 ); CDebugMenuOption * p_current_option( NULL ); // Remain paused until the Select button is pressed again bool need_update_display( true ); bool dump_next_screen( false ); bool dump_texture_dlist( false ); while( (pad_state.NewButtons & PSP_CTRL_HOME) != 0 || !menu_button_pressed ) { //guSwapBuffersBehaviour( PSP_DISPLAY_SETBUF_IMMEDIATE ); if( dump_next_screen ) { dump_next_screen = false; CGraphicsContext::Get()->DumpScreenShot(); } DLDebugOutput * debug_output = NULL; if( dump_texture_dlist ) { dump_texture_dlist = false; printf( TERMINAL_TOP_LEFT ); printf( TERMINAL_CLEAR_LINE ); printf( "Dumping Display List and Textures...\n" ); // Dump the display list debug_output = DLDebug_CreateFileOutput(); // Dump textures MutexLock lock(CTextureCache::Get()->GetDebugMutex()); std::vector<CTextureCache::STextureInfoSnapshot> snapshot; CTextureCache::Get()->Snapshot( lock, snapshot ); sort( snapshot.begin(), snapshot.end(), &OrderTextures ); // Dump each in turn for( u32 i = 0; i < snapshot.size(); ++i ) { CachedTexture::DumpTexture( snapshot[i].Info, snapshot[i].Texture ); } } CGraphicsContext::Get()->BeginFrame(); CGraphicsContext::Get()->ClearToBlack(); CGraphicsContext::Get()->EndFrame(); u64 time_before; NTiming::GetPreciseTime( &time_before ); // // Re-render the current frame // bool render_dlist( true ); if( p_current_option != NULL ) { if( p_current_option->OverrideDisplay() ) { render_dlist = false; } } if( render_dlist ) { DLParser_Process(instruction_limit, debug_output); // We can delete the sink as soon as we're done with it. delete debug_output; debug_output = NULL; } u64 time_after; NTiming::GetPreciseTime( &time_after ); // // Figure out how long the last frame took // u64 elapsed_ticks( time_after - time_before ); float elapsed_ms( f32(elapsed_ticks) * 1000.0f * freq_inv ); float framerate( 0.0f ); if(elapsed_ms > 0) { framerate = 1000.0f / elapsed_ms; } CGraphicsContext::Get()->UpdateFrame( false ); //sceDisplayWaitVblankStart(); sceCtrlPeekBufferPositive(&pad, 1); pad_state.NewButtons = pad.Buttons; const s32 STICK_DEADZONE = 20; s32 stick_x( pad.Lx - 128 ); s32 stick_y( pad.Ly - 128 ); if(stick_x >= -STICK_DEADZONE && stick_x <= STICK_DEADZONE) { stick_x = 0; } if(stick_y >= -STICK_DEADZONE && stick_y <= STICK_DEADZONE) { stick_y = 0; } pad_state.Stick.x = float(stick_x) / 128.0f; pad_state.Stick.y = float(stick_y) / 128.0f; float actual_elapsed_time( timer.GetElapsedSeconds() ); // // Update input // if( p_current_option != NULL ) { p_current_option->Update( pad_state, actual_elapsed_time ); if(p_current_option->NeedsUpdateDisplay()) { need_update_display = true; } } // // Refresh display // if(need_update_display) { printf( TERMINAL_CLEAR_SCREEN ); printf( TERMINAL_TOP_LEFT ); printf( "Dlist took %dms (%fHz) [%d/%d]\n", s32(elapsed_ms), framerate, instruction_limit, total_instruction_count ); printf( "\n" ); if( p_current_option != NULL ) { p_current_option->UpdateDisplay(); } else { printf( "(HOME) -> Resume game\n" ); printf( "(START) -> Screen shot\n" ); printf( "(SELECT) -> Go to next frame\n" ); printf( "(R-TRIG) -> Dump DList & Textures\n" ); printf( "(L-TRIG) -> Scale Screen\n\n" ); u32 idx = 0; for( DebugMenuOptionVector::const_iterator it = menu_options.begin(); it != menu_options.end(); ++it, idx++ ) { bool selected( idx == highlighted_option ); CDebugMenuOption * p_option( *it ); printf( "%c%s\n", selected ? '*' : ' ', p_option->GetDescription() ); } } need_update_display = false; printf( TERMINAL_SAVE_POS ); } else { // Just update timing info printf( TERMINAL_TOP_LEFT ); printf( TERMINAL_CLEAR_LINE ); printf( "Dlist took %dms (%fHz) [%d/%d]\n", s32(elapsed_ms), framerate, instruction_limit, total_instruction_count ); printf( TERMINAL_RESTORE_POS ); } fflush( stdout ); // // Input // if( p_current_option != NULL ) { if(pad_state.OldButtons != pad_state.NewButtons) { if(pad_state.NewButtons & PSP_CTRL_SQUARE) { p_current_option = NULL; need_update_display = true; } } } else { if(pad_state.OldButtons != pad_state.NewButtons) { if(pad_state.NewButtons & PSP_CTRL_UP) { if( highlighted_option > 0 ) { highlighted_option--; need_update_display = true; } } if(pad_state.NewButtons & PSP_CTRL_DOWN) { if( highlighted_option < menu_options.size() - 1 ) { highlighted_option++; need_update_display = true; } } if(pad_state.NewButtons & PSP_CTRL_CROSS) { p_current_option = menu_options[ highlighted_option ]; need_update_display = true; } } } if(pad_state.OldButtons != pad_state.NewButtons) { if(pad_state.NewButtons & PSP_CTRL_HOME) { menu_button_pressed = true; } if(pad_state.NewButtons & PSP_CTRL_START) { dump_next_screen = true; } if(pad_state.NewButtons & PSP_CTRL_LTRIGGER) { gGlobalPreferences.ViewportType = EViewportType( (gGlobalPreferences.ViewportType+1) % NUM_VIEWPORT_TYPES ); CGraphicsContext::Get()->ClearAllSurfaces(); } if(pad_state.NewButtons & PSP_CTRL_RTRIGGER) { dump_texture_dlist = true; } if(pad_state.NewButtons & PSP_CTRL_SELECT) { gSingleStepFrames = true; menu_button_pressed = true; } } pad_state.OldButtons = pad_state.NewButtons; } gRendererPSP->SetRecordCombinerStates( false ); // // Clean up // for( DebugMenuOptionVector::const_iterator it = menu_options.begin(); it != menu_options.end(); ++it ) { CDebugMenuOption * p_option( *it ); delete p_option; } }