+void
+Renderer::resize(int w, int h)
+{
+ // This causes the screen to go black, which is annoying, but seems
+ // unavoidable with SDL at the moment
+ SDL_SetVideoMode(w, h, 0, SDL_OPENGL | SDL_RESIZABLE);
+
+ config->window_width = w;
+ config->window_height = h;
+
+ apply_config();
+}
+
+void
+Renderer::apply_config()
+{
+ if (0)
+ {
+ std::cout << "Applying Config:"
+ << "\n Desktop: " << desktop_width << "x" << desktop_height
+ << "\n Window: " << config->window_width << "x" << config->window_height
+ << "\n FullRes: " << config->fullscreen_width << "x" << config->fullscreen_height
+ << "\n Aspect: " << config->aspect_width << ":" << config->aspect_height
+ << "\n Magnif: " << config->magnification
+ << std::endl;
+ }
+
+ int w,h;
+ float target_aspect = float(desktop_width) / desktop_height;
+
+ if (config->aspect_width != 0 && config->aspect_height != 0)
+ target_aspect = float(config->aspect_width) / float(config->aspect_height);
+
+ float desktop_aspect = 4.0f / 3.0f; // random default fallback guess
+
+ if (desktop_width != -1 && desktop_height != -1)
+ {
+ desktop_aspect = float(desktop_width) / float(desktop_height);
+ }
+
+ // Get the screen width
+ if (config->use_fullscreen)
+ {
+ w = config->fullscreen_width;
+ h = config->fullscreen_height;
+ desktop_aspect = float(w) / float(h);
+ }
+ else
+ {
+ w = config->window_width;
+ h = config->window_height;
+ }
+
+ if (target_aspect > 1.0f)
+ {
+ SCREEN_WIDTH = static_cast<int>(w * (target_aspect / desktop_aspect));
+ SCREEN_HEIGHT = static_cast<int>(h);
+ }
+ else
+ {
+ SCREEN_WIDTH = static_cast<int>(w);
+ SCREEN_HEIGHT = static_cast<int>(h * (target_aspect / desktop_aspect));
+ }
+
+ int max_width = 1600; // FIXME: Maybe 1920 is ok too
+ int max_height = 1200;
+
+ if (config->magnification == 0.0f) // Magic value that means 'minfill'
+ {
+ // This scales SCREEN_WIDTH/SCREEN_HEIGHT so that they never excede
+ // max_width/max_height
+ if (SCREEN_WIDTH > max_width || SCREEN_HEIGHT > max_height)
+ {
+ float scale1 = float(max_width)/SCREEN_WIDTH;
+ float scale2 = float(max_height)/SCREEN_HEIGHT;
+ float scale = (scale1 < scale2) ? scale1 : scale2;
+ SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH * scale);
+ SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT * scale);
+ }
+
+ glViewport(0, 0, w, h);
+ }
+ else
+ {
+ SCREEN_WIDTH = static_cast<int>(SCREEN_WIDTH / config->magnification);
+ SCREEN_HEIGHT = static_cast<int>(SCREEN_HEIGHT / config->magnification);
+
+ // This works by adding black borders around the screen to limit
+ // SCREEN_WIDTH/SCREEN_HEIGHT to max_width/max_height
+ int nw = w;
+ int nh = h;
+
+ if (SCREEN_WIDTH > max_width)
+ {
+ nw = static_cast<int>((float) nw * float(max_width)/SCREEN_WIDTH);
+ SCREEN_WIDTH = static_cast<int>(max_width);
+ }
+
+ if (SCREEN_HEIGHT > max_height)
+ {
+ nh = static_cast<int>((float) nh * float(max_height)/SCREEN_HEIGHT);
+ SCREEN_HEIGHT = static_cast<int>(max_height);
+ }
+
+ // Clear both buffers so that we get a clean black border without junk
+ glClear(GL_COLOR_BUFFER_BIT);
+ SDL_GL_SwapBuffers();
+ glClear(GL_COLOR_BUFFER_BIT);
+ SDL_GL_SwapBuffers();
+
+ if (0)
+ std::cout << (w-nw)/2 << " "
+ << (h-nh)/2 << " "
+ << nw << "x" << nh << std::endl;
+
+ glViewport(std::max(0, (w-nw)/2),
+ std::max(0, (h-nh)/2),
+ std::min(nw, w),
+ std::min(nh, h));
+ }
+
+ if (0)
+ std::cout << " -> " << SCREEN_WIDTH << "x" << SCREEN_HEIGHT << std::endl;
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1, 1);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0, 0, 0);
+ check_gl_error("Setting up view matrices");
+}
+
+} // namespace GL
+