From 999db79bc601ba44ceb627f1f5ac5f147e1f533c Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 28 Jan 2012 18:06:59 +0200 Subject: [PATCH] 2400b14 --- cfgfile.cpp | 10 + custom.cpp | 300 ++++++++++++++--------- gfxutil.cpp | 11 +- include/inputdevice.h | 51 +++- include/keyboard.h | 6 +- include/options.h | 13 +- include/xwin.h | 2 +- inputdevice.cpp | 444 ++++++++++++++++++++++++++-------- inputevents.def | 21 ++ od-win32/ahidsound_dsonly.cpp | 56 +++-- od-win32/clipboard_win32.cpp | 2 +- od-win32/dinput.cpp | 183 ++++++++------ od-win32/direct3d.cpp | 30 ++- od-win32/direct3d.h | 1 + od-win32/dxwrap.cpp | 60 +++-- od-win32/dxwrap.h | 2 + od-win32/keyboard_win32.cpp | 130 +++++----- od-win32/picasso96_win.cpp | 4 +- od-win32/resources/resource | 4 +- od-win32/resources/winuae.rc | 10 +- od-win32/win32.cpp | 11 +- od-win32/win32.h | 5 +- od-win32/win32gfx.cpp | 90 ++++--- od-win32/win32gfx.h | 1 + od-win32/win32gui.cpp | 143 ++++++++++- od-win32/winuaechangelog.txt | 32 +++ 26 files changed, 1129 insertions(+), 493 deletions(-) diff --git a/cfgfile.cpp b/cfgfile.cpp index cc2b4079..7d7bd5d3 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -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; diff --git a/custom.cpp b/custom.cpp index d0e07832..245d6149 100644 --- a/custom.cpp +++ b/custom.cpp @@ -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 (); diff --git a/gfxutil.cpp b/gfxutil.cpp index 7690ce09..44792f23 100644 --- a/gfxutil.cpp +++ b/gfxutil.cpp @@ -16,10 +16,17 @@ #include -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; } diff --git a/include/inputdevice.h b/include/inputdevice.h index 9ea6313c..9572cb19 100644 --- a/include/inputdevice.h +++ b/include/inputdevice.h @@ -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 diff --git a/include/keyboard.h b/include/keyboard.h index e1bcbded..c0d62e99 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -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 diff --git a/include/options.h b/include/options.h index a6c029d6..2df5ae4c 100644 --- a/include/options.h +++ b/include/options.h @@ -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]; diff --git a/include/xwin.h b/include/xwin.h index 5806d2fe..e836f579 100644 --- a/include/xwin.h +++ b/include/xwin.h @@ -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. diff --git a/inputdevice.cpp b/inputdevice.cpp index 861c55fc..ed93b8c7 100644 --- a/inputdevice.cpp +++ b/inputdevice.cpp @@ -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) diff --git a/inputevents.def b/inputevents.def index b7c89d03..b6607b4b 100644 --- a/inputevents.def +++ b/inputevents.def @@ -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) diff --git a/od-win32/ahidsound_dsonly.cpp b/od-win32/ahidsound_dsonly.cpp index c322953c..ddb27837 100644 --- a/od-win32/ahidsound_dsonly.cpp +++ b/od-win32/ahidsound_dsonly.cpp @@ -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] diff --git a/od-win32/clipboard_win32.cpp b/od-win32/clipboard_win32.cpp index 7e5b9035..38ee0e2f 100644 --- a/od-win32/clipboard_win32.cpp +++ b/od-win32/clipboard_win32.cpp @@ -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; diff --git a/od-win32/dinput.cpp b/od-win32/dinput.cpp index 79d5c2d7..da12323a 100644 --- a/od-win32/dinput.cpp +++ b/od-win32/dinput.cpp @@ -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) diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index 188025d8..5eb71b01 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -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 (); } diff --git a/od-win32/direct3d.h b/od-win32/direct3d.h index b3574846..e8a0838b 100644 --- a/od-win32/direct3d.h +++ b/od-win32/direct3d.h @@ -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 diff --git a/od-win32/dxwrap.cpp b/od-win32/dxwrap.cpp index ed7764ac..2c502944 100644 --- a/od-win32/dxwrap.cpp +++ b/od-win32/dxwrap.cpp @@ -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); +} diff --git a/od-win32/dxwrap.h b/od-win32/dxwrap.h index 4c5673e0..08fc91fe 100644 --- a/od-win32/dxwrap.h +++ b/od-win32/dxwrap.h @@ -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); diff --git a/od-win32/keyboard_win32.cpp b/od-win32/keyboard_win32.cpp index 0b155cc5..8d08b0f6 100644 --- a/od-win32/keyboard_win32.cpp +++ b/od-win32/keyboard_win32.cpp @@ -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); } diff --git a/od-win32/picasso96_win.cpp b/od-win32/picasso96_win.cpp index f10f0450..95554ab5 100644 --- a/od-win32/picasso96_win.cpp +++ b/od-win32/picasso96_win.cpp @@ -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; diff --git a/od-win32/resources/resource b/od-win32/resources/resource index e8058eea..444f4073 100644 --- a/od-win32/resources/resource +++ b/od-win32/resources/resource @@ -264,6 +264,7 @@ #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 @@ -352,7 +353,6 @@ #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 @@ -756,6 +756,8 @@ #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 diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index c0be8ed0..bde0a3a6 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -487,7 +487,7 @@ BEGIN GROUPBOX "Miscellaneous Options",IDC_STATIC,4,2,293,165 CONTROL "Untrap = middle button",IDC_JULIAN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,19,110,10 CONTROL "Show GUI on startup",IDC_SHOWGUI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,43,109,10 - CONTROL "Native on-screen display",IDC_SHOWLEDS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,139,109,10 + CONTROL "Native on-screen display",IDC_SHOWLEDS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,182,103,109,10 CONTROL "Don't show taskbar button",IDC_NOTASKBARBUTTON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,67,109,10 CONTROL "Use CTRL-F11 to quit",IDC_CTRLF11,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,55,110,10 GROUPBOX "Keyboard LEDs",IDC_STATIC,3,207,294,29 @@ -512,13 +512,14 @@ BEGIN CONTROL "Synchronize clock",IDC_CLOCKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,103,111,10 CONTROL "Faster RTG [] Enables less accurate custom chipset emulation mode when Picasso96 is enabled.",IDC_FASTERRTG, "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,19,115,111,10 - CONTROL "RTG on-screen display",IDC_SHOWLEDSRTG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,151,109,10 + CONTROL "RTG on-screen display",IDC_SHOWLEDSRTG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,182,114,109,10 RTEXT "Graphics API:",IDC_STATIC,130,62,79,10,SS_CENTERIMAGE COMBOBOX IDC_DXMODE,213,60,79,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP CONTROL "Minimize when focus is lost",IDC_FOCUSMINIMIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,31,110,10 RTEXT "Windowed style:",IDC_STATIC,128,45,81,10,SS_CENTERIMAGE COMBOBOX IDC_WINDOWEDMODE,213,43,79,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP CONTROL "Clipboard sharing",IDC_CLIPBOARDSHARE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,127,111,10 + CONTROL "Allow native code",IDC_NATIVECODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,139,111,10 END IDD_HARDFILE DIALOGEX 0, 0, 299, 249 @@ -1699,6 +1700,11 @@ BEGIN IDS_SCREEN_VSYNC_NONE "-" END +STRINGTABLE +BEGIN + IDS_INPUTQUALIFIER "Qualifiers" +END + #endif // English resources ///////////////////////////////////////////////////////////////////////////// diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 466e1a9e..92fda294 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -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; diff --git a/od-win32/win32.h b/od-win32/win32.h index 67954d61..210afd8e 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -19,9 +19,10 @@ #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 diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index b40f1f49..c529a9d7 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -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"); diff --git a/od-win32/win32gfx.h b/od-win32/win32gfx.h index 509dc202..6f50d9be 100644 --- a/od-win32/win32gfx.h +++ b/od-win32/win32gfx.h @@ -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 diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 506b6287..b39c2235 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -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); diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 08c1fe75..805693b5 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -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+ and END+ 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 -- 2.47.3