| 45 return; |
45 return; |
| 46 } |
46 } |
| 47 |
47 |
| 48 SDL_WindowFlags flags = SDL_WINDOW_OPENGL; |
48 SDL_WindowFlags flags = SDL_WINDOW_OPENGL; |
| 49 flags |= settings.fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE; |
49 flags |= settings.fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE; |
| 50 window->window = SDL_CreateWindow("Ascension",800, 600, flags); |
50 window->sdl = SDL_CreateWindow("Ascension",800, 600, flags); |
| 51 if (window->window == NULL) { |
51 if (window->sdl == NULL) { |
| 52 asc_error("Creating Window failed: %s", SDL_GetError()); |
52 asc_error("Creating Window failed: %s", SDL_GetError()); |
| 53 return; |
53 return; |
| 54 } |
54 } |
| 55 |
55 |
| 56 window->id = SDL_GetWindowID(window->window); |
56 window->id = SDL_GetWindowID(window->sdl); |
| 57 { |
57 { |
| 58 Sint32 w, h; |
58 int x,y, w, h; |
| 59 SDL_GetWindowSize(window->window, &w, &h); |
59 SDL_GetWindowPosition(window->sdl, &x, &y); |
| 60 window->dimensions = ASC_VEC2U(w, h); |
60 SDL_GetWindowSize(window->sdl, &w, &h); |
| |
61 window->rect = ASC_RECT(x, y, w, h); |
| 61 } |
62 } |
| 62 window->resized = true; // count initial sizing as resize |
63 window->resized = true; // count initial sizing as resize |
| 63 |
64 |
| 64 // default UI scale |
65 // default UI scale |
| 65 window->ui_scale = 1.0f; |
66 window->ui_scale = 1.0f; |
| 66 |
67 |
| 67 if (asc_gl_context_initialize(&window->glctx, window->window, &settings)) { |
68 if (asc_gl_context_initialize(&window->glctx, window->sdl, &settings)) { |
| 68 char ui_scene_name[16]; |
69 char ui_scene_name[16]; |
| 69 snprintf(ui_scene_name, sizeof(ui_scene_name), "Window %u UI", index); |
70 snprintf(ui_scene_name, sizeof(ui_scene_name), "Window %u UI", index); |
| 70 asc_camera_init(&window->ui_camera, .type = ASC_CAMERA_ORTHO, |
71 asc_camera_init(&window->ui_camera, .type = ASC_CAMERA_ORTHO, |
| 71 .ortho.rect = ASC_RECT(0, 0, window->dimensions.width, window->dimensions.height), |
72 .ortho.rect = ASC_RECTV(ASC_VEC2I_0, window->rect.size), |
| 72 .viewport_update_func = asc_camera_ortho_update_size); |
73 .viewport_update_func = asc_camera_ortho_update_size); |
| 73 asc_scene_init(&window->ui, ui_scene_name, &window->ui_camera); |
74 asc_scene_init(&window->ui, ui_scene_name, &window->ui_camera); |
| 74 asc_dprintf("Window %u initialized at index %u", window->id, index); |
75 asc_dprintf("Window %u initialized at index %u", window->id, index); |
| 75 asc_context.active_window = index; |
76 asc_context.active_window = index; |
| 76 } else { |
77 } else { |
| 77 asc_error("Creating GL context failed for window %u at index %u", window->id, index); |
78 asc_error("Creating GL context failed for window %u at index %u", window->id, index); |
| 78 // cleanup on error |
79 // cleanup on error |
| 79 SDL_DestroyWindow(window->window); |
80 SDL_DestroyWindow(window->sdl); |
| 80 window->window = NULL; |
81 window->sdl = NULL; |
| 81 window->id = 0; |
82 window->id = 0; |
| 82 } |
83 } |
| 83 } |
84 } |
| 84 |
85 |
| 85 void asc_window_destroy(unsigned int index) { |
86 void asc_window_destroy(unsigned int index) { |
| 150 if (index != active_index) { |
151 if (index != active_index) { |
| 151 asc_window_activate(index); |
152 asc_window_activate(index); |
| 152 } |
153 } |
| 153 |
154 |
| 154 // Clear the color buffer for the window frame |
155 // Clear the color buffer for the window frame |
| 155 int window_width = window->dimensions.width; |
156 glViewport(0, 0, |
| 156 int window_height = window->dimensions.height; |
157 (GLsizei) window->rect.size.width, |
| 157 glViewport(0, 0, window_width, window_height); |
158 (GLsizei) window->rect.size.height); |
| 158 glClear(GL_COLOR_BUFFER_BIT); |
159 glClear(GL_COLOR_BUFFER_BIT); |
| 159 |
160 |
| 160 // Update the viewports when the window resized |
161 // Update the viewports when the window resized |
| 161 if (window->resized) { |
162 if (window->resized) { |
| 162 for (unsigned int i = 0; i < ASC_MAX_SCENES; i++) { |
163 for (unsigned int i = 0; i < ASC_MAX_SCENES; i++) { |
| 163 if (asc_scene_active(&window->scenes[i])) { |
164 if (asc_scene_active(&window->scenes[i])) { |
| 164 asc_window_update_viewport(window->scenes[i].camera, window->dimensions); |
165 asc_window_update_viewport(window->scenes[i].camera, window->rect.size); |
| 165 } |
166 } |
| 166 } |
167 } |
| 167 asc_window_update_viewport(window->ui.camera, window->dimensions); |
168 asc_window_update_viewport(window->ui.camera, window->rect.size); |
| 168 } |
169 } |
| 169 |
170 |
| 170 // Execute camera updates |
171 // Execute camera updates |
| 171 for (unsigned int i = 0; i < ASC_MAX_SCENES; i++) { |
172 for (unsigned int i = 0; i < ASC_MAX_SCENES; i++) { |
| 172 if (asc_scene_active(&window->scenes[i])) { |
173 if (asc_scene_active(&window->scenes[i])) { |
| 216 return &asc_active_window->scenes[index]; |
218 return &asc_active_window->scenes[index]; |
| 217 } |
219 } |
| 218 |
220 |
| 219 asc_vec2u asc_window_display_resolution(void) { |
221 asc_vec2u asc_window_display_resolution(void) { |
| 220 const AscWindow *window = asc_active_window; |
222 const AscWindow *window = asc_active_window; |
| 221 SDL_DisplayID display = SDL_GetDisplayForWindow(window->window); |
223 SDL_DisplayID display = SDL_GetDisplayForWindow(window->sdl); |
| 222 const SDL_DisplayMode *dm = SDL_GetDesktopDisplayMode(display); |
224 const SDL_DisplayMode *dm = SDL_GetDesktopDisplayMode(display); |
| 223 if (dm == NULL) { |
225 if (dm == NULL) { |
| 224 asc_error("Failed to get display mode for window %u on display %d: %s", |
226 asc_error("Failed to get display mode for window %u on display %d: %s", |
| 225 window->id, display, SDL_GetError()); |
227 window->id, display, SDL_GetError()); |
| 226 } |
228 } |
| 227 return ASC_VEC2U(dm->w, dm->h); |
229 return ASC_VEC2U(dm->w, dm->h); |
| 228 } |
230 } |
| 229 |
231 |
| 230 float asc_window_ui_scale(unsigned int index) { |
232 float asc_window_ui_scale(unsigned int index) { |
| 231 assert(asc_context.windows[index].window != NULL); |
233 assert(asc_context.windows[index].sdl != NULL); |
| 232 return asc_context.windows[index].ui_scale; |
234 return asc_context.windows[index].ui_scale; |
| 233 } |
235 } |
| 234 |
236 |
| |
237 // TODO: error handling for all SDL_SetStuff() functions |
| |
238 |
| 235 void asc_window_set_title(unsigned index, const char *title) { |
239 void asc_window_set_title(unsigned index, const char *title) { |
| 236 assert(asc_context.windows[index].window != NULL); |
240 assert(asc_context.windows[index].sdl != NULL); |
| 237 SDL_SetWindowTitle(asc_context.windows[index].window, title); |
241 SDL_SetWindowTitle(asc_context.windows[index].sdl, title); |
| 238 } |
242 } |
| 239 |
243 |
| 240 void asc_window_set_position(unsigned index, asc_vec2i pos) { |
244 void asc_window_set_position(unsigned index, asc_vec2i pos) { |
| 241 assert(asc_context.windows[index].window != NULL); |
245 assert(asc_context.windows[index].sdl != NULL); |
| 242 SDL_SetWindowPosition(asc_context.windows[index].window, pos.x, pos.y); |
246 SDL_SetWindowPosition(asc_context.windows[index].sdl, pos.x, pos.y); |
| 243 } |
247 } |
| 244 |
248 |
| 245 void asc_window_center(unsigned index) { |
249 void asc_window_center(unsigned index) { |
| 246 // TODO: add support for multiple displays |
250 // TODO: add support for multiple displays |
| 247 // TODO: add support for centering just one axis |
251 const AscWindow *window = asc_context.windows + index; |
| 248 assert(asc_context.windows[index].window != NULL); |
252 assert(window->sdl != NULL); |
| 249 SDL_SetWindowPosition(asc_context.windows[index].window, |
253 SDL_SetWindowPosition(window->sdl, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); |
| 250 SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); |
254 } |
| |
255 |
| |
256 void asc_window_hcenter(unsigned index) { |
| |
257 // TODO: add support for multiple displays |
| |
258 const AscWindow *window = asc_context.windows + index; |
| |
259 assert(window->sdl != NULL); |
| |
260 SDL_SetWindowPosition(window->sdl, SDL_WINDOWPOS_CENTERED, window->rect.pos.y); |
| |
261 } |
| |
262 |
| |
263 void asc_window_vcenter(unsigned index) { |
| |
264 // TODO: add support for multiple displays |
| |
265 const AscWindow *window = asc_context.windows + index; |
| |
266 assert(window->sdl != NULL); |
| |
267 SDL_SetWindowPosition(window->sdl, window->rect.pos.x, SDL_WINDOWPOS_CENTERED); |
| 251 } |
268 } |
| 252 |
269 |
| 253 void asc_window_set_size(unsigned index, asc_vec2u size) { |
270 void asc_window_set_size(unsigned index, asc_vec2u size) { |
| 254 assert(asc_context.windows[index].window != NULL); |
271 const AscWindow *window = asc_context.windows + index; |
| 255 asc_context.windows[index].dimensions = size; |
272 assert(window->sdl != NULL); |
| 256 // TODO: check what needs to be changed when SDL_WINDOW_ALLOW_HIGHDPI is supported by the engine |
273 // TODO: check what needs to be changed when SDL_WINDOW_ALLOW_HIGHDPI is supported by the engine |
| 257 SDL_SetWindowSize(asc_context.windows[index].window, (int)size.width, (int)size.height); |
274 SDL_SetWindowSize(window->sdl, (int)size.width, (int)size.height); |
| 258 } |
275 } |