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 void DLL_PREFIX common_initialize()
48 // get the initial current path when the software starts
49 get_initial_current_path();
52 uint32_t DLL_PREFIX EndianToLittle_DWORD(uint32_t x)
54 #if defined(__LITTLE_ENDIAN__)
58 y = ((x & 0x000000ff) << 24) | ((x & 0x0000ff00) << 8) |
59 ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
64 uint16_t DLL_PREFIX EndianToLittle_WORD(uint16_t x)
66 #if defined(__LITTLE_ENDIAN__)
70 y = ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8);
75 uint32_t DLL_PREFIX EndianFromLittle_DWORD(uint32_t x)
77 #if defined(__LITTLE_ENDIAN__)
81 y = ((x & 0x000000ff) << 24) | ((x & 0x0000ff00) << 8) |
82 ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
87 uint16_t DLL_PREFIX EndianFromLittle_WORD(uint16_t x)
89 #if defined(__LITTLE_ENDIAN__)
93 y = ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8);
99 uint32_t DLL_PREFIX EndianToBig_DWORD(uint32_t x)
101 #if defined(__BIG_ENDIAN__)
105 y = ((x & 0x000000ff) << 24) | ((x & 0x0000ff00) << 8) |
106 ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
111 uint16_t DLL_PREFIX EndianToBig_WORD(uint16_t x)
113 #if defined(__BIG_ENDIAN__)
117 y = ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8);
122 uint32_t DLL_PREFIX EndianFromBig_DWORD(uint32_t x)
124 #if defined(__BIG_ENDIAN__)
128 y = ((x & 0x000000ff) << 24) | ((x & 0x0000ff00) << 8) |
129 ((x & 0x00ff0000) >> 8) | ((x & 0xff000000) >> 24);
134 uint16_t DLL_PREFIX EndianFromBig_WORD(uint16_t x)
136 #if defined(__BIG_ENDIAN__)
140 y = ((x & 0x00ff) << 8) | ((x & 0xff00) >> 8);
147 int DLL_PREFIX max(int a, int b)
157 unsigned DLL_PREFIX int max(unsigned int a, int b)
160 if(a > (unsigned int)b) {
167 unsigned DLL_PREFIX int max(int a, unsigned int b)
170 if((unsigned int)a > b) {
177 unsigned int DLL_PREFIX max(unsigned int a, unsigned int b)
186 int DLL_PREFIX min(int a, int b)
195 int DLL_PREFIX min(unsigned int a, int b)
198 if(a > INT_MAX) return b;
207 int DLL_PREFIX min(int a, unsigned int b)
210 if(b > INT_MAX) return a;
219 unsigned int DLL_PREFIX min(unsigned int a, unsigned int b)
229 #ifndef SUPPORT_SECURE_FUNCTIONS
230 //errno_t my_tfopen_s(FILE** pFile, const _TCHAR *filename, const _TCHAR *mode)
232 // if((*pFile = _tfopen(filename, mode)) != NULL) {
239 errno_t DLL_PREFIX my_tcscat_s(_TCHAR *strDestination, size_t numberOfElements, const _TCHAR *strSource)
241 _tcscat(strDestination, strSource);
245 errno_t DLL_PREFIX my_strcpy_s(char *strDestination, size_t numberOfElements, const char *strSource)
247 strcpy(strDestination, strSource);
251 errno_t DLL_PREFIX my_tcscpy_s(_TCHAR *strDestination, size_t numberOfElements, const _TCHAR *strSource)
253 _tcscpy(strDestination, strSource);
257 errno_t DLL_PREFIX my_strncpy_s(char *strDestination, size_t numberOfElements, const char *strSource, size_t count)
259 strncpy(strDestination, strSource, count);
263 errno_t DLL_PREFIX my_tcsncpy_s(_TCHAR *strDestination, size_t numberOfElements, const _TCHAR *strSource, size_t count)
265 _tcsncpy(strDestination, strSource, count);
269 char *DLL_PREFIX my_strtok_s(char *strToken, const char *strDelimit, char **context)
271 return strtok(strToken, strDelimit);
274 _TCHAR *DLL_PREFIX my_tcstok_s(_TCHAR *strToken, const char *strDelimit, _TCHAR **context)
276 return _tcstok(strToken, strDelimit);
279 int DLL_PREFIX my_sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...)
282 va_start(ap, format);
283 int result = vsnprintf(buffer, sizeOfBuffer, format, ap);
288 int DLL_PREFIX my_swprintf_s(wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format, ...)
291 va_start(ap, format);
292 int result = vswprintf(buffer, sizeOfBuffer, format, ap);
297 int DLL_PREFIX my_stprintf_s(_TCHAR *buffer, size_t sizeOfBuffer, const _TCHAR *format, ...)
300 va_start(ap, format);
301 int result = vsnprintf(buffer, sizeOfBuffer, format, ap);
306 int DLL_PREFIX my_vsprintf_s(char *buffer, size_t numberOfElements, const char *format, va_list argptr)
308 return vsnprintf(buffer, numberOfElements * sizeof(char), format, argptr);
311 int DLL_PREFIX my_vstprintf_s(_TCHAR *buffer, size_t numberOfElements, const _TCHAR *format, va_list argptr)
313 return vsnprintf(buffer, numberOfElements * sizeof(_TCHAR), format, argptr);
317 //#ifdef USE_FAST_MEMCPY
319 void DLL_PREFIX *my_memcpy(void *dst, void *src, size_t len)
321 return memcpy(dst, src, len);
327 BOOL DLL_PREFIX MyWritePrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString, LPCTSTR lpFileName)
330 FILEIO* fio_i = new FILEIO();
331 if(fio_i->Fopen(lpFileName, FILEIO_READ_ASCII)) {
332 char tmp_path[_MAX_PATH];
333 my_sprintf_s(tmp_path, _MAX_PATH, "%s.$$$", lpFileName);
334 FILEIO* fio_o = new FILEIO();
335 if(fio_o->Fopen(tmp_path, FILEIO_WRITE_ASCII)) {
336 bool in_section = false;
337 char section[1024], line[1024], *equal;
338 my_sprintf_s(section, 1024, "[%s]", lpAppName);
339 while(fio_i->Fgets(line, 1024) != NULL && strlen(line) > 0) {
340 if(line[strlen(line) - 1] == '\n') {
341 line[strlen(line) - 1] = '\0';
346 fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
348 } else if(strcmp(line, section) == 0) {
351 } else if(in_section && (equal = strstr(line, "=")) != NULL) {
353 if(strcmp(line, lpKeyName) == 0) {
354 fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
361 fio_o->Fprintf("%s\n", line);
365 fio_o->Fprintf("[%s]\n", lpAppName);
367 fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
375 if(!(FILEIO::RemoveFile(lpFileName) && FILEIO::RenameFile(tmp_path, lpFileName))) {
380 FILEIO* fio_o = new FILEIO();
381 if(fio_o->Fopen(lpFileName, FILEIO_WRITE_ASCII)) {
382 fio_o->Fprintf("[%s]\n", lpAppName);
383 fio_o->Fprintf("%s=%s\n", lpKeyName, lpString);
393 DWORD DLL_PREFIX MyGetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName)
395 _TCHAR *lpp = (_TCHAR *)lpReturnedString;
396 if(lpDefault != NULL) {
397 my_strcpy_s(lpp, nSize, lpDefault);
401 FILEIO* fio = new FILEIO();
402 if(!(fio->IsFileExisting(lpFileName))) return 0;
403 if(fio->Fopen(lpFileName, FILEIO_READ_ASCII)) {
404 bool in_section = false;
405 char section[1024], line[1024], *equal;
406 my_sprintf_s(section, 1024, "[%s]", lpAppName);
407 while(fio->Fgets(line, 1024) != NULL && strlen(line) > 0) {
408 if(line[strlen(line) - 1] == '\n') {
409 line[strlen(line) - 1] = '\0';
414 } else if(strcmp(line, section) == 0) {
417 } else if(in_section && (equal = strstr(line, "=")) != NULL) {
419 if(strcmp(line, lpKeyName) == 0) {
420 my_strcpy_s(lpp, nSize, equal + 1);
428 //csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Try App: %s Key: %s", lpAppName, lpKeyName);
432 UINT DLL_PREFIX MyGetPrivateProfileInt(LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault, LPCTSTR lpFileName)
438 memset(sstr, 0x00, sizeof(sstr));
439 memset(sval, 0x00, sizeof(sval));
440 snprintf(sval, 128, "%d", nDefault);
441 MyGetPrivateProfileString(lpAppName,lpKeyName, sval, sstr, 128, lpFileName);
447 i = strtol(s.c_str(), NULL, 10);
449 //csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Got Int: %d\n", i);
455 scrntype_t DLL_PREFIX RGB_COLOR(uint32_t r, uint32_t g, uint32_t b)
457 scrntype_t rr = ((scrntype_t)r * 0x1f) / 0xff;
458 scrntype_t gg = ((scrntype_t)g * 0x1f) / 0xff;
459 scrntype_t bb = ((scrntype_t)b * 0x1f) / 0xff;
460 return (rr << 10) | (gg << 5) | bb;
463 scrntype_t DLL_PREFIX RGBA_COLOR(uint32_t r, uint32_t g, uint b, uint32_t a)
465 return RGB_COLOR(r, g, b);
468 uint8_t DLL_PREFIX R_OF_COLOR(scrntype_t c)
470 c = (c >> 10) & 0x1f;
471 c = (c * 0xff) / 0x1f;
475 uint8_t DLL_PREFIX G_OF_COLOR(scrntype_t c)
478 c = (c * 0xff) / 0x1f;
482 uint8_t DLL_PREFIX B_OF_COLOR(scrntype_t c)
485 c = (c * 0xff) / 0x1f;
489 uint8_t DLL_PREFIX A_OF_COLOR(scrntype_t c)
493 #elif defined(_RGB565)
494 scrntype_t DLL_PREFIX RGB_COLOR(uint32_t r, uint32_t g, uint32_t b)
496 scrntype_t rr = ((scrntype_t)r * 0x1f) / 0xff;
497 scrntype_t gg = ((scrntype_t)g * 0x3f) / 0xff;
498 scrntype_t bb = ((scrntype_t)b * 0x1f) / 0xff;
499 return (rr << 11) | (gg << 5) | bb;
502 scrntype_t DLL_PREFIX RGBA_COLOR(uint32_t r, uint32_t g, uint32_t b, uint32_t a)
504 return RGB_COLOR(r, g, b);
507 uint8_t DLL_PREFIX R_OF_COLOR(scrntype_t c)
509 c = (c >> 11) & 0x1f;
510 c = (c * 0xff) / 0x1f;
514 uint8_t DLL_PREFIX G_OF_COLOR(scrntype_t c)
517 c = (c * 0xff) / 0x3f;
521 uint8_t DLL_PREFIX B_OF_COLOR(scrntype_t c)
524 c = (c * 0xff) / 0x1f;
528 uint8_t DLL_PREFIX A_OF_COLOR(scrntype_t c)
530 return 0xff; // Alpha = 255
534 // Note: table strongly recommend to be aligned by sizeof(uint16_vec8_t).
535 // This is sizeof(uint16) * 8, some compilers may require to align 16bytes(128)
536 // when using SIMD128 -- 20181105 K.O
537 void DLL_PREFIX PrepareBitTransTableUint16(_bit_trans_table_t *tbl, uint16_t on_val, uint16_t off_val)
539 if(tbl == NULL) return;
540 for(uint16_t i = 0; i < 256; i++) {
542 for(int j = 0; j < 8; j++) {
543 tbl->plane_table[i].w[j] = ((n & 0x80) == 0) ? off_val : on_val;
549 // Note: table strongly recommend to be aligned by sizeof(scrntype_vec8_t).
550 // This is sizeof(uint16) * 8, some compilers may require to align 32bytes(256) or 16bytes(128)
551 // when using SIMD256 or SIMD128 -- 20181105 K.O
552 void DLL_PREFIX PrepareBitTransTableScrnType(_bit_trans_table_scrn_t *tbl, scrntype_t on_val, scrntype_t off_val)
554 if(tbl == NULL) return;
555 for(uint16_t i = 0; i < 256; i++) {
557 for(int j = 0; j < 8; j++) {
558 tbl->plane_table[i].w[j] = ((n & 0x80) == 0) ? off_val : on_val;
564 // Prepare reverse byte-order table(s).
565 void DLL_PREFIX PrepareReverseBitTransTableUint16(_bit_trans_table_t *tbl, uint16_t on_val, uint16_t off_val)
567 if(tbl == NULL) return;
568 for(uint16_t i = 0; i < 256; i++) {
570 for(int j = 0; j < 8; j++) {
571 tbl->plane_table[i].w[j] = ((n & 0x01) == 0) ? off_val : on_val;
577 void DLL_PREFIX PrepareReverseBitTransTableScrnType(_bit_trans_table_scrn_t *tbl, scrntype_t on_val, scrntype_t off_val)
579 if(tbl == NULL) return;
580 for(uint16_t i = 0; i < 256; i++) {
582 for(int j = 0; j < 8; j++) {
583 tbl->plane_table[i].w[j] = ((n & 0x01) == 0) ? off_val : on_val;
589 // With _bit_trans_table_scrn_t.
590 void DLL_PREFIX ConvertByteToPackedPixelByColorTable2(uint8_t *src, scrntype_t* dst, int bytes, _bit_trans_table_scrn_t *tbl, scrntype_t *on_color_table, scrntype_t* off_color_table)
593 __DECL_ALIGNED(32) scrntype_vec8_t tmpd;
594 __DECL_ALIGNED(32) scrntype_vec8_t tmpdd;
595 __DECL_ALIGNED(32) scrntype_vec8_t colors;
596 scrntype_vec8_t* vt = (scrntype_vec8_t*)__builtin_assume_aligned(&(tbl->plane_table[0]), sizeof(scrntype_vec8_t));
598 uintptr_t disalign = (uintptr_t)dst;
599 disalign = disalign & (sizeof(scrntype_vec8_t) - 1); //Is align by 128bits or 256bytes?
602 scrntype_vec8_t *vdst = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
603 __DECL_VECTORIZED_LOOP
604 for(int i = 0; i < bytes; i++) {
605 tmpd.v = vt[src[i]].v;
608 __DECL_VECTORIZED_LOOP
609 for(int j = 0; j < 8; j++) {
610 colors.w[j] = on_color_table[j];
612 tmpd.v = tmpd.v & colors.v;
613 __DECL_VECTORIZED_LOOP
614 for(int j = 0; j < 8; j++) {
615 colors.w[j] = off_color_table[j];
617 tmpdd.v = tmpdd.v & colors.v;
618 vdst->v = (tmpd.v | tmpdd.v);
619 off_color_table += 8;
624 // Sorry, not aligned.
625 __DECL_VECTORIZED_LOOP
626 for(int i = 0; i < bytes; i++) {
627 tmpd.v = vt[src[i]].v;
630 __DECL_VECTORIZED_LOOP
631 for(int j = 0; j < 8; j++) {
632 colors.w[j] = on_color_table[j];
634 tmpd.v = tmpd.v & colors.v;
635 __DECL_VECTORIZED_LOOP
636 for(int j = 0; j < 8; j++) {
637 colors.w[j] = off_color_table[j];
639 tmpdd.v = tmpdd.v & colors.v;
640 tmpdd.v = tmpdd.v | tmpd.v;
641 __DECL_VECTORIZED_LOOP
642 for(int j = 0; j < 8; j++) {
645 off_color_table += 8;
653 // Convert uint8_t[] ed VRAM to uint16_t[] mono pixel pattern.
654 // You must set table to "ON_VALUE" : "OFF_VALUE" via PrepareBitTransTableUint16().
656 void DLL_PREFIX ConvertByteToSparceUint16(uint8_t *src, uint16_t* dst, int bytes, _bit_trans_table_t *tbl, uint16_t mask)
659 __DECL_ALIGNED(16) uint16_vec8_t tmpd;
660 uint16_vec8_t* vt = (uint16_vec8_t*)__builtin_assume_aligned(&(tbl->plane_table[0]), sizeof(uint16_vec8_t));
662 __DECL_ALIGNED(16) uint16_vec8_t __masks;
664 __DECL_VECTORIZED_LOOP
665 for(int i = 0; i < 8; i++) {
668 uintptr_t disalign = (uintptr_t)dst;
669 disalign = disalign & 0x0f; //Is align by 128bits?
672 uint16_vec8_t *vdst = (uint16_vec8_t*)__builtin_assume_aligned(dst, sizeof(uint16_vec8_t));
673 __DECL_VECTORIZED_LOOP
674 for(int i = 0; i < bytes; i++) {
675 tmpd.v = vt[src[i]].v;
676 tmpd.v = tmpd.v & __masks.v;
681 // Sorry, not aligned.
682 __DECL_VECTORIZED_LOOP
683 for(int i = 0; i < bytes; i++) {
684 tmpd.v = vt[src[i]].v;
685 tmpd.v = tmpd.v & __masks.v;
686 __DECL_VECTORIZED_LOOP
687 for(int j = 0; j < 8; j++) {
695 // Convert uint8_t[] ed VRAM to uint8_t[] mono pixel pattern.
696 // You must set table to "ON_VALUE" : "OFF_VALUE" via PrepareBitTransTableUint16().
698 void DLL_PREFIX ConvertByteToSparceUint8(uint8_t *src, uint16_t* dst, int bytes, _bit_trans_table_t *tbl, uint16_t mask)
701 __DECL_ALIGNED(16) uint16_vec8_t tmpd;
702 uint16_vec8_t* vt = (uint16_vec8_t*)__builtin_assume_aligned(&(tbl->plane_table[0]), sizeof(uint16_vec8_t));
704 __DECL_ALIGNED(16) uint16_vec8_t __masks;
705 __DECL_ALIGNED(16) uint8_vec8_t tmpdd;
707 __DECL_VECTORIZED_LOOP
708 for(int i = 0; i < 8; i++) {
711 uintptr_t disalign = (uintptr_t)dst;
712 disalign = disalign & 0x07; //Is align by 128bits?
715 uint8_vec8_t *vdst = (uint8_vec8_t*)__builtin_assume_aligned(dst, sizeof(uint8_vec8_t));
716 __DECL_VECTORIZED_LOOP
717 for(int i = 0; i < bytes; i++) {
718 tmpd.v = vt[src[i]].v;
719 tmpd.v = tmpd.v & __masks.v;
720 __DECL_VECTORIZED_LOOP
721 for(int j = 0; j < 8; j++) {
722 tmpdd.w[j] = (uint8_t)(tmpd.w[j]);
728 // Sorry, not aligned.
729 __DECL_VECTORIZED_LOOP
730 for(int i = 0; i < bytes; i++) {
731 tmpd.v = vt[src[i]].v;
732 tmpd.v = tmpd.v & __masks.v;
733 __DECL_VECTORIZED_LOOP
734 for(int j = 0; j < 8; j++) {
735 dst[j] = (uint8_t)(tmpd.w[j]);
743 void DLL_PREFIX ConvertByteToPackedPixelByColorTable(uint8_t *src, scrntype_t* dst, int bytes, _bit_trans_table_t *tbl, scrntype_t *on_color_table, scrntype_t* off_color_table)
746 __DECL_ALIGNED(16) uint16_vec8_t tmpd;
747 __DECL_ALIGNED(32) scrntype_vec8_t tmpdd;
748 uint16_vec8_t* vt = (uint16_vec8_t*)__builtin_assume_aligned(&(tbl->plane_table[0]), sizeof(uint16_vec8_t));
750 uintptr_t disalign = (uintptr_t)dst;
751 disalign = disalign & 0x0f; //Is align by 128bits?
754 scrntype_vec8_t *vdst = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
755 __DECL_VECTORIZED_LOOP
756 for(int i = 0; i < bytes; i++) {
757 tmpd.v = vt[src[i]].v;
758 __DECL_VECTORIZED_LOOP
759 for(int j = 0; j < 8; j++) {
760 tmpdd.w[j] = (tmpd.w[j] == 0) ? off_color_table[j] : on_color_table[j];
763 off_color_table += 8;
768 // Sorry, not aligned.
769 __DECL_VECTORIZED_LOOP
770 for(int i = 0; i < bytes; i++) {
771 tmpd.v = vt[src[i]].v;
772 __DECL_VECTORIZED_LOOP
773 for(int j = 0; j < 8; j++) {
774 dst[j] = (tmpd.w[j] == 0) ? off_color_table[j] : on_color_table[j];
776 off_color_table += 8;
784 void DLL_PREFIX Render8Colors_Line(_render_command_data_t *src, scrntype_t *dst, scrntype_t* dst2, bool scan_line)
786 if(src == NULL) return;
787 if(dst == NULL) return;
789 //__DECL_VECTORIZED_LOOP
790 // for(int i = 0; i < 3; i++) {
791 // if(src->bit_trans_table[i] == NULL) return;
792 // if(src->data[i] == NULL) return;
794 scrntype_t dummy_palette[8]; // fallback
795 scrntype_t *palette = src->palette;
797 uint16_vec8_t *vpb = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[0], sizeof(uint16_vec8_t));
798 uint16_vec8_t *vpr = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[1], sizeof(uint16_vec8_t));
799 uint16_vec8_t *vpg = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[2], sizeof(uint16_vec8_t));
802 __DECL_ALIGNED(16) uint32_t offset[4] = {0};
803 __DECL_ALIGNED(16) uint32_t beginaddr[4] = {0};
804 uint32_t mask = src->addrmask;
805 uint32_t offsetmask = src->addrmask2;
806 __DECL_VECTORIZED_LOOP
807 for(int i = 0; i < 3; i++) {
808 offset[i] = src->voffset[i];
810 if(palette == NULL) {
811 __DECL_VECTORIZED_LOOP
812 for(int i = 0; i < 8; i++) {
813 dummy_palette[i] = RGB_COLOR(((i & 2) << 5) | 0x1f,
814 ((i & 4) << 5) | 0x1f,
815 ((i & 1) << 5) | 0x1f);
817 palette = dummy_palette;
819 uint8_t *bp = &(src->data[0][src->baseaddress[0]]);
820 uint8_t *rp = &(src->data[1][src->baseaddress[1]]);
821 uint8_t *gp = &(src->data[2][src->baseaddress[2]]);
824 int shift = src->shift;
825 const bool is_render[3] = { src->is_render[0], src->is_render[1], src->is_render[2] };
826 __DECL_ALIGNED(16) uint16_vec8_t tmpd;
827 __DECL_ALIGNED(32) scrntype_vec8_t tmp_dd;
828 scrntype_vec8_t* vdp = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
833 __DECL_VECTORIZED_LOOP
834 for(uint32_t xx = 0; xx < src->render_width; xx++) {
835 b = (is_render[0]) ? bp[(offset[0] + n) & mask] : 0;
836 r = (is_render[1]) ? rp[(offset[1] + n) & mask] : 0;
837 g = (is_render[2]) ? gp[(offset[2] + n) & mask] : 0;
839 tmpd.v = tmpd.v | vpr[r].v;
840 tmpd.v = tmpd.v | vpg[g].v;
841 tmpd.v = tmpd.v >> shift;
842 n = (n + 1) & offsetmask;
843 __DECL_VECTORIZED_LOOP
844 for(int i = 0; i < 8; i++) {
845 tmp_dd.w[i] = palette[tmpd.w[i]];
847 vdp[xx].v = tmp_dd.v;
850 #if defined(_RGB555) || defined(_RGBA565)
851 static const int shift_factor = 2;
853 static const int shift_factor = 3;
855 __DECL_ALIGNED(32) scrntype_vec8_t sline;
856 scrntype_vec8_t* vdp2 = (scrntype_vec8_t*)__builtin_assume_aligned(dst2, sizeof(scrntype_vec8_t));
857 __DECL_VECTORIZED_LOOP
858 for(int i = 0; i < 8; i++) {
859 sline.w[i] = (scrntype_t)RGBA_COLOR(31, 31, 31, 255);
861 __DECL_VECTORIZED_LOOP
862 for(uint32_t xx = 0; xx < src->render_width; xx++) {
863 b = (is_render[0]) ? bp[(offset[0] + n) & mask] : 0;
864 r = (is_render[1]) ? rp[(offset[1] + n) & mask] : 0;
865 g = (is_render[2]) ? gp[(offset[2] + n) & mask] : 0;
867 tmpd.v = tmpd.v | vpr[r].v;
868 tmpd.v = tmpd.v | vpg[g].v;
869 tmpd.v = tmpd.v >> shift;
870 n = (n + 1) & offsetmask;
871 __DECL_VECTORIZED_LOOP
872 for(int i = 0; i < 8; i++) {
873 tmp_dd.w[i] = palette[tmpd.w[i]];
875 vdp[xx].v = tmp_dd.v;
877 tmp_dd.v = tmp_dd.v >> shift_factor;
878 tmp_dd.v = tmp_dd.v & sline.v;
880 vdp2[xx].v = tmp_dd.v;
885 void DLL_PREFIX Render16Colors_Line(_render_command_data_t *src, scrntype_t *dst, scrntype_t* dst2, bool scan_line)
887 if(src == NULL) return;
888 if(dst == NULL) return;
890 //__DECL_VECTORIZED_LOOP
891 // for(int i = 0; i < 3; i++) {
892 // if(src->bit_trans_table[i] == NULL) return;
893 // if(src->data[i] == NULL) return;
895 scrntype_t dummy_palette[16]; // fallback
896 scrntype_t *palette = src->palette;
898 uint16_vec8_t *vpb = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[0], sizeof(uint16_vec8_t));
899 uint16_vec8_t *vpr = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[1], sizeof(uint16_vec8_t));
900 uint16_vec8_t *vpg = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[2], sizeof(uint16_vec8_t));
901 uint16_vec8_t *vpn = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[3], sizeof(uint16_vec8_t));
904 __DECL_ALIGNED(16) uint32_t offset[4];
905 __DECL_ALIGNED(16) uint32_t beginaddr[4];
906 uint32_t mask = src->addrmask;
907 uint32_t offsetmask = src->addrmask2;
909 __DECL_VECTORIZED_LOOP
910 for(int i = 0; i < 4; i++) {
911 offset[i] = src->voffset[i];
913 if(palette == NULL) {
914 __DECL_VECTORIZED_LOOP
915 for(int i = 0; i < 16; i++) {
916 dummy_palette[i] = RGB_COLOR((((i & 2) + (i & 8)) << 4) | 0x0f,
917 (((i & 4) + (i & 8)) << 4) | 0x0f,
918 (((i & 1) + (i & 8)) << 4) | 0x0f);
920 palette = dummy_palette;
922 uint8_t *bp = &(src->data[0][src->baseaddress[0]]);
923 uint8_t *rp = &(src->data[1][src->baseaddress[1]]);
924 uint8_t *gp = &(src->data[2][src->baseaddress[2]]);
925 uint8_t *np = &(src->data[3][src->baseaddress[3]]);
928 int shift = src->shift;
929 const bool is_render[4] = { src->is_render[0], src->is_render[1], src->is_render[2], src->is_render[3] };
930 __DECL_ALIGNED(16) uint16_vec8_t tmpd;
931 __DECL_ALIGNED(32) scrntype_vec8_t tmp_dd;
932 scrntype_vec8_t* vdp = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
937 __DECL_VECTORIZED_LOOP
938 for(uint32_t xx = 0; xx < src->render_width; xx++) {
939 b = (is_render[0]) ? bp[(offset[0] + xn) & mask] : 0;
940 r = (is_render[1]) ? rp[(offset[1] + xn) & mask] : 0;
941 g = (is_render[2]) ? gp[(offset[2] + xn) & mask] : 0;
942 n = (is_render[3]) ? np[(offset[3] + xn) & mask] : 0;
944 tmpd.v = tmpd.v | vpr[r].v;
945 tmpd.v = tmpd.v | vpg[g].v;
946 tmpd.v = tmpd.v | vpn[n].v;
947 tmpd.v = tmpd.v >> shift;
948 xn = (xn + 1) & offsetmask;
949 __DECL_VECTORIZED_LOOP
950 for(int i = 0; i < 8; i++) {
951 tmp_dd.w[i] = palette[tmpd.w[i]];
953 vdp[xx].v = tmp_dd.v;
956 #if defined(_RGB555) || defined(_RGBA565)
957 static const int shift_factor = 2;
959 static const int shift_factor = 3;
961 __DECL_ALIGNED(32) scrntype_vec8_t sline;
962 scrntype_vec8_t* vdp2 = (scrntype_vec8_t*)__builtin_assume_aligned(dst2, sizeof(scrntype_vec8_t));
963 __DECL_VECTORIZED_LOOP
964 for(int i = 0; i < 8; i++) {
965 sline.w[i] = (scrntype_t)RGBA_COLOR(31, 31, 31, 255);
967 __DECL_VECTORIZED_LOOP
968 for(uint32_t xx = 0; xx < src->render_width; xx++) {
969 b = (is_render[0]) ? bp[(offset[0] + xn) & mask] : 0;
970 r = (is_render[1]) ? rp[(offset[1] + xn) & mask] : 0;
971 g = (is_render[2]) ? gp[(offset[2] + xn) & mask] : 0;
972 n = (is_render[3]) ? np[(offset[3] + xn) & mask] : 0;
974 tmpd.v = tmpd.v | vpr[r].v;
975 tmpd.v = tmpd.v | vpg[g].v;
976 tmpd.v = tmpd.v | vpn[n].v;
977 tmpd.v = tmpd.v >> shift;
978 xn = (xn + 1) & offsetmask;
979 __DECL_VECTORIZED_LOOP
980 for(int i = 0; i < 8; i++) {
981 tmp_dd.w[i] = palette[tmpd.w[i]];
983 vdp[xx].v = tmp_dd.v;
985 tmp_dd.v = tmp_dd.v >> shift_factor;
986 tmp_dd.v = tmp_dd.v & sline.v;
988 vdp2[xx].v = tmp_dd.v;
993 // src->palette Must be 2^planes entries.
994 void DLL_PREFIX Render2NColors_Line(_render_command_data_t *src, scrntype_t *dst, scrntype_t* dst2, bool scan_line, int planes)
996 if(src == NULL) return;
997 if(dst == NULL) return;
998 if(src->palette == NULL) return;
999 if(planes <= 0) return;
1000 if(planes >= 16) planes = 16;
1001 //__DECL_VECTORIZED_LOOP
1002 // for(int i = 0; i < 3; i++) {
1003 // if(src->bit_trans_table[i] == NULL) return;
1004 // if(src->data[i] == NULL) return;
1006 scrntype_t *palette = src->palette;
1008 uint16_vec8_t* vp[16];
1009 for(int i = 0; i < planes; i++) {
1010 vp[i] = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[i], sizeof(uint16_vec8_t));
1014 __DECL_ALIGNED(16) uint32_t offset[16];
1015 __DECL_ALIGNED(16) uint32_t beginaddr[16];
1016 uint32_t mask = src->addrmask;
1017 uint32_t offsetmask = src->addrmask2;
1018 __DECL_VECTORIZED_LOOP
1019 for(int i = 0; i < planes; i++) {
1020 offset[i] = src->voffset[i];
1023 for(int i = 0; i < planes; i++) {
1024 pp[i] = &(src->data[i][src->baseaddress[i]]);
1028 int shift = src->shift;
1029 const bool is_render[4] = { src->is_render[0], src->is_render[1], src->is_render[2], src->is_render[3] };
1030 __DECL_ALIGNED(16) uint16_vec8_t tmpd;
1031 __DECL_ALIGNED(32) scrntype_vec8_t tmp_dd;
1032 scrntype_vec8_t* vdp = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
1037 __DECL_VECTORIZED_LOOP
1038 for(uint32_t xx = 0; xx < src->render_width; xx++) {
1039 d[0] = (is_render[0]) ? pp[0][(offset[0] + n) & mask] : 0;
1040 tmpd.v = vp[0][d[0]].v;
1041 __DECL_VECTORIZED_LOOP
1042 for(int i = 1; i < planes; i++) {
1043 d[i] = (is_render[i]) ? pp[i][(offset[i] + n) & mask] : 0;
1044 tmpd.v = tmpd.v | vp[i][d[i]].v;
1046 n = (n + 1) & offsetmask;
1047 tmpd.v = tmpd.v >> shift;
1048 __DECL_VECTORIZED_LOOP
1049 for(int i = 0; i < 8; i++) {
1050 tmp_dd.w[i] = palette[tmpd.w[i]];
1052 vdp[xx].v = tmp_dd.v;
1055 #if defined(_RGB555) || defined(_RGBA565)
1056 static const int shift_factor = 2;
1058 static const int shift_factor = 3;
1060 __DECL_ALIGNED(32) scrntype_vec8_t sline;
1061 scrntype_vec8_t* vdp2 = (scrntype_vec8_t*)__builtin_assume_aligned(dst2, sizeof(scrntype_vec8_t));
1062 __DECL_VECTORIZED_LOOP
1063 for(int i = 0; i < 8; i++) {
1064 sline.w[i] = (scrntype_t)RGBA_COLOR(31, 31, 31, 255);
1067 __DECL_VECTORIZED_LOOP
1068 for(uint32_t xx = 0; xx < src->render_width; xx++) {
1069 d[0] = (is_render[0]) ? pp[0][(offset[0] + n) & mask] : 0;
1070 tmpd.v = vp[0][d[0]].v;
1071 __DECL_VECTORIZED_LOOP
1072 for(int i = 1; i < planes; i++) {
1073 d[i] = (is_render[i]) ? pp[i][(offset[i] + n) & mask] : 0;
1074 tmpd.v = tmpd.v | vp[i][d[i]].v;
1076 n = (n + 1) & offsetmask;
1077 tmpd.v = tmpd.v >> shift;
1078 __DECL_VECTORIZED_LOOP
1079 for(int i = 0; i < 8; i++) {
1080 tmp_dd.w[i] = palette[tmpd.w[i]];
1082 vdp[xx].v = tmp_dd.v;
1084 tmp_dd.v = tmp_dd.v >> shift_factor;
1085 tmp_dd.v = tmp_dd.v & sline.v;
1087 vdp2[xx].v = tmp_dd.v;
1092 void DLL_PREFIX Convert2NColorsToByte_Line(_render_command_data_t *src, uint8_t *dst, int planes)
1094 if(planes >= 8) planes = 8;
1095 if(planes <= 0) return;
1098 __DECL_ALIGNED(32) uint32_t offset[8] = {0};
1099 __DECL_ALIGNED(16) uint16_vec8_t dat;
1100 uint16_vec8_t* bp[8] ;
1102 __DECL_VECTORIZED_LOOP
1103 for(int i = 0; i < planes; i++) {
1104 bp[i] = (uint16_vec8_t*)__builtin_assume_aligned(&(src->bit_trans_table[i]->plane_table[0]), sizeof(uint16_vec8_t));
1105 srcp[i] = &(src->data[i][src->baseaddress[i]]);
1107 uint32_t addrmask = src->addrmask;
1108 uint32_t offsetmask = src->addrmask2;
1109 int shift = src->shift;
1111 __DECL_VECTORIZED_LOOP
1112 for(int i = 0; i < planes; i++) {
1113 offset[i] = src->voffset[i];
1116 uint32_t noffset = src->begin_pos & offsetmask;
1118 __DECL_VECTORIZED_LOOP
1119 for(int x = 0; x < src->render_width; x++) {
1120 __DECL_VECTORIZED_LOOP
1121 for(int i = 0; i < planes; i++) {
1122 td[i] = srcp[i][(noffset + offset[i]) & addrmask];
1124 noffset = (noffset + 1) & offsetmask;
1125 dat.v = bp[0][td[0]].v;
1126 __DECL_VECTORIZED_LOOP
1127 for(int i = 1; i < planes; i++) {
1128 dat.v = dat.v | bp[i][td[i]].v;
1130 dat.v = dat.v >> shift;
1131 __DECL_VECTORIZED_LOOP
1132 for(int i = 0; i < 8; i++) {
1133 dst[i] = (uint8_t)(dat.w[i]);
1140 void DLL_PREFIX Convert2NColorsToByte_LineZoom2(_render_command_data_t *src, uint8_t *dst, int planes)
1142 if(planes >= 8) planes = 8;
1143 if(planes <= 0) return;
1146 __DECL_ALIGNED(32) uint32_t offset[8] = {0};
1147 __DECL_ALIGNED(16) uint16_vec8_t dat;
1148 uint16_vec8_t* bp[8] ;
1150 __DECL_VECTORIZED_LOOP
1151 for(int i = 0; i < planes; i++) {
1152 bp[i] = (uint16_vec8_t*)__builtin_assume_aligned(&(src->bit_trans_table[i]->plane_table[0]), sizeof(uint16_vec8_t));
1153 srcp[i] = &(src->data[i][src->baseaddress[i]]);
1155 uint32_t addrmask = src->addrmask;
1156 uint32_t offsetmask = src->addrmask2;
1157 int shift = src->shift;
1159 __DECL_VECTORIZED_LOOP
1160 for(int i = 0; i < planes; i++) {
1161 offset[i] = src->voffset[i];
1164 uint32_t noffset = src->begin_pos & offsetmask;
1166 __DECL_VECTORIZED_LOOP
1167 for(int x = 0; x < src->render_width; x++) {
1168 __DECL_VECTORIZED_LOOP
1169 for(int i = 0; i < planes; i++) {
1170 td[i] = srcp[i][(noffset + offset[i]) & addrmask];
1172 noffset = (noffset + 1) & offsetmask;
1173 dat.v = bp[0][td[0]].v;
1174 __DECL_VECTORIZED_LOOP
1175 for(int i = 1; i < planes; i++) {
1176 dat.v = dat.v | bp[i][td[i]].v;
1178 dat.v = dat.v >> shift;
1179 __DECL_VECTORIZED_LOOP
1180 for(int i = 0, j = 0; i < 16; i +=2, j++) {
1181 dst[i] = (uint8_t)(dat.w[j]);
1182 dst[i + 1] = (uint8_t)(dat.w[j]);
1188 void DLL_PREFIX Convert8ColorsToByte_Line(_render_command_data_t *src, uint8_t *dst)
1190 uint8_t *bp = &(src->data[0][src->baseaddress[0]]);
1191 uint8_t *rp = &(src->data[1][src->baseaddress[1]]);
1192 uint8_t *gp = &(src->data[2][src->baseaddress[2]]);
1193 __DECL_ALIGNED(16) uint32_t offset[4] = {0};
1195 __DECL_ALIGNED(16) uint16_vec8_t rdat;
1196 __DECL_ALIGNED(16) uint16_vec8_t gdat;
1197 __DECL_ALIGNED(16) uint16_vec8_t bdat;
1198 __DECL_ALIGNED(16) uint16_vec8_t tmpd;
1200 uint16_vec8_t* bpb = (uint16_vec8_t*)__builtin_assume_aligned(&(src->bit_trans_table[0]->plane_table[0]), sizeof(uint16_vec8_t));
1201 uint16_vec8_t* bpr = (uint16_vec8_t*)__builtin_assume_aligned(&(src->bit_trans_table[1]->plane_table[0]), sizeof(uint16_vec8_t));
1202 uint16_vec8_t* bpg = (uint16_vec8_t*)__builtin_assume_aligned(&(src->bit_trans_table[2]->plane_table[0]), sizeof(uint16_vec8_t));
1204 uint32_t addrmask = src->addrmask;
1205 uint32_t offsetmask = src->addrmask2;
1206 int shift = src->shift;
1208 __DECL_VECTORIZED_LOOP
1209 for(int i = 0; i < 3; i++) {
1210 offset[i] = src->voffset[i];
1213 uint32_t noffset = src->begin_pos & offsetmask;
1215 __DECL_VECTORIZED_LOOP
1216 for(int x = 0; x < src->render_width; x++) {
1217 b = bp[(noffset + offset[0]) & addrmask];
1218 r = rp[(noffset + offset[1]) & addrmask];
1219 g = gp[(noffset + offset[2]) & addrmask];
1221 noffset = (noffset + 1) & offsetmask;
1227 tmpd.v = tmpd.v | rdat.v;
1228 tmpd.v = tmpd.v | gdat.v;
1229 tmpd.v = tmpd.v >> shift;
1231 __DECL_VECTORIZED_LOOP
1232 for(int i = 0; i < 8; i++) {
1233 dst[i] = (uint8_t)(tmpd.w[i]);
1241 struct to_upper { // Refer from documentation of libstdc++, GCC5.
1242 char operator() (char c) const { return std::toupper(c); }
1246 #if defined(_USE_QT)
1247 static void _my_mkdir(std::string t_dir)
1250 //#if !defined(__WIN32) && !defined(__WIN64)
1251 // if(fstatat(AT_FDCWD, csppath.c_str(), &st, 0) != 0) {
1252 // mkdirat(AT_FDCWD, t_dir.c_str(), 0700); // Not found
1254 #if defined(_USE_QT)
1255 if(stat(t_dir.c_str(), &st) != 0) {
1256 QDir dir = QDir::current();
1257 dir.mkdir(QString::fromStdString(t_dir));
1258 //dir.mkpath(QString::fromUtf8(app_path));
1261 if(stat(csppath.c_str(), &st) != 0) {
1262 _mkdir(t_dir.c_str()); // Not found
1268 const _TCHAR *DLL_PREFIX get_application_path()
1270 static _TCHAR app_path[_MAX_PATH];
1271 static bool initialized = false;
1274 #if defined(_WIN32) && !defined(_USE_QT)
1275 _TCHAR tmp_path[_MAX_PATH], *ptr = NULL;
1276 if(GetModuleFileName(NULL, tmp_path, _MAX_PATH) != 0 && GetFullPathName(tmp_path, _MAX_PATH, app_path, &ptr) != 0 && ptr != NULL) {
1279 my_tcscpy_s(app_path, _MAX_PATH, _T(".\\"));
1282 #if defined(Q_OS_WIN)
1283 std::string delim = "\\";
1285 std::string delim = "/";
1287 std::string csppath = cpp_homedir + "CommonSourceCodeProject" + delim ;
1290 std::string cpath = csppath + my_procname + delim;
1292 strncpy(app_path, cpath.c_str(), _MAX_PATH - 1);
1296 return (const _TCHAR *)app_path;
1299 const _TCHAR *DLL_PREFIX get_initial_current_path()
1301 static _TCHAR current_path[_MAX_PATH];
1302 static bool initialized = false;
1305 #if defined(_WIN32) && !defined(_USE_QT)
1306 GetCurrentDirectoryA(_MAX_PATH, current_path);
1308 getcwd(current_path, _MAX_PATH);
1310 int len = strlen(current_path);
1311 if(current_path[len - 1] != '\\' && current_path[len - 1] != '/') {
1312 #if defined(_WIN32) || defined(Q_OS_WIN)
1313 current_path[len] = '\\';
1315 current_path[len] = '/';
1317 current_path[len + 1] = '\0';
1322 return (const _TCHAR *)current_path;
1325 const _TCHAR *DLL_PREFIX create_local_path(const _TCHAR *format, ...)
1327 static _TCHAR file_path[8][_MAX_PATH];
1328 static unsigned int table_index = 0;
1329 unsigned int output_index = (table_index++) & 7;
1330 _TCHAR file_name[_MAX_PATH];
1331 //printf("%d %d\n", table_index, output_index);
1334 va_start(ap, format);
1335 my_vstprintf_s(file_name, _MAX_PATH, format, ap);
1337 my_stprintf_s(file_path[output_index], _MAX_PATH, _T("%s%s"), get_application_path(), file_name);
1338 return (const _TCHAR *)file_path[output_index];
1341 void DLL_PREFIX create_local_path(_TCHAR *file_path, int length, const _TCHAR *format, ...)
1343 _TCHAR file_name[_MAX_PATH];
1346 va_start(ap, format);
1347 my_vstprintf_s(file_name, _MAX_PATH, format, ap);
1349 my_stprintf_s(file_path, length, _T("%s%s"), get_application_path(), file_name);
1352 bool DLL_PREFIX is_absolute_path(const _TCHAR *file_path)
1355 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(':')) {
1359 return (_tcslen(file_path) > 1 && (file_path[0] == _T('/') || file_path[0] == _T('\\')));
1362 const _TCHAR *DLL_PREFIX create_date_file_path(const _TCHAR *extension)
1364 cur_time_t cur_time;
1366 get_host_time(&cur_time);
1367 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);
1370 void DLL_PREFIX create_date_file_path(_TCHAR *file_path, int length, const _TCHAR *extension)
1372 my_tcscpy_s(file_path, length, create_date_file_path(extension));
1375 const _TCHAR *DLL_PREFIX create_date_file_name(const _TCHAR *extension)
1377 static _TCHAR file_name[8][_MAX_PATH];
1378 static unsigned int table_index = 0;
1379 unsigned int output_index = (table_index++) & 7;
1380 cur_time_t cur_time;
1382 get_host_time(&cur_time);
1383 my_stprintf_s(file_name[output_index], _MAX_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);
1384 return (const _TCHAR *)file_name[output_index];
1387 void DLL_PREFIX create_date_file_name(_TCHAR *file_path, int length, const _TCHAR *extension)
1389 my_tcscpy_s(file_path, length, create_date_file_name(extension));
1392 bool DLL_PREFIX check_file_extension(const _TCHAR *file_path, const _TCHAR *ext)
1394 #if defined(_USE_QT)
1395 std::string s_fpath = file_path;
1396 std::string s_ext = ext;
1399 std::transform(s_fpath.begin(), s_fpath.end(), s_fpath.begin(), to_upper());
1400 std::transform(s_ext.begin(), s_ext.end(), s_ext.begin(), to_upper());
1401 if(s_fpath.length() < s_ext.length()) return false;
1402 pos = s_fpath.rfind(s_ext.c_str(), s_fpath.length());
1403 if((pos != (int)std::string::npos) && (pos >= ((int)s_fpath.length() - (int)s_ext.length()))) return true;
1406 int nam_len = _tcslen(file_path);
1407 int ext_len = _tcslen(ext);
1409 return (nam_len >= ext_len && _tcsncicmp(&file_path[nam_len - ext_len], ext, ext_len) == 0);
1413 const _TCHAR *DLL_PREFIX get_file_path_without_extensiton(const _TCHAR *file_path)
1415 static _TCHAR path[8][_MAX_PATH];
1416 static unsigned int table_index = 0;
1417 unsigned int output_index = (table_index++) & 7;
1419 my_tcscpy_s(path[output_index], _MAX_PATH, file_path);
1420 #if defined(_WIN32) && defined(_MSC_VER)
1421 PathRemoveExtension(path[output_index]);
1422 #elif defined(_USE_QT)
1424 delim = QString::fromUtf8(".");
1425 QString tmp_path = QString::fromUtf8(file_path);
1426 int n = tmp_path.lastIndexOf(delim);
1428 tmp_path = tmp_path.left(n);
1430 //printf("%s\n", tmp_path.toUtf8().constData());
1431 memset(path[output_index], 0x00, sizeof(_TCHAR) * _MAX_PATH);
1432 strncpy(path[output_index], tmp_path.toUtf8().constData(), _MAX_PATH - 1);
1435 return (const _TCHAR *)path[output_index];
1438 void DLL_PREFIX get_long_full_path_name(const _TCHAR* src, _TCHAR* dst, size_t dst_len)
1441 _TCHAR tmp[_MAX_PATH];
1442 if(GetFullPathName(src, _MAX_PATH, tmp, NULL) == 0) {
1443 my_tcscpy_s(dst, dst_len, src);
1444 } else if(GetLongPathName(tmp, dst, _MAX_PATH) == 0) {
1445 my_tcscpy_s(dst, dst_len, tmp);
1447 #elif defined(_USE_QT)
1448 QString tmp_path = QString::fromUtf8(src);
1449 QFileInfo info(tmp_path);
1450 my_tcscpy_s(dst, dst_len, info.absoluteFilePath().toLocal8Bit().constData());
1452 // write code for your environment
1457 const _TCHAR *DLL_PREFIX get_parent_dir(const _TCHAR* file)
1459 static _TCHAR path[8][_MAX_PATH];
1460 static unsigned int table_index = 0;
1461 unsigned int output_index = (table_index++) & 7;
1465 GetFullPathName(file, _MAX_PATH, path[output_index], &ptr);
1469 #elif defined(_USE_QT)
1471 #if defined(Q_OS_WIN)
1472 delim = QString::fromUtf8("\\");
1474 delim = QString::fromUtf8("/");
1476 QString tmp_path = QString::fromUtf8(file);
1477 int n = tmp_path.lastIndexOf(delim);
1479 tmp_path = tmp_path.left(n);
1480 tmp_path.append(delim);
1482 //printf("%s\n", tmp_path.toUtf8().constData());
1483 memset(path[output_index], 0x00, sizeof(_TCHAR) * _MAX_PATH);
1484 strncpy(path[output_index], tmp_path.toUtf8().constData(), _MAX_PATH - 1);
1486 // write code for your environment
1488 return path[output_index];
1491 const wchar_t *DLL_PREFIX char_to_wchar(const char *cs)
1494 static wchar_t ws[4096];
1496 #if defined(_WIN32) || defined(_USE_QT)
1497 mbstowcs(ws, cs, strlen(cs));
1499 // write code for your environment
1504 const char *DLL_PREFIX wchar_to_char(const wchar_t *ws)
1507 static char cs[4096];
1510 wcstombs(cs, ws, wcslen(ws));
1511 #elif defined(_USE_QT)
1512 wcstombs(cs, ws, wcslen(ws));
1514 // write code for your environment
1519 const _TCHAR *DLL_PREFIX char_to_tchar(const char *cs)
1521 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1523 return char_to_wchar(cs);
1530 const char *DLL_PREFIX tchar_to_char(const _TCHAR *ts)
1532 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1534 return wchar_to_char(ts);
1541 const _TCHAR *DLL_PREFIX wchar_to_tchar(const wchar_t *ws)
1543 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1544 // wchar_t to wchar_t
1548 return wchar_to_char(ws);
1552 const wchar_t *DLL_PREFIX tchar_to_wchar(const _TCHAR *ts)
1554 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1555 // wchar_t to wchar_t
1559 return char_to_wchar(ts);
1563 const _TCHAR *DLL_PREFIX create_string(const _TCHAR* format, ...)
1565 static _TCHAR buffer[8][1024];
1566 static unsigned int table_index = 0;
1567 unsigned int output_index = (table_index++) & 7;
1570 va_start(ap, format);
1571 my_vstprintf_s(buffer[output_index], 1024, format, ap);
1573 return (const _TCHAR *)buffer[output_index];
1576 int32_t DLL_PREFIX muldiv_s32(int32_t nNumber, int32_t nNumerator, int32_t nDenominator)
1580 tmp = (int64_t)nNumber;
1581 tmp *= (int64_t)nNumerator;
1582 tmp /= (int64_t)nDenominator;
1583 return (int32_t)tmp;
1586 tmp = (double)nNumber;
1587 tmp *= (double)nNumerator;
1588 tmp /= (double)nDenominator;
1590 return (int32_t)(tmp - 0.5);
1592 return (int32_t)(tmp + 0.5);
1597 uint32_t DLL_PREFIX muldiv_u32(uint32_t nNumber, uint32_t nNumerator, uint32_t nDenominator)
1601 tmp = (uint64_t)nNumber;
1602 tmp *= (uint64_t)nNumerator;
1603 tmp /= (uint64_t)nDenominator;
1604 return (uint32_t)tmp;
1607 tmp = (double)nNumber;
1608 tmp *= (double)nNumerator;
1609 tmp /= (double)nDenominator;
1610 return (uint32_t)(tmp + 0.5);
1614 static bool _crc_initialized = false;
1615 static uint32_t _crc_table[256] = {0};
1616 static void init_crc32_table(void)
1618 for(int i = 0; i < 256; i++) {
1620 for(int j = 0; j < 8; j++) {
1622 c = (c >> 1) ^ 0xedb88320;
1629 _crc_initialized = true;
1632 uint32_t DLL_PREFIX get_crc32(uint8_t data[], int size)
1634 const uint32_t *table = (const uint32_t *)_crc_table;
1635 if(!_crc_initialized) {
1640 for(int i = 0; i < size; i++) {
1641 c = table[(c ^ data[i]) & 0xff] ^ (c >> 8);
1646 uint32_t DLL_PREFIX calc_crc32(uint32_t seed, uint8_t data[], int size)
1649 if(!_crc_initialized) {
1652 const uint32_t *table = (const uint32_t *)_crc_table;
1655 for(int i = 0; i < size; i++) {
1656 c = table[(c ^ data[i]) & 0xff] ^ (c >> 8);
1661 // Refer to : https://qiita.com/mikecat_mixc/items/e5d236e3a3803ef7d3c5
1662 static const uint32_t CRC_MAGIC_WORD = 0x04C11DB7;
1663 uint32_t crc = seed;
1664 uint8_t *ptr = data;
1668 for(int i = 0; i < bytes; i++) {
1670 for(int bit = 0; bit < 8; bit++) {
1671 is_overflow = ((crc & 0x1) != 0);
1673 if((d & 0x01) != 0) crc = crc | 0x80000000;
1674 if(is_overflow) crc = crc ^ ((uint32_t)~CRC_MAGIC_WORD);
1682 uint16_t DLL_PREFIX jis_to_sjis(uint16_t jis)
1686 tmp.w.l = jis - 0x2121;
1687 if(tmp.w.l & 0x100) {
1692 if(tmp.b.l > 0x7f) {
1695 tmp.b.h = (tmp.b.h >> 1) + 0x81;
1696 if(tmp.w.l >= 0xa000) {
1702 int DLL_PREFIX decibel_to_volume(int decibel)
1704 // +1 equals +0.5dB (same as fmgen)
1705 return (int)(1024.0 * pow(10.0, decibel / 40.0) + 0.5);
1708 int32_t DLL_PREFIX apply_volume(int32_t sample, int volume)
1722 // if(output > 2147483647) {
1723 // return 2147483647;
1724 // } else if(output < (-2147483647 - 1)) {
1725 // return (-2147483647 - 1);
1727 // return (int32_t)output;
1732 void DLL_PREFIX get_host_time(cur_time_t* cur_time)
1736 GetLocalTime(&sTime);
1737 cur_time->year = sTime.wYear;
1738 cur_time->month = sTime.wMonth;
1739 cur_time->day = sTime.wDay;
1740 cur_time->day_of_week = sTime.wDayOfWeek;
1741 cur_time->hour = sTime.wHour;
1742 cur_time->minute = sTime.wMinute;
1743 cur_time->second = sTime.wSecond;
1745 time_t timer = time(NULL);
1746 struct tm *local = localtime(&timer);
1747 cur_time->year = local->tm_year + 1900;
1748 cur_time->month = local->tm_mon + 1;
1749 cur_time->day = local->tm_mday;
1750 cur_time->day_of_week = local->tm_wday;
1751 cur_time->hour = local->tm_hour;
1752 cur_time->minute = local->tm_min;
1753 cur_time->second = local->tm_sec;
1759 void DLL_PREFIX cur_time_t::increment()
1761 if(++second >= 60) {
1763 if(++minute >= 60) {
1767 // days in this month
1770 days = LEAP_YEAR(year) ? 29 : 28;
1771 } else if(month == 4 || month == 6 || month == 9 || month == 11) {
1781 if(++day_of_week >= 7) {
1789 void DLL_PREFIX cur_time_t::update_year()
1794 } else if(year < 100) {
1799 void DLL_PREFIX cur_time_t::update_day_of_week()
1801 static const int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
1802 int y = year - (month < 3);
1803 day_of_week = (y + y / 4 - y / 100 + y / 400 + t[month - 1] + day) % 7;
1806 #define STATE_VERSION 1
1809 bool DLL_PREFIX cur_time_t::process_state(void *f, bool loading)
1811 FILEIO *state_fio = (FILEIO *)f;
1813 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1816 state_fio->StateValue(year);
1817 state_fio->StateValue(month);
1818 state_fio->StateValue(day);
1819 state_fio->StateValue(day_of_week);
1820 state_fio->StateValue(hour);
1821 state_fio->StateValue(minute);
1822 state_fio->StateValue(second);
1823 state_fio->StateValue(initialized);
1827 const _TCHAR *DLL_PREFIX get_symbol(symbol_t *first_symbol, uint32_t addr)
1829 static _TCHAR name[8][1024];
1830 static unsigned int table_index = 0;
1831 unsigned int output_index = (table_index++) & 7;
1833 if(first_symbol != NULL) {
1834 for(symbol_t* symbol = first_symbol; symbol; symbol = symbol->next_symbol) {
1835 if(symbol->addr == addr) {
1836 my_tcscpy_s(name[output_index], 1024, symbol->name);
1837 return name[output_index];
1844 const _TCHAR *DLL_PREFIX get_value_or_symbol(symbol_t *first_symbol, const _TCHAR *format, uint32_t addr)
1846 static _TCHAR name[8][1024];
1847 static unsigned int table_index = 0;
1848 unsigned int output_index = (table_index++) & 7;
1850 if(first_symbol != NULL) {
1851 for(symbol_t* symbol = first_symbol; symbol; symbol = symbol->next_symbol) {
1852 if(symbol->addr == addr) {
1853 my_tcscpy_s(name[output_index], 1024, symbol->name);
1854 return name[output_index];
1858 my_stprintf_s(name[output_index], 1024, format, addr);
1859 return name[output_index];
1862 const _TCHAR *DLL_PREFIX get_value_and_symbol(symbol_t *first_symbol, const _TCHAR *format, uint32_t addr)
1864 static _TCHAR name[8][1024];
1865 static unsigned int table_index = 0;
1866 unsigned int output_index = (table_index++) & 7;
1868 my_stprintf_s(name[output_index], 1024, format, addr);
1870 if(first_symbol != NULL) {
1871 for(symbol_t* symbol = first_symbol; symbol; symbol = symbol->next_symbol) {
1872 if(symbol->addr == addr) {
1874 // my_stprintf_s(temp, 1024, _T(" (%s)"), symbol->name);
1875 my_stprintf_s(temp, 1024, _T(";%s"), symbol->name);
1876 my_tcscat_s(name[output_index], 1024, temp);
1877 return name[output_index];
1881 return name[output_index];
1884 // Use this before writing wav_data.
1885 bool DLL_PREFIX write_dummy_wav_header(void *__fio)
1887 if(__fio == NULL) return false;
1889 FILEIO *fio = (FILEIO *)__fio;
1890 uint8_t dummy[sizeof(wav_header_t) + sizeof(wav_chunk_t)];
1892 if(!fio->IsOpened()) return false;
1894 memset(dummy, 0, sizeof(dummy));
1895 fio->Fwrite(dummy, sizeof(dummy), 1);
1898 // Use this after writing wav_data.
1899 bool DLL_PREFIX set_wav_header(wav_header_t *header, wav_chunk_t *first_chunk, uint16_t channels, uint32_t rate,
1900 uint16_t bits, size_t file_length)
1902 uint32_t length = (uint32_t) file_length;
1904 if(header == NULL) return false;
1905 if(first_chunk == NULL) return false;
1907 pair32_t __riff_chunk_size;
1908 pair32_t __fmt_chunk_size;
1909 pair32_t __wav_chunk_size;
1911 pair16_t __channels;
1912 pair32_t __sample_rate;
1913 pair32_t __data_speed;
1914 pair16_t __block_size;
1915 pair16_t __sample_bits;
1917 __riff_chunk_size.d = length - 8;
1918 __fmt_chunk_size.d = 16;
1920 __channels.u16 = channels;
1921 __sample_rate.d = rate;
1922 __block_size.u16 = (uint16_t)((channels * bits) / 8);
1923 __sample_bits.u16 = bits;
1924 __data_speed.d = rate * (uint32_t)(__block_size.u16);
1926 memcpy(&(header->riff_chunk.id), "RIFF", 4);
1927 header->riff_chunk.size = __riff_chunk_size.get_4bytes_le_to();
1929 memcpy(&(header->wave), "WAVE", 4);
1930 memcpy(&(header->fmt_chunk.id), "fmt ", 4);
1931 header->fmt_chunk.size = __fmt_chunk_size.get_4bytes_le_to();
1932 header->format_id = __fmt_id.get_2bytes_le_to();
1933 header->channels = __channels.get_2bytes_le_to();
1934 header->sample_rate = __sample_rate.get_4bytes_le_to();
1935 header->data_speed = __data_speed.get_4bytes_le_to();
1936 header->block_size = __block_size.get_2bytes_le_to();
1937 header->sample_bits = __sample_bits.get_2bytes_le_to();
1939 memcpy(&(first_chunk->id), "data", 4);
1940 __wav_chunk_size.d = length - sizeof(wav_header_t) - sizeof(wav_chunk_t);
1941 first_chunk->size = __wav_chunk_size.get_4bytes_le_to();
1945 // Note: buffers are allocated by this, You should free() within user class.
1946 bool DLL_PREFIX load_wav_to_stereo(void *__fio, int16_t **left_buf, int16_t **right_buf, uint32_t *rate, int *got_samples)
1949 if(__fio == NULL) return false;
1950 if(left_buf == NULL) return false;
1951 if(right_buf == NULL) return false;
1952 if(rate == NULL) return false;
1953 if(got_samples == NULL) return false;
1954 //if((bits != 8) && (bits != 16) && (bits != 32)) return false;
1956 FILEIO *fio = (FILEIO *)__fio;
1957 if(!fio->IsOpened()) return false;
1960 int16_t *left_buffer = NULL;
1961 int16_t *right_buffer = NULL;
1963 uint32_t sample_rate = 0;
1965 wav_header_t header;
1969 pair16_t __sample_bits;
1970 pair16_t __channels;
1971 pair32_t __sample_rate;
1972 pair32_t __chunk_size;
1974 fio->Fread(&header, sizeof(header), 1);
1975 __fmt_id.set_2bytes_le_from(header.format_id);
1976 __sample_bits.set_2bytes_le_from(header.sample_bits);
1977 __chunk_size.set_4bytes_le_from(header.fmt_chunk.size);
1978 __channels.set_2bytes_le_from(header.channels);
1979 __sample_rate.set_4bytes_le_from(header.sample_rate);
1981 if((__fmt_id.u16 == 1) && ((__sample_bits.u16 == 8) || (__sample_bits.u16 == 16) || (__sample_bits.u16 == 32))) {
1982 fio->Fseek(__chunk_size.d - 16, FILEIO_SEEK_CUR);
1983 bool is_eof = false;
1985 if(fio->Fread(&chunk, sizeof(chunk), 1) != 1) {
1989 __chunk_size.set_4bytes_le_from(chunk.size);
1990 if(strncmp(chunk.id, "data", 4) == 0) {
1993 fio->Fseek(__chunk_size.d, FILEIO_SEEK_CUR);
1995 __chunk_size.set_4bytes_le_from(chunk.size);
2002 samples = (size_t)(__chunk_size.d / __channels.u16);
2003 int16_t data_l, data_r;
2013 uint8_t l, h, h2, h3;
2018 if(__sample_bits.u16 == 16) {
2020 } else if(__sample_bits.u16 == 32) {
2023 if(samples == 0) return false;
2024 sample_rate = __sample_rate.d;
2026 left_buffer = (int16_t *)malloc(samples * sizeof(int16_t));
2027 right_buffer = (int16_t *)malloc(samples * sizeof(int16_t));
2028 if(left_buffer == NULL) {
2029 if(right_buffer != NULL) free(right_buffer);
2032 if(right_buffer == NULL) {
2033 if(left_buffer != NULL) free(left_buffer);
2036 switch(__sample_bits.u16) {
2038 if(__channels.s16 == 1) {
2039 for(int i = 0; i < samples; i++) {
2040 data_l = (int16_t)(fio->FgetUint8());
2041 data_l = (data_l - 128) * 256;
2042 left_buffer[i] = data_l;
2043 right_buffer[i] = data_l;
2045 } else if(__channels.s16 == 2) {
2046 for(int i = 0; i < samples; i++) {
2047 data_l = (int16_t)(fio->FgetUint8());
2048 data_l = (data_l - 128) * 256;
2049 data_r = (int16_t)(fio->FgetUint8());
2050 data_r = (data_r - 128) * 256;
2051 left_buffer[i] = data_l;
2052 right_buffer[i] = data_r;
2057 if(__channels.s16 == 1) {
2058 for(int i = 0; i < samples; i++) {
2059 pair16.b.l = fio->FgetUint8();
2060 pair16.b.h = fio->FgetUint8();
2061 data_l = pair16.s16;
2063 left_buffer[i] = data_l;
2064 right_buffer[i] = data_l;
2066 } else if(__channels.s16 == 2) {
2067 for(int i = 0; i < samples; i++) {
2068 pair16.b.l = fio->FgetUint8();
2069 pair16.b.h = fio->FgetUint8();
2070 data_l = pair16.s16;
2072 pair16.b.l = fio->FgetUint8();
2073 pair16.b.h = fio->FgetUint8();
2074 data_r = pair16.s16;
2075 left_buffer[i] = data_l;
2076 right_buffer[i] = data_r;
2081 if(__channels.s16 == 1) {
2082 for(int i = 0; i < samples; i++) {
2083 pair32.b.l = fio->FgetUint8();
2084 pair32.b.h = fio->FgetUint8();
2085 pair32.b.h2 = fio->FgetUint8();
2086 pair32.b.h3 = fio->FgetUint8();
2087 data_l = (int16_t)(pair32.s32 / 65536);
2089 left_buffer[i] = data_l;
2090 right_buffer[i] = data_l;
2092 } else if(__channels.s16 == 2) {
2093 for(int i = 0; i < samples; i++) {
2094 pair32.b.l = fio->FgetUint8();
2095 pair32.b.h = fio->FgetUint8();
2096 pair32.b.h2 = fio->FgetUint8();
2097 pair32.b.h3 = fio->FgetUint8();
2098 data_l = (int16_t)(pair32.s32 / 65536);
2100 pair32.b.l = fio->FgetUint8();
2101 pair32.b.h = fio->FgetUint8();
2102 pair32.b.h2 = fio->FgetUint8();
2103 pair32.b.h3 = fio->FgetUint8();
2104 data_r = (int16_t)(pair32.s32 / 65536);
2106 left_buffer[i] = data_l;
2107 right_buffer[i] = data_r;
2118 *left_buf = left_buffer;
2119 *right_buf = right_buffer;
2120 *rate = sample_rate;
2121 *got_samples = (int)samples;
2125 bool DLL_PREFIX load_wav_to_monoral(void *__fio, int16_t **buffer, uint32_t *rate, int *got_samples)
2128 if(__fio == NULL) return false;
2129 if(buffer == NULL) return false;
2130 if(rate == NULL) return false;
2131 if(got_samples == NULL) return false;
2132 //if((bits != 8) && (bits != 16) && (bits != 32)) return false;
2134 FILEIO *fio = (FILEIO *)__fio;
2135 if(!fio->IsOpened()) return false;
2138 int16_t *left_buffer = NULL;
2140 uint32_t sample_rate = 0;
2142 wav_header_t header;
2146 pair16_t __sample_bits;
2147 pair16_t __channels;
2148 pair32_t __sample_rate;
2149 pair32_t __chunk_size;
2151 fio->Fread(&header, sizeof(header), 1);
2152 __fmt_id.set_2bytes_le_from(header.format_id);
2153 __sample_bits.set_2bytes_le_from(header.sample_bits);
2154 __chunk_size.set_4bytes_le_from(header.fmt_chunk.size);
2155 __channels.set_2bytes_le_from(header.channels);
2156 __sample_rate.set_4bytes_le_from(header.sample_rate);
2158 if((__fmt_id.u16 == 1) && ((__sample_bits.u16 == 8) || (__sample_bits.u16 == 16) || (__sample_bits.u16 == 32))) {
2159 fio->Fseek(__chunk_size.d - 16, FILEIO_SEEK_CUR);
2160 bool is_eof = false;
2162 if(fio->Fread(&chunk, sizeof(chunk), 1) != 1) {
2166 __chunk_size.set_4bytes_le_from(chunk.size);
2167 if(strncmp(chunk.id, "data", 4) == 0) {
2170 fio->Fseek(__chunk_size.d, FILEIO_SEEK_CUR);
2172 __chunk_size.set_4bytes_le_from(chunk.size);
2179 samples = (size_t)(__chunk_size.d / __channels.u16);
2180 int16_t data_l, data_r;
2181 int32_t data32_l, data32_r;
2191 uint8_t l, h, h2, h3;
2196 if(__sample_bits.u16 == 16) {
2198 } else if(__sample_bits.u16 == 32) {
2201 if(samples == 0) return false;
2202 sample_rate = __sample_rate.d;
2204 left_buffer = (int16_t *)malloc(samples * sizeof(int16_t));
2205 if(left_buffer == NULL) {
2208 switch(__sample_bits.u16) {
2210 if(__channels.s16 == 1) {
2211 for(int i = 0; i < samples; i++) {
2212 data_l = (int16_t)(fio->FgetUint8());
2213 data_l = (data_l - 128) * 256;
2214 left_buffer[i] = data_l;
2216 } else if(__channels.s16 == 2) {
2217 for(int i = 0; i < samples; i++) {
2218 data_l = (int16_t)(fio->FgetUint8());
2219 data_l = (data_l - 128) * 256;
2220 data_r = (int16_t)(fio->FgetUint8());
2221 data_r = (data_r - 128) * 256;
2222 left_buffer[i] = (data_l + data_r) / 2;
2227 if(__channels.s16 == 1) {
2228 for(int i = 0; i < samples; i++) {
2229 pair16.b.l = fio->FgetUint8();
2230 pair16.b.h = fio->FgetUint8();
2231 data_l = pair16.s16;
2233 left_buffer[i] = data_l;
2235 } else if(__channels.s16 == 2) {
2236 for(int i = 0; i < samples; i++) {
2237 pair16.b.l = fio->FgetUint8();
2238 pair16.b.h = fio->FgetUint8();
2239 data_l = pair16.s16;
2241 pair16.b.l = fio->FgetUint8();
2242 pair16.b.h = fio->FgetUint8();
2243 data_r = pair16.s16;
2244 left_buffer[i] = (data_l + data_r) / 2;
2249 if(__channels.s16 == 1) {
2250 for(int i = 0; i < samples; i++) {
2251 pair32.b.l = fio->FgetUint8();
2252 pair32.b.h = fio->FgetUint8();
2253 pair32.b.h2 = fio->FgetUint8();
2254 pair32.b.h3 = fio->FgetUint8();
2255 data_l = (int16_t)(pair32.s32 / 65536);
2257 left_buffer[i] = data_l;
2259 } else if(__channels.s16 == 2) {
2260 for(int i = 0; i < samples; i++) {
2261 pair32.b.l = fio->FgetUint8();
2262 pair32.b.h = fio->FgetUint8();
2263 pair32.b.h2 = fio->FgetUint8();
2264 pair32.b.h3 = fio->FgetUint8();
2265 data32_l = pair32.s32 / 65536;
2267 pair32.b.l = fio->FgetUint8();
2268 pair32.b.h = fio->FgetUint8();
2269 pair32.b.h2 = fio->FgetUint8();
2270 pair32.b.h3 = fio->FgetUint8();
2271 data32_r = pair32.s32 / 65536;
2273 left_buffer[i] = (int16_t)((data32_l + data32_r) / 2);
2284 *buffer = left_buffer;
2285 *rate = sample_rate;
2286 *got_samples = (int)samples;
2290 DLL_PREFIX const _TCHAR *get_lib_common_version()
2292 #if defined(__LIBEMU_UTIL_VERSION)
2293 return (const _TCHAR *)__LIBEMU_UTIL_VERSION;
2295 return (const _TCHAR *)"\0";