]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
2400b14
authorToni Wilen <twilen@winuae.net>
Sat, 28 Jan 2012 16:06:59 +0000 (18:06 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 28 Jan 2012 16:06:59 +0000 (18:06 +0200)
26 files changed:
cfgfile.cpp
custom.cpp
gfxutil.cpp
include/inputdevice.h
include/keyboard.h
include/options.h
include/xwin.h
inputdevice.cpp
inputevents.def
od-win32/ahidsound_dsonly.cpp
od-win32/clipboard_win32.cpp
od-win32/dinput.cpp
od-win32/direct3d.cpp
od-win32/direct3d.h
od-win32/dxwrap.cpp
od-win32/dxwrap.h
od-win32/keyboard_win32.cpp
od-win32/picasso96_win.cpp
od-win32/resources/resource
od-win32/resources/winuae.rc
od-win32/win32.cpp
od-win32/win32.h
od-win32/win32gfx.cpp
od-win32/win32gfx.h
od-win32/win32gui.cpp
od-win32/winuaechangelog.txt

index cc2b407963c1ef86a16456a4b52b5af61aff5dbd..7d7bd5d39e18ab1fd76096e8cd83ceb07e206a81 100644 (file)
@@ -793,6 +793,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
        cfgfile_dwrite_str (f, L"magic_mousecursor", magiccursors[p->input_magic_mouse_cursor]);
        cfgfile_dwrite_str (f, L"absolute_mouse", abspointers[p->input_tablet]);
        cfgfile_dwrite_bool (f, L"clipboard_sharing", p->clipboard_sharing);
+       cfgfile_dwrite_bool (f, L"native_code", p->native_code);
 
        cfgfile_write (f, L"gfx_display", L"%d", p->gfx_display);
        cfgfile_dwrite_str (f, L"gfx_display_name", p->gfx_display_name);
@@ -812,6 +813,8 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
 
        cfgfile_write (f, L"gfx_backbuffers", L"%d", p->gfx_apmode[0].gfx_backbuffers);
        cfgfile_write (f, L"gfx_backbuffers_rtg", L"%d", p->gfx_apmode[1].gfx_backbuffers);
+       if (p->gfx_apmode[0].gfx_interlaced)
+               cfgfile_write_bool (f, L"gfx_interlace", p->gfx_apmode[0].gfx_interlaced);
        cfgfile_write_str (f, L"gfx_vsync", vsyncmodes[p->gfx_apmode[0].gfx_vsync]);
        cfgfile_write_str (f, L"gfx_vsyncmode", vsyncmodes2[p->gfx_apmode[0].gfx_vsyncmode]);
        cfgfile_write_str (f, L"gfx_vsync_picasso", vsyncmodes[p->gfx_apmode[1].gfx_vsync]);
@@ -929,6 +932,7 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
                if (p->cr[i].rate <= 0)
                        continue;
                struct chipset_refresh *cr = &p->cr[i];
+               cr->index = i;
                _stprintf (tmp, L"%f", cr->rate);
                TCHAR *s = tmp + _tcslen (tmp);
                if (cr->label[0] > 0 && i < MAX_CHIPSET_REFRESH)
@@ -1478,6 +1482,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
                || cfgfile_yesno (option, value, L"gfx_autoresolution", &p->gfx_autoresolution)
                || cfgfile_intval (option, value, L"gfx_backbuffers", &p->gfx_apmode[0].gfx_backbuffers, 1)
                || cfgfile_intval (option, value, L"gfx_backbuffers_rtg", &p->gfx_apmode[1].gfx_backbuffers, 1)
+               || cfgfile_yesno (option, value, L"gfx_interlace", &p->gfx_apmode[0].gfx_interlaced)
                
                || cfgfile_intval (option, value, L"gfx_center_horizontal_position", &p->gfx_xcenter_pos, 1)
                || cfgfile_intval (option, value, L"gfx_center_vertical_position", &p->gfx_ycenter_pos, 1)
@@ -1539,6 +1544,7 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
                || cfgfile_yesno (option, value, L"warp", &p->turbo_emulation)
                || cfgfile_yesno (option, value, L"headless", &p->headless)
                || cfgfile_yesno (option, value, L"clipboard_sharing", &p->clipboard_sharing)
+               || cfgfile_yesno (option, value, L"native_code", &p->native_code)
                || cfgfile_yesno (option, value, L"bsdsocket_emu", &p->socket_emu))
                return 1;
 
@@ -3991,6 +3997,7 @@ void default_prefs (struct uae_prefs *p, int type)
        p->cart_internal = 1;
        p->sana2 = 0;
        p->clipboard_sharing = false;
+       p->native_code = false;
 
        p->cs_compatible = 1;
        p->cs_rtc = 2;
@@ -4108,9 +4115,11 @@ void default_prefs (struct uae_prefs *p, int type)
        struct chipset_refresh *cr;
        for (int i = 0; i < MAX_CHIPSET_REFRESH_TOTAL; i++) {
                cr = &p->cr[i];
+               cr->index = i;
                cr->rate = -1;
        }
        cr = &p->cr[CHIPSET_REFRESH_PAL];
+       cr->index = CHIPSET_REFRESH_PAL;
        cr->horiz = -1;
        cr->vert = -1;
        cr->lace = -1;
@@ -4121,6 +4130,7 @@ void default_prefs (struct uae_prefs *p, int type)
        cr->locked = false;
        _tcscpy (cr->label, L"PAL");
        cr = &p->cr[CHIPSET_REFRESH_NTSC];
+       cr->index = CHIPSET_REFRESH_NTSC;
        cr->horiz = -1;
        cr->vert = -1;
        cr->lace = -1;
index d0e0783213a9c180771762f92842996c87aabe54..245d6149a69546568116d866cd4263661b5ae66d 100644 (file)
@@ -140,7 +140,7 @@ static int lof_current; // what display device thinks
 static int lol;
 static int next_lineno, prev_lineno;
 static enum nln_how nextline_how;
-static int lof_changed = 0;
+static int lof_changed = 0, interlace_changed = 0;
 static int scandoubled_line;
 static bool vsync_rendered;
 static int jitcount = 0;
@@ -185,7 +185,9 @@ static int maxvpos_total = 511;
 int minfirstline = VBLANK_ENDLINE_PAL;
 int equ_vblank_endline = EQU_ENDLINE_PAL;
 double vblank_hz = VBLANK_HZ_PAL, fake_vblank_hz, vblank_hz_stored;
-int vblank_skip, doublescan;
+static int vblank_hz_mult, vblank_hz_state;
+static struct chipset_refresh *stored_chipset_refresh;
+int doublescan;
 frame_time_t syncbase;
 static int fmode;
 uae_u16 beamcon0, new_beamcon0;
@@ -2729,13 +2731,16 @@ int vsynctime_orig;
 void compute_vsynctime (void)
 {
        fake_vblank_hz = 0;
+       vblank_hz_mult = 0;
+       vblank_hz_state = 1;
        if (abs (currprefs.chipset_refreshrate) > 0.1) {
                vblank_hz = currprefs.chipset_refreshrate;
                if (isvsync_chipset ()) {
-                       vblank_skip = 1;
-                       if (!fake_vblank_hz && getvsyncrate (vblank_hz) != vblank_hz) {
-                               vblank_hz = getvsyncrate (vblank_hz);
-                               vblank_skip = -1;
+                       int mult = 0;
+                       if (!fake_vblank_hz && getvsyncrate (vblank_hz, &mult) != vblank_hz) {
+                               vblank_hz = getvsyncrate (vblank_hz, &vblank_hz_mult);
+                               if (vblank_hz_mult > 0)
+                                       vblank_hz_state = 0;
                        }
                }
        }
@@ -2745,9 +2750,11 @@ void compute_vsynctime (void)
                vsynctime = vsynctime_orig = 1;
        else
                vsynctime = vsynctime_orig = syncbase / fake_vblank_hz;
+#if 0
        if (!picasso_on) {
                updatedisplayarea ();
        }
+#endif
        if (currprefs.produce_sound > 1)
                update_sound (fake_vblank_hz, (bplcon0 & 4) ? -1 : lof_store, islinetoggle ());
 }
@@ -2770,6 +2777,149 @@ int current_maxvpos (void)
        return maxvpos + (lof_store ? 1 : 0);
 }
 
+static struct chipset_refresh *get_chipset_refresh (void)
+{
+       int islace = (bplcon0 & 4) ? 1 : 0;
+       int isntsc = (beamcon0 & 0x20) ? 0 : 1;
+
+       if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
+               isntsc = currprefs.ntscmode ? 1 : 0;
+
+       for (int i = 0; i < MAX_CHIPSET_REFRESH_TOTAL; i++) {
+               struct chipset_refresh *cr = &currprefs.cr[i];
+               if ((cr->horiz < 0 || cr->horiz == maxhpos) &&
+                       (cr->vert < 0 || cr->vert == maxvpos_nom) &&
+                       (cr->ntsc < 0 || (cr->ntsc > 0 && isntsc) || (cr->ntsc == 0 && !isntsc)) &&
+                       (cr->lace < 0 || (cr->lace > 0 && islace) || (cr->lace == 0 && !islace)) &&
+                       (cr->framelength < 0 || (cr->framelength > 0 && lof_store) || (cr->framelength == 0 && !lof_store) || (cr->framelength >= 0 && islace)) &&
+                       ((cr->rtg && picasso_on) || (!cr->rtg && !picasso_on)) &&
+                       (cr->vsync < 0 || (cr->vsync > 0 && isvsync_chipset ()) || (cr->vsync == 0 && !isvsync_chipset ())))
+                               return cr;
+       }
+       return NULL;
+}
+
+static bool changed_chipset_refresh (void)
+{
+       return stored_chipset_refresh != get_chipset_refresh ();
+}
+
+static void compute_framesync (void)
+{
+       int islace = (bplcon0 & 4) ? 1 : 0;
+       int isntsc = (beamcon0 & 0x20) ? 0 : 1;
+       bool found = false;
+
+       struct chipset_refresh *cr = get_chipset_refresh ();
+       while (cr) {
+               double v = -1;
+               if (!picasso_on) {
+                       if (isvsync_chipset ()) {
+                               if (cr->index == CHIPSET_REFRESH_PAL || cr->index == CHIPSET_REFRESH_NTSC) {
+                                       if ((abs (vblank_hz - 50) < 1 || abs (vblank_hz - 60) < 1) && currprefs.gfx_apmode[0].gfx_vsync == 2 && currprefs.gfx_apmode[0].gfx_fullscreen > 0) {
+                                               vsync_switchmode (vblank_hz > 55 ? 60 : 50);
+                                       }
+                               }
+                               if (isvsync_chipset () < 0) {
+                                       double v2;
+                                       v2 = vblank_calibrate (cr->locked ? cr->rate : vblank_hz, cr->locked);
+                                       if (!cr->locked)
+                                               v = v2;
+                               }
+                       } else {
+                               if (cr->locked == false) {
+                                       changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate = vblank_hz;
+                                       cfgfile_parse_lines (&changed_prefs, cr->commands, -1);
+                                       break;
+                               } else {
+                                       v = cr->rate;
+                               }
+                       }
+                       if (v < 0)
+                               v = cr->rate;
+                       if (v > 0) {
+                               changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate = v;
+                               cfgfile_parse_lines (&changed_prefs, cr->commands, -1);
+                       }
+               } else {
+                       if (cr->locked == false)
+                               v = vblank_hz;
+                       else
+                               v = cr->rate;
+                       changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate = v;
+                       cfgfile_parse_lines (&changed_prefs, cr->commands, -1);
+               }
+               found = true;
+               break;
+       }
+       if (!found) {
+               changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate = vblank_hz;
+       }
+       stored_chipset_refresh = cr;
+       interlace_changed = islace;
+
+       if (beamcon0 & 0x80) {
+               int res = GET_RES_AGNUS (bplcon0);
+               int vres = islace ? 1 : 0;
+               int res2, vres2;
+               
+               res2 = currprefs.gfx_resolution;
+               if (doublescan)
+                       res2++;
+               if (res2 > RES_MAX)
+                       res2 = RES_MAX;
+               
+               vres2 = currprefs.gfx_vresolution;
+               if (doublescan && !islace)
+                       vres2--;
+
+               if (vres2 < 0)
+                       vres2 = 0;
+               if (vres2 > VRES_QUAD)
+                       vres2 = VRES_QUAD;
+
+               gfxvidinfo.drawbuffer.inwidth = (((hbstrt > hbstop ? 0 : (maxhpos - (hbstop - hbstrt))) * 2) << res2);
+               gfxvidinfo.drawbuffer.extrawidth = 0;
+               gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth;
+
+               gfxvidinfo.drawbuffer.inheight = (maxvpos - minfirstline) << vres2;
+               gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight;
+
+       } else {
+
+               gfxvidinfo.drawbuffer.inwidth = AMIGA_WIDTH_MAX << currprefs.gfx_resolution;
+               gfxvidinfo.drawbuffer.extrawidth = 1;
+               gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth;
+               gfxvidinfo.drawbuffer.inheight = (maxvpos - minfirstline) << currprefs.gfx_vresolution;
+               gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight;
+
+       }
+
+
+       if (gfxvidinfo.drawbuffer.inwidth > gfxvidinfo.drawbuffer.width)
+               gfxvidinfo.drawbuffer.inwidth = gfxvidinfo.drawbuffer.width;
+       if (gfxvidinfo.drawbuffer.inwidth2 > gfxvidinfo.drawbuffer.width)
+               gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.width;
+
+       if (gfxvidinfo.drawbuffer.inheight > gfxvidinfo.drawbuffer.height)
+               gfxvidinfo.drawbuffer.inheight = gfxvidinfo.drawbuffer.height;
+       if (gfxvidinfo.drawbuffer.inheight2 > gfxvidinfo.drawbuffer.height)
+               gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.height;
+
+       compute_vsynctime ();
+
+       write_log (L"%s mode%s%s V=%.4fHz H=%0.4fHz (%dx%d+%d) IDX=%d\n",
+               isntsc ? L"NTSC" : L"PAL",
+               islace ? L" laced" : L"",
+               doublescan > 0 ? L" dblscan" : L"",
+               vblank_hz, vblank_hz * maxvpos_nom,
+               maxhpos, maxvpos, lof_store ? 1 : 0,
+               cr ? cr->index : -1
+               );
+
+       config_changed = 1;
+}
+
 /* set PAL/NTSC or custom timing variables */
 void init_hz (bool fullinit)
 {
@@ -2871,62 +3021,6 @@ void init_hz (bool fullinit)
                reset_drawing ();
        }
 
-       bool found = false;
-       for (int i = 0; i < MAX_CHIPSET_REFRESH_TOTAL; i++) {
-               struct chipset_refresh *cr = &currprefs.cr[i];
-               if ((cr->horiz < 0 || cr->horiz == maxhpos) &&
-                       (cr->vert < 0 || cr->vert == maxvpos_nom) &&
-                       (cr->ntsc < 0 || (cr->ntsc > 0 && isntsc) || (cr->ntsc == 0 && !isntsc)) &&
-                       (cr->lace < 0 || (cr->lace > 0 && islace) || (cr->lace == 0 && !islace)) &&
-                       (cr->framelength < 0 || (cr->framelength > 0 && lof_store) || (cr->framelength == 0 && !lof_store) || (cr->framelength >= 0 && islace)) &&
-                       ((cr->rtg && picasso_on) || (!cr->rtg && !picasso_on)) &&
-                       (cr->vsync < 0 || (cr->vsync > 0 && isvsync_chipset ()) || (cr->vsync == 0 && !isvsync_chipset ()))) {
-                               double v = -1;
-
-                               if (!picasso_on) {
-                                       if (isvsync_chipset ()) {
-                                               if (i == CHIPSET_REFRESH_PAL || i == CHIPSET_REFRESH_NTSC) {
-                                                       if ((abs (vblank_hz - 50) < 1 || abs (vblank_hz - 60) < 1) && currprefs.gfx_apmode[0].gfx_vsync == 2 && currprefs.gfx_apmode[0].gfx_fullscreen > 0) {
-                                                               vsync_switchmode (vblank_hz > 55 ? 60 : 50);
-                                                       }
-                                               }
-                                               if (isvsync_chipset () < 0) {
-                                                       double v2;
-                                                       v2 = vblank_calibrate (cr->locked ? vblank_hz : cr->rate, cr->locked);
-                                                       if (!cr->locked)
-                                                               v = v2;
-                                               }
-                                       } else {
-                                               if (cr->locked == false) {
-                                                       changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate = vblank_hz;
-                                                       cfgfile_parse_lines (&changed_prefs, cr->commands, -1);
-                                                       break;
-                                               }
-                                               v = cr->rate;
-                                       }
-                                       if (v < 0)
-                                               v = cr->rate;
-                                       if (v > 0) {
-                                               changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate = v;
-                                               cfgfile_parse_lines (&changed_prefs, cr->commands, -1);
-                                       }
-                               } else {
-                                       if (cr->locked == false)
-                                               v = vblank_hz;
-                                       else
-                                               v = cr->rate;
-                                       changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate = v;
-                                       cfgfile_parse_lines (&changed_prefs, cr->commands, -1);
-                               }
-                               found = true;
-                               break;
-               }
-       }
-
-       if (!found) {
-               changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate = vblank_hz;
-       }
-
        maxvpos_total = (currprefs.chipset_mask & CSMASK_ECS_AGNUS) ? 2047 : 511;
        if (maxvpos_total > MAXVPOS)
                maxvpos_total = MAXVPOS;
@@ -2936,68 +3030,14 @@ void init_hz (bool fullinit)
                vblank_hz_stored = vblank_hz;
        }
 
-       if (beamcon0 & 0x80) {
-               int res = GET_RES_AGNUS (bplcon0);
-               int vres = islace ? 1 : 0;
-               int res2, vres2;
-               
-               res2 = currprefs.gfx_resolution;
-               if (doublescan)
-                       res2++;
-               if (res2 > RES_MAX)
-                       res2 = RES_MAX;
-               
-               vres2 = currprefs.gfx_vresolution;
-               if (doublescan && !islace)
-                       vres2--;
-
-               if (vres2 < 0)
-                       vres2 = 0;
-               if (vres2 > VRES_QUAD)
-                       vres2 = VRES_QUAD;
-
-               gfxvidinfo.drawbuffer.inwidth = (((hbstrt > hbstop ? 0 : (maxhpos - (hbstop - hbstrt))) * 2) << res2);
-               gfxvidinfo.drawbuffer.extrawidth = 0;
-               gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth;
-
-               gfxvidinfo.drawbuffer.inheight = (maxvpos - minfirstline) << vres2;
-               gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight;
-
-       } else {
-
-               gfxvidinfo.drawbuffer.inwidth = AMIGA_WIDTH_MAX << currprefs.gfx_resolution;
-               gfxvidinfo.drawbuffer.extrawidth = 1;
-               gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth;
-               gfxvidinfo.drawbuffer.inheight = (maxvpos - minfirstline) << currprefs.gfx_vresolution;
-               gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight;
-
-       }
-
+       compute_framesync ();
 
-       if (gfxvidinfo.drawbuffer.inwidth > gfxvidinfo.drawbuffer.width)
-               gfxvidinfo.drawbuffer.inwidth = gfxvidinfo.drawbuffer.width;
-       if (gfxvidinfo.drawbuffer.inwidth2 > gfxvidinfo.drawbuffer.width)
-               gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.width;
-
-       if (gfxvidinfo.drawbuffer.inheight > gfxvidinfo.drawbuffer.height)
-               gfxvidinfo.drawbuffer.inheight = gfxvidinfo.drawbuffer.height;
-       if (gfxvidinfo.drawbuffer.inheight2 > gfxvidinfo.drawbuffer.height)
-               gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.height;
-
-       compute_vsynctime ();
 #ifdef PICASSO96
        init_hz_p96 ();
 #endif
        if (vblank_hz != ovblank)
                updatedisplayarea ();
        inputdevice_tablet_strobe ();
-       write_log (L"%s mode%s%s V=%.4fHz H=%0.4fHz (%dx%d+%d)\n",
-               isntsc ? L"NTSC" : L"PAL",
-               islace ? L" laced" : L"",
-               doublescan > 0 ? L" dblscan" : L"",
-               vblank_hz, vblank_hz * maxvpos_nom,
-               maxhpos, maxvpos, lof_store ? 1 : 0);
-       config_changed = 1;
 }
 
 void init_hz (void)
@@ -3760,6 +3800,9 @@ static void BPLCON0 (int hpos, uae_u16 v)
        if (bplcon0 == v)
                return;
 
+       if ((bplcon0 & 4) != (v & 4))
+               write_log (L"lace=%d\n", v & 4);
+
        if (!issyncstopped ()) {
                vpos_previous = vpos;
                hpos_previous = hpos;
@@ -5123,8 +5166,12 @@ static void framewait (void)
 
                int freetime;
                extern int extraframewait;
-               vsyncmintime = vsynctime;
                
+               if (!vblank_hz_state)
+                       return;
+
+               vsyncmintime = vsynctime;
+
                if (vs == -2 || vs == -3) {
                        // fastest possible
                        curr_time = vsync_busywait_end ();
@@ -5250,12 +5297,17 @@ static void vsync_handler_pre (void)
        if (!vsync_rendered) {
                vsync_handle_redraw (lof_store, lof_changed);
                vsync_rendered = true;
-               if (isvsync_chipset () == -3) {
+               if (vblank_hz_state != 0 && isvsync_chipset () == -3) {
                        render_screen ();
                        show_screen_maybe ();
                }
        }
 
+       if (vblank_hz_mult > 0)
+               vblank_hz_state ^= 1;
+       else
+               vblank_hz_state = 1;
+
        vsync_handle_check ();
 }
 
@@ -5327,8 +5379,12 @@ static void vsync_handler_post (void)
        }
        if ((beamcon0 & (0x20 | 0x80)) != (new_beamcon0 & (0x20 | 0x80)) || (abs (vpos_count - vpos_count_prev)  > 1))
                init_hz ();
+       else if (lof_changed || interlace_changed != ((bplcon0 & 4) ? 1 : 0) || changed_chipset_refresh ())
+               compute_framesync ();
+#if 0
        if (lof_changed)
                compute_vsynctime ();
+#endif
        vpos_count_prev = vpos_count;
 
        lof_changed = 0;
@@ -5884,8 +5940,10 @@ static void hsync_handler_post (bool onvsync)
                /* fastest possible + last line, render the frame as early as possible */
                vsync_rendered = true;
                vsync_handle_redraw (lof_store, lof_changed);
-               render_screen ();
-               show_screen_maybe ();
+               if (vblank_hz_state) {
+                       render_screen ();
+                       show_screen_maybe ();
+               }
        }
        rtg_vsynccheck ();
 
index 7690ce09c8409b5299426bdc0e6fb4107dd6b19b..44792f2334ddf65ebfc4ebdc336210283c381cae 100644 (file)
 
 #include <math.h>
 
-double getvsyncrate (double hz)
+double getvsyncrate (double hz, int *mult)
 {
-       if (hz > 85)
+       if (hz > 85) {
+               *mult = -1;
                return hz / 2;
+       }
+       if (hz < 35) {
+               *mult = 1;
+               return hz * 2;
+       }
+       *mult = 0;
        return hz;
 }
 
index 9ea6313c04e45f3930a624697a1af459a6c21f00..9572cb193eb0a8fd9cf464dd58c259fded2e39a8 100644 (file)
@@ -51,10 +51,15 @@ extern struct inputdevice_functions inputdevicefunc_mouse;
 extern struct inputdevice_functions inputdevicefunc_keyboard;
 extern int pause_emulation;
 
+struct uae_input_device_default_node
+{
+       int evt;
+       int flags;
+};
+
 struct uae_input_device_kbr_default {
     int scancode;
-    int evt;
-       int flags;
+    struct uae_input_device_default_node node[MAX_INPUT_SUB_EVENT];
 };
 
 struct inputevent {
@@ -66,6 +71,8 @@ struct inputevent {
        int data;
 };
 
+#define MAX_INPUT_QUALIFIERS (8+4)
+
 /* event flags */
 #define ID_FLAG_AUTOFIRE 1
 #define ID_FLAG_TOGGLE 2
@@ -73,10 +80,28 @@ struct inputevent {
 #define ID_FLAG_GAMEPORTSCUSTOM2 8
 #define ID_FLAG_INVERTTOGGLE 16
 
-#define ID_FLAG_SAVE_MASK 0xff
 #define ID_FLAG_GAMEPORTSCUSTOM_MASK (ID_FLAG_GAMEPORTSCUSTOM1 | ID_FLAG_GAMEPORTSCUSTOM2)
 #define ID_FLAG_AUTOFIRE_MASK (ID_FLAG_TOGGLE | ID_FLAG_INVERTTOGGLE | ID_FLAG_AUTOFIRE)
-#define ID_FLAG_TOGGLED 0x100
+#define ID_FLAG_CANRELEASE 0x2000
+#define ID_FLAG_TOGGLED 0x4000
+#define ID_FLAG_CUSTOMEVENT_TOGGLED 0x8000
+#define ID_FLAG_QUALIFIER1 0x00010000
+#define ID_FLAG_QUALIFIER2 0x00020000
+#define ID_FLAG_QUALIFIER3 0x00040000
+#define ID_FLAG_QUALIFIER4 0x00080000
+#define ID_FLAG_QUALIFIER5 0x00100000
+#define ID_FLAG_QUALIFIER6 0x00200000
+#define ID_FLAG_QUALIFIER7 0x00400000
+#define ID_FLAG_QUALIFIER8 0x00800000
+#define ID_FLAG_QUALIFIER_SPECIAL 0x01000000
+#define ID_FLAG_QUALIFIER_SHIFT 0x02000000
+#define ID_FLAG_QUALIFIER_CONTROL 0x04000000
+#define ID_FLAG_QUALIFIER_ALT 0x08000000
+#define ID_FLAG_QUALIFIER_MASK 0x0fff0000
+
+#define ID_FLAG_SAVE_MASK_CONFIG 0xff
+#define ID_FLAG_SAVE_MASK_QUALIFIERS ID_FLAG_QUALIFIER_MASK
+#define ID_FLAG_SAVE_MASK_FULL (ID_FLAG_SAVE_MASK_CONFIG | ID_FLAG_SAVE_MASK_QUALIFIERS)
 
 #define IDEV_WIDGET_NONE 0
 #define IDEV_WIDGET_BUTTON 1
@@ -90,6 +115,19 @@ struct inputevent {
 #define IDEV_MAPPED_INVERTTOGGLE 8
 #define IDEV_MAPPED_GAMEPORTSCUSTOM1 16
 #define IDEV_MAPPED_GAMEPORTSCUSTOM2 32
+#define IDEV_MAPPED_QUALIFIER1 0x00010000
+#define IDEV_MAPPED_QUALIFIER2 0x00020000
+#define IDEV_MAPPED_QUALIFIER3 0x00040000
+#define IDEV_MAPPED_QUALIFIER4 0x00080000
+#define IDEV_MAPPED_QUALIFIER5 0x00100000
+#define IDEV_MAPPED_QUALIFIER6 0x00200000
+#define IDEV_MAPPED_QUALIFIER7 0x00400000
+#define IDEV_MAPPED_QUALIFIER8 0x00800000
+#define IDEV_MAPPED_QUALIFIER_SPECIAL 0x01000000
+#define IDEV_MAPPED_QUALIFIER_SHIFT 0x02000000
+#define IDEV_MAPPED_QUALIFIER_CONTROL 0x04000000
+#define IDEV_MAPPED_QUALIFIER_ALT 0x08000000
+#define IDEV_MAPPED_QUALIFIER_MASK 0x0fff0000
 
 #define ID_BUTTON_OFFSET 0
 #define ID_BUTTON_TOTAL 32
@@ -101,7 +139,7 @@ extern bool inputdevice_set_gameports_mapping (struct uae_prefs *prefs, int devn
 extern int inputdevice_set_mapping (int devnum, int num, const TCHAR *name, TCHAR *custom, int flags, int port, int sub);
 extern int inputdevice_get_mapping (int devnum, int num, int *pflags, int *port, TCHAR *name, TCHAR *custom, int sub);
 extern void inputdevice_copyconfig (const struct uae_prefs *src, struct uae_prefs *dst);
-extern void inputdevice_copy_single_config (struct uae_prefs *p, int src, int dst, int devnum);
+extern void inputdevice_copy_single_config (struct uae_prefs *p, int src, int dst, int devnum, int selectedwidget);
 extern void inputdevice_swap_ports (struct uae_prefs *p, int devnum);
 extern void inputdevice_swap_compa_ports (struct uae_prefs *p, int portswap);
 extern void inputdevice_config_change (void);
@@ -158,6 +196,7 @@ extern void inputdevice_updateconfig (struct uae_prefs *prefs);
 extern void inputdevice_devicechange (struct uae_prefs *prefs);
 
 extern int inputdevice_translatekeycode (int keyboard, int scancode, int state);
+extern void inputdevice_checkqualifierkeycode (int keyboard, int scancode, int state);
 extern void inputdevice_setkeytranslation (struct uae_input_device_kbr_default **trans, int **kbmaps);
 extern void inputdevice_do_keyboard (int code, int state);
 extern int inputdevice_iskeymapped (int keyboard, int scancode);
@@ -213,6 +252,8 @@ extern void inputdevice_tablet (int x, int y, int z,
 extern void inputdevice_tablet_info (int maxx, int maxy, int maxz, int maxax, int maxay, int maxaz, int xres, int yres);
 extern void inputdevice_tablet_strobe (void);
 
+extern int input_getqualifiers (void);
+
 
 #define JSEM_MODE_DEFAULT 0
 #define JSEM_MODE_MOUSE 1
index e1bcbded9b1123349af1503b24c122825a4a70d4..c0d62e99ab452f3103c816008e12f065befaae9e 100644 (file)
@@ -164,7 +164,11 @@ enum aks { AKS_ENTERGUI = 0x200, AKS_SCREENSHOT_FILE, AKS_SCREENSHOT_CLIPBOARD,
        AKS_DISK_PREV0, AKS_DISK_PREV1, AKS_DISK_PREV2, AKS_DISK_PREV3,
        AKS_DISK_NEXT0, AKS_DISK_NEXT1, AKS_DISK_NEXT2, AKS_DISK_NEXT3,
        AKS_CDTV_FRONT_PANEL_STOP, AKS_CDTV_FRONT_PANEL_PLAYPAUSE, AKS_CDTV_FRONT_PANEL_PREV,
-       AKS_CDTV_FRONT_PANEL_NEXT, AKS_CDTV_FRONT_PANEL_REW, AKS_CDTV_FRONT_PANEL_FF
+       AKS_CDTV_FRONT_PANEL_NEXT, AKS_CDTV_FRONT_PANEL_REW, AKS_CDTV_FRONT_PANEL_FF,
+       AKS_QUALIFIER1, AKS_QUALIFIER2, AKS_QUALIFIER3, AKS_QUALIFIER4,
+       AKS_QUALIFIER5, AKS_QUALIFIER6, AKS_QUALIFIER7, AKS_QUALIFIER8,
+       AKS_QUALIFIER_SPECIAL, AKS_QUALIFIER_SHIFT, AKS_QUALIFIER_CONTROL,
+       AKS_QUALIFIER_ALT
 };
 
 extern int target_checkcapslock (int, int *);
\ No newline at end of file
index a6c029d6aa7eef2d170b3d62753cbfa546d24548..2df5ae4cecc39cf318df923b909ca31933db4929 100644 (file)
@@ -36,16 +36,17 @@ struct strlist {
 /* 4 different customization settings */
 #define MAX_INPUT_SETTINGS 4
 #define GAMEPORT_INPUT_SETTINGS 3 // last slot is for gameport panel mappings
-#define MAX_INPUT_SUB_EVENT 4
-#define MAX_INPUT_SUB_EVENT_ALL 5
-#define SPARE_SUB_EVENT 4
+
+#define MAX_INPUT_SUB_EVENT 8
+#define MAX_INPUT_SUB_EVENT_ALL 9
+#define SPARE_SUB_EVENT 8
 
 struct uae_input_device {
        TCHAR *name;
        TCHAR *configname;
        uae_s16 eventid[MAX_INPUT_DEVICE_EVENTS][MAX_INPUT_SUB_EVENT_ALL];
        TCHAR *custom[MAX_INPUT_DEVICE_EVENTS][MAX_INPUT_SUB_EVENT_ALL];
-       uae_u16 flags[MAX_INPUT_DEVICE_EVENTS][MAX_INPUT_SUB_EVENT_ALL];
+       uae_u32 flags[MAX_INPUT_DEVICE_EVENTS][MAX_INPUT_SUB_EVENT_ALL];
        uae_s8 port[MAX_INPUT_DEVICE_EVENTS][MAX_INPUT_SUB_EVENT_ALL];
        uae_s16 extra[MAX_INPUT_DEVICE_EVENTS];
        uae_s8 enabled;
@@ -152,6 +153,7 @@ enum { CP_GENERIC = 1, CP_CDTV, CP_CD32, CP_A500, CP_A500P, CP_A600, CP_A1000,
 #define CHIPSET_REFRESH_NTSC (MAX_CHIPSET_REFRESH + 1)
 struct chipset_refresh
 {
+       int index;
        bool locked;
        bool rtg;
        int horiz;
@@ -172,6 +174,7 @@ struct apmode
        bool gfx_vflip;
        int gfx_vsyncmode;
        int gfx_backbuffers;
+       bool gfx_interlaced;
 };
 
 struct uae_prefs {
@@ -404,6 +407,7 @@ struct uae_prefs {
        bool mmkeyboard;
        int uae_hide;
        bool clipboard_sharing;
+       bool native_code;
 
        int mountitems;
        struct uaedev_config_info mountconfig[MOUNT_CONFIG_SIZE];
@@ -450,7 +454,6 @@ struct uae_prefs {
        int win32_soundcard;
        int win32_samplersoundcard;
        bool win32_norecyclebin;
-       int win32_specialkey;
        int win32_guikey;
        int win32_kbledmode;
        TCHAR win32_commandpathstart[MAX_DPATH];
index 5806d2fe0fbe244ba235be3ab648ddbefe4ad384..e836f579565cc06d400bb7576eeebc644cbc20f7 100644 (file)
@@ -69,7 +69,7 @@ extern void setup_greydither (int bits, allocfunc_type allocfunc);
 extern void setup_greydither_maxcol (int maxcol, allocfunc_type allocfunc);
 extern void setup_dither (int bits, allocfunc_type allocfunc);
 extern void DitherLine (uae_u8 *l, uae_u16 *r4g4b4, int x, int y, uae_s16 len, int bits) ASM_SYM_FOR_FUNC("DitherLine");
-extern double getvsyncrate (double hz);
+extern double getvsyncrate (double hz, int *mult);
 
     /* The graphics code has a choice whether it wants to use a large buffer
      * for the whole display, or only a small buffer for a single line.
index 861c55fc1b43adcbb373ab1983f5dc3657507be8..ed93b8c7beac9662772e36b1da33b96dd79832ff 100644 (file)
@@ -81,6 +81,7 @@ int inputdevice_logging = 0;
 #define AM_DUMMY 128 /* placeholder */
 #define AM_CUSTOM 256 /* custom event */
 #define AM_K (AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT|AM_AF) /* generic button/switch */
+#define AM_KK (AM_KEY|AM_JOY_BUT|AM_MOUSE_BUT)
 
 #define JOYMOUSE_CDTV 8
 
@@ -94,6 +95,9 @@ static struct inputevent events[] = {
 
 static int sublevdir[2][MAX_INPUT_SUB_EVENT];
 
+static const int slotorder1[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+static const int slotorder2[] = { 8, 1, 2, 3, 4, 5, 6, 7 };
+
 struct uae_input_device2 {
        uae_u32 buttonmask;
        int states[MAX_INPUT_DEVICE_EVENTS / 2];
@@ -102,6 +106,7 @@ struct uae_input_device2 {
 static struct uae_input_device2 joysticks2[MAX_INPUT_DEVICES];
 static struct uae_input_device2 mice2[MAX_INPUT_DEVICES];
 static uae_u8 scancodeused[MAX_INPUT_DEVICES][256];
+static int qualifiers;
 
 // fire/left mouse button pullup resistors enabled?
 static bool mouse_pullup = true;
@@ -327,15 +332,26 @@ static bool write_config_head (struct zfile *f, int idnum, int devnum, TCHAR *na
 static bool write_slot (TCHAR *p, struct uae_input_device *uid, int i, int j)
 {
        bool ok = false;
+       int flags = uid->flags[i][j];
        if (uid->custom[i][j] && _tcslen (uid->custom[i][j]) > 0) {
-               _stprintf (p, L"'%s'.%d", uid->custom[i][j], uid->flags[i][j] & ID_FLAG_SAVE_MASK);
+               _stprintf (p, L"'%s'.%d", uid->custom[i][j], flags & ID_FLAG_SAVE_MASK_CONFIG);
                ok = true;
        } else if (uid->eventid[i][j] > 0) {
-               _stprintf (p, L"%s.%d", events[uid->eventid[i][j]].confname, uid->flags[i][j] & ID_FLAG_SAVE_MASK);
+               _stprintf (p, L"%s.%d", events[uid->eventid[i][j]].confname, flags & ID_FLAG_SAVE_MASK_CONFIG);
                ok = true;
        } else {
                _tcscpy (p, L"NULL");
        }
+       if (ok && (flags & ID_FLAG_SAVE_MASK_QUALIFIERS)) {
+               TCHAR *p2 = p + _tcslen (p);
+               *p2++ = '.';
+               for (int i = 0; i < MAX_INPUT_QUALIFIERS; i++) {
+                       if ((ID_FLAG_QUALIFIER1 << i) & flags) {
+                               _stprintf (p2, L"%c", 'A' + i);
+                               p2++;
+                       }
+               }
+       }
        return ok;
 }
 
@@ -356,9 +372,7 @@ static void write_config2 (struct zfile *f, int idnum, int i, int offset, const
        TCHAR tmp2[200], tmp3[200], *p;
        int evt, got, j, k;
        TCHAR *custom;
-       int slotorder1[] = { 0, 1, 2, 3 };
-       int slotorder2[] = { 4, 1, 2, 3 };
-       int *slotorder;
+       const int *slotorder;
        int io = i + offset;
 
        tmp2[0] = 0;
@@ -415,9 +429,7 @@ static void write_kbr_config (struct zfile *f, int idnum, int devnum, struct uae
 {
        TCHAR tmp1[200], tmp2[200], tmp3[200], tmp4[200], tmp5[200], *p;
        int i, j, k, evt, skip;
-       int slotorder1[] = { 0, 1, 2, 3 };
-       int slotorder2[] = { 4, 1, 2, 3 };
-       int *slotorder;
+       const int *slotorder;
 
        if (!keyboard_default)
                return;
@@ -438,25 +450,27 @@ static void write_kbr_config (struct zfile *f, int idnum, int devnum, struct uae
                while (keyboard_default[k].scancode >= 0) {
                        if (keyboard_default[k].scancode == kbr->extra[i]) {
                                skip = 1;
-                               for (j = 1; j < MAX_INPUT_SUB_EVENT; j++) {
-                                       if ((kbr->flags[i][slotorder[j]] & ID_FLAG_SAVE_MASK) != 0 || kbr->eventid[i][slotorder[j]] > 0)
+                               for (j = 0; j < MAX_INPUT_SUB_EVENT; j++) {
+                                       if (keyboard_default[k].node[j].evt != 0) {
+                                               if (keyboard_default[k].node[j].evt != kbr->eventid[i][slotorder[j]] || keyboard_default[k].node[j].flags != (kbr->flags[i][slotorder[j]] & ID_FLAG_SAVE_MASK_FULL))
+                                                       skip = 0;
+                                       } else if ((kbr->flags[i][slotorder[j]] & ID_FLAG_SAVE_MASK_FULL) != 0 || kbr->eventid[i][slotorder[j]] > 0) {
                                                skip = 0;
+                                       }
                                }
-                               if (keyboard_default[k].evt != kbr->eventid[i][slotorder[0]] || keyboard_default[k].flags != (kbr->flags[i][slotorder[0]] & ID_FLAG_SAVE_MASK))
-                                       skip = 0;
                                break;
                        }
                        k++;
                }
                bool isdefaultspare =
                        kbr->port[i][SPARE_SUB_EVENT] &&
-                       keyboard_default[k].evt == kbr->eventid[i][SPARE_SUB_EVENT] && keyboard_default[k].flags == (kbr->flags[i][SPARE_SUB_EVENT] & ID_FLAG_SAVE_MASK);
+                       keyboard_default[k].node[0].evt == kbr->eventid[i][SPARE_SUB_EVENT] && keyboard_default[k].node[0].flags == (kbr->flags[i][SPARE_SUB_EVENT] & ID_FLAG_SAVE_MASK_FULL);
 
                if (kbr->port[i][0] > 0 && !(kbr->flags[i][0] & ID_FLAG_GAMEPORTSCUSTOM_MASK) && 
                        (kbr->eventid[i][1] <= 0 && kbr->eventid[i][2] <= 0 && kbr->eventid[i][3] <= 0) &&
                        (kbr->port[i][SPARE_SUB_EVENT] == 0 || isdefaultspare))
                        skip = 1;
-               if (kbr->eventid[i][0] == 0 && (kbr->flags[i][0] & ID_FLAG_SAVE_MASK) == 0 && keyboard_default[k].scancode < 0)
+               if (kbr->eventid[i][0] == 0 && (kbr->flags[i][0] & ID_FLAG_SAVE_MASK_FULL) == 0 && keyboard_default[k].scancode < 0)
                        skip = 1;
                if (skip) {
                        i++;
@@ -552,6 +566,23 @@ void write_inputdevice_config (struct uae_prefs *p, struct zfile *f)
        }
 }
 
+static int getqual (const TCHAR **pp)
+{
+       const TCHAR *p = *pp;
+       int mask = 0;
+
+       while (*p >= 'A' && *p <= 'Z') {
+               mask |= ID_FLAG_QUALIFIER1 << (*p - 'A');
+               p++;
+       }
+       while (*p != 0 && *p !='.' && *p != ',')
+               p++;
+       if (*p == '.' || *p == ',')
+               p++;
+       *pp = p;
+       return mask;
+}
+
 static int getnum (const TCHAR **pp)
 {
        const TCHAR *p = *pp;
@@ -617,7 +648,7 @@ void reset_inputdevice_config (struct uae_prefs *prefs)
 
 static void set_kbr_default_event (struct uae_input_device *kbr, struct uae_input_device_kbr_default *trans, int num)
 {
-       for (int i = 0;  trans[i].scancode >= 0; i++) {
+       for (int i = 0; trans[i].scancode >= 0; i++) {
                if (kbr->extra[num] == trans[i].scancode) {
                        int k;
                        for (k = 0; k < MAX_INPUT_SUB_EVENT; k++) {
@@ -628,17 +659,40 @@ static void set_kbr_default_event (struct uae_input_device *kbr, struct uae_inpu
                                write_log (L"corrupt default keyboard mappings\n");
                                return;
                        }
-                       kbr->eventid[num][k] = trans[i].evt;
-                       kbr->flags[num][k] = trans[i].flags;
+                       int l = 0;
+                       while (k < MAX_INPUT_SUB_EVENT && trans[i].node[l].evt) {
+                               int evt = trans[i].node[l].evt;
+                               if (evt < 0 || evt >= INPUTEVENT_SPC_LAST)
+                                       gui_message(L"invalid event in default keyboard table!");
+                               kbr->eventid[num][k] = evt;
+                               kbr->flags[num][k] = trans[i].node[l].flags;
+                               l++;
+                               k++;
+                       }
                        break;
                }
        }
 }
 
-static void set_kbr_default (struct uae_prefs *p, int index, int devnum)
+static void clear_id (struct uae_input_device *id)
+{
+#ifndef        _DEBUG
+       int i, j;
+       for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
+               for (j = 0; j < MAX_INPUT_SUB_EVENT_ALL; j++)
+                       xfree (id->custom[i][j]);
+       }
+#endif
+       TCHAR *cn = id->configname;
+       TCHAR *n = id->name;
+       memset (id, 0, sizeof (struct uae_input_device));
+       id->configname = cn;
+       id->name = n;
+}
+
+static void set_kbr_default (struct uae_prefs *p, int index, int devnum, struct uae_input_device_kbr_default *trans)
 {
        int i, j;
-       struct uae_input_device_kbr_default *trans = keyboard_default;
        struct uae_input_device *kbr;
        struct inputdevice_functions *id = &idev[IDTYPE_KEYBOARD];
        uae_u32 scancode;
@@ -650,7 +704,7 @@ static void set_kbr_default (struct uae_prefs *p, int index, int devnum)
                        continue;
                kbr = &p->keyboard_settings[index][j];
                for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
-                       memset (kbr, 0, sizeof (struct uae_input_device));
+                       clear_id (kbr);
                        kbr->extra[i] = -1;
                }
                if (j < id->get_num ()) {
@@ -665,37 +719,21 @@ static void set_kbr_default (struct uae_prefs *p, int index, int devnum)
        }
 }
 
-static void inputdevice_default_kb (struct uae_prefs *p)
+static void inputdevice_default_kb (struct uae_prefs *p, int num)
 {
-       keyboard_default = keyboard_default_table[p->input_keyboard_type];
-       for (int i = 0; i < MAX_INPUT_SETTINGS; i++) {
-               if (i == GAMEPORT_INPUT_SETTINGS) {
-                       if (p->jports[0].id != JPORT_CUSTOM || p->jports[1].id != JPORT_CUSTOM) {
-                               reset_inputdevice_slot (p, i);
-                       }
-               }
-               set_kbr_default (p, i, -1);
+       if (num == GAMEPORT_INPUT_SETTINGS) {
+               if (p->jports[0].id != JPORT_CUSTOM || p->jports[1].id != JPORT_CUSTOM)
+                       reset_inputdevice_slot (p, num);
        }
+       set_kbr_default (p, num, -1, keyboard_default);
 }
-
-static void clear_id (struct uae_input_device *id)
+static void inputdevice_default_kb_all (struct uae_prefs *p)
 {
-#ifndef        _DEBUG
-       int i, j;
-       for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++) {
-               for (j = 0; j < MAX_INPUT_SUB_EVENT_ALL; j++)
-                       xfree (id->custom[i][j]);
-       }
-#endif
-       TCHAR *cn = id->configname;
-       TCHAR *n = id->name;
-       memset (id, 0, sizeof (struct uae_input_device));
-       id->configname = cn;
-       id->name = n;
+       for (int i = 0; i < MAX_INPUT_SETTINGS; i++)
+               inputdevice_default_kb (p, i);
 }
 
-
-static bool readslot (TCHAR *parm, int num, int joystick, int button, struct uae_input_device *id, int keynum, int subnum, struct inputevent *ie, int flags, int port, TCHAR *custom)
+static bool read_slot (TCHAR *parm, int num, int joystick, int button, struct uae_input_device *id, int keynum, int subnum, struct inputevent *ie, int flags, int port, TCHAR *custom)
 {
        int mask;
 
@@ -801,7 +839,8 @@ void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *
                pr->input_analog_joystick_offset = _tstol (value);
        if (!strcasecmp (p, L"keyboard_type")) {
                cfgfile_strval (option, value, NULL, &pr->input_analog_joystick_offset, kbtypes, 0);
-               inputdevice_default_kb (pr);
+               keyboard_default = keyboard_default_table[pr->input_keyboard_type];
+               inputdevice_default_kb_all (pr);
        }
 
        if (!strcasecmp (p, L"contact_bounce"))
@@ -866,7 +905,7 @@ void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *
                if (idnum == GAMEPORT_INPUT_SETTINGS) {
                        clear_id (id);
                        if (joystick < 0)
-                               set_kbr_default (pr, idnum, devnum);
+                               set_kbr_default (pr, idnum, devnum, keyboard_default);
                        id->enabled = iscustom;
                } else {
                        id->enabled = false;
@@ -881,7 +920,7 @@ void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *
                clear_id (id);
                if (!empty) {
                        if (joystick < 0)
-                               set_kbr_default (pr, idnum, devnum);
+                               set_kbr_default (pr, idnum, devnum, keyboard_default);
                }
                id->enabled = 1;
                if (idnum == GAMEPORT_INPUT_SETTINGS)
@@ -936,9 +975,12 @@ void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *
                flags = 0;
                port = 0;
                if (p[-1] == '.')
-                       flags = getnum (&p);
+                       flags = getnum (&p) & ID_FLAG_SAVE_MASK_CONFIG;
                if (p[-1] == '.') {
-                       port = getnum (&p) + 1;
+                       if (p[0] >= 'A' && p[0] <= 'Z')
+                               flags |= getqual (&p);
+                       if (p[-1] == '.')
+                               port = getnum (&p) + 1;
                }
                if (idnum == GAMEPORT_INPUT_SETTINGS && port == 0)
                        continue;
@@ -947,10 +989,12 @@ void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *
                        if (p2) {
                                int flags2 = 0;
                                if (p[-1] == '.')
-                                       flags2 = getnum (&p);
+                                       flags2 = getnum (&p) & ID_FLAG_SAVE_MASK_CONFIG;
+                               if (p[-1] == '.' && p[0] >= 'A' && p[0] <= 'Z')
+                                       flags |= getqual (&p);
                                TCHAR *custom2 = NULL;
                                struct inputevent *ie2 = readevent (p2, &custom2);
-                               readslot (p2, num, joystick, button, id, keynum, SPARE_SUB_EVENT, ie2, flags2, MAX_JPORTS + 1, custom2);
+                               read_slot (p2, num, joystick, button, id, keynum, SPARE_SUB_EVENT, ie2, flags2, MAX_JPORTS + 1, custom2);
                        }
                }
 
@@ -959,7 +1003,7 @@ void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *
                                break;
                        p++;
                }
-               if (!readslot (p2, num, joystick, button, id, keynum, subnum, ie, flags, port, custom))
+               if (!read_slot (p2, num, joystick, button, id, keynum, subnum, ie, flags, port, custom))
                        continue;
                custom = NULL;
        }
@@ -2644,12 +2688,13 @@ end:
        }
 }
 
-int handle_custom_event (TCHAR *custom)
+static int handle_custom_event (TCHAR *custom)
 {
        TCHAR *p, *buf, *nextp;
 
        if (custom == NULL)
                return 0;
+       //write_log (L"%s\n", custom);
        p = buf = my_strdup (custom);
        while (p && *p) {
                TCHAR *p2;
@@ -2668,11 +2713,18 @@ int handle_custom_event (TCHAR *custom)
                cfgfile_parse_line (&changed_prefs, p, 0);
                p = nextp;
        }
-       xfree(buf);
+       xfree (buf);
        config_changed = 1;
        return 0;
 }
 
+static int isqual (int evt)
+{
+       if (evt > INPUTEVENT_SPC_QUALIFIER_START && evt < INPUTEVENT_SPC_QUALIFIER_END)
+               return ID_FLAG_QUALIFIER1 << (evt - INPUTEVENT_SPC_QUALIFIER1);
+       return 0;
+}
+
 static int handle_input_event (int nr, int state, int max, int autofire, bool canstopplayback, bool playbackevent)
 {
        struct inputevent *ie;
@@ -2682,8 +2734,13 @@ static int handle_input_event (int nr, int state, int max, int autofire, bool ca
        if (nr <= 0)
                return 0;
        ie = &events[nr];
-       if (ie->unit == 0 && ie->data >= 0x200)
+       if (isqual (nr))
+               return 0; // qualifiers do nothing
+       if (ie->unit == 0 && ie->data >= 0x200) {
                isaks = true;
+               if (!state) // release AKS_ does nothing
+                       return 0;
+       }
 
        if (!isaks) {
                if (input_record && input_record != INPREC_RECORD_PLAYING)
@@ -2699,7 +2756,7 @@ static int handle_input_event (int nr, int state, int max, int autofire, bool ca
        }
 
        if ((inputdevice_logging & 1) || input_record || input_play)
-               write_log (L"'%s' STATE=%d MAX=%d AF=%d\n", ie->name, state, max, autofire);
+               write_log (L"STATE=%05d MAX=%05d AF=%d QUAL=%08x '%s' \n", state, max, autofire, qualifiers, ie->name);
        if (autofire) {
                if (state)
                        queue_input_event (nr, state, max, currprefs.input_autofire_linecnt, 1);
@@ -3208,12 +3265,66 @@ static int switchdevice (struct uae_input_device *id, int num, bool buttonmode)
        return 0;
 }
 
-static void process_custom_event (struct uae_input_device *id, int offset, int state)
+int input_getqualifiers (void)
+{
+       return qualifiers;
+}
+
+static bool checkqualifiers (int evt, int flags, int qualmask)
+{
+       flags &= ID_FLAG_QUALIFIER_MASK;
+       /* special set and new qualifier pressed? do not sent it to Amiga-side */
+       if ((qualifiers & ID_FLAG_QUALIFIER_SPECIAL) && isqual (evt))
+               return false;
+       if (!qualmask) // no qualifiers in any slot
+               return true;
+       if (flags == qualifiers || (flags && flags == (qualifiers & ~ID_FLAG_QUALIFIER_SPECIAL)))
+               return true;
+       return false;
+}
+static void setqualifiers (int evt, int state)
 {
-       int idx = -1;
-       int custompos = (id->flags[offset][0] >> 15) & 1;
+       int mask = isqual (evt);
+       if (!mask)
+               return;
+       if (state)
+               qualifiers |= mask;
+       else
+               qualifiers &= ~mask;
+}
+static int getqualmask (struct uae_input_device *id, int num, bool *qualonly)
+{
+       int mask = 0, mask2 = 0;
+       for (int i = 0; i < MAX_INPUT_SUB_EVENT; i++) {
+               int evt = id->eventid[num][i];
+               mask |= id->flags[num][i];
+               mask2 |= isqual (evt);
+       }
+       mask &= ID_FLAG_QUALIFIER_MASK;
+       *qualonly = false;
+       if (qualifiers & ID_FLAG_QUALIFIER_SPECIAL) {
+               // ID_FLAG_QUALIFIER_SPECIAL already active and this event has one or more qualifiers configured
+               *qualonly = mask2 != 0;
+       }
+       return mask;
+}
+
+static void process_custom_event (struct uae_input_device *id, int offset, int state, int qualmask)
+{
+       int idx, slotoffset, flags, custompos;
        TCHAR *custom;
 
+       slotoffset = 0;
+       if (!checkqualifiers (id->eventid[offset][slotoffset], id->flags[offset][slotoffset], qualmask)) {
+               slotoffset = 4;
+               if (!checkqualifiers (id->eventid[offset][slotoffset], id->flags[offset][slotoffset], qualmask))
+                       return;
+       }
+
+       flags = id->flags[offset][slotoffset];
+       custompos = (flags & ID_FLAG_CUSTOMEVENT_TOGGLED) ? 1 : 0;
+       idx = -1;
        if (state < 0) {
                idx = 0;
                custompos = 0;
@@ -3224,14 +3335,17 @@ static void process_custom_event (struct uae_input_device *id, int offset, int s
                if (state == 0)
                        custompos ^= 1;
        }
-       custom = id->custom[offset][idx];
+
+       custom = id->custom[offset][idx + slotoffset];
        if (custom == NULL) {
                if (idx >= 2)
-                       custom = id->custom[offset][idx - 2];
+                       custom = id->custom[offset][idx - 2 + slotoffset];
        }
+
        handle_custom_event (custom);
-       id->flags[offset][0] &= ~(1 << 15);
-       id->flags[offset][0] |= custompos << 15;
+
+       id->flags[offset][slotoffset] &= ~ID_FLAG_CUSTOMEVENT_TOGGLED;
+       id->flags[offset][slotoffset] |= custompos ? ID_FLAG_CUSTOMEVENT_TOGGLED : 0;
 }
 
 static void setbuttonstateall (struct uae_input_device *id, struct uae_input_device2 *id2, int button, int state)
@@ -3241,6 +3355,8 @@ static void setbuttonstateall (struct uae_input_device *id, struct uae_input_dev
        uae_u32 mask = 1 << button;
        uae_u32 omask = id2->buttonmask & mask;
        uae_u32 nmask = (state ? 1 : 0) << button;
+       int qualmask;
+       bool qualonly;
 
        if (input_play && state)
                inprec_realtime ();
@@ -3261,17 +3377,27 @@ static void setbuttonstateall (struct uae_input_device *id, struct uae_input_dev
        if (button >= ID_BUTTON_TOTAL)
                return;
 
+       qualmask = getqualmask (id, ID_BUTTON_OFFSET + button, &qualonly);
+
        for (i = 0; i < MAX_INPUT_SUB_EVENT; i++) {
+               uae_u32 *flagsp = &id->flags[ID_BUTTON_OFFSET + button][sublevdir[state <= 0 ? 1 : 0][i]];
                int evt = evt = id->eventid[ID_BUTTON_OFFSET + button][sublevdir[state <= 0 ? 1 : 0][i]];
-               int autofire = (id->flags[ID_BUTTON_OFFSET + button][sublevdir[state <= 0 ? 1 : 0][i]] & ID_FLAG_AUTOFIRE) ? 1 : 0;
-               int toggle = (id->flags[ID_BUTTON_OFFSET + button][sublevdir[state <= 0 ? 1 : 0][i]] & ID_FLAG_TOGGLE) ? 1 : 0;
-               int inverttoggle = (id->flags[ID_BUTTON_OFFSET + button][sublevdir[state <= 0 ? 1 : 0][i]] & ID_FLAG_INVERTTOGGLE) ? 1 : 0;
+               int flags = flagsp[0];
+               int autofire = (flags & ID_FLAG_AUTOFIRE) ? 1 : 0;
+               int toggle = (flags & ID_FLAG_TOGGLE) ? 1 : 0;
+               int inverttoggle = (flags & ID_FLAG_INVERTTOGGLE) ? 1 : 0;
+
+               setqualifiers (flags, state > 0);
+               if (qualonly)
+                       continue;
 
                if (state < 0) {
+                       if (!checkqualifiers (evt, flags, qualmask))
+                               continue;
                        handle_input_event (evt, 1, 1, 0, true, false);
                        queue_input_event (evt, 0, 1, 1, 0); /* send release event next frame */
                        if (i == 0)
-                               process_custom_event (id, ID_BUTTON_OFFSET + button, state);
+                               process_custom_event (id, ID_BUTTON_OFFSET + button, state, qualmask);
                } else if (inverttoggle) {
                        /* pressed = firebutton, not pressed = autofire */
                        if (state) {
@@ -3281,22 +3407,34 @@ static void setbuttonstateall (struct uae_input_device *id, struct uae_input_dev
                                handle_input_event (evt, 1, 1, autofire, true, false);
                        }
                        if (i == 0)
-                               process_custom_event (id, ID_BUTTON_OFFSET + button, 1);
+                               process_custom_event (id, ID_BUTTON_OFFSET + button, 1, qualmask);
                } else if (toggle) {
                        if (!state)
                                continue;
                        if (omask & mask)
                                continue;
-                       id->flags[ID_BUTTON_OFFSET + button][sublevdir[state <= 0 ? 1 : 0][i]] ^= ID_FLAG_TOGGLED;
-                       int toggled = (id->flags[ID_BUTTON_OFFSET + button][sublevdir[state <= 0 ? 1 : 0][i]] & ID_FLAG_TOGGLED) ? 1 : 0;
+                       if (!checkqualifiers (evt, flags, qualmask))
+                               continue;
+                       *flagsp ^= ID_FLAG_TOGGLED;
+                       int toggled = (*flagsp & ID_FLAG_TOGGLED) ? 1 : 0;
                        handle_input_event (evt, toggled, 1, autofire, true, false);
                        if (i == 0)
-                               process_custom_event (id, ID_BUTTON_OFFSET + button, toggled);
+                               process_custom_event (id, ID_BUTTON_OFFSET + button, toggled, qualmask);
                } else {
+                       if (!checkqualifiers (evt, flags, qualmask)) {
+                               if (!state && !(flags & ID_FLAG_CANRELEASE))
+                                       continue;
+                               else if (state)
+                                       continue;
+                       }
+                       if (!state)
+                               *flagsp &= ~ID_FLAG_CANRELEASE;
+                       else
+                               *flagsp |= ID_FLAG_CANRELEASE;
                        if ((omask ^ nmask) & mask) {
                                handle_input_event (evt, state, 1, autofire, true, false);
                                if (i == 0)
-                                       process_custom_event (id, ID_BUTTON_OFFSET + button, state);
+                                       process_custom_event (id, ID_BUTTON_OFFSET + button, state, qualmask);
                        }
                }
        }
@@ -3392,6 +3530,10 @@ static int isdigitalbutton (int ei)
        return 0;
 }
 
+static void isqualifier (int ei)
+{
+}
+
 static void scanevents (struct uae_prefs *p)
 {
        int i, j, k, ei;
@@ -3402,6 +3544,7 @@ static void scanevents (struct uae_prefs *p)
        cd32_pad_enabled[0] = cd32_pad_enabled[1] = 0;
        parport_joystick_enabled = 0;
        mouse_port[0] = mouse_port[1] = 0;
+       qualifiers = 0;
 
        for (i = 0; i < NORMAL_JPORTS; i++) {
                for (j = 0; j < 2; j++) {
@@ -3424,6 +3567,7 @@ static void scanevents (struct uae_prefs *p)
                                        isparport (ei);
                                        ismouse (ei);
                                        isdigitalbutton (ei);
+                                       isqualifier (ei);
                                        if (joysticks[i].eventid[ID_BUTTON_OFFSET + j][k] > 0)
                                                use_joysticks[i] = 1;
                                }
@@ -3434,6 +3578,7 @@ static void scanevents (struct uae_prefs *p)
                                        isparport (ei);
                                        ismouse (ei);
                                        isdigitalbutton (ei);
+                                       isqualifier (ei);
                                        if (mice[i].eventid[ID_BUTTON_OFFSET + j][k] > 0)
                                                use_mice[i] = 1;
                                }
@@ -3449,6 +3594,7 @@ static void scanevents (struct uae_prefs *p)
                                        ismouse (ei);
                                        isanalog (ei);
                                        isdigitalbutton (ei);
+                                       isqualifier (ei);
                                        if (ei > 0)
                                                use_joysticks[i] = 1;
                                }
@@ -3459,6 +3605,7 @@ static void scanevents (struct uae_prefs *p)
                                        ismouse (ei);
                                        isanalog (ei);
                                        isdigitalbutton (ei);
+                                       isqualifier (ei);
                                        if (ei > 0)
                                                use_mice[i] = 1;
                                }
@@ -3478,6 +3625,7 @@ static void scanevents (struct uae_prefs *p)
                                        isparport (ei);
                                        ismouse (ei);
                                        isdigitalbutton (ei);
+                                       isqualifier (ei);
                                        if (ei > 0)
                                                scancodeused[i][keyboards[i].extra[j]] = ei;
                                }
@@ -3704,21 +3852,22 @@ static void checkcompakb (int *kb, int *srcmap)
                struct uae_input_device *uid = &keyboards[0];
                while (kb[j] >= 0) {
                        int id = kb[j];
-                       int evt = 0;
+                       int evt0 = 0, evt1 = 0;
                        k = 0;
                        while (keyboard_default[k].scancode >= 0) {
                                if (keyboard_default[k].scancode == kb[j]) {
-                                       evt = keyboard_default[k].evt;
+                                       for (int l = 0; l < MAX_INPUT_DEVICE_EVENTS; l++) {
+                                               if (uid->extra[l] == id) {
+                                                       for (int m = 0; m < MAX_INPUT_SUB_EVENT && keyboard_default[k].node[m].evt; m++) {
+                                                               uid->eventid[l][m] = keyboard_default[k].node[m].evt;
+                                                       }
+                                                       break;
+                                               }
+                                       }
                                        break;
                                }
                                k++;
                        }
-                       for (int l = 0; l < MAX_INPUT_DEVICE_EVENTS; l++) {
-                               if (uid->extra[l] == id) {
-                                       uid->eventid[l][0] = evt;
-                                       break;
-                               }
-                       }
                        j++;
                }
                j++;
@@ -4692,7 +4841,8 @@ void inputdevice_default_prefs (struct uae_prefs *p)
        p->input_mouse_speed = 100;
        p->input_autofire_linecnt = 600;
        p->input_keyboard_type = 0;
-       inputdevice_default_kb (p);
+       keyboard_default = keyboard_default_table[p->input_keyboard_type];
+       inputdevice_default_kb_all (p);
 }
 
 // set default keyboard and keyboard>joystick layouts
@@ -4735,7 +4885,7 @@ int inputdevice_synccapslock (int oldcaps, int *capstable)
        return -1;
 }
 
-static int inputdevice_translatekeycode_2 (int keyboard, int scancode, int state)
+static int inputdevice_translatekeycode_2 (int keyboard, int scancode, int state, bool qualifiercheckonly)
 {
        struct uae_input_device *na = &keyboards[keyboard];
        int j, k;
@@ -4747,13 +4897,23 @@ static int inputdevice_translatekeycode_2 (int keyboard, int scancode, int state
        j = 0;
        while (j < MAX_INPUT_DEVICE_EVENTS && na->extra[j] >= 0) {
                if (na->extra[j] == scancode) {
+                       bool qualonly;
+                       int qualmask = getqualmask (na, j, &qualonly);
+                       if (qualonly)
+                               qualifiercheckonly = true;
                        for (k = 0; k < MAX_INPUT_SUB_EVENT; k++) {/* send key release events in reverse order */
-                               int autofire = (na->flags[j][sublevdir[state == 0 ? 1 : 0][k]] & ID_FLAG_AUTOFIRE) ? 1 : 0;
-                               int toggle = (na->flags[j][sublevdir[state == 0 ? 1 : 0][k]] & ID_FLAG_TOGGLE) ? 1 : 0;
-                               int inverttoggle = (na->flags[j][sublevdir[state == 0 ? 1 : 0][k]] & ID_FLAG_INVERTTOGGLE) ? 1 : 0;
+                               uae_u32 *flagsp = &na->flags[j][sublevdir[state == 0 ? 1 : 0][k]];
                                int evt = na->eventid[j][sublevdir[state == 0 ? 1 : 0][k]];
+                               int flags = *flagsp;
+                               int autofire = (flags & ID_FLAG_AUTOFIRE) ? 1 : 0;
+                               int toggle = (flags & ID_FLAG_TOGGLE) ? 1 : 0;
+                               int inverttoggle = (flags & ID_FLAG_INVERTTOGGLE) ? 1 : 0;
                                int toggled;
 
+                               setqualifiers (evt, state > 0);
+                               if (qualifiercheckonly)
+                                       continue;
+
                                // if evt == caps and scan == caps: sync with native caps led
                                if (evt == INPUTEVENT_KEY_CAPS_LOCK) {
                                        int v;
@@ -4780,14 +4940,27 @@ static int inputdevice_translatekeycode_2 (int keyboard, int scancode, int state
                                } else if (toggle) {
                                        if (!state)
                                                continue;
-                                       na->flags[j][sublevdir[state == 0 ? 1 : 0][k]] ^= ID_FLAG_TOGGLED;
-                                       toggled = (na->flags[j][sublevdir[state == 0 ? 1 : 0][k]] & ID_FLAG_TOGGLED) ? 1 : 0;
+                                       if (!checkqualifiers (evt, flags, qualmask))
+                                               continue;
+                                       *flagsp ^= ID_FLAG_TOGGLED;
+                                       toggled = (*flagsp & ID_FLAG_TOGGLED) ? 1 : 0;
                                        handled |= handle_input_event (evt, toggled, 1, autofire, true, false);
                                } else {
+                                       if (!checkqualifiers (evt, flags, qualmask)) {
+                                               if (!state && !(flags & ID_FLAG_CANRELEASE))
+                                                       continue;
+                                               else if (state)
+                                                       continue;
+                                       }
+                                       if (state)
+                                               *flagsp |= ID_FLAG_CANRELEASE;
+                                       else
+                                               *flagsp &= ~ID_FLAG_CANRELEASE;
                                        handled |= handle_input_event (evt, state, 1, autofire, true, false);
+
                                }
                        }
-                       process_custom_event (na, j, state);
+                       process_custom_event (na, j, state, qualmask);
                        return handled;
                }
                j++;
@@ -4825,12 +4998,16 @@ static void sendmmcodes (int code, int newstate)
 // main keyboard press/release entry point
 int inputdevice_translatekeycode (int keyboard, int scancode, int state)
 {
-       if (inputdevice_translatekeycode_2 (keyboard, scancode, state))
+       if (inputdevice_translatekeycode_2 (keyboard, scancode, state, false))
                return 1;
        if (currprefs.mmkeyboard && scancode > 0)
                sendmmcodes (scancode, state);
        return 0;
 }
+void inputdevice_checkqualifierkeycode (int keyboard, int scancode, int state)
+{
+       inputdevice_translatekeycode_2 (keyboard, scancode, state, true);
+}
 
 static struct inputdevice_functions idev[3];
 
@@ -5154,14 +5331,18 @@ int inputdevice_get_mapping (int devnum, int num, int *pflags, int *pport, TCHAR
                flags |= IDEV_MAPPED_GAMEPORTSCUSTOM1;
        if (flag & ID_FLAG_GAMEPORTSCUSTOM2)
                flags |= IDEV_MAPPED_GAMEPORTSCUSTOM2;
+       if (flag & ID_FLAG_QUALIFIER_MASK)
+               flags |= flag & ID_FLAG_QUALIFIER_MASK;
+       if (pflags)
+               *pflags = flags;
+       if (pport)
+               *pport = port;
        if (!data)
                return 0;
        if (events[data].allow_mask & AM_AF)
                flags |= IDEV_MAPPED_AUTOFIRE_POSSIBLE;
        if (pflags)
                *pflags = flags;
-       if (pport)
-               *pport = port;
        inputdevice_get_eventname (&events[data], name);
        return data;
 }
@@ -5197,7 +5378,7 @@ int inputdevice_set_mapping (int devnum, int num, const TCHAR *name, TCHAR *cust
                return 0;
        if (data >= 0) {
                amask = events[eid].allow_mask;
-               flag &= ~(ID_FLAG_AUTOFIRE_MASK | ID_FLAG_GAMEPORTSCUSTOM_MASK);
+               flag &= ~(ID_FLAG_AUTOFIRE_MASK | ID_FLAG_GAMEPORTSCUSTOM_MASK | IDEV_MAPPED_QUALIFIER_MASK);
                if (amask & AM_AF) {
                        flag |= (flags & IDEV_MAPPED_AUTOFIRE_SET) ? ID_FLAG_AUTOFIRE : 0;
                        flag |= (flags & IDEV_MAPPED_TOGGLE) ? ID_FLAG_TOGGLE : 0;
@@ -5205,6 +5386,7 @@ int inputdevice_set_mapping (int devnum, int num, const TCHAR *name, TCHAR *cust
                }
                flag |= (flags & IDEV_MAPPED_GAMEPORTSCUSTOM1) ? ID_FLAG_GAMEPORTSCUSTOM1 : 0;
                flag |= (flags & IDEV_MAPPED_GAMEPORTSCUSTOM2) ? ID_FLAG_GAMEPORTSCUSTOM2 : 0;
+               flag |= flags & IDEV_MAPPED_QUALIFIER_MASK;
                if (port >= 0)
                        portp = port;
                put_event_data (idf, devindex, num, eid, custom, flag, portp, sub);
@@ -5346,24 +5528,66 @@ void inputdevice_swap_ports (struct uae_prefs *p, int devnum)
        }
 }
 
+//memcpy (p->joystick_settings[dst], p->joystick_settings[src], sizeof (struct uae_input_device) * MAX_INPUT_DEVICES);
+static void copydev (struct uae_input_device *dst, struct uae_input_device *src)
+{
+       for (int i = 0; i < MAX_INPUT_DEVICES; i++) {
+               for (int j = 0; j < MAX_INPUT_DEVICE_EVENTS; j++) {
+                       for (int k = 0; k < MAX_INPUT_SUB_EVENT_ALL; k++) {
+                               xfree (dst[i].custom[j][k]);
+                       }
+               }
+               xfree (dst[i].configname);
+               xfree (dst[i].name);
+       }
+       memcpy (dst, src, sizeof (struct uae_input_device) * MAX_INPUT_DEVICES);
+       for (int i = 0; i < MAX_INPUT_DEVICES; i++) {
+               for (int j = 0; j < MAX_INPUT_DEVICE_EVENTS; j++) {
+                       for (int k = 0; k < MAX_INPUT_SUB_EVENT_ALL; k++) {
+                               if (dst[i].custom)
+                                       dst[i].custom[j][k] = my_strdup (dst[i].custom[j][k]);
+                       }
+               }
+               dst[i].configname = my_strdup (dst[i].configname);
+               dst[i].name = my_strdup (dst[i].name);
+       }
+}
+
 // copy whole configuration #x-slot to another
-void inputdevice_copy_single_config (struct uae_prefs *p, int src, int dst, int devnum)
+// +1 = default
+// +2 = default (pc keyboard)
+void inputdevice_copy_single_config (struct uae_prefs *p, int src, int dst, int devnum, int selectedwidget)
 {
+       if (src >= MAX_INPUT_SETTINGS) {
+               if (gettype (devnum) == IDTYPE_KEYBOARD) {
+                       p->input_keyboard_type = src > MAX_INPUT_SETTINGS ? 1 : 0;
+                       keyboard_default = keyboard_default_table[p->input_keyboard_type];
+                       inputdevice_default_kb (p, dst);
+               }
+       }
        if (src == dst)
                return;
-       if (devnum < 0 || gettype (devnum) == IDTYPE_JOYSTICK)
-               memcpy (p->joystick_settings[dst], p->joystick_settings[src], sizeof (struct uae_input_device) * MAX_INPUT_DEVICES);
-       if (devnum < 0 || gettype (devnum) == IDTYPE_MOUSE)
-               memcpy (p->mouse_settings[dst], p->mouse_settings[src], sizeof (struct uae_input_device) * MAX_INPUT_DEVICES);
-       if (devnum < 0 || gettype (devnum) == IDTYPE_KEYBOARD)
-               memcpy (p->keyboard_settings[dst], p->keyboard_settings[src], sizeof (struct uae_input_device) * MAX_INPUT_DEVICES);
+       if (src < MAX_INPUT_SETTINGS) {
+               if (devnum < 0 || gettype (devnum) == IDTYPE_JOYSTICK)
+                       copydev (p->joystick_settings[dst], p->joystick_settings[src]);
+               if (devnum < 0 || gettype (devnum) == IDTYPE_MOUSE)
+                       copydev (p->mouse_settings[dst], p->mouse_settings[src]);
+               if (devnum < 0 || gettype (devnum) == IDTYPE_KEYBOARD)
+                       copydev (p->keyboard_settings[dst], p->keyboard_settings[src]);
+       }
 }
 
 void inputdevice_acquire (int allmode)
 {
        int i;
 
-       inputdevice_unacquire ();
+       for (i = 0; i < MAX_INPUT_DEVICES; i++)
+               idev[IDTYPE_JOYSTICK].unacquire (i);
+       for (i = 0; i < MAX_INPUT_DEVICES; i++)
+               idev[IDTYPE_MOUSE].unacquire (i);
+       for (i = 0; i < MAX_INPUT_DEVICES; i++)
+               idev[IDTYPE_KEYBOARD].unacquire (i);
+
        for (i = 0; i < MAX_INPUT_DEVICES; i++) {
                if ((use_joysticks[i] && allmode >= 0) || (allmode && !idev[IDTYPE_JOYSTICK].get_flags (i)))
                        idev[IDTYPE_JOYSTICK].acquire (i, 0);
@@ -5376,6 +5600,13 @@ void inputdevice_acquire (int allmode)
                if ((use_keyboards[i] && allmode >= 0) || (allmode <  0 && !idev[IDTYPE_KEYBOARD].get_flags (i)))
                        idev[IDTYPE_KEYBOARD].acquire (i, allmode < 0);
        }
+
+       if (input_acquired)
+               return;
+
+       idev[IDTYPE_JOYSTICK].acquire (-1, 0);
+       idev[IDTYPE_MOUSE].acquire (-1, 0);
+       idev[IDTYPE_KEYBOARD].acquire (-1, 0);
        //    if (!input_acquired)
        //      write_log (L"input devices acquired (%s)\n", allmode ? "all" : "selected only");
        input_acquired = 1;
@@ -5385,15 +5616,20 @@ void inputdevice_unacquire (void)
 {
        int i;
 
-       //    if (input_acquired)
-       //      write_log (L"input devices unacquired\n");
-       input_acquired = 0;
        for (i = 0; i < MAX_INPUT_DEVICES; i++)
                idev[IDTYPE_JOYSTICK].unacquire (i);
        for (i = 0; i < MAX_INPUT_DEVICES; i++)
                idev[IDTYPE_MOUSE].unacquire (i);
        for (i = 0; i < MAX_INPUT_DEVICES; i++)
                idev[IDTYPE_KEYBOARD].unacquire (i);
+
+       if (!input_acquired)
+               return;
+
+       input_acquired = 0;
+       idev[IDTYPE_JOYSTICK].unacquire (-1);
+       idev[IDTYPE_MOUSE].unacquire (-1);
+       idev[IDTYPE_KEYBOARD].unacquire (-1);
 }
 
 void inputdevice_testrecord (int type, int num, int wtype, int wnum, int state)
index b7c89d03b877108c93bd1a9a7e5e03199bd7a595..b6607b4bdd76b91f2057c4652e3c581ba2922f6f 100644 (file)
@@ -135,6 +135,25 @@ DEFEVENT(PAR_JOY2_2ND_BUTTON,L"Parallel Joy2 Spare/2nd Button",AM_K,4,4,JOYBUTTO
 
 DEFEVENT(PAR_JOY_END, L"", AM_DUMMY, 0,0,0)
 
+/* qualifiers */
+
+DEFEVENT(SPC_QUALIFIER_START,L"Qualifiers",AM_INFO, 0,0,0)
+
+DEFEVENT(SPC_QUALIFIER1,L"Qualifier 1",AM_KK,0,0,AKS_QUALIFIER1)
+DEFEVENT(SPC_QUALIFIER2,L"Qualifier 2",AM_KK,0,0,AKS_QUALIFIER2)
+DEFEVENT(SPC_QUALIFIER3,L"Qualifier 3",AM_KK,0,0,AKS_QUALIFIER3)
+DEFEVENT(SPC_QUALIFIER4,L"Qualifier 4",AM_KK,0,0,AKS_QUALIFIER4)
+DEFEVENT(SPC_QUALIFIER5,L"Qualifier 5",AM_KK,0,0,AKS_QUALIFIER5)
+DEFEVENT(SPC_QUALIFIER6,L"Qualifier 6",AM_KK,0,0,AKS_QUALIFIER6)
+DEFEVENT(SPC_QUALIFIER7,L"Qualifier 7",AM_KK,0,0,AKS_QUALIFIER7)
+DEFEVENT(SPC_QUALIFIER8,L"Qualifier 8",AM_KK,0,0,AKS_QUALIFIER8)
+DEFEVENT(SPC_QUALIFIER_SPECIAL,L"Qualifier Special",AM_KK,0,0,AKS_QUALIFIER_SPECIAL)
+DEFEVENT(SPC_QUALIFIER_SHIFT,L"Qualifier Shift",AM_KK,0,0,AKS_QUALIFIER_SHIFT)
+DEFEVENT(SPC_QUALIFIER_CONTROL,L"Qualifier Control",AM_KK,0,0,AKS_QUALIFIER_CONTROL)
+DEFEVENT(SPC_QUALIFIER_ALT,L"Qualifier Alt",AM_KK,0,0,AKS_QUALIFIER_ALT)
+
+DEFEVENT(SPC_QUALIFIER_END, L"", AM_DUMMY, 0,0,0)
+
 /* keys */
 
 DEFEVENT(KEY_START,L"Keyboard",AM_INFO, 0,0,0)
@@ -334,6 +353,7 @@ DEFEVENT(SPC_STATERESTOREDIALOG,L"Restore state",AM_K,0,0,AKS_STATERESTOREDIALOG
 DEFEVENT(SPC_TOGGLEFULLSCREEN,L"Toggle windowed/fullscreen",AM_K,0,0,AKS_TOGGLEWINDOWEDFULLSCREEN)
 DEFEVENT(SPC_TOGGLEFULLWINDOWFULLSCREEN,L"Toggle full-window/fullscreen",AM_K,0,0,AKS_TOGGLEFULLWINDOWFULLSCREEN)
 DEFEVENT(SPC_TOGGLEWINDOWFULLWINDOW,L"Toggle window/full-window",AM_K,0,0,AKS_TOGGLEWINDOWFULLWINDOW)
+DEFEVENT(SPC_TOGGLEDEFAULTSCREEN,L"Toggle window/default screen",AM_K,0,0,AKS_TOGGLEDEFAULTSCREEN)
 DEFEVENT(SPC_TOGGLEMOUSEGRAB,L"Toggle between mouse grabbed and un-grabbed",AM_K,0,0,AKS_TOGGLEMOUSEGRAB)
 DEFEVENT(SPC_DECREASE_REFRESHRATE,L"Decrease emulation speed",AM_K,0,0,AKS_DECREASEREFRESHRATE)
 DEFEVENT(SPC_INCREASE_REFRESHRATE,L"Increase emulation speed",AM_K,0,0,AKS_INCREASEREFRESHRATE)
@@ -373,3 +393,4 @@ DEFEVENT(SPC_CDTV_FRONT_PANEL_NEXT,L"CDTV Front Panel Next",AM_K,0,0,AKS_CDTV_FR
 DEFEVENT(SPC_CDTV_FRONT_PANEL_REW,L"CDTV Front Panel Rewind",AM_K,0,0,AKS_CDTV_FRONT_PANEL_REW)
 DEFEVENT(SPC_CDTV_FRONT_PANEL_FF,L"CDTV Front Panel Fast Forward",AM_K,0,0,AKS_CDTV_FRONT_PANEL_FF)
 
+DEFEVENT(SPC_LAST, L"", AM_DUMMY, 0,0,0)
index c322953c4287f9fb39e7dd147f3ce28f4fbeee63..ddb27837459f7a5eaa0765daf370a2e8a16bc8b6 100644 (file)
@@ -632,6 +632,8 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context)
 
        case 100: // open dll
                {
+                       if (!currprefs.native_code)
+                               return 0;
                        TCHAR *dlldir = TEXT ("winuae_dll");
                        TCHAR *dllname;
                        uaecptr dllptr;
@@ -682,37 +684,44 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context)
 
        case 101:       //get dll label
                {
-                       HMODULE m;
-                       uaecptr funcaddr;
-                       char *funcname;
-                       m = (HMODULE) m68k_dreg (regs, 1);
-                       funcaddr = m68k_areg (regs, 0);
-                       funcname = (char*)get_real_address (funcaddr);
-                       return (uae_u32) GetProcAddress (m, funcname);
+                       if (currprefs.native_code) {
+                               HMODULE m;
+                               uaecptr funcaddr;
+                               char *funcname;
+                               m = (HMODULE) m68k_dreg (regs, 1);
+                               funcaddr = m68k_areg (regs, 0);
+                               funcname = (char*)get_real_address (funcaddr);
+                               return (uae_u32) GetProcAddress (m, funcname);
+                       }
+                       return 0;
                }
 
        case 102:       //execute native code
                {
-                       uae_u32 ret;
-                       unsigned long rate1;
-                       double v;
-                       rate1 = read_processor_time ();
-                       ret = emulib_ExecuteNativeCode2 (context);
-                       rate1 = read_processor_time () - rate1;
-                       v = syncdivisor * rate1;
-                       if (v > 0) {
-                               if (v > 1000000 * CYCLE_UNIT)
-                                       v = 1000000 * CYCLE_UNIT;
-                               do_extra_cycles ((unsigned long)(syncdivisor * rate1)); //compensate the time stay in native func
+                       uae_u32 ret = 0;
+                       if (currprefs.native_code) {
+                               unsigned long rate1;
+                               double v;
+                               rate1 = read_processor_time ();
+                               ret = emulib_ExecuteNativeCode2 (context);
+                               rate1 = read_processor_time () - rate1;
+                               v = syncdivisor * rate1;
+                               if (v > 0) {
+                                       if (v > 1000000 * CYCLE_UNIT)
+                                               v = 1000000 * CYCLE_UNIT;
+                                       do_extra_cycles ((unsigned long)(syncdivisor * rate1)); //compensate the time stay in native func
+                               }
                        }
                        return ret;
                }
 
        case 103:       //close dll
                {
-                       HMODULE libaddr;
-                       libaddr = (HMODULE) m68k_dreg (regs, 1);
-                       FreeLibrary (libaddr);
+                       if (currprefs.native_code) {
+                               HMODULE libaddr;
+                               libaddr = (HMODULE) m68k_dreg (regs, 1);
+                               FreeLibrary (libaddr);
+                       }
                        return 0;
                }
 #endif
@@ -743,6 +752,9 @@ uae_u32 REGPARAM2 ahi_demux (TrapContext *context)
                        free(bswap_buffer);
                        bswap_buffer = (void*)malloc(bswap_buffer_size);
                }
+               if (!bswap_buffer)
+                       return 0;
+
                __asm {
                        mov esi, dword ptr [src]
                        mov edi, dword ptr [bswap_buffer]
@@ -805,6 +817,8 @@ BSWAP_WORD_END:
                        free(bswap_buffer);
                        bswap_buffer = (void*)malloc(bswap_buffer_size);
                }
+               if (!bswap_buffer)
+                       return 0;
                __asm {
                        mov esi, dword ptr [src]
                        mov edi, dword ptr [bswap_buffer]
index 7e5b903531eacede7f5d9b953ec6793c43af467c..38ee0e2fb4521285f8093462acfba8abcdea8da3 100644 (file)
@@ -153,7 +153,7 @@ static void to_iff_text (const TCHAR *pctxt)
 
        s = ua (pctxt);
        txt = pctoamiga (s);
-       txtlen = strlen (s);
+       txtlen = strlen (txt);
        xfree (to_amiga);
        size = txtlen + sizeof b + (txtlen & 1) - 8;
        b[4] = size >> 24;
index 79d5c2d72d36cf7d5201ac48dd3a9ffe42303eee..da12323ae9cc7ab45b0e63ecf4f808fdc5cc17c7 100644 (file)
@@ -7,14 +7,11 @@
 */
 
 int rawinput_enabled_hid = -1;
+int rawinput_log = 0;
 
 #define _WIN32_WINNT 0x501 /* enable RAWINPUT support */
 
 #define DI_DEBUG 1
-#define DI_DEBUG2 0
-#define DI_DEBUG_RAWINPUT_KB 0
-#define DI_DEBUG_RAWINPUT_MOUSE 0
-#define DI_DEBUG_RAWINPUT_HID 0
 #define IGNOREEVERYTHING 0
 
 #include "sysconfig.h"
@@ -367,6 +364,7 @@ static void fixthings_mouse (struct didata *did)
 
 static int rawinput_available;
 static bool rawinput_registered;
+static int rawinput_reg;
 
 static bool test_rawinput (int usage)
 {
@@ -374,12 +372,12 @@ static bool test_rawinput (int usage)
 
        rid.usUsagePage = 1;
        rid.usUsage = usage;
-       if (RegisterRawInputDevices (&rid, 1, sizeof (RAWINPUTDEVICE)) == FALSE) {
+       if (RegisterRawInputDevices (&rid, 1, sizeof RAWINPUTDEVICE) == FALSE) {
                write_log (L"RAWINPUT test failed, usage=%d ERR=%d\n", usage, GetLastError ());
                return false;
        }
        rid.dwFlags |= RIDEV_REMOVE;
-       if (RegisterRawInputDevices (&rid, 1, sizeof (RAWINPUTDEVICE)) == FALSE) {
+       if (RegisterRawInputDevices (&rid, 1, sizeof RAWINPUTDEVICE) == FALSE) {
                write_log (L"RAWINPUT test failed (release), usage=%d, ERR=%d\n", usage, GetLastError ());
                return false;
        }
@@ -469,11 +467,16 @@ static int doregister_rawinput (void)
        }
 
        //write_log (L"RegisterRawInputDevices = %d (%d)\n", activate, num);
-       if (RegisterRawInputDevices (rid, num, sizeof (RAWINPUTDEVICE)) == FALSE) {
+       rawinput_reg = num;
+       if (!add)
+               rawinput_reg = -rawinput_reg;
+       //write_log (L"+++++++++++++++++++++++++++%x\n", hMainWnd);
+       if (RegisterRawInputDevices (rid, num, sizeof RAWINPUTDEVICE) == FALSE) {
                write_log (L"RAWINPUT %sregistration failed %d\n",
                        add ? L"" : L"un", GetLastError ());
                return 0;
        }
+       //write_log (L"-------------------------- %x\n", hMainWnd);
 
        return 1;
 }
@@ -932,7 +935,7 @@ static void sortobjects (struct didata *did)
 
 #if DI_DEBUG
        if (did->axles + did->buttons > 0) {
-               write_log (L"%s: (%x/%x)\n", did->name, did->vid, did->pid);
+               write_log (L"%s: (%04X/%04X)\n", did->name, did->vid, did->pid);
                if (did->connection == DIDC_DX)
                        write_log (L"PGUID=%s\n", outGUID (&did->pguid));
                for (i = 0; i < did->axles; i++) {
@@ -1678,17 +1681,17 @@ static void handle_rawinput_2 (RAWINPUT *raw)
                                        break;
                        }
                }
-#if DI_DEBUG_RAWINPUT_MOUSE
-               write_log (L"HANDLE=%08x %04x %04x %04x %08x %3d %3d %08x M=%d\n",
-                       raw->header.hDevice,
-                       rm->usFlags,
-                       rm->usButtonFlags,
-                       rm->usButtonData,
-                       rm->ulRawButtons,
-                       rm->lLastX,
-                       rm->lLastY,
-                       rm->ulExtraInformation, num < num_mouse ? num + 1 : -1);
-#endif
+               if (rawinput_log & 2)
+                       write_log (L"HANDLE=%08x %04x %04x %04x %08x %3d %3d %08x M=%d\n",
+                               raw->header.hDevice,
+                               rm->usFlags,
+                               rm->usButtonFlags,
+                               rm->usButtonData,
+                               rm->ulRawButtons,
+                               rm->lLastX,
+                               rm->lLastY,
+                               rm->ulExtraInformation, num < num_mouse ? num + 1 : -1);
+
                if (num == num_mouse)
                        return;
 
@@ -1757,11 +1760,11 @@ static void handle_rawinput_2 (RAWINPUT *raw)
                PRAWHID hid = &raw->data.hid;
                HANDLE h = raw->header.hDevice;
                PCHAR rawdata;
-#if DI_DEBUG_RAWINPUT_HID
-               uae_u8 *r = hid->bRawData;
-               write_log (L"%d %d %02x%02x%02x%02x%02x%02x%02x\n", hid->dwCount, hid->dwSizeHid,
-                       r[0], r[1], r[2], r[3], r[4], r[5], r[6]);
-#endif
+               if (rawinput_log & 4) {
+                       uae_u8 *r = hid->bRawData;
+                       write_log (L"%d %d %02x%02x%02x%02x%02x%02x%02x\n", hid->dwCount, hid->dwSizeHid,
+                               r[0], r[1], r[2], r[3], r[4], r[5], r[6]);
+               }
                for (num = 0; num < num_joystick; num++) {
                        did = &di_joystick[num];
                        if (did->connection != DIDC_RAW)
@@ -1786,9 +1789,9 @@ static void handle_rawinput_2 (RAWINPUT *raw)
                                                                break;
                                                }
                                                if (j == did->maxusagelistlength || did->prevusagelist[j].Usage == 0) {
-#if DI_DEBUG_RAWINPUT_HID
-                                                       write_log (L"%d/%d ON\n", did->usagelist[k].UsagePage, did->usagelist[k].Usage);
-#endif
+                                                       if (rawinput_log & 4)
+                                                               write_log (L"%d/%d ON\n", did->usagelist[k].UsagePage, did->usagelist[k].Usage);
+
                                                        for (int l = 0; l < did->buttons; l++) {
                                                                if (did->buttonmappings[l] == did->usagelist[k].Usage)
                                                                        setjoybuttonstate (num, l, 1);
@@ -1799,9 +1802,9 @@ static void handle_rawinput_2 (RAWINPUT *raw)
                                        }
                                        for (j = 0; j < did->maxusagelistlength; j++) {
                                                if (did->prevusagelist[j].Usage) {
-#if DI_DEBUG_RAWINPUT_HID
-                                                       write_log (L"%d/%d OFF\n", did->prevusagelist[j].UsagePage, did->prevusagelist[j].Usage);
-#endif
+                                                       if (rawinput_log & 4)
+                                                               write_log (L"%d/%d OFF\n", did->prevusagelist[j].UsagePage, did->prevusagelist[j].Usage);
+
                                                        for (int l = 0; l < did->buttons; l++) {
                                                                if (did->buttonmappings[l] == did->prevusagelist[j].Usage)
                                                                        setjoybuttonstate (num, l, 0);
@@ -1907,24 +1910,24 @@ static void handle_rawinput_2 (RAWINPUT *raw)
                int scancode = rk->MakeCode & 0x7f;
                int pressed = (rk->Flags & RI_KEY_BREAK) ? 0 : 1;
 
-#if DI_DEBUG_RAWINPUT_KB
-               write_log (L"HANDLE=%x CODE=%x Flags=%x VK=%x MSG=%x EXTRA=%x SC=%x\n",
-                       raw->header.hDevice,
-                       rk->MakeCode,
-                       rk->Flags,
-                       rk->VKey,
-                       rk->Message,
-                       rk->ExtraInformation,
-                       scancode);
-#endif
+               if (rawinput_log & 1)
+                       write_log (L"HANDLE=%x CODE=%x Flags=%x VK=%x MSG=%x EXTRA=%x SC=%x\n",
+                               raw->header.hDevice,
+                               rk->MakeCode,
+                               rk->Flags,
+                               rk->VKey,
+                               rk->Message,
+                               rk->ExtraInformation,
+                               scancode);
+
                // eat E1 extended keys
                if (rk->Flags & (RI_KEY_E1))
                        return;
                if (scancode == 0) {
                        scancode = MapVirtualKey (rk->VKey, MAPVK_VK_TO_VSC);
-#if DI_DEBUG_RAWINPUT_KB
-                       write_log (L"VK->CODE: %x\n", scancode);
-#endif
+                       if (rawinput_log & 1)
+                               write_log (L"VK->CODE: %x\n", scancode);
+
                }
                if (rk->VKey == 0xff || (rk->Flags & RI_KEY_E0))
                        scancode |= 0x80;
@@ -2024,13 +2027,18 @@ void handle_rawinput (LPARAM lParam)
 
        if (!rawinput_available)
                return;
-       GetRawInputData ((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof (RAWINPUTHEADER));
-       if (dwSize <= sizeof (lpb)) {
-               if (GetRawInputData ((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof (RAWINPUTHEADER)) == dwSize) {
-                       raw = (RAWINPUT*)lpb;
-                       handle_rawinput_2 (raw);
-                       DefRawInputProc (&raw, 1, sizeof (RAWINPUTHEADER));
+       if (GetRawInputData ((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof (RAWINPUTHEADER)) >= 0) {
+               if (dwSize <= sizeof (lpb)) {
+                       if (GetRawInputData ((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof (RAWINPUTHEADER)) == dwSize) {
+                               raw = (RAWINPUT*)lpb;
+                               handle_rawinput_2 (raw);
+                               DefRawInputProc (&raw, 1, sizeof (RAWINPUTHEADER));
+                       } else {
+                               write_log (L"GetRawInputData(%d) failed, %d\n", dwSize, GetLastError ());
+                       }
                }
+       }  else {
+               write_log (L"GetRawInputData(-1) failed, %d\n", GetLastError ());
        }
 }
 
@@ -2570,6 +2578,11 @@ static int acquire_mouse (int num, int flags)
        DIPROPDWORD dipdw;
        HRESULT hr;
 
+       if (num < 0) {
+               doregister_rawinput ();
+               return 1;
+       }
+
        unacquire (lpdi, L"mouse");
        if (did->connection == DIDC_DX && lpdi) {
                setcoop (&di_mouse[num], flags ? (DISCL_FOREGROUND | DISCL_EXCLUSIVE) : (DISCL_BACKGROUND | DISCL_NONEXCLUSIVE), L"mouse");
@@ -2597,12 +2610,15 @@ static int acquire_mouse (int num, int flags)
                } else
                        normalmouse++;
        }
-       doregister_rawinput ();
        return di_mouse[num].acquired > 0 ? 1 : 0;
 }
 
 static void unacquire_mouse (int num)
 {
+       if (num < 0) {
+               doregister_rawinput ();
+               return;
+       }
        unacquire (di_mouse[num].lpdi, L"mouse");
        if (di_mouse[num].acquired > 0) {
                if (di_mouse[num].rawinput)
@@ -2615,7 +2631,6 @@ static void unacquire_mouse (int num)
                        normalmouse--;
                di_mouse[num].acquired = 0;
        }
-       doregister_rawinput ();
 }
 
 static void read_mouse (void)
@@ -2661,9 +2676,9 @@ static void read_mouse (void)
                                int dimofs = didod[j].dwOfs;
                                int data = didod[j].dwData;
                                int state = (data & 0x80) ? 1 : 0;
-#if DI_DEBUG2
-                               write_log (L"MOUSE: %d OFF=%d DATA=%d STATE=%d\n", i, dimofs, data, state);
-#endif
+                               if (rawinput_log & 8)
+                                       write_log (L"MOUSE: %d OFF=%d DATA=%d STATE=%d\n", i, dimofs, data, state);
+
                                if (istest || isfocus () > 0) {
                                        for (k = 0; k < did->axles; k++) {
                                                if (did->axismappings[k] == dimofs)
@@ -2846,8 +2861,14 @@ static void release_keys (void)
 
 static int acquire_kb (int num, int flags)
 {
-       LPDIRECTINPUTDEVICE8 lpdi = di_keyboard[num].lpdi;
+       LPDIRECTINPUTDEVICE8 lpdi;
+
+       if (num < 0) {
+               doregister_rawinput ();
+               return 1;
+       }
 
+       lpdi = di_keyboard[num].lpdi;
        unacquire (lpdi, L"keyboard");
        if (currprefs.keyboard_leds_in_use) {
 #ifdef WINDDK
@@ -2885,14 +2906,17 @@ static int acquire_kb (int num, int flags)
                        normalkb++;
                di_keyboard[num].acquired = 1;
        }
-       doregister_rawinput ();
        return di_keyboard[num].acquired > 0 ? 1 : 0;
 }
 
 static void unacquire_kb (int num)
 {
-       LPDIRECTINPUTDEVICE8 lpdi = di_keyboard[num].lpdi;
-
+       LPDIRECTINPUTDEVICE8 lpdi;
+       if (num < 0) {
+               doregister_rawinput ();
+               return;
+       }
+       lpdi = di_keyboard[num].lpdi;
        unacquire (lpdi, L"keyboard");
        if (di_keyboard[num].acquired > 0) {
                if (di_keyboard[num].rawinput)
@@ -2917,7 +2941,6 @@ static void unacquire_kb (int num)
                }
 #endif
        }
-       doregister_rawinput ();
        //unlock_kb ();
 }
 
@@ -3278,18 +3301,17 @@ static void read_joystick (void)
                                                if (bstate >= 0 && axisold[i][k] != bstate) {
                                                        setjoybuttonstate (i, k, bstate);
                                                        axisold[i][k] = bstate;
-#if DI_DEBUG2
-                                                       write_log (L"AB:NUM=%d OFF=%d AXIS=%d DIR=%d NAME=%s VAL=%d STATE=%d BS=%d\n",
-                                                               k, dimofs, axis, dir, did->buttonname[k], data, state, bstate);
-#endif
+                                                       if (rawinput_log & 8)
+                                                               write_log (L"AB:NUM=%d OFF=%d AXIS=%d DIR=%d NAME=%s VAL=%d STATE=%d BS=%d\n",
+                                                                       k, dimofs, axis, dir, did->buttonname[k], data, state, bstate);
+
                                                }
 
 
                                        } else if (did->buttonaxisparent[k] < 0 && did->buttonmappings[k] == dimofs) {
-#if DI_DEBUG2
-                                               write_log (L"B:NUM=%d OFF=%d NAME=%s VAL=%d STATE=%d\n",
-                                                       k, dimofs, did->buttonname[k], data, state);
-#endif
+                                               if (rawinput_log & 8)
+                                                       write_log (L"B:NUM=%d OFF=%d NAME=%s VAL=%d STATE=%d\n",
+                                                               k, dimofs, did->buttonname[k], data, state);
                                                setjoybuttonstate (i, k, state);
                                        }
                                }
@@ -3300,14 +3322,13 @@ static void read_joystick (void)
                                                        setjoystickstate (i, k, (data2 >= 20250 && data2 <= 33750) ? -1 : (data2 >= 2250 && data2 <= 15750) ? 1 : 0, 1);
                                                } else if (did->axistype[k] == 2) {
                                                        setjoystickstate (i, k, ((data2 >= 29250 && data2 <= 33750) || (data2 >= 0 && data2 <= 6750)) ? -1 : (data2 >= 11250 && data2 <= 24750) ? 1 : 0, 1);
-#if DI_DEBUG2
-                                                       write_log (L"P:NUM=%d OFF=%d NAME=%s VAL=%d\n", k, dimofs, did->axisname[k], data2);
-#endif
+                                                       if (rawinput_log & 8)
+                                                               write_log (L"P:NUM=%d OFF=%d NAME=%s VAL=%d\n", k, dimofs, did->axisname[k], data2);
                                                } else if (did->axistype[k] == 0) {
-#if DI_DEBUG2
-                                                       if (data < -20000 || data > 20000)
-                                                               write_log (L"A:NUM=%d OFF=%d NAME=%s VAL=%d\n", k, dimofs, did->axisname[k], data);
-#endif
+                                                       if (rawinput_log & 8) {
+                                                               if (data < -20000 || data > 20000)
+                                                                       write_log (L"A:NUM=%d OFF=%d NAME=%s VAL=%d\n", k, dimofs, did->axisname[k], data);
+                                                       }
                                                        if (istest) {
                                                                if (data < -20000)
                                                                        data = -20000;
@@ -3393,10 +3414,15 @@ void dinput_window (void)
 
 static int acquire_joystick (int num, int flags)
 {
-       LPDIRECTINPUTDEVICE8 lpdi = di_joystick[num].lpdi;
+       LPDIRECTINPUTDEVICE8 lpdi;
        DIPROPDWORD dipdw;
        HRESULT hr;
 
+       if (num < 0) {
+               doregister_rawinput ();
+               return 1;
+       }
+       lpdi = di_joystick[num].lpdi;
        unacquire (lpdi, L"joystick");
        if (di_joystick[num].connection == DIDC_DX && lpdi) {
                setcoop (&di_joystick[num], flags ? (DISCL_FOREGROUND | DISCL_EXCLUSIVE) : (DISCL_BACKGROUND | DISCL_NONEXCLUSIVE), L"joystick");
@@ -3416,7 +3442,6 @@ static int acquire_joystick (int num, int flags)
        } else {
                di_joystick[num].acquired = 1;
        }
-       doregister_rawinput ();
        return di_joystick[num].acquired > 0 ? 1 : 0;
 }
 
@@ -3424,13 +3449,17 @@ static void unacquire_joystick (int num)
 {
        struct didata *did = &di_joystick[num];
 
+       if (num < 0) {
+               doregister_rawinput ();
+               return;
+       }
+
        unacquire (did->lpdi, L"joystick");
        if (did->connection == DIDC_RAW) {
                if (di_joystick[num].acquired)
                        rawhid--;
        }
        di_joystick[num].acquired = 0;
-       doregister_rawinput ();
 }
 
 static int get_joystick_flags (int num)
index 188025d81e4587be732a640c7b076feffaad2347..5eb71b0114079813f4db4166ce8b72b6810d4a5f 100644 (file)
@@ -937,8 +937,8 @@ static int psEffect_SetTextures (LPDIRECT3DTEXTURE9 lpSource, LPDIRECT3DTEXTURE9
                fDims.x = (FLOAT) Desc.Width;
                fDims.y = (FLOAT) Desc.Height;
        }
-       fTexelSize.x = 1 / fDims.x;
-       fTexelSize.y = 1 / fDims.y;
+       fTexelSize.x = 1.0f / fDims.x;
+       fTexelSize.y = 1.0f / fDims.y;
        if (m_SourceDimsEffectHandle) {
                hr = pEffect->SetVector (m_SourceDimsEffectHandle, &fDims);
                if (FAILED (hr)) {
@@ -1867,6 +1867,12 @@ bool D3D_getvblankpos (int *vpos)
        return true;
 }
 
+void D3D_vblank_reset (void)
+{
+       if (!isd3d ())
+               return;
+}
+
 static int getd3dadapter (IDirect3D9 *d3d)
 {
        struct MultiDisplay *md = getdisplay (&currprefs);
@@ -1977,7 +1983,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth
        modeex.Width = w_w;
        modeex.Height = w_h;
        modeex.RefreshRate = 0;
-       modeex.ScanLineOrdering = D3DSCANLINEORDERING_PROGRESSIVE;
+       modeex.ScanLineOrdering = ap->gfx_interlaced ? D3DSCANLINEORDERING_INTERLACED : D3DSCANLINEORDERING_PROGRESSIVE;
        modeex.Format = mode.Format;
 
        vsync2 = 0;
@@ -1986,11 +1992,14 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth
                modeex.RefreshRate = dpp.FullScreen_RefreshRateInHz;
                if (vsync > 0) {
                        dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
-                       if (getvsyncrate (dpp.FullScreen_RefreshRateInHz) != dpp.FullScreen_RefreshRateInHz) {
+                       getvsyncrate (dpp.FullScreen_RefreshRateInHz, &mult);
+                       if (mult < 0) {
                                if (d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO)
                                        dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO;
                                else
-                                       vsync2 = 1;
+                                       vsync2 = -1;
+                       } else if (mult > 0) {
+                               vsync2 = 1;
                        }
                }
        }
@@ -2078,7 +2087,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int t_w, int t_h, int depth
                (d3dCaps.PixelShaderVersion >> 8) & 0xff, d3dCaps.PixelShaderVersion & 0xff,
                (d3dCaps.VertexShaderVersion >> 8) & 0xff, d3dCaps.VertexShaderVersion & 0xff,
                max_texture_w, max_texture_h,
-               dpp.Windowed ? 0 : dpp.FullScreen_RefreshRateInHz,
+               dpp.FullScreen_RefreshRateInHz,
                dpp.Windowed ? L"" : L" FS",
                vsync, dpp.BackBufferCount,
                dpp.PresentationInterval & D3DPRESENT_INTERVAL_IMMEDIATE ? L"I" : L"F",
@@ -2609,11 +2618,18 @@ uae_u8 *D3D_locktexture (int *pitch, int fullupdate)
 
 bool D3D_renderframe (void)
 {
+       static int vsync2_cnt;
+
        if (!isd3d ())
                return false;
 
+       if (vsync2 > 0) {
+               vsync2_cnt ^= 1;
+               if (vsync2_cnt == 0)
+                       return true;
+       }
        D3D_render2 ();
-       if (vsync2 && !currprefs.turbo_emulation) {
+       if (vsync2 < 0 && !currprefs.turbo_emulation) {
                D3D_render2 ();
        }
 
index b35748468c46c09641b0a7cf2eaa1a8cff4a3f28..e8a0838b68aa9e116c9dd57e0c820947a80d3b26 100644 (file)
@@ -18,6 +18,7 @@ extern int D3D_goodenough (void);
 extern void D3D_setcursor (int x, int y, int width, int height, bool visible);
 extern bool D3D_getvblankpos (int *vpos);
 extern double D3D_getrefreshrate (void);
+extern void D3D_vblank_reset (void);
 extern LPDIRECT3DTEXTURE9 cursorsurfaced3d;
 
 #define CURSORMAXWIDTH 64
index ed7764ac41dedc77eabdb59bf75d65327dda2bce..2c5029448e933a5a5c93f7e4bb2a3de452d45d29 100644 (file)
@@ -418,6 +418,9 @@ HRESULT DirectDraw_SetDisplayMode (int width, int height, int bits, int freq)
        if (dxdata.fsmodeset && dxdata.width == width && dxdata.height == height &&
                dxdata.depth == bits && dxdata.freq == freq)
                return DD_OK;
+
+       getvsyncrate (freq, &dxdata.vblank_skip);
+       dxdata.vblank_skip_cnt = 0;
        ddrval = IDirectDraw7_SetDisplayMode (dxdata.maindd, width, height, bits, freq, 0);
        if (FAILED (ddrval)) {
                write_log (L"IDirectDraw7_SetDisplayMode: %s\n", DXError (ddrval));
@@ -900,39 +903,60 @@ void DirectDraw_FillPrimary (void)
        DirectDraw_FillSurface (dxdata.primary, NULL, 0);
 }
 
-extern int vblank_skip;
 static void flip (void)
 {
        int result = 0;
        HRESULT ddrval = DD_OK;
        DWORD flags = DDFLIP_DONOTWAIT;
        int vsync = isvsync ();
+       bool novsync = false;
        struct apmode *ap = WIN32GFX_IsPicassoScreen () ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0];
 
-       if (currprefs.turbo_emulation || !ap->gfx_vflip)
+       if (currprefs.turbo_emulation || !ap->gfx_vflip) {
+               novsync = true;
                flags |= DDFLIP_NOVSYNC;
+       }
        if (dxdata.backbuffers == 2) {
                DirectDraw_Blit (dxdata.flipping[1], dxdata.flipping[0]);
                if (vsync) {
-                       if (vblank_skip >= 0 || currprefs.turbo_emulation) {
+                       if (currprefs.turbo_emulation || dxdata.vblank_skip == 0) {
+                               ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags);
+                       } else if (dxdata.vblank_skip > 0) {
+                               dxdata.vblank_skip_cnt ^= 1;
+                               if (dxdata.vblank_skip_cnt == 0)
+                                       return;
                                ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags);
+                       } else if (flipinterval_supported && !novsync) {
+                               ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags | DDFLIP_INTERVAL2);
                        } else {
-                               if (flipinterval_supported) {
-                                       ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags | DDFLIP_INTERVAL2);
-                               } else {
-                                       ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags);
-                                       DirectDraw_Blit (dxdata.flipping[1], dxdata.primary);
-                                       ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags);
-                               }
+                               ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags);
+                               DirectDraw_Blit (dxdata.flipping[1], dxdata.primary);
+                               ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags);
                        }
                } else {
                        ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags| DDFLIP_NOVSYNC);
                }
        } else if(dxdata.backbuffers == 1) {
-               if (!vsync)
-                       flags |= DDFLIP_NOVSYNC;
-               ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags);
-               DirectDraw_Blit (dxdata.flipping[0], dxdata.primary);
+               if (vsync) {
+                       if (currprefs.turbo_emulation || dxdata.vblank_skip == 0) {
+                               ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags);
+                       } else if (dxdata.vblank_skip > 0) {
+                               dxdata.vblank_skip_cnt ^= 1;
+                               if (dxdata.vblank_skip_cnt == 0)
+                                       return;
+                               ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags);
+                       } else if (flipinterval_supported && !novsync) {
+                               ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags | DDFLIP_INTERVAL2);
+                       } else {
+                               ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags);
+                               DirectDraw_Blit (dxdata.flipping[0], dxdata.primary);
+                               ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags);
+                       }
+                       DirectDraw_Blit (dxdata.flipping[0], dxdata.primary);
+               } else {
+                       ddrval = IDirectDrawSurface7_Flip (dxdata.primary, NULL, flags | DDFLIP_NOVSYNC);
+                       DirectDraw_Blit (dxdata.flipping[0], dxdata.primary);
+               }
        }
        if (ddrval == DDERR_SURFACELOST) {
                static int recurse;
@@ -1253,3 +1277,11 @@ bool DD_getvblankpos (int *vpos)
                *vpos = -1;
        return true;
 }
+
+void DD_vblank_reset (void)
+{
+       dx_check ();
+       if ((dxdata.primary == NULL && dxdata.fsmodeset > 0) || dxdata.islost || !dxdata.maindd)
+               return;
+       IDirectDraw7_WaitForVerticalBlank (dxdata.maindd, DDWAITVB_BLOCKBEGIN, NULL);
+}
index 4c5673e063a2e43e5315bc71411a910d1e7a9edc..08fc91feb019b67fd674ff5bea506acf8cc58f95 100644 (file)
@@ -22,6 +22,7 @@ struct ddstuff
        DWORD overlayflags;
        int fsmodeset, backbuffers;
        int width, height, depth, freq;
+       int vblank_skip, vblank_skip_cnt;
        int swidth, sheight;
        DDSURFACEDESC2 native;
        DDSURFACEDESC2 locksurface;
@@ -131,6 +132,7 @@ void DirectDraw_FillSurface (LPDIRECTDRAWSURFACE7 dst, RECT *rect, uae_u32 color
 void DirectDraw_Fill (RECT *rect, uae_u32 color);
 void DirectDraw_FillPrimary (void);
 bool DD_getvblankpos (int *vpos);
+void DD_vblank_reset (void);
 
 void dx_check (void);
 int dx_islost (void);
index 0b155cc52bea7813c9506c743067dff3edbc43b3..8d08b0f60e6944f0e2d438fc929e241e8852c0cc 100644 (file)
@@ -47,16 +47,16 @@ static struct uae_input_device_kbr_default keytrans_amiga[] = {
 
        { DIK_ESCAPE, INPUTEVENT_KEY_ESC },
 
-       { DIK_F1, INPUTEVENT_KEY_F1 },
-       { DIK_F2, INPUTEVENT_KEY_F2 },
-       { DIK_F3, INPUTEVENT_KEY_F3 },
-       { DIK_F4, INPUTEVENT_KEY_F4 },
-       { DIK_F5, INPUTEVENT_KEY_F5 },
-
-       { DIK_F6, INPUTEVENT_KEY_F6 },
-       { DIK_F7, INPUTEVENT_KEY_F7 },
-       { DIK_F8, INPUTEVENT_KEY_F8 },
-       { DIK_F9, INPUTEVENT_KEY_F9 },
+       {  DIK_F1,  INPUTEVENT_KEY_F1, 0, INPUTEVENT_SPC_FLOPPY0, ID_FLAG_QUALIFIER_SPECIAL, INPUTEVENT_SPC_EFLOPPY0, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_SHIFT },
+       {  DIK_F2,  INPUTEVENT_KEY_F2, 0, INPUTEVENT_SPC_FLOPPY1, ID_FLAG_QUALIFIER_SPECIAL, INPUTEVENT_SPC_EFLOPPY1, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_SHIFT },
+       {  DIK_F3,  INPUTEVENT_KEY_F3, 0, INPUTEVENT_SPC_FLOPPY2, ID_FLAG_QUALIFIER_SPECIAL, INPUTEVENT_SPC_EFLOPPY2, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_SHIFT },
+       {  DIK_F4,  INPUTEVENT_KEY_F4, 0, INPUTEVENT_SPC_FLOPPY3, ID_FLAG_QUALIFIER_SPECIAL, INPUTEVENT_SPC_EFLOPPY3, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_SHIFT },
+
+       {  DIK_F5,  INPUTEVENT_KEY_F5, 0, INPUTEVENT_SPC_STATERESTOREDIALOG, ID_FLAG_QUALIFIER_SPECIAL, INPUTEVENT_SPC_STATESAVEDIALOG, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_SHIFT },
+       {  DIK_F6,  INPUTEVENT_KEY_F6 },
+       {  DIK_F7,  INPUTEVENT_KEY_F7 },
+       {  DIK_F8,  INPUTEVENT_KEY_F8 },
+       {  DIK_F9,  INPUTEVENT_KEY_F9 },
        { DIK_F10, INPUTEVENT_KEY_F10 },
 
        { DIK_1, INPUTEVENT_KEY_1 },
@@ -112,10 +112,10 @@ static struct uae_input_device_kbr_default keytrans_amiga[] = {
        { DIK_NUMPAD9, INPUTEVENT_KEY_NP_9 },
        { DIK_NUMPAD0, INPUTEVENT_KEY_NP_0 },
        { DIK_DECIMAL, INPUTEVENT_KEY_NP_PERIOD },
-       { DIK_ADD, INPUTEVENT_KEY_NP_ADD },
-       { DIK_SUBTRACT, INPUTEVENT_KEY_NP_SUB },
-       { DIK_MULTIPLY, INPUTEVENT_KEY_NP_MUL },
-       { DIK_DIVIDE, INPUTEVENT_KEY_NP_DIV },
+       { DIK_ADD, INPUTEVENT_KEY_NP_ADD, 0, INPUTEVENT_SPC_VOLUME_UP, ID_FLAG_QUALIFIER_SPECIAL, INPUTEVENT_SPC_MASTER_VOLUME_UP, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_CONTROL, INPUTEVENT_SPC_INCREASE_REFRESHRATE, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_SHIFT  },
+       { DIK_SUBTRACT, INPUTEVENT_KEY_NP_SUB, 0, INPUTEVENT_SPC_VOLUME_DOWN, ID_FLAG_QUALIFIER_SPECIAL, INPUTEVENT_SPC_MASTER_VOLUME_DOWN, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_CONTROL, INPUTEVENT_SPC_DECREASE_REFRESHRATE, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_SHIFT  },
+       { DIK_MULTIPLY, INPUTEVENT_KEY_NP_MUL, 0, INPUTEVENT_SPC_VOLUME_MUTE, ID_FLAG_QUALIFIER_SPECIAL, INPUTEVENT_SPC_MASTER_VOLUME_MUTE, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_CONTROL },
+       { DIK_DIVIDE, INPUTEVENT_KEY_NP_DIV, 0, INPUTEVENT_SPC_STATEREWIND, ID_FLAG_QUALIFIER_SPECIAL },
        { DIK_NUMPADENTER, INPUTEVENT_KEY_ENTER },
 
        { DIK_MINUS, INPUTEVENT_KEY_SUB },
@@ -124,15 +124,15 @@ static struct uae_input_device_kbr_default keytrans_amiga[] = {
        { DIK_RETURN, INPUTEVENT_KEY_RETURN },
        { DIK_SPACE, INPUTEVENT_KEY_SPACE },
 
-       { DIK_LSHIFT, INPUTEVENT_KEY_SHIFT_LEFT },
-       { DIK_LCONTROL, INPUTEVENT_KEY_CTRL },
+       { DIK_LSHIFT, INPUTEVENT_KEY_SHIFT_LEFT, 0, INPUTEVENT_SPC_QUALIFIER_SHIFT },
+       { DIK_LCONTROL, INPUTEVENT_KEY_CTRL, 0, INPUTEVENT_SPC_QUALIFIER_CONTROL },
        { DIK_LWIN, INPUTEVENT_KEY_AMIGA_LEFT },
-       { DIK_LMENU, INPUTEVENT_KEY_ALT_LEFT },
-       { DIK_RMENU, INPUTEVENT_KEY_ALT_RIGHT },
+       { DIK_LMENU, INPUTEVENT_KEY_ALT_LEFT, 0, INPUTEVENT_SPC_QUALIFIER_ALT },
+       { DIK_RMENU, INPUTEVENT_KEY_ALT_RIGHT, 0, INPUTEVENT_SPC_QUALIFIER_ALT },
        { DIK_RWIN, INPUTEVENT_KEY_AMIGA_RIGHT },
        { DIK_APPS, INPUTEVENT_KEY_AMIGA_RIGHT },
-       { DIK_RCONTROL, INPUTEVENT_KEY_CTRL },
-       { DIK_RSHIFT, INPUTEVENT_KEY_SHIFT_RIGHT },
+       { DIK_RCONTROL, INPUTEVENT_KEY_CTRL, 0, INPUTEVENT_SPC_QUALIFIER_CONTROL },
+       { DIK_RSHIFT, INPUTEVENT_KEY_SHIFT_RIGHT, 0, INPUTEVENT_SPC_QUALIFIER_SHIFT },
 
        { DIK_UP, INPUTEVENT_KEY_CURSOR_UP },
        { DIK_DOWN, INPUTEVENT_KEY_CURSOR_DOWN },
@@ -155,19 +155,12 @@ static struct uae_input_device_kbr_default keytrans_amiga[] = {
        { DIK_PERIOD, INPUTEVENT_KEY_PERIOD },
        { DIK_SLASH, INPUTEVENT_KEY_DIV },
        { DIK_OEM_102, INPUTEVENT_KEY_30 },
+       { DIK_SYSRQ, INPUTEVENT_SPC_SCREENSHOT_CLIPBOARD, 0, INPUTEVENT_SPC_SCREENSHOT_CLIPBOARD, ID_FLAG_QUALIFIER_SPECIAL },
 
-//     { DIK_VOLUMEDOWN, INPUTEVENT_SPC_MASTER_VOLUME_DOWN },
-//     { DIK_VOLUMEUP, INPUTEVENT_SPC_MASTER_VOLUME_UP },
-//     { DIK_MUTE, INPUTEVENT_SPC_MASTER_VOLUME_MUTE },
+       { DIK_END, INPUTEVENT_SPC_QUALIFIER_SPECIAL },
+       { DIK_PAUSE, INPUTEVENT_SPC_PAUSE, 0, INPUTEVENT_SPC_WARP, ID_FLAG_QUALIFIER_SPECIAL, INPUTEVENT_SPC_IRQ7, ID_FLAG_QUALIFIER_SPECIAL | ID_FLAG_QUALIFIER_SHIFT },
 
-//     { DIK_HOME, INPUTEVENT_KEY_70 },
-       { DIK_END, INPUTEVENT_KEY_END },
-//     { DIK_SYSRQ, INPUTEVENT_KEY_6E },
-//     { DIK_F12, INPUTEVENT_KEY_6F },
-//     { DIK_INSERT, INPUTEVENT_KEY_47 },
-//     { DIK_PRIOR, INPUTEVENT_KEY_48 },
-//     { DIK_NEXT, INPUTEVENT_KEY_49 },
-       { DIK_F11, INPUTEVENT_KEY_F11 },
+       { DIK_F12, INPUTEVENT_SPC_ENTERGUI, 0, INPUTEVENT_SPC_ENTERDEBUGGER, ID_FLAG_QUALIFIER_SPECIAL, INPUTEVENT_SPC_ENTERDEBUGGER, ID_FLAG_QUALIFIER_SHIFT, INPUTEVENT_SPC_TOGGLEDEFAULTSCREEN, ID_FLAG_QUALIFIER_CONTROL },
 
        { DIK_MEDIASTOP, INPUTEVENT_KEY_CDTV_STOP },
        { DIK_PLAYPAUSE, INPUTEVENT_KEY_CDTV_PLAYPAUSE },
@@ -333,32 +326,21 @@ static int *kbmaps[] = {
        kb_xa1, kb_xa2, kb_arcadia, kb_arcadiaxa, kb_cdtv
 };
 
-extern int ispressed (int key);
-
-static int specialkeycode (void)
-{
-       if (currprefs.input_keyboard_type == 0)
-               return currprefs.win32_specialkey;
-       return -1;
-}
 static int specialpressed (void)
 {
-       return ispressed (specialkeycode ());
+       return input_getqualifiers () & ID_FLAG_QUALIFIER_SPECIAL;
 }
-
 static int shiftpressed (void)
 {
-       return ispressed (DIK_LSHIFT) || ispressed (DIK_RSHIFT);
+       return input_getqualifiers () & ID_FLAG_QUALIFIER_SHIFT;
 }
-
 static int altpressed (void)
 {
-       return ispressed (DIK_LMENU) || ispressed (DIK_RMENU);
+       return input_getqualifiers () & ID_FLAG_QUALIFIER_ALT;
 }
-
 static int ctrlpressed (void)
 {
-       return ispressed (DIK_LCONTROL) || ispressed (DIK_RCONTROL);
+       return input_getqualifiers () & ID_FLAG_QUALIFIER_CONTROL;
 }
 
 static int capslockstate;
@@ -397,7 +379,7 @@ void clearallkeys (void)
        inputdevice_updateconfig (&currprefs);
 }
 
-static int np[] = {
+static const int np[] = {
        DIK_NUMPAD0, 0, DIK_NUMPADPERIOD, 0, DIK_NUMPAD1, 1, DIK_NUMPAD2, 2,
        DIK_NUMPAD3, 3, DIK_NUMPAD4, 4, DIK_NUMPAD5, 5, DIK_NUMPAD6, 6, DIK_NUMPAD7, 7,
        DIK_NUMPAD8, 8, DIK_NUMPAD9, 9, -1 };
@@ -408,10 +390,15 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
        int scancode_new;
        int defaultguikey;
        bool amode = currprefs.input_keyboard_type == 0;
+       bool special = false;
        static int swapperdrive = 0;
 
-       if (scancode == specialkeycode ())
+#if 0
+       if (scancode == specialkeycode ()) {
+               inputdevice_checkqualifierkeycode (keyboard, scancode, newstate);
                return;
+       }
+#endif
 
        if (amode && scancode == DIK_F11 && currprefs.win32_ctrl_F11_is_quit && ctrlpressed ())
                code = AKS_QUIT;
@@ -429,37 +416,11 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
        
        //write_log (L"keyboard = %d scancode = 0x%02x state = %d\n", keyboard, scancode, newstate );
 
-       if (amode && newstate == 0 && code == 0) {
-               switch (scancode)
-               {
-                       case DIK_SYSRQ:
-                       screenshot (specialpressed () ? 1 : 0, 1);
-                       break;
-               }
-       }
-
-
-       if (newstate && code == 0) {
-
-               if (scancode == defaultguikey || scancode == currprefs.win32_guikey) {
-                       if (ctrlpressed ()) {
-                               code = AKS_TOGGLEDEFAULTSCREEN;
-                       } else if (shiftpressed () || specialpressed ()) {
-                               if (isfullscreen() <= 0) {
-                                       disablecapture ();
-                                       code = AKS_ENTERDEBUGGER;
-                               }
-                       } else {
-                               code = AKS_ENTERGUI;
-                       }
-               }
-
-       }
-
        if (newstate && code == 0 && amode) {
 
                switch (scancode)
                {
+#if 0
                case DIK_F1:
                case DIK_F2:
                case DIK_F3:
@@ -473,6 +434,7 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
                                                code = AKS_FLOPPY0 + (scancode - DIK_F1);
                                }
                        }
+                       special = true;
                        break;
                case DIK_F5:
 #if 0
@@ -489,7 +451,10 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
                                else
                                        code = AKS_STATERESTOREDIALOG;
                        }
+                       special = true;
                        break;
+#endif
+
                case DIK_1:
                case DIK_2:
                case DIK_3:
@@ -517,6 +482,7 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
                                        _tcscpy (changed_prefs.floppyslots[swapperdrive].df, currprefs.dfxlist[num]);
                                        config_changed = 1;
                                }
+                               special = true;
                        }
                        break;
                case DIK_NUMPAD0:
@@ -540,8 +506,10 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
                                }
                                if (v >= 0)
                                        code = AKS_STATESAVEQUICK + v * 2 + ((shiftpressed () || ctrlpressed ()) ? 0 : 1);
+                               special = true;
                        }
                        break;
+#if 0
                case DIK_PAUSE:
                        if (specialpressed ()) {
                                if (shiftpressed ())
@@ -551,6 +519,7 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
                        } else {
                                code = AKS_PAUSE;
                        }
+                       special = true;
                        break;
 #if 0
                case DIK_SCROLL:
@@ -566,6 +535,7 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
                                else
                                        code = AKS_VOLDOWN;
                        }
+                       special = true;
                        break;
                case DIK_NUMPADPLUS:
                        if (specialpressed ()) {
@@ -576,6 +546,7 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
                                else
                                        code = AKS_VOLUP;
                        }
+                       special = true;
                        break;
                case DIK_NUMPADSTAR:
                        if (specialpressed ()) {
@@ -584,11 +555,14 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
                                else
                                        code = AKS_VOLMUTE;
                        }
+                       special = true;
                        break;
                case DIK_NUMPADSLASH:
                        if (specialpressed ())
                                code = AKS_STATEREWIND;
+                       special = true;
                        break;
+#endif
                }
        }
 
@@ -597,6 +571,7 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
                return;
        }
 
+
        scancode = scancode_new;
        if (!specialpressed () && newstate) {
                if (scancode == DIK_CAPITAL) {
@@ -612,8 +587,11 @@ void my_kbd_handler (int keyboard, int scancode, int newstate)
                        capslockstate = host_scrolllockstate;
                }
        }
-       if (specialpressed ())
+
+       if (special) {
+               inputdevice_checkqualifierkeycode (keyboard, scancode, newstate);
                return;
+       }
 
        inputdevice_translatekeycode (keyboard, scancode, newstate);
 }
index f10f0450ce0555db21232d9339c08e1508122081..95554ab55d36c4e5b648616dcdb2094f3a95a236 100644 (file)
@@ -684,6 +684,7 @@ static void picasso_handle_vsync2 (void)
        static int vsynccnt;
        int thisisvsync = 1;
        int vsync = isvsync_rtg ();
+       int mult;
 
 #ifdef RETROPLATFORM
        rp_vsync ();
@@ -693,7 +694,8 @@ static void picasso_handle_vsync2 (void)
        if (!picasso_on)
                createwindowscursor (0, 0, 0, 0, 0, 1);
 
-       if (vsync >= 0 && currprefs.chipset_refreshrate >= 85) {
+       getvsyncrate (currprefs.chipset_refreshrate, &mult);
+       if (vsync >= 0 && mult < 0) {
                vsynccnt++;
                if (vsynccnt < 2)
                        thisisvsync = 0;
index e8058eeacdd46e7c17ac052d7064afd942906d32..444f4073612d9caa0404941fd3cc059cac608080 100644 (file)
 #define IDS_FILTER_NOOVERLAYS           269
 #define IDS_STMENUNOCD                  270
 #define IDS_ON                          271
+#define IDS_INPUTQUALIFIER              272
 #define IDS_NUMSG_NEEDEXT2              300
 #define IDS_NUMSG_NOROMKEY              301
 #define IDS_NUMSG_KSROMCRCERROR         302
 #define IDS_AUTOSCALE_INTEGER           375
 #define IDS_SCREEN_VSYNC2_AUTOSWITCH    376
 #define IDS_SCREEN_VSYNC2               377
-#define IDS_STRING23                    378
 #define IDS_SCREEN_VSYNC_NONE           378
 #define IDS_QS_MODELS                   1000
 #define IDS_QS_MODEL_A500               1001
 #define IDC_AVIOUTPUT_VIDEO             1613
 #define IDC_INPUTAUTOFIRE               1613
 #define IDC_PORT_MOUSETRICK             1613
+#define IDC_CLIPBOARDSHARE2             1613
+#define IDC_NATIVECODE                  1613
 #define IDC_AVIOUTPUT_AUDIO             1614
 #define IDC_INPUTCOPYFROM               1614
 #define IDC_SANA2                       1614
index c0be8ed0bd6b258bd430b072bbce71b2a5c2561c..bde0a3a634f7276052513fdfd7371f79580b7b47 100644 (file)
@@ -487,7 +487,7 @@ BEGIN
     GROUPBOX        "Miscellaneous Options",IDC_STATIC,4,2,293,165\r
     CONTROL         "Untrap = middle button",IDC_JULIAN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,19,110,10\r
     CONTROL         "Show GUI on startup",IDC_SHOWGUI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,43,109,10\r
-    CONTROL         "Native on-screen display",IDC_SHOWLEDS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,139,109,10\r
+    CONTROL         "Native on-screen display",IDC_SHOWLEDS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,182,103,109,10\r
     CONTROL         "Don't show taskbar button",IDC_NOTASKBARBUTTON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,67,109,10\r
     CONTROL         "Use CTRL-F11 to quit",IDC_CTRLF11,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,55,110,10\r
     GROUPBOX        "Keyboard LEDs",IDC_STATIC,3,207,294,29\r
@@ -512,13 +512,14 @@ BEGIN
     CONTROL         "Synchronize clock",IDC_CLOCKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,103,111,10\r
     CONTROL         "Faster RTG [] Enables less accurate custom chipset emulation mode when Picasso96 is enabled.",IDC_FASTERRTG,\r
                     "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,19,115,111,10\r
-    CONTROL         "RTG on-screen display",IDC_SHOWLEDSRTG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,151,109,10\r
+    CONTROL         "RTG on-screen display",IDC_SHOWLEDSRTG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,182,114,109,10\r
     RTEXT           "Graphics API:",IDC_STATIC,130,62,79,10,SS_CENTERIMAGE\r
     COMBOBOX        IDC_DXMODE,213,60,79,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
     CONTROL         "Minimize when focus is lost",IDC_FOCUSMINIMIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,31,110,10\r
     RTEXT           "Windowed style:",IDC_STATIC,128,45,81,10,SS_CENTERIMAGE\r
     COMBOBOX        IDC_WINDOWEDMODE,213,43,79,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
     CONTROL         "Clipboard sharing",IDC_CLIPBOARDSHARE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,127,111,10\r
+    CONTROL         "Allow native code",IDC_NATIVECODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,139,111,10\r
 END\r
 \r
 IDD_HARDFILE DIALOGEX 0, 0, 299, 249\r
@@ -1699,6 +1700,11 @@ BEGIN
     IDS_SCREEN_VSYNC_NONE   "-"\r
 END\r
 \r
+STRINGTABLE\r
+BEGIN\r
+    IDS_INPUTQUALIFIER      "Qualifiers"\r
+END\r
+\r
 #endif    // English resources\r
 /////////////////////////////////////////////////////////////////////////////\r
 \r
index 466e1a9e90ec9ca3c659f259ca9c433447cdc72d..92fda294563e2deedd11dae691c7b693ff02bcaa 100644 (file)
@@ -94,7 +94,7 @@
 extern int harddrive_dangerous, do_rdbdump, aspi_allow_all, no_rawinput;
 extern int force_directsound;
 extern int log_a2065, a2065_promiscuous;
-extern int rawinput_enabled_hid;
+extern int rawinput_enabled_hid, rawinput_log;
 int log_scsi;
 int log_net;
 int log_vsync;
@@ -692,7 +692,6 @@ static void winuae_active (HWND hWnd, int minimized)
        if (WIN32GFX_IsPicassoScreen ())
                WIN32GFX_EnablePicasso ();
        getcapslock ();
-       inputdevice_acquire (FALSE);
        wait_keyrelease ();
        inputdevice_acquire (TRUE);
        if (isfullscreen() != 0 && !gui_active)
@@ -2785,7 +2784,6 @@ void target_default_options (struct uae_prefs *p, int type)
                p->win32_iconified_priority = 3;
                p->win32_notaskbarbutton = 0;
                p->win32_alwaysontop = 0;
-               p->win32_specialkey = 0xcf; // DIK_END
                p->win32_guikey = -1;
                p->win32_automount_removable = 0;
                p->win32_automount_drives = 0;
@@ -2900,7 +2898,6 @@ void target_save_options (struct zfile *f, struct uae_prefs *p)
        cfgfile_target_dwrite_bool (f, L"notaskbarbutton", p->win32_notaskbarbutton);
        cfgfile_target_dwrite_bool (f, L"always_on_top", p->win32_alwaysontop);
        cfgfile_target_dwrite_bool (f, L"no_recyclebin", p->win32_norecyclebin);
-       cfgfile_target_dwrite (f, L"specialkey", L"0x%x", p->win32_specialkey);
        if (p->win32_guikey >= 0)
                cfgfile_target_dwrite (f, L"guikey", L"0x%x", p->win32_guikey);
        cfgfile_target_dwrite (f, L"kbledmode", L"%d", p->win32_kbledmode);
@@ -2940,6 +2937,7 @@ static const TCHAR *obsolete[] = {
        L"sound_sync", L"sound_tweak", L"directx6", L"sound_style",
        L"file_path", L"iconified_nospeed", L"activepriority", L"magic_mouse",
        L"filesystem_codepage", L"aspi", L"no_overlay", L"soundcard_exclusive",
+       L"specialkey",
        0
 };
 
@@ -2975,7 +2973,6 @@ int target_parse_option (struct uae_prefs *p, const TCHAR *option, const TCHAR *
                || cfgfile_string (option, value, L"parjoyport0", p->win32_parjoyport0, sizeof p->win32_parjoyport0 / sizeof (TCHAR))
                || cfgfile_string (option, value, L"parjoyport1", p->win32_parjoyport1, sizeof p->win32_parjoyport1 / sizeof (TCHAR))
                || cfgfile_string (option, value, L"gui_page", p->win32_guipage, sizeof p->win32_guipage / sizeof (TCHAR))
-               || cfgfile_intval (option, value, L"specialkey", &p->win32_specialkey, 1)
                || cfgfile_intval (option, value, L"guikey", &p->win32_guikey, 1)
                || cfgfile_intval (option, value, L"kbledmode", &p->win32_kbledmode, 1)
                || cfgfile_intval (option, value, L"cpu_idle", &p->cpu_idle, 1));
@@ -4723,6 +4720,10 @@ static int parseargs (const TCHAR *argx, const TCHAR *np, const TCHAR *np2)
        if (!np)
                return 0;
 
+       if (!_tcscmp (arg, L"inputlog")) {
+               rawinput_log = getval (np);
+               return 2;
+       }
        if (!_tcscmp (arg, L"vsyncbusywait")) {
                vsync_busy_wait_mode = getval (np);
                return 2;
index 67954d61a17eb3c57269e85c02416a418a9280e4..210afd8ee5ad890f5d8c29b3eed28f027dcdd329 100644 (file)
 #define LANG_DLL 1
 
 //#define WINUAEBETA L""
-#define WINUAEBETA L"Beta 13"
-#define WINUAEDATE MAKEBD(2012, 1, 20)
+#define WINUAEBETA L"Beta 14"
+#define WINUAEDATE MAKEBD(2012, 1, 28)
 #define WINUAEEXTRA L""
+//#define WINUAEEXTRA L"AmiKit Preview"
 #define WINUAEREV L""
 
 #define IHF_WINDOWHIDDEN 6
index b40f1f4986c3ac9b350970a76cf0606d66a61ed5..c529a9d78c58800f6083ebcaeb568fa5a86c367e 100644 (file)
@@ -1371,6 +1371,7 @@ int check_prefs_changed_gfx (void)
        c |= _tcscmp (currprefs.gfx_display_name, changed_prefs.gfx_display_name) ? (2|4|8) : 0;
        c |= currprefs.gfx_blackerthanblack != changed_prefs.gfx_blackerthanblack ? (2 | 8) : 0;
        c |= currprefs.gfx_apmode[0].gfx_backbuffers != changed_prefs.gfx_apmode[0].gfx_backbuffers ? (2 | 8) : 0;
+       c |= currprefs.gfx_apmode[0].gfx_interlaced != changed_prefs.gfx_apmode[0].gfx_interlaced ? (2 | 8) : 0;
        c |= currprefs.gfx_apmode[1].gfx_backbuffers != changed_prefs.gfx_apmode[1].gfx_backbuffers ? (2 | 8) : 0;
 
        c |= currprefs.win32_alwaysontop != changed_prefs.win32_alwaysontop ? 32 : 0;
@@ -1437,6 +1438,7 @@ int check_prefs_changed_gfx (void)
                _tcscpy (currprefs.gfx_display_name, changed_prefs.gfx_display_name);
                currprefs.gfx_blackerthanblack = changed_prefs.gfx_blackerthanblack;
                currprefs.gfx_apmode[0].gfx_backbuffers = changed_prefs.gfx_apmode[0].gfx_backbuffers;
+               currprefs.gfx_apmode[0].gfx_interlaced = changed_prefs.gfx_apmode[0].gfx_interlaced;
                currprefs.gfx_apmode[1].gfx_backbuffers = changed_prefs.gfx_apmode[1].gfx_backbuffers;
 
                currprefs.win32_alwaysontop = changed_prefs.win32_alwaysontop;
@@ -2269,7 +2271,7 @@ static bool waitvblankstate (bool state, int *maxvpos)
        }
 }
 
-bool vblank_wait (void)
+static bool vblank_wait (void)
 {
        int vp;
 
@@ -2285,7 +2287,7 @@ bool vblank_wait (void)
        }
 }
 
-bool vblank_getstate (bool *state)
+static bool vblank_getstate (bool *state)
 {
        int vp, opos;
 
@@ -2305,6 +2307,13 @@ bool vblank_getstate (bool *state)
        return true;
 }
 
+void vblank_reset (void)
+{
+       if (currprefs.gfx_api)
+               D3D_vblank_reset ();
+       else
+               DD_vblank_reset ();
+}
 
 static unsigned int __stdcall flipthread (void *dummy)
 {
@@ -2501,19 +2510,21 @@ struct remembered_vsync
        int width, height, depth, rate, mode;
        bool rtg;
        double remembered_rate, remembered_rate2;
+       int maxscanline, maxvpos;
 };
 
 double vblank_calibrate (double approx_vblank, bool waitonly)
 {
        frame_time_t t1, t2;
-       double tsum, tsum2, tval, tfirst;
+       double tsum, tsum2, tval, tfirst, div;
        int maxcnt, maxtotal, total, cnt, tcnt2;
        HANDLE th;
-       int maxvpos, div;
+       int maxvpos, mult;
        int width, height, depth, rate, mode;
        struct remembered_vsync *rv;
        double rval = -1;
        struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0];
+       bool remembered = false;
 
        if (picasso_on) {
                width = picasso96_state.Width;
@@ -2524,6 +2535,7 @@ double vblank_calibrate (double approx_vblank, bool waitonly)
                height = currentmode->native_height;
                depth = (currentmode->native_depth + 7) / 8;
        }
+
        rate = currprefs.gfx_refreshrate;
        mode = isfullscreen ();
        rv = vsyncmemory;
@@ -2531,22 +2543,15 @@ double vblank_calibrate (double approx_vblank, bool waitonly)
                if (rv->width == width && rv->height == height && rv->depth == depth && rv->rate == rate && rv->mode == mode && rv->rtg == picasso_on) {
                        approx_vblank = rv->remembered_rate2;
                        rval = rv->remembered_rate;
+                       maxscanline = rv->maxscanline;
+                       maxvpos = rv->maxvpos;
                        waitonly = true;
-                       write_log (L"VSync calibration: remembered rate %.6fHz (%.6fHz)\n", rval, approx_vblank);
-                       break;
+                       remembered = true;
+                       goto skip;
                }
                rv = rv->next;
        }
        
-       if (waitonly) {
-               vblankbasefull = syncbase / approx_vblank;
-               vblankbasewait = (syncbase / approx_vblank) * 3 / 4;
-               vblankbasewait2 = (syncbase / approx_vblank) * 70 / 100;
-               vblankbasewait3 = (syncbase / approx_vblank) * 90 / 100;
-               vblank_prev_time = read_processor_time ();
-               return rval;
-       }
-
        th = GetCurrentThread ();
        int oldpri = GetThreadPriority (th);
        SetThreadPriority (th, THREAD_PRIORITY_HIGHEST);
@@ -2561,8 +2566,10 @@ double vblank_calibrate (double approx_vblank, bool waitonly)
                changevblankthreadmode (VBLANKTH_CALIBRATE);
        }
        sleep_millis (100);
+
        maxtotal = 10;
        maxcnt = maxtotal;
+       maxscanline = 0;
        tsum2 = 0;
        tcnt2 = 0;
        for (maxcnt = 0; maxcnt < maxtotal; maxcnt++) {
@@ -2608,34 +2615,49 @@ double vblank_calibrate (double approx_vblank, bool waitonly)
        } else {
                tsum /= total;
        }
-       div = 1;
-       if (tsum >= 85)
-               div = 2;
+
+skip:
+       if (waitonly)
+               tsum = approx_vblank;
+
+       getvsyncrate (tsum, &mult);
+       if (mult < 0)
+               div = 2.0;
+       else if (mult > 0)
+               div = 0.5;
+       else
+               div = 1.0;
        tsum2 = tsum / div;
+
        vblankbasefull = (syncbase / tsum2);
        vblankbasewait = (syncbase / tsum2) * 3 / 4;
        vblankbasewait2 = (syncbase / tsum2) * 70 / 100;
        vblankbasewait3 = (syncbase / tsum2) * 90 / 100;
-       write_log (L"VSync calibration: %.6fHz/%d=%.6fHz. MaxV=%d Units=%d\n", tsum, div, tsum2, maxvpos, vblankbasefull);
+       write_log (L"VSync %s: %.6fHz/%.1f=%.6fHz. MaxV=%d Units=%d\n", waitonly ? L"remembered" : L"calibrated", tsum, div, tsum2, maxvpos, vblankbasefull);
        remembered_vblank = tsum;
        vblank_prev_time = read_processor_time ();
        
-       rv = xcalloc (struct remembered_vsync, 1);
-       rv->width = width;
-       rv->height = height;
-       rv->depth = depth;
-       rv->rate = rate;
-       rv->mode = isfullscreen ();
-       rv->rtg = picasso_on;
-       rv->remembered_rate = tsum;
-       rv->remembered_rate2 = tsum2;
-       if (vsyncmemory == NULL) {
-               vsyncmemory = rv;
-       } else {
-               rv->next = vsyncmemory;
-               vsyncmemory = rv;
-       } 
+       if (!remembered) {
+               rv = xcalloc (struct remembered_vsync, 1);
+               rv->width = width;
+               rv->height = height;
+               rv->depth = depth;
+               rv->rate = rate;
+               rv->mode = isfullscreen ();
+               rv->rtg = picasso_on;
+               rv->remembered_rate = tsum;
+               rv->remembered_rate2 = tsum2;
+               rv->maxscanline = maxscanline;
+               rv->maxvpos = maxvpos;
+               if (vsyncmemory == NULL) {
+                       vsyncmemory = rv;
+               } else {
+                       rv->next = vsyncmemory;
+                       vsyncmemory = rv;
+               }
+       }
        
+       vblank_reset ();
        return tsum;
 fail:
        write_log (L"VSync calibration failed\n");
index 509dc202b706cf97a576adda52aa952834615a6a..6f50d9beed9df76fafdd064d410760574eaad82d 100644 (file)
@@ -41,4 +41,5 @@ void DX_Blit (int x, int y, int w, int h);
 void centerdstrect (RECT *);
 struct MultiDisplay *getdisplay (struct uae_prefs *p);
 double getcurrentvblankrate (void);
+void vblank_reset (void);
 #endif
index 506b6287559d8090e9eda41cb334b66872adabad..b39c223593a3f23e506128ec768ab3fcd9aa3f6f 100644 (file)
@@ -1779,6 +1779,8 @@ static void flipgui (bool opengui)
        D3D_guimode (opengui);
        if (opengui)
                DirectDraw_FlipToGDISurface ();
+       else
+               vblank_reset ();
 }
 
 static int GetSettings (int all_options, HWND hwnd);
@@ -1839,13 +1841,13 @@ void gui_display (int shortcut)
        clearallkeys ();
        inputdevice_acquire (TRUE);
        setmouseactive (1);
-       flipgui (false);
 #ifdef AVIOUTPUT
        AVIOutput_Begin ();
 #endif
        fpscounter_reset ();
        screenshot_free ();
        write_disk_history ();
+       flipgui (false);
        gui_active--;
        here--;
 }
@@ -3318,6 +3320,27 @@ static int disk_swap (int entry, int mode)
 
 static int input_selected_device, input_selected_widget, input_total_devices;
 static int input_selected_event, input_selected_sub_num;
+static int input_copy_from;
+
+static void getqualifiername (TCHAR *p, int mask)
+{
+       int i, j;
+       *p = 0;
+       if (mask == IDEV_MAPPED_QUALIFIER_SPECIAL) {
+               _tcscpy (p, L"*");
+       } else if (mask == IDEV_MAPPED_QUALIFIER_SHIFT) {
+               _tcscpy (p, L"Shift");
+       } else if (mask == IDEV_MAPPED_QUALIFIER_CONTROL) {
+               _tcscpy (p, L"Ctrl");
+       } else if (mask == IDEV_MAPPED_QUALIFIER_ALT) {
+               _tcscpy (p, L"Alt");
+       } else {
+               for (i = IDEV_MAPPED_QUALIFIER1, j = 0; i <= IDEV_MAPPED_QUALIFIER8; i <<= 1, j++) {
+                       if (i == mask)
+                               _stprintf (p, L"%d", j + 1);
+               }
+       }
+}
 
 static void set_lventry_input (HWND list, int index)
 {
@@ -3342,7 +3365,7 @@ static void set_lventry_input (HWND list, int index)
        else if (flags & IDEV_MAPPED_AUTOFIRE_POSSIBLE)
                WIN32GUI_LoadUIString (IDS_NO, toggle, sizeof toggle / sizeof (TCHAR));
        else
-               _tcscpy (toggle, L"-");
+               _tcscpy (toggle, L"-"); 
        if (port > 0) {
                TCHAR tmp[256];
                _tcscpy (tmp, name);
@@ -3351,13 +3374,28 @@ static void set_lventry_input (HWND list, int index)
        ListView_SetItemText (list, index, 1, custom[0] ? custom : name);
        ListView_SetItemText (list, index, 2, af);
        ListView_SetItemText (list, index, 3, toggle);
+       _tcscpy (name, L"-");   
+       if (flags & IDEV_MAPPED_QUALIFIER_MASK) {
+               TCHAR *p;
+               p = name;
+               for (i = 0; i < MAX_INPUT_QUALIFIERS; i++) {
+                       int mask = IDEV_MAPPED_QUALIFIER1 << i;
+                       if (flags & mask) {
+                               if (p != name)
+                                       *p++ = ',';
+                               getqualifiername (p, mask);
+                               p += _tcslen (p);
+                       }
+               }
+       }
+       ListView_SetItemText (list, index, 4, name);
        sub = 0;
        for (i = 0; i < MAX_INPUT_SUB_EVENT; i++) {
                if (inputdevice_get_mapping (input_selected_device, index, &flags, NULL, name, custom, i) || custom[0])
                        sub++;
        }
        _stprintf (name, L"%d", sub);
-       ListView_SetItemText (list, index, 4, name);
+       ListView_SetItemText (list, index, 5, name);
 }
 
 static void update_listview_input (HWND hDlg)
@@ -3491,7 +3529,7 @@ static void update_listview_inputmap (HWND hDlg)
 static int clicked_entry = -1;
 
 #define LOADSAVE_COLUMNS 2
-#define INPUT_COLUMNS 5
+#define INPUT_COLUMNS 6
 #define HARDDISK_COLUMNS 8
 #define DISK_COLUMNS 3
 #define MISC2_COLUMNS 2
@@ -3559,7 +3597,8 @@ void InitializeListView (HWND hDlg)
                WIN32GUI_LoadUIString (IDS_INPUTAMIGAEVENT, column_heading[1], MAX_COLUMN_HEADING_WIDTH);
                WIN32GUI_LoadUIString (IDS_INPUTAUTOFIRE, column_heading[2], MAX_COLUMN_HEADING_WIDTH);
                WIN32GUI_LoadUIString (IDS_INPUTTOGGLE, column_heading[3], MAX_COLUMN_HEADING_WIDTH);
-               _tcscpy (column_heading[4], L"#");
+               WIN32GUI_LoadUIString (IDS_INPUTQUALIFIER, column_heading[4], MAX_COLUMN_HEADING_WIDTH);
+               _tcscpy (column_heading[5], L"#");
                list = GetDlgItem (hDlg, IDC_INPUTLIST);
 
        } else if (hDlg == pages[INPUTMAP_ID]) {
@@ -3642,7 +3681,8 @@ void InitializeListView (HWND hDlg)
                listview_column_width[1] = 260;
                listview_column_width[2] = 65;
                listview_column_width[3] = 65;
-               listview_column_width[4] = 30;
+               listview_column_width[4] = 65;
+               listview_column_width[5] = 30;
                update_listview_input (hDlg);
 
        } else if (lv_type == LV_INPUTMAP) {
@@ -7293,6 +7333,7 @@ static void enable_for_miscdlg (HWND hDlg)
                ew (hDlg, IDC_SCSIMODE, FALSE);
                ew (hDlg, IDC_CLOCKSYNC, FALSE);
                ew (hDlg, IDC_CLIPBOARDSHARE, FALSE);
+               ew (hDlg, IDC_NATIVECODE, FALSE);
        } else {
 #if !defined (SCSIEMU)
                EnableWindow (GetDlgItem(hDlg, IDC_SCSIMODE), TRUE);
@@ -7438,6 +7479,7 @@ static void values_to_miscdlg (HWND hDlg)
                CheckDlgButton (hDlg, IDC_ALWAYSONTOP, workprefs.win32_alwaysontop);
                CheckDlgButton (hDlg, IDC_CLOCKSYNC, workprefs.tod_hack);
                CheckDlgButton (hDlg, IDC_CLIPBOARDSHARE, workprefs.clipboard_sharing);
+               CheckDlgButton (hDlg, IDC_NATIVECODE, workprefs.native_code);
                CheckDlgButton (hDlg, IDC_POWERSAVE, workprefs.win32_powersavedisabled);
                CheckDlgButton (hDlg, IDC_FASTERRTG, workprefs.picasso96_nocustom);
 
@@ -7676,6 +7718,9 @@ static INT_PTR MiscDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
                case IDC_CLIPBOARDSHARE:
                        workprefs.clipboard_sharing = ischecked (hDlg, IDC_CLIPBOARDSHARE);
                        break;
+               case IDC_NATIVECODE:
+                       workprefs.native_code = ischecked (hDlg, IDC_NATIVECODE);
+                       break;
                case IDC_NOTASKBARBUTTON:
                        workprefs.win32_notaskbarbutton = ischecked (hDlg, IDC_NOTASKBARBUTTON);
                        break;
@@ -11349,7 +11394,9 @@ static void init_inputdlg (HWND hDlg)
        }
        WIN32GUI_LoadUIString (IDS_INPUT_COPY_DEFAULT, buf, sizeof (buf) / sizeof (TCHAR));
        SendDlgItemMessage (hDlg, IDC_INPUTCOPYFROM, CB_ADDSTRING, 0, (LPARAM)buf);
-       SendDlgItemMessage (hDlg, IDC_INPUTCOPYFROM, CB_SETCURSEL, 0, 0);
+       SendDlgItemMessage (hDlg, IDC_INPUTCOPYFROM, CB_ADDSTRING, 0, (LPARAM)L"Default");
+       SendDlgItemMessage (hDlg, IDC_INPUTCOPYFROM, CB_ADDSTRING, 0, (LPARAM)L"Default (PC KB)");
+       SendDlgItemMessage (hDlg, IDC_INPUTCOPYFROM, CB_SETCURSEL, input_copy_from, 0);
 
 
        SendDlgItemMessage (hDlg, IDC_INPUTAMIGACNT, CB_RESETCONTENT, 0, 0L);
@@ -11951,10 +11998,8 @@ static void input_copy (HWND hDlg)
        LRESULT src = SendDlgItemMessage (hDlg, IDC_INPUTCOPYFROM, CB_GETCURSEL, 0, 0L);
        if (src == CB_ERR)
                return;
-       int v = (int)src;
-       if (v >= 0 && v <= 3) {
-               inputdevice_copy_single_config (&workprefs, v, workprefs.input_selected_setting, input_selected_device);
-       }
+       input_copy_from = src;
+       inputdevice_copy_single_config (&workprefs, (int)src, workprefs.input_selected_setting, input_selected_device, input_selected_widget);
        init_inputdlg (hDlg);
 }
 
@@ -11981,6 +12026,69 @@ static void input_toggleautofire (void)
        inputdevice_set_mapping (input_selected_device, input_selected_widget,
                name, custom, flags, -1, input_selected_sub_num);
 }
+
+static int genericpopupmenu (HWND hwnd, TCHAR **items, int *flags, int num)
+{
+       int i, item;
+       HMENU menu;
+       POINT pt;
+
+       menu = CreatePopupMenu ();
+       for (i = 0; i < num; i++) {
+               MENUITEMINFO mii = { 0 };
+               mii.cbSize = sizeof mii;
+               mii.fMask = MIIM_STRING | MIIM_ID | MIIM_STATE;
+               mii.fType = MFT_STRING;
+               mii.fState = MFS_ENABLED;
+               if (flags[i])
+                       mii.fState |= MFS_CHECKED;
+               mii.wID = i + 1;
+               mii.dwTypeData = items[i];
+               mii.cch = _tcslen (mii.dwTypeData);
+               InsertMenuItem (menu, -1, TRUE, &mii);
+       }
+       GetCursorPos (&pt);
+       item = TrackPopupMenu (menu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD,
+               pt.x, pt.y, 0, hwnd, NULL);
+       PostMessage (hwnd, WM_NULL, 0, 0);
+       DestroyMenu (menu);
+       return item - 1;
+}
+
+static void input_qualifiers (HWND hDlg)
+{
+       int flags, evt, item;
+       TCHAR name[256];
+       TCHAR custom[MAX_DPATH];
+       TCHAR *names[MAX_INPUT_QUALIFIERS];
+       int mflags[MAX_INPUT_QUALIFIERS];
+       TCHAR tmp[MAX_DPATH];
+       
+       if (input_selected_device < 0 || input_selected_widget < 0)
+               return;
+       evt = inputdevice_get_mapping (input_selected_device, input_selected_widget,
+               &flags, NULL, name, custom, input_selected_sub_num);
+       if (evt <= 0)
+               name[0] = 0;
+       
+       for (int i = 0; i < MAX_INPUT_QUALIFIERS; i++) {
+               getqualifiername (tmp, IDEV_MAPPED_QUALIFIER1 << i);
+               mflags[i] = 0;
+               if (flags & (IDEV_MAPPED_QUALIFIER1 << i))
+                       mflags[i] = 1;
+               names[i] = my_strdup (tmp);
+       }
+       item = genericpopupmenu (hDlg, names, mflags, MAX_INPUT_QUALIFIERS);
+       if (item >= 0)
+               flags ^= IDEV_MAPPED_QUALIFIER1 << item;
+
+       inputdevice_set_mapping (input_selected_device, input_selected_widget,
+               name, custom, flags, -1, input_selected_sub_num);
+
+       for (int i = 0; i < MAX_INPUT_QUALIFIERS; i++) {
+               xfree (names[i]);
+       }
+}
 static void input_toggletoggle (void)
 {
        int flags, evt;
@@ -12086,6 +12194,13 @@ static INT_PTR CALLBACK InputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
                        list = nmlistview->hdr.hwndFrom;
                        switch (nmlistview->hdr.code)
                        {
+                       case NM_RDBLCLK:
+                       case NM_RCLICK:
+                               input_selected_widget = -1;
+                               ListView_SetItemState (list, -1, 0, LVIS_SELECTED);
+                               update_listview_input (hDlg);
+                               init_inputdlg_2 (hDlg);
+                               break;
                        case NM_DBLCLK:
                                dblclick = 1;
                                /* fall-through */
@@ -12098,7 +12213,9 @@ static INT_PTR CALLBACK InputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
                                                input_toggleautofire ();
                                        if (row == 3 && entry == oldentry)
                                                input_toggletoggle ();
-                                       if (row == 4) {
+                                       if (row == 4 && entry == oldentry)
+                                               input_qualifiers (hDlg);
+                                       if (row == 5) {
                                                input_selected_sub_num++;
                                                if (input_selected_sub_num >= MAX_INPUT_SUB_EVENT)
                                                        input_selected_sub_num = 0;
@@ -12107,7 +12224,7 @@ static INT_PTR CALLBACK InputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
                                } else {
                                        input_selected_widget = -1;
                                }
-                               if (dblclick)
+                               if (dblclick && row <= 1)
                                        doinputcustom (hDlg, 0);
                                update_listview_input (hDlg);
                                init_inputdlg_2 (hDlg);
index 08c1fe7512d164599ede1b22d2332258b043707a..805693b5e852fbf090d4dc4a13815b8842c2b2a1 100644 (file)
@@ -1,4 +1,36 @@
 
+Beta 14:
+
+- Input panel qualifier key/button support. I think this was requested many many years ago.
+  (I didn't originally plan to this now but someone reminded me few days ago..)
+  - Any key or button can be configured as a qualifier (like a shift or control key that modifies behavior
+    of other keys)
+  - Any Input Target can be configured to require qualifiers. Input Target only triggers if it's
+    Input Source and all configured qualifiers are active at the same time.
+  - If multiple slots are configured, only slot(s) that have matching qualifier will be triggered,
+    for example if slot 1 has qualifier and slot 2 has none: Only slot 2 triggers if Input Source matches
+    without qualifier active and only slot 1 if Input Source matches with active qualifier.
+  - Same qualifer code (1-8) can be configured to more than one key/button.
+  - Qualifier(s) set to any other types than keys or buttons is currently undefined.
+  - End ("*" in GUI), Shift, Alt and Control keys are mapped to built-in qualifiers.
+  - Most previously hardwired key mappings (END+F1 etc..) are now implemented using Input qualifier system
+    Exceptions: F12 so that there is no way for users to accidentally disable GUI access.
+    END+<number> and END+<numpad number> disk swapper and statefile shortcuts, I didn't want to add 30+
+    new mostly pointless input targets.. Disabled if END-key's qualifier flag is removed.
+  - Qualifiers and custom events: slots 1 to 4 and 5 to 8 can have different qualifiers.
+
+- Doubled number of input target slots (4 to 8)
+- "Copy from"-button corrupted memory.
+- Added keyboard default options to "Copy from"-button. Can select either Amiga or PC default mapping.
+- TODO: restore only single input target to default.
+
+- Less than 35Hz vsync display refresh rate: show only every other frame.
+- Workaround for strange Windows feature or a bug. First call raw input RegisterRawInputDevices() to unregister
+  HID devices and then immediately call to register them again: Windows randomly stops reporting HID events.
+- Windows to Amiga clipboard sharing wrong string size if string contained cr/lf line endings.
+- Low latency VSync screen mode switch fixes and updates.
+- Native code execution (winlauch.alib etc..) is not anymore allowed by default. Option in misc panel.
+
 Beta 13:
 
 - bsdsocket emulation: use SOCK_DGRAM if requesting IPPROTO_UDP + SOCK_RAW. Raw sockets require