Added function to list valid resolutions and build resolutions menu dynamically with the resulting list

This commit is contained in:
zicodxx 2010-06-24 09:29:11 +00:00
parent 16b0092af7
commit 5a8ff256ae
5 changed files with 148 additions and 68 deletions

View file

@ -1,5 +1,9 @@
D2X-Rebirth Changelog D2X-Rebirth Changelog
20100624
--------
arch/ogl/gr.c, arch/sdl/gr.c, include/gr.h, main/menu.c: Added function to list valid resolutions and build resolutions menu dynamically with the resulting list
20100623 20100623
-------- --------
main/menu.c, main/newmenu.c, main/newmenu.h, main/net_ipx.c: Making menus recreated on the fly in case resolution or font-size changes; Removing arguments to pass width and height to menu which was not used except on one IPX menu; Fixing measurement of menu strings of type NM_TYPE_INPUT_MENU; Fixing slight bug in freeing IPX netlist main/menu.c, main/newmenu.c, main/newmenu.h, main/net_ipx.c: Making menus recreated on the fly in case resolution or font-size changes; Removing arguments to pass width and height to menu which was not used except on one IPX menu; Fixing measurement of menu strings of type NM_TYPE_INPUT_MENU; Fixing slight bug in freeing IPX netlist

View file

@ -104,7 +104,7 @@ void gr_do_fullscreen(int f)
cury=480; cury=480;
Game_screen_mode=SM(curx,cury); Game_screen_mode=SM(curx,cury);
} }
ogl_init_window(curx,cury); ogl_init_window(curx,cury);
} }
} }
@ -198,13 +198,46 @@ void ogl_get_verinfo(void)
#endif #endif
} }
// returns possible (fullscreen) resolutions if any.
int gr_list_modes( u_int32_t gsmodes[] )
{
SDL_Rect** modes;
int i = 0, modesnum = 0;
int sdl_check_flags = SDL_OPENGL | SDL_FULLSCREEN; // always use Fullscreen as lead.
modes = SDL_ListModes(NULL, sdl_check_flags);
if (modes == (SDL_Rect**)0) // check if we get any modes - if not, return 0
return 0;
if (modes == (SDL_Rect**)-1)
{
return 0; // can obviously use any resolution... strange!
}
else
{
for (i = 0; modes[i]; ++i)
{
if (modes[i]->w > 0xFFFF || modes[i]->h > 0xFFFF // resolutions saved in 32bits. so skip bigger ones (unrealistic in 2010)
|| modes[i]->w < 320 || modes[i]->h < 200) // also skip everything smaller than 320x200
continue;
gsmodes[modesnum] = SM(modes[i]->w,modes[i]->h);
modesnum++;
if (modesnum >= 50) // that really seems to be enough big boy.
break;
}
return modesnum;
}
}
int gr_check_mode(u_int32_t mode) int gr_check_mode(u_int32_t mode)
{ {
unsigned int w, h; unsigned int w, h;
w=SM_W(mode); w=SM_W(mode);
h=SM_H(mode); h=SM_H(mode);
return SDL_VideoModeOK(w, h, GameArg.DbgBpp, SDL_OPENGL | (ogl_fullscreen?SDL_FULLSCREEN:0)); return SDL_VideoModeOK(w, h, GameArg.DbgBpp, SDL_OPENGL | (ogl_fullscreen?SDL_FULLSCREEN:0));
} }
@ -391,7 +424,7 @@ int gr_init(int mode)
ogl_init_pixel_buffers(256, 128); // for gamefont_init ogl_init_pixel_buffers(256, 128); // for gamefont_init
gr_installed = 1; gr_installed = 1;
return 0; return 0;
} }
@ -434,7 +467,7 @@ void ogl_urect(int left,int top,int right,int bot)
{ {
GLfloat xo,yo,xf,yf; GLfloat xo,yo,xf,yf;
int c=COLOR; int c=COLOR;
xo=(left+grd_curcanv->cv_bitmap.bm_x)/(float)last_width; xo=(left+grd_curcanv->cv_bitmap.bm_x)/(float)last_width;
xf = (right + 1 + grd_curcanv->cv_bitmap.bm_x) / (float)last_width; xf = (right + 1 + grd_curcanv->cv_bitmap.bm_x) / (float)last_width;
yo=1.0-(top+grd_curcanv->cv_bitmap.bm_y)/(float)last_height; yo=1.0-(top+grd_curcanv->cv_bitmap.bm_y)/(float)last_height;
@ -492,7 +525,7 @@ void ogl_do_palfx(void)
glVertex2f(1,1); glVertex2f(1,1);
glVertex2f(1,0); glVertex2f(1,0);
glEnd(); glEnd();
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
} }
@ -615,7 +648,7 @@ void save_screen_shot(int automap_flag)
static int savenum=0; static int savenum=0;
char savename[13+sizeof(SCRNS_DIR)]; char savename[13+sizeof(SCRNS_DIR)];
unsigned char *buf; unsigned char *buf;
if (!GameArg.DbgGlReadPixelsOk){ if (!GameArg.DbgGlReadPixelsOk){
if (!automap_flag) if (!automap_flag)
hud_message(MSGC_GAME_FEEDBACK,"glReadPixels not supported on your configuration"); hud_message(MSGC_GAME_FEEDBACK,"glReadPixels not supported on your configuration");

View file

@ -30,7 +30,7 @@ void gr_flip()
dest.x = src.x = dest.y = src.y = 0; dest.x = src.x = dest.y = src.y = 0;
dest.w = src.w = canvas->w; dest.w = src.w = canvas->w;
dest.h = src.h = canvas->h; dest.h = src.h = canvas->h;
SDL_BlitSurface(canvas, &src, screen, &dest); SDL_BlitSurface(canvas, &src, screen, &dest);
SDL_Flip(screen); SDL_Flip(screen);
} }
@ -42,6 +42,41 @@ void gr_set_draw_buffer(int buf)
buf = buf; buf = buf;
} }
// returns possible (fullscreen) resolutions if any.
int gr_list_modes( u_int32_t gsmodes[] )
{
SDL_Rect** modes;
int i = 0, modesnum = 0;
int sdl_check_flags = sdl_video_flags;
sdl_check_flags |= SDL_FULLSCREEN; // always use Fullscreen as lead.
modes = SDL_ListModes(NULL, sdl_check_flags);
if (modes == (SDL_Rect**)0) // check if we get any modes - if not, return 0
return 0;
if (modes == (SDL_Rect**)-1)
{
return 0; // can obviously use any resolution... strange!
}
else
{
for (i = 0; modes[i]; ++i)
{
if (modes[i]->w > 0xFFFF || modes[i]->h > 0xFFFF // resolutions saved in 32bits. so skip bigger ones (unrealistic in 2010)
|| modes[i]->w < 320 || modes[i]->h < 200) // also skip everything smaller than 320x200
continue;
gsmodes[modesnum] = SM(modes[i]->w,modes[i]->h);
modesnum++;
if (modesnum >= 50) // that really seems to be enough big boy.
break;
}
return modesnum;
}
}
int gr_check_mode(u_int32_t mode) int gr_check_mode(u_int32_t mode)
{ {
unsigned int w, h; unsigned int w, h;
@ -195,7 +230,7 @@ void gr_palette_step_up( int r, int g, int b )
int temp; int temp;
SDL_Palette *palette; SDL_Palette *palette;
SDL_Color colors[256]; SDL_Color colors[256];
if ( (r==last_r) && (g==last_g) && (b==last_b) ) if ( (r==last_r) && (g==last_g) && (b==last_b) )
return; return;
@ -242,7 +277,7 @@ void gr_palette_step_up( int r, int g, int b )
#undef min #undef min
static inline int min(int x, int y) { return x < y ? x : y; } static inline int min(int x, int y) { return x < y ? x : y; }
void gr_palette_load( ubyte *pal ) void gr_palette_load( ubyte *pal )
{ {
int i, j; int i, j;
SDL_Palette *palette; SDL_Palette *palette;

View file

@ -147,6 +147,7 @@ typedef struct _grs_screen { // This is a video screen
int gr_init(int mode); int gr_init(int mode);
int gr_list_modes( u_int32_t gsmodes[] );
int gr_check_mode(u_int32_t mode); int gr_check_mode(u_int32_t mode);
int gr_set_mode(u_int32_t mode); int gr_set_mode(u_int32_t mode);
void gr_set_attributes(void); void gr_set_attributes(void);

View file

@ -980,92 +980,99 @@ int gcd(int a, int b)
return gcd(b, a%b); return gcd(b, a%b);
} }
int change_res_poll() { return 0; }
void change_res() void change_res()
{ {
newmenu_item m[15]; u_int32_t modes[50], new_mode = 0;
u_int32_t modes[15]; int i = 0, mc = 0, num_presets = 0, citem = -1, opt_cval = -1, opt_cres = -1, opt_casp = -1, opt_fullscr = -1;
int i = 0, mc = 0, num_presets = 0;
char customres[16], aspect[16];
int fullscreenc;
u_int32_t screen_mode = 0, aspect_mode = 0;
// the list of pre-defined resolutions num_presets = gr_list_modes( modes );
if (gr_check_mode(SM(320,200))) { m[mc].type = NM_TYPE_RADIO; m[mc].text = "320x200 (16x10)"; m[mc].value = (Game_screen_mode == SM(320,200)); m[mc].group = 0; modes[mc] = SM(320,200); mc++; }
if (gr_check_mode(SM(640,480))) { m[mc].type = NM_TYPE_RADIO; m[mc].text = "640x480 (4x3)"; m[mc].value = (Game_screen_mode == SM(640,480)); m[mc].group = 0; modes[mc] = SM(640,480); mc++; }
if (gr_check_mode(SM(800,600))) { m[mc].type = NM_TYPE_RADIO; m[mc].text = "800x600 (4x3)"; m[mc].value = (Game_screen_mode == SM(800,600)); m[mc].group = 0; modes[mc] = SM(800,600); mc++; }
if (gr_check_mode(SM(1024,768))) { m[mc].type = NM_TYPE_RADIO; m[mc].text = "1024x768 (4x3)"; m[mc].value = (Game_screen_mode == SM(1024,768)); m[mc].group = 0; modes[mc] = SM(1024,768); mc++; }
if (gr_check_mode(SM(1280,800))) { m[mc].type = NM_TYPE_RADIO; m[mc].text = "1280x800 (16x10)"; m[mc].value = (Game_screen_mode == SM(1280,800)); m[mc].group = 0; modes[mc] = SM(1280,800); mc++; }
if (gr_check_mode(SM(1280,1024))) { m[mc].type = NM_TYPE_RADIO; m[mc].text = "1280x1024 (5x4)"; m[mc].value = (Game_screen_mode == SM(1280,1024)); m[mc].group = 0; modes[mc] = SM(1280,1024); mc++; }
if (gr_check_mode(SM(1440,900))) { m[mc].type = NM_TYPE_RADIO; m[mc].text = "1440x900 (16x10)"; m[mc].value = (Game_screen_mode == SM(1440,900)); m[mc].group = 0; modes[mc] = SM(1440,900); mc++; }
if (gr_check_mode(SM(1600,1200))) { m[mc].type = NM_TYPE_RADIO; m[mc].text = "1600x1200 (4x3)"; m[mc].value = (Game_screen_mode == SM(1600,1200)); m[mc].group = 0; modes[mc] = SM(1600,1200); mc++; }
if (gr_check_mode(SM(1920,1200))) { m[mc].type = NM_TYPE_RADIO; m[mc].text = "1920x1200 (16x10)"; m[mc].value = (Game_screen_mode == SM(1920,1200)); m[mc].group = 0; modes[mc] = SM(1920,1200); mc++; }
num_presets = mc;
// now see which field is true and break there {
m[mc].value=0; newmenu_item m[num_presets+8];
for (i = 0; i < mc; i++) char restext[num_presets][12], crestext[12], casptext[12];
for (i = 0; i <= num_presets-1; i++)
{
snprintf(restext[mc], sizeof(restext[mc]), "%ix%i", SM_W(modes[i]), SM_H(modes[i]));
m[mc].type = NM_TYPE_RADIO;
m[mc].text = restext[mc];
m[mc].value = ((citem == -1) && (Game_screen_mode == modes[i]) && GameCfg.AspectY == SM_W(modes[i])/gcd(SM_W(modes[i]),SM_H(modes[i])) && GameCfg.AspectX == SM_H(modes[i])/gcd(SM_W(modes[i]),SM_H(modes[i])));
m[mc].group = 0;
if (m[mc].value) if (m[mc].value)
break; citem = mc;
mc++;
}
// the field for custom resolution and aspect m[mc].type = NM_TYPE_TEXT; m[mc].text = ""; mc++; // little space for overview
m[mc].type = NM_TYPE_RADIO; m[mc].text = "use custom values"; m[mc].value = (i == mc); m[mc].group = 0; modes[mc] = 0; mc++; // the fields for custom resolution and aspect
opt_cval = mc;
m[mc].type = NM_TYPE_RADIO; m[mc].text = "use custom values"; m[mc].value = (citem == -1); m[mc].group = 0; mc++;
m[mc].type = NM_TYPE_TEXT; m[mc].text = "resolution:"; mc++; m[mc].type = NM_TYPE_TEXT; m[mc].text = "resolution:"; mc++;
sprintf(customres, "%ix%i", SM_W(Game_screen_mode), SM_H(Game_screen_mode)); snprintf(crestext, sizeof(crestext), "%ix%i", SM_W(Game_screen_mode), SM_H(Game_screen_mode));
m[mc].type = NM_TYPE_INPUT; m[mc].text = customres; m[mc].text_len = 11; modes[mc] = 0; mc++; opt_cres = mc;
m[mc].type = NM_TYPE_INPUT; m[mc].text = crestext; m[mc].text_len = 11; modes[mc] = 0; mc++;
m[mc].type = NM_TYPE_TEXT; m[mc].text = "aspect:"; mc++; m[mc].type = NM_TYPE_TEXT; m[mc].text = "aspect:"; mc++;
sprintf(aspect, "%ix%i", GameCfg.AspectY, GameCfg.AspectX); opt_casp = mc;
m[mc].type = NM_TYPE_INPUT; m[mc].text = aspect; m[mc].text_len = 11; modes[mc] = 0; mc++; snprintf(casptext, sizeof(casptext), "%ix%i", GameCfg.AspectY, GameCfg.AspectX);
m[mc].type = NM_TYPE_INPUT; m[mc].text = casptext; m[mc].text_len = 11; modes[mc] = 0; mc++;
// fullscreen toggle m[mc].type = NM_TYPE_TEXT; m[mc].text = ""; mc++; // little space for overview
fullscreenc = mc; m[mc].type = NM_TYPE_CHECK; m[mc].text = "Fullscreen"; m[mc].value = gr_check_fullscreen(); mc++; // fullscreen
opt_fullscr = mc;
m[mc].type = NM_TYPE_CHECK; m[mc].text = "Fullscreen"; m[mc].value = gr_check_fullscreen(); mc++;
// create the menu // create the menu
i = newmenu_do1(NULL, "Screen Resolution", mc, m, change_res_poll, NULL, 0); newmenu_do1(NULL, "Screen Resolution", mc, m, NULL, NULL, 0);
// menu is done, now do what we need to do // menu is done, now do what we need to do
// check which resolution field was selected
for (i = 0; i <= mc; i++)
if ((m[i].type == NM_TYPE_RADIO) && (m[i].group==0) && (m[i].value == 1))
break;
// now check for fullscreen toggle and apply if necessary // now check for fullscreen toggle and apply if necessary
if (m[fullscreenc].value != gr_check_fullscreen()) if (m[opt_fullscr].value != gr_check_fullscreen())
gr_toggle_fullscreen(); gr_toggle_fullscreen();
// check which preset field was selected if (i == opt_cval) // set custom resolution and aspect
for (i = 0; (m[i].value == 0) && (i < num_presets); i++);
if (modes[i]==0) // no preset selected, use custom values and set screen_mode and aspect
{ {
if (!strchr(customres, 'x')) u_int32_t cmode = Game_screen_mode, casp = Game_screen_mode;
if (!strchr(crestext, 'x'))
return; return;
screen_mode = SM(atoi(customres), atoi(strchr(customres, 'x')+1)); cmode = SM(atoi(crestext), atoi(strchr(crestext, 'x')+1));
if (SM_W(screen_mode) < 320 || SM_H(screen_mode) < 200) // oh oh - the resolution is too small. Revert! if (SM_W(cmode) < 320 || SM_H(cmode) < 200) // oh oh - the resolution is too small. Revert!
{ {
nm_messagebox( TXT_WARNING, 1, "OK", "Entered resolution is too small.\nReverting ..." ); nm_messagebox( TXT_WARNING, 1, "OK", "Entered resolution is too small.\nReverting ..." );
return; cmode = new_mode;
} }
if (strchr(aspect, 'x')) // we even have a custom aspect set up
{
aspect_mode = SM(atoi(aspect), atoi(strchr(aspect, 'x')+1));
GameCfg.AspectY = SM_W(aspect_mode)/gcd(SM_W(aspect_mode),SM_H(aspect_mode));
GameCfg.AspectX = SM_H(aspect_mode)/gcd(SM_W(aspect_mode),SM_H(aspect_mode));
}
}
else // a preset field is selected - set screen_mode and aspect
{
screen_mode = modes[i];
GameCfg.AspectY = SM_W(screen_mode)/gcd(SM_W(screen_mode),SM_H(screen_mode));
GameCfg.AspectX = SM_H(screen_mode)/gcd(SM_W(screen_mode),SM_H(screen_mode));
}
casp = cmode;
if (strchr(casptext, 'x')) // we even have a custom aspect set up
{
casp = SM(atoi(casptext), atoi(strchr(casptext, 'x')+1));
}
GameCfg.AspectY = SM_W(casp)/gcd(SM_W(casp),SM_H(casp));
GameCfg.AspectX = SM_H(casp)/gcd(SM_W(casp),SM_H(casp));
new_mode = cmode;
}
else if (i >= 0 && i < num_presets) // set preset resolution
{
new_mode = modes[i];
GameCfg.AspectY = SM_W(new_mode)/gcd(SM_W(new_mode),SM_H(new_mode));
GameCfg.AspectX = SM_H(new_mode)/gcd(SM_W(new_mode),SM_H(new_mode));
}
// clean up and apply everything // clean up and apply everything
newmenu_close(); newmenu_close();
set_screen_mode(SCREEN_MENU); set_screen_mode(SCREEN_MENU);
Game_screen_mode = screen_mode; if (new_mode != Game_screen_mode)
gr_set_mode(Game_screen_mode); gr_set_mode(new_mode);
Game_screen_mode = new_mode;
init_cockpit(); init_cockpit();
game_init_render_buffers(SM_W(screen_mode), SM_H(screen_mode), VR_NONE); game_init_render_buffers(SM_W(Game_screen_mode), SM_H(Game_screen_mode), VR_NONE);
}
} }
int input_menuset(newmenu *menu, d_event *event, void *userdata) int input_menuset(newmenu *menu, d_event *event, void *userdata)