Beispiel #1
0
  Font * Fonts::load(XML_Element_c &xml_element, const String &/*name*/, const String &/*filename*/) {
    const String filepath = xml_element["filepath"].to_string();
    const float height = xml_element["height"].to_float();

    const float screen_height = float(get_Window().get_height());
    float virtual_screen_height = screen_height;
    XML_Element_c virtual_screen = xml_element["virtual_screen"];
    if(virtual_screen.good()) {
      XML_Element_c vsw = virtual_screen["width"];
      XML_Element_c vsh = virtual_screen["height"];

      if(vsw.good()) {
        const float vsw_ratio = vsw.to_float() / get_Window().get_width();

        if(vsh.good()) {
          virtual_screen_height = vsh.to_float();

          if(vsw_ratio > virtual_screen_height / screen_height)
            virtual_screen_height = vsw_ratio * screen_height;
        }
        else
          virtual_screen_height = vsw_ratio * screen_height;
      }
      else if(vsh.good())
        virtual_screen_height = vsh.to_float();
    }

    return get_Video().create_Font(filepath, height, virtual_screen_height);
  }
void Play_State_Base::render()	{
	Game_Model::get().render();

	int width = get_Window().get_width();
	int height = get_Window().get_height();
//	get_Video().set_2d(pair<Point2f, Point2f>(Point2f(0,0), Point2f(width, height)));
//	get_Fonts()["system_36_800x600"].render_text(controllers[0]->give_stick_status().c_str(), Point2f(0, 0), Color(1, 0.1, 0.85, 0.1 ));
//	if (Game_Model::get().table.get_collided())
//		get_Fonts()["system_36_800x600"].render_text("Collision detected.", Point2f(0, 300), Color(1, 0.1, 0.85, 0.1 ));
}
Beispiel #3
0
 Font_FT::Font_FT(const String &filepath,
                  const bool &bold, const bool &italic,
                  const float &glyph_height,
                  const float &virtual_screen_height)
   : Font(bold, italic, glyph_height,
          (virtual_screen_height < MINIMUM_VIRTUAL_SCREEN_HEIGHT ||
          virtual_screen_height > MAXIMUM_VIRTUAL_SCREEN_HEIGHT) ?
          float(get_Window().get_height()) : virtual_screen_height,
          filepath),
   m_font_height(glyph_height),
   m_vratio(get_Window().get_height() / get_virtual_screen_height())
 {
   init(filepath);
 }
void Play_State_Base::on_pop()	{
	get_Window().mouse_hide(false);
	get_Window().mouse_grab(false);
	get_Video().set_clear_Color(m_prev_clear_color);
	get_Game().joy_mouse.enabled = true;
	Game_Model::get().clean();

	for (int i = 0 ; i < player_info->size() ; i++)
		delete player_info->at(i);
	delete player_info;

	for(int i = 0; i < controllers.size() ; i++)	{
		delete controllers[i];
	}
}
  Console_State::Console_State()
    : m_virtual_screen(Point2f(0.0f, 0.0f), Point2f(float(get_Window().get_width() * 600.0f / get_Window().get_height()), 600.0f)),
    m_projector(m_virtual_screen),
    m_bg(Vertex2f_Color(Point2f(0.0f, 0.0f), get_Colors()["console_border"]),
         Vertex2f_Color(Point2f(0.0f, 54.0f + 7.0f * get_Fonts()["system_36_x600"].get_text_height()), get_Colors()["console_border"]),
         Vertex2f_Color(Point2f(m_virtual_screen.second.x, 54.0f + 7.0f * get_Fonts()["system_36_x600"].get_text_height()), get_Colors()["console_border"]),
         Vertex2f_Color(Point2f(m_virtual_screen.second.x, 0.0f), get_Colors()["console_border"])),
    m_log(Point2f(18.0f, 18.0f),
          Point2f(m_virtual_screen.second.x - 18.0f,
                  18.0f + 6.0f * get_Fonts()["system_36_x600"].get_text_height()),
          "system_36_x600",
          "",
          get_Colors()["console_foreground"],
          false),
    m_prompt(Point2f(18.0f, 36.0f + 6.0f * get_Fonts()["system_36_x600"].get_text_height()),
             Point2f(m_virtual_screen.second.x - 18.0f,
                     36.0f + 7.0f * get_Fonts()["system_36_x600"].get_text_height()),
             "system_36_x600",
             "",
             get_Colors()["console_foreground"],
             true),
    m_log_dirty(false),
    m_child(0)
  {
    m_functions["args"] = new Console_Function;

    m_log.give_BG_Renderer(new Widget_Renderer_Color(get_Colors()["console_background"]));
    m_prompt.give_BG_Renderer(new Widget_Renderer_Color(get_Colors()["console_background"]));
  }
void Play_State_Base::on_push()	{
		get_Window().mouse_hide(true);
		get_Window().mouse_grab(true);
		get_Video().set_clear_Color(Color(0,.1,.1,.1));
		get_Game().joy_mouse.enabled = false;

		Game_Model::get().change_level(create_level(level.std_str()));
		Game_Model::get().start_up(*player_info);

		if(!isLocal)
			Game_Model::get().initialize_peer(isServer, host_addr);
				
		for(int i = 0; i < Game_Model::get().num_players_here() ; i++)	{
			controllers.push_back(new Controls(false, i));
			if(player_info->at(i)->controls_ == 1)
				controllers[i]->set_inverted(true);
			controllers[i]->set_input_sensitivity(player_info->at(i)->sensitivities_);
		}
}
  void Widget_Gamestate::on_pop() {
    get_Video().set_clear_Color(m_clear_color);

#ifndef ANDROID
    Window &wr = get_Window();

    if(m_hide_cursor)
      wr.mouse_hide(true);

    if(m_grab_input)
      wr.mouse_grab(true);
#endif
  }
Beispiel #8
0
  bool Video_DX9::begin_render() {
    assert(!m_render_target && !m_render_to_surface);

    HRESULT result = m_d3d_device->Present(0, 0, 0, 0);

    if(result == S_OK) {
      D3DVIEWPORT9 vp = {0, 0, DWORD(get_Window().get_width()), DWORD(get_Window().get_height()), 0, 1};
      m_d3d_device->SetViewport(&vp);
      m_d3d_device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(get_clear_Color().r_ub(), get_clear_Color().g_ub(), get_clear_Color().b_ub()), 1.0f, 0);
      m_d3d_device->BeginScene();

      return true;
    }
    else if(result == D3DERR_DEVICELOST) {
      g_video_dx9_reset = true;
      return false;
    }
    else if(result == D3DERR_DEVICEREMOVED) {
      throw Video_Device_Failure();
    }

    return false;
  }
  void Widget_Gamestate::on_push() {
#ifndef ANDROID
    Window &wr = get_Window();

    m_hide_cursor = wr.is_mouse_hidden();
    if(m_hide_cursor)
      wr.mouse_hide(false);

    m_grab_input = wr.is_mouse_grabbed();
    if(m_grab_input)
      wr.mouse_grab(false);
#endif

    m_clear_color = get_Video().get_clear_Color();
  }
Beispiel #10
0
  void Console_State::perform_logic() {
    m_virtual_screen = std::make_pair(Point2f(0.0f, 0.0f), Point2f(float(get_Window().get_width() * 600.0f / get_Window().get_height()), 600.0f));
    m_projector = Projector2D(m_virtual_screen);

    if(m_bg.c.position.x != m_virtual_screen.second.x) {
      m_bg.c.position.x = m_virtual_screen.second.x;
      m_bg.d.position.x = m_virtual_screen.second.x;

      const float right = m_virtual_screen.second.x - 18.0f;
      m_log.set_lower_right(Point2f(right, m_log.get_lower_right().y));
      m_prompt.set_lower_right(Point2f(right, m_prompt.get_lower_right().y));
    }

    m_child->perform_logic();
  }
Beispiel #11
0
void
x_gui_rep::emulate_leave_enter (widget old_widget, widget new_widget) {
  Window root, child;
  SI root_x, root_y, x, y;
  unsigned int mask;

  XQueryPointer (dpy, get_Window (old_widget),
		 &root, &child, &root_x, &root_y, &x, &y, &mask);
  set_button_state (mask);
  x= (x * PIXEL);
  y= ((-y) * PIXEL);
  // cout << "\nLeave " << old_widget << "\n";
  send_mouse (old_widget, "leave", x, y, state, 0);
  // cout << "Leave OK\n";

  XQueryPointer (dpy, get_Window (new_widget),
		 &root, &child, &root_x, &root_y, &x, &y, &mask);
  set_button_state (mask);
  x= (x * PIXEL);
  y= ((-y) * PIXEL);
  // cout << "Enter " << new_widget << "\n";
  send_mouse (new_widget, "enter", x, y, state, 0);
  // cout << "Enter OK\n\n";
}
Beispiel #12
0
void
x_gui_rep::obtain_mouse_grab (widget wid) {
  Window win= get_Window (wid);
  if ((!is_nil (grab_ptr)) && (wid==grab_ptr->item)) return;
  widget old_widget; if (!is_nil (grab_ptr)) old_widget= grab_ptr->item;
  grab_ptr= list<widget> (wid, grab_ptr);
  widget new_widget= grab_ptr->item;
  notify_mouse_grab (new_widget, true);
  XGrabPointer (dpy, win, false,
		PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
		GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
  // cout << "\n---> In grab " << pritty ((tree) wid) << "\n\n";
  if (!is_nil (old_widget)) {
    notify_mouse_grab (old_widget, false);
    emulate_leave_enter (old_widget, new_widget);
  }
}
Beispiel #13
0
  Video::Video()
    :
    m_color(1.0f, 1.0f, 1.0f, 1.0f),
    m_preview(Matrix4f::Translate(Vector3f(-0.5f, -0.5f, 0.0f)) *
      Matrix4f::Scale(Vector3f(0.5f, -0.5f, -1.0f)) *
      Matrix4f::Translate(Vector3f(1.0f, -1.0f, 0.0f))),
    m_alpha_test(false),
    m_alpha_function(Video::ZENI_ALWAYS),
    m_alpha_value(0.0f),
    m_3d(false)
  {
    Window::remove_post_reinit(&g_reinit);

    Window &wr = get_Window();

    wr.lend_pre_uninit(&g_uninit);
    wr.lend_post_reinit(&g_reinit);
  }
Beispiel #14
0
  void Video::change_resolution(const Point2i &resolution) {
    Window &wr = get_Window();

    if(wr.get_width() == resolution.x && wr.get_height() == resolution.y)
      return;

    destroy();

    try {
      preinit_from_file(get_File_Ops().get_appdata_path() + "config/zenilib.xml");
    }
    catch(XML_Load_Failure &) {
      preinit_from_file("config/zenilib.xml");
    }

#ifndef ANDROID
    wr.alert_window_resized(resolution);
#endif

    get();
  }
Beispiel #15
0
 void Console_State::on_mouse_motion(const SDL_MouseMotionEvent &event) {
   m_prompt.on_event(event, m_virtual_screen);
   m_handled_event = (float(event.y) / get_Window().get_height()) < (m_bg.c.position.y / 600.0f);
 }
Beispiel #16
0
 void Crate_State::on_push() {
   get_Window().set_mouse_state(Window::MOUSE_RELATIVE);
 }
Beispiel #17
0
  Window * Window::create() {
    Window * window = 0;

#ifndef ANDROID
    File_Ops &fo = get_File_Ops();

    const String appdata_path = fo.get_appdata_path();

    const String user_normal = appdata_path + "config/zenilib.xml";
    const String user_backup = user_normal + ".bak";
    const String local_normal = "config/zenilib.xml";
    const String local_backup = local_normal + ".bak";

    static bool last_resort_taken = false;
#endif

#ifndef ANDROID
    try {
      switch(Video::get_video_mode()) {
      case Video::ZENI_VIDEO_ANY:
#ifndef DISABLE_GL_SHADER
      case Video::ZENI_VIDEO_GL_SHADER:
        Window::set_opengl_flag(true);
        break;
#endif
#ifndef DISABLE_DX9
      case Video::ZENI_VIDEO_DX9:
        Window::set_opengl_flag(false);
        break;
#endif
#ifndef DISABLE_GL_FIXED
      case Video::ZENI_VIDEO_GL_FIXED:
        Window::set_opengl_flag(true);
        break;
#endif
      default:
        throw Window_Init_Failure();
      }
#endif

      window = new Window;
#ifndef ANDROID
    }
    catch(Window_Init_Failure &) {
      if(fo.copy_file(user_backup, user_normal) && fo.delete_file(user_backup)) {
        std::cerr << '\'' << user_normal << "' backup restored due to initialization failure.\n";
        Video::preinit_from_file(user_normal);
        get_Window();
      }
      else if(fo.copy_file(local_backup, local_normal) && fo.delete_file(local_backup)) {
        std::cerr << '\'' << local_normal << "' backup restored due to initialization failure.\n";
        Video::preinit_from_file(local_normal);
        get_Window();
      }
      else if(!last_resort_taken) {
        Window::set_failsafe_defaults();

        last_resort_taken = true;

        get_Window();
      }
      else
        throw;
    }

    last_resort_taken = false;
#endif

    return window;
  }
  void Widget_Gamestate::perform_logic() {
    m_viewport = get_Video().calculate_viewport(m_virtual_window, std::make_pair(Point2i(), get_Window().get_size()), m_fix_aspect_ratio);
    m_projector = Projector2D(m_virtual_window, m_viewport);

    m_widgets.perform_logic();
  }
void Play_State_Base::on_uncover()	{
	get_Window().mouse_hide(true);
	get_Window().mouse_grab(true);
	get_Game().joy_mouse.enabled = false;
}
Beispiel #20
0
 void Level_1::on_push() {
   get_Window().set_mouse_state(Window::MOUSE_RELATIVE);
 }
Beispiel #21
0
  void Video_DX9::init() {
    SDL_SysWMinfo wmInfo;
    SDL_VERSION(&wmInfo.version);
#if SDL_VERSION_ATLEAST(1,3,0)
    SDL_GetWindowWMInfo(get_Window().get_window(), &wmInfo);
    HWND hWnd = wmInfo.win.window;
#else
    SDL_GetWMInfo(&wmInfo);
    HWND hWnd = wmInfo.window;
#endif

    std::cout << "Initializing DirectX 9" << std::endl;

    try {
      m_d3d_capabilities = new D3DCAPS9;
      m_d3d_parameters = new D3DPRESENT_PARAMETERS;
    }
    catch (...) {
      throw Video_Init_Failure();
    }

    m_d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_d3d_capabilities);

    m_dpi = GetDeviceCaps(GetDC(hWnd), LOGPIXELSY);

    ZeroMemory(m_d3d_parameters, sizeof(m_d3d_parameters));

    m_d3d_parameters->hDeviceWindow = hWnd;
    
    m_d3d_parameters->Windowed = true;
    m_d3d_parameters->FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;

    m_d3d_parameters->BackBufferCount = 1;
    m_d3d_parameters->BackBufferWidth = UINT(get_Window().get_width());
    m_d3d_parameters->BackBufferHeight = UINT(get_Window().get_height());
    m_d3d_parameters->BackBufferFormat = D3DFMT_A8R8G8B8;
    m_d3d_parameters->SwapEffect = D3DSWAPEFFECT_DISCARD;
    m_d3d_parameters->PresentationInterval = get_vertical_sync() ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
    m_d3d_parameters->Flags = 0; //D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;

    m_d3d_parameters->EnableAutoDepthStencil = true;
    m_d3d_parameters->AutoDepthStencilFormat = D3DFMT_D16;

    if(get_multisampling() > 1)
      switch(get_multisampling()) {
      case 2: m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_2_SAMPLES; break;
      case 3: m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_3_SAMPLES; break;
      case 4: m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_4_SAMPLES; break;
      case 5: m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_5_SAMPLES; break;
      case 6: m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_6_SAMPLES; break;
      case 7: m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_7_SAMPLES; break;
      case 8: m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_8_SAMPLES; break;
      case 9: m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_9_SAMPLES; break;
      case 10: m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_10_SAMPLES; break;
      case 11: m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_11_SAMPLES; break;
      case 12: m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_12_SAMPLES; break;
      case 13: m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_13_SAMPLES; break;
      case 14: m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_14_SAMPLES; break;
      case 15: m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_15_SAMPLES; break;
      case 16:
      default: m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_16_SAMPLES; break;
      }
    else if(get_multisampling() < 0)
      m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_16_SAMPLES;
    else
      m_d3d_parameters->MultiSampleType = D3DMULTISAMPLE_NONE;
    m_d3d_parameters->MultiSampleQuality = 0;

    // Initialize the D3D device
    if(!init_device())
      throw Video_Init_Failure();

    // Initialize the rendering context
    init_context();
  }
Beispiel #22
0
 inline const Point2i & Video_DX9::get_render_target_size() const {
   if(m_render_target)
     return m_render_target->get_size();
   else
     return get_Window().get_size();
 }
Beispiel #23
0
  void Game::run() {
#ifdef TEST_NASTY_CONDITIONS
    Random random;
    const float time_scale = NASTY_MIN_RATE + (NASTY_MAX_RATE - NASTY_MIN_RATE) * random.frand_lte();
    Time::Second_Type time_used = Time::Second_Type();
    Time start_time;
#endif

    Sound_Source_Pool &sspr = get_Sound_Source_Pool();
    Time time_processed;

    for(;;) {
      const Time time_passed;
      float time_step = time_passed.get_seconds_since(time_processed);
      time_processed = time_passed;

#ifdef ENABLE_XINPUT
      get_Joysticks().poll();
#endif

      if(joy_mouse.enabled && (joy_mouse.velocity.x != 0 || joy_mouse.velocity.y != 0)) {
        Point2f adjusted_vel(joy_mouse.velocity.x + 0.5f, joy_mouse.velocity.y + 0.5f);
        if(adjusted_vel.x < 0.0f)
          adjusted_vel.x = std::min(0.0f, adjusted_vel.x + joy_mouse.noise_zone.x);
        else
          adjusted_vel.x = std::max(0.0f, adjusted_vel.x - joy_mouse.noise_zone.x);
        if(adjusted_vel.y < 0.0f)
          adjusted_vel.y = std::min(0.0f, adjusted_vel.y + joy_mouse.noise_zone.y);
        else
          adjusted_vel.y = std::max(0.0f, adjusted_vel.y - joy_mouse.noise_zone.y);
        adjusted_vel.x /= 32767.5f - joy_mouse.noise_zone.x;
        adjusted_vel.y /= 32767.5f - joy_mouse.noise_zone.y;

        int xrel = int(adjusted_vel.x * joy_mouse.pixels_per_second.x * time_step);
        int yrel = int(adjusted_vel.y * joy_mouse.pixels_per_second.y * time_step);

        if(xrel || yrel) {
          int x, y;
          SDL_GetMouseState(&x, &y);

          x += xrel;
          y += yrel;
          if(x < 0)
            x = 0;
          else if(x >= get_Window().get_width())
            x = get_Window().get_width() - 1;
          if(y < 0)
            y = 0;
          else if(y >= get_Window().get_width())
            y = get_Window().get_height() - 1;

          SDL_WarpMouse(Uint16(x), Uint16(y));
        }
      }

      for(SDL_Event event; SDL_PollEvent(&event);) {
        if(event.type == SDL_KEYDOWN ||
           event.type == SDL_KEYUP)
        {
          const SDL_keysym &s = event.key.keysym;
          const bool alt = get_key_state(SDLK_LALT) || get_key_state(SDLK_RALT);
          const bool ctrl = get_key_state(SDLK_LCTRL) || get_key_state(SDLK_RCTRL);
          const bool shift = get_key_state(SDLK_LSHIFT) || get_key_state(SDLK_RSHIFT);
          const bool gui = 
#if SDL_VERSION_ATLEAST(1,3,0)
                           get_key_state(SDLK_LGUI) || get_key_state(SDLK_RGUI);
#else
                           get_key_state(SDLK_LMETA) || get_key_state(SDLK_RMETA) || get_key_state(SDLK_LSUPER) || get_key_state(SDLK_RSUPER);
#endif

#ifndef NDEBUG
          if(s.sym == SDLK_BACKQUOTE && alt && !ctrl && !gui && !shift) {
            if(event.type == SDL_KEYDOWN) {
              if(m_console_active)
                deactivate_console();
              else
                activate_console();
            }

            continue;
          }
#endif

          on_event(event);

          if(event.type == SDL_KEYDOWN && (
#if defined(_MACOSX)
              (!alt && !ctrl &&  gui && !shift && s.sym == SDLK_q) ||
#endif
              (!alt &&  ctrl && !gui && !shift && s.sym == SDLK_q) ||
              ( alt && !ctrl && !gui && !shift && s.sym == SDLK_F4)))
          {
            throw Quit_Event();
          }
        }
#if SDL_VERSION_ATLEAST(1,3,0)
        else if(event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE) {
          on_event(event);

          if(event.window.windowID == SDL_GetWindowID(get_Window().get_window())) {
            get_Window().alert_window_destroyed();
            throw Quit_Event();
          }
        }
#endif
        else if(event.type == SDL_JOYAXISMOTION) {
          if(joy_mouse.enabled && (joy_mouse.joy_axes.x == event.jaxis.axis || joy_mouse.joy_axes.y == event.jaxis.axis)) {
            if(joy_mouse.joy_axes.x == event.jaxis.axis)
              joy_mouse.velocity.x = event.jaxis.value;
            else
              joy_mouse.velocity.y = event.jaxis.value;
          }
          else
            on_event(event);
        }
        else if(event.type == SDL_JOYBUTTONDOWN || event.type == SDL_JOYBUTTONUP) {
#ifdef _MACOSX
          if(event.jbutton.which < 4 && event.jbutton.button < 4) {
            static bool values[4][4] = {{false, false, false, false},
                                        {false, false, false, false},
                                        {false, false, false, false},
                                        {false, false, false, false}};
            values[event.jbutton.which][event.jbutton.button] = event.jbutton.state == SDL_PRESSED;

            SDL_Event e;

            e.type = Uint8(SDL_JOYHATMOTION);
            e.jhat.which = event.jbutton.which;
            e.jhat.hat = 0;

            if(values[event.jbutton.which][0]) {
              if(values[event.jbutton.which][2])
                e.jhat.value = SDL_HAT_LEFTUP;
              else if(values[event.jbutton.which][3])
                e.jhat.value = SDL_HAT_RIGHTUP;
              else
                e.jhat.value = SDL_HAT_UP;
            }
            else if(values[event.jbutton.which][1]) {
              if(values[event.jbutton.which][2])
                e.jhat.value = SDL_HAT_LEFTDOWN;
              else if(values[event.jbutton.which][3])
                e.jhat.value = SDL_HAT_RIGHTDOWN;
              else
                e.jhat.value = SDL_HAT_DOWN;
            }
            else {
              if(values[event.jbutton.which][2])
                e.jhat.value = SDL_HAT_LEFT;
              else if(values[event.jbutton.which][3])
                e.jhat.value = SDL_HAT_RIGHT;
              else
                e.jhat.value = SDL_HAT_CENTERED;
            }

            SDL_PushEvent(&e);
          }
          else
#endif

          if(joy_mouse.enabled && joy_mouse.left_click == event.jbutton.button) {
            SDL_Event e;

            e.type = Uint8(event.type == SDL_JOYBUTTONDOWN ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP);
            e.button.which = Uint8(event.jbutton.which + 1);
            e.button.state = event.jbutton.state;
            e.button.button = SDL_BUTTON_LEFT;

            int x, y;
            SDL_GetMouseState(&x, &y);
            e.button.x = Uint16(x);
            e.button.y = Uint16(y);

            on_event(e);
          }
          else if(joy_mouse.enabled && joy_mouse.escape == event.jbutton.button) {
            SDL_Event e;

            e.type = Uint8(event.type == SDL_JOYBUTTONDOWN ? SDL_KEYDOWN : SDL_KEYUP);
            e.key.which = Uint8(event.jbutton.which + 1);
            e.key.state = event.jbutton.state;
            e.key.keysym.mod = SDL_GetModState();
            e.key.keysym.scancode = 0;
            e.key.keysym.sym = SDLK_ESCAPE;
            e.key.keysym.unicode = 0;

            on_event(e);
          }
          else
            on_event(event);
        }
        else if(event.type == SDL_JOYHATMOTION) {
          if(joy_mouse.enabled && joy_mouse.scroll_hat == event.jhat.hat && (event.jhat.value == SDL_HAT_DOWN || event.jhat.value == SDL_HAT_UP)) {
            SDL_Event e;

            e.type = SDL_MOUSEBUTTONDOWN;
            e.button.which = Uint8(event.jhat.which + 1);
            e.button.state = SDL_PRESSED;
            e.button.button = Uint8(event.jhat.value == SDL_HAT_DOWN ? SDL_BUTTON_WHEELDOWN : SDL_BUTTON_WHEELUP);

            int x, y;
            SDL_GetMouseState(&x, &y);
            e.button.x = Uint16(x);
            e.button.y = Uint16(y);

            on_event(e);

            e.type = SDL_MOUSEBUTTONUP;
            e.button.state = SDL_RELEASED;

            on_event(e);
          }
          else
            on_event(event);
        }
        else {
          on_event(event);

          if(event.type == SDL_QUIT)
            throw Quit_Event();
        }
      }

#ifdef TEST_NASTY_CONDITIONS
      {
        const Time current_time;
        const Time::Second_Type time_passed = time_scale * current_time.get_seconds_since(start_time);
        size_t step_count = 0u;
        while(time_used + (1 / 60.0f) < time_passed) {
          time_used += (1 / 60.0f);
          perform_logic();
          if(++step_count == NASTY_RATE_CUTOFF)
            time_used = time_passed;
        }
        if(!random.rand_lt(NASTY_ZERO_STEP_FREQUENCY))
          perform_logic();
      }
#else
      perform_logic();
#endif

      sspr.update();

      if(Window::is_enabled()) {
        Video &vr = get_Video();

        if(vr.begin_prerender()) {
          prerender();

          if(vr.begin_render()) {
            try {
              render();
            }
            catch(...) {
              vr.end_render();
              throw;
            }

            vr.end_render();
          }
        }
      }
    }
  }