X-Git-Url: https://deadsoftware.ru/gitweb?p=flatwaifu.git;a=blobdiff_plain;f=src%2Fconfig.c;h=1980bc61ec2986f13e9d82bfe4100a47abecfa9e;hp=2985a4f8e6e0e427736db2c2a700a49e873601c4;hb=4a99fe51561ca331df54512eb25c502d0fcd2b55;hpb=66126249063c1a47b3e48e76e7178e05f838f9ea diff --git a/src/config.c b/src/config.c index 2985a4f..1980bc6 100644 --- a/src/config.c +++ b/src/config.c @@ -24,274 +24,240 @@ #include #include #include -//#include -//#include -#include "config.h" -#include "vga.h" -#include "error.h" -#include "sound.h" -#include "keyb.h" +#include +#include +#include "system.h" #include "files.h" -#include "memory.h" -#include "view.h" -#include "player.h" +#include "input.h" -#include - -extern byte _warp,fastdraw,nomon; -extern int mem_chk_sz; - -enum{NONE,BYTE,WORD,DWORD,STRING,SW_ON,SW_OFF,FILES,KEY}; - -typedef struct{ - char *par,*cfg; - void *p; - byte t,o; -}cfg_t; - - -byte cheat=0; - -byte shot_vga=0; - - -char cd_path[128]=""; - -static cfg_t cfg[]={ - {"file",NULL,NULL,FILES,0}, - {"cheat",NULL,&cheat,SW_ON,0}, - {"vga","screenshot",&shot_vga,SW_ON,0}, - {"sndvol","sound_volume",&snd_vol,WORD,0}, - {"musvol","music_volume",&mus_vol,WORD,0}, - {"fullscr","fullscreen",&fullscreen,SW_ON,0}, - {"window",NULL,&fullscreen,SW_OFF,0}, - {NULL,"sky",&w_horiz,SW_ON,0}, - {"mon",NULL,&nomon,SW_OFF,0}, - {"gamma","gamma",&gammaa,DWORD,0}, - {"warp",NULL,&_warp,BYTE,0}, - {"width","screen_width",&SCRW,DWORD,0}, - {"height","screen_height",&SCRH,DWORD,0}, - {NULL,"music_random",&music_random,SW_ON,0}, - {NULL,"music_time",&music_time,DWORD,0}, - {NULL,"music_fade",&music_fade,DWORD,0}, - {NULL,"pl1_left", &pl1.kl,KEY,0}, - {NULL,"pl1_right",&pl1.kr,KEY,0}, - {NULL,"pl1_up", &pl1.ku,KEY,0}, - {NULL,"pl1_down", &pl1.kd,KEY,0}, - {NULL,"pl1_jump", &pl1.kj,KEY,0}, - {NULL,"pl1_fire", &pl1.kf,KEY,0}, - {NULL,"pl1_next", &pl1.kwr,KEY,0}, - {NULL,"pl1_prev", &pl1.kwl,KEY,0}, - {NULL,"pl1_use", &pl1.kp,KEY,0}, - {NULL,"pl2_left", &pl2.kl,KEY,0}, - {NULL,"pl2_right",&pl2.kr,KEY,0}, - {NULL,"pl2_up", &pl2.ku,KEY,0}, - {NULL,"pl2_down", &pl2.kd,KEY,0}, - {NULL,"pl2_jump", &pl2.kj,KEY,0}, - {NULL,"pl2_fire", &pl2.kf,KEY,0}, - {NULL,"pl2_next", &pl2.kwr,KEY,0}, - {NULL,"pl2_prev", &pl2.kwl,KEY,0}, - {NULL,"pl2_use", &pl2.kp,KEY,0}, - {"config",NULL,cfg_file,STRING,0}, - {NULL,NULL,NONE,0} -}; +static FILE *f; +static int ch; +const cfg_t *CFG_find_entry (const char *key, const cfg_t *cfg) { + assert(key != NULL); + if (cfg != NULL) { + int i = 0; + while (cfg[i].cfg && strcasecmp(cfg[i].cfg, key) != 0) { + i++; + } + return cfg[i].cfg ? &cfg[i] : NULL; + } else { + return NULL; + } +} -char cfg_file[128]="default.cfg"; +int CFG_update_key (const char *key, const char *value, const cfg_t *cfg) { + assert(key != NULL); + assert(value != NULL); + const cfg_t *entry = CFG_find_entry(key, cfg); + if (entry != NULL) { + void *p = entry->p; + switch (entry->t) { + case Y_BYTE: *(byte*)p = atoi(value); break; + case Y_WORD: *(word*)p = atoi(value); break; + case Y_DWORD: *(dword*)p = atoi(value); break; + case Y_STRING: strcpy(p, value); break; // TODO fix this security problem + case Y_SW_ON: *(byte*)p = strcasecmp(value, "on") == 0 ? 1 : 0; break; + case Y_SW_OFF: *(byte*)p = strcasecmp(value, "off") == 0 ? 1 : 0; break; + case Y_FILES: F_addwad(value); break; + case Y_KEY: *(int*)p = I_string_to_key(value); break; + default: assert(0); // unknown type -> something broken + } + //logo("CFG_update_key: [%s] = [%s]\n", key, value); + return 1; + } else { + return 0; + } +} -static char buf[256]; +/* --- parser --- */ -void CFG_args(int argc, char *argv[]) { - int j; - dword n; - char *s; +int CFG_open_iterator (const char *name) { + assert(f == NULL); + f = fopen(name, "rb"); + if (f != NULL) { + ch = fgetc(f); + } + return f != NULL; +} - logo("CFG_args: проверка командной строки\n"); +static void CFG_skip_space (void) { + while (feof(f) == 0 && isspace(ch)) { + ch = fgetc(f); + } +} - int i; - char *pbuf = buf; - for (i=1;i0) if(cfg[j-1].t==SW_OFF && cfg[j-1].p==cfg[j].p) cfg[j-1].o=1; - break; - case SW_OFF: - *((byte *)cfg[j].p)=OFF; - if(cfg[j+1].t==SW_ON && cfg[j+1].p==cfg[j].p) cfg[j+1].o=1; - if(j>0) if(cfg[j-1].t==SW_ON && cfg[j-1].p==cfg[j].p) cfg[j-1].o=1; - break; - case FILES: - for(s=strtok(NULL," \r\n\t");s;s=strtok(NULL," \r\n\t")) { - if(*s=='/' || *s=='-') goto next; -#ifdef DEMO - logo(" %s НЕ подключен!\n",s); -#else - F_addwad(s); -#endif - }break; - default: - ERR_failinit("!!! Неизвестный тип в cfg !!!"); - } - cfg[j].o=1;break; +int CFG_scan_iterator (char *key, int keylen, char *value, int valuelen) { + assert(key != NULL); + assert(keylen > 0); + assert(value != NULL); + assert(valuelen > 0); + int i; + int found = 0; + while (feof(f) == 0 && found == 0) { + CFG_skip_space(); + if (ch == ';') { + CFG_skip_line(); + } else if (feof(f) == 0) { + found = 1; + i = 0; + while (feof(f) == 0 && isspace(ch) == 0 && ch != '=') { + if (i < keylen - 1) { + key[i] = ch; + i += 1; + } + ch = fgetc(f); + } + key[i] = 0; + CFG_skip_space(); + if (feof(f) == 0 && ch == '=') { + ch = fgetc(f); + CFG_skip_space(); + } + i = 0; + while (feof(f) == 0 && ch != '\n' && ch != '\r') { + if (i < valuelen - 1) { + value[i] = ch; + i += 1; + } + ch = fgetc(f); + } + value[i] = 0; + CFG_skip_line(); } } + return found; } -int get_key(char *name) -{ - int i; - for(i=1; i= 0); + assert(cfg != NULL); + int i; + char key[64]; + char value[64]; + assert(name != NULL); + if (CFG_open_iterator(name)) { + while (CFG_scan_iterator(key, 64, value, 64)) { + i = 0; + while (i < n && CFG_update_key(key, value, cfg[i]) == 0) { + i++; + } } + CFG_close_iterator(); + return 1; + } else { return 0; + } } -void CFG_load(void) { - int j; - FILE *h; - dword n; - char s[128]; - char *p1,*p2; - char pc[50]; - char *e = getenv("HOME"); - strncpy(pc, e, 30); - strcpy(&pc[strlen(pc)], "/default.cfg"); - if (!fexists(pc)) { - strcpy(pc, "default.cfg"); - if (!fexists(pc)) { - strcpy(pc, "/usr/share/doom2d-rembo/default.cfg"); - if (!fexists(pc)) { - logo("default.cfg not found\n"); - return; - } - } - } - logo("CFG_load: загрузка конфигурации из %s\n",pc); - if((h=fopen(pc,"rb"))==NULL) { - perror("Cannot open file");return; - } - while(!feof(h)) { - F_readstr(h,s,127); - if(*s==';' || s[1]==';') continue; // comment - if(!(p1=strtok(s,"\r\n\t=;"))) continue;//if(!(p1=strtok(s,"\r\n\t =;"))) continue; - if(!(p2=strtok(NULL,"\r\n\t=;"))) continue;//if(!(p2=strtok(NULL,"\r\n\t =;"))) continue; - for(j=0;cfg[j].t;++j) if(cfg[j].cfg && !cfg[j].o) - if(strcasecmp(p1,cfg[j].cfg)==0) { - switch(cfg[j].t) { - case BYTE: - n=strtol(p2,NULL,0); - *((byte *)cfg[j].p)=(byte)n; - break; - case WORD: - n=strtol(p2,NULL,0); - *((word *)cfg[j].p)=(word)n; - break; - case DWORD: - n=strtol(p2,NULL,0); - *((dword *)cfg[j].p)=n; - break; - case STRING: - strcpy((char *)cfg[j].p,p2); - break; - case SW_ON: - case SW_OFF: - if(strcasecmp(p2,"ON")==0) {*((byte *)cfg[j].p)=ON;break;} - if(strcasecmp(p2,"OFF")==0) {*((byte *)cfg[j].p)=OFF;break;} - *((byte *)cfg[j].p)=strtol(p2,NULL,0); - break; - case FILES: - break; +/* --- writer --- */ - case KEY: - { - int k = get_key(p2); - if (k) { - *((int *)cfg[j].p)=k; - } - else { - logo("Unknown key in cfg: %s=%s\n",p1,p2); - logo("List available key names:\n"); - int i; - for(i=1; icfg; + if (key != NULL) { + switch (entry->t) { + case Y_BYTE: + snprintf(buf, 16, "%i", *(byte*)entry->p); + CFG_write_key_value(f, key, buf); break; - - default: - ERR_failinit("!!! Неизвестный тип в cfg !!!"); - } - break; + case Y_WORD: + snprintf(buf, 16, "%i", *(word*)entry->p); + CFG_write_key_value(f, key, buf); + break; + case Y_DWORD: + snprintf(buf, 16, "%i", *(dword*)entry->p); + CFG_write_key_value(f, key, buf); + break; + case Y_STRING: + CFG_write_key_value(f, key, entry->p); + break; + case Y_SW_ON: + case Y_SW_OFF: + str = *(byte*)entry->p ? "on" : "off"; + CFG_write_key_value(f, key, str); + break; + case Y_KEY: + str = I_key_to_string(*(int*)entry->p); + CFG_write_key_value(f, key, str); + break; + case Y_FILES: return 1; // ignore + case 0: return 0; // end + default: assert(0); // unknown type -> something broken } } - fclose(h); + return entry->t == 0 ? 0 : 1; } -void CFG_save(void) { -/* - char s[140],str[140]; - char *p; - FILE *h,*oh; - - remove("CONFIG.ZZZ"); - if(rename(cfg_file,"CONFIG.ZZZ")) return; - if(!(h=fopen("CONFIG.ZZZ","rt"))) - {rename("CONFIG.ZZZ",cfg_file);return;} - if(!(oh=fopen(cfg_file,"wt"))) - {fclose(h);rename("CONFIG.ZZZ",cfg_file);return;} - for(;;) { - if(!fgets(s,128,h)) break; - strcpy(str,s); - if(!(p=strtok(str,"\r\n\t =;"))) {fprintf(oh,"%s",s);continue;} - if(strcasecmp(p,"sound_volume")==0) - sprintf(s,"sound_volume=%d\n",snd_vol); - else if(strcasecmp(p,"music_volume")==0) - sprintf(s,"music_volume=%d\n",mus_vol); - else if(strcasecmp(p,"gamma")==0) - sprintf(s,"gamma=%d\n",gammaa); - else if(strcasecmp(p,"sound_interp")==0) - sprintf(s,"sound_interp=%s\n",s_interp?"on":"off"); - fprintf(oh,"%s",s); +int CFG_update_config (const char *old, const char *new, int n, const cfg_t **cfg, const char *msg) { + assert(old != NULL); + assert(new != NULL); + assert(n >= 0); + assert(cfg != NULL); + int i, j; + char key[64]; + char value[64]; + FILE *nf = fopen(new, "wb"); + if (nf != NULL) { + if (msg != NULL) { + fwrite("; ", 2, 1, nf); + fwrite(msg, strlen(msg), 1, nf); + fwrite("\n", 1, 1, nf); + } + if (CFG_open_iterator(old)) { + while (CFG_scan_iterator(key, 64, value, 64)) { + i = 0; + while (i < n && CFG_find_entry(key, cfg[i]) == NULL) { + i++; + } + if (i >= n) { + CFG_write_key_value(nf, key, value); + } + } + CFG_close_iterator(); + } + for (j = 0; j < n; j++) { + if (cfg[j] != NULL) { + i = 0; + while (CFG_write_entry(nf, &cfg[j][i])) { + i++; + } + } + } + fclose(nf); } - fclose(oh);fclose(h); - remove("CONFIG.ZZZ"); -*/ + return nf != NULL; }