Subversion Repositories pentevo

Rev

Rev 716 | Blame | Last modification | View Log | Download | RSS feed

  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. }
  464.