Ejemplo n.º 1
0
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;
}
Ejemplo n.º 3
0
/**
 * 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;
}
Ejemplo n.º 4
0
/**
 * 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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
/**** 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
}
Ejemplo n.º 10
0
/**** 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
}
Ejemplo n.º 11
0
 void Run(int max_outgoing)
 {
     Start(max_outgoing);
     while (PumpEvents(true))
         ;
 }
Ejemplo n.º 12
0
/*********************************************************************************************************
* 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;
}
Ejemplo n.º 13
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 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;
}