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 __DECL_VECTORIZED_LOOP
541 for(uint16_t i = 0; i < 256; i++) {
543 __DECL_VECTORIZED_LOOP
544 for(int j = 0; j < 8; j++) {
545 tbl->plane_table[i].w[j] = ((n & 0x80) == 0) ? off_val : on_val;
551 // Note: table strongly recommend to be aligned by sizeof(scrntype_vec8_t).
552 // This is sizeof(uint16) * 8, some compilers may require to align 32bytes(256) or 16bytes(128)
553 // when using SIMD256 or SIMD128 -- 20181105 K.O
554 void DLL_PREFIX PrepareBitTransTableScrnType(_bit_trans_table_scrn_t *tbl, scrntype_t on_val, scrntype_t off_val)
556 if(tbl == NULL) return;
557 __DECL_VECTORIZED_LOOP
558 for(uint16_t i = 0; i < 256; i++) {
560 __DECL_VECTORIZED_LOOP
561 for(int j = 0; j < 8; j++) {
562 tbl->plane_table[i].w[j] = ((n & 0x80) == 0) ? off_val : on_val;
568 // Prepare reverse byte-order table(s).
569 void DLL_PREFIX PrepareReverseBitTransTableUint16(_bit_trans_table_t *tbl, uint16_t on_val, uint16_t off_val)
571 if(tbl == NULL) return;
572 __DECL_VECTORIZED_LOOP
573 for(uint16_t i = 0; i < 256; i++) {
575 __DECL_VECTORIZED_LOOP
576 for(int j = 0; j < 8; j++) {
577 tbl->plane_table[i].w[j] = ((n & 0x01) == 0) ? off_val : on_val;
583 void DLL_PREFIX PrepareReverseBitTransTableScrnType(_bit_trans_table_scrn_t *tbl, scrntype_t on_val, scrntype_t off_val)
585 if(tbl == NULL) return;
586 __DECL_VECTORIZED_LOOP
587 for(uint16_t i = 0; i < 256; i++) {
589 __DECL_VECTORIZED_LOOP
590 for(int j = 0; j < 8; j++) {
591 tbl->plane_table[i].w[j] = ((n & 0x01) == 0) ? off_val : on_val;
597 // With _bit_trans_table_scrn_t.
598 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)
601 scrntype_vec8_t tmpd;
602 scrntype_vec8_t tmpdd;
603 scrntype_vec8_t colors;
604 scrntype_vec8_t* vt = (scrntype_vec8_t*)__builtin_assume_aligned(&(tbl->plane_table[0]), sizeof(scrntype_vec8_t));
606 uintptr_t disalign = (uintptr_t)dst;
607 disalign = disalign & (sizeof(scrntype_vec8_t) - 1); //Is align by 128bits or 256bytes?
610 scrntype_vec8_t *vdst = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
611 __DECL_VECTORIZED_LOOP
612 for(int i = 0; i < bytes; i++) {
613 tmpd.v = vt[src[i]].v;
616 __DECL_VECTORIZED_LOOP
617 for(int j = 0; j < 8; j++) {
618 colors.w[j] = on_color_table[j];
620 tmpd.v = tmpd.v & colors.v;
621 __DECL_VECTORIZED_LOOP
622 for(int j = 0; j < 8; j++) {
623 colors.w[j] = off_color_table[j];
625 tmpdd.v = tmpdd.v & colors.v;
626 vdst->v = (tmpd.v | tmpdd.v);
627 off_color_table += 8;
632 // Sorry, not aligned.
633 __DECL_VECTORIZED_LOOP
634 for(int i = 0; i < bytes; i++) {
635 tmpd.v = vt[src[i]].v;
638 __DECL_VECTORIZED_LOOP
639 for(int j = 0; j < 8; j++) {
640 colors.w[j] = on_color_table[j];
642 tmpd.v = tmpd.v & colors.v;
643 __DECL_VECTORIZED_LOOP
644 for(int j = 0; j < 8; j++) {
645 colors.w[j] = off_color_table[j];
647 tmpdd.v = tmpdd.v & colors.v;
648 tmpdd.v = tmpdd.v | tmpd.v;
649 __DECL_VECTORIZED_LOOP
650 for(int j = 0; j < 8; j++) {
653 off_color_table += 8;
661 // Convert uint8_t[] ed VRAM to uint16_t[] mono pixel pattern.
662 // You must set table to "ON_VALUE" : "OFF_VALUE" via PrepareBitTransTableUint16().
664 void DLL_PREFIX ConvertByteToSparceUint16(uint8_t *src, uint16_t* dst, int bytes, _bit_trans_table_t *tbl, uint16_t mask)
668 uint16_vec8_t* vt = (uint16_vec8_t*)__builtin_assume_aligned(&(tbl->plane_table[0]), sizeof(uint16_vec8_t));
670 uint16_vec8_t __masks;
672 __DECL_VECTORIZED_LOOP
673 for(int i = 0; i < 8; i++) {
676 uintptr_t disalign = (uintptr_t)dst;
677 disalign = disalign & 0x0f; //Is align by 128bits?
680 uint16_vec8_t *vdst = (uint16_vec8_t*)__builtin_assume_aligned(dst, sizeof(uint16_vec8_t));
681 __DECL_VECTORIZED_LOOP
682 for(int i = 0; i < bytes; i++) {
683 tmpd.v = vt[src[i]].v;
684 tmpd.v = tmpd.v & __masks.v;
689 // Sorry, not aligned.
690 __DECL_VECTORIZED_LOOP
691 for(int i = 0; i < bytes; i++) {
692 tmpd.v = vt[src[i]].v;
693 tmpd.v = tmpd.v & __masks.v;
694 __DECL_VECTORIZED_LOOP
695 for(int j = 0; j < 8; j++) {
703 // Convert uint8_t[] ed VRAM to uint8_t[] mono pixel pattern.
704 // You must set table to "ON_VALUE" : "OFF_VALUE" via PrepareBitTransTableUint16().
706 void DLL_PREFIX ConvertByteToSparceUint8(uint8_t *src, uint16_t* dst, int bytes, _bit_trans_table_t *tbl, uint16_t mask)
710 uint16_vec8_t* vt = (uint16_vec8_t*)__builtin_assume_aligned(&(tbl->plane_table[0]), sizeof(uint16_vec8_t));
712 uint16_vec8_t __masks;
715 __DECL_VECTORIZED_LOOP
716 for(int i = 0; i < 8; i++) {
719 uintptr_t disalign = (uintptr_t)dst;
720 disalign = disalign & 0x07; //Is align by 128bits?
723 uint8_vec8_t *vdst = (uint8_vec8_t*)__builtin_assume_aligned(dst, sizeof(uint8_vec8_t));
724 __DECL_VECTORIZED_LOOP
725 for(int i = 0; i < bytes; i++) {
726 tmpd.v = vt[src[i]].v;
727 tmpd.v = tmpd.v & __masks.v;
728 __DECL_VECTORIZED_LOOP
729 for(int j = 0; j < 8; j++) {
730 tmpdd.w[j] = (uint8_t)(tmpd.w[j]);
736 // Sorry, not aligned.
737 __DECL_VECTORIZED_LOOP
738 for(int i = 0; i < bytes; i++) {
739 tmpd.v = vt[src[i]].v;
740 tmpd.v = tmpd.v & __masks.v;
741 __DECL_VECTORIZED_LOOP
742 for(int j = 0; j < 8; j++) {
743 dst[j] = (uint8_t)(tmpd.w[j]);
751 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)
755 scrntype_vec8_t tmpdd;
756 uint16_vec8_t* vt = (uint16_vec8_t*)__builtin_assume_aligned(&(tbl->plane_table[0]), sizeof(uint16_vec8_t));
758 uintptr_t disalign = (uintptr_t)dst;
759 disalign = disalign & 0x0f; //Is align by 128bits?
762 scrntype_vec8_t *vdst = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
763 __DECL_VECTORIZED_LOOP
764 for(int i = 0; i < bytes; i++) {
765 tmpd.v = vt[src[i]].v;
766 __DECL_VECTORIZED_LOOP
767 for(int j = 0; j < 8; j++) {
768 tmpdd.w[j] = (tmpd.w[j] == 0) ? off_color_table[j] : on_color_table[j];
771 off_color_table += 8;
776 // Sorry, not aligned.
777 __DECL_VECTORIZED_LOOP
778 for(int i = 0; i < bytes; i++) {
779 tmpd.v = vt[src[i]].v;
780 __DECL_VECTORIZED_LOOP
781 for(int j = 0; j < 8; j++) {
782 dst[j] = (tmpd.w[j] == 0) ? off_color_table[j] : on_color_table[j];
784 off_color_table += 8;
792 void DLL_PREFIX Render8Colors_Line(_render_command_data_t *src, scrntype_t *dst, scrntype_t* dst2, bool scan_line)
794 if(src == NULL) return;
795 if(dst == NULL) return;
797 //__DECL_VECTORIZED_LOOP
798 // for(int i = 0; i < 3; i++) {
799 // if(src->bit_trans_table[i] == NULL) return;
800 // if(src->data[i] == NULL) return;
802 scrntype_t dummy_palette[8]; // fallback
803 scrntype_t *palette = src->palette;
805 uint16_vec8_t *vpb = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[0], sizeof(uint16_vec8_t));
806 uint16_vec8_t *vpr = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[1], sizeof(uint16_vec8_t));
807 uint16_vec8_t *vpg = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[2], sizeof(uint16_vec8_t));
810 __DECL_ALIGNED(16) uint32_t offset[4] = {0};
811 __DECL_ALIGNED(16) uint32_t beginaddr[4] = {0};
812 uint32_t mask = src->addrmask;
813 uint32_t offsetmask = src->addrmask2;
814 __DECL_VECTORIZED_LOOP
815 for(int i = 0; i < 3; i++) {
816 offset[i] = src->voffset[i];
818 if(palette == NULL) {
819 __DECL_VECTORIZED_LOOP
820 for(int i = 0; i < 8; i++) {
821 dummy_palette[i] = RGB_COLOR(((i & 2) << 5) | 0x1f,
822 ((i & 4) << 5) | 0x1f,
823 ((i & 1) << 5) | 0x1f);
825 palette = dummy_palette;
827 uint8_t *bp = &(src->data[0][src->baseaddress[0]]);
828 uint8_t *rp = &(src->data[1][src->baseaddress[1]]);
829 uint8_t *gp = &(src->data[2][src->baseaddress[2]]);
832 int shift = src->shift;
833 const bool is_render[3] = { src->is_render[0], src->is_render[1], src->is_render[2] };
835 scrntype_vec8_t tmp_dd;
836 scrntype_vec8_t* vdp = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
841 __DECL_VECTORIZED_LOOP
842 for(uint32_t xx = 0; xx < src->render_width; xx++) {
843 b = (is_render[0]) ? bp[(offset[0] + n) & mask] : 0;
844 r = (is_render[1]) ? rp[(offset[1] + n) & mask] : 0;
845 g = (is_render[2]) ? gp[(offset[2] + n) & mask] : 0;
847 tmpd.v = tmpd.v | vpr[r].v;
848 tmpd.v = tmpd.v | vpg[g].v;
849 tmpd.v = tmpd.v >> shift;
850 n = (n + 1) & offsetmask;
851 __DECL_VECTORIZED_LOOP
852 for(int i = 0; i < 8; i++) {
853 tmp_dd.w[i] = palette[tmpd.w[i]];
855 vdp[xx].v = tmp_dd.v;
858 #if defined(_RGB555) || defined(_RGBA565)
859 static const int shift_factor = 2;
861 static const int shift_factor = 3;
863 scrntype_vec8_t sline;
864 scrntype_vec8_t* vdp2 = (scrntype_vec8_t*)__builtin_assume_aligned(dst2, sizeof(scrntype_vec8_t));
865 __DECL_VECTORIZED_LOOP
866 for(int i = 0; i < 8; i++) {
867 sline.w[i] = (scrntype_t)RGBA_COLOR(31, 31, 31, 255);
869 __DECL_VECTORIZED_LOOP
870 for(uint32_t xx = 0; xx < src->render_width; xx++) {
871 b = (is_render[0]) ? bp[(offset[0] + n) & mask] : 0;
872 r = (is_render[1]) ? rp[(offset[1] + n) & mask] : 0;
873 g = (is_render[2]) ? gp[(offset[2] + n) & mask] : 0;
875 tmpd.v = tmpd.v | vpr[r].v;
876 tmpd.v = tmpd.v | vpg[g].v;
877 tmpd.v = tmpd.v >> shift;
878 n = (n + 1) & offsetmask;
879 __DECL_VECTORIZED_LOOP
880 for(int i = 0; i < 8; i++) {
881 tmp_dd.w[i] = palette[tmpd.w[i]];
883 vdp[xx].v = tmp_dd.v;
885 tmp_dd.v = tmp_dd.v >> shift_factor;
886 tmp_dd.v = tmp_dd.v & sline.v;
888 vdp2[xx].v = tmp_dd.v;
893 void DLL_PREFIX Render16Colors_Line(_render_command_data_t *src, scrntype_t *dst, scrntype_t* dst2, bool scan_line)
895 if(src == NULL) return;
896 if(dst == NULL) return;
898 //__DECL_VECTORIZED_LOOP
899 // for(int i = 0; i < 3; i++) {
900 // if(src->bit_trans_table[i] == NULL) return;
901 // if(src->data[i] == NULL) return;
903 scrntype_t dummy_palette[16]; // fallback
904 scrntype_t *palette = src->palette;
906 uint16_vec8_t *vpb = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[0], sizeof(uint16_vec8_t));
907 uint16_vec8_t *vpr = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[1], sizeof(uint16_vec8_t));
908 uint16_vec8_t *vpg = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[2], sizeof(uint16_vec8_t));
909 uint16_vec8_t *vpn = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[3], sizeof(uint16_vec8_t));
912 __DECL_ALIGNED(16) uint32_t offset[4];
913 __DECL_ALIGNED(16) uint32_t beginaddr[4];
914 uint32_t mask = src->addrmask;
915 uint32_t offsetmask = src->addrmask2;
917 __DECL_VECTORIZED_LOOP
918 for(int i = 0; i < 4; i++) {
919 offset[i] = src->voffset[i];
921 if(palette == NULL) {
922 __DECL_VECTORIZED_LOOP
923 for(int i = 0; i < 16; i++) {
924 dummy_palette[i] = RGB_COLOR((((i & 2) + (i & 8)) << 4) | 0x0f,
925 (((i & 4) + (i & 8)) << 4) | 0x0f,
926 (((i & 1) + (i & 8)) << 4) | 0x0f);
928 palette = dummy_palette;
930 uint8_t *bp = &(src->data[0][src->baseaddress[0]]);
931 uint8_t *rp = &(src->data[1][src->baseaddress[1]]);
932 uint8_t *gp = &(src->data[2][src->baseaddress[2]]);
933 uint8_t *np = &(src->data[3][src->baseaddress[3]]);
936 int shift = src->shift;
937 const bool is_render[4] = { src->is_render[0], src->is_render[1], src->is_render[2], src->is_render[3] };
939 scrntype_vec8_t tmp_dd;
940 scrntype_vec8_t* vdp = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
945 __DECL_VECTORIZED_LOOP
946 for(uint32_t xx = 0; xx < src->render_width; xx++) {
947 b = (is_render[0]) ? bp[(offset[0] + xn) & mask] : 0;
948 r = (is_render[1]) ? rp[(offset[1] + xn) & mask] : 0;
949 g = (is_render[2]) ? gp[(offset[2] + xn) & mask] : 0;
950 n = (is_render[3]) ? np[(offset[3] + xn) & mask] : 0;
952 tmpd.v = tmpd.v | vpr[r].v;
953 tmpd.v = tmpd.v | vpg[g].v;
954 tmpd.v = tmpd.v | vpn[n].v;
955 tmpd.v = tmpd.v >> shift;
956 xn = (xn + 1) & offsetmask;
957 __DECL_VECTORIZED_LOOP
958 for(int i = 0; i < 8; i++) {
959 tmp_dd.w[i] = palette[tmpd.w[i]];
961 vdp[xx].v = tmp_dd.v;
964 #if defined(_RGB555) || defined(_RGBA565)
965 static const int shift_factor = 2;
967 static const int shift_factor = 3;
969 scrntype_vec8_t sline;
970 scrntype_vec8_t* vdp2 = (scrntype_vec8_t*)__builtin_assume_aligned(dst2, sizeof(scrntype_vec8_t));
971 __DECL_VECTORIZED_LOOP
972 for(int i = 0; i < 8; i++) {
973 sline.w[i] = (scrntype_t)RGBA_COLOR(31, 31, 31, 255);
975 __DECL_VECTORIZED_LOOP
976 for(uint32_t xx = 0; xx < src->render_width; xx++) {
977 b = (is_render[0]) ? bp[(offset[0] + xn) & mask] : 0;
978 r = (is_render[1]) ? rp[(offset[1] + xn) & mask] : 0;
979 g = (is_render[2]) ? gp[(offset[2] + xn) & mask] : 0;
980 n = (is_render[3]) ? np[(offset[3] + xn) & mask] : 0;
982 tmpd.v = tmpd.v | vpr[r].v;
983 tmpd.v = tmpd.v | vpg[g].v;
984 tmpd.v = tmpd.v | vpn[n].v;
985 tmpd.v = tmpd.v >> shift;
986 xn = (xn + 1) & offsetmask;
987 __DECL_VECTORIZED_LOOP
988 for(int i = 0; i < 8; i++) {
989 tmp_dd.w[i] = palette[tmpd.w[i]];
991 vdp[xx].v = tmp_dd.v;
993 tmp_dd.v = tmp_dd.v >> shift_factor;
994 tmp_dd.v = tmp_dd.v & sline.v;
996 vdp2[xx].v = tmp_dd.v;
1001 // src->palette Must be 2^planes entries.
1002 void DLL_PREFIX Render2NColors_Line(_render_command_data_t *src, scrntype_t *dst, scrntype_t* dst2, bool scan_line, int planes)
1004 if(src == NULL) return;
1005 if(dst == NULL) return;
1006 if(src->palette == NULL) return;
1007 if(planes <= 0) return;
1008 if(planes >= 16) planes = 16;
1009 //__DECL_VECTORIZED_LOOP
1010 // for(int i = 0; i < 3; i++) {
1011 // if(src->bit_trans_table[i] == NULL) return;
1012 // if(src->data[i] == NULL) return;
1014 scrntype_t *palette = src->palette;
1016 uint16_vec8_t* vp[16];
1017 for(int i = 0; i < planes; i++) {
1018 vp[i] = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[i], sizeof(uint16_vec8_t));
1022 __DECL_ALIGNED(16) uint32_t offset[16];
1023 __DECL_ALIGNED(16) uint32_t beginaddr[16];
1024 uint32_t mask = src->addrmask;
1025 uint32_t offsetmask = src->addrmask2;
1026 __DECL_VECTORIZED_LOOP
1027 for(int i = 0; i < planes; i++) {
1028 offset[i] = src->voffset[i];
1031 for(int i = 0; i < planes; i++) {
1032 pp[i] = &(src->data[i][src->baseaddress[i]]);
1036 int shift = src->shift;
1037 const bool is_render[4] = { src->is_render[0], src->is_render[1], src->is_render[2], src->is_render[3] };
1039 scrntype_vec8_t tmp_dd;
1040 scrntype_vec8_t* vdp = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
1045 __DECL_VECTORIZED_LOOP
1046 for(uint32_t xx = 0; xx < src->render_width; xx++) {
1047 d[0] = (is_render[0]) ? pp[0][(offset[0] + n) & mask] : 0;
1048 tmpd.v = vp[0][d[0]].v;
1049 __DECL_VECTORIZED_LOOP
1050 for(int i = 1; i < planes; i++) {
1051 d[i] = (is_render[i]) ? pp[i][(offset[i] + n) & mask] : 0;
1052 tmpd.v = tmpd.v | vp[i][d[i]].v;
1054 n = (n + 1) & offsetmask;
1055 tmpd.v = tmpd.v >> shift;
1056 __DECL_VECTORIZED_LOOP
1057 for(int i = 0; i < 8; i++) {
1058 tmp_dd.w[i] = palette[tmpd.w[i]];
1060 vdp[xx].v = tmp_dd.v;
1063 #if defined(_RGB555) || defined(_RGBA565)
1064 static const int shift_factor = 2;
1066 static const int shift_factor = 3;
1068 scrntype_vec8_t sline;
1069 scrntype_vec8_t* vdp2 = (scrntype_vec8_t*)__builtin_assume_aligned(dst2, sizeof(scrntype_vec8_t));
1070 __DECL_VECTORIZED_LOOP
1071 for(int i = 0; i < 8; i++) {
1072 sline.w[i] = (scrntype_t)RGBA_COLOR(31, 31, 31, 255);
1075 __DECL_VECTORIZED_LOOP
1076 for(uint32_t xx = 0; xx < src->render_width; xx++) {
1077 d[0] = (is_render[0]) ? pp[0][(offset[0] + n) & mask] : 0;
1078 tmpd.v = vp[0][d[0]].v;
1079 __DECL_VECTORIZED_LOOP
1080 for(int i = 1; i < planes; i++) {
1081 d[i] = (is_render[i]) ? pp[i][(offset[i] + n) & mask] : 0;
1082 tmpd.v = tmpd.v | vp[i][d[i]].v;
1084 n = (n + 1) & offsetmask;
1085 tmpd.v = tmpd.v >> shift;
1086 __DECL_VECTORIZED_LOOP
1087 for(int i = 0; i < 8; i++) {
1088 tmp_dd.w[i] = palette[tmpd.w[i]];
1090 vdp[xx].v = tmp_dd.v;
1092 tmp_dd.v = tmp_dd.v >> shift_factor;
1093 tmp_dd.v = tmp_dd.v & sline.v;
1095 vdp2[xx].v = tmp_dd.v;
1100 void DLL_PREFIX Convert2NColorsToByte_Line(_render_command_data_t *src, uint8_t *dst, int planes)
1102 if(planes >= 8) planes = 8;
1103 if(planes <= 0) return;
1106 __DECL_ALIGNED(32) uint32_t offset[8] = {0};
1108 uint16_vec8_t* bp[8] ;
1110 __DECL_VECTORIZED_LOOP
1111 for(int i = 0; i < planes; i++) {
1112 bp[i] = (uint16_vec8_t*)__builtin_assume_aligned(&(src->bit_trans_table[i]->plane_table[0]), sizeof(uint16_vec8_t));
1113 srcp[i] = &(src->data[i][src->baseaddress[i]]);
1115 uint32_t addrmask = src->addrmask;
1116 uint32_t offsetmask = src->addrmask2;
1117 int shift = src->shift;
1119 __DECL_VECTORIZED_LOOP
1120 for(int i = 0; i < planes; i++) {
1121 offset[i] = src->voffset[i];
1124 uint32_t noffset = src->begin_pos & offsetmask;
1126 __DECL_VECTORIZED_LOOP
1127 for(int x = 0; x < src->render_width; x++) {
1128 __DECL_VECTORIZED_LOOP
1129 for(int i = 0; i < planes; i++) {
1130 td[i] = srcp[i][(noffset + offset[i]) & addrmask];
1132 noffset = (noffset + 1) & offsetmask;
1133 dat.v = bp[0][td[0]].v;
1134 __DECL_VECTORIZED_LOOP
1135 for(int i = 1; i < planes; i++) {
1136 dat.v = dat.v | bp[i][td[i]].v;
1138 dat.v = dat.v >> shift;
1139 __DECL_VECTORIZED_LOOP
1140 for(int i = 0; i < 8; i++) {
1141 dst[i] = (uint8_t)(dat.w[i]);
1148 void DLL_PREFIX Convert2NColorsToByte_LineZoom2(_render_command_data_t *src, uint8_t *dst, int planes)
1150 if(planes >= 8) planes = 8;
1151 if(planes <= 0) return;
1154 __DECL_ALIGNED(32) uint32_t offset[8] = {0};
1156 uint16_vec8_t* bp[8] ;
1158 __DECL_VECTORIZED_LOOP
1159 for(int i = 0; i < planes; i++) {
1160 bp[i] = (uint16_vec8_t*)__builtin_assume_aligned(&(src->bit_trans_table[i]->plane_table[0]), sizeof(uint16_vec8_t));
1161 srcp[i] = &(src->data[i][src->baseaddress[i]]);
1163 uint32_t addrmask = src->addrmask;
1164 uint32_t offsetmask = src->addrmask2;
1165 int shift = src->shift;
1167 __DECL_VECTORIZED_LOOP
1168 for(int i = 0; i < planes; i++) {
1169 offset[i] = src->voffset[i];
1172 uint32_t noffset = src->begin_pos & offsetmask;
1174 __DECL_VECTORIZED_LOOP
1175 for(int x = 0; x < src->render_width; x++) {
1176 __DECL_VECTORIZED_LOOP
1177 for(int i = 0; i < planes; i++) {
1178 td[i] = srcp[i][(noffset + offset[i]) & addrmask];
1180 noffset = (noffset + 1) & offsetmask;
1181 dat.v = bp[0][td[0]].v;
1182 __DECL_VECTORIZED_LOOP
1183 for(int i = 1; i < planes; i++) {
1184 dat.v = dat.v | bp[i][td[i]].v;
1186 dat.v = dat.v >> shift;
1187 __DECL_VECTORIZED_LOOP
1188 for(int i = 0, j = 0; i < 16; i +=2, j++) {
1189 dst[i] = (uint8_t)(dat.w[j]);
1190 dst[i + 1] = (uint8_t)(dat.w[j]);
1196 void DLL_PREFIX Convert8ColorsToByte_Line(_render_command_data_t *src, uint8_t *dst)
1198 uint8_t *bp = &(src->data[0][src->baseaddress[0]]);
1199 uint8_t *rp = &(src->data[1][src->baseaddress[1]]);
1200 uint8_t *gp = &(src->data[2][src->baseaddress[2]]);
1201 __DECL_ALIGNED(16) uint32_t offset[4] = {0};
1208 uint16_vec8_t* bpb = (uint16_vec8_t*)__builtin_assume_aligned(&(src->bit_trans_table[0]->plane_table[0]), sizeof(uint16_vec8_t));
1209 uint16_vec8_t* bpr = (uint16_vec8_t*)__builtin_assume_aligned(&(src->bit_trans_table[1]->plane_table[0]), sizeof(uint16_vec8_t));
1210 uint16_vec8_t* bpg = (uint16_vec8_t*)__builtin_assume_aligned(&(src->bit_trans_table[2]->plane_table[0]), sizeof(uint16_vec8_t));
1212 uint32_t addrmask = src->addrmask;
1213 uint32_t offsetmask = src->addrmask2;
1214 int shift = src->shift;
1216 __DECL_VECTORIZED_LOOP
1217 for(int i = 0; i < 3; i++) {
1218 offset[i] = src->voffset[i];
1221 uint32_t noffset = src->begin_pos & offsetmask;
1223 __DECL_VECTORIZED_LOOP
1224 for(int x = 0; x < src->render_width; x++) {
1225 b = bp[(noffset + offset[0]) & addrmask];
1226 r = rp[(noffset + offset[1]) & addrmask];
1227 g = gp[(noffset + offset[2]) & addrmask];
1229 noffset = (noffset + 1) & offsetmask;
1235 tmpd.v = tmpd.v | rdat.v;
1236 tmpd.v = tmpd.v | gdat.v;
1237 tmpd.v = tmpd.v >> shift;
1239 __DECL_VECTORIZED_LOOP
1240 for(int i = 0; i < 8; i++) {
1241 dst[i] = (uint8_t)(tmpd.w[i]);
1249 struct to_upper { // Refer from documentation of libstdc++, GCC5.
1250 char operator() (char c) const { return std::toupper(c); }
1254 #if defined(_USE_QT)
1255 static void _my_mkdir(std::string t_dir)
1258 //#if !defined(__WIN32) && !defined(__WIN64)
1259 // if(fstatat(AT_FDCWD, csppath.c_str(), &st, 0) != 0) {
1260 // mkdirat(AT_FDCWD, t_dir.c_str(), 0700); // Not found
1262 #if defined(_USE_QT)
1263 if(stat(t_dir.c_str(), &st) != 0) {
1264 QDir dir = QDir::current();
1265 dir.mkdir(QString::fromStdString(t_dir));
1266 //dir.mkpath(QString::fromUtf8(app_path));
1269 if(stat(csppath.c_str(), &st) != 0) {
1270 _mkdir(t_dir.c_str()); // Not found
1276 const _TCHAR *DLL_PREFIX get_application_path()
1278 static _TCHAR app_path[_MAX_PATH];
1279 static bool initialized = false;
1282 #if defined(_WIN32) && !defined(_USE_QT)
1283 _TCHAR tmp_path[_MAX_PATH], *ptr = NULL;
1284 if(GetModuleFileName(NULL, tmp_path, _MAX_PATH) != 0 && GetFullPathName(tmp_path, _MAX_PATH, app_path, &ptr) != 0 && ptr != NULL) {
1287 my_tcscpy_s(app_path, _MAX_PATH, _T(".\\"));
1290 #if defined(Q_OS_WIN)
1291 std::string delim = "\\";
1293 std::string delim = "/";
1295 std::string csppath = cpp_homedir + "CommonSourceCodeProject" + delim ;
1298 std::string cpath = csppath + my_procname + delim;
1300 strncpy(app_path, cpath.c_str(), _MAX_PATH - 1);
1304 return (const _TCHAR *)app_path;
1307 const _TCHAR *DLL_PREFIX get_initial_current_path()
1309 static _TCHAR current_path[_MAX_PATH];
1310 static bool initialized = false;
1313 #if defined(_WIN32) && !defined(_USE_QT)
1314 GetCurrentDirectoryA(_MAX_PATH, current_path);
1316 getcwd(current_path, _MAX_PATH);
1318 int len = strlen(current_path);
1319 if(current_path[len - 1] != '\\' && current_path[len - 1] != '/') {
1320 #if defined(_WIN32) || defined(Q_OS_WIN)
1321 current_path[len] = '\\';
1323 current_path[len] = '/';
1325 current_path[len + 1] = '\0';
1330 return (const _TCHAR *)current_path;
1333 const _TCHAR *DLL_PREFIX create_local_path(const _TCHAR *format, ...)
1335 static _TCHAR file_path[8][_MAX_PATH];
1336 static unsigned int table_index = 0;
1337 unsigned int output_index = (table_index++) & 7;
1338 _TCHAR file_name[_MAX_PATH];
1339 //printf("%d %d\n", table_index, output_index);
1342 va_start(ap, format);
1343 my_vstprintf_s(file_name, _MAX_PATH, format, ap);
1345 my_stprintf_s(file_path[output_index], _MAX_PATH, _T("%s%s"), get_application_path(), file_name);
1346 return (const _TCHAR *)file_path[output_index];
1349 void DLL_PREFIX create_local_path(_TCHAR *file_path, int length, const _TCHAR *format, ...)
1351 _TCHAR file_name[_MAX_PATH];
1354 va_start(ap, format);
1355 my_vstprintf_s(file_name, _MAX_PATH, format, ap);
1357 my_stprintf_s(file_path, length, _T("%s%s"), get_application_path(), file_name);
1360 bool DLL_PREFIX is_absolute_path(const _TCHAR *file_path)
1363 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(':')) {
1367 return (_tcslen(file_path) > 1 && (file_path[0] == _T('/') || file_path[0] == _T('\\')));
1370 const _TCHAR *DLL_PREFIX create_date_file_path(const _TCHAR *extension)
1372 cur_time_t cur_time;
1374 get_host_time(&cur_time);
1375 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);
1378 void DLL_PREFIX create_date_file_path(_TCHAR *file_path, int length, const _TCHAR *extension)
1380 my_tcscpy_s(file_path, length, create_date_file_path(extension));
1383 const _TCHAR *DLL_PREFIX create_date_file_name(const _TCHAR *extension)
1385 static _TCHAR file_name[8][_MAX_PATH];
1386 static unsigned int table_index = 0;
1387 unsigned int output_index = (table_index++) & 7;
1388 cur_time_t cur_time;
1390 get_host_time(&cur_time);
1391 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);
1392 return (const _TCHAR *)file_name[output_index];
1395 void DLL_PREFIX create_date_file_name(_TCHAR *file_path, int length, const _TCHAR *extension)
1397 my_tcscpy_s(file_path, length, create_date_file_name(extension));
1400 bool DLL_PREFIX check_file_extension(const _TCHAR *file_path, const _TCHAR *ext)
1402 #if defined(_USE_QT)
1403 std::string s_fpath = file_path;
1404 std::string s_ext = ext;
1407 std::transform(s_fpath.begin(), s_fpath.end(), s_fpath.begin(), to_upper());
1408 std::transform(s_ext.begin(), s_ext.end(), s_ext.begin(), to_upper());
1409 if(s_fpath.length() < s_ext.length()) return false;
1410 pos = s_fpath.rfind(s_ext.c_str(), s_fpath.length());
1411 if((pos != (int)std::string::npos) && (pos >= ((int)s_fpath.length() - (int)s_ext.length()))) return true;
1414 int nam_len = _tcslen(file_path);
1415 int ext_len = _tcslen(ext);
1417 return (nam_len >= ext_len && _tcsncicmp(&file_path[nam_len - ext_len], ext, ext_len) == 0);
1421 const _TCHAR *DLL_PREFIX get_file_path_without_extensiton(const _TCHAR *file_path)
1423 static _TCHAR path[8][_MAX_PATH];
1424 static unsigned int table_index = 0;
1425 unsigned int output_index = (table_index++) & 7;
1427 my_tcscpy_s(path[output_index], _MAX_PATH, file_path);
1428 #if defined(_WIN32) && defined(_MSC_VER)
1429 PathRemoveExtension(path[output_index]);
1430 #elif defined(_USE_QT)
1432 delim = QString::fromUtf8(".");
1433 QString tmp_path = QString::fromUtf8(file_path);
1434 int n = tmp_path.lastIndexOf(delim);
1436 tmp_path = tmp_path.left(n);
1438 //printf("%s\n", tmp_path.toUtf8().constData());
1439 memset(path[output_index], 0x00, sizeof(_TCHAR) * _MAX_PATH);
1440 strncpy(path[output_index], tmp_path.toUtf8().constData(), _MAX_PATH - 1);
1443 return (const _TCHAR *)path[output_index];
1446 void DLL_PREFIX get_long_full_path_name(const _TCHAR* src, _TCHAR* dst, size_t dst_len)
1449 _TCHAR tmp[_MAX_PATH];
1450 if(GetFullPathName(src, _MAX_PATH, tmp, NULL) == 0) {
1451 my_tcscpy_s(dst, dst_len, src);
1452 } else if(GetLongPathName(tmp, dst, _MAX_PATH) == 0) {
1453 my_tcscpy_s(dst, dst_len, tmp);
1455 #elif defined(_USE_QT)
1456 QString tmp_path = QString::fromUtf8(src);
1457 QFileInfo info(tmp_path);
1458 my_tcscpy_s(dst, dst_len, info.absoluteFilePath().toLocal8Bit().constData());
1460 // write code for your environment
1465 const _TCHAR *DLL_PREFIX get_parent_dir(const _TCHAR* file)
1467 static _TCHAR path[8][_MAX_PATH];
1468 static unsigned int table_index = 0;
1469 unsigned int output_index = (table_index++) & 7;
1473 GetFullPathName(file, _MAX_PATH, path[output_index], &ptr);
1477 #elif defined(_USE_QT)
1479 #if defined(Q_OS_WIN)
1480 delim = QString::fromUtf8("\\");
1482 delim = QString::fromUtf8("/");
1484 QString tmp_path = QString::fromUtf8(file);
1485 int n = tmp_path.lastIndexOf(delim);
1487 tmp_path = tmp_path.left(n);
1488 tmp_path.append(delim);
1490 //printf("%s\n", tmp_path.toUtf8().constData());
1491 memset(path[output_index], 0x00, sizeof(_TCHAR) * _MAX_PATH);
1492 strncpy(path[output_index], tmp_path.toUtf8().constData(), _MAX_PATH - 1);
1494 // write code for your environment
1496 return path[output_index];
1499 const wchar_t *DLL_PREFIX char_to_wchar(const char *cs)
1502 static wchar_t ws[4096];
1504 #if defined(_WIN32) || defined(_USE_QT)
1505 mbstowcs(ws, cs, strlen(cs));
1507 // write code for your environment
1512 const char *DLL_PREFIX wchar_to_char(const wchar_t *ws)
1515 static char cs[4096];
1518 wcstombs(cs, ws, wcslen(ws));
1519 #elif defined(_USE_QT)
1520 wcstombs(cs, ws, wcslen(ws));
1522 // write code for your environment
1527 const _TCHAR *DLL_PREFIX char_to_tchar(const char *cs)
1529 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1531 return char_to_wchar(cs);
1538 const char *DLL_PREFIX tchar_to_char(const _TCHAR *ts)
1540 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1542 return wchar_to_char(ts);
1549 const _TCHAR *DLL_PREFIX wchar_to_tchar(const wchar_t *ws)
1551 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1552 // wchar_t to wchar_t
1556 return wchar_to_char(ws);
1560 const wchar_t *DLL_PREFIX tchar_to_wchar(const _TCHAR *ts)
1562 #if defined(_UNICODE) && defined(SUPPORT_TCHAR_TYPE)
1563 // wchar_t to wchar_t
1567 return char_to_wchar(ts);
1571 const _TCHAR *DLL_PREFIX create_string(const _TCHAR* format, ...)
1573 static _TCHAR buffer[8][1024];
1574 static unsigned int table_index = 0;
1575 unsigned int output_index = (table_index++) & 7;
1578 va_start(ap, format);
1579 my_vstprintf_s(buffer[output_index], 1024, format, ap);
1581 return (const _TCHAR *)buffer[output_index];
1584 int32_t DLL_PREFIX muldiv_s32(int32_t nNumber, int32_t nNumerator, int32_t nDenominator)
1588 tmp = (int64_t)nNumber;
1589 tmp *= (int64_t)nNumerator;
1590 tmp /= (int64_t)nDenominator;
1591 return (int32_t)tmp;
1594 tmp = (double)nNumber;
1595 tmp *= (double)nNumerator;
1596 tmp /= (double)nDenominator;
1598 return (int32_t)(tmp - 0.5);
1600 return (int32_t)(tmp + 0.5);
1605 uint32_t DLL_PREFIX muldiv_u32(uint32_t nNumber, uint32_t nNumerator, uint32_t nDenominator)
1609 tmp = (uint64_t)nNumber;
1610 tmp *= (uint64_t)nNumerator;
1611 tmp /= (uint64_t)nDenominator;
1612 return (uint32_t)tmp;
1615 tmp = (double)nNumber;
1616 tmp *= (double)nNumerator;
1617 tmp /= (double)nDenominator;
1618 return (uint32_t)(tmp + 0.5);
1622 static bool _crc_initialized = false;
1623 static uint32_t _crc_table[256] = {0};
1624 static void init_crc32_table(void)
1626 for(int i = 0; i < 256; i++) {
1628 for(int j = 0; j < 8; j++) {
1630 c = (c >> 1) ^ 0xedb88320;
1637 _crc_initialized = true;
1640 uint32_t DLL_PREFIX get_crc32(uint8_t data[], int size)
1642 const uint32_t *table = (const uint32_t *)_crc_table;
1643 if(!_crc_initialized) {
1648 for(int i = 0; i < size; i++) {
1649 c = table[(c ^ data[i]) & 0xff] ^ (c >> 8);
1654 uint32_t DLL_PREFIX calc_crc32(uint32_t seed, uint8_t data[], int size)
1657 if(!_crc_initialized) {
1660 const uint32_t *table = (const uint32_t *)_crc_table;
1663 for(int i = 0; i < size; i++) {
1664 c = table[(c ^ data[i]) & 0xff] ^ (c >> 8);
1669 // Refer to : https://qiita.com/mikecat_mixc/items/e5d236e3a3803ef7d3c5
1670 static const uint32_t CRC_MAGIC_WORD = 0x04C11DB7;
1671 uint32_t crc = seed;
1672 uint8_t *ptr = data;
1676 for(int i = 0; i < bytes; i++) {
1678 for(int bit = 0; bit < 8; bit++) {
1679 is_overflow = ((crc & 0x1) != 0);
1681 if((d & 0x01) != 0) crc = crc | 0x80000000;
1682 if(is_overflow) crc = crc ^ ((uint32_t)~CRC_MAGIC_WORD);
1690 uint16_t DLL_PREFIX jis_to_sjis(uint16_t jis)
1694 tmp.w.l = jis - 0x2121;
1695 if(tmp.w.l & 0x100) {
1700 if(tmp.b.l > 0x7f) {
1703 tmp.b.h = (tmp.b.h >> 1) + 0x81;
1704 if(tmp.w.l >= 0xa000) {
1710 int DLL_PREFIX decibel_to_volume(int decibel)
1712 // +1 equals +0.5dB (same as fmgen)
1713 return (int)(1024.0 * pow(10.0, decibel / 40.0) + 0.5);
1716 int32_t DLL_PREFIX apply_volume(int32_t sample, int volume)
1730 // if(output > 2147483647) {
1731 // return 2147483647;
1732 // } else if(output < (-2147483647 - 1)) {
1733 // return (-2147483647 - 1);
1735 // return (int32_t)output;
1740 void DLL_PREFIX get_host_time(cur_time_t* cur_time)
1744 GetLocalTime(&sTime);
1745 cur_time->year = sTime.wYear;
1746 cur_time->month = sTime.wMonth;
1747 cur_time->day = sTime.wDay;
1748 cur_time->day_of_week = sTime.wDayOfWeek;
1749 cur_time->hour = sTime.wHour;
1750 cur_time->minute = sTime.wMinute;
1751 cur_time->second = sTime.wSecond;
1753 time_t timer = time(NULL);
1754 struct tm *local = localtime(&timer);
1755 cur_time->year = local->tm_year + 1900;
1756 cur_time->month = local->tm_mon + 1;
1757 cur_time->day = local->tm_mday;
1758 cur_time->day_of_week = local->tm_wday;
1759 cur_time->hour = local->tm_hour;
1760 cur_time->minute = local->tm_min;
1761 cur_time->second = local->tm_sec;
1767 void DLL_PREFIX cur_time_t::increment()
1769 if(++second >= 60) {
1771 if(++minute >= 60) {
1775 // days in this month
1778 days = LEAP_YEAR(year) ? 29 : 28;
1779 } else if(month == 4 || month == 6 || month == 9 || month == 11) {
1789 if(++day_of_week >= 7) {
1797 void DLL_PREFIX cur_time_t::update_year()
1802 } else if(year < 100) {
1807 void DLL_PREFIX cur_time_t::update_day_of_week()
1809 static const int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
1810 int y = year - (month < 3);
1811 day_of_week = (y + y / 4 - y / 100 + y / 400 + t[month - 1] + day) % 7;
1814 #define STATE_VERSION 1
1817 bool DLL_PREFIX cur_time_t::process_state(void *f, bool loading)
1819 FILEIO *state_fio = (FILEIO *)f;
1821 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1824 state_fio->StateValue(year);
1825 state_fio->StateValue(month);
1826 state_fio->StateValue(day);
1827 state_fio->StateValue(day_of_week);
1828 state_fio->StateValue(hour);
1829 state_fio->StateValue(minute);
1830 state_fio->StateValue(second);
1831 state_fio->StateValue(initialized);
1835 const _TCHAR *DLL_PREFIX get_symbol(symbol_t *first_symbol, uint32_t addr)
1837 static _TCHAR name[8][1024];
1838 static unsigned int table_index = 0;
1839 unsigned int output_index = (table_index++) & 7;
1841 if(first_symbol != NULL) {
1842 for(symbol_t* symbol = first_symbol; symbol; symbol = symbol->next_symbol) {
1843 if(symbol->addr == addr) {
1844 my_tcscpy_s(name[output_index], 1024, symbol->name);
1845 return name[output_index];
1852 const _TCHAR *DLL_PREFIX get_value_or_symbol(symbol_t *first_symbol, const _TCHAR *format, uint32_t addr)
1854 static _TCHAR name[8][1024];
1855 static unsigned int table_index = 0;
1856 unsigned int output_index = (table_index++) & 7;
1858 if(first_symbol != NULL) {
1859 for(symbol_t* symbol = first_symbol; symbol; symbol = symbol->next_symbol) {
1860 if(symbol->addr == addr) {
1861 my_tcscpy_s(name[output_index], 1024, symbol->name);
1862 return name[output_index];
1866 my_stprintf_s(name[output_index], 1024, format, addr);
1867 return name[output_index];
1870 const _TCHAR *DLL_PREFIX get_value_and_symbol(symbol_t *first_symbol, const _TCHAR *format, uint32_t addr)
1872 static _TCHAR name[8][1024];
1873 static unsigned int table_index = 0;
1874 unsigned int output_index = (table_index++) & 7;
1876 my_stprintf_s(name[output_index], 1024, format, addr);
1878 if(first_symbol != NULL) {
1879 for(symbol_t* symbol = first_symbol; symbol; symbol = symbol->next_symbol) {
1880 if(symbol->addr == addr) {
1882 // my_stprintf_s(temp, 1024, _T(" (%s)"), symbol->name);
1883 my_stprintf_s(temp, 1024, _T(";%s"), symbol->name);
1884 my_tcscat_s(name[output_index], 1024, temp);
1885 return name[output_index];
1889 return name[output_index];
1892 // Use this before writing wav_data.
1893 bool DLL_PREFIX write_dummy_wav_header(void *__fio)
1895 if(__fio == NULL) return false;
1897 FILEIO *fio = (FILEIO *)__fio;
1898 uint8_t dummy[sizeof(wav_header_t) + sizeof(wav_chunk_t)];
1900 if(!fio->IsOpened()) return false;
1902 memset(dummy, 0, sizeof(dummy));
1903 fio->Fwrite(dummy, sizeof(dummy), 1);
1906 // Use this after writing wav_data.
1907 bool DLL_PREFIX set_wav_header(wav_header_t *header, wav_chunk_t *first_chunk, uint16_t channels, uint32_t rate,
1908 uint16_t bits, size_t file_length)
1910 uint32_t length = (uint32_t) file_length;
1912 if(header == NULL) return false;
1913 if(first_chunk == NULL) return false;
1915 pair32_t __riff_chunk_size;
1916 pair32_t __fmt_chunk_size;
1917 pair32_t __wav_chunk_size;
1919 pair16_t __channels;
1920 pair32_t __sample_rate;
1921 pair32_t __data_speed;
1922 pair16_t __block_size;
1923 pair16_t __sample_bits;
1925 __riff_chunk_size.d = length - 8;
1926 __fmt_chunk_size.d = 16;
1928 __channels.u16 = channels;
1929 __sample_rate.d = rate;
1930 __block_size.u16 = (uint16_t)((channels * bits) / 8);
1931 __sample_bits.u16 = bits;
1932 __data_speed.d = rate * (uint32_t)(__block_size.u16);
1934 memcpy(&(header->riff_chunk.id), "RIFF", 4);
1935 header->riff_chunk.size = __riff_chunk_size.get_4bytes_le_to();
1937 memcpy(&(header->wave), "WAVE", 4);
1938 memcpy(&(header->fmt_chunk.id), "fmt ", 4);
1939 header->fmt_chunk.size = __fmt_chunk_size.get_4bytes_le_to();
1940 header->format_id = __fmt_id.get_2bytes_le_to();
1941 header->channels = __channels.get_2bytes_le_to();
1942 header->sample_rate = __sample_rate.get_4bytes_le_to();
1943 header->data_speed = __data_speed.get_4bytes_le_to();
1944 header->block_size = __block_size.get_2bytes_le_to();
1945 header->sample_bits = __sample_bits.get_2bytes_le_to();
1947 memcpy(&(first_chunk->id), "data", 4);
1948 __wav_chunk_size.d = length - sizeof(wav_header_t) - sizeof(wav_chunk_t);
1949 first_chunk->size = __wav_chunk_size.get_4bytes_le_to();
1953 // Note: buffers are allocated by this, You should free() within user class.
1954 bool DLL_PREFIX load_wav_to_stereo(void *__fio, int16_t **left_buf, int16_t **right_buf, uint32_t *rate, int *got_samples)
1957 if(__fio == NULL) return false;
1958 if(left_buf == NULL) return false;
1959 if(right_buf == NULL) return false;
1960 if(rate == NULL) return false;
1961 if(got_samples == NULL) return false;
1962 //if((bits != 8) && (bits != 16) && (bits != 32)) return false;
1964 FILEIO *fio = (FILEIO *)__fio;
1965 if(!fio->IsOpened()) return false;
1968 int16_t *left_buffer = NULL;
1969 int16_t *right_buffer = NULL;
1971 uint32_t sample_rate = 0;
1973 wav_header_t header;
1977 pair16_t __sample_bits;
1978 pair16_t __channels;
1979 pair32_t __sample_rate;
1980 pair32_t __chunk_size;
1982 fio->Fread(&header, sizeof(header), 1);
1983 __fmt_id.set_2bytes_le_from(header.format_id);
1984 __sample_bits.set_2bytes_le_from(header.sample_bits);
1985 __chunk_size.set_4bytes_le_from(header.fmt_chunk.size);
1986 __channels.set_2bytes_le_from(header.channels);
1987 __sample_rate.set_4bytes_le_from(header.sample_rate);
1989 if((__fmt_id.u16 == 1) && ((__sample_bits.u16 == 8) || (__sample_bits.u16 == 16) || (__sample_bits.u16 == 32))) {
1990 fio->Fseek(__chunk_size.d - 16, FILEIO_SEEK_CUR);
1991 bool is_eof = false;
1993 if(fio->Fread(&chunk, sizeof(chunk), 1) != 1) {
1997 __chunk_size.set_4bytes_le_from(chunk.size);
1998 if(strncmp(chunk.id, "data", 4) == 0) {
2001 fio->Fseek(__chunk_size.d, FILEIO_SEEK_CUR);
2003 __chunk_size.set_4bytes_le_from(chunk.size);
2010 samples = (size_t)(__chunk_size.d / __channels.u16);
2011 int16_t data_l, data_r;
2021 uint8_t l, h, h2, h3;
2026 if(__sample_bits.u16 == 16) {
2028 } else if(__sample_bits.u16 == 32) {
2031 if(samples == 0) return false;
2032 sample_rate = __sample_rate.d;
2034 left_buffer = (int16_t *)malloc(samples * sizeof(int16_t));
2035 right_buffer = (int16_t *)malloc(samples * sizeof(int16_t));
2036 if(left_buffer == NULL) {
2037 if(right_buffer != NULL) free(right_buffer);
2040 if(right_buffer == NULL) {
2041 if(left_buffer != NULL) free(left_buffer);
2044 switch(__sample_bits.u16) {
2046 if(__channels.s16 == 1) {
2047 for(int i = 0; i < samples; i++) {
2048 data_l = (int16_t)(fio->FgetUint8());
2049 data_l = (data_l - 128) * 256;
2050 left_buffer[i] = data_l;
2051 right_buffer[i] = data_l;
2053 } else if(__channels.s16 == 2) {
2054 for(int i = 0; i < samples; i++) {
2055 data_l = (int16_t)(fio->FgetUint8());
2056 data_l = (data_l - 128) * 256;
2057 data_r = (int16_t)(fio->FgetUint8());
2058 data_r = (data_r - 128) * 256;
2059 left_buffer[i] = data_l;
2060 right_buffer[i] = data_r;
2065 if(__channels.s16 == 1) {
2066 for(int i = 0; i < samples; i++) {
2067 pair16.b.l = fio->FgetUint8();
2068 pair16.b.h = fio->FgetUint8();
2069 data_l = pair16.s16;
2071 left_buffer[i] = data_l;
2072 right_buffer[i] = data_l;
2074 } else if(__channels.s16 == 2) {
2075 for(int i = 0; i < samples; i++) {
2076 pair16.b.l = fio->FgetUint8();
2077 pair16.b.h = fio->FgetUint8();
2078 data_l = pair16.s16;
2080 pair16.b.l = fio->FgetUint8();
2081 pair16.b.h = fio->FgetUint8();
2082 data_r = pair16.s16;
2083 left_buffer[i] = data_l;
2084 right_buffer[i] = data_r;
2089 if(__channels.s16 == 1) {
2090 for(int i = 0; i < samples; i++) {
2091 pair32.b.l = fio->FgetUint8();
2092 pair32.b.h = fio->FgetUint8();
2093 pair32.b.h2 = fio->FgetUint8();
2094 pair32.b.h3 = fio->FgetUint8();
2095 data_l = (int16_t)(pair32.s32 / 65536);
2097 left_buffer[i] = data_l;
2098 right_buffer[i] = data_l;
2100 } else if(__channels.s16 == 2) {
2101 for(int i = 0; i < samples; i++) {
2102 pair32.b.l = fio->FgetUint8();
2103 pair32.b.h = fio->FgetUint8();
2104 pair32.b.h2 = fio->FgetUint8();
2105 pair32.b.h3 = fio->FgetUint8();
2106 data_l = (int16_t)(pair32.s32 / 65536);
2108 pair32.b.l = fio->FgetUint8();
2109 pair32.b.h = fio->FgetUint8();
2110 pair32.b.h2 = fio->FgetUint8();
2111 pair32.b.h3 = fio->FgetUint8();
2112 data_r = (int16_t)(pair32.s32 / 65536);
2114 left_buffer[i] = data_l;
2115 right_buffer[i] = data_r;
2126 *left_buf = left_buffer;
2127 *right_buf = right_buffer;
2128 *rate = sample_rate;
2129 *got_samples = (int)samples;
2133 bool DLL_PREFIX load_wav_to_monoral(void *__fio, int16_t **buffer, uint32_t *rate, int *got_samples)
2136 if(__fio == NULL) return false;
2137 if(buffer == NULL) return false;
2138 if(rate == NULL) return false;
2139 if(got_samples == NULL) return false;
2140 //if((bits != 8) && (bits != 16) && (bits != 32)) return false;
2142 FILEIO *fio = (FILEIO *)__fio;
2143 if(!fio->IsOpened()) return false;
2146 int16_t *left_buffer = NULL;
2148 uint32_t sample_rate = 0;
2150 wav_header_t header;
2154 pair16_t __sample_bits;
2155 pair16_t __channels;
2156 pair32_t __sample_rate;
2157 pair32_t __chunk_size;
2159 fio->Fread(&header, sizeof(header), 1);
2160 __fmt_id.set_2bytes_le_from(header.format_id);
2161 __sample_bits.set_2bytes_le_from(header.sample_bits);
2162 __chunk_size.set_4bytes_le_from(header.fmt_chunk.size);
2163 __channels.set_2bytes_le_from(header.channels);
2164 __sample_rate.set_4bytes_le_from(header.sample_rate);
2166 if((__fmt_id.u16 == 1) && ((__sample_bits.u16 == 8) || (__sample_bits.u16 == 16) || (__sample_bits.u16 == 32))) {
2167 fio->Fseek(__chunk_size.d - 16, FILEIO_SEEK_CUR);
2168 bool is_eof = false;
2170 if(fio->Fread(&chunk, sizeof(chunk), 1) != 1) {
2174 __chunk_size.set_4bytes_le_from(chunk.size);
2175 if(strncmp(chunk.id, "data", 4) == 0) {
2178 fio->Fseek(__chunk_size.d, FILEIO_SEEK_CUR);
2180 __chunk_size.set_4bytes_le_from(chunk.size);
2187 samples = (size_t)(__chunk_size.d / __channels.u16);
2188 int16_t data_l, data_r;
2189 int32_t data32_l, data32_r;
2199 uint8_t l, h, h2, h3;
2204 if(__sample_bits.u16 == 16) {
2206 } else if(__sample_bits.u16 == 32) {
2209 if(samples == 0) return false;
2210 sample_rate = __sample_rate.d;
2212 left_buffer = (int16_t *)malloc(samples * sizeof(int16_t));
2213 if(left_buffer == NULL) {
2216 switch(__sample_bits.u16) {
2218 if(__channels.s16 == 1) {
2219 for(int i = 0; i < samples; i++) {
2220 data_l = (int16_t)(fio->FgetUint8());
2221 data_l = (data_l - 128) * 256;
2222 left_buffer[i] = data_l;
2224 } else if(__channels.s16 == 2) {
2225 for(int i = 0; i < samples; i++) {
2226 data_l = (int16_t)(fio->FgetUint8());
2227 data_l = (data_l - 128) * 256;
2228 data_r = (int16_t)(fio->FgetUint8());
2229 data_r = (data_r - 128) * 256;
2230 left_buffer[i] = (data_l + data_r) / 2;
2235 if(__channels.s16 == 1) {
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 left_buffer[i] = data_l;
2243 } else if(__channels.s16 == 2) {
2244 for(int i = 0; i < samples; i++) {
2245 pair16.b.l = fio->FgetUint8();
2246 pair16.b.h = fio->FgetUint8();
2247 data_l = pair16.s16;
2249 pair16.b.l = fio->FgetUint8();
2250 pair16.b.h = fio->FgetUint8();
2251 data_r = pair16.s16;
2252 left_buffer[i] = (data_l + data_r) / 2;
2257 if(__channels.s16 == 1) {
2258 for(int i = 0; i < samples; i++) {
2259 pair32.b.l = fio->FgetUint8();
2260 pair32.b.h = fio->FgetUint8();
2261 pair32.b.h2 = fio->FgetUint8();
2262 pair32.b.h3 = fio->FgetUint8();
2263 data_l = (int16_t)(pair32.s32 / 65536);
2265 left_buffer[i] = data_l;
2267 } else if(__channels.s16 == 2) {
2268 for(int i = 0; i < samples; i++) {
2269 pair32.b.l = fio->FgetUint8();
2270 pair32.b.h = fio->FgetUint8();
2271 pair32.b.h2 = fio->FgetUint8();
2272 pair32.b.h3 = fio->FgetUint8();
2273 data32_l = pair32.s32 / 65536;
2275 pair32.b.l = fio->FgetUint8();
2276 pair32.b.h = fio->FgetUint8();
2277 pair32.b.h2 = fio->FgetUint8();
2278 pair32.b.h3 = fio->FgetUint8();
2279 data32_r = pair32.s32 / 65536;
2281 left_buffer[i] = (int16_t)((data32_l + data32_r) / 2);
2292 *buffer = left_buffer;
2293 *rate = sample_rate;
2294 *got_samples = (int)samples;
2298 DLL_PREFIX const _TCHAR *get_lib_common_version()
2300 #if defined(__LIBEMU_UTIL_VERSION)
2301 return (const _TCHAR *)__LIBEMU_UTIL_VERSION;
2303 return (const _TCHAR *)"\0";