Subversion Repositories pentevo

Rev

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

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