1 /* vim:expandtab:ts=2 sw=2:
2 */
3 /* Grafx2 - The Ultimate 256-color bitmap paint program
4
5 Copyright owned by various GrafX2 authors, see COPYRIGHT.txt for details.
6
7 Grafx2 is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; version 2
10 of the License.
11
12 Grafx2 is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Grafx2; if not, see <http://www.gnu.org/licenses/>
19 */
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <ctype.h>
24 #if defined(_MSC_VER)
25 #define strdup _strdup
26 #endif
27
28 #include "const.h"
29 #include "errors.h"
30 #include "global.h"
31 #include "misc.h"
32 #include "readini.h"
33 #include "setup.h"
34 #include "realpath.h"
35 #include "io.h"
36 #include "windows.h"
37 #include "gfx2log.h"
38 #include "gfx2mem.h"
39
40
41 /**
42 * Clean a line of the ini file.
43 *
44 * - Suppress all leading and trailing spaces
45 * - convert the key to uppercase
46 *
47 * Comments start with ";". The result will be in the following format :
48 * <tt>KEY=value</tt>
49 *
50 * @param[in,out] str
51 * @param[in] keep_comments if set, the comments are kept
52 */
Load_INI_clear_string(char * str,byte keep_comments)53 void Load_INI_clear_string(char * str, byte keep_comments)
54 {
55 int index;
56 int equal_found=0;
57
58 for (index=0;str[index]!='\0';)
59 {
60 if (str[index]=='=')
61 {
62 equal_found=1;
63 index++;
64 // On enleve les espaces après le '='
65 while (str[index]==' ' || str[index]=='\t')
66 memmove(str+index,str+index+1,strlen(str+index));
67 }
68 else if ((str[index]==' ' && !equal_found) || (str[index]=='\t'))
69 {
70 // Suppression d'un espace ou d'un tab:
71 memmove(str+index,str+index+1,strlen(str+index));
72 }
73 else if (!keep_comments && ((str[index]==';') || (str[index]=='#')))
74 {
75 // Comment
76 str[index]='\0';
77 }
78 else if ((str[index]=='\r') || (str[index]=='\n'))
79 {
80 // Line break
81 str[index]='\0';
82 }
83 else
84 {
85 if (!equal_found)
86 {
87 // Passage en majuscule d'un caractère:
88 #ifndef GCWZERO //this causes gcw to crash
89 str[index]=toupper((int)str[index]);
90 #endif
91 }
92 index++;
93 }
94 }
95 // On enlève les espaces avant la fin de chaine
96 while (index>0 && (str[index-1]==' ' || str[index-1]=='\t'))
97 {
98 index--;
99 str[index]='\0';
100 }
101 }
102
103 /**
104 * Search for a substring in a string
105 *
106 * @param buffer the string to search into
107 * @param pattern the string to search for
108 * @return 0 if the pattern was not found
109 * @return >0 the position (+1) where the pattern was found
110 */
Load_INI_seek_pattern(const char * buffer,const char * pattern)111 int Load_INI_seek_pattern(const char * buffer,const char * pattern)
112 {
113 int buffer_index;
114 int pattern_index;
115
116 // A partir de chaque lettre de la chaîne buffer
117 for (buffer_index=0;buffer[buffer_index]!='\0';buffer_index++)
118 {
119 // On regarde si la chaîne pattern est équivalente à la position courante
120 // de la chaîne buffer:
121 for (pattern_index=0;(pattern[pattern_index]!='\0') && (buffer[buffer_index+pattern_index]==pattern[pattern_index]);pattern_index++);
122
123 // Si on a trouvé la chaîne pattern dans la chaîne buffer, on renvoie la
124 // position à laquelle on l'a trouvée (+1 pour que si on la trouve au
125 // début ça ne renvoie pas la même chose que si on ne l'avait pas
126 // trouvée):
127 if (pattern[pattern_index]=='\0')
128 return (buffer_index+1);
129 }
130
131 // Si on ne l'a pas trouvée, on renvoie 0:
132 return 0;
133 }
134
135 /**
136 * Read lines until a group is found
137 *
138 * @return 0 when the group is reached
139 * @return @ref ERROR_INI_CORRUPTED if the group is not found
140 */
Load_INI_reach_group(FILE * file,char * buffer,const char * group)141 static int Load_INI_reach_group(FILE * file,char * buffer,const char * group)
142 {
143 int stop_seek;
144 char * group_upper;
145 char * upper_buffer;
146
147 // On alloue les zones de mémoire:
148 group_upper=(char *)malloc(1024);
149 upper_buffer=(char *)malloc(1024);
150
151 // On commence par se faire une version majuscule du groupe à rechercher:
152 strcpy(group_upper,group);
153 Load_INI_clear_string(group_upper, 0);
154
155 stop_seek=0;
156 do
157 {
158 // On lit une ligne dans le fichier:
159 if (fgets(buffer,1024,file)==0)
160 {
161 free(upper_buffer);
162 free(group_upper);
163 return ERROR_INI_CORRUPTED;
164 }
165
166 Line_number_in_INI_file++;
167
168 // On s'en fait une version en majuscule:
169 strcpy(upper_buffer,buffer);
170 Load_INI_clear_string(upper_buffer, 0);
171
172 // On compare la chaîne avec le groupe recherché:
173 stop_seek=Load_INI_seek_pattern(upper_buffer,group_upper);
174 }
175 while (!stop_seek);
176
177 free(upper_buffer);
178 free(group_upper);
179
180 return 0;
181 }
182
183 ///
184 /// Find the next string in the .INI file.
185 /// @param file INI file currently opened
186 /// @param buffer Current text buffer, preserved from one call to the next
187 /// @param option_name string to search
188 /// @param return_code the found value will be copied there. (must be allocaed)
189 /// @param raw_text Boolean: true to return the raw value (up to end-of-line), false to strip comments.
190 /// @return 0 when OK
191 /// @return @ref ERROR_INI_CORRUPTED if the option is not found
Load_INI_get_string(FILE * file,char * buffer,const char * option_name,char * return_code,byte raw_text)192 static int Load_INI_get_string(FILE * file,char * buffer,const char * option_name,char * return_code, byte raw_text)
193 {
194 int stop_seek;
195 char * option_upper;
196 char * upper_buffer;
197 int buffer_index;
198
199 // On alloue les zones de mémoire:
200 option_upper=(char *)malloc(1024);
201 upper_buffer=(char *)malloc(1024);
202
203 // On commence par se faire une version majuscule de l'option à rechercher:
204 strcpy(option_upper,option_name);
205 Load_INI_clear_string(option_upper, 0);
206
207 stop_seek=0;
208 do
209 {
210 // On lit une ligne dans le fichier:
211 if (fgets(buffer,1024,file)==NULL)
212 {
213 free(upper_buffer);
214 free(option_upper);
215 return ERROR_INI_CORRUPTED;
216 }
217
218 Line_number_in_INI_file++;
219
220 // On s'en fait une version en majuscule:
221 strcpy(upper_buffer,buffer);
222 Load_INI_clear_string(upper_buffer, raw_text);
223
224 // On compare la chaîne avec l'option recherchée:
225 stop_seek=Load_INI_seek_pattern(upper_buffer,option_upper);
226
227 // Si on l'a trouvée:
228 if (stop_seek)
229 {
230 // On se positionne juste après la chaîne "="
231 buffer_index=Load_INI_seek_pattern(upper_buffer,"=");
232
233 strcpy(return_code, upper_buffer + buffer_index);
234 }
235 }
236 while (!stop_seek);
237
238 free(upper_buffer);
239 free(option_upper);
240
241 return 0;
242 }
243
244 /**
245 * Read a value from the string
246 *
247 * @ref index is updated according to the number of characters read
248 * from the source string.
249 *
250 * @param str the source string (option "values")
251 * @param index a pointer to the current index in the source string
252 * @param value the read value will be put there
253 * @return 0
254 * @return @ref ERROR_INI_CORRUPTED
255 */
Load_INI_get_value(const char * str,int * index,int * value)256 static int Load_INI_get_value(const char * str,int * index,int * value)
257 {
258 int negative = 0;
259
260 // On teste si la valeur actuelle est YES (ou Y):
261
262 if (Load_INI_seek_pattern(str+(*index),"yes,")==1)
263 {
264 (*value)=1;
265 (*index)+=4;
266 return 0;
267 }
268 if (strcmp(str+(*index),"yes")==0)
269 {
270 (*value)=1;
271 (*index)+=3;
272 return 0;
273 }
274 if (Load_INI_seek_pattern(str+(*index),"y,")==1)
275 {
276 (*value)=1;
277 (*index)+=2;
278 return 0;
279 }
280 if (strcmp(str+(*index),"y")==0)
281 {
282 (*value)=1;
283 (*index)+=1;
284 return 0;
285 }
286
287 // On teste si la valeur actuelle est NO (ou N):
288
289 if (Load_INI_seek_pattern(str+(*index),"no,")==1)
290 {
291 (*value)=0;
292 (*index)+=3;
293 return 0;
294 }
295 if (strcmp(str+(*index),"no")==0)
296 {
297 (*value)=0;
298 (*index)+=2;
299 return 0;
300 }
301 if (Load_INI_seek_pattern(str+(*index),"n,")==1)
302 {
303 (*value)=0;
304 (*index)+=2;
305 return 0;
306 }
307 if (strcmp(str+(*index),"n")==0)
308 {
309 (*value)=0;
310 (*index)+=1;
311 return 0;
312 }
313 if (str[*index]=='$')
314 {
315 (*value)=0;
316
317 for (;;)
318 {
319 (*index)++;
320
321 if ((str[*index]>='0') && (str[*index]<='9'))
322 (*value)=((*value)*16)+str[*index]-'0';
323 else
324 if ((str[*index]>='A') && (str[*index]<='F'))
325 (*value)=((*value)*16)+str[*index]-'A'+10;
326 else
327 if (str[*index]==',')
328 {
329 (*index)++;
330 return 0;
331 }
332 else
333 if (str[*index]=='\0')
334 return 0;
335 else
336 return ERROR_INI_CORRUPTED;
337 }
338 }
339 if (str[*index]=='-')
340 {
341 negative = 1;
342 // next character
343 (*index)++;
344 // Fall thru
345 }
346 if ((str[*index]>='0') && (str[*index]<='9'))
347 {
348 (*value)=0;
349
350 for (;;)
351 {
352 if ((str[*index]>='0') && (str[*index]<='9'))
353 {
354 (*value)=((*value)*10)+str[*index]-'0';
355 if (negative)
356 {
357 (*value)*= -1;
358 // This is to do it once per number.
359 negative = 0;
360 }
361 }
362 else
363 if (str[*index]==',')
364 {
365 (*index)++;
366 return 0;
367 }
368 else
369 if (str[*index]=='\0')
370 return 0;
371 else
372 return ERROR_INI_CORRUPTED;
373
374 (*index)++;
375 }
376 }
377 else
378 return ERROR_INI_CORRUPTED;
379 }
380
381
382 /**
383 * Read all values from a string
384 *
385 * The values are comma separated
386 *
387 * @param file handle to gfx2.ini
388 * @param buffer Current text buffer, preserved from one call to the next
389 * @param option_name name of the option to read
390 * @param nb_expected_values number of values to read from the line
391 * @param[out] values the values will be put there
392 * @return 0 when OK
393 * @return @ref ERROR_INI_CORRUPTED if no value was found, or not enough
394 */
Load_INI_get_values(FILE * file,char * buffer,const char * option_name,int nb_expected_values,int * values)395 static int Load_INI_get_values(FILE * file,char * buffer,const char * option_name,int nb_expected_values,int * values)
396 {
397 int stop_seek;
398 char * option_upper;
399 char * upper_buffer;
400 int buffer_index;
401 int nb_values;
402
403 // On alloue les zones de mémoire:
404 option_upper=(char *)malloc(1024);
405 upper_buffer=(char *)malloc(1024);
406
407 // On commence par se faire une version majuscule de l'option à rechercher:
408 strcpy(option_upper,option_name);
409 Load_INI_clear_string(option_upper, 0);
410
411 stop_seek=0;
412 do
413 {
414 // On lit une ligne dans le fichier:
415 if (fgets(buffer,1024,file)==0)
416 {
417 free(upper_buffer);
418 free(option_upper);
419 return ERROR_INI_CORRUPTED;
420 }
421
422 Line_number_in_INI_file++;
423
424 // On s'en fait une version en majuscule:
425 strcpy(upper_buffer,buffer);
426 Load_INI_clear_string(upper_buffer, 0);
427
428 // On compare la chaîne avec l'option recherchée:
429 stop_seek=Load_INI_seek_pattern(upper_buffer,option_upper);
430
431 // Si on l'a trouvée:
432 if (stop_seek)
433 {
434 nb_values=0;
435
436 // On se positionne juste après la chaîne "="
437 buffer_index=Load_INI_seek_pattern(upper_buffer,"=");
438
439 // Tant qu'on a pas atteint la fin de la ligne
440 while (upper_buffer[buffer_index]!='\0')
441 {
442 if (Load_INI_get_value(upper_buffer,&buffer_index,values+nb_values))
443 {
444 free(upper_buffer);
445 free(option_upper);
446 return ERROR_INI_CORRUPTED;
447 }
448
449 if ( ((++nb_values) == nb_expected_values) &&
450 (upper_buffer[buffer_index]!='\0') )
451 {
452 // Too many values !
453 free(upper_buffer);
454 free(option_upper);
455 return ERROR_INI_CORRUPTED;
456 }
457 }
458
459 if (nb_values<nb_expected_values)
460 {
461 // Not enough values !
462 free(upper_buffer);
463 free(option_upper);
464 return ERROR_INI_CORRUPTED;
465 }
466 }
467 }
468 while (!stop_seek);
469
470 free(upper_buffer);
471 free(option_upper);
472
473 return 0;
474 }
475
476
477 /**
478 * Load config from the gfx2.ini file
479 *
480 * @param[out] conf the configuration to read to
481 * @return 0 when OK
482 * @return @ref ERROR_INI_CORRUPTED for any error
483 */
Load_INI(T_Config * conf)484 int Load_INI(T_Config * conf)
485 {
486 FILE * file;
487 char * buffer;
488 int values[3];
489 int index;
490 char * filename;
491 int return_code;
492 char value_label[1024];
493
494 Line_number_in_INI_file=0;
495
496 #if defined(__WIZ__) || defined(__CAANOO__)
497 conf->Stylus_mode = 1;
498 #else
499 conf->Stylus_mode = 0;
500 #endif
501
502 // allocate buffer
503 buffer = (char *)GFX2_malloc(1024);
504
505 filename = Filepath_append_to_dir(Config_directory, INI_FILENAME);
506 file = fopen(filename, "r");
507 if (file == NULL)
508 {
509 free(filename);
510 // Si le fichier ini est absent on le relit depuis gfx2def.ini
511 filename = Filepath_append_to_dir(Data_directory, INIDEF_FILENAME);
512 file = fopen(filename, "r");
513 if (file == NULL)
514 {
515 GFX2_Log(GFX2_ERROR, "Load_INI() cannot open %s\n", filename);
516 free(filename);
517 free(buffer);
518 return ERROR_INI_MISSING;
519 }
520 }
521 GFX2_Log(GFX2_DEBUG, "Load_INI() loading %s\n", filename);
522 free(filename);
523
524 if ((return_code=Load_INI_reach_group(file,buffer,"[MOUSE]")))
525 goto Erreur_Retour;
526
527 if ((return_code=Load_INI_get_values (file,buffer,"X_sensitivity",1,values)))
528 goto Erreur_Retour;
529 if ((values[0]<1) || (values[0]>4))
530 conf->Mouse_sensitivity_index_x=1;
531 else
532 conf->Mouse_sensitivity_index_x=values[0];
533
534 if ((return_code=Load_INI_get_values (file,buffer,"Y_sensitivity",1,values)))
535 goto Erreur_Retour;
536 if ((values[0]<1) || (values[0]>4))
537 conf->Mouse_sensitivity_index_y=1;
538 else
539 conf->Mouse_sensitivity_index_y=values[0];
540
541 if ((return_code=Load_INI_get_values (file,buffer,"X_correction_factor",1,values)))
542 goto Erreur_Retour;
543 if ((values[0]<0) || (values[0]>4))
544 goto Erreur_ERREUR_INI_CORROMPU;
545 // Deprecated setting, unused
546
547 if ((return_code=Load_INI_get_values (file,buffer,"Y_correction_factor",1,values)))
548 goto Erreur_Retour;
549 if ((values[0]<0) || (values[0]>4))
550 goto Erreur_ERREUR_INI_CORROMPU;
551 // Deprecated setting, unused
552
553 if ((return_code=Load_INI_get_values (file,buffer,"Cursor_aspect",1,values)))
554 goto Erreur_Retour;
555 if ((values[0]<1) || (values[0]>3))
556 goto Erreur_ERREUR_INI_CORROMPU;
557 conf->Cursor=values[0]-1;
558
559 if ((return_code=Load_INI_reach_group(file,buffer,"[MENU]")))
560 goto Erreur_Retour;
561
562 conf->Fav_menu_colors[0].R=0;
563 conf->Fav_menu_colors[0].G=0;
564 conf->Fav_menu_colors[0].B=0;
565 conf->Fav_menu_colors[3].R=255;
566 conf->Fav_menu_colors[3].G=255;
567 conf->Fav_menu_colors[3].B=255;
568
569 if ((return_code=Load_INI_get_values (file,buffer,"Light_color",3,values)))
570 goto Erreur_Retour;
571 if ((values[0]<0) || (values[0]>63))
572 goto Erreur_ERREUR_INI_CORROMPU;
573 if ((values[1]<0) || (values[1]>63))
574 goto Erreur_ERREUR_INI_CORROMPU;
575 if ((values[2]<0) || (values[2]>63))
576 goto Erreur_ERREUR_INI_CORROMPU;
577 conf->Fav_menu_colors[2].R=(values[0]<<2)|(values[0]>>4);
578 conf->Fav_menu_colors[2].G=(values[1]<<2)|(values[1]>>4);
579 conf->Fav_menu_colors[2].B=(values[2]<<2)|(values[2]>>4);
580
581 if ((return_code=Load_INI_get_values (file,buffer,"Dark_color",3,values)))
582 goto Erreur_Retour;
583 if ((values[0]<0) || (values[0]>63))
584 goto Erreur_ERREUR_INI_CORROMPU;
585 if ((values[1]<0) || (values[1]>63))
586 goto Erreur_ERREUR_INI_CORROMPU;
587 if ((values[2]<0) || (values[2]>63))
588 goto Erreur_ERREUR_INI_CORROMPU;
589 conf->Fav_menu_colors[1].R=(values[0]<<2)|(values[0]>>4);
590 conf->Fav_menu_colors[1].G=(values[1]<<2)|(values[1]>>4);
591 conf->Fav_menu_colors[1].B=(values[2]<<2)|(values[2]>>4);
592
593 if ((return_code=Load_INI_get_values (file,buffer,"Menu_ratio",1,values)))
594 goto Erreur_Retour;
595 if ((values[0]<-4) || (values[0]>2))
596 goto Erreur_ERREUR_INI_CORROMPU;
597 conf->Ratio=values[0];
598
599 if ((return_code=Load_INI_reach_group(file,buffer,"[FILE_SELECTOR]")))
600 goto Erreur_Retour;
601
602 if ((return_code=Load_INI_get_values (file,buffer,"Show_hidden_files",1,values)))
603 goto Erreur_Retour;
604 if ((values[0]<0) || (values[0]>1))
605 goto Erreur_ERREUR_INI_CORROMPU;
606 conf->Show_hidden_files=values[0]?1:0;
607
608 if ((return_code=Load_INI_get_values (file,buffer,"Show_hidden_directories",1,values)))
609 goto Erreur_Retour;
610 if ((values[0]<0) || (values[0]>1))
611 goto Erreur_ERREUR_INI_CORROMPU;
612 conf->Show_hidden_directories=values[0]?1:0;
613
614 /* if ((return_code=Load_INI_get_values (file,buffer,"Show_system_directories",1,values)))
615 goto Erreur_Retour;
616 if ((values[0]<0) || (values[0]>1))
617 goto Erreur_ERREUR_INI_CORROMPU;
618 conf->Show_system_directories=values[0]?1:0;
619 */
620 if ((return_code=Load_INI_get_values (file,buffer,"Preview_delay",1,values)))
621 goto Erreur_Retour;
622 if ((values[0]<1) || (values[0]>256))
623 goto Erreur_ERREUR_INI_CORROMPU;
624 conf->Timer_delay=values[0];
625
626 if ((return_code=Load_INI_get_values (file,buffer,"Maximize_preview",1,values)))
627 goto Erreur_Retour;
628 if ((values[0]<0) || (values[0]>1))
629 goto Erreur_ERREUR_INI_CORROMPU;
630 conf->Maximize_preview=values[0];
631
632 if ((return_code=Load_INI_get_values (file,buffer,"Find_file_fast",1,values)))
633 goto Erreur_Retour;
634 if ((values[0]<0) || (values[0]>2))
635 goto Erreur_ERREUR_INI_CORROMPU;
636 conf->Find_file_fast=values[0];
637
638
639 if ((return_code=Load_INI_reach_group(file,buffer,"[LOADING]")))
640 goto Erreur_Retour;
641
642 if ((return_code=Load_INI_get_values (file,buffer,"Auto_set_resolution",1,values)))
643 goto Erreur_Retour;
644 if ((values[0]<0) || (values[0]>1))
645 goto Erreur_ERREUR_INI_CORROMPU;
646 conf->Auto_set_res=values[0];
647
648 if ((return_code=Load_INI_get_values (file,buffer,"Set_resolution_according_to",1,values)))
649 goto Erreur_Retour;
650 if ((values[0]<1) || (values[0]>2))
651 goto Erreur_ERREUR_INI_CORROMPU;
652 conf->Set_resolution_according_to=values[0];
653
654 if ((return_code=Load_INI_get_values (file,buffer,"Clear_palette",1,values)))
655 goto Erreur_Retour;
656 if ((values[0]<0) || (values[0]>1))
657 goto Erreur_ERREUR_INI_CORROMPU;
658 conf->Clear_palette=values[0];
659
660
661 if ((return_code=Load_INI_reach_group(file,buffer,"[MISCELLANEOUS]")))
662 goto Erreur_Retour;
663
664 if ((return_code=Load_INI_get_values (file,buffer,"Draw_limits",1,values)))
665 goto Erreur_Retour;
666 if ((values[0]<0) || (values[0]>1))
667 goto Erreur_ERREUR_INI_CORROMPU;
668 conf->Display_image_limits=values[0];
669
670 if ((return_code=Load_INI_get_values (file,buffer,"Adjust_brush_pick",1,values)))
671 goto Erreur_Retour;
672 if ((values[0]<0) || (values[0]>1))
673 goto Erreur_ERREUR_INI_CORROMPU;
674 conf->Adjust_brush_pick=values[0];
675
676 if ((return_code=Load_INI_get_values (file,buffer,"Coordinates",1,values)))
677 goto Erreur_Retour;
678 if ((values[0]<1) || (values[0]>2))
679 goto Erreur_ERREUR_INI_CORROMPU;
680 conf->Coords_rel=2-values[0];
681
682 if ((return_code=Load_INI_get_values (file,buffer,"Backup",1,values)))
683 goto Erreur_Retour;
684 if ((values[0]<0) || (values[0]>1))
685 goto Erreur_ERREUR_INI_CORROMPU;
686 conf->Backup=values[0];
687
688 if ((return_code=Load_INI_get_values (file,buffer,"Undo_pages",1,values)))
689 goto Erreur_Retour;
690 if ((values[0]<1) || (values[0]>99))
691 goto Erreur_ERREUR_INI_CORROMPU;
692 conf->Max_undo_pages=values[0];
693
694 if ((return_code=Load_INI_get_values (file,buffer,"Gauges_scrolling_speed_Left",1,values)))
695 goto Erreur_Retour;
696 if ((values[0]<1) || (values[0]>255))
697 goto Erreur_ERREUR_INI_CORROMPU;
698 conf->Delay_left_click_on_slider=values[0];
699
700 if ((return_code=Load_INI_get_values (file,buffer,"Gauges_scrolling_speed_Right",1,values)))
701 goto Erreur_Retour;
702 if ((values[0]<1) || (values[0]>255))
703 goto Erreur_ERREUR_INI_CORROMPU;
704 conf->Delay_right_click_on_slider=values[0];
705
706 if ((return_code=Load_INI_get_values (file,buffer,"Auto_save",1,values)))
707 goto Erreur_Retour;
708 if ((values[0]<0) || (values[0]>1))
709 goto Erreur_ERREUR_INI_CORROMPU;
710 conf->Auto_save=values[0];
711
712 if ((return_code=Load_INI_get_values (file,buffer,"Vertices_per_polygon",1,values)))
713 goto Erreur_Retour;
714 if ((values[0]<2) || (values[0]>16384))
715 goto Erreur_ERREUR_INI_CORROMPU;
716 conf->Nb_max_vertices_per_polygon=values[0];
717
718 if ((return_code=Load_INI_get_values (file,buffer,"Fast_zoom",1,values)))
719 goto Erreur_Retour;
720 if ((values[0]<0) || (values[0]>1))
721 goto Erreur_ERREUR_INI_CORROMPU;
722 conf->Fast_zoom=values[0];
723
724 if ((return_code=Load_INI_get_values (file,buffer,"Separate_colors",1,values)))
725 goto Erreur_Retour;
726 if ((values[0]<0) || (values[0]>1))
727 goto Erreur_ERREUR_INI_CORROMPU;
728 conf->Separate_colors=values[0];
729
730 if ((return_code=Load_INI_get_values (file,buffer,"FX_feedback",1,values)))
731 goto Erreur_Retour;
732 if ((values[0]<0) || (values[0]>1))
733 goto Erreur_ERREUR_INI_CORROMPU;
734 conf->FX_Feedback=values[0];
735
736 if ((return_code=Load_INI_get_values (file,buffer,"Safety_colors",1,values)))
737 goto Erreur_Retour;
738 if ((values[0]<0) || (values[0]>1))
739 goto Erreur_ERREUR_INI_CORROMPU;
740 conf->Safety_colors=values[0];
741
742 if ((return_code=Load_INI_get_values (file,buffer,"Opening_message",1,values)))
743 goto Erreur_Retour;
744 if ((values[0]<0) || (values[0]>1))
745 goto Erreur_ERREUR_INI_CORROMPU;
746 conf->Opening_message=values[0];
747
748 if ((return_code=Load_INI_get_values (file,buffer,"Clear_with_stencil",1,values)))
749 goto Erreur_Retour;
750 if ((values[0]<0) || (values[0]>1))
751 goto Erreur_ERREUR_INI_CORROMPU;
752 conf->Clear_with_stencil=values[0];
753
754 if ((return_code=Load_INI_get_values (file,buffer,"Auto_discontinuous",1,values)))
755 goto Erreur_Retour;
756 if ((values[0]<0) || (values[0]>1))
757 goto Erreur_ERREUR_INI_CORROMPU;
758 conf->Auto_discontinuous=values[0];
759
760 if ((return_code=Load_INI_get_values (file,buffer,"Save_screen_size_in_GIF",1,values)))
761 goto Erreur_Retour;
762 if ((values[0]<0) || (values[0]>1))
763 goto Erreur_ERREUR_INI_CORROMPU;
764 conf->Screen_size_in_GIF=values[0];
765
766 if ((return_code=Load_INI_get_values (file,buffer,"Auto_nb_colors_used",1,values)))
767 goto Erreur_Retour;
768 if ((values[0]<0) || (values[0]>1))
769 goto Erreur_ERREUR_INI_CORROMPU;
770 conf->Auto_nb_used=values[0];
771
772 // Optionnel, le mode video par défaut (à partir de beta 97.0%)
773 conf->Default_resolution=0;
774 if (!Load_INI_get_string (file,buffer,"Default_video_mode",value_label, 0))
775 {
776 int mode = Convert_videomode_arg(value_label);
777 if (mode>=0)
778 conf->Default_resolution=mode;
779 }
780
781 // Optionnel, les dimensions de la fenêtre (à partir de beta 97.0%)
782 // Do that only if the first mode is actually windowed (not the case on gp2x for example)
783 if(Video_mode[0].Fullscreen==0)
784 {
785 Video_mode[0].Width = 640;
786 Video_mode[0].Height = 480;
787 if (!Load_INI_get_values (file,buffer,"Default_window_size",2,values))
788 {
789 if ((values[0]>=320))
790 Default_window_width = Video_mode[0].Width = values[0];
791 if ((values[1]>=200))
792 Default_window_height = Video_mode[0].Height = values[1];
793 }
794 }
795
796 conf->Mouse_merge_movement=100;
797 // Optionnel, paramètre pour grouper les mouvements souris (>98.0%)
798 if (!Load_INI_get_values (file,buffer,"Merge_movement",1,values))
799 {
800 if ((values[0]<0) || (values[0]>1000))
801 goto Erreur_ERREUR_INI_CORROMPU;
802 conf->Mouse_merge_movement=values[0];
803 }
804
805 conf->Palette_cells_X=16;
806 // Optionnel, nombre de colonnes dans la palette (>98.0%)
807 if (!Load_INI_get_values (file,buffer,"Palette_cells_X",1,values))
808 {
809 if ((values[0]<1) || (values[0]>256))
810 goto Erreur_ERREUR_INI_CORROMPU;
811 conf->Palette_cells_X=values[0];
812 }
813 conf->Palette_cells_Y=4;
814 // Optionnel, nombre de lignes dans la palette (>98.0%)
815 if (!Load_INI_get_values (file,buffer,"Palette_cells_Y",1,values))
816 {
817 if (values[0]<1 || values[0]>16)
818 goto Erreur_ERREUR_INI_CORROMPU;
819 conf->Palette_cells_Y=values[0];
820 }
821 // Optionnel, bookmarks (>98.0%)
822 for (index=0;index<NB_BOOKMARKS;index++)
823 {
824 conf->Bookmark_directory[index]=NULL;
825 conf->Bookmark_label[index][0]='\0';
826 }
827 for (index=0;index<NB_BOOKMARKS;index++)
828 {
829 if (!Load_INI_get_string (file,buffer,"Bookmark_label",value_label, 1))
830 {
831 size_t size = strlen(value_label);
832 if (size!=0)
833 {
834 if (size >= sizeof(conf->Bookmark_label[0]))
835 {
836 memcpy(conf->Bookmark_label[index], value_label, sizeof(conf->Bookmark_label[0]) - 1);
837 conf->Bookmark_label[index][sizeof(conf->Bookmark_label[0]) - 1] = '\0';
838 }
839 else
840 memcpy(conf->Bookmark_label[index], value_label, size + 1);
841 }
842 }
843 else
844 break;
845 if (!Load_INI_get_string (file,buffer,"Bookmark_directory",value_label, 1))
846 {
847 size_t size = strlen(value_label);
848 if (size!=0)
849 {
850 conf->Bookmark_directory[index]=(char *)malloc(size+1);
851 strcpy(conf->Bookmark_directory[index],value_label);
852 }
853 }
854 else
855 break;
856 }
857 conf->Palette_vertical=1;
858 // Optional, vertical palette option (>98.0%)
859 if (!Load_INI_get_values (file,buffer,"Palette_vertical",1,values))
860 {
861 if ((values[0]<0) || (values[0]>1))
862 goto Erreur_ERREUR_INI_CORROMPU;
863 conf->Palette_vertical=values[0];
864 }
865
866 // Optional, the window position (>98.0%)
867 conf->Window_pos_x=9999;
868 conf->Window_pos_y=9999;
869 if (!Load_INI_get_values (file,buffer,"Window_position",2,values))
870 {
871 conf->Window_pos_x = values[0];
872 conf->Window_pos_y = values[1];
873 }
874
875 conf->Double_click_speed=500;
876 // Optional, speed of double-click (>2.0)
877 if (!Load_INI_get_values (file,buffer,"Double_click_speed",1,values))
878 {
879 if ((values[0]>0) || (values[0]<=2000))
880 conf->Double_click_speed=values[0];
881 }
882
883 conf->Double_key_speed=500;
884 // Optional, speed of double-keypress (>2.0)
885 if (!Load_INI_get_values (file,buffer,"Double_key_speed",1,values))
886 {
887 if ((values[0]>0) || (values[0]<=2000))
888 conf->Double_key_speed=values[0];
889 }
890
891 // Optional, name of skin file. (>2.0)
892 if(!Load_INI_get_string(file,buffer,"Skin_file",value_label,1))
893 {
894 conf->Skin_file = strdup(value_label);
895 }
896 else
897 conf->Skin_file = strdup(DEFAULT_SKIN_FILENAME);
898
899 // Optional, name of font file. (>2.0)
900 if(!Load_INI_get_string(file,buffer,"Font_file",value_label,1))
901 conf->Font_file = strdup(value_label);
902 else
903 conf->Font_file = strdup(DEFAULT_FONT_FILENAME);
904
905 // Optional, "fake hardware zoom" factor (>2.1)
906 if (!Load_INI_get_values (file, buffer,"Pixel_ratio",1,values))
907 {
908 Pixel_ratio = values[0];
909 switch(Pixel_ratio) {
910 case PIXEL_WIDE:
911 if(Video_mode[0].Width < 640)
912 Pixel_ratio = PIXEL_SIMPLE;
913 break;
914 case PIXEL_TALL:
915 if(Video_mode[0].Height < 400)
916 Pixel_ratio = PIXEL_SIMPLE;
917 break;
918 case PIXEL_DOUBLE:
919 if(Video_mode[0].Width < 640 || Video_mode[0].Height < 400)
920 Pixel_ratio = PIXEL_SIMPLE;
921 break;
922 case PIXEL_TRIPLE:
923 if(Video_mode[0].Width < 3*320 || Video_mode[0].Height < 3*200)
924 Pixel_ratio = PIXEL_SIMPLE;
925 break;
926 case PIXEL_WIDE2:
927 if(Video_mode[0].Width < 4*320 || Video_mode[0].Height < 2*200)
928 Pixel_ratio = PIXEL_SIMPLE;
929 break;
930 case PIXEL_TALL2:
931 if(Video_mode[0].Width < 2*320 || Video_mode[0].Height < 4*200)
932 Pixel_ratio = PIXEL_SIMPLE;
933 break;
934 case PIXEL_TALL3:
935 if(Video_mode[0].Width < 3*320 || Video_mode[0].Height < 4*200)
936 Pixel_ratio = PIXEL_SIMPLE;
937 break;
938 case PIXEL_QUAD:
939 if(Video_mode[0].Width < 4*320 || Video_mode[0].Height < 4*200)
940 Pixel_ratio = PIXEL_SIMPLE;
941 break;
942 default:
943 // Convert back unknown values to PIXEL_SIMPLE
944 Pixel_ratio = PIXEL_SIMPLE;
945 break;
946 }
947 }
948
949 // Optional, Menu bars visibility (> 2.1)
950 if (!Load_INI_get_values (file, buffer,"Menubars_visible",1,values))
951 {
952 byte anim_visible = (values[0] & 2)!=0;
953 byte tools_visible = (values[0] & 4)!=0;
954
955 // Skip status bar, always enabled.
956 Menu_bars[MENUBAR_LAYERS].Visible = anim_visible;
957 Menu_bars[MENUBAR_ANIMATION].Visible = 0;
958 Menu_bars[MENUBAR_TOOLS].Visible = tools_visible;
959 }
960
961 conf->Right_click_colorpick=0;
962 // Optional, right mouse button to pick colors (>=2.3)
963 if (!Load_INI_get_values (file,buffer,"Right_click_colorpick",1,values))
964 {
965 conf->Right_click_colorpick=(values[0]!=0);
966 }
967
968 conf->Sync_views=1;
969 // Optional, synced view of main and spare (>=2.3)
970 if (!Load_INI_get_values (file,buffer,"Sync_views",1,values))
971 {
972 conf->Sync_views=(values[0]!=0);
973 }
974
975 conf->Swap_buttons=0;
976 // Optional, key for swap buttons (>=2.3)
977 if (!Load_INI_get_values (file,buffer,"Swap_buttons",1,values))
978 {
979 switch(values[0])
980 {
981 case 1:
982 conf->Swap_buttons=GFX2_MOD_CTRL;
983 break;
984 case 2:
985 conf->Swap_buttons=GFX2_MOD_ALT;
986 break;
987 }
988 }
989
990 // Optional, Location of last directory used for Lua scripts browsing (>=2.3)
991 free(conf->Scripts_directory);
992 conf->Scripts_directory = NULL;
993 if (!Load_INI_get_string (file,buffer,"Scripts_directory",value_label, 1))
994 {
995 if (value_label[0] != '\0')
996 conf->Scripts_directory = strdup(value_label);
997 }
998 if (conf->Scripts_directory == NULL)
999 {
1000 // Default when empty:
1001 char * path = Realpath(Data_directory);
1002 conf->Scripts_directory = Filepath_append_to_dir(path, SCRIPTS_SUBDIRECTORY);
1003 free(path);
1004 }
1005
1006 conf->Allow_multi_shortcuts=0;
1007 // Optional, allow or disallow multiple shortcuts on same key (>=2.3)
1008 if (!Load_INI_get_values (file,buffer,"Allow_multi_shortcuts",1,values))
1009 {
1010 conf->Allow_multi_shortcuts=(values[0]!=0);
1011 }
1012
1013 conf->Tilemap_allow_flipped_x=0;
1014 // Optional, makes tilemap effect detect x-flipped tiles (>=2.4)
1015 if (!Load_INI_get_values (file,buffer,"Tilemap_detect_mirrored_x",1,values))
1016 {
1017 conf->Tilemap_allow_flipped_x=(values[0]!=0);
1018 }
1019
1020 conf->Tilemap_allow_flipped_y=0;
1021 // Optional, makes tilemap effect detect y-flipped tiles (>=2.4)
1022 if (!Load_INI_get_values (file,buffer,"Tilemap_detect_mirrored_y",1,values))
1023 {
1024 conf->Tilemap_allow_flipped_y=(values[0]!=0);
1025 }
1026
1027 conf->Tilemap_show_count=0;
1028 // Optional, makes tilemap effect display tile count (>=2.4)
1029 if (!Load_INI_get_values (file,buffer,"Tilemap_count",1,values))
1030 {
1031 conf->Tilemap_show_count=(values[0]!=0);
1032 }
1033
1034 conf->Use_virtual_keyboard=0;
1035 // Optional, enables virtual keyboard (>=2.4)
1036 if (!Load_INI_get_values (file,buffer,"Use_virtual_keyboard",1,values))
1037 {
1038 if (values[0]>=0 && values[0]<=2)
1039 conf->Use_virtual_keyboard=values[0];
1040 }
1041
1042 conf->Default_mode_layers=0;
1043 // Optional, remembers if the user last chose layers or anim (>=2.4)
1044 if (!Load_INI_get_values (file,buffer,"Default_mode_layers",1,values))
1045 {
1046 conf->Default_mode_layers=(values[0]!=0);
1047 }
1048
1049 conf->MOTO_gamma=28;
1050 // Optional, gamma value used for palette of load/save Thomson MO/TO pictures (>=2.6)
1051 if (!Load_INI_get_values (file,buffer,"MOTO_gamma",1,values))
1052 {
1053 conf->MOTO_gamma=(byte)values[0];
1054 }
1055
1056 // Insert new values here
1057
1058 fclose(file);
1059
1060 free(buffer);
1061 return 0;
1062
1063 // Gestion des erreurs:
1064
1065 Erreur_Retour:
1066 fclose(file);
1067 free(buffer);
1068 return return_code;
1069
1070 Erreur_ERREUR_INI_CORROMPU:
1071
1072 fclose(file);
1073 free(buffer);
1074 return ERROR_INI_CORRUPTED;
1075 }
1076