Subversion Repositories pentevo

Rev

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