1 #ifndef VG_SETTINGS_MENU_H
2 #define VG_SETTINGS_MENU_H
7 struct ui_enum_opt vg_settings_vsync_enum
[] = {
13 struct ui_enum_opt vg_settings_quality_enum
[] = {
14 { 0, "High Quality" },
16 { 2, "Absolute Minimum" },
19 struct ui_enum_opt vg_settings_screen_mode_enum
[] = {
20 { 0, "Fullscreen (desktop)" },
21 { 1, "Fullscreen (native)" },
22 { 2, "Floating Window" }
26 struct vg_setting_ranged_i32
{
27 i32 new_value
, *actual_value
, min
, max
;
33 struct vg_setting_enum
{
34 i32 new_value
, *actual_value
;
36 struct ui_enum_opt
*options
;
40 vsync
, quality
, screenmode
;
42 int windowed_before
[4];
44 static vg_settings
= {
45 .fps_limit
= { .label
= "Fps Limit",
46 .min
=24, .max
=300, .actual_value
= &vg
.fps_limit
},
47 .vsync
= { .label
= "Vsync",
48 .actual_value
= &vg
.vsync
,
49 .options
= vg_settings_vsync_enum
, .option_count
= 3 },
50 .quality
= { .label
= "Graphic Quality",
51 .actual_value
= &vg
.quality_profile
,
52 .options
= vg_settings_quality_enum
, .option_count
= 3 },
53 .screenmode
= { .label
= "Type",
54 .actual_value
= &vg
.screen_mode
,
55 .options
= vg_settings_screen_mode_enum
, .option_count
=3 }
59 static void vg_settings_ui_draw_diff( ui_rect orig
){
61 ui_split( orig
, k_ui_axis_v
, -32, 0, l
, r
);
62 ui_text( r
, "*", 1, k_ui_align_middle_center
, ui_colour(k_ui_blue
) );
66 * ------------------------------------------------------------------------- */
68 static void vg_settings_ui_int( char *buf
, u32 len
){
69 for( u32 i
=0, j
=0; i
<len
; i
++ ){
70 if( ((buf
[i
] >= '0') && (buf
[i
] <= '9')) || (buf
[i
] == '\0') )
75 struct ui_textbox_callbacks
static vg_settings_ui_int_callbacks
= {
76 .change
= vg_settings_ui_int
79 static bool vg_settings_ranged_i32_valid( struct vg_setting_ranged_i32
*prop
){
80 if( prop
->new_value
< prop
->min
) return 0;
81 if( prop
->new_value
> prop
->max
) return 0;
85 static bool vg_settings_ranged_i32_diff( struct vg_setting_ranged_i32
*prop
){
86 if( prop
->new_value
!= *prop
->actual_value
) return 1;
90 static bool vg_settings_ui_ranged_i32( struct vg_setting_ranged_i32
*prop
,
93 rect_copy( rect
, orig
);
95 ui_textbox( rect
, prop
->label
, prop
->buf
, sizeof(prop
->buf
),
96 1, 0, &vg_settings_ui_int_callbacks
);
97 prop
->new_value
= atoi( prop
->buf
);
99 if( vg_settings_ranged_i32_diff( prop
) )
100 vg_settings_ui_draw_diff( orig
);
102 bool valid
= vg_settings_ranged_i32_valid( prop
);
105 ui_split( orig
, k_ui_axis_h
, -1, 0, _null
, line
);
108 ui_fill( line
, ui_colour( k_ui_red
) );
114 static void ui_settings_ranged_i32_init( struct vg_setting_ranged_i32
*prop
){
116 vg_strnull( &tmp
, prop
->buf
, sizeof(prop
->buf
) );
117 vg_strcati32( &tmp
, *prop
->actual_value
);
118 prop
->new_value
= *prop
->actual_value
;
122 * ------------------------------------------------------------------------- */
124 static bool vg_settings_enum_diff( struct vg_setting_enum
*prop
){
125 if( prop
->new_value
!= *prop
->actual_value
) return 1;
129 static bool vg_settings_enum( struct vg_setting_enum
*prop
, ui_rect rect
){
131 rect_copy( rect
, orig
);
133 ui_enum( rect
, prop
->label
,
134 prop
->options
, prop
->option_count
, &prop
->new_value
);
136 if( vg_settings_enum_diff( prop
) )
137 vg_settings_ui_draw_diff( orig
);
142 static void ui_settings_enum_init( struct vg_setting_enum
*prop
){
143 prop
->new_value
= *prop
->actual_value
;
148 static void vg_settings_ui_header( ui_rect inout_panel
, const char *name
){
150 ui_standard_widget( inout_panel
, rect
, 2 );
151 ui_text( rect
, name
, 1, k_ui_align_middle_center
, ui_colour(k_ui_fg
+3) );
154 static void vg_settings_video_apply(void){
155 if( vg_settings_enum_diff( &vg_settings
.screenmode
) ){
156 vg
.screen_mode
= vg_settings
.screenmode
.new_value
;
158 if( (vg
.screen_mode
== 0) || (vg
.screen_mode
== 1) ){
159 SDL_GetWindowPosition( vg
.window
,
160 &vg_settings
.windowed_before
[0],
161 &vg_settings
.windowed_before
[1] );
162 vg_settings
.windowed_before
[2] = vg
.window_x
;
163 vg_settings
.windowed_before
[3] = vg
.window_y
;
165 SDL_DisplayMode video_mode
;
166 if( SDL_GetDesktopDisplayMode( 0, &video_mode
) ){
167 vg_error("SDL_GetDesktopDisplayMode failed: %s\n", SDL_GetError());
170 //vg.display_refresh_rate = video_mode.refresh_rate;
171 vg
.window_x
= video_mode
.w
;
172 vg
.window_y
= video_mode
.h
;
174 SDL_SetWindowResizable( vg
.window
, SDL_FALSE
);
175 SDL_SetWindowSize( vg
.window
, vg
.window_x
, vg
.window_y
);
178 if( vg
.screen_mode
== 0 )
179 SDL_SetWindowFullscreen( vg
.window
, SDL_WINDOW_FULLSCREEN_DESKTOP
);
180 if( vg
.screen_mode
== 1 )
181 SDL_SetWindowFullscreen( vg
.window
, SDL_WINDOW_FULLSCREEN
);
182 if( vg
.screen_mode
== 2 ){
183 SDL_SetWindowFullscreen( vg
.window
, 0 );
184 SDL_SetWindowSize( vg
.window
,
185 vg_settings
.windowed_before
[2],
186 vg_settings
.windowed_before
[3] );
187 SDL_SetWindowPosition( vg
.window
,
188 vg_settings
.windowed_before
[0],
189 vg_settings
.windowed_before
[1] );
190 SDL_SetWindowResizable( vg
.window
, SDL_TRUE
);
194 vg
.fps_limit
= vg_settings
.fps_limit
.new_value
;
195 vg
.quality_profile
= vg_settings
.quality
.new_value
;
196 vg
.vsync
= vg_settings
.vsync
.new_value
;
199 static void aaaaaaaaaaaaaaaaa( ui_rect r
);
200 static void vg_settings_video_gui( ui_rect panel
){
203 ui_standard_widget( panel
, rq
, 1 );
204 vg_settings_enum( &vg_settings
.quality
, rq
);
208 if( vg
.vsync_feature
== k_vsync_feature_error
){
209 ui_info( panel
, "There was an error activating vsync feature." );
214 vg_settings_ui_header( panel
, "Frame Timing" );
216 ui_standard_widget( panel
, duo
, 1 );
217 ui_split_ratio( duo
, k_ui_axis_v
, 0.5f
, 16, d0
, d1
);
219 vg_settings_enum( &vg_settings
.vsync
, d0
);
220 validated
&= vg_settings_ui_ranged_i32( &vg_settings
.fps_limit
, d1
);
222 ui_standard_widget( panel
, duo
, 10 );
223 aaaaaaaaaaaaaaaaa( duo
);
226 vg_settings_ui_header( panel
, "Window Specification" );
228 ui_standard_widget( panel
, duo
, 1 );
229 vg_settings_enum( &vg_settings
.screenmode
, duo
);
233 ui_px height
= (vg_ui
.font
->glyph_height
+ 18) * k_ui_scale
;
234 ui_split( panel
, k_ui_axis_h
, -height
, k_ui_padding
,
237 const char *string
= "Apply";
239 if( ui_button( last_row
, string
) == 1 )
240 vg_settings_video_apply();
244 ui_standard_widget( last_row
, rect
, 1 );
245 ui_fill( rect
, ui_colour( k_ui_bg
+1 ) );
246 ui_outline( rect
, -1, ui_colour( k_ui_red
), 0 );
248 ui_rect t
= { 0,0, ui_text_line_width( string
), 14 };
249 ui_rect_center( rect
, t
);
250 ui_text( t
, string
, 1, k_ui_align_left
, ui_colour(k_ui_fg
+3) );
254 static void vg_settings_gui(void){
256 ui_rect screen
= { 0, 0, vg
.window_x
, vg
.window_y
};
257 ui_rect window
= { 0, 0, 1000, 700 };
258 ui_rect_center( screen
, window
);
259 vg_ui
.wants_mouse
= 1;
261 ui_fill( window
, ui_colour( k_ui_bg
+1 ) );
262 ui_outline( window
, 1, ui_colour( k_ui_bg
+7 ), 0 );
264 ui_rect title
, panel
;
265 ui_split( window
, k_ui_axis_h
, 28, 0, title
, panel
);
266 ui_fill( title
, ui_colour( k_ui_bg
+7 ) );
267 ui_text( title
, "Settings", 1, k_ui_align_middle_center
,
268 ui_colourcont(k_ui_bg
+7) );
271 ui_split( title
, k_ui_axis_v
, title
[2]-title
[3], 2, title
, quit_button
);
273 if( ui_button_text( quit_button
, "X", 1 ) == 1 ){
274 vg
.settings_open
= 0;
278 ui_rect_pad( panel
, (ui_px
[2]){ 8, 8 } );
281 ui_tabs( panel
, panel
, (const char *[]){ "video", "audio", "game" },
285 vg_settings_video_gui( panel
);
289 static int cmd_vg_settings_toggle( int argc
, const char *argv
[] ){
290 vg
.settings_open
= !vg
.settings_open
;
292 if( vg
.settings_open
){
293 ui_settings_ranged_i32_init( &vg_settings
.fps_limit
);
294 ui_settings_enum_init( &vg_settings
.vsync
);
295 ui_settings_enum_init( &vg_settings
.quality
);
296 ui_settings_enum_init( &vg_settings
.screenmode
);
301 #endif /* VG_SETTINGS_MENU_H */