OSDN Git Service

[VM][STATE][WIP] Apply csp_state_utils:: to some VMs.This is WIP.
[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
10 #if defined(_USE_QT)
11         #include <string.h>
12         #include <fcntl.h>
13         #if !defined(__WIN32) && !defined(__WIN64)
14                 #include <unistd.h>
15         #else
16                 #include <io.h>
17                 #include <direct.h>
18         #endif
19         #include <sys/types.h>
20         #include <sys/stat.h>
21         #include "csp_logger.h"
22         #include <string>
23         #include <algorithm>
24         #include <cctype>
25         #include <QDir>
26         #include <QFileInfo>
27 #elif defined(_WIN32)
28         #include <shlwapi.h>
29         #pragma comment(lib, "shlwapi.lib")
30 #else
31         #include <time.h>
32 #endif
33 #include <math.h>
34 #include "common.h"
35 #include "fileio.h"
36
37 #if defined(__MINGW32__) || defined(__MINGW64__)
38         extern DWORD GetLongPathName(LPCTSTR lpszShortPath, LPTSTR lpszLongPath, DWORD cchBuffer);
39 #endif
40 #if defined(_USE_QT)
41         std::string DLL_PREFIX cpp_homedir;
42         std::string DLL_PREFIX my_procname;
43 #endif
44
45 uint32_t DLL_PREFIX EndianToLittle_DWORD(uint32_t x)
46 {
47 #if defined(__LITTLE_ENDIAN__)
48         return x;
49 #else
50         uint32_t y;
51         y = ((x & 0x000000ff) << 24) | ((x & 0x0000ff00) << 8) |
52             ((x & 0x00ff0000) >> 8)  | ((x & 0xff000000) >> 24);
53         return y;
54 #endif
55 }
56
57 uint16_t DLL_PREFIX EndianToLittle_WORD(uint16_t x)
58 {
59 #if defined(__LITTLE_ENDIAN__)
60         return x;
61 #else
62         uint16_t y;
63         y = ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8);
64         return y;
65 #endif
66 }
67
68 #ifndef _MSC_VER
69 int DLL_PREFIX max(int a, int b)
70 {
71         if(a > b) {
72                 return a;
73         } else {
74                 return b;
75         }
76 }
77
78 unsigned DLL_PREFIX int max(unsigned int a, unsigned int b)
79 {
80         if(a > b) {
81                 return a;
82         } else {
83                 return b;
84         }
85 }
86
87 int DLL_PREFIX min(int a, int b)
88 {
89         if(a < b) {
90                 return a;
91         } else {
92                 return b;
93         }
94 }
95
96 unsigned int DLL_PREFIX min(unsigned int a, unsigned int b)
97 {
98         if(a < b) {
99                 return a;
100         } else {
101                 return b;
102         }
103 }
104 #endif
105
106 #ifndef SUPPORT_SECURE_FUNCTIONS
107 //errno_t my_tfopen_s(FILE** pFile, const _TCHAR *filename, const _TCHAR *mode)
108 //{
109 //      if((*pFile = _tfopen(filename, mode)) != NULL) {
110 //              return 0;
111 //      } else {
112 //              return errno;
113 //      }
114 //}
115
116 errno_t DLL_PREFIX my_tcscat_s(_TCHAR *strDestination, size_t numberOfElements, const _TCHAR *strSource)
117 {
118         _tcscat(strDestination, strSource);
119         return 0;
120 }
121
122 errno_t DLL_PREFIX my_strcpy_s(char *strDestination, size_t numberOfElements, const char *strSource)
123 {
124         strcpy(strDestination, strSource);
125         return 0;
126 }
127
128 errno_t DLL_PREFIX my_tcscpy_s(_TCHAR *strDestination, size_t numberOfElements, const _TCHAR *strSource)
129 {
130         _tcscpy(strDestination, strSource);
131         return 0;
132 }
133
134 errno_t DLL_PREFIX my_strncpy_s(char *strDestination, size_t numberOfElements, const char *strSource, size_t count)
135 {
136         strncpy(strDestination, strSource, count);
137         return 0;
138 }
139
140 errno_t DLL_PREFIX my_tcsncpy_s(_TCHAR *strDestination, size_t numberOfElements, const _TCHAR *strSource, size_t count)
141 {
142         _tcsncpy(strDestination, strSource, count);
143         return 0;
144 }
145
146 char *DLL_PREFIX my_strtok_s(char *strToken, const char *strDelimit, char **context)
147 {
148         return strtok(strToken, strDelimit);
149 }
150
151 _TCHAR *DLL_PREFIX my_tcstok_s(_TCHAR *strToken, const char *strDelimit, _TCHAR **context)
152 {
153         return _tcstok(strToken, strDelimit);
154 }
155
156 int DLL_PREFIX my_sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...)
157 {
158         va_list ap;
159         va_start(ap, format);
160         int result = vsnprintf(buffer, sizeOfBuffer, format, ap);
161         va_end(ap);
162         return result;
163 }
164
165 int DLL_PREFIX my_swprintf_s(wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format, ...)
166 {
167         va_list ap;
168         va_start(ap, format);
169         int result = vswprintf(buffer, sizeOfBuffer, format, ap);
170         va_end(ap);
171         return result;
172 }
173
174 int DLL_PREFIX my_stprintf_s(_TCHAR *buffer, size_t sizeOfBuffer, const _TCHAR *format, ...)
175 {
176         va_list ap;
177         va_start(ap, format);
178         int result = vsnprintf(buffer, sizeOfBuffer, format, ap);
179         va_end(ap);
180         return result;
181 }
182
183 int DLL_PREFIX my_vsprintf_s(char *buffer, size_t numberOfElements, const char *format, va_list argptr)
184 {
185         return vsnprintf(buffer, numberOfElements * sizeof(char), format, argptr);
186 }
187
188 int DLL_PREFIX my_vstprintf_s(_TCHAR *buffer, size_t numberOfElements, const _TCHAR *format, va_list argptr)
189 {
190         return vsnprintf(buffer, numberOfElements * sizeof(_TCHAR), format, argptr);
191 }
192 #endif
193
194 //#ifdef USE_FAST_MEMCPY
195
196 void DLL_PREFIX *my_memcpy(void *dst, void *src, size_t len)
197 {
198         size_t len1;
199         register size_t len2;
200         register uint32_t s_align = (uint32_t)(((size_t)src) & 0x1f);
201         register uint32_t d_align = (uint32_t)(((size_t)dst) & 0x1f);
202         int i;
203         
204         if(len == 0) return dst;
205         if(len < 8) {
206                 return memcpy(dst, src, len);
207         }
208         len1 = len;
209
210 #if defined(WITHOUT_UNALIGNED_SIMD)
211 // Using SIMD without un-aligned instructions.
212         switch(s_align) {
213         case 0: // Align 256
214                 {
215                         uint64_t b64[4];
216                         register uint64_t *s64 = (uint64_t *)src;
217                         register uint64_t *d64 = (uint64_t *)dst;
218                         switch(d_align) {
219                         case 0: // 256 vs 256
220                                 {
221                                         len2 = len1 >> 5;
222                                         while(len2 > 0) {
223                                                 for(i = 0; i < 4; i++) b64[i] = s64[i];
224                                                 for(i = 0; i < 4; i++) d64[i] = b64[i];
225                                                 s64 += 4;
226                                                 d64 += 4;
227                                                 --len2;
228                                         }
229                                         len1 = len1 & 0x1f;
230                                         if(len1 != 0) return memcpy(d64, s64, len1);
231                                         return dst;
232                                 }
233                                 break;
234                         case 0x10: // 256 vs 128
235                                 {
236                                         len2 = len1 >> 5;
237                                         while(len2 > 0) {
238                                                 for(i = 0; i < 4; i++) b64[i] = s64[i];
239                                                 for(i = 0; i < 2; i++) d64[i] = b64[i];
240                                                 d64 += 2;
241                                                 for(i = 2; i < 4; i++) d64[i - 2] = b64[i];
242                                                 d64 += 2;
243                                                 s64 += 4;
244                                                 --len2;
245                                         }
246                                         len1 = len1 & 0x1f;
247                                         if(len1 != 0) return memcpy(d64, s64, len1);
248                                         return dst;
249                                 }
250                                 break;
251                         case 0x08:
252                         case 0x18: // 256 vs 64
253                                 {
254                                         len2 = len1 >> 5;
255                                         while(len2 > 0) {
256                                                 for(i = 0; i < 4; ++i) b64[i] = s64[i];
257                                                 for(i = 0; i < 4; ++i) {
258                                                         *d64 = b64[i];
259                                                         ++d64;
260                                                 }
261                                                 s64 += 4;
262                                                 --len2;
263                                         }
264                                         len1 = len1 & 0x1f;
265                                         if(len1 != 0) return memcpy(d64, s64, len1);
266                                         return dst;
267                                 }
268                                 break;
269                         case 0x04:
270                         case 0x0c: 
271                         case 0x14:
272                         case 0x1c: // 256 vs 32
273                                 {
274                                         uint32_t b32[8];
275                                         register uint32_t *s32 = (uint32_t *)src;
276                                         register uint32_t *d32 = (uint32_t *)dst;
277                                         len2 = len1 >> 5;
278                                         while(len2 > 0) {
279                                                 for(i = 0; i < 8; ++i) b32[i] = s32[i];
280                                                 *d32 = b32[0];
281                                                 ++d32;
282                                                 *d32 = b32[1];
283                                                 ++d32;
284                                                 *d32 = b32[2];
285                                                 ++d32;
286                                                 *d32 = b32[3];
287                                                 ++d32;
288                                                 *d32 = b32[4];
289                                                 ++d32;
290                                                 *d32 = b32[5];
291                                                 ++d32;
292                                                 *d32 = b32[6];
293                                                 ++d32;
294                                                 *d32 = b32[7];
295                                                 ++d32;
296                                                 s32 += 8;
297                                                 --len2;
298                                         }
299                                         len1 = len1 & 0x1f;
300                                         if(len1 != 0) return memcpy(d32, s32, len1);
301                                         return dst;
302                                 }
303                                 break;
304                         default:
305                                 return memcpy(dst, src, len1);
306                                 break;
307                         }
308                 }
309                 break;
310         case 0x10: // Src alignn to 16.
311                 {
312                         uint32_t b32[4];
313                         register uint32_t *s32 = (uint32_t *)src;
314                         register uint32_t *d32 = (uint32_t *)dst;
315                         switch(d_align) {
316                         case 0: // 128 vs 256/128
317                         case 0x10:
318                                 {
319                                         len2 = len1 >> 4;
320                                         while(len2 > 0) {
321                                                 for(i = 0; i < 4; i++) b32[i] = s32[i];
322                                                 for(i = 0; i < 4; i++) d32[i] = b32[i];
323                                                 s32 += 4;
324                                                 d32 += 4;
325                                                 --len2;
326                                         }
327                                         len1 = len1 & 0x0f;
328                                         if(len1 != 0) return memcpy(d32, s32, len1);
329                                         return dst;
330                                 }
331                                 break;
332                         case 0x08:
333                         case 0x18: // 128 vs 64
334                                 {
335                                         len2 = len1 >> 4;
336                                         while(len2 > 0) {
337                                                 for(i = 0; i < 4; ++i) b32[i] = s32[i];
338                                                 for(i = 0; i < 2; ++i) {
339                                                         d32[i] = b32[i];
340                                                 }
341                                                 d32 += 2;
342                                                 for(i = 2; i < 4; ++i) {
343                                                         d32[i - 2] = b32[i];
344                                                 }
345                                                 d32 += 2;
346                                                 s32 += 4;
347                                                 --len2;
348                                         }
349                                         len1 = len1 & 0x0f;
350                                         if(len1 != 0) return memcpy(d32, s32, len1);
351                                         return dst;
352                                 }
353                                 break;
354                         case 0x04:
355                         case 0x0c:
356                         case 0x14:
357                         case 0x1c: // 128 vs 32
358                                 {
359                                         len2 = len1 >> 4;
360                                         while(len2 > 0) {
361                                                 for(i = 0; i < 4; ++i) b32[i] = s32[i];
362                                                 *d32 = b32[0];
363                                                 ++d32;
364                                                 *d32 = b32[1];
365                                                 ++d32;
366                                                 *d32 = b32[2];
367                                                 ++d32;
368                                                 *d32 = b32[3];
369                                                 ++d32;
370                                                 s32 += 4;
371                                                 --len2;
372                                         }
373                                         len1 = len1 & 0x0f;
374                                         if(len1 != 0) return memcpy(d32, s32, len1);
375                                         return dst;
376                                 }
377                                 break;
378                         default:
379                                 return memcpy(dst, src, len1);
380                                 break;
381                         }
382                 }
383                 break;
384         case 0x08:
385         case 0x18: // Src alignn to 64.
386                 {
387                         register uint32_t *s32 = (uint32_t *)src;
388                         register uint32_t *d32 = (uint32_t *)dst;
389                         register uint64_t *s64 = (uint64_t *)src;
390                         register uint64_t *d64 = (uint64_t *)dst;
391                         switch(d_align) {
392                         case 0:
393                         case 0x10: // 64 vs 128
394                                 {
395                                         uint64_t b128[2];
396                                         len2 = len1 >> 4;
397                                         while(len2 > 0) {
398                                                 b128[0] = *s64;
399                                                 ++s64;
400                                                 b128[1] = *s64;
401                                                 ++s64;
402                                                 for(i = 0; i < 2; i++) d64[i] = b128[i];
403                                                 d64 += 2;
404                                                 --len2;
405                                         }
406                                         len1 = len1 & 0x0f;
407                                         if(len1 != 0) return memcpy(d64, s64, len1);
408                                         return dst;
409                                 }
410                                 break;
411                         case 0x08:
412                         case 0x18: // 64 vs 64
413                                 {
414                                         len2 = len1 >> 3;
415                                         while(len2 > 0) {
416                                                 *d64 = *s64;
417                                                 ++s64;
418                                                 ++d64;
419                                                 --len2;
420                                         }
421                                         len1 = len1 & 0x07;
422                                         if(len1 != 0) return memcpy(d64, s64, len1);
423                                         return dst;
424                                 }
425                                 break;
426                         case 0x04:
427                         case 0x0c: // 64 vs 32
428                         case 0x14:
429                         case 0x1c: // 64 vs 32
430                                 {
431                                         uint32_t b32[2];
432                                         len2 = len1 >> 3;
433                                         while(len2 > 0) {
434                                                 for(i = 0; i < 2; ++i) b32[i] = s32[i];
435                                                 d32[0] = b32[0];
436                                                 d32[1] = b32[1];
437                                                 s32 += 2;
438                                                 d32 += 2;
439                                                 --len2;
440                                         }
441                                         len1 = len1 & 0x07;
442                                         if(len1 != 0) return memcpy(d32, s32, len1);
443                                         return dst;
444                                 }
445                                 break;
446                         default:
447                                 return memcpy(dst, src, len1);
448                                 break;
449                         }
450                 }
451         case 0x04:
452         case 0x0c:
453         case 0x14:
454         case 0x1c:  // Src align 32
455                 {
456                         register uint32_t *s32 = (uint32_t *)src;
457                         register uint32_t *d32 = (uint32_t *)dst;
458                         register uint64_t *d64 = (uint64_t *)dst;
459                         switch(d_align) {
460                         case 0:
461                         case 0x10: // 32 vs 128
462                                 {
463                                         uint32_t b128[4];
464                                         len2 = len1 >> 4;
465                                         while(len2 > 0) {
466                                                 b128[0] = *s32;
467                                                 ++s32;
468                                                 b128[1] = *s32;
469                                                 ++s32;
470                                                 b128[3] = *s32;
471                                                 ++s32;
472                                                 b128[4] = *s32;
473                                                 ++s32;
474                                                 for(i = 0; i < 4; i++) d32[i] = b128[i];
475                                                 d32 += 4;
476                                                 --len2;
477                                         }
478                                         len1 = len1 & 0x0f;
479                                         if(len1 != 0) return memcpy(d32, s32, len1);
480                                         return dst;
481                                 }
482                                 break;
483                         case 0x08:
484                         case 0x18: // 32 vs 64
485                                 {
486                                         uint32_t b64[2];
487                                         len2 = len1 >> 3;
488                                         while(len2 > 0) {
489                                                 b64[0] = *s32;
490                                                 ++s32;
491                                                 b64[1] = *s32;
492                                                 ++s32;
493
494                                                 for(i = 0; i < 2; i++) d32[i] = b64[i];
495                                                 d32 += 2;
496                                                 --len2;
497                                         }
498                                         len1 = len1 & 0x07;
499                                         if(len1 != 0) return memcpy(d32, s32, len1);
500                                         return dst;
501                                 }
502                                 break;
503                         case 0x04:
504                         case 0x0c: 
505                         case 0x14:
506                         case 0x1c: // 32 vs 32
507                                 {
508                                         len2 = len1 >> 2;
509                                         while(len2 > 0) {
510                                                 *d32 = *s32;
511                                                 ++s32;
512                                                 ++d32;
513                                                 --len2;
514                                         }
515                                         len1 = len1 & 0x03;
516                                         if(len1 != 0) return memcpy(d32, s32, len1);
517                                         return dst;
518                                 }
519                                 break;
520                         default:
521                                 return memcpy(dst, src, len1);
522                                 break;
523                         }
524                 }
525                 break;
526         default:
527                 if(len1 != 0) return memcpy(dst, src, len1);
528                 break;
529         }
530
531 #else
532 // Using SIMD *with* un-aligned instructions.
533         register uint32_t *s32 = (uint32_t *)src;
534         register uint32_t *d32 = (uint32_t *)dst;
535         if(((s_align & 0x07) != 0x0) && ((d_align & 0x07) != 0x0)) { // None align.
536                 return memcpy(dst, src, len);
537         }
538         if((s_align == 0x0) || (d_align == 0x0)) { // Align to 256bit
539                 uint32_t b256[8];
540                 len2 = len1 >> 5;
541                 while(len2 > 0) {
542                         for(i = 0; i < 8; i++) b256[i] = s32[i];
543                         for(i = 0; i < 8; i++) d32[i] = b256[i];
544                         s32 += 8;
545                         d32 += 8;
546                         --len2;
547                 }
548                 len1 = len1 & 0x1f;
549                 if(len1 != 0) return memcpy(d32, s32, len1);
550                 return dst;
551         }
552         if(((s_align & 0x0f) == 0x0) || ((d_align & 0x0f) == 0x0)) { // Align to 128bit
553                 uint32_t b128[4];
554                 len2 = len1 >> 4;
555                 while(len2 > 0) {
556                         for(i = 0; i < 4; i++) b128[i] = s32[i];
557                         for(i = 0; i < 4; i++) d32[i] = b128[i];
558                         s32 += 4;
559                         d32 += 4;
560                         --len2;
561                 }
562                 len1 = len1 & 0x0f;
563                 if(len1 != 0) return memcpy(d32, s32, len1);
564                 return dst;
565         }               
566         if(((s_align & 0x07) == 0x0) || ((d_align & 0x07) == 0x0)) { // Align to 64bit
567                 uint32_t b64[2];
568                 len2 = len1 >> 3;
569                 while(len2 > 0) {
570                         for(i = 0; i < 2; i++) b64[i] = s32[i];
571                         for(i = 0; i < 2; i++) d32[i] = b64[i];
572                         s32 += 2;
573                         d32 += 2;
574                         --len2;
575                 }
576                 len1 = len1 & 0x07;
577                 if(len1 != 0) return memcpy(d32, s32, len1);
578                 return dst;
579         }               
580         //if(len1 != 0) return memcpy(dst, src, len1);
581 #endif
582         // Trap
583         return dst;
584 }
585 //#endif
586
587
588 #ifndef _WIN32
589 BOOL DLL_PREFIX MyWritePrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString, LPCTSTR lpFileName)
590 {
591         BOOL result = FALSE;
592         FILEIO* fio_i = new FILEIO();
593         if(fio_i->Fopen(lpFileName, FILEIO_READ_ASCII)) {
594                 char tmp_path[_MAX_PATH];
595                 my_sprintf_s(tmp_path, _MAX_PATH, "%s.$$$", lpFileName);
596                 FILEIO* fio_o = new FILEIO();
597                 if(fio_o->Fopen(tmp_path, FILEIO_WRITE_ASCII)) {
598                         bool in_section = false;
599                         char section[1024], line[1024], *equal;
600                         my_sprintf_s(section, 1024, "[%s]", lpAppName);
601                         while(fio_i->Fgets(line, 1024) != NULL && strlen(line) > 0) {
602                                 if(line[strlen(line) - 1] == '\n') {
603                                         line[strlen(line) - 1] = '\0';
604                                 }
605                                 if(!result) {
606                                         if(line[0] == '[') {
607                                                 if(in_section) {
608                                                         fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
609                                                         result = TRUE;
610                                                 } else if(strcmp(line, section) == 0) {
611                                                         in_section = true;
612                                                 }
613                                         } else if(in_section && (equal = strstr(line, "=")) != NULL) {
614                                                 *equal = '\0';
615                                                 if(strcmp(line, lpKeyName) == 0) {
616                                                         fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
617                                                         result = TRUE;
618                                                         continue;
619                                                 }
620                                                 *equal = '=';
621                                         }
622                                 }
623                                 fio_o->Fprintf("%s\n", line);
624                         }
625                         if(!result) {
626                                 if(!in_section) {
627                                         fio_o->Fprintf("[%s]\n", lpAppName);
628                                 }
629                                 fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
630                                 result = TRUE;
631                         }
632                         fio_o->Fclose();
633                 }
634                 delete fio_o;
635                 fio_i->Fclose();
636                 if(result) {
637                         if(!(FILEIO::RemoveFile(lpFileName) && FILEIO::RenameFile(tmp_path, lpFileName))) {
638                                 result = FALSE;
639                         }
640                 }
641         } else {
642                 FILEIO* fio_o = new FILEIO();
643                 if(fio_o->Fopen(lpFileName, FILEIO_WRITE_ASCII)) {
644                         fio_o->Fprintf("[%s]\n", lpAppName);
645                         fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
646                         fio_o->Fclose();
647                 }
648                 delete fio_o;
649         }
650         delete fio_i;
651         return result;
652 }
653
654
655 DWORD DLL_PREFIX MyGetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName)
656 {
657         _TCHAR *lpp = (_TCHAR *)lpReturnedString;
658         if(lpDefault != NULL) {
659                 my_strcpy_s(lpp, nSize, lpDefault);
660         } else {
661                 lpp[0] = '\0';
662         }
663         FILEIO* fio = new FILEIO();
664         if(fio->Fopen(lpFileName, FILEIO_READ_ASCII)) {
665                 bool in_section = false;
666                 char section[1024], line[1024], *equal;
667                 my_sprintf_s(section, 1024, "[%s]", lpAppName);
668                 while(fio->Fgets(line, 1024) != NULL && strlen(line) > 0) {
669                         if(line[strlen(line) - 1] == '\n') {
670                                 line[strlen(line) - 1] = '\0';
671                         }
672                         if(line[0] == '[') {
673                                 if(in_section) {
674                                         break;
675                                 } else if(strcmp(line, section) == 0) {
676                                         in_section = true;
677                                 }
678                         } else if(in_section && (equal = strstr(line, "=")) != NULL) {
679                                 *equal = '\0';
680                                 if(strcmp(line, lpKeyName) == 0) {
681                                         my_strcpy_s(lpp, nSize, equal + 1);
682                                         break;
683                                 }
684                         }
685                 }
686                 fio->Fclose();
687         }
688         delete fio;
689         //csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Try App: %s Key: %s", lpAppName, lpKeyName);
690         return strlen(lpp);
691 }
692
693 UINT DLL_PREFIX MyGetPrivateProfileInt(LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault, LPCTSTR lpFileName)
694 {
695         int i;
696         char sstr[128];
697         char sval[128];
698         std::string s;
699         memset(sstr, 0x00, sizeof(sstr));
700         memset(sval, 0x00, sizeof(sval));
701         snprintf(sval, 128, "%d", nDefault); 
702         MyGetPrivateProfileString(lpAppName,lpKeyName, sval, sstr, 128, lpFileName);
703         s = sstr;
704         
705         if(s.empty()) {
706                 i = nDefault;
707         } else {
708                 i = strtol(s.c_str(), NULL, 10);
709         }
710         //csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Got Int: %d\n", i);
711         return i;
712 }
713 #endif
714
715 #if defined(_RGB555)
716 scrntype_t DLL_PREFIX RGB_COLOR(uint32_t r, uint32_t g, uint32_t b)
717 {
718         scrntype_t rr = ((scrntype_t)r * 0x1f) / 0xff;
719         scrntype_t gg = ((scrntype_t)g * 0x1f) / 0xff;
720         scrntype_t bb = ((scrntype_t)b * 0x1f) / 0xff;
721         return (rr << 10) | (gg << 5) | bb;
722 }
723
724 scrntype_t DLL_PREFIX RGBA_COLOR(uint32_t r, uint32_t g, uint b, uint32_t a)
725 {
726         return RGB_COLOR(r, g, b);
727 }
728
729 uint8_t DLL_PREFIX R_OF_COLOR(scrntype_t c)
730 {
731         c = (c >> 10) & 0x1f;
732         c = (c * 0xff) / 0x1f;
733         return (uint8_t)c;
734 }
735
736 uint8_t DLL_PREFIX G_OF_COLOR(scrntype_t c)
737 {
738         c = (c >>  5) & 0x1f;
739         c = (c * 0xff) / 0x1f;
740         return (uint8_t)c;
741 }
742
743 uint8_t DLL_PREFIX B_OF_COLOR(scrntype_t c)
744 {
745         c = (c >>  0) & 0x1f;
746         c = (c * 0xff) / 0x1f;
747         return (uint8_t)c;
748 }
749
750 uint8_t DLL_PREFIX A_OF_COLOR(scrntype_t c)
751 {
752         return 0;
753 }
754 #elif defined(_RGB565)
755 scrntype_t DLL_PREFIX RGB_COLOR(uint32_t r, uint32_t g, uint32_t b)
756 {
757         scrntype_t rr = ((scrntype_t)r * 0x1f) / 0xff;
758         scrntype_t gg = ((scrntype_t)g * 0x3f) / 0xff;
759         scrntype_t bb = ((scrntype_t)b * 0x1f) / 0xff;
760         return (rr << 11) | (gg << 5) | bb;
761 }
762
763 scrntype_t DLL_PREFIX RGBA_COLOR(uint32_t r, uint32_t g, uint32_t b, uint32_t a)
764 {
765         return RGB_COLOR(r, g, b);
766 }
767
768 uint8_t DLL_PREFIX R_OF_COLOR(scrntype_t c)
769 {
770         c = (c >> 11) & 0x1f;
771         c = (c * 0xff) / 0x1f;
772         return (uint8_t)c;
773 }
774
775 uint8_t DLL_PREFIX G_OF_COLOR(scrntype_t c)
776 {
777         c = (c >>  5) & 0x3f;
778         c = (c * 0xff) / 0x3f;
779         return (uint8_t)c;
780 }
781
782 uint8_t DLL_PREFIX B_OF_COLOR(scrntype_t c)
783 {
784         c = (c >>  0) & 0x1f;
785         c = (c * 0xff) / 0x1f;
786         return (uint8_t)c;
787 }
788
789 uint8_t DLL_PREFIX A_OF_COLOR(scrntype_t c)
790 {
791         return 0;
792 }
793 #endif
794
795 #ifndef _MSC_VER
796 struct to_upper {  // Refer from documentation of libstdc++, GCC5.
797         char operator() (char c) const { return std::toupper(c); }
798 };
799 #endif
800
801 #if defined(_USE_QT)
802 static void _my_mkdir(std::string t_dir)
803 {
804         struct stat st;
805 //#if !defined(__WIN32) && !defined(__WIN64)
806 //      if(fstatat(AT_FDCWD, csppath.c_str(), &st, 0) != 0) {
807 //              mkdirat(AT_FDCWD, t_dir.c_str(), 0700); // Not found
808 //      }
809 #if defined(_USE_QT)
810         if(stat(t_dir.c_str(), &st) != 0) {
811                 QDir dir = QDir::current();
812                 dir.mkdir(QString::fromStdString(t_dir));
813                 //dir.mkpath(QString::fromUtf8(app_path));
814         }
815 #else
816         if(stat(csppath.c_str(), &st) != 0) {
817                 _mkdir(t_dir.c_str()); // Not found
818         }
819 #endif
820 }
821 #endif
822
823 const _TCHAR *DLL_PREFIX get_application_path()
824 {
825         static _TCHAR app_path[_MAX_PATH];
826         static bool initialized = false;
827         
828         if(!initialized) {
829 #if defined(_WIN32) && !defined(_USE_QT)
830                 _TCHAR tmp_path[_MAX_PATH], *ptr = NULL;
831                 if(GetModuleFileName(NULL, tmp_path, _MAX_PATH) != 0 && GetFullPathName(tmp_path, _MAX_PATH, app_path, &ptr) != 0 && ptr != NULL) {
832                         *ptr = _T('\0');
833                 } else {
834                         my_tcscpy_s(app_path, _MAX_PATH, _T(".\\"));
835                 }
836 #else
837 #if defined(Q_OS_WIN)
838                 std::string delim = "\\";
839 #else
840                 std::string delim = "/";
841 #endif
842                 std::string csppath = cpp_homedir + "CommonSourceCodeProject" + delim ;
843                 _my_mkdir(csppath);
844            
845                 std::string cpath = csppath + my_procname + delim;
846                 _my_mkdir(cpath);
847                 strncpy(app_path, cpath.c_str(), _MAX_PATH);
848 #endif
849                 initialized = true;
850         }
851         return (const _TCHAR *)app_path;
852 }
853
854 const _TCHAR *DLL_PREFIX create_local_path(const _TCHAR *format, ...)
855 {
856         static _TCHAR file_path[8][_MAX_PATH];
857         static unsigned int table_index = 0;
858         unsigned int output_index = (table_index++) & 7;
859         _TCHAR file_name[_MAX_PATH];
860         //printf("%d %d\n", table_index, output_index);
861         va_list ap;
862         
863         va_start(ap, format);
864         my_vstprintf_s(file_name, _MAX_PATH, format, ap);
865         va_end(ap);
866         my_stprintf_s(file_path[output_index], _MAX_PATH, _T("%s%s"), get_application_path(), file_name);
867         return (const _TCHAR *)file_path[output_index];
868 }
869
870 void DLL_PREFIX create_local_path(_TCHAR *file_path, int length, const _TCHAR *format, ...)
871 {
872         _TCHAR file_name[_MAX_PATH];
873         va_list ap;
874         
875         va_start(ap, format);
876         my_vstprintf_s(file_name, _MAX_PATH, format, ap);
877         va_end(ap);
878         my_stprintf_s(file_path, length, _T("%s%s"), get_application_path(), file_name);
879 }
880
881 bool DLL_PREFIX is_absolute_path(const _TCHAR *file_path)
882 {
883 #ifdef _WIN32
884         if(_tcslen(file_path) > 2 && ((file_path[0] >= _T('A') && file_path[0] <= _T('Z')) || (file_path[0] >= _T('a') && file_path[0] <= _T('z'))) && file_path[1] == _T(':')) {
885                 return true;
886         }
887 #endif
888         return (_tcslen(file_path) > 1 && (file_path[0] == _T('/') || file_path[0] == _T('\\')));
889 }
890
891 const _TCHAR *DLL_PREFIX create_absolute_path(const _TCHAR *file_name)
892 {
893         static _TCHAR file_path[8][_MAX_PATH];
894         static unsigned int table_index = 0;
895         unsigned int output_index = (table_index++) & 7;
896         
897         if(is_absolute_path(file_name)) {
898                 my_tcscpy_s(file_path[output_index], _MAX_PATH, file_name);
899         } else {
900                 my_tcscpy_s(file_path[output_index], _MAX_PATH, create_local_path(file_name));
901         }
902         return (const _TCHAR *)file_path[output_index];
903 }
904
905 void DLL_PREFIX create_absolute_path(_TCHAR *file_path, int length, const _TCHAR *file_name)
906 {
907         my_tcscpy_s(file_path, length, create_absolute_path(file_name));
908 }
909
910 const _TCHAR *DLL_PREFIX create_date_file_path(const _TCHAR *extension)
911 {
912         cur_time_t cur_time;
913         
914         get_host_time(&cur_time);
915         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);
916 }
917
918 void DLL_PREFIX create_date_file_path(_TCHAR *file_path, int length, const _TCHAR *extension)
919 {
920         my_tcscpy_s(file_path, length, create_date_file_path(extension));
921 }
922
923 bool DLL_PREFIX check_file_extension(const _TCHAR *file_path, const _TCHAR *ext)
924 {
925 #if defined(_USE_QT)
926         std::string s_fpath = file_path;
927         std::string s_ext = ext;
928         //bool f = false;
929         int pos;
930         std::transform(s_fpath.begin(), s_fpath.end(), s_fpath.begin(), to_upper());
931         std::transform(s_ext.begin(), s_ext.end(), s_ext.begin(), to_upper());
932         if(s_fpath.length() < s_ext.length()) return false;
933         pos = s_fpath.rfind(s_ext.c_str(), s_fpath.length());
934         if((pos != (int)std::string::npos) && (pos >= ((int)s_fpath.length() - (int)s_ext.length()))) return true; 
935         return false;
936 #else
937         int nam_len = _tcslen(file_path);
938         int ext_len = _tcslen(ext);
939         
940         return (nam_len >= ext_len && _tcsncicmp(&file_path[nam_len - ext_len], ext, ext_len) == 0);
941 #endif
942 }
943
944 const _TCHAR *DLL_PREFIX get_file_path_without_extensiton(const _TCHAR *file_path)
945 {
946         static _TCHAR path[8][_MAX_PATH];
947         static unsigned int table_index = 0;
948         unsigned int output_index = (table_index++) & 7;
949         
950         my_tcscpy_s(path[output_index], _MAX_PATH, file_path);
951 #if defined(_WIN32) && defined(_MSC_VER)
952         PathRemoveExtension(path[output_index]);
953 #elif defined(_USE_QT)
954         QString delim;
955         delim = QString::fromUtf8(".");
956         QString tmp_path = QString::fromUtf8(file_path);
957         int n = tmp_path.lastIndexOf(delim);
958         if(n > 0) {
959                 tmp_path = tmp_path.left(n);
960         }
961         //printf("%s\n", tmp_path.toUtf8().constData());
962         memset(path[output_index], 0x00, sizeof(_TCHAR) * _MAX_PATH);
963         strncpy(path[output_index], tmp_path.toUtf8().constData(), _MAX_PATH - 1);
964 #else
965 #endif
966         return (const _TCHAR *)path[output_index];
967 }
968
969 void DLL_PREFIX get_long_full_path_name(const _TCHAR* src, _TCHAR* dst, size_t dst_len)
970 {
971 #ifdef _WIN32
972         _TCHAR tmp[_MAX_PATH];
973         if(GetFullPathName(src, _MAX_PATH, tmp, NULL) == 0) {
974                 my_tcscpy_s(dst, dst_len, src);
975         } else if(GetLongPathName(tmp, dst, _MAX_PATH) == 0) {
976                 my_tcscpy_s(dst, dst_len, tmp);
977         }
978 #elif defined(_USE_QT)
979         QString tmp_path = QString::fromUtf8(src);
980         QFileInfo info(tmp_path);
981         my_tcscpy_s(dst, dst_len, info.absoluteFilePath().toLocal8Bit().constData());
982 #else
983         // write code for your environment
984         
985 #endif
986 }
987
988 const _TCHAR *DLL_PREFIX get_parent_dir(const _TCHAR* file)
989 {
990         static _TCHAR path[8][_MAX_PATH];
991         static unsigned int table_index = 0;
992         unsigned int output_index = (table_index++) & 7;
993         
994 #ifdef _WIN32
995         _TCHAR *ptr;
996         GetFullPathName(file, _MAX_PATH, path[output_index], &ptr);
997         if(ptr != NULL) {
998                 *ptr = _T('\0');
999         }
1000 #elif defined(_USE_QT)
1001         QString delim;
1002 #if defined(Q_OS_WIN)
1003         delim = QString::fromUtf8("\\");
1004 #else
1005         delim = QString::fromUtf8("/");
1006 #endif
1007         QString tmp_path = QString::fromUtf8(file);
1008         int n = tmp_path.lastIndexOf(delim);
1009         if(n > 0) {
1010                 tmp_path = tmp_path.left(n);
1011                 tmp_path.append(delim);
1012         }
1013         //printf("%s\n", tmp_path.toUtf8().constData());
1014         memset(path[output_index], 0x00, sizeof(_TCHAR) * _MAX_PATH);
1015         strncpy(path[output_index], tmp_path.toUtf8().constData(), _MAX_PATH - 1);
1016 #else
1017         // write code for your environment
1018 #endif
1019         return path[output_index];
1020 }
1021
1022 const wchar_t *DLL_PREFIX char_to_wchar(const char *cs)
1023 {
1024         // char to wchar_t
1025         static wchar_t ws[4096];
1026         
1027 #if defined(_WIN32) || defined(_USE_QT)
1028         mbstowcs(ws, cs, strlen(cs));
1029 #else
1030         // write code for your environment
1031 #endif
1032         return ws;
1033 }
1034
1035 const char *DLL_PREFIX wchar_to_char(const wchar_t *ws)
1036 {
1037         // wchar_t to char
1038         static char cs[4096];
1039         
1040 #ifdef _WIN32
1041         wcstombs(cs, ws, wcslen(ws));
1042 #elif defined(_USE_QT)
1043         wcstombs(cs, ws, wcslen(ws));
1044 #else
1045         // write code for your environment
1046 #endif
1047         return cs;
1048 }
1049
1050 const _TCHAR *DLL_PREFIX char_to_tchar(const char *cs)
1051 {
1052 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1053         // char to wchar_t
1054         return char_to_wchar(cs);
1055 #else
1056         // char to char
1057         return cs;
1058 #endif
1059 }
1060
1061 const char *DLL_PREFIX tchar_to_char(const _TCHAR *ts)
1062 {
1063 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1064         // wchar_t to char
1065         return wchar_to_char(ts);
1066 #else
1067         // char to char
1068         return ts;
1069 #endif
1070 }
1071
1072 const _TCHAR *DLL_PREFIX wchar_to_tchar(const wchar_t *ws)
1073 {
1074 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1075         // wchar_t to wchar_t
1076         return ws;
1077 #else
1078         // wchar_t to char
1079         return wchar_to_char(ws);
1080 #endif
1081 }
1082
1083 const wchar_t *DLL_PREFIX tchar_to_wchar(const _TCHAR *ts)
1084 {
1085 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1086         // wchar_t to wchar_t
1087         return ts;
1088 #else
1089         // char to wchar_t
1090         return char_to_wchar(ts);
1091 #endif
1092 }
1093
1094 const _TCHAR *DLL_PREFIX create_string(const _TCHAR* format, ...)
1095 {
1096         static _TCHAR buffer[8][1024];
1097         static unsigned int table_index = 0;
1098         unsigned int output_index = (table_index++) & 7;
1099         va_list ap;
1100         
1101         va_start(ap, format);
1102         my_vstprintf_s(buffer[output_index], 1024, format, ap);
1103         va_end(ap);
1104         return (const _TCHAR *)buffer[output_index];
1105 }
1106
1107 int32_t DLL_PREFIX muldiv_s32(int32_t nNumber, int32_t nNumerator, int32_t nDenominator)
1108 {
1109         try {
1110                 int64_t tmp;
1111                 tmp  = (int64_t)nNumber;
1112                 tmp *= (int64_t)nNumerator;
1113                 tmp /= (int64_t)nDenominator;
1114                 return (int32_t)tmp;
1115         } catch(...) {
1116                 double tmp;
1117                 tmp  = (double)nNumber;
1118                 tmp *= (double)nNumerator;
1119                 tmp /= (double)nDenominator;
1120                 if(tmp < 0) {
1121                         return (int32_t)(tmp - 0.5);
1122                 } else {
1123                         return (int32_t)(tmp + 0.5);
1124                 }
1125         }
1126 }
1127
1128 uint32_t DLL_PREFIX muldiv_u32(uint32_t nNumber, uint32_t nNumerator, uint32_t nDenominator)
1129 {
1130         try {
1131                 uint64_t tmp;
1132                 tmp  = (uint64_t)nNumber;
1133                 tmp *= (uint64_t)nNumerator;
1134                 tmp /= (uint64_t)nDenominator;
1135                 return (uint32_t)tmp;
1136         } catch(...) {
1137                 double tmp;
1138                 tmp  = (double)nNumber;
1139                 tmp *= (double)nNumerator;
1140                 tmp /= (double)nDenominator;
1141                 return (uint32_t)(tmp + 0.5);
1142         }
1143 }
1144
1145 static bool _crc_initialized = false;
1146 static uint32_t _crc_table[256] = {0};
1147 static void init_crc32_table(void)
1148 {
1149         for(int i = 0; i < 256; i++) {
1150                 uint32_t c = i;
1151                 for(int j = 0; j < 8; j++) {
1152                         if(c & 1) {
1153                                 c = (c >> 1) ^ 0xedb88320;
1154                         } else {
1155                                 c >>= 1;
1156                         }
1157                 }
1158                 _crc_table[i] = c;
1159         }
1160         _crc_initialized = true;
1161 }
1162
1163 uint32_t DLL_PREFIX get_crc32(uint8_t data[], int size)
1164 {
1165         const uint32_t *table = (const uint32_t *)_crc_table;
1166         if(!_crc_initialized) {
1167                 init_crc32_table();
1168         }
1169         
1170         uint32_t c = ~0;
1171         for(int i = 0; i < size; i++) {
1172                 c = table[(c ^ data[i]) & 0xff] ^ (c >> 8);
1173         }
1174         return ~c;
1175 }
1176
1177 uint32_t DLL_PREFIX calc_crc32(uint32_t seed, uint8_t data[], int size)
1178 {
1179 #if 0
1180         if(!_crc_initialized) {
1181                 init_crc32_table();
1182         }
1183         const uint32_t *table = (const uint32_t *)_crc_table;
1184
1185         uint32_t c = ~seed;
1186         for(int i = 0; i < size; i++) {
1187                 c = table[(c ^ data[i]) & 0xff] ^ (c >> 8);
1188         }
1189         return ~c;
1190 #else
1191         // Calculate CRC32
1192         // Refer to : https://qiita.com/mikecat_mixc/items/e5d236e3a3803ef7d3c5
1193         static const uint32_t CRC_MAGIC_WORD = 0x04C11DB7;
1194         uint32_t crc = seed;
1195         uint8_t *ptr = data;
1196         uint8_t d;
1197         int bytes = size;
1198         bool is_overflow;
1199         for(int i = 0; i < bytes; i++) {
1200                 d = *ptr++;
1201                 for(int bit = 0; bit < 8; bit++) {
1202                         is_overflow = ((crc & 0x1) != 0);
1203                         crc = crc >> 1;
1204                         if((d & 0x01) != 0) crc = crc | 0x80000000;
1205                         if(is_overflow) crc = crc ^ ((uint32_t)~CRC_MAGIC_WORD);
1206                         d >>= 1;
1207                 }
1208         }
1209         return crc;
1210 #endif
1211 }
1212
1213 uint16_t DLL_PREFIX jis_to_sjis(uint16_t jis)
1214 {
1215         pair_t tmp;
1216         
1217         tmp.w.l = jis - 0x2121;
1218         if(tmp.w.l & 0x100) {
1219                 tmp.w.l += 0x9e;
1220         } else {
1221                 tmp.w.l += 0x40;
1222         }
1223         if(tmp.b.l > 0x7f) {
1224                 tmp.w.l += 0x01;
1225         }
1226         tmp.b.h = (tmp.b.h >> 1) + 0x81;
1227         if(tmp.w.l >= 0xa000) {
1228                 tmp.w.l += 0x4000;
1229         }
1230         return tmp.w.l;
1231 }
1232
1233 int DLL_PREFIX decibel_to_volume(int decibel)
1234 {
1235         // +1 equals +0.5dB (same as fmgen)
1236         return (int)(1024.0 * pow(10.0, decibel / 40.0) + 0.5);
1237 }
1238
1239 int32_t DLL_PREFIX apply_volume(int32_t sample, int volume)
1240 {
1241 //      int64_t output;
1242         int32_t output;
1243         if(sample < 0) {
1244                 output = -sample;
1245                 output *= volume;
1246                 output >>= 10;
1247                 output = -output;
1248         } else {
1249                 output = sample;
1250                 output *= volume;
1251                 output >>= 10;
1252         }
1253 //      if(output > 2147483647) {
1254 //              return 2147483647;
1255 //      } else if(output < (-2147483647 - 1)) {
1256 //              return (-2147483647 - 1);
1257 //      } else {
1258 //              return (int32_t)output;
1259 //      }
1260         return output;
1261 }
1262
1263 void DLL_PREFIX get_host_time(cur_time_t* cur_time)
1264 {
1265 #ifdef _WIN32
1266         SYSTEMTIME sTime;
1267         GetLocalTime(&sTime);
1268         cur_time->year = sTime.wYear;
1269         cur_time->month = sTime.wMonth;
1270         cur_time->day = sTime.wDay;
1271         cur_time->day_of_week = sTime.wDayOfWeek;
1272         cur_time->hour = sTime.wHour;
1273         cur_time->minute = sTime.wMinute;
1274         cur_time->second = sTime.wSecond;
1275 #else
1276         time_t timer = time(NULL);
1277         struct tm *local = localtime(&timer);
1278         cur_time->year = local->tm_year + 1900;
1279         cur_time->month = local->tm_mon + 1;
1280         cur_time->day = local->tm_mday;
1281         cur_time->day_of_week = local->tm_wday;
1282         cur_time->hour = local->tm_hour;
1283         cur_time->minute = local->tm_min;
1284         cur_time->second = local->tm_sec;
1285 #endif
1286 }
1287
1288
1289
1290 void DLL_PREFIX cur_time_t::increment()
1291 {
1292         if(++second >= 60) {
1293                 second = 0;
1294                 if(++minute >= 60) {
1295                         minute = 0;
1296                         if(++hour >= 24) {
1297                                 hour = 0;
1298                                 // days in this month
1299                                 int days = 31;
1300                                 if(month == 2) {
1301                                         days = LEAP_YEAR(year) ? 29 : 28;
1302                                 } else if(month == 4 || month == 6 || month == 9 || month == 11) {
1303                                         days = 30;
1304                                 }
1305                                 if(++day > days) {
1306                                         day = 1;
1307                                         if(++month > 12) {
1308                                                 month = 1;
1309                                                 year++;
1310                                         }
1311                                 }
1312                                 if(++day_of_week >= 7) {
1313                                         day_of_week = 0;
1314                                 }
1315                         }
1316                 }
1317         }
1318 }
1319
1320 void DLL_PREFIX cur_time_t::update_year()
1321 {
1322         // 1970-2069
1323         if(year < 70) {
1324                 year += 2000;
1325         } else if(year < 100) {
1326                 year += 1900;
1327         }
1328 }
1329
1330 void DLL_PREFIX cur_time_t::update_day_of_week()
1331 {
1332         static const int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
1333         int y = year - (month < 3);
1334         day_of_week = (y + y / 4 - y / 100 + y / 400 + t[month - 1] + day) % 7;
1335 }
1336
1337 #define STATE_VERSION   1
1338
1339 void DLL_PREFIX cur_time_t::save_state(void *f)
1340 {
1341         FILEIO *state_fio = (FILEIO *)f;
1342         
1343         state_fio->FputUint32(STATE_VERSION);
1344         
1345         state_fio->FputInt32(year);
1346         state_fio->FputInt32(month);
1347         state_fio->FputInt32(day);
1348         state_fio->FputInt32(day_of_week);
1349         state_fio->FputInt32(hour);
1350         state_fio->FputInt32(minute);
1351         state_fio->FputInt32(second);
1352         state_fio->FputBool(initialized);
1353 }
1354
1355 bool DLL_PREFIX cur_time_t::load_state(void *f)
1356 {
1357         FILEIO *state_fio = (FILEIO *)f;
1358         
1359         if(state_fio->FgetUint32() != STATE_VERSION) {
1360                 return false;
1361         }
1362         year = state_fio->FgetInt32();
1363         month = state_fio->FgetInt32();
1364         day = state_fio->FgetInt32();
1365         day_of_week = state_fio->FgetInt32();
1366         hour = state_fio->FgetInt32();
1367         minute = state_fio->FgetInt32();
1368         second = state_fio->FgetInt32();
1369         initialized = state_fio->FgetBool();
1370         return true;
1371 }
1372
1373 const _TCHAR *DLL_PREFIX get_symbol(symbol_t *first_symbol, uint32_t addr)
1374 {
1375         static _TCHAR name[8][1024];
1376         static unsigned int table_index = 0;
1377         unsigned int output_index = (table_index++) & 7;
1378         
1379         if(first_symbol != NULL) {
1380                 for(symbol_t* symbol = first_symbol; symbol; symbol = symbol->next_symbol) {
1381                         if(symbol->addr == addr) {
1382                                 my_tcscpy_s(name[output_index], 1024, symbol->name);
1383                                 return name[output_index];
1384                         }
1385                 }
1386         }
1387         return NULL;
1388 }
1389
1390 const _TCHAR *DLL_PREFIX get_value_or_symbol(symbol_t *first_symbol, const _TCHAR *format, uint32_t addr)
1391 {
1392         static _TCHAR name[8][1024];
1393         static unsigned int table_index = 0;
1394         unsigned int output_index = (table_index++) & 7;
1395         
1396         if(first_symbol != NULL) {
1397                 for(symbol_t* symbol = first_symbol; symbol; symbol = symbol->next_symbol) {
1398                         if(symbol->addr == addr) {
1399                                 my_tcscpy_s(name[output_index], 1024, symbol->name);
1400                                 return name[output_index];
1401                         }
1402                 }
1403         }
1404         my_stprintf_s(name[output_index], 1024, format, addr);
1405         return name[output_index];
1406 }
1407
1408 const _TCHAR *DLL_PREFIX get_value_and_symbol(symbol_t *first_symbol, const _TCHAR *format, uint32_t addr)
1409 {
1410         static _TCHAR name[8][1024];
1411         static unsigned int table_index = 0;
1412         unsigned int output_index = (table_index++) & 7;
1413         
1414         my_stprintf_s(name[output_index], 1024, format, addr);
1415         
1416         if(first_symbol != NULL) {
1417                 for(symbol_t* symbol = first_symbol; symbol; symbol = symbol->next_symbol) {
1418                         if(symbol->addr == addr) {
1419                                 _TCHAR temp[1024];
1420 //                              my_stprintf_s(temp, 1024, _T(" (%s)"), symbol->name);
1421                                 my_stprintf_s(temp, 1024, _T(";%s"), symbol->name);
1422                                 my_tcscat_s(name[output_index], 1024, temp);
1423                                 return name[output_index];
1424                         }
1425                 }
1426         }
1427         return name[output_index];
1428 }