on screen keyboard

This commit is contained in:
Toni Wilen 2023-10-21 19:45:56 +03:00
parent 12ca839df5
commit 0025e60685
9 changed files with 731 additions and 52 deletions

View File

@ -134,4 +134,5 @@ AKS(CUBOCOIN1)
AKS(CUBOCOIN2)
AKS(CUBOCOIN3)
AKS(CUBOCOIN4)
AKS(OSK)

View 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 */

View 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;

View 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 */

View 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)

View 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];

View 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;
}

View 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

View 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);