sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
librm.c
Go to the documentation of this file.
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright 2001-2004, ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
15
16#include <stdio.h>
17#include <tamtypes.h>
18#include <sifrpc.h>
19#include <kernel.h>
20#include <string.h>
21#include <iopcontrol.h>
22#include "librm.h"
23
24static SifRpcClientData_t rmmanif __attribute__((aligned(64)));
25static struct rmRpcPacket buffer __attribute__((aligned(64)));
26static int rmman_type;
27
29{
30 int opened;
31 struct rmEEData *rmData;
32};
33
34static struct port_state ports[2];
35
36static struct rmEEData *rmGetDmaStr(int port, int slot)
37{
38 struct rmEEData *pdata;
39
40 (void)slot;
41
42 pdata = ports[port].rmData;
43 SyncDCache(pdata, (u8 *)pdata + 256);
44
45 if (pdata[0].frame < pdata[1].frame)
46 {
47 return &pdata[1];
48 }
49 else
50 {
51 return &pdata[0];
52 }
53}
54
55static void RMMan_Cleanup(void)
56{
57 memset(&rmmanif, 0, sizeof(rmmanif));
58 rmman_type = 0;
59}
60
61int RMMan_Init(void)
62{
63 int i;
64 if (HasIopRebootedSinceLastCall())
65 RMMan_Cleanup();
66
67 if (rmmanif.server)
68 {
69 printf("RMMan Library already initialised\n");
70 return 0;
71 }
72
73 {
74 SifRpcClientData_t rpciftmp[3] __attribute__((aligned(64)));
75 int rpc_ids[3] = {
76 RMMANX_RPC_ID,
77 RMMAN2_RPC_ID,
78 RMMAN_RPC_ID,
79 };
80
81 rmmanif.server = NULL;
82 for (i = 0; i < (int)(sizeof(rpc_ids)/sizeof(rpc_ids[0])); i += 1)
83 {
84 rpciftmp[i].server = NULL;
85 }
86
87 for (;;)
88 {
89 for (i = 0; i < (int)(sizeof(rpc_ids)/sizeof(rpc_ids[0])); i += 1)
90 {
91 if ((sceSifBindRpc(&rpciftmp[i], rpc_ids[i], 0) < 0))
92 {
93 return -1;
94 }
95 if (rpciftmp[i].server != NULL)
96 {
97 switch (rpc_ids[i])
98 {
99 case RMMANX_RPC_ID:
100 case RMMAN2_RPC_ID:
101 {
102 rmman_type = 2;
103 break;
104 }
105 case RMMAN_RPC_ID:
106 {
107 rmman_type = 1;
108 break;
109 }
110 default:
111 {
112 break;
113 }
114 }
115 memcpy(&rmmanif, &rpciftmp[i], sizeof(rmmanif));
116 break;
117 }
118 }
119 if (rmmanif.server != NULL)
120 {
121 break;
122 }
123 nopdelay();
124 }
125 }
126
127 if (rmman_type == 0)
128 {
129 return -1;
130 }
131
132 buffer.cmd.command = (rmman_type == 2) ? RMMAN2_RPCFUNC_INIT : RMMAN_RPCFUNC_INIT;
133
134 if (sceSifCallRpc(&rmmanif, 0, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
135 {
136 rmman_type = 0;
137 return -1;
138 }
139
140 for (i = 0; i < (int)(sizeof(ports)/sizeof(ports[0])); i += 1)
141 {
142 ports[i].opened = 0;
143 ports[i].rmData = NULL;
144 }
145
146 switch (rmman_type)
147 {
148 case 1:
149 return buffer.cmd.u.cmd1.result;
150 case 2:
151 return buffer.cmd.u.cmd2.result;
152 default:
153 return 0;
154 }
155}
156
158{
159 buffer.cmd.command = (rmman_type == 2) ? RMMAN2_RPCFUNC_VERSION : RMMAN_RPCFUNC_VERSION;
160
161 if (sceSifCallRpc(&rmmanif, 0, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
162 {
163 return 0;
164 }
165
166 switch (rmman_type)
167 {
168 case 1:
169 return buffer.cmd.u.cmd1.result;
170 case 2:
171 return buffer.cmd.u.cmd2.result;
172 default:
173 return 0;
174 }
175}
176
177int RMMan_Open(int port, int slot, void *pData)
178{
179 if ((port < 0) || (port > 1) || (slot != 0))
180 {
181 printf("Error, port must be 0 or 1 and slot set to 0\n");
182 return 0;
183 }
184
185 if ((u32)pData & 0x3F)
186 {
187 printf("Error, pData not aligned to 64byte boundary");
188 return 0;
189 }
190
191 if (rmman_type != 1 && port != 0)
192 {
193 port = 0;
194 }
195
196 buffer.cmd.command = (rmman_type == 2) ? RMMAN2_RPCFUNC_OPEN : RMMAN_RPCFUNC_OPEN;
197 switch (rmman_type)
198 {
199 case 1:
200 {
201 buffer.cmd.u.cmd1.port = port;
202 buffer.cmd.u.cmd1.slot = slot;
203 buffer.cmd.u.cmd1.data = pData;
204 break;
205 }
206 case 2:
207 {
208 buffer.cmd.u.cmd2.data = pData;
209 break;
210 }
211 default:
212 {
213 break;
214 }
215 }
216
217 if (sceSifCallRpc(&rmmanif, 0, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
218 {
219 return 0;
220 }
221
222 ports[port].opened = 1;
223 ports[port].rmData = pData;
224
225 switch (rmman_type)
226 {
227 case 1:
228 return buffer.cmd.u.cmd1.result;
229 case 2:
230 return buffer.cmd.u.cmd2.result;
231 default:
232 return 0;
233 }
234}
235
236int RMMan_End(void)
237{
238 buffer.cmd.command = (rmman_type == 2) ? RMMAN2_RPCFUNC_END : RMMAN_RPCFUNC_END;
239
240 if (sceSifCallRpc(&rmmanif, 0, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
241 {
242 return 0;
243 }
244
245 switch (rmman_type)
246 {
247 case 1:
248 return buffer.cmd.u.cmd1.result;
249 case 2:
250 return buffer.cmd.u.cmd2.result;
251 default:
252 return 0;
253 }
254}
255
256int RMMan_Close(int port, int slot)
257{
258 if ((port < 0) || (port > 1) || (slot != 0))
259 {
260 printf("Error, port must be 0 or 1 and slot set to 0\n");
261 return 0;
262 }
263
264 if (rmman_type != 1 && port != 0)
265 {
266 port = 0;
267 }
268
269 if (!ports[port].opened)
270 {
271 return 0;
272 }
273
274 buffer.cmd.command = (rmman_type == 2) ? RMMAN2_RPCFUNC_CLOSE : RMMAN_RPCFUNC_CLOSE;
275 switch (rmman_type)
276 {
277 case 1:
278 {
279 buffer.cmd.u.cmd1.port = port;
280 buffer.cmd.u.cmd1.slot = slot;
281 break;
282 }
283 default:
284 {
285 break;
286 }
287 }
288
289 if (sceSifCallRpc(&rmmanif, 0, 0, &buffer, 128, &buffer, 128, NULL, NULL) < 0)
290 {
291 return 0;
292 }
293
294 switch (rmman_type)
295 {
296 case 1:
297 return buffer.cmd.u.cmd1.result;
298 case 2:
299 return buffer.cmd.u.cmd2.result;
300 default:
301 return 0;
302 }
303}
304
305void RMMan_Read(int port, int slot, struct remote_data *data)
306{
307 const struct rmEEData *pdata;
308
309 if ((port < 0) || (port > 1) || (slot != 0))
310 {
311 printf("Error, port must be 0 or 1 and slot set to 0\n");
312 return;
313 }
314
315 if (rmman_type != 1 && port != 0)
316 {
317 port = 0;
318 }
319
320 pdata = rmGetDmaStr(port, slot);
321
322 if (rmman_type == 2)
323 {
324 data->status = (pdata->data[0] == 0x14) ? RM_KEYPRESSED : RM_READY;
325 data->button = (data->status == RM_KEYPRESSED) ? (pdata->data[1] | (pdata->data[2] << 8) | ((pdata->data[3] & ~7) << 16)) : 0;
326 /* rmman2 bitwise ORs into the unused four bits, while rmmanx separates it out into tne next element */
327 data->front_button = (pdata->data[3] & 7) | pdata->data[4];
328 }
329 else
330 {
331 memcpy(data, pdata->data, 8);
332 }
333}
RPC Interface for PS2 Remote Control Driver (RMMAN).
void RMMan_Read(int port, int slot, struct remote_data *data)
Read remote data.
Definition librm.c:305
int RMMan_End(void)
Ends all remote communication.
Definition librm.c:236
int RMMan_Close(int port, int slot)
Closes an opened port.
Definition librm.c:256
int RMMan_Init(void)
Initialise librm.
Definition librm.c:61
int RMMan_Open(int port, int slot, void *pData)
Definition librm.c:177
u32 RMMan_GetModuleVersion(void)
Returns the rmman.irx version.
Definition librm.c:157