Subversion Repositories pentevo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1088 alone 1
#include "std.h"
2
 
3
#include "emul.h"
4
#include "vars.h"
5
#include "draw.h"
6
#include "dxrframe.h"
7
#include "fontdata.h"
8
#include "font8.h"
9
#include "font14.h"
10
#include "font16.h"
11
#include "dxr_text.h"
12
#include "init.h"
13
#include "util.h"
14
 
15
static void *root_tab;
16
const unsigned char *fontdata = fontdata1;
17
 
18
static void recognize_text(const unsigned char *st, unsigned char *d[])
19
{
20
    void **dst = (void **)d;
21
    const u32 *start = (const u32 *)st;
22
    for(unsigned i = 0; i < 64; i++)
23
    {
24
        dst[i] = root_tab;
25
    }
26
 
27
    for(unsigned j = conf.fontsize; j != 0; j--, start += temp.scx >> 4)
28
    {
29
        for(unsigned i = 0; i < 64 / 4; i++)
30
        {
31
            dst[4*i+0] = ((void **)dst[4*i+0])[(start[i] >> 4) & 0xF];
32
            dst[4*i+1] = ((void **)dst[4*i+1])[(start[i] & 0xF)];
33
            dst[4*i+2] = ((void **)dst[4*i+2])[(start[i] >> 20) & 0xF];
34
            dst[4*i+3] = ((void **)dst[4*i+3])[(start[i] >> 16) & 0xF];
35
        }
36
    }
37
}
38
 
39
#define line_a64_8_2 line_a64_8 // scanlines �������� ����� ����� � ������� 8x16
40
#define line_a64_8_1 line_a64_8 // ������� scanlines �� �����p���
41
#define line_a64_16_2 line_a64_16
42
#define line_a64_16_1 line_a64_16
43
#define line_a64_32_2 line_a64_32
44
#define line_a64_32_1 line_a64_32
45
 
46
static void line_a64_8(unsigned char *dst, unsigned char *src, unsigned char *chars[], unsigned line)
47
{
48
   for (unsigned x = 0; x < 512; x += 32) {
49
      unsigned s = *(unsigned*)src;
50
      unsigned attr = (s >> 6) & 0x3FC;
51
      unsigned char *ptr = *chars++;
52
      if (!ptr) {
53
         *(unsigned*)(dst+x+ 0) = t.sctab8d[0][((s >> 6) & 3) + attr];
54
         *(unsigned*)(dst+x+ 4) = t.sctab8d[0][((s >> 4) & 3) + attr];
55
      } else {
56
         unsigned attr = 0xF0*4;
57
         *(unsigned*)(dst+x+ 0) = t.sctab8[0][((ptr[line] >> 4) & 0xF) + attr*4];
58
         *(unsigned*)(dst+x+ 4) = t.sctab8[0][((ptr[line]     ) & 0xF) + attr*4];
59
      }
60
      ptr = *chars++;
61
      if (!ptr) {
62
         *(unsigned*)(dst+x+ 8) = t.sctab8d[0][((s >> 2) & 3) + attr];
63
         *(unsigned*)(dst+x+12) = t.sctab8d[0][((s >> 0) & 3) + attr];
64
      } else {
65
         unsigned attr = 0xF0*4;
66
         *(unsigned*)(dst+x+ 8) = t.sctab8[0][((ptr[line] >> 4) & 0xF) + attr*4];
67
         *(unsigned*)(dst+x+12) = t.sctab8[0][((ptr[line]     ) & 0xF) + attr*4];
68
      }
69
      ptr = *chars++;
70
      attr = (s >> 22) & 0x3FC;
71
      if (!ptr) {
72
         *(unsigned*)(dst+x+16) = t.sctab8d[0][((s >>22) & 3) + attr];
73
         *(unsigned*)(dst+x+20) = t.sctab8d[0][((s >>20) & 3) + attr];
74
      } else {
75
         unsigned attr = 0xF0*4;
76
         *(unsigned*)(dst+x+16) = t.sctab8[0][((ptr[line] >> 4) & 0xF) + attr*4];
77
         *(unsigned*)(dst+x+20) = t.sctab8[0][((ptr[line]     ) & 0xF) + attr*4];
78
      }
79
      ptr = *chars++;
80
      if (!ptr) {
81
         *(unsigned*)(dst+x+24) = t.sctab8d[0][((s >>18) & 3) + attr];
82
         *(unsigned*)(dst+x+28) = t.sctab8d[0][((s >>16) & 3) + attr];
83
      } else {
84
         unsigned attr = 0xF0*4;
85
         *(unsigned*)(dst+x+24) = t.sctab8[0][((ptr[line] >> 4) & 0xF) + attr*4];
86
         *(unsigned*)(dst+x+28) = t.sctab8[0][((ptr[line]     ) & 0xF) + attr*4];
87
      }
88
 
89
      src += 4;
90
   }
91
}
92
 
93
static void line_a64_16(unsigned char *dst, unsigned char *src, unsigned char *chars[], unsigned line)
94
{
95
   for (unsigned x = 0; x < 1024; x += 32) {
96
      unsigned char s = *src++;
97
      unsigned attr = *src++;
98
      unsigned *tab1 = t.sctab16d[0] + attr;
99
      unsigned *tab2 = t.sctab16 [0] + attr*4;
100
      unsigned char *ptr = *chars++;
101
      if (!ptr) {
102
         *(unsigned*)(dst+x+ 0) = tab1[(s << 1) & 0x100];
103
         *(unsigned*)(dst+x+ 4) = tab1[(s << 2) & 0x100];
104
         *(unsigned*)(dst+x+ 8) = tab1[(s << 3) & 0x100];
105
         *(unsigned*)(dst+x+12) = tab1[(s << 4) & 0x100];
106
      } else {
107
         unsigned s = ptr[line];
108
         *(unsigned*)(dst+x)   = tab2[(s >> 6) & 3];
109
         *(unsigned*)(dst+x+4) = tab2[(s >> 4) & 3];
110
         *(unsigned*)(dst+x+8) = tab2[(s >> 2) & 3];
111
         *(unsigned*)(dst+x+12)= tab2[(s >> 0) & 3];
112
      }
113
      ptr = *chars++;
114
      if (!ptr) {
115
         *(unsigned*)(dst+x+16) = tab1[(s << 5) & 0x100];
116
         *(unsigned*)(dst+x+20) = tab1[(s << 6) & 0x100];
117
         *(unsigned*)(dst+x+24) = tab1[(s << 7) & 0x100];
118
         *(unsigned*)(dst+x+28) = tab1[(s << 8) & 0x100];
119
      } else {
120
         unsigned s = ptr[line];
121
         *(unsigned*)(dst+x+16) = tab2[(s >> 6) & 3];
122
         *(unsigned*)(dst+x+20) = tab2[(s >> 4) & 3];
123
         *(unsigned*)(dst+x+24) = tab2[(s >> 2) & 3];
124
         *(unsigned*)(dst+x+28) = tab2[(s >> 0) & 3];
125
      }
126
   }
127
}
128
 
129
static void line_a64_32(unsigned char *dst, unsigned char *src, unsigned char *chars[], unsigned line)
130
{
131
   for (unsigned x = 0; x < 2048; x += 64) {
132
      unsigned char s = *src++;
133
      unsigned attr = *src++;
134
      unsigned *tab = t.sctab32[0] + attr;
135
      unsigned char *ptr = *chars++;
136
      if (!ptr) {
137
         *(unsigned*)(dst+x+ 0) =
138
         *(unsigned*)(dst+x+ 4) = tab[(s << 1) & 0x100];
139
         *(unsigned*)(dst+x+ 8) =
140
         *(unsigned*)(dst+x+12) = tab[(s << 2) & 0x100];
141
         *(unsigned*)(dst+x+16) =
142
         *(unsigned*)(dst+x+20) = tab[(s << 3) & 0x100];
143
         *(unsigned*)(dst+x+24) =
144
         *(unsigned*)(dst+x+28) = tab[(s << 4) & 0x100];
145
      } else {
146
         unsigned s = ptr[line];
147
         *(unsigned*)(dst+x+ 0) = tab[(s << 1) & 0x100];
148
         *(unsigned*)(dst+x+ 4) = tab[(s << 2) & 0x100];
149
         *(unsigned*)(dst+x+ 8) = tab[(s << 3) & 0x100];
150
         *(unsigned*)(dst+x+12) = tab[(s << 4) & 0x100];
151
         *(unsigned*)(dst+x+16) = tab[(s << 5) & 0x100];
152
         *(unsigned*)(dst+x+20) = tab[(s << 6) & 0x100];
153
         *(unsigned*)(dst+x+24) = tab[(s << 7) & 0x100];
154
         *(unsigned*)(dst+x+28) = tab[(s << 8) & 0x100];
155
      }
156
      ptr = *chars++;
157
      if (!ptr) {
158
         *(unsigned*)(dst+x+32) =
159
         *(unsigned*)(dst+x+36) = tab[(s << 5) & 0x100];
160
         *(unsigned*)(dst+x+40) =
161
         *(unsigned*)(dst+x+44) = tab[(s << 6) & 0x100];
162
         *(unsigned*)(dst+x+48) =
163
         *(unsigned*)(dst+x+52) = tab[(s << 7) & 0x100];
164
         *(unsigned*)(dst+x+56) =
165
         *(unsigned*)(dst+x+60) = tab[(s << 8) & 0x100];
166
      } else {
167
         unsigned s = ptr[line];
168
         *(unsigned*)(dst+x+32) = tab[(s << 1) & 0x100];
169
         *(unsigned*)(dst+x+36) = tab[(s << 2) & 0x100];
170
         *(unsigned*)(dst+x+40) = tab[(s << 3) & 0x100];
171
         *(unsigned*)(dst+x+44) = tab[(s << 4) & 0x100];
172
         *(unsigned*)(dst+x+48) = tab[(s << 5) & 0x100];
173
         *(unsigned*)(dst+x+52) = tab[(s << 6) & 0x100];
174
         *(unsigned*)(dst+x+56) = tab[(s << 7) & 0x100];
175
         *(unsigned*)(dst+x+60) = tab[(s << 8) & 0x100];
176
      }
177
   }
178
}
179
 
180
static unsigned char *zero64[64] = { };
181
 
182
static void rend_anti64_8s(unsigned char *dst, unsigned pitch, unsigned char *src, unsigned scroll = 0)
183
{
184
   ATTR_ALIGN(16) unsigned char *chars[64];
185
 
186
   unsigned delta = temp.scx/4;
187
   if (scroll) for (unsigned y = 0; y < 64; y++) chars[y] = nullptr;
188
   else
189
   {
190
       recognize_text(src, chars);
191
       scroll = conf.fontsize;
192
   }
193
   for (unsigned s = 0; s < scroll; s++) {
194
      line_a64_8_1(dst, src, chars, s); dst += pitch;
195
      src += delta;
196
   }
197
   for (unsigned y = conf.fontsize; y < 192; y+=conf.fontsize) {
198
      recognize_text(src, chars);
199
      for (unsigned line = 0; line < conf.fontsize; line++) {
200
         line_a64_8_1(dst, src, chars, line); dst += pitch;
201
         src += delta;
202
      }
203
   }
204
   for (unsigned line = scroll; line < conf.fontsize; line++) {
205
      line_a64_8_1(dst, src, zero64, 0); dst += pitch;
206
      src += delta;
207
   }
208
}
209
 
210
static void rend_anti64_8d(unsigned char *dst, unsigned pitch, unsigned char *src, unsigned scroll = 0)
211
{
212
   ATTR_ALIGN(16) unsigned char *chars[64];
213
   unsigned delta = temp.scx/4;
214
   if (scroll) for (unsigned y = 0; y < 64; y++) chars[y] = nullptr;
215
   else
216
   {
217
       recognize_text(src, chars);
218
       scroll = conf.fontsize;
219
   }
220
   for (unsigned s = 0; s < scroll; s++) {
221
      line_a64_8_1(dst, src, chars, s*2); dst += pitch;
222
      line_a64_8_2(dst, src, chars, s*2+1); dst += pitch;
223
      src += delta;
224
   }
225
   for (unsigned y = conf.fontsize; y < 192; y+=conf.fontsize) {
226
      recognize_text(src, chars);
227
      for (unsigned line = 0; line < conf.fontsize; line++) {
228
         line_a64_8_1(dst, src, chars, line*2); dst += pitch;
229
         line_a64_8_2(dst, src, chars, line*2+1); dst += pitch;
230
         src += delta;
231
      }
232
   }
233
   for (unsigned line = scroll; line < conf.fontsize; line++) {
234
      line_a64_8_1(dst, src, zero64, 0); dst += pitch;
235
      line_a64_8_2(dst, src, zero64, 0); dst += pitch;
236
      src += delta;
237
   }
238
}
239
 
240
static void rend_anti64_16s(unsigned char *dst, unsigned pitch, unsigned char *src, unsigned scroll = 0)
241
{
242
   ATTR_ALIGN(16) unsigned char *chars[64];
243
   unsigned delta = temp.scx/4;
244
   if (scroll) for (unsigned y = 0; y < 64; y++) chars[y] = nullptr;
245
   else
246
   {
247
       recognize_text(src, chars);
248
       scroll = conf.fontsize;
249
   }
250
   for (unsigned s = 0; s < scroll; s++) {
251
      line_a64_16_1(dst, src, chars, s); dst += pitch;
252
      src += delta;
253
   }
254
   for (unsigned y = conf.fontsize; y < 192; y+=conf.fontsize) {
255
      recognize_text(src, chars);
256
      for (unsigned line = 0; line < conf.fontsize; line++) {
257
         line_a64_16_1(dst, src, chars, line); dst += pitch;
258
         src += delta;
259
      }
260
   }
261
   for (unsigned line = scroll; line < conf.fontsize; line++) {
262
      line_a64_16_1(dst, src, zero64, 0); dst += pitch;
263
      src += delta;
264
   }
265
}
266
 
267
static void rend_anti64_16d(unsigned char *dst, unsigned pitch, unsigned char *src, unsigned scroll = 0)
268
{
269
   ATTR_ALIGN(16) unsigned char *chars[64];
270
   unsigned delta = temp.scx/4;
271
   if (scroll) for (unsigned y = 0; y < 64; y++) chars[y] = nullptr;
272
   else
273
   {
274
       recognize_text(src, chars);
275
       scroll = conf.fontsize;
276
   }
277
   for (unsigned s = 0; s < scroll; s++) {
278
      line_a64_16_1(dst, src, chars, s*2); dst += pitch;
279
      line_a64_16_2(dst, src, chars, s*2+1); dst += pitch;
280
      src += delta;
281
   }
282
   for (unsigned y = conf.fontsize; y < 192; y+=conf.fontsize) {
283
      recognize_text(src, chars);
284
      for (unsigned line = 0; line < conf.fontsize; line++) {
285
         line_a64_16_1(dst, src, chars, line*2); dst += pitch;
286
         line_a64_16_2(dst, src, chars, line*2+1); dst += pitch;
287
         src += delta;
288
      }
289
   }
290
   for (unsigned line = scroll; line < conf.fontsize; line++) {
291
      line_a64_16_1(dst, src, zero64, 0); dst += pitch;
292
      line_a64_16_2(dst, src, zero64, 0); dst += pitch;
293
      src += delta;
294
   }
295
}
296
 
297
static void rend_anti64_32s(unsigned char *dst, unsigned pitch, unsigned char *src, unsigned scroll = 0)
298
{
299
   ATTR_ALIGN(16) unsigned char *chars[64];
300
   unsigned delta = temp.scx/4;
301
   if (scroll) for (unsigned y = 0; y < 64; y++) chars[y] = nullptr;
302
   else
303
   {
304
       recognize_text(src, chars);
305
       scroll = conf.fontsize;
306
   }
307
   for (unsigned s = 0; s < scroll; s++) {
308
      line_a64_32_1(dst, src, chars, s); dst += pitch;
309
      src += delta;
310
   }
311
   for (unsigned y = conf.fontsize; y < 192; y+=conf.fontsize) {
312
      recognize_text(src, chars);
313
      for (unsigned line = 0; line < conf.fontsize; line++) {
314
         line_a64_32_1(dst, src, chars, line); dst += pitch;
315
         src += delta;
316
      }
317
   }
318
   for (unsigned line = scroll; line < conf.fontsize; line++) {
319
      line_a64_32_1(dst, src, zero64, 0); dst += pitch;
320
      src += delta;
321
   }
322
}
323
 
324
static void rend_anti64_32d(unsigned char *dst, unsigned pitch, unsigned char *src, unsigned scroll = 0)
325
{
326
   ATTR_ALIGN(16) unsigned char *chars[64];
327
   unsigned delta = temp.scx/4;
328
   if (scroll) for (unsigned y = 0; y < 64; y++) chars[y] = nullptr;
329
   else
330
   {
331
       recognize_text(src, chars);
332
       scroll = conf.fontsize;
333
   }
334
   for (unsigned s = 0; s < scroll; s++) {
335
      line_a64_32_1(dst, src, chars, s*2); dst += pitch;
336
      line_a64_32_2(dst, src, chars, s*2+1); dst += pitch;
337
      src += delta;
338
   }
339
   for (unsigned y = conf.fontsize; y < 192; y+=conf.fontsize) {
340
      recognize_text(src, chars);
341
      for (unsigned line = 0; line < conf.fontsize; line++) {
342
         line_a64_32_1(dst, src, chars, line*2); dst += pitch;
343
         line_a64_32_2(dst, src, chars, line*2+1); dst += pitch;
344
         src += delta;
345
      }
346
   }
347
   for (unsigned line = scroll; line < conf.fontsize; line++) {
348
      line_a64_32_1(dst, src, zero64, 0); dst += pitch;
349
      line_a64_32_2(dst, src, zero64, 0); dst += pitch;
350
      src += delta;
351
   }
352
}
353
 
354
static unsigned detect_scroll(unsigned char *src)
355
{
356
   unsigned char *chars[64];
357
   unsigned delta = temp.scx/4, delta2 = delta * conf.fontsize;
358
   uintptr_t max = 0;
359
   unsigned scroll = 0;
360
   for (unsigned line = 0; line < conf.fontsize; line++)
361
   {
362
      uintptr_t found = 0; unsigned char *src_pos = src; src += delta;
363
      for (unsigned pos = line; pos < 192; pos += conf.fontsize)
364
      {
365
         recognize_text(src_pos, chars);
366
         for (unsigned i = 0; i < 64; i++)
367
             found += uintptr_t(chars[i]) >> 16;
368
         src_pos += delta2;
369
      }
370
      if(found > max)
371
      {
372
          max = found;
373
          scroll = line;
374
      }
375
   }
376
   return scroll;
377
}
378
 
379
void __fastcall render_text(unsigned char *dst, unsigned pitch)
380
{
381
   unsigned char *dst2 = dst + temp.b_left*temp.obpp/4 +
382
                       temp.b_top*pitch * ((temp.oy > temp.scy)?2:1);
383
   if (temp.oy > temp.scy && conf.fast_sl) pitch *= 2;
384
   unsigned char *src = rbuf + (temp.b_top*temp.scx+temp.b_left)/4;
385
   unsigned scroll = conf.pixelscroll? detect_scroll(src) : 0;
386
 
387
   if(temp.obpp == 8)
388
   {
389
       if(conf.fast_sl)
390
       {
391
           rend_frame_8d1(dst, pitch);
392
           rend_anti64_8s(dst2, pitch, src, scroll);
393
       }
394
       else
395
       {
396
           rend_frame_8d(dst, pitch);
397
           rend_anti64_8d(dst2, pitch, src, scroll);
398
       }
399
       return;
400
   }
401
   if(temp.obpp == 16)
402
   {
403
       if(conf.fast_sl)
404
       {
405
           rend_frame_16d1(dst, pitch);
406
           rend_anti64_16s(dst2, pitch, src, scroll);
407
       }
408
       else
409
       {
410
           rend_frame_16d(dst, pitch);
411
           rend_anti64_16d(dst2, pitch, src, scroll);
412
       }
413
       return;
414
   }
415
   if(temp.obpp == 32)
416
   {
417
       if(conf.fast_sl)
418
       {
419
           rend_frame_32d1(dst, pitch);
420
           rend_anti64_32s(dst2, pitch, src, scroll);
421
       }
422
       else
423
       {
424
           rend_frame_32d(dst, pitch);
425
           rend_anti64_32d(dst2, pitch, src, scroll);
426
       }
427
       return;
428
   }
429
 
430
}
431
 
432
static void *alloc_table(void **&tptr, void *startval)
433
{
434
   void *res = (void *)tptr;
435
   for (unsigned i = 0; i < 16; i++)
436
       tptr[i] = startval;
437
   tptr += 16;
438
   return res;
439
}
440
 
441
//
442
//    dt[i-1] -> dt[i] -> dt[i+1]
443
//               |        dt[i+1]
444
//               |
445
//               dt[i] -> dt[i+1]
446
//               |        dt[i+1]
447
//               |
448
//               dt[i] -> dt[i+1]
449
//                        dt[i+1]
450
 
451
// l1[] = { 0, 0, 0 };
452
// l2[] = { l1, l1, l1 };
453
// l3[] = { l2, l2, l2 };
454
 
455
void create_font_tables()
456
{
457
   unsigned char *fontbase = conf.fast_sl ? font8 : font16;
458
   unsigned fonth = conf.fast_sl ? 8 : 16;
459
 
460
   if (conf.fontsize < 8)
461
   {
462
       fontbase = conf.fast_sl ? font8 : font14;
463
       fonth = conf.fast_sl ? 8 : 14;
464
   }
465
 
466
   void *dummy_tab[8];
467
   void **ts = (void **)t.font_tables;
468
   dummy_tab[conf.fontsize-1] = alloc_table(ts, nullptr);
469
   for (unsigned i = conf.fontsize-1; i; i--)
470
      dummy_tab[i-1] = alloc_table(ts, dummy_tab[i]);
471
   root_tab = dummy_tab[0];
472
 
473
   // todo: collapse tree to graph
474
   // (last bytes of same char with
475
   // different first bytes may be same)
476
   for (unsigned invert = 0; invert < 0x100; invert += 0xFF)
477
   {
478
      for (const unsigned char *ptr = fontdata; *ptr; ptr += 8)
479
      {
480
         unsigned code = *ptr++;
481
         void **tab = (void **)root_tab;
482
 
483
         for (unsigned level = 0; ; level++)
484
         {
485
            unsigned bits = (ptr[level] ^ (unsigned char)invert) & 0x0F;
486
            if (level == conf.fontsize-1)
487
            {
488
               if (tab[bits])
489
               {
490
#if 0 // 1 - debug
491
                  color(CONSCLR_ERROR);
492
                  printf("duplicate char %d (%02X)! - font table may corrupt\n", (ptr-1-fontdata)/9, code);
493
                  exit();
494
#endif
495
               }
496
               else
497
               {
498
                  unsigned *newchar;
499
                  unsigned *basechar = (unsigned*)(fontbase + fonth*code); // ����� 8xh, h=8,14,16
500
                  if (invert)
501
                  {
502
                     newchar = (unsigned *)ts;
503
                     ts += 4;
504
                     newchar[0] = ~basechar[0];
505
                     newchar[1] = ~basechar[1];
506
                     newchar[2] = ~basechar[2];
507
                     newchar[3] = ~basechar[3];
508
                  }
509
                  else
510
                     newchar = basechar;
511
 
512
                  tab[bits] = newchar;
513
               }
514
               break;
515
            }
516
            void *next = tab[bits];
517
            if (next == dummy_tab[level+1])
518
               tab[bits] = next = alloc_table(ts, (level==conf.fontsize-2)? nullptr : dummy_tab[level+2]);
519
            tab = (void **)next;
520
         }
521
      }
522
   }
523
 
524
   size_t usedsize = size_t(((u8 *)ts) - ((u8 *)t.font_tables));
525
   if (usedsize > sizeof(t.font_tables))
526
   {
527
      color(CONSCLR_ERROR);
528
      printf("font table overflow: size=%u (0x%X) of 0x%X\n", unsigned(usedsize), unsigned(usedsize), unsigned(sizeof t.font_tables));
529
      exit();
530
   }
531
}