Skip to content

Commit d8e64e0

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

2 files changed

Lines changed: 197 additions & 14 deletions

File tree

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: 185 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,25 @@ 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+
394+
printf("We checking %d\n", chan);
395+
383396
if(!(type&SI_GC_WIRELESS) || type&SI_WIRELESS_IR) {
384397
if(recal_bits) ret = SI_Transfer(__pad_resettingchan,&__pad_cmdcalibrate,3,__pad_origin[__pad_resettingchan],10,__pad_origincallback,0);
385398
else ret = SI_Transfer(__pad_resettingchan,&__pad_cmdreadorigin,1,__pad_origin[__pad_resettingchan],10,__pad_origincallback,0);
@@ -424,6 +437,18 @@ static void __pad_enable(u32 chan)
424437
SI_EnablePolling(__pad_enabledbits);
425438
}
426439

440+
static void __pad_enablekeyboard(u32 chan)
441+
{
442+
u32 buf[2];
443+
#ifdef _PAD_DEBUG
444+
printf("__pad_enablekeyboard(%d)\n",chan);
445+
#endif
446+
__pad_enabledbits |= PAD_ENABLEDMASK(chan);
447+
SI_GetResponse(chan,(void*)buf);
448+
SI_SetCommand(chan,__pad_cmdinitkeyboard);
449+
SI_EnablePolling(__pad_enabledbits);
450+
}
451+
427452
static void __pad_disable(u32 chan)
428453
{
429454
u32 level,mask;
@@ -675,6 +700,43 @@ void PAD_ControlMotor(s32 chan,u32 cmd)
675700
_CPU_ISR_Restore(level);
676701
}
677702

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

715780
resetBits = 0;
@@ -719,22 +784,85 @@ u32 PAD_ScanPads(void)
719784
//PAD_Clamp(padstatus);
720785
for(i=0;i<PAD_CHANMAX;i++) {
721786
padBit = (PAD_CHAN0_BIT>>i);
787+
type = PAD_GetType(i);
722788

723789
switch(padstatus[i].err) {
724790
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;
791+
if (type == PAD_TYPE_KEYBOARD) {
792+
keys[0] = (u8)(padstatus[i].substickX - 128);
793+
keys[1] = (u8)(padstatus[i].substickY - 128);
794+
keys[2] = (u8)(padstatus[i].triggerL);
795+
796+
// Only update if keys did not roll over
797+
if (keys[0] != 2 && keys[1] != 2 && keys[2] != 2) {
798+
oldkeys[0] = __pad_keys[i].keyboard_state[0];
799+
oldkeys[1] = __pad_keys[i].keyboard_state[1];
800+
oldkeys[2] = __pad_keys[i].keyboard_state[2];
801+
802+
__pad_keys[i].keyboard_down[0] = 0;
803+
__pad_keys[i].keyboard_down[1] = 0;
804+
__pad_keys[i].keyboard_down[2] = 0;
805+
806+
__pad_keys[i].keyboard_up[0] = 0;
807+
__pad_keys[i].keyboard_up[1] = 0;
808+
__pad_keys[i].keyboard_up[2] = 0;
809+
810+
// Check if any keyboard keys are being newly pressed
811+
if (keys[0] && ((keys[0] != oldkeys[0]) && (keys[0] != oldkeys[1]) && (keys[0] != oldkeys[2])))
812+
__pad_keys[i].keyboard_down[0] = keys[0];
813+
if (keys[1] && ((keys[1] != oldkeys[0]) && (keys[1] != oldkeys[1]) && (keys[1] != oldkeys[2])))
814+
__pad_keys[i].keyboard_down[1] = keys[1];
815+
if (keys[2] && ((keys[2] != oldkeys[0]) && (keys[2] != oldkeys[1]) && (keys[2] != oldkeys[2])))
816+
__pad_keys[i].keyboard_down[2] = keys[2];
817+
818+
if (!__pad_keys[i].keyboard_down[0]) {
819+
__pad_keys[i].keyboard_down[0] = __pad_keys[i].keyboard_down[1];
820+
__pad_keys[i].keyboard_down[1] = __pad_keys[i].keyboard_down[2];
821+
__pad_keys[i].keyboard_down[2] = 0;
822+
}
823+
824+
if (!__pad_keys[i].keyboard_down[1]) {
825+
__pad_keys[i].keyboard_down[1] = __pad_keys[i].keyboard_down[2];
826+
__pad_keys[i].keyboard_down[2] = 0;
827+
}
828+
829+
// Check if any keyboard keys have been released
830+
if (oldkeys[0] && ((oldkeys[0] != keys[0]) && (oldkeys[0] != keys[1]) && (oldkeys[0] != keys[2])))
831+
__pad_keys[i].keyboard_up[0] = oldkeys[0];
832+
if (oldkeys[1] && ((oldkeys[1] != keys[0]) && (oldkeys[1] != keys[1]) && (oldkeys[1] != keys[2])))
833+
__pad_keys[i].keyboard_up[1] = oldkeys[1];
834+
if (oldkeys[2] && ((oldkeys[2] != keys[0]) && (oldkeys[2] != keys[1]) && (oldkeys[2] != keys[2])))
835+
__pad_keys[i].keyboard_up[2] = oldkeys[2];
836+
837+
if (!__pad_keys[i].keyboard_up[0]) {
838+
__pad_keys[i].keyboard_up[0] = __pad_keys[i].keyboard_up[1];
839+
__pad_keys[i].keyboard_up[1] = __pad_keys[i].keyboard_up[2];
840+
__pad_keys[i].keyboard_up[2] = 0;
841+
}
842+
843+
if (!__pad_keys[i].keyboard_up[1]) {
844+
__pad_keys[i].keyboard_up[1] = __pad_keys[i].keyboard_up[2];
845+
__pad_keys[i].keyboard_up[2] = 0;
846+
}
737847

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

@@ -776,6 +904,49 @@ u16 PAD_ButtonsHeld(int pad)
776904
return __pad_keys[pad].state;
777905
}
778906

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

0 commit comments

Comments
 (0)