]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
on screen keyboard
authorToni Wilen <twilen@winuae.net>
Sat, 21 Oct 2023 16:45:56 +0000 (19:45 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 21 Oct 2023 16:45:56 +0000 (19:45 +0300)
aks.def
include/inputdevice.h
include/uae.h
inputdevice.cpp
inputevents.def
od-win32/dinput.cpp
od-win32/win32gfx.cpp
od-win32/win32gfx.h
od-win32/win32gui.cpp

diff --git a/aks.def b/aks.def
index 9690194dcb8d82a0e3d36c8ab2338cf0b4b3e61c..277f117dc22a9426d7bce065be1acc3adbab0be0 100644 (file)
--- a/aks.def
+++ b/aks.def
@@ -134,4 +134,5 @@ AKS(CUBOCOIN1)
 AKS(CUBOCOIN2)
 AKS(CUBOCOIN3)
 AKS(CUBOCOIN4)
+AKS(OSK)
 
index 44d08cec9196f8626133e227f66ba88971e7241a..072ad8fecd91449c1f1e51e67a4da257100ab334 100644 (file)
@@ -378,6 +378,9 @@ bool key_shiftpressed(void);
 bool key_altpressed(void);
 bool key_ctrlpressed(void);
 
+void osk_setup(int, int);
+bool osk_status(void);
+
 extern int key_swap_hack, key_swap_hack2;
 
 #endif /* UAE_INPUTDEVICE_H */
index a4e871a9f8122dcfa160520fa81225c8532ebdcd..2fd0982fd480a420b5caf0f1e98c3df5df6ba743 100644 (file)
@@ -53,6 +53,8 @@ extern bool is_mainthread(void);
 extern void fpu_reset(void);
 extern void fpux_save(int*);
 extern void fpux_restore(int*);
+extern bool target_osd_keyboard(int);
+extern void target_osk_control(int, int, int, int);
 
 extern int quit_program;
 extern bool console_emulation;
index d3787dc0e4db86f5902ed0838275017987bee73b..7ef17809b4cf40967826c8974b9cebe57c3c4f21 100644 (file)
@@ -195,6 +195,50 @@ static struct temp_uids temp_uid;
 static int temp_uid_index[MAX_INPUT_DEVICES][IDTYPE_MAX];
 static int temp_uid_cnt[IDTYPE_MAX];
 static int gp_swappeddevices[MAX_INPUT_DEVICES][IDTYPE_MAX];
+static int osk_state;
+
+bool osk_status(void)
+{
+       return osk_state != 0;
+}
+
+static void osk_control(int x, int y, int button, int buttonstate)
+{
+       if (!osk_state) {
+               return;
+       }
+       target_osk_control(x, y, button, buttonstate);
+}
+
+void osk_setup(int monid, int state)
+{
+       if (monid) {
+               return;
+       }
+       if (state < -1) {
+               if (osk_state) {
+                       target_osd_keyboard(0);
+                       if (!target_osd_keyboard(1)) {
+                               target_osd_keyboard(0);
+                       }
+               }
+               return;
+       }
+       if (state == -1) {
+               osk_state = osk_state ? 0 : 1;
+       } else {
+               osk_state = state;
+       }
+       if (!osk_state) {
+               target_osd_keyboard(0);
+               return;
+       }
+       if (!target_osd_keyboard(1)) {
+               target_osd_keyboard(0);
+               osk_state = 0;
+               return;
+       }
+}
 
 static int isdevice (struct uae_input_device *id)
 {
@@ -4753,6 +4797,9 @@ static bool inputdevice_handle_inputcode2(int monid, int code, int state, const
 
        switch (code)
        {
+       case AKS_OSK:
+               osk_setup(0, -1);
+               break;
        case AKS_ENTERGUI:
                gui_display (-1);
                setsystime ();
@@ -5299,25 +5346,27 @@ static int handle_input_event2(int nr, int state, int max, int flags, int extra)
        case 4: /* ->Parallel port joystick adapter port #2 */
                joy = ie->unit - 1;
                if (ie->type & 4) {
-                       int old = joybutton[joy] & (1 << ie->data);
-
-                       if (state) {
-                               joybutton[joy] |= 1 << ie->data;
-                               gui_gameport_button_change (joy, ie->data, 1);
+                       if (osk_state) {
+                               osk_control(0, 0, 1 << ie->data, state);
                        } else {
-                               joybutton[joy] &= ~(1 << ie->data);
-                               gui_gameport_button_change (joy, ie->data, 0);
-                       }
+                               int old = joybutton[joy] & (1 << ie->data);
+                               if (state) {
+                                       joybutton[joy] |= 1 << ie->data;
+                                       gui_gameport_button_change (joy, ie->data, 1);
+                               } else {
+                                       joybutton[joy] &= ~(1 << ie->data);
+                                       gui_gameport_button_change (joy, ie->data, 0);
+                               }
 
-                       if (ie->data == 0 && old != (joybutton[joy] & (1 << ie->data)) && currprefs.cpu_cycle_exact) {
-                               if (!input_record && !input_play && currprefs.input_contact_bounce) {
-                                       // emulate contact bounce, 1st button only, others have capacitors
-                                       bouncy = 1;
-                                       bouncy_cycles = get_cycles () + CYCLE_UNIT * currprefs.input_contact_bounce;
+                               if (ie->data == 0 && old != (joybutton[joy] & (1 << ie->data)) && currprefs.cpu_cycle_exact) {
+                                       if (!input_record && !input_play && currprefs.input_contact_bounce) {
+                                               // emulate contact bounce, 1st button only, others have capacitors
+                                               bouncy = 1;
+                                               bouncy_cycles = get_cycles () + CYCLE_UNIT * currprefs.input_contact_bounce;
+                                       }
                                }
                        }
 
-
                } else if (ie->type & 8) {
 
                        /* real mouse / analog stick mouse emulation */
@@ -5546,38 +5595,53 @@ static int handle_input_event2(int nr, int state, int max, int flags, int extra)
                        }
                        mouse_deltanoreset[joy][0] = 1;
                        mouse_deltanoreset[joy][1] = 1;
-                       joydir[joy] = 0;
-                       if (left) {
-                               if (!allowoppositestick) {
-                                       joydir[joy] &= ~DIR_RIGHT;
+                       if (osk_state) {
+                               if (left) {
+                                       osk_control(-1, 0, 0, 0);
                                }
-                               joydir[joy] |= DIR_LEFT;
-                       }
-                       if (right) {
-                               if (!allowoppositestick) {
-                                       joydir[joy] &= ~DIR_LEFT;
+                               if (right) {
+                                       osk_control(1, 0, 0, 0);
                                }
-                               joydir[joy] |= DIR_RIGHT;
-                       }
-                       if (top) {
-                               if (!allowoppositestick) {
-                                       joydir[joy] &= ~DIR_DOWN;
+                               if (top) {
+                                       osk_control(0, -1, 0, 0);
                                }
-                               joydir[joy] |= DIR_UP;
-                       }
-                       if (bot) {
-                               if (!allowoppositestick) {
-                                       joydir[joy] &= ~DIR_UP;
+                               if (bot) {
+                                       osk_control(0, 1, 0, 0);
                                }
-                               joydir[joy] |= DIR_DOWN;
-                       }
-                       if (joy == 0 || joy == 1)
-                               joymousecounter (joy); 
+                       } else {
+                               joydir[joy] = 0;
+                               if (left) {
+                                       if (!allowoppositestick) {
+                                               joydir[joy] &= ~DIR_RIGHT;
+                                       }
+                                       joydir[joy] |= DIR_LEFT;
+                               }
+                               if (right) {
+                                       if (!allowoppositestick) {
+                                               joydir[joy] &= ~DIR_LEFT;
+                                       }
+                                       joydir[joy] |= DIR_RIGHT;
+                               }
+                               if (top) {
+                                       if (!allowoppositestick) {
+                                               joydir[joy] &= ~DIR_DOWN;
+                                       }
+                                       joydir[joy] |= DIR_UP;
+                               }
+                               if (bot) {
+                                       if (!allowoppositestick) {
+                                               joydir[joy] &= ~DIR_UP;
+                                       }
+                                       joydir[joy] |= DIR_DOWN;
+                               }
+                               if (joy == 0 || joy == 1)
+                                       joymousecounter (joy); 
 
-                       gui_gameport_axis_change (joy, DIR_LEFT_BIT, left, 0);
-                       gui_gameport_axis_change (joy, DIR_RIGHT_BIT, right, 0);
-                       gui_gameport_axis_change (joy, DIR_UP_BIT, top, 0);
-                       gui_gameport_axis_change (joy, DIR_DOWN_BIT, bot, 0);
+                               gui_gameport_axis_change (joy, DIR_LEFT_BIT, left, 0);
+                               gui_gameport_axis_change (joy, DIR_RIGHT_BIT, right, 0);
+                               gui_gameport_axis_change (joy, DIR_UP_BIT, top, 0);
+                               gui_gameport_axis_change (joy, DIR_DOWN_BIT, bot, 0);
+                       }
                }
                break;
        case 0: /* ->KEY */
index 76930bf71112dcf56b8dfcd8ae15d418b496de87..d9629b2bdc0d4ece8c4bf33862e30e13372cc4aa 100644 (file)
@@ -453,4 +453,6 @@ DEFEVENT(SPC_VIDEOGRAB_PAUSE,_T("VideoGrab Pause"),AM_K,0,0,AKS_VIDEOGRAB_PAUSE)
 DEFEVENT(SPC_VIDEOGRAB_PREV,_T("VideoGrab Previous Frame"),AM_K,0,0,AKS_VIDEOGRAB_PREV)
 DEFEVENT(SPC_VIDEOGRAB_NEXT,_T("VideoGrab Next Frame"),AM_K,0,0,AKS_VIDEOGRAB_NEXT)
 
+DEFEVENT(SPC_OSK,_T("On screen keyboard"),AM_K,0,0,AKS_OSK)
+
 DEFEVENT(SPC_LAST, _T(""), AM_DUMMY, 0,0,0)
index 670e434dd7f1e5bd99de0ea0a36b1052a27b3f34..ceff6deb3e5a959e930b593437940bb8fcd007a7 100644 (file)
@@ -4580,6 +4580,8 @@ int input_get_default_joystick (struct uae_input_device *uid, int i, int port, i
                        if (isrealbutton (did, 2))
                                setid (uid, i, ID_BUTTON_OFFSET + 2, 0, port, port ? INPUTEVENT_JOY2_3RD_BUTTON : INPUTEVENT_JOY1_3RD_BUTTON, gp);
                }
+               if (isrealbutton(did, 3))
+                       setid(uid, i, ID_BUTTON_OFFSET + 3, 0, port, INPUTEVENT_SPC_OSK, gp);
        }
 
        for (j = 2; j < MAX_MAPPINGS - 1; j++) {
@@ -4629,12 +4631,14 @@ int input_get_default_joystick_analog (struct uae_input_device *uid, int i, int
        setid (uid, i, ID_AXIS_OFFSET + 0, 0, port, port ? INPUTEVENT_JOY2_HORIZ_POT : INPUTEVENT_JOY1_HORIZ_POT, gp);
        setid (uid, i, ID_AXIS_OFFSET + 1, 0, port, port ? INPUTEVENT_JOY2_VERT_POT : INPUTEVENT_JOY1_VERT_POT, gp);
        setid (uid, i, ID_BUTTON_OFFSET + 0, 0, port, port ? INPUTEVENT_JOY2_LEFT : INPUTEVENT_JOY1_LEFT, af, gp);
-       if (isrealbutton (did, 1))
-               setid (uid, i, ID_BUTTON_OFFSET + 1, 0, port, port ? INPUTEVENT_JOY2_RIGHT : INPUTEVENT_JOY1_RIGHT, gp);
-       if (isrealbutton (did, 2))
-               setid (uid, i, ID_BUTTON_OFFSET + 2, 0, port, port ? INPUTEVENT_JOY2_UP : INPUTEVENT_JOY1_UP, gp);
-       if (isrealbutton (did, 3))
-               setid (uid, i, ID_BUTTON_OFFSET + 3, 0, port, port ? INPUTEVENT_JOY2_DOWN : INPUTEVENT_JOY1_DOWN, gp);
+       if (isrealbutton(did, 1))
+               setid(uid, i, ID_BUTTON_OFFSET + 1, 0, port, port ? INPUTEVENT_JOY2_RIGHT : INPUTEVENT_JOY1_RIGHT, gp);
+       if (isrealbutton(did, 2))
+               setid(uid, i, ID_BUTTON_OFFSET + 2, 0, port, port ? INPUTEVENT_JOY2_UP : INPUTEVENT_JOY1_UP, gp);
+       if (isrealbutton(did, 3))
+               setid(uid, i, ID_BUTTON_OFFSET + 3, 0, port, port ? INPUTEVENT_JOY2_DOWN : INPUTEVENT_JOY1_DOWN, gp);
+       if (isrealbutton(did, 4))
+               setid(uid, i, ID_BUTTON_OFFSET + 4, 0, port, INPUTEVENT_SPC_OSK, gp);
 
        for (j = 2; j < MAX_MAPPINGS - 1; j++) {
                int type = did->axistype[j];
index 5dcc1a798e406ffb61286f0536665aaf47d4f2be..ca69f8543096845f620ddb6b2e55a780842a82d1 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/*
 /*
 * UAE - The Un*x Amiga Emulator
 *
@@ -57,6 +57,7 @@
 #include "gfxboard.h"
 #include "cpuboard.h"
 #include "x86.h"
+#include "keybuf.h"
 #ifdef RETROPLATFORM
 #include "rp.h"
 #endif
@@ -4112,9 +4113,12 @@ retry:
        if (isfullscreen () != 0)
                setmouseactive(mon->monitor_id, -1);
 
+       osk_setup(mon->monitor_id, -2);
+
        return 1;
 
 oops:
+       osk_setup(mon->monitor_id, 0);
        close_hwnds(mon);
        return ret;
 }
@@ -4140,8 +4144,10 @@ bool target_graphics_buffer_update(int monid)
                h = vb->outheight;
        }
        
-       if (oldtex_w[monid] == w && oldtex_h[monid] == h && oldtex_rtg[monid] == mon->screen_is_picasso && D3D_alloctexture(mon->monitor_id, -1, -1))
+       if (oldtex_w[monid] == w && oldtex_h[monid] == h && oldtex_rtg[monid] == mon->screen_is_picasso && D3D_alloctexture(mon->monitor_id, -1, -1)) {
+               osk_setup(monid, -2);
                return false;
+       }
 
        if (!w || !h) {
                oldtex_w[monid] = w;
@@ -4159,6 +4165,7 @@ bool target_graphics_buffer_update(int monid)
        oldtex_w[monid] = w;
        oldtex_h[monid] = h;
        oldtex_rtg[monid] = mon->screen_is_picasso;
+       osk_setup(monid, -2);
 
        write_log (_T("Buffer %d size (%d*%d) %s\n"), monid, w, h, mon->screen_is_picasso ? _T("RTG") : _T("Native"));
 
@@ -4413,3 +4420,597 @@ const TCHAR *DXError(HRESULT ddrval)
                HRESULT_CODE(ddrval));
        return dderr;
 }
+
+struct osd_kb
+{
+       uae_s16 x, y;
+       uae_s16 w, h;
+       uae_u16 code;
+       uae_s8 pressed;
+       uae_s8 inverted;
+};
+
+static struct osd_kb *osd_kb_data;
+static int osd_kb_selected = 11, osd_kb_x, osd_kb_y;
+struct extoverlay osd_kb_eo = { 0 };
+
+#define OSD_KB_TRANSPARENCY 0xee
+#define OSD_KB_ACTIVE_TRANSPARENCY 0xee
+#define OSD_KB_PRESSED_TRANSPARENCY 0xff
+#define OSD_KB_COLOR 0xeeeeee
+#define OSD_KB_ACTIVE_COLOR 0x44cc44
+#define OSD_KB_PRESSED_COLOR 0x222222
+#define OSD_KB_PRESSED_COLOR2 0x444444
+
+static void drawpixel(uae_u8 *p, uae_u32 c, uae_u8 trans)
+{
+       ((uae_u32*)p)[0] = (c & 0x00ffffff) | (trans << 24);
+}
+
+static void drawline(struct extoverlay *eo, int x1, int y1, int x2, int y2)
+{
+       uae_u8 *p = eo->data + y1 * eo->width * 4 + x1 * 4;
+       if (x1 != x2) {
+               x2++;
+       }
+       if (y1 != y2) {
+               y2++;
+       }
+       while (x1 != x2) {
+               drawpixel(p, OSD_KB_COLOR, OSD_KB_TRANSPARENCY);
+               if (x1 < x2) {
+                       x1++;
+                       p += 4;
+               } else {
+                       x1--;
+                       p -= 4;
+               }
+       }
+       while (y1 != y2) {
+               drawpixel(p, OSD_KB_COLOR, OSD_KB_TRANSPARENCY);
+               if (y1 < y2) {
+                       y1++;
+                       p += eo->width * 4;
+               } else {
+                       y1--;
+                       p -= eo->width * 4;
+               }
+       }
+}
+
+static void highlight(struct extoverlay *eo, struct osd_kb *kb, bool mode)
+{
+       if (kb->inverted) {
+               kb->inverted = false;
+               highlight(eo, kb, true);
+               kb->inverted = false;
+       }
+       int x1 = kb->x;
+       int x2 = kb->x + kb->w;
+       int y1 = kb->y;
+       int y2 = kb->y + kb->h;
+       uae_u8 *p = eo->data + y1 * eo->width * 4;
+       uae_u32 color = 0;
+       uae_u8 tr = 0;
+       if (mode) {
+               kb->inverted = true;
+               color = OSD_KB_COLOR;
+               tr = OSD_KB_TRANSPARENCY;
+       } else {
+               color = !mode ? OSD_KB_COLOR : OSD_KB_ACTIVE_COLOR;
+               tr = !mode ? OSD_KB_TRANSPARENCY : OSD_KB_ACTIVE_TRANSPARENCY;
+               if (kb->pressed) {
+                       color = OSD_KB_PRESSED_COLOR;
+                       tr = OSD_KB_PRESSED_TRANSPARENCY;
+               }
+       }
+       while (y1 <= y2) {
+               uae_u8 *pp = p + x1 * 4;
+               for (int x = x1; x <= x2; x++) {
+                       if (kb->inverted) {
+                               uae_u32 *p32 = (uae_u32*)pp;
+                               *p32 ^= 0xffffff;
+                       } else {
+                               if (pp[0] || pp[1] || pp[2]) {
+                                       drawpixel(pp, color, tr);
+                               } else {
+                                       pp[3] = tr;
+                               }
+                       }
+                       pp += 4;
+               }
+               p += eo->width * 4;
+               y1++;
+       }
+       if (mode) {
+               if (osd_kb_x < kb->x || osd_kb_x > kb->x + kb->w) {
+                       osd_kb_x = kb->x + kb->w / 2;
+               }
+               if (osd_kb_y < kb->y || osd_kb_y > kb->y + kb->h) {
+                       osd_kb_y = kb->y + kb->h / 2;
+               }
+       }
+}
+
+static const uae_s16 layout[] = {
+       10,-5,13,13,13,13,13,-5,13,13,13,13,13,-5,13,13,13,13,0,
+       15,10,10,10,10,10,10,10,10,10,10,10,10,10,10,-5,15,15,-5,10,10,10,10,0,
+       23,10,10,10,10,10,10,10,10,10,10,10,10,12 + 256,-40,10,10,10,10,0,
+       13,10,10,10,10,10,10,10,10,10,10,10,10,10,-27,10,-15,10,10,10,10,0,
+       18,10,10,10,10,10,10,10,10,10,10,10,27,-5,10,10,10,-5,10,10,10,10 + 256,0,
+       -8,13,13,90,13,13,-45,20,10,0,
+       0
+};
+static const TCHAR *key_labels[] = {
+       L"Esc",L"F1",L"F2",L"F3",L"F4",L"F5",L"F6",L"F7",L"F8",L"F9",L"F10",L"GUI",L"J<>M",L"↑↓",L"X",
+       L"~|´",L"!|1",L"@|2",L"#|3",L"$|4",L"%|5",L"^|6",L"&|7",L"*|8",L"(|9",L")|0",L"_|-",L"+|=",L"\\||\\\\",L"←",L"Del",L"Help",L"(",L")",L"/",L"*",
+       L"←|→",L"Q",L"W",L"E",L"R",L"T",L"Y",L"U",L"I",L"O",L"P",L"{|[",L"}|]",L"Ret",L"7",L"8",L"9",L"-",
+       L"Ctrl",L"Caps|Lock",L"A",L"S",L"D",L"F",L"G",L"H",L"J",L"K",L"L",L":|;",L"*|'",L"",L"↑",L"4",L"5",L"6",L"+",
+       L"Shift",L"",L"Z",L"X",L"C",L"V",L"B",L"N",L"M",L"<|,",L">|.",L"?|/",L"Shift",L"←",L"↓",L"→",L"1",L"2",L"3",L"E|n|t|e|r",
+       L"Alt",L"\\iA",L"",L"\\iA",L"Alt",L"0",L".",
+       0,0
+};
+static const uae_u16 key_codes[] = {
+       0x45, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, AKS_ENTERGUI | 0x8000, AKS_SWAPJOYPORTS | 0x8000, 0xf001, AKS_OSK | 0x8000,
+       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x41, 0x46, 0x5f, 0x5a, 0x5b, 0x5c, 0x5d,
+       0x42, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x44, 0x3d, 0x3e, 0x3f, 0x4a,
+       0x63, 0x62, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x4c, 0x2d, 0x2e, 0x2f, 0x5e,
+       0x60, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x61, 0x4f, 0x4d, 0x4e, 0x1d, 0x1e, 0x1f, 0x43,
+       0x64, 0x66, 0x40, 0x67, 0x64, 0x0f, 0x3c,
+       0
+};
+
+static void draw_key(HDC hdc, void *bm, int bmw, int bmh, struct extoverlay *eo, float sx, float sy, const TCHAR *key, int len, int fw, int fh)
+{
+       SetBkMode(hdc, OPAQUE);
+       BitBlt(hdc, 0, 0, bmw, bmh, NULL, 0, 0, BLACKNESS);
+       TextOut(hdc, 10, 10, key, len);
+       int offsetx = 10;
+       int offsety = 10 - 1;
+       for (int y = 0; y < fh + 2; y++) {
+               uae_u8 *src = (uae_u8 *)bm + (y + offsety) * bmw + offsetx;
+               uae_u8 *dst = eo->data + (int)(sx + 0.5f) * 4 + ((int)(sy + 0.5f) + y) * eo->width * 4;
+               for (int x = 0; x < bmw; x++) {
+                       uae_u8 b = *src++;
+                       if (b == 2) {
+                               drawpixel(dst, OSD_KB_COLOR, OSD_KB_TRANSPARENCY);
+                       }
+                       dst += 4;
+               }
+       }
+}
+
+static bool draw_keyboard(HDC hdc, HFONT *fonts, void *bm, int bmw, int bmh, struct extoverlay *eo, int fw, int fh)
+{
+       int num = 0, knum = 0;
+       int maxcols = 240;
+
+       float space = (float)eo->width / maxcols;
+       float colwidth = (float)eo->width / maxcols;
+       float rowheight = colwidth * 7.5f;
+
+       int theight = (int)((rowheight + space) * 6 + 2 * space);
+       if (eo->height < theight) {
+               eo->height = theight;
+       }
+       eo->data = xcalloc(uae_u8, eo->width * eo->height * 4);
+       if (!eo->data) {
+               return false;
+       }
+
+       for (int y = 0; y < eo->height; y++) {
+               uae_u8 *p = eo->data + y * eo->width * 4;
+               for (int x = 0; x < eo->width; x++) {
+                       p[3] = OSD_KB_TRANSPARENCY;
+                       p += 4;
+               }
+       }
+
+       float y = 2.0f * space;
+       float x = 2.0f * space;
+       const uae_s16 *lp = layout;
+       const TCHAR **ll = key_labels;
+       while (*lp) {
+               uae_s16 v = *lp++;
+               float w = (abs(v) & 255) * colwidth - space;
+               float h = rowheight;
+               if ((abs(v) >> 8) > 0) {
+                       h += rowheight;
+                       h += space;
+               }
+               if (v > 0) {
+                       const TCHAR *lab = key_labels[knum];
+                       if (lab) {
+                               float kx = x;
+                               float ky = y;
+                               int i = 0;
+                               bool esc = false;
+                               TCHAR out[10];
+                               TCHAR *outp = out;
+                               bool italic = false;
+                               for (;;) {
+                                       bool skip = false;
+                                       TCHAR c = lab[i];
+                                       TCHAR cn = lab[i + 1];
+                                       if (c == '\\' && cn != '\\' && !esc) {
+                                               esc = true;
+                                       } else if (c == 'i' && esc) {
+                                               italic = true;
+                                               esc = false;
+                                       } else if (c == '|' && esc) {
+                                               *outp++ = c;
+                                               esc = false;
+                                               skip = true;
+                                       } else if (c != '|' && c) {
+                                               *outp++ = c;
+                                               esc = false;
+                                       }
+                                       if ((c == '|' && !esc && !skip) || c == 0) {
+                                               SelectObject(hdc, italic ? fonts[1] : fonts[0]);
+                                               draw_key(hdc, bm, bmw, bmh, eo, kx + space, ky + space, out, outp - out, fw, fh);
+                                               ky += fh + 2;
+                                               outp = out;
+                                               italic = false;
+                                       }
+                                       if (!c) {
+                                               break;
+                                       }
+                                       i++;
+                               }
+                       }
+                       if (key_labels[knum] != NULL || key_labels[knum + 1] != NULL) {
+                               knum++;
+                       }
+
+                       struct osd_kb *kb = &osd_kb_data[num];
+                       kb->x = (int)(x + 0.5f);
+                       kb->y = (int)(y + 0.5f);
+                       kb->w = (int)(w + 0.5f);
+                       kb->h = (int)(h + 0.5f);
+                       kb->code = key_codes[num];
+
+                       drawline(eo, kb->x, kb->y, kb->x + kb->w, kb->y);
+                       drawline(eo, kb->x, kb->y + 1, kb->x + kb->w, kb->y + 1);
+
+                       drawline(eo, kb->x, kb->y + kb->h, kb->x + kb->w, kb->y + kb->h);
+                       drawline(eo, kb->x, kb->y + kb->h - 1, kb->x + kb->w, kb->y + kb->h - 1);
+
+                       drawline(eo, kb->x, kb->y, kb->x, kb->y + kb->h);
+                       drawline(eo, kb->x + 1, kb->y, kb->x + 1, kb->y + kb->h);
+
+                       drawline(eo, kb->x + kb->w, kb->y, kb->x + kb->w, kb->y + kb->h);
+                       drawline(eo, kb->x + kb->w - 1, kb->y, kb->x + kb->w - 1, kb->y + kb->h);
+
+                       if (num == osd_kb_selected) {
+                               highlight(eo, kb, true);
+                       }
+                       num++;
+               }
+               x += w + space;
+
+               if (*lp == 0) {
+                       y += rowheight + space;
+                       x = 2 * space;
+                       lp++;
+               }
+       }
+
+       return true;
+}
+
+static const TCHAR *ab = _T("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
+
+static bool drawkeys(HWND parent, struct extoverlay *eo)
+{
+       bool ret = false;
+       HDC hdc;
+       LPLOGPALETTE lp;
+       HPALETTE hpal;
+       BITMAPINFO *bi;
+       BITMAPINFOHEADER *bih;
+       HBITMAP bitmap = NULL;
+       int width = 128;
+       int height = 128;
+       void *bm;
+       int fsize = eo->height / 30;
+       
+       if (fsize < 4) {
+               return false;
+       }
+
+       hdc = CreateCompatibleDC(NULL);
+       if (hdc) {
+               int y = getdpiforwindow(parent);
+               int fontsize = -MulDiv(fsize, y, 72);
+               fontsize = fontsize * statusline_get_multiplier(0) / 100;
+               lp = (LOGPALETTE *)xcalloc(uae_u8, sizeof(LOGPALETTE) + 3 * sizeof(PALETTEENTRY));
+               if (lp) {
+                       lp->palNumEntries = 4;
+                       lp->palVersion = 0x300;
+                       lp->palPalEntry[1].peBlue = lp->palPalEntry[1].peGreen = lp->palPalEntry[0].peRed = 0x10;
+                       lp->palPalEntry[2].peBlue = lp->palPalEntry[2].peGreen = lp->palPalEntry[2].peRed = 0xff;
+                       lp->palPalEntry[3].peBlue = lp->palPalEntry[3].peGreen = lp->palPalEntry[3].peRed = 0x7f;
+                       hpal = CreatePalette(lp);
+                       if (hpal) {
+                               SelectPalette(hdc, hpal, FALSE);
+                               bi = (BITMAPINFO *)xcalloc(uae_u8, sizeof(BITMAPINFOHEADER) + 4 * sizeof(RGBQUAD));
+                               if (bi) {
+                                       bih = &bi->bmiHeader;
+                                       bih->biSize = sizeof(BITMAPINFOHEADER);
+                                       bih->biWidth = width;
+                                       bih->biHeight = -height;
+                                       bih->biPlanes = 1;
+                                       bih->biBitCount = 8;
+                                       bih->biCompression = BI_RGB;
+                                       bih->biClrUsed = 4;
+                                       bih->biClrImportant = 4;
+                                       bi->bmiColors[1].rgbBlue = bi->bmiColors[1].rgbGreen = bi->bmiColors[1].rgbRed = 0x10;
+                                       bi->bmiColors[2].rgbBlue = bi->bmiColors[2].rgbGreen = bi->bmiColors[2].rgbRed = 0xff;
+                                       bi->bmiColors[3].rgbBlue = bi->bmiColors[3].rgbGreen = bi->bmiColors[3].rgbRed = 0x7f;
+                                       bitmap = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bm, NULL, 0);
+                                       if (bitmap) {
+                                               SelectObject(hdc, bitmap);
+                                               RealizePalette(hdc);
+                                               HFONT fonts[3] = { 0, 0, 0 };
+                                               fonts[0] = CreateFont(fontsize, 0,
+                                                       0, 0,
+                                                       FW_BOLD,
+                                                       FALSE,
+                                                       FALSE,
+                                                       FALSE,
+                                                       DEFAULT_CHARSET,
+                                                       OUT_TT_PRECIS,
+                                                       CLIP_DEFAULT_PRECIS,
+                                                       PROOF_QUALITY,
+                                                       FIXED_PITCH | FF_DONTCARE,
+                                                       _T("Lucida Console"));
+                                               fonts[1] = CreateFont(fontsize, 0,
+                                                       0, 0,
+                                                       FW_BOLD,
+                                                       TRUE,
+                                                       FALSE,
+                                                       FALSE,
+                                                       DEFAULT_CHARSET,
+                                                       OUT_TT_PRECIS,
+                                                       CLIP_DEFAULT_PRECIS,
+                                                       PROOF_QUALITY,
+                                                       FIXED_PITCH | FF_DONTCARE,
+                                                       _T("Lucida Console"));
+                                               if (fonts[0] && fonts[1]) {
+                                                       SelectObject(hdc, fonts[0]);
+                                                       SetTextColor(hdc, PALETTEINDEX(2));
+                                                       SetBkColor(hdc, PALETTEINDEX(1));
+
+                                                       TEXTMETRIC tm;
+                                                       GetTextMetrics(hdc, &tm);
+                                                       int w = 0;
+                                                       int h = tm.tmAscent + 2;
+                                                       for (int i = 0; i < ab[i]; i++) {
+                                                               SIZE sz;
+                                                               if (GetTextExtentPoint32(hdc, &ab[i], 1, &sz)) {
+                                                                       if (sz.cx > w)
+                                                                               w = sz.cx;
+                                                               }
+                                                       }
+                                                       w += 1;
+
+                                                       if (draw_keyboard(hdc, fonts, bm, width, height, eo, w, h)) {
+                                                               ret = true;
+                                                       }
+                                               }
+                                               if (fonts[0]) {
+                                                       DeleteObject(fonts[0]);
+                                               }
+                                               if (fonts[1]) {
+                                                       DeleteObject(fonts[1]);
+                                               }
+                                               DeleteObject(bitmap);
+                                       }
+                                       xfree(bi);
+                               }
+                               DeleteObject(hpal);
+                       }
+                       xfree(lp);
+               }
+               ReleaseDC(NULL, hdc);
+       }
+       return ret;
+}
+
+void target_osk_control(int x, int y, int button, int buttonstate)
+{
+       if (button == 2) {
+               if (buttonstate) {
+                       struct osd_kb *kb = &osd_kb_data[osd_kb_selected];
+                       kb->pressed = kb->pressed ? 0 : 1;
+                       highlight(&osd_kb_eo, kb, false);
+                       D3D_extoverlay(&osd_kb_eo, 0);
+                       if ((kb->code & 0xf000) != 0xf000) {
+                               if (kb->pressed) {
+                                       record_key((kb->code << 1) | 0);
+                               } else {
+                                       record_key((kb->code << 1) | 1);
+                               }
+                       }
+               }
+               return;
+       }
+       if (button == 1) {
+               struct osd_kb *kb = &osd_kb_data[osd_kb_selected];
+               if (kb->pressed) {
+                       kb->pressed = 0;
+                       highlight(&osd_kb_eo, kb, true);
+                       D3D_extoverlay(&osd_kb_eo, 0);
+                       if (kb->code != 0x62) {
+                               record_key((kb->code << 1) | 1);
+                       }
+               }
+               if (buttonstate) {
+                       kb->pressed = -1;
+                       highlight(&osd_kb_eo, kb, false);
+                       D3D_extoverlay(&osd_kb_eo, 0);
+               }
+
+               if (kb->code & 0x8000) {
+                       if ((kb->code & 0xf000) != 0xf000) {
+                               inputdevice_add_inputcode(kb->code & 0x7fff, buttonstate, NULL);
+                       } else {
+                               int c = kb->code & 0xfff;
+                               if (c == 1) {
+                                       if (buttonstate) {
+                                               struct AmigaMonitor *amon = &AMonitors[0];
+                                               if (osd_kb_eo.ypos == 0) {
+                                                       osd_kb_eo.ypos = (amon->amigawin_rect.bottom - amon->amigawin_rect.top) - osd_kb_eo.height;
+                                               } else {
+                                                       osd_kb_eo.ypos = 0;
+                                               }
+                                               D3D_extoverlay(&osd_kb_eo, 0);
+                                       }
+                               }
+                       }
+               } else {
+                       // capslock?
+                       if (kb->code == 0x62) {
+                               if (buttonstate) {
+                                       int capsstate = getcapslockstate();
+                                       capsstate = capsstate ? 0 : 1;
+                                       record_key((kb->code << 1) | capsstate);
+                                       setcapslockstate(capsstate);
+                               }
+                       } else {
+                               if (buttonstate) {
+                                       record_key((kb->code << 1) | 0);
+                               } else {
+                                       record_key((kb->code << 1) | 1);
+                               }
+                       }
+               }
+               return;
+       }
+
+       if (x > 1) {
+               x = 1;
+       }
+       if (x < -1) {
+               x = -1;
+       }
+       if (y > 1) {
+               y = 1;
+       }
+       if (y < -1) {
+               y = -1;
+       }
+
+       if (x || y) {
+               for (int i = 0; osd_kb_data[i].w; i++) {
+                       struct osd_kb *kb = &osd_kb_data[i];
+                       if (kb->pressed < 0) {
+                               return;
+                       }
+               }
+       }
+
+       int max = 1000;
+       while (x || y) {
+               osd_kb_x += x * 5;
+               osd_kb_y += y * 5;
+               if (osd_kb_x < 0) {
+                       for (int i = 0; osd_kb_data[i].w; i++) {
+                               struct osd_kb *kb = &osd_kb_data[i];
+                               if (kb->x + kb->w > osd_kb_x) {
+                                       osd_kb_x = kb->x + kb->w;
+                               }
+                       }
+               }
+               if (osd_kb_y < 0) {
+                       for (int i = 0; osd_kb_data[i].w; i++) {
+                               struct osd_kb *kb = &osd_kb_data[i];
+                               if (kb->y + kb->h > osd_kb_y) {
+                                       osd_kb_y = kb->y + kb->h;
+                               }
+                       }
+               }
+               int xmax = 0, ymax = 0;
+               int i;
+               for (i = 0; osd_kb_data[i].w; i++) {
+                       struct osd_kb *kb = &osd_kb_data[i];
+                       if (osd_kb_x > kb->x + kb->w) {
+                               xmax++;
+                       }
+                       if (osd_kb_y > kb->y + kb->h) {
+                               ymax++;
+                       }
+                       if (i != osd_kb_selected) {
+                               if (kb->x <= osd_kb_x && kb->x + kb->w >= osd_kb_x && kb->y <= osd_kb_y && kb->y + kb->h >= osd_kb_y) {
+                                       highlight(&osd_kb_eo, &osd_kb_data[osd_kb_selected], false);
+                                       highlight(&osd_kb_eo, kb, true);
+                                       osd_kb_selected = i;
+                                       D3D_extoverlay(&osd_kb_eo, 0);
+                                       return;
+                               }
+                       }
+               }
+               if (xmax >= i) {
+                       osd_kb_x = 0;
+               }
+               if (ymax >= i) {
+                       osd_kb_y = 0;
+               }
+               max--;
+               if (max < 0) {
+                       highlight(&osd_kb_eo, &osd_kb_data[osd_kb_selected], false);
+                       osd_kb_selected = 0;
+                       highlight(&osd_kb_eo, &osd_kb_data[osd_kb_selected], true);
+                       D3D_extoverlay(&osd_kb_eo, 0);
+                       return;
+               }
+       }
+
+}
+
+bool target_osd_keyboard(int show)
+{
+       struct AmigaMonitor *amon = &AMonitors[0];
+       static bool first;
+
+       xfree(osd_kb_data);
+       osd_kb_data = NULL;
+       osd_kb_eo.idx = 0x7f7f0000;
+       if (!show) {
+               osd_kb_eo.width = -1;
+               osd_kb_eo.height = -1;
+               D3D_extoverlay(&osd_kb_eo, 0);
+               return true;
+       }
+
+       int w = amon->amigawin_rect.right - amon->amigawinclip_rect.left;
+       int h = amon->amigawin_rect.bottom - amon->amigawinclip_rect.top;
+
+       if (w > h * 4 / 3) {
+               w = h * 4 / 3;
+       }
+       osd_kb_eo.width = w;
+       osd_kb_eo.height = w * 10 / 44;
+       osd_kb_data = xcalloc(struct osd_kb, 120);
+       if (osd_kb_data) {
+               if (!drawkeys(amon->hAmigaWnd, &osd_kb_eo)) {
+                       return false;
+               }
+       }
+       if (!first) {
+               osd_kb_eo.ypos = (amon->amigawin_rect.bottom - amon->amigawin_rect.top) - osd_kb_eo.height;
+       }
+       if (osd_kb_eo.ypos) {
+               osd_kb_eo.ypos = (amon->amigawin_rect.bottom - amon->amigawin_rect.top) - osd_kb_eo.height;
+       }
+       osd_kb_eo.xpos = ((amon->amigawin_rect.right - amon->amigawinclip_rect.left) - w) / 2;
+       if (!osd_kb_eo.data) {
+               return false;
+       }
+       if (!D3D_extoverlay(&osd_kb_eo, 0)) {
+               return false;
+       }
+
+       first = true;
+       return true;
+}
index 8ceecdc60b352b5b6de677ccfb70c3f60573517f..73bef122c1becf38af271b553d62020c16b572e9 100644 (file)
@@ -30,16 +30,15 @@ extern HDC gethdc(int monid);
 extern void releasehdc(int monid, HDC hdc);
 extern void close_windows(struct AmigaMonitor*);
 extern void updatewinfsmode(int monid, struct uae_prefs *p);
-extern int is3dmode(void);
 extern void gfx_lock(void);
 extern void gfx_unlock(void);
 
 extern bool lockscr3d(struct vidbuffer *vb);
 extern void unlockscr3d(struct vidbuffer *vb);
 
-void DX_Fill(struct AmigaMonitor*, int dstx, int dsty, int width, int height, uae_u32 color);
-void DX_Blit(int x, int y, int w, int h);
 void centerdstrect(struct AmigaMonitor*, RECT *);
 struct MultiDisplay *getdisplay(struct uae_prefs *p, int monid);
 extern int getrefreshrate(int monid, int width, int height);
+
+bool osd_keyboard(int show);
 #endif
index 45d99b164d8784dcb4cbbbe8e0532b6eb014a726..b3b37b85e68bc9d5d06f9f30184ae1215585f5af 100644 (file)
@@ -23357,6 +23357,9 @@ static int GetSettings (int all_options, HWND hwnd)
        int resetcount = 0;
        bool boxart_reopen = false;
        int use_gui_control = gui_control > 0 ? 2 : -1;
+       if (osk_status()) {
+               use_gui_control = 2;
+       }
        setdefaultguisize(0);
        getstoredguisize();
        scaleresource_setsize(-1, -1, -1);