Advertisement
Guest User

Untitled

a guest
Apr 20th, 2015
295
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.89 KB | None | 0 0
  1. //std
  2. #include <array>
  3. #include <chrono>
  4. #include <iostream>
  5.  
  6. //mandala
  7. #include "platform_win32.hpp"
  8.  
  9. //glew
  10. #include <GL\glew.h>
  11.  
  12. //glfw
  13. #include <GLFW\glfw3.h>
  14.  
  15. //boost
  16. #include <boost\python.hpp>
  17.     BOOST_PYTHON_MODULE(platform)
  18.     {
  19.         boost::python::class_<mandala::platform_win32_t, boost::noncopyable>("platform", boost::python::no_init)
  20.             .def("get_window_title", &mandala::platform_win32_t::get_window_title);
  21.     }
  22.  
  23. namespace mandala
  24. {
  25.     platform_win32_t platform;
  26.  
  27.     static inline void on_keyboard_key(GLFWwindow* window, int key, int scancode, int action, int mods)
  28.     {
  29.         input_event_t input_event;
  30.         input_event.device_type = input_event_t::device_type_e::keyboard;
  31.         input_event.keyboard.key = static_cast<input_event_t::keyboard_t::key_e>(key);
  32.  
  33.         if ((mods & GLFW_MOD_SHIFT) == GLFW_MOD_SHIFT)
  34.         {
  35.             input_event.keyboard.mod_flags |= input_event_t::mod_flag_shift;
  36.         }
  37.  
  38.         if ((mods & GLFW_MOD_CONTROL) == GLFW_MOD_CONTROL)
  39.         {
  40.             input_event.keyboard.mod_flags |= input_event_t::mod_flag_ctrl;
  41.         }
  42.  
  43.         if ((mods & GLFW_MOD_ALT) == GLFW_MOD_ALT)
  44.         {
  45.             input_event.keyboard.mod_flags |= input_event_t::mod_flag_alt;
  46.         }
  47.  
  48.         if ((mods & GLFW_MOD_SUPER) == GLFW_MOD_SUPER)
  49.         {
  50.             input_event.keyboard.mod_flags |= input_event_t::mod_flag_super;
  51.         }
  52.  
  53.         switch (action)
  54.         {
  55.         case GLFW_RELEASE:
  56.             input_event.keyboard.type = input_event_t::keyboard_t::type_e::key_release;
  57.             break;
  58.         case GLFW_PRESS:
  59.             input_event.keyboard.type = input_event_t::keyboard_t::type_e::key_press;
  60.             break;
  61.         case GLFW_REPEAT:
  62.             input_event.keyboard.type = input_event_t::keyboard_t::type_e::key_repeat;
  63.             break;
  64.         }
  65.  
  66.         platform.input.events.push_back(input_event);
  67.     }
  68.  
  69.     static inline void on_keyboard_character(GLFWwindow* window, unsigned int character)
  70.     {
  71.         input_event_t input_event;
  72.         input_event.device_type = input_event_t::device_type_e::keyboard;
  73.         input_event.keyboard.type = input_event_t::keyboard_t::type_e::character;
  74.         input_event.keyboard.character = character;
  75.  
  76.         platform.input.events.push_back(input_event);
  77.     }
  78.  
  79.     static inline void on_mouse_button(GLFWwindow* window, int button, int action, int mods)
  80.     {
  81.         input_event_t input_event;
  82.         input_event.device_type = input_event_t::device_type_e::touch;
  83.         input_event.touch.button = static_cast<input_event_t::touch_t::button_e>(button);
  84.         input_event.touch.mod_flags = mods;
  85.  
  86.         bool is_press = (action == GLFW_PRESS);
  87.  
  88.         input_event.touch.type = is_press ? input_event_t::touch_t::type_e::press : input_event_t::touch_t::type_e::release;
  89.  
  90.         if (is_press)
  91.         {
  92.             ++platform.input.touch_id;
  93.  
  94.             input_event.touch.id = platform.input.touch_id;
  95.         }
  96.         else
  97.         {
  98.             platform.input.touch_id = 0;    //TODO: replace with something better
  99.         }
  100.  
  101.         input_event.touch.location = platform.get_cursor_location();
  102.  
  103.         platform.input.events.push_back(input_event);
  104.     }
  105.  
  106.     static inline void on_mouse_move(GLFWwindow* window, double x, double y)
  107.     {
  108.         const auto screen_size = platform.get_screen_size();
  109.  
  110.         input_event_t input_event;
  111.         input_event.device_type = input_event_t::device_type_e::touch;
  112.         input_event.touch.type = input_event_t::touch_t::type_e::move;
  113.         input_event.touch.location.x = x;
  114.         input_event.touch.location.y = screen_size.y - y;
  115.         input_event.touch.location_delta.x = x - platform.cursor_location.x;
  116.         input_event.touch.location_delta.y = -(y - platform.cursor_location.y);
  117.  
  118.         input_event.touch.id = platform.input.touch_id;
  119.  
  120.         if (platform.is_cursor_centered)
  121.         {
  122.             const auto screen_size = platform.get_screen_size();
  123.  
  124.             auto cursor_location = glm::floor(static_cast<vec2_f64_t>(screen_size) / 2.0);
  125.  
  126.             platform.set_cursor_location(cursor_location);
  127.         }
  128.  
  129.         platform.cursor_location = platform.get_cursor_location();
  130.  
  131.         platform.input.events.push_back(input_event);
  132.     }
  133.  
  134.     static inline void on_mouse_scroll(GLFWwindow* window, double x, double y)
  135.     {
  136.         const auto screen_size = platform.get_screen_size();
  137.  
  138.         input_event_t input_event;
  139.         input_event.device_type = input_event_t::device_type_e::touch;
  140.         input_event.touch.type = input_event_t::touch_t::type_e::scroll;
  141.         input_event.touch.location = platform.get_cursor_location();
  142.         input_event.touch.location_delta.x = x;
  143.         input_event.touch.location_delta.y = y;
  144.  
  145.         platform.input.events.push_back(input_event);
  146.     }
  147.  
  148.     static inline void on_window_resize(GLFWwindow* window, int width, int height)
  149.     {
  150.         //TODO: a less vebose solution is possible
  151.         auto window_events_itr = std::find_if(platform.window.events.begin(), platform.window.events.end(), [](const window_event_t& window_event)
  152.         {
  153.             return window_event.type == window_event_t::type_e::resize;
  154.         });
  155.  
  156.         if (window_events_itr != platform.window.events.end())
  157.         {
  158.             window_events_itr->rectangle.width = width;
  159.             window_events_itr->rectangle.height = height;
  160.         }
  161.         else
  162.         {
  163.             window_event_t window_event;
  164.             window_event.type = window_event_t::type_e::resize;
  165.             window_event.rectangle.width = width;
  166.             window_event.rectangle.height = height;
  167.  
  168.             platform.window.events.push_back(window_event);
  169.         }
  170.  
  171.         platform.window.rectangle.width = width;
  172.         platform.window.rectangle.height = height;
  173.     }
  174.  
  175.     static inline void on_window_move(GLFWwindow* window, int x, int y)
  176.     {
  177.         //TODO: a less vebose solution is possible
  178.         auto window_events_itr = std::find_if(platform.window.events.begin(), platform.window.events.end(), [](const window_event_t& window_event)
  179.         {
  180.             return window_event.type == window_event_t::type_e::move;
  181.         });
  182.  
  183.         if (window_events_itr != platform.window.events.end())
  184.         {
  185.             window_events_itr->rectangle.x = x;
  186.             window_events_itr->rectangle.y = y;
  187.         }
  188.         else
  189.         {
  190.             window_event_t window_event;
  191.             window_event.type = window_event_t::type_e::move;
  192.             window_event.rectangle.x = x;
  193.             window_event.rectangle.y = y;
  194.  
  195.             platform.window.events.push_back(window_event);
  196.         }
  197.  
  198.         platform.window.rectangle.x = x;
  199.         platform.window.rectangle.y = y;
  200.     }
  201.  
  202.     static inline void on_error(int error_code, const char* message)
  203.     {
  204.         throw std::exception();
  205.     }
  206.  
  207.     void platform_win32_t::app_run_start()
  208.     {
  209.         //glfw
  210.         glfwInit();
  211.  
  212.         window_ptr = glfwCreateWindow(1, 1, "mandala", nullptr, nullptr);
  213.  
  214.         glfwMakeContextCurrent(window_ptr);
  215.  
  216.         glfwSetKeyCallback(window_ptr, on_keyboard_key);
  217.         glfwSetCharCallback(window_ptr, on_keyboard_character);
  218.         glfwSetMouseButtonCallback(window_ptr, on_mouse_button);
  219.         glfwSetCursorPosCallback(window_ptr, on_mouse_move);
  220.         glfwSetScrollCallback(window_ptr, on_mouse_scroll);
  221.         glfwSetWindowSizeCallback(window_ptr, on_window_resize);
  222.         glfwSetWindowPosCallback(window_ptr, on_window_move);
  223.  
  224.         //glew
  225.         auto glew_init_result = glewInit();
  226.  
  227.         if (glew_init_result != GLEW_OK)
  228.         {
  229.             throw std::exception(unsafe_cast<char*>(glewGetErrorString(glew_init_result)));
  230.         }
  231.     }
  232.  
  233.     void platform_win32_t::app_run_end()
  234.     {
  235.         glfwDestroyWindow(window_ptr);
  236.         glfwTerminate();
  237.  
  238.         window_ptr = nullptr;
  239.     }
  240.  
  241.     void platform_win32_t::app_tick_start(float32_t dt)
  242.     {
  243.         glfwPollEvents();
  244.  
  245.         for (size_t gamepad_index = 0; gamepad_index < input.gamepad_states.size(); ++gamepad_index)
  246.         {
  247.             if (!glfwJoystickPresent(static_cast<int>(gamepad_index)))
  248.             {
  249.                 break;
  250.             }
  251.  
  252.             auto& gamepad_state = input.gamepad_states[gamepad_index];
  253.  
  254.             int axis_count = 0;
  255.             auto axes = glfwGetJoystickAxes(static_cast<int>(gamepad_index), &axis_count);
  256.  
  257.             for (auto axis_index = 0; axis_index < axis_count; ++axis_index)
  258.             {
  259.                 if (axes[axis_index] != gamepad_state.axes[axis_index])
  260.                 {
  261.                     input_event_t input_event;
  262.                     input_event.device_type = input_event_t::device_type_e::gamepad;
  263.                     input_event.gamepad.index = gamepad_index;
  264.                     input_event.gamepad.type = input_event_t::gamepad_t::type_e::axis_move;
  265.                     input_event.gamepad.axis_index = axis_index;
  266.                     input_event.gamepad.axis_value = axes[axis_index];
  267.                     input_event.gamepad.axis_value_delta = axes[axis_index] - gamepad_state.axes[axis_index];
  268.  
  269.                     platform.input.events.push_back(input_event);
  270.                 }
  271.  
  272.                 gamepad_state.axes[axis_index] = axes[axis_index];
  273.             }
  274.  
  275.             int button_count = 0;
  276.             auto buttons = glfwGetJoystickButtons(static_cast<int>(gamepad_index), &button_count);
  277.  
  278.             for (auto button_index = 0; button_index < button_count; ++button_index)
  279.             {
  280.                 if (buttons[button_index] != gamepad_state.buttons[button_index])
  281.                 {
  282.                     input_event_t input_event;
  283.                     input_event.device_type = input_event_t::device_type_e::gamepad;
  284.                     input_event.gamepad.index = gamepad_index;
  285.                     input_event.gamepad.type = buttons[button_index] == 0 ? input_event_t::gamepad_t::type_e::release : input_event_t::gamepad_t::type_e::press;
  286.                     input_event.gamepad.button_index = button_index;
  287.  
  288.                     platform.input.events.push_back(input_event);
  289.                 }
  290.  
  291.                 gamepad_state.buttons[button_index] = buttons[button_index];
  292.             }
  293.         }
  294.     }
  295.  
  296.     void platform_win32_t::app_tick_end(float32_t dt)
  297.     {
  298.     }
  299.  
  300.     void platform_win32_t::app_render_start()
  301.     {
  302.     }
  303.  
  304.     void platform_win32_t::app_render_end()
  305.     {
  306.         glfwSwapBuffers(window_ptr);
  307.     }
  308.  
  309.     bool platform_win32_t::should_exit() const
  310.     {
  311.         return glfwWindowShouldClose(window_ptr) != 0;
  312.     }
  313.  
  314.     platform_t::screen_size_type platform_win32_t::get_screen_size() const
  315.     {
  316.         screen_size_type screen_size;
  317.  
  318.         glfwGetWindowSize(window_ptr, &screen_size.x, &screen_size.y);
  319.  
  320.         return screen_size;
  321.     }
  322.    
  323.     void platform_win32_t::set_screen_size(const screen_size_type& screen_size) const
  324.     {
  325.         glfwSetWindowSize(window_ptr, screen_size.x, screen_size.y);
  326.     }
  327.  
  328.     bool platform_win32_t::pop_input_event(input_event_t& input_event)
  329.     {
  330.         if (input.events.empty())
  331.         {
  332.             return false;
  333.         }
  334.  
  335.         input_event = input.events.front();
  336.         input_event.id = input.event_id;
  337.         input_event.is_consumed = false;
  338.  
  339.         input.events.pop_front();
  340.  
  341.         ++input.event_id;
  342.  
  343.         return true;
  344.     }
  345.  
  346.     bool platform_win32_t::pop_window_event(window_event_t& window_event)
  347.     {
  348.         if (window.events.empty())
  349.         {
  350.             return false;
  351.         }
  352.  
  353.         window_event = window.events.front();
  354.        
  355.         window.events.pop_front();
  356.  
  357.         return true;
  358.     }
  359.  
  360.     platform_t::cursor_location_type platform_win32_t::get_cursor_location() const
  361.     {
  362.         cursor_location_type cursor_location;
  363.  
  364.         glfwGetCursorPos(window_ptr, &cursor_location.x, &cursor_location.y);
  365.  
  366.         return cursor_location;
  367.     }
  368.  
  369.     void platform_win32_t::set_cursor_location(const cursor_location_type& cursor_location) const
  370.     {
  371.         glfwSetCursorPos(window_ptr, cursor_location.x, cursor_location.y);
  372.     }
  373.  
  374.     bool platform_win32_t::is_cursor_hidden() const
  375.     {
  376.         return glfwGetInputMode(window_ptr, GLFW_CURSOR) == GLFW_CURSOR_HIDDEN;
  377.     }
  378.  
  379.     void platform_win32_t::set_cursor_hidden(bool is_hidden) const
  380.     {
  381.         glfwSetInputMode(window_ptr, GLFW_CURSOR, is_hidden ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL);
  382.     }
  383.  
  384.     platform_t::window_title_type platform_win32_t::get_window_title() const
  385.     {
  386.         //TODO: implement this
  387.         return std::string();
  388.     }
  389.  
  390.     void platform_win32_t::set_window_title(const window_title_type& window_title) const
  391.     {
  392.         glfwSetWindowTitle(window_ptr, window_title.c_str());
  393.     }
  394.  
  395.     platform_t::window_size_type platform_win32_t::get_window_size() const
  396.     {
  397.         window_size_type window_size;
  398.  
  399.         glfwGetWindowSize(window_ptr, &window_size.x, &window_size.y);
  400.  
  401.         return window_size;
  402.     }
  403.  
  404.     void platform_win32_t::set_window_size(const window_size_type& window_size) const
  405.     {
  406.         glfwSetWindowSize(window_ptr, window_size.x, window_size.y);
  407.     }
  408.  
  409.     platform_t::window_size_type platform_win32_t::get_window_location() const
  410.     {
  411.         vec2_i32_t window_location;
  412.  
  413.         glfwGetWindowPos(window_ptr, &window_location.x, &window_location.y);
  414.  
  415.         return window_location;
  416.     }
  417.  
  418.     void platform_win32_t::set_window_location(const window_size_type& window_location) const
  419.     {
  420.         glfwSetWindowPos(window_ptr, window_location.x, window_location.y);
  421.     }
  422.  
  423.     std::string platform_win32_t::get_clipboard_string() const
  424.     {
  425.         return glfwGetClipboardString(window_ptr);
  426.     }
  427.  
  428.     void platform_win32_t::set_clipboard_string(const std::string& clipboard_string) const
  429.     {
  430.         glfwSetClipboardString(window_ptr, clipboard_string.c_str());
  431.     }
  432. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement