Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. #include "std.h"
  2.  
  3. #include "emul.h"
  4. #include "vars.h"
  5. #include "snapshot.h"
  6. #include "init.h"
  7.  
  8. #include "util.h"
  9.  
  10. #include "emul_no_modal_windows.h"      // hwnd-ы немодальных окон [NS]
  11.  
  12.  
  13. // для передачи кодов клавишь в качестве результата функции
  14. int key_down_oem_key = 0;                       // [NS]
  15. unsigned char key_down_kbdpc_key = 0;   // [NS]
  16. int key_down_v_key = 0;                         // [NS]
  17.  
  18.  
  19.  
  20. //=============================================================================
  21. static void cpuid( unsigned CpuInfo[ 4], unsigned _eax)
  22. {
  23. //-----------------------------------------------------------------------------
  24. #ifdef _MSC_VER
  25.     __cpuid((int *)CpuInfo, int(_eax));
  26. #endif
  27. //-----------------------------------------------------------------------------
  28. #ifdef __GNUC__
  29. #ifdef __clang__
  30.     __cpuid((int *)CpuInfo, _eax);
  31. #else
  32.     __cpuid(_eax, CpuInfo[0], CpuInfo[1], CpuInfo[2], CpuInfo[3]);
  33. #endif // __clang__
  34. #endif
  35. //-----------------------------------------------------------------------------
  36. }
  37. //=============================================================================
  38.  
  39.  
  40. //=============================================================================
  41. void fillCpuString( char dst[ 49])
  42. {
  43.     dst[0] = dst[12] = dst[48] = 0;
  44.     unsigned CpuInfo[4];
  45.     unsigned *d = (unsigned *)dst;
  46.  
  47.     cpuid( CpuInfo, 0x80000000);
  48.     //-------------------------------------------------------------------------
  49.     if (CpuInfo[0] < 0x80000004)
  50.     {
  51.         cpuid( CpuInfo, 0);
  52.         d[0] = CpuInfo[1];
  53.         d[1] = CpuInfo[3];
  54.         d[2] = CpuInfo[2];
  55.         return;
  56.     }
  57.     //-------------------------------------------------------------------------
  58.     cpuid( CpuInfo, 0x80000002);
  59.     d[ 0] = CpuInfo[0];
  60.     d[ 1] = CpuInfo[1];
  61.     d[ 2] = CpuInfo[2];
  62.     d[ 3] = CpuInfo[3];
  63.     //-------------------------------------------------------------------------
  64.     cpuid( CpuInfo, 0x80000003);
  65.     d[ 4] = CpuInfo[0];
  66.     d[ 5] = CpuInfo[1];
  67.     d[ 6] = CpuInfo[2];
  68.     d[ 7] = CpuInfo[3];
  69.     //-------------------------------------------------------------------------
  70.     cpuid( CpuInfo, 0x80000004);
  71.     d[ 8] = CpuInfo[0];
  72.     d[ 9] = CpuInfo[1];
  73.     d[10] = CpuInfo[2];
  74.     d[11] = CpuInfo[3];
  75.     //-------------------------------------------------------------------------
  76. }
  77. //=============================================================================
  78.  
  79.  
  80. //=============================================================================
  81. unsigned cpuid(unsigned _eax, int ext)
  82. {
  83.     unsigned CpuInfo[ 4];
  84.  
  85.     cpuid( CpuInfo, _eax);
  86.  
  87.     return ext    ?     CpuInfo[3] :
  88.                         CpuInfo[0];
  89. }
  90. //=============================================================================
  91.  
  92.  
  93. //=============================================================================
  94. unsigned __int64 GetCPUFrequency()
  95. {
  96.     LARGE_INTEGER Frequency;
  97.     LARGE_INTEGER Start;
  98.     LARGE_INTEGER Stop;
  99.     unsigned long long c1;
  100.     unsigned long long c2;
  101.  
  102.     QueryPerformanceFrequency( &Frequency);
  103.     LONGLONG t = Frequency.QuadPart >> 3;
  104.     c1 = rdtsc();
  105.     QueryPerformanceCounter( &Start);
  106.     //-------------------------------------------------------------------------
  107.     do
  108.     {
  109.         QueryPerformanceCounter( &Stop);
  110.     }
  111.     while ((Stop.QuadPart - Start.QuadPart) < t);
  112.     //-------------------------------------------------------------------------
  113.     c2 = rdtsc();
  114.  
  115.     return (c2 - c1) << 3;
  116. }
  117. //=============================================================================
  118.  
  119.  
  120. //=============================================================================
  121. void trim(char *dst)
  122. {
  123.     size_t i = strlen(dst);
  124.     //-------------------------------------------------------------------------
  125.     // trim right spaces
  126.     while (i && isspace( u8( dst[ i - 1])))
  127.         i--;
  128.     //-------------------------------------------------------------------------
  129.     dst[i] = 0;
  130.     //-------------------------------------------------------------------------
  131.     // trim left spaces
  132.     for (i = 0;   isspace( u8( dst[ i]));   i++);
  133.     //-------------------------------------------------------------------------
  134.     strcpy( dst, dst+i);
  135. }
  136. //=============================================================================
  137.  
  138. const char nop = 0;
  139. const char * const nil = &nop;
  140.  
  141. //=============================================================================
  142. int ishex(char c)
  143. {
  144.     return (isdigit( c) || (tolower( c) >= 'a' && tolower( c) <= 'f'));
  145. }
  146. //=============================================================================
  147.  
  148.  
  149. //=============================================================================
  150. unsigned char hex( char p)
  151. {
  152.     p = char( tolower( p));
  153.     return u8(( p < 'a') ? p-'0' : p-'a'+10);
  154. }
  155. //=============================================================================
  156.  
  157.  
  158. //=============================================================================
  159. unsigned char hex( const char *p)
  160. {
  161.     return 0x10 * hex( p[0]) + hex( p[1]);
  162. }
  163. //=============================================================================
  164.  
  165.  
  166. //=============================================================================
  167. unsigned process_msgs()
  168. {
  169.     MSG msg;
  170.     unsigned key = 0;           // для return V_KEY
  171.  
  172.     // глобальные переменные
  173.     key_down_oem_key = 0;       // [NS]
  174.     key_down_kbdpc_key = 0;     // [NS]
  175.     key_down_v_key = 0;         // [NS]
  176.            
  177.     //printf("msgs ");
  178.  
  179.     //-------------------------------------------------------------------------
  180.     while (PeekMessage( &msg, nullptr, 0, 0, PM_REMOVE))
  181.     {
  182.        
  183.         // IsDialogMessage вроде какпроверяет сообщение ли это для нужного hwnd
  184.         // и если для него то отправляет и возвращает TRUE
  185.         //---------------------------------------------------------------------
  186.         // немодальное окна бряков [NS]                    //
  187.         if (hwnd_bp_dialog != NULL)                     // hwnd существует
  188.             if (IsDialogMessage( hwnd_bp_dialog, &msg)) // сообщение для hwnd
  189.                 continue;                               // значит сообение не для main window !!!
  190.         //---------------------------------------------------------------------
  191.         // немодальное окна вачесов [NS]          //
  192.         if (hwnd_watchdlg != NULL)                      // hwnd существует
  193.             if (IsDialogMessage( hwnd_watchdlg, &msg))  // сообщение для hwnd
  194.                 continue;                               // значит сообение не для main window !!!
  195.         //---------------------------------------------------------------------
  196.        
  197.        
  198.        
  199.         /*
  200.         if (msg.message == WM_NCLBUTTONDOWN)
  201.             continue;
  202.         */
  203.  
  204.  
  205.         // можот добавить обработку паузы прямо сюда еще ?
  206.  
  207. // WM_LBUTTONDOWN WM_LBUTTONUP WM_LBUTTONDBLCLK
  208. // WM_MBUTTONDOWN WM_MBUTTONUP WM_MBUTTONDBLCLK
  209. // WM_RBUTTONDOWN WM_RBUTTONUP WM_RBUTTONDBLCLK
  210.  
  211.  
  212.         //---------------------------------------------------------------------
  213.         // mouse messages must be processed further
  214.         if (msg.message == WM_LBUTTONDBLCLK)
  215.         {
  216.             debug_mouse_keys |= DEBUG_MOUSE_LEFT_DBL;
  217.             mousepos = DWORD( msg.lParam);
  218.             key = VK_LMB;
  219.         }
  220.         //---------------------------------------------------------------------
  221.         if (msg.message == WM_LBUTTONDOWN)
  222.         {
  223.             debug_mouse_keys |= DEBUG_MOUSE_LEFT_ON;
  224.             mousepos = DWORD( msg.lParam);
  225.             key = VK_LMB;
  226.         }
  227.         //---------------------------------------------------------------------
  228.         if (msg.message == WM_RBUTTONDOWN)
  229.         {
  230.             debug_mouse_keys |= DEBUG_MOUSE_RIGHT_ON;
  231.             // видимо оно ТУПО ИГНОРИТ
  232.             // то что мыша может летать по координате 0x8000+
  233.             mousepos = DWORD( msg.lParam | 0x80000000); // ВЫПИЛИТЬ НАХ!!!
  234.             key = VK_RMB;
  235.         }
  236.         //---------------------------------------------------------------------
  237.         if (msg.message == WM_MBUTTONDOWN)
  238.         {
  239.             mousepos = DWORD( msg.lParam | 0x80000000); // ВЫПИЛИТЬ НАХ!!!
  240.             key = VK_MMB;
  241.         }
  242.         //---------------------------------------------------------------------
  243.         // [vv] Process mouse whell only in client area
  244.         if (msg.message == WM_MOUSEWHEEL)
  245.         {
  246.             //-----------------------------------------------------------------
  247.             POINT Pos =
  248.             {
  249.                 GET_X_LPARAM( msg.lParam),
  250.                 GET_Y_LPARAM( msg.lParam)
  251.             };
  252.             //-----------------------------------------------------------------
  253.             RECT ClientRect;
  254.             GetClientRect( msg.hwnd, &ClientRect);
  255.             MapWindowPoints( msg.hwnd, HWND_DESKTOP, (LPPOINT) &ClientRect, 2);
  256.             //-----------------------------------------------------------------
  257.             if (PtInRect( &ClientRect, Pos))
  258.             {
  259.                 key = GET_WHEEL_DELTA_WPARAM( msg.wParam) < 0  ?  VK_MWD :
  260.                                                                   VK_MWU;
  261.                 //printf("whell %x\n",key);
  262.             }
  263.             //-----------------------------------------------------------------
  264.         }
  265.         //---------------------------------------------------------------------
  266.         // WM_KEYDOWN and WM_SYSKEYDOWN must not be dispatched,
  267.         // bcoz window will be closed on alt-f4
  268.         if ((msg.message == WM_KEYDOWN) || (msg.message == WM_SYSKEYDOWN))
  269.         {
  270.             //-----------------------------------------------------------------
  271.             // wparam
  272.             //     V_KEY
  273.             //-----------------------------------------------------------------
  274.             // lparam
  275.             //     d31 - Transition State               0x8000
  276.             //     d30 - Previos Key State              0x4000
  277.             //     d29 - Context Code                   0x2000
  278.             //               1 - alt pressed
  279.             //     d28...d25                           
  280.             //     d24 - Extended Key Flag              0x100
  281.             //     d23...d16 - 8-Bit OEM Scan Code
  282.             //     d15...d0 - 16-Bit Repeat Count
  283.             //-----------------------------------------------------------------
  284.             if (conf.atm.xt_kbd)
  285.             {
  286.                
  287.                 input.atm51.setkey( unsigned( msg.lParam >> 16), 1);
  288.             }
  289.             //  тобешь щас xt клава вообще не работает без глобального отключения хоткеев !!!!
  290.             //  что есть не пральна?
  291.             //-----------------------------------------------------------------
  292.             switch ((msg.lParam >> 16) & 0x1FF)
  293.             {
  294.                 case 0x02A:     kbdpcEX[0] = (kbdpcEX[0] ^ 0x01) | 0x80;        break;  //XT LShift
  295.                 case 0x036:     kbdpcEX[1] = (kbdpcEX[1] ^ 0x01) | 0x80;        break;  //XT RShift
  296.                 case 0x01D:     kbdpcEX[2] = (kbdpcEX[2] ^ 0x01) | 0x80;        break;  //XT LCtrl
  297.                 case 0x11D:     kbdpcEX[3] = (kbdpcEX[3] ^ 0x01) | 0x80;        break;  //XT RCtrl ???
  298.                 case 0x038:     kbdpcEX[4] = (kbdpcEX[4] ^ 0x01) | 0x80;        break;  //XT LAlt
  299.                 case 0x138:     kbdpcEX[5] = (kbdpcEX[5] ^ 0x01) | 0x80;        break;  //XT RAlt ???
  300.             } //Dexus
  301.             //-----------------------------------------------------------------
  302. //          printf("%s, WM_KEYDOWN, WM_SYSKEYDOWN\n", __FUNCTION__);
  303.                 //printf("V_KEY %02X\n",( msg.wParam));
  304.                 //printf("oem key %X\n",( msg.lParam >> 16));
  305.             key = unsigned( msg.wParam);
  306.             // тут был бы полезен oem scan code...
  307.            
  308.             // глобальные переменные
  309.             key_down_oem_key = (msg.lParam >> 16);      // [NS]
  310.             key_down_v_key = msg.wParam;                // [NS]
  311.            
  312.                 //  oem - kbdpc
  313.                 //
  314.                 // 4000 - АВТОПОВТОР
  315.                 // 2000 - ALT+
  316.                 // 0100 - ext key
  317.                 //
  318.                 //  152 - D2            insert
  319.                 //  153 - D3            del
  320.                 //   45 - C5            pause   (иссключениe)
  321.                 //  15B - DB            lwin
  322.                 //  15C - DC            rwin
  323.                 // 2038 - 38            lalt
  324.                 // 2138 - B8            ralt
  325.                 //  15D - DD            menu
  326.                 //  11D - 9D            rctrl
  327.                 //  149 - C9            pg up
  328.                 //  151 - D1            pg down
  329.                 //  14B - CB            left
  330.                 //  14D - CD            right
  331.                 //  148 - C8            up
  332.                 //  150 - D0            down
  333.                 //  145 - 45            numlock (иссключениe)
  334.                 //  135 - B5            num "/"
  335.                 //  11C - 9C            num enter
  336.                 //  147 - C7            home
  337.                 //  14F - CF            end
  338.                 //  146 - C6            break
  339.                 //
  340.                 //  119 - 99    player next
  341.                 //  110 - 90    player prew
  342.                 //  124 - A4    player stop
  343.                 //  122 - A2    player play\pause
  344.                 //
  345.                 //
  346.                 //
  347.                 // иссключения
  348.                 // 45 -> С5 pause
  349.                 // 145 -> 45 numlock
  350.  
  351.                 // конфликты
  352.                 // oem - wvk - kbdpc
  353.                 //  1D -  11 - 1D       lctrl (нормальный вариант)
  354.                 //
  355.                 // 11D -  11 - 9D       rctrl (нормальный вариант)
  356.                 //  E0 -  11 -          rctrl (win osk)
  357.                 //
  358.                 // 145 -  90 - 45       numlock (нормальный вариант)
  359.                 //  45 -  90 - 45       numlock (win osk)
  360.                 //
  361.                 //  45 -  13 - C5       pause   (иссключениe)
  362.                 //  E1 -  13 -          brk (win osk)
  363.                 //
  364.                 // 146 -  03 - C6       break (нормальный вариант)
  365.  
  366.  
  367.  
  368.             //-----------------------------------------------------------------
  369.             // numlock (обычный?)
  370.             if ((key_down_oem_key & 0x1FF) == 0x145)           
  371.             {
  372.                 key_down_kbdpc_key = 0x45;      // исключение
  373.             }
  374.             //-----------------------------------------------------------------
  375.             // numlock (win osk)
  376.             else if (   ((key_down_oem_key & 0x1FF) == 0x045)   &&
  377.                         (key_down_v_key == 0x90) // дополнительная проверка
  378.                )
  379.             {
  380.                 key_down_kbdpc_key = 0x45;      // исключение
  381.             }
  382.             //-----------------------------------------------------------------
  383.             // pause (обычная?)
  384.             else if ((key_down_oem_key & 0x1FF) == 0x045)              
  385.             {
  386.                 key_down_kbdpc_key = 0xC5;      // исключение
  387.             }
  388.             //-----------------------------------------------------------------
  389.             // brk (win osk) вместо pause почему то
  390.             else if (   ((key_down_oem_key & 0x1FF) == 0x0E1)   &&
  391.                         (key_down_v_key == 0x13) // дополнительная проверка
  392.                )
  393.             {
  394.                 key_down_kbdpc_key = 0xC5;      // исключение
  395.             }
  396.             //-----------------------------------------------------------------
  397.             // rctrl (win osk)
  398.             else if (   ((key_down_oem_key & 0x1FF) == 0x0E0)   &&
  399.                         (key_down_v_key == 0x11) // дополнительная проверка
  400.                )
  401.             {
  402.                 key_down_kbdpc_key = 0x9D;      // исключение
  403.                 // E0 - все равно при этом проскакивает !!!
  404.                 // через readdevice()
  405.             }
  406.             //-----------------------------------------------------------------
  407.             // 0x1xx - ext key
  408.             else if (key_down_oem_key & 0x100)                 
  409.             {
  410.                 key_down_kbdpc_key = key_down_oem_key | 0x80;
  411.             }
  412.             //-----------------------------------------------------------------
  413.             // 0x0xx - simple key
  414.             else                                               
  415.             {
  416.                 key_down_kbdpc_key = (key_down_oem_key & 0xFF);         //0x7F);
  417.                 // win osk вполне себе шлет всякие E0, E1
  418.                 // так что пусть будет 0xFF
  419.             }
  420.             //-----------------------------------------------------------------
  421.         }
  422.         //---------------------------------------------------------------------
  423.         else if ((msg.message == WM_KEYUP) || (msg.message == WM_SYSKEYUP))
  424.         {
  425.             //-----------------------------------------------------------------
  426.             if (conf.atm.xt_kbd)
  427.                 input.atm51.setkey( unsigned( msg.lParam >> 16), 0);
  428.             //-----------------------------------------------------------------
  429.             switch (( msg.lParam >> 16) & 0x1FF)
  430.             {
  431.                 case 0x02A:     kbdpcEX[0] &= 0x01; kbdpcEX[1] &= 0x01; break;  //XT LShift
  432.                 case 0x036:     kbdpcEX[0] &= 0x01; kbdpcEX[1] &= 0x01; break;  //XT RShift
  433.                 case 0x01D:     kbdpcEX[2] &= 0x01;                     break;  //XT LCtrl
  434.                 case 0x11D:     kbdpcEX[3] &= 0x01;                     break;  //XT RCtrl ???
  435.                 case 0x038:     kbdpcEX[4] &= 0x01;                     break;  //XT LAlt
  436.                 case 0x138:     kbdpcEX[5] &= 0x01;                     break;  //XT RAlt ???
  437.             } //Dexus
  438.             //-----------------------------------------------------------------
  439. //          printf("%s, WM_KEYUP, WM_SYSKEYUP\n", __FUNCTION__);
  440. //          DispatchMessage(&msg); //Dexus
  441.         }
  442.         //---------------------------------------------------------------------
  443.         if (    !((WM_KEYFIRST <= msg.message) && (msg.message <= WM_KEYLAST))
  444.                 ||
  445.                 ((WM_MOUSEFIRST <= msg.message) && (msg.message <= WM_MOUSELAST))
  446.          )
  447.         {
  448.             DispatchMessage( &msg);
  449.         }
  450.         //---------------------------------------------------------------------
  451.     }
  452.     //-------------------------------------------------------------------------
  453.     return key;
  454. }
  455. //=============================================================================
  456.  
  457.  
  458. //=============================================================================
  459. // eat messages
  460. void eat()
  461. {
  462.     //printf("EAT ");
  463.     Sleep( 20);
  464.     //-------------------------------------------------------------------------
  465.     while (process_msgs())
  466.         Sleep( 10);
  467.     //-------------------------------------------------------------------------
  468. }
  469. //=============================================================================
  470.  
  471.  
  472.  
  473.  
  474.  
  475. /*
  476. //=============================================================================
  477. // эксперемментальная kbdpc_prev вверрсия
  478. // рабочая ниже
  479. // Опрос клавы по таблице хоткеев
  480. bool dispatch_more( action *table)
  481. {
  482.     //printf("more\n");
  483.     //-------------------------------------------------------------------------
  484.     if (!table)
  485.         return false;
  486.     //-------------------------------------------------------------------------
  487.     u8 tmp = kbdpc_prev[0];
  488.     kbdpc_prev[0] = 0x80;       // nil button is always pressed
  489.     //-------------------------------------------------------------------------
  490. //   __debugbreak();
  491.     while (table->name)
  492.     {
  493. //      printf("table->name %s\n",table->name);
  494. //      printf("%02X|%02X|%02X|%02X\n", table->k1, table->k2, table->k3, table->k4);
  495.        
  496.         if (0) //(table->k1 == 0xC5)    // debug        //45
  497.         {
  498.         printf("%x|%x|%x|%x brute\n", table->k1, table->k2, table->k3, table->k4);
  499.        
  500.                 for (int temp = 0;    temp < 256;   temp++)     //VK_MAX
  501.                 {
  502.                
  503.                         if(kbdpc_prev[temp])
  504.                         printf("%02x ",kbdpc_prev[temp]);
  505.                         else
  506.                         printf(".. ");
  507.                         if ((temp % 16) == 15) printf("\n");
  508.                 }
  509.                 printf("\n");
  510.         }
  511.         //---------------------------------------------------------------------
  512.         unsigned k[4] =
  513.         {
  514.             table->k1,
  515.             table->k2,
  516.             table->k3,
  517.             table->k4
  518.         };
  519.         unsigned b[4];
  520.         //---------------------------------------------------------------------
  521.         for (unsigned i = 0;   i < 4;   i++)
  522.         {
  523.             switch (k[ i])
  524.             {
  525.                 //-------------------------------------------------------------
  526.                 // игнор левости правости?
  527.                 // но оно же предлагаетсо вводить в конфиге
  528.                 // слевостями и праавостями?
  529.                 case DIK_MENU:
  530.                     b[i] = kbdpc_prev[ DIK_LMENU] | kbdpc_prev[ DIK_RMENU]; // Alt
  531.                         if (table->k1 == 0xc5)
  532.                         {
  533.                         printf("DIK_RMENU %x\n",b[i]);
  534.                         }
  535.                     break;
  536.                 //-------------------------------------------------------------
  537.                 case DIK_CONTROL:
  538.                     b[i] = kbdpc_prev[ DIK_LCONTROL] | kbdpc_prev[ DIK_RCONTROL];
  539.                         if (table->k1 == 0xc5)
  540.                         {
  541.                         printf("DIK_LCONTROL %x\n",b[i]);
  542.                         }
  543.                     break;
  544.                 //-------------------------------------------------------------
  545.                 case DIK_SHIFT:
  546.                     b[i] = kbdpc_prev[ DIK_LSHIFT] | kbdpc_prev[ DIK_RSHIFT];
  547.                         if (table->k1 == 0xc5)
  548.                         {
  549.                         printf("DIK_LSHIFT %x\n",b[i]);
  550.                         }
  551.                     break;
  552.                 //-------------------------------------------------------------
  553.                 default:
  554.                     b[i] = kbdpc_prev[ k[ i]];
  555.                         if (table->k1 == 0xc5)
  556.                         {
  557.                         printf("kbdpc_prev[ k[ i] %x\n",b[i]);
  558.                         }
  559.                 //-------------------------------------------------------------
  560.             }
  561.         }
  562.         //---------------------------------------------------------------------
  563.         //printf("b[0]b[1]b[2]b[3] %x %x %x %x\n",b[0],b[1],b[2],b[3]);
  564.         if (b[0] & b[1] & b[2] & b[3] & 0x80)
  565.         {
  566.             printf("    func %x\n",table->k1);
  567.             table->func();      // это каким то хуем вызывает функцию из таблицы
  568.             kbdpc_prev[0] = tmp;
  569.             return true;
  570.         }
  571.         //---------------------------------------------------------------------
  572.         table++;
  573.         //---------------------------------------------------------------------
  574.     }
  575.     //-------------------------------------------------------------------------
  576.     kbdpc_prev[0] = tmp;
  577.     return false;
  578. }
  579. //=============================================================================
  580. */
  581.  
  582.  
  583.  
  584. //=============================================================================
  585. // Опрос клавы по таблице хоткеев
  586. bool dispatch_more( action *table)
  587. {
  588.     //printf("more\n");
  589.     //-------------------------------------------------------------------------
  590.     if (!table)
  591.         return false;
  592.     //-------------------------------------------------------------------------
  593.     u8 tmp = kbdpc[0];
  594.     kbdpc[0] = 0x80;    // nil button is always pressed
  595.     //-------------------------------------------------------------------------
  596. //   __debugbreak();
  597.  
  598.         //      // tzt
  599.         //      for (int temp = 1;    temp < 256;   temp++)     //VK_MAX
  600.         //      {
  601.         //          if (kbdpc[ temp])
  602.         //              printf("%02X - %02x\n", temp,kbdpc[ temp]);
  603.         //      }// tzt
  604.                
  605.     while (table->name)
  606.     {
  607. //      printf("table->name %s\n",table->name);
  608. //      printf("%02X|%02X|%02X|%02X\n", table->k1, table->k2, table->k3, table->k4);
  609.        
  610.         //if (table->k1 == 1)   // debug        //45
  611.         //{
  612.         //printf("%x|%x|%x|%x brute\n", table->k1, table->k2, table->k3, table->k4);
  613.         //}
  614.         //---------------------------------------------------------------------
  615.         unsigned k[4] =
  616.         {
  617.             table->k1,
  618.             table->k2,
  619.             table->k3,
  620.             table->k4
  621.         };
  622.         unsigned b[4];
  623.         //---------------------------------------------------------------------
  624.         for (unsigned i = 0;   i < 4;   i++)
  625.         {
  626.             switch (k[ i])
  627.             {
  628.                 //-------------------------------------------------------------
  629.                 // игнор левости правости?
  630.                 // но оно же предлагаетсо вводить в конфиге
  631.                 // слевостями и праавостями?
  632.                 case DIK_MENU:
  633.                     b[i] = kbdpc[ DIK_LMENU] | kbdpc[ DIK_RMENU]; // Alt
  634.                     break;
  635.                 //-------------------------------------------------------------
  636.                 case DIK_CONTROL:
  637.                     b[i] = kbdpc[ DIK_LCONTROL] | kbdpc[ DIK_RCONTROL];
  638.                     break;
  639.                 //-------------------------------------------------------------
  640.                 case DIK_SHIFT:
  641.                     b[i] = kbdpc[ DIK_LSHIFT] | kbdpc[ DIK_RSHIFT];
  642.                     break;
  643.                 //-------------------------------------------------------------
  644.                 default:
  645.                     b[i] = kbdpc[ k[ i]];
  646.                 //-------------------------------------------------------------
  647.             }
  648.         }
  649.         //---------------------------------------------------------------------
  650.         if (b[0] & b[1] & b[2] & b[3] & 0x80)
  651.         {
  652.             //printf("  func %x\n",table->k1);
  653.             table->func();      // это каким то хуем вызывает функцию из таблицы
  654.             kbdpc[0] = tmp;
  655.             return true;
  656.         }
  657.         //---------------------------------------------------------------------
  658.         table++;
  659.         //---------------------------------------------------------------------
  660.     }
  661.     //-------------------------------------------------------------------------
  662.     kbdpc[0] = tmp;
  663.     return false;
  664. }
  665. //=============================================================================
  666.  
  667.  
  668. //=============================================================================
  669. bool dispatch( action *table)
  670. {
  671.     //-------------------------------------------------------------------------
  672.     if (*droppedFile)
  673.     {
  674.         trd_toload = DefaultDrive;
  675.         loadsnap( droppedFile);
  676.         *droppedFile = 0;
  677.     }
  678.     //-------------------------------------------------------------------------
  679.     if (!input.readdevices())
  680.     {
  681.         return false;   // выходит если небыло K-On !!
  682.     }
  683.     //-------------------------------------------------------------------------
  684.     // дальше хоткеи обрабатываютсо по K-On или по автоповтору венды
  685.     dispatch_more( table);
  686.     return true;
  687. }
  688. //=============================================================================
  689.  
  690.  
  691. //=============================================================================
  692. bool wcmatch(char *string, char *wc)
  693. {
  694.     //-------------------------------------------------------------------------
  695.     for (    ;    ;wc++, string++)
  696.     {
  697.         //---------------------------------------------------------------------
  698.         if (!*string && !*wc)
  699.             return 1;
  700.         //---------------------------------------------------------------------
  701.         if (*wc == '?')
  702.         {
  703.             //-----------------------------------------------------------------
  704.             if (*string)
  705.             {
  706.                 continue;
  707.             }
  708.             //-----------------------------------------------------------------
  709.             else
  710.             {
  711.                 return 0;
  712.             }
  713.             //-----------------------------------------------------------------
  714.         }
  715.         //---------------------------------------------------------------------
  716.         if (*wc == '*')
  717.         {
  718.             //-----------------------------------------------------------------
  719.             for (wc++;    *string;    string++)
  720.                 if (wcmatch( string, wc))
  721.                     return 1;
  722.             //-----------------------------------------------------------------
  723.             return 0;
  724.         }
  725.         //---------------------------------------------------------------------
  726.         if (tolower( *string) != tolower( *wc))
  727.             return 0;
  728.         //---------------------------------------------------------------------
  729.     }
  730. }
  731. //=============================================================================
  732.  
  733.  
  734.  
  735. //=============================================================================
  736. void dump1( BYTE *p, unsigned sz)
  737. {
  738.     //-------------------------------------------------------------------------
  739.     while (sz)
  740.     {
  741.         printf("\t");
  742.         unsigned chunk = (sz > 16)  ?  16 :
  743.                                        sz;
  744.         unsigned i;                             // Alone Coder 0.36.7
  745.         //---------------------------------------------------------------------
  746.         for (/*unsigned*/ i = 0;    i < chunk;    i++)
  747.             printf("%02X ", p[i]);
  748.         //---------------------------------------------------------------------
  749.         for (    ; i < 16;    i++)
  750.             printf("   ");
  751.         //---------------------------------------------------------------------
  752.         for (i = 0;    i < chunk;    i++)
  753.             printf("%c", (p[i] < 0x20)  ?  '.'  :
  754.                                            p[i] );
  755.         //---------------------------------------------------------------------
  756.         printf("\n");
  757.         sz -= chunk;
  758.         p += chunk;
  759.     }
  760.     //-------------------------------------------------------------------------
  761.     printf("\n");
  762. }
  763. //=============================================================================
  764.  
  765.  
  766. //=============================================================================
  767. void color( int ink)
  768. {
  769.    SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE), WORD( ink));
  770. }
  771. //=============================================================================
  772.  
  773.  
  774.  
  775. //=============================================================================
  776. void err_win32( DWORD errcode)
  777. {
  778.     //-------------------------------------------------------------------------
  779.     if (errcode == 0xFFFFFFFF)
  780.         errcode = GetLastError();
  781.     //-------------------------------------------------------------------------
  782.  
  783.     char msg[ 512];
  784.     //-------------------------------------------------------------------------
  785.     if (!FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  786.                         nullptr,
  787.                         errcode,
  788.                         MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT),
  789.                         msg,
  790.                         sizeof( msg),
  791.                         nullptr
  792.                 )
  793.      )
  794.     {  
  795.         *msg = 0;
  796.     }
  797.     //-------------------------------------------------------------------------
  798.     trim( msg);
  799.     CharToOem( msg, msg);
  800.  
  801.     color();
  802.     printf( ( *msg)  ?  "win32 error message: " :
  803.                         "win32 error code: ");
  804.     color( CONSCLR_ERRCODE);
  805.     //-------------------------------------------------------------------------
  806.     if (*msg)
  807.     {
  808.         printf("%s\n", msg);
  809.     }
  810.     //-------------------------------------------------------------------------
  811.     else
  812.     {
  813.         printf("%04lX\n", errcode);
  814.     }
  815.     //-------------------------------------------------------------------------
  816.     color();
  817. }
  818. //=============================================================================
  819.  
  820.  
  821.  
  822. //=============================================================================
  823. void errmsg( const char *err, const char *str)
  824. {
  825.     color();
  826.     printf("error: ");
  827.     color( CONSCLR_ERROR);
  828.     printf( err, str);
  829.     color();
  830.     printf("\n");
  831.  
  832. #ifdef _DEBUG
  833.     OutputDebugString( err);
  834.     OutputDebugString( str);
  835.     OutputDebugString("\n");
  836. #endif
  837. }
  838. //=============================================================================
  839.  
  840.  
  841.  
  842. //=============================================================================
  843. void err_printf( const char *format, ...)
  844. {
  845.     va_list args;
  846.     va_start( args, format);
  847.     color();
  848.     printf("error: ");
  849.     color( CONSCLR_ERROR);
  850.     vprintf( format, args);
  851.     color();
  852.     printf("\n");
  853.     va_end( args);
  854. }
  855. //=============================================================================
  856.  
  857.  
  858. //=============================================================================
  859. void __declspec( noreturn) errexit( const char *err, const char *str)
  860. {
  861.     errmsg( err, str);
  862.     exit();
  863. }
  864. //=============================================================================
  865.  
  866.  
  867. extern "C" void * _ReturnAddress( void);
  868.  
  869. //=============================================================================
  870.  
  871. #ifndef __INTEL_COMPILER
  872. #pragma intrinsic(_ReturnAddress)
  873. #pragma intrinsic(_byteswap_ulong)
  874. #pragma intrinsic(_byteswap_ushort)
  875. #endif
  876.  
  877. //=============================================================================
  878.  
  879.  
  880.  
  881.  
  882.  
  883.  
  884.  
  885.  
  886. //=============================================================================
  887. // обрезалка пробелов и табов перед ";" у строк                               // [NS]
  888. // тк GetPrivateProfileString ниче не можот...
  889. // юзать так    string_comment_trimmer(helpname);
  890.  
  891. void string_comment_trimmer( char *string_for_comment_trim)
  892. {
  893.     int comment_trim_cnt = 0;
  894.     //-------------------------------------------------------------------------
  895.     while (     *string_for_comment_trim != '\0' &&     // 0x00 string end
  896.                 *string_for_comment_trim != 0x3B        // ";"
  897.       )
  898.     {
  899.         // printf("%d %x %c \n",comment_trim_cnt,*string_for_comment_trim,*string_for_comment_trim);
  900.         string_for_comment_trim++;
  901.         comment_trim_cnt++;
  902.     }
  903.     //-------------------------------------------------------------------------
  904.     // затыкаем ";" или 0х00 если на него наехали
  905.     // printf("%d %x %c \n",comment_trim_cnt,*string_for_comment_trim,*string_for_comment_trim);
  906.     *string_for_comment_trim = 0x00;
  907.     // printf("%d %x %c \n",comment_trim_cnt,*string_for_comment_trim,*string_for_comment_trim);
  908.     // подтираем пробелы и табы
  909.     //-------------------------------------------------------------------------
  910.     while (comment_trim_cnt > 0)
  911.     {
  912.         string_for_comment_trim--;
  913.         comment_trim_cnt--;
  914.         //---------------------------------------------------------------------
  915.         if (    *string_for_comment_trim == 0x09 ||             // TAB
  916.                         *string_for_comment_trim == 0x20        // SPACE
  917.          )
  918.         {
  919.             // printf("%d %x %c \n",comment_trim_cnt,*string_for_comment_trim,*string_for_comment_trim);
  920.             *string_for_comment_trim = 0x00;
  921.         }
  922.         //---------------------------------------------------------------------
  923.         else
  924.         {
  925.             break;
  926.         }
  927.         //---------------------------------------------------------------------
  928.     }
  929.     //-------------------------------------------------------------------------
  930.     return;
  931. }
  932.  
  933.  
  934.         /*
  935.         int comment_trim_cnt = 0;
  936.         int comment_trim_cnt_size = strlen(helpname);
  937.         while (comment_trim_cnt < comment_trim_cnt_size)
  938.         {
  939.                 printf("%d %x %c \n",comment_trim_cnt,helpname[comment_trim_cnt],helpname[comment_trim_cnt]);
  940.                 if (helpname[comment_trim_cnt] == 0x3B)
  941.                 {
  942.                 helpname[comment_trim_cnt] = 0;
  943.                 break;
  944.                 }
  945.         comment_trim_cnt++;
  946.         }
  947.         while (comment_trim_cnt > 0)
  948.         {
  949.                 comment_trim_cnt--;
  950.                 printf("%d %x %c \n",comment_trim_cnt,helpname[comment_trim_cnt],helpname[comment_trim_cnt]);
  951.                 if (    helpname[comment_trim_cnt] == 0x09 ||
  952.                         helpname[comment_trim_cnt] == 0x20 )
  953.                 {
  954.                 helpname[comment_trim_cnt] = 0;
  955.                 }
  956.                 else
  957.                 {
  958.                 break;
  959.                 }
  960.         }
  961.         */
  962. //=============================================================================
  963.  
  964.