Merge lp:~mxsscott/widelands/windowed-graphics into lp:widelands

Proposed by Mark Scott
Status: Merged
Merged at revision: 6484
Proposed branch: lp:~mxsscott/widelands/windowed-graphics
Merge into: lp:widelands
Diff against target: 414 lines (+138/-75)
8 files modified
src/sound/sound_handler.cc (+2/-2)
src/ui_fsmenu/base.cc (+2/-2)
src/ui_fsmenu/options.cc (+76/-24)
src/ui_fsmenu/options.h (+19/-6)
src/wlapplication.cc (+25/-4)
src/wlapplication.h (+12/-2)
src/wui/interactive_base.cc (+2/-32)
src/wui/interactive_base.h (+0/-3)
To merge this branch: bzr merge lp:~mxsscott/widelands/windowed-graphics
Reviewer Review Type Date Requested Status
SirVer Approve
Review via email: mp+142048@code.launchpad.net

Description of the change

Fix resizing of the game window after the user chooses a new resolution bug 1096651.

- Also menus use the current graphics dimensions, not the dimensions in the options (not really a problem now!)

- Some graphics resolution tidyups.

- Support Enter/Escape for triggering the Apply or Cancel buttons within the Options menu. This allows the user to reselect a smaller window size if they get stuck due to bug 900784.

The screen resolution issue fix could possibly be improved if we display a window for 5-10 seconds asking the user to confirm they can see it. If they don't click OK, we revert the graphics mode back to the previous one. However, I believe the Enter/Escape solution is 'good enough' for now.

To post a comment you must log in.
Revision history for this message
SirVer (sirver) wrote :

Nice change in total. The only issue I have is const SDL_Rect * const *. Maybe it's because i am a bad programmer, but i do not even know what type this is... a const pointer to pointer to constant SDL_Rects? does const SDL_Rect** compile without casting?

I also agree with the struct -> class changes and the simplifications concerning pulling the resolutions from the conf file periodically vs taking the real resolution.

I think here

 for (/* init above */; modes && *modes; ++modes)

you could just pull the initialization into the for loop as you do not do anything with the variable anyways.

otherwise looks good to me. Btw, I really enjoy reviewing your code :-). In the past we have always granted push to trunk rights to developers who have made good contributions. Are you interested in this? Then, we also no longer did code reviews and devs just push whatever they think is appropriate - however i am interested in changing this because I'd love to have code review for my own stuff as well in the future. .... this kinda went offtopic of this merge - I'd like to hear the comments of everybody though!

review: Approve
Revision history for this message
Mark Scott (mxsscott) wrote :

Reading right to left, it's a pointer to a const pointer to a const SDL_Rect.

const SDL_Rect** should also work because that's what SDL_ListModes() returns (we declare our variable to be more consty to indicate we don't mess with it.

The reason I left the init out of the for loop was due to line-length, but this is a pretty poor reason to do so.

I'll make these changes and re-push the branch.

I'm happy having trunk rights - but I do see the benefit of having code reviewed, especially where it is an area people are touching significantly or haven't touched before. Even if the coding is fine, there may be opportunity to say "Why don't you do this too?", or point out something that was missed "You left a todo in for function X's documentation" - we all forget these in the haste to commit before going away to do something else (sleep?)

Revision history for this message
Mark Scott (mxsscott) wrote :

Wasn't able to change the type
   const SDL_Rect * const *
to
   const SDL_Rect * *.

SDL_ListModes() returns a "SDL_Rect **" so we need to say we'll keep all but the final pointer variable constant (which is fine because that variable is ours), or nothing constant.

Revision history for this message
SirVer (sirver) wrote :

Okay, Ack. Code LGTM, so feel free to push it.

I gave you push rights to trunk (by adding you to widelands dev). here comes the very important usual disclaimer: bzr is awefull in one regard that you can push your branch history to trunk without confirmation. that is, if you work in a branch and someone adds new revisions to trunk in the meantime, when you push your branch to trunk you will overwrite those changes!!!

so, the proper thing is to always keep a version of trunk around that you do not modify. I personally use this workflow: http://www.taoeffect.com/blog/2009/06/using-bazaar-like-git-repoalias-plugin/

you then always work in branches:

$ cd trunk && bzr switch -b bug123
hack hack, commit, commit
$ bzr switch trunk && bzr pull && bzr merge .bzr-repo/bug123
$ bzr push lp:widelands

especially never push to lp:widelands from a feature branch or before you pulled. bzr uncommit helps sometimes to undo errors.

feel free to ask for anything when you need help. this is really important to get right - though basically everybody gets it wrong once. this will result in mailbombs from bzr and "XXX revisions removed." mails which are confusing at best.

Revision history for this message
Hans Joachim Desserud (hjd) wrote :

>I'd love to have code review for my own stuff as well in the future. .... this kinda went offtopic of this merge - I'd like to hear the comments of everybody though!

+1
Code reviews are really nice as they can often reveal and resolve issues before they hit trunk. And if something breaks in the future, both the author and reviewer should be familiar with the code as opposed to only a single person.

One potential issue I see is of shortage of reviewers. We currently have nine branches waiting for review, some of which are quite old. On the other hand, some of those have raised issues which authors haven't addressed yet.

I think this would be worth a try. We can always re-assess later if we end up with lots of unmerged reviews and a trunk gathering dust.

And since this is completely off-topic, we should find some better place to discuss it; a forum thread, meta bug?

Revision history for this message
SirVer (sirver) wrote :

right, maybe we should take this to widelands-public which is still the goto place to discuss dev topics.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/sound/sound_handler.cc'
--- src/sound/sound_handler.cc 2013-01-04 16:39:48 +0000
+++ src/sound/sound_handler.cc 2013-01-07 20:42:25 +0000
@@ -330,8 +330,8 @@
330 Interactive_Base const & ibase = *m_egbase->get_ibase();330 Interactive_Base const & ibase = *m_egbase->get_ibase();
331 Point const vp = ibase.get_viewpoint();331 Point const vp = ibase.get_viewpoint();
332332
333 int32_t const xres = ibase.get_xres();333 int32_t const xres = g_gr->get_xres();
334 int32_t const yres = ibase.get_yres();334 int32_t const yres = g_gr->get_yres();
335335
336 MapviewPixelFunctions::get_pix(m_egbase->map(), position, sx, sy);336 MapviewPixelFunctions::get_pix(m_egbase->map(), position, sx, sy);
337 sx -= vp.x;337 sx -= vp.x;
338338
=== modified file 'src/ui_fsmenu/base.cc'
--- src/ui_fsmenu/base.cc 2013-01-05 21:03:10 +0000
+++ src/ui_fsmenu/base.cc 2013-01-07 20:42:25 +0000
@@ -86,11 +86,11 @@
8686
8787
88uint32_t Fullscreen_Menu_Base::gr_x() {88uint32_t Fullscreen_Menu_Base::gr_x() {
89 return g_options.pull_section("global").get_int("xres", XRES);89 return g_gr->get_xres();
90}90}
9191
92uint32_t Fullscreen_Menu_Base::gr_y() {92uint32_t Fullscreen_Menu_Base::gr_y() {
93 return g_options.pull_section("global").get_int("yres", YRES);93 return g_gr->get_yres();
94}94}
9595
9696
9797
=== modified file 'src/ui_fsmenu/options.cc'
--- src/ui_fsmenu/options.cc 2012-12-16 19:08:53 +0000
+++ src/ui_fsmenu/options.cc 2013-01-07 20:42:25 +0000
@@ -236,37 +236,47 @@
236236
237 // GRAPHIC_TODO: this shouldn't be here List all resolutions237 // GRAPHIC_TODO: this shouldn't be here List all resolutions
238 // take a copy to not change real video info structure238 // take a copy to not change real video info structure
239 SDL_PixelFormat fmt = *SDL_GetVideoInfo()->vfmt;239 SDL_PixelFormat fmt = *SDL_GetVideoInfo()->vfmt;
240
240 fmt.BitsPerPixel = 16;241 fmt.BitsPerPixel = 16;
241 if242 for
242 (SDL_Rect const * const * const modes =243 (const SDL_Rect * const * modes = SDL_ListModes(&fmt, SDL_SWSURFACE | SDL_FULLSCREEN);
243 SDL_ListModes(&fmt, SDL_SWSURFACE | SDL_FULLSCREEN))244 modes && *modes;
244 for (uint32_t i = 0; modes[i]; ++i)245 ++modes)
245 if (640 <= modes[i]->w and 480 <= modes[i]->h) {246 {
246 res const this_res = {modes[i]->w, modes[i]->h, 16};247 const SDL_Rect & mode = **modes;
248 if (640 <= mode.w and 480 <= mode.h)
249 {
250 const Resolution this_res = {mode.w, mode.h, fmt.BitsPerPixel};
247 if251 if
248 (m_resolutions.empty()252 (m_resolutions.empty()
249 or253 || this_res.xres != m_resolutions.rbegin()->xres
250 this_res.xres != m_resolutions.rbegin()->xres254 || this_res.yres != m_resolutions.rbegin()->yres)
251 or255 {
252 this_res.yres != m_resolutions.rbegin()->yres)
253 m_resolutions.push_back(this_res);256 m_resolutions.push_back(this_res);
254 }257 }
258 }
259 }
260
255 fmt.BitsPerPixel = 32;261 fmt.BitsPerPixel = 32;
256 if262 for
257 (SDL_Rect const * const * const modes =263 (const SDL_Rect * const * modes = SDL_ListModes(&fmt, SDL_SWSURFACE | SDL_FULLSCREEN);
258 SDL_ListModes(&fmt, SDL_SWSURFACE | SDL_FULLSCREEN))264 modes && *modes;
259 for (uint32_t i = 0; modes[i]; ++i)265 ++modes)
260 if (640 <= modes[i]->w and 480 <= modes[i]->h) {266 {
261 res const this_res = {modes[i]->w, modes[i]->h, 32};267 const SDL_Rect & mode = **modes;
262 if268 if (640 <= mode.w and 480 <= mode.h)
263 (m_resolutions.empty()269 {
264 or270 const Resolution this_res = {mode.w, mode.h, fmt.BitsPerPixel};
265 this_res.xres != m_resolutions.rbegin()->xres271 if
266 or272 (m_resolutions.empty()
267 this_res.yres != m_resolutions.rbegin()->yres)273 || this_res.xres != m_resolutions.rbegin()->xres
268 m_resolutions.push_back(this_res);274 || this_res.yres != m_resolutions.rbegin()->yres)
275 {
276 m_resolutions.push_back(this_res);
269 }277 }
278 }
279 }
270280
271 bool did_select_a_res = false;281 bool did_select_a_res = false;
272 for (uint32_t i = 0; i < m_resolutions.size(); ++i) {282 for (uint32_t i = 0; i < m_resolutions.size(); ++i) {
@@ -343,6 +353,26 @@
343 }353 }
344}354}
345355
356bool Fullscreen_Menu_Options::handle_key(bool down, SDL_keysym code)
357{
358 if (down)
359 {
360 switch (code.sym)
361 {
362 case SDLK_KP_ENTER:
363 case SDLK_RETURN:
364 end_modal(static_cast<int32_t>(om_ok));
365 return true;
366 case SDLK_ESCAPE:
367 end_modal(static_cast<int32_t>(om_cancel));
368 return true;
369 default:
370 break; // not handled
371 }
372 }
373
374 return Fullscreen_Menu_Base::handle_key(down, code);
375}
346376
347Options_Ctrl::Options_Struct Fullscreen_Menu_Options::get_values() {377Options_Ctrl::Options_Struct Fullscreen_Menu_Options::get_values() {
348 const uint32_t res_index = m_reslist.selection_index();378 const uint32_t res_index = m_reslist.selection_index();
@@ -561,6 +591,28 @@
561 }591 }
562}592}
563593
594bool Fullscreen_Menu_Advanced_Options::handle_key(bool down, SDL_keysym code)
595{
596 if (down)
597 {
598 switch (code.sym)
599 {
600 case SDLK_KP_ENTER:
601 case SDLK_RETURN:
602 end_modal(static_cast<int32_t>(om_ok));
603 return true;
604 case SDLK_ESCAPE:
605 end_modal(static_cast<int32_t>(om_cancel));
606 return true;
607 default:
608 break; // not handled
609 }
610 }
611
612 return Fullscreen_Menu_Base::handle_key(down, code);
613}
614
615
564Options_Ctrl::Options_Struct Fullscreen_Menu_Advanced_Options::get_values() {616Options_Ctrl::Options_Struct Fullscreen_Menu_Advanced_Options::get_values() {
565 // Write all remaining data from UI elements617 // Write all remaining data from UI elements
566 os.message_sound = m_message_sound.get_state();618 os.message_sound = m_message_sound.get_state();
567619
=== modified file 'src/ui_fsmenu/options.h'
--- src/ui_fsmenu/options.h 2012-02-15 21:25:34 +0000
+++ src/ui_fsmenu/options.h 2013-01-07 20:42:25 +0000
@@ -32,10 +32,11 @@
32#include <cstring>32#include <cstring>
33#include <vector>33#include <vector>
3434
35struct Fullscreen_Menu_Options;35class Fullscreen_Menu_Options;
36struct Section;36struct Section;
3737
38struct Options_Ctrl {38class Options_Ctrl {
39public:
39 struct Options_Struct {40 struct Options_Struct {
40 int32_t xres;41 int32_t xres;
41 int32_t yres;42 int32_t yres;
@@ -80,7 +81,8 @@
80 * Fullscreen Optionsmenu. A modal optionsmenu81 * Fullscreen Optionsmenu. A modal optionsmenu
81 */82 */
8283
83struct Fullscreen_Menu_Options : public Fullscreen_Menu_Base {84class Fullscreen_Menu_Options : public Fullscreen_Menu_Base {
85public:
84 Fullscreen_Menu_Options(Options_Ctrl::Options_Struct opt);86 Fullscreen_Menu_Options(Options_Ctrl::Options_Struct opt);
85 Options_Ctrl::Options_Struct get_values();87 Options_Ctrl::Options_Struct get_values();
86 enum {88 enum {
@@ -89,6 +91,9 @@
89 om_restart = 291 om_restart = 2
90 };92 };
9193
94 /// Handle keypresses
95 virtual bool handle_key(bool down, SDL_keysym code);
96
92private:97private:
93 uint32_t m_vbutw;98 uint32_t m_vbutw;
94 uint32_t m_butw;99 uint32_t m_butw;
@@ -127,19 +132,24 @@
127132
128 void advanced_options();133 void advanced_options();
129134
130 struct res {135 /// A screen resolution in terms of width, height and pixel depth.
136 class Resolution {
137 public:
131 int32_t xres;138 int32_t xres;
132 int32_t yres;139 int32_t yres;
133 int32_t depth;140 int32_t depth;
134 };141 };
135 std::vector<res> m_resolutions;142
143 /// All supported screen resolutions.
144 std::vector<Resolution> m_resolutions;
136};145};
137146
138/**147/**
139 * Fullscreen Optionsmenu. A modal optionsmenu148 * Fullscreen Optionsmenu. A modal optionsmenu
140 */149 */
141150
142struct Fullscreen_Menu_Advanced_Options : public Fullscreen_Menu_Base {151class Fullscreen_Menu_Advanced_Options : public Fullscreen_Menu_Base {
152public:
143 Fullscreen_Menu_Advanced_Options(Options_Ctrl::Options_Struct opt);153 Fullscreen_Menu_Advanced_Options(Options_Ctrl::Options_Struct opt);
144 Options_Ctrl::Options_Struct get_values();154 Options_Ctrl::Options_Struct get_values();
145 enum {155 enum {
@@ -147,6 +157,9 @@
147 om_ok = 1157 om_ok = 1
148 };158 };
149159
160 /// Handle keypresses
161 virtual bool handle_key(bool down, SDL_keysym code);
162
150private:163private:
151 uint32_t m_vbutw;164 uint32_t m_vbutw;
152 uint32_t m_butw;165 uint32_t m_butw;
153166
=== modified file 'src/wlapplication.cc'
--- src/wlapplication.cc 2013-01-04 15:24:56 +0000
+++ src/wlapplication.cc 2013-01-07 20:42:25 +0000
@@ -263,7 +263,7 @@
263m_mouse_locked (0),263m_mouse_locked (0),
264m_mouse_compensate_warp(0, 0),264m_mouse_compensate_warp(0, 0),
265m_should_die (false),265m_should_die (false),
266m_gfx_w(0), m_gfx_h(0),266m_gfx_w(0), m_gfx_h(0), m_gfx_bpp(0),
267m_gfx_fullscreen (false),267m_gfx_fullscreen (false),
268m_gfx_opengl (true),268m_gfx_opengl (true),
269m_default_datadirs (true),269m_default_datadirs (true),
@@ -790,11 +790,11 @@
790 */790 */
791791
792void WLApplication::init_graphics792void WLApplication::init_graphics
793 (int32_t const w, int32_t const h, int32_t const bpp,793 (const int32_t w, const int32_t h, const int32_t bpp,
794 bool const fullscreen, bool const opengl)794 const bool fullscreen, const bool opengl)
795{795{
796 if796 if
797 (w == m_gfx_w && h == m_gfx_h &&797 (w == m_gfx_w && h == m_gfx_h && bpp == m_gfx_bpp &&
798 fullscreen == m_gfx_fullscreen &&798 fullscreen == m_gfx_fullscreen &&
799 opengl == m_gfx_opengl)799 opengl == m_gfx_opengl)
800 return;800 return;
@@ -804,6 +804,7 @@
804804
805 m_gfx_w = w;805 m_gfx_w = w;
806 m_gfx_h = h;806 m_gfx_h = h;
807 m_gfx_bpp = bpp;
807 m_gfx_fullscreen = fullscreen;808 m_gfx_fullscreen = fullscreen;
808 m_gfx_opengl = opengl;809 m_gfx_opengl = opengl;
809810
@@ -815,6 +816,23 @@
815 }816 }
816}817}
817818
819void WLApplication::refresh_graphics()
820{
821 Section & s = g_options.pull_section("global");
822
823 // Switch to the new graphics system now, if necessary.
824 init_graphics
825 (s.get_int("xres", XRES),
826 s.get_int("yres", YRES),
827 s.get_int("depth", 16),
828 s.get_bool("fullscreen", false),
829#if USE_OPENGL
830 s.get_bool("opengl", true));
831#else
832 false);
833#endif
834}
835
818/**836/**
819 * Read the config file, parse the commandline and give all other internal837 * Read the config file, parse the commandline and give all other internal
820 * parameters sensible default values838 * parameters sensible default values
@@ -1515,6 +1533,9 @@
1515 std::string message;1533 std::string message;
15161534
1517 for (;;) {1535 for (;;) {
1536 // Refresh graphics system in case we just changed resolution.
1537 refresh_graphics();
1538
1518 Fullscreen_Menu_Main mm;1539 Fullscreen_Menu_Main mm;
15191540
1520 if (message.size()) {1541 if (message.size()) {
15211542
=== modified file 'src/wlapplication.h'
--- src/wlapplication.h 2012-02-15 21:25:34 +0000
+++ src/wlapplication.h 2013-01-07 20:42:25 +0000
@@ -179,8 +179,15 @@
179 //@}179 //@}
180180
181 void init_graphics181 void init_graphics
182 (int32_t w, int32_t h, int32_t bpp,182 (const int32_t w, const int32_t h, const int32_t bpp,
183 bool fullscreen, bool opengl);183 const bool fullscreen, const bool opengl);
184
185 /**
186 * Refresh the graphics from the latest options.
187 *
188 * \note See caveats for \ref init_graphics()
189 */
190 void refresh_graphics();
184191
185 void handle_input(InputCallback const *);192 void handle_input(InputCallback const *);
186193
@@ -282,6 +289,9 @@
282 ///The Widelands window's height in pixels289 ///The Widelands window's height in pixels
283 int32_t m_gfx_h;290 int32_t m_gfx_h;
284291
292 ///The Widelands window's bits per pixel
293 int32_t m_gfx_bpp;
294
285 ///If true Widelands is (should be, we never know ;-) running295 ///If true Widelands is (should be, we never know ;-) running
286 ///in a fullscreen window296 ///in a fullscreen window
287 bool m_gfx_fullscreen;297 bool m_gfx_fullscreen;
288298
=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc 2012-12-16 14:29:46 +0000
+++ src/wui/interactive_base.cc 2013-01-07 20:42:25 +0000
@@ -71,7 +71,7 @@
71Interactive_Base::Interactive_Base71Interactive_Base::Interactive_Base
72 (Editor_Game_Base & the_egbase, Section & global_s)72 (Editor_Game_Base & the_egbase, Section & global_s)
73 :73 :
74 Map_View(0, 0, 0, get_xres(), get_yres(), *this),74 Map_View(0, 0, 0, global_s.get_int("xres", XRES), global_s.get_int("yres", YRES), *this),
75 m_show_workarea_preview(global_s.get_bool("workareapreview", true)),75 m_show_workarea_preview(global_s.get_bool("workareapreview", true)),
76 m76 m
77 (new InteractiveBaseInternals77 (new InteractiveBaseInternals
@@ -112,15 +112,7 @@
112 (global_s.get_bool("dock_windows_to_edges", false));112 (global_s.get_bool("dock_windows_to_edges", false));
113113
114 // Switch to the new graphics system now, if necessary.114 // Switch to the new graphics system now, if necessary.
115 WLApplication::get()->init_graphics115 WLApplication::get()->refresh_graphics();
116 (get_xres(), get_yres(),
117 global_s.get_int("depth", 16),
118 global_s.get_bool("fullscreen", false),
119#if USE_OPENGL
120 global_s.get_bool("opengl", true));
121#else
122 false);
123#endif
124116
125 // Having this in the initializer list (before Sys_InitGraphics) will give117 // Having this in the initializer list (before Sys_InitGraphics) will give
126 // funny results.118 // funny results.
@@ -238,28 +230,6 @@
238230
239231
240/**232/**
241 * Retrieves the configured in-game resolution.
242 *
243 * \note For most purposes, you should use \ref Graphic::get_xres instead.
244 */
245int32_t Interactive_Base::get_xres()
246{
247 return g_options.pull_section("global").get_int("xres", XRES);
248}
249
250
251/**
252 * Retrieves the configured in-game resolution.
253 *
254 * \note For most purposes, you should use \ref Graphic::get_yres instead.
255 */
256int32_t Interactive_Base::get_yres()
257{
258 return g_options.pull_section("global").get_int("yres", YRES);
259}
260
261
262/**
263 * Called by \ref Game::postload at the end of the game loading233 * Called by \ref Game::postload at the end of the game loading
264 * sequence.234 * sequence.
265 *235 *
266236
=== modified file 'src/wui/interactive_base.h'
--- src/wui/interactive_base.h 2012-12-13 10:41:22 +0000
+++ src/wui/interactive_base.h 2013-01-07 20:42:25 +0000
@@ -113,9 +113,6 @@
113 virtual void cleanup_for_load() {};113 virtual void cleanup_for_load() {};
114114
115private:115private:
116 static int32_t get_xres();
117 static int32_t get_yres();
118
119 void roadb_add_overlay ();116 void roadb_add_overlay ();
120 void roadb_remove_overlay();117 void roadb_remove_overlay();
121118

Subscribers

People subscribed via source and target branches

to status/vote changes: