controller.c
6.89 KB
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
/*
--------------------------------------------------------------------------------
controller.c
Martin Hollis 19/06/95 (c) Rare Ltd 1995
Functions for initing and reading controllers
Todo
Change remapping so that different maps
can be selected from the keypad? (by pressing all 6 keys
at once)
--------------------------------------------------------------------------------
*/
#include <ultra64.h> /* For CONT_* */
#define REMAP_VERSION 1 /* Affects remap solution */
/* 0=no remap needed */
/* 1=swap ABC and DEF */
#define MAX_MESGS (MAXCONTROLLERS*10)
/* NO LONGER NEEDED */
/* Maximum number of messages */
/* expected to accumulate between */
/* two reads. 1 per controller per */
/* frame, for 1/6th of a second */
/* 6*10*4=240 bytes */
#if REMAP_VERSION == 1 /* REMAP 1 19/06/95 controllers */
#define REMAPS 6 /* 6 keys are wrong in this remap */
static int remaps[REMAPS][2]={ /* 'Change { A, to B },' */
{ CONT_A, CONT_B }, /* Not done for efficiency, but for ease */
{ CONT_B, CONT_A },
{ CONT_C, CONT_D },
{ CONT_D, CONT_C },
{ CONT_E, CONT_F },
{ CONT_F, CONT_E }
};
#else /* REMAP 0 */
#define REMAPS 0 /* All OK in this remap */
static int remaps[1][2]; /* Just for compile's sake */
#endif
/*
--------------------------------------------------------------------------------
remap
Remaps the given controller input using the REMAP_VERSION
--------------------------------------------------------------------------------
*/
static void remap(OSContPad *pad) {
OSContPad store; /* u16 button; s8 stick_x,y; u8 errno; */
int i;
store=*pad; /* Temporary store */
for (i=0; i<REMAPS; i++)
pad->button&=65535^remaps[i][0]; /* Remove bits that'll be changed */
for (i=0; i<REMAPS; i++) /* Remap keys: */
if (store.button&remaps[i][0]) /* if old meaning set */
pad->button|=remaps[i][1]; /* set new meaning */
}
/*
--------------------------------------------------------------------------------
global variables
For initcontrollers and readcontrollers
pad[] lpad[] numof are externally visible for the client
--------------------------------------------------------------------------------
*/
int numof=0; /* Number of controllers */
static u8 map[MAXCONTROLLERS]={0}; /* 0=absent n=use pad[n-1] */
static OSContStatus statusdata[MAXCONTROLLERS];
/* u16|u8|u8 */
/* type|status|errno */
OSContPad pad[MAXCONTROLLERS]; /* u16|s8|s8|u8|u8 6*6=36 bytes */
/* u16 button; s8 stick_x,y; u8 errno; */
/* [0]..[numof-1] are valid */
OSContPad lpad[MAXCONTROLLERS]; /* Last pad values */
static OSMesgQueue contMessageQ;
static OSMesg contMessageBuf;
/*
--------------------------------------------------------------------------------
initcontrollers
Initialize all controllers
Return the number of controllers found
--------------------------------------------------------------------------------
*/
static u8 contpattern; /* Could really be local to initcontrollers */
/* Here for print */
int initcontrollers(void) {
int i; int num=0;
osCreateMesgQueue(&contMessageQ, &contMessageBuf, 1);
osSetEventMesg(OS_EVENT_SI, &contMessageQ, (OSMesg)1);
osContInit(&contMessageQ, &contpattern, &statusdata[0]); /* Get pattern and status */
osContStartReadData(&contMessageQ);
for (i=0; i<MAXCONTROLLERS; i++)
if ((contpattern & (1<<i)) &&
!(statusdata[i].errno & CONT_NO_RESPONSE_ERROR))
map[num++]=i+1; /* Keep a map */
numof=num; /* Keep number */
return num; /* Number of controllers found */
}
/*
--------------------------------------------------------------------------------
readcontrollers
Read all controllers, updating pad[0..numof-1]
This function does not block
--------------------------------------------------------------------------------
*/
void readcontrollers(void) {
int i;
static OSContPad *p = NULL;
OSMesg dummyMessage;
if (osRecvMesg(&contMessageQ, &dummyMessage, OS_MESG_NOBLOCK) == 0) {
osContGetReadData(pad); /* Now pad[0]..[MAXCONT] are valid */
#if 0
{ /* Another type of copy */
register u8 *a,*b,*c;
a=(u8*)lpad; b=(u8*)pad; c=((u8*)pad)+sizeof(pad);
do { *a=*b; a++; b++; } while (b!=c);
}
#endif
for (i=0; i<MAXCONTROLLERS; i++) /* Copy old values */
lpad[i]=pad[i];
for (i=0; i<MAXCONTROLLERS; i++) /* Find mapped ctrlers */
if (map[i]) { /* Here's one */
pad[i]=pad[map[i]-1]; /* Pack values in lowest entries */
remap(pad+i); /* Remap the keys in this pad */
} /* Now pad[0]..[numof-1] are valid */
osContStartReadData(&contMessageQ); /* request latest controller information */
}
}
/*
--------------------------------------------------------------------------------
printcontrollers
Prints info about each controller
masks=
0x0001 controller1
0x0002 controller2
0x0004 controller3
0x0008 controller4
0x0010 controller5
0x0020 controller6
0x0100 print general misc info
0x0200 print status for specified controllers
0x0400 print pad for specified controllers
--------------------------------------------------------------------------------
*/
void printcontrollers(u32 masks) {
int i,j;
if (masks&0x0100) {
rmonPrintf("numof=%d map=",numof);
for (i=0; i<MAXCONTROLLERS; i++) rmonPrintf("%d",map[i]);
rmonPrintf("\n\n");
}
for (i=0; i<MAXCONTROLLERS; i++) {
if (masks&(1<<i)) {
rmonPrintf(" controller[%d]\n",i);
rmonPrintf(" --------------\n");
rmonPrintf("\n");
if (masks&0x0200) {
rmonPrintf(" statusdata[%d].type =0x%04x\n",i,statusdata[i].type);
rmonPrintf(" statusdata[%d].status =%d\n",i,statusdata[i].status);
rmonPrintf(" statusdata[%d].errno =%d\n",i,statusdata[i].errno);
rmonPrintf("\n");
}
if (masks&0x0400) {
rmonPrintf(" pad[%d].button =0x%04x\n",i,pad[i].button);
rmonPrintf(" pad[%d].stick_x =%+d\n",i,pad[i].stick_x);
rmonPrintf(" pad[%d].stick_y =%+d\n",i,pad[i].stick_y);
rmonPrintf(" pad[%d].errno =%d\n",i,pad[i].errno);
rmonPrintf("\n");
}
}
}
if (masks&0x0100) {
rmonPrintf("contpattern=0x%02x\n",contpattern);
rmonPrintf("\n");
rmonPrintf("contMessageQ.mtqueue =0x%08x\n",contMessageQ.mtqueue);
rmonPrintf("contMessageQ.fullqueue =0x%08x\n",contMessageQ.fullqueue);
rmonPrintf("contMessageQ.validCount=%d\n",contMessageQ.validCount);
rmonPrintf("contMessageQ.first =%d\n",contMessageQ.first);
rmonPrintf("contMessageQ.msgCount =%d\n",contMessageQ.msgCount);
rmonPrintf("contMessageQ.msg =0x%08x\n",contMessageQ.msg);
rmonPrintf("\n");
rmonPrintf("contMessageBuf=0x%08x\n",contMessageBuf);
#if 0 /* For when contMessageBuf was an array */
for (i=0; i<MAX_MESGS; i+=MAXCONTROLLERS) {
rmonPrintf(" ");
for (j=i; j<i+MAXCONTROLLERS; j++)
if (j<MAX_MESGS) rmonPrintf("%08x, ",contMessageBuf[j]);
rmonPrintf("\n");
}
rmonPrintf("};\n");
#endif
}
}