diff --git a/README.md b/README.md index fb983b0..f344bb2 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ You will need to compile the following by yourself, or get hold of precompiled b * libdeflate * enet -Follow the instructions on their project page, then place produced static libraries in `lib/`. +Follow the instructions on their project page, then place produced static libraries in `libs/`. Some files need to be copied to the `src/` directory. diff --git a/resources/png/ui/arrow.png b/resources/png/ui/arrow.png new file mode 100644 index 0000000..78a0284 Binary files /dev/null and b/resources/png/ui/arrow.png differ diff --git a/resources/png/ui/box_check.png b/resources/png/ui/box_check.png new file mode 100644 index 0000000..1ebeacb Binary files /dev/null and b/resources/png/ui/box_check.png differ diff --git a/resources/png/ui/box_empty.png b/resources/png/ui/box_empty.png new file mode 100644 index 0000000..ebff8fd Binary files /dev/null and b/resources/png/ui/box_empty.png differ diff --git a/src/common.h b/src/common.h index 2f292c8..f22007c 100644 --- a/src/common.h +++ b/src/common.h @@ -66,6 +66,7 @@ #include #include #include +#include #include "lodepng/lodepng.h" #include "libdeflate.h" diff --git a/src/config.c b/src/config.c index 378f34e..2330360 100644 --- a/src/config.c +++ b/src/config.c @@ -21,6 +21,7 @@ struct RENDER_OPTIONS settings; struct list config_keys; +struct list config_settings; static int config_read_key(void* user, const char* section, const char* name, const char* value) { if(!strcmp(section,"client")) { @@ -46,7 +47,7 @@ static int config_read_key(void* user, const char* section, const char* name, co settings.vsync = atoi(value); } if(!strcmp(name,"mouse_sensitivity")) { - settings.mouse_sensitivity = atof(value)/5.0F*MOUSE_SENSITIVITY; + settings.mouse_sensitivity = atof(value); } if(!strcmp(name,"show_news")) { settings.show_news = atoi(value); @@ -160,7 +161,7 @@ void config_reload() { config_register_key(WINDOW_KEY_COMMAND,SDLK_SLASH,"chat_command",0); config_register_key(WINDOW_KEY_HIDEHUD,SDLK_F6,"hide_hud",1); #endif - + #ifdef USE_GLFW config_register_key(WINDOW_KEY_UP,GLFW_KEY_W,"move_forward",0); config_register_key(WINDOW_KEY_DOWN,GLFW_KEY_S,"move_backward",0); @@ -204,5 +205,75 @@ void config_reload() { config_register_key(WINDOW_KEY_HIDEHUD,GLFW_KEY_F6,"hide_hud",1); #endif + list_create(&config_settings,sizeof(struct config_setting)); + + list_add(&config_settings,&(struct config_setting){ + .value=settings.name, + .type=CONFIG_TYPE_STRING, + .max=sizeof(settings.name)-1, + .name="Name", + .help="ingame player name" + }); + list_add(&config_settings,&(struct config_setting){ + .value=&settings.mouse_sensitivity, + .type=CONFIG_TYPE_FLOAT, + .max=INT_MAX, + .name="Mouse sensitivity" + }); + list_add(&config_settings,&(struct config_setting){ + .value=&settings.window_width, + .type=CONFIG_TYPE_INT, + .max=INT_MAX, + .name="Game width", + .defaults=640,800,854,1024,1280,1920, + .defaults_length=6 + }); + list_add(&config_settings,&(struct config_setting){ + .value=&settings.window_height, + .type=CONFIG_TYPE_INT, + .max=INT_MAX, + .name="Game height", + .defaults=480,600,720,768,1024,1080, + .defaults_length=6 + }); + list_add(&config_settings,&(struct config_setting){ + .value=&settings.vsync, + .type=CONFIG_TYPE_INT, + .max=INT_MAX, + .name="V-Sync", + .help="limits your game's fps", + .defaults=0,1,60,120,240, + .defaults_length=5 + }); + list_add(&config_settings,&(struct config_setting){ + .value=&settings.fullscreen, + .type=CONFIG_TYPE_INT, + .max=1, + .name="Fullscreen" + }); + list_add(&config_settings,&(struct config_setting){ + .value=&settings.multisamples, + .type=CONFIG_TYPE_INT, + .max=16, + .name="Multisamples", + .help="smooth out block edges", + .defaults=0,1,2,4,8,16, + .defaults_length=6 + }); + list_add(&config_settings,&(struct config_setting){ + .value=&settings.show_fps, + .type=CONFIG_TYPE_INT, + .max=1, + .name="Show fps", + .help="show your current fps and ping" + }); + list_add(&config_settings,&(struct config_setting){ + .value=&settings.show_news, + .type=CONFIG_TYPE_INT, + .max=1, + .name="Show news", + .help="opens the bns news on exit" + }); + ini_parse("config.ini",config_read_key,NULL); } diff --git a/src/config.h b/src/config.h index b0ee81f..862849c 100644 --- a/src/config.h +++ b/src/config.h @@ -18,7 +18,7 @@ */ extern struct RENDER_OPTIONS { - char name[17]; + char name[16]; int opengl14; int color_correction; int shadow_entities; @@ -29,11 +29,11 @@ extern struct RENDER_OPTIONS { unsigned char multisamples; int player_arms; int fullscreen; - int greedy_meshing; - int vsync; - float mouse_sensitivity; - int show_news; - int show_fps; + int greedy_meshing; + int vsync; + float mouse_sensitivity; + int show_news; + int show_fps; } settings; extern struct list config_keys; @@ -45,6 +45,24 @@ struct config_key_pair { char name[32]; }; +enum { + CONFIG_TYPE_STRING, + CONFIG_TYPE_INT, + CONFIG_TYPE_FLOAT +}; + +struct config_setting { + void* value; + int type; + int max; + char name[32]; + char help[32]; + int defaults[8]; + int defaults_length; +}; + +extern struct list config_settings; + void config_register_key(int internal, int def, const char* name, int toggle); int config_key_translate(int key, int dir); struct config_key_pair* config_key(int key); diff --git a/src/hud.c b/src/hud.c index fb578a8..a5a3779 100644 --- a/src/hud.c +++ b/src/hud.c @@ -860,8 +860,8 @@ static void hud_ingame_mouselocation(double x, double y) { s = 0.5F; } - camera_rot_x -= dx*settings.mouse_sensitivity*s; - camera_rot_y += dy*settings.mouse_sensitivity*s; + camera_rot_x -= dx*settings.mouse_sensitivity/5.0F*MOUSE_SENSITIVITY*s; + camera_rot_y += dy*settings.mouse_sensitivity/5.0F*MOUSE_SENSITIVITY*s; camera_overflow_adjust(); } @@ -1588,17 +1588,17 @@ static void hud_serverlist_scroll(double yoffset) { } static void server_c(char* s) { - if(file_exists(s)) { - map_vxl_load(file_load(s),map_colors); - chunk_rebuild_all(); - camera_mode = CAMERAMODE_FPS; - players[local_player_id].pos.x = map_size_x/2.0F; - players[local_player_id].pos.y = map_size_y-1.0F; - players[local_player_id].pos.z = map_size_z/2.0F; - hud_change(&hud_ingame); - } else { - hud_change(network_connect_string(s)?&hud_ingame:&hud_serverlist); - } + if(file_exists(s)) { + map_vxl_load(file_load(s),map_colors); + chunk_rebuild_all(); + camera_mode = CAMERAMODE_FPS; + players[local_player_id].pos.x = map_size_x/2.0F; + players[local_player_id].pos.y = map_size_y-1.0F; + players[local_player_id].pos.z = map_size_z/2.0F; + hud_change(&hud_ingame); + } else { + hud_change(network_connect_string(s)?&hud_ingame:&hud_serverlist); + } } static void hud_serverlist_mouseclick(int button, int action, int mods) { @@ -1663,6 +1663,8 @@ struct hud hud_serverlist = { /* HUD_SETTINGS START */ +static struct config_setting* hud_settings_edit = NULL; + static void hud_settings_render(float scalex, float scaley) { glColor3f(0.5F,0.5F,0.5F); float t = window_time()*0.03125F; @@ -1678,10 +1680,122 @@ static void hud_settings_render(float scalex, float scaley) { glColor3f(0.5F,0.5F,0.5F); font_centered((settings.window_width-600*scaley)/2.0F+210*scaley,535*scaley-12*scaley,20*scaley,"Controls"); font_centered((settings.window_width-600*scaley)/2.0F+320*scaley,535*scaley-12*scaley,20*scaley,"Server list"); + + for(int k=0;kname); + + char tmp[32]; + switch(a->type) { + case CONFIG_TYPE_STRING: + glColor3f(1.0F,1.0F,1.0F); + texture_draw_sector(&texture_ui_input,(settings.window_width-600*scaley)/2.0F+174*scaley,(466-40*k)*scaley,8*scaley,32*scaley,0.0F,0.0F,0.25F,1.0F); + texture_draw_sector(&texture_ui_input,(settings.window_width-600*scaley)/2.0F+182*scaley,(466-40*k)*scaley,200*scaley,32*scaley,0.25F,0.0F,0.5F,1.0F); + texture_draw_sector(&texture_ui_input,settings.window_width/2.0F-300*scaley+382*scaley,(466-40*k)*scaley,8*scaley,32*scaley,0.75F,0.0F,0.25F,1.0F); + if(hud_settings_edit==a) + glColor3f(1.0F,0.0F,0.0F); + font_render((settings.window_width-600*scaley)/2.0F+182*scaley,(460-40*k)*scaley,20*scaley,(hud_settings_edit==a)?chat[0][0]:a->value); + break; + case CONFIG_TYPE_INT: + glColor3f(1.0F,1.0F,1.0F); + if(hud_settings_edit==a) + strcpy(tmp,chat[0][0]); + else + sprintf(tmp,"%i",*(int*)a->value); + if(a->max==1) { + texture_draw_rotated(*(int*)a->value?&texture_ui_box_check:&texture_ui_box_empty, + (settings.window_width-600*scaley)/2.0F+240*scaley,(450-40*k)*scaley,32*scaley,32*scaley,0.0F); + } else { + texture_draw_rotated(&texture_ui_arrow,(settings.window_width-600*scaley)/2.0F+290*scaley,(450-40*k)*scaley,32*scaley,32*scaley,0.0F); + texture_draw_rotated(&texture_ui_arrow,(settings.window_width-600*scaley)/2.0F+190*scaley,(450-40*k)*scaley,32*scaley,32*scaley,PI); + if(hud_settings_edit==a) + glColor3f(1.0F,0.0F,0.0F); + font_centered((settings.window_width-600*scaley)/2.0F+240*scaley,(460-40*k)*scaley,20*scaley,tmp); + } + break; + case CONFIG_TYPE_FLOAT: + glColor3f(1.0F,1.0F,1.0F); + texture_draw_rotated(&texture_ui_arrow,(settings.window_width-600*scaley)/2.0F+290*scaley,(450-40*k)*scaley,32*scaley,32*scaley,0.0F); + texture_draw_rotated(&texture_ui_arrow,(settings.window_width-600*scaley)/2.0F+190*scaley,(450-40*k)*scaley,32*scaley,32*scaley,PI); + if(hud_settings_edit==a) { + glColor3f(1.0F,0.0F,0.0F); + strcpy(tmp,chat[0][0]); + } else { + sprintf(tmp,"%0.2f",*(float*)a->value); + } + font_centered((settings.window_width-600*scaley)/2.0F+240*scaley,(460-40*k)*scaley,20*scaley,tmp); + break; + } + } +} + +static int is_inside_centered(double mx, double my, int x, int y, int w, int h) { + return mx>=x-w/2 && mx=y-h/2 && my=x && mx=y && my='0' && *x<='9')) + return 0; + x++; + } + return 1; +} + +static int is_float(char* x) { + char* decimalpoint = strchr(x,'.'); + if(!decimalpoint) { + return is_int(x); + } else { + *decimalpoint = 0; + if(is_int(x)) { + if(is_int(decimalpoint+1)) { + *decimalpoint = '.'; + return 1; + } else { + return 0; + } + } else { + return 0; + } + } +} + +static void hud_settings_keyboard(int key, int action, int mods) { + if(hud_settings_edit && action!=WINDOW_RELEASE && key==WINDOW_KEY_BACKSPACE) { + size_t text_len = strlen(chat[0][0]); + if(text_len>0){ + chat[0][0][text_len-1] = 0; + } + } } static void hud_settings_mouseclick(int button, int action, int mods) { if(action==WINDOW_PRESS) { + if(hud_settings_edit) { + if(strlen(chat[0][0])) { + switch(hud_settings_edit->type) { + case CONFIG_TYPE_INT: + if(is_int(chat[0][0])) + *(int*)hud_settings_edit->value = max(min(strtol(chat[0][0],NULL,10),hud_settings_edit->max),0); + break; + case CONFIG_TYPE_FLOAT: + if(is_float(chat[0][0])) + *(float*)hud_settings_edit->value = max(min(strtod(chat[0][0],NULL),hud_settings_edit->max),0); + break; + case CONFIG_TYPE_STRING: + strncpy(hud_settings_edit->value,chat[0][0],hud_settings_edit->max); + break; + } + } + hud_settings_edit = NULL; + } + double x,y; window_mouseloc(&x,&y); float scaley = settings.window_height/600.0F; @@ -1697,6 +1811,79 @@ static void hud_settings_mouseclick(int button, int action, int mods) { && y>=77*scaley && y<97*scaley) { hud_change(&hud_controls); } + + y = settings.window_height-y; + + for(int k=0;ktype==CONFIG_TYPE_INT && a->max==1)) { + hud_settings_edit = a; + switch(a->type) { + case CONFIG_TYPE_INT: + sprintf(chat[0][0],"%i",*(int*)a->value); + break; + case CONFIG_TYPE_FLOAT: + sprintf(chat[0][0],"%0.2f",*(float*)a->value); + break; + case CONFIG_TYPE_STRING: + strcpy(chat[0][0],a->value); + break; + } + } + switch(a->type) { + case CONFIG_TYPE_INT: + if(a->max==1) { + if(is_inside_centered(x,y, + (settings.window_width-600*scaley)/2.0F+240*scaley, + (450-40*k)*scaley,32*scaley,32*scaley)) { //checkbox pressed + *(int*)a->value = !*(int*)a->value; + } + } else { + if(is_inside_centered(x,y, + (settings.window_width-600*scaley)/2.0F+290*scaley, + (450-40*k)*scaley,32*scaley,32*scaley)) { //right arrow pressed + int next = (*(int*)a->value)+1; + int diff = INT_MAX; + for(int l=0;ldefaults_length;l++) { + if(a->defaults[l]>*(int*)a->value && a->defaults[l]-*(int*)a->valuedefaults[l]-*(int*)a->value; + next = a->defaults[l]; + } + } + *(int*)a->value = min(next,a->max); + } + if(is_inside_centered(x,y, + (settings.window_width-600*scaley)/2.0F+190*scaley, + (450-40*k)*scaley,32*scaley,32*scaley)) { //left arrow pressed + int next = (*(int*)a->value)-1; + int diff = INT_MAX; + for(int l=0;ldefaults_length;l++) { + if(a->defaults[l]<*(int*)a->value && *(int*)a->value-a->defaults[l]value-a->defaults[l]; + next = a->defaults[l]; + } + } + *(int*)a->value = max(next,0); + } + } + break; + case CONFIG_TYPE_FLOAT: + if(is_inside_centered(x,y, + (settings.window_width-600*scaley)/2.0F+290*scaley, + (450-40*k)*scaley,32*scaley,32*scaley)) { //right arrow pressed + *(float*)a->value = min((*(float*)a->value)+0.1F,a->max); + } + if(is_inside_centered(x,y, + (settings.window_width-600*scaley)/2.0F+190*scaley, + (450-40*k)*scaley,32*scaley,32*scaley)) { //left arrow pressed + *(float*)a->value = max((*(float*)a->value)-0.1F,0); + } + break; + } + } } } @@ -1704,7 +1891,7 @@ struct hud hud_settings = { (void*)NULL, (void*)NULL, hud_settings_render, - (void*)NULL, + hud_settings_keyboard, (void*)NULL, hud_settings_mouseclick, (void*)NULL, @@ -1713,7 +1900,7 @@ struct hud hud_settings = { }; -/* HUD_SETTINGS START */ +/* HUD_CONTROLS START */ static void hud_controls_render(float scalex, float scaley) { glColor3f(0.5F,0.5F,0.5F); diff --git a/src/texture.c b/src/texture.c index 91f9381..ba84554 100644 --- a/src/texture.c +++ b/src/texture.c @@ -53,6 +53,9 @@ struct texture texture_ui_join; struct texture texture_ui_reload; struct texture texture_ui_bg; struct texture texture_ui_input; +struct texture texture_ui_box_empty; +struct texture texture_ui_box_check; +struct texture texture_ui_arrow; void texture_filter(struct texture* t, int filter) { glBindTexture(GL_TEXTURE_2D,t->texture_id); @@ -326,6 +329,10 @@ void texture_init() { texture_create(&texture_ui_bg,"png/ui/bg.png"); texture_create(&texture_ui_input,"png/ui/input.png"); + texture_create(&texture_ui_box_empty,"png/ui/box_empty.png"); + texture_create(&texture_ui_box_check,"png/ui/box_check.png"); + texture_create(&texture_ui_arrow,"png/ui/arrow.png"); + unsigned int* pixels = malloc(64*64*sizeof(unsigned int)); CHECK_ALLOCATION_ERROR(pixels) diff --git a/src/texture.h b/src/texture.h index 6dea6be..3d30948 100644 --- a/src/texture.h +++ b/src/texture.h @@ -55,6 +55,9 @@ extern struct texture texture_ui_join; extern struct texture texture_ui_reload; extern struct texture texture_ui_bg; extern struct texture texture_ui_input; +extern struct texture texture_ui_box_empty; +extern struct texture texture_ui_box_check; +extern struct texture texture_ui_arrow; #define TEXTURE_FILTER_NEAREST 0 #define TEXTURE_FILTER_LINEAR 1