// File: Alcaro[P]bridges/arlib/game-x11.cpp
// Function: gameview_x11::calc_keyboard_map()
void calc_keyboard_map()
{
	struct {
		uint8_t arlib; // there's a byte of padding, but there's no real way to remove it without making a mess
		uint16_t x11; // and such a thing would save 138 bytes at most
	} static const keymap[] = {
		{ K_BACKSPACE, XK_BackSpace }, { K_TAB, XK_Tab }, { K_CLEAR, XK_Clear }, { K_RETURN, XK_Return }, { K_PAUSE, XK_Pause },
		{ K_ESCAPE, XK_Escape }, { K_SPACE, XK_space }, { K_EXCLAIM, XK_exclam }, { K_QUOTEDBL, XK_quotedbl },
		{ K_HASH, XK_numbersign }, { K_DOLLAR, XK_dollar }, { K_AMPERSAND, XK_ampersand }, { K_QUOTE, XK_apostrophe },
		{ K_LEFTPAREN, XK_parenleft }, { K_RIGHTPAREN, XK_parenright }, { K_ASTERISK, XK_asterisk }, { K_PLUS, XK_plus },
		{ K_COMMA, XK_comma }, { K_MINUS, XK_minus }, { K_PERIOD, XK_period }, { K_SLASH, XK_slash },
		
		{ K_0, XK_0 }, { K_1, XK_1 }, { K_2, XK_2 }, { K_3, XK_3 }, { K_4, XK_4 },
		{ K_5, XK_5 }, { K_6, XK_6 }, { K_7, XK_7 }, { K_8, XK_8 }, { K_9, XK_9 },
		
		{ K_COLON, XK_colon }, { K_SEMICOLON, XK_semicolon }, { K_LESS, XK_less }, { K_EQUALS, XK_equal }, { K_GREATER, XK_greater },
		{ K_QUESTION, XK_question }, { K_AT, XK_at }, { K_LEFTBRACKET, XK_bracketleft }, { K_BACKSLASH, XK_backslash },
		{ K_RIGHTBRACKET, XK_bracketright }, { K_CARET, XK_asciicircum }, { K_UNDERSCORE, XK_underscore },
		{ K_BACKQUOTE, XK_grave }, { K_BACKQUOTE, XK_dead_acute },
		{ K_a, XK_a }, { K_b, XK_b }, { K_c, XK_c }, { K_d, XK_d }, { K_e, XK_e }, { K_f, XK_f }, { K_g, XK_g }, { K_h, XK_h },
		{ K_i, XK_i }, { K_j, XK_j }, { K_k, XK_k }, { K_l, XK_l }, { K_m, XK_m }, { K_n, XK_n }, { K_o, XK_o }, { K_p, XK_p },
		{ K_q, XK_q }, { K_r, XK_r }, { K_s, XK_s }, { K_t, XK_t }, { K_u, XK_u }, { K_v, XK_v }, { K_w, XK_w }, { K_x, XK_x },
		{ K_y, XK_y }, { K_z, XK_z }, { K_DELETE, XK_Delete },
		
		{ K_KP0, XK_KP_0 }, { K_KP1, XK_KP_1 }, { K_KP2, XK_KP_2 }, { K_KP3, XK_KP_3 }, { K_KP4, XK_KP_4 },
		{ K_KP5, XK_KP_5 }, { K_KP6, XK_KP_6 }, { K_KP7, XK_KP_7 }, { K_KP8, XK_KP_8 }, { K_KP9, XK_KP_9 },
		{ K_KP_PERIOD, XK_KP_Separator }, { K_KP_DIVIDE, XK_KP_Divide }, { K_KP_MULTIPLY, XK_KP_Multiply },
		{ K_KP_MINUS, XK_KP_Subtract }, { K_KP_PLUS, XK_KP_Add }, { K_KP_ENTER, XK_KP_Enter }, { K_KP_EQUALS, XK_KP_Equal },
		
		{ K_UP, XK_Up }, { K_DOWN, XK_Down }, { K_RIGHT, XK_Right }, { K_LEFT, XK_Left },
		{ K_INSERT, XK_Insert }, { K_HOME, XK_Home }, { K_END, XK_End }, { K_PAGEUP, XK_Page_Up }, { K_PAGEDOWN, XK_Page_Down },
		
		{ K_F1, XK_F1 }, { K_F2, XK_F2 }, { K_F3, XK_F3 }, { K_F4, XK_F4 }, { K_F5, XK_F5 },
		{ K_F6, XK_F6 }, { K_F7, XK_F7 }, { K_F8, XK_F8 }, { K_F9, XK_F9 }, { K_F10, XK_F10 },
		{ K_F11, XK_F11 }, { K_F12, XK_F12 }, { K_F13, XK_F13 }, { K_F14, XK_F14 }, { K_F15, XK_F15 },
		
		{ K_NUMLOCK, XK_Num_Lock }, { K_CAPSLOCK, XK_Caps_Lock }, { K_SCROLLOCK, XK_Scroll_Lock },
		{ K_RSHIFT, XK_Shift_R }, { K_LSHIFT, XK_Shift_L }, { K_RCTRL, XK_Control_R }, { K_LCTRL, XK_Control_L },
		{ K_RALT, XK_Alt_R }, { K_LALT, XK_Alt_L }, { K_RMETA, XK_Meta_R }, { K_LMETA, XK_Meta_L },
		{ K_LSUPER, XK_Super_L }, { K_RSUPER, XK_Super_R }, { K_MODE, XK_Mode_switch }, { K_COMPOSE, XK_Multi_key },
		
		{ K_HELP, XK_Help }, { K_PRINT, XK_Print }, { K_SYSREQ, XK_Sys_Req }, { K_BREAK, XK_Break }, { K_MENU, XK_Menu },
		/*{ K_POWER, x },*/ { K_EURO, XK_EuroSign }, { K_UNDO, XK_Undo }, /*{ K_OEM_102, x },*/
		
		{ K_RALT, XK_ISO_Level3_Shift/*AltGr*/ }, { K_CARET, XK_dead_circumflex }, { K_KP_PERIOD, XK_KP_Decimal },
	};
	
	int minkc;
	int maxkc;
	XDisplayKeycodes(display, &minkc, &maxkc);
	int sym_per_code;
	KeySym* sym = XGetKeyboardMapping(display, minkc, maxkc-minkc+1, &sym_per_code);
	
	// run loop backwards, so the unshifted state is the one that stays in the array
	memset(scan_to_key, 0, sizeof(scan_to_key));
	size_t i = sym_per_code*(maxkc-minkc);
	while (i--)
	{
		if (sym[i] == NoSymbol) continue; // most of them point nowhere, ignore inner loop
		if (sym[i]&~0xFFFF) continue; // ignore extended (non-0x0000xxxx) keysyms too, there are none in the above table
		                              // if one shows up, gcc will throw a warning about constant truncation
		for (size_t j : range(ARRAY_SIZE(keymap)))
		{
			if (keymap[j].x11 == sym[i])
				scan_to_key[minkc + i/sym_per_code] = keymap[j].arlib;
		}
	}
	
	XFree(sym);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x98(%rbp)
movq 0x8(%rax), %rdi
leaq -0x2c(%rbp), %rsi
leaq -0x30(%rbp), %rdx
callq 0x43e0
movq -0x98(%rbp), %rax
movq 0x8(%rax), %rdi
movl -0x2c(%rbp), %eax
movl -0x30(%rbp), %edx
subl -0x2c(%rbp), %edx
addl $0x1, %edx
leaq -0x34(%rbp), %rcx
movzbl %al, %esi
callq 0x4690
movq -0x98(%rbp), %rdi
movq %rax, -0x40(%rbp)
addq $0x78, %rdi
xorl %esi, %esi
movl $0x200, %edx            # imm = 0x200
callq 0x4170
movl -0x34(%rbp), %eax
movl -0x30(%rbp), %ecx
subl -0x2c(%rbp), %ecx
imull %ecx, %eax
cltq
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movq %rax, %rcx
addq $-0x1, %rcx
movq %rcx, -0x48(%rbp)
cmpq $0x0, %rax
je 0x1335d
movq -0x40(%rbp), %rax
movq -0x48(%rbp), %rcx
cmpq $0x0, (%rax,%rcx,8)
jne 0x13245
jmp 0x1321b
movq -0x40(%rbp), %rax
movq -0x48(%rbp), %rcx
movq (%rax,%rcx,8), %rax
andq $-0x10000, %rax         # imm = 0xFFFF0000
cmpq $0x0, %rax
je 0x1325f
jmp 0x1321b
leaq -0x68(%rbp), %rdi
movl $0x8a, %esi
callq 0x12cd0
leaq -0x68(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
callq 0x13f00
movq %rax, -0x78(%rbp)
movq %rdx, -0x70(%rbp)
movq -0x50(%rbp), %rdi
callq 0x13f30
movq %rax, -0x88(%rbp)
movq %rdx, -0x80(%rbp)
leaq -0x78(%rbp), %rax
movq %rax, -0x18(%rbp)
leaq -0x88(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq -0x20(%rbp), %rcx
cmpq (%rcx), %rax
jae 0x13358
leaq -0x78(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rcx
leaq 0x5032b(%rip), %rax     # 0x63610
movzwl 0x2(%rax,%rcx,4), %eax
movq -0x40(%rbp), %rcx
movq -0x48(%rbp), %rdx
cmpq (%rcx,%rdx,8), %rax
jne 0x1333b
movq -0x90(%rbp), %rcx
leaq 0x5030a(%rip), %rax     # 0x63610
movzbl (%rax,%rcx,4), %eax
movw %ax, -0x9a(%rbp)
movslq -0x2c(%rbp), %rcx
movq -0x48(%rbp), %rax
movslq -0x34(%rbp), %rsi
xorl %edx, %edx
divq %rsi
movw -0x9a(%rbp), %dx
movq %rax, %rsi
movq -0x98(%rbp), %rax
addq %rsi, %rcx
movw %dx, 0x78(%rax,%rcx,2)
jmp 0x1333d
leaq -0x78(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rcx
addq (%rax), %rcx
movq %rcx, (%rax)
jmp 0x1329a
jmp 0x1321b
movq -0x40(%rbp), %rdi
callq 0x4470
addq $0xa0, %rsp
popq %rbp
retq
nop