2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
13 #if !defined(__WIN32) && !defined(__WIN64)
19 #include <sys/types.h>
21 #include "csp_logger.h"
29 #pragma comment(lib, "shlwapi.lib")
37 #if defined(__MINGW32__) || defined(__MINGW64__)
38 extern DWORD GetLongPathName(LPCTSTR lpszShortPath, LPTSTR lpszLongPath, DWORD cchBuffer);
41 std::string DLL_PREFIX cpp_homedir;
42 std::string DLL_PREFIX my_procname;
45 uint32_t DLL_PREFIX EndianToLittle_DWORD(uint32_t x)
47 #if defined(__LITTLE_ENDIAN__)
51 y = ((x & 0x000000ff) << 24) | ((x & 0x0000ff00) << 8) |
52 ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
57 uint16_t DLL_PREFIX EndianToLittle_WORD(uint16_t x)
59 #if defined(__LITTLE_ENDIAN__)
63 y = ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8);
69 int DLL_PREFIX max(int a, int b)
78 unsigned DLL_PREFIX int max(unsigned int a, unsigned int b)
87 int DLL_PREFIX min(int a, int b)
96 unsigned int DLL_PREFIX min(unsigned int a, unsigned int b)
106 #ifndef SUPPORT_SECURE_FUNCTIONS
107 //errno_t my_tfopen_s(FILE** pFile, const _TCHAR *filename, const _TCHAR *mode)
109 // if((*pFile = _tfopen(filename, mode)) != NULL) {
116 errno_t DLL_PREFIX my_tcscat_s(_TCHAR *strDestination, size_t numberOfElements, const _TCHAR *strSource)
118 _tcscat(strDestination, strSource);
122 errno_t DLL_PREFIX my_strcpy_s(char *strDestination, size_t numberOfElements, const char *strSource)
124 strcpy(strDestination, strSource);
128 errno_t DLL_PREFIX my_tcscpy_s(_TCHAR *strDestination, size_t numberOfElements, const _TCHAR *strSource)
130 _tcscpy(strDestination, strSource);
134 errno_t DLL_PREFIX my_strncpy_s(char *strDestination, size_t numberOfElements, const char *strSource, size_t count)
136 strncpy(strDestination, strSource, count);
140 errno_t DLL_PREFIX my_tcsncpy_s(_TCHAR *strDestination, size_t numberOfElements, const _TCHAR *strSource, size_t count)
142 _tcsncpy(strDestination, strSource, count);
146 char *DLL_PREFIX my_strtok_s(char *strToken, const char *strDelimit, char **context)
148 return strtok(strToken, strDelimit);
151 _TCHAR *DLL_PREFIX my_tcstok_s(_TCHAR *strToken, const char *strDelimit, _TCHAR **context)
153 return _tcstok(strToken, strDelimit);
156 int DLL_PREFIX my_sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...)
159 va_start(ap, format);
160 int result = vsnprintf(buffer, sizeOfBuffer, format, ap);
165 int DLL_PREFIX my_swprintf_s(wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format, ...)
168 va_start(ap, format);
169 int result = vswprintf(buffer, sizeOfBuffer, format, ap);
174 int DLL_PREFIX my_stprintf_s(_TCHAR *buffer, size_t sizeOfBuffer, const _TCHAR *format, ...)
177 va_start(ap, format);
178 int result = vsnprintf(buffer, sizeOfBuffer, format, ap);
183 int DLL_PREFIX my_vsprintf_s(char *buffer, size_t numberOfElements, const char *format, va_list argptr)
185 return vsnprintf(buffer, numberOfElements * sizeof(char), format, argptr);
188 int DLL_PREFIX my_vstprintf_s(_TCHAR *buffer, size_t numberOfElements, const _TCHAR *format, va_list argptr)
190 return vsnprintf(buffer, numberOfElements * sizeof(_TCHAR), format, argptr);
194 //#ifdef USE_FAST_MEMCPY
196 void DLL_PREFIX *my_memcpy(void *dst, void *src, size_t len)
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);
204 if(len == 0) return dst;
206 return memcpy(dst, src, len);
210 #if defined(WITHOUT_UNALIGNED_SIMD)
211 // Using SIMD without un-aligned instructions.
216 register uint64_t *s64 = (uint64_t *)src;
217 register uint64_t *d64 = (uint64_t *)dst;
219 case 0: // 256 vs 256
223 for(i = 0; i < 4; i++) b64[i] = s64[i];
224 for(i = 0; i < 4; i++) d64[i] = b64[i];
230 if(len1 != 0) return memcpy(d64, s64, len1);
234 case 0x10: // 256 vs 128
238 for(i = 0; i < 4; i++) b64[i] = s64[i];
239 for(i = 0; i < 2; i++) d64[i] = b64[i];
241 for(i = 2; i < 4; i++) d64[i - 2] = b64[i];
247 if(len1 != 0) return memcpy(d64, s64, len1);
252 case 0x18: // 256 vs 64
256 for(i = 0; i < 4; ++i) b64[i] = s64[i];
257 for(i = 0; i < 4; ++i) {
265 if(len1 != 0) return memcpy(d64, s64, len1);
272 case 0x1c: // 256 vs 32
275 register uint32_t *s32 = (uint32_t *)src;
276 register uint32_t *d32 = (uint32_t *)dst;
279 for(i = 0; i < 8; ++i) b32[i] = s32[i];
300 if(len1 != 0) return memcpy(d32, s32, len1);
305 return memcpy(dst, src, len1);
310 case 0x10: // Src alignn to 16.
313 register uint32_t *s32 = (uint32_t *)src;
314 register uint32_t *d32 = (uint32_t *)dst;
316 case 0: // 128 vs 256/128
321 for(i = 0; i < 4; i++) b32[i] = s32[i];
322 for(i = 0; i < 4; i++) d32[i] = b32[i];
328 if(len1 != 0) return memcpy(d32, s32, len1);
333 case 0x18: // 128 vs 64
337 for(i = 0; i < 4; ++i) b32[i] = s32[i];
338 for(i = 0; i < 2; ++i) {
342 for(i = 2; i < 4; ++i) {
350 if(len1 != 0) return memcpy(d32, s32, len1);
357 case 0x1c: // 128 vs 32
361 for(i = 0; i < 4; ++i) b32[i] = s32[i];
374 if(len1 != 0) return memcpy(d32, s32, len1);
379 return memcpy(dst, src, len1);
385 case 0x18: // Src alignn to 64.
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;
393 case 0x10: // 64 vs 128
402 for(i = 0; i < 2; i++) d64[i] = b128[i];
407 if(len1 != 0) return memcpy(d64, s64, len1);
412 case 0x18: // 64 vs 64
422 if(len1 != 0) return memcpy(d64, s64, len1);
427 case 0x0c: // 64 vs 32
429 case 0x1c: // 64 vs 32
434 for(i = 0; i < 2; ++i) b32[i] = s32[i];
442 if(len1 != 0) return memcpy(d32, s32, len1);
447 return memcpy(dst, src, len1);
454 case 0x1c: // Src align 32
456 register uint32_t *s32 = (uint32_t *)src;
457 register uint32_t *d32 = (uint32_t *)dst;
458 register uint64_t *d64 = (uint64_t *)dst;
461 case 0x10: // 32 vs 128
474 for(i = 0; i < 4; i++) d32[i] = b128[i];
479 if(len1 != 0) return memcpy(d32, s32, len1);
484 case 0x18: // 32 vs 64
494 for(i = 0; i < 2; i++) d32[i] = b64[i];
499 if(len1 != 0) return memcpy(d32, s32, len1);
506 case 0x1c: // 32 vs 32
516 if(len1 != 0) return memcpy(d32, s32, len1);
521 return memcpy(dst, src, len1);
527 if(len1 != 0) return memcpy(dst, src, len1);
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);
538 if((s_align == 0x0) || (d_align == 0x0)) { // Align to 256bit
542 for(i = 0; i < 8; i++) b256[i] = s32[i];
543 for(i = 0; i < 8; i++) d32[i] = b256[i];
549 if(len1 != 0) return memcpy(d32, s32, len1);
552 if(((s_align & 0x0f) == 0x0) || ((d_align & 0x0f) == 0x0)) { // Align to 128bit
556 for(i = 0; i < 4; i++) b128[i] = s32[i];
557 for(i = 0; i < 4; i++) d32[i] = b128[i];
563 if(len1 != 0) return memcpy(d32, s32, len1);
566 if(((s_align & 0x07) == 0x0) || ((d_align & 0x07) == 0x0)) { // Align to 64bit
570 for(i = 0; i < 2; i++) b64[i] = s32[i];
571 for(i = 0; i < 2; i++) d32[i] = b64[i];
577 if(len1 != 0) return memcpy(d32, s32, len1);
580 //if(len1 != 0) return memcpy(dst, src, len1);
589 BOOL DLL_PREFIX MyWritePrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString, LPCTSTR lpFileName)
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';
608 fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
610 } else if(strcmp(line, section) == 0) {
613 } else if(in_section && (equal = strstr(line, "=")) != NULL) {
615 if(strcmp(line, lpKeyName) == 0) {
616 fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
623 fio_o->Fprintf("%s\n", line);
627 fio_o->Fprintf("[%s]\n", lpAppName);
629 fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
637 if(!(FILEIO::RemoveFile(lpFileName) && FILEIO::RenameFile(tmp_path, lpFileName))) {
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);
655 DWORD DLL_PREFIX MyGetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName)
657 _TCHAR *lpp = (_TCHAR *)lpReturnedString;
658 if(lpDefault != NULL) {
659 my_strcpy_s(lpp, nSize, lpDefault);
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';
675 } else if(strcmp(line, section) == 0) {
678 } else if(in_section && (equal = strstr(line, "=")) != NULL) {
680 if(strcmp(line, lpKeyName) == 0) {
681 my_strcpy_s(lpp, nSize, equal + 1);
689 //csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Try App: %s Key: %s", lpAppName, lpKeyName);
693 UINT DLL_PREFIX MyGetPrivateProfileInt(LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault, LPCTSTR lpFileName)
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);
708 i = strtol(s.c_str(), NULL, 10);
710 //csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Got Int: %d\n", i);
716 scrntype_t DLL_PREFIX RGB_COLOR(uint32_t r, uint32_t g, uint32_t b)
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;
724 scrntype_t DLL_PREFIX RGBA_COLOR(uint32_t r, uint32_t g, uint b, uint32_t a)
726 return RGB_COLOR(r, g, b);
729 uint8_t DLL_PREFIX R_OF_COLOR(scrntype_t c)
731 c = (c >> 10) & 0x1f;
732 c = (c * 0xff) / 0x1f;
736 uint8_t DLL_PREFIX G_OF_COLOR(scrntype_t c)
739 c = (c * 0xff) / 0x1f;
743 uint8_t DLL_PREFIX B_OF_COLOR(scrntype_t c)
746 c = (c * 0xff) / 0x1f;
750 uint8_t DLL_PREFIX A_OF_COLOR(scrntype_t c)
754 #elif defined(_RGB565)
755 scrntype_t DLL_PREFIX RGB_COLOR(uint32_t r, uint32_t g, uint32_t b)
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;
763 scrntype_t DLL_PREFIX RGBA_COLOR(uint32_t r, uint32_t g, uint32_t b, uint32_t a)
765 return RGB_COLOR(r, g, b);
768 uint8_t DLL_PREFIX R_OF_COLOR(scrntype_t c)
770 c = (c >> 11) & 0x1f;
771 c = (c * 0xff) / 0x1f;
775 uint8_t DLL_PREFIX G_OF_COLOR(scrntype_t c)
778 c = (c * 0xff) / 0x3f;
782 uint8_t DLL_PREFIX B_OF_COLOR(scrntype_t c)
785 c = (c * 0xff) / 0x1f;
789 uint8_t DLL_PREFIX A_OF_COLOR(scrntype_t c)
796 struct to_upper { // Refer from documentation of libstdc++, GCC5.
797 char operator() (char c) const { return std::toupper(c); }
802 static void _my_mkdir(std::string t_dir)
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
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));
816 if(stat(csppath.c_str(), &st) != 0) {
817 _mkdir(t_dir.c_str()); // Not found
823 const _TCHAR *DLL_PREFIX get_application_path()
825 static _TCHAR app_path[_MAX_PATH];
826 static bool initialized = false;
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) {
834 my_tcscpy_s(app_path, _MAX_PATH, _T(".\\"));
837 #if defined(Q_OS_WIN)
838 std::string delim = "\\";
840 std::string delim = "/";
842 std::string csppath = cpp_homedir + "CommonSourceCodeProject" + delim ;
845 std::string cpath = csppath + my_procname + delim;
847 strncpy(app_path, cpath.c_str(), _MAX_PATH);
851 return (const _TCHAR *)app_path;
854 const _TCHAR *DLL_PREFIX create_local_path(const _TCHAR *format, ...)
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);
863 va_start(ap, format);
864 my_vstprintf_s(file_name, _MAX_PATH, format, 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];
870 void DLL_PREFIX create_local_path(_TCHAR *file_path, int length, const _TCHAR *format, ...)
872 _TCHAR file_name[_MAX_PATH];
875 va_start(ap, format);
876 my_vstprintf_s(file_name, _MAX_PATH, format, ap);
878 my_stprintf_s(file_path, length, _T("%s%s"), get_application_path(), file_name);
881 bool DLL_PREFIX is_absolute_path(const _TCHAR *file_path)
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(':')) {
888 return (_tcslen(file_path) > 1 && (file_path[0] == _T('/') || file_path[0] == _T('\\')));
891 const _TCHAR *DLL_PREFIX create_absolute_path(const _TCHAR *file_name)
893 static _TCHAR file_path[8][_MAX_PATH];
894 static unsigned int table_index = 0;
895 unsigned int output_index = (table_index++) & 7;
897 if(is_absolute_path(file_name)) {
898 my_tcscpy_s(file_path[output_index], _MAX_PATH, file_name);
900 my_tcscpy_s(file_path[output_index], _MAX_PATH, create_local_path(file_name));
902 return (const _TCHAR *)file_path[output_index];
905 void DLL_PREFIX create_absolute_path(_TCHAR *file_path, int length, const _TCHAR *file_name)
907 my_tcscpy_s(file_path, length, create_absolute_path(file_name));
910 const _TCHAR *DLL_PREFIX create_date_file_path(const _TCHAR *extension)
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);
918 void DLL_PREFIX create_date_file_path(_TCHAR *file_path, int length, const _TCHAR *extension)
920 my_tcscpy_s(file_path, length, create_date_file_path(extension));
923 bool DLL_PREFIX check_file_extension(const _TCHAR *file_path, const _TCHAR *ext)
926 std::string s_fpath = file_path;
927 std::string s_ext = ext;
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;
937 int nam_len = _tcslen(file_path);
938 int ext_len = _tcslen(ext);
940 return (nam_len >= ext_len && _tcsncicmp(&file_path[nam_len - ext_len], ext, ext_len) == 0);
944 const _TCHAR *DLL_PREFIX get_file_path_without_extensiton(const _TCHAR *file_path)
946 static _TCHAR path[8][_MAX_PATH];
947 static unsigned int table_index = 0;
948 unsigned int output_index = (table_index++) & 7;
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)
955 delim = QString::fromUtf8(".");
956 QString tmp_path = QString::fromUtf8(file_path);
957 int n = tmp_path.lastIndexOf(delim);
959 tmp_path = tmp_path.left(n);
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);
966 return (const _TCHAR *)path[output_index];
969 void DLL_PREFIX get_long_full_path_name(const _TCHAR* src, _TCHAR* dst, size_t dst_len)
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);
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());
983 // write code for your environment
988 const _TCHAR *DLL_PREFIX get_parent_dir(const _TCHAR* file)
990 static _TCHAR path[8][_MAX_PATH];
991 static unsigned int table_index = 0;
992 unsigned int output_index = (table_index++) & 7;
996 GetFullPathName(file, _MAX_PATH, path[output_index], &ptr);
1000 #elif defined(_USE_QT)
1002 #if defined(Q_OS_WIN)
1003 delim = QString::fromUtf8("\\");
1005 delim = QString::fromUtf8("/");
1007 QString tmp_path = QString::fromUtf8(file);
1008 int n = tmp_path.lastIndexOf(delim);
1010 tmp_path = tmp_path.left(n);
1011 tmp_path.append(delim);
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);
1017 // write code for your environment
1019 return path[output_index];
1022 const wchar_t *DLL_PREFIX char_to_wchar(const char *cs)
1025 static wchar_t ws[4096];
1027 #if defined(_WIN32) || defined(_USE_QT)
1028 mbstowcs(ws, cs, strlen(cs));
1030 // write code for your environment
1035 const char *DLL_PREFIX wchar_to_char(const wchar_t *ws)
1038 static char cs[4096];
1041 wcstombs(cs, ws, wcslen(ws));
1042 #elif defined(_USE_QT)
1043 wcstombs(cs, ws, wcslen(ws));
1045 // write code for your environment
1050 const _TCHAR *DLL_PREFIX char_to_tchar(const char *cs)
1052 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1054 return char_to_wchar(cs);
1061 const char *DLL_PREFIX tchar_to_char(const _TCHAR *ts)
1063 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1065 return wchar_to_char(ts);
1072 const _TCHAR *DLL_PREFIX wchar_to_tchar(const wchar_t *ws)
1074 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1075 // wchar_t to wchar_t
1079 return wchar_to_char(ws);
1083 const wchar_t *DLL_PREFIX tchar_to_wchar(const _TCHAR *ts)
1085 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1086 // wchar_t to wchar_t
1090 return char_to_wchar(ts);
1094 const _TCHAR *DLL_PREFIX create_string(const _TCHAR* format, ...)
1096 static _TCHAR buffer[8][1024];
1097 static unsigned int table_index = 0;
1098 unsigned int output_index = (table_index++) & 7;
1101 va_start(ap, format);
1102 my_vstprintf_s(buffer[output_index], 1024, format, ap);
1104 return (const _TCHAR *)buffer[output_index];
1107 int32_t DLL_PREFIX muldiv_s32(int32_t nNumber, int32_t nNumerator, int32_t nDenominator)
1111 tmp = (int64_t)nNumber;
1112 tmp *= (int64_t)nNumerator;
1113 tmp /= (int64_t)nDenominator;
1114 return (int32_t)tmp;
1117 tmp = (double)nNumber;
1118 tmp *= (double)nNumerator;
1119 tmp /= (double)nDenominator;
1121 return (int32_t)(tmp - 0.5);
1123 return (int32_t)(tmp + 0.5);
1128 uint32_t DLL_PREFIX muldiv_u32(uint32_t nNumber, uint32_t nNumerator, uint32_t nDenominator)
1132 tmp = (uint64_t)nNumber;
1133 tmp *= (uint64_t)nNumerator;
1134 tmp /= (uint64_t)nDenominator;
1135 return (uint32_t)tmp;
1138 tmp = (double)nNumber;
1139 tmp *= (double)nNumerator;
1140 tmp /= (double)nDenominator;
1141 return (uint32_t)(tmp + 0.5);
1145 static bool _crc_initialized = false;
1146 static uint32_t _crc_table[256] = {0};
1147 static void init_crc32_table(void)
1149 for(int i = 0; i < 256; i++) {
1151 for(int j = 0; j < 8; j++) {
1153 c = (c >> 1) ^ 0xedb88320;
1160 _crc_initialized = true;
1163 uint32_t DLL_PREFIX get_crc32(uint8_t data[], int size)
1165 const uint32_t *table = (const uint32_t *)_crc_table;
1166 if(!_crc_initialized) {
1171 for(int i = 0; i < size; i++) {
1172 c = table[(c ^ data[i]) & 0xff] ^ (c >> 8);
1177 uint32_t DLL_PREFIX calc_crc32(uint32_t seed, uint8_t data[], int size)
1180 if(!_crc_initialized) {
1183 const uint32_t *table = (const uint32_t *)_crc_table;
1186 for(int i = 0; i < size; i++) {
1187 c = table[(c ^ data[i]) & 0xff] ^ (c >> 8);
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;
1199 for(int i = 0; i < bytes; i++) {
1201 for(int bit = 0; bit < 8; bit++) {
1202 is_overflow = ((crc & 0x1) != 0);
1204 if((d & 0x01) != 0) crc = crc | 0x80000000;
1205 if(is_overflow) crc = crc ^ ((uint32_t)~CRC_MAGIC_WORD);
1213 uint16_t DLL_PREFIX jis_to_sjis(uint16_t jis)
1217 tmp.w.l = jis - 0x2121;
1218 if(tmp.w.l & 0x100) {
1223 if(tmp.b.l > 0x7f) {
1226 tmp.b.h = (tmp.b.h >> 1) + 0x81;
1227 if(tmp.w.l >= 0xa000) {
1233 int DLL_PREFIX decibel_to_volume(int decibel)
1235 // +1 equals +0.5dB (same as fmgen)
1236 return (int)(1024.0 * pow(10.0, decibel / 40.0) + 0.5);
1239 int32_t DLL_PREFIX apply_volume(int32_t sample, int volume)
1253 // if(output > 2147483647) {
1254 // return 2147483647;
1255 // } else if(output < (-2147483647 - 1)) {
1256 // return (-2147483647 - 1);
1258 // return (int32_t)output;
1263 void DLL_PREFIX get_host_time(cur_time_t* cur_time)
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;
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;
1290 void DLL_PREFIX cur_time_t::increment()
1292 if(++second >= 60) {
1294 if(++minute >= 60) {
1298 // days in this month
1301 days = LEAP_YEAR(year) ? 29 : 28;
1302 } else if(month == 4 || month == 6 || month == 9 || month == 11) {
1312 if(++day_of_week >= 7) {
1320 void DLL_PREFIX cur_time_t::update_year()
1325 } else if(year < 100) {
1330 void DLL_PREFIX cur_time_t::update_day_of_week()
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;
1337 #define STATE_VERSION 1
1339 void DLL_PREFIX cur_time_t::save_state(void *f)
1341 FILEIO *state_fio = (FILEIO *)f;
1343 state_fio->FputUint32(STATE_VERSION);
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);
1355 bool DLL_PREFIX cur_time_t::load_state(void *f)
1357 FILEIO *state_fio = (FILEIO *)f;
1359 if(state_fio->FgetUint32() != STATE_VERSION) {
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();
1373 const _TCHAR *DLL_PREFIX get_symbol(symbol_t *first_symbol, uint32_t addr)
1375 static _TCHAR name[8][1024];
1376 static unsigned int table_index = 0;
1377 unsigned int output_index = (table_index++) & 7;
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];
1390 const _TCHAR *DLL_PREFIX get_value_or_symbol(symbol_t *first_symbol, const _TCHAR *format, uint32_t addr)
1392 static _TCHAR name[8][1024];
1393 static unsigned int table_index = 0;
1394 unsigned int output_index = (table_index++) & 7;
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];
1404 my_stprintf_s(name[output_index], 1024, format, addr);
1405 return name[output_index];
1408 const _TCHAR *DLL_PREFIX get_value_and_symbol(symbol_t *first_symbol, const _TCHAR *format, uint32_t addr)
1410 static _TCHAR name[8][1024];
1411 static unsigned int table_index = 0;
1412 unsigned int output_index = (table_index++) & 7;
1414 my_stprintf_s(name[output_index], 1024, format, addr);
1416 if(first_symbol != NULL) {
1417 for(symbol_t* symbol = first_symbol; symbol; symbol = symbol->next_symbol) {
1418 if(symbol->addr == addr) {
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];
1427 return name[output_index];