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;
43 std::string DLL_PREFIX sRssDir;
46 uint32_t DLL_PREFIX EndianToLittle_DWORD(uint32_t x)
48 #if defined(__LITTLE_ENDIAN__)
52 y = ((x & 0x000000ff) << 24) | ((x & 0x0000ff00) << 8) |
53 ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
58 uint16_t DLL_PREFIX EndianToLittle_WORD(uint16_t x)
60 #if defined(__LITTLE_ENDIAN__)
64 y = ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8);
69 uint32_t DLL_PREFIX EndianFromLittle_DWORD(uint32_t x)
71 #if defined(__LITTLE_ENDIAN__)
75 y = ((x & 0x000000ff) << 24) | ((x & 0x0000ff00) << 8) |
76 ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
81 uint16_t DLL_PREFIX EndianFromLittle_WORD(uint16_t x)
83 #if defined(__LITTLE_ENDIAN__)
87 y = ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8);
93 uint32_t DLL_PREFIX EndianToBig_DWORD(uint32_t x)
95 #if defined(__BIG_ENDIAN__)
99 y = ((x & 0x000000ff) << 24) | ((x & 0x0000ff00) << 8) |
100 ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
105 uint16_t DLL_PREFIX EndianToBig_WORD(uint16_t x)
107 #if defined(__BIG_ENDIAN__)
111 y = ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8);
116 uint32_t DLL_PREFIX EndianFromBig_DWORD(uint32_t x)
118 #if defined(__BIG_ENDIAN__)
122 y = ((x & 0x000000ff) << 24) | ((x & 0x0000ff00) << 8) |
123 ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
128 uint16_t DLL_PREFIX EndianFromBig_WORD(uint16_t x)
130 #if defined(__BIG_ENDIAN__)
134 y = ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8);
140 int DLL_PREFIX max(int a, int b)
149 unsigned DLL_PREFIX int max(unsigned int a, unsigned int b)
158 unsigned DLL_PREFIX int max(unsigned int a, int b)
161 if(a > (unsigned int)b) {
168 unsigned DLL_PREFIX int max(int a, unsigned int b)
171 if((unsigned int)a > b) {
178 int DLL_PREFIX min(int a, int b)
187 int DLL_PREFIX min(unsigned int a, int b)
190 if(a > INT_MAX) return b;
199 int DLL_PREFIX min(int a, unsigned int b)
202 if(b > INT_MAX) return a;
211 unsigned int DLL_PREFIX min(unsigned int a, unsigned int b)
221 #ifndef SUPPORT_SECURE_FUNCTIONS
222 //errno_t my_tfopen_s(FILE** pFile, const _TCHAR *filename, const _TCHAR *mode)
224 // if((*pFile = _tfopen(filename, mode)) != NULL) {
231 errno_t DLL_PREFIX my_tcscat_s(_TCHAR *strDestination, size_t numberOfElements, const _TCHAR *strSource)
233 _tcscat(strDestination, strSource);
237 errno_t DLL_PREFIX my_strcpy_s(char *strDestination, size_t numberOfElements, const char *strSource)
239 strcpy(strDestination, strSource);
243 errno_t DLL_PREFIX my_tcscpy_s(_TCHAR *strDestination, size_t numberOfElements, const _TCHAR *strSource)
245 _tcscpy(strDestination, strSource);
249 errno_t DLL_PREFIX my_strncpy_s(char *strDestination, size_t numberOfElements, const char *strSource, size_t count)
251 strncpy(strDestination, strSource, count);
255 errno_t DLL_PREFIX my_tcsncpy_s(_TCHAR *strDestination, size_t numberOfElements, const _TCHAR *strSource, size_t count)
257 _tcsncpy(strDestination, strSource, count);
261 char *DLL_PREFIX my_strtok_s(char *strToken, const char *strDelimit, char **context)
263 return strtok(strToken, strDelimit);
266 _TCHAR *DLL_PREFIX my_tcstok_s(_TCHAR *strToken, const char *strDelimit, _TCHAR **context)
268 return _tcstok(strToken, strDelimit);
271 int DLL_PREFIX my_sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...)
274 va_start(ap, format);
275 int result = vsnprintf(buffer, sizeOfBuffer, format, ap);
280 int DLL_PREFIX my_swprintf_s(wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format, ...)
283 va_start(ap, format);
284 int result = vswprintf(buffer, sizeOfBuffer, format, ap);
289 int DLL_PREFIX my_stprintf_s(_TCHAR *buffer, size_t sizeOfBuffer, const _TCHAR *format, ...)
292 va_start(ap, format);
293 int result = vsnprintf(buffer, sizeOfBuffer, format, ap);
298 int DLL_PREFIX my_vsprintf_s(char *buffer, size_t numberOfElements, const char *format, va_list argptr)
300 return vsnprintf(buffer, numberOfElements * sizeof(char), format, argptr);
303 int DLL_PREFIX my_vstprintf_s(_TCHAR *buffer, size_t numberOfElements, const _TCHAR *format, va_list argptr)
305 return vsnprintf(buffer, numberOfElements * sizeof(_TCHAR), format, argptr);
309 //#ifdef USE_FAST_MEMCPY
311 void DLL_PREFIX *my_memcpy(void *dst, void *src, size_t len)
314 register size_t len2;
315 register uint32_t s_align = (uint32_t)(((size_t)src) & 0x1f);
316 register uint32_t d_align = (uint32_t)(((size_t)dst) & 0x1f);
319 if(len == 0) return dst;
321 return memcpy(dst, src, len);
325 #if defined(WITHOUT_UNALIGNED_SIMD)
326 // Using SIMD without un-aligned instructions.
331 register uint64_t *s64 = (uint64_t *)src;
332 register uint64_t *d64 = (uint64_t *)dst;
334 case 0: // 256 vs 256
338 for(i = 0; i < 4; i++) b64[i] = s64[i];
339 for(i = 0; i < 4; i++) d64[i] = b64[i];
345 if(len1 != 0) return memcpy(d64, s64, len1);
349 case 0x10: // 256 vs 128
353 for(i = 0; i < 4; i++) b64[i] = s64[i];
354 for(i = 0; i < 2; i++) d64[i] = b64[i];
356 for(i = 2; i < 4; i++) d64[i - 2] = b64[i];
362 if(len1 != 0) return memcpy(d64, s64, len1);
367 case 0x18: // 256 vs 64
371 for(i = 0; i < 4; ++i) b64[i] = s64[i];
372 for(i = 0; i < 4; ++i) {
380 if(len1 != 0) return memcpy(d64, s64, len1);
387 case 0x1c: // 256 vs 32
390 register uint32_t *s32 = (uint32_t *)src;
391 register uint32_t *d32 = (uint32_t *)dst;
394 for(i = 0; i < 8; ++i) b32[i] = s32[i];
415 if(len1 != 0) return memcpy(d32, s32, len1);
420 return memcpy(dst, src, len1);
425 case 0x10: // Src alignn to 16.
428 register uint32_t *s32 = (uint32_t *)src;
429 register uint32_t *d32 = (uint32_t *)dst;
431 case 0: // 128 vs 256/128
436 for(i = 0; i < 4; i++) b32[i] = s32[i];
437 for(i = 0; i < 4; i++) d32[i] = b32[i];
443 if(len1 != 0) return memcpy(d32, s32, len1);
448 case 0x18: // 128 vs 64
452 for(i = 0; i < 4; ++i) b32[i] = s32[i];
453 for(i = 0; i < 2; ++i) {
457 for(i = 2; i < 4; ++i) {
465 if(len1 != 0) return memcpy(d32, s32, len1);
472 case 0x1c: // 128 vs 32
476 for(i = 0; i < 4; ++i) b32[i] = s32[i];
489 if(len1 != 0) return memcpy(d32, s32, len1);
494 return memcpy(dst, src, len1);
500 case 0x18: // Src alignn to 64.
502 register uint32_t *s32 = (uint32_t *)src;
503 register uint32_t *d32 = (uint32_t *)dst;
504 register uint64_t *s64 = (uint64_t *)src;
505 register uint64_t *d64 = (uint64_t *)dst;
508 case 0x10: // 64 vs 128
517 for(i = 0; i < 2; i++) d64[i] = b128[i];
522 if(len1 != 0) return memcpy(d64, s64, len1);
527 case 0x18: // 64 vs 64
537 if(len1 != 0) return memcpy(d64, s64, len1);
542 case 0x0c: // 64 vs 32
544 case 0x1c: // 64 vs 32
549 for(i = 0; i < 2; ++i) b32[i] = s32[i];
557 if(len1 != 0) return memcpy(d32, s32, len1);
562 return memcpy(dst, src, len1);
569 case 0x1c: // Src align 32
571 register uint32_t *s32 = (uint32_t *)src;
572 register uint32_t *d32 = (uint32_t *)dst;
573 register uint64_t *d64 = (uint64_t *)dst;
576 case 0x10: // 32 vs 128
589 for(i = 0; i < 4; i++) d32[i] = b128[i];
594 if(len1 != 0) return memcpy(d32, s32, len1);
599 case 0x18: // 32 vs 64
609 for(i = 0; i < 2; i++) d32[i] = b64[i];
614 if(len1 != 0) return memcpy(d32, s32, len1);
621 case 0x1c: // 32 vs 32
631 if(len1 != 0) return memcpy(d32, s32, len1);
636 return memcpy(dst, src, len1);
642 if(len1 != 0) return memcpy(dst, src, len1);
647 // Using SIMD *with* un-aligned instructions.
648 register uint32_t *s32 = (uint32_t *)src;
649 register uint32_t *d32 = (uint32_t *)dst;
650 if(((s_align & 0x07) != 0x0) && ((d_align & 0x07) != 0x0)) { // None align.
651 return memcpy(dst, src, len);
653 if((s_align == 0x0) || (d_align == 0x0)) { // Align to 256bit
657 for(i = 0; i < 8; i++) b256[i] = s32[i];
658 for(i = 0; i < 8; i++) d32[i] = b256[i];
664 if(len1 != 0) return memcpy(d32, s32, len1);
667 if(((s_align & 0x0f) == 0x0) || ((d_align & 0x0f) == 0x0)) { // Align to 128bit
671 for(i = 0; i < 4; i++) b128[i] = s32[i];
672 for(i = 0; i < 4; i++) d32[i] = b128[i];
678 if(len1 != 0) return memcpy(d32, s32, len1);
681 if(((s_align & 0x07) == 0x0) || ((d_align & 0x07) == 0x0)) { // Align to 64bit
685 for(i = 0; i < 2; i++) b64[i] = s32[i];
686 for(i = 0; i < 2; i++) d32[i] = b64[i];
692 if(len1 != 0) return memcpy(d32, s32, len1);
695 //if(len1 != 0) return memcpy(dst, src, len1);
704 BOOL DLL_PREFIX MyWritePrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString, LPCTSTR lpFileName)
707 FILEIO* fio_i = new FILEIO();
708 if(fio_i->Fopen(lpFileName, FILEIO_READ_ASCII)) {
709 char tmp_path[_MAX_PATH];
710 my_sprintf_s(tmp_path, _MAX_PATH, "%s.$$$", lpFileName);
711 FILEIO* fio_o = new FILEIO();
712 if(fio_o->Fopen(tmp_path, FILEIO_WRITE_ASCII)) {
713 bool in_section = false;
714 char section[1024], line[1024], *equal;
715 my_sprintf_s(section, 1024, "[%s]", lpAppName);
716 while(fio_i->Fgets(line, 1024) != NULL && strlen(line) > 0) {
717 if(line[strlen(line) - 1] == '\n') {
718 line[strlen(line) - 1] = '\0';
723 fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
725 } else if(strcmp(line, section) == 0) {
728 } else if(in_section && (equal = strstr(line, "=")) != NULL) {
730 if(strcmp(line, lpKeyName) == 0) {
731 fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
738 fio_o->Fprintf("%s\n", line);
742 fio_o->Fprintf("[%s]\n", lpAppName);
744 fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
752 if(!(FILEIO::RemoveFile(lpFileName) && FILEIO::RenameFile(tmp_path, lpFileName))) {
757 FILEIO* fio_o = new FILEIO();
758 if(fio_o->Fopen(lpFileName, FILEIO_WRITE_ASCII)) {
759 fio_o->Fprintf("[%s]\n", lpAppName);
760 fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
770 DWORD DLL_PREFIX MyGetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName)
772 _TCHAR *lpp = (_TCHAR *)lpReturnedString;
773 if(lpDefault != NULL) {
774 my_strcpy_s(lpp, nSize, lpDefault);
778 FILEIO* fio = new FILEIO();
779 if(fio->Fopen(lpFileName, FILEIO_READ_ASCII)) {
780 bool in_section = false;
781 char section[1024], line[1024], *equal;
782 my_sprintf_s(section, 1024, "[%s]", lpAppName);
783 while(fio->Fgets(line, 1024) != NULL && strlen(line) > 0) {
784 if(line[strlen(line) - 1] == '\n') {
785 line[strlen(line) - 1] = '\0';
790 } else if(strcmp(line, section) == 0) {
793 } else if(in_section && (equal = strstr(line, "=")) != NULL) {
795 if(strcmp(line, lpKeyName) == 0) {
796 my_strcpy_s(lpp, nSize, equal + 1);
804 //csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Try App: %s Key: %s", lpAppName, lpKeyName);
808 UINT DLL_PREFIX MyGetPrivateProfileInt(LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault, LPCTSTR lpFileName)
814 memset(sstr, 0x00, sizeof(sstr));
815 memset(sval, 0x00, sizeof(sval));
816 snprintf(sval, 128, "%d", nDefault);
817 MyGetPrivateProfileString(lpAppName,lpKeyName, sval, sstr, 128, lpFileName);
823 i = strtol(s.c_str(), NULL, 10);
825 //csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Got Int: %d\n", i);
831 scrntype_t DLL_PREFIX RGB_COLOR(uint32_t r, uint32_t g, uint32_t b)
833 scrntype_t rr = ((scrntype_t)r * 0x1f) / 0xff;
834 scrntype_t gg = ((scrntype_t)g * 0x1f) / 0xff;
835 scrntype_t bb = ((scrntype_t)b * 0x1f) / 0xff;
836 return (rr << 10) | (gg << 5) | bb;
839 scrntype_t DLL_PREFIX RGBA_COLOR(uint32_t r, uint32_t g, uint b, uint32_t a)
841 return RGB_COLOR(r, g, b);
844 uint8_t DLL_PREFIX R_OF_COLOR(scrntype_t c)
846 c = (c >> 10) & 0x1f;
847 c = (c * 0xff) / 0x1f;
851 uint8_t DLL_PREFIX G_OF_COLOR(scrntype_t c)
854 c = (c * 0xff) / 0x1f;
858 uint8_t DLL_PREFIX B_OF_COLOR(scrntype_t c)
861 c = (c * 0xff) / 0x1f;
865 uint8_t DLL_PREFIX A_OF_COLOR(scrntype_t c)
869 #elif defined(_RGB565)
870 scrntype_t DLL_PREFIX RGB_COLOR(uint32_t r, uint32_t g, uint32_t b)
872 scrntype_t rr = ((scrntype_t)r * 0x1f) / 0xff;
873 scrntype_t gg = ((scrntype_t)g * 0x3f) / 0xff;
874 scrntype_t bb = ((scrntype_t)b * 0x1f) / 0xff;
875 return (rr << 11) | (gg << 5) | bb;
878 scrntype_t DLL_PREFIX RGBA_COLOR(uint32_t r, uint32_t g, uint32_t b, uint32_t a)
880 return RGB_COLOR(r, g, b);
883 uint8_t DLL_PREFIX R_OF_COLOR(scrntype_t c)
885 c = (c >> 11) & 0x1f;
886 c = (c * 0xff) / 0x1f;
890 uint8_t DLL_PREFIX G_OF_COLOR(scrntype_t c)
893 c = (c * 0xff) / 0x3f;
897 uint8_t DLL_PREFIX B_OF_COLOR(scrntype_t c)
900 c = (c * 0xff) / 0x1f;
904 uint8_t DLL_PREFIX A_OF_COLOR(scrntype_t c)
911 struct to_upper { // Refer from documentation of libstdc++, GCC5.
912 char operator() (char c) const { return std::toupper(c); }
917 static void _my_mkdir(std::string t_dir)
920 //#if !defined(__WIN32) && !defined(__WIN64)
921 // if(fstatat(AT_FDCWD, csppath.c_str(), &st, 0) != 0) {
922 // mkdirat(AT_FDCWD, t_dir.c_str(), 0700); // Not found
925 if(stat(t_dir.c_str(), &st) != 0) {
926 QDir dir = QDir::current();
927 dir.mkdir(QString::fromStdString(t_dir));
928 //dir.mkpath(QString::fromUtf8(app_path));
931 if(stat(csppath.c_str(), &st) != 0) {
932 _mkdir(t_dir.c_str()); // Not found
938 const _TCHAR *DLL_PREFIX get_application_path()
940 static _TCHAR app_path[_MAX_PATH];
941 static bool initialized = false;
944 #if defined(_WIN32) && !defined(_USE_QT)
945 _TCHAR tmp_path[_MAX_PATH], *ptr = NULL;
946 if(GetModuleFileName(NULL, tmp_path, _MAX_PATH) != 0 && GetFullPathName(tmp_path, _MAX_PATH, app_path, &ptr) != 0 && ptr != NULL) {
949 my_tcscpy_s(app_path, _MAX_PATH, _T(".\\"));
952 #if defined(Q_OS_WIN)
953 std::string delim = "\\";
955 std::string delim = "/";
957 std::string csppath = cpp_homedir + "CommonSourceCodeProject" + delim ;
960 std::string cpath = csppath + my_procname + delim;
962 strncpy(app_path, cpath.c_str(), _MAX_PATH - 1);
966 return (const _TCHAR *)app_path;
969 const _TCHAR *DLL_PREFIX create_local_path(const _TCHAR *format, ...)
971 static _TCHAR file_path[8][_MAX_PATH];
972 static unsigned int table_index = 0;
973 unsigned int output_index = (table_index++) & 7;
974 _TCHAR file_name[_MAX_PATH];
975 //printf("%d %d\n", table_index, output_index);
978 va_start(ap, format);
979 my_vstprintf_s(file_name, _MAX_PATH, format, ap);
981 my_stprintf_s(file_path[output_index], _MAX_PATH, _T("%s%s"), get_application_path(), file_name);
982 return (const _TCHAR *)file_path[output_index];
985 void DLL_PREFIX create_local_path(_TCHAR *file_path, int length, const _TCHAR *format, ...)
987 _TCHAR file_name[_MAX_PATH];
990 va_start(ap, format);
991 my_vstprintf_s(file_name, _MAX_PATH, format, ap);
993 my_stprintf_s(file_path, length, _T("%s%s"), get_application_path(), file_name);
996 bool DLL_PREFIX is_absolute_path(const _TCHAR *file_path)
999 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(':')) {
1003 return (_tcslen(file_path) > 1 && (file_path[0] == _T('/') || file_path[0] == _T('\\')));
1006 const _TCHAR *DLL_PREFIX create_absolute_path(const _TCHAR *file_name)
1008 static _TCHAR file_path[8][_MAX_PATH];
1009 static unsigned int table_index = 0;
1010 unsigned int output_index = (table_index++) & 7;
1012 if(is_absolute_path(file_name)) {
1013 my_tcscpy_s(file_path[output_index], _MAX_PATH, file_name);
1015 my_tcscpy_s(file_path[output_index], _MAX_PATH, create_local_path(file_name));
1017 return (const _TCHAR *)file_path[output_index];
1020 void DLL_PREFIX create_absolute_path(_TCHAR *file_path, int length, const _TCHAR *file_name)
1022 my_tcscpy_s(file_path, length, create_absolute_path(file_name));
1025 const _TCHAR *DLL_PREFIX create_date_file_path(const _TCHAR *extension)
1027 cur_time_t cur_time;
1029 get_host_time(&cur_time);
1030 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);
1033 void DLL_PREFIX create_date_file_path(_TCHAR *file_path, int length, const _TCHAR *extension)
1035 my_tcscpy_s(file_path, length, create_date_file_path(extension));
1038 bool DLL_PREFIX check_file_extension(const _TCHAR *file_path, const _TCHAR *ext)
1040 #if defined(_USE_QT)
1041 std::string s_fpath = file_path;
1042 std::string s_ext = ext;
1045 std::transform(s_fpath.begin(), s_fpath.end(), s_fpath.begin(), to_upper());
1046 std::transform(s_ext.begin(), s_ext.end(), s_ext.begin(), to_upper());
1047 if(s_fpath.length() < s_ext.length()) return false;
1048 pos = s_fpath.rfind(s_ext.c_str(), s_fpath.length());
1049 if((pos != (int)std::string::npos) && (pos >= ((int)s_fpath.length() - (int)s_ext.length()))) return true;
1052 int nam_len = _tcslen(file_path);
1053 int ext_len = _tcslen(ext);
1055 return (nam_len >= ext_len && _tcsncicmp(&file_path[nam_len - ext_len], ext, ext_len) == 0);
1059 const _TCHAR *DLL_PREFIX get_file_path_without_extensiton(const _TCHAR *file_path)
1061 static _TCHAR path[8][_MAX_PATH];
1062 static unsigned int table_index = 0;
1063 unsigned int output_index = (table_index++) & 7;
1065 my_tcscpy_s(path[output_index], _MAX_PATH, file_path);
1066 #if defined(_WIN32) && defined(_MSC_VER)
1067 PathRemoveExtension(path[output_index]);
1068 #elif defined(_USE_QT)
1070 delim = QString::fromUtf8(".");
1071 QString tmp_path = QString::fromUtf8(file_path);
1072 int n = tmp_path.lastIndexOf(delim);
1074 tmp_path = tmp_path.left(n);
1076 //printf("%s\n", tmp_path.toUtf8().constData());
1077 memset(path[output_index], 0x00, sizeof(_TCHAR) * _MAX_PATH);
1078 strncpy(path[output_index], tmp_path.toUtf8().constData(), _MAX_PATH - 1);
1081 return (const _TCHAR *)path[output_index];
1084 void DLL_PREFIX get_long_full_path_name(const _TCHAR* src, _TCHAR* dst, size_t dst_len)
1087 _TCHAR tmp[_MAX_PATH];
1088 if(GetFullPathName(src, _MAX_PATH, tmp, NULL) == 0) {
1089 my_tcscpy_s(dst, dst_len, src);
1090 } else if(GetLongPathName(tmp, dst, _MAX_PATH) == 0) {
1091 my_tcscpy_s(dst, dst_len, tmp);
1093 #elif defined(_USE_QT)
1094 QString tmp_path = QString::fromUtf8(src);
1095 QFileInfo info(tmp_path);
1096 my_tcscpy_s(dst, dst_len, info.absoluteFilePath().toLocal8Bit().constData());
1098 // write code for your environment
1103 const _TCHAR *DLL_PREFIX get_parent_dir(const _TCHAR* file)
1105 static _TCHAR path[8][_MAX_PATH];
1106 static unsigned int table_index = 0;
1107 unsigned int output_index = (table_index++) & 7;
1111 GetFullPathName(file, _MAX_PATH, path[output_index], &ptr);
1115 #elif defined(_USE_QT)
1117 #if defined(Q_OS_WIN)
1118 delim = QString::fromUtf8("\\");
1120 delim = QString::fromUtf8("/");
1122 QString tmp_path = QString::fromUtf8(file);
1123 int n = tmp_path.lastIndexOf(delim);
1125 tmp_path = tmp_path.left(n);
1126 tmp_path.append(delim);
1128 //printf("%s\n", tmp_path.toUtf8().constData());
1129 memset(path[output_index], 0x00, sizeof(_TCHAR) * _MAX_PATH);
1130 strncpy(path[output_index], tmp_path.toUtf8().constData(), _MAX_PATH - 1);
1132 // write code for your environment
1134 return path[output_index];
1137 const wchar_t *DLL_PREFIX char_to_wchar(const char *cs)
1140 static wchar_t ws[4096];
1142 #if defined(_WIN32) || defined(_USE_QT)
1143 mbstowcs(ws, cs, strlen(cs));
1145 // write code for your environment
1150 const char *DLL_PREFIX wchar_to_char(const wchar_t *ws)
1153 static char cs[4096];
1156 wcstombs(cs, ws, wcslen(ws));
1157 #elif defined(_USE_QT)
1158 wcstombs(cs, ws, wcslen(ws));
1160 // write code for your environment
1165 const _TCHAR *DLL_PREFIX char_to_tchar(const char *cs)
1167 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1169 return char_to_wchar(cs);
1176 const char *DLL_PREFIX tchar_to_char(const _TCHAR *ts)
1178 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1180 return wchar_to_char(ts);
1187 const _TCHAR *DLL_PREFIX wchar_to_tchar(const wchar_t *ws)
1189 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1190 // wchar_t to wchar_t
1194 return wchar_to_char(ws);
1198 const wchar_t *DLL_PREFIX tchar_to_wchar(const _TCHAR *ts)
1200 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1201 // wchar_t to wchar_t
1205 return char_to_wchar(ts);
1209 const _TCHAR *DLL_PREFIX create_string(const _TCHAR* format, ...)
1211 static _TCHAR buffer[8][1024];
1212 static unsigned int table_index = 0;
1213 unsigned int output_index = (table_index++) & 7;
1216 va_start(ap, format);
1217 my_vstprintf_s(buffer[output_index], 1024, format, ap);
1219 return (const _TCHAR *)buffer[output_index];
1222 int32_t DLL_PREFIX muldiv_s32(int32_t nNumber, int32_t nNumerator, int32_t nDenominator)
1226 tmp = (int64_t)nNumber;
1227 tmp *= (int64_t)nNumerator;
1228 tmp /= (int64_t)nDenominator;
1229 return (int32_t)tmp;
1232 tmp = (double)nNumber;
1233 tmp *= (double)nNumerator;
1234 tmp /= (double)nDenominator;
1236 return (int32_t)(tmp - 0.5);
1238 return (int32_t)(tmp + 0.5);
1243 uint32_t DLL_PREFIX muldiv_u32(uint32_t nNumber, uint32_t nNumerator, uint32_t nDenominator)
1247 tmp = (uint64_t)nNumber;
1248 tmp *= (uint64_t)nNumerator;
1249 tmp /= (uint64_t)nDenominator;
1250 return (uint32_t)tmp;
1253 tmp = (double)nNumber;
1254 tmp *= (double)nNumerator;
1255 tmp /= (double)nDenominator;
1256 return (uint32_t)(tmp + 0.5);
1260 static bool _crc_initialized = false;
1261 static uint32_t _crc_table[256] = {0};
1262 static void init_crc32_table(void)
1264 for(int i = 0; i < 256; i++) {
1266 for(int j = 0; j < 8; j++) {
1268 c = (c >> 1) ^ 0xedb88320;
1275 _crc_initialized = true;
1278 uint32_t DLL_PREFIX get_crc32(uint8_t data[], int size)
1280 const uint32_t *table = (const uint32_t *)_crc_table;
1281 if(!_crc_initialized) {
1286 for(int i = 0; i < size; i++) {
1287 c = table[(c ^ data[i]) & 0xff] ^ (c >> 8);
1292 uint32_t DLL_PREFIX calc_crc32(uint32_t seed, uint8_t data[], int size)
1295 if(!_crc_initialized) {
1298 const uint32_t *table = (const uint32_t *)_crc_table;
1301 for(int i = 0; i < size; i++) {
1302 c = table[(c ^ data[i]) & 0xff] ^ (c >> 8);
1307 // Refer to : https://qiita.com/mikecat_mixc/items/e5d236e3a3803ef7d3c5
1308 static const uint32_t CRC_MAGIC_WORD = 0x04C11DB7;
1309 uint32_t crc = seed;
1310 uint8_t *ptr = data;
1314 for(int i = 0; i < bytes; i++) {
1316 for(int bit = 0; bit < 8; bit++) {
1317 is_overflow = ((crc & 0x1) != 0);
1319 if((d & 0x01) != 0) crc = crc | 0x80000000;
1320 if(is_overflow) crc = crc ^ ((uint32_t)~CRC_MAGIC_WORD);
1328 uint16_t DLL_PREFIX jis_to_sjis(uint16_t jis)
1332 tmp.w.l = jis - 0x2121;
1333 if(tmp.w.l & 0x100) {
1338 if(tmp.b.l > 0x7f) {
1341 tmp.b.h = (tmp.b.h >> 1) + 0x81;
1342 if(tmp.w.l >= 0xa000) {
1348 int DLL_PREFIX decibel_to_volume(int decibel)
1350 // +1 equals +0.5dB (same as fmgen)
1351 return (int)(1024.0 * pow(10.0, decibel / 40.0) + 0.5);
1354 int32_t DLL_PREFIX apply_volume(int32_t sample, int volume)
1368 // if(output > 2147483647) {
1369 // return 2147483647;
1370 // } else if(output < (-2147483647 - 1)) {
1371 // return (-2147483647 - 1);
1373 // return (int32_t)output;
1378 void DLL_PREFIX get_host_time(cur_time_t* cur_time)
1382 GetLocalTime(&sTime);
1383 cur_time->year = sTime.wYear;
1384 cur_time->month = sTime.wMonth;
1385 cur_time->day = sTime.wDay;
1386 cur_time->day_of_week = sTime.wDayOfWeek;
1387 cur_time->hour = sTime.wHour;
1388 cur_time->minute = sTime.wMinute;
1389 cur_time->second = sTime.wSecond;
1391 time_t timer = time(NULL);
1392 struct tm *local = localtime(&timer);
1393 cur_time->year = local->tm_year + 1900;
1394 cur_time->month = local->tm_mon + 1;
1395 cur_time->day = local->tm_mday;
1396 cur_time->day_of_week = local->tm_wday;
1397 cur_time->hour = local->tm_hour;
1398 cur_time->minute = local->tm_min;
1399 cur_time->second = local->tm_sec;
1405 void DLL_PREFIX cur_time_t::increment()
1407 if(++second >= 60) {
1409 if(++minute >= 60) {
1413 // days in this month
1416 days = LEAP_YEAR(year) ? 29 : 28;
1417 } else if(month == 4 || month == 6 || month == 9 || month == 11) {
1427 if(++day_of_week >= 7) {
1435 void DLL_PREFIX cur_time_t::update_year()
1440 } else if(year < 100) {
1445 void DLL_PREFIX cur_time_t::update_day_of_week()
1447 static const int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
1448 int y = year - (month < 3);
1449 day_of_week = (y + y / 4 - y / 100 + y / 400 + t[month - 1] + day) % 7;
1452 #define STATE_VERSION 1
1454 #include "./state_data.h"
1456 void DLL_PREFIX cur_time_t::save_state_helper(void *f, uint32_t *sumseed, bool *__stat)
1458 csp_state_data_saver *state_saver = (csp_state_data_saver *)f;
1459 const _TCHAR *_ns = "cur_time_t::BEGIN";
1460 const _TCHAR *_ne = "cur_time_t::END";
1462 if(f == NULL) return;
1464 state_saver->save_string_data(_ns, sumseed, strlen(_ns) + 1, __stat);
1465 state_saver->put_dword(STATE_VERSION, sumseed, __stat);
1467 state_saver->put_int32(year, sumseed, __stat);
1468 state_saver->put_int8((int8_t)month, sumseed, __stat);
1469 state_saver->put_int8((int8_t)day, sumseed, __stat);
1470 state_saver->put_int8((int8_t)day_of_week, sumseed, __stat);
1471 state_saver->put_int8((int8_t)hour, sumseed, __stat);
1472 state_saver->put_int8((int8_t)minute, sumseed, __stat);
1473 state_saver->put_int16((int16_t)second, sumseed, __stat);
1474 state_saver->put_bool(initialized, sumseed, __stat);
1476 state_saver->save_string_data(_ne, sumseed, strlen(_ne) + 1, __stat);
1479 bool DLL_PREFIX cur_time_t::load_state_helper(void *f, uint32_t *sumseed, bool *__stat)
1481 csp_state_data_saver *state_saver = (csp_state_data_saver *)f;
1482 const _TCHAR *_ns = "cur_time_t::BEGIN";
1483 const _TCHAR *_ne = "cur_time_t::END";
1487 if(f == NULL) return false;
1488 memset(sbuf, 0x00, sizeof(sbuf));
1489 state_saver->load_string_data(sbuf, sumseed, strlen(_ns) + 1, __stat);
1490 tmpvar = state_saver->get_dword(sumseed, __stat);
1491 if(strncmp(sbuf, _ns, strlen(_ns) + 1) != 0) {
1492 if(__stat != NULL) *__stat = false;
1495 if(tmpvar != STATE_VERSION) {
1496 if(__stat != NULL) *__stat = false;
1499 year = state_saver->get_int32(sumseed, __stat);
1500 month = (int)(state_saver->get_int8(sumseed, __stat));
1501 day = (int)(state_saver->get_int8(sumseed, __stat));
1502 day_of_week = (int)(state_saver->get_int8(sumseed, __stat));
1503 hour = (int)(state_saver->get_int8(sumseed, __stat));
1504 minute = (int)(state_saver->get_int8(sumseed, __stat));
1505 second = (int)(state_saver->get_int16(sumseed, __stat));
1506 initialized = state_saver->get_bool(sumseed, __stat);
1508 memset(sbuf, 0x00, sizeof(sbuf));
1509 state_saver->load_string_data(sbuf, sumseed, strlen(_ne) + 1, __stat);
1510 if(strncmp(_ne, sbuf, strlen(_ne) + 1) != 0) {
1511 if(__stat != NULL) *__stat = false;
1515 if(__stat != NULL) {
1516 if(*__stat == false) return false;
1522 void DLL_PREFIX cur_time_t::save_state(void *f)
1524 FILEIO *state_fio = (FILEIO *)f;
1526 state_fio->FputUint32(STATE_VERSION);
1528 state_fio->FputInt32(year);
1529 state_fio->FputInt32(month);
1530 state_fio->FputInt32(day);
1531 state_fio->FputInt32(day_of_week);
1532 state_fio->FputInt32(hour);
1533 state_fio->FputInt32(minute);
1534 state_fio->FputInt32(second);
1535 state_fio->FputBool(initialized);
1538 bool DLL_PREFIX cur_time_t::load_state(void *f)
1540 FILEIO *state_fio = (FILEIO *)f;
1542 if(state_fio->FgetUint32() != STATE_VERSION) {
1545 year = state_fio->FgetInt32();
1546 month = state_fio->FgetInt32();
1547 day = state_fio->FgetInt32();
1548 day_of_week = state_fio->FgetInt32();
1549 hour = state_fio->FgetInt32();
1550 minute = state_fio->FgetInt32();
1551 second = state_fio->FgetInt32();
1552 initialized = state_fio->FgetBool();
1556 const _TCHAR *DLL_PREFIX get_symbol(symbol_t *first_symbol, uint32_t addr)
1558 static _TCHAR name[8][1024];
1559 static unsigned int table_index = 0;
1560 unsigned int output_index = (table_index++) & 7;
1562 if(first_symbol != NULL) {
1563 for(symbol_t* symbol = first_symbol; symbol; symbol = symbol->next_symbol) {
1564 if(symbol->addr == addr) {
1565 my_tcscpy_s(name[output_index], 1024, symbol->name);
1566 return name[output_index];
1573 const _TCHAR *DLL_PREFIX get_value_or_symbol(symbol_t *first_symbol, const _TCHAR *format, uint32_t addr)
1575 static _TCHAR name[8][1024];
1576 static unsigned int table_index = 0;
1577 unsigned int output_index = (table_index++) & 7;
1579 if(first_symbol != NULL) {
1580 for(symbol_t* symbol = first_symbol; symbol; symbol = symbol->next_symbol) {
1581 if(symbol->addr == addr) {
1582 my_tcscpy_s(name[output_index], 1024, symbol->name);
1583 return name[output_index];
1587 my_stprintf_s(name[output_index], 1024, format, addr);
1588 return name[output_index];
1591 const _TCHAR *DLL_PREFIX get_value_and_symbol(symbol_t *first_symbol, const _TCHAR *format, uint32_t addr)
1593 static _TCHAR name[8][1024];
1594 static unsigned int table_index = 0;
1595 unsigned int output_index = (table_index++) & 7;
1597 my_stprintf_s(name[output_index], 1024, format, addr);
1599 if(first_symbol != NULL) {
1600 for(symbol_t* symbol = first_symbol; symbol; symbol = symbol->next_symbol) {
1601 if(symbol->addr == addr) {
1603 // my_stprintf_s(temp, 1024, _T(" (%s)"), symbol->name);
1604 my_stprintf_s(temp, 1024, _T(";%s"), symbol->name);
1605 my_tcscat_s(name[output_index], 1024, temp);
1606 return name[output_index];
1610 return name[output_index];
1613 // Use this before writing wav_data.
1614 bool DLL_PREFIX write_dummy_wav_header(void *__fio)
1616 if(__fio == NULL) return false;
1618 FILEIO *fio = (FILEIO *)__fio;
1619 uint8_t dummy[sizeof(wav_header_t) + sizeof(wav_chunk_t)];
1621 if(!fio->IsOpened()) return false;
1623 memset(dummy, 0, sizeof(dummy));
1624 fio->Fwrite(dummy, sizeof(dummy), 1);
1627 // Use this after writing wav_data.
1628 bool DLL_PREFIX set_wav_header(wav_header_t *header, wav_chunk_t *first_chunk, uint16_t channels, uint32_t rate,
1629 uint16_t bits, size_t file_length)
1631 uint32_t length = (uint32_t) file_length;
1633 if(header == NULL) return false;
1634 if(first_chunk == NULL) return false;
1636 pair_t __riff_chunk_size;
1637 pair_t __fmt_chunk_size;
1638 pair_t __wav_chunk_size;
1640 pair16_t __channels;
1641 pair_t __sample_rate;
1642 pair_t __data_speed;
1643 pair16_t __block_size;
1644 pair16_t __sample_bits;
1646 __riff_chunk_size.d = length - 8;
1647 __fmt_chunk_size.d = 16;
1649 __channels.w = channels;
1650 __sample_rate.d = rate;
1651 __block_size.w = (uint16_t)((channels * bits) / 8);
1652 __sample_bits.w = bits;
1653 __data_speed.d = rate * (uint32_t)(__block_size.w);
1655 memcpy(&(header->riff_chunk.id), "RIFF", 4);
1656 header->riff_chunk.size = __riff_chunk_size.get_4bytes_le_to();
1658 memcpy(&(header->wave), "WAVE", 4);
1659 memcpy(&(header->fmt_chunk.id), "fmt ", 4);
1660 header->fmt_chunk.size = __fmt_chunk_size.get_4bytes_le_to();
1661 header->format_id = __fmt_id.get_2bytes_le_to();
1662 header->channels = __channels.get_2bytes_le_to();
1663 header->sample_rate = __sample_rate.get_4bytes_le_to();
1664 header->data_speed = __data_speed.get_4bytes_le_to();
1665 header->block_size = __block_size.get_2bytes_le_to();
1666 header->sample_bits = __sample_bits.get_2bytes_le_to();
1668 memcpy(&(first_chunk->id), "data", 4);
1669 __wav_chunk_size.d = length - sizeof(wav_header_t) - sizeof(wav_chunk_t);
1670 first_chunk->size = __wav_chunk_size.get_4bytes_le_to();
1674 // Note: buffers are allocated by this, You should free() within user class.
1675 bool DLL_PREFIX load_wav_to_stereo(void *__fio, int16_t **left_buf, int16_t **right_buf, uint32_t *rate, int *got_samples)
1678 if(__fio == NULL) return false;
1679 if(left_buf == NULL) return false;
1680 if(right_buf == NULL) return false;
1681 if(rate == NULL) return false;
1682 if(got_samples == NULL) return false;
1683 //if((bits != 8) && (bits != 16) && (bits != 32)) return false;
1685 FILEIO *fio = (FILEIO *)__fio;
1686 if(!fio->IsOpened()) return false;
1689 int16_t *left_buffer = NULL;
1690 int16_t *right_buffer = NULL;
1692 uint32_t sample_rate = 0;
1694 wav_header_t header;
1698 pair16_t __sample_bits;
1699 pair16_t __channels;
1700 pair_t __sample_rate;
1701 pair_t __chunk_size;
1703 fio->Fread(&header, sizeof(header), 1);
1704 __fmt_id.set_2bytes_le_from(header.format_id);
1705 __sample_bits.set_2bytes_le_from(header.sample_bits);
1706 __chunk_size.set_4bytes_le_from(header.fmt_chunk.size);
1707 __channels.set_2bytes_le_from(header.channels);
1708 __sample_rate.set_4bytes_le_from(header.sample_rate);
1710 if((__fmt_id.w == 1) && ((__sample_bits.w == 8) || (__sample_bits.w == 16) || (__sample_bits.w == 32))) {
1711 fio->Fseek(__chunk_size.d - 16, FILEIO_SEEK_CUR);
1712 bool is_eof = false;
1714 if(fio->Fread(&chunk, sizeof(chunk), 1) != 1) {
1718 __chunk_size.set_4bytes_le_from(chunk.size);
1719 if(strncmp(chunk.id, "data", 4) == 0) {
1722 fio->Fseek(__chunk_size.d, FILEIO_SEEK_CUR);
1724 __chunk_size.set_4bytes_le_from(chunk.size);
1731 samples = (size_t)(__chunk_size.d / __channels.w);
1732 int16_t data_l, data_r;
1742 uint8_t l, h, h2, h3;
1747 if(__sample_bits.w == 16) {
1749 } else if(__sample_bits.w == 32) {
1752 if(samples == 0) return false;
1753 sample_rate = __sample_rate.d;
1755 left_buffer = (int16_t *)malloc(samples * sizeof(int16_t));
1756 right_buffer = (int16_t *)malloc(samples * sizeof(int16_t));
1757 if(left_buffer == NULL) {
1758 if(right_buffer != NULL) free(right_buffer);
1761 if(right_buffer == NULL) {
1762 if(left_buffer != NULL) free(left_buffer);
1765 switch(__sample_bits.w) {
1767 if(__channels.sw == 1) {
1768 for(int i = 0; i < samples; i++) {
1769 data_l = (int16_t)(fio->FgetUint8());
1770 data_l = (data_l - 128) * 256;
1771 left_buffer[i] = data_l;
1772 right_buffer[i] = data_l;
1774 } else if(__channels.sw == 2) {
1775 for(int i = 0; i < samples; i++) {
1776 data_l = (int16_t)(fio->FgetUint8());
1777 data_l = (data_l - 128) * 256;
1778 data_r = (int16_t)(fio->FgetUint8());
1779 data_r = (data_r - 128) * 256;
1780 left_buffer[i] = data_l;
1781 right_buffer[i] = data_r;
1786 if(__channels.sw == 1) {
1787 for(int i = 0; i < samples; i++) {
1788 pair16.b.l = fio->FgetUint8();
1789 pair16.b.h = fio->FgetUint8();
1790 data_l = pair16.s16;
1792 left_buffer[i] = data_l;
1793 right_buffer[i] = data_l;
1795 } else if(__channels.sw == 2) {
1796 for(int i = 0; i < samples; i++) {
1797 pair16.b.l = fio->FgetUint8();
1798 pair16.b.h = fio->FgetUint8();
1799 data_l = pair16.s16;
1801 pair16.b.l = fio->FgetUint8();
1802 pair16.b.h = fio->FgetUint8();
1803 data_r = pair16.s16;
1804 left_buffer[i] = data_l;
1805 right_buffer[i] = data_r;
1810 if(__channels.sw == 1) {
1811 for(int i = 0; i < samples; i++) {
1812 pair32.b.l = fio->FgetUint8();
1813 pair32.b.h = fio->FgetUint8();
1814 pair32.b.h2 = fio->FgetUint8();
1815 pair32.b.h3 = fio->FgetUint8();
1816 data_l = (int16_t)(pair32.s32 / 65536);
1818 left_buffer[i] = data_l;
1819 right_buffer[i] = data_l;
1821 } else if(__channels.sw == 2) {
1822 for(int i = 0; i < samples; i++) {
1823 pair32.b.l = fio->FgetUint8();
1824 pair32.b.h = fio->FgetUint8();
1825 pair32.b.h2 = fio->FgetUint8();
1826 pair32.b.h3 = fio->FgetUint8();
1827 data_l = (int16_t)(pair32.s32 / 65536);
1829 pair32.b.l = fio->FgetUint8();
1830 pair32.b.h = fio->FgetUint8();
1831 pair32.b.h2 = fio->FgetUint8();
1832 pair32.b.h3 = fio->FgetUint8();
1833 data_r = (int16_t)(pair32.s32 / 65536);
1835 left_buffer[i] = data_l;
1836 right_buffer[i] = data_r;
1847 *left_buf = left_buffer;
1848 *right_buf = right_buffer;
1849 *rate = sample_rate;
1850 *got_samples = (int)samples;
1854 bool DLL_PREFIX load_wav_to_monoral(void *__fio, int16_t **buffer, uint32_t *rate, int *got_samples)
1857 if(__fio == NULL) return false;
1858 if(buffer == NULL) return false;
1859 if(rate == NULL) return false;
1860 if(got_samples == NULL) return false;
1861 //if((bits != 8) && (bits != 16) && (bits != 32)) return false;
1863 FILEIO *fio = (FILEIO *)__fio;
1864 if(!fio->IsOpened()) return false;
1867 int16_t *left_buffer = NULL;
1869 uint32_t sample_rate = 0;
1871 wav_header_t header;
1875 pair16_t __sample_bits;
1876 pair16_t __channels;
1877 pair_t __sample_rate;
1878 pair_t __chunk_size;
1880 fio->Fread(&header, sizeof(header), 1);
1881 __fmt_id.set_2bytes_le_from(header.format_id);
1882 __sample_bits.set_2bytes_le_from(header.sample_bits);
1883 __chunk_size.set_4bytes_le_from(header.fmt_chunk.size);
1884 __channels.set_2bytes_le_from(header.channels);
1885 __sample_rate.set_4bytes_le_from(header.sample_rate);
1887 if((__fmt_id.w == 1) && ((__sample_bits.w == 8) || (__sample_bits.w == 16) || (__sample_bits.w == 32))) {
1888 fio->Fseek(__chunk_size.d - 16, FILEIO_SEEK_CUR);
1889 bool is_eof = false;
1891 if(fio->Fread(&chunk, sizeof(chunk), 1) != 1) {
1895 __chunk_size.set_4bytes_le_from(chunk.size);
1896 if(strncmp(chunk.id, "data", 4) == 0) {
1899 fio->Fseek(__chunk_size.d, FILEIO_SEEK_CUR);
1901 __chunk_size.set_4bytes_le_from(chunk.size);
1908 samples = (size_t)(__chunk_size.d / __channels.w);
1909 int16_t data_l, data_r;
1910 int32_t data32_l, data32_r;
1920 uint8_t l, h, h2, h3;
1925 if(__sample_bits.w == 16) {
1927 } else if(__sample_bits.w == 32) {
1930 if(samples == 0) return false;
1931 sample_rate = __sample_rate.d;
1933 left_buffer = (int16_t *)malloc(samples * sizeof(int16_t));
1934 if(left_buffer == NULL) {
1937 switch(__sample_bits.w) {
1939 if(__channels.sw == 1) {
1940 for(int i = 0; i < samples; i++) {
1941 data_l = (int16_t)(fio->FgetUint8());
1942 data_l = (data_l - 128) * 256;
1943 left_buffer[i] = data_l;
1945 } else if(__channels.sw == 2) {
1946 for(int i = 0; i < samples; i++) {
1947 data_l = (int16_t)(fio->FgetUint8());
1948 data_l = (data_l - 128) * 256;
1949 data_r = (int16_t)(fio->FgetUint8());
1950 data_r = (data_r - 128) * 256;
1951 left_buffer[i] = (data_l + data_r) / 2;
1956 if(__channels.sw == 1) {
1957 for(int i = 0; i < samples; i++) {
1958 pair16.b.l = fio->FgetUint8();
1959 pair16.b.h = fio->FgetUint8();
1960 data_l = pair16.s16;
1962 left_buffer[i] = data_l;
1964 } else if(__channels.sw == 2) {
1965 for(int i = 0; i < samples; i++) {
1966 pair16.b.l = fio->FgetUint8();
1967 pair16.b.h = fio->FgetUint8();
1968 data_l = pair16.s16;
1970 pair16.b.l = fio->FgetUint8();
1971 pair16.b.h = fio->FgetUint8();
1972 data_r = pair16.s16;
1973 left_buffer[i] = (data_l + data_r) / 2;
1978 if(__channels.sw == 1) {
1979 for(int i = 0; i < samples; i++) {
1980 pair32.b.l = fio->FgetUint8();
1981 pair32.b.h = fio->FgetUint8();
1982 pair32.b.h2 = fio->FgetUint8();
1983 pair32.b.h3 = fio->FgetUint8();
1984 data_l = (int16_t)(pair32.s32 / 65536);
1986 left_buffer[i] = data_l;
1988 } else if(__channels.sw == 2) {
1989 for(int i = 0; i < samples; i++) {
1990 pair32.b.l = fio->FgetUint8();
1991 pair32.b.h = fio->FgetUint8();
1992 pair32.b.h2 = fio->FgetUint8();
1993 pair32.b.h3 = fio->FgetUint8();
1994 data32_l = pair32.s32 / 65536;
1996 pair32.b.l = fio->FgetUint8();
1997 pair32.b.h = fio->FgetUint8();
1998 pair32.b.h2 = fio->FgetUint8();
1999 pair32.b.h3 = fio->FgetUint8();
2000 data32_r = pair32.s32 / 65536;
2002 left_buffer[i] = (int16_t)((data32_l + data32_r) / 2);
2013 *buffer = left_buffer;
2014 *rate = sample_rate;
2015 *got_samples = (int)samples;
2019 DLL_PREFIX const _TCHAR *get_lib_common_version()
2021 #if defined(__LIBEMU_UTIL_VERSION)
2022 return (const _TCHAR *)__LIBEMU_UTIL_VERSION;
2024 return (const _TCHAR *)"\0";