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 "draw.h"
  6. #include "drawnomc.h"
  7. #include "dx.h"
  8. #include "dxr_text.h"
  9. #include "dxr_rsm.h"
  10. #include "dxr_advm.h"
  11. #include "memory.h"
  12. #include "config.h"
  13.  
  14. #include "util.h"
  15.  
  16. // 44 146
  17.  
  18. //                                              R       G       B
  19.     unsigned char dbg_clr_array[16][3] = {  {   0,      0,      0       },      //black
  20.                                             {   16,     16,     64      },      // selected window
  21.                                             {   (59),   16,     16      },      //BPW
  22.                                             {   61,     0,      61      },
  23.                                                                
  24.                                             {   16,     (45),   16      },      //BPR
  25.                                             {   37,     72,     84      },      // panelz       //32,   96,     96      //{     64,     200,    200     },
  26.                                             {   (55),   (55),   16      },      //BPR BPW
  27.                                             {   190,    210,    200     },      // ROM
  28.                                                                
  29.                                             {   33,     33,     33      },
  30.                                             {   38,     38,     255     },      // watches
  31.                                             {   (255)40,     40      },      //BREAK EX
  32.                                             {   255,    64,     255     },      //cursor
  33.                                                                
  34.                                             {   32,     255,    32      },      //
  35.                                             {   96,     255,    255     },      // window names
  36.                                             {   255,    255,    32      },      //
  37.                                             {   255,    255,    255     }       //WHITE
  38.                                         };
  39.  
  40.         unsigned char dbg_clr_R[16] = { 0x00,0x50,0xC0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
  41.         unsigned char dbg_clr_G[16] = { 0x00,0x00,0x00,0x00,0x40,0x70,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
  42.         unsigned char dbg_clr_B[16] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
  43.  
  44.  
  45. //=============================================================================
  46. #ifdef CACHE_ALIGNED
  47. CACHE_ALIGNED unsigned char rbuf[sizeof_rbuf];
  48. #else // __declspec(align) not available, force QWORD align with old method
  49. __int64 rbuf__[sizeof_rbuf/sizeof(__int64)];
  50. unsigned char * const rbuf = (unsigned char*)rbuf__;
  51. #endif
  52. //=============================================================================
  53.  
  54. unsigned char * const rbuf_s = rbuf + rb2_offs;                 // frames to mix with noflic and resampler filters
  55. unsigned char * const save_buf = rbuf_s + rb2_offs*MAX_BUFFERS; // used in monitor
  56.  
  57. T t;    //alco style :rofl:
  58.  
  59. videopoint *vcurr; // ╙ърчрЄхы№ эр Єхъє∙шщ ¤ыхьхэЄ шч video[]
  60.  
  61. // ╠рёёшт тшфхюёЄЁюъ тъы■ўр  сюЁф■Ё
  62. // video[i] - эрўрыю ёЄЁюъш (шёяюы№чєхЄё  Єюы№ъю next_t)
  63. // video[i+1] - ъюэхЎ ёЄЁюъш  (шёяюы№чє■Єё  тёх ярЁрьхЄЁ√)
  64. static videopoint video[4*MAX_HEIGHT];
  65.  
  66. unsigned vmode;                 // what are drawing: 0-not visible, 1-border, 2-screen
  67. static unsigned prev_t;         // ЄръЄ эр ъюЄюЁюь с√ы юЄЁшёютрэ яюёыхфэшщ яшъёхы№
  68. unsigned *atrtab;
  69.  
  70. unsigned char colortab[0x100];  // map zx attributes to pc attributes
  71.  
  72. unsigned colortab_s8[0x100];    // colortab shifted to 8 and 24
  73. unsigned colortab_s24[0x100];
  74.  
  75. /*
  76. #include "drawnomc.cpp"
  77. #include "draw_384.cpp"
  78. */
  79.  
  80. PALETTEENTRY pal0[ 0x100];      // emulator palette
  81.  
  82. PALETTEENTRY pal_dbg[ 0x100];   // debuger palette [NS]
  83.  
  84. //=============================================================================
  85. void AtmVideoController::PrepareFrameATM2(int VideoMode)
  86. {
  87.     for (int y=0; y<256; y++)
  88.     {
  89.         if ( VideoMode == 6 )
  90.         {
  91.             // ёьх∙хэш  т ЄхъёЄютюь тшфхюЁхцшьх
  92.             Scanlines[y].Offset = 64 * (y / 8);
  93.         }
  94.         else
  95.         {
  96.             // ёьх∙хэш  т ЁрёЄЁютюь тшфхюЁхцшьх
  97.             Scanlines[y].Offset = (y < 56)  ?   0               :
  98.                                                 40*(y-56)       ;
  99.         }
  100.         Scanlines[y].VideoMode = VideoMode;
  101.     }
  102.     CurrentRayLine = 0;
  103.     IncCounter_InRaster = 0;
  104.     IncCounter_InBorder = 0;
  105. }
  106. //=============================================================================
  107.  
  108.  
  109. //=============================================================================
  110. void AtmVideoController::PrepareFrameATM1(int VideoMode)
  111. {
  112.     for (int y=56; y<256; y++)
  113.     {
  114.         Scanlines[y].Offset = 40 * (y - 56);
  115.         Scanlines[y].VideoMode = VideoMode;
  116.     }
  117. }
  118. //=============================================================================
  119.  
  120. AtmVideoController AtmVideoCtrl;
  121.  
  122. //=============================================================================
  123. void video_permanent_tables()                   //ухэхЁрЎш  ЄрсышЎ фы  тшфхю?
  124. {
  125.     // pixel doubling table
  126.     unsigned i; //Alone Coder 0.36.7
  127.     for (/*unsigned*/ i = 0; i < 0x100; i++)
  128.     {
  129.         unsigned res = 0;
  130.         for (unsigned j = 0x80; j; j/=2)
  131.         {
  132.             res <<= 2;
  133.             if (i & j)
  134.             {
  135.                 res |= 3;
  136.             }
  137.         }
  138.         t.dbl[i] = res;
  139.     }
  140.  
  141.     for (i = 0; i < 0x100; i++)
  142.     {
  143.         unsigned r1 = 0, r2 = 0;
  144.         if (i & 0x01)
  145.         {
  146.             r1++;
  147.             r2 += 1;
  148.         }
  149.         if (i & 0x02)
  150.         {
  151.             r1++;
  152.             r2 += 1;
  153.         }
  154.         if (i & 0x04)
  155.         {
  156.             r1++;
  157.             r2 += 0x100;
  158.         }
  159.         if (i & 0x08)
  160.         {
  161.             r1++;
  162.             r2 += 0x100;
  163.         }
  164.         if (i & 0x10)
  165.         {
  166.             r1 += 0x100;
  167.             r2 += 0x10000;
  168.         }
  169.         if (i & 0x20)
  170.         {
  171.             r1 += 0x100;
  172.             r2 += 0x10000;
  173.         }
  174.         if (i & 0x40)
  175.         {
  176.             r1 += 0x100;
  177.             r2 += 0x1000000;
  178.         }
  179.         if (i & 0x80)
  180.         {
  181.             r1 += 0x100;
  182.             r2 += 0x1000000;
  183.         }
  184.         // low byte of settab - number of pixels in low nibble of i
  185.         // high byte of low word of settab - number of pixels in high nibble of i
  186.         t.settab[i] = r1;
  187.         t.settab2[i] = r2*4;    // *4 - convert square 2x2 to 4x4
  188.     }
  189.  
  190.     //-------------------------------------------------------------------------
  191.     // calc screen addresses
  192.     i = 0;
  193.     for(unsigned p = 0; p < 4; p++)
  194.     {
  195.         for(unsigned y = 0; y < 8; y++)
  196.         {
  197.             for(unsigned o = 0; o < 8; o++, i++)
  198.             {
  199.                 t.scrtab[i] = p * 0x800 + y * 0x20 + o * 0x100;
  200.                 t.atrtab_hwmc[i] = t.scrtab[i] + 0x2000;
  201.                 t.atrtab[i] = 0x1800 + (p * 8 + y) * 32;
  202.             }
  203.         }
  204.     }
  205.     //-------------------------------------------------------------------------
  206.  
  207.     // alco table
  208.     static unsigned disp_0[] = {        0x0018,
  209.                                         0x2000,
  210.                                         0x2008,
  211.                                         0x2010,
  212.                                         0x2018,
  213.                                         0x0008
  214.                                 };
  215.     static unsigned base_s[] = {        0x10000,
  216.                                         0x14000,
  217.                                         0x14800,
  218.                                         0x15000,
  219.                                         0x11800
  220.                                 };
  221.     static unsigned base_a[] = {        0x11000,
  222.                                         0x15800,
  223.                                         0x15900,
  224.                                         0x15A00,
  225.                                         0x11300
  226.                                 };
  227.                                
  228.     for (unsigned y = 0; y < 304; y++)
  229.         for (unsigned x = 0; x < 6; x++)
  230.         {
  231.             unsigned disp = disp_0[x] + (y & 0x38)*4;
  232.             ::t.alco[y][x].a = memory + base_a[y/64] + disp;
  233.             ::t.alco[y][x].s = memory + base_s[y/64] + disp + (y & 7)*0x100;
  234.         }
  235.  
  236.     //-------------------------------------------------------------------------
  237.     // Video Drive by SAM style
  238.     #ifdef MOD_VID_VD
  239.     // this code is only for ygrbYGRB palette
  240.     for (unsigned byte = 0; byte < 0x100; byte++)
  241.         for (int bit = 0; bit < 8; bit++)
  242.             t.vdtab[0][0][byte].m64_u8[7-bit] = (byte & (1 << bit)) ? 0x11 : 0;
  243.     for (int pl = 1; pl < 4; pl++)
  244.         for (unsigned byte = 0; byte < 0x100; byte++)
  245.             t.vdtab[0][pl][byte] = _mm_slli_pi32(t.vdtab[0][0][byte], pl);
  246.     for (i = 0; i < sizeof t.vdtab[0]; i++)
  247.         ((unsigned char*)t.vdtab[1])[i] = ((unsigned char*)t.vdtab[0])[i] & 0x0F;
  248.     _mm_empty();
  249.     #endif
  250.     //-------------------------------------------------------------------------
  251.  
  252.     temp.offset_vscroll_prev = 0;
  253.     temp.offset_vscroll = 0;
  254.     temp.offset_hscroll_prev = 0;
  255.     temp.offset_hscroll = 0;
  256. }
  257. //=============================================================================
  258.  
  259.  
  260.  
  261. //=============================================================================
  262. static unsigned getYUY2(unsigned r, unsigned g, unsigned b)
  263. {
  264.     int y = (int)(0.29*r + 0.59*g + 0.14*b);
  265.     int u = (int)(128.0 - 0.14*r - 0.29*g + 0.43*b);
  266.     int v = (int)(128.0 + 0.36*r - 0.29*g - 0.07*b);
  267.     if (y < 0) y = 0; if (y > 255) y = 255;
  268.     if (u < 0) u = 0; if (u > 255) u = 255;
  269.     if (v < 0) v = 0; if (v > 255) v = 255;
  270.     return WORD4(y,u,y,v);
  271. }
  272. //=============================================================================
  273.  
  274.  
  275.  
  276. //=============================================================================
  277. static void create_palette()
  278. {
  279.     //printf("create_palette()\n");
  280.  
  281.     if ((temp.rflags & RF_8BPCH) && temp.obpp == 8)
  282.     {
  283.         temp.rflags |= RF_GRAY;
  284.         conf.flashcolor = 0;
  285.     }
  286.  
  287.     PALETTE_OPTIONS *pl = &pals[conf.pal];
  288.     //                                Ii          Ii          Ii          Ii
  289.     //                                00          01          10          11
  290.     unsigned char brights[4] = { u8(pl->ZZ), u8(pl->ZN), u8(pl->NN), u8(pl->BB) };
  291.     unsigned char brtab[16] =
  292.     {   //   ZZ          NN          ZZ          BB
  293.         u8(pl->ZZ), u8(pl->ZN), u8(pl->ZZ), u8(pl->ZB), // ZZ
  294.         u8(pl->ZN), u8(pl->NN), u8(pl->ZN), u8(pl->NB), // NN
  295.         u8(pl->ZZ), u8(pl->ZN), u8(pl->ZZ), u8(pl->ZB), // ZZ (bright=1,ink=0)
  296.         u8(pl->ZB), u8(pl->NB), u8(pl->ZB), u8(pl->BB)  // BB
  297.     };
  298.  
  299.  
  300.  
  301. //draw.cpp:262:43: warning: iteration 1 invokes undefined behavior [-Waggressive-loop-optimizations]
  302.  
  303.     int i = 255;                                // ╨└┴╬╫╚╔ ъюёЄ√ы№
  304.     while (i >= 0)                              // чряюыэхэшх т юсЁрЄэюь яюЁ фъх
  305.     {
  306. //
  307. //  for (unsigned i = 0; i < 0x100; i++)        // юЁшушэры
  308. //  {                                           // єёыютшх эх ёЁрсрЄ√трхЄ яЁш -O1+ !!!!!
  309. //
  310. //  int i = 0;
  311. //  while (i < 256)                             // єёыютшх эх ёЁрсрЄ√трхЄ яЁш -O1+ !!!!!
  312. //  {
  313.  
  314.         unsigned r0, g0, b0;
  315.         if (temp.rflags & RF_GRAY)
  316.         { // grayscale palette
  317.             r0 = g0 = b0 = i;
  318.         }
  319.         else if (temp.rflags & RF_PALB)
  320.         { // palette index:
  321.             if (comp.ula_plus_en) // gggrrrbb (ULA+)
  322.             { // ╦шэхщэр  шэЄхЁяюы Ўш   ЁъюёЄш
  323.                 b0 = ((i & 3) * 255) / 3;               // 2 сшЄр
  324.                 r0 = (((i >> 2) & 7) * 255) / 7;        // 3 сшЄр
  325.                 g0 = (((i >> 5) & 7) * 255) / 7;        // 3 сшЄр
  326.             }
  327.             else // gg0rr0bb (ATM / profi / bilinear filter)
  328.             { // ═хышэхщэр  ъюЁЁхъЎш   ЁъюёЄш (эр 2 сшЄр) яю ЄрсышЎх ярышЄЁ√ шч .ini Їрщыр
  329.                 b0 = brights[i & 3];
  330.                 r0 = brights[(i >> 3) & 3];
  331.                 g0 = brights[(i >> 6) & 3];
  332.             }
  333.         }
  334.         else
  335.         { // palette index: ygrbYGRB (юс√ўэ√щ zx Ёхцшь схч ярышЄЁ√)
  336.           // ═хышэхщэр  ъюЁЁхъЎш   ЁъюёЄш (эр 4 сшЄр) яю ЄрсышЎх ярышЄЁ√ шч .ini Їрщыр
  337.             b0 = brtab[((i >> 0) & 1) + ((i >> 2) & 2) + ((i >> 2) & 4) + ((i >> 4) & 8)]; // brtab[ybYB]
  338.             r0 = brtab[((i >> 1) & 1) + ((i >> 2) & 2) + ((i >> 3) & 4) + ((i >> 4) & 8)]; // brtab[yrYR]
  339.             g0 = brtab[((i >> 2) & 1) + ((i >> 2) & 2) + ((i >> 4) & 4) + ((i >> 4) & 8)]; // brtab[ygYG]
  340.         }
  341.         //      printf("i = %d\n",i);
  342.              
  343.         // transform with current settings
  344.         unsigned r = 0xFF & ((r0 * pl->r11 + g0 * pl->r12 + b0 * pl->r13) / 0x100);
  345.         unsigned g = 0xFF & ((r0 * pl->r21 + g0 * pl->r22 + b0 * pl->r23) / 0x100);
  346.         unsigned b = 0xFF & ((r0 * pl->r31 + g0 * pl->r32 + b0 * pl->r33) / 0x100);
  347.  
  348. //draw.cpp:262:43: warning: iteration 1 invokes undefined behavior [-Waggressive-l
  349. //oop-optimizations]
  350. //  262 |         gdibmp.header.bmiColors[i].rgbRed = pal0[i].peRed = BYTE(r);
  351. //      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
  352. //draw.cpp:226:27: note: within this loop
  353. //  226 |     for(unsigned i = 0; i < 0x100; i++)
  354. //      |                         ~~^~~~~~~
  355.      
  356.  
  357.  
  358.         // prepare palette in bitmap header for GDI renderer
  359.         gdibmp.header.bmiColors[i].rgbRed =             pal0[i].peRed =         BYTE(r);
  360.         gdibmp.header.bmiColors[i].rgbGreen =           pal0[i].peGreen =       BYTE(g);
  361.         gdibmp.header.bmiColors[i].rgbBlue =            pal0[i].peBlue =        BYTE(b);
  362.        
  363.  
  364.         gdi_dbg_bmp.header.bmiColors[i].rgbRed =        pal_dbg[i].peRed =      BYTE( dbg_clr_array[i%16][0] );
  365.         gdi_dbg_bmp.header.bmiColors[i].rgbGreen =      pal_dbg[i].peGreen =    BYTE( dbg_clr_array[i%16][1] );
  366.         gdi_dbg_bmp.header.bmiColors[i].rgbBlue =       pal_dbg[i].peBlue =     BYTE( dbg_clr_array[i%16][2] );
  367.  
  368.        
  369.         //system ("pause");
  370.  
  371.         i--;
  372.  
  373. //            printf("i = %d\n",i);
  374.     }
  375.    
  376.    
  377.  
  378.  
  379.  
  380.        
  381.     memcpy(syspalette + 10, pal0 + 10, (246 - 9) * sizeof *syspalette);
  382.  
  383.     if (conf.mem_model == MM_PROFI)
  384.     {
  385.         // profi palette mapping (port out to palette index)
  386.         for(unsigned i = 0; i < 0x100; i++)
  387.         {
  388.             unsigned dst;
  389.             dst = i;                    // Gg0Rr0Bb => Gg0Rr0Bb
  390.             t.profi_pal_map[i] = dst;
  391.         }
  392.     }
  393. }
  394. //=============================================================================
  395.  
  396. void atm_zc_tables();           //forward
  397.  
  398. //=============================================================================
  399. // make colortab: zx-attr -> pc-attr
  400.  
  401. static void make_colortab(char flash_active)
  402. {
  403. // тю тЁхь  ьшурэш  Їых°р Єюц√ т√ч√трхЄёю !!
  404. //printf("make_colortab\n");
  405.  
  406.     if (conf.flashcolor || conf.ula_plus)
  407.         flash_active = 0;
  408.  
  409.     for (unsigned a = 0; a < 0x100; a++)        // a - zx-attr
  410.     {
  411.         unsigned char ink = a & 7;              //.....III
  412.         unsigned char paper = (a >> 3) & 7;     //>>>..PPP ...
  413.         unsigned char bright = (a >> 6) & 1;    //>>>>>>.B ......
  414.         unsigned char flash = (a >> 7) & 1;     //>>>>>>>F .......
  415.  
  416. // if((conf.flashcolor && ink) || !conf.flashcolor)
  417.         ink |= bright << 3;                     //....BIII
  418.  
  419. // if((conf.flashcolor && paper) || !conf.flashcolor)
  420.  
  421.         paper |= ( (conf.flashcolor || (conf.ula_plus && comp.ula_plus_en))  ?  flash :
  422.                                                                                 bright ) << 3;
  423.        
  424. //                                              //....FPPP - flash color / ula plus
  425. //                                              //....BPPP - 6912
  426.  
  427.         //ink/paper swap
  428.         if (flash_active && flash)
  429.         {
  430.             unsigned char t = ink;
  431.             ink = paper;
  432.             paper = t;
  433.         }
  434.  
  435.         u8 color = u8((paper << 4) | ink);      // color - pc-attr
  436.  
  437.         colortab[a] = color;
  438.         colortab_s8[a] = unsigned(color << 8U);
  439.         colortab_s24[a] = unsigned(color << 24U);
  440.     }
  441.  
  442.    if (conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3 || conf.mem_model == MM_ATM450)
  443.         atm_zc_tables();        // update with new flash bit
  444. }
  445. //=============================================================================
  446.  
  447.  
  448. //=============================================================================
  449. // make attrtab: pc-attr + 0x100*pixel -> palette index
  450.  
  451. static void attr_tables()
  452. {
  453.     unsigned char flashcolor = (temp.rflags & RF_MON)? 0 : conf.flashcolor;
  454.    
  455.     for (unsigned a = 0; a < 0x100; a++)
  456.     {
  457.         unsigned char ink = (a & 0x0F), paper = u8(a >> 4);
  458.         if (flashcolor)
  459.             paper = (paper & 7) + (ink & 8);    // paper_bright from ink
  460.                
  461.         //---------------------------------------------------------------------
  462.         if (temp.rflags & RF_GRAY)
  463.         {
  464.             // grayscale palette
  465.             t.attrtab[a] =       paper * 16;
  466.             t.attrtab[a+0x100] = ink   * 16;
  467.         }
  468.         //---------------------------------------------------------------------
  469.         else if (temp.rflags & RF_COMPPAL)
  470.         {
  471.             // ╧рышЄЁр т ЇюЁьрЄх ULA+
  472.             u8 paper_idx;               // fb1ppp
  473.             u8 ink_idx;                 // fb0iii
  474.            
  475.             //-----------------------------------------------------------------
  476.             if (comp.ula_plus_en)
  477.             {
  478.                 u8 flash = (a & 0x80) >> 7;
  479.                 u8 bright = (a & 8) >> 3;
  480.                 paper &= 7;
  481.                 ink &= 7;
  482.                 u8 pal_no = u8(((flash << 1) | bright) << 4);
  483.                 paper_idx = u8(pal_no | 8 | paper);
  484.                 ink_idx   = u8(pal_no | 0 | ink);
  485.             }
  486.             //-----------------------------------------------------------------
  487.             else
  488.             {
  489.                 //ATM / profi palette
  490.                 //direct values from palette registers
  491.                 paper = a >> 4;
  492.                 ink = a & 0x0F;
  493.                 paper_idx = u8(((paper & 8) << 1) | (paper & 7));
  494.                 ink_idx = u8(((ink & 8) << 1) | (ink & 7));
  495.             }
  496.             //-----------------------------------------------------------------
  497.             t.attrtab[a] =              comp.comp_pal[paper_idx];  // paper
  498.             t.attrtab[a | 0x100] =      comp.comp_pal[ink_idx];    // ink
  499.         }
  500.         //---------------------------------------------------------------------
  501.         else if (temp.rflags & RF_PALB)
  502.         {
  503.             //for bilinear
  504.             unsigned char b0,b1, r0,r1, g0,g1;
  505.             b0 = (paper >> 0) & 1;
  506.             r0 = (paper >> 1) & 1;
  507.             g0 = (paper >> 2) & 1;
  508.             b1 = (ink   >> 0) & 1;
  509.             r1 = (ink   >> 1) & 1;
  510.             g1 = (ink   >> 2) & 1;
  511.  
  512.             if (flashcolor && (a & 0x80))
  513.             {
  514.                 b1 += b0; r1 += r0; g1 += g0;
  515.                 r0 = b0 = g0 = 0;
  516.             }
  517.             else
  518.             {
  519.                 b0 *= 2; r0 *= 2; g0 *= 2;
  520.                 b1 *= 2; r1 *= 2; g1 *= 2;
  521.             }
  522.  
  523.             unsigned char br1 = (ink >> 3) & 1;
  524.             if (r1) r1 += br1;
  525.             if (g1) g1 += br1;
  526.             if (b1) b1 += br1;
  527.  
  528.             unsigned char br0 = (paper >> 3) & 1;
  529.             if (r0) r0 += br0;
  530.             if (g0) g0 += br0;
  531.             if (b0) b0 += br0;
  532.  
  533.             // palette index: gg0rr0bb
  534.             t.attrtab[a+0x100]  = u8((g1 << 6) + (r1 << 3) + b1);
  535.             t.attrtab[a]        = u8((g0 << 6) + (r0 << 3) + b0);
  536.         }
  537.         //---------------------------------------------------------------------
  538.         else
  539.         {
  540.         // all others
  541.        
  542.             // palette index: ygrbYGRB
  543.             if (flashcolor && (a & 0x80))
  544.             {
  545.                 t.attrtab[a] = 0;
  546.                 t.attrtab[a+0x100] = u8(ink+(paper<<4));
  547.             }
  548.             else
  549.             {
  550.                 t.attrtab[a] =       paper * 0x11; // p[3..0]:p[3..0] (єфтюхэшх)
  551.                 t.attrtab[a+0x100] = ink   * 0x11; // i[3..0]:i[3..0] (єфтюхэшх)
  552.             }
  553.         }
  554.     }
  555. }
  556. //=============================================================================
  557.  
  558.  
  559. //=============================================================================
  560. static void p4bpp_tables()
  561. {
  562.     for (unsigned pass = 0; pass < 2; pass++)
  563.     {
  564.         for (unsigned bt = 0; bt < 0x100; bt++)
  565.         {
  566.             unsigned lf = ((bt >> 3) & 7) + ((bt >> 4) & 8);
  567.             unsigned rt = (bt & 7) + ((bt >> 3) & 8);
  568.             //-----------------------------------------------------------------
  569.             if (temp.obpp == 8)
  570.             {
  571.                 t.p4bpp8[pass][bt] =    (t.sctab8[pass][0x0F+0x10*rt] & 0xFFFF) +
  572.                                         (t.sctab8[pass][0x0F+0x10*lf] & 0xFFFF0000);
  573.             }
  574.             //-----------------------------------------------------------------
  575.             else if (temp.obpp == 16)
  576.             {
  577.                 t.p4bpp16[pass][bt * 2 + 0] = t.sctab16[pass][0x03 + 4 * rt];
  578.                 t.p4bpp16[pass][bt * 2 + 1] = t.sctab16[pass][0x03 + 4 * lf];
  579.             }
  580.             //-----------------------------------------------------------------
  581.             else /* if (temp.obpp == 32) */
  582.             {
  583.                 t.p4bpp32[pass][bt * 2 + 0] = t.sctab32[pass][0x100 + rt];
  584.                 t.p4bpp32[pass][bt * 2 + 1] = t.sctab32[pass][0x100 + lf];
  585.             }
  586.             //-----------------------------------------------------------------
  587.         }
  588.     }
  589. }
  590. //=============================================================================
  591.  
  592.  
  593. //=============================================================================
  594. void atm_zc_tables()    // atm,profi screens (use normal zx-flash)
  595. {
  596.     for (unsigned pass = 0; pass < 2; pass++)
  597.     {
  598.         for (unsigned at = 0; at < 0x100; at++)
  599.         {
  600.             unsigned pc_attr = colortab[at];
  601.             //-----------------------------------------------------------------
  602.             if (temp.obpp == 8)
  603.             {
  604.                 for(unsigned j = 0; j < 4; j++)
  605.                 {
  606.                     t.zctab8ad[pass][at * 4 + j] = t.sctab8d[pass][pc_attr * 4 + j];
  607.                 }
  608.             }
  609.             //-----------------------------------------------------------------
  610.             else if (temp.obpp == 16)
  611.             {
  612.                 t.zctab16ad[pass][at] = t.sctab16d[pass][pc_attr];
  613.                 t.zctab16ad[pass][at + 0x100] = t.sctab16d[pass][pc_attr + 0x100];
  614.             }
  615.             //-----------------------------------------------------------------
  616.             else /* if (temp.obpp == 32) */
  617.             {
  618.                 t.zctab32ad[pass][at] = t.sctab32[pass][pc_attr];
  619.                 t.zctab32ad[pass][at + 0x100] = t.sctab32[pass][pc_attr + 0x100];
  620.             }
  621.             //-----------------------------------------------------------------
  622.         }
  623.     }
  624.  
  625.     // atm palette mapping (port out to palette index)
  626.     for (unsigned i = 0; i < 0x100; i++)
  627.     {
  628.         unsigned v = i ^ 0xFF, dst;
  629.        
  630.         if (conf.mem_model == MM_ATM450)
  631.         {
  632.             // ATM1: --grbGRB => Gg0Rr0Bb
  633.             dst =       ((v & 0x20) << 1) | // g
  634.                         ((v & 0x10) >> 1) | // r
  635.                         ((v & 0x08) >> 3) | // b
  636.                         ((v & 0x04) << 5) | // G
  637.                         ((v & 0x02) << 3) | // R
  638.                         ((v & 0x01) << 1) ; // B
  639.         }
  640.         else
  641.         {
  642.             // ATM2: grbG--RB => Gg0Rr0Bb
  643.             dst =       ((v & 0x80) >> 1) | // g
  644.                         ((v & 0x40) >> 3) | // r
  645.                         ((v & 0x20) >> 5) | // b
  646.                         ((v & 0x10) << 3) | // G
  647.                         ((v & 0x02) << 3) | // R
  648.                         ((v & 0x01) << 1) ; // B
  649.         }
  650.        
  651.         t.atm_pal_map[i] = dst;
  652.     }
  653. }
  654. //=============================================================================
  655.  
  656.  
  657. //=============================================================================
  658. static void hires_sc_tables()  // atm,profi screens (use zx-attributes & flash -> paper_bright)
  659. {
  660.     for (unsigned pass = 0; pass < 2; pass++)
  661.     {
  662.         for (unsigned at = 0; at < 0x100; at++)
  663.         {
  664.             unsigned pc_attr = (at & 0x80) + (at & 0x38)*2 + (at & 0x40)/8 + (at & 7);
  665.             //-----------------------------------------------------------------
  666.             if (temp.obpp == 8)
  667.                 for (unsigned j = 0; j < 16; j++)
  668.                     t.zctab8[pass][at*0x10+j] = t.sctab8[pass][pc_attr*0x10+j];
  669.             //-----------------------------------------------------------------
  670.             else if (temp.obpp == 16)
  671.                 for (unsigned j = 0; j < 4; j++)
  672.                     t.zctab16[pass][at*4+j] = t.sctab16[pass][pc_attr*4+j];
  673.             //-----------------------------------------------------------------
  674.             else /* if (temp.obpp == 32) */
  675.                 for (unsigned j = 0; j < 2; j++)
  676.                     t.zctab32[pass][at+0x100*j] = t.sctab32[pass][pc_attr+0x100*j];
  677.             //-----------------------------------------------------------------
  678.         }
  679.     }
  680. }
  681. //=============================================================================
  682.  
  683.  
  684. //=============================================================================
  685. static void calc_noflic_16_32()
  686. {
  687.     unsigned at, pass;
  688.     //-------------------------------------------------------------------------
  689.     if (temp.obpp == 16)
  690.     {
  691.         for (pass = 0; pass < 2; pass++)
  692.         {
  693.             for (at = 0; at < 2*0x100; at++)
  694.                 t.sctab16d_nf[pass][at] = (t.sctab16d[pass][at] & temp.shift_mask)/2;
  695.             for (at = 0; at < 4*0x100; at++)
  696.                 t.sctab16_nf[pass][at] = (t.sctab16[pass][at] & temp.shift_mask)/2;
  697.             for (at = 0; at < 2*0x100; at++)
  698.                 t.p4bpp16_nf[pass][at] = (t.p4bpp16[pass][at] & temp.shift_mask)/2;
  699.         }
  700.     }
  701.     //-------------------------------------------------------------------------
  702.     if (temp.obpp == 32)
  703.     {
  704.         unsigned shift_mask = 0xFEFEFEFE;
  705.         for (pass = 0; pass < 2; pass++)
  706.         {
  707.             for (at = 0; at < 2*0x100; at++)
  708.                 t.sctab32_nf[pass][at] = (t.sctab32[pass][at] & shift_mask)/2;
  709.             for (at = 0; at < 2*0x100; at++)
  710.                 t.p4bpp32_nf[pass][at] = (t.p4bpp32[pass][at] & shift_mask)/2;
  711.         }
  712.     }
  713.     //-------------------------------------------------------------------------
  714. }
  715. //=============================================================================
  716.  
  717.  
  718. //=============================================================================
  719. // pal.index => raw video data, shadowed with current scanline pass
  720. static unsigned raw_data(unsigned index, unsigned pass, unsigned bpp)
  721. {
  722.     if (bpp == 8)
  723.     {
  724.         if (pass)
  725.         {
  726.             if (!conf.scanbright)
  727.                 return 0;
  728.                
  729.             // palette too small to realize noflic/atari with shaded scanlines
  730.             if (conf.scanbright < 100 && !conf.noflic && !conf.atariset[0])
  731.             {
  732.                 if (temp.rflags & RF_PALB)
  733.                     index = (index & (index << 1) & 0x92) | ((index ^ 0xFF) & (index >> 1) & 0x49);
  734.                 else
  735.                     index &= 0x0F;
  736.             }
  737.         }
  738.         return index * 0x01010101;      // 4 Єюўъш (8bit)
  739.     }
  740.  
  741.    unsigned r = pal0[index].peRed, g = pal0[index].peGreen, b = pal0[index].peBlue;
  742.  
  743.     if (pass)
  744.     {
  745.         r = r * conf.scanbright / 100;
  746.         g = g * conf.scanbright / 100;
  747.         b = b * conf.scanbright / 100;
  748.     }
  749.     //-------------------------------------------------------------------------
  750.     if (bpp == 32)
  751.         return WORD4(b,g,r,0);                                  // 1 Єюўър (32bit)
  752.     //-------------------------------------------------------------------------
  753.     // else (bpp == 16)
  754.     if (temp.hi15==0)
  755.         return ((b/8) + ((g/4)<<5) + ((r/8)<<11)) * 0x10001;    // 2 Єюўъш (16bit)
  756.     //-------------------------------------------------------------------------
  757.     if (temp.hi15==1)
  758.         return ((b/8) + ((g/8)<<5) + ((r/8)<<10)) * 0x10001;    // 2 Єюўъш (16bit)
  759.     //-------------------------------------------------------------------------
  760.     if (temp.hi15==2)
  761.         return getYUY2(r,g,b);                                  // yuyv (32bit)
  762.     //-------------------------------------------------------------------------
  763.     return 0;
  764. }
  765. //=============================================================================
  766.  
  767.  
  768. //=============================================================================
  769. static unsigned atari_to_raw(unsigned at, unsigned pass)
  770. {
  771.     unsigned c1 = at/0x10, c2 = at & 0x0F;
  772.     unsigned raw0 = raw_data(   t.attrtab[c1+0x100],
  773.                                 pass,
  774.                                 temp.obpp
  775.                              );
  776.     unsigned raw1 = raw_data(   t.attrtab[c2+0x100],
  777.                                 pass,
  778.                                 temp.obpp
  779.                              );
  780.     if (raw0 == raw1)
  781.         return raw1;
  782.  
  783.     if (temp.obpp == 8)
  784.         return (temp.rflags & RF_PALB)    ?     (0x49494949 & ((raw0&raw1)^((raw0^raw1)>>1))) |
  785.                                                 (0x92929292 & ((raw0&raw1)|((raw0|raw1)&((raw0&raw1)<<1))))
  786.                                           :
  787.                                                 (0x0F0F0F0F & raw0) | (0xF0F0F0F0 & raw1);
  788.  
  789.     return (raw0 & temp.shift_mask)/2 + (raw1 & temp.shift_mask)/2;
  790. }
  791. //=============================================================================
  792.  
  793.  
  794. //=============================================================================
  795. void pixel_tables()
  796. {
  797.     attr_tables();
  798.     for (unsigned pass = 0; pass < 2; pass++)
  799.     {
  800.         for (unsigned at = 0; at < 0x100; at++)
  801.         {
  802.             // ╥юўър т√ъы■ўхэр (шэфхъё ярышЄЁ√ ¤ьєы ЄюЁр, ярышЄЁр 8[idx]->32[xrgb])
  803.             unsigned px0 = t.attrtab[at];
  804.             // ╥юўър тъы■ўхэр (шэфхъё ярышЄЁ√ ¤ьєы ЄюЁр, ярышЄЁр 8[idx]->32[xrgb])
  805.             unsigned px1 = t.attrtab[at + 0x100];
  806.  
  807.             // 4 Єюўъш (юфшэръют√ї, єўхЄтхЁхэшх) фы  8bpp
  808.             // 2 Єюўъш (юфшэръют√ї, єфтюхэшх) фы  16bpp
  809.             // 1 Єюўър фы  32bpp
  810.            
  811.             // ╥юўър т√ъы■ўхэр (фрээ√х фы  pc тшфхюярь Єш)
  812.             unsigned p0 = raw_data(     px0,
  813.                                         pass,
  814.                                         temp.obpp
  815.                                    );
  816.             // ╥юўър тъы■ўхэр (фрээ√х фы  pc тшфхюярь Єш)          
  817.             unsigned p1 = raw_data(     px1,
  818.                                         pass,
  819.                                         temp.obpp
  820.                                    );
  821.  
  822.             //-----------------------------------------------------------------
  823.             // sctab32 required for frame resampler in 16-bit mode, so temp.obpp=16 here
  824.             // ┬їюфэ√х фрээ√х 1 сшЄ
  825.             //
  826.             // ╥юўър т√ъы■ўхэр (фрээ√х фы  pc тшфхюярь Єш xrgb)
  827.             t.sctab32[pass][at] = raw_data(     px0,
  828.                                                 pass,
  829.                                                 32
  830.                                            );
  831.             // ╥юўър тъы■ўхэр (фрээ√х фы  pc тшфхюярь Єш xrgb)
  832.             t.sctab32[pass][at + 0x100] = raw_data(     px1,
  833.                                                         pass,
  834.                                                         32
  835.                                                    );
  836.             //-----------------------------------------------------------------
  837.             // 8 bit
  838.             unsigned j;
  839.             // j - ┬їюфэ√х фрээ√х (чэрўхэшх ў/с яшъёхыхщ) 4сшЄр (16 ъюьсшэрЎшщ)
  840.             for (j = 0; j < 0x10; j++)
  841.             {
  842.                 unsigned mask = (j >> 3) * 0xFF + (j & 0x04)*(0xFF00 / 4) +
  843.                                 (j & 0x02)*(0xFF0000 / 2) + (j & 1) * 0xFF000000;
  844.                 // ─рээ√х фы  pc тшфхюярь Єш 4 Єюўъш
  845.                 t.sctab8[pass][j + at * 0x10] = (mask & p1) + (~mask & p0);
  846.             }
  847.             //-----------------------------------------------------------------
  848.             // j - ┬їюфэ√х фрээ√х (чэрўхэшх ў/с яшъёхыхщ) 2сшЄр (4 ъюьсшэрЎшш)
  849.             for (j = 0; j < 4; j++)
  850.             {
  851.                 unsigned mask = (j >> 1) * 0xFFFF + (j & 1) * 0xFFFF0000;
  852.                 // ─рээ√х фы  pc тшфхюярь Єш 2 Єюўъш ё єфтюхэшхь
  853.                 t.sctab8d[pass][j + at * 4] = (mask & p1) + (~mask & p0);
  854.             }
  855.             //-----------------------------------------------------------------
  856.             // ┬їюфэ√х фрээ√х (чэрўхэшх ў/с яшъёхыхщ) 1сшЄ (2 ъюьсшэрЎшш)
  857.                
  858.                 // ─рээ√х фы  pc тшфхюярь Єш 1 Єюўър ё єўхЄтхЁхэшхь
  859.                 t.sctab8q[at] = p0; t.sctab8q[at + 0x100] = p1;
  860.             //-----------------------------------------------------------------
  861.             // 16 bit
  862.             // j - ┬їюфэ√х фрээ√х (чэрўхэшх ў/с яшъёхыхщ) 2сшЄр (4 ъюьсшэрЎшш)
  863.             for (j = 0; j < 4; j++)
  864.             {
  865.                 unsigned mask = (j >> 1) * 0xFFFF + (j & 1) * 0xFFFF0000;
  866.                 // ─рээ√х фы  pc тшфхюярь Єш 2 Єюўъш
  867.                 t.sctab16[pass][j + at * 4] = (mask & p1) + (~mask & p0);
  868.             }
  869.             //-----------------------------------------------------------------
  870.             // ┬їюфэ√х фрээ√х (чэрўхэшх ў/с яшъёхыхщ) 1сшЄ (2 ъюьсшэрЎшш)
  871.                
  872.                 // ─рээ√х фы  pc тшфхюярь Єш 1 Єюўър ё єфтюхэшхь
  873.                 t.sctab16d[pass][at] = p0; t.sctab16d[pass][at + 0x100] = p1;
  874.             //-----------------------------------------------------------------
  875.             unsigned atarimode;
  876.             if (!(temp.rflags & RF_MON) && (atarimode = temp.ataricolors[at]))
  877.             {
  878.                 unsigned rawdata[4], i;
  879.                 //-------------------------------------------------------------
  880.                 for (i = 0; i < 4; i++)
  881.                 {
  882.                     rawdata[i] = atari_to_raw(  (atarimode >> (8 * i)) & 0xFF,
  883.                                                 pass
  884.                                               );
  885.                 }
  886.                 //-------------------------------------------------------------
  887.                 for (i = 0; i < 16; i++)
  888.                 {
  889.                     t.sctab8[pass][at * 0x10 + i] = rawdata[i / 4] + 16 * rawdata[i & 3];
  890.                 }
  891.                 //-------------------------------------------------------------
  892.                 for (i = 0; i < 4; i++)
  893.                 {
  894.                     t.sctab8d[pass][at * 4 + i] = rawdata[i];
  895.                 }
  896.                 //-------------------------------------------------------------
  897.                 for (i = 0; i < 4; i++)
  898.                 {
  899.                     t.sctab16[pass][at * 4 + i] = rawdata[i];
  900.                 }
  901.                 //-------------------------------------------------------------
  902.             }
  903.         }
  904.     }
  905.     //-------------------------------------------------------------------------
  906.  
  907.     p4bpp_tables();     // used for ATM2+ mode0 and Pentagon-4bpp
  908.  
  909.     //-------------------------------------------------------------------------
  910.     if (temp.obpp > 8 && conf.noflic)
  911.     {
  912.         calc_noflic_16_32();
  913.     }
  914.     //-------------------------------------------------------------------------
  915.     if (    (   ( temp.rflags & (RF_DRIVER | RF_2X | RF_USEFONT) ) == (RF_DRIVER | RF_2X)
  916.              )
  917.             && // render="double"
  918.             (   (conf.mem_model == MM_ATM450)   ||
  919.                 (conf.mem_model == MM_ATM710)   ||
  920.                 (conf.mem_model == MM_ATM3)     ||
  921.                 (conf.mem_model == MM_PROFI)
  922.              )
  923.       )
  924.     {
  925.         hires_sc_tables();
  926.     }
  927.     //-------------------------------------------------------------------------
  928.    
  929.    
  930.    
  931.     //-----------------------------------------------------------------------------
  932.     // DDp ярышЄЁр !!!!!!!!
  933.    
  934.     if (conf.ATM_DDp_4K_Palette != 0) // [NS]
  935.     {
  936.         //added by Alone Coder 04.12.2021 (no ULAplus!!! no default palette!!! ATM3 only!!!):
  937.         if (    (conf.mem_model == MM_ATM3)     &&              //NEDOREPO
  938.                 ((comp.pBF & 0x20) != 0)
  939.           )        
  940.         {
  941.             PALETTE_OPTIONS *pl = &pals[conf.pal];
  942.            
  943.             //colorindex = comp.border_attr;
  944.             for (u8 colorindex = 0; colorindex < 16; colorindex++) //чєсюфЁюсшЄхы№э√щ рыюэюъюф
  945.             {
  946.                 unsigned r0, g0, b0;
  947.                 u16 atm3color = comp.atm3_pal[colorindex];
  948.                 r0 = (((atm3color>>1)<<3)&8) + (((atm3color>>6)<<2)&4) + (((atm3color>>9)<<1)&2) + ((atm3color>>14)&1);
  949.                 g0 = (((atm3color>>4)<<3)&8) + (((atm3color>>7)<<2)&4) +(((atm3color>>12)<<1)&2) + ((atm3color>>15)&1);
  950.                 b0 = (((atm3color>>0)<<3)&8) + (((atm3color>>5)<<2)&4) + (((atm3color>>8)<<1)&2) + ((atm3color>>13)&1);
  951.                 r0 = (r0^15) * 17;      //0..255
  952.                 g0 = (g0^15) * 17;      //0..255
  953.                 b0 = (b0^15) * 17;      //0..255
  954.                 unsigned r = 0xFF & ((r0 * pl->r11 + g0 * pl->r12 + b0 * pl->r13) / 0x100); //pl->r11 etc. = 0..0x100
  955.                 unsigned g = 0xFF & ((r0 * pl->r21 + g0 * pl->r22 + b0 * pl->r23) / 0x100);
  956.                 unsigned b = 0xFF & ((r0 * pl->r31 + g0 * pl->r32 + b0 * pl->r33) / 0x100);
  957.                
  958.                 // prepare palette in bitmap header for GDI renderer
  959.                 /*             
  960.                 gdibmp.header.bmiColors[colorindex].rgbRed = pal0[colorindex].peRed = BYTE(r);
  961.                 gdibmp.header.bmiColors[colorindex].rgbGreen = pal0[colorindex].peGreen = BYTE(g);
  962.                 gdibmp.header.bmiColors[colorindex].rgbBlue = pal0[colorindex].peBlue = BYTE(b);
  963.                 setpal(0);
  964.                 */
  965.                 u32 rgb = (r<<16) + (g<<8) + b;
  966.                 //pixels in EGA are shown in order "ink","paper" (%PIpppiii) with this code (src[] is ZX Spectrum memory):
  967.                 //        d[x+0]  = d[x+1]  = tab[0+2*src[ega0_ofs + src_offset]]; //"ink" pixel
  968.                 //        d[x+2]  = d[x+3]  = tab[1+2*src[ega0_ofs + src_offset]]; //"paper" pixel
  969.                 //unsigned *tab = t.p4bpp32[0] (even lines) or [1] (odd lines);
  970.                
  971.                 u8 inkindex = (colorindex&7) + ((colorindex&8)<<3);
  972.                
  973.                 for (u8 paper = 0; paper < 16; paper++)
  974.                 {
  975.                     u8 paperindex = ((paper&7)<<3) + ((paper&8)<<4);
  976.                     t.p4bpp32[0][0+2*(inkindex+paperindex)] = rgb;      //"ink" pixel (even lines)
  977.                     t.p4bpp32[1][0+2*(inkindex+paperindex)] = rgb;      //"ink" pixel (odd lines)
  978.                 }
  979.                
  980.                 u8 paperindex = ((colorindex&7)<<3) + ((colorindex&8)<<4);
  981.                
  982.                 for (u8 ink = 0; ink < 16; ink++)
  983.                 {
  984.                    u8 inkindex = (ink&7) + ((ink&8)<<3);
  985.                    t.p4bpp32[0][1+2*(inkindex+paperindex)] = rgb; //"paper" pixel (even lines)
  986.                    t.p4bpp32[1][1+2*(inkindex+paperindex)] = rgb; //"paper" pixel (odd lines)
  987.                 }
  988.             }
  989.         }
  990.     } // ATM_DDp_4K_Palette
  991.        
  992. //-----------------------------------------------------------------------------
  993.    
  994. } // pixel_tables()
  995.  
  996. //=============================================================================
  997.  
  998.  
  999.  
  1000.  
  1001. //=============================================================================
  1002. void video_color_tables()
  1003. {
  1004.     temp.shift_mask = 0xFEFEFEFE;       // 32bit, 16bit YUY2
  1005.     if (temp.obpp == 16 && temp.hi15==0) temp.shift_mask = 0xF7DEF7DE;
  1006.     if (temp.obpp == 16 && temp.hi15==1) temp.shift_mask = 0x7BDE7BDE;
  1007.  
  1008.     create_palette();
  1009.     pixel_tables();
  1010.     make_colortab(0);
  1011.  
  1012.     if (temp.rflags & (RF_USEC32 | RF_USE32AS16))
  1013.     {
  1014.         for (unsigned at = 0; at < 0x100; at++)
  1015.         {
  1016.             for (unsigned vl = 0; vl <= 0x10; vl++)
  1017.             {
  1018.                 unsigned br = (at & 0x40) ?     0xFF :
  1019.                                                 0xBF ;
  1020.                 unsigned c1, c2, res;
  1021.                 c1 = (at & 1) >> 0;
  1022.                 c2 = (at & 0x08) >> 3;
  1023.                 unsigned b = (c1*vl + c2*(0x10-vl))*br/0x10;
  1024.                
  1025.                 c1 = (at & 2) >> 1;
  1026.                 c2 = (at & 0x10) >> 4;
  1027.                 unsigned r = (c1*vl + c2*(0x10-vl))*br/0x10;
  1028.                
  1029.                 c1 = (at & 4) >> 2;
  1030.                 c2 = (at & 0x20) >> 5;
  1031.                 unsigned g = (c1*vl + c2*(0x10-vl))*br/0x10;
  1032.                
  1033.                 if (temp.rflags & RF_USE32AS16)
  1034.                 {
  1035.                     if (temp.hi15 == 0) res = (b/8) + ((g/4)<<5) + ((r/8)<<11);
  1036.                     if (temp.hi15 == 1) res = (b/8) + ((g/8)<<5) + ((r/8)<<10);
  1037.                     if (temp.hi15 == 2)
  1038.                         res = getYUY2(r,g,b);
  1039.                     else
  1040.                         res *= 0x10001; // for hi15=0,1
  1041.                 }
  1042.                 else
  1043.                 {
  1044.                     res =  WORD4(b,g,r,0);
  1045.                 }
  1046.                
  1047.                 t.c32tab[at][vl] = res;
  1048.             }
  1049.         }
  1050.     }
  1051.    
  1052.     setpal(0);
  1053. }
  1054. //=============================================================================
  1055.  
  1056.  
  1057. //=============================================================================
  1058. void video_timing_tables()
  1059. {
  1060. // яЁш шэшЎшрышчрЎшш ш ёьхэх тшфхюфЁрщтхЁр
  1061. // яЁш ёьхэх эрёЄЁюхъ
  1062.  
  1063.         //printf("video_timing_tables()\n");
  1064.  
  1065.     if (conf.frame < 2000)      //!!!!!!!!!!!
  1066.     {
  1067.         conf.frame = 2000;
  1068.         cpu.SetTpi(conf.frame);
  1069.     }
  1070.     if (conf.t_line < 128) conf.t_line = 128;
  1071.    
  1072.     conf.nopaper &= 1;
  1073.     atrtab = (comp.pEFF7 & EFF7_HWMC) ? t.atrtab_hwmc   :
  1074.                                         t.atrtab        ;
  1075.  
  1076. //   conf.bordersize=2;
  1077. //   temp.scx = 384, temp.scy = 300;
  1078.  
  1079.  
  1080.     // ╧хЁхтюф тхышўшэ√ т яшъёхы ї т ўшёыю чэръюьхёЄ ё єўхЄюь рЄЁшсєЄют
  1081.     // (ърцфюх чэръюьхёЄю чрэшьрхЄ 2 срщЄр, срщЄ фрээ√ї ш срщЄ рЄЁшсєЄют)
  1082.  
  1083. #define p2cc(p) ((p)/4)
  1084.  
  1085.     // ╪шЁшэр ¤ъЁрэр т чэръюьхёЄрї * 2 (Є.ъ. шёяюы№чє■Єё  яшъёхыш ш рЄЁшсєЄ√ эр 1 чэръюьхёЄю)
  1086.     const unsigned width = p2cc(temp.scx);
  1087.     //temp.vidbufsize = temp.scx*temp.scy/4;
  1088.  
  1089.     // make video table
  1090.     unsigned mid_lines = 192;           // ╫шёыю ёЄЁюъ т ЎхэЄЁры№эющ ўрёЄш ¤ъЁрэр (схч сюЁф■Ёр)
  1091.     const unsigned buf_mid = 256;       // ╫шёыю яшъёхыхщ т ЎхэЄЁры№эющ ўрёЄш ¤ъЁрэр (схч сюЁф■Ёр)
  1092.  
  1093.     //-------------------------------------------------------------------------
  1094.     // ╨рёўхЄ ЁрчьхЁ сюЁф■Ёр т яшъёхы ї (1 яшъёхы№ = 2 ЄръЄр)
  1095.     temp.b_bottom = temp.b_top = conf.b_top_small;
  1096.     temp.b_left = conf.b_left_small;                            // border small
  1097.     //-------------------------------------------------------------------------
  1098.     if (conf.bordersize == 0)                                   // border none
  1099.     {
  1100.         temp.b_top = temp.b_left = 0;
  1101.     }
  1102.     //-------------------------------------------------------------------------
  1103.     if (conf.bordersize == 2)                                   // border wide
  1104.     {
  1105.         temp.b_top = conf.b_top_full;
  1106.         temp.b_left = conf.b_left_full;
  1107.     }
  1108.     //-------------------------------------------------------------------------
  1109.     if (conf.bordersize == 3)           // border full  // Єъ ЁрчьхЁ√ яю X эєцэ√ ъЁрЄэ√х 8
  1110.     {                                   // [NS]         // Єю эхы№ч  юЄюсЁрчшЄ№ яЁртшы№э√щ ЁрчьхЁ
  1111.                                         //              // фюсрты   ёыхтр юЄ·хфрхЄёю ўрёЄ№ шчюсЁрцхэш  ёяЁртр
  1112.                                         //              // яю¤Єюьє шчюсЁрцхэшх чрфрхЄёю ё чрярёюь ёю тёхї ёЄюЁюэ
  1113.                                         //              // ш тшфэю ьєёюЁ
  1114.                                         //              // ьюцхЄ тсєфєї∙хь эхтрышфэр  ўрёЄ№ сєфхЄ чрЄшЁрЄёю яютхЁї
  1115.                                         //              // Єръ цх 16ё Ёхцшь√ Ёшёє■Є ьшью !!!!!!111
  1116. //      temp.b_top = (conf.paper / conf.t_line) + 2;
  1117. //      temp.b_left = (((conf.paper % conf.t_line) & 0x07 ) == 0)   ?   (conf.paper % conf.t_line)              :
  1118. //                                                                      (((conf.paper % conf.t_line) | 0x07)+1) ;
  1119. //   conf.paper = GetPrivateProfileInt(ula, "Paper", 17989, ininame);
  1120. // 17989 / 224 = 80,308035714285714285714285714286 y
  1121. // 17989 % 224 = 69,000000000000000000000000000064 ??? x
  1122.  
  1123.         temp.b_top = 84;
  1124.         temp.b_left = 128;
  1125.     }
  1126.     //-------------------------------------------------------------------------
  1127.    
  1128.         //printf("temp.b_top %d\n",temp.b_top);
  1129.         //printf("temp.b_left %d\n",temp.b_left);
  1130.        
  1131.  
  1132.  
  1133.  
  1134.    // temp.scx - ўшёыю Єюўхъ т ьєы№ЄшъюыюЁх яю уюЁшчюэЄрыш
  1135.    // temp.scy - ўшёыю ёЄЁюъ т ьєы№ЄшъюыюЁх
  1136.    // 256x192 - border none
  1137.    // 320x240 - border small
  1138.    // 384x300 - border full, pentagon: ((36+128+28)*2=384)x(304=64+192+48), scorpion: ((24+128+32)*2=368)x(296=64+192+40)))
  1139.  
  1140.     // ╨рёўхЄ ЁрчьхЁр яЁртющ ўрёЄш сюЁф■Ёр т яшъёхы ї (1 яшъёхы№ = 1/2 ЄръЄр)
  1141.     temp.b_right = temp.scx - buf_mid - temp.b_left;
  1142.     // ╨рёўхЄ ЁрчьхЁр эшцэхщ ўрёЄш сюЁф■Ёр т яшъёхы ї (1 яшъёхы№ = 1/2 ЄръЄр)
  1143.     temp.b_bottom = temp.scy - mid_lines - temp.b_top;
  1144.  
  1145.     //-------------------------------------------------------------------------
  1146.     // ╨хцшь nopaper (ЁрёЄЁ т ёхЁхфшэх ¤ъЁрэр юЄёєЄёЄтєхЄ)
  1147.     if (conf.nopaper)
  1148.     {
  1149.         temp.b_bottom += mid_lines;
  1150.         mid_lines = 0;
  1151.     }
  1152.     //-------------------------------------------------------------------------
  1153.    
  1154.    
  1155.    
  1156.     //-------------------------------------------------------------------------
  1157.     int inx = 0;
  1158.  
  1159.     unsigned i;
  1160.    
  1161. #define ts(t) (((int)(t) < 0) ? 0 : t)
  1162.  
  1163. // ╧хЁхтюф яшъёхыхщ т ЄръЄ√
  1164. #define p2t(p) ((p)/2)
  1165.  
  1166.     // conf.paper - ╫шёыю ЄръЄют юЄ эрўрыр ЁрёЄЁр фю ЎхэЄЁры№эющ ўрёЄш spectrum ¤ъЁрэр
  1167.     // (тъы■ўрхЄ эхтшфшьє■ ўрёЄ№ + яюыэюёЄ№■ тхЁїэшщ сюЁф■Ё + эрўрыю ёЄЁюъш °шЁшэющ hblank + ыхт√щ сюЁф■Ё)
  1168.     // ─ы  pentagon 128: (16+64)*(32+36+128+28)+32+36 = 17988 ЄръЄют
  1169.     // 16 ёЄЁюъ эрф тхЁїэшь сюЁф■Ёюь
  1170.     // 64 ёЄЁюъш - тхЁїэшщ сюЁф■Ё
  1171.     // ърцфр  ёЄЁюър 224 ЄръЄр:
  1172.     // 32 ЄръЄр hblank
  1173.     // 36 ЄръЄют - ыхт√щ сюЁф■Ё
  1174.     // 128 ЄръЄют - ЎхэЄЁ ¤ъЁрэр
  1175.     // 28 ЄръЄют - яЁрт√щ сюЁф■Ё
  1176.    
  1177.     // ╫шёыю ЄръЄют фю эрўрыр тхЁїэхую сюЁф■Ёр (тъы■ўр  hblank + ыхт√щ сюЁф■Ё т яхЁтющ ёЄЁюъх paper)
  1178.     unsigned t = conf.paper - temp.b_top*conf.t_line;
  1179.     // ╫шёыю ЄръЄют т hblank
  1180.     const unsigned hblank = conf.t_line - p2t(temp.scx);
  1181.     // ╚ёъы■ўхэшх ыхтюую сюЁф■Ёр (next_t - ЄръЄ эрўрыр яхЁтющ ёЄЁюъш тхЁїэхую сюЁф■Ёр)
  1182.     video[inx++].next_t = ts(t - p2t(temp.b_left));
  1183.  
  1184. //   printf("btop: temp.b_top=%u, conf.b_top_full=%u\n", temp.b_top, conf.b_top_full);
  1185.  
  1186.     //-------------------------------------------------------------------------
  1187.     // тхЁїэшщ сюЁф■Ё
  1188.     for (i = 0; i < temp.b_top; i++)
  1189.     {
  1190.    
  1191.         // ╩юэхЎ яЁртюую сюЁф■Ёр (ЄръЄ ъюэЎр Єхъє∙хщ ёЄЁюъш)
  1192.         video[inx].next_t = ts(t + p2t(buf_mid+temp.b_right));
  1193.         // ╙ърчрЄхы№ эр эрўрыю Єхъє∙хщ ёЄЁюъш т сєЇхЁх юЄЁшёютъш
  1194.         video[inx].screen_ptr = rbuf+width*i;
  1195.         // hblank (яхЁхїюф ъ эютющ ёЄЁюъх)
  1196.         video[inx].nextvmode = 0;      
  1197.        
  1198. // printf("%3u: b=%u, e=%u, o=%u\n", i, video[inx-1].next_t, video[inx].next_t, width*i);
  1199.  
  1200.         // ╧хЁхїюф ъ ёыхфє■∙хщ ёЄЁюъх (t - ЄръЄ эрўрыр paper ёыхфє■∙хщ ёЄЁюъш hblank + ыхт√щ сюЁф■Ё)
  1201.         inx++; t += conf.t_line;
  1202.         // ╚ёъы■ўхэшх ыхтюую сюЁф■Ёр (ЄръЄ эрўрыр ыхтюую сюЁф■Ёр эр ёыхфє■∙хщ ёЄЁюъх)
  1203.         video[inx++].next_t = ts(t - p2t(temp.b_left));
  1204.     }
  1205.     //-------------------------------------------------------------------------
  1206.    
  1207. //   printf("paper:\n");
  1208.  
  1209.     //-------------------------------------------------------------------------
  1210.     // hblank + ыхт√щ сюЁф■Ё + ¤ъЁрэ + яЁрт√щ сюЁф■Ё
  1211.     for (i = 0; i < mid_lines; i++)
  1212.     {  
  1213.         // ╩юэхЎ ыхтюую сюЁф■Ёр (ЄръЄ эрўрыр paper эр Єхъє∙хщ ёЄЁюъх)
  1214.         video[inx].next_t = ts(t);
  1215.         // ╙ърчрЄхы№ эр эрўрыю iщ ёЄЁюъш ыхтюую сюЁф■Ёр т сєЇхЁх юЄЁшёютъш
  1216.         video[inx].screen_ptr = rbuf+width*(i+temp.b_top);
  1217.         // ─рыхх яЁюЁшёют√трхЄё  paper
  1218.         video[inx].nextvmode = 2;
  1219. // printf("%3u: b=%u ", i, video[inx-1].next_t);
  1220.         inx++;
  1221.         //---------------------------------------------------------------------
  1222.         // ╩юэхЎ paper (ЄръЄ эрўрыр яЁртюую сюЁф■Ёр эр Єхъє∙хщ ёЄЁюъх)
  1223.         video[inx].next_t = ts(t + p2t(buf_mid));
  1224.         // ╙ърчрЄхы№ эр эрўрыю iщ ёЄЁюъш paper т сєЇхЁх юЄЁшёютъш
  1225.         video[inx].screen_ptr = rbuf+width*(i+temp.b_top)+p2cc(temp.b_left);
  1226.         // ╤ьх∙хэшх юЄ эрўрыр zx ¤ъЁрэр (яшъёхыш)
  1227.         video[inx].scr_offs = ::t.scrtab[i];
  1228.         // ╤ьх∙хэшх юЄ эрўрыр чюэ√ рЄЁшсєЄют zx ¤ъЁрэр
  1229.         video[inx].atr_offs = atrtab[i];
  1230.         inx++;
  1231.         //---------------------------------------------------------------------
  1232.         // ╩юэхЎ яЁртюую сюЁф■Ёр (ЄръЄ ъюэЎр Єхъє∙хщ ёЄЁюъш)
  1233.         video[inx].next_t = ts(t + p2t(buf_mid+temp.b_right));
  1234.         // ╙ърчрЄхы№ эр эрўрыю iщ ёЄЁюъш яЁртюую сюЁф■Ёр т сєЇхЁх юЄЁшёютъш
  1235.         video[inx].screen_ptr = rbuf+width*(i+temp.b_top)+p2cc(buf_mid+temp.b_left);
  1236.         // hblank (яхЁхїюф ъ эютющ ёЄЁюъх)
  1237.         video[inx].nextvmode = 0;      
  1238.  
  1239. // printf("e=%u\n", video[inx].next_t);
  1240.  
  1241.         // ╧хЁхїюф ъ ёыхфє■∙хщ ёЄЁюъх (t - ЄръЄ эрўрыр paper ёыхфє■∙хщ ёЄЁюъш hblank + ыхт√щ сюЁф■Ё)
  1242.         inx++;          t += conf.t_line;
  1243.         // ╚ёъы■ўхэшх ыхтюую сюЁф■Ёр (ЄръЄ эрўрыр ёыхфє■∙хщ ёЄЁюъш)
  1244.         video[inx++].next_t = ts(t - p2t(temp.b_left));
  1245.     }
  1246.     //-------------------------------------------------------------------------
  1247.    
  1248. //   printf("bbot:\n");
  1249.  
  1250.     //-------------------------------------------------------------------------
  1251.     // эшцэшщ сюЁф■Ё
  1252.     for (i = 0; i < temp.b_bottom; i++)
  1253.     {
  1254.         // ╩юэхЎ яЁртюую сюЁф■Ёр (ЄръЄ ъюэЎр Єхъє∙хщ ёЄЁюъш)
  1255.         video[inx].next_t = ts(t + p2t(buf_mid+temp.b_right));
  1256.         // ╙ърчрЄхы№ эр эрўрыю iщ ёЄЁюъш эшцэхую сюЁф■Ёр т сєЇхЁх юЄЁшёютъш
  1257.         video[inx].screen_ptr = rbuf+width*(i+temp.b_top+mid_lines);
  1258.         // hblank (яхЁхїюф ъ эютющ ёЄЁюъх)
  1259.         video[inx].nextvmode = 0;
  1260.        
  1261. // printf("%3u: b=%u, e=%u\n", i, video[inx-1].next_t, video[inx].next_t);
  1262.  
  1263.         // ╧хЁхїюф ъ ёыхфє■∙хщ ёЄЁюъх (t - ЄръЄ эрўрыр paper ёыхфє■∙хщ ёЄЁюъш hblank + ыхт√щ сюЁф■Ё)
  1264.         inx++;          t += conf.t_line;
  1265.         // ╚ёъы■ўхэшх ыхтюую сюЁф■Ёр (ЄръЄ эрўрыр ёыхфє■∙хщ ёЄЁюъш)
  1266.         video[inx++].next_t = ts(t - p2t(temp.b_left));
  1267.    }
  1268.    //-------------------------------------------------------------------------
  1269.    
  1270.     video[inx-1].next_t = 0x7FFFFFFF;   // ╧Ёшчэръ яюёыхфэхщ ёЄЁюъш
  1271. //   exit(0);
  1272.  
  1273.     temp.evenM1_C0 = conf.even_M1    ?  0xC0 :
  1274.                                         0x00;
  1275.     temp.border_add = conf.border_4T ?  6 :
  1276.                                         0;
  1277.     temp.border_and = conf.border_4T ?  0xFFFFFFFC :
  1278.                                         0xFFFFFFFF;
  1279.  
  1280.     //-------------------------------------------------------------------------
  1281.     for (i = 0; i < NUM_LEDS; i++)
  1282.     {
  1283.         unsigned z = *(&conf.led.ay + i);
  1284.    
  1285.         int x = (signed short)(z & 0xFFFF);
  1286.         int y = (signed short)(((z >> 16) & 0x7FFF) + ((z >> 15) & 0x8000));
  1287.         //printf("leds convert??? %X %X %X\n",z,x,y);
  1288.         if (x < 0) x += width * 8;
  1289.         if (y < 0) y += temp.scy;
  1290.         *(&temp.led.ay + i) = (z & 0x80000000)    ?     rbuf + ( (x >> 2) & 0xFE ) + unsigned(y) * width :
  1291.                                                         nullptr;
  1292.       //printf("leds convert??? %X\n",*(&temp.led.ay+i));
  1293.     }
  1294.     //-------------------------------------------------------------------------
  1295.       //printf("\n");
  1296.      
  1297.     if (temp.rflags & RF_USEFONT)
  1298.         create_font_tables();
  1299.  
  1300.     needclr = 2;
  1301. }
  1302. //=============================================================================
  1303.  
  1304.  
  1305.  
  1306. //=============================================================================
  1307. //void set_video()
  1308. void set_video( bool preserve_size)
  1309. {
  1310. // bool preserve_size = FALSE by default
  1311. //   printf("%s\n", __FUNCTION__);
  1312. //    set_vidmode();
  1313.     set_vidmode( preserve_size);        // preserve size tezt
  1314.     video_color_tables();
  1315. }
  1316. //=============================================================================
  1317.  
  1318.  
  1319.  
  1320. //=============================================================================
  1321. // void apply_video()
  1322. void apply_video( bool preserve_size)                                   // [NS]
  1323. {
  1324. // bool preserve_size = FALSE by default !!!!
  1325.  
  1326. //   printf("%s\n", __FUNCTION__);
  1327.     load_ula_preset();
  1328.  
  1329.     //-------------------------------------------------------------------------
  1330.     if (        (conf.mem_model == MM_ATM710)   ||
  1331.                 (conf.mem_model == MM_ATM3)     ||
  1332.                 (conf.mem_model == MM_ATM450)   ||
  1333.                 (conf.mem_model == MM_PROFI)
  1334.       )
  1335.     {
  1336.         // ─ы  ьюфхыхщ ё ¤ъЁрэюь 640x200 яюффхЁцштрхЄё  Єюы№ъю redner = double (640x480)
  1337.         conf.render = 1;        //"double" - RENDER renders[] т dx.cpp
  1338.         printf("Force <double> video filter\n");
  1339.         //      тЁюфх эх яЁштюфшЄ ъ ярфхэш ь
  1340.         //      ═╬ эшўхую эх юЄюсЁрцрхЄёю яЁш ¤Єюь т Ёрё°шЁхэюь Ёхцшьх
  1341.  
  1342.         // [NS] чряєёъ └╥╠ тшфхю Ёхцшьют т Ёхцшьх схч сюЁф■Ёр
  1343.         // ьюцхЄ тююс∙х т√чтрЄ№ ярфхэшх фЁрщтхЁр тшф■їш эрї!
  1344.         //      яю їюЁю°хьє эрфю тъы■ўрЄ№ Єюы№ъю ъюуфр ЁрсюЄрхЄ ¤ЄюЄ тшфхю Ёхцшь !!!
  1345.         if (!conf.bordersize)
  1346.         {
  1347.             conf.bordersize = 1;
  1348.             printf("Force <Small> border\n");
  1349.         }
  1350.     }
  1351.     //-------------------------------------------------------------------------
  1352.    
  1353.     temp.rflags = renders[ conf.render].flags;
  1354.    
  1355.     //-------------------------------------------------------------------------
  1356.     if ( conf.use_comp_pal && ( (conf.mem_model == MM_ATM710)   ||
  1357.                                 (conf.mem_model == MM_ATM3)     ||
  1358.                                 (conf.mem_model == MM_ATM450)   ||
  1359.                                 (conf.mem_model == MM_PROFI)
  1360.                                )
  1361.       )
  1362.     {
  1363.         temp.rflags |= ( RF_COMPPAL | RF_PALB );
  1364.        
  1365.         // disable palette noflic, only if it is really used
  1366.         if (  (temp.obpp == 8)  &&  ( (temp.rflags & (RF_DRIVER | RF_USEFONT | RF_8BPCH) ) == RF_DRIVER)  )
  1367.             conf.noflic = 0;
  1368.     }
  1369.     //-------------------------------------------------------------------------
  1370.     if (conf.ula_plus/* && comp.ula_plus_en*/)
  1371.     {
  1372.         temp.rflags |= RF_COMPPAL | RF_PALB;
  1373.     }
  1374.     //-------------------------------------------------------------------------
  1375.     if (renders[conf.render].func == render_rsm)
  1376.         conf.flip = 1;  // todo: revert back after returning from frame resampler //Alone Coder
  1377.   //-------------------------------------------------------------------------
  1378.     if (renders[ conf.render].func == render_advmame)
  1379.     {
  1380.         if (conf.videoscale == 2)       temp.rflags |= RF_2X;
  1381.         if (conf.videoscale == 3)       temp.rflags |= RF_3X;
  1382.         if (conf.videoscale == 4)       temp.rflags |= RF_4X;
  1383.     } //Alone Coder
  1384.     //-------------------------------------------------------------------------
  1385.    
  1386.     set_video( preserve_size);
  1387.    
  1388.     calc_rsm_tables();
  1389.    
  1390.     video_timing_tables();
  1391. }
  1392. //=============================================================================
  1393.  
  1394.  
  1395.  
  1396. //=============================================================================
  1397. //__inline unsigned char *raypointer()  // ¤Єю Ёрчютр  ЇєэъЎш  [NS]
  1398. unsigned char *raypointer()             // хщ ёютхЁ°хээю эх эєцэю с√Є№ inline
  1399. {                                       // ш яЁш ¤Єюь хх эрфю т√ч√трЄ№ шч фЁєушї Їрщыют
  1400.     //-------------------------------------------------------------------------
  1401.     if (prev_t > conf.frame)
  1402.     {
  1403.         return rbuf + rb2_offs;
  1404.     }
  1405.     //-------------------------------------------------------------------------
  1406.     if (!vmode)
  1407.     {
  1408.         return vcurr[1].screen_ptr;
  1409.     }
  1410.     //-------------------------------------------------------------------------
  1411.     unsigned offs = (prev_t - vcurr[-1].next_t) / 4;
  1412. //  prev_t ш vcurr[-1].next_t сюы№°х эх юсэюты ■Єёю яюёых ъюэЎр ЇЁхщьр т фхсрухЁх!!!
  1413.  
  1414. //  printf("offs %d             prev_t %d       vcurr[-1].next_t %d\n",offs,prev_t,vcurr[-1].next_t);  
  1415.     return vcurr->screen_ptr + (offs+1) * 2;
  1416.     //-------------------------------------------------------------------------
  1417.  
  1418. }
  1419. //=============================================================================
  1420.  
  1421.  
  1422.  
  1423. //=============================================================================
  1424. // ьхЁчёър  ёЄшЁрыър "яюёых ыєўр"
  1425. // фы  яюърчр т фхсрухЁх
  1426.  
  1427. __inline void clear_until_ray()
  1428. {    
  1429.     unsigned char *dst = raypointer();
  1430.    
  1431.     //printf ("ray_addr %x\n",dst);
  1432.     while (dst < rbuf + rb2_offs)
  1433.     {
  1434.         //*dst++ = 0;   //px
  1435.         //*dst++ = 0x55;        //attr
  1436.  
  1437.         // хфшэёЄтхээюх ўЄю ьюцэю ёфхырЄ№ ё ¤Єшь урЇэюь         // [NS]
  1438.         // invert                              
  1439.         //*dst = ~(*dst);       //px
  1440.         dst++;
  1441.         *dst = ~(*dst);         //attr
  1442.         dst++;
  1443.     }
  1444. }
  1445. //=============================================================================
  1446.  
  1447.  
  1448.  
  1449.  
  1450. //=============================================================================
  1451. void paint_scr( char alt)       // alt=0/1 - main/alt screen,
  1452. {                               // alt=2 - ray-painted
  1453.  
  1454. // т√ч√трхЄё  яЁш юЄЁшёютъш юъэр т фхсрухЁх
  1455. // printf("paint_scr ");
  1456.  
  1457.     //-------------------------------------------------------------------------
  1458.     if (alt == 2)
  1459.     {
  1460.         update_screen();
  1461.         clear_until_ray();
  1462.     }
  1463.     //-------------------------------------------------------------------------
  1464.     else
  1465.     {
  1466.         //---------------------------------------------------------------------
  1467.         if (alt)
  1468.         {
  1469.             comp.p7FFD ^= 8;    // ыюы°Єю юэю ўЄю фхЁурхЄ срэъш фы  юЄЁшёютъш?
  1470.             set_banks();
  1471.         }
  1472.         //---------------------------------------------------------------------
  1473.         draw_screen();
  1474.         //---------------------------------------------------------------------
  1475.         if (alt)
  1476.         {
  1477.             comp.p7FFD ^= 8;
  1478.             set_banks();
  1479.         }
  1480.         //---------------------------------------------------------------------
  1481.     }
  1482. }
  1483. //=============================================================================
  1484.  
  1485.  
  1486.  
  1487. //=============================================================================
  1488. // ┬√ч√трхЄё  яЁш чряшёш т тшфхюярь Є№/(яюЁЄ√ FE/7FFD) эютюую чэрўхэш 
  1489. // ╧ЁюшчтюфшЄ юЄЁшёютъє сюЁф■Ёр/¤ъЁрэр т яЁюьхцєЄюўэ√щ сєЇхЁ ё шёяюы№чютрэшхь pc рЄЁшсєЄют
  1490.  
  1491. // ъЄюц фюфєьрыёю Єръюх фхыюЄ№...
  1492.  
  1493. void update_screen()
  1494. {
  1495. //printf("update_screen() ");
  1496.  
  1497.     unsigned last_t = (cpu.t + temp.border_add) & temp.border_and;
  1498.     unsigned t = prev_t;
  1499.  
  1500. // ┬√яюыэ хЄё  юЄЁшёютър юЄ яюёыхфэхую юЄЁшёютрээюую ЄръЄр prev_t фю Єхъє∙хую юъЁєуыхээюую ЄръЄр last_t
  1501. //   printf("upd_scr: t=%u, lt=%u, vm=%u\n", t, last_t, vmode);
  1502.    
  1503.     // ═хтшфшьр  ўрёЄ№ ёЄЁюъш (hblank ышсю эхтшфшь√х ёЄЁюъш тхЁїэхую сюЁф■Ёр)
  1504.     if (t >= last_t)
  1505.         return; // [NS] схч ¤Єюую єэЁшры ьюцюЄ ъЁр°шЄёю ё чряшё№■ т эхЄєфр
  1506.  
  1507.     unsigned char b = comp.border_attr;
  1508.     b |= (b<<4); // └ЄЁшсєЄ√ сюЁф■Ёр фєсышЁє■Єё  т ЇюЁьрЄх pc рЄЁшсєЄют ink=paper
  1509.  
  1510.     if (vmode == 1)
  1511.     {
  1512.         goto mode1; // border
  1513.     }
  1514.  
  1515.     if(vmode == 2) // screen
  1516.     {
  1517.         goto mode2;
  1518.     }
  1519.  
  1520. //-----------------------------------------------------------------------------
  1521. mode0: // not visible
  1522.     {
  1523.         vmode = 1;
  1524.         t = vcurr->next_t;      // ╥ръЄ эрўрыр ёЄЁюъш
  1525.         vcurr++;                // ╧хЁхїюф ъ ъюэЎє ёЄЁюъш
  1526.      
  1527.         if (t >= last_t)
  1528.         {
  1529. done:
  1530.             prev_t = t;         // ╧юёыхфэшщ юЄЁшёютрээ√щ ЄръЄ
  1531.             return;
  1532.         }
  1533.     }
  1534. //-----------------------------------------------------------------------------
  1535. mode1: // border
  1536.     {
  1537.         // ╤ьх∙хэшх т ЄръЄрї юЄ эрўрыр ёЄЁюъш (1 ЄръЄ = 2 яшъёхы )
  1538.         unsigned offs = (t - vcurr[-1].next_t);
  1539.         // ╙ърчрЄхы№ эр рфЁхё Єюўъш т яЁюьхцєЄюўэюь сєЇхЁх (ёЄЁєъЄєЁр сєЇхЁр 8pix:attr)
  1540.         unsigned char *ptr = vcurr->screen_ptr + offs/2;
  1541. //      u8 *pp =ptr;
  1542.         ptr = (unsigned char*)(ULONG_PTR(ptr) & ~ULONG_PTR(1)); // ┬√Ёртрэшх фю ўхЄэюую рфЁхёр
  1543.        
  1544.         //---------------------------------------------------------------------
  1545.         if (offs & 3)
  1546.         {
  1547.             // ╤ьхэр ЎтхЄр сюЁф■Ёр яЁюшчю°ыр эх яю уЁрэшЎх чэръюьхёЄр
  1548.             // (фтр ЎтхЄр сюЁф■Ёр тэєЄЁш юфэюую чэръюьхёЄр, ¤ьєышЁє■Єё  ўхЁхч ink/paper)
  1549.             //
  1550.             u8 old_b = (ptr[1] & 0x0F);
  1551.             if (old_b ^ (b & 0xF))
  1552.             {
  1553.                 // ╓тхЄ сюЁф■Ёр шчьхэшыё  яю ёЁртэхэш■ ё яЁхф√фє∙шь
  1554.                 //
  1555.                 // ╠рёър яшъёхыхщ (фы  1 - шёяюы№чєхЄё  ЎтхЄ ink, фы  0 - paper)
  1556.                 u8 mask = u8((unsigned)0xFF00 >> ((offs & 3) * 2));
  1557.                 *ptr = mask;
  1558.                 ptr++;
  1559.                 t += 4 - (offs & 3);
  1560.                 // └ЄЁшсєЄ√ (ink - ёЄрЁ√щ ЎтхЄ сюЁф■Ёр, paper - Єхъє∙шщ ЎтхЄ сюЁф■Ёр)
  1561.                 *ptr = old_b | (b & 0xF0);
  1562.                 ptr++;
  1563.             }
  1564.         }
  1565.         //---------------------------------------------------------------------
  1566.         unsigned end = min(vcurr->next_t, last_t);
  1567.        
  1568. // printf("upd_scr_m1: o=%uT, p=%u, t=%uT, end=%uT\n", offs, pp - rbuf, t, end);
  1569.  
  1570.         //---------------------------------------------------------------------
  1571.         // ╬сЁрсюЄър яшъёхыхщ яю чэръюьхёЄрь (яю 8 Єюўхъ)
  1572.         for (; t < end; t+=4)
  1573.         {
  1574.             *ptr++ = 0; // ╧шъёхыш эх шёяюы№чє■Єё 
  1575.             *ptr++ = b; // └ЄЁшсєЄ√
  1576.         }
  1577.         //---------------------------------------------------------------------
  1578.         t = end;
  1579.         //---------------------------------------------------------------------
  1580.         // ╤ЄЁюър чръюэўшырё№,  яхЁхїюф ъ ёыхфє■∙хщ Єюўъх
  1581.         if (t == vcurr->next_t)
  1582.         {
  1583.             vmode = vcurr->nextvmode;
  1584.             vcurr++;
  1585.         }
  1586.         //---------------------------------------------------------------------
  1587.         // ╬ЄЁшёютър чръюэўхэр, т√їюф
  1588.         if (t == last_t)
  1589.             goto done;
  1590.         //---------------------------------------------------------------------
  1591.         // ═рўрыю ёыхфє■∙хщ ёЄЁюъш
  1592.         if (!vmode)
  1593.             goto mode0;
  1594.         //---------------------------------------------------------------------
  1595.     }
  1596. //-----------------------------------------------------------------------------
  1597. mode2: // screen
  1598.     {
  1599.         // ╤ьх∙хэшх т чэръюьхёЄрї юЄ эрўрыр ёЄЁюъш (1 чэръюьхёЄю = 4 ЄръЄр = 8 яшъёхыхщ)
  1600.         unsigned offs = (t - vcurr[-1].next_t)/4;
  1601.         // spectrum яшъёхыш
  1602.         unsigned char *scr = temp.base + vcurr->scr_offs + offs;       
  1603.         // spectrum рЄЁшсєЄ√
  1604.         unsigned char *atr = temp.base + vcurr->atr_offs + offs;
  1605.         // ╤ЄЁєъЄєЁр сєЇхЁр 8pix:attr
  1606.         unsigned char *ptr = vcurr->screen_ptr + offs*2;
  1607.        
  1608.         unsigned end = min(last_t, vcurr->next_t);
  1609.        
  1610.         //---------------------------------------------------------------------
  1611.         for (int i = 0; t < end; t += 4, i++)
  1612.         {
  1613.             // ╩юяшЁютрэшх spectrum яшъёхыхщ
  1614.             ptr[2*i] = scr[i];
  1615.             // ╩юэтхЁЄшЁютрэшх spectrum рЄЁшсєЄют т pc рЄЁшсєЄ√
  1616.             ptr[2*i+1] = colortab[atr[i]];
  1617.         }
  1618.         //---------------------------------------------------------------------
  1619.         t = end;
  1620.         //---------------------------------------------------------------------
  1621.         // ╓хэЄЁры№эр  ўрёЄ№ ¤ъЁрэр чръюэўшырё№, юЄЁшёютър яЁртюую сюЁф■Ёр
  1622.         if (t == vcurr->next_t)
  1623.         {
  1624.             vmode = 1; // border
  1625.             vcurr++;
  1626.         }
  1627.         //---------------------------------------------------------------------
  1628.         // ╬ЄЁшёютър чръюэўхэр, т√їюф
  1629.         if (t == last_t)
  1630.             goto done;
  1631.         //---------------------------------------------------------------------
  1632.         goto mode1; // ╬ЄЁшёютър яЁртюую сюЁф■Ёр
  1633.     }
  1634. }
  1635. //=============================================================================
  1636.  
  1637.  
  1638.  
  1639. //=============================================================================
  1640. void init_frame()
  1641. {
  1642.     // recreate colors with flash attribute
  1643.     unsigned char frame = (unsigned char)comp.frame_counter;
  1644.  
  1645.     if (!(frame & 15) /* && !conf.flashcolor */ )
  1646.         make_colortab(frame & 16);
  1647.  
  1648.     prev_t = -1U;               // block MCR
  1649.     temp.base_2 = nullptr;      // block paper trace
  1650.  
  1651.     if (temp.vidblock)
  1652.         return;
  1653.  
  1654.  
  1655. /* [vv] ╬Єъы■ўхэ, Є.ъ. ¤ЄюЄ сшЄ шёяюы№чєхЄё  фы  DDp scroll
  1656.     //-------------------------------------------------------------------------
  1657.     // AlCo384 - no border/paper rendering
  1658.     if (comp.pEFF7 & EFF7_384)
  1659.         return;
  1660.     //-------------------------------------------------------------------------
  1661. */
  1662.  
  1663.     //-------------------------------------------------------------------------
  1664.     // GIGASCREEN - no paper rendering
  1665. //  if (comp.pEFF7 & EFF7_GIGASCREEN) goto allow_border; //Alone Coder
  1666.     //-------------------------------------------------------------------------
  1667.  
  1668.     //-------------------------------------------------------------------------
  1669.     // disable multicolors, border still works
  1670.     if (     (temp.rflags & RF_BORDER)                                  ||      // chunk/etc filter
  1671.          (   (conf.mem_model == MM_PROFI) && (comp.pDFFD & 0x80)   )    ||      // profi hires screen
  1672.          ( ( (conf.mem_model == MM_ATM710) || (conf.mem_model == MM_ATM3) )  &&  (comp.pFF77 & 7) != 3 ) ||  // ATM-2 hires screen
  1673.          (   (conf.mem_model == MM_ATM450) && ((comp.aFE & 0x60) != 0x60) )     // ATM-1 hires screen
  1674.        )
  1675.     {
  1676.         //---------------------------------------------------------------------
  1677.         // ATM2, юфшэ шч Ёрё°шЁхээ√ї тшфхюЁхцшьют
  1678.         if (    (conf.mem_model == MM_ATM710)   ||
  1679.                 (conf.mem_model == MM_ATM3)
  1680.           )
  1681.         {
  1682.             AtmVideoCtrl.PrepareFrameATM2(comp.pFF77 & 7);
  1683.         }
  1684.         //---------------------------------------------------------------------
  1685.         // ATM1, юфшэ шч Ёрё°шЁхээ√ї тшфхюЁхцшьют
  1686.         if (conf.mem_model == MM_ATM450)
  1687.         {
  1688.             AtmVideoCtrl.PrepareFrameATM1( (comp.aFE >> 5) & 3 );
  1689.         }
  1690.         //---------------------------------------------------------------------
  1691.         // if border update disabled, dont show anything on zx-screen
  1692.         if (!conf.updateb)
  1693.             return;
  1694.         //---------------------------------------------------------------------
  1695.     }
  1696.     //-------------------------------------------------------------------------
  1697.     // paper + border
  1698.     temp.base_2 = temp.base;
  1699. //allow_border:                 //юёЄрЄюъ юЄ GIGASCREEN
  1700.     prev_t = vmode = 0;
  1701.     vcurr = video;
  1702. }
  1703. //=============================================================================
  1704.  
  1705.  
  1706.  
  1707. //=============================================================================
  1708. void flush_frame()
  1709. {
  1710.     //-------------------------------------------------------------------------
  1711.     if (temp.vidblock)
  1712.         return;
  1713.     //-------------------------------------------------------------------------  
  1714.     if (prev_t != -1U)
  1715.     {
  1716.         // MCR on
  1717.         if (prev_t)
  1718.         {  
  1719.             // paint until end of frame
  1720.             // paint until screen bottom, even if n_lines*t_line < cpu.t (=t_frame)
  1721.             unsigned t = cpu.t;
  1722.             cpu.t = 0x7FFF0000;
  1723.             update_screen();
  1724.             cpu.t = t;
  1725. //          if (comp.pEFF7 & EFF7_GIGASCREEN) draw_gigascreen_no_border(); //Alone Coder
  1726.         }
  1727.         // MCR on, but no screen updates in last frame - use fast painter
  1728.         else
  1729.         {
  1730.             if (temp.base_2 /*|| (comp.pEFF7 & EFF7_GIGASCREEN)*/ /*Alone Coder*/)
  1731.                 draw_screen();
  1732.             else
  1733.                 draw_border();
  1734.         }
  1735.         return;
  1736.     }
  1737.     //-------------------------------------------------------------------------
  1738.     if (comp.pEFF7 & EFF7_384)
  1739.         draw_alco();
  1740.     //-------------------------------------------------------------------------
  1741. }
  1742. //=============================================================================
  1743.  
  1744.  
  1745.  
  1746. //=============================================================================
  1747. // spectrum colors -> palette indexes (RF_PALB - gggrrrbb format)
  1748. static const u8 comp_pal[16] =
  1749. {
  1750.     // normal bright  g   r   b   g  r  b
  1751.     0x00, // black   000|000|00  00|00|00
  1752.     0x02, // blue    000|000|10  00|00|10
  1753.     0x10, // red     000|100|00  00|10|00
  1754.     0x12, // magenta 000|100|10  00|10|10
  1755.     0x80, // green   100|000|00  10|00|00
  1756.     0x82, // cyan    100|000|10  10|00|10
  1757.     0x90, // yellow  100|100|00  10|10|00
  1758.     0x92, // white   100|100|10  10|10|10
  1759.  
  1760.     // high bright    g   r   b   g  r  b
  1761.     0x00, // black   000|000|00  00|00|00
  1762.     0x03, // blue    000|000|11  00|00|11
  1763.     0x1C, // red     000|111|00  00|11|00
  1764.     0x1F, // magenta 000|111|11  00|11|11
  1765.     0xE0, // green   111|000|00  11|00|00
  1766.     0xE3, // cyan    111|000|11  11|00|11
  1767.     0xFC, // yellow  111|111|00  11|11|00
  1768.     0xFF  // white   111|111|11  11|11|11
  1769. };
  1770. //=============================================================================
  1771.  
  1772.  
  1773.  
  1774.  
  1775. //=============================================================================
  1776. void load_spec_colors()
  1777. {
  1778.     for (unsigned flash = 0; flash < 2; flash++)
  1779.     {
  1780.         for (unsigned bright = 0; bright < 2; bright++)
  1781.         {
  1782.             unsigned PalNo = ((flash << 1) | bright) << 4;
  1783.             // ink ------------------------------------------------------------
  1784.             memcpy(     comp.comp_pal + (PalNo | (0 << 3)),
  1785.                         comp_pal + (bright << 3),
  1786.                         sizeof(comp_pal) / 2
  1787.                    );
  1788.             // paper ----------------------------------------------------------
  1789.             memcpy(     comp.comp_pal + (PalNo | (1 << 3)),
  1790.                         comp_pal + (bright << 3),
  1791.                         sizeof(comp_pal) / 2
  1792.                    );
  1793.             //-----------------------------------------------------------------
  1794.         }
  1795.     }
  1796.     temp.comp_pal_changed = 1;
  1797. }
  1798. //=============================================================================
  1799.  
  1800.