Skip to content

Commit eb1accb

Browse files
authored
[xbox] add keyboard support back into xbox retail (#49)
* [xbox] add keyboard support back into xbox retail * clean up TranslateVK
1 parent 02e352e commit eb1accb

File tree

5 files changed

+140
-0
lines changed

5 files changed

+140
-0
lines changed

include/ports_xbox360.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
#define PORT_DATASETELEM 0x82760b38 // DataSetElem
150150
#define PORT_DATAONELEM 0x8275ff50 // DataOnElem
151151
#define PORT_DATANODEGETOBJ 0x8274b088 // DataNode::GetObj
152+
#define PORT_DATAARRAYEXECUTE 0x8274d198 // DataArray::Execute
152153
#define PORT_DXRND_SUSPEND 0x8273A370 // DxRnd::Suspend
153154
#define PORT_XBOXCONTENT_CONSTRUCTOR 0x8251fb40 // XboxContent::__ct
154155
#define PORT_CACHEMGRXBOX_MOUNTASYNC 0x827d7b38 // CacheMgrXbox::MountAsync

include/rb3/Data.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ extern DataNode *DataSet(DataNode *ret, DataArray *array);
8282
extern DataNode *DataSetElem(DataNode *ret, DataArray *array);
8383
extern DataNode *DataOnElem(DataNode *ret, DataArray *array);
8484

85+
extern DataNode *DataArrayExecute(DataNode *ret, DataArray *thisArr);
86+
8587
extern void *DataNodeGetObj(DataNode *node);
8688

8789
// inlined on 360

source/_functions.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ RB3E_STUB(HeapInit)
112112
RB3E_STUB(ResolvedModuleKeyboard)
113113
RB3E_STUB(XboxContentConstruct)
114114
RB3E_STUB(CacheMgrXbox_MountAsync)
115+
RB3E_STUB(DataArrayExecute)
115116

116117
#ifdef RB3E_WII
117118
// Wii-specific functions

source/rb3enhanced.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ static unsigned int framecount = 0;
171171
// STUFF YOU DO HERE WILL **DIRECTLY** IMPACT THE GAME'S FRAMERATE!
172172
void HTTP_Server_RunLoop();
173173
void Liveless_Poll();
174+
void KeyboardPoll();
174175
void RB3E_RunLoop()
175176
{
176177
if (config.EnableNATPMP)
@@ -182,6 +183,7 @@ void RB3E_RunLoop()
182183
Liveless_Poll();
183184
if (config.EnableUPnP)
184185
UPNP_Poll();
186+
KeyboardPoll();
185187
#endif
186188
#ifdef RB3EDEBUG
187189
// print out memory every 5 seconds
@@ -385,6 +387,9 @@ void InitialiseFunctions()
385387
POKE_B(&BinstreamRead, PORT_BINSTREAMREAD);
386388
POKE_B(&BinstreamWriteEndian, PORT_BINSTREAMWRITEENDIAN);
387389
POKE_B(&BinstreamReadEndian, PORT_BINSTREAMREADENDIAN);
390+
#ifdef RB3E_XBOX
391+
POKE_B(&DataArrayExecute, PORT_DATAARRAYEXECUTE);
392+
#endif
388393
#ifndef RB3E_XBOX
389394
POKE_B(&DataRegisterFunc, PORT_DATAREGISTERFUNC);
390395
#endif

source/xbox_keyboard.c

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#ifdef RB3E_XBOX
2+
#include <xtl.h>
3+
#include "rb3/Data.h"
4+
#include "ports.h"
5+
6+
// Reimplementation of DC3's TranslateVK
7+
// This function translates the system XInput VirtualKey value into Harmonix's keycode values
8+
int TranslateVK(DWORD virtualKey, char shift)
9+
{
10+
// ASCII range
11+
// Honestly not sure why this range is even mapped, at these ranges the Unicode translation should be handling it
12+
if (virtualKey >= 0x41 && virtualKey <= 0x5a) {
13+
if (!shift) {
14+
return virtualKey;
15+
} else {
16+
return tolower(virtualKey);
17+
}
18+
}
19+
20+
// Function key range
21+
if (virtualKey >= VK_F1 && virtualKey <= VK_F12) {
22+
return virtualKey + 0x121;
23+
}
24+
25+
// Other keycode mappings
26+
switch (virtualKey) {
27+
case VK_HOME:
28+
return 0x138;
29+
case VK_CAPITAL:
30+
return 0x122;
31+
case VK_BACK:
32+
return 0x08;
33+
case VK_TAB:
34+
return 0x09;
35+
case VK_RETURN:
36+
return 0x0a;
37+
case VK_PAUSE:
38+
return 0x12d;
39+
case VK_ESCAPE:
40+
return 0x12e;
41+
case VK_PRIOR:
42+
return 0x13a;
43+
case VK_NEXT:
44+
return 0x13b;
45+
case VK_END:
46+
return 0x139;
47+
case VK_PRINT:
48+
return 0x12c;
49+
case VK_LEFT:
50+
return 0x140;
51+
case VK_UP:
52+
return 0x142;
53+
case VK_RIGHT:
54+
return 0x141;
55+
case VK_DOWN:
56+
return 0x143;
57+
case VK_INSERT:
58+
return 0x136;
59+
case VK_DELETE:
60+
return 0x137;
61+
case VK_NUMLOCK:
62+
return 0x123;
63+
case VK_SCROLL:
64+
return 0x124;
65+
}
66+
67+
return virtualKey;
68+
}
69+
70+
71+
// Reimplementation of KeyboardPoll from DC3
72+
void KeyboardPoll() {
73+
XINPUT_KEYSTROKE keystroke;
74+
DWORD keystrokeResult;
75+
static DataNode msgNodes[6] = {0};
76+
static DataArray keyMsg = {0};
77+
static DataNode retNode;
78+
Symbol uiSym;
79+
Symbol keySym;
80+
char unicodeChar[4];
81+
int keyCode;
82+
83+
keystrokeResult = XInputGetKeystroke(XUSER_INDEX_ANY, 2, &keystroke);
84+
if (keystrokeResult == ERROR_SUCCESS && (keystroke.Flags & XINPUT_KEYSTROKE_KEYUP) == 0) {
85+
WideCharToMultiByte(0, 0, &keystroke.Unicode, 1, unicodeChar, 2, 0x0, 0x0);
86+
if (unicodeChar[0] == '\0' || unicodeChar[0] < ' ' || unicodeChar[0] > '~') {
87+
keyCode = TranslateVK(keystroke.VirtualKey, (keystroke.Flags & XINPUT_KEYSTROKE_SHIFT) > 0);
88+
} else {
89+
keyCode = (int)unicodeChar[0];
90+
}
91+
92+
keyMsg.mNodes = (DataNodes *)&msgNodes;
93+
keyMsg.mNodeCount = 6;
94+
keyMsg.mRefCount = 1;
95+
keyMsg.mFile = *(Symbol *)PORT_NULLSYMBOL;
96+
97+
SymbolConstruct(&uiSym, "ui");
98+
SymbolConstruct(&keySym, "key");
99+
100+
// Construct a command array to do this:
101+
// {ui key $key $shift $ctrl $alt}
102+
103+
// ui object
104+
msgNodes[0].type = SYMBOL;
105+
msgNodes[0].value.string = uiSym.sym;
106+
107+
// key handler
108+
msgNodes[1].type = SYMBOL;
109+
msgNodes[1].value.string = keySym.sym;
110+
111+
// key
112+
msgNodes[2].type = INT_VALUE;
113+
msgNodes[2].value.intVal = keyCode;
114+
115+
// shift
116+
msgNodes[3].type = INT_VALUE;
117+
msgNodes[3].value.intVal = (keystroke.Flags & XINPUT_KEYSTROKE_SHIFT) > 0;
118+
119+
// ctrl
120+
msgNodes[4].type = INT_VALUE;
121+
msgNodes[4].value.intVal = (keystroke.Flags & XINPUT_KEYSTROKE_CTRL) > 0;
122+
123+
// alt
124+
msgNodes[5].type = INT_VALUE;
125+
msgNodes[5].value.intVal = (keystroke.Flags & XINPUT_KEYSTROKE_ALT) > 0;
126+
127+
DataArrayExecute(&retNode, &keyMsg);
128+
129+
}
130+
}
131+
#endif

0 commit comments

Comments
 (0)