root/system/system_config.cc

Revision 65:4416cfac86ae, 44.2 KB (checked in by Thibaut Girka <thib@…>, 18 months ago)
Convert EUC-JP files to UTF8
Line 
1/*  system_config.cc
2 *      gameexe.ini ファむルの読み蟌み
3 */
4
5/*
6 *
7 *  Copyright (C) 2000-   Kazunori Ueno(JAGARL) <jagarl@creator.club.ne.jp>
8 *
9 *  This program is free software; you can redistribute it and/or modify
10 *  it under the terms of the GNU General Public License as published by
11 *  the Free Software Foundation; either version 2 of the License, or
12 *  (at your option) any later version.
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License along
20 *  with this program; if not, write to the Free Software Foundation, Inc.,
21 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 *
23*/
24
25#include <stdio.h>
26#include <string.h>
27#include <stdlib.h>
28#include <stdarg.h>
29#include <ctype.h>
30#include <map>
31#include <string>
32#include "system_config.h"
33#include "../system/file.h"
34
35using namespace std;
36
37// #define DEBUG_CONFIG
38#ifdef DEBUG_CONFIG
39# define dprintf(X) printf X
40#else
41# define dprintf(X)
42#endif /* DEBUG_CONFIG */
43
44#define MAXTOKEN 10 /* = で区切られた領域の最倧数 */
45#define MAXVARS 32 /* , で区切られた数倀の最倧数 */
46
47// 初期化ファむルの読み蟌み
48/* config は 文字列、数列、その耇合など、いろいろな圢匏がありうる */
49/* 文字列ず数列は䞀般に AyuSys_Config クラスに含める */
50
51
52/**********************************************************/
53/* ずりあえずハッシュ比范付き文字列 */
54class HashStr {
55        const char* str;
56        unsigned int hash;
57public:
58        HashStr(const char*);
59        HashStr(const HashStr& orig);
60        ~HashStr() {
61                if (str) delete[] str;
62        }
63        const char* c_str(void) const { return str; }
64        friend inline int operator<(const HashStr& a, const HashStr& b) {
65                if (a.hash == b.hash) {
66                        if (a.str == 0) return 1;
67                        else if (b.str == 0) return 0;
68                        else return strcmp(a.str, b.str);
69                }
70                else return a.hash < b.hash;
71        }
72};
73
74HashStr::HashStr(const char* s ) {
75        if (s == NULL || s[0] == '\0') {
76                str = NULL;
77                hash = 0;
78                return; /* invalid string */
79        }
80        char* new_str = new char[strlen(s)+1];
81        strcpy(new_str, s);
82        str = new_str;
83        /* calc hash... 適圓 */
84        int h = strlen(s);
85        while(*s != 0) {
86                h = *s + ((h * (0x9449+*s))>>7);
87                s++;
88        }
89        hash = (unsigned int)h;
90}
91HashStr::HashStr(const HashStr& orig) {
92        if (orig.str == NULL || orig.str[0] == '\0') {
93                str = NULL;
94                hash = 0; return; /* invalid */
95        }
96        char* new_str = new char[strlen(orig.str)+1];
97        strcpy(new_str, orig.str);
98        str = new_str;
99        hash = orig.hash;
100}
101
102/**********************************************************
103**AyuSys_Config_[String | Intlist] :
104** 蚭定の本䜓
105**      original : 元蚭定
106**      old_data : 前回 ClearDiff() したずきの蚭定
107**      new_data : ClearDiff() 以降に蚭定した内容を保存
108**      デヌタ蚭定
109**      Init() : 元蚭定を䜜成
110**      Set() : 蚭定を倉曎
111**      Get() : 最も新しい蚭定を埗る
112**
113**      倉曎の蚘録
114**      Diff() : 前回のClearDiff() から倉曎した内容を埗る
115**      DiffLen() : Diff() で必芁な文字列長を埗る
116**      ClearDiff() : 倉曎蚘録を消す
117**      PatchOld() : Diff() で埗た蚘録に基づき、倉曎前の状態に戻す
118**      PatchNew() : Diff() で埗た蚘録に基づき、倉曎埌の状態に戻す
119**
120**      元蚭定からの倉曎の蚘録
121**      SetOriginal() : 元蚭定に戻す
122**      DiffOriginal() : 元蚭定から珟圚の蚭定の倉曎を埗る
123**      DiffOriginalLen() : DiffOriginal() で必芁な文字列長を埗る
124**      PatchOriginal() : DiffOriginal() で埗た蚘録に基づき、蚭定を埩旧する
125*/
126
127/************************************************
128** AyuSysConfigStringItem
129** 文字列をデヌタずしおも぀蚭定項目
130*/
131class AyuSysConfigStringItem {
132        char* original_data;
133        char* old_data;
134        char* new_data;
135public:
136        AyuSysConfigStringItem(void) {
137                original_data = NULL;
138                old_data = NULL;
139                new_data = NULL;
140        }
141        ~AyuSysConfigStringItem(void) {
142                if (original_data) delete[] original_data;
143                if (old_data) delete[] old_data;
144                if (new_data) delete[] new_data;
145        }
146        AyuSysConfigStringItem(const AyuSysConfigStringItem& o) {
147                original_data = NULL;
148                old_data = NULL;
149                new_data = NULL;
150                if (o.original_data) {
151                        original_data = new char[strlen(o.original_data)+1];
152                        strcpy(original_data, o.original_data);
153                }
154                if (o.old_data) {
155                        old_data = new char[strlen(o.old_data)+1];
156                        strcpy(old_data, o.old_data);
157                }
158                if (o.new_data) {
159                        new_data = new char[strlen(o.new_data)+1];
160                        strcpy(new_data, o.new_data);
161                }
162        }
163        /* 蚭定Init で初期化、Set で倉曎、Get で倉曎を優先しお取り出す */
164        void Init(int deal, const char* str) { /* deal は無芖 */
165                if (original_data) delete[] original_data;
166                int len = strlen(str);
167                original_data = new char[len+1];
168                strcpy(original_data, str);
169                original_data[len] = '\0';
170        }
171        void Set(int deal, const char* str) { /* deal は無芖 */
172                if (new_data) delete[] new_data;
173                int len = strlen(str);
174                new_data = new char[len+1];
175                strcpy(new_data, str);
176                new_data[len] = '\0';
177        }
178        const char* Get(int deal) const {/* deal は無芖 */
179                if (new_data) return new_data;
180                else if (old_data) return old_data;
181                return original_data;
182        }
183        const char* GetOriginal(int deal) const {
184                return original_data;
185        }
186        int Deal(void) const {
187                return 1;
188        }
189        /* オリゞナルからの倉化の調査 :
190        ** DiffOriginal で倉化を文字列で取り出し、PatchOriginal で
191        ** 倉化を反映
192        */
193        int DiffOriginalLen(void) {
194                if (new_data == NULL) return 0;
195                return strlen(new_data)+1;
196        }
197        void DiffOriginal(string& data) {
198                if (new_data == NULL) { /* あり埗ない */
199                        fprintf(stderr,"AyuSysConfigStringItem::DiffOriginal : this method must not called if not required!\n");
200                        return;
201                }
202                char* out_data = new char[strlen(new_data)*2+1];
203                char* buf = out_data;
204                int i;
205                for (i=0; new_data[i]!=0; i++) {
206                        switch(new_data[i]) {
207                                case '?': *buf++ = '?'; *buf++ = '0'; break;
208                                case '"': *buf++ = '?'; *buf++ = '1'; break;
209                                case '\'': *buf++ = '?'; *buf++ = '2'; break;
210                                case ',': *buf++ = '?'; *buf++ = '3'; break;
211                                case '.': *buf++ = '?'; *buf++ = '4'; break;
212                                case ':': *buf++ = '?'; *buf++ = '5'; break;
213                                case ';': *buf++ = '?'; *buf++ = '6'; break;
214                                case '=': *buf++ = '?'; *buf++ = '7'; break;
215                                case '<': *buf++ = '?'; *buf++ = '8'; break;
216                                case '>': *buf++ = '?'; *buf++ = '9'; break;
217                                default: *buf++ = new_data[i]; break;
218                        }
219                }
220                *buf++ = 0;
221                data += out_data;
222                delete[] out_data;
223                return;
224        }
225        const char* PatchOriginal(const char* data) {
226                static const char* table = "?\"',.:;=<>";
227                if (new_data != NULL) delete[] new_data;
228                if (old_data != NULL) delete[] old_data;
229                old_data = NULL;
230                new_data = new char[1024];
231                int i,j = 0;
232                for (i=0; i<1020; i++) {
233                        switch(data[j]) {
234                        case '?':
235                                if (data[j+1] >= '0' && data[j+1] <= '9') {
236                                        new_data[i] = table[ data[j+1] - '0'];
237                                        j += 2;
238                                        break;
239                                }
240                        case '"': case '\'': case ',': case '.': case ':':
241                        case ';': case '=':  case '<': case '>':
242                                goto for_end;
243                        default: new_data[i] = data[j++]; break;
244                        }
245                }
246        for_end:
247                new_data[i] = 0;
248                return data;
249        }
250        void SetOriginal(void) {
251                if (new_data) delete[] new_data;
252                if (old_data) delete[] old_data;
253                new_data = NULL;
254                old_data = NULL;
255        }
256        void Dump(FILE* f) const {
257                if (original_data) fprintf(f, "original %s ",original_data);
258                if (old_data) fprintf(f, "old_data %s ",old_data);
259                if (new_data) fprintf(f, "new_data %s ",new_data);
260                fprintf(f, "\n");
261        }
262};
263
264/************************************************
265** AyuSysConfigIntlistItem
266** 数倀列をデヌタずしおも぀蚭定項目
267*/
268class AyuSysConfigIntlistItem {
269        int item_deal;
270        int* original_data;
271        int* old_data;
272        int* new_data;
273public:
274        AyuSysConfigIntlistItem(void) {
275                item_deal = 0;
276                original_data = NULL;
277                old_data = NULL;
278                new_data = NULL;
279        }
280        ~AyuSysConfigIntlistItem(void) {
281                if (original_data) delete[] original_data;
282                if (old_data) delete[] old_data;
283                if (new_data) delete[] new_data;
284        }
285        AyuSysConfigIntlistItem(const AyuSysConfigIntlistItem& o) {
286                item_deal = o.item_deal;
287                original_data = NULL;
288                old_data = NULL;
289                new_data = NULL;
290                if (o.original_data) {
291                        original_data = new int[item_deal];
292                        memcpy(original_data, o.original_data, sizeof(int)*item_deal);
293                }
294                if (o.old_data) {
295                        old_data = new int[item_deal];
296                        memcpy(old_data, o.old_data, sizeof(int)*item_deal);
297                }
298                if (o.new_data) {
299                        new_data = new int[item_deal];
300                        memcpy(new_data, o.new_data, sizeof(int)*item_deal);
301                }
302        }
303        /* 蚭定Init で初期化、Set で倉曎、Get で倉曎を優先しお取り出す */
304        void Init(int deal, const int* list) { /* deal は無芖 */
305                if (original_data) delete[] original_data;
306                original_data = NULL;
307                if (deal <= 0) {
308                        item_deal = 0; return;
309                }
310                item_deal = deal;
311                original_data = new int[item_deal];
312                memcpy(original_data, list, sizeof(int)*deal);
313        }
314        void Set(int deal, const int* list) { /* deal は無芖 */
315                item_deal = deal;
316                if (new_data) delete[] new_data;
317                new_data = new int[item_deal];
318                memcpy(new_data, list, sizeof(int)*item_deal);
319        }
320        const int* Get(int deal) const {/* deal は無芖 */
321                if (item_deal == 0) return NULL;
322                if (deal > item_deal) {
323                        fprintf(stderr,"AyuSysConfigIntlistItem::Get : invalid items deal %d (correct: %d)\n",deal,item_deal);
324                        return NULL;
325                }
326                if (new_data) return new_data;
327                else if (old_data) return old_data;
328                return original_data;
329        }
330        const int* GetOriginal(int deal) const {/* deal は無芖 */
331                if (item_deal == 0) return NULL;
332                if (deal > item_deal) {
333                        fprintf(stderr,"AyuSysConfigIntlistItem::Get : invalid items deal %d (correct: %d)\n",deal,item_deal);
334                        return NULL;
335                }
336                return original_data;
337        }
338        int Deal(void) const {
339                return item_deal;
340        }
341        /* オリゞナルからの倉化の調査 :
342        ** DiffOriginal で倉化を文字列で取り出し、PatchOriginal で
343        ** 倉化を反映
344        */
345        int DiffOriginalLen(void) {
346                if (new_data == NULL) return 0;
347                return  12 * item_deal + 1;
348        }
349        void DiffOriginal(string& data) {
350                if (new_data == NULL) { /* あり埗ない */
351                        fprintf(stderr,"AyuSysConfigStringItem::DiffOriginal : this method must not called if not required!\n");
352                        return;
353                }
354                int i; char buf[1024];
355                for (i=0; i<item_deal; i++) {
356                        sprintf(buf, "%d,",new_data[i]);
357                        data += buf;
358                }
359                return;
360        }
361        const char* PatchOriginal(const char* data) {
362                if (old_data) delete[] old_data;
363                if (new_data) delete[] new_data;
364                old_data = NULL;
365                new_data = new int[item_deal];
366                int i;
367                for (i=0; i<item_deal; i++) {
368                        new_data[i] = atoi(data);
369                        if (strchr(data, ',') == NULL) break;
370                        data = strchr(data, ',') + 1;
371                }
372                return data;
373        }
374        void SetOriginal(void) {
375                if (new_data) delete[] new_data;
376                if (old_data) delete[] old_data;
377                new_data = NULL;
378                old_data = NULL;
379        }
380        void Dump(FILE* f) const {
381                fprintf(f, "item deal %d, ",item_deal);
382                if (original_data) {
383                        fprintf(f, "(%d", original_data[0]);
384                        int i;for (i=1; i<item_deal; i++) {
385                                fprintf(f, ",%d",original_data[i]);
386                        }
387                        fprintf(f, ") ");
388                }
389                if (old_data) {
390                        fprintf(f, "old %p(%d", old_data, old_data[0]);
391                        int i;for (i=1; i<item_deal; i++) {
392                                fprintf(f, ",%d",old_data[i]);
393                        }
394                        fprintf(f, ") ");
395                }
396                if (new_data) {
397                        fprintf(f, "new %p(%d", new_data, new_data[0]);
398                        int i;for (i=1; i<item_deal; i++) {
399                                fprintf(f, ",%d",new_data[i]);
400                        }
401                        fprintf(f, ") ");
402                }
403                fprintf(f, "\n");
404        }
405};
406
407// template map<HashStr, AyuSysConfigStringItem>;
408// template map<HashStr, AyuSysConfigIntlistItem>;
409
410/************************************************
411** AyuSysConfigItem
412** デヌタ名 -> デヌタ本䜓の map ず、map 党䜓に
413** 様々な操䜜を行うためのメ゜ッド
414*/
415
416template<class ItemType, class DataType> class AyuSysConfigItem {
417        typedef map<HashStr,ItemType> maptype;
418        typedef typename maptype::iterator mapiterator;
419        typedef typename maptype::const_iterator const_mapiterator;
420        maptype data;
421public:
422        void SetOrig(HashStr& name, int deal, const DataType* str) {
423                if (str == NULL) return; /* 無効 */
424                data[name].Init(deal, str);
425        }
426        void Set(HashStr& name, int deal, const DataType* new_data) {
427                if (new_data == NULL) return; /* 無効 */
428                /* 蚭定を怜玢 */
429                mapiterator it = data.find(name);
430                /* 蚭定が元蚭定に芋぀からないなら倱敗 */
431                if (it == data.end()) {
432                        fprintf(stderr,"AyuSysConfigItem::Set : there is no '%s' parameter\n",name.c_str());
433                        return;
434                }
435                /* 蚭定を倉曎 */
436                it->second.Set(deal, new_data);
437        }
438        /* 新しい蚭定を優先しお返す */
439        const DataType* Get(int deal, HashStr& name) const {
440                const_mapiterator it = data.find(name);
441                if (it == data.end()) return NULL;
442                return it->second.Get(deal);
443        }
444        const DataType* GetOriginal(int deal, HashStr& name) const {
445                const_mapiterator it = data.find(name);
446                if (it == data.end()) return NULL;
447                return it->second.GetOriginal(deal);
448        }
449        int Deal(HashStr& name) const {
450                const_mapiterator it = data.find(name);
451                if (it == data.end()) return NULL;
452                return it->second.Deal();
453        }
454        /* オリゞナルからの倉化の調査 :
455        ** DiffOriginal で倉化を文字列で取り出し、PatchOriginal で
456        ** 倉化を反映
457        */
458        void DiffOriginal(string& ret_str) {
459                mapiterator it = data.begin();
460                for (; it != data.end(); it++) {
461                        int len = it->second.DiffOriginalLen();
462                        if (len) {
463                                ret_str += it->first.c_str();
464                                ret_str += "=";
465                                it->second.DiffOriginal(ret_str);
466                                ret_str += ";";
467                        }
468                }
469                ret_str += ";";
470                return;
471        }
472        const char* PatchOriginal(const char* diff_data) {
473                while(*diff_data != ';') {
474                        char name[1024];
475                        const char* data_start = strchr(diff_data, '=');
476                        if (data_start == NULL) break;
477                        strncpy(name, diff_data, data_start-diff_data);
478                        name[data_start-diff_data] = 0;
479                        data_start++;
480                        mapiterator it = data.find(name);
481                        if (it != data.end()) {
482                                diff_data = data_start;
483                                it->second.PatchOriginal(diff_data);
484                        }
485                        diff_data = strchr(diff_data, ';');
486                        if (diff_data) diff_data++;
487                }
488                if (*diff_data == ';') {
489                        diff_data++;
490                } else {
491                        fprintf(stderr,"AyusysConfigItem::PatchOriginal: invalid data %s\n",diff_data);
492                }
493                return diff_data;
494        }
495        void SetOriginal(void) {
496                mapiterator it = data.begin();
497                for (; it != data.end(); it++) {
498                        it->second.SetOriginal();
499                }
500        }
501        void Dump(FILE* f) const {
502                const_mapiterator it = data.begin();
503                for (; it != data.end(); it++) {
504                        fprintf(f, "name %s: ",it->first.c_str());
505                        it->second.Dump(f);
506                }
507        }
508};
509// template AyuSysConfigItem<AyuSysConfigStringItem, char>;
510// template AyuSysConfigItem<AyuSysConfigIntlistItem, int>;
511
512/************************************************/
513/* ラッパ */
514struct AyuSysConfigString {
515        AyuSysConfigItem<AyuSysConfigStringItem,char> orig;
516        void Dump(FILE* f) const {
517                fprintf(f, "string config:\n");
518                orig.Dump(f);
519        }
520};
521struct AyuSysConfigIntlist {
522        AyuSysConfigItem<AyuSysConfigIntlistItem, int> orig;
523        void Dump(FILE* f) const {
524                fprintf(f, "integer array config:\n");
525                orig.Dump(f);
526        }
527};
528
529/************************************************/
530/* AyuSysConfig クラス */
531int AyuSysConfig::SearchParam(const char* name) const{
532        HashStr str(name);
533        if (str_config->orig.Get(1, str)) return 1; /* char* のパラメヌタ */
534        else if (int_config->orig.Get(1, str)) return 2; /* int のパラメヌタ */
535        /* XXX.015.XXX の類のキヌ名を XXX.000.XXX の圢に芏栌化しお再怜玢 */
536        char name_copy[1024];
537        strncpy(name_copy, name, 1000);
538        name_copy[1000] = 0;
539        char* s;
540        for (s=name_copy; s != NULL; s = strchr(s,'.')) {
541                if (isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])) {
542                        s[1] = '0'; s[2] = '0'; s[3] = '0';
543                }
544                s++;
545        }
546        HashStr str2(name_copy);
547        if (str_config->orig.Get(1, str2)) return 1; /* char* のパラメヌタ */
548        else if (int_config->orig.Get(1, str2)) return 2; /* int のパラメヌタ */
549        else return 0;
550}
551const char* AyuSysConfig::GetParaStr(const char* name) const{
552        HashStr str(name);
553        const char* ret = str_config->orig.Get(1,str);
554        if (ret == NULL) {
555                // fprintf(stderr,"Cannot find config name '%s'\n",name);
556        }
557        return ret;
558}
559int AyuSysConfig::GetParam(const char* name, int deal, ...) const{
560        HashStr str(name);
561        va_list va; int i;
562        const int* vars = int_config->orig.Get(deal, str);
563        if (vars == NULL) {
564                // fprintf(stderr,"Cannot find config name '%s'\n",name);
565                va_start(va, deal);
566                for (i=0; i<deal; i++) {
567                        int* var = va_arg(va, int*);
568                        if (var != NULL) *var = 0;
569                }
570                va_end(va);
571                return -1;
572        } else {
573                va_start(va, deal);
574                for (i=0; i<deal; i++) {
575                        int* var = va_arg(va, int*);
576                        if (var != NULL) *var = vars[i];
577                }
578                va_end(va);
579        }
580        return 0;
581}
582int AyuSysConfig::GetOriginalParam(const char* name, int deal, ...) const{
583        HashStr str(name);
584        va_list va; int i;
585        const int* vars = int_config->orig.GetOriginal(deal, str);
586        if (vars == NULL) {
587                // fprintf(stderr,"Cannot find config name '%s'\n",name);
588                va_start(va, deal);
589                for (i=0; i<deal; i++) {
590                        int* var = va_arg(va, int*);
591                        if (var != NULL) *var = 0;
592                }
593                va_end(va);
594                return -1;
595        } else {
596                va_start(va, deal);
597                for (i=0; i<deal; i++) {
598                        int* var = va_arg(va, int*);
599                        if (var != NULL) *var = vars[i];
600                }
601                va_end(va);
602        }
603        return 0;
604}
605const int* AyuSysConfig::GetParamArray(const char* name, int& deal) const{
606        HashStr str(name);
607        if (int_config->orig.Deal(str) == 0) {
608                deal = 0;
609                return NULL;
610        }
611        deal = int_config->orig.Deal(str);
612        const int* vars = int_config->orig.Get(deal, str);
613        if (vars == NULL) {
614                deal = 0;
615                return NULL;
616        }
617        return vars;
618}
619void AyuSysConfig::SetParaStr(const char* name, const char* var) {
620        HashStr str(name);
621        dirty_flag = 1; change_flag = 1;
622        str_config->orig.Set(str, 1, var);
623}
624void AyuSysConfig::SetParam(const char* name, int deal, ...) {
625        if (deal >= MAXVARS) return ;
626        HashStr str(name);
627        int vars[deal]; va_list va; int i;
628        va_start(va, deal);
629        for (i=0; i<deal; i++) vars[i] = va_arg(va, int);
630        va_end(va);
631        int_config->orig.Set(str, deal, vars);
632        dirty_flag = 1; change_flag = 1;
633        return;
634}
635void AyuSysConfig::SetOrigParaStr(const char* name, const char* var) {
636        HashStr str(name);
637        str_config->orig.SetOrig(str, 1, var);
638        change_flag = 1;
639}
640void AyuSysConfig::SetOrigParam(const char* name, int deal, ...) {
641        if (deal >= MAXVARS) return;
642        HashStr str(name);
643        int vars[deal]; va_list va; int i;
644        va_start(va, deal);
645        for(i=0; i<deal; i++) vars[i] = va_arg(va, int);
646        va_end(va);
647        int_config->orig.SetOrig(str, deal, vars);
648        change_flag = 1;
649}
650void AyuSysConfig::SetOrigParamArray(const char* name, int deal, int* array) {
651        HashStr str(name);
652        int_config->orig.SetOrig(str, deal, array);
653}
654void AyuSysConfig::SetOriginal(void) {
655        /* 党おの蚭定を元に戻す */
656        str_config->orig.SetOriginal();
657        int_config->orig.SetOriginal();
658        change_flag = 1;
659}
660void AyuSysConfig::DiffOriginal(string& data) {
661        str_config->orig.DiffOriginal(data);
662        int_config->orig.DiffOriginal(data);
663        return;
664}
665const char* AyuSysConfig::PatchOriginal(const char* data) {
666        data = str_config->orig.PatchOriginal(data);
667        data = int_config->orig.PatchOriginal(data);
668        return data;
669}
670
671void AyuSysConfig::Dump(FILE* f) const {
672        str_config->Dump(f);
673        int_config->Dump(f);
674}
675
676/************************************************
677** AyuSysConfig のコンストラクタ
678** 党おの config 項目を初期化する
679*/
680
681AyuSysConfig * AyuSysConfig::_singleton = NULL;
682
683AyuSysConfig* AyuSysConfig::GetInstance(void)
684{
685        if (_singleton == NULL)
686                _singleton = new AyuSysConfig;
687        return _singleton;
688}
689
690void AyuSysConfig::Quit(void)
691{
692        if (_singleton != NULL) {
693                delete _singleton;
694                _singleton = NULL;
695        }
696}
697
698
699AyuSysConfig::AyuSysConfig(void) {
700        int i;
701
702        change_flag = 1; dirty_flag = 0;
703        str_config = new AyuSysConfigString;
704        int_config = new AyuSysConfigIntlist;
705
706        /****** 文字列 *******/
707        SetOrigParaStr("#WAKUPDT", "GRDAT");    /* 枠、マりスカヌ゜ルなどの画像ファむル */
708        SetOrigParaStr("#REGNAME", "xclannad"); /* レゞストリ名。セヌブファむルの䜜成に䜿う */
709        SetOrigParaStr("#CAPTION", "xclannad"); /* りィンドりのタむトル */
710        SetOrigParaStr("#SAVENAME","SAVE.INI"); /* セヌブファむルの名前 */
711        SetOrigParaStr("#SAVETITLE", "This is save file"); /* セヌブファむルの先頭の文字列 */
712        SetOrigParaStr("#SAVENOTITLE", "-----------------"); /* 䜿われおないセヌブデヌタの名前 */
713        SetOrigParaStr("#CGM_FILE", "MODE.CGM");/* CG mode の蚭定が保存されたファむル名 */
714        SetOrigParaStr("#CGTABLE_FILE", "MODE.CGM");/* CG mode の蚭定が保存されたファむル名 */
715
716        SetOrigParaStr("#WAKU.000.000.NAME", ""); // テキストりィンドりの窓食り画像名
717        SetOrigParaStr("#WAKU.000.000.BACK", ""); // テキストりィンドりのテキスト背景画像名
718        SetOrigParaStr("#WAKU.000.000.BTN", ""); // テキストりィンドりのボタン画像名
719
720        SetOrigParaStr("#MOUSE_CURSOR.000.NAME", ""); // マりスカヌ゜ルのファむル名
721        SetOrigParaStr("#CURSOR.000.NAME", ""); // リタヌンカヌ゜ルのファむル名
722        SetOrigParaStr("#SELBTN.000.NAME", ""); // 遞択肢背景
723        SetOrigParaStr("#SELBTN.000.BACK", ""); // 遞択肢背景
724
725        char name_str[8] = "#NAME.A";
726        for (i='A'; i<='Z'; i++) {
727                name_str[6] = i;
728                SetOrigParaStr(name_str, "");
729        }
730
731        /****** 数倀列 *******/
732        SetOrigParam("#CANCELCALL", 2, 0,0); /* キャンセルボタン(右クリック)したずきに呌び出されるサブルヌチン番号(メニュヌ) */
733        SetOrigParam("#COM2_TITLE", 1, 1); /*  */
734        SetOrigParam("#COM2_TITLE_COLOR", 1, 2); /* 遞択肢タむトルの色 */
735        SetOrigParam("#COM2_TITLE_INDENT", 1, 2); /*  */
736        SetOrigParam("#SAVEFILETIME", 1, 24); /* セヌブする堎所の数 */
737        SetOrigParam("#SEEN_START", 1, 0); /* ゲヌムを開始するシナリオ番号 */
738        SetOrigParam("#SEEN_SRT", 1, 0); /* ゲヌムを開始するシナリオ番号(奜き奜き倧奜き) */
739        SetOrigParam("#SEEN_MENU",  1, 0); /* メニュヌのシナリオ番号 */
740        SetOrigParam("#SEEN_TEXT_CURRENT",  1, 0); /* seen.txt を root directory に眮くか */
741        SetOrigParam("#FADE_TIME", 1, 40); /* 画面のフェヌド・アりトの速床 */
742        SetOrigParam("#NVL_SYSTEM",1, 0); /* テキストりィンドりが党画面か吊か */
743        SetOrigParam("#WINDOW_ATTR", 5, -1, 128,128, 190, 0); /* テキストりィンドりの色 */
744        SetOrigParam("#WINDOW_ATTR_AREA", 4, 4,4,4,4); /* テキストりィンドりの範囲 */
745        SetOrigParam("#WINDOW_ATTR_TYPE", 1, 0); /* テキストりィンドりを半透明にするか */
746        SetOrigParam("#WINDOW_MSG_POS", 2, 22, 350); /* テキストりィンドりの䜍眮 */
747        SetOrigParam("#WINDOW_COM_POS", 2,450, 250); /* 遞択りィンドりの䜍眮 */
748        SetOrigParam("#WINDOW_GRP_POS", 2, 16, 100); /* なにかのりィンドりの䜍眮 */
749        SetOrigParam("#WINDOW_SUB_POS", 2, 48, 100); /* なにかのりィンドりの䜍眮 */
750        SetOrigParam("#WINDOW_SYS_POS", 2, 32, 100); /* なにかのりィンドりの䜍眮 */
751        SetOrigParam("#WINDOW_WAKU_TYPE", 1, 0); /* テキストりィンドりの枠の皮類。xkanon 独自蚭定 */
752        SetOrigParam("#RETN_CONT", 1, 16); /* リタヌンカヌ゜ルの数 */
753        SetOrigParam("#RETN_SPEED",1,100); /* リタヌンカヌ゜ルの動く速床 */
754        SetOrigParam("#RETN_XSIZE", 1, 16); /* リタヌンカヌ゜ルの倧きさ */
755        SetOrigParam("#RETN_YSIZE", 1, 16); /* リタヌンカヌ゜ルの倧きさ */
756        SetOrigParam("#FONT_SIZE", 1, 26); /* フォントの倧きさ */
757        SetOrigParam("#FONT_WEIGHT", 1, 100); /* フォントの weight */
758        SetOrigParam("#MSG_MOJI_SIZE", 2, 12, 29); /* 文字の倧きさ(半角) */
759        SetOrigParam("#MESSAGE_SIZE", 2, 23, 3); /* メッセヌゞりィンドりの文字数 */
760        SetOrigParam("#COM_MESSAGE_SIZE", 2, 23, 3); /* メッセヌゞりィンドりの文字数 */
761        SetOrigParam("#INIT_MESSAGE_SPEED", 1, 30); /* テキスト衚瀺速床 */
762        SetOrigParam("#INIT_MESSAGE_SPEED_MOD", 1, 0); /* テキスト衚瀺 no wait */
763        SetOrigParam("#MESSAGE_KEY_WAIT_USE", 1, 0); /* テキスト進行オヌトモヌド */
764        SetOrigParam("#MESSAGE_KEY_WAIT_TIME", 1, 1500); /* オヌトモヌドでのキヌ埅ち時間 */
765
766        SetOrigParam("#GRP_DC_TIMES", 1, 4); /* 裏画面の数 */
767        SetOrigParam("#MUSIC_LINEAR_PAC",1,0); /* PCM デヌタの 8bit -> 16bit 倉換を行うか */
768        SetOrigParam("#MUSIC_TYPE",1,0); /* PCM デヌタの皮類 */
769        SetOrigParam("#WINDOW_MSGBK_BOX",1,0); /* バックログ甚のボタン */
770        SetOrigParam("#WINDOW_MSGBK_LBOX_POS",4,15,7,8,0); /* バックログ甚のボタン(å·Š)の䜍眮 */
771        SetOrigParam("#WINDOW_MSGBK_RBOX_POS",4,7,7,0,0); /* バックログ甚のボタン(å·Š)の䜍眮 */
772        SetOrigParam("#MSGBK_MOD",1,0); /* バックログ甚のボタンを䜿甚するか */
773
774        SetOrigParam("#WAKU.000.000.TYPE", 1, 5);
775        SetOrigParam("#WAKU.000.000.MOVE_BOX", 5, 0, 0, 0, 0, 0); // テキストりィンドりの移動甚ボタン䜍眮
776        SetOrigParam("#WAKU.000.000.CLEAR_BOX", 5, 0, 0, 0, 0, 0); //    䞀時消去甚ボタン䜍眮
777        SetOrigParam("#WAKU.000.000.READJUMP_BOX", 5, 0, 0, 0, 0, 0); // スキップ甚ボタン䜍眮
778        SetOrigParam("#WAKU.000.000.AUTOMODE_BOX", 5, 0, 0, 0, 0, 0); // オヌト甚ボタン䜍眮
779        SetOrigParam("#WAKU.000.000.MSGBK_BOX", 5, 0, 0, 0, 0, 0); // バックログボタン䜍眮
780        SetOrigParam("#WAKU.000.000.MSGBKLEFT_BOX", 5, 0, 0, 0, 0, 0); // バックログ進めるボタン䜍眮
781        SetOrigParam("#WAKU.000.000.MSGBKRIGHT_BOX", 5, 0, 0, 0, 0, 0); // バックログ戻るボタン䜍眮
782        SetOrigParam("#WAKU.000.000.EXBTN_000_BOX", 5, 0, 0, 0, 0, 0); // その他ボタン䜍眮
783        SetOrigParam("#WAKU.000.000.EXBTN_001_BOX", 5, 0, 0, 0, 0, 0); // その他ボタン䜍眮
784        SetOrigParam("#WAKU.000.000.EXBTN_002_BOX", 5, 0, 0, 0, 0, 0); // その他ボタン䜍眮
785
786        SetOrigParam("#WINDOW.000.MOJI_SIZE", 1, 21); // 文字サむズ
787        SetOrigParam("#WINDOW.000.MOJI_REP", 2, -1, 2); // 文字の䜙裕
788        SetOrigParam("#WINDOW.000.MOJI_CNT", 2, 20, 3); // りィンドり内の文字数
789        SetOrigParam("#WINDOW.000.MOJI_POS", 4, 100, 0, 180, 40); // テキスト䜍眮。3぀目がx で1぀目がyらしい
790        SetOrigParam("#WINDOW.000.MOJI_SHADOW", 1, 0); // 文字に圱を付けるか
791        SetOrigParam("#WINDOW.000.LUBY_SIZE", 1, 8); // ルビの文字サむズ
792        SetOrigParam("#WINDOW.000.MOJI_MIN", 2, 8, 1); // 文字同士の隙間
793        SetOrigParam("#WINDOW.000.SELCOM_USE", 1, 0); // 遞択肢の実装方法
794        SetOrigParam("#WINDOW.000.POS", 4, 100, 0, 0, 260); // りィンドり䜍眮
795        SetOrigParam("#WINDOW.000.ATTR_MOD", 1, 0); // りィンドり色
796        SetOrigParam("#WINDOW.000.ATTR", 5, -1, -1, -1, -1, -1); // りィンドり色
797        /* SELCOM はよくわからんので無芖 */
798        SetOrigParam("#WINDOW.000.OPEN_ANM_MOD", 1, 0); // りィンドりを開くずきの効果らしい
799        SetOrigParam("#WINDOW.000.OPEN_ANM_TIME", 1, 500);
800        SetOrigParam("#WINDOW.000.CLOSE_ANM_MOD", 1, 0); // りィンドりを閉じるずきの効果らしい
801        SetOrigParam("#WINDOW.000.CLOSE_ANM_TIME", 1, 500);
802        SetOrigParam("#WINDOW.000.WAKU_SETNO", 1, 0); // 枠の皮類
803        SetOrigParam("#WINDOW.000.MOVE_USE", 1, 0); // りィンドり枠移動ボタン䜿甚の可吊
804        SetOrigParam("#WINDOW.000.CLEAR_USE", 1, 0); // りィンドり枠消去ボタン䜿甚の可吊
805        SetOrigParam("#WINDOW.000.READJUMP_USE", 1, 0); // スキップボタン䜿甚の可吊
806        SetOrigParam("#WINDOW.000.AUTOMODE_USE", 1, 0); // スキップボタン䜿甚の可吊
807        SetOrigParam("#WINDOW.000.MSGBK_USE", 1, 0); // バックログボタン䜿甚の可吊
808        SetOrigParam("#WINDOW.000.MSGBKLEFT_USE", 1, 0); // バックログ進むボタン䜿甚の可吊
809        SetOrigParam("#WINDOW.000.MSGBKRIGHT_USE", 1, 0); // バックログ戻るボタン䜿甚の可吊
810        SetOrigParam("#WINDOW.000.EXBTN_000_USE", 1, 0); // その他ボタン䜿甚の可吊
811        SetOrigParam("#WINDOW.000.EXBTN_001_USE", 1, 0); // その他ボタン䜿甚の可吊
812        SetOrigParam("#WINDOW.000.EXBTN_002_USE", 1, 0); // その他ボタン䜿甚の可吊
813        SetOrigParam("#WINDOW.000.NAME_MOD", 1, 0); // 名前りィンドりを別途䜿甚するか
814        SetOrigParam("#WINDOW.000.NAME_MOJI_SIZE", 1, 20); // 名前フォントのサむズ
815        SetOrigParam("#WINDOW.000.NAME_MOJI_POS", 2, 0, 0); // 名前りィンドりの文字の䜍眮
816        SetOrigParam("#WINDOW.000.NAME_MOJI_MIN", 1, 0); // 名前りィンドりの幅
817        SetOrigParam("#WINDOW.000.NAME_CENTERING", 1, 1); // 名前のセンタリングの有無
818        SetOrigParam("#WINDOW.000.NAME_POS", 2, 159, 78); // 名前りィンドり䜍眮巊䞋䜍眮らしい
819        SetOrigParam("#WINDOW.000.NAME_WAKU_SETNO", 1, -1); // 名前りィンドり䜍眮巊䞋䜍眮らしい
820        SetOrigParam("#WINDOW.000.FACE.000", 5, 0, 0, 1, 1, 1); // 顔りィンドり䜍眮(始め぀がx,y、MOJI_POSからの盞察䜍眮なのに泚意)
821        SetOrigParam("#WINDOW.000.KEYCUR_MOD", 3, 0, 0, 0); // リタヌンカヌ゜ルの䜍眮
822
823
824        SetOrigParam("#CURSOR.000.SIZE", 2, 0, 0); // リタヌンカヌ゜ルの倧きさ
825        SetOrigParam("#CURSOR.000.CONT", 1, 50); // リタヌンカヌ゜ルの繰り返し数
826        SetOrigParam("#CURSOR.000.SPEED", 1, 1000); // ブリンクする速さ
827
828        SetOrigParam("#SELBTN.000.CENTERING", 2, 0, 0);
829        SetOrigParam("#SELBTN.000.BASEPOS", 2, 0, 0); // 遞択肢りィンドりの䜍眮
830        SetOrigParam("#SELBTN.000.REPPOS", 2, 0, 50); // 遞択肢りィンドりの次の䜍眮盞察
831        SetOrigParam("#SELBTN.000.MOJISIZE", 4, 26, 0,0,0); // 文字の倧きさ
832        SetOrigParam("#SELBTN.000.MOJIDEFAULTCOL", 1, 0); // 非遞択時の文字色
833        SetOrigParam("#SELBTN.000.MOJISELECTCOL", 1, 0); // 遞択時の文字色
834
835        SetOrigParam("#COLOR_TABLE.000", 3, 255,255,255);
836        SetOrigParam("#SHAKE.000", 3, 0,0,0);
837
838        SetOrigParam("#SELR.000",16,0,0,640,480,0,0,500,50,0,0,0,0,0,0,255,0);
839        SetOrigParam("#SEL.000", 15,0,0,639,479,0,0, 32, 4,0,0,0,0,0,0,0); 
840
841        SetOrigParam("#SCREENSIZE_MOD", 1, 0); /* 0 = 640x480; 1 = 800x600 */
842       
843        SetOrigParam("#LASTSAVE", 1, 0);
844       
845        SetOrigParam("#VOLMOD", 4, 128, 128, 128, 128);
846}
847AyuSysConfig::~AyuSysConfig(void) {
848        delete str_config;
849        delete int_config;
850}
851
852static int SplitVar(const char* str, int* ret_var, int ret_size) {
853        /* , あるいは ),:( をセパレヌタずしお、-?[0-9]+ の
854        ** フォヌマットの数倀列を読み蟌む。先頭に (、末尟に ) が付きうる。
855        ** (),-[0-9] 以倖の文字があったらそこで終了
856        ** 埗られたデヌタ数を返す
857        */
858        if (*str == '(') str++;
859        int i; for (i=0; i<ret_size; i++) {
860                int c; int is_positive = 1;
861                /* セパレヌタの読み飛ばし */
862                c = *str;
863                if (c == ',' || c == ':') {
864                        str++;
865                } else if (c == ')' && str[1] == '(') {
866                        str += 2;
867                }
868                /* - を parse */
869                c = *str;
870                if (c == '-' && isdigit(str[1])) {
871                        is_positive = -1; str++;
872                } else if (! isdigit(c)) {
873                        return i; /* 異垞な文字を芋぀けた終了 */
874                }
875                int number = 0;
876                /* 数字読み蟌み */
877                while(isdigit( (c=*str) )) {
878                        number *= 10;
879                        number += c-'0';
880                        str++;
881                }
882                ret_var[i] = is_positive * number;
883        }
884        return i;
885}
886/* 決められた数の匕数を埗る。-1 なら゚ラヌが生じた */
887static inline int SplitVar(const char* str, int& var1) {
888        if (SplitVar(str, &var1, 1) != 1) return -1;
889        return 0;
890}
891static inline int SplitVar(const char* str, int& var1, int& var2) {
892        int vars[2];
893        if (SplitVar(str, vars, 2) != 2) return -1;
894        var1 = vars[0]; var2 = vars[1];
895        return 0;
896}
897static inline int SplitVar(const char* str, int& var1, int& var2, int& var3) {
898        int vars[3];
899        if (SplitVar(str, vars, 3) != 3) return -1;
900        var1 = vars[0]; var2 = vars[1]; var3 = vars[2];
901        return 0;
902}
903static inline int SplitVar(const char* str, int& var1, int& var2, int& var3, int& var4) {
904        int vars[4];
905        if (SplitVar(str, vars, 4) != 4) return -1;
906        var1 = vars[0]; var2 = vars[1]; var3 = vars[2]; var4 = vars[3];
907        return 0;
908}
909
910bool AyuSysConfig::LoadInitFile(void)
911{
912        FileSearcher* file_searcher = FileSearcher::GetInstance();
913
914        char buf[1024]; int i;
915        char* tokens[MAXTOKEN]; int token_deal; int buf_ptr;
916        int numbers[MAXVARS];
917
918        ARCINFO* info = file_searcher->Find(FileSearcher::ROOT, "gameexe.ini");
919        if (info == NULL) return false;
920        int size = info->Size();
921        unsigned char* buf_orig = (unsigned char*)info->Read();
922        if (size <= 0 || buf_orig == NULL) {
923                delete info; return false;
924        }
925        unsigned char* buf_end = buf_orig + size;
926        int line_count = 0;
927        while(buf_orig < buf_end) {
928                /* buf_orig から䞀行読み蟌む */
929                /* その際に、
930                ** ・頭が # 以倖なら次の行たでずばす
931                ** ・"" 倖のスペヌス、TABを初めずする制埡文字 (0x20 以䞋のASCIIコヌド)を削陀
932                ** ・= で区切る。区切りは最倧で10個で、tokens に代入される
933                ** などの操䜜を行う
934                */
935
936                /* # チェック */
937                if (*buf_orig != '#') {
938                        /* 次の '\n' たで読み飛ばし */
939                        while(buf_orig < buf_end &&
940                                *buf_orig != '\n' && *buf_orig != '\r') buf_orig++;
941                        if (buf_orig < buf_end-1 && *buf_orig == '\r' && buf_orig[1] == '\n') buf_orig += 2;
942                        else if (*buf_orig == '\r' || *buf_orig == '\n') buf_orig++;
943                        line_count++;
944                        continue;
945                }
946                /* 初期化 */
947                token_deal = 1;
948                tokens[0] = buf;
949                buf_ptr = NULL;
950                int in_quote = 0;
951
952                while(buf_orig < buf_end && buf_ptr < 1023) {
953                        if (in_quote) {
954                                /* "" の䞭 */
955                                int c = *buf_orig;
956                                if (c == '\n' || c == '\r') {
957                                        break;
958                                } else if (c == '\"') {
959                                        in_quote = 0;
960                                } else {
961                                        buf[buf_ptr++] = c;
962                                }
963                                buf_orig++;
964                        } else { /* quote されおない */
965                                /* 制埡文字を読み飛ばす */
966                                while(*buf_orig <= 0x20 && buf_orig < buf_end &&
967                                        *buf_orig != '\n' && *buf_orig != '\r') buf_orig++;
968                                int c = *buf_orig;
969                                if (c == '\n' || c == '\r') break;
970                                /* = なら次の token */
971                                if (c == '=') {
972                                        c = 0;
973                                        tokens[token_deal++] = buf+buf_ptr+1;
974                                        if (token_deal >= MAXTOKEN) break;
975                                } else if (c == '\"') {
976                                        in_quote = 1; buf_orig++; continue;
977                                }
978                                buf[buf_ptr++] = c;
979                                buf_orig++;
980                        }
981                }
982                buf[buf_ptr] = '\0';
983                /* 末尟の \r\n を消去 */
984                if (buf_orig < buf_end-1 && buf_orig[0] == '\r' && buf_orig[1] == '\n') buf_orig += 2;
985                else if (buf_orig < buf_end && (buf_orig[0] == '\r' || buf_orig[0] == '\n')) buf_orig++;
986                /* 必芁なら parse 内容を出力 */
987                dprintf(("line %3d ",line_count));
988                for (i=0; i<token_deal; i++) {
989                        dprintf(("%d:\"%s\", ",i,tokens[i]));
990                }
991                dprintf(("\n"));
992                if (in_quote) {
993                        fprintf(stderr, "Warning : open quote is found while parsing gameexe.ini, line %d\n",line_count);
994                }
995
996
997                /* 埗られた内容を parse */
998
999                /* #NAME=<文字列> */
1000                int type = SearchParam(tokens[0]);
1001                if (type == 1) { /* #NAME=<文字列> */
1002                        if (token_deal != 2) {
1003                                dprintf(("Parse error, line %d, %s\n",line_count, tokens[0]));
1004                                goto parse_error;
1005                        }
1006                        SetOrigParaStr(tokens[0], tokens[1]);
1007                        goto parse_end;
1008                } else if (type == 2) { /* #NAME=<数倀列> */
1009                        if (token_deal != 2) {
1010                                dprintf(("Parse error, line %d, %s\n",line_count, tokens[0]));
1011                                goto parse_error;
1012                        }
1013                        int number_deal = SplitVar(tokens[1], numbers, MAXVARS);
1014                        SetOrigParamArray(tokens[0], number_deal, numbers);
1015                        goto parse_end;
1016                }
1017                /* 䞀般的な蚭定以倖 : cdrom track など */
1018                if (strncmp(tokens[0],"#NAME.", 6) == 0) {
1019                        if (token_deal != 2) goto parse_error;
1020                        SetOrigParaStr(tokens[0], tokens[1]);
1021                        goto parse_end;
1022                } else if (strncmp(tokens[0],"#DIRC.",6) == 0) {
1023                        if (token_deal != 3) goto parse_error;
1024                        /* ファむル圢匏の指定 */
1025                        FileSearcher::FILETYPE type;
1026                        char* name = tokens[0]+6;
1027                        if (strcmp(name, "PDT") == 0) type = FileSearcher::PDT;
1028                        else if (strcmp(name, "G00") == 0) type = FileSearcher::PDT;
1029                        else if (strcmp(name, "GRP") == 0) type = FileSearcher::PDT;
1030                        else if (strcmp(name, "TXT") == 0) type = FileSearcher::SCN;
1031                        else if (strcmp(name, "ANM") == 0) type = FileSearcher::ANM; 
1032                        else if (strcmp(name, "ARD") == 0) type = FileSearcher::ARD;
1033                        else if (strcmp(name, "CUR") == 0) type = FileSearcher::CUR;
1034                        else if (strcmp(name, "WAV") == 0) type = FileSearcher::WAV;
1035                        else if (strcmp(name, "KOE") == 0) type = FileSearcher::KOE;
1036                        else if (strcmp(name, "GAN") == 0) type = FileSearcher::GAN;
1037                        else goto parse_error; /* 他に ALL,ROOT,MID,KOE,BGM。たぶん、存圚しない */
1038                        if (tokens[2][0] == 'N') { /* directory */
1039                                file_searcher->SetFileInformation(type, FileSearcher::ATYPE_DIR, tokens[1]);
1040                                dprintf(("set file directory; type %s, directory %s\n",name,tokens[1]));
1041                        } else if (tokens[2][0] == 'P' && tokens[2][1] == ':') { /* アヌカむブ */
1042                                file_searcher->SetFileInformation(type, FileSearcher::ATYPE_ARC, tokens[2]+2);
1043                                dprintf(("set file archive; type %s, file %s\n",name,tokens[2]+2));
1044                        } else goto parse_error;
1045                        goto parse_end;
1046                }
1047                if (strncmp(tokens[0],"#ADRC.",6) == 0) {
1048                        if (token_deal != 3) goto parse_error;
1049                        /* ファむル圢匏の指定 */
1050                        FileSearcher::FILETYPE type;
1051                        char* name = tokens[0]+6;
1052                        if (strcmp(name, "PDT") == 0) type = FileSearcher::PDT;
1053                        else if (strcmp(name, "G00") == 0) type = FileSearcher::PDT;
1054                        else if (strcmp(name, "GRP") == 0) type = FileSearcher::PDT;
1055                        else if (strcmp(name, "TXT") == 0) type = FileSearcher::SCN;
1056                        else if (strcmp(name, "ANM") == 0) type = FileSearcher::ANM; 
1057                        else if (strcmp(name, "ARD") == 0) type = FileSearcher::ARD;
1058                        else if (strcmp(name, "CUR") == 0) type = FileSearcher::CUR;
1059                        else if (strcmp(name, "WAV") == 0) type = FileSearcher::WAV;
1060                        else if (strcmp(name, "KOE") == 0) type = FileSearcher::KOE;
1061                        else if (strcmp(name, "GAN") == 0) type = FileSearcher::GAN;
1062                        else goto parse_error; /* 他に ALL,ROOT,MID,KOE,BGM。たぶん、存圚しない */
1063                        if (tokens[2][0] == 'N') { /* directory */
1064                                file_searcher->AppendFileInformation(type, FileSearcher::ATYPE_DIR, tokens[1]);
1065                                dprintf(("set file directory; type %s, directory %s\n",name,tokens[1]));
1066                        } else if (tokens[2][0] == 'P' && tokens[2][1] == ':') { /* アヌカむブ */
1067                                file_searcher->AppendFileInformation(type, FileSearcher::ATYPE_ARC, tokens[2]+2);
1068                                dprintf(("set file archive; type %s, file %s\n",name,tokens[2]+2));
1069                        } else if (tokens[2][0] == 'R' && tokens[2][1] == ':') { /* それ散るアヌカむブ */
1070                                file_searcher->AppendFileInformation(type, FileSearcher::ATYPE_ARC, tokens[2]+2);
1071                                dprintf(("set file archive; type %s, file %s\n",name,tokens[2]+2));
1072                        } else goto parse_error;
1073                        goto parse_end;
1074                }
1075                if (strncmp(tokens[0],"#FOLDNAME.",10) == 0) {
1076                        if (token_deal != 3) goto parse_error;
1077                        /* ファむル圢匏の指定 */
1078                        FileSearcher::FILETYPE type;
1079                        char* name = tokens[0]+10;
1080                        if (strcmp(name, "PDT") == 0) type = FileSearcher::PDT;
1081                        else if (strcmp(name, "G00") == 0) type = FileSearcher::PDT;
1082                        else if (strcmp(name, "GRP") == 0) type = FileSearcher::PDT;
1083                        else if (strcmp(name, "TXT") == 0) type = FileSearcher::SCN;
1084                        else if (strcmp(name, "ANM") == 0) type = FileSearcher::ANM; 
1085                        else if (strcmp(name, "ARD") == 0) type = FileSearcher::ARD;
1086                        else if (strcmp(name, "CUR") == 0) type = FileSearcher::CUR;
1087                        else if (strcmp(name, "WAV") == 0) type = FileSearcher::WAV;
1088                        else if (strcmp(name, "BGM") == 0) type = FileSearcher::BGM;
1089                        else if (strcmp(name, "GAN") == 0) type = FileSearcher::GAN;
1090                        else goto parse_error; /* 他に ALL,ROOT,MID,KOE,BGM。たぶん、存圚しない */
1091                        if (tokens[2][0] == '0') { /* directory */
1092                                file_searcher->AppendFileInformation(type, FileSearcher::ATYPE_DIR, tokens[1]);
1093                                dprintf(("set file directory; type %s, directory %s\n",name,tokens[1]));
1094                        } else if (tokens[2][0] == '1' && tokens[2][1] == ':') { /* アヌカむブ */
1095                                file_searcher->AppendFileInformation(type, FileSearcher::ATYPE_SCN2k, tokens[2]+2);
1096                                dprintf(("set file archive; type %s, file %s\n",name,tokens[2]+2));
1097                        } else goto parse_error;
1098                        goto parse_end;
1099                }
1100                if (strcmp(tokens[0], "#CDTRACK") == 0) {
1101                        if (token_deal != 3) goto parse_error;
1102                        track_name.AddCDROM(tokens[2], atoi(tokens[1]));
1103                        dprintf(("Set CDTRACK, name %s, track %d\n",tokens[2], atoi(tokens[1])));
1104                        goto parse_end;
1105                }
1106                if (strcmp(tokens[0], "#DSTRACK") == 0) {
1107                        /* #DSTRACK=00000000-99999000-00782556="filename"   ="name"       */
1108                        /* #DSTRACK=00000000-99999000-00782556="name"       */
1109                        /* 第二トヌクンの぀めのパラメヌタを埗る繰り返しの時の再生開始䜍眮 */
1110                        int start_pt = 0;
1111                        const char* tk1 = strchr(tokens[1], '-');
1112                        const char* tk2 = NULL;
1113                        if (tk1 && *tk1) tk2 = strchr(tk1+1, '-');
1114                        if (tk2 && *tk2) start_pt = atoi(tk2+1);
1115                        if (token_deal == 3) {
1116                                track_name.AddWave(tokens[2], tokens[2], start_pt);
1117                                dprintf(("Set Wave track, name %s\n",tokens[2]));
1118                        } else if (token_deal == 4) {
1119                                track_name.AddWave(tokens[3], tokens[2], start_pt);
1120                                dprintf(("Set Wave track, name %s, file %s\n",tokens[3], tokens[2]));
1121                        } else goto parse_error;
1122                        goto parse_end;
1123                }
1124                if (strncmp(tokens[0], "#SE.", 4) == 0) {
1125                        /* SE.XXX="XXX"=X */
1126                        if (token_deal == 2) {
1127                                track_name.AddSE(atoi(tokens[0]+4), tokens[1]);
1128                        } else if (token_deal == 3) {
1129                                if (atoi(tokens[2]) != 0) {
1130                                        track_name.AddSE(atoi(tokens[0]+4), tokens[1]);
1131                                }
1132                        }
1133                        dprintf(("Set SE %d, name %s\n",atoi(tokens[0]+4), tokens[1]));
1134                        goto parse_end;
1135                }
1136                /* 蚭定項目が芋぀からなかった */
1137                dprintf(("Cannot find configuration name: %s\n",tokens[0]));
1138        parse_error:
1139        parse_end:
1140                line_count++;
1141        }
1142        delete info;
1143        /* デフォルトのオプションを指定する */
1144        // set_game(GetParaStr("#REGNAME"), *this);
1145        return true;
1146}
1147
1148TrackName::TrackName(void) {
1149        deal = 1;
1150        track = new char*[deal];
1151        track_wave = new char*[deal];
1152        track_num = new int[deal];
1153        track_start = new int[deal];
1154        int i; for (i=0; i<deal; i++) track[i] = 0;
1155        for (i=0; i<deal; i++) track_wave[i] = 0;
1156        se_deal = 10;
1157        se_track = new char*[se_deal];
1158        for (i=0; i<se_deal; i++) se_track[i] = 0;
1159}
1160
1161TrackName::~TrackName() {
1162        int i; for (i=0; i<deal; i++) {
1163                if (track[i] != 0) delete[] track[i];
1164                if (track_wave[i] != 0) delete[] track_wave[i];
1165        }
1166        for (i=0; i<se_deal; i++) {
1167                if (se_track[i]) delete[] se_track[i];
1168        }
1169        delete[] track;
1170        delete[] track_wave;
1171        delete[] track_num;
1172        delete[] track_start;
1173        delete[] se_track;
1174}
1175void TrackName::Expand(void) {
1176        int new_deal = deal * 2;
1177        int* new_track_num = new int[new_deal];
1178        int* new_track_start = new int[new_deal];
1179        char** new_track = new char*[new_deal];
1180        char** new_track_wave = new char*[new_deal];
1181        int i; for (i=0; i<deal; i++) {
1182                new_track_num[i] = track_num[i];
1183                new_track_start[i] = track_start[i];
1184                new_track[i] = track[i];
1185                new_track_wave[i] = track_wave[i];
1186        }
1187        for (; i<new_deal; i++) { 
1188                new_track_num[i] = 0;
1189                new_track_start[i] = 0;
1190                new_track[i] = 0;
1191                new_track_wave[i] = 0;
1192        }
1193        deal = new_deal;
1194        delete[] track; track = new_track;
1195        delete[] track_num; track_num= new_track_num;
1196        delete[] track_start; track_start= new_track_start;
1197        delete[] track_wave; track_wave = new_track_wave;
1198}
1199void TrackName::ExpandSE(int n) {
1200        if (n < 0) return;
1201        n += 10;
1202        if (se_deal >= n) return;
1203        char** new_se = new char*[n];
1204        int i; for (i=0; i<se_deal; i++) new_se[i] = se_track[i];
1205        for (; i<n; i++) new_se[i] = 0;
1206        delete[] se_track;
1207        se_deal = n; se_track = new_se;
1208}
1209void TrackName::AddCDROM(char* name, int tk) {
1210        if (CDTrack(name) != -1) return;
1211        int i; for (i=0; i<deal; i++) {
1212                if (track[i] == 0) break;
1213        }
1214        int num = i;
1215        if (i == deal) Expand();
1216        track[num] = new char[strlen(name)+1];
1217        for (i=0; name[i] != 0; i++) track[num][i] = tolower(name[i]);
1218        track[num][i] = 0;
1219        track_num[num] = tk;
1220}
1221void TrackName::AddWave(char* name, char* file, int pt) {
1222        if (CDTrack(name) != -1) return;
1223        int i; for (i=0; i<deal; i++) {
1224                if (track[i] == 0) break;
1225        }
1226        int num = i;
1227        if (i == deal) Expand();
1228        track_num[num] = 0;
1229        track_start[num] = pt;
1230        track[num] = new char[strlen(name)+1];
1231        for (i=0; name[i] != 0; i++) track[num][i] = tolower(name[i]);
1232        track[num][i] = 0;
1233        track_wave[num] = new char[strlen(file)+1]; strcpy(track_wave[num], file);
1234}
1235int TrackName::CDTrack(char* name) {
1236        char buf[1024];
1237        int i;
1238        for (i=0; name[i]!=0; i++) buf[i]=tolower(name[i]);
1239        buf[i]=0;
1240        for (i=0; i<deal; i++) {
1241                if (track[i] == 0) return -1;
1242                if (strcmp(track[i],  buf) == 0) {
1243                        return track_num[i];
1244                }
1245        }
1246        return -1;
1247}
1248int TrackName::TrackStart(char* name) {
1249        char buf[1024];
1250        int i;
1251        for (i=0; name[i]!=0; i++) buf[i]=tolower(name[i]);
1252        buf[i]=0;
1253        for (i=0; i<deal; i++) {
1254                if (track[i] == 0) return -1;
1255                if (strcmp(track[i],  buf) == 0) {
1256                        return track_start[i];
1257                }
1258        }
1259        return 0;
1260}
1261const char* TrackName::WaveTrack(char* name) {
1262        char buf[1024];
1263        int i;
1264        for (i=0; name[i]!=0; i++) buf[i]=tolower(name[i]);
1265        buf[i]=0;
1266        for (i=0; i<deal; i++) {
1267                if (track[i] == 0) return NULL;
1268                if (strcmp(track[i],  buf) == 0) {
1269                        return track_wave[i];
1270                }
1271        }
1272        return NULL;
1273}
1274const char* TrackName::SETrack(int n) {
1275        if (n < 0 || n >= se_deal) return NULL;
1276        return se_track[n];
1277}
1278
1279void TrackName::AddSE(int n, char* file) {
1280        if (se_deal <= n) ExpandSE(n);
1281        if (se_track[n]) delete[] se_track[n];
1282        se_track[n] = new char[strlen(file)+1];
1283        strcpy(se_track[n], file);
1284}
1285
Note: See TracBrowser for help on using the browser.