Subversion Repositories pentevo

Rev

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