summaryrefslogtreecommitdiff
path: root/src/classic_controller.S
blob: 6084c057ec2f3c0ca2a96cd412d4047b5953b41b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#ifndef __MWERKS__
.set r0,0;   .set r1,1;   .set r2,2;   .set r3,3;   .set r4,4
.set r5,5;   .set r6,6;   .set r7,7;   .set r8,8;   .set r9,9
.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14
.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19
.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24
.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29
.set r30,30; .set r31,31; .set f0,0;   .set f2,2;   .set f3,3
.set f1,1;   .set f8,8;   .set f9,9;   .set f10,10; .set f11,11;
.set f30,30; .set f31,31
#endif

#define WPAD_BUTTON_2							0x0001
#define WPAD_BUTTON_1							0x0002
#define WPAD_BUTTON_B							0x0004
#define WPAD_BUTTON_A							0x0008
#define WPAD_BUTTON_MINUS						0x0010
#define WPAD_BUTTON_HOME						0x0080
#define WPAD_BUTTON_LEFT						0x0100
#define WPAD_BUTTON_RIGHT						0x0200
#define WPAD_BUTTON_DOWN						0x0400
#define WPAD_BUTTON_UP							0x0800
#define WPAD_BUTTON_PLUS						0x1000

#define WPAD_CLASSIC_BUTTON_UP					0x0001
#define WPAD_CLASSIC_BUTTON_LEFT				0x0002
#define WPAD_CLASSIC_BUTTON_ZR					0x0004
#define WPAD_CLASSIC_BUTTON_X					0x0008
#define WPAD_CLASSIC_BUTTON_A					0x0010
#define WPAD_CLASSIC_BUTTON_Y					0x0020
#define WPAD_CLASSIC_BUTTON_B					0x0040
#define WPAD_CLASSIC_BUTTON_ZL					0x0080
#define WPAD_CLASSIC_BUTTON_FULL_R				0x0200
#define WPAD_CLASSIC_BUTTON_PLUS				0x0400
#define WPAD_CLASSIC_BUTTON_HOME				0x0800
#define WPAD_CLASSIC_BUTTON_MINUS				0x1000
#define WPAD_CLASSIC_BUTTON_FULL_L				0x2000
#define WPAD_CLASSIC_BUTTON_DOWN				0x4000
#define WPAD_CLASSIC_BUTTON_RIGHT				0x8000

.set stackSize,0x30;
.set r4Place,0x10;
.set r5Place,0x14;
.set r6Place,0x18;
.set r26Place,0x1c;
.set f8Place,0x20;
.set f9Place,0x24;
.set f10Place,0x28;
.set f11Place,0x2c;

.text
.align 4

;TODO - check that classic controller is attached
;TODO - add tilt to right analog
;TODO - add R/L to be full tilt
.global _switch_buttons
_switch_buttons:
	addi    r1,r1,0x50			# replaced instruction

	stwu	r1,-stackSize(r1)		# provide new stack for saving regs
	mflr    r0
	stw		r4,r4Place(r1)
	stw		r5,r5Place(r1)
	stw		r6,r6Place(r1)
	stw		r26,r26Place(r1)
	stfs	f8,f8Place(r1)
	stfs	f9,f9Place(r1)
	stfs	f10,f10Place(r1)
	stfs	f11,f11Place(r1)

	lbz		r5,0x5C(r26)		# wiimote extension type
	cmpwi	r5, 2				# classic controller
	beq		cleanup

	lwz     r5,0x60(r26)		# wiimote cc data ; KPADInsideStatus->KPADEXStatus_bl->hold
	bl      map_buttons
	lwz     r4,0(r26)			# wiimote ; KPADInsideStatus->hold
	or      r5,r5,r4
	stw     r5,0(r26)			# wiimote ; KPADInsideStatus->hold
	lwz     r5,0x64(r26)		# wiimote cc data ; KPADInsideStatus->KPADEXStatus_bl->trig
	bl      map_buttons
	lwz     r4,4(r26)			# wiimote ; KPADInsideStatus->trig
	or      r5,r5,r4
	stw     r5,4(r26)			# wiimote ; KPADInsideStatus->trig
	lwz     r5,0x68(r26)		# wiimote cc data ; KPADInsideStatus->KPADEXStatus_bl->release
	bl      map_buttons
	lwz     r4,8(r26)			# wiimote ; KPADInsideStatus->release
	or      r5,r5,r4
	stw     r5,8(r26)			# wiimote ; KPADInsideStatus->release

cleanup:
	lwz		r4,r4Place(r1)
	lwz		r5,r5Place(r1)
	lwz		r6,r6Place(r1)
	lwz		r26,r26Place(r1)
	lfs		f8,f8Place(r1)
	lfs		f9,f9Place(r1)
	lfs		f10,f10Place(r1)
	lfs		f11,f11Place(r1)
	mtlr    r0
	addi	r1,r1,stackSize
	blr

; r5 == CC data
; r5 returns the wpad data
map_buttons:
	andi.   r4,r5,0x10		// WPAD_CLASSIC_BUTTON_A
	cmpwi	r4,0
	beq-    skip_waggle
	lis     r6,0x7fc0		// float
	stw     r6,0x10(r26)	// set waggle ; KPADInsideStatus->acc->y
skip_waggle:
	li      r6,0
	andi.   r4,r5,0x800		// WPAD_CLASSIC_BUTTON_HOME
	beq-    skip_home
	ori     r6,r6,0x8000	// WPAD_BUTTON_HOME
skip_home:
	andi.   r4,r5,0x20		// WPAD_CLASSIC_BUTTON_Y
	beq-    skip_run_one
	ori     r6,r6,0x200		// WPAD_BUTTON_1
skip_run_one:
	andi.   r4,r5,0x8		// WPAD_CLASSIC_BUTTON_X
	beq-    skip_run_two
	ori		r6,r6,0x200		// WPAD_BUTTON_1
skip_run_two:
	andi.   r4,r5,0x40		// WPAD_CLASSIC_BUTTON_B
	beq-    skip_jump
	ori     r6,r6,0x100		// WPAD_BUTTON_2
skip_jump:
	andi.   r4,r5,0x80		// WPAD_CLASSIC_BUTTON_ZL
	beq-    skip_bubble1
	ori     r6,r6,0x8		// WPAD_BUTTON_A
skip_bubble1:
	andi.   r4,r5,0x4		// WPAD_CLASSIC_BUTTON_ZR
	beq-    skip_bubble2
	ori     r6,r6,0x8		// WPAD_BUTTON_A
skip_bubble2:
	andi.   r4,r5,1			// WPAD_CLASSIC_BUTTON_UP
	beq-    skip_right
	ori     r6,r6,2			// WPAD_BUTTON_RIGHT
skip_right:
	andi.   r4,r5,2			// WPAD_CLASSIC_BUTTON_LEFT
	beq-    skip_up
	ori     r6,r6,8			// WPAD_BUTTON_UP
skip_up:
	andi.   r4,r5,0x8000	// WPAD_CLASSIC_BUTTON_RIGHT
	beq-    skip_down
	ori     r6,r6,4			// WPAD_BUTTON_DOWN
skip_down:
	andi.   r4,r5,0x4000	// WPAD_CLASSIC_BUTTON_DOWN
	beq-    skip_left
	ori     r6,r6,1			// WPAD_BUTTON_LEFT
skip_left:
	andi.   r4,r5,0x400		// WPAD_CLASSIC_BUTTON_PLUS
	beq-    skip_plus
	ori     r6,r6,0x10		// WPAD_BUTTON_PLUS
skip_plus:
	andi.   r4,r5,0x1000	// WPAD_CLASSIC_BUTTON_MINUS
	beq-    skip_minus
	ori     r6,r6,0x1000	// WPAD_BUTTON_MINUS
skip_minus:
	lfs		f8,0x6c(r26)	// left analog x ; KPADInsideStatus->KPADEXStatus_cl->lstick
	lfs		f9,0x70(r26)	// left analog y ; KPADInsideStatus->KPADEXStatus_cl->rstick
	lis		r5,float_one@ha
	lfs		f10,float_one@l(r5)
	lfs		f11,float_neg_one@l(r5)
;	fcmpu	cr0,f8,f10
;	bne		skip_right_analog
;	ori     r6,r6,4			// WPAD_BUTTON_DOWN
;skip_right_analog:
;	fcmpu	cr0,f9,f10
;	bne		skip_right_analog
;	ori     r6,r6,2			// WPAD_BUTTON_RIGHT
;skip_up_analog:
;	fcmpu	cr0,f9,f11
;	bne		skip_right_analog
;	ori     r6,r6,1			// WPAD_BUTTON_LEFT
;skip_down_analog:
;	fcmpu	cr0,f8,f11
;	bne		skip_right_analog
;	ori     r6,r6,8			// WPAD_BUTTON_UP
;skip_left_analog:
	mr      r5,r6
	blr

.data

float_one:
.float 1.0
float_neg_one:
.float -1.0
float_zero:
.float 0.0