5unsigned int Window::cnt = 0;
6std::map<unsigned int, std::shared_ptr<Gamepad> > Window::gamepad_instance_id_map;
7std::map<unsigned int, std::shared_ptr<Joystick> > Window::joystick_instance_id_map;
9Window::Window(
const std::string& title,
int res_x,
int res_y,
int offset_x,
int offset_y,
unsigned int flags) {
13 mouse_relative =
false;
14 keys = SDL_GetKeyboardState(
nullptr);
17 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
21 window = SDL_CreateWindow(title.c_str(), offset_x, offset_y,
24 SDL_WINDOW_RESIZABLE |
27 std::string error = std::string(
"Error opening window: ") + SDL_GetError();
29 throw std::runtime_error(error);
32 SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &
gl_maj);
33 SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &
gl_min);
34 context = SDL_GL_CreateContext(
window);
41 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,
gl_maj);
42 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,
gl_min);
43 context = SDL_GL_CreateContext(
window);
53 std::string error = std::string(
"Error creating OpenGL context: ") +
56 throw std::runtime_error(error);
59 glGetIntegerv(GL_MAX_PATCH_VERTICES, &
App::sys_info.max_patch_vertices);
60 glGetIntegerv(GL_MAX_TESS_GEN_LEVEL, &
App::sys_info.max_tess_level);
68 SDL_GL_DeleteContext(context);
72 gamepad_instance_id_map.clear();
73 joystick_instance_id_map.clear();
78 Image img(filename.c_str());
87 SDL_SetWindowTitle(
window, title.c_str());
91 SDL_SetWindowResizable(
window, (SDL_bool)on);
95 std::unique_ptr<char[]> buf = std::make_unique<char[]>(4 *
width *
height);
96 glReadPixels(0, 0,
width,
height, GL_RGBA, GL_UNSIGNED_BYTE, buf.get());
102 SDL_SetWindowGrab(
window, (SDL_bool)on);
106 int ret = SDL_GetWindowDisplayIndex(
window);
109 "display index: ") + SDL_GetError());
115 if(SDL_SetWindowDisplayMode(
window, &mode)) {
117 "window display mode: ") + SDL_GetError());
124 if(SDL_SetWindowFullscreen(
window,
static_cast<unsigned int>(mode)) < 0) {
126 "window fullscreen state: ") + SDL_GetError());
134 SDL_SetRelativeMouseMode((SDL_bool)on);
138 SDL_WarpMouseInWindow(
window, x, y);
142 int toggle = SDL_DISABLE;
146 SDL_ShowCursor(toggle);
150 int ret = SDL_ShowCursor(SDL_QUERY);
151 if(ret == SDL_ENABLE)
160 std::shared_ptr<Gamepad> gamepad;
161 std::shared_ptr<Joystick> joystick;
162 std::map<unsigned int, std::shared_ptr<Gamepad> >::iterator gamepad_it;
163 std::map<unsigned int, std::shared_ptr<Joystick> >::iterator joystick_it;
164 std::vector<int>::iterator button;
166 while(SDL_PollEvent(&event)) {
171 case SDL_WINDOWEVENT:
172 switch(event.window.event) {
173 case SDL_WINDOWEVENT_CLOSE:
176 case SDL_WINDOWEVENT_RESIZED:
177 width =
event.window.data1;
178 height =
event.window.data2;
184 if(event.key.repeat == 0) {
185 keys_pressed.push_back(SDL_GetKeyName(event.key.keysym.sym));
191 std::string key_name = SDL_GetKeyName(event.key.keysym.sym);
192 auto it = std::find(keys_pressed.begin(), keys_pressed.end(), key_name);
193 if(it != keys_pressed.end()) {
194 keys_pressed.erase(it);
202 case SDL_MOUSEBUTTONDOWN:
203 case SDL_MOUSEBUTTONUP:
206 (event.button.state == SDL_PRESSED),
207 event.button.clicks);
211 (event.button.state == SDL_PRESSED),
212 event.button.clicks);
214 case SDL_MOUSEMOTION:
222 case SDL_CONTROLLERDEVICEADDED:
223 gamepad = std::make_shared<Gamepad>(event.cdevice.which);
224 gamepad_instance_id_map[gamepad->instance_id] = gamepad;
227 case SDL_CONTROLLERDEVICEREMOVED:
228 gamepad_it = gamepad_instance_id_map.find(event.cdevice.which);
229 if(gamepad_it != gamepad_instance_id_map.end()) {
230 gamepad = gamepad_it->second;
232 gamepad_instance_id_map.erase(gamepad->instance_id);
235 case SDL_CONTROLLERBUTTONDOWN:
236 gamepad_it = gamepad_instance_id_map.find(event.cdevice.which);
237 if(gamepad_it != gamepad_instance_id_map.end()) {
238 gamepad = gamepad_it->second;
239 gamepad->set_button_state(event.cbutton.button,
true);
243 case SDL_CONTROLLERBUTTONUP:
244 gamepad_it = gamepad_instance_id_map.find(event.cdevice.which);
245 if(gamepad_it != gamepad_instance_id_map.end()) {
246 gamepad = gamepad_it->second;
247 gamepad->set_button_state(event.cbutton.button,
false);
251 case SDL_CONTROLLERAXISMOTION:
252 gamepad_it = gamepad_instance_id_map.find(event.cdevice.which);
253 if(gamepad_it != gamepad_instance_id_map.end()) {
254 gamepad = gamepad_it->second;
257 gamepad->get_axis_value(event.caxis.axis));
260 case SDL_JOYDEVICEADDED:
261 if(!SDL_IsGameController(event.jdevice.which)) {
262 joystick = std::make_shared<Joystick>(event.jdevice.which);
263 joystick_instance_id_map[joystick->instance_id] = joystick;
267 case SDL_JOYDEVICEREMOVED:
268 joystick_it = joystick_instance_id_map.find(event.jdevice.which);
269 if(joystick_it != joystick_instance_id_map.end()) {
270 joystick = joystick_it->second;
272 joystick_instance_id_map.erase(joystick->instance_id);
275 case SDL_JOYBUTTONDOWN:
276 joystick_it = joystick_instance_id_map.find(event.jdevice.which);
277 if(joystick_it != joystick_instance_id_map.end()) {
278 joystick = joystick_it->second;
279 joystick->set_button_state(event.jbutton.button,
true);
281 event.jbutton.button,
true);
284 case SDL_JOYBUTTONUP:
285 joystick_it = joystick_instance_id_map.find(event.jdevice.which);
286 if(joystick_it != joystick_instance_id_map.end()) {
287 joystick = joystick_it->second;
288 joystick->set_button_state(event.jbutton.button,
false);
290 event.jbutton.button,
false);
293 case SDL_JOYAXISMOTION:
294 joystick_it = joystick_instance_id_map.find(event.jdevice.which);
295 if(joystick_it != joystick_instance_id_map.end()) {
296 joystick = joystick_it->second;
299 joystick->get_axis_value(event.jaxis.axis));
302 case SDL_JOYHATMOTION:
303 joystick_it = joystick_instance_id_map.find(event.jdevice.which);
304 if(joystick_it != joystick_instance_id_map.end()) {
305 joystick = joystick_it->second;
311 case SDL_JOYBALLMOTION:
312 joystick_it = joystick_instance_id_map.find(event.jdevice.which);
313 if(joystick_it != joystick_instance_id_map.end()) {
314 joystick = joystick_it->second;
324 for(std::string key : keys_pressed) {
328 for(
const auto& device : gamepad_instance_id_map) {
331 for(
unsigned int axis = 0; axis < device.second->num_axes; axis++) {
332 value = device.second->get_axis_value(axis);
335 for(
unsigned int button = 0; button < device.second->buttons_pressed.size(); button++) {
340 for(
const auto& device : joystick_instance_id_map) {
343 for(
unsigned int axis = 0; axis < device.second->num_axes; axis++) {
344 value = device.second->get_axis_value(axis);
347 for(
unsigned int button = 0; button < device.second->buttons_pressed.size(); button++) {
350 for(
unsigned int hat = 0; hat < device.second->num_hats; hat++) {
427 glClearColor(0.0, 0.0, 0.0, 1.0);
428 glClear(GL_COLOR_BUFFER_BIT);
438 frame_time = 1000.0 / fps;
451 time_to_wait = std::max(frame_time - frame_timer.
get_time_ms(), 0.0);
452 if(time_to_wait > 0) {
453 std::this_thread::sleep_for(std::chrono::duration<double, std::milli>(time_to_wait));
457 SDL_GL_SwapWindow(
window);
static std::vector< std::string > error_string
A list of all error strings.
static bool gl_version_manual
True if set_gl_version was called, false otherwise.
static struct SYS_INFO sys_info
System information.
static bool init_glew()
Initializes GLEW.
SDL_Surface * image
The image surface.
void vertical_flip()
Flips the image along its x-axis.
bool load(const std::string &filename)
Loads a new image file.
void start()
Starts the timer.
double get_time_s()
Returns the time in seconds since the timer was started.
double get_time_ms()
Returns the time in milliseconds since the timer was started.
virtual void handle_joystick_added(std::shared_ptr< sgltk::Joystick > joystick)
This function is called by poll_events() to handle the addition of new joysticks. This function shoul...
virtual void handle_gamepad_axis_change(std::shared_ptr< sgltk::Gamepad > gamepad, unsigned int axis, int value)
This function is called by poll_events() for every axis value change. This function should be overrid...
double delta_time
The time it took to draw the last frame.
int get_display_index()
Returns the index of the display that currently contains the window. This index corresponds to the in...
virtual void handle_key_press(const std::string &key, bool pressed)
This function is called by poll_events() once for every key pressed or released. This function should...
void set_relative_mode(bool on)
Activates the relative mouse motion mode In the relative mouse motion mode the cursor is invisible an...
virtual void handle_mouse_motion(int x, int y)
This function is called by poll_events() to handle mouse motion. This function should be overridden.
void set_mouse_position(int x, int y)
Sets the mouse position inside the window.
void poll_events()
Polls all events and calls the handlers. Called by the run function.
virtual void handle_mouse_button(int x, int y, int button, bool down, int clicks)
This function is called by poll_events() to handle mouse button presses. This function should be over...
virtual void handle_mouse_wheel(int x, int y)
This function is called by poll_events() to handle mouse wheel movements. This function should be ove...
virtual void handle_joystick_hat(std::shared_ptr< sgltk::Joystick > joystick, unsigned int hat, unsigned int value)
This function is called by poll_events() every frame for every hat of every joystick....
void set_title(const std::string &title)
Set window title.
bool set_display_mode(const SDL_DisplayMode &mode)
Changes the window display mode when in fullscreen mode.
void stop()
Stops the main loop.
int gl_min
The minor OpenGL version number.
void set_cursor_visibility(bool show)
Sets mouse cursor visibility.
virtual void handle_gamepad_removed(unsigned int gamepad_id)
This function is called by poll_events() to handle the removal of gamepads. This function should be o...
virtual void handle_joystick_hat_change(std::shared_ptr< sgltk::Joystick > joystick, unsigned int hat, unsigned int value)
This function is called by poll_events() for every hat value change. This function should be overridd...
Window(const std::string &title, int res_x, int res_y, int offset_x, int offset_y, unsigned int flags=0)
int height
The height of the window surface.
int width
The width of the window surface.
virtual void handle_exit()
This function is called by run when the window is being closed. This function should be overridden.
virtual void handle_joystick_axis_change(std::shared_ptr< sgltk::Joystick > joystick, unsigned int axis, int value)
This function is called by poll_events() for every axis value change. This function should be overrid...
void run(unsigned int fps=0)
Starts the main loop. This function calls poll_events() and display()
bool fullscreen_mode(sgltk::WINDOW_MODE mode)
Changes the window mode.
virtual void handle_joystick_removed(unsigned int joystick_id)
This function is called by poll_events() to handle the removal of joysticks. This function should be ...
virtual void handle_gamepad_button_press(std::shared_ptr< sgltk::Gamepad > gamepad, int button, bool pressed)
This function is called by poll_events() once for every gamepad button press or release....
virtual void handle_gamepad_axis(std::shared_ptr< sgltk::Gamepad > gamepad, unsigned int axis, int value)
This function is called by poll_events() every frame for every axis of every gamepad....
virtual void handle_joystick_ball_motion(std::shared_ptr< sgltk::Joystick > joystick, unsigned int ball, int xrel, int yrel)
This function is called by poll_events() for every ball that has changed value change....
virtual void handle_gamepad_added(std::shared_ptr< sgltk::Gamepad > gamepad)
This function is called by poll_events() to handle the addition of new gamepads. This function should...
void set_resizable(bool on)
Sets or removes the ability to resize the window.
void take_screenshot(sgltk::Image &image)
Takes a screenshot of the window.
bool get_cursor_visibility()
Returns mouse cursor visibility status.
virtual void handle_gamepad_button(std::shared_ptr< sgltk::Gamepad > gamepad, int button)
This function is called by poll_events() every frame for every gamepad button currently being pressed...
void grab_mouse(bool on)
Sets the window to grab the mouse When activate the mouse can not leave the window boundaries.
virtual void handle_joystick_button_press(std::shared_ptr< sgltk::Joystick > joystick, int button, bool pressed)
This function is called by poll_events() once for every joystick button pressed or released....
int gl_maj
The manjor OpenGL version number.
virtual void handle_joystick_axis(std::shared_ptr< sgltk::Joystick > joystick, unsigned int axis, int value)
This function is called by poll_events() every frame for every axis of every joystick....
virtual void handle_joystick_button(std::shared_ptr< sgltk::Joystick > joystick, int button)
This function is called by poll_events() every frame for every joystick button currently being presse...
virtual void handle_keyboard(const std::string &key)
This function is called by poll_events() every frame for every key currently being pressed....
virtual void handle_resize()
This function is called by run when the window is resized. This function should be overridden.
SDL_Window * window
The window surface.
virtual void display()
This function is called by run() to draw a frame. This function should be overridden.
void set_icon(const std::string &filename)
Sets the window icon.