Skip to content

Commit bb2ca1f

Browse files
committed
ASCII Keyboard Controller support
1 parent c76d61d commit bb2ca1f

File tree

2 files changed

+195
-14
lines changed

2 files changed

+195
-14
lines changed

gc/ogc/pad.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33

44
#include <gctypes.h>
55

6+
#define PAD_TYPE_NONE 0
7+
#define PAD_TYPE_STANDARD 1
8+
#define PAD_TYPE_WAVEBIRD 2
9+
#define PAD_TYPE_KEYBOARD 3
10+
#define PAD_TYPE_STEERING 4
11+
612
#define PAD_CHAN0 0
713
#define PAD_CHAN1 1
814
#define PAD_CHAN2 2
@@ -53,6 +59,7 @@ typedef struct _padstatus {
5359
u8 triggerR;
5460
u8 analogA;
5561
u8 analogB;
62+
u8 keyboard[3];
5663
s8 err;
5764
} PADStatus;
5865

@@ -69,13 +76,18 @@ u32 PAD_Recalibrate(u32 mask);
6976
void PAD_Clamp(PADStatus *status);
7077
void PAD_ControlMotor(s32 chan,u32 cmd);
7178
void PAD_SetSpec(u32 spec);
79+
u32 PAD_GetType(s32 chan);
7280

7381
u32 PAD_ScanPads(void);
7482

7583
u16 PAD_ButtonsUp(int pad);
7684
u16 PAD_ButtonsDown(int pad);
7785
u16 PAD_ButtonsHeld(int pad);
7886

87+
s32 PAD_KeyboardUp(int pad, u8 *keys);
88+
s32 PAD_KeyboardDown(int pad, u8 *keys);
89+
s32 PAD_KeyboardHeld(int pad, u8 *keys);
90+
7991
s8 PAD_SubStickX(int pad);
8092
s8 PAD_SubStickY(int pad);
8193

libogc/pad.c

Lines changed: 183 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ typedef struct _keyinput {
2626
u16 up;
2727
u16 down;
2828
u16 state;
29+
u8 keyboard_up[3];
30+
u8 keyboard_down[3];
31+
u8 keyboard_state[3];
2932
u32 chan;
3033
} keyinput;
3134

@@ -43,6 +46,7 @@ static u32 __pad_checkingbits = 0;
4346
static u32 __pad_resettingchan = 32;
4447
static u32 __pad_spec = 5;
4548

49+
static u32 __pad_cmdinitkeyboard = 0x00540000;
4650
static u32 __pad_analogmode = 0x00000300;
4751
static u32 __pad_cmdreadorigin = 0x41000000;
4852
static u32 __pad_cmdcalibrate = 0x42000000;
@@ -63,6 +67,7 @@ static u8 __pad_clampregion[8] = {30, 180, 15, 72, 40, 15, 59, 31};
6367
extern u32 __PADFixBits;
6468

6569
static void __pad_enable(u32 chan);
70+
static void __pad_enablekeyboard(u32 chan);
6671
static void __pad_disable(u32 chan);
6772
static void __pad_doreset(void);
6873
static s32 __pad_onreset(s32 final);
@@ -369,17 +374,23 @@ static void __pad_typeandstatuscallback(s32 chan,u32 type)
369374

370375
__pad_type[__pad_resettingchan] = (type&~0xff);
371376
if(((type&SI_TYPE_MASK)-SI_TYPE_GC)
372-
|| !(type&SI_GC_STANDARD)) {
377+
|| !(type&SI_TYPE_GC)) {
373378
__pad_doreset();
374379
return;
375380
}
376-
381+
377382
if(__pad_spec<2) {
378383
__pad_enable(__pad_resettingchan);
379384
__pad_doreset();
380385
return;
381386
}
382387

388+
if (type == SI_GC_KEYBOARD) {
389+
__pad_enablekeyboard(__pad_resettingchan);
390+
__pad_doreset();
391+
return;
392+
}
393+
383394
if(!(type&SI_GC_WIRELESS) || type&SI_WIRELESS_IR) {
384395
if(recal_bits) ret = SI_Transfer(__pad_resettingchan,&__pad_cmdcalibrate,3,__pad_origin[__pad_resettingchan],10,__pad_origincallback,0);
385396
else ret = SI_Transfer(__pad_resettingchan,&__pad_cmdreadorigin,1,__pad_origin[__pad_resettingchan],10,__pad_origincallback,0);
@@ -424,6 +435,18 @@ static void __pad_enable(u32 chan)
424435
SI_EnablePolling(__pad_enabledbits);
425436
}
426437

438+
static void __pad_enablekeyboard(u32 chan)
439+
{
440+
u32 buf[2];
441+
#ifdef _PAD_DEBUG
442+
printf("__pad_enablekeyboard(%d)\n",chan);
443+
#endif
444+
__pad_enabledbits |= PAD_ENABLEDMASK(chan);
445+
SI_GetResponse(chan,(void*)buf);
446+
SI_SetCommand(chan,__pad_cmdinitkeyboard);
447+
SI_EnablePolling(__pad_enabledbits);
448+
}
449+
427450
static void __pad_disable(u32 chan)
428451
{
429452
u32 level,mask;
@@ -675,6 +698,43 @@ void PAD_ControlMotor(s32 chan,u32 cmd)
675698
_CPU_ISR_Restore(level);
676699
}
677700

701+
u32 PAD_GetType(s32 chan)
702+
{
703+
u32 level;
704+
u32 mask, sitype;
705+
u32 type = PAD_TYPE_NONE;
706+
707+
_CPU_ISR_Disable(level);
708+
709+
mask = PAD_ENABLEDMASK(chan);
710+
if(__pad_enabledbits&mask) {
711+
sitype = SI_GetType(chan)&~0xff;
712+
switch (sitype)
713+
{
714+
case SI_GC_CONTROLLER:
715+
type = PAD_TYPE_STANDARD;
716+
break;
717+
case SI_GC_WAVEBIRD:
718+
type = PAD_TYPE_WAVEBIRD;
719+
break;
720+
case SI_GC_KEYBOARD:
721+
type = PAD_TYPE_KEYBOARD;
722+
break;
723+
case SI_GC_STEERING:
724+
type = PAD_TYPE_STEERING;
725+
break;
726+
default:
727+
#ifdef _PAD_DEBUG
728+
printf("Unknown pad type %08x\n", sitype);
729+
#endif
730+
break;
731+
}
732+
}
733+
_CPU_ISR_Restore(level);
734+
735+
return type;
736+
}
737+
678738
sampling_callback PAD_SetSamplingCallback(sampling_callback cb)
679739
{
680740
sampling_callback ret;
@@ -710,6 +770,9 @@ u32 PAD_ScanPads(void)
710770
u32 resetBits;
711771
u32 padBit,connected;
712772
u16 state,oldstate;
773+
u32 type;
774+
u8 oldkeys[3];
775+
u8 keys[3];
713776
PADStatus padstatus[PAD_CHANMAX];
714777

715778
resetBits = 0;
@@ -719,22 +782,85 @@ u32 PAD_ScanPads(void)
719782
//PAD_Clamp(padstatus);
720783
for(i=0;i<PAD_CHANMAX;i++) {
721784
padBit = (PAD_CHAN0_BIT>>i);
785+
type = PAD_GetType(i);
722786

723787
switch(padstatus[i].err) {
724788
case PAD_ERR_NONE:
725-
oldstate = __pad_keys[i].state;
726-
state = padstatus[i].button;
727-
__pad_keys[i].stickX = padstatus[i].stickX;
728-
__pad_keys[i].stickY = padstatus[i].stickY;
729-
__pad_keys[i].substickX = padstatus[i].substickX;
730-
__pad_keys[i].substickY = padstatus[i].substickY;
731-
__pad_keys[i].triggerL = padstatus[i].triggerL;
732-
__pad_keys[i].triggerR = padstatus[i].triggerR;
733-
__pad_keys[i].up = oldstate & ~state;
734-
__pad_keys[i].down = state & (state ^ oldstate);
735-
__pad_keys[i].state = state;
736-
__pad_keys[i].chan = i;
789+
if (type == PAD_TYPE_KEYBOARD) {
790+
keys[0] = (u8)(padstatus[i].substickX - 128);
791+
keys[1] = (u8)(padstatus[i].substickY - 128);
792+
keys[2] = (u8)(padstatus[i].triggerL);
793+
794+
// Only update if keys did not roll over
795+
if (keys[0] != 2 && keys[1] != 2 && keys[2] != 2) {
796+
oldkeys[0] = __pad_keys[i].keyboard_state[0];
797+
oldkeys[1] = __pad_keys[i].keyboard_state[1];
798+
oldkeys[2] = __pad_keys[i].keyboard_state[2];
799+
800+
__pad_keys[i].keyboard_down[0] = 0;
801+
__pad_keys[i].keyboard_down[1] = 0;
802+
__pad_keys[i].keyboard_down[2] = 0;
803+
804+
__pad_keys[i].keyboard_up[0] = 0;
805+
__pad_keys[i].keyboard_up[1] = 0;
806+
__pad_keys[i].keyboard_up[2] = 0;
807+
808+
// Check if any keyboard keys are being newly pressed
809+
if (keys[0] && ((keys[0] != oldkeys[0]) && (keys[0] != oldkeys[1]) && (keys[0] != oldkeys[2])))
810+
__pad_keys[i].keyboard_down[0] = keys[0];
811+
if (keys[1] && ((keys[1] != oldkeys[0]) && (keys[1] != oldkeys[1]) && (keys[1] != oldkeys[2])))
812+
__pad_keys[i].keyboard_down[1] = keys[1];
813+
if (keys[2] && ((keys[2] != oldkeys[0]) && (keys[2] != oldkeys[1]) && (keys[2] != oldkeys[2])))
814+
__pad_keys[i].keyboard_down[2] = keys[2];
815+
816+
if (!__pad_keys[i].keyboard_down[0]) {
817+
__pad_keys[i].keyboard_down[0] = __pad_keys[i].keyboard_down[1];
818+
__pad_keys[i].keyboard_down[1] = __pad_keys[i].keyboard_down[2];
819+
__pad_keys[i].keyboard_down[2] = 0;
820+
}
821+
822+
if (!__pad_keys[i].keyboard_down[1]) {
823+
__pad_keys[i].keyboard_down[1] = __pad_keys[i].keyboard_down[2];
824+
__pad_keys[i].keyboard_down[2] = 0;
825+
}
826+
827+
// Check if any keyboard keys have been released
828+
if (oldkeys[0] && ((oldkeys[0] != keys[0]) && (oldkeys[0] != keys[1]) && (oldkeys[0] != keys[2])))
829+
__pad_keys[i].keyboard_up[0] = oldkeys[0];
830+
if (oldkeys[1] && ((oldkeys[1] != keys[0]) && (oldkeys[1] != keys[1]) && (oldkeys[1] != keys[2])))
831+
__pad_keys[i].keyboard_up[1] = oldkeys[1];
832+
if (oldkeys[2] && ((oldkeys[2] != keys[0]) && (oldkeys[2] != keys[1]) && (oldkeys[2] != keys[2])))
833+
__pad_keys[i].keyboard_up[2] = oldkeys[2];
834+
835+
if (!__pad_keys[i].keyboard_up[0]) {
836+
__pad_keys[i].keyboard_up[0] = __pad_keys[i].keyboard_up[1];
837+
__pad_keys[i].keyboard_up[1] = __pad_keys[i].keyboard_up[2];
838+
__pad_keys[i].keyboard_up[2] = 0;
839+
}
840+
841+
if (!__pad_keys[i].keyboard_up[1]) {
842+
__pad_keys[i].keyboard_up[1] = __pad_keys[i].keyboard_up[2];
843+
__pad_keys[i].keyboard_up[2] = 0;
844+
}
737845

846+
__pad_keys[i].keyboard_state[0] = keys[0];
847+
__pad_keys[i].keyboard_state[1] = keys[1];
848+
__pad_keys[i].keyboard_state[2] = keys[2];
849+
}
850+
} else {
851+
oldstate = __pad_keys[i].state;
852+
state = padstatus[i].button;
853+
__pad_keys[i].stickX = padstatus[i].stickX;
854+
__pad_keys[i].stickY = padstatus[i].stickY;
855+
__pad_keys[i].substickX = padstatus[i].substickX;
856+
__pad_keys[i].substickY = padstatus[i].substickY;
857+
__pad_keys[i].triggerL = padstatus[i].triggerL;
858+
__pad_keys[i].triggerR = padstatus[i].triggerR;
859+
__pad_keys[i].up = oldstate & ~state;
860+
__pad_keys[i].down = state & (state ^ oldstate);
861+
__pad_keys[i].state = state;
862+
}
863+
__pad_keys[i].chan = i;
738864
connected |= (1<<i);
739865
break;
740866

@@ -776,6 +902,49 @@ u16 PAD_ButtonsHeld(int pad)
776902
return __pad_keys[pad].state;
777903
}
778904

905+
s32 PAD_KeyboardUp(int pad, u8 *keys)
906+
{
907+
s32 i, count = 0;
908+
if(pad<PAD_CHAN0 || pad>PAD_CHAN3 || __pad_keys[pad].chan==-1 || keys==NULL || PAD_GetType(pad) != PAD_TYPE_KEYBOARD) return 0;
909+
for (i = 0; i < 3; i++) {
910+
if (__pad_keys[pad].keyboard_up[i]) {
911+
keys[i] = __pad_keys[pad].keyboard_up[i];
912+
count++;
913+
}
914+
}
915+
// Clear after checking so new buttons are only seen once
916+
memset(__pad_keys[pad].keyboard_up, 0, sizeof(__pad_keys[pad].keyboard_up));
917+
return count;
918+
}
919+
920+
s32 PAD_KeyboardDown(int pad, u8 *keys)
921+
{
922+
s32 i, count = 0;
923+
if(pad<PAD_CHAN0 || pad>PAD_CHAN3 || __pad_keys[pad].chan==-1 || keys==NULL || PAD_GetType(pad) != PAD_TYPE_KEYBOARD) return 0;
924+
for (i = 0; i < 3; i++) {
925+
if (__pad_keys[pad].keyboard_down[i]) {
926+
keys[i] = __pad_keys[pad].keyboard_down[i];
927+
count++;
928+
}
929+
}
930+
// Clear after checking so new buttons are only seen once
931+
memset(__pad_keys[pad].keyboard_down, 0, sizeof(__pad_keys[pad].keyboard_down));
932+
return count;
933+
}
934+
935+
s32 PAD_KeyboardHeld(int pad, u8 *keys)
936+
{
937+
s32 i, count = 0;
938+
if(pad<PAD_CHAN0 || pad>PAD_CHAN3 || __pad_keys[pad].chan==-1 || keys==NULL || PAD_GetType(pad) != PAD_TYPE_KEYBOARD) return 0;
939+
for (i = 0; i < 3; i++) {
940+
if (__pad_keys[pad].keyboard_state[i]) {
941+
keys[i] = __pad_keys[pad].keyboard_state[i];
942+
count++;
943+
}
944+
}
945+
return count;
946+
}
947+
779948
s8 PAD_SubStickX(int pad)
780949
{
781950
if(pad<PAD_CHAN0 || pad>PAD_CHAN3 || __pad_keys[pad].chan==-1) return 0;

0 commit comments

Comments
 (0)