Subversion Repositories pentevo

Rev

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

  1. #include "std.h"
  2.  
  3. #include "resource.h"
  4. #include "emul.h"
  5. #include "vars.h"
  6. #include "dxr_text.h"
  7.  
  8. #include "util.h"
  9.  
  10. #ifdef MOD_SETTINGS
  11. unsigned font_maxmem = 0xFFFF;
  12. unsigned char r21=1, r30=1, r41=1, r61=1, r80=1, rae=1, rf0=0, roth=0;
  13. unsigned char linear = 0, right = 1, x100 = 1;
  14. unsigned char rmask[0x100];
  15. unsigned font_address;
  16. unsigned char fontdata2[0x900*2];
  17. unsigned fontsize = 8;
  18. static unsigned block_font_dialog = 0;
  19. unsigned char *font_base;
  20.  
  21.  
  22. void update_rmask()
  23. {
  24.    memset(rmask, 0, sizeof rmask);
  25.    if (r21) memset(rmask+0x21, 1, 0x0F);
  26.    if (r30) memset(rmask+0x30, 1, 10);
  27.    if (r41) memset(rmask+0x41, 1, 26);
  28.    if (r61) memset(rmask+0x61, 1, 26);
  29.    if (r80) memset(rmask+0x80, 1, 32);
  30.    if (rae) memset(rmask+0xA0, 1, 16), memset(rmask+0xE0, 1, 16);
  31.    if (rf0) rmask[0xF0] = rmask[0xF1] = 1;
  32.    if (roth)
  33.        memset(rmask+1, 1, 0x1F), memset(rmask+0xB0, 1, 0x30),
  34.        memset(rmask+0xF2, 1, 13), memset(rmask+0x3A, 1, 7),
  35.        memset(rmask+0x5B, 1, 6), memset(rmask+0x7B, 1, 5);
  36. }
  37.  
  38. void get_ranges(HWND dlg)
  39. {
  40.    char ln[64]; GetDlgItemText(dlg, IDE_ADDRESS, ln, sizeof ln);
  41.    sscanf(ln, "%X", &font_address); font_address &= font_maxmem;
  42.  
  43.    linear = (IsDlgButtonChecked(dlg, IDC_LINEAR) == BST_CHECKED)? 1 : 0;
  44.    right = (IsDlgButtonChecked(dlg, IDC_RIGHT) == BST_CHECKED)? 1 : 0;
  45.    x100 = (IsDlgButtonChecked(dlg, IDC_100) == BST_CHECKED)? 1 : 0;
  46.  
  47.    r21 = IsDlgButtonChecked(dlg, IDC_R212F) == BST_CHECKED;
  48.    r30 = IsDlgButtonChecked(dlg, IDC_R3039) == BST_CHECKED;
  49.    r41 = IsDlgButtonChecked(dlg, IDC_R415A) == BST_CHECKED;
  50.    r61 = IsDlgButtonChecked(dlg, IDC_R617A) == BST_CHECKED;
  51.    r80 = IsDlgButtonChecked(dlg, IDC_R809F) == BST_CHECKED;
  52.    rae = IsDlgButtonChecked(dlg, IDC_RA0AF) == BST_CHECKED;
  53.    rf0 = IsDlgButtonChecked(dlg, IDC_RF0F1) == BST_CHECKED;
  54.    roth = IsDlgButtonChecked(dlg, IDC_ROTH2) == BST_CHECKED;
  55.    fontsize = 5 + SendDlgItemMessage(dlg, IDC_FONTSIZE, CB_GETCURSEL, 0, 0);
  56.    update_rmask();
  57. }
  58.  
  59. void paint_font(HWND dlg, int paint=0)
  60. {
  61.    const int sz = 340;
  62.    char *buf = (char*)malloc(sz*sz);
  63.    if (!buf) return;
  64.    RECT rc; GetWindowRect(GetDlgItem(dlg, IDC_FRAME), &rc);
  65.    RECT r2; GetWindowRect(dlg, &r2);
  66.    rc.top -= r2.top, rc.bottom -= r2.top, rc.left -= r2.left, rc.right -= r2.left;
  67.    static struct {
  68.       BITMAPINFO header;
  69.       RGBQUAD waste[0x100];
  70.    } gdibmp = { { sizeof(BITMAPINFOHEADER), sz, -sz, 1, 8, BI_RGB } };
  71.    static RGBQUAD cl[] = { {0xFF,0,0},{0xC0,0xC0,0xC0},{0,0,0} };
  72.    memcpy(gdibmp.header.bmiColors, cl, sizeof(cl));
  73.    memset(buf, 0, sz*sz);
  74.  
  75.    unsigned next_pixel, next_char;
  76.    if (linear) next_pixel = 1, next_char = 8;
  77.    else next_pixel = 0x100, next_char = 1;
  78.  
  79.    unsigned t1[4], t2[4];
  80.    for (unsigned j = 0; j < 4; j++) {
  81.       unsigned mask = (j >> 1)*0xFFFF + (j & 1)*0xFFFF0000;
  82.       t1[j] = mask & 0x01010101; t2[j] = mask & 0x02020202;
  83.    }
  84.  
  85.    for (unsigned ch = 0; ch < 0x100; ch++) {
  86.       unsigned x = ch & 0x0F, y = ch / 0x10;
  87.       x = x*20 + ((x>>2)&3) * 2;
  88.       y = y*20 + ((y>>2)&3) * 2;
  89.       x += 10, y += 10;
  90.       for (unsigned i = 0; i < fontsize; i++) {
  91.          unsigned char byte = font_base[(font_address + i*next_pixel + ch*next_char) & font_maxmem];
  92.          unsigned *t0 = t1;
  93.          if (right || !rmask[ch]) t0 = t2;
  94.          *(unsigned*)(buf+sz*(y+2*i) + x) = t0[byte >> 6];
  95.          *(unsigned*)(buf+sz*(y+2*i) + x + 4) = t0[(byte >> 4) & 3];
  96.          *(unsigned*)(buf+sz*(y+2*i+1) + x) = t0[byte >> 6];
  97.          *(unsigned*)(buf+sz*(y+2*i+1) + x + 4) = t0[(byte >> 4) & 3];
  98.  
  99.          t0 = t1;
  100.          if (!right || !rmask[ch]) t0 = t2;
  101.          *(unsigned*)(buf+sz*(y+2*i) + x + 8) = t0[(byte >> 2) & 3];
  102.          *(unsigned*)(buf+sz*(y+2*i) + x + 12) = t0[byte & 3];
  103.          *(unsigned*)(buf+sz*(y+2*i+1) + x + 8) = t0[(byte >> 2) & 3];
  104.          *(unsigned*)(buf+sz*(y+2*i+1) + x + 12) = t0[byte & 3];
  105.       }
  106.    }
  107.  
  108.    PAINTSTRUCT ps;
  109.    if (paint) BeginPaint(dlg, &ps); else ps.hdc = GetDC(dlg);
  110.    SetDIBitsToDevice(ps.hdc, rc.left + (int)(rc.right-rc.left-sz)/2, rc.top + (int)(rc.bottom-rc.top-sz)/2, sz, sz, 0, 0, 0, sz, buf, &gdibmp.header, DIB_RGB_COLORS);
  111.    if (paint) EndPaint(dlg, &ps); else ReleaseDC(dlg, ps.hdc);
  112.    free(buf);
  113.    char ln[64];
  114.    if (font_base == RAM_BASE_M)
  115.       sprintf(ln, "bank #%02X, offset %04X", (font_address & font_maxmem) >> 14, font_address & 0x3FFF);
  116.    else
  117.       sprintf(ln, "file offset %04X", font_address);
  118.    SetDlgItemText(dlg, IDC_ADDRESS, ln);
  119. }
  120.  
  121. unsigned char pattern[12][8];
  122.  
  123. void kill_pattern(unsigned x, unsigned y, unsigned mode)
  124. {
  125.    unsigned sx[64], sy[64], sp = 1;
  126.    sx[0] = x, sy[0] = y;
  127.    pattern[y][x] = 0;
  128.    while (sp--) {
  129.       x = sx[sp], y = sy[sp];
  130.       if (pattern[y-1][x]) pattern[y-1][x] = 0, sx[sp] = x, sy[sp] = y-1, sp++;
  131.       if (pattern[y+1][x]) pattern[y+1][x] = 0, sx[sp] = x, sy[sp] = y+1, sp++;
  132.       if (pattern[y][x-1]) pattern[y][x-1] = 0, sx[sp] = x-1, sy[sp] = y, sp++;
  133.       if (pattern[y][x+1]) pattern[y][x+1] = 0, sx[sp] = x+1, sy[sp] = y, sp++;
  134.       if (mode) {
  135.          if (pattern[y-1][x+1]) pattern[y-1][x+1] = 0, sx[sp] = x+1, sy[sp] = y-1, sp++;
  136.          if (pattern[y+1][x+1]) pattern[y+1][x+1] = 0, sx[sp] = x+1, sy[sp] = y+1, sp++;
  137.          if (pattern[y-1][x-1]) pattern[y-1][x-1] = 0, sx[sp] = x-1, sy[sp] = y-1, sp++;
  138.          if (pattern[y+1][x-1]) pattern[y+1][x-1] = 0, sx[sp] = x-1, sy[sp] = y+1, sp++;
  139.       }
  140.    }
  141. }
  142.  
  143. unsigned kill_raw(unsigned x, unsigned y, unsigned mode)
  144. {
  145.    unsigned result = 0;
  146.    if (pattern[y][x])   kill_pattern(x, y, mode), result++;
  147.    if (pattern[y][x+1]) kill_pattern(x+1, y, mode), result++;
  148.    if (pattern[y][x+2]) kill_pattern(x+2, y, mode), result++;
  149.    if (pattern[y][x+3]) kill_pattern(x+3, y, mode), result++;
  150.    return result;
  151. }
  152.  
  153. unsigned count_lnk(unsigned mode)
  154. {
  155.    unsigned result = 0;
  156.    for (;;) {
  157.       unsigned r1 = result;
  158.       for (unsigned line = 1; line < 11; line++) {
  159.          if (*(unsigned*)&(pattern[line][0])) result += kill_raw(0, line, mode);
  160.          if (*(unsigned*)&(pattern[line][4])) result += kill_raw(4, line, mode);
  161.       }
  162.       if (result == r1) break;
  163.    }
  164.    return result;
  165. }
  166.  
  167. static union { unsigned v32; unsigned char v8[4]; } c_map0[16];
  168. static union { unsigned v32; unsigned char v8[4]; } c_map1[16];
  169. static union { unsigned v32; unsigned char v8[4]; } c_map2[16];
  170. static union { unsigned v32; unsigned char v8[4]; } c_map3[16];
  171. static union { unsigned v32; unsigned char v8[4]; } c_map4[16];
  172.  
  173. void create_maps()
  174. {
  175.    unsigned i; //Alone Coder 0.36.7
  176.    for (/*unsigned*/ i = 0; i < 16; i++)
  177.       for (unsigned j = 0; j < 4; j++)
  178.          c_map0[i].v8[3-j] = (i >> j) & 1;
  179.    for (i = 0; i < 16; i++) {
  180.       c_map1[i].v32 = c_map0[i >> 1].v32,
  181.       c_map2[i].v32 = c_map0[(i&1) << 3].v32;
  182.       c_map3[i].v32 = c_map0[(((~i)>>2) | 4) & 0x07].v32,
  183.       c_map4[i].v32 = c_map0[(((~i)<<2) | 2) & 0x0E].v32;
  184.    }
  185. }
  186.  
  187. unsigned linked_cells(unsigned sym)
  188. {
  189.    unsigned pix = 0x100, shift = right? 0 : 4;
  190.    if (linear) sym *= 8, pix = 1;
  191.    sym += font_address;
  192. //   *(unsigned*)&(pattern[0][0]) = *(unsigned*)&(pattern[0][4]) = 0;
  193.    for (unsigned i = 0; i < fontsize; i++, sym += pix)
  194.       *(unsigned*)&(pattern[i+1][0]) = c_map1[(font_base[sym & font_maxmem] >> shift) & 0x0F].v32,
  195.       *(unsigned*)&(pattern[i+1][4]) = c_map2[(font_base[sym & font_maxmem] >> shift) & 0x0F].v32;
  196.    *(unsigned*)&(pattern[fontsize+1][0]) = *(unsigned*)&(pattern[fontsize+1][4]) = 0;
  197.    *(unsigned*)&(pattern[fontsize+2][0]) = *(unsigned*)&(pattern[fontsize+2][4]) = 0;
  198. //   *(unsigned*)&(pattern[fontsize+3][0]) = *(unsigned*)&(pattern[fontsize+3][4]) = 0;
  199.    return count_lnk(1);
  200. }
  201.  
  202. unsigned linked_empties(unsigned sym)
  203. {
  204.    unsigned pix = 0x100, shift = right? 0 : 4;
  205.    if (linear) sym *= 8, pix = 1;
  206.    sym += font_address;
  207. //   *(unsigned*)&(pattern[0][0]) = *(unsigned*)&(pattern[0][4]) = 0;
  208.    *(unsigned*)&(pattern[1][0]) = WORD4(0,1,1,1),
  209.    *(unsigned*)&(pattern[1][4]) = WORD4(1,1,1,0);
  210.    for (unsigned i = 0; i < fontsize; i++, sym += pix)
  211.       *(unsigned*)&(pattern[i+2][0]) = c_map3[(font_base[sym & font_maxmem] >> shift) & 0x0F].v32,
  212.       *(unsigned*)&(pattern[i+2][4]) = c_map4[(font_base[sym & font_maxmem] >> shift) & 0x0F].v32;
  213.    *(unsigned*)&(pattern[fontsize+2][0]) = WORD4(0,1,1,1),
  214.    *(unsigned*)&(pattern[fontsize+2][4]) = WORD4(1,1,1,0);
  215. //   *(unsigned*)&(pattern[fontsize+3][0]) = *(unsigned*)&(pattern[fontsize+3][4]) = 0;
  216.    return count_lnk(0);
  217. }
  218.  
  219. unsigned char is_font()
  220. {
  221.    const int max_err = 2;
  222.    int err = 0;
  223.    #define RET_ERR { if (++err > max_err) return 0; }
  224.    if (r21) {
  225.       if (linked_cells('!') != 2) RET_ERR
  226.       if (linked_empties('!') != 1) RET_ERR
  227.       if (linked_cells('*') != 1) RET_ERR
  228.       if (linked_empties('*') != 1) RET_ERR
  229.       if (linked_cells('(') != 1) RET_ERR
  230.       if (linked_empties('(') != 1) RET_ERR
  231.       if (linked_cells(')') != 1) RET_ERR
  232.       if (linked_empties(')') != 1) RET_ERR
  233.       if (linked_cells('$') != 1) RET_ERR
  234.    }
  235.    if (r30) {
  236.       if (linked_cells('1') != 1) RET_ERR
  237.       if (linked_empties('1') != 1) RET_ERR
  238.       if (linked_cells('6') != 1) RET_ERR
  239.       if (linked_empties('6') != 2) RET_ERR
  240.       if (linked_cells('8') != 1) RET_ERR
  241.       if (linked_empties('8') != 3) RET_ERR
  242.       if (linked_cells('9') != 1) RET_ERR
  243.       if (linked_empties('9') != 2) RET_ERR
  244.       if (linked_cells('0') != 1) RET_ERR
  245.       int e = linked_empties('0');
  246.       if (e != 2 && e != 3) RET_ERR
  247.    }
  248.    if (r41) {
  249.       if (linked_cells('A') != 1) RET_ERR
  250.       if (linked_empties('A') != 2) RET_ERR
  251.       if (linked_cells('O') != 1) RET_ERR
  252.       if (linked_empties('O') != 2) RET_ERR
  253.       if (linked_cells('S') != 1) RET_ERR
  254.       if (linked_empties('S') != 1) RET_ERR
  255.       if (linked_cells('T') != 1) RET_ERR
  256.       if (linked_empties('T') != 1) RET_ERR
  257.       if (linked_cells('Z') != 1) RET_ERR
  258.       if (linked_empties('Z') != 1) RET_ERR
  259.    }
  260.    if (r61) {
  261.       if (linked_cells('b') != 1) RET_ERR
  262.       if (linked_empties('b') != 2) RET_ERR
  263.       if (linked_cells('o') != 1) RET_ERR
  264.       if (linked_empties('o') != 2) RET_ERR
  265.       if (linked_cells('s') != 1) RET_ERR
  266.       if (linked_empties('s') != 1) RET_ERR
  267.       if (linked_cells('t') != 1) RET_ERR
  268.       if (linked_empties('t') != 1) RET_ERR
  269.       if (linked_cells('z') != 1) RET_ERR
  270.       if (linked_empties('z') != 1) RET_ERR
  271.    }
  272.    if (r80) {
  273.       if (linked_cells(0x80) != 1) RET_ERR // A
  274.       if (linked_empties(0x80) != 2) RET_ERR
  275.       if (linked_cells(0x81) != 1) RET_ERR // Б
  276.       if (linked_empties(0x81) != 2) RET_ERR
  277.       if (linked_cells(0x83) != 1) RET_ERR // Г
  278.       if (linked_empties(0x83) != 1) RET_ERR
  279.       if (linked_cells(0x9F) != 1) RET_ERR // Я
  280.       if (linked_empties(0x9F) != 2) RET_ERR
  281.    }
  282.    if (rae) {
  283.       if (linked_cells(0xAE) != 1) RET_ERR // o
  284.       if (linked_empties(0xAE) != 2) RET_ERR
  285.       if (linked_cells(0xE1) != 1) RET_ERR // c
  286.       if (linked_empties(0xE1) != 1) RET_ERR
  287.       if (linked_cells(0xE2) != 1) RET_ERR // T
  288.       if (linked_empties(0xE2) != 1) RET_ERR
  289.    }
  290.    if (rf0) {
  291.       // if (linked_cells(0xF0) != 1) RET_ERR // Ё
  292.    }
  293.    if (roth) {
  294.       if (linked_cells(':') != 2) RET_ERR
  295.       if (linked_empties(':') != 1) RET_ERR
  296.       if (linked_cells(';') != 2) RET_ERR
  297.       if (linked_empties(';') != 1) RET_ERR
  298.    }
  299.    #undef RET_ERR
  300.    return 1;
  301. }
  302.  
  303. inline int pretest_font(unsigned pix, unsigned chr, unsigned shift)
  304. {
  305.    unsigned i; //Alone Coder 0.36.7
  306.    // check space
  307.    for (/*unsigned*/ i = 0; i < fontsize; i++)
  308.       if ((font_base[(font_address + i*pix + chr * 0x20) & font_maxmem] >> shift) & 0x0F) return 0;
  309.    // check non-spaces
  310.    for (i = 0; i < 0x100; i++) {
  311.       if (!rmask[i]) continue;
  312.       unsigned char s = 0;
  313.       for (unsigned k = 0; k < fontsize; k++)
  314.          s += (font_base[(font_address + k*pix + i*chr) & font_maxmem] >> shift) & 0x0F;
  315.       if (!s) return 0;
  316.    }
  317.    return 1;
  318. }
  319.  
  320. void set_data(HWND dlg)
  321. {
  322.    unsigned prev = block_font_dialog;
  323.    block_font_dialog = 1;
  324.    char ln[64]; sprintf(ln, "0%04X", font_address);
  325.    SetDlgItemText(dlg, IDE_ADDRESS, ln);
  326.  
  327.    if (linear)
  328.       CheckDlgButton(dlg, IDC_PLANES, BST_UNCHECKED),
  329.       CheckDlgButton(dlg, IDC_LINEAR, BST_CHECKED);
  330.    else
  331.       CheckDlgButton(dlg, IDC_PLANES, BST_CHECKED),
  332.       CheckDlgButton(dlg, IDC_LINEAR, BST_UNCHECKED);
  333.  
  334.    if (right)
  335.       CheckDlgButton(dlg, IDC_LEFT, BST_UNCHECKED),
  336.       CheckDlgButton(dlg, IDC_RIGHT, BST_CHECKED);
  337.    else
  338.       CheckDlgButton(dlg, IDC_LEFT, BST_CHECKED),
  339.       CheckDlgButton(dlg, IDC_RIGHT, BST_UNCHECKED);
  340.    block_font_dialog = prev;
  341. }
  342.  
  343. void fnt_search(HWND dlg)
  344. {
  345.    create_maps();
  346.    memset(pattern, 0, sizeof pattern);
  347.  
  348.    unsigned start = font_address,
  349.             st_linear = linear, st_right = right;
  350.  
  351.    unsigned pix = linear? 1 : 0x100,
  352.             chr = linear? 8 : 1,
  353.             shift = right? 0 : 4;
  354.  
  355.    for (;;) {
  356.       font_address = (font_address+1) & font_maxmem;
  357.       if (font_address == start) {
  358.          right ^= 1; shift = right? 0 : 4;
  359.          if (right == st_right) {
  360.             linear ^= 1; pix = linear? 1 : 0x100, chr = linear? 8 : 1;
  361.             if (linear == st_linear) {
  362.                MessageBox(dlg, "font not found", "font searcher", MB_OK | MB_ICONWARNING);
  363.                return;
  364.             }
  365.          }
  366.       }
  367.       if (!pretest_font(pix, chr, shift)) continue;
  368.       if (is_font()) break;
  369.    }
  370.    paint_font(dlg);
  371.    set_data(dlg);
  372. }
  373.  
  374. void save_font()
  375. {
  376.    unsigned chr = 1, line = 0x100, shift = 4;
  377.    if (linear) chr = 8, line = 1;
  378.    if (right) shift = 0;
  379.    unsigned char *dst = fontdata2;
  380.  
  381.    unsigned j; //Alone Coder 0.36.7
  382.    for (unsigned i = 0; i < 0x100; i++) {
  383.       if (!i || i == 0x20) continue;
  384.       if (!rmask[i]) continue;
  385.       unsigned chardata = font_address + i*chr;
  386.       unsigned char sum = 0;
  387.       for (/*unsigned*/ j = 0; j < fontsize; j++) sum |= font_base[(chardata + j*line) & font_maxmem];
  388.       if (!((sum >> shift) & 0x0F)) continue;
  389.       *dst++ = (unsigned char)i;
  390.       for (j = 0; j < 8; j++)
  391.          *dst++ = j < fontsize?
  392.                    (font_base[(chardata + j*line) & font_maxmem] >> shift) & 0x0F : 0;
  393.    }
  394.    *dst = 0;
  395.    fontdata = fontdata2;
  396. }
  397.  
  398. void FontFromFile(HWND dlg)
  399. {
  400.    OPENFILENAME ofn = { 0 };
  401.    char fname[0x200]; *fname = 0;
  402.  
  403.    ofn.lStructSize = (WinVerMajor < 5) ? OPENFILENAME_SIZE_VERSION_400 : sizeof(OPENFILENAME);
  404.    ofn.hwndOwner = dlg;
  405.    ofn.lpstrFilter = "font files (*.FNT,*.FNX)\0*.fnt;*.fnx\0All files\0*.*\0";
  406.    ofn.lpstrFile = fname; ofn.nMaxFile = sizeof fname;
  407.    ofn.lpstrTitle = "Load font from file";
  408.    ofn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | OFN_HIDEREADONLY;
  409.    if (!GetOpenFileName(&ofn)) return;
  410.  
  411.    FILE *ff = fopen(fname, "rb"); if (!ff) return;
  412.    memset(font_base = snbuf, 0, sizeof snbuf);
  413.    unsigned size = fread(snbuf, 1, sizeof snbuf, ff);
  414.    fclose(ff);
  415.  
  416.    for (font_maxmem = 0x800; font_maxmem < size; font_maxmem *= 2);
  417.    font_maxmem--;
  418.  
  419.    SetDlgItemText(dlg, IDE_ADDRESS, "0");
  420.    get_ranges(dlg);
  421.    paint_font(dlg);
  422. }
  423.  
  424. INT_PTR CALLBACK fonts_dlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  425. {
  426.    if (msg == WM_INITDIALOG) {
  427.       block_font_dialog = 1;
  428.       font_maxmem = conf.ramsize * 1024 - 1;
  429.       font_base = RAM_BASE_M;
  430.       CheckDlgButton(dlg, IDC_100, x100? BST_CHECKED : BST_UNCHECKED);
  431.       CheckDlgButton(dlg, IDC_R212F, r21? BST_CHECKED : BST_UNCHECKED);
  432.       CheckDlgButton(dlg, IDC_R3039, r30? BST_CHECKED : BST_UNCHECKED);
  433.       CheckDlgButton(dlg, IDC_R415A, r41? BST_CHECKED : BST_UNCHECKED);
  434.       CheckDlgButton(dlg, IDC_R617A, r61? BST_CHECKED : BST_UNCHECKED);
  435.       CheckDlgButton(dlg, IDC_R809F, r80? BST_CHECKED : BST_UNCHECKED);
  436.       CheckDlgButton(dlg, IDC_RA0AF, rae? BST_CHECKED : BST_UNCHECKED);
  437.       CheckDlgButton(dlg, IDC_RF0F1, rf0? BST_CHECKED : BST_UNCHECKED);
  438.       CheckDlgButton(dlg, IDC_ROTH2, roth? BST_CHECKED : BST_UNCHECKED);
  439.       SendDlgItemMessage(dlg, IDC_FONTSIZE, CB_ADDSTRING, 0, (LPARAM)"5 pixels");
  440.       SendDlgItemMessage(dlg, IDC_FONTSIZE, CB_ADDSTRING, 0, (LPARAM)"6 pixels");
  441.       SendDlgItemMessage(dlg, IDC_FONTSIZE, CB_ADDSTRING, 0, (LPARAM)"7 pixels");
  442.       SendDlgItemMessage(dlg, IDC_FONTSIZE, CB_ADDSTRING, 0, (LPARAM)"8 pixels");
  443.       SendDlgItemMessage(dlg, IDC_FONTSIZE, CB_SETCURSEL, fontsize-5, 0);
  444.       set_data(dlg);
  445.       update_rmask();
  446.       block_font_dialog = 0;
  447.       return 1;
  448.    }
  449.  
  450.    if (msg == WM_PAINT) { paint_font(dlg, 1); return 1; }
  451.    if (msg == WM_SYSCOMMAND && (wp & 0xFFF0) == SC_CLOSE) EndDialog(dlg, 0);
  452.  
  453.    if (block_font_dialog) return 0;
  454.  
  455.    if (msg == WM_NOTIFY && wp == IDC_SPIN) {
  456.       char ln[64]; GetDlgItemText(dlg, IDE_ADDRESS, ln, sizeof ln);
  457.       sscanf(ln, "%X", &font_address);
  458.       font_address += ((LPNMUPDOWN)lp)->iDelta * (x100? 0x100 : 1);
  459.       font_address &= font_maxmem;
  460.       sprintf(ln, "0%04X", font_address); SetDlgItemText(dlg, IDE_ADDRESS, ln);
  461.       paint_font(dlg);
  462.       return 0;
  463.    }
  464.  
  465.    if (msg != WM_COMMAND) return 0;
  466.    unsigned id = LOWORD(wp), code = HIWORD(wp);
  467.  
  468.    if ((id == IDE_ADDRESS && code == EN_CHANGE) ||
  469.        (id == IDC_FONTSIZE && code == CBN_SELCHANGE) ||
  470.        ((id == IDC_LINEAR || id == IDC_PLANES ||
  471.          id == IDC_LEFT || id == IDC_RIGHT || id == IDC_100 ||
  472.          id == IDC_R212F || id == IDC_R3039 || id == IDC_R415A ||
  473.          id == IDC_R617A || id == IDC_R809F || id == IDC_RA0AF ||
  474.          id == IDC_RF0F1 || id == IDC_ROTH2) && code == BN_CLICKED))
  475.    {
  476.       get_ranges(dlg);
  477.       paint_font(dlg);
  478.    }
  479.  
  480.    if (id == IDC_FILE) FontFromFile(dlg);
  481.    if (id == IDC_FIND) fnt_search(dlg);
  482.    if (id == IDCANCEL) EndDialog(dlg, 0);
  483.    if (id == IDOK) save_font(), EndDialog(dlg, 0);
  484.  
  485.    return 0;
  486. }
  487.  
  488. void font_setup(HWND dlg)
  489. {
  490.    DialogBox(hIn, MAKEINTRESOURCE(IDD_FONTS), dlg, fonts_dlg);
  491. }
  492. #endif // MOD_SETTINGS
  493.