void SDLApp::Run() { timer_.reset(); while( run_ ) { PumpEvents(); float dt = timer_.reset() / 1000.f; OnFrame(dt); } }
/** * asynchronously copy file. */ static nsresult RunTest(nsIFile *srcFile, nsIFile *destFile) { nsresult rv; LOG(("RunTest\n")); nsCOMPtr<nsIStreamTransportService> sts = do_GetService(kStreamTransportServiceCID, &rv); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIInputStream> srcStr; rv = NS_NewLocalFileInputStream(getter_AddRefs(srcStr), srcFile); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIOutputStream> destStr; rv = NS_NewLocalFileOutputStream(getter_AddRefs(destStr), destFile); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsITransport> srcTransport; rv = sts->CreateInputTransport(srcStr, PRInt64(-1), PRInt64(-1), PR_TRUE, getter_AddRefs(srcTransport)); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsITransport> destTransport; rv = sts->CreateOutputTransport(destStr, PRInt64(-1), PRInt64(-1), PR_TRUE, getter_AddRefs(destTransport)); if (NS_FAILED(rv)) return rv; MyCopier *copier = new MyCopier(); if (copier == nsnull) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(copier); rv = copier->AsyncCopy(srcTransport, destTransport); if (NS_FAILED(rv)) return rv; PumpEvents(); NS_RELEASE(copier); return NS_OK; }
/** * asynchronously copy file. */ static nsresult RunTest(nsIFile *file, int64_t offset, int64_t length) { nsresult rv; LOG(("RunTest\n")); nsCOMPtr<nsIInputStream> stream; rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIInputStreamPump> pump; rv = NS_NewInputStreamPump(getter_AddRefs(pump), stream, offset, length); if (NS_FAILED(rv)) return rv; rv = pump->AsyncRead(new MyListener(), nullptr); if (NS_FAILED(rv)) return rv; PumpEvents(); return NS_OK; }
/** * asynchronously read socket stream */ static nsresult RunTest(nsISocketTransportService *sts, const char *host, int port, const char *path, uint32_t inFlags, uint32_t outFlags) { nsresult rv; LOG(("RunTest\n")); nsCOMPtr<nsISocketTransport> transport; rv = sts->CreateTransport(nullptr, 0, nsDependentCString(host), port, nullptr, getter_AddRefs(transport)); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIInputStream> in; rv = transport->OpenInputStream(inFlags, 0, 0, getter_AddRefs(in)); nsCOMPtr<nsIAsyncInputStream> asyncIn = do_QueryInterface(in, &rv); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIOutputStream> out; rv = transport->OpenOutputStream(outFlags, 0, 0, getter_AddRefs(out)); nsCOMPtr<nsIAsyncOutputStream> asyncOut = do_QueryInterface(out, &rv); if (NS_FAILED(rv)) return rv; MyHandler *handler = new MyHandler(path, asyncIn, asyncOut); if (handler == nullptr) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(handler); rv = asyncOut->AsyncWait(handler, 0, 0, nullptr); if (NS_SUCCEEDED(rv)) PumpEvents(); NS_RELEASE(handler); return NS_OK; }
int main(int argc, char* argv[]) { if (test_common_init(&argc, &argv) != 0) return -1; nsresult rv= (nsresult)-1; if (argc < 2) { printf("usage: %s <port>\n", argv[0]); return -1; } #if defined(PR_LOGGING) gTestLog = PR_NewLogModule("Test"); #endif /* * The following code only deals with XPCOM registration stuff. and setting * up the event queues. Copied from TestSocketIO.cpp */ rv = NS_InitXPCOM2(nullptr, nullptr, nullptr); if (NS_FAILED(rv)) return rv; { rv = MakeServer(atoi(argv[1])); if (NS_FAILED(rv)) { LOG(("MakeServer failed [rv=%x]\n", rv)); return -1; } // Enter the message pump to allow the URL load to proceed. PumpEvents(); } // this scopes the nsCOMPtrs // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM NS_ShutdownXPCOM(nullptr); return rv; }
int main(int argc, char* argv[]) { if (test_common_init(&argc, &argv) != 0) return -1; nsresult rv; if (argc < 2) { printf("usage: %s <url> <file-to-upload>\n", argv[0]); return -1; } char* uriSpec = argv[1]; char* fileName = argv[2]; #if defined(PR_LOGGING) gTestLog = PR_NewLogModule("Test"); #endif { nsCOMPtr<nsIServiceManager> servMan; NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull); nsCOMPtr<nsIIOService> ioService(do_GetService(kIOServiceCID, &rv)); // first thing to do is create ourselves a stream that // is to be uploaded. nsCOMPtr<nsIInputStream> uploadStream; rv = NS_NewPostDataStream(getter_AddRefs(uploadStream), PR_TRUE, nsDependentCString(fileName), // XXX UTF-8 0, ioService); if (NS_FAILED(rv)) return rv; // create our url. nsCOMPtr<nsIURI> uri; rv = NS_NewURI(getter_AddRefs(uri), uriSpec); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIChannel> channel; rv = ioService->NewChannelFromURI(uri, getter_AddRefs(channel)); if (NS_FAILED(rv)) return rv; // QI and set the upload stream nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(channel)); uploadChannel->SetUploadStream(uploadStream, EmptyCString(), -1); // create a dummy listener InputTestConsumer* listener; listener = new InputTestConsumer; if (!listener) { NS_ERROR("Failed to create a new stream listener!"); return -1; } NS_ADDREF(listener); channel->AsyncOpen(listener, nsnull); PumpEvents(); } // this scopes the nsCOMPtrs // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM rv = NS_ShutdownXPCOM(nsnull); NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); return 0; }
static void Frame() { g_Profiler2.RecordFrameStart(); PROFILE2("frame"); g_Profiler2.IncrementFrameNumber(); PROFILE2_ATTR("%d", g_Profiler2.GetFrameNumber()); ogl_WarnIfError(); // get elapsed time const double time = timer_Time(); g_frequencyFilter->Update(time); // .. old method - "exact" but contains jumps #if 0 static double last_time; const double time = timer_Time(); const float TimeSinceLastFrame = (float)(time-last_time); last_time = time; ONCE(return); // first call: set last_time and return // .. new method - filtered and more smooth, but errors may accumulate #else const float realTimeSinceLastFrame = 1.0 / g_frequencyFilter->SmoothedFrequency(); #endif ENSURE(realTimeSinceLastFrame > 0.0f); // decide if update/render is necessary bool need_render = !g_app_minimized; bool need_update = true; // If we are not running a multiplayer game, disable updates when the game is // minimized or out of focus and relinquish the CPU a bit, in order to make // debugging easier. if(g_PauseOnFocusLoss && !g_NetClient && !g_app_has_focus) { PROFILE3("non-focus delay"); need_update = false; // don't use SDL_WaitEvent: don't want the main loop to freeze until app focus is restored SDL_Delay(10); } // TODO: throttling: limit update and render frequency to the minimum. // this is mostly relevant for "inactive" state, so that other windows // get enough CPU time, but it's always nice for power+thermal management. // this scans for changed files/directories and reloads them, thus // allowing hotloading (changes are immediately assimilated in-game). ReloadChangedFiles(); ProgressiveLoad(); RendererIncrementalLoad(); PumpEvents(); // if the user quit by closing the window, the GL context will be broken and // may crash when we call Render() on some drivers, so leave this loop // before rendering if (quit) return; // respond to pumped resize events if (g_ResizedW || g_ResizedH) { g_VideoMode.ResizeWindow(g_ResizedW, g_ResizedH); g_ResizedW = g_ResizedH = 0; } if (g_NetClient) g_NetClient->Poll(); ogl_WarnIfError(); g_GUI->TickObjects(); ogl_WarnIfError(); if (g_Game && g_Game->IsGameStarted() && need_update) { g_Game->Update(realTimeSinceLastFrame); g_Game->GetView()->Update(float(realTimeSinceLastFrame)); } // Immediately flush any messages produced by simulation code if (g_NetClient) g_NetClient->Flush(); g_UserReporter.Update(); g_Console->Update(realTimeSinceLastFrame); ogl_WarnIfError(); if(need_render) { Render(); PROFILE3("swap buffers"); #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_GL_SwapWindow(g_VideoMode.GetWindow()); #else SDL_GL_SwapBuffers(); #endif } ogl_WarnIfError(); g_Profiler.Frame(); g_GameRestarted = false; }
/**** Main ****/ int main(int32_t argc, char *argv[]) { nsresult rv; ScopedXPCOM xpcom("UDP ServerSocket"); if (xpcom.failed()) return -1; // Create UDPSocket nsCOMPtr<nsIUDPSocket> server, client; server = do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv); NS_ENSURE_SUCCESS(rv, -1); client = do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv); NS_ENSURE_SUCCESS(rv, -1); // Create UDPServerListener to process UDP packets nsRefPtr<UDPServerListener> serverListener = new UDPServerListener(); // Bind server socket to 127.0.0.1 rv = server->Init(0, true); NS_ENSURE_SUCCESS(rv, -1); int32_t serverPort; server->GetPort(&serverPort); server->AsyncListen(serverListener); // Bind clinet on arbitrary port nsRefPtr<UDPClientListener> clientListener = new UDPClientListener(); client->Init(0, true); client->AsyncListen(clientListener); // Write data to server uint32_t count; const uint32_t data = REQUEST; phase = TEST_OUTPUT_STREAM; rv = client->Send(NS_LITERAL_CSTRING("127.0.0.1"), serverPort, (uint8_t*)&data, sizeof(uint32_t), &count); NS_ENSURE_SUCCESS(rv, -1); REQUIRE_EQUAL(count, sizeof(uint32_t), "Error"); passed("Request written by Send"); // Wait for server PumpEvents(); NS_ENSURE_SUCCESS(serverListener->mResult, -1); // Read response from server NS_ENSURE_SUCCESS(clientListener->mResult, -1); mozilla::net::NetAddr clientAddr; rv = client->GetAddress(&clientAddr); NS_ENSURE_SUCCESS(rv, -1); phase = TEST_SEND_API; rv = server->SendWithAddress(&clientAddr, (uint8_t*)&data, sizeof(uint32_t), &count); NS_ENSURE_SUCCESS(rv, -1); REQUIRE_EQUAL(count, sizeof(uint32_t), "Error"); passed("Request written by SendWithAddress"); // Wait for server PumpEvents(); NS_ENSURE_SUCCESS(serverListener->mResult, -1); // Read response from server NS_ENSURE_SUCCESS(clientListener->mResult, -1); // Close server printf("*** Attempting to close server ...\n"); server->Close(); client->Close(); PumpEvents(); passed("Server closed"); return 0; // failure is a non-zero return }
/**** Main ****/ int main(int32_t argc, char *argv[]) { nsresult rv; ScopedXPCOM xpcom("UDP ServerSocket"); if (xpcom.failed()) return -1; // Create UDPServerSocket nsCOMPtr<nsIUDPServerSocket> server; server = do_GetService("@mozilla.org/network/server-socket-udp;1", &rv); NS_ENSURE_SUCCESS(rv, -1); // Create UDPListener to process UDP packets nsCOMPtr<UDPListener> listener = new UDPListener(); // Init async server server->Init(UDP_PORT, false); server->AsyncListen(listener); // Create UDP socket and streams nsCOMPtr<nsISocketTransportService> sts = do_GetService("@mozilla.org/network/socket-transport-service;1", &rv); NS_ENSURE_SUCCESS(rv, -1); nsCOMPtr<nsISocketTransport> transport; const char *protocol = "udp"; rv = sts->CreateTransport(&protocol, 1, NS_LITERAL_CSTRING("127.0.0.1"), UDP_PORT, nullptr, getter_AddRefs(transport)); NS_ENSURE_SUCCESS(rv, -1); nsCOMPtr<nsIOutputStream> outstream; rv = transport->OpenOutputStream(nsITransport::OPEN_BLOCKING, 0, 0, getter_AddRefs(outstream)); NS_ENSURE_SUCCESS(rv, -1); nsCOMPtr<nsIInputStream> instream; rv = transport->OpenInputStream(nsITransport::OPEN_BLOCKING, 0, 0, getter_AddRefs(instream)); NS_ENSURE_SUCCESS(rv, -1); // Write data to server uint32_t count, read; const uint32_t data = REQUEST; printf("*** Attempting to write request 0x%x to server ...\n", REQUEST); rv = outstream->Write((const char*)&data, sizeof(uint32_t), &count); NS_ENSURE_SUCCESS(rv, -1); REQUIRE_EQUAL(count, sizeof(uint32_t), "Error"); passed("Request written"); // Wait for server PumpEvents(); NS_ENSURE_SUCCESS(listener->mResult, -1); // Read response from server printf("*** Attempting to read response from server ...\n"); rv = instream->Read((char*)&read, sizeof(uint32_t), &count); REQUIRE_EQUAL(count, sizeof(uint32_t), "Did not read enough bytes from input stream"); REQUIRE_EQUAL(read, RESPONSE, "Did not read expected data from stream. Received 0x%x", read); passed("Response from server 0x%x", read); // Close server printf("*** Attempting to close server ...\n"); server->Close(); PumpEvents(); passed("Server closed"); return 0; // failure is a non-zero return }
/**** Main ****/ int main(int32_t argc, char *argv[]) { nsresult rv; ScopedXPCOM xpcom("UDP ServerSocket"); if (xpcom.failed()) return -1; // Create UDPSocket nsCOMPtr<nsIUDPSocket> server, client; server = do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv); NS_ENSURE_SUCCESS(rv, -1); client = do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv); NS_ENSURE_SUCCESS(rv, -1); // Create UDPServerListener to process UDP packets nsRefPtr<UDPServerListener> serverListener = new UDPServerListener(); // Bind server socket to 0.0.0.0 rv = server->Init(0, false); NS_ENSURE_SUCCESS(rv, -1); int32_t serverPort; server->GetPort(&serverPort); server->AsyncListen(serverListener); // Bind clinet on arbitrary port nsRefPtr<UDPClientListener> clientListener = new UDPClientListener(); client->Init(0, false); client->AsyncListen(clientListener); // Write data to server uint32_t count; const uint32_t data = REQUEST; phase = TEST_OUTPUT_STREAM; rv = client->Send(NS_LITERAL_CSTRING("127.0.0.1"), serverPort, (uint8_t*)&data, sizeof(uint32_t), &count); NS_ENSURE_SUCCESS(rv, -1); REQUIRE_EQUAL(count, sizeof(uint32_t), "Error"); passed("Request written by Send"); // Wait for server PumpEvents(); NS_ENSURE_SUCCESS(serverListener->mResult, -1); // Read response from server NS_ENSURE_SUCCESS(clientListener->mResult, -1); mozilla::net::NetAddr clientAddr; rv = client->GetAddress(&clientAddr); NS_ENSURE_SUCCESS(rv, -1); // The client address is 0.0.0.0, but Windows won't receive packets there, so // use 127.0.0.1 explicitly clientAddr.inet.ip = PR_htonl(127 << 24 | 1); phase = TEST_SEND_API; rv = server->SendWithAddress(&clientAddr, (uint8_t*)&data, sizeof(uint32_t), &count); NS_ENSURE_SUCCESS(rv, -1); REQUIRE_EQUAL(count, sizeof(uint32_t), "Error"); passed("Request written by SendWithAddress"); // Wait for server PumpEvents(); NS_ENSURE_SUCCESS(serverListener->mResult, -1); // Read response from server NS_ENSURE_SUCCESS(clientListener->mResult, -1); // Setup timer to detect multicast failure nsCOMPtr<nsITimer> timer = do_CreateInstance("@mozilla.org/timer;1"); if (NS_WARN_IF(!timer)) { return -1; } nsRefPtr<MulticastTimerCallback> timerCb = new MulticastTimerCallback(); // The following multicast tests using multiple sockets require a firewall // exception on Windows XP before they pass. For now, we'll skip them here. // Later versions of Windows don't seem to have this issue. #ifdef XP_WIN OSVERSIONINFO OsVersion; OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); #pragma warning(push) #pragma warning(disable:4996) // 'GetVersionExA': was declared deprecated GetVersionEx(&OsVersion); #pragma warning(pop) if (OsVersion.dwMajorVersion == 5 && OsVersion.dwMinorVersion == 1) { goto close; } #endif // Join multicast group printf("Joining multicast group\n"); phase = TEST_MULTICAST; mozilla::net::NetAddr multicastAddr; multicastAddr.inet.family = AF_INET; multicastAddr.inet.ip = PR_htonl(224 << 24 | 255); multicastAddr.inet.port = PR_htons(serverPort); rv = server->JoinMulticastAddr(multicastAddr, nullptr); if (NS_WARN_IF(NS_FAILED(rv))) { return -1; } // Send multicast ping timerCb->mResult = NS_OK; timer->InitWithCallback(timerCb, MULTICAST_TIMEOUT, nsITimer::TYPE_ONE_SHOT); rv = client->SendWithAddress(&multicastAddr, (uint8_t*)&data, sizeof(uint32_t), &count); if (NS_WARN_IF(NS_FAILED(rv))) { return -1; } REQUIRE_EQUAL(count, sizeof(uint32_t), "Error"); passed("Multicast ping written by SendWithAddress"); // Wait for server to receive successfully PumpEvents(); if (NS_WARN_IF(NS_FAILED(serverListener->mResult))) { return -1; } if (NS_WARN_IF(NS_FAILED(timerCb->mResult))) { return -1; } timer->Cancel(); passed("Server received ping successfully"); // Disable multicast loopback printf("Disable multicast loopback\n"); client->SetMulticastLoopback(false); server->SetMulticastLoopback(false); // Send multicast ping timerCb->mResult = NS_OK; timer->InitWithCallback(timerCb, MULTICAST_TIMEOUT, nsITimer::TYPE_ONE_SHOT); rv = client->SendWithAddress(&multicastAddr, (uint8_t*)&data, sizeof(uint32_t), &count); if (NS_WARN_IF(NS_FAILED(rv))) { return -1; } REQUIRE_EQUAL(count, sizeof(uint32_t), "Error"); passed("Multicast ping written by SendWithAddress"); // Wait for server to fail to receive PumpEvents(); if (NS_WARN_IF(NS_SUCCEEDED(timerCb->mResult))) { return -1; } timer->Cancel(); passed("Server failed to receive ping correctly"); // Reset state client->SetMulticastLoopback(true); server->SetMulticastLoopback(true); // Change multicast interface printf("Changing multicast interface\n"); mozilla::net::NetAddr loopbackAddr; loopbackAddr.inet.family = AF_INET; loopbackAddr.inet.ip = PR_htonl(INADDR_LOOPBACK); client->SetMulticastInterfaceAddr(loopbackAddr); // Send multicast ping timerCb->mResult = NS_OK; timer->InitWithCallback(timerCb, MULTICAST_TIMEOUT, nsITimer::TYPE_ONE_SHOT); rv = client->SendWithAddress(&multicastAddr, (uint8_t*)&data, sizeof(uint32_t), &count); if (NS_WARN_IF(NS_FAILED(rv))) { return -1; } REQUIRE_EQUAL(count, sizeof(uint32_t), "Error"); passed("Multicast ping written by SendWithAddress"); // Wait for server to fail to receive PumpEvents(); if (NS_WARN_IF(NS_SUCCEEDED(timerCb->mResult))) { return -1; } timer->Cancel(); passed("Server failed to receive ping correctly"); // Reset state mozilla::net::NetAddr anyAddr; anyAddr.inet.family = AF_INET; anyAddr.inet.ip = PR_htonl(INADDR_ANY); client->SetMulticastInterfaceAddr(anyAddr); // Leave multicast group printf("Leave multicast group\n"); rv = server->LeaveMulticastAddr(multicastAddr, nullptr); if (NS_WARN_IF(NS_FAILED(rv))) { return -1; } // Send multicast ping timerCb->mResult = NS_OK; timer->InitWithCallback(timerCb, MULTICAST_TIMEOUT, nsITimer::TYPE_ONE_SHOT); rv = client->SendWithAddress(&multicastAddr, (uint8_t*)&data, sizeof(uint32_t), &count); if (NS_WARN_IF(NS_FAILED(rv))) { return -1; } REQUIRE_EQUAL(count, sizeof(uint32_t), "Error"); passed("Multicast ping written by SendWithAddress"); // Wait for server to fail to receive PumpEvents(); if (NS_WARN_IF(NS_SUCCEEDED(timerCb->mResult))) { return -1; } timer->Cancel(); passed("Server failed to receive ping correctly"); goto close; close: // Close server printf("*** Attempting to close server ...\n"); server->Close(); client->Close(); PumpEvents(); passed("Server closed"); return 0; // failure is a non-zero return }
void Run(int max_outgoing) { Start(max_outgoing); while (PumpEvents(true)) ; }
/********************************************************************************************************* * emulation thread - runs the core */ m64p_error main_run(void) { VILimit = (float) GetVILimit(); VILimitMilliseconds = (double) 1000.0/VILimit; /* take the r4300 emulator mode from the config file at this point and cache it in a global variable */ r4300emu = ConfigGetParamInt(g_CoreConfig, "R4300Emulator"); /* set some other core parameters based on the config file values */ savestates_set_autoinc_slot(ConfigGetParamBool(g_CoreConfig, "AutoStateSlotIncrement")); savestates_select_slot(ConfigGetParamInt(g_CoreConfig, "CurrentStateSlot")); no_compiled_jump = ConfigGetParamBool(g_CoreConfig, "NoCompiledJump"); // initialize memory, and do byte-swapping if it's not been done yet if (g_MemHasBeenBSwapped == 0) { init_memory(1); g_MemHasBeenBSwapped = 1; } else { init_memory(0); } // Attach rom to plugins if (!romOpen_gfx()) { free_memory(); return M64ERR_PLUGIN_FAIL; } if (!romOpen_audio()) { romClosed_gfx(); free_memory(); return M64ERR_PLUGIN_FAIL; } if (!romOpen_input()) { romClosed_audio(); romClosed_gfx(); free_memory(); return M64ERR_PLUGIN_FAIL; } #ifdef WITH_LIRC lircStart(); #endif // WITH_LIRC #ifdef DBG if (ConfigGetParamBool(g_CoreConfig, "EnableDebugger")) init_debugger(); #endif PumpEvents(); g_EmulatorRunning = 1; StateChanged(M64CORE_EMU_STATE, M64EMU_RUNNING); /* call r4300 CPU core and run the game */ r4300_reset_hard(); r4300_reset_soft(); r4300_execute(); #ifdef WITH_LIRC lircStop(); #endif // WITH_LIRC #ifdef DBG if (g_DebuggerActive) destroy_debugger(); #endif romClosed_RSP(); romClosed_input(); romClosed_audio(); romClosed_gfx(); free_memory(); // clean up g_EmulatorRunning = 0; StateChanged(M64CORE_EMU_STATE, M64EMU_STOPPED); return M64ERR_SUCCESS; }
static void Frame() { g_Profiler2.RecordFrameStart(); PROFILE2("frame"); g_Profiler2.IncrementFrameNumber(); PROFILE2_ATTR("%d", g_Profiler2.GetFrameNumber()); ogl_WarnIfError(); // get elapsed time const double time = timer_Time(); g_frequencyFilter->Update(time); // .. old method - "exact" but contains jumps #if 0 static double last_time; const double time = timer_Time(); const float TimeSinceLastFrame = (float)(time-last_time); last_time = time; ONCE(return); // first call: set last_time and return // .. new method - filtered and more smooth, but errors may accumulate #else const float TimeSinceLastFrame = 1.0 / g_frequencyFilter->SmoothedFrequency(); #endif ENSURE(TimeSinceLastFrame > 0.0f); // decide if update/render is necessary bool need_render = !g_app_minimized; bool need_update = true; // If we are not running a multiplayer game, disable updates when the game is // minimized or out of focus and relinquish the CPU a bit, in order to make // debugging easier. if( g_PauseOnFocusLoss && !g_NetClient && !g_app_has_focus ) { PROFILE3("non-focus delay"); need_update = false; // don't use SDL_WaitEvent: don't want the main loop to freeze until app focus is restored SDL_Delay(10); } // TODO: throttling: limit update and render frequency to the minimum. // this is mostly relevant for "inactive" state, so that other windows // get enough CPU time, but it's always nice for power+thermal management. bool is_building_archive = ProgressiveBuildArchive(); // this scans for changed files/directories and reloads them, thus // allowing hotloading (changes are immediately assimilated in-game). // must not be done during archive building because it changes the // archive file each iteration, but keeps it locked; reloading // would trigger a warning because the file can't be opened. if(!is_building_archive) ReloadChangedFiles(); ProgressiveLoad(); RendererIncrementalLoad(); PumpEvents(); // if the user quit by closing the window, the GL context will be broken and // may crash when we call Render() on some drivers, so leave this loop // before rendering if (quit) return; // respond to pumped resize events if (g_ResizedW || g_ResizedH) { g_VideoMode.ResizeWindow(g_ResizedW, g_ResizedH); g_ResizedW = g_ResizedH = 0; } if (g_NetClient) g_NetClient->Poll(); ogl_WarnIfError(); g_GUI->TickObjects(); ogl_WarnIfError(); if (g_Game && g_Game->IsGameStarted() && need_update) { g_Game->Update(TimeSinceLastFrame); g_Game->GetView()->Update(float(TimeSinceLastFrame)); CCamera* camera = g_Game->GetView()->GetCamera(); CMatrix3D& orientation = camera->m_Orientation; float* pos = &orientation._data[12]; float* dir = &orientation._data[8]; float* up = &orientation._data[4]; // HACK: otherwise sound effects are L/R flipped. No idea what else // is going wrong, because the listener and camera are supposed to // coincide in position and orientation. float down[3] = { -up[0], -up[1], -up[2] }; { PROFILE3("sound update"); if (snd_update(pos, dir, down) < 0) debug_printf(L"snd_update failed\n"); } } else { PROFILE3("sound update (0)"); if (snd_update(0, 0, 0) < 0) debug_printf(L"snd_update (pos=0 version) failed\n"); } // Immediately flush any messages produced by simulation code if (g_NetClient) g_NetClient->Flush(); g_UserReporter.Update(); g_Console->Update(TimeSinceLastFrame); ogl_WarnIfError(); if(need_render) { Render(); PROFILE3("swap buffers"); #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_GL_SwapWindow(g_VideoMode.GetWindow()); #else SDL_GL_SwapBuffers(); #endif } ogl_WarnIfError(); g_Profiler.Frame(); g_GameRestarted = false; }