Subversion Repositories pentevo

Rev

Rev 796 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
716 lvd 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
#ifdef CACHE_ALIGNED
17
CACHE_ALIGNED unsigned char rbuf[sizeof_rbuf];
18
#else // __declspec(align) not available, force QWORD align with old method
19
__int64 rbuf__[sizeof_rbuf/sizeof(__int64)];
20
unsigned char * const rbuf = (unsigned char*)rbuf__;
21
#endif
22
 
23
unsigned char * const rbuf_s = rbuf + rb2_offs; // frames to mix with noflic and resampler filters
24
unsigned char * const save_buf = rbuf_s + rb2_offs*MAX_BUFFERS; // used in monitor
25
 
26
T t;
27
 
28
videopoint *vcurr; // ��������� �� ������� ������� �� video[]
29
// ������ ���������� ������� ������
30
// video[i] - ������ ������ (������������ ������ next_t)
31
// video[i+1] - ����� ������  (������������ ��� ���������)
796 DimkaM 32
static videopoint video[4*MAX_HEIGHT];
716 lvd 33
unsigned vmode;  // what are drawing: 0-not visible, 1-border, 2-screen
796 DimkaM 34
static unsigned prev_t; // ���� �� ������� ��� ��������� ��������� �������
716 lvd 35
unsigned *atrtab;
36
 
37
unsigned char colortab[0x100];// map zx attributes to pc attributes
38
// colortab shifted to 8 and 24
39
unsigned colortab_s8[0x100];
40
unsigned colortab_s24[0x100];
41
 
42
/*
43
#include "drawnomc.cpp"
44
#include "draw_384.cpp"
45
*/
46
 
47
PALETTEENTRY pal0[0x100]; // emulator palette
48
 
49
void AtmVideoController::PrepareFrameATM2(int VideoMode)
50
{
51
    for (int y=0; y<256; y++)
52
    {
53
        if ( VideoMode == 6 )
54
        {
55
            // �������� � ��������� �����������
56
            Scanlines[y].Offset = 64*(y/8);
57
        } else {
58
            // �������� � ��������� �����������
59
            Scanlines[y].Offset = (y<56) ? 0 : 40*(y-56);
60
        }
61
        Scanlines[y].VideoMode = VideoMode;
62
    }
63
    CurrentRayLine = 0;
64
    IncCounter_InRaster = 0;
65
    IncCounter_InBorder = 0;
66
}
67
 
68
void AtmVideoController::PrepareFrameATM1(int VideoMode)
69
{
70
    for (int y=56; y<256; y++)
71
    {
72
        Scanlines[y].Offset = 40*(y-56);
73
        Scanlines[y].VideoMode = VideoMode;
74
    }
75
}
76
 
77
 
78
AtmVideoController AtmVideoCtrl;
79
 
80
void video_permanent_tables()
81
{
82
   // pixel doubling table
83
   unsigned i; //Alone Coder 0.36.7
84
   for (/*unsigned*/ i = 0; i < 0x100; i++) {
85
      unsigned res = 0;
796 DimkaM 86
      for (unsigned j = 0x80; j; j/=2) {
87
         res <<= 2;
88
         if(i & j)
89
         {
90
             res |= 3;
91
         }
716 lvd 92
      }
93
      t.dbl[i] = res;
94
   }
95
 
96
   for (i = 0; i < 0x100; i++) {
97
      unsigned r1 = 0, r2 = 0;
796 DimkaM 98
      if(i & 0x01)
99
      {
100
          r1++; r2 += 1;
101
      }
102
      if(i & 0x02)
103
      {
104
          r1++; r2 += 1;
105
      }
106
      if(i & 0x04)
107
      {
108
          r1++; r2 += 0x100;
109
      }
110
      if(i & 0x08)
111
      {
112
          r1++; r2 += 0x100;
113
      }
114
      if(i & 0x10)
115
      {
116
          r1 += 0x100; r2 += 0x10000;
117
      }
118
      if(i & 0x20)
119
      {
120
          r1 += 0x100; r2 += 0x10000;
121
      }
122
      if(i & 0x40)
123
      {
124
          r1 += 0x100; r2 += 0x1000000;
125
      }
126
      if(i & 0x80)
127
      {
128
          r1 += 0x100; r2 += 0x1000000;
129
      }
716 lvd 130
      // low byte of settab - number of pixels in low nibble of i
131
      // high byte of low word of settab - number of pixels in high nibble of i
132
      t.settab[i] = r1;
133
      t.settab2[i] = r2*4; // *4 - convert square 2x2 to 4x4
134
   }
135
 
136
   i = 0; // calc screen addresses
796 DimkaM 137
   for(unsigned p = 0; p < 4; p++)
138
   {
139
       for(unsigned y = 0; y < 8; y++)
140
       {
141
           for(unsigned o = 0; o < 8; o++, i++)
142
           {
143
               t.scrtab[i] = p * 0x800 + y * 0x20 + o * 0x100;
144
               t.atrtab_hwmc[i] = t.scrtab[i] + 0x2000;
145
               t.atrtab[i] = 0x1800 + (p * 8 + y) * 32;
146
           }
147
       }
148
   }
716 lvd 149
 
150
   // alco table
151
   static unsigned disp_0[] = { 0x0018, 0x2000, 0x2008, 0x2010, 0x2018, 0x0008 };
152
   static unsigned base_s[] = { 0x10000, 0x14000, 0x14800, 0x15000, 0x11800 };
153
   static unsigned base_a[] = { 0x11000, 0x15800, 0x15900, 0x15A00, 0x11300 };
154
   for (unsigned y = 0; y < 304; y++)
155
      for (unsigned x = 0; x < 6; x++) {
156
         unsigned disp = disp_0[x] + (y & 0x38)*4;
157
         ::t.alco[y][x].a = memory + base_a[y/64] + disp;
158
         ::t.alco[y][x].s = memory + base_s[y/64] + disp + (y & 7)*0x100;
159
      }
160
 
161
   #ifdef MOD_VID_VD
162
   // this code is only for ygrbYGRB palette
163
   for (unsigned byte = 0; byte < 0x100; byte++)
164
      for (int bit = 0; bit < 8; bit++)
165
         t.vdtab[0][0][byte].m64_u8[7-bit] = (byte & (1 << bit))? 0x11 : 0;
166
   for (int pl = 1; pl < 4; pl++)
167
      for (unsigned byte = 0; byte < 0x100; byte++)
168
         t.vdtab[0][pl][byte] = _mm_slli_pi32(t.vdtab[0][0][byte], pl);
169
   for (i = 0; i < sizeof t.vdtab[0]; i++)
170
      ((unsigned char*)t.vdtab[1])[i] = ((unsigned char*)t.vdtab[0])[i] & 0x0F;
171
   _mm_empty();
172
   #endif
173
 
174
   temp.offset_vscroll_prev = 0;
175
   temp.offset_vscroll = 0;
176
   temp.offset_hscroll_prev = 0;
177
   temp.offset_hscroll = 0;
178
}
179
 
796 DimkaM 180
static unsigned getYUY2(unsigned r, unsigned g, unsigned b)
716 lvd 181
{
182
   int y = (int)(0.29*r + 0.59*g + 0.14*b);
183
   int u = (int)(128.0 - 0.14*r - 0.29*g + 0.43*b);
184
   int v = (int)(128.0 + 0.36*r - 0.29*g - 0.07*b);
185
   if (y < 0) y = 0; if (y > 255) y = 255;
186
   if (u < 0) u = 0; if (u > 255) u = 255;
187
   if (v < 0) v = 0; if (v > 255) v = 255;
188
   return WORD4(y,u,y,v);
189
}
190
 
796 DimkaM 191
static void create_palette()
716 lvd 192
{
796 DimkaM 193
    if((temp.rflags & RF_8BPCH) && temp.obpp == 8)
194
    {
195
        temp.rflags |= RF_GRAY;
196
        conf.flashcolor = 0;
197
    }
716 lvd 198
 
796 DimkaM 199
    PALETTE_OPTIONS *pl = &pals[conf.pal];
200
    //                                Ii          Ii          Ii          Ii
201
    //                                00          01          10          11
202
    unsigned char brights[4] = { u8(pl->ZZ), u8(pl->ZN), u8(pl->NN), u8(pl->BB) };
203
    unsigned char brtab[16] =
204
    {   //   ZZ          NN          ZZ          BB
205
        u8(pl->ZZ), u8(pl->ZN), u8(pl->ZZ), u8(pl->ZB), // ZZ
206
        u8(pl->ZN), u8(pl->NN), u8(pl->ZN), u8(pl->NB), // NN
207
        u8(pl->ZZ), u8(pl->ZN), u8(pl->ZZ), u8(pl->ZB), // ZZ (bright=1,ink=0)
208
        u8(pl->ZB), u8(pl->NB), u8(pl->ZB), u8(pl->BB)  // BB
209
    };
716 lvd 210
 
796 DimkaM 211
    for(unsigned i = 0; i < 0x100; i++)
212
    {
213
        unsigned r0, g0, b0;
214
        if(temp.rflags & RF_GRAY)
215
        { // grayscale palette
216
            r0 = g0 = b0 = i;
217
        }
218
        else if(temp.rflags & RF_PALB)
219
        { // palette index:
220
            if(comp.ula_plus_en) // gggrrrbb (ULA+)
221
            { // �������� ������������ �������
222
                b0 = ((i & 3) * 255) / 3; // 2 ����
223
                r0 = (((i >> 2) & 7) * 255) / 7; // 3 ����
224
                g0 = (((i >> 5) & 7) * 255) / 7; // 3 ����
225
            }
226
            else // gg0rr0bb (ATM / profi / bilinear filter)
227
            { // ���������� ��������� ������� (�� 2 ����) �� ������� ������� �� .ini �����
228
                b0 = brights[i & 3];
229
                r0 = brights[(i >> 3) & 3];
230
                g0 = brights[(i >> 6) & 3];
231
            }
232
        }
233
        else
234
        { // palette index: ygrbYGRB (������� zx ����� ��� �������)
235
          // ���������� ��������� ������� (�� 4 ����) �� ������� ������� �� .ini �����
236
            b0 = brtab[((i >> 0) & 1) + ((i >> 2) & 2) + ((i >> 2) & 4) + ((i >> 4) & 8)]; // brtab[ybYB]
237
            r0 = brtab[((i >> 1) & 1) + ((i >> 2) & 2) + ((i >> 3) & 4) + ((i >> 4) & 8)]; // brtab[yrYR]
238
            g0 = brtab[((i >> 2) & 1) + ((i >> 2) & 2) + ((i >> 4) & 4) + ((i >> 4) & 8)]; // brtab[ygYG]
239
        }
716 lvd 240
 
796 DimkaM 241
        // transform with current settings
242
        unsigned r = 0xFF & ((r0 * pl->r11 + g0 * pl->r12 + b0 * pl->r13) / 0x100);
243
        unsigned g = 0xFF & ((r0 * pl->r21 + g0 * pl->r22 + b0 * pl->r23) / 0x100);
244
        unsigned b = 0xFF & ((r0 * pl->r31 + g0 * pl->r32 + b0 * pl->r33) / 0x100);
716 lvd 245
 
796 DimkaM 246
        // prepare palette in bitmap header for GDI renderer
247
        gdibmp.header.bmiColors[i].rgbRed = pal0[i].peRed = BYTE(r);
248
        gdibmp.header.bmiColors[i].rgbGreen = pal0[i].peGreen = BYTE(g);
249
        gdibmp.header.bmiColors[i].rgbBlue = pal0[i].peBlue = BYTE(b);
250
    }
251
    memcpy(syspalette + 10, pal0 + 10, (246 - 9) * sizeof *syspalette);
252
 
253
    if(conf.mem_model == MM_PROFI)
254
    {
255
        // profi palette mapping (port out to palette index)
256
        for(unsigned i = 0; i < 0x100; i++)
257
        {
258
            unsigned dst;
259
            dst = i; // Gg0Rr0Bb => Gg0Rr0Bb
260
            t.profi_pal_map[i] = dst;
261
        }
262
    }
716 lvd 263
}
264
 
265
void atm_zc_tables();//forward
266
 
267
// make colortab: zx-attr -> pc-attr
796 DimkaM 268
static void make_colortab(char flash_active)
716 lvd 269
{
796 DimkaM 270
   if (conf.flashcolor || conf.ula_plus)
716 lvd 271
       flash_active = 0;
272
 
796 DimkaM 273
   for (unsigned a = 0; a < 0x100; a++) // a - zx-attr
716 lvd 274
   {
275
      unsigned char ink = a & 7;
276
      unsigned char paper = (a >> 3) & 7;
277
      unsigned char bright = (a >> 6) & 1;
278
      unsigned char flash = (a >> 7) & 1;
279
 
796 DimkaM 280
//      if((conf.flashcolor && ink) || !conf.flashcolor)
281
      ink |= bright << 3;
716 lvd 282
 
796 DimkaM 283
//      if((conf.flashcolor && paper) || !conf.flashcolor)
284
          paper |= ((conf.flashcolor || (conf.ula_plus && comp.ula_plus_en)) ? flash : bright) << 3;
716 lvd 285
 
286
      if (flash_active && flash)
287
      {
288
          unsigned char t = ink;
289
          ink = paper;
290
          paper = t;
291
      }
292
 
796 DimkaM 293
      u8 color = u8((paper << 4) | ink); // color - pc-attr
716 lvd 294
 
295
      colortab[a] = color;
796 DimkaM 296
      colortab_s8[a] = unsigned(color << 8U);
297
      colortab_s24[a] = unsigned(color << 24U);
716 lvd 298
   }
299
 
300
   if (conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3 || conf.mem_model == MM_ATM450)
301
       atm_zc_tables(); // update with new flash bit
302
}
303
 
304
// make attrtab: pc-attr + 0x100*pixel -> palette index
796 DimkaM 305
static void attr_tables()
716 lvd 306
{
307
   unsigned char flashcolor = (temp.rflags & RF_MON)? 0 : conf.flashcolor;
308
   for (unsigned a = 0; a < 0x100; a++)
309
   {
796 DimkaM 310
      unsigned char ink = (a & 0x0F), paper = u8(a >> 4);
716 lvd 311
      if (flashcolor)
312
          paper = (paper & 7) + (ink & 8); // paper_bright from ink
313
 
314
      if (temp.rflags & RF_GRAY)
315
      { // grayscale palette
316
         t.attrtab[a] = paper*16;
317
         t.attrtab[a+0x100] = ink*16;
318
      }
319
      else if (temp.rflags & RF_COMPPAL)
796 DimkaM 320
      {
321
          // ������� � ������� ULA+
322
          u8 paper_idx; // fb1ppp
323
          u8 ink_idx;   // fb0iii
324
          if(comp.ula_plus_en)
325
          {
326
              u8 flash = (a & 0x80) >> 7;
327
              u8 bright = (a & 8) >> 3;
328
              paper &= 7;
329
              ink &= 7;
330
              u8 pal_no = u8(((flash << 1) | bright) << 4);
331
              paper_idx = u8(pal_no | 8 | paper);
332
              ink_idx   = u8(pal_no | 0 | ink);
333
          }
334
          else
335
          { //------ for ATM / profi palette - direct values from palette registers
336
              paper = a >> 4;
337
              ink = a & 0x0F;
338
              paper_idx = u8(((paper & 8) << 1) | (paper & 7));
339
              ink_idx = u8(((ink & 8) << 1) | (ink & 7));
340
          }
341
          t.attrtab[a] = comp.comp_pal[paper_idx]; // paper
342
          t.attrtab[a | 0x100] = comp.comp_pal[ink_idx]; // ink
716 lvd 343
      }
344
      else if (temp.rflags & RF_PALB)
345
      { //----------------------------- for bilinear
346
         unsigned char b0,b1, r0,r1, g0,g1;
796 DimkaM 347
         b0 = (paper >> 0) & 1; r0 = (paper >> 1) & 1; g0 = (paper >> 2) & 1;
348
         b1 = (ink >> 0) & 1; r1 = (ink >> 1) & 1; g1 = (ink >> 2) & 1;
716 lvd 349
 
350
         if (flashcolor && (a & 0x80))
351
         {
796 DimkaM 352
             b1 += b0; r1 += r0; g1 += g0;
353
             r0 = b0 = g0 = 0;
716 lvd 354
         }
355
         else
356
         {
796 DimkaM 357
             b0 *= 2; r0 *= 2; g0 *= 2;
358
             b1 *= 2; r1 *= 2; g1 *= 2;
716 lvd 359
         }
360
 
361
         unsigned char br1 = (ink >> 3) & 1;
362
         if (r1) r1 += br1;
363
         if (g1) g1 += br1;
364
         if (b1) b1 += br1;
365
 
366
         unsigned char br0 = (paper >> 3) & 1;
367
         if (r0) r0 += br0;
368
         if (g0) g0 += br0;
369
         if (b0) b0 += br0;
370
 
371
         // palette index: gg0rr0bb
796 DimkaM 372
         t.attrtab[a+0x100]  = u8((g1 << 6) + (r1 << 3) + b1);
373
         t.attrtab[a]        = u8((g0 << 6) + (r0 << 3) + b0);
716 lvd 374
      }
375
      else //------------------------------------ all others
376
      {
377
         // palette index: ygrbYGRB
378
         if (flashcolor && (a & 0x80))
379
         {
380
             t.attrtab[a] = 0;
796 DimkaM 381
             t.attrtab[a+0x100] = u8(ink+(paper<<4));
716 lvd 382
         }
383
         else
384
         {
796 DimkaM 385
             t.attrtab[a] = paper * 0x11; // p[3..0]:p[3..0] (��������)
386
             t.attrtab[a+0x100] = ink * 0x11; // i[3..0]:i[3..0] (��������)
716 lvd 387
         }
388
      }
389
   }
390
}
391
 
796 DimkaM 392
static void p4bpp_tables()
716 lvd 393
{
394
   for (unsigned pass = 0; pass < 2; pass++) {
395
      for (unsigned bt = 0; bt < 0x100; bt++) {
396
         unsigned lf = ((bt >> 3) & 7) + ((bt >> 4) & 8);
397
         unsigned rt = (bt & 7) + ((bt >> 3) & 8);
398
         if (temp.obpp == 8) {
399
            t.p4bpp8[pass][bt] = (t.sctab8[pass][0x0F+0x10*rt] & 0xFFFF) +
400
                                   (t.sctab8[pass][0x0F+0x10*lf] & 0xFFFF0000);
401
         } else if (temp.obpp == 16) {
796 DimkaM 402
             t.p4bpp16[pass][bt * 2 + 0] = t.sctab16[pass][0x03 + 4 * rt];
403
             t.p4bpp16[pass][bt * 2 + 1] = t.sctab16[pass][0x03 + 4 * lf];
716 lvd 404
         } else /* if (temp.obpp == 32) */ {
796 DimkaM 405
             t.p4bpp32[pass][bt * 2 + 0] = t.sctab32[pass][0x100 + rt];
406
             t.p4bpp32[pass][bt * 2 + 1] = t.sctab32[pass][0x100 + lf];
716 lvd 407
         }
408
      }
409
   }
410
}
411
 
412
void atm_zc_tables() // atm,profi screens (use normal zx-flash)
413
{
414
   for (unsigned pass = 0; pass < 2; pass++) {
415
      for (unsigned at = 0; at < 0x100; at++) {
416
         unsigned pc_attr = colortab[at];
796 DimkaM 417
         if(temp.obpp == 8)
418
         {
419
             for(unsigned j = 0; j < 4; j++)
420
             {
421
                 t.zctab8ad[pass][at * 4 + j] = t.sctab8d[pass][pc_attr * 4 + j];
422
             }
423
         }
424
         else if(temp.obpp == 16)
425
         {
426
             t.zctab16ad[pass][at] = t.sctab16d[pass][pc_attr];
427
             t.zctab16ad[pass][at + 0x100] = t.sctab16d[pass][pc_attr + 0x100];
428
         }
716 lvd 429
         else /* if (temp.obpp == 32) */
796 DimkaM 430
         {
431
             t.zctab32ad[pass][at] = t.sctab32[pass][pc_attr];
432
             t.zctab32ad[pass][at + 0x100] = t.sctab32[pass][pc_attr + 0x100];
433
         }
716 lvd 434
      }
435
   }
436
 
437
   // atm palette mapping (port out to palette index)
438
   for (unsigned i = 0; i < 0x100; i++) {
439
      unsigned v = i ^ 0xFF, dst;
440
      if (conf.mem_model == MM_ATM450)
441
         dst = // ATM1: --grbGRB => Gg0Rr0Bb
442
               ((v & 0x20) << 1) | // g
443
               ((v & 0x10) >> 1) | // r
444
               ((v & 0x08) >> 3) | // b
445
               ((v & 0x04) << 5) | // G
446
               ((v & 0x02) << 3) | // R
447
               ((v & 0x01) << 1);  // B
448
      else
449
         dst = // ATM2: grbG--RB => Gg0Rr0Bb
450
               ((v & 0x80) >> 1) | // g
451
               ((v & 0x40) >> 3) | // r
452
               ((v & 0x20) >> 5) | // b
453
               ((v & 0x10) << 3) | // G
454
               ((v & 0x02) << 3) | // R
455
               ((v & 0x01) << 1);  // B
456
      t.atm_pal_map[i] = dst;
457
   }
458
}
459
 
796 DimkaM 460
static void hires_sc_tables()  // atm,profi screens (use zx-attributes & flash -> paper_bright)
716 lvd 461
{
462
   for (unsigned pass = 0; pass < 2; pass++) {
463
      for (unsigned at = 0; at < 0x100; at++) {
464
         unsigned pc_attr = (at & 0x80) + (at & 0x38)*2 + (at & 0x40)/8 + (at & 7);
465
         if (temp.obpp == 8)
466
            for (unsigned j = 0; j < 16; j++)
467
               t.zctab8[pass][at*0x10+j] = t.sctab8[pass][pc_attr*0x10+j];
468
         else if (temp.obpp == 16)
469
            for (unsigned j = 0; j < 4; j++)
470
               t.zctab16[pass][at*4+j] = t.sctab16[pass][pc_attr*4+j];
471
         else /* if (temp.obpp == 32) */
472
            for (unsigned j = 0; j < 2; j++)
473
               t.zctab32[pass][at+0x100*j] = t.sctab32[pass][pc_attr+0x100*j];
474
      }
475
   }
476
}
477
 
796 DimkaM 478
static void calc_noflic_16_32()
716 lvd 479
{
480
   unsigned at, pass;
481
   if (temp.obpp == 16) {
482
      for (pass = 0; pass < 2; pass++) {
483
         for (at = 0; at < 2*0x100; at++)
484
            t.sctab16d_nf[pass][at] = (t.sctab16d[pass][at] & temp.shift_mask)/2;
485
         for (at = 0; at < 4*0x100; at++)
486
            t.sctab16_nf[pass][at] = (t.sctab16[pass][at] & temp.shift_mask)/2;
487
         for (at = 0; at < 2*0x100; at++)
488
            t.p4bpp16_nf[pass][at] = (t.p4bpp16[pass][at] & temp.shift_mask)/2;
489
      }
490
   }
491
   if (temp.obpp == 32) {
492
      unsigned shift_mask = 0xFEFEFEFE;
493
      for (pass = 0; pass < 2; pass++) {
494
         for (at = 0; at < 2*0x100; at++)
495
            t.sctab32_nf[pass][at] = (t.sctab32[pass][at] & shift_mask)/2;
496
         for (at = 0; at < 2*0x100; at++)
497
            t.p4bpp32_nf[pass][at] = (t.p4bpp32[pass][at] & shift_mask)/2;
498
      }
499
   }
500
}
501
 
502
// pal.index => raw video data, shadowed with current scanline pass
796 DimkaM 503
static unsigned raw_data(unsigned index, unsigned pass, unsigned bpp)
716 lvd 504
{
505
   if (bpp == 8)
506
   {
507
      if (pass)
508
      {
509
         if (!conf.scanbright)
510
             return 0;
511
         // palette too small to realize noflic/atari with shaded scanlines
512
         if (conf.scanbright < 100 && !conf.noflic && !conf.atariset[0])
513
         {
514
            if (temp.rflags & RF_PALB)
515
                index = (index & (index << 1) & 0x92) | ((index ^ 0xFF) & (index >> 1) & 0x49);
516
            else
517
                index &= 0x0F;
518
         }
519
      }
796 DimkaM 520
      return index * 0x01010101; // 4 ����� (8bit)
716 lvd 521
   }
522
 
523
   unsigned r = pal0[index].peRed, g = pal0[index].peGreen, b = pal0[index].peBlue;
524
   if (pass)
525
   {
526
       r = r * conf.scanbright / 100;
527
       g = g * conf.scanbright / 100;
528
       b = b * conf.scanbright / 100;
529
   }
530
 
531
   if (bpp == 32)
796 DimkaM 532
       return WORD4(b,g,r,0); // 1 ����� (32bit)
716 lvd 533
 
534
   // else (bpp == 16)
535
   if (temp.hi15==0)
796 DimkaM 536
       return ((b/8) + ((g/4)<<5) + ((r/8)<<11)) * 0x10001; // 2 ����� (16bit)
716 lvd 537
   if (temp.hi15==1)
796 DimkaM 538
       return ((b/8) + ((g/8)<<5) + ((r/8)<<10)) * 0x10001; // 2 ����� (16bit)
716 lvd 539
   if (temp.hi15==2)
796 DimkaM 540
       return getYUY2(r,g,b); // yuyv (32bit)
716 lvd 541
   return 0;
542
}
543
 
796 DimkaM 544
static unsigned atari_to_raw(unsigned at, unsigned pass)
716 lvd 545
{
546
   unsigned c1 = at/0x10, c2 = at & 0x0F;
547
   unsigned raw0 = raw_data(t.attrtab[c1+0x100], pass, temp.obpp);
548
   unsigned raw1 = raw_data(t.attrtab[c2+0x100], pass, temp.obpp);
549
   if (raw0 == raw1) return raw1;
550
 
551
   if (temp.obpp == 8)
552
      return (temp.rflags & RF_PALB)? (0x49494949 & ((raw0&raw1)^((raw0^raw1)>>1))) |
553
                                      (0x92929292 & ((raw0&raw1)|((raw0|raw1)&((raw0&raw1)<<1))))
554
                                    : (0x0F0F0F0F & raw0) | (0xF0F0F0F0 & raw1);
555
 
556
   return (raw0 & temp.shift_mask)/2 + (raw1 & temp.shift_mask)/2;
557
}
558
 
559
void pixel_tables()
560
{
796 DimkaM 561
    attr_tables();
562
    for(unsigned pass = 0; pass < 2; pass++)
563
    {
564
        for(unsigned at = 0; at < 0x100; at++)
565
        {
566
            unsigned px0 = t.attrtab[at]; // ����� ��������� (������ ������� ���������, ������� 8[idx]->32[xrgb])
567
            unsigned px1 = t.attrtab[at + 0x100]; // ����� �������� (������ ������� ���������, ������� 8[idx]->32[xrgb])
716 lvd 568
 
796 DimkaM 569
            // 4 ����� (����������, �����������) ��� 8bpp
570
            // 2 ����� (����������, ��������) ��� 16bpp
571
            // 1 ����� ��� 32bpp
572
            unsigned p0 = raw_data(px0, pass, temp.obpp); // ����� ��������� (������ ��� pc �����������)
573
            unsigned p1 = raw_data(px1, pass, temp.obpp); // ����� �������� (������ ��� pc �����������)
716 lvd 574
 
796 DimkaM 575
            // sctab32 required for frame resampler in 16-bit mode, so temp.obpp=16 here
576
            // ������� ������ 1 ���
577
            t.sctab32[pass][at] = raw_data(px0, pass, 32); // ����� ��������� (������ ��� pc ����������� xrgb)
578
            t.sctab32[pass][at + 0x100] = raw_data(px1, pass, 32); // ����� �������� (������ ��� pc ����������� xrgb)
716 lvd 579
 
796 DimkaM 580
            // 8 bit
581
            unsigned j;
582
            for(j = 0; j < 0x10; j++) // j - ������� ������ (�������� �/� ��������) 4���� (16 ����������)
583
            {
584
                unsigned mask = (j >> 3) * 0xFF + (j & 0x04)*(0xFF00 / 4) +
585
                    (j & 0x02)*(0xFF0000 / 2) + (j & 1) * 0xFF000000;
586
                t.sctab8[pass][j + at * 0x10] = (mask & p1) + (~mask & p0); // ������ ��� pc ����������� 4 �����
587
            }
588
            for(j = 0; j < 4; j++) // j - ������� ������ (�������� �/� ��������) 2���� (4 ����������)
589
            {
590
                unsigned mask = (j >> 1) * 0xFFFF + (j & 1) * 0xFFFF0000;
591
                t.sctab8d[pass][j + at * 4] = (mask & p1) + (~mask & p0); // ������ ��� pc ����������� 2 ����� � ���������
592
            }
593
            // ������� ������ (�������� �/� ��������) 1��� (2 ����������)
594
            t.sctab8q[at] = p0; t.sctab8q[at + 0x100] = p1; // ������ ��� pc ����������� 1 ����� � ������������
716 lvd 595
 
796 DimkaM 596
            // 16 bit
597
            for(j = 0; j < 4; j++) // j - ������� ������ (�������� �/� ��������) 2���� (4 ����������)
598
            {
599
                unsigned mask = (j >> 1) * 0xFFFF + (j & 1) * 0xFFFF0000;
600
                t.sctab16[pass][j + at * 4] = (mask & p1) + (~mask & p0); // ������ ��� pc ����������� 2 �����
601
            }
602
            // ������� ������ (�������� �/� ��������) 1��� (2 ����������)
603
            t.sctab16d[pass][at] = p0; t.sctab16d[pass][at + 0x100] = p1; // ������ ��� pc ����������� 1 ����� � ���������
716 lvd 604
 
796 DimkaM 605
            unsigned atarimode;
606
            if(!(temp.rflags & RF_MON) && (atarimode = temp.ataricolors[at]))
607
            {
608
                unsigned rawdata[4], i;
609
                for(i = 0; i < 4; i++)
610
                {
611
                    rawdata[i] = atari_to_raw((atarimode >> (8 * i)) & 0xFF, pass);
612
                }
613
                for(i = 0; i < 16; i++)
614
                {
615
                    t.sctab8[pass][at * 0x10 + i] = rawdata[i / 4] + 16 * rawdata[i & 3];
616
                }
617
                for(i = 0; i < 4; i++)
618
                {
619
                    t.sctab8d[pass][at * 4 + i] = rawdata[i];
620
                }
621
                for(i = 0; i < 4; i++)
622
                {
623
                    t.sctab16[pass][at * 4 + i] = rawdata[i];
624
                }
625
            }
626
        }
627
    }
716 lvd 628
 
796 DimkaM 629
    p4bpp_tables(); // used for ATM2+ mode0 and Pentagon-4bpp
716 lvd 630
 
796 DimkaM 631
    if(temp.obpp > 8 && conf.noflic)
632
    {
633
        calc_noflic_16_32();
634
    }
716 lvd 635
 
796 DimkaM 636
    if((temp.rflags & (RF_DRIVER | RF_2X | RF_USEFONT)) == (RF_DRIVER | RF_2X) && // render="double"
637
        (conf.mem_model == MM_ATM450 || conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3 || conf.mem_model == MM_PROFI))
638
    {
639
        hires_sc_tables();
640
    }
716 lvd 641
}
642
 
643
void video_color_tables()
644
{
645
   temp.shift_mask = 0xFEFEFEFE; // 32bit, 16bit YUY2
646
   if (temp.obpp == 16 && temp.hi15==0) temp.shift_mask = 0xF7DEF7DE;
647
   if (temp.obpp == 16 && temp.hi15==1) temp.shift_mask = 0x7BDE7BDE;
648
 
649
   create_palette();
650
   pixel_tables();
651
   make_colortab(0);
652
 
653
   if (temp.rflags & (RF_USEC32 | RF_USE32AS16)) {
654
      for (unsigned at = 0; at < 0x100; at++) {
655
         for (unsigned vl = 0; vl <= 0x10; vl++) {
656
            unsigned br = (at & 0x40) ? 0xFF : 0xBF;
657
            unsigned c1, c2, res;
796 DimkaM 658
            c1 = (at & 1) >> 0; c2 = (at & 0x08) >> 3;
716 lvd 659
            unsigned b = (c1*vl + c2*(0x10-vl))*br/0x10;
796 DimkaM 660
            c1 = (at & 2) >> 1; c2 = (at & 0x10) >> 4;
716 lvd 661
            unsigned r = (c1*vl + c2*(0x10-vl))*br/0x10;
796 DimkaM 662
            c1 = (at & 4) >> 2; c2 = (at & 0x20) >> 5;
716 lvd 663
            unsigned g = (c1*vl + c2*(0x10-vl))*br/0x10;
664
            if (temp.rflags & RF_USE32AS16) {
665
               if (temp.hi15==0) res = (b/8) + ((g/4)<<5) + ((r/8)<<11);
666
               if (temp.hi15==1) res = (b/8) + ((g/8)<<5) + ((r/8)<<10);
667
               if (temp.hi15==2) res = getYUY2(r,g,b);
668
               else res *= 0x10001; // for hi15=0,1
669
            } else res =  WORD4(b,g,r,0);
670
            t.c32tab[at][vl] = res;
671
         }
672
      }
673
   }
674
   setpal(0);
675
}
676
 
677
void video_timing_tables()
678
{
679
   if (conf.frame < 2000)
680
   {
681
       conf.frame = 2000;
682
       cpu.SetTpi(conf.frame);
683
   }
684
   if (conf.t_line < 128) conf.t_line = 128;
685
   conf.nopaper &= 1;
686
   atrtab = (comp.pEFF7 & EFF7_HWMC) ? t.atrtab_hwmc : t.atrtab;
687
 
688
//   conf.bordersize=2;
689
//   temp.scx = 384, temp.scy = 300;
690
   #define p2cc(p) ((p)/4) // ������� �������� � �������� � ����� ��������� � ������ ��������� (������ ���������� �������� 2 �����, ���� ������ � ���� ���������)
691
   const unsigned width = p2cc(temp.scx); // ������ ������ � ����������� * 2 (�.�. ������������ ������� � �������� �� 1 ����������)
692
   //temp.vidbufsize = temp.scx*temp.scy/4;
693
 
694
   // make video table
695
   unsigned mid_lines = 192; // ����� ����� � ����������� ����� ������ (��� �������)
696
   const unsigned buf_mid = 256; // ����� �������� � ����������� ����� ������ (��� �������)
697
 
698
   // ������ ������ ������� � �������� (1 ������� = 2 �����)
796 DimkaM 699
   temp.b_bottom = temp.b_top = conf.b_top_small; temp.b_left = conf.b_left_small; // border small
716 lvd 700
   if (conf.bordersize==0) temp.b_top = temp.b_left = 0; // border none
701
   if (conf.bordersize==2) { temp.b_top = conf.b_top_full; temp.b_left = conf.b_left_full; } // border full
702
 
703
   // temp.scx - ����� ����� � ������������ �� �����������
704
   // temp.scy - ����� ����� � ������������
705
   // 256x192 - border none
706
   // 320x240 - border small
707
   // 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)))
708
   temp.b_right = temp.scx - buf_mid - temp.b_left; // ������ ������� ������ ����� ������� � �������� (1 ������� = 1/2 �����)
709
   temp.b_bottom = temp.scy - mid_lines - temp.b_top; // ������ ������� ������ ����� ������� � �������� (1 ������� = 1/2 �����)
710
 
796 DimkaM 711
   if(conf.nopaper) // ����� nopaper (����� � �������� ������ �����������)
712
   {
713
       temp.b_bottom += mid_lines;
714
       mid_lines = 0;
715
   }
716 lvd 716
   int inx = 0;
717
 
718
   unsigned i;
719
   #define ts(t) (((int)(t) < 0) ? 0 : t)
720
   #define p2t(p) ((p)/2) // ������� �������� � �����
721
   // conf.paper - ����� ������ �� ������ ������ �� ����������� ����� spectrum ������
722
   // (�������� ��������� ����� + ��������� ������� ������ + ������ ������ ������� hblank + ����� ������)
723
   // ��� pentagon 128: (16+64)*(32+36+128+28)+32+36 = 17988 ������
724
   // 16 ����� ��� ������� ��������
725
   // 64 ������ - ������� ������
726
   // ������ ������ 224 �����:
727
   // 32 ����� hblank
728
   // 36 ������ - ����� ������
729
   // 128 ������ - ����� ������
730
   // 28 ������ - ������ ������
731
   unsigned t = conf.paper - temp.b_top*conf.t_line; // ����� ������ �� ������ �������� ������� (������� hblank + ����� ������ � ������ ������ paper)
732
   const unsigned hblank = conf.t_line - p2t(temp.scx); // ����� ������ � hblank
733
   video[inx++].next_t = ts(t - p2t(temp.b_left)); // ���������� ������ ������� (next_t - ���� ������ ������ ������ �������� �������)
734
//   printf("btop: temp.b_top=%u, conf.b_top_full=%u\n", temp.b_top, conf.b_top_full);
735
   for (i = 0; i < temp.b_top; i++)
736
   { // ������� ������
737
      video[inx].next_t = ts(t + p2t(buf_mid+temp.b_right)); // ����� ������� ������� (���� ����� ������� ������)
738
      video[inx].screen_ptr = rbuf+width*i; // ��������� �� �� ���� ������� ������ � ������ ���������
739
      video[inx].nextvmode = 0; // hblank (������� � ����� ������)
740
//      printf("%3u: b=%u, e=%u, o=%u\n", i, video[inx-1].next_t, video[inx].next_t, width*i);
741
 
742
       // ������� � ��������� ������ (t - ���� ������ paper ��������� ������ hblank + ����� ������)
743
      inx++; t += conf.t_line;
744
      video[inx++].next_t = ts(t - p2t(temp.b_left)); // ���������� ������ ������� (���� ������ ������ ������� �� ��������� ������)
745
   }
746
//   printf("paper:\n");
747
   for (i = 0; i < mid_lines; i++)
748
   { // hblank + ����� ������ + ����� + ������ ������
749
      video[inx].next_t = ts(t); // ����� ������ ������� (���� ������ paper �� ������� ������)
750
      video[inx].screen_ptr = rbuf+width*(i+temp.b_top); // ��������� �� ������ i� ������ ������ ������� � ������ ���������
751
      video[inx].nextvmode = 2; // ����� ��������������� paper
752
//      printf("%3u: b=%u ", i, video[inx-1].next_t);
753
 
754
      inx++;
755
      video[inx].next_t = ts(t + p2t(buf_mid)); // ����� paper (���� ������ ������� ������� �� ������� ������)
756
      video[inx].screen_ptr = rbuf+width*(i+temp.b_top)+p2cc(temp.b_left);// ��������� �� ������ i� ������ paper � ������ ���������
757
      video[inx].scr_offs = ::t.scrtab[i]; // �������� �� ������ zx ������ (�������)
758
      video[inx].atr_offs = atrtab[i]; // �������� �� ������ ���� ��������� zx ������
759
 
760
      inx++;
761
      video[inx].next_t = ts(t + p2t(buf_mid+temp.b_right));  // ����� ������� ������� (���� ����� ������� ������)
762
      video[inx].screen_ptr = rbuf+width*(i+temp.b_top)+p2cc(buf_mid+temp.b_left); // ��������� �� ������ i� ������ ������� ������� � ������ ���������
763
      video[inx].nextvmode = 0; // hblank (������� � ����� ������)
764
 
765
//      printf("e=%u\n", video[inx].next_t);
766
       // ������� � ��������� ������ (t - ���� ������ paper ��������� ������ hblank + ����� ������)
767
      inx++; t += conf.t_line;
768
      video[inx++].next_t = ts(t - p2t(temp.b_left)); // ���������� ������ ������� (���� ������ ��������� ������)
769
   }
770
//   printf("bbot:\n");
771
   for (i = 0; i < temp.b_bottom; i++)
772
   { // ������ ������
773
      video[inx].next_t = ts(t + p2t(buf_mid+temp.b_right)); // ����� ������� ������� (���� ����� ������� ������)
774
      video[inx].screen_ptr = rbuf+width*(i+temp.b_top+mid_lines); // ��������� �� �� ���� i� ������ ������� ������� � ������ ���������
775
      video[inx].nextvmode = 0; // hblank (������� � ����� ������)
776
//      printf("%3u: b=%u, e=%u\n", i, video[inx-1].next_t, video[inx].next_t);
777
 
778
       // ������� � ��������� ������ (t - ���� ������ paper ��������� ������ hblank + ����� ������)
779
      inx++; t += conf.t_line;
780
      video[inx++].next_t = ts(t - p2t(temp.b_left)); // ���������� ������ ������� (���� ������ ��������� ������)
781
   }
782
   video[inx-1].next_t = 0x7FFFFFFF; // ������� ��������� ������
783
//   exit(0);
784
 
785
   temp.evenM1_C0 = conf.even_M1 ? 0xC0 : 0x00;
786
   temp.border_add = conf.border_4T ? 6 : 0;
787
   temp.border_and = conf.border_4T ? 0xFFFFFFFC : 0xFFFFFFFF;
788
 
789
   for (i = 0; i < NUM_LEDS; i++)
790
   {
791
      unsigned z = *(&conf.led.ay + i);
792
      int x = (signed short)(z & 0xFFFF);
793
      int y = (signed short)(((z >> 16) & 0x7FFF) + ((z >> 15) & 0x8000));
794
      if (x < 0) x += width*8;
795
      if (y < 0) y += temp.scy;
796 DimkaM 796
      *(&temp.led.ay+i) = (z & 0x80000000) ? rbuf + ((x>>2)&0xFE) + unsigned(y)*width : nullptr;
716 lvd 797
   }
798
 
799
   if (temp.rflags & RF_USEFONT)
800
       create_font_tables();
801
 
802
   needclr = 2;
803
}
804
 
805
void set_video()
806
{
807
//   printf("%s\n", __FUNCTION__);
808
   set_vidmode();
809
   video_color_tables();
810
}
811
 
812
void apply_video()
813
{
814
//   printf("%s\n", __FUNCTION__);
815
   load_ula_preset();
816
 
817
   if(conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3 || conf.mem_model == MM_ATM450 || conf.mem_model == MM_PROFI)
818
   {
819
       conf.render = 1; // ��� ������� � ������� 640x200 �������������� ������ redner = double (640x480)
820
   }
821
 
822
   temp.rflags = renders[conf.render].flags;
823
   if (conf.use_comp_pal && (conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3 || conf.mem_model == MM_ATM450 || conf.mem_model == MM_PROFI))
824
   {
825
      temp.rflags |= RF_COMPPAL | RF_PALB;
826
      // disable palette noflic, only if it is really used
827
      if (temp.obpp == 8 && (temp.rflags & (RF_DRIVER | RF_USEFONT | RF_8BPCH)) == RF_DRIVER)
828
      conf.noflic = 0;
829
   }
830
 
796 DimkaM 831
   if(conf.ula_plus/* && comp.ula_plus_en*/)
832
   {
833
       temp.rflags |= RF_COMPPAL | RF_PALB;
834
   }
835
 
716 lvd 836
   if (renders[conf.render].func == render_rsm)
837
       conf.flip = 1; // todo: revert back after returning from frame resampler //Alone Coder
838
 
839
   if (renders[conf.render].func == render_advmame)
840
   {
841
      if (conf.videoscale == 2)
842
          temp.rflags |= RF_2X;
843
      if (conf.videoscale == 3)
844
          temp.rflags |= RF_3X;
845
      if (conf.videoscale == 4)
846
          temp.rflags |= RF_4X;
847
   } //Alone Coder
848
 
849
   set_video();
850
   calc_rsm_tables();
851
   video_timing_tables();
852
}
853
 
854
__inline unsigned char *raypointer()
855
{
856
   if (prev_t > conf.frame)
857
       return rbuf + rb2_offs;
858
   if (!vmode)
859
       return vcurr[1].screen_ptr;
860
   unsigned offs = (prev_t - vcurr[-1].next_t) / 4;
861
   return vcurr->screen_ptr + (offs+1) * 2;
862
}
863
 
864
__inline void clear_until_ray()
865
{
866
   unsigned char *dst = raypointer();
796 DimkaM 867
   while(dst < rbuf + rb2_offs)
868
   {
869
       *dst++ = 0;
870
       *dst++ = 0x55;
871
   }
716 lvd 872
}
873
 
874
void paint_scr(char alt) // alt=0/1 - main/alt screen, alt=2 - ray-painted
875
{
796 DimkaM 876
    if(alt == 2)
877
    {
878
        update_screen();
879
        clear_until_ray();
880
    }
881
    else
882
    {
883
        if(alt)
884
        {
885
            comp.p7FFD ^= 8;
886
            set_banks();
887
        }
888
        draw_screen();
889
        if(alt)
890
        {
891
            comp.p7FFD ^= 8;
892
            set_banks();
893
        }
894
    }
716 lvd 895
}
896
 
897
// ���������� ��� ������ � �����������/(����� FE/7FFD) ������ ��������
898
// ���������� ��������� �������/������ � ������������� ����� � �������������� pc ���������
899
void update_screen()
900
{
901
   unsigned last_t = (cpu.t + temp.border_add) & temp.border_and;
796 DimkaM 902
   unsigned t = prev_t; // ����������� ��������� �� ���������� ������������� ����� prev_t �� �������� ������������ ����� last_t
716 lvd 903
//   printf("upd_scr: t=%u, lt=%u, vm=%u\n", t, last_t, vmode);
904
   if (t >= last_t) // ��������� ����� ������ (hblank ���� ��������� ������ �������� �������)
905
       return;
906
 
907
   unsigned char b = comp.border_attr;
908
   b |= (b<<4); // �������� ������� ����������� � ������� pc ��������� ink=paper
909
 
796 DimkaM 910
   if(vmode == 1)
911
   {
912
       goto mode1; // border
913
   }
716 lvd 914
 
796 DimkaM 915
   if(vmode == 2) // screen
916
   {
716 lvd 917
       goto mode2;
796 DimkaM 918
   }
716 lvd 919
 
920
mode0: // not visible
921
   {
922
      vmode = 1;
923
      t = vcurr->next_t; // ���� ������ ������
924
      vcurr++; // ������� � ����� ������
925
      if (t >= last_t)
926
      {
927
done:
796 DimkaM 928
          prev_t = t; // ��������� ������������ ����
716 lvd 929
          return;
930
      }
931
   }
932
mode1: // border
933
   {
934
      unsigned offs = (t - vcurr[-1].next_t); // �������� � ������ �� ������ ������ (1 ���� = 2 �������)
796 DimkaM 935
      unsigned char *ptr = vcurr->screen_ptr + offs/2; // ��������� �� ����� ����� � ������������� ������ (��������� ������ 8pix:attr)
716 lvd 936
//      u8 *pp =ptr;
937
      ptr = (unsigned char*)(ULONG_PTR(ptr) & ~ULONG_PTR(1)); // ��������� �� ������� ������
938
      if(offs & 3)
796 DimkaM 939
      { // ����� ����� ������� ��������� �� �� ������� ���������� (��� ����� ������� ������ ������ ����������, ����������� ����� ink/paper)
940
          u8 old_b = (ptr[1] & 0x0F);
941
          if(old_b ^ (b & 0xF)) // ���� ������� ��������� �� ��������� � ����������
942
          {
943
              u8 mask = u8((unsigned)0xFF00 >> ((offs & 3) * 2)); // ����� �������� (��� 1 - ������������ ���� ink, ��� 0 - paper)
944
              *ptr = mask;
945
              ptr++;
946
              t += 4 - (offs & 3);
947
              *ptr = old_b | (b & 0xF0); // �������� (ink - ������ ���� �������, paper - ������� ���� �������)
948
              ptr++;
949
          }
716 lvd 950
      }
951
      unsigned end = min(vcurr->next_t, last_t);
952
//      printf("upd_scr_m1: o=%uT, p=%u, t=%uT, end=%uT\n", offs, pp - rbuf, t, end);
953
      for (; t < end; t+=4) // ��������� �������� �� ����������� (�� 8 �����)
954
      {
955
         *ptr++ = 0; // ������� �� ������������
956
         *ptr++ = b; // ��������
957
      }
958
      t = end;
959
      if (t == vcurr->next_t)
960
      { // ������ �����������,  ������� � ��������� �����
961
          vmode = vcurr->nextvmode;
962
          vcurr++;
963
      }
964
      if (t == last_t) // ��������� ���������, �����
965
          goto done;
966
 
967
      if (!vmode) // ������ ��������� ������
968
          goto mode0;
969
   }
970
mode2: // screen
971
   {
972
      unsigned offs = (t - vcurr[-1].next_t)/4; // �������� � ����������� �� ������ ������ (1 ���������� = 4 ����� = 8 ��������)
973
      unsigned char *scr = temp.base + vcurr->scr_offs + offs; // spectrum �������
974
      unsigned char *atr = temp.base + vcurr->atr_offs + offs; // spectrum ��������
975
      unsigned char *ptr = vcurr->screen_ptr + offs*2; // ��������� ������ 8pix:attr
976
      unsigned end = min(last_t, vcurr->next_t);
977
      for (int i = 0; t < end; t += 4, i++)
978
      {
979
         ptr[2*i] = scr[i]; // ����������� spectrum ��������
980
         ptr[2*i+1] = colortab[atr[i]]; // ��������������� spectrum ��������� � pc ��������
981
      }
982
      t = end;
983
      if (t == vcurr->next_t)
984
      { // ����������� ����� ������ �����������, ��������� ������� �������
985
          vmode = 1; // border
986
          vcurr++;
987
      }
988
      if (t == last_t) // ��������� ���������, �����
989
          goto done;
990
      goto mode1; // ��������� ������� �������
991
   }
992
}
993
 
994
void init_frame()
995
{
996
   // recreate colors with flash attribute
997
   unsigned char frame = (unsigned char)comp.frame_counter;
998
   if (!(frame & 15) /* && !conf.flashcolor */ )
999
       make_colortab(frame & 16);
1000
 
796 DimkaM 1001
   prev_t = -1U; // block MCR
1002
   temp.base_2 = nullptr; // block paper trace
716 lvd 1003
 
1004
   if (temp.vidblock)
1005
       return;
1006
 
1007
/* [vv] ��������, �.�. ���� ��� ������������ ��� DDp scroll
1008
   // AlCo384 - no border/paper rendering
1009
   if (comp.pEFF7 & EFF7_384)
1010
       return;
1011
*/
1012
   // GIGASCREEN - no paper rendering
1013
//   if (comp.pEFF7 & EFF7_GIGASCREEN) goto allow_border; //Alone Coder
1014
 
1015
   // disable multicolors, border still works
1016
   if ((temp.rflags & RF_BORDER) || // chunk/etc filter
1017
       (conf.mem_model == MM_PROFI && (comp.pDFFD & 0x80)) ||   // profi hires screen
1018
       ((conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3)&& (comp.pFF77 & 7) != 3) ||  // ATM-2 hires screen
1019
       (conf.mem_model == MM_ATM450 && (comp.aFE & 0x60) != 0x60)) // ATM-1 hires screen
1020
   {
1021
       if ((conf.mem_model == MM_ATM710 || conf.mem_model == MM_ATM3))
1022
       {
1023
           // ATM2, ���� �� ����������� ������������
1024
           AtmVideoCtrl.PrepareFrameATM2(comp.pFF77 & 7);
1025
       }
1026
 
1027
       if (conf.mem_model == MM_ATM450)
1028
       {
1029
           // ATM1, ���� �� ����������� ������������
1030
           AtmVideoCtrl.PrepareFrameATM1( (comp.aFE >> 5) & 3 );
1031
 
1032
       }
1033
 
1034
      // if border update disabled, dont show anything on zx-screen
1035
      if (!conf.updateb)
1036
          return;
1037
   }
1038
 
1039
   // paper + border
1040
   temp.base_2 = temp.base;
1041
//allow_border:
1042
   prev_t = vmode = 0;
1043
   vcurr = video;
1044
}
1045
 
1046
void flush_frame()
1047
{
1048
   if (temp.vidblock)
1049
       return;
796 DimkaM 1050
   if (prev_t != -1U)
716 lvd 1051
   { // MCR on
1052
      if (prev_t)
1053
      {  // paint until end of frame
1054
         // paint until screen bottom, even if n_lines*t_line < cpu.t (=t_frame)
1055
         unsigned t = cpu.t;
1056
         cpu.t = 0x7FFF0000;
1057
         update_screen();
1058
         cpu.t = t;
1059
//         if (comp.pEFF7 & EFF7_GIGASCREEN) draw_gigascreen_no_border(); //Alone Coder
1060
      }
1061
      else
1062
      { // MCR on, but no screen updates in last frame - use fast painter
1063
         if (temp.base_2 /*|| (comp.pEFF7 & EFF7_GIGASCREEN)*/ /*Alone Coder*/)
1064
             draw_screen();
1065
         else
1066
             draw_border();
1067
      }
1068
      return;
1069
   }
1070
   if (comp.pEFF7 & EFF7_384)
1071
       draw_alco();
1072
}
1073
 
796 DimkaM 1074
// spectrum colors -> palette indexes (RF_PALB - gggrrrbb format)
1075
static const u8 comp_pal[16] =
1076
{
1077
    // normal bright  g   r   b   g  r  b
1078
    0x00, // black   000|000|00  00|00|00
1079
    0x02, // blue    000|000|10  00|00|10
1080
    0x10, // red     000|100|00  00|10|00
1081
    0x12, // magenta 000|100|10  00|10|10
1082
    0x80, // green   100|000|00  10|00|00
1083
    0x82, // cyan    100|000|10  10|00|10
1084
    0x90, // yellow  100|100|00  10|10|00
1085
    0x92, // white   100|100|10  10|10|10
1086
 
1087
    // high bright    g   r   b   g  r  b
1088
    0x00, // black   000|000|00  00|00|00
1089
    0x03, // blue    000|000|11  00|00|11
1090
    0x1C, // red     000|111|00  00|11|00
1091
    0x1F, // magenta 000|111|11  00|11|11
1092
    0xE0, // green   111|000|00  11|00|00
1093
    0xE3, // cyan    111|000|11  11|00|11
1094
    0xFC, // yellow  111|111|00  11|11|00
1095
    0xFF  // white   111|111|11  11|11|11
1096
};
1097
 
716 lvd 1098
void load_spec_colors()
1099
{
796 DimkaM 1100
    for(unsigned flash = 0; flash < 2; flash++)
1101
    {
1102
        for(unsigned bright = 0; bright < 2; bright++)
1103
        {
1104
            unsigned PalNo = ((flash << 1) | bright) << 4;
1105
            memcpy(comp.comp_pal + (PalNo | (0 << 3)), comp_pal + (bright << 3), sizeof(comp_pal) / 2); // ink
1106
            memcpy(comp.comp_pal + (PalNo | (1 << 3)), comp_pal + (bright << 3), sizeof(comp_pal) / 2); // paper
1107
        }
1108
    }
1109
    temp.comp_pal_changed = 1;
716 lvd 1110
}