Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. #include "std.h"
  2.  
  3. #include <io.h>
  4. #include <fcntl.h>
  5. #include <sys/stat.h>
  6.  
  7. #include "resource.h"
  8. #include "emul.h"
  9. #include "vars.h"
  10. #include "config.h"
  11. #include "draw.h"
  12. #include "dx.h"
  13. #include "dxrend.h"
  14. #include "dxr_advm.h"
  15. #include "dxr_rsm.h"
  16. #include "fntsrch.h"
  17. #include "tape.h"
  18. #include "snapshot.h"
  19. #include "leds.h"
  20. #include "sdcard.h"
  21. #include "zc.h"
  22. #include "gs.h"
  23. #include "gui.h"
  24.  
  25. #include "util.h"
  26.  
  27.  
  28. //=============================================================================
  29. void setcheck(int ID, unsigned char state)
  30. {
  31.    CheckDlgButton( dlg, ID, state ? BST_CHECKED : BST_UNCHECKED);
  32. }
  33. //=============================================================================
  34. unsigned char getcheck(int ID)
  35. {
  36.    return (IsDlgButtonChecked(dlg, ID) == BST_CHECKED);
  37. }
  38. //=============================================================================
  39.  
  40. #ifdef MOD_SETTINGS
  41.  
  42. static CONFIG c1;
  43. static char dlgok = 0;
  44.  
  45. const char *lastpage;
  46.  
  47. static char rset_list[0x800];
  48.  
  49. //=============================================================================
  50. static char compare_rset(char *rname)
  51. {
  52.    CONFIG c2; load_romset(&c2, rname);
  53.    if (stricmp(c2.sos_rom_path, c1.sos_rom_path)) return 0;
  54.    if (stricmp(c2.dos_rom_path, c1.dos_rom_path)) return 0;
  55.    if (stricmp(c2.sys_rom_path, c1.sys_rom_path)) return 0;
  56.    if (stricmp(c2.zx128_rom_path, c1.zx128_rom_path)) return 0;
  57.    return 1;
  58. }
  59. //=============================================================================
  60.  
  61.  
  62. //=============================================================================
  63. static void find_romset()
  64. {
  65.    HWND box = GetDlgItem(dlg, IDC_ROMSET); int cur = -1, i = 0;
  66.    for (char *dst = rset_list; *dst; dst += strlen(dst)+1, i++)
  67.       if (compare_rset(dst)) cur = i;
  68.    SendMessage(box, CB_SETCURSEL, cur, 0);
  69. }
  70. //=============================================================================
  71.  
  72.  
  73. //=============================================================================
  74. static char select_romfile(char *dstname)
  75. {
  76.    char fname[FILENAME_MAX];
  77.    fname[0] = 0;
  78. /*
  79.    strcpy(fname, dstname);
  80.    char *x = strrchr(fname+2, ':');
  81.    if(x)
  82.        *x = 0;
  83. */
  84.    OPENFILENAME ofn = { };
  85.    ofn.lStructSize = (WinVerMajor < 5) ? OPENFILENAME_SIZE_VERSION_400 : sizeof(OPENFILENAME);
  86.    ofn.hwndOwner = dlg;
  87.    ofn.lpstrFilter = "ROM image (*.ROM)\0*.ROM\0All files\0*.*\0";
  88.    ofn.lpstrFile = fname;
  89.    ofn.nMaxFile = _countof(fname);
  90.    ofn.lpstrTitle = "Select ROM";
  91.    ofn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | OFN_HIDEREADONLY;
  92.    ofn.lpstrInitialDir   = temp.RomDir;
  93.    if (!GetOpenFileName(&ofn))
  94.        return 0;
  95.    strcpy(dstname, fname);
  96.    strcpy(temp.RomDir, ofn.lpstrFile);
  97.    char *Ptr = strrchr(temp.RomDir, '\\');
  98.    if(Ptr)
  99.     *Ptr = 0;
  100.    return 1;
  101. }
  102. //=============================================================================
  103.  
  104.  
  105. //=============================================================================
  106. static char *MemDlg_get_bigrom()
  107. {
  108.    if (c1.mem_model == MM_ATM450) return c1.atm1_rom_path;
  109.    if (c1.mem_model == MM_ATM710) return c1.atm2_rom_path;
  110.    if (c1.mem_model == MM_ATM3) return c1.atm3_rom_path;
  111.    if (c1.mem_model == MM_PROFI) return c1.profi_rom_path;
  112.    if (c1.mem_model == MM_SCORP) return c1.scorp_rom_path;
  113.    if (c1.mem_model == MM_PROFSCORP) return c1.prof_rom_path;
  114.  //[vv] kay-1024 эх шьхы ёЄрэфрЁЄэющ Ёрёъырфъш ╧╟╙ (Ёрёъырфър яхЁхъы■ўрырё№ фцрьяхЁюь J5)
  115. //   if (c1.mem_model == MM_KAY) return c1.kay_rom_path;
  116.    if (c1.mem_model == MM_PLUS3) return c1.plus3_rom_path;
  117.    if (c1.mem_model == MM_QUORUM) return c1.quorum_rom_path;
  118.    return nullptr;
  119. }
  120. //=============================================================================
  121.  
  122.  
  123. //=============================================================================
  124. static void change_rompage(int dx, int reload)
  125. {
  126.    int x = int(SendDlgItemMessage(dlg, IDC_ROMPAGE, CB_GETCURSEL, 0, 0));
  127.    static char *pgs[] = { c1.sos_rom_path, c1.zx128_rom_path, c1.dos_rom_path, c1.sys_rom_path };
  128.    char *ptr = pgs[x];
  129.    if (reload)
  130.        select_romfile(ptr);
  131.    if (dx) {
  132.       char *x = strrchr(ptr+2, ':');
  133.       unsigned pg = 0;
  134.       if (!x) x = ptr + strlen(ptr); else { *x = 0; pg = unsigned(atoi(x+1)); }
  135.       FILE *ff = fopen(ptr, "rb");
  136.       long sz = 0;
  137.       if(ff)
  138.       {
  139.           fseek(ff, 0, SEEK_END);
  140.           sz = ftell(ff) / PAGE;
  141.           fclose(ff);
  142.       }
  143.       if ((int(pg)+dx) < sz) {
  144.          pg = unsigned(int(pg) + dx);
  145.          SendDlgItemMessage(dlg, IDC_ROMSET, CB_SETCURSEL, 0, 0);
  146.       }
  147.       sprintf(x, ":%u", pg);
  148.    }
  149.    SendDlgItemMessage(dlg, IDE_ROMNAME, WM_SETTEXT, 0, (LPARAM)ptr);
  150.    find_romset();
  151. }
  152. //=============================================================================
  153.  
  154.  
  155. //=============================================================================
  156. static void change_rombank(int dx, int reload)
  157. {
  158.    char *romname = MemDlg_get_bigrom();
  159.  
  160.    char line[512];
  161.  
  162.    strcpy(line, romname);
  163.  
  164.    char *x = strrchr(line+2, ':');
  165.  
  166.    unsigned pg = 0;
  167.    if (!x)
  168.        x = line + strlen(line);
  169.    else
  170.    {
  171.        *x = 0;
  172.        pg = unsigned(atoi(x+1));
  173.    }
  174.  
  175.    if (reload)
  176.    {
  177.        if (!select_romfile(line))
  178.            return;
  179.        x = line + strlen(line);
  180.    }
  181.  
  182.    FILE *ff = fopen(line, "rb");
  183.    long sz = 0;
  184.    if (ff)
  185.    {
  186.        fseek(ff, 0, SEEK_END);
  187.        sz = ftell(ff);
  188.        fclose(ff);
  189.    }
  190.    
  191.    if (!sz || (sz & 0xFFFF))
  192.    {
  193.        err: MessageBox(dlg, "Invalid ROM size", "error", MB_ICONERROR | MB_OK);
  194.        return;
  195.    }
  196.  
  197.    sz /= 1024;
  198.  
  199.    if ((c1.mem_model == MM_SCORP || c1.mem_model == MM_PROFI || c1.mem_model == MM_KAY) && sz != 64)
  200.        goto err;
  201.    if ((c1.mem_model == MM_ATM710 || c1.mem_model == MM_ATM3) && sz != 64 && sz != 128 && sz != 256 && sz != 512 && sz != 1024)
  202.        goto err;
  203.    if (c1.mem_model == MM_PROFSCORP && sz != 128 && sz != 256 && sz != 512 && sz != 1024)
  204.        goto err;
  205.  
  206.    if ((int(pg)+dx) < sz/256)
  207.        pg = unsigned(int(pg) + dx);
  208.    if (sz > 256)
  209.        sprintf(x, ":%u", pg);
  210.    strcpy(romname, line);
  211.    SendDlgItemMessage(dlg, IDE_BIGROM, WM_SETTEXT, 0, (LPARAM)romname);
  212.  
  213.    sprintf(line, "Loaded ROM size: %ldK", sz);
  214.    if (c1.mem_model == MM_PROFSCORP && sz > 256)
  215.        sprintf(line, "Loaded ROM size: %ld*256K", sz/256);
  216.    SetDlgItemText(dlg, IDC_TOTAL_ROM, line);
  217.    ShowWindow(GetDlgItem(dlg, IDC_TOTAL_ROM), SW_SHOW);
  218. }
  219. //=============================================================================
  220.  
  221. //=============================================================================
  222. static void reload_roms()
  223. {
  224.    unsigned i = 0, n = unsigned(SendDlgItemMessage(dlg, IDC_ROMSET, CB_GETCURSEL, 0, 0));
  225.    char *dst; //Alone Coder 0.36.7
  226.    for (/*char * */dst = rset_list; *dst && i < n; i++, dst += strlen(dst)+1);
  227.    if (!*dst) return;
  228.    load_romset(&c1, dst);
  229.    change_rompage(0,0);
  230. }
  231. //=============================================================================
  232.  
  233.  
  234. //=============================================================================
  235. static void MemDlg_set_visible()
  236. {
  237.    int vis = !c1.use_romset? SW_SHOW : SW_HIDE;
  238.    ShowWindow(GetDlgItem(dlg, IDE_BIGROM), vis);
  239.    ShowWindow(GetDlgItem(dlg, IDB_ROMSEL_S), vis);
  240.    if (c1.mem_model != MM_PROFSCORP) vis = SW_HIDE; // todo: scorp+smuc
  241.    ShowWindow(GetDlgItem(dlg, IDC_FILEBANK), vis);
  242.    vis = c1.use_romset? SW_SHOW : SW_HIDE;
  243.    ShowWindow(GetDlgItem(dlg, IDC_ROMSET), vis);
  244.    ShowWindow(GetDlgItem(dlg, IDC_ROMPAGE), vis);
  245.    ShowWindow(GetDlgItem(dlg, IDE_ROMNAME), vis);
  246.    ShowWindow(GetDlgItem(dlg, IDC_FILEPAGE), vis);
  247.    ShowWindow(GetDlgItem(dlg, IDB_ROMSEL_P), vis);
  248.    ShowWindow(GetDlgItem(dlg, IDC_TOTAL_ROM), SW_HIDE);
  249. }
  250. //=============================================================================
  251.  
  252.  
  253. //=============================================================================
  254. static void mem_set_sizes()
  255. {
  256.    unsigned mems = mem_model[c1.mem_model].availRAMs;
  257.    unsigned best = mem_model[c1.mem_model].defaultRAM;
  258.  
  259.    EnableWindow(GetDlgItem(dlg, IDC_RAM128),  (mems & RAM_128)?  1:0);
  260.    EnableWindow(GetDlgItem(dlg, IDC_RAM256),  (mems & RAM_256)?  1:0);
  261.    EnableWindow(GetDlgItem(dlg, IDC_RAM512),  (mems & RAM_512)?  1:0);
  262.    EnableWindow(GetDlgItem(dlg, IDC_RAM1024), (mems & RAM_1024)? 1:0);
  263.    EnableWindow(GetDlgItem(dlg, IDC_RAM4096), (mems & RAM_4096)? 1:0);
  264.  
  265.    char ok = 1;
  266.    if (getcheck(IDC_RAM128) && !(mems & RAM_128))  ok = 0;
  267.    if (getcheck(IDC_RAM256) && !(mems & RAM_256))  ok = 0;
  268.    if (getcheck(IDC_RAM512) && !(mems & RAM_512))  ok = 0;
  269.    if (getcheck(IDC_RAM1024)&& !(mems & RAM_1024)) ok = 0;
  270.    if (getcheck(IDC_RAM4096)&& !(mems & RAM_4096)) ok = 0;
  271.  
  272.    if (!ok) {
  273.       setcheck(IDC_RAM128, 0);
  274.       setcheck(IDC_RAM256, 0);
  275.       setcheck(IDC_RAM512, 0);
  276.       setcheck(IDC_RAM1024,0);
  277.       setcheck(IDC_RAM4096,0);
  278.       if (best == 128) setcheck(IDC_RAM128);
  279.       if (best == 256) setcheck(IDC_RAM256);
  280.       if (best == 512) setcheck(IDC_RAM512);
  281.       if (best == 1024)setcheck(IDC_RAM1024);
  282.       if (best == 4096)setcheck(IDC_RAM4096);
  283.    }
  284.  
  285.    char *romname = MemDlg_get_bigrom();
  286.    EnableWindow(GetDlgItem(dlg, IDC_SINGLE_ROM), romname? 1 : 0);
  287.    if (romname) SetDlgItemText(dlg, IDE_BIGROM, romname);
  288.    else
  289.    {
  290.        c1.use_romset = 1;
  291.        setcheck(IDC_CUSTOM_ROM, 1);
  292.        setcheck(IDC_SINGLE_ROM, 0);
  293.    }
  294.  
  295.    int cache_ok = (c1.mem_model == MM_ATM450)? 0 : 1;
  296.    EnableWindow(GetDlgItem(dlg, IDC_CACHE0), cache_ok);
  297.    EnableWindow(GetDlgItem(dlg, IDC_CACHE16), cache_ok);
  298.    EnableWindow(GetDlgItem(dlg, IDC_CACHE32), cache_ok);
  299.  
  300.    MemDlg_set_visible();
  301. }
  302. //=============================================================================
  303.  
  304.  
  305. //=============================================================================
  306. static INT_PTR CALLBACK MemDlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  307. {
  308.    ::dlg = dlg; char bf[0x800];
  309.    static char lock = 0;
  310.  
  311.    if (msg == WM_INITDIALOG) {
  312.       HWND box = GetDlgItem(dlg, IDC_MEM);
  313.       for (unsigned i = 0; i < N_MM_MODELS; i++)
  314.          SendMessage(box, CB_ADDSTRING, 0, (LPARAM)mem_model[i].fullname);
  315.  
  316.       box = GetDlgItem(dlg, IDC_ROMPAGE);
  317.       SendMessage(box, CB_ADDSTRING, 0, (LPARAM)"BASIC48");
  318.       SendMessage(box, CB_ADDSTRING, 0, (LPARAM)"BASIC128");
  319.       SendMessage(box, CB_ADDSTRING, 0, (LPARAM)"TR-DOS");
  320.       SendMessage(box, CB_ADDSTRING, 0, (LPARAM)"SERVICE");
  321.       SendMessage(box, CB_SETCURSEL, 0, 0);
  322.  
  323.       GetPrivateProfileSectionNames(bf, sizeof bf, ininame);
  324.       box = GetDlgItem(dlg, IDC_ROMSET);
  325.       char *dst = rset_list;
  326.       for (char *p = bf; *p; p += strlen(p)+1) {
  327.          if ((*(unsigned*)p | 0x20202020) != WORD4('r','o','m','.')) continue;
  328.          strcpy(dst, p+4); dst += strlen(dst)+1;
  329.          char line[128]; GetPrivateProfileString(p, "title", p+4, line, sizeof line, ininame);
  330.                 string_comment_trimmer(line); //юсЁхчър ыш°эхую //NS
  331.                 //printf("title <%s>\n",line);
  332.          SendMessage(box, CB_ADDSTRING, 0, (LPARAM)line);
  333.       }
  334.       *dst = 0;
  335.    }
  336.    if (!lock && msg == WM_COMMAND) {
  337.       unsigned id = LOWORD(wp), code = HIWORD(wp);
  338.       if (code == BN_CLICKED) {
  339.           if(id == IDC_SINGLE_ROM)
  340.           {
  341.               c1.use_romset = 0;
  342.               MemDlg_set_visible();
  343.           }
  344.           if(id == IDC_CUSTOM_ROM)
  345.           {
  346.               c1.use_romset = 1;
  347.               MemDlg_set_visible();
  348.           }
  349.          if (id == IDB_ROMSEL_P) change_rompage(0,1);
  350.          if (id == IDB_ROMSEL_S) change_rombank(0,1);
  351.       }
  352.       if (code == CBN_SELCHANGE) {
  353.          if (id == IDC_ROMSET) reload_roms();
  354.          if (id == IDC_ROMPAGE) change_rompage(0,0);
  355.          if(id == IDC_MEM)
  356.          {
  357.              c1.mem_model = (MEM_MODEL)SendDlgItemMessage(dlg, IDC_MEM, CB_GETCURSEL, 0, 0);
  358.              lock = 1;
  359.              mem_set_sizes();
  360.              lock = 0;
  361.          }
  362.       }
  363.       return 1;
  364.    }
  365.    if (msg != WM_NOTIFY) return 0;
  366.    NM_UPDOWN *nud = (NM_UPDOWN*)lp;
  367.    if (nud->hdr.code == UDN_DELTAPOS) {
  368.       if (wp == IDC_FILEPAGE) change_rompage(nud->iDelta > 0 ? 1 : -1, 0);
  369.       if (wp == IDC_FILEBANK) change_rombank(nud->iDelta > 0 ? 1 : -1, 0);
  370.       return TRUE; // don't chage up-down state
  371.    }
  372.    NMHDR *nm = (NMHDR*)lp;
  373.    if (nm->code == PSN_KILLACTIVE) {
  374.       if (getcheck(IDC_CACHE0)) c1.cache = 0;
  375.       if (getcheck(IDC_CACHE16)) c1.cache = 16;
  376.       if (getcheck(IDC_CACHE32)) c1.cache = 32;
  377.  
  378.       if (getcheck(IDC_CMOS_NONE)) c1.cmos = 0;
  379.       if (getcheck(IDC_CMOS_DALLAS)) c1.cmos = 1;
  380.       if (getcheck(IDC_CMOS_RUS)) c1.cmos = 2;
  381.  
  382.       if (getcheck(IDC_RAM128)) c1.ramsize = 128;
  383.       if (getcheck(IDC_RAM256)) c1.ramsize = 256;
  384.       if (getcheck(IDC_RAM512)) c1.ramsize = 512;
  385.       if (getcheck(IDC_RAM1024))c1.ramsize = 1024;
  386.       if (getcheck(IDC_RAM4096))c1.ramsize = 4096;
  387.  
  388.       c1.smuc = getcheck(IDC_SMUC);
  389.    }
  390.    if (nm->code == PSN_SETACTIVE) {
  391.       lock = 1;
  392.       SendDlgItemMessage(dlg, IDC_MEM, CB_SETCURSEL, c1.mem_model, 0);
  393.       setcheck(IDC_RAM128, (c1.ramsize == 128));
  394.       setcheck(IDC_RAM256, (c1.ramsize == 256));
  395.       setcheck(IDC_RAM512, (c1.ramsize == 512));
  396.       setcheck(IDC_RAM1024,(c1.ramsize == 1024));
  397.       setcheck(IDC_RAM4096,(c1.ramsize == 4096));
  398.       setcheck(IDC_SINGLE_ROM, !c1.use_romset);
  399.       setcheck(IDC_CUSTOM_ROM, c1.use_romset);
  400.       find_romset();
  401.  
  402.       setcheck(IDC_CACHE0,  (c1.cache == 0));
  403.       setcheck(IDC_CACHE16, (c1.cache == 16));
  404.       setcheck(IDC_CACHE32, (c1.cache == 32));
  405.  
  406.       setcheck(IDC_CMOS_NONE, (c1.cmos == 0));
  407.       setcheck(IDC_CMOS_DALLAS, (c1.cmos == 1));
  408.       setcheck(IDC_CMOS_RUS, (c1.cmos == 2));
  409.  
  410.       setcheck(IDC_SMUC, c1.smuc);
  411.  
  412.       mem_set_sizes();
  413.       lock = 0;
  414.  
  415.       lastpage = "MEMORY";
  416.    }
  417.    if (nm->code == PSN_APPLY) dlgok = 1;
  418.    if (nm->code == PSN_RESET) dlgok = 0;
  419.    return 1;
  420. }
  421. //=============================================================================
  422. static int getint(int ID) {
  423.    HWND wnd = GetDlgItem(dlg, ID);
  424.    char bf[64]; SendMessage(wnd, WM_GETTEXT, sizeof bf, (LPARAM)bf);
  425.    return atoi(bf);
  426. }
  427. //=============================================================================
  428. static void setint(int ID, int num) {
  429.    HWND wnd = GetDlgItem(dlg, ID);
  430.    char bf[64]; sprintf(bf, "%d", num);
  431.    SendMessage(wnd, WM_SETTEXT, 0, (LPARAM)bf);
  432. }
  433. //=============================================================================
  434.  
  435.  
  436. //=============================================================================
  437. static INT_PTR CALLBACK UlaDlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  438. {
  439.    ::dlg = dlg;
  440.    NMHDR *nm = (NMHDR*)lp;
  441.    static volatile char block=0;
  442.    if (msg == WM_INITDIALOG) {
  443.       HWND box = GetDlgItem(dlg, IDC_ULAPRESET);
  444.       for (unsigned i = 0; i < num_ula; i++)
  445.          SendMessage(box, CB_ADDSTRING, 0, (LPARAM)ulapreset[i]);
  446.       SendMessage(box, CB_ADDSTRING, 0, (LPARAM)"<custom>");
  447.    }
  448.    if (msg == WM_COMMAND && !block) {
  449.       unsigned id = LOWORD(wp), code = HIWORD(wp);
  450.       if ((code == EN_CHANGE && (id==IDE_FRAME || id==IDE_LINE || id==IDE_INT || id==IDE_INT_LEN || id==IDE_PAPER))
  451.           || (code == BN_CLICKED && (id==IDC_EVENM1 || id==IDC_4TBORDER || id==IDC_FLOAT_BUS || id==IDC_FLOAT_DOS || id==IDC_PORT_FF)))
  452.       {
  453.          c1.ula_preset = u8(-1U);
  454.          SendDlgItemMessage(dlg, IDC_ULAPRESET, CB_SETCURSEL, num_ula, 0);
  455.       }
  456.       if (code == CBN_SELCHANGE) {
  457.          if (id == IDC_ULAPRESET) {
  458.             unsigned pre = unsigned(SendDlgItemMessage(dlg, IDC_ULAPRESET, CB_GETCURSEL, 0, 0));
  459.             if (pre == num_ula) pre = -1U;
  460.             c1.ula_preset = (unsigned char)pre;
  461.             if (pre == -1U) return 1;
  462.             CONFIG tmp = conf;
  463.             conf.ula_preset = (unsigned char)pre; load_ula_preset();
  464.             c1.frame = /*conf.frame*/frametime/*Alone Coder*/;
  465.             c1.intfq = conf.intfq;
  466.             c1.intlen = conf.intlen;
  467.             c1.t_line = conf.t_line;
  468.             c1.paper = conf.paper;
  469.             c1.even_M1 = conf.even_M1;
  470.             c1.border_4T = conf.border_4T;
  471.             c1.floatbus = conf.floatbus;
  472.             c1.floatdos = conf.floatdos;
  473.             c1.portff = conf.portff;
  474.             conf = tmp;
  475.             goto refresh;
  476.          }
  477.       }
  478.       return 1;
  479.    }
  480.    if (msg != WM_NOTIFY) return 0;
  481.    if (nm->code == PSN_KILLACTIVE) {
  482.       c1.frame = unsigned(getint(IDE_FRAME));
  483.       c1.t_line = unsigned(getint(IDE_LINE));
  484.       c1.paper = unsigned(getint(IDE_PAPER));
  485.       c1.intfq = unsigned(getint(IDE_INT));
  486.       c1.intlen = unsigned(getint(IDE_INT_LEN));
  487.       c1.nopaper = unsigned(getcheck(IDC_NOPAPER));
  488.       c1.even_M1 = getcheck(IDC_EVENM1);
  489.       c1.border_4T = getcheck(IDC_4TBORDER);
  490.       c1.floatbus = getcheck(IDC_FLOAT_BUS);
  491.       c1.floatdos = getcheck(IDC_FLOAT_DOS);
  492.       c1.portff = getcheck(IDC_PORT_FF) != 0;
  493.       if(c1.mem_model == MM_PROFI)
  494.       {
  495.            c1.profi_monochrome = getcheck(IDC_PROFI_MONOCHROME);
  496.       }
  497.       if (c1.mem_model == MM_ATM710 || c1.mem_model == MM_ATM3 || c1.mem_model == MM_ATM450 || c1.mem_model == MM_PROFI)
  498.       {
  499.           c1.use_comp_pal = getcheck(IDC_ATMPAL);
  500.       }
  501.       if (c1.mem_model == MM_ATM710 || c1.mem_model == MM_ATM3 || c1.mem_model == MM_ATM450)
  502.       {
  503.          c1.atm.mem_swap = getcheck(IDC_ATM_SWAP);
  504.       }
  505.       c1.ula_plus = getcheck(IDC_ULA_PLUS);
  506.    }
  507.    if (nm->code == PSN_SETACTIVE) {
  508. refresh:
  509.       SendDlgItemMessage(dlg, IDC_ULAPRESET, CB_SETCURSEL, c1.ula_preset<num_ula? c1.ula_preset : num_ula, 0);
  510.       block=1;
  511.       setint(IDE_FRAME, int(c1.frame));
  512.       setint(IDE_LINE, int(c1.t_line));
  513.       setint(IDE_PAPER, int(c1.paper));
  514.       setint(IDE_INT, int(c1.intfq));
  515.       setint(IDE_INT_LEN, int(c1.intlen));
  516.       setcheck(IDC_NOPAPER, u8(c1.nopaper));
  517.       setcheck(IDC_EVENM1, c1.even_M1);
  518.       setcheck(IDC_4TBORDER, c1.border_4T);
  519.       setcheck(IDC_FLOAT_BUS, c1.floatbus);
  520.       setcheck(IDC_FLOAT_DOS, c1.floatdos);
  521.       setcheck(IDC_PORT_FF, c1.portff);
  522.  
  523.       BOOL en_atm =  (c1.mem_model == MM_ATM710 || c1.mem_model == MM_ATM3 || c1.mem_model == MM_ATM450);
  524.       BOOL en_profi =  (c1.mem_model == MM_PROFI);
  525.       EnableWindow(GetDlgItem(dlg, IDC_ATM_SWAP), en_atm);
  526.       EnableWindow(GetDlgItem(dlg, IDC_PROFI_MONOCHROME), en_profi);
  527.       EnableWindow(GetDlgItem(dlg, IDC_ATMPAL), en_atm || en_profi);
  528.       setcheck(IDC_PROFI_MONOCHROME, en_profi ? c1.profi_monochrome : 0);
  529.       setcheck(IDC_ATM_SWAP, en_atm ? c1.atm.mem_swap : 0);
  530.       setcheck(IDC_ATMPAL, (en_atm || en_profi) ? c1.use_comp_pal : 0);
  531.       setcheck(IDC_ULA_PLUS, c1.ula_plus);
  532.  
  533.       block=0;
  534.       lastpage = "ULA";
  535.       return 1;
  536.    }
  537.    if (nm->code == PSN_APPLY) dlgok = 1;
  538.    if (nm->code == PSN_RESET) dlgok = 0;
  539.    return 1;
  540. }
  541. //=============================================================================
  542.  
  543.  
  544. //=============================================================================
  545. static void HddDlg_set_active()
  546. {
  547.    int enable = (c1.ide_scheme != 0);
  548.    EnableWindow(GetDlgItem(dlg, IDB_HDD0), enable);
  549.    EnableWindow(GetDlgItem(dlg, IDE_HDD0_CHS), enable);
  550.    EnableWindow(GetDlgItem(dlg, IDE_HDD0_LBA), enable);
  551.    EnableWindow(GetDlgItem(dlg, IDC_HDD0_RO), enable);
  552.    EnableWindow(GetDlgItem(dlg, IDB_HDD1), enable);
  553.    EnableWindow(GetDlgItem(dlg, IDE_HDD1_CHS), enable);
  554.    EnableWindow(GetDlgItem(dlg, IDE_HDD1_LBA), enable);
  555.    EnableWindow(GetDlgItem(dlg, IDC_HDD1_RO), enable);
  556.    if (!enable) return;
  557. }
  558. //=============================================================================
  559.  
  560.  
  561. //=============================================================================
  562. static void HddDlg_show_info(int device)
  563. {
  564.    unsigned c = c1.ide[device].c, h = c1.ide[device].h, s = c1.ide[device].s;
  565.    u64 l = c1.ide[device].lba;
  566.    DWORD readonly = 0;
  567.    if (!*c1.ide[device].image) readonly = 1;
  568.    if (*c1.ide[device].image == '<') {
  569.       unsigned drive = find_hdd_device(c1.ide[device].image);
  570.       if (drive < MAX_PHYS_HD_DRIVES + MAX_PHYS_CD_DRIVES) {
  571.          c = ((unsigned short*)phys[drive].idsector)[1];
  572.          h = ((unsigned short*)phys[drive].idsector)[3];
  573.          s = ((unsigned short*)phys[drive].idsector)[6];
  574.          l = *(unsigned*)(phys[drive].idsector+60*2); // lba28
  575.          if(*((u16*)(phys[drive].idsector+83*2)) & (1<<10))
  576.          {
  577.              l = *(u64*)(phys[drive].idsector+100*2); // lba48
  578.          }
  579.          if (!l) l = c*h*s;
  580.          readonly = 1;
  581.       }
  582.    }
  583.    HWND edit_l = GetDlgItem(dlg, device? IDE_HDD1_LBA : IDE_HDD0_LBA);
  584.    HWND edit_c = GetDlgItem(dlg, device? IDE_HDD1_CHS : IDE_HDD0_CHS);
  585.    SendMessage(edit_l, EM_SETREADONLY, readonly, 0);
  586.    SendMessage(edit_c, EM_SETREADONLY, readonly, 0);
  587.  
  588.    SetDlgItemText(dlg, device? IDE_HDD1 : IDE_HDD0, c1.ide[device].image);
  589.    char textbuf[512];
  590.    *textbuf = 0; if (*c1.ide[device].image) sprintf(textbuf, "%I64u", l);
  591.    SetWindowText(edit_l, textbuf);
  592.    *textbuf = 0; if (*c1.ide[device].image) sprintf(textbuf, "%u/%u/%u", c,h,s);
  593.    SetWindowText(edit_c, textbuf);
  594. }
  595. //=============================================================================
  596.  
  597.  
  598. //=============================================================================
  599. static void HddDlg_select_image(int device)
  600. {
  601.    HMENU selmenu = CreatePopupMenu();
  602.    AppendMenu(selmenu, MF_STRING, 1, "Select image file...");
  603.    AppendMenu(selmenu, MF_STRING, 2, "Remove device");
  604.    unsigned max, drive; char textbuf[512];
  605.    for (max = drive = 0; drive < n_phys; drive++) {
  606.  
  607.       if (phys[drive].type == ATA_NTHDD)
  608.          sprintf(textbuf, "HDD %u: %s, %u Mb", phys[drive].spti_id, phys[drive].viewname, phys[drive].hdd_size / (2*1024));
  609.  
  610.       else if (phys[drive].type == ATA_SPTI_CD)
  611.          sprintf(textbuf, "CD-ROM %u: %s", phys[drive].spti_id, phys[drive].viewname);
  612.  
  613.       else if (phys[drive].type == ATA_ASPI_CD)
  614.          sprintf(textbuf, "CD-ROM %u.%u: %s", phys[drive].adapterid, phys[drive].targetid, phys[drive].viewname);
  615.  
  616.       else continue;
  617.  
  618.       if (!max) AppendMenu(selmenu, MF_SEPARATOR, 0, nullptr);
  619.       max++;
  620.       AppendMenu(selmenu, MF_STRING, drive + 8, textbuf);
  621.    }
  622.  
  623.    RECT rc; GetWindowRect(GetDlgItem(dlg, device? IDB_HDD1 : IDB_HDD0), &rc);
  624.    int code = TrackPopupMenu(selmenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTBUTTON, rc.left, rc.bottom, 0, dlg, nullptr);
  625.    DestroyMenu(selmenu);
  626.    if (!code) return;
  627.  
  628.    if (code == 2) { // remove
  629.       *c1.ide[device].image = 0;
  630.       HddDlg_show_info(device);
  631.       return;
  632.    }
  633.  
  634.    if (code >= 8)
  635.    { // physical device
  636.       if(MessageBox(dlg, "All volumes on drive will be dismounted\n", "Warning",
  637.           MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2) != IDYES)
  638.           return;
  639.       strcpy(c1.ide[device].image, phys[code-8].viewname);
  640.       HddDlg_show_info(device);
  641.       return;
  642.    }
  643.  
  644.    // open HDD image
  645.    OPENFILENAME fn = { };
  646. /*
  647.    strcpy(textbuf, c1.ide[device].image);
  648.    if (textbuf[0] == '<') *textbuf = 0;
  649. */
  650.    textbuf[0] = 0;
  651.    fn.lStructSize = (WinVerMajor < 5) ? OPENFILENAME_SIZE_VERSION_400 : sizeof(OPENFILENAME);
  652.    fn.hwndOwner = dlg;
  653.    fn.lpstrFilter = "Hard disk drive image (*.HDD)\0*.HDD\0";
  654.    fn.lpstrFile = textbuf;
  655.    fn.nMaxFile = _countof(textbuf);
  656.    fn.lpstrTitle = "Select image file for HDD emulator";
  657.    fn.Flags = OFN_CREATEPROMPT | OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
  658.    fn.lpstrInitialDir   = temp.HddDir;
  659.    if (!GetOpenFileName(&fn))
  660.        return;
  661.    strcpy(temp.HddDir, fn.lpstrFile);
  662.    char *Ptr = strrchr(temp.HddDir, '\\');
  663.    if(Ptr)
  664.     *Ptr = 0;
  665.  
  666.    int file = open(textbuf, O_RDONLY | O_BINARY, S_IREAD);
  667.    if(file < 0)
  668.        return;
  669.    __int64 sz = _filelengthi64(file);
  670.    close(file);
  671.  
  672.    strcpy(c1.ide[device].image, textbuf);
  673.    c1.ide[device].c = 0;
  674.    c1.ide[device].h = 0;
  675.    c1.ide[device].s = 0;
  676.    c1.ide[device].lba = unsigned(sz / 512);
  677.    HddDlg_show_info(device);
  678. }
  679. //=============================================================================
  680.  
  681.  
  682. //=============================================================================
  683. static void HddDlg_show_size(unsigned id, unsigned sectors)
  684. {
  685.    unsigned __int64 sz = ((unsigned __int64)sectors) << 9;
  686.    char num[64]; int ptr = 0, tri = 0;
  687.    for (;;) {
  688.       num[ptr++] = char((unsigned char)(sz % 10) + '0');
  689.       sz /= 10; if (!sz) break;
  690.       if(++tri == 3)
  691.       {
  692.           num[ptr++] = ',';
  693.           tri = 0;
  694.       }
  695.    }
  696.    char dst[64]; dst[0] = '-'; dst[1] = ' ';
  697.    int k; //Alone Coder 0.36.7
  698.    for (/*int*/ k = 2; ptr; k++) dst[k] = num[--ptr];
  699.    strcpy(dst+k, " bytes");
  700.    SetDlgItemText(dlg, id, dst);
  701. }
  702. //=============================================================================
  703.  
  704.  
  705. //=============================================================================
  706. static INT_PTR CALLBACK HddDlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  707. {
  708.    ::dlg = dlg;
  709.    NMHDR *nm = (NMHDR*)lp;
  710.    static volatile char block=0;
  711.    if (msg == WM_INITDIALOG)
  712.    {
  713.       HWND box = GetDlgItem(dlg, IDC_IDESCHEME);
  714.       ComboBox_AddString(box, "NONE");
  715.       ComboBox_AddString(box, "ATM");
  716.       ComboBox_AddString(box, "NEMO");
  717.       ComboBox_AddString(box, "NEMO (A8)");
  718.       ComboBox_AddString(box, "NEMO (DIVIDE)");
  719.       ComboBox_AddString(box, "SMUC");
  720.       ComboBox_AddString(box, "PROFI");
  721.       ComboBox_AddString(box, "DIVIDE");
  722.       ComboBox_SetItemData(box, 0, (LPARAM)IDE_NONE);
  723.       ComboBox_SetItemData(box, 1, (LPARAM)IDE_ATM);
  724.       ComboBox_SetItemData(box, 2, (LPARAM)IDE_NEMO);
  725.       ComboBox_SetItemData(box, 3, (LPARAM)IDE_NEMO_A8);
  726.       ComboBox_SetItemData(box, 4, (LPARAM)IDE_NEMO_DIVIDE);
  727.       ComboBox_SetItemData(box, 5, (LPARAM)IDE_SMUC);
  728.       ComboBox_SetItemData(box, 6, (LPARAM)IDE_PROFI);
  729.       ComboBox_SetItemData(box, 7, (LPARAM)IDE_DIVIDE);
  730.    }
  731.    if (msg == WM_COMMAND && !block)
  732.    {
  733.       unsigned id = LOWORD(wp), code = HIWORD(wp);
  734.       if (code == CBN_SELCHANGE && id == IDC_IDESCHEME)
  735.       {
  736.          HWND box = GetDlgItem(dlg, IDC_IDESCHEME);
  737.          int Idx = ComboBox_GetCurSel(box);
  738.          c1.ide_scheme = (IDE_SCHEME)ComboBox_GetItemData(box, Idx);
  739.          HddDlg_set_active();
  740.       }
  741.       if (id == IDB_HDD0) HddDlg_select_image(0);
  742.       if (id == IDB_HDD1) HddDlg_select_image(1);
  743.  
  744.       if (code == EN_CHANGE)
  745.       {
  746.          char bf[64]; unsigned c=0, h=0, s=0, l=0;
  747.          GetWindowText((HWND)lp, bf, sizeof bf);
  748.          sscanf(bf, "%u/%u/%u", &c, &h, &s);
  749.          sscanf(bf, "%u", &l);
  750.          switch (id)
  751.          {
  752.             case IDE_HDD0_CHS: HddDlg_show_size(IDS_HDD0_CHS, c*h*s); break;
  753.             case IDE_HDD0_LBA: HddDlg_show_size(IDS_HDD0_LBA, l); break;
  754.             case IDE_HDD1_CHS: HddDlg_show_size(IDS_HDD1_CHS, c*h*s); break;
  755.             case IDE_HDD1_LBA: HddDlg_show_size(IDS_HDD1_LBA, l); break;
  756.          }
  757.       }
  758.  
  759.       return 1;
  760.    }
  761.    if (msg != WM_NOTIFY) return 0;
  762.    if (nm->code == PSN_KILLACTIVE) {
  763.       // ide_scheme read in CBN_SELCHANGE
  764.       // image read in 'select drive/image' button click
  765.       c1.ide[0].readonly = getcheck(IDC_HDD0_RO);
  766.       c1.ide[1].readonly = getcheck(IDC_HDD1_RO);
  767.       for (unsigned device = 0; device < 2; device++)
  768.          if (*c1.ide[device].image && *c1.ide[device].image != '<') {
  769.             char textbuf[64];
  770.             GetDlgItemText(dlg, device? IDE_HDD1_LBA : IDE_HDD0_LBA, textbuf, sizeof textbuf);
  771.             sscanf(textbuf, "%llu", &c1.ide[device].lba);
  772.             GetDlgItemText(dlg, device? IDE_HDD1_CHS : IDE_HDD0_CHS, textbuf, sizeof textbuf);
  773.             sscanf(textbuf, "%u/%u/%u", &c1.ide[device].c, &c1.ide[device].h, &c1.ide[device].s);
  774.          }
  775.  
  776.    }
  777.    if (nm->code == PSN_SETACTIVE)
  778.    {
  779.       block=1;
  780.       HWND box = GetDlgItem(dlg, IDC_IDESCHEME);
  781.       int Cnt = ComboBox_GetCount(box);
  782.       for(int i = 0; i < Cnt; i++)
  783.       {
  784.           ULONG_PTR Data = (ULONG_PTR)ComboBox_GetItemData(box, i);
  785.           if(Data == c1.ide_scheme)
  786.           {
  787.               ComboBox_SetCurSel(box, i);
  788.               break;
  789.           }
  790.       }
  791.       HddDlg_set_active();
  792.       block=0;
  793.       setcheck(IDC_HDD0_RO, c1.ide[0].readonly);
  794.       setcheck(IDC_HDD1_RO, c1.ide[1].readonly);
  795.       HddDlg_show_info(0);
  796.       HddDlg_show_info(1);
  797.       lastpage = "HDD";
  798.       return 1;
  799.    }
  800.    if (nm->code == PSN_APPLY) dlgok = 1;
  801.    if (nm->code == PSN_RESET) dlgok = 0;
  802.    return 1;
  803. }
  804. //=============================================================================
  805.  
  806.  
  807. //=============================================================================
  808. static INT_PTR CALLBACK EFF7Dlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  809. {
  810.     (void)wp;
  811.  
  812.    ::dlg = dlg;
  813.    NMHDR *nm = (NMHDR*)lp;
  814.    if (msg != WM_NOTIFY) return 0;
  815.    static int bits[] = { IDC_BIT0, IDC_BIT1, IDC_BIT2, IDC_BIT3,
  816.                          IDC_BIT4, IDC_BIT5, IDC_BIT6, IDC_BIT7 };
  817.    static int lock[] = { IDC_LOCK0, IDC_LOCK1, IDC_LOCK2, IDC_LOCK3,
  818.                          IDC_LOCK4, IDC_LOCK5, IDC_LOCK6, IDC_LOCK7 };
  819.    if (nm->code == PSN_KILLACTIVE) {
  820.       u8 mask = 0, eff7 = 0;
  821.       for (unsigned i = 0; i < 8; i++) {
  822.          if (getcheck(lock[i])) mask |= (1<<i);
  823.          if (getcheck(bits[i])) eff7 |= (1<<i);
  824.       }
  825.       c1.EFF7_mask = mask;
  826.       comp.pEFF7 = eff7;
  827.    }
  828.    if (nm->code == PSN_SETACTIVE) {
  829.       for (unsigned i = 0; i < 8; i++) {
  830.          setcheck(lock[i], c1.EFF7_mask & (1<<i));
  831.          setcheck(bits[i], comp.pEFF7 & (1<<i));
  832.       }
  833.       lastpage = "EFF7";
  834.       return 1;
  835.    }
  836.    if (nm->code == PSN_APPLY) dlgok = 1;
  837.    if (nm->code == PSN_RESET) dlgok = 0;
  838.    return 1;
  839. }
  840. //=============================================================================
  841.  
  842.  
  843. //=============================================================================
  844. static INT_PTR CALLBACK ChipDlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  845. {
  846.     (void)wp;
  847.     ::dlg = dlg;
  848.    
  849.     //-------------------------------------------------------------------------
  850.     if (msg == WM_INITDIALOG)
  851.     {
  852.         unsigned i; HWND aybox;
  853.         //---------------------------------------------------------------------
  854.         aybox = GetDlgItem(dlg, IDC_CHIP_BUS);
  855.         for (i = 0; i < SNDCHIP::CHIP_MAX; i++)
  856.             SendMessage(aybox, CB_ADDSTRING, 0, (LPARAM)SNDCHIP::get_chipname((SNDCHIP::CHIP_TYPE)i));
  857.         //---------------------------------------------------------------------
  858.         aybox = GetDlgItem(dlg, IDC_CHIP_SCHEME);
  859.         for (i = 0; i < AY_SCHEME_MAX; i++)
  860.             SendMessage(aybox, CB_ADDSTRING, 0, (LPARAM)ay_schemes[i]);
  861.         //---------------------------------------------------------------------
  862.         aybox = GetDlgItem(dlg, IDC_CHIP_VOL);
  863.         for (unsigned char UCi = 0; UCi < num_ayvols; UCi++)            //Alone Coder
  864.             SendMessage(aybox, CB_ADDSTRING, 0, (LPARAM)ayvols[UCi]);   //Alone Coder
  865.         //---------------------------------------------------------------------
  866.         aybox = GetDlgItem(dlg, IDC_CHIP_STEREO);
  867.         for (i = 0; i < num_aystereo; i++)
  868.             SendMessage(aybox, CB_ADDSTRING, 0, (LPARAM)aystereo[i]);
  869.         //---------------------------------------------------------------------
  870.         // CBS_SORT тючых IDC_CHIP_CLK т settings.rc ёюЁЄшЁєхЄ юэю яю рыЇртшЄє !!!
  871.         // т√яхыхэю ўЄюс с√ыю шьхээю т ¤Єющ яюёыхфютрЄхы№эюёЄх
  872.         aybox = GetDlgItem(dlg, IDC_CHIP_CLK);
  873.         SendMessage(aybox, CB_ADDSTRING, 0, (LPARAM)"1756160 - Pentagon (corrected)");
  874.         SendMessage(aybox, CB_ADDSTRING, 0, (LPARAM)"1747200 - Clones (corrected)");
  875.         SendMessage(aybox, CB_ADDSTRING, 0, (LPARAM)"3512320 - Pentagon 2x (corrected)");
  876.         //SendMessage(aybox, MF_SEPARATOR, 0, 0);       //їч ъръ ёфхыюЄ№
  877.         SendMessage(aybox, CB_ADDSTRING, 0, (LPARAM)"1750000 - Clones");
  878.         SendMessage(aybox, CB_ADDSTRING, 0, (LPARAM)"1773450 - 128, +2, +3");           //1774400 °ю¤Єр? ю_╬
  879.         SendMessage(aybox, CB_ADDSTRING, 0, (LPARAM)"3500000 - Pentagon 2x");
  880.         //---------------------------------------------------------------------
  881.     }
  882.     //-------------------------------------------------------------------------
  883.     if (msg != WM_NOTIFY)
  884.         return 0;
  885.     //-------------------------------------------------------------------------
  886.     NMHDR *nm = (NMHDR*)lp;
  887.     //-------------------------------------------------------------------------
  888.     if (nm->code == PSN_KILLACTIVE)
  889.     {
  890.         c1.sound.ayfq = unsigned(getint(IDC_CHIP_CLK));
  891.         c1.sound.ay_chip = (unsigned char)SendDlgItemMessage(dlg, IDC_CHIP_BUS, CB_GETCURSEL, 0, 0);
  892.         c1.sound.ay_scheme = (unsigned char)SendDlgItemMessage(dlg, IDC_CHIP_SCHEME, CB_GETCURSEL, 0, 0);
  893.         c1.sound.ay_vols = (unsigned char)SendDlgItemMessage(dlg, IDC_CHIP_VOL, CB_GETCURSEL, 0, 0);
  894.         c1.sound.ay_stereo = (unsigned char)SendDlgItemMessage(dlg, IDC_CHIP_STEREO, CB_GETCURSEL, 0, 0);
  895.         c1.sound.ay_samples = getcheck(IDC_CHIP_DIGITAL);
  896.     }
  897.    //-------------------------------------------------------------------------
  898.     if (nm->code == PSN_SETACTIVE)
  899.     {
  900.         setint(IDC_CHIP_CLK, int(c1.sound.ayfq));
  901.         SendDlgItemMessage(dlg, IDC_CHIP_BUS, CB_SETCURSEL, c1.sound.ay_chip, 0);
  902.         SendDlgItemMessage(dlg, IDC_CHIP_SCHEME, CB_SETCURSEL, c1.sound.ay_scheme, 0);
  903.         SendDlgItemMessage(dlg, IDC_CHIP_VOL, CB_SETCURSEL, c1.sound.ay_vols, 0);
  904.         SendDlgItemMessage(dlg, IDC_CHIP_STEREO, CB_SETCURSEL, c1.sound.ay_stereo, 0);
  905.         setcheck(IDC_CHIP_DIGITAL, c1.sound.ay_samples);
  906.         lastpage = "AY";
  907.     }
  908.     //-------------------------------------------------------------------------
  909.     if (nm->code == PSN_APPLY)
  910.         dlgok = 1;
  911.     //-------------------------------------------------------------------------
  912.     if (nm->code == PSN_RESET)
  913.         dlgok = 0;
  914.     //-------------------------------------------------------------------------
  915.     return 1;
  916. }
  917. //=============================================================================
  918.  
  919.  
  920. //=============================================================================
  921. static INT_PTR CALLBACK fir_dlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  922. {
  923.     (void)lp;
  924.    ::dlg = dlg;
  925.    if (msg == WM_INITDIALOG) {
  926.       setcheck(IDC_SIMPLE, (c1.rsm.mode == RSM_SIMPLE));
  927.       setcheck(IDC_FIR0, (c1.rsm.mode == RSM_FIR0));
  928.       setcheck(IDC_FIR1, (c1.rsm.mode == RSM_FIR1));
  929.       setcheck(IDC_FIR2, (c1.rsm.mode == RSM_FIR2));
  930.       SendDlgItemMessage(dlg, IDC_FRAMES, TBM_SETRANGE, 0, MAKELONG(2,8));
  931.       SendDlgItemMessage(dlg, IDC_FRAMES, TBM_SETPOS, 1, c1.rsm.mix_frames);
  932.    enable_slider:
  933.       BOOL en = !getcheck(IDC_SIMPLE);
  934.       EnableWindow(GetDlgItem(dlg, IDC_FRAMES), en);
  935.       EnableWindow(GetDlgItem(dlg, IDC_FRAMES_BOX), en);
  936.       return 0;
  937.    }
  938.    if (msg == WM_SYSCOMMAND && (wp & 0xFFF0) == SC_CLOSE) EndDialog(dlg, 0);
  939.    if (msg != WM_COMMAND) return 0;
  940.    unsigned id = LOWORD(wp), code = HIWORD(wp);
  941.    if (id == IDCANCEL) EndDialog(dlg, 0);
  942.    if (id == IDOK) {
  943.       if (getcheck(IDC_SIMPLE)) c1.rsm.mode = RSM_SIMPLE;
  944.       if (getcheck(IDC_FIR0)) c1.rsm.mode = RSM_FIR0;
  945.       if (getcheck(IDC_FIR1)) c1.rsm.mode = RSM_FIR1;
  946.       if (getcheck(IDC_FIR2)) c1.rsm.mode = RSM_FIR2;
  947.       c1.rsm.mix_frames = (unsigned char)SendDlgItemMessage(dlg, IDC_FRAMES, TBM_GETPOS, 0, 0);
  948.       EndDialog(dlg, 0);
  949.    }
  950.    if (code == BN_CLICKED && (id == IDC_FIR0 || id == IDC_FIR1 || id == IDC_FIR2 || id == IDC_SIMPLE)) goto enable_slider;
  951.    return 0;
  952. }
  953. //=============================================================================
  954.  
  955.  
  956. //=============================================================================
  957. static INT_PTR CALLBACK VideoDlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  958. {
  959.     ::dlg = dlg; unsigned id, code;
  960.     int i; //Alone Coder 0.36.7
  961.  
  962.     //-------------------------------------------------------------------------
  963.     if (msg == WM_INITDIALOG)
  964.     {
  965.         //---------------------------------------------------------------------
  966.         // video filter
  967.         HWND box = GetDlgItem(  dlg,
  968.                                 IDC_VIDEOFILTER
  969.                               );
  970.                              
  971.         for (/*int*/ i = 0; renders[i].func; i++)
  972.             SendMessage(        box,
  973.                                 CB_ADDSTRING,
  974.                                 0,
  975.                                 (LPARAM)renders[i].name
  976.                         );
  977.          
  978.         SendMessage(    box,
  979.                         CB_SETCURSEL,
  980.                         c1.render,
  981.                         0
  982.                    );
  983.         //---------------------------------------------------------------------
  984.         // render - driver
  985.         box = GetDlgItem(       dlg,
  986.                                 IDC_RENDER
  987.                          );
  988.  
  989.         for (i = 0; drivers[i].name; i++)
  990.             SendMessage(        box,
  991.                                 CB_ADDSTRING,
  992.                                 0,
  993.                                 (LPARAM)drivers[i].name
  994.                         );
  995.                        
  996.         SendMessage(    box,
  997.                         CB_SETCURSEL,
  998.                         c1.driver,
  999.                         0
  1000.                     );
  1001.         //---------------------------------------------------------------------
  1002.         // palette
  1003.         box = GetDlgItem(dlg, IDC_PALETTE);
  1004.        
  1005.         for (i = 0; i < (int)c1.num_pals; i++)
  1006.             SendMessage(        box,
  1007.                                 CB_ADDSTRING,
  1008.                                 0,
  1009.                                 (LPARAM)pals[i].name
  1010.                         );
  1011.                        
  1012.         SendMessage(    box,
  1013.                         CB_SETCURSEL,
  1014.                         c1.pal,
  1015.                         0
  1016.                     );
  1017.         //---------------------------------------------------------------------
  1018.         // font for anti text 64 filter?
  1019.        
  1020.         box = GetDlgItem(       dlg,
  1021.                                 IDC_FONTHEIGHT
  1022.                          );
  1023.         SendMessage( box, CB_ADDSTRING, 0, (LPARAM)"5pix, scroll" );
  1024.         SendMessage( box, CB_ADDSTRING, 0, (LPARAM)"6pix, scroll" );
  1025.         SendMessage( box, CB_ADDSTRING, 0, (LPARAM)"7pix, scroll" );
  1026.         SendMessage( box, CB_ADDSTRING, 0, (LPARAM)"8pix, scroll" );
  1027.         SendMessage( box, CB_ADDSTRING, 0, (LPARAM)"8pix, fixed"  );
  1028.        
  1029.         unsigned index = c1.fontsize - 5;
  1030.        
  1031.         if (!c1.pixelscroll && index == 3) index++;
  1032.             SendMessage(box, CB_SETCURSEL, index, 0);
  1033.  
  1034.         //---------------------------------------------------------------------
  1035.         SendDlgItemMessage( dlg, IDC_SCRSHOT, CB_ADDSTRING, 0,                  (LPARAM)"scr");
  1036.         SendDlgItemMessage( dlg, IDC_SCRSHOT, CB_ADDSTRING, 0,                  (LPARAM)"bmp");
  1037.         SendDlgItemMessage( dlg, IDC_SCRSHOT, CB_ADDSTRING, 0,                  (LPARAM)"png");
  1038.         SendDlgItemMessage( dlg, IDC_SCRSHOT, CB_SETCURSEL, conf.scrshot,       0);
  1039.  
  1040.         goto filter_changed;
  1041.        
  1042.     } //if (msg == WM_INITDIALOG)
  1043.     //-------------------------------------------------------------------------
  1044.     if (msg == WM_COMMAND)
  1045.     {
  1046.         id = LOWORD(wp);
  1047.         code = HIWORD(wp);
  1048.         //---------------------------------------------------------------------
  1049.         if (id == IDC_FONT)
  1050.         {
  1051.             font_setup(dlg);
  1052.             return 1;
  1053.         }
  1054.         //---------------------------------------------------------------------
  1055.         if (id == IDC_FIR)
  1056.         {
  1057.             DialogBox(  hIn,
  1058.                         MAKEINTRESOURCE(IDD_FIR),
  1059.                         dlg,
  1060.                         fir_dlg
  1061.                       );
  1062.             return 1;
  1063.         }
  1064.         //---------------------------------------------------------------------
  1065.         if ( ( (id == IDC_NOFLIC) || (id == IDC_FAST_SL) ) && (code == BN_CLICKED) )
  1066.             goto filter_changed;
  1067.         //---------------------------------------------------------------------
  1068.         if ( (code == CBN_SELCHANGE) && (id == IDC_VIDEOFILTER) )
  1069.         {
  1070. filter_changed:
  1071.             unsigned filt_n = unsigned( SendDlgItemMessage(     dlg,
  1072.                                                                 IDC_VIDEOFILTER,
  1073.                                                                 CB_GETCURSEL,
  1074.                                                                 0,
  1075.                                                                 0
  1076.                                                            ) );
  1077.             DWORD f = renders[filt_n].flags;
  1078.             RENDER_FUNC rend = renders[filt_n].func;
  1079.             //-----------------------------------------------------------------
  1080.             // єёыютэюх юЄюсЁрцхэшх ьхэ■°хъ
  1081.             // sh - Їыру юЄюсЁрцхэш  ьхэ■°ъш
  1082.             //-----------------------------------------------------------------
  1083.             int sh = (f & (RF_USE32AS16 | RF_USEC32)) ? SW_SHOW :
  1084.                                                         SW_HIDE ;
  1085.                                                        
  1086.             ShowWindow(  GetDlgItem( dlg, IDC_CH_TITLE ),       sh  );
  1087.             ShowWindow(  GetDlgItem( dlg, IDC_CH2),             sh  );
  1088.             ShowWindow(  GetDlgItem( dlg, IDC_CH4),             sh  );
  1089.             ShowWindow(  GetDlgItem( dlg, IDC_CH_AUTO ),        sh  );
  1090.             //-----------------------------------------------------------------
  1091.             sh = !sh;
  1092.             ShowWindow(  GetDlgItem( dlg, IDC_B_TITLE),         sh  );
  1093.             ShowWindow(  GetDlgItem( dlg, IDC_B0),              sh  );
  1094.             ShowWindow(  GetDlgItem( dlg, IDC_B1),              sh  );
  1095.             ShowWindow(  GetDlgItem( dlg, IDC_B2),              sh  );
  1096.             ShowWindow(  GetDlgItem( dlg, IDC_B3),              sh  );  //NS
  1097.             //-----------------------------------------------------------------
  1098.             sh = (f & RF_BORDER)   ?    SW_HIDE :
  1099.                                         SW_SHOW ;
  1100.                                        
  1101.             ShowWindow(  GetDlgItem( dlg, IDC_FLASH),           sh  );
  1102.             //-----------------------------------------------------------------
  1103.             sh = (
  1104.                         (  (f & (RF_DRIVER | RF_8BPCH | RF_USEFONT) ) == RF_DRIVER)     ||
  1105.                         (rend == render_tv)                                             ||
  1106.                         (rend == render_advmame)
  1107.                  )
  1108.                     ?   SW_SHOW :
  1109.                         SW_HIDE ;
  1110.                
  1111.             ShowWindow(  GetDlgItem( dlg, IDC_NOFLIC),          sh  );
  1112.             //-----------------------------------------------------------------
  1113.             if ( !(f & RF_2X) || getcheck(IDC_FAST_SL) || !getcheck(IDC_NOFLIC) )
  1114.                 sh = SW_HIDE;
  1115.            
  1116.             ShowWindow(  GetDlgItem( dlg, IDC_ALT_NOFLIC),      sh  );
  1117.             //-----------------------------------------------------------------
  1118.             sh = (f & (RF_USEFONT))  ?  SW_SHOW :
  1119.                                         SW_HIDE ;
  1120.        
  1121.             ShowWindow(  GetDlgItem( dlg, IDC_FNTTITLE ),       sh  );
  1122.             ShowWindow(  GetDlgItem( dlg, IDC_FONTHEIGHT ),     sh  );
  1123.             ShowWindow(  GetDlgItem( dlg, IDC_FONT ),           sh  );
  1124.             //-----------------------------------------------------------------
  1125.             sh = (f & RF_DRIVER)   ?    SW_SHOW :
  1126.                                         SW_HIDE;
  1127.                                
  1128.             ShowWindow(  GetDlgItem( dlg, IDC_REND_TITLE ),     sh  );
  1129.             ShowWindow(  GetDlgItem( dlg, IDC_RENDER ),         sh  );
  1130.             //-----------------------------------------------------------------
  1131.             sh = (rend == render_rsm) ? SW_SHOW :
  1132.                                         SW_HIDE;
  1133.                                        
  1134.             ShowWindow(  GetDlgItem( dlg, IDC_FIR ),            sh  );
  1135.             //-----------------------------------------------------------------
  1136.             sh = (f & RF_2X) && (f & (RF_DRIVER | RF_USEC32)) ? SW_SHOW :
  1137.                                                                 SW_HIDE ;
  1138.                                                                
  1139.             ShowWindow(  GetDlgItem( dlg, IDC_FAST_SL ),        sh  );
  1140.             //-----------------------------------------------------------------
  1141.             sh = (rend == render_advmame)   ?   SW_SHOW :
  1142.                                                 SW_HIDE ;
  1143.             ShowWindow(  GetDlgItem( dlg, IDC_VIDEOSCALE ),     sh  );
  1144.             ShowWindow(  GetDlgItem( dlg, IDC_VSCALE_TITLE1 ),  sh  );
  1145.             ShowWindow(  GetDlgItem( dlg, IDC_VSCALE_TITLE2 ),  sh  );
  1146.             ShowWindow(  GetDlgItem( dlg, IDC_VSCALE_TITLE3 ),  sh  );
  1147.             //-----------------------------------------------------------------
  1148.         }
  1149.         //---------------------------------------------------------------------
  1150.         return 1;
  1151.     } //if (msg == WM_COMMAND)
  1152.     //-------------------------------------------------------------------------
  1153.     if (msg != WM_NOTIFY)
  1154.         return 0;
  1155.     //-------------------------------------------------------------------------
  1156.     NMHDR *nm = (NMHDR*)lp;
  1157.     //-------------------------------------------------------------------------
  1158.     if (nm->code == PSN_KILLACTIVE)
  1159.     {
  1160.         unsigned index = unsigned( SendDlgItemMessage( dlg, IDC_FONTHEIGHT, CB_GETCURSEL, 0, 0 ) );
  1161.  
  1162.         c1.pixelscroll = (index == 4) ? 0 :
  1163.                                         1 ;
  1164.                                        
  1165.         c1.fontsize = (index == 4)  ?   8 :
  1166.                                         index + 5 ;
  1167.                                        
  1168.         c1.render = unsigned    ( SendDlgItemMessage( dlg, IDC_VIDEOFILTER, CB_GETCURSEL, 0, 0 ) );
  1169.         c1.driver = unsigned    ( SendDlgItemMessage( dlg, IDC_RENDER,      CB_GETCURSEL, 0, 0 ) );
  1170.         c1.frameskip = u8 (getint(IDE_SKIP1));
  1171.         c1.minres = unsigned (getint(IDE_MINX));
  1172.         c1.frameskipmax = u8 (getint(IDE_SKIP2));
  1173.         c1.scanbright = unsigned (getint(IDE_SCBRIGHT));
  1174.         c1.fast_sl = getcheck(IDC_FAST_SL);
  1175.         c1.scrshot = int        ( SendDlgItemMessage( dlg, IDC_SCRSHOT, CB_GETCURSEL, 0, 0 ) );
  1176.         c1.flip = (conf.SyncMode == SM_VIDEO) ? 1 :
  1177.                                                 getcheck(IDC_FLIP) ;
  1178.         c1.updateb = getcheck(IDC_UPDB);
  1179.         c1.pal = unsigned       ( SendDlgItemMessage( dlg, IDC_PALETTE, CB_GETCURSEL, 0, 0 ) );
  1180.         c1.flashcolor = getcheck(IDC_FLASH);
  1181.         c1.noflic = getcheck(IDC_NOFLIC);
  1182.         c1.alt_nf = getcheck(IDC_ALT_NOFLIC);
  1183.         if ( getcheck(IDC_B0)   )       c1.bordersize = 0;
  1184.         if ( getcheck(IDC_B1)   )       c1.bordersize = 1;
  1185.         if ( getcheck(IDC_B2)   )       c1.bordersize = 2;
  1186.         if ( getcheck(IDC_B3)   )       c1.bordersize = 3;      //NS
  1187.         if ( getcheck(IDC_CH_AUTO) )    c1.ch_size = 0;
  1188.         if ( getcheck(IDC_CH2)  )       c1.ch_size = 2;
  1189.         if ( getcheck(IDC_CH4)  )       c1.ch_size = 4;
  1190.         c1.videoscale = (unsigned char)(SendDlgItemMessage( dlg, IDC_VIDEOSCALE, TBM_GETPOS, 0, 0 ) );
  1191.     }
  1192.     //-------------------------------------------------------------------------
  1193.     if (nm->code == PSN_SETACTIVE)
  1194.     {
  1195.         setint( IDE_SKIP1,      c1.frameskip    );
  1196.         setint( IDE_SKIP2,      c1.frameskipmax );
  1197.         setint( IDE_MINX,       int(c1.minres)  );
  1198.         setint( IDE_SCBRIGHT,   int(c1.scanbright) );
  1199.  
  1200.         SendDlgItemMessage( dlg, IDC_SCRSHOT, CB_SETCURSEL, c1.scrshot, 0 );
  1201.  
  1202.         setcheck( IDC_FLIP,     c1.flip         );
  1203.         setcheck( IDC_UPDB,     c1.updateb      );
  1204.         setcheck( IDC_FLASH,    c1.flashcolor   );
  1205.         setcheck( IDC_NOFLIC,   c1.noflic       );
  1206.         setcheck( IDC_ALT_NOFLIC, c1.alt_nf     );
  1207.         setcheck( IDC_FAST_SL,  c1.fast_sl      );
  1208.  
  1209.         SendDlgItemMessage( dlg, IDC_VIDEOSCALE, TBM_SETRANGE, 0, MAKELONG(1,4) );
  1210.         SendDlgItemMessage( dlg, IDC_VIDEOSCALE, TBM_SETPOS, 1, c1.videoscale );
  1211.  
  1212.         SendDlgItemMessage( dlg, IDC_B0, BM_SETCHECK, (c1.bordersize == 0) ? BST_CHECKED : BST_UNCHECKED, 0 );
  1213.         SendDlgItemMessage( dlg, IDC_B1, BM_SETCHECK, (c1.bordersize == 1) ? BST_CHECKED : BST_UNCHECKED, 0 );
  1214.         SendDlgItemMessage( dlg, IDC_B2, BM_SETCHECK, (c1.bordersize == 2) ? BST_CHECKED : BST_UNCHECKED, 0 );
  1215.         SendDlgItemMessage( dlg, IDC_B3, BM_SETCHECK, (c1.bordersize == 3) ? BST_CHECKED : BST_UNCHECKED, 0 );  //NS
  1216.  
  1217.         SendDlgItemMessage( dlg, IDC_CH_AUTO, BM_SETCHECK, (c1.ch_size == 0) ? BST_CHECKED : BST_UNCHECKED, 0);
  1218.         SendDlgItemMessage( dlg, IDC_CH2, BM_SETCHECK,     (c1.ch_size == 2) ? BST_CHECKED : BST_UNCHECKED, 0);
  1219.         SendDlgItemMessage( dlg, IDC_CH4, BM_SETCHECK,     (c1.ch_size == 4) ? BST_CHECKED : BST_UNCHECKED, 0);
  1220.  
  1221.         lastpage = "VIDEO";
  1222.  
  1223.         goto filter_changed;
  1224.     }
  1225.     //-------------------------------------------------------------------------
  1226.     if (nm->code == PSN_APPLY) dlgok = 1;
  1227.     if (nm->code == PSN_RESET) dlgok = 0;
  1228.     return 1;
  1229. }
  1230. //=============================================================================
  1231.  
  1232.  
  1233.  
  1234. #ifdef MOD_GSBASS
  1235. void SaveModDlg(HWND dlg)
  1236. {
  1237.     char fname[FILENAME_MAX];
  1238.     strncpy(fname, (char*)gs.mod, 20);
  1239.     fname[20] = 0;
  1240.     static const char *InvalidChars = "|<>?/\\\":*";
  1241.     for(char *ptr = fname; *ptr; ptr++)
  1242.     {
  1243.         if((*(u8*)ptr < ' ') || (strchr(InvalidChars, *ptr) != nullptr))
  1244.         {
  1245.             *ptr = ' ';
  1246.         }
  1247.     }
  1248.  
  1249.     OPENFILENAME ofn = { };
  1250.     ofn.lStructSize = (WinVerMajor < 5) ? OPENFILENAME_SIZE_VERSION_400 : sizeof(OPENFILENAME);
  1251.     ofn.lpstrFilter = "Amiga music module (MOD)\0*.mod\0";
  1252.     ofn.lpstrFile = fname;
  1253.     ofn.nMaxFile = _countof(fname);
  1254.     ofn.lpstrTitle = "Save music from GS";
  1255.     ofn.lpstrDefExt = "mod";
  1256.     ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_ENABLESIZING;
  1257.     ofn.hwndOwner = dlg;
  1258.     ofn.nFilterIndex = 1;
  1259.     if(GetSaveFileName(&ofn))
  1260.     {
  1261.         gs.debug_save_mod(fname);
  1262.     }
  1263. }
  1264. #endif // MOD_GSBASS
  1265.  
  1266. static struct
  1267. {
  1268.    unsigned ID;
  1269.    int *value;
  1270. } slider[] = {
  1271.    { IDC_SND_BEEPER,  &c1.sound.beeper_vol  },
  1272.    { IDC_SND_MICOUT,  &c1.sound.micout_vol  },
  1273.    { IDC_SND_MICIN,   &c1.sound.micin_vol   },
  1274.    { IDC_SND_AY,      &c1.sound.ay_vol      },
  1275.    { IDC_SND_COVOXFB, &c1.sound.covoxFB_vol },
  1276.    { IDC_SND_COVOXDD, &c1.sound.covoxDD_vol },
  1277.    { IDC_SND_SD,      &c1.sound.sd_vol      },
  1278.    { IDC_SND_BASS,    &c1.sound.bass_vol    },
  1279.    { IDC_SND_GS,      &c1.sound.gs_vol      },
  1280. };
  1281. //=============================================================================
  1282.  
  1283.  
  1284. //=============================================================================
  1285. static INT_PTR CALLBACK SoundDlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  1286. {
  1287.    ::dlg = dlg;
  1288.    if (msg == WM_INITDIALOG)
  1289.    {
  1290.       BOOL savemod = FALSE, reset = FALSE, fx_vol = FALSE, bass_vol = FALSE;
  1291. //      unsigned here_soundfilter = 1; //Alone Coder 0.36.4
  1292.       #ifdef MOD_GS
  1293.       if (c1.gs_type)
  1294.       {
  1295.          reset = TRUE;
  1296.  
  1297.          #ifdef MOD_GSZ80
  1298.          if (c1.gs_type == 1) fx_vol = TRUE;
  1299.          #endif
  1300.  
  1301.          #ifdef MOD_GSBASS
  1302.          if (c1.gs_type == 2) {
  1303.             fx_vol = bass_vol = TRUE;
  1304.             if (gs.mod && gs.modsize) savemod = TRUE;
  1305.          }
  1306.          #endif
  1307.       }
  1308.       #endif
  1309.  
  1310. //      EnableWindow(GetDlgItem(dlg, IDC_SOUNDFILTER), here_soundfilter); //Alone Coder 0.36.4
  1311.  
  1312.       EnableWindow(GetDlgItem(dlg, IDC_GSRESET), reset);
  1313.       EnableWindow(GetDlgItem(dlg, IDB_SAVEMOD), savemod);
  1314.       EnableWindow(GetDlgItem(dlg, IDC_GS_TITLE), fx_vol);
  1315.       EnableWindow(GetDlgItem(dlg, IDC_SND_GS), fx_vol);
  1316.       EnableWindow(GetDlgItem(dlg, IDC_SND_BASS), bass_vol);
  1317.       EnableWindow(GetDlgItem(dlg, IDC_BASS_TITLE), bass_vol);
  1318.    }
  1319.    if (msg == WM_COMMAND && LOWORD(wp) == IDC_NOSOUND) {
  1320.       c1.sound.enabled = !getcheck(IDC_NOSOUND);
  1321. upd:  for (size_t i = 0; i < sizeof slider/sizeof*slider; i++) {
  1322.          SendDlgItemMessage(dlg, slider[i].ID, TBM_SETRANGE, 0, MAKELONG(0,8192));
  1323.          SendDlgItemMessage(dlg, slider[i].ID, TBM_SETPOS, 1, c1.sound.enabled ? *slider[i].value : 0);
  1324.          SendDlgItemMessage(dlg, slider[i].ID, WM_ENABLE, c1.sound.enabled, 0);
  1325.       }
  1326.       return 1;
  1327.    }
  1328.  
  1329. #ifdef MOD_GSBASS
  1330.    if ((msg == WM_COMMAND) && (LOWORD(wp) == IDB_SAVEMOD) && (HIWORD(wp) == BN_CLICKED))
  1331.    {
  1332.        SaveModDlg(dlg);
  1333.        return 1;
  1334.    }
  1335. #endif
  1336.  
  1337.    if (msg != WM_NOTIFY) return 0;
  1338.    NMHDR *nm = (NMHDR*)lp;
  1339.    if (nm->code == PSN_KILLACTIVE) {
  1340.       if ((c1.sound.enabled = (IsDlgButtonChecked(dlg, IDC_NOSOUND) != BST_CHECKED)))
  1341.          for (size_t i = 0; i < sizeof slider/sizeof*slider; i++)
  1342.             *slider[i].value = int(SendDlgItemMessage(dlg, slider[i].ID, TBM_GETPOS, 0, 0));
  1343.       c1.sound.gsreset = getcheck(IDC_GSRESET);
  1344.       c1.soundfilter = getcheck(IDC_SOUNDFILTER); //Alone Coder 0.36.4
  1345.    }
  1346.    if (nm->code == PSN_SETACTIVE) {
  1347.       setcheck(IDC_NOSOUND, !c1.sound.enabled);
  1348.       setcheck(IDC_GSRESET, c1.sound.gsreset);
  1349.       setcheck(IDC_SOUNDFILTER, c1.soundfilter); //Alone Coder 0.36.4
  1350.       lastpage = "SOUND";
  1351.       goto upd;
  1352.    }
  1353.    if (nm->code == PSN_APPLY) dlgok = 1;
  1354.    if (nm->code == PSN_RESET) dlgok = 0;
  1355.    return 1;
  1356. }
  1357. //=============================================================================
  1358.  
  1359.  
  1360. //=============================================================================
  1361. static INT_PTR CALLBACK TapeDlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  1362. {
  1363.     (void)wp;
  1364.     ::dlg = dlg;
  1365.     if (msg == WM_INITDIALOG)
  1366.     {
  1367.         find_tape_index();
  1368.         for (unsigned i = 0; i < tape_infosize; i++)
  1369.         {
  1370.             SendDlgItemMessage(dlg, IDC_TAPE, LB_ADDSTRING, 0, (LPARAM)tapeinfo[i].desc);
  1371.         }
  1372.     }
  1373.     if (msg != WM_NOTIFY) return 0;
  1374.     NMHDR *nm = (NMHDR*)lp;
  1375.     if (nm->code == PSN_KILLACTIVE)
  1376.     {
  1377.         unsigned Idx = unsigned(SendDlgItemMessage(dlg, IDC_TAPE, LB_GETCURSEL, 0, 0));
  1378.         if(Idx != -1U && Idx != comp.tape.index)
  1379.         {
  1380.             comp.tape.index = Idx;
  1381.             comp.tape.play_pointer = tape_image + tapeinfo[comp.tape.index].pos;
  1382.         }
  1383.  
  1384.         c1.tape_autostart = getcheck(IDC_TAPE_AUTOSTART);
  1385.         c1.tape_traps = getcheck(IDC_TAPE_TRAPS);
  1386.     }
  1387.     if (nm->code == PSN_SETACTIVE)
  1388.     {
  1389.         SendDlgItemMessage(dlg, IDC_TAPE, LB_SETCURSEL, comp.tape.index, 0);
  1390.         setcheck(IDC_TAPE_AUTOSTART, c1.tape_autostart);
  1391.         setcheck(IDC_TAPE_TRAPS, c1.tape_traps);
  1392.         lastpage = "TAPE";
  1393.     }
  1394.     if (nm->code == PSN_APPLY) dlgok = 1;
  1395.     if (nm->code == PSN_RESET) dlgok = 0;
  1396.     return 1;
  1397. }
  1398. //=============================================================================
  1399.  
  1400.  
  1401. //=============================================================================
  1402. static void FillModemList(HWND box)
  1403. {
  1404.    ComboBox_AddString(box, "NONE");
  1405.    for (unsigned port = 1; port < 256; port++)
  1406.    {
  1407.       HANDLE hPort;
  1408.       if (modem.open_port == port)
  1409.           hPort = modem.hPort;
  1410.       else
  1411.       {
  1412.          char portName[11];
  1413.          _snprintf(portName, _countof(portName), "\\\\.\\COM%u", port);
  1414.  
  1415.          hPort = CreateFile(portName, 0, 0, nullptr, OPEN_EXISTING, 0, nullptr);
  1416.          if (hPort == INVALID_HANDLE_VALUE)
  1417.              continue;
  1418.       }
  1419.  
  1420.       struct
  1421.       {
  1422.          COMMPROP comm;
  1423.          char xx[4000];
  1424.       } b;
  1425.  
  1426.       b.comm.wPacketLength = sizeof(b);
  1427.       b.comm.dwProvSpec1 = COMMPROP_INITIALIZED;
  1428.       if (GetCommProperties(hPort, &b.comm) && b.comm.dwProvSubType == PST_MODEM)
  1429.       {
  1430.          MODEMDEVCAPS *mc = (MODEMDEVCAPS*)&b.comm.wcProvChar;
  1431.          char vendor[0x100], model[0x100];
  1432.  
  1433.          int vsize = int(mc->dwModemManufacturerSize / sizeof(WCHAR));
  1434.          WideCharToMultiByte(CP_ACP, 0, (WCHAR*)(PCHAR(mc) + mc->dwModemManufacturerOffset), vsize, vendor, sizeof vendor, nullptr, nullptr);
  1435.          vendor[vsize] = 0;
  1436.  
  1437.          int msize = int(mc->dwModemModelSize / sizeof(WCHAR));
  1438.          WideCharToMultiByte(CP_ACP, 0, (WCHAR*)(PCHAR(mc) + mc->dwModemModelOffset), msize, model, sizeof model, nullptr, nullptr);
  1439.          model[msize] = 0;
  1440.          char line[0x200];
  1441.          _snprintf(line, _countof(line), "COM%u: %s %s", port, vendor, model);
  1442.          ComboBox_AddString(box, line);
  1443.       }
  1444.       else
  1445.       {
  1446.          char portName[11];
  1447.          _snprintf(portName, _countof(portName), "COM%u:", port);
  1448.          ComboBox_AddString(box, portName);
  1449.       }
  1450.       if (modem.open_port != port)
  1451.           CloseHandle(hPort);
  1452.    }
  1453. }
  1454. //=============================================================================
  1455.  
  1456.  
  1457. //=============================================================================
  1458. static void SelectModem(HWND box)
  1459. {
  1460.    if (!c1.modem_port)
  1461.    {
  1462.        ComboBox_SetCurSel(box, 0);
  1463.        return;
  1464.    }
  1465.  
  1466.    char line[0x200];
  1467.    int Cnt = ComboBox_GetCount(box);
  1468.    for (int i = 0; i < Cnt; i++)
  1469.    {
  1470.       ComboBox_GetLBText(box, i, line);
  1471.       int Port = 0;
  1472.       sscanf(line, "COM%d", &Port);
  1473.       if (Port == c1.modem_port)
  1474.       {
  1475.          SendMessage(box, CB_SETCURSEL, i, 0);
  1476.          ComboBox_SetCurSel(box, i);
  1477.          return;
  1478.       }
  1479.    }
  1480. }
  1481. //=============================================================================
  1482.  
  1483.  
  1484. //=============================================================================
  1485. static int GetModemPort(HWND box)
  1486. {
  1487.    int index = ComboBox_GetCurSel(box);
  1488.    if (!index)
  1489.        return 0;
  1490.  
  1491.    char line[0x200];
  1492.    ComboBox_GetLBText(box, index, line);
  1493.    int Port = 0;
  1494.    sscanf(line, "COM%d", &Port);
  1495.    return Port;
  1496. }
  1497. //=============================================================================
  1498.  
  1499.  
  1500. //=============================================================================
  1501. static INT_PTR CALLBACK InputDlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  1502. {
  1503.     (void)wp;
  1504.    ::dlg = dlg; char names[0x2000];
  1505.    if (msg == WM_INITDIALOG) {
  1506.       zxkeymap *active_zxk = conf.input.active_zxk;
  1507.       for (unsigned i = 0; i < active_zxk->zxk_size; i++)
  1508.          SendDlgItemMessage(dlg, IDC_FIREKEY, CB_ADDSTRING, 0, (LPARAM)active_zxk->zxk[i].name);
  1509.       GetPrivateProfileSectionNames(names, sizeof names, ininame);
  1510.       for (char *ptr = names; *ptr; ptr += strlen(ptr)+1)
  1511.          if (!strnicmp(ptr, "ZX.KEYS.", sizeof("ZX.KEYS.")-1)) {
  1512.             char line[0x200]; GetPrivateProfileString(ptr, "Name", ptr, line, sizeof line, ininame);
  1513.                 string_comment_trimmer(line); //юсЁхчър ыш°эхую //NS
  1514.                 //printf("ZX.KEYS <%s>\n",line);
  1515.             SendDlgItemMessage(dlg, IDC_KLAYOUT, CB_ADDSTRING, 0, (LPARAM)line);
  1516.          }
  1517.       FillModemList(GetDlgItem(dlg, IDC_MODEM));
  1518.    }
  1519.    if (msg != WM_NOTIFY) return 0;
  1520.    NMHDR *nm = (NMHDR*)lp;
  1521.    if (nm->code == PSN_KILLACTIVE) {
  1522.       if (getcheck(IDC_MOUSE_NONE)) c1.input.mouse = 0;
  1523.       if (getcheck(IDC_MOUSE_KEMPSTON)) c1.input.mouse = 1;
  1524.       if (getcheck(IDC_MOUSE_AY)) c1.input.mouse = 2;
  1525.       if (getcheck(IDC_WHEEL_NONE)) c1.input.mousewheel = MOUSE_WHEEL_NONE;
  1526.       if (getcheck(IDC_WHEEL_KEYBOARD)) c1.input.mousewheel = MOUSE_WHEEL_KEYBOARD;
  1527.       if (getcheck(IDC_WHEEL_KEMPSTON)) c1.input.mousewheel = MOUSE_WHEEL_KEMPSTON;
  1528.       c1.input.keybpcmode = getcheck(IDC_PC_LAYOUT);
  1529.       c1.input.mouseswap = getcheck(IDC_MOUSESWAP);
  1530.       c1.input.kjoy = getcheck(IDC_KJOY);
  1531.       c1.input.fjoy = getcheck(IDC_FJOY);
  1532.       c1.input.keymatrix = getcheck(IDC_KEYMATRIX);
  1533.       c1.input.mousescale = (char)(SendDlgItemMessage(dlg, IDC_MOUSESCALE, TBM_GETPOS, 0, 0) - 3);
  1534.       c1.input.joymouse = getcheck(IDC_JOYMOUSE);
  1535.       c1.input.firenum = unsigned(SendDlgItemMessage(dlg, IDC_FIREKEY, CB_GETCURSEL, 0, 0));
  1536.       c1.input.fire = getcheck(IDC_AUTOFIRE);
  1537.       c1.input.firedelay = u8(getint(IDE_FIRERATE));
  1538.       c1.input.altlock = getcheck(IDC_ALTLOCK);
  1539.       c1.input.paste_hold = u8(getint(IDE_HOLD_DELAY));
  1540.       c1.input.paste_release = u8(getint(IDE_RELEASE_DELAY));
  1541.       c1.input.paste_newline = u8(getint(IDE_NEWLINE_DELAY));
  1542.       c1.atm.xt_kbd = getcheck(IDC_ATM_KBD);
  1543.       c1.modem_port = GetModemPort(GetDlgItem(dlg, IDC_MODEM));
  1544.       GetPrivateProfileSectionNames(names, sizeof names, ininame);
  1545.       int n = int(SendDlgItemMessage(dlg, IDC_KLAYOUT, CB_GETCURSEL, 0, 0)), i = 0;
  1546.       for (char *ptr = names; *ptr; ptr += strlen(ptr)+1)
  1547.          if (!strnicmp(ptr, "ZX.KEYS.", sizeof("ZX.KEYS.")-1)) {
  1548.             if (i == n) strcpy(c1.keyset, ptr+sizeof("ZX.KEYS.")-1);
  1549.             i++;
  1550.          }
  1551.    }
  1552.    if (nm->code == PSN_SETACTIVE) {
  1553.       setcheck(IDC_MOUSE_NONE, c1.input.mouse == 0);
  1554.       setcheck(IDC_MOUSE_KEMPSTON, c1.input.mouse == 1);
  1555.       setcheck(IDC_MOUSE_AY, c1.input.mouse == 2);
  1556.       setcheck(IDC_PC_LAYOUT, c1.input.keybpcmode);
  1557.       setcheck(IDC_WHEEL_NONE, c1.input.mousewheel == MOUSE_WHEEL_NONE);
  1558.       setcheck(IDC_WHEEL_KEYBOARD, c1.input.mousewheel == MOUSE_WHEEL_KEYBOARD);
  1559.       setcheck(IDC_WHEEL_KEMPSTON, c1.input.mousewheel == MOUSE_WHEEL_KEMPSTON);
  1560.       setcheck(IDC_MOUSESWAP, c1.input.mouseswap);
  1561.       setcheck(IDC_KJOY, c1.input.kjoy);
  1562.       setcheck(IDC_FJOY, c1.input.fjoy);
  1563.       setcheck(IDC_KEYMATRIX, c1.input.keymatrix);
  1564.       setcheck(IDC_JOYMOUSE, c1.input.joymouse);
  1565.       setcheck(IDC_AUTOFIRE, c1.input.fire);
  1566.       setcheck(IDC_ALTLOCK, c1.input.altlock);
  1567.       setcheck(IDC_ATM_KBD, c1.atm.xt_kbd);
  1568.       SendDlgItemMessage(dlg, IDC_MOUSESCALE, TBM_SETRANGE, 0, MAKELONG(0,6));
  1569.       SendDlgItemMessage(dlg, IDC_MOUSESCALE, TBM_SETPOS, 1, c1.input.mousescale+3);
  1570.       SendDlgItemMessage(dlg, IDC_FIREKEY, CB_SETCURSEL, c1.input.firenum, 0);
  1571.       setint(IDE_FIRERATE, c1.input.firedelay);
  1572.       setint(IDE_HOLD_DELAY, c1.input.paste_hold);
  1573.       setint(IDE_RELEASE_DELAY, c1.input.paste_release);
  1574.       setint(IDE_NEWLINE_DELAY, c1.input.paste_newline);
  1575.       SelectModem(GetDlgItem(dlg, IDC_MODEM));
  1576.       GetPrivateProfileSectionNames(names, sizeof names, ininame);
  1577.       int i = 0;
  1578.       for (char *ptr = names; *ptr; ptr += strlen(ptr)+1)
  1579.          if (!strnicmp(ptr, "ZX.KEYS.", sizeof("ZX.KEYS.")-1)) {
  1580.             if (!strnicmp(c1.keyset, ptr+sizeof("ZX.KEYS.")-1, strlen(c1.keyset)))
  1581.                SendDlgItemMessage(dlg, IDC_KLAYOUT, CB_SETCURSEL, i, 0);
  1582.             i++;
  1583.          }
  1584.       lastpage = "INPUT";
  1585.    }
  1586.    if (nm->code == PSN_APPLY) dlgok = 1;
  1587.    if (nm->code == PSN_RESET) dlgok = 0;
  1588.    return 1;
  1589. }
  1590. //=============================================================================
  1591.  
  1592.  
  1593. //=============================================================================
  1594. static INT_PTR CALLBACK LedsDlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  1595. {
  1596.     //-------------------------------------------------------------------------
  1597.     static int ids[ NUM_LEDS][3] =
  1598.     {
  1599.         { IDC_LED_AY,      IDC_LED_AY_X,      IDC_LED_AY_Y },
  1600.         { IDC_LED_PERF,    IDC_LED_PERF_X,    IDC_LED_PERF_Y },
  1601.         { IDC_LED_LOAD,    IDC_LED_ROM_X,     IDC_LED_ROM_Y },
  1602.         { IDC_LED_INPUT,   IDC_LED_INPUT_X,   IDC_LED_INPUT_Y },
  1603.         { IDC_LED_TIME,    IDC_LED_TIME_X,    IDC_LED_TIME_Y },
  1604.         { IDC_LED_DEBUG,   IDC_LED_DEBUG_X,   IDC_LED_DEBUG_Y },
  1605.         { IDC_LED_MEMBAND, IDC_LED_MEMBAND_X, IDC_LED_MEMBAND_Y }
  1606.     };
  1607.     //-------------------------------------------------------------------------
  1608.     static volatile char block = 0;
  1609.     ::dlg = dlg;
  1610.     //-------------------------------------------------------------------------
  1611.     if (  (msg == WM_USER)
  1612.              ||
  1613.           (     !block                  &&
  1614.                 (msg == WM_COMMAND)     &&
  1615.                 (   (HIWORD( wp) == EN_CHANGE)  ||
  1616.                     (HIWORD( wp) == BN_CLICKED)
  1617.                   )
  1618.              )
  1619.      )
  1620.     {
  1621.         unsigned char ld_on = getcheck( IDC_LED_ON);
  1622.         c1.led.enabled = ld_on;
  1623.         c1.led.perf_t = getcheck( IDC_PERF_T);
  1624.         c1.led.flash_ay_kbd = getcheck( IDC_LED_AYKBD);
  1625.         //---------------------------------------------------------------------
  1626.         for (unsigned i = 0;    i < NUM_LEDS;    i++)
  1627.         {
  1628.             char b1[16];
  1629.             char b2[16];
  1630.             SendDlgItemMessage( dlg, ids[i][1], WM_GETTEXT, sizeof b1, (LPARAM) b1);
  1631.             SendDlgItemMessage( dlg, ids[i][2], WM_GETTEXT, sizeof b2, (LPARAM) b2);
  1632.             //-----------------------------------------------------------------
  1633.             if (!*b1 || !*b2)    // skip first notification with empty controls
  1634.                 continue;      
  1635.             //-----------------------------------------------------------------
  1636.             unsigned a = unsigned( atoi( b1) & 0xFFFF) + unsigned(( atoi( b2) & 0x7FFF) << 16);
  1637.             //-----------------------------------------------------------------
  1638.             if (IsDlgButtonChecked( dlg, ids[i][0]) == BST_CHECKED)
  1639.                 a |= 0x80000000;
  1640.             //-----------------------------------------------------------------
  1641.             unsigned char x = ld_on && (a & 0x80000000);
  1642.             EnableWindow( GetDlgItem( dlg, ids[i][0]), ld_on);
  1643.             EnableWindow( GetDlgItem( dlg, ids[i][1]), x);
  1644.             EnableWindow( GetDlgItem( dlg, ids[i][2]), x);
  1645.             (&c1.led.ay)[i] = a;
  1646.         }
  1647.         //---------------------------------------------------------------------
  1648.         EnableWindow( GetDlgItem( dlg, IDC_LED_AYKBD), (ld_on && hndKbdDev));
  1649.         EnableWindow( GetDlgItem( dlg, IDC_PERF_T),     ld_on && (c1.led.perf    & 0x80000000));
  1650.         EnableWindow( GetDlgItem( dlg, IDC_LED_BPP),    ld_on && (c1.led.memband & 0x80000000));
  1651.                 //printf("leds enabling\n");
  1652.         //---------------------------------------------------------------------
  1653.         #ifndef MOD_MONITOR
  1654.             c1.led.osw &= 0x7FFFFFFF;
  1655.             EnableWindow( GetDlgItem( dlg, IDC_LED_DEBUG), 0);
  1656.         #endif
  1657.         //---------------------------------------------------------------------
  1658.         #ifndef MOD_MEMBAND_LED
  1659.             c1.led.memband &= 0x7FFFFFFF;
  1660.             c1.led.memband_256 &= 0x7FFFFFFF;
  1661.             EnableWindow( GetDlgItem( dlg, IDC_LED_MEMBAND), 0);
  1662.         #endif
  1663.         //---------------------------------------------------------------------
  1664.     }
  1665.     //-------------------------------------------------------------------------  
  1666.     if (msg != WM_NOTIFY)
  1667.         return 0;
  1668.     //-------------------------------------------------------------------------
  1669.     NMHDR *nm = (NMHDR*)lp;
  1670.     //-------------------------------------------------------------------------
  1671.     if (nm->code == PSN_KILLACTIVE)
  1672.     {
  1673.         unsigned pos = unsigned( SendDlgItemMessage( dlg, IDC_LED_BPP, TBM_GETPOS, 0, 0));
  1674.         //printf("leds enabling\n");
  1675.         //---------------------------------------------------------------------
  1676.         if      (pos == 0)      c1.led.bandBpp = 64;
  1677.         else if (pos == 1)      c1.led.bandBpp = 128;
  1678.         else if (pos == 2)      c1.led.bandBpp = 256;
  1679.         else                    c1.led.bandBpp = 512;
  1680.         //---------------------------------------------------------------------
  1681.     }
  1682.     //-------------------------------------------------------------------------
  1683.     if (nm->code == PSN_SETACTIVE)
  1684.     {
  1685.         block = 1;
  1686.         setcheck( IDC_LED_ON,    c1.led.enabled);
  1687.         setcheck( IDC_LED_AYKBD, c1.led.flash_ay_kbd);
  1688.         setcheck( IDC_PERF_T,    c1.led.perf_t);
  1689.         //printf("leds enabling\n");
  1690.         unsigned pos = 3;
  1691.         //---------------------------------------------------------------------
  1692.         if (c1.led.bandBpp == 64)        pos = 0;
  1693.         if (c1.led.bandBpp == 128)       pos = 1;
  1694.         if (c1.led.bandBpp == 256)       pos = 2;
  1695.         //---------------------------------------------------------------------
  1696.         SendDlgItemMessage( dlg, IDC_LED_BPP, TBM_SETRANGE, 0, MAKELONG( 0, 3));
  1697.         SendDlgItemMessage( dlg, IDC_LED_BPP, TBM_SETPOS, 1, pos);
  1698.         //---------------------------------------------------------------------
  1699.         for (unsigned i = 0;    i < NUM_LEDS;    i++)
  1700.         {
  1701.             unsigned a = (&c1.led.ay)[i];
  1702.             char bf[16];
  1703.             sprintf( bf, "%d", (signed short)(a & 0xFFFF));
  1704.             SendDlgItemMessage( dlg, ids[i][1], WM_SETTEXT, 0, (LPARAM)bf);
  1705.             sprintf( bf, "%d", (signed short)(((a >> 16) & 0x7FFF) + ((a >> 15) & 0x8000)));
  1706.             SendDlgItemMessage( dlg, ids[i][2], WM_SETTEXT, 0, (LPARAM)bf);
  1707.             setcheck( ids[i][0], a >> 31);
  1708.         }
  1709.         //---------------------------------------------------------------------
  1710.         LedsDlg( dlg, WM_USER, 0, 0);
  1711.         block = 0;
  1712.         lastpage = "LEDS";
  1713.     }
  1714.     //-------------------------------------------------------------------------
  1715.  
  1716.     if (nm->code == PSN_APPLY)  dlgok = 1;
  1717.     if (nm->code == PSN_RESET)  dlgok = 0;
  1718.     return 1;
  1719. }
  1720. //=============================================================================
  1721.  
  1722.  
  1723. //=============================================================================
  1724. static INT_PTR CALLBACK BetaDlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  1725. {
  1726.    ::dlg = dlg;
  1727.    unsigned ID = LOWORD(wp);
  1728.    if (msg == WM_INITDIALOG)
  1729.    {
  1730.       setcheck(IDC_DISK_TRAPS, c1.trdos_traps);
  1731.    }
  1732.    if (msg == WM_COMMAND)
  1733.    {
  1734.       unsigned disk;
  1735.       switch (ID)
  1736.       {
  1737.          case IDB_INS_A: disk = 0; goto load;
  1738.          case IDB_INS_B: disk = 1; goto load;
  1739.          case IDB_INS_C: disk = 2; goto load;
  1740.          case IDB_INS_D: disk = 3; goto load;
  1741.          load:
  1742.             if (!comp.fdd[disk].test())
  1743.                 return 1;
  1744.             opensnap(disk+1);
  1745.             c1.trdos_wp[disk] = conf.trdos_wp[disk];
  1746.             goto reload;
  1747.  
  1748.          case IDB_REM_A: disk = 0; goto remove;
  1749.          case IDB_REM_B: disk = 1; goto remove;
  1750.          case IDB_REM_C: disk = 2; goto remove;
  1751.          case IDB_REM_D: disk = 3; goto remove;
  1752.          remove:
  1753.             if (!comp.fdd[disk].test())
  1754.                 return 1;
  1755.             comp.wd.Eject(disk);
  1756.             c1.trdos_wp[disk] = conf.trdos_wp[disk];
  1757.             goto reload;
  1758.  
  1759.          case IDB_SAVE_A: savesnap(0); goto reload;
  1760.          case IDB_SAVE_B: savesnap(1); goto reload;
  1761.          case IDB_SAVE_C: savesnap(2); goto reload;
  1762.          case IDB_SAVE_D: savesnap(3); goto reload;
  1763.  
  1764.          case IDC_BETA128:
  1765.             c1.trdos_present = getcheck(IDC_BETA128);
  1766.             goto reload;
  1767.  
  1768.          case IDC_DISK_TRAPS:
  1769.             c1.trdos_traps = getcheck(IDC_DISK_TRAPS); break;
  1770.  
  1771.          case IDC_DISK_NODELAY:
  1772.             c1.wd93_nodelay = getcheck(IDC_DISK_NODELAY); break;
  1773.       }
  1774.    }
  1775.    if (msg != WM_NOTIFY) return 0;
  1776.    {NMHDR *nm = (NMHDR*)lp;
  1777.    if (nm->code == PSN_KILLACTIVE) {
  1778.       c1.trdos_present = getcheck(IDC_BETA128);
  1779.       c1.trdos_traps = getcheck(IDC_DISK_TRAPS);
  1780.       c1.wd93_nodelay = getcheck(IDC_DISK_NODELAY);
  1781.       c1.trdos_wp[0] = getcheck(IDC_WPA);
  1782.       c1.trdos_wp[1] = getcheck(IDC_WPB);
  1783.       c1.trdos_wp[2] = getcheck(IDC_WPC);
  1784.       c1.trdos_wp[3] = getcheck(IDC_WPD);
  1785.    }
  1786.    if (nm->code == PSN_SETACTIVE) { lastpage = "Beta128"; goto reload; }
  1787.    if (nm->code == PSN_APPLY) dlgok = 1;
  1788.    if (nm->code == PSN_RESET) dlgok = 0;
  1789.    return 1;}
  1790. reload:
  1791.    SendDlgItemMessage(dlg, IDE_DISK_A, WM_SETTEXT, 0, (LPARAM)comp.fdd[0].name);
  1792.    SendDlgItemMessage(dlg, IDE_DISK_B, WM_SETTEXT, 0, (LPARAM)comp.fdd[1].name);
  1793.    SendDlgItemMessage(dlg, IDE_DISK_C, WM_SETTEXT, 0, (LPARAM)comp.fdd[2].name);
  1794.    SendDlgItemMessage(dlg, IDE_DISK_D, WM_SETTEXT, 0, (LPARAM)comp.fdd[3].name);
  1795.    setcheck(IDC_BETA128, c1.trdos_present);
  1796.    setcheck(IDC_DISK_TRAPS, c1.trdos_traps);
  1797.    setcheck(IDC_DISK_NODELAY, c1.wd93_nodelay);
  1798.    setcheck(IDC_WPA, c1.trdos_wp[0]);
  1799.    setcheck(IDC_WPB, c1.trdos_wp[1]);
  1800.    setcheck(IDC_WPC, c1.trdos_wp[2]);
  1801.    setcheck(IDC_WPD, c1.trdos_wp[3]);
  1802.    BOOL on = getcheck(IDC_BETA128);
  1803.    EnableWindow(GetDlgItem(dlg, IDC_DISK_TRAPS), on);
  1804.    EnableWindow(GetDlgItem(dlg, IDC_DISK_NODELAY), on);
  1805.  
  1806.    EnableWindow(GetDlgItem(dlg, IDB_INS_A), on);
  1807.    EnableWindow(GetDlgItem(dlg, IDB_INS_B), on);
  1808.    EnableWindow(GetDlgItem(dlg, IDB_INS_C), on);
  1809.    EnableWindow(GetDlgItem(dlg, IDB_INS_D), on);
  1810.  
  1811.    EnableWindow(GetDlgItem(dlg, IDB_REM_A), on);
  1812.    EnableWindow(GetDlgItem(dlg, IDB_REM_B), on);
  1813.    EnableWindow(GetDlgItem(dlg, IDB_REM_C), on);
  1814.    EnableWindow(GetDlgItem(dlg, IDB_REM_D), on);
  1815.  
  1816.    EnableWindow(GetDlgItem(dlg, IDB_SAVE_A), on && comp.fdd[0].rawdata);
  1817.    EnableWindow(GetDlgItem(dlg, IDB_SAVE_B), on && comp.fdd[1].rawdata);
  1818.    EnableWindow(GetDlgItem(dlg, IDB_SAVE_C), on && comp.fdd[2].rawdata);
  1819.    EnableWindow(GetDlgItem(dlg, IDB_SAVE_D), on && comp.fdd[3].rawdata);
  1820.  
  1821.    ShowWindow(GetDlgItem(dlg, IDC_MODA), comp.fdd[0].optype? SW_SHOW : SW_HIDE);
  1822.    ShowWindow(GetDlgItem(dlg, IDC_MODB), comp.fdd[1].optype? SW_SHOW : SW_HIDE);
  1823.    ShowWindow(GetDlgItem(dlg, IDC_MODC), comp.fdd[2].optype? SW_SHOW : SW_HIDE);
  1824.    ShowWindow(GetDlgItem(dlg, IDC_MODD), comp.fdd[3].optype? SW_SHOW : SW_HIDE);
  1825.    return 1;
  1826. }
  1827. //=============================================================================
  1828.  
  1829. // Ngs=true/Zc=false
  1830.  
  1831. //=============================================================================
  1832. static bool OpenSdImage(bool Ngs)
  1833. {
  1834.    OPENFILENAME fn = { };
  1835.  
  1836.    char SdImage[FILENAME_MAX];
  1837.    SdImage[0] = 0;
  1838.  
  1839.    fn.lStructSize = (WinVerMajor < 5) ? OPENFILENAME_SIZE_VERSION_400 : sizeof(OPENFILENAME);
  1840.    fn.hwndOwner = dlg;
  1841.    fn.lpstrFilter = "SD card image (*.*)\0*.*\0";
  1842.    fn.lpstrFile = SdImage;
  1843.    fn.nMaxFile = _countof(SdImage);
  1844.    fn.lpstrTitle = "Select SD card image";
  1845.    fn.Flags = OFN_CREATEPROMPT | OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
  1846.    fn.lpstrInitialDir   = temp.SdDir;
  1847.    if (!GetOpenFileName(&fn))
  1848.        return false;
  1849.    strcpy(temp.SdDir, fn.lpstrFile);
  1850.    char *Ptr = strrchr(temp.SdDir, '\\');
  1851.    if(Ptr)
  1852.     *Ptr = 0;
  1853.  
  1854.    int file = open(SdImage, O_RDONLY | O_BINARY, S_IREAD);
  1855.    if(file < 0)
  1856.        return false;
  1857.    __int64 sz = _filelengthi64(file);
  1858.    close(file);
  1859.  
  1860.    strcpy(Ngs ? c1.ngs_sd_card_path : c1.zc_sd_card_path, SdImage);
  1861.    return true;
  1862. }
  1863. //=============================================================================
  1864.  
  1865.  
  1866. //=============================================================================
  1867. static void NgsDlgSetEnable()
  1868. {
  1869.     bool on = (c1.gs_type != 0);
  1870.     EnableWindow(GetDlgItem(dlg, IDC_COMBO_GS_RAM_SIZE), on);
  1871.     EnableWindow(GetDlgItem(dlg, IDB_SD_NGS), on);
  1872. }
  1873. //=============================================================================
  1874.  
  1875.  
  1876. //=============================================================================
  1877. static INT_PTR CALLBACK NgsDlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  1878. {
  1879.    ::dlg = dlg;
  1880.     switch(msg)
  1881.     {
  1882.     case WM_INITDIALOG:
  1883.     {
  1884.         HWND CbGsType = GetDlgItem(dlg, IDC_COMBO_GS_TYPE);
  1885.         ComboBox_AddString(CbGsType, "None"); // 0
  1886.         ComboBox_AddString(CbGsType, "Z80"); // 1
  1887.         ComboBox_AddString(CbGsType, "Bass"); // 2
  1888.  
  1889.         HWND CbGsRamSize = GetDlgItem(dlg, IDC_COMBO_GS_RAM_SIZE);
  1890.         ComboBox_AddString(CbGsRamSize, "512"); // 0
  1891.         ComboBox_AddString(CbGsRamSize, "2048"); // 1
  1892.         ComboBox_AddString(CbGsRamSize, "4096"); // 2
  1893.  
  1894.         return TRUE;
  1895.     }
  1896.  
  1897.     case WM_COMMAND:
  1898.         {
  1899.             unsigned id = LOWORD(wp);
  1900.             unsigned nc = HIWORD(wp);
  1901.             if ((id == IDB_SD_NGS) && (nc == BN_CLICKED))
  1902.             {
  1903.                 if (OpenSdImage(true))
  1904.                 {
  1905.                     SetDlgItemText(dlg, IDE_SD_NGS, c1.ngs_sd_card_path);
  1906.                 }
  1907.                 return TRUE;
  1908.             }
  1909.  
  1910.             if ((id == IDC_COMBO_GS_TYPE) && (nc == CBN_SELCHANGE))
  1911.             {
  1912.                 c1.gs_type = u8(ComboBox_GetCurSel(HWND(lp)));
  1913.  
  1914.                 NgsDlgSetEnable();
  1915.                 return TRUE;
  1916.             }
  1917.  
  1918.             if ((id == IDC_COMBO_GS_RAM_SIZE) && (nc == CBN_SELCHANGE))
  1919.             {
  1920.                 int GsRamSize = ComboBox_GetCurSel(HWND(lp));
  1921.                 switch (GsRamSize)
  1922.                 {
  1923.                 case 0:
  1924.                     c1.gs_ramsize = 512;
  1925.                     break;
  1926.                 case 1:
  1927.                     c1.gs_ramsize = 2048;
  1928.                     break;
  1929.                 case 2:
  1930.                     c1.gs_ramsize = 4096;
  1931.                     break;
  1932.                 }
  1933.                 return TRUE;
  1934.             }
  1935.         }
  1936.         return FALSE;
  1937.  
  1938.     case WM_NOTIFY:
  1939.     break;
  1940.  
  1941.     default:
  1942.         return FALSE;
  1943.     }
  1944.  
  1945.     // WM_NOTIFY
  1946.     const NMHDR *nm = (const NMHDR *)lp;
  1947.     if (nm->code == PSN_KILLACTIVE)
  1948.     {
  1949.     }
  1950.  
  1951.     if (nm->code == PSN_SETACTIVE)
  1952.     {
  1953.         lastpage = "NGS";
  1954.         SetDlgItemText(dlg, IDE_SD_NGS, c1.ngs_sd_card_path);
  1955.  
  1956.  
  1957.         ComboBox_SetCurSel(GetDlgItem(dlg, IDC_COMBO_GS_TYPE), c1.gs_type);
  1958.  
  1959.         switch (c1.gs_ramsize)
  1960.         {
  1961.         case 512:
  1962.             ComboBox_SetCurSel(GetDlgItem(dlg, IDC_COMBO_GS_RAM_SIZE), 0);
  1963.             break;
  1964.         case 2048:
  1965.             ComboBox_SetCurSel(GetDlgItem(dlg, IDC_COMBO_GS_RAM_SIZE), 1);
  1966.             break;
  1967.         case 4096:
  1968.             ComboBox_SetCurSel(GetDlgItem(dlg, IDC_COMBO_GS_RAM_SIZE), 2);
  1969.             break;
  1970.         }
  1971.  
  1972.         NgsDlgSetEnable();
  1973.  
  1974.         return TRUE;
  1975.     }
  1976.  
  1977.     if (nm->code == PSN_APPLY) dlgok = 1;
  1978.     if (nm->code == PSN_RESET) dlgok = 0;
  1979.  
  1980.     return TRUE;
  1981. }
  1982. //=============================================================================
  1983.  
  1984.  
  1985. //=============================================================================
  1986. static void ZcDlgEnableControls()
  1987. {
  1988.     EnableWindow(GetDlgItem(dlg, IDE_SD_ZC), c1.zc);
  1989.     EnableWindow(GetDlgItem(dlg, IDB_SD_ZC), c1.zc);
  1990. }
  1991. //=============================================================================
  1992.  
  1993.  
  1994. //=============================================================================
  1995. static INT_PTR CALLBACK ZcDlg(HWND dlg, UINT msg, WPARAM wp, LPARAM lp)
  1996. {
  1997.    ::dlg = dlg;
  1998.     switch(msg)
  1999.     {
  2000.     case WM_INITDIALOG:
  2001.         return TRUE;
  2002.  
  2003.     case WM_COMMAND:
  2004.         {
  2005.             unsigned id = LOWORD(wp);
  2006.             unsigned nc = HIWORD(wp);
  2007.             if ((id == IDB_SD_ZC) && (nc == BN_CLICKED)) // ═рцрЄшх ъэюяъш [...]
  2008.             {
  2009.                 if (OpenSdImage(false))
  2010.                 {
  2011.                     SetDlgItemText(dlg, IDE_SD_ZC, c1.zc_sd_card_path);
  2012.                 }
  2013.                 return TRUE;
  2014.             }
  2015.             if ((id == IDC_ZC_ENABLED) && (nc == BN_CLICKED))
  2016.             {
  2017.                 c1.zc = getcheck(IDC_ZC_ENABLED);
  2018.                 ZcDlgEnableControls();
  2019.                 return TRUE;
  2020.             }
  2021.         }
  2022.         return FALSE;
  2023.  
  2024.     case WM_NOTIFY:
  2025.     break;
  2026.  
  2027.     default:
  2028.         return FALSE;
  2029.     }
  2030.  
  2031.     // WM_NOTIFY
  2032.     const NMHDR *nm = (const NMHDR *)lp;
  2033.     if (nm->code == PSN_KILLACTIVE)
  2034.     {
  2035.     }
  2036.  
  2037.     if (nm->code == PSN_SETACTIVE)
  2038.     {
  2039.         lastpage = "ZC";
  2040.         SetDlgItemText(dlg, IDE_SD_ZC, c1.zc_sd_card_path);
  2041.         setcheck(IDC_ZC_ENABLED, c1.zc);
  2042.  
  2043.         ZcDlgEnableControls();
  2044.         return TRUE;
  2045.     }
  2046.  
  2047.     if (nm->code == PSN_APPLY) dlgok = 1;
  2048.     if (nm->code == PSN_RESET) dlgok = 0;
  2049.  
  2050.     return TRUE;
  2051. }
  2052. //=============================================================================
  2053.  
  2054.  
  2055. //=============================================================================
  2056. void setup_dlg()
  2057. {
  2058.    PROPSHEETPAGE psp[18] = { };
  2059.    PROPSHEETPAGE *ps = psp;
  2060.  
  2061.    ps->pszTemplate   = MAKEINTRESOURCE(IDD_MEM);
  2062.    ps->pszTitle      = "MEMORY";
  2063.    ps->pfnDlgProc    = MemDlg;
  2064.    ps++;
  2065.  
  2066.    ps->pszTemplate   = MAKEINTRESOURCE(IDD_VIDEO);
  2067.    ps->pszTitle      = "VIDEO";
  2068.    ps->pfnDlgProc    = VideoDlg;
  2069.    ps++;
  2070.  
  2071.    ps->pszTemplate   = MAKEINTRESOURCE(IDD_ULA);
  2072.    ps->pszTitle      = "ULA";
  2073.    ps->pfnDlgProc    = UlaDlg;
  2074.    ps++;
  2075.  
  2076.    ps->pszTemplate   = MAKEINTRESOURCE(IDD_HDD);
  2077.    ps->pszTitle      = "HDD";
  2078.    ps->pfnDlgProc    = HddDlg;
  2079.    ps++;
  2080.  
  2081.    ps->pszTemplate   = MAKEINTRESOURCE(IDD_SETTINGS_ZC);
  2082.    ps->pszTitle      = "ZC";
  2083.    ps->pfnDlgProc    = ZcDlg;
  2084.    ps++;
  2085.    
  2086.    ps->pszTemplate   = MAKEINTRESOURCE(IDD_EFF7);
  2087.    ps->pszTitle      = "EFF7";
  2088.    ps->pfnDlgProc    = EFF7Dlg;
  2089.    ps++;
  2090.  
  2091.    ps->pszTemplate   = MAKEINTRESOURCE(IDD_CHIP);
  2092.    ps->pszTitle      = "AY";
  2093.    ps->pfnDlgProc    = ChipDlg;
  2094.    ps++;
  2095.  
  2096. //-----------------------------------------------------------------------------
  2097.  
  2098.    ps->pszTemplate   = MAKEINTRESOURCE(IDD_SOUND);
  2099.    ps->pszTitle      = "SOUND";
  2100.    ps->pfnDlgProc    = SoundDlg;
  2101.    ps++;
  2102.  
  2103.    ps->pszTemplate   = MAKEINTRESOURCE(IDD_INPUT);
  2104.    ps->pszTitle      = "INPUT";
  2105.    ps->pfnDlgProc    = InputDlg;
  2106.    ps++;
  2107.  
  2108.    ps->pszTemplate   = MAKEINTRESOURCE(IDD_TAPE);
  2109.    ps->pszTitle      = "TAPE";
  2110.    ps->pfnDlgProc    = TapeDlg;
  2111.    ps++;
  2112.  
  2113.    ps->pszTemplate   = MAKEINTRESOURCE(IDD_BETA128);
  2114.    ps->pszTitle      = "Beta128";
  2115.    ps->pfnDlgProc    = BetaDlg;
  2116.    ps++;
  2117.  
  2118.    ps->pszTemplate   = MAKEINTRESOURCE(IDD_SETTINGS_NGS);
  2119.    ps->pszTitle      = "NGS";
  2120.    ps->pfnDlgProc    = NgsDlg;
  2121.    ps++;
  2122.  
  2123.    ps->pszTemplate   = MAKEINTRESOURCE(IDD_LEDS);
  2124.    ps->pszTitle      = "LEDS";
  2125.    ps->pfnDlgProc    = LedsDlg;
  2126.    ps++;
  2127. //-----------------------------------------------------------------------------
  2128.  
  2129.  
  2130. //-----------------------------------------------------------------------------
  2131.    PROPSHEETHEADER psh = { sizeof(PROPSHEETHEADER) };
  2132.    psh.dwFlags          = PSH_USEICONID | PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW | (lastpage ? PSH_USEPSTARTPAGE : 0);
  2133.    psh.hwndParent       = wnd;
  2134.    psh.hInstance        = hIn;
  2135.    psh.pszIcon          = MAKEINTRESOURCE(IDI_ICON2);
  2136.    psh.pszCaption       = "Emulation Settings";
  2137.    psh.ppsp             = (LPCPROPSHEETPAGE)&psp;
  2138.    psh.pStartPage       = lastpage;
  2139.    psh.nPages           = UINT(ps - psp);
  2140.  
  2141.    for (unsigned i = 0; i < psh.nPages; i++)
  2142.    {
  2143.       psp[i].dwSize = sizeof(PROPSHEETPAGE);
  2144.       psp[i].hInstance = hIn;
  2145.       psp[i].dwFlags = PSP_USETITLE;
  2146.    }
  2147.  
  2148.    OnEnterGui();
  2149.    // temp.rflags = RF_MONITOR; set_video();
  2150.  
  2151.    bool MemModelChanged = false;
  2152.    bool NgsSdImageChanged = false;
  2153.    bool ZcSdImageChanged = false;
  2154.    c1 = conf; PropertySheet(&psh);
  2155.    if (dlgok) {
  2156.            if (conf.render != c1.render)
  2157.                temp.scale = 1;
  2158.            if (conf.mem_model != c1.mem_model)
  2159.                MemModelChanged = true;
  2160.            if (strcmp(conf.ngs_sd_card_path, c1.ngs_sd_card_path) != 0)
  2161.                NgsSdImageChanged = true;
  2162.            if (strcmp(conf.zc_sd_card_path, c1.zc_sd_card_path) != 0)
  2163.                ZcSdImageChanged = true;
  2164.  
  2165. #ifdef MOD_GSZ80
  2166.            if (conf.gs_type == 1 && c1.gs_type != 1)
  2167.            {
  2168.                done_gs();
  2169.            }
  2170. #endif // MOD_GSZ80
  2171.  
  2172. #ifdef MOD_GSBASS
  2173.            if (conf.gs_type == 2 && c1.gs_type != 2)
  2174.            {
  2175.                reset_gs();
  2176.            }
  2177. #endif // MOD_GSBASS
  2178.  
  2179.            conf = c1;
  2180.            frametime = conf.frame; //Alone Coder 0.36.5
  2181.    };
  2182.  
  2183.    eat();
  2184.    SendMessage(wnd, WM_SETFOCUS, (WPARAM)wnd, 0); // show cursor for 'kempston on mouse'
  2185.  
  2186.    if (dlgok)
  2187.    {
  2188.        applyconfig(false);
  2189.    }
  2190.  
  2191.    OnExitGui();
  2192.  
  2193.    extern void main_reset();
  2194.    if (MemModelChanged)
  2195.    {
  2196.         //main_reset(); //єсхтрф№яшфюЁютчрЄръюх!
  2197.    }
  2198.    else
  2199.    {
  2200.        if (NgsSdImageChanged)
  2201.        {
  2202.            SdCard.Reset();
  2203.        }
  2204.        if (ZcSdImageChanged)
  2205.        {
  2206.            Zc.Reset();
  2207.        }
  2208.    }
  2209. }
  2210. //=============================================================================
  2211.  
  2212.  
  2213. #endif
  2214.