OSDN Git Service

[Qt][MinGW] common.cpp : More workaround.
[csp-qt/common_source_project-fm7.git] / source / src / common.cpp
1 /*
2         Skelton for retropc emulator
3
4         Author : Takeda.Toshiya
5         Date   : 2013.01.17-
6
7         [ common ]
8 */
9 #if defined(_USE_QT)
10 #include <string.h>
11 #include <fcntl.h>
12 #if !defined(__WIN32) && !defined(__WIN64)
13 #include <unistd.h>
14 #else
15 #include <io.h>
16 #include <direct.h>
17 #endif
18
19 #include <sys/types.h>
20 #include <sys/stat.h>
21
22 #include "agar_logger.h"
23
24 #include <string>
25 #include <algorithm>
26 #include <cctype>
27
28 #elif defined(_WIN32)
29 #include <shlwapi.h>
30 #pragma comment(lib, "shlwapi.lib")
31 #else
32 #include <time.h>
33 #endif
34
35 #include <math.h>
36 #include "common.h"
37 #include "config.h"
38
39 uint32 EndianToLittle_DWORD(uint32 x)
40 {
41 #if defined(__LITTLE_ENDIAN__)
42         return x;
43 #else
44         uint32 y;
45         y = ((x & 0x000000ff) << 24) | ((x & 0x0000ff00) << 8) |
46             ((x & 0x00ff0000) >> 8)  | ((x & 0xff000000) >> 24);
47         return y;
48 #endif
49 }
50
51 uint16 EndianToLittle_WORD(uint16 x)
52 {
53 #if defined(__LITTLE_ENDIAN__)
54         return x;
55 #else
56         uint16 y;
57         y = ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8);
58         return y;
59 #endif
60 }
61
62 #ifndef _MSC_BER
63 int max(int a, int b)
64 {
65         if(a > b) {
66                 return a;
67         } else {
68                 return b;
69         }
70 }
71
72 unsigned int max(unsigned int a, unsigned int b)
73 {
74         if(a > b) {
75                 return a;
76         } else {
77                 return b;
78         }
79 }
80
81 int min(int a, int b)
82 {
83         if(a < b) {
84                 return a;
85         } else {
86                 return b;
87         }
88 }
89
90 unsigned int min(unsigned int a, unsigned int b)
91 {
92         if(a < b) {
93                 return a;
94         } else {
95                 return b;
96         }
97 }
98 #endif
99
100
101 #ifndef SUPPORT_SECURE_FUNCTIONS
102 errno_t my_strcpy_s(char *strDestination, size_t numberOfElements, const char *strSource)
103 {
104         strcpy(strDestination, strSource);
105         return 0;
106 }
107
108 errno_t my_tcscpy_s(_TCHAR *strDestination, size_t numberOfElements, const _TCHAR *strSource)
109 {
110         _tcscpy(strDestination, strSource);
111         return 0;
112 }
113
114 errno_t my_strncpy_s(char *strDestination, size_t numberOfElements, const char *strSource, size_t count)
115 {
116         strncpy(strDestination, strSource, count);
117         return 0;
118 }
119
120 errno_t my_tcsncpy_s(_TCHAR *strDestination, size_t numberOfElements, const _TCHAR *strSource, size_t count)
121 {
122         _tcsncpy(strDestination, strSource, count);
123         return 0;
124 }
125
126 char *my_strtok_s(char *strToken, const char *strDelimit, char **context)
127 {
128         return strtok(strToken, strDelimit);
129 }
130
131 _TCHAR *my_tcstok_s(_TCHAR *strToken, const char *strDelimit, _TCHAR **context)
132 {
133         return _tcstok(strToken, strDelimit);
134 }
135
136 int my_sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...)
137 {
138         va_list ap;
139         va_start(ap, format);
140         int result = vsprintf(buffer, format, ap);
141         va_end(ap);
142         return result;
143 }
144
145 int my_stprintf_s(_TCHAR *buffer, size_t sizeOfBuffer, const _TCHAR *format, ...)
146 {
147         va_list ap;
148         va_start(ap, format);
149         int result = _vstprintf(buffer, format, ap);
150         va_end(ap);
151         return result;
152 }
153
154 int my_vsprintf_s(char *buffer, size_t numberOfElements, const char *format, va_list argptr)
155 {
156         return vsprintf(buffer, format, argptr);
157 }
158
159 int my_vstprintf_s(_TCHAR *buffer, size_t numberOfElements, const _TCHAR *format, va_list argptr)
160 {
161         return _vstprintf(buffer, format, argptr);
162 }
163 #endif
164
165  
166 #ifndef _WIN32
167 BOOL MyWritePrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString, LPCTSTR lpFileName)
168 {
169         BOOL result = FALSE;
170         FILEIO* fio_i = new FILEIO();
171         if(fio_i->Fopen(lpFileName, FILEIO_READ_ASCII)) {
172                 char tmp_path[_MAX_PATH];
173                 my_sprintf_s(tmp_path, _MAX_PATH, "%s.$$$", lpFileName);
174                 FILEIO* fio_o = new FILEIO();
175                 if(fio_o->Fopen(tmp_path, FILEIO_WRITE_ASCII)) {
176                         bool in_section = false;
177                         char section[1024], line[1024], *equal;
178                         my_sprintf_s(section, 1024, "[%s]", lpAppName);
179                         while(fio_i->Fgets(line, 1024) != NULL && strlen(line) > 0) {
180                                 if(line[strlen(line) - 1] == '\n') {
181                                         line[strlen(line) - 1] = '\0';
182                                 }
183                                 if(!result) {
184                                         if(line[0] == '[') {
185                                                 if(in_section) {
186                                                         fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
187                                                         result = TRUE;
188                                                 } else if(strcmp(line, section) == 0) {
189                                                         in_section = true;
190                                                 }
191                                         } else if(in_section && (equal = strstr(line, "=")) != NULL) {
192                                                 *equal = '\0';
193                                                 if(strcmp(line, lpKeyName) == 0) {
194                                                         fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
195                                                         result = TRUE;
196                                                         continue;
197                                                 }
198                                                 *equal = '=';
199                                         }
200                                 }
201                                 fio_o->Fprintf("%s\n", line);
202                         }
203                         if(!result) {
204                                 if(!in_section) {
205                                         fio_o->Fprintf("[%s]\n", lpAppName);
206                                 }
207                                 fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
208                                 result = TRUE;
209                         }
210                         fio_o->Fclose();
211                 }
212                 delete fio_o;
213                 fio_i->Fclose();
214                 if(result) {
215                         if(!(FILEIO::RemoveFile(lpFileName) && FILEIO::RenameFile(tmp_path, lpFileName))) {
216                                 result = FALSE;
217                         }
218                 }
219         } else {
220                 FILEIO* fio_o = new FILEIO();
221                 if(fio_o->Fopen(lpFileName, FILEIO_WRITE_ASCII)) {
222                         fio_o->Fprintf("[%s]\n", lpAppName);
223                         fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
224                         fio_o->Fclose();
225                 }
226                 delete fio_o;
227         }
228         delete fio_i;
229         return result;
230 }
231
232 static std::string MyGetPrivateProfileStr(const _TCHAR *lpAppName, const _TCHAR *lpKeyName, _TCHAR *lpFileName)
233 {
234    std::string key;
235    char ibuf[4096 + 102];
236    int64_t i;
237    int l_len;
238    int c = '\0';
239    std::string::size_type  pos;
240    std::string key_str;
241    std::string got_str;
242    FILEIO *pf = new FILEIO;
243    
244    key = lpAppName;
245    key = key + ".";
246    key = key + lpKeyName;
247    got_str = "";
248    if(pf->Fopen(lpFileName, FILEIO_READ_ASCII) != true) {
249            delete pf;
250            return got_str;
251    }
252    AGAR_DebugLog(AGAR_LOG_DEBUG, "Try App: %s Key: %s", lpAppName, lpKeyName);
253    pf->Fseek(0, FILEIO_SEEK_SET);
254    do {
255            key_str = key;
256            ibuf[0] = '\0';
257            i = 0;
258            l_len = 0;
259            while(1) {
260                    if(l_len > (4096 + 100)) { // Too long, read dummy.
261                            c = (char)pf->Fgetc();
262                            if((c != EOF) && (c != '\n') && (c != '\0')) continue;
263                            break;
264                    }
265                    c = (char)pf->Fgetc();
266                    if((c == EOF) || (c == '\n') || (c == '\0')) break;
267                    ibuf[i] = (char)c;
268                    i++;
269                    l_len++;
270            }
271            l_len = 0;
272            ibuf[i] = '\0';
273            got_str = ibuf;
274            key_str = key_str + "=";
275            pos = got_str.find(key_str);
276            if(pos != std::string::npos) break;
277            if(c == EOF) return "";
278    } while(c != EOF);
279    pf->Fclose();
280    delete pf;
281    
282    got_str.erase(0, pos + key_str.length());
283    AGAR_DebugLog(AGAR_LOG_DEBUG, "Got: %s Length: %d", got_str.c_str(), got_str.length());
284    return got_str;
285 }
286
287
288 DWORD MyGetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPCTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName)
289 {
290         if(lpDefault != NULL) {
291                 my_strcpy_s(lpReturnedString, nSize, lpDefault);
292         } else {
293                 lpReturnedString[0] = '\0';
294         }
295         FILEIO* fio = new FILEIO();
296         if(fio->Fopen(lpFileName, FILEIO_READ_ASCII)) {
297                 bool in_section = false;
298                 char section[1024], line[1024], *equal;
299                 my_sprintf_s(section, 1024, "[%s]", lpAppName);
300                 while(fio->Fgets(line, 1024) != NULL && strlen(line) > 0) {
301                         if(line[strlen(line) - 1] == '\n') {
302                                 line[strlen(line) - 1] = '\0';
303                         }
304                         if(line[0] == '[') {
305                                 if(in_section) {
306                                         break;
307                                 } else if(strcmp(line, section) == 0) {
308                                         in_section = true;
309                                 }
310                         } else if(in_section && (equal = strstr(line, "=")) != NULL) {
311                                 *equal = '\0';
312                                 if(strcmp(line, lpKeyName) == 0) {
313                                         my_strcpy_s(lpReturnedString, nSize, equal + 1);
314                                         break;
315                                 }
316                         }
317                 }
318                 fio->Fclose();
319         }
320         delete fio;
321         return strlen(lpReturnedString);
322 }
323
324 UINT MyGetPrivateProfileInt(LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault, LPCTSTR lpFileName)
325 {
326         // write your compatible function, if possible in standard C/C++ code
327         int i;
328         char sstr[128];
329         char sval[128];
330         std::string s;
331         memset(sstr, 0x00, sizeof(sstr));
332         memset(sval, 0x00, sizeof(sval));
333         snprintf(sval, 128, "%d", nDefault); 
334         MyGetPrivateProfileString(lpAppName,lpKeyName, sval, sstr, 128, lpFileName);
335         s = sstr;
336         
337         if(s.empty()) {
338                 i = nDefault;
339         } else {
340                 i = strtol(s.c_str(), NULL, 10);
341         }
342         //AGAR_DebugLog(AGAR_LOG_DEBUG, "Got Int: %d\n", i);
343         return i;
344 }
345 #endif
346
347 #if defined(_RGB555)
348 scrntype RGB_COLOR(uint r, uint g, uint b)
349 {
350         scrntype rr = ((scrntype)r * 0x1f) / 0xff;
351         scrntype gg = ((scrntype)g * 0x1f) / 0xff;
352         scrntype bb = ((scrntype)b * 0x1f) / 0xff;
353         return (rr << 10) | (gg << 5) | bb;
354 }
355
356 scrntype RGBA_COLOR(uint r, uint g, uint b, uint a)
357 {
358         return RGB_COLOR(r, g, b);
359 }
360
361 uint8 R_OF_COLOR(scrntype c)
362 {
363         c = (c >> 10) & 0x1f;
364         c = (c * 0xff) / 0x1f;
365         return (uint8)c;
366 }
367
368 uint8 G_OF_COLOR(scrntype c)
369 {
370         c = (c >>  5) & 0x1f;
371         c = (c * 0xff) / 0x1f;
372         return (uint8)c;
373 }
374
375 uint8 B_OF_COLOR(scrntype c)
376 {
377         c = (c >>  0) & 0x1f;
378         c = (c * 0xff) / 0x1f;
379         return (uint8)c;
380 }
381
382 uint8 A_OF_COLOR(scrntype c)
383 {
384         return 0;
385 }
386 #elif defined(_RGB565)
387 scrntype RGB_COLOR(uint r, uint g, uint b)
388 {
389         scrntype rr = ((scrntype)r * 0x1f) / 0xff;
390         scrntype gg = ((scrntype)g * 0x3f) / 0xff;
391         scrntype bb = ((scrntype)b * 0x1f) / 0xff;
392         return (rr << 11) | (gg << 5) | bb;
393 }
394
395 scrntype RGBA_COLOR(uint r, uint g, uint b, uint a)
396 {
397         return RGB_COLOR(r, g, b);
398 }
399
400 uint8 R_OF_COLOR(scrntype c)
401 {
402         c = (c >> 11) & 0x1f;
403         c = (c * 0xff) / 0x1f;
404         return (uint8)c;
405 }
406
407 uint8 G_OF_COLOR(scrntype c)
408 {
409         c = (c >>  5) & 0x3f;
410         c = (c * 0xff) / 0x3f;
411         return (uint8)c;
412 }
413
414 uint8 B_OF_COLOR(scrntype c)
415 {
416         c = (c >>  0) & 0x1f;
417         c = (c * 0xff) / 0x1f;
418         return (uint8)c;
419 }
420
421 uint8 A_OF_COLOR(scrntype c)
422 {
423         return 0;
424 }
425 #endif
426
427
428 #include "fileio.h"
429 struct to_upper {  // Refer from documentation of libstdc++, GCC5.
430         char operator() (char c) const { return std::toupper(c); }
431 };
432
433 #if defined(_USE_QT)
434 extern std::string cpp_homedir;
435 extern std::string my_procname;
436 #endif
437
438 const _TCHAR *get_application_path()
439 {
440         static _TCHAR app_path[_MAX_PATH];
441         static bool initialized = false;
442         
443         if(!initialized) {
444 #ifdef _MSC_VER
445                 _TCHAR tmp_path[_MAX_PATH], *ptr = NULL;
446                 if(GetModuleFileName(NULL, tmp_path, _MAX_PATH) != 0 && GetFullPathName(tmp_path, _MAX_PATH, app_path, &ptr) != 0 && ptr != NULL) {
447                         *ptr = _T('\0');
448                 } else {
449                         my_tcscpy_s(app_path, _MAX_PATH, _T(".\\"));
450                 }
451 #else
452         #if defined(Q_OS_WIN)
453                 std::string delim = "\\";
454         #else
455                 std::string delim = "/";
456         #endif
457                 std::string cpath = cpp_homedir + my_procname + delim;
458                 strncpy(app_path, cpath.c_str(), _MAX_PATH);
459                 {
460                         struct stat st;
461 #if !defined(__WIN32) && !defined(__WIN64)
462                         if(fstatat(AT_FDCWD, app_path, &st, 0) != 0) {
463                                 mkdirat(AT_FDCWD, app_path, 0700); // Not found
464                         }
465 #else // __WIN32
466 # if defined(Q_OS_WIN)
467                         if(stat(app_path, &st) != 0) {
468                                 mkdir(app_path); // Not found
469                         }
470 # else                  
471                         if(stat(app_path, &st) != 0) {
472                                 _mkdir(app_path); // Not found
473                         }
474 # endif                 
475 #endif             
476                 }
477 #endif
478                 
479                 initialized = true;
480         }
481         return (const _TCHAR *)app_path;
482 }
483
484 const _TCHAR *create_local_path(const _TCHAR *format, ...)
485 {
486         static _TCHAR file_path[8][_MAX_PATH];
487         static unsigned int table_index = 0;
488         unsigned int output_index = (table_index++) & 7;
489         _TCHAR file_name[_MAX_PATH];
490         va_list ap;
491         
492         va_start(ap, format);
493         my_vstprintf_s(file_name, _MAX_PATH, format, ap);
494         va_end(ap);
495         my_stprintf_s(file_path[output_index], _MAX_PATH, _T("%s%s"), get_application_path(), file_name);       
496         return (const _TCHAR *)file_path[output_index];
497 }
498
499 void create_local_path(_TCHAR *file_path, int length, const _TCHAR *format, ...)
500 {
501         _TCHAR file_name[_MAX_PATH];
502         va_list ap;
503         
504         va_start(ap, format);
505         my_vstprintf_s(file_name, _MAX_PATH, format, ap);
506         va_end(ap);
507         my_stprintf_s(file_path, length, _T("%s%s"), get_application_path(), file_name);
508 }
509
510 const _TCHAR *create_date_file_path(const _TCHAR *extension)
511 {
512         cur_time_t cur_time;
513         
514         get_host_time(&cur_time);
515         return create_local_path(_T("%d-%0.2d-%0.2d_%0.2d-%0.2d-%0.2d.%s"), cur_time.year, cur_time.month, cur_time.day, cur_time.hour, cur_time.minute, cur_time.second, extension);
516 }
517
518 void create_date_file_path(_TCHAR *file_path, int length, const _TCHAR *extension)
519 {
520         my_tcscpy_s(file_path, length, create_date_file_path(extension));
521 }
522
523 bool check_file_extension(const _TCHAR *file_path, const _TCHAR *ext)
524 {
525 #if defined(_USE_QT)
526         std::string s_fpath = file_path;
527         std::string s_ext = ext;
528         bool f = false;
529         int pos;
530         std::transform(s_fpath.begin(), s_fpath.end(), s_fpath.begin(), to_upper());
531         std::transform(s_ext.begin(), s_ext.end(), s_ext.begin(), to_upper());
532         if(s_fpath.length() < s_ext.length()) return false;
533         pos = s_fpath.rfind(s_ext.c_str(), s_fpath.length());
534         if((pos != std::string::npos) && (pos >= (s_fpath.length() - s_ext.length()))) return true; 
535         return false;
536 #else
537         int nam_len = _tcslen(file_path);
538         int ext_len = _tcslen(ext);
539         
540         return (nam_len >= ext_len && _tcsncicmp(&file_path[nam_len - ext_len], ext, ext_len) == 0);
541 #endif
542 }
543
544 const _TCHAR *get_file_path_without_extensiton(const _TCHAR *file_path)
545 {
546         static _TCHAR path[8][_MAX_PATH];
547         static unsigned int table_index = 0;
548         unsigned int output_index = (table_index++) & 7;
549         
550         my_tcscpy_s(path[output_index], _MAX_PATH, file_path);
551 #ifdef _MSC_VER
552         PathRemoveExtension(path[output_index]);
553 #else
554         _TCHAR *p = _tcsrchr(path[output_index], _T('.'));
555         if(p != NULL) {
556                 *p = _T('\0');
557         }
558 #endif
559         return (const _TCHAR *)path[output_index];
560 }
561
562 const _TCHAR *create_string(const _TCHAR* format, ...)
563 {
564         static _TCHAR buffer[8][1024];
565         static unsigned int table_index = 0;
566         unsigned int output_index = (table_index++) & 7;
567         va_list ap;
568         
569         va_start(ap, format);
570         my_vstprintf_s(buffer[output_index], 1024, format, ap);
571         va_end(ap);
572         return (const _TCHAR *)buffer[output_index];
573 }
574
575 uint32 get_crc32(uint8 data[], int size)
576 {
577         static bool initialized = false;
578         static uint32 table[256];
579         
580         if(!initialized) {
581                 for(int i = 0; i < 256; i++) {
582                         uint32 c = i;
583                         for(int j = 0; j < 8; j++) {
584                                 if(c & 1) {
585                                         c = (c >> 1) ^ 0xedb88320;
586                                 } else {
587                                         c >>= 1;
588                                 }
589                         }
590                         table[i] = c;
591                 }
592                 initialized = true;
593         }
594         
595         uint32 c = ~0;
596         for(int i = 0; i < size; i++) {
597                 c = table[(c ^ data[i]) & 0xff] ^ (c >> 8);
598         }
599         return ~c;
600 }
601
602 uint16 jis_to_sjis(uint16 jis)
603 {
604         pair tmp;
605         
606         tmp.w.l = jis - 0x2121;
607         if(tmp.w.l & 0x100) {
608                 tmp.w.l += 0x9e;
609         } else {
610                 tmp.w.l += 0x40;
611         }
612         if(tmp.b.l > 0x7f) {
613                 tmp.w.l += 0x01;
614         }
615         tmp.b.h = (tmp.b.h >> 1) + 0x81;
616         if(tmp.w.l >= 0xa000) {
617                 tmp.w.l += 0x4000;
618         }
619         return tmp.w.l;
620 }
621
622 int decibel_to_volume(int decibel)
623 {
624         // +1 equals +0.5dB (same as fmgen)
625         return (int)(1024.0 * pow(10.0, decibel / 40.0) + 0.5);
626 }
627
628 int32 apply_volume(int32 sample, int volume)
629 {
630 //      int64 output;
631         int32 output;
632         if(sample < 0) {
633                 output = -sample;
634                 output *= volume;
635                 output >>= 10;
636                 output = -output;
637         } else {
638                 output = sample;
639                 output *= volume;
640                 output >>= 10;
641         }
642 //      if(output > 2147483647) {
643 //              return 2147483647;
644 //      } else if(output < (-2147483647 - 1)) {
645 //              return (-2147483647 - 1);
646 //      } else {
647 //              return (int32)output;
648 //      }
649         return output;
650 }
651
652 void get_host_time(cur_time_t* cur_time)
653 {
654 #ifdef _WIN32
655         SYSTEMTIME sTime;
656         GetLocalTime(&sTime);
657         cur_time->year = sTime.wYear;
658         cur_time->month = sTime.wMonth;
659         cur_time->day = sTime.wDay;
660         cur_time->day_of_week = sTime.wDayOfWeek;
661         cur_time->hour = sTime.wHour;
662         cur_time->minute = sTime.wMinute;
663         cur_time->second = sTime.wSecond;
664 #else
665         time_t timer = time(NULL);
666         struct tm *local = localtime(&timer);
667         cur_time->year = local->tm_year + 1900;
668         cur_time->month = local->tm_mon + 1;
669         cur_time->day = local->tm_mday;
670         cur_time->day_of_week = local->tm_wday;
671         cur_time->hour = local->tm_hour;
672         cur_time->minute = local->tm_min;
673         cur_time->second = local->tm_sec;
674 #endif
675 }
676
677 void cur_time_t::increment()
678 {
679         if(++second >= 60) {
680                 second = 0;
681                 if(++minute >= 60) {
682                         minute = 0;
683                         if(++hour >= 24) {
684                                 hour = 0;
685                                 // days in this month
686                                 int days = 31;
687                                 if(month == 2) {
688                                         days = LEAP_YEAR(year) ? 29 : 28;
689                                 } else if(month == 4 || month == 6 || month == 9 || month == 11) {
690                                         days = 30;
691                                 }
692                                 if(++day > days) {
693                                         day = 1;
694                                         if(++month > 12) {
695                                                 month = 1;
696                                                 year++;
697                                         }
698                                 }
699                                 if(++day_of_week >= 7) {
700                                         day_of_week = 0;
701                                 }
702                         }
703                 }
704         }
705 }
706
707 void cur_time_t::update_year()
708 {
709         // 1970-2069
710         if(year < 70) {
711                 year += 2000;
712         } else if(year < 100) {
713                 year += 1900;
714         }
715 }
716
717 void cur_time_t::update_day_of_week()
718 {
719         static const int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
720         int y = year - (month < 3);
721         day_of_week = (y + y / 4 - y / 100 + y / 400 + t[month - 1] + day) % 7;
722 }
723
724 #define STATE_VERSION   1
725
726 void cur_time_t::save_state(void *f)
727 {
728         FILEIO *state_fio = (FILEIO *)f;
729         
730         state_fio->FputUint32(STATE_VERSION);
731         
732         state_fio->FputInt32(year);
733         state_fio->FputInt32(month);
734         state_fio->FputInt32(day);
735         state_fio->FputInt32(day_of_week);
736         state_fio->FputInt32(hour);
737         state_fio->FputInt32(minute);
738         state_fio->FputInt32(second);
739         state_fio->FputBool(initialized);
740 }
741
742 bool cur_time_t::load_state(void *f)
743 {
744         FILEIO *state_fio = (FILEIO *)f;
745         
746         if(state_fio->FgetUint32() != STATE_VERSION) {
747                 return false;
748         }
749         year = state_fio->FgetInt32();
750         month = state_fio->FgetInt32();
751         day = state_fio->FgetInt32();
752         day_of_week = state_fio->FgetInt32();
753         hour = state_fio->FgetInt32();
754         minute = state_fio->FgetInt32();
755         second = state_fio->FgetInt32();
756         initialized = state_fio->FgetBool();
757         return true;
758 }
759