Subversion Repositories pentevo

Rev

Rev 883 | Blame | Compare with Previous | 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 "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. }
  532.