Example #1
0
CEN64_THREAD_RETURN_TYPE run_vr4300_thread(void *opaque) {
  struct cen64_device *device = (struct cen64_device *) opaque;

  while (1) {
    unsigned i, j;

    for (i = 0; i < 6250 / 10; i++) {
      for (j = 0; j < 10; j++)
        ai_cycle(&device->ai);

      for (j = 0; j < 15; j++)
        vr4300_cycle(&device->vr4300);
    }

    // Sync up with the RCP thread.
    cen64_mutex_lock(&device->sync_mutex);

    if (!device->other_thread_is_waiting) {
      device->other_thread_is_waiting = true;
      cen64_cv_wait(&device->sync_cv, &device->sync_mutex);
    }

    else {
      device->other_thread_is_waiting = false;
      cen64_mutex_unlock(&device->sync_mutex);
      cen64_cv_signal(&device->sync_cv);
    }
  }

  return CEN64_THREAD_RETURN_VAL;
}
Example #2
0
CEN64_THREAD_RETURN_TYPE run_rcp_thread(void *opaque) {
  struct cen64_device *device = (struct cen64_device *) opaque;

  if (setjmp(device->bus.unwind_data))
    return CEN64_THREAD_RETURN_VAL;

  while (1) {
    unsigned i;

    for (i = 0; i < 6250; i++) {
      rsp_cycle(&device->rsp);
      vi_cycle(&device->vi);
    }

    // Sync up with the VR4300 thread.
    cen64_mutex_lock(&device->sync_mutex);

    if (!device->other_thread_is_waiting) {
      device->other_thread_is_waiting = true;
      cen64_cv_wait(&device->sync_cv, &device->sync_mutex);
    }

    else {
      device->other_thread_is_waiting = false;
      cen64_mutex_unlock(&device->sync_mutex);
      cen64_cv_signal(&device->sync_cv);
    }
  }

  return CEN64_THREAD_RETURN_VAL;
}
Example #3
0
// Handles events that come from Windows.
bool cen64_gl_window_pump_events(struct vi_controller *vi,
  cen64_time *last_update_time, unsigned *frame_count) {
  struct bus_controller *bus;
  bool exit_requested = false;
  MSG msg;

  memcpy(&bus, vi, sizeof(bus));

  while (1) {
    GetMessage(&msg, NULL, 0, 0);

    if (msg.message == WM_QUIT) {
      cen64_mutex_lock(&vi->window->event_mutex);
      vi->window->exit_requested = exit_requested = true;
      cen64_mutex_unlock(&vi->window->event_mutex);
      break;
    }

    else if (msg.message == WM_KEYDOWN) {
      cen64_mutex_lock(&vi->window->event_mutex);
      keyboard_press_callback(bus, msg.wParam);
      cen64_mutex_unlock(&vi->window->event_mutex);
    }

    else if (msg.message == WM_KEYUP) {
      cen64_mutex_lock(&vi->window->event_mutex);
      keyboard_release_callback(bus, msg.wParam);
      cen64_mutex_unlock(&vi->window->event_mutex);
    }

    else if (msg.message == WM_USER) {
      cen64_gl_window window = vi->window;

      cen64_mutex_lock(&window->render_mutex);

      gl_window_render_frame(vi, window->frame_buffer,
        window->frame_hres, window->frame_vres,
        window->frame_hskip, window->frame_type);

      cen64_mutex_unlock(&window->render_mutex);

      // Update the window title every 60 VIs
      // to display the current VI/s rate.
      if (++(*frame_count) == 60) {
        char title[128];
        cen64_time current_time;
        float ns;

        // Compute time spent rendering last 60 frames, reset timer/counter.
        get_time(&current_time);
        ns = compute_time_difference(&current_time, last_update_time);
        *last_update_time = current_time;
        *frame_count = 0;

        sprintf(title,
          "CEN64 ["CEN64_COMPILER" - "CEN64_ARCH_DIR"/"CEN64_ARCH_SUPPORT"]"
          " - %.1f VI/s", (60 / (ns / NS_PER_SEC)));

        cen64_gl_window_set_title(window, title);
      }
    }

    else {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }

  return exit_requested;
}