OSDN Git Service

[COMMON] Fix unaligned SIMD variables.Fix crash built with "-msse2" at Win32.
[csp-qt/common_source_project-fm7.git] / source / src / common.cpp
index 5a94f4e..9a10c0a 100644 (file)
@@ -43,8 +43,9 @@
        std::string DLL_PREFIX sRssDir;
 #endif
 
-void common_initialize()
+void DLL_PREFIX common_initialize()
 {
+       // get the initial current path when the software starts
        get_initial_current_path();
 }
 
@@ -141,6 +142,7 @@ uint16_t DLL_PREFIX EndianFromBig_WORD(uint16_t x)
 #endif
 }
 
+
 #ifndef _MSC_VER
 int DLL_PREFIX max(int a, int b)
 {
@@ -151,14 +153,6 @@ int DLL_PREFIX max(int a, int b)
        }
 }
 
-unsigned DLL_PREFIX int max(unsigned int a, unsigned int b)
-{
-       if(a > b) {
-               return a;
-       } else {
-               return b;
-       }
-}
 
 unsigned DLL_PREFIX int max(unsigned int a, int b)
 {
@@ -180,6 +174,15 @@ unsigned DLL_PREFIX int max(int a, unsigned int b)
        }
 }
 
+unsigned int DLL_PREFIX max(unsigned int a, unsigned int b)
+{
+       if(a > b) {
+               return a;
+       } else {
+               return b;
+       }
+}
+
 int DLL_PREFIX min(int a, int b)
 {
        if(a < b) {
@@ -315,392 +318,7 @@ int DLL_PREFIX my_vstprintf_s(_TCHAR *buffer, size_t numberOfElements, const _TC
 
 void DLL_PREFIX *my_memcpy(void *dst, void *src, size_t len)
 {
-       size_t len1;
-       register size_t len2;
-       register uint32_t s_align = (uint32_t)(((size_t)src) & 0x1f);
-       register uint32_t d_align = (uint32_t)(((size_t)dst) & 0x1f);
-       int i;
-       
-       if(len == 0) return dst;
-       if(len < 8) {
-               return memcpy(dst, src, len);
-       }
-       len1 = len;
-
-#if defined(WITHOUT_UNALIGNED_SIMD)
-// Using SIMD without un-aligned instructions.
-       switch(s_align) {
-       case 0: // Align 256
-               {
-                       uint64_t b64[4];
-                       register uint64_t *s64 = (uint64_t *)src;
-                       register uint64_t *d64 = (uint64_t *)dst;
-                       switch(d_align) {
-                       case 0: // 256 vs 256
-                               {
-                                       len2 = len1 >> 5;
-                                       while(len2 > 0) {
-                                               for(i = 0; i < 4; i++) b64[i] = s64[i];
-                                               for(i = 0; i < 4; i++) d64[i] = b64[i];
-                                               s64 += 4;
-                                               d64 += 4;
-                                               --len2;
-                                       }
-                                       len1 = len1 & 0x1f;
-                                       if(len1 != 0) return memcpy(d64, s64, len1);
-                                       return dst;
-                               }
-                               break;
-                       case 0x10: // 256 vs 128
-                               {
-                                       len2 = len1 >> 5;
-                                       while(len2 > 0) {
-                                               for(i = 0; i < 4; i++) b64[i] = s64[i];
-                                               for(i = 0; i < 2; i++) d64[i] = b64[i];
-                                               d64 += 2;
-                                               for(i = 2; i < 4; i++) d64[i - 2] = b64[i];
-                                               d64 += 2;
-                                               s64 += 4;
-                                               --len2;
-                                       }
-                                       len1 = len1 & 0x1f;
-                                       if(len1 != 0) return memcpy(d64, s64, len1);
-                                       return dst;
-                               }
-                               break;
-                       case 0x08:
-                       case 0x18: // 256 vs 64
-                               {
-                                       len2 = len1 >> 5;
-                                       while(len2 > 0) {
-                                               for(i = 0; i < 4; ++i) b64[i] = s64[i];
-                                               for(i = 0; i < 4; ++i) {
-                                                       *d64 = b64[i];
-                                                       ++d64;
-                                               }
-                                               s64 += 4;
-                                               --len2;
-                                       }
-                                       len1 = len1 & 0x1f;
-                                       if(len1 != 0) return memcpy(d64, s64, len1);
-                                       return dst;
-                               }
-                               break;
-                       case 0x04:
-                       case 0x0c: 
-                       case 0x14:
-                       case 0x1c: // 256 vs 32
-                               {
-                                       uint32_t b32[8];
-                                       register uint32_t *s32 = (uint32_t *)src;
-                                       register uint32_t *d32 = (uint32_t *)dst;
-                                       len2 = len1 >> 5;
-                                       while(len2 > 0) {
-                                               for(i = 0; i < 8; ++i) b32[i] = s32[i];
-                                               *d32 = b32[0];
-                                               ++d32;
-                                               *d32 = b32[1];
-                                               ++d32;
-                                               *d32 = b32[2];
-                                               ++d32;
-                                               *d32 = b32[3];
-                                               ++d32;
-                                               *d32 = b32[4];
-                                               ++d32;
-                                               *d32 = b32[5];
-                                               ++d32;
-                                               *d32 = b32[6];
-                                               ++d32;
-                                               *d32 = b32[7];
-                                               ++d32;
-                                               s32 += 8;
-                                               --len2;
-                                       }
-                                       len1 = len1 & 0x1f;
-                                       if(len1 != 0) return memcpy(d32, s32, len1);
-                                       return dst;
-                               }
-                               break;
-                       default:
-                               return memcpy(dst, src, len1);
-                               break;
-                       }
-               }
-               break;
-       case 0x10: // Src alignn to 16.
-               {
-                       uint32_t b32[4];
-                       register uint32_t *s32 = (uint32_t *)src;
-                       register uint32_t *d32 = (uint32_t *)dst;
-                       switch(d_align) {
-                       case 0: // 128 vs 256/128
-                       case 0x10:
-                               {
-                                       len2 = len1 >> 4;
-                                       while(len2 > 0) {
-                                               for(i = 0; i < 4; i++) b32[i] = s32[i];
-                                               for(i = 0; i < 4; i++) d32[i] = b32[i];
-                                               s32 += 4;
-                                               d32 += 4;
-                                               --len2;
-                                       }
-                                       len1 = len1 & 0x0f;
-                                       if(len1 != 0) return memcpy(d32, s32, len1);
-                                       return dst;
-                               }
-                               break;
-                       case 0x08:
-                       case 0x18: // 128 vs 64
-                               {
-                                       len2 = len1 >> 4;
-                                       while(len2 > 0) {
-                                               for(i = 0; i < 4; ++i) b32[i] = s32[i];
-                                               for(i = 0; i < 2; ++i) {
-                                                       d32[i] = b32[i];
-                                               }
-                                               d32 += 2;
-                                               for(i = 2; i < 4; ++i) {
-                                                       d32[i - 2] = b32[i];
-                                               }
-                                               d32 += 2;
-                                               s32 += 4;
-                                               --len2;
-                                       }
-                                       len1 = len1 & 0x0f;
-                                       if(len1 != 0) return memcpy(d32, s32, len1);
-                                       return dst;
-                               }
-                               break;
-                       case 0x04:
-                       case 0x0c:
-                       case 0x14:
-                       case 0x1c: // 128 vs 32
-                               {
-                                       len2 = len1 >> 4;
-                                       while(len2 > 0) {
-                                               for(i = 0; i < 4; ++i) b32[i] = s32[i];
-                                               *d32 = b32[0];
-                                               ++d32;
-                                               *d32 = b32[1];
-                                               ++d32;
-                                               *d32 = b32[2];
-                                               ++d32;
-                                               *d32 = b32[3];
-                                               ++d32;
-                                               s32 += 4;
-                                               --len2;
-                                       }
-                                       len1 = len1 & 0x0f;
-                                       if(len1 != 0) return memcpy(d32, s32, len1);
-                                       return dst;
-                               }
-                               break;
-                       default:
-                               return memcpy(dst, src, len1);
-                               break;
-                       }
-               }
-               break;
-       case 0x08:
-       case 0x18: // Src alignn to 64.
-               {
-                       register uint32_t *s32 = (uint32_t *)src;
-                       register uint32_t *d32 = (uint32_t *)dst;
-                       register uint64_t *s64 = (uint64_t *)src;
-                       register uint64_t *d64 = (uint64_t *)dst;
-                       switch(d_align) {
-                       case 0:
-                       case 0x10: // 64 vs 128
-                               {
-                                       uint64_t b128[2];
-                                       len2 = len1 >> 4;
-                                       while(len2 > 0) {
-                                               b128[0] = *s64;
-                                               ++s64;
-                                               b128[1] = *s64;
-                                               ++s64;
-                                               for(i = 0; i < 2; i++) d64[i] = b128[i];
-                                               d64 += 2;
-                                               --len2;
-                                       }
-                                       len1 = len1 & 0x0f;
-                                       if(len1 != 0) return memcpy(d64, s64, len1);
-                                       return dst;
-                               }
-                               break;
-                       case 0x08:
-                       case 0x18: // 64 vs 64
-                               {
-                                       len2 = len1 >> 3;
-                                       while(len2 > 0) {
-                                               *d64 = *s64;
-                                               ++s64;
-                                               ++d64;
-                                               --len2;
-                                       }
-                                       len1 = len1 & 0x07;
-                                       if(len1 != 0) return memcpy(d64, s64, len1);
-                                       return dst;
-                               }
-                               break;
-                       case 0x04:
-                       case 0x0c: // 64 vs 32
-                       case 0x14:
-                       case 0x1c: // 64 vs 32
-                               {
-                                       uint32_t b32[2];
-                                       len2 = len1 >> 3;
-                                       while(len2 > 0) {
-                                               for(i = 0; i < 2; ++i) b32[i] = s32[i];
-                                               d32[0] = b32[0];
-                                               d32[1] = b32[1];
-                                               s32 += 2;
-                                               d32 += 2;
-                                               --len2;
-                                       }
-                                       len1 = len1 & 0x07;
-                                       if(len1 != 0) return memcpy(d32, s32, len1);
-                                       return dst;
-                               }
-                               break;
-                       default:
-                               return memcpy(dst, src, len1);
-                               break;
-                       }
-               }
-       case 0x04:
-       case 0x0c:
-       case 0x14:
-       case 0x1c:  // Src align 32
-               {
-                       register uint32_t *s32 = (uint32_t *)src;
-                       register uint32_t *d32 = (uint32_t *)dst;
-                       register uint64_t *d64 = (uint64_t *)dst;
-                       switch(d_align) {
-                       case 0:
-                       case 0x10: // 32 vs 128
-                               {
-                                       uint32_t b128[4];
-                                       len2 = len1 >> 4;
-                                       while(len2 > 0) {
-                                               b128[0] = *s32;
-                                               ++s32;
-                                               b128[1] = *s32;
-                                               ++s32;
-                                               b128[3] = *s32;
-                                               ++s32;
-                                               b128[4] = *s32;
-                                               ++s32;
-                                               for(i = 0; i < 4; i++) d32[i] = b128[i];
-                                               d32 += 4;
-                                               --len2;
-                                       }
-                                       len1 = len1 & 0x0f;
-                                       if(len1 != 0) return memcpy(d32, s32, len1);
-                                       return dst;
-                               }
-                               break;
-                       case 0x08:
-                       case 0x18: // 32 vs 64
-                               {
-                                       uint32_t b64[2];
-                                       len2 = len1 >> 3;
-                                       while(len2 > 0) {
-                                               b64[0] = *s32;
-                                               ++s32;
-                                               b64[1] = *s32;
-                                               ++s32;
-
-                                               for(i = 0; i < 2; i++) d32[i] = b64[i];
-                                               d32 += 2;
-                                               --len2;
-                                       }
-                                       len1 = len1 & 0x07;
-                                       if(len1 != 0) return memcpy(d32, s32, len1);
-                                       return dst;
-                               }
-                               break;
-                       case 0x04:
-                       case 0x0c: 
-                       case 0x14:
-                       case 0x1c: // 32 vs 32
-                               {
-                                       len2 = len1 >> 2;
-                                       while(len2 > 0) {
-                                               *d32 = *s32;
-                                               ++s32;
-                                               ++d32;
-                                               --len2;
-                                       }
-                                       len1 = len1 & 0x03;
-                                       if(len1 != 0) return memcpy(d32, s32, len1);
-                                       return dst;
-                               }
-                               break;
-                       default:
-                               return memcpy(dst, src, len1);
-                               break;
-                       }
-               }
-               break;
-       default:
-               if(len1 != 0) return memcpy(dst, src, len1);
-               break;
-       }
-
-#else
-// Using SIMD *with* un-aligned instructions.
-       register uint32_t *s32 = (uint32_t *)src;
-       register uint32_t *d32 = (uint32_t *)dst;
-       if(((s_align & 0x07) != 0x0) && ((d_align & 0x07) != 0x0)) { // None align.
-               return memcpy(dst, src, len);
-       }
-       if((s_align == 0x0) || (d_align == 0x0)) { // Align to 256bit
-               uint32_t b256[8];
-               len2 = len1 >> 5;
-               while(len2 > 0) {
-                       for(i = 0; i < 8; i++) b256[i] = s32[i];
-                       for(i = 0; i < 8; i++) d32[i] = b256[i];
-                       s32 += 8;
-                       d32 += 8;
-                       --len2;
-               }
-               len1 = len1 & 0x1f;
-               if(len1 != 0) return memcpy(d32, s32, len1);
-               return dst;
-       }
-       if(((s_align & 0x0f) == 0x0) || ((d_align & 0x0f) == 0x0)) { // Align to 128bit
-               uint32_t b128[4];
-               len2 = len1 >> 4;
-               while(len2 > 0) {
-                       for(i = 0; i < 4; i++) b128[i] = s32[i];
-                       for(i = 0; i < 4; i++) d32[i] = b128[i];
-                       s32 += 4;
-                       d32 += 4;
-                       --len2;
-               }
-               len1 = len1 & 0x0f;
-               if(len1 != 0) return memcpy(d32, s32, len1);
-               return dst;
-       }               
-       if(((s_align & 0x07) == 0x0) || ((d_align & 0x07) == 0x0)) { // Align to 64bit
-               uint32_t b64[2];
-               len2 = len1 >> 3;
-               while(len2 > 0) {
-                       for(i = 0; i < 2; i++) b64[i] = s32[i];
-                       for(i = 0; i < 2; i++) d32[i] = b64[i];
-                       s32 += 2;
-                       d32 += 2;
-                       --len2;
-               }
-               len1 = len1 & 0x07;
-               if(len1 != 0) return memcpy(d32, s32, len1);
-               return dst;
-       }               
-       //if(len1 != 0) return memcpy(dst, src, len1);
-#endif
-       // Trap
-       return dst;
+       return memcpy(dst, src, len);
 }
 //#endif
 
@@ -781,6 +399,7 @@ DWORD DLL_PREFIX MyGetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName,
                lpp[0] = '\0';
        }
        FILEIO* fio = new FILEIO();
+       if(!(fio->IsFileExisting(lpFileName))) return 0;
        if(fio->Fopen(lpFileName, FILEIO_READ_ASCII)) {
                bool in_section = false;
                char section[1024], line[1024], *equal;
@@ -869,7 +488,7 @@ uint8_t DLL_PREFIX B_OF_COLOR(scrntype_t c)
 
 uint8_t DLL_PREFIX A_OF_COLOR(scrntype_t c)
 {
-       return 0;
+       return 0xff; //
 }
 #elif defined(_RGB565)
 scrntype_t DLL_PREFIX RGB_COLOR(uint32_t r, uint32_t g, uint32_t b)
@@ -908,10 +527,716 @@ uint8_t DLL_PREFIX B_OF_COLOR(scrntype_t c)
 
 uint8_t DLL_PREFIX A_OF_COLOR(scrntype_t c)
 {
-       return 0;
+       return 0xff; // Alpha = 255
 }
 #endif
 
+// Note: table strongly recommend to be aligned by sizeof(uint16_vec8_t).
+// This is sizeof(uint16) * 8, some compilers may require to align 16bytes(128)
+// when using SIMD128 -- 20181105 K.O
+void DLL_PREFIX PrepareBitTransTableUint16(_bit_trans_table_t *tbl, uint16_t on_val, uint16_t off_val)
+{
+       if(tbl == NULL) return;
+       for(uint16_t i = 0; i < 256; i++) {
+               uint16_t n = i;
+               for(int j = 0; j < 8; j++) {
+                       tbl->plane_table[i].w[j] = ((n & 0x80) == 0) ? off_val : on_val;
+                       n <<= 1;
+               }
+       }
+}
+
+// Note: table strongly recommend to be aligned by sizeof(scrntype_vec8_t).
+// This is sizeof(uint16) * 8, some compilers may require to align 32bytes(256) or 16bytes(128)
+// when using SIMD256 or SIMD128 -- 20181105 K.O
+void DLL_PREFIX PrepareBitTransTableScrnType(_bit_trans_table_scrn_t *tbl, scrntype_t on_val, scrntype_t off_val)
+{
+       if(tbl == NULL) return;
+       for(uint16_t i = 0; i < 256; i++) {
+               uint16_t n = i;
+               for(int j = 0; j < 8; j++) {
+                       tbl->plane_table[i].w[j] = ((n & 0x80) == 0) ? off_val : on_val;
+                       n <<= 1;
+               }
+       }
+}
+
+// Prepare reverse byte-order table(s).
+void DLL_PREFIX PrepareReverseBitTransTableUint16(_bit_trans_table_t *tbl, uint16_t on_val, uint16_t off_val)
+{
+       if(tbl == NULL) return;
+       for(uint16_t i = 0; i < 256; i++) {
+               uint16_t n = i;
+               for(int j = 0; j < 8; j++) {
+                       tbl->plane_table[i].w[j] = ((n & 0x01) == 0) ? off_val : on_val;
+                       n >>= 1;
+               }
+       }
+}
+
+void DLL_PREFIX PrepareReverseBitTransTableScrnType(_bit_trans_table_scrn_t *tbl, scrntype_t on_val, scrntype_t off_val)
+{
+       if(tbl == NULL) return;
+       for(uint16_t i = 0; i < 256; i++) {
+               uint16_t n = i;
+               for(int j = 0; j < 8; j++) {
+                       tbl->plane_table[i].w[j] = ((n & 0x01) == 0) ? off_val : on_val;
+                       n >>= 1;
+               }
+       }
+}
+
+// With _bit_trans_table_scrn_t.
+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)
+{
+       
+    __DECL_ALIGNED(32) scrntype_vec8_t tmpd;
+       __DECL_ALIGNED(32) scrntype_vec8_t tmpdd;
+       __DECL_ALIGNED(32) scrntype_vec8_t colors;
+       scrntype_vec8_t* vt = (scrntype_vec8_t*)__builtin_assume_aligned(&(tbl->plane_table[0]), sizeof(scrntype_vec8_t));
+       
+       uintptr_t disalign = (uintptr_t)dst;
+       disalign = disalign & (sizeof(scrntype_vec8_t) - 1); //Is align by 128bits or 256bytes?
+       if(disalign == 0) {
+               // Yes.
+               scrntype_vec8_t *vdst = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < bytes; i++) {
+                       tmpd.v = vt[src[i]].v;
+                       tmpdd.v = ~tmpd.v;
+                       
+__DECL_VECTORIZED_LOOP
+                       for(int j = 0; j < 8; j++) {
+                               colors.w[j] = on_color_table[j];
+                       }
+                       tmpd.v = tmpd.v & colors.v;
+__DECL_VECTORIZED_LOOP
+                       for(int j = 0; j < 8; j++) {
+                               colors.w[j] = off_color_table[j];
+                       }
+                       tmpdd.v = tmpdd.v & colors.v;
+                       vdst->v = (tmpd.v | tmpdd.v);
+                       off_color_table += 8;
+                       on_color_table += 8;
+                       vdst++;
+               }
+       } else {
+               // Sorry, not aligned.
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < bytes; i++) {
+                       tmpd.v = vt[src[i]].v;
+                       tmpdd.v = ~tmpd.v;
+                       
+__DECL_VECTORIZED_LOOP
+                       for(int j = 0; j < 8; j++) {
+                               colors.w[j] = on_color_table[j];
+                       }
+                       tmpd.v = tmpd.v & colors.v;
+__DECL_VECTORIZED_LOOP
+                       for(int j = 0; j < 8; j++) {
+                               colors.w[j] = off_color_table[j];
+                       }
+                       tmpdd.v = tmpdd.v & colors.v;
+                       tmpdd.v = tmpdd.v | tmpd.v;
+__DECL_VECTORIZED_LOOP
+                       for(int j = 0; j < 8; j++) {
+                               dst[j] = tmpdd.w[j];
+                       }
+                       off_color_table += 8;
+                       on_color_table += 8;
+                       dst += 8;
+               }
+       }
+}
+
+
+// Convert uint8_t[] ed VRAM to uint16_t[] mono pixel pattern.
+// You must set table to "ON_VALUE" : "OFF_VALUE" via PrepareBitTransTableUint16().
+// -- 20181105 K.O
+void DLL_PREFIX ConvertByteToSparceUint16(uint8_t *src, uint16_t* dst, int bytes, _bit_trans_table_t *tbl, uint16_t mask)
+{
+       
+       __DECL_ALIGNED(16) uint16_vec8_t   tmpd;
+       uint16_vec8_t*  vt = (uint16_vec8_t*)__builtin_assume_aligned(&(tbl->plane_table[0]), sizeof(uint16_vec8_t));
+
+       __DECL_ALIGNED(16) uint16_vec8_t __masks;
+
+__DECL_VECTORIZED_LOOP
+       for(int i = 0; i < 8; i++) {
+               __masks.w[i] = mask;
+       }
+       uintptr_t disalign = (uintptr_t)dst;
+       disalign = disalign & 0x0f; //Is align by 128bits?
+       if(disalign == 0) {
+               // Yes.
+               uint16_vec8_t *vdst = (uint16_vec8_t*)__builtin_assume_aligned(dst, sizeof(uint16_vec8_t));
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < bytes; i++) {
+                       tmpd.v = vt[src[i]].v;
+                       tmpd.v = tmpd.v & __masks.v;
+                       vdst->v = tmpd.v;
+                       vdst++;
+               }
+       } else {
+               // Sorry, not aligned.
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < bytes; i++) {
+                       tmpd.v = vt[src[i]].v;
+                       tmpd.v = tmpd.v & __masks.v;
+__DECL_VECTORIZED_LOOP
+                       for(int j = 0; j < 8; j++) {
+                               dst[j] = tmpd.w[j];
+                       }
+                       dst += 8;
+               }
+       }
+}
+
+// Convert uint8_t[] ed VRAM to uint8_t[] mono pixel pattern.
+// You must set table to "ON_VALUE" : "OFF_VALUE" via PrepareBitTransTableUint16().
+// -- 20181105 K.O
+void DLL_PREFIX ConvertByteToSparceUint8(uint8_t *src, uint16_t* dst, int bytes, _bit_trans_table_t *tbl, uint16_t mask)
+{
+       
+       __DECL_ALIGNED(16) uint16_vec8_t   tmpd;
+       uint16_vec8_t*  vt = (uint16_vec8_t*)__builtin_assume_aligned(&(tbl->plane_table[0]), sizeof(uint16_vec8_t));
+
+       __DECL_ALIGNED(16) uint16_vec8_t __masks;
+       __DECL_ALIGNED(16) uint8_vec8_t tmpdd;
+
+__DECL_VECTORIZED_LOOP
+       for(int i = 0; i < 8; i++) {
+               __masks.w[i] = mask;
+       }
+       uintptr_t disalign = (uintptr_t)dst;
+       disalign = disalign & 0x07; //Is align by 128bits?
+       if(disalign == 0) {
+               // Yes.
+               uint8_vec8_t *vdst = (uint8_vec8_t*)__builtin_assume_aligned(dst, sizeof(uint8_vec8_t));
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < bytes; i++) {
+                       tmpd.v = vt[src[i]].v;
+                       tmpd.v = tmpd.v & __masks.v;
+__DECL_VECTORIZED_LOOP
+                       for(int j = 0; j < 8; j++) {
+                               tmpdd.w[j] = (uint8_t)(tmpd.w[j]);
+                       }
+                       vdst->v = tmpdd.v;
+                       vdst++;
+               }
+       } else {
+               // Sorry, not aligned.
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < bytes; i++) {
+                       tmpd.v = vt[src[i]].v;
+                       tmpd.v = tmpd.v & __masks.v;
+__DECL_VECTORIZED_LOOP
+                       for(int j = 0; j < 8; j++) {
+                               dst[j] = (uint8_t)(tmpd.w[j]);
+                       }
+                       dst += 8;
+               }
+       }
+}
+
+
+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)
+{
+       
+       __DECL_ALIGNED(16) uint16_vec8_t   tmpd;
+       __DECL_ALIGNED(32) scrntype_vec8_t tmpdd;
+       uint16_vec8_t*  vt = (uint16_vec8_t*)__builtin_assume_aligned(&(tbl->plane_table[0]), sizeof(uint16_vec8_t));
+       
+       uintptr_t disalign = (uintptr_t)dst;
+       disalign = disalign & 0x0f; //Is align by 128bits?
+       if(disalign == 0) {
+               // Yes.
+               scrntype_vec8_t *vdst = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < bytes; i++) {
+                       tmpd.v = vt[src[i]].v;
+__DECL_VECTORIZED_LOOP
+                       for(int j = 0; j < 8; j++) {
+                               tmpdd.w[j] = (tmpd.w[j] == 0) ? off_color_table[j] : on_color_table[j];
+                       }
+                       vdst->v = tmpdd.v;
+                       off_color_table += 8;
+                       on_color_table += 8;
+                       vdst++;
+               }
+       } else {
+               // Sorry, not aligned.
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < bytes; i++) {
+                       tmpd.v = vt[src[i]].v;
+__DECL_VECTORIZED_LOOP
+                       for(int j = 0; j < 8; j++) {
+                               dst[j] = (tmpd.w[j] == 0) ? off_color_table[j] : on_color_table[j];
+                       }
+                       off_color_table += 8;
+                       on_color_table += 8;
+                       dst += 8;
+               }
+       }
+}
+
+
+void DLL_PREFIX Render8Colors_Line(_render_command_data_t *src, scrntype_t *dst, scrntype_t* dst2, bool scan_line)
+{
+       if(src == NULL) return;
+       if(dst == NULL) return;
+
+//__DECL_VECTORIZED_LOOP
+//     for(int i = 0; i < 3; i++) {
+//             if(src->bit_trans_table[i] == NULL) return;
+//             if(src->data[i] == NULL) return;
+//     }
+       scrntype_t dummy_palette[8]; // fallback
+       scrntype_t *palette = src->palette;
+       
+       uint16_vec8_t *vpb = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[0], sizeof(uint16_vec8_t));
+       uint16_vec8_t *vpr = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[1], sizeof(uint16_vec8_t));
+       uint16_vec8_t *vpg = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[2], sizeof(uint16_vec8_t));
+
+       uint32_t x;
+       __DECL_ALIGNED(16) uint32_t offset[4] = {0};
+       __DECL_ALIGNED(16) uint32_t beginaddr[4] = {0};
+       uint32_t mask = src->addrmask;
+       uint32_t offsetmask = src->addrmask2;
+__DECL_VECTORIZED_LOOP
+       for(int i = 0; i < 3; i++) {
+               offset[i] = src->voffset[i];
+       }
+       if(palette == NULL) {
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < 8; i++) {
+                       dummy_palette[i] = RGB_COLOR(((i & 2) << 5) | 0x1f,
+                                                                                ((i & 4) << 5) | 0x1f,
+                                                                                ((i & 1) << 5) | 0x1f);
+               }
+               palette = dummy_palette;
+       }
+       uint8_t *bp = &(src->data[0][src->baseaddress[0]]);
+       uint8_t *rp = &(src->data[1][src->baseaddress[1]]);
+       uint8_t *gp = &(src->data[2][src->baseaddress[2]]);
+       
+       uint8_t r, g, b;
+       int shift = src->shift;
+       const bool is_render[3] = { src->is_render[0], src->is_render[1],  src->is_render[2] };
+       __DECL_ALIGNED(16) uint16_vec8_t tmpd;
+       __DECL_ALIGNED(32) scrntype_vec8_t tmp_dd; 
+       scrntype_vec8_t* vdp = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
+       
+       x = src->begin_pos;
+       uint32_t n = x;
+       if(dst2 == NULL) {
+       __DECL_VECTORIZED_LOOP
+               for(uint32_t xx = 0; xx < src->render_width; xx++) {
+                       b = (is_render[0]) ? bp[(offset[0] + n) & mask] : 0;
+                       r = (is_render[1]) ? rp[(offset[1] + n) & mask] : 0;
+                       g = (is_render[2]) ? gp[(offset[2] + n) & mask] : 0;
+                       tmpd.v = vpb[b].v;
+                       tmpd.v = tmpd.v | vpr[r].v;
+                       tmpd.v = tmpd.v | vpg[g].v;
+                       tmpd.v = tmpd.v >> shift;
+                       n = (n + 1) & offsetmask;
+       __DECL_VECTORIZED_LOOP
+                       for(int i = 0; i < 8; i++) {
+                               tmp_dd.w[i] = palette[tmpd.w[i]];
+                       }
+                       vdp[xx].v = tmp_dd.v;
+               }
+       } else {
+#if defined(_RGB555) || defined(_RGBA565)
+               static const int shift_factor = 2;
+#else // 24bit
+               static const int shift_factor = 3;
+#endif
+               __DECL_ALIGNED(32) scrntype_vec8_t sline;
+               scrntype_vec8_t* vdp2 = (scrntype_vec8_t*)__builtin_assume_aligned(dst2, sizeof(scrntype_vec8_t));
+       __DECL_VECTORIZED_LOOP
+               for(int i = 0; i < 8; i++) {
+                       sline.w[i] = (scrntype_t)RGBA_COLOR(31, 31, 31, 255);
+               }
+       __DECL_VECTORIZED_LOOP
+               for(uint32_t xx = 0; xx < src->render_width; xx++) {
+                       b = (is_render[0]) ? bp[(offset[0] + n) & mask] : 0;
+                       r = (is_render[1]) ? rp[(offset[1] + n) & mask] : 0;
+                       g = (is_render[2]) ? gp[(offset[2] + n) & mask] : 0;
+                       tmpd.v = vpb[b].v;
+                       tmpd.v = tmpd.v | vpr[r].v;
+                       tmpd.v = tmpd.v | vpg[g].v;
+                       tmpd.v = tmpd.v >> shift;
+                       n = (n + 1) & offsetmask;
+       __DECL_VECTORIZED_LOOP
+                       for(int i = 0; i < 8; i++) {
+                               tmp_dd.w[i] = palette[tmpd.w[i]];
+                       }
+                       vdp[xx].v = tmp_dd.v;
+                       if(scan_line) {
+                               tmp_dd.v = tmp_dd.v >> shift_factor;
+                               tmp_dd.v = tmp_dd.v & sline.v;
+                       }
+                       vdp2[xx].v = tmp_dd.v;
+               }
+       }
+}
+
+void DLL_PREFIX Render16Colors_Line(_render_command_data_t *src, scrntype_t *dst, scrntype_t* dst2, bool scan_line)
+{
+       if(src == NULL) return;
+       if(dst == NULL) return;
+
+//__DECL_VECTORIZED_LOOP
+//     for(int i = 0; i < 3; i++) {
+//             if(src->bit_trans_table[i] == NULL) return;
+//             if(src->data[i] == NULL) return;
+//     }
+       scrntype_t dummy_palette[16]; // fallback
+       scrntype_t *palette = src->palette;
+       
+       uint16_vec8_t *vpb = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[0], sizeof(uint16_vec8_t));
+       uint16_vec8_t *vpr = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[1], sizeof(uint16_vec8_t));
+       uint16_vec8_t *vpg = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[2], sizeof(uint16_vec8_t));
+       uint16_vec8_t *vpn = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[3], sizeof(uint16_vec8_t));
+
+       uint32_t x;
+       __DECL_ALIGNED(16) uint32_t offset[4];
+       __DECL_ALIGNED(16) uint32_t beginaddr[4];
+       uint32_t mask = src->addrmask;
+       uint32_t offsetmask = src->addrmask2;
+       
+__DECL_VECTORIZED_LOOP
+       for(int i = 0; i < 4; i++) {
+               offset[i] = src->voffset[i];
+       }
+       if(palette == NULL) {
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < 16; i++) {
+                       dummy_palette[i] = RGB_COLOR((((i & 2) + (i & 8)) << 4) | 0x0f,
+                                                                                (((i & 4) + (i & 8)) << 4) | 0x0f,
+                                                                                (((i & 1) + (i & 8)) << 4) | 0x0f);
+               }
+               palette = dummy_palette;
+       }
+       uint8_t *bp = &(src->data[0][src->baseaddress[0]]);
+       uint8_t *rp = &(src->data[1][src->baseaddress[1]]);
+       uint8_t *gp = &(src->data[2][src->baseaddress[2]]);
+       uint8_t *np = &(src->data[3][src->baseaddress[3]]);
+       
+       uint8_t r, g, b, n;
+       int shift = src->shift;
+       const bool is_render[4] = { src->is_render[0], src->is_render[1],  src->is_render[2], src->is_render[3] };
+       __DECL_ALIGNED(16) uint16_vec8_t tmpd;
+       __DECL_ALIGNED(32) scrntype_vec8_t tmp_dd; 
+       scrntype_vec8_t* vdp = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
+       
+       x = src->begin_pos;
+       uint32_t xn = x;
+       if(dst2 == NULL) {      
+       __DECL_VECTORIZED_LOOP
+               for(uint32_t xx = 0; xx < src->render_width; xx++) {
+                       b = (is_render[0]) ? bp[(offset[0] + xn) & mask] : 0;
+                       r = (is_render[1]) ? rp[(offset[1] + xn) & mask] : 0;
+                       g = (is_render[2]) ? gp[(offset[2] + xn) & mask] : 0;
+                       n = (is_render[3]) ? np[(offset[3] + xn) & mask] : 0;
+                       tmpd.v = vpb[b].v;
+                       tmpd.v = tmpd.v | vpr[r].v;
+                       tmpd.v = tmpd.v | vpg[g].v;
+                       tmpd.v = tmpd.v | vpn[n].v;
+                       tmpd.v = tmpd.v >> shift;
+                       xn = (xn + 1) & offsetmask;
+       __DECL_VECTORIZED_LOOP
+                       for(int i = 0; i < 8; i++) {
+                               tmp_dd.w[i] = palette[tmpd.w[i]];
+                       }
+                       vdp[xx].v = tmp_dd.v;
+               }
+       } else {
+#if defined(_RGB555) || defined(_RGBA565)
+               static const int shift_factor = 2;
+#else // 24bit
+               static const int shift_factor = 3;
+#endif
+               __DECL_ALIGNED(32) scrntype_vec8_t sline;
+               scrntype_vec8_t* vdp2 = (scrntype_vec8_t*)__builtin_assume_aligned(dst2, sizeof(scrntype_vec8_t));
+       __DECL_VECTORIZED_LOOP
+               for(int i = 0; i < 8; i++) {
+                       sline.w[i] = (scrntype_t)RGBA_COLOR(31, 31, 31, 255);
+               }
+       __DECL_VECTORIZED_LOOP
+               for(uint32_t xx = 0; xx < src->render_width; xx++) {
+                       b = (is_render[0]) ? bp[(offset[0] + xn) & mask] : 0;
+                       r = (is_render[1]) ? rp[(offset[1] + xn) & mask] : 0;
+                       g = (is_render[2]) ? gp[(offset[2] + xn) & mask] : 0;
+                       n = (is_render[3]) ? np[(offset[3] + xn) & mask] : 0;
+                       tmpd.v = vpb[b].v;
+                       tmpd.v = tmpd.v | vpr[r].v;
+                       tmpd.v = tmpd.v | vpg[g].v;
+                       tmpd.v = tmpd.v | vpn[n].v;
+                       tmpd.v = tmpd.v >> shift;
+                       xn = (xn + 1) & offsetmask;
+       __DECL_VECTORIZED_LOOP
+                       for(int i = 0; i < 8; i++) {
+                               tmp_dd.w[i] = palette[tmpd.w[i]];
+                       }
+                       vdp[xx].v = tmp_dd.v;
+                       if(scan_line) {
+                               tmp_dd.v = tmp_dd.v >> shift_factor;
+                               tmp_dd.v = tmp_dd.v & sline.v;
+                       }
+                       vdp2[xx].v = tmp_dd.v;
+               }
+       }
+}
+
+// src->palette Must be 2^planes entries.
+void DLL_PREFIX Render2NColors_Line(_render_command_data_t *src, scrntype_t *dst, scrntype_t* dst2, bool scan_line, int planes)
+{
+       if(src == NULL) return;
+       if(dst == NULL) return;
+       if(src->palette == NULL) return;
+       if(planes <= 0) return;
+       if(planes >= 16) planes = 16;
+//__DECL_VECTORIZED_LOOP
+//     for(int i = 0; i < 3; i++) {
+//             if(src->bit_trans_table[i] == NULL) return;
+//             if(src->data[i] == NULL) return;
+//     }
+       scrntype_t *palette = src->palette;
+       
+       uint16_vec8_t* vp[16];
+       for(int i = 0; i < planes; i++) {
+               vp[i] = (uint16_vec8_t*)__builtin_assume_aligned(src->bit_trans_table[i], sizeof(uint16_vec8_t));
+       }
+
+       uint32_t x;
+       __DECL_ALIGNED(16) uint32_t offset[16];
+       __DECL_ALIGNED(16) uint32_t beginaddr[16];
+       uint32_t mask = src->addrmask;
+       uint32_t offsetmask = src->addrmask2;
+__DECL_VECTORIZED_LOOP
+       for(int i = 0; i < planes; i++) {
+               offset[i] = src->voffset[i];
+       }
+       uint8_t *pp[16];
+       for(int i = 0; i < planes; i++) {
+               pp[i] = &(src->data[i][src->baseaddress[i]]);
+       }
+       
+       uint8_t d[16];
+       int shift = src->shift;
+       const bool is_render[4] = { src->is_render[0], src->is_render[1],  src->is_render[2], src->is_render[3] };
+       __DECL_ALIGNED(16) uint16_vec8_t tmpd;
+       __DECL_ALIGNED(32) scrntype_vec8_t tmp_dd; 
+       scrntype_vec8_t* vdp = (scrntype_vec8_t*)__builtin_assume_aligned(dst, sizeof(scrntype_vec8_t));
+       
+       x = src->begin_pos;
+       if(dst2 == NULL) {
+               uint32_t n = x;
+       __DECL_VECTORIZED_LOOP
+               for(uint32_t xx = 0; xx < src->render_width; xx++) {
+                       d[0] = (is_render[0]) ? pp[0][(offset[0] + n) & mask] : 0;
+                       tmpd.v = vp[0][d[0]].v;
+       __DECL_VECTORIZED_LOOP
+                       for(int i = 1; i < planes; i++) {
+                               d[i] = (is_render[i]) ? pp[i][(offset[i] + n) & mask] : 0;
+                               tmpd.v = tmpd.v | vp[i][d[i]].v;
+                       }
+                       n = (n + 1) & offsetmask;
+                       tmpd.v = tmpd.v >> shift;
+       __DECL_VECTORIZED_LOOP
+                       for(int i = 0; i < 8; i++) {
+                               tmp_dd.w[i] = palette[tmpd.w[i]];
+                       }
+                       vdp[xx].v = tmp_dd.v;
+               }
+       } else {
+#if defined(_RGB555) || defined(_RGBA565)
+               static const int shift_factor = 2;
+#else // 24bit
+               static const int shift_factor = 3;
+#endif
+               __DECL_ALIGNED(32) scrntype_vec8_t sline;
+               scrntype_vec8_t* vdp2 = (scrntype_vec8_t*)__builtin_assume_aligned(dst2, sizeof(scrntype_vec8_t));
+       __DECL_VECTORIZED_LOOP
+               for(int i = 0; i < 8; i++) {
+                       sline.w[i] = (scrntype_t)RGBA_COLOR(31, 31, 31, 255);
+               }
+               uint32_t n = x;
+       __DECL_VECTORIZED_LOOP
+               for(uint32_t xx = 0; xx < src->render_width; xx++) {
+                       d[0] = (is_render[0]) ? pp[0][(offset[0] + n) & mask] : 0;
+                       tmpd.v = vp[0][d[0]].v;
+       __DECL_VECTORIZED_LOOP
+                       for(int i = 1; i < planes; i++) {
+                               d[i] = (is_render[i]) ? pp[i][(offset[i] + n) & mask] : 0;
+                               tmpd.v = tmpd.v | vp[i][d[i]].v;
+                       }
+                       n = (n + 1) & offsetmask;
+                       tmpd.v = tmpd.v >> shift;
+       __DECL_VECTORIZED_LOOP
+                       for(int i = 0; i < 8; i++) {
+                               tmp_dd.w[i] = palette[tmpd.w[i]];
+                       }
+                       vdp[xx].v = tmp_dd.v;
+                       if(scan_line) {
+                               tmp_dd.v = tmp_dd.v >> shift_factor;
+                               tmp_dd.v = tmp_dd.v & sline.v;
+                       }
+                       vdp2[xx].v = tmp_dd.v;
+               }
+       }
+}
+
+void DLL_PREFIX Convert2NColorsToByte_Line(_render_command_data_t *src, uint8_t *dst, int planes)
+{
+       if(planes >= 8) planes = 8;
+       if(planes <= 0) return;
+
+       uint8_t* srcp[8];
+       __DECL_ALIGNED(32) uint32_t offset[8] = {0};
+       __DECL_ALIGNED(16) uint16_vec8_t dat;
+       uint16_vec8_t* bp[8] ;
+               
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < planes; i++) {
+               bp[i] = (uint16_vec8_t*)__builtin_assume_aligned(&(src->bit_trans_table[i]->plane_table[0]), sizeof(uint16_vec8_t));
+               srcp[i] = &(src->data[i][src->baseaddress[i]]);
+       }
+       uint32_t addrmask = src->addrmask;
+       uint32_t offsetmask = src->addrmask2;
+       int shift = src->shift;
+       
+__DECL_VECTORIZED_LOOP
+       for(int i = 0; i < planes; i++) {
+               offset[i] = src->voffset[i];
+       }
+
+       uint32_t noffset = src->begin_pos & offsetmask;
+       uint8_t td[16];
+__DECL_VECTORIZED_LOOP
+       for(int x = 0; x < src->render_width; x++) {
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < planes; i++) {
+                       td[i] = srcp[i][(noffset + offset[i]) & addrmask];
+               }
+               noffset = (noffset + 1) & offsetmask;
+               dat.v = bp[0][td[0]].v;
+__DECL_VECTORIZED_LOOP
+               for(int i = 1; i < planes; i++) {
+                       dat.v = dat.v | bp[i][td[i]].v;
+               }
+               dat.v = dat.v >> shift;
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < 8; i++) {
+                       dst[i] = (uint8_t)(dat.w[i]);
+               }
+               dst += 8;
+               
+       }
+}
+
+void DLL_PREFIX Convert2NColorsToByte_LineZoom2(_render_command_data_t *src, uint8_t *dst, int planes)
+{
+       if(planes >= 8) planes = 8;
+       if(planes <= 0) return;
+
+       uint8_t* srcp[8];
+       __DECL_ALIGNED(32) uint32_t offset[8] = {0};
+       __DECL_ALIGNED(16) uint16_vec8_t dat;
+       uint16_vec8_t* bp[8] ;
+               
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < planes; i++) {
+               bp[i] = (uint16_vec8_t*)__builtin_assume_aligned(&(src->bit_trans_table[i]->plane_table[0]), sizeof(uint16_vec8_t));
+               srcp[i] = &(src->data[i][src->baseaddress[i]]);
+       }
+       uint32_t addrmask = src->addrmask;
+       uint32_t offsetmask = src->addrmask2;
+       int shift = src->shift;
+       
+__DECL_VECTORIZED_LOOP
+       for(int i = 0; i < planes; i++) {
+               offset[i] = src->voffset[i];
+       }
+
+       uint32_t noffset = src->begin_pos & offsetmask;
+       uint8_t td[16];
+__DECL_VECTORIZED_LOOP
+       for(int x = 0; x < src->render_width; x++) {
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < planes; i++) {
+                       td[i] = srcp[i][(noffset + offset[i]) & addrmask];
+               }
+               noffset = (noffset + 1) & offsetmask;
+               dat.v = bp[0][td[0]].v;
+__DECL_VECTORIZED_LOOP
+               for(int i = 1; i < planes; i++) {
+                       dat.v = dat.v | bp[i][td[i]].v;
+               }
+               dat.v = dat.v >> shift;
+__DECL_VECTORIZED_LOOP
+       for(int i = 0, j = 0; i < 16; i +=2, j++) {
+                       dst[i]     = (uint8_t)(dat.w[j]);
+                       dst[i + 1] = (uint8_t)(dat.w[j]);
+               }
+               dst += 16;
+       }
+}
+
+void DLL_PREFIX Convert8ColorsToByte_Line(_render_command_data_t *src, uint8_t *dst)
+{
+       uint8_t *bp = &(src->data[0][src->baseaddress[0]]);
+       uint8_t *rp = &(src->data[1][src->baseaddress[1]]);
+       uint8_t *gp = &(src->data[2][src->baseaddress[2]]);
+       __DECL_ALIGNED(16) uint32_t offset[4] = {0};
+
+       __DECL_ALIGNED(16) uint16_vec8_t rdat;
+       __DECL_ALIGNED(16) uint16_vec8_t gdat;
+       __DECL_ALIGNED(16) uint16_vec8_t bdat;
+       __DECL_ALIGNED(16) uint16_vec8_t tmpd;
+
+       uint16_vec8_t* bpb = (uint16_vec8_t*)__builtin_assume_aligned(&(src->bit_trans_table[0]->plane_table[0]), sizeof(uint16_vec8_t));
+       uint16_vec8_t* bpr = (uint16_vec8_t*)__builtin_assume_aligned(&(src->bit_trans_table[1]->plane_table[0]), sizeof(uint16_vec8_t));
+       uint16_vec8_t* bpg = (uint16_vec8_t*)__builtin_assume_aligned(&(src->bit_trans_table[2]->plane_table[0]), sizeof(uint16_vec8_t));
+       
+       uint32_t addrmask = src->addrmask;
+       uint32_t offsetmask = src->addrmask2;
+       int shift = src->shift;
+       
+__DECL_VECTORIZED_LOOP
+       for(int i = 0; i < 3; i++) {
+               offset[i] = src->voffset[i];
+       }
+
+       uint32_t noffset = src->begin_pos & offsetmask;
+       uint8_t b, r, g;
+__DECL_VECTORIZED_LOOP
+       for(int x = 0; x < src->render_width; x++) {
+               b = bp[(noffset + offset[0]) & addrmask];
+               r = rp[(noffset + offset[1]) & addrmask];
+               g = gp[(noffset + offset[2]) & addrmask];
+
+               noffset = (noffset + 1) & offsetmask;
+               
+               bdat.v = bpb[b].v;
+               rdat.v = bpr[r].v;
+               gdat.v = bpg[g].v;
+               tmpd.v = bdat.v;
+               tmpd.v = tmpd.v | rdat.v;
+               tmpd.v = tmpd.v | gdat.v;
+               tmpd.v = tmpd.v >> shift;
+
+__DECL_VECTORIZED_LOOP
+               for(int i = 0; i < 8; i++) {
+                       dst[i] = (uint8_t)(tmpd.w[i]);
+               }
+               dst += 8;
+       }
+}
+       
+
 #ifndef _MSC_VER
 struct to_upper {  // Refer from documentation of libstdc++, GCC5.
        char operator() (char c) const { return std::toupper(c); }
@@ -1047,6 +1372,23 @@ void DLL_PREFIX create_date_file_path(_TCHAR *file_path, int length, const _TCHA
        my_tcscpy_s(file_path, length, create_date_file_path(extension));
 }
 
+const _TCHAR *DLL_PREFIX create_date_file_name(const _TCHAR *extension)
+{
+       static _TCHAR file_name[8][_MAX_PATH];
+       static unsigned int table_index = 0;
+       unsigned int output_index = (table_index++) & 7;
+       cur_time_t cur_time;
+       
+       get_host_time(&cur_time);
+       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);
+       return (const _TCHAR *)file_name[output_index];
+}
+
+void DLL_PREFIX create_date_file_name(_TCHAR *file_path, int length, const _TCHAR *extension)
+{
+       my_tcscpy_s(file_path, length, create_date_file_name(extension));
+}
+
 bool DLL_PREFIX check_file_extension(const _TCHAR *file_path, const _TCHAR *ext)
 {
 #if defined(_USE_QT)
@@ -1339,7 +1681,7 @@ uint32_t DLL_PREFIX calc_crc32(uint32_t seed, uint8_t data[], int size)
 
 uint16_t DLL_PREFIX jis_to_sjis(uint16_t jis)
 {
-       pair_t tmp;
+       pair32_t tmp;
        
        tmp.w.l = jis - 0x2121;
        if(tmp.w.l & 0x100) {
@@ -1463,105 +1805,22 @@ void DLL_PREFIX cur_time_t::update_day_of_week()
 
 #define STATE_VERSION  1
 
-#include "./state_data.h"
-
-void DLL_PREFIX cur_time_t::save_state_helper(void *f, uint32_t *sumseed, bool *__stat)
-{
-       csp_state_data_saver *state_saver = (csp_state_data_saver *)f;
-       const _TCHAR *_ns = "cur_time_t::BEGIN";
-       const _TCHAR *_ne = "cur_time_t::END";
-       
-       if(f == NULL) return;
-       
-       state_saver->save_string_data(_ns, sumseed, strlen(_ns) + 1, __stat);
-       state_saver->put_dword(STATE_VERSION, sumseed, __stat);
-
-       state_saver->put_int32(year, sumseed, __stat);
-       state_saver->put_int8((int8_t)month, sumseed, __stat);
-       state_saver->put_int8((int8_t)day, sumseed, __stat);
-       state_saver->put_int8((int8_t)day_of_week, sumseed, __stat);
-       state_saver->put_int8((int8_t)hour, sumseed, __stat);
-       state_saver->put_int8((int8_t)minute, sumseed, __stat);
-       state_saver->put_int16((int16_t)second, sumseed, __stat);
-       state_saver->put_bool(initialized, sumseed, __stat);
-       
-       state_saver->save_string_data(_ne, sumseed, strlen(_ne) + 1, __stat);
-}
-
-bool DLL_PREFIX cur_time_t::load_state_helper(void *f, uint32_t *sumseed, bool *__stat)
-{
-       csp_state_data_saver *state_saver = (csp_state_data_saver *)f;
-       const _TCHAR *_ns = "cur_time_t::BEGIN";
-       const _TCHAR *_ne = "cur_time_t::END";
-       _TCHAR sbuf[128];
-       uint32_t tmpvar;
-
-       if(f == NULL) return false;
-       memset(sbuf, 0x00, sizeof(sbuf));
-       state_saver->load_string_data(sbuf, sumseed, strlen(_ns) + 1, __stat);
-       tmpvar = state_saver->get_dword(sumseed, __stat);
-       if(strncmp(sbuf, _ns, strlen(_ns) + 1) != 0) {
-               if(__stat != NULL) *__stat = false;
-               return false;
-       }
-       if(tmpvar != STATE_VERSION) {
-               if(__stat != NULL) *__stat = false;
-               return false;
-       }
-       year =              state_saver->get_int32(sumseed, __stat);
-       month =       (int)(state_saver->get_int8(sumseed, __stat));
-       day =         (int)(state_saver->get_int8(sumseed, __stat));
-       day_of_week = (int)(state_saver->get_int8(sumseed, __stat));
-       hour =        (int)(state_saver->get_int8(sumseed, __stat));
-       minute =      (int)(state_saver->get_int8(sumseed, __stat));
-       second =      (int)(state_saver->get_int16(sumseed, __stat));
-       initialized = state_saver->get_bool(sumseed, __stat);
-       
-       memset(sbuf, 0x00, sizeof(sbuf));
-       state_saver->load_string_data(sbuf, sumseed, strlen(_ne) + 1, __stat);
-       if(strncmp(_ne, sbuf, strlen(_ne) + 1) != 0) {
-               if(__stat != NULL) *__stat = false;
-               return false;
-       }
-       
-       if(__stat != NULL) {
-               if(*__stat == false) return false;
-               //*__stat = true;
-       }
-       return true;
-}
-
-void DLL_PREFIX cur_time_t::save_state(void *f)
-{
-       FILEIO *state_fio = (FILEIO *)f;
-       
-       state_fio->FputUint32(STATE_VERSION);
-       
-       state_fio->FputInt32(year);
-       state_fio->FputInt32(month);
-       state_fio->FputInt32(day);
-       state_fio->FputInt32(day_of_week);
-       state_fio->FputInt32(hour);
-       state_fio->FputInt32(minute);
-       state_fio->FputInt32(second);
-       state_fio->FputBool(initialized);
-}
 
-bool DLL_PREFIX cur_time_t::load_state(void *f)
+bool DLL_PREFIX cur_time_t::process_state(void *f, bool loading)
 {
        FILEIO *state_fio = (FILEIO *)f;
        
-       if(state_fio->FgetUint32() != STATE_VERSION) {
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
                return false;
        }
-       year = state_fio->FgetInt32();
-       month = state_fio->FgetInt32();
-       day = state_fio->FgetInt32();
-       day_of_week = state_fio->FgetInt32();
-       hour = state_fio->FgetInt32();
-       minute = state_fio->FgetInt32();
-       second = state_fio->FgetInt32();
-       initialized = state_fio->FgetBool();
+       state_fio->StateValue(year);
+       state_fio->StateValue(month);
+       state_fio->StateValue(day);
+       state_fio->StateValue(day_of_week);
+       state_fio->StateValue(hour);
+       state_fio->StateValue(minute);
+       state_fio->StateValue(second);
+       state_fio->StateValue(initialized);
        return true;
 }
 
@@ -1645,24 +1904,24 @@ bool DLL_PREFIX set_wav_header(wav_header_t *header, wav_chunk_t *first_chunk, u
        if(header == NULL) return false;
        if(first_chunk == NULL) return false;
 
-       pair_t __riff_chunk_size;
-       pair_t __fmt_chunk_size;
-       pair_t __wav_chunk_size;
+       pair32_t __riff_chunk_size;
+       pair32_t __fmt_chunk_size;
+       pair32_t __wav_chunk_size;
        pair16_t __fmt_id;
        pair16_t __channels;
-       pair_t __sample_rate;
-       pair_t __data_speed;
+       pair32_t __sample_rate;
+       pair32_t __data_speed;
        pair16_t __block_size;
        pair16_t __sample_bits;
 
        __riff_chunk_size.d = length - 8;
        __fmt_chunk_size.d = 16;
-       __fmt_id.w = 1;
-       __channels.w = channels;
+       __fmt_id.u16 = 1;
+       __channels.u16 = channels;
        __sample_rate.d = rate;
-       __block_size.w = (uint16_t)((channels * bits) / 8);
-       __sample_bits.w = bits;
-       __data_speed.d = rate * (uint32_t)(__block_size.w);
+       __block_size.u16 = (uint16_t)((channels * bits) / 8);
+       __sample_bits.u16 = bits;
+       __data_speed.d = rate * (uint32_t)(__block_size.u16);
 
        memcpy(&(header->riff_chunk.id), "RIFF", 4);
        header->riff_chunk.size = __riff_chunk_size.get_4bytes_le_to();
@@ -1709,8 +1968,8 @@ bool DLL_PREFIX load_wav_to_stereo(void *__fio, int16_t **left_buf, int16_t **ri
        pair16_t __fmt_id;
        pair16_t __sample_bits;
        pair16_t __channels;
-       pair_t __sample_rate;
-       pair_t __chunk_size;
+       pair32_t __sample_rate;
+       pair32_t __chunk_size;
 
        fio->Fread(&header, sizeof(header), 1);
        __fmt_id.set_2bytes_le_from(header.format_id);
@@ -1719,7 +1978,7 @@ bool DLL_PREFIX load_wav_to_stereo(void *__fio, int16_t **left_buf, int16_t **ri
        __channels.set_2bytes_le_from(header.channels);
        __sample_rate.set_4bytes_le_from(header.sample_rate);
 
-       if((__fmt_id.w == 1) && ((__sample_bits.w == 8) || (__sample_bits.w == 16) || (__sample_bits.w == 32))) {
+       if((__fmt_id.u16 == 1) && ((__sample_bits.u16 == 8) || (__sample_bits.u16 == 16) || (__sample_bits.u16 == 32))) {
                fio->Fseek(__chunk_size.d - 16, FILEIO_SEEK_CUR);
                bool is_eof = false;
                while(1) {
@@ -1740,7 +1999,7 @@ bool DLL_PREFIX load_wav_to_stereo(void *__fio, int16_t **left_buf, int16_t **ri
                        return false;
                }
                
-               samples = (size_t)(__chunk_size.d / __channels.w);
+               samples = (size_t)(__chunk_size.d / __channels.u16);
                int16_t data_l, data_r;
                union {
                        int16_t s16;
@@ -1756,9 +2015,9 @@ bool DLL_PREFIX load_wav_to_stereo(void *__fio, int16_t **left_buf, int16_t **ri
                } pair32;
                
                if(samples > 0) {
-                       if(__sample_bits.w == 16) {
+                       if(__sample_bits.u16 == 16) {
                                samples /= 2;
-                       } else if(__sample_bits.w == 32) {
+                       } else if(__sample_bits.u16 == 32) {
                                samples /= 4;
                        }
                        if(samples == 0) return false;
@@ -1774,16 +2033,16 @@ bool DLL_PREFIX load_wav_to_stereo(void *__fio, int16_t **left_buf, int16_t **ri
                                if(left_buffer != NULL) free(left_buffer);
                                return false;
                        }
-                       switch(__sample_bits.w) {
+                       switch(__sample_bits.u16) {
                        case 8:
-                               if(__channels.sw == 1) {
+                               if(__channels.s16 == 1) {
                                        for(int i = 0; i < samples; i++) {
                                                data_l = (int16_t)(fio->FgetUint8());
                                                data_l = (data_l - 128) * 256;
                                                left_buffer[i] = data_l;
                                                right_buffer[i] = data_l;
                                        }
-                               } else if(__channels.sw == 2) {
+                               } else if(__channels.s16 == 2) {
                                        for(int i = 0; i < samples; i++) {
                                                data_l = (int16_t)(fio->FgetUint8());
                                                data_l = (data_l - 128) * 256;
@@ -1795,7 +2054,7 @@ bool DLL_PREFIX load_wav_to_stereo(void *__fio, int16_t **left_buf, int16_t **ri
                                }
                                break;
                        case 16:
-                               if(__channels.sw == 1) {
+                               if(__channels.s16 == 1) {
                                        for(int i = 0; i < samples; i++) {
                                                pair16.b.l = fio->FgetUint8();
                                                pair16.b.h = fio->FgetUint8();
@@ -1804,7 +2063,7 @@ bool DLL_PREFIX load_wav_to_stereo(void *__fio, int16_t **left_buf, int16_t **ri
                                                left_buffer[i] = data_l;
                                                right_buffer[i] = data_l;
                                        }
-                               } else if(__channels.sw == 2) {
+                               } else if(__channels.s16 == 2) {
                                        for(int i = 0; i < samples; i++) {
                                                pair16.b.l = fio->FgetUint8();
                                                pair16.b.h = fio->FgetUint8();
@@ -1819,7 +2078,7 @@ bool DLL_PREFIX load_wav_to_stereo(void *__fio, int16_t **left_buf, int16_t **ri
                                }
                                break;
                        case 32:
-                               if(__channels.sw == 1) {
+                               if(__channels.s16 == 1) {
                                        for(int i = 0; i < samples; i++) {
                                                pair32.b.l = fio->FgetUint8();
                                                pair32.b.h = fio->FgetUint8();
@@ -1830,7 +2089,7 @@ bool DLL_PREFIX load_wav_to_stereo(void *__fio, int16_t **left_buf, int16_t **ri
                                                left_buffer[i] = data_l;
                                                right_buffer[i] = data_l;
                                        }
-                               } else if(__channels.sw == 2) {
+                               } else if(__channels.s16 == 2) {
                                        for(int i = 0; i < samples; i++) {
                                                pair32.b.l = fio->FgetUint8();
                                                pair32.b.h = fio->FgetUint8();
@@ -1886,8 +2145,8 @@ bool DLL_PREFIX load_wav_to_monoral(void *__fio, int16_t **buffer, uint32_t *rat
        pair16_t __fmt_id;
        pair16_t __sample_bits;
        pair16_t __channels;
-       pair_t __sample_rate;
-       pair_t __chunk_size;
+       pair32_t __sample_rate;
+       pair32_t __chunk_size;
 
        fio->Fread(&header, sizeof(header), 1);
        __fmt_id.set_2bytes_le_from(header.format_id);
@@ -1896,7 +2155,7 @@ bool DLL_PREFIX load_wav_to_monoral(void *__fio, int16_t **buffer, uint32_t *rat
        __channels.set_2bytes_le_from(header.channels);
        __sample_rate.set_4bytes_le_from(header.sample_rate);
 
-       if((__fmt_id.w == 1) && ((__sample_bits.w == 8) || (__sample_bits.w == 16) || (__sample_bits.w == 32))) {
+       if((__fmt_id.u16 == 1) && ((__sample_bits.u16 == 8) || (__sample_bits.u16 == 16) || (__sample_bits.u16 == 32))) {
                fio->Fseek(__chunk_size.d - 16, FILEIO_SEEK_CUR);
                bool is_eof = false;
                while(1) {
@@ -1917,7 +2176,7 @@ bool DLL_PREFIX load_wav_to_monoral(void *__fio, int16_t **buffer, uint32_t *rat
                        return false;
                }
                
-               samples = (size_t)(__chunk_size.d / __channels.w);
+               samples = (size_t)(__chunk_size.d / __channels.u16);
                int16_t data_l, data_r;
                int32_t data32_l, data32_r;
                union {
@@ -1934,9 +2193,9 @@ bool DLL_PREFIX load_wav_to_monoral(void *__fio, int16_t **buffer, uint32_t *rat
                } pair32;
                
                if(samples > 0) {
-                       if(__sample_bits.w == 16) {
+                       if(__sample_bits.u16 == 16) {
                                samples /= 2;
-                       } else if(__sample_bits.w == 32) {
+                       } else if(__sample_bits.u16 == 32) {
                                samples /= 4;
                        }
                        if(samples == 0) return false;
@@ -1946,15 +2205,15 @@ bool DLL_PREFIX load_wav_to_monoral(void *__fio, int16_t **buffer, uint32_t *rat
                        if(left_buffer == NULL) {
                                return false;
                        }
-                       switch(__sample_bits.w) {
+                       switch(__sample_bits.u16) {
                        case 8:
-                               if(__channels.sw == 1) {
+                               if(__channels.s16 == 1) {
                                        for(int i = 0; i < samples; i++) {
                                                data_l = (int16_t)(fio->FgetUint8());
                                                data_l = (data_l - 128) * 256;
                                                left_buffer[i] = data_l;
                                        }
-                               } else if(__channels.sw == 2) {
+                               } else if(__channels.s16 == 2) {
                                        for(int i = 0; i < samples; i++) {
                                                data_l = (int16_t)(fio->FgetUint8());
                                                data_l = (data_l - 128) * 256;
@@ -1965,7 +2224,7 @@ bool DLL_PREFIX load_wav_to_monoral(void *__fio, int16_t **buffer, uint32_t *rat
                                }
                                break;
                        case 16:
-                               if(__channels.sw == 1) {
+                               if(__channels.s16 == 1) {
                                        for(int i = 0; i < samples; i++) {
                                                pair16.b.l = fio->FgetUint8();
                                                pair16.b.h = fio->FgetUint8();
@@ -1973,7 +2232,7 @@ bool DLL_PREFIX load_wav_to_monoral(void *__fio, int16_t **buffer, uint32_t *rat
                                                
                                                left_buffer[i] = data_l;
                                        }
-                               } else if(__channels.sw == 2) {
+                               } else if(__channels.s16 == 2) {
                                        for(int i = 0; i < samples; i++) {
                                                pair16.b.l = fio->FgetUint8();
                                                pair16.b.h = fio->FgetUint8();
@@ -1987,7 +2246,7 @@ bool DLL_PREFIX load_wav_to_monoral(void *__fio, int16_t **buffer, uint32_t *rat
                                }
                                break;
                        case 32:
-                               if(__channels.sw == 1) {
+                               if(__channels.s16 == 1) {
                                        for(int i = 0; i < samples; i++) {
                                                pair32.b.l = fio->FgetUint8();
                                                pair32.b.h = fio->FgetUint8();
@@ -1997,7 +2256,7 @@ bool DLL_PREFIX load_wav_to_monoral(void *__fio, int16_t **buffer, uint32_t *rat
                                                
                                                left_buffer[i] = data_l;
                                        }
-                               } else if(__channels.sw == 2) {
+                               } else if(__channels.s16 == 2) {
                                        for(int i = 0; i < samples; i++) {
                                                pair32.b.l = fio->FgetUint8();
                                                pair32.b.h = fio->FgetUint8();