4 * Copyright (C) 2004-2011 Simon Wunderlich <dotslash@packetmixer.de>
6 * This file is part of s3d, a 3d network display server.
7 * See http://s3d.berlios.de/ for more updates.
9 * s3d is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * s3d is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with s3d; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 #include <stdlib.h> /* malloc() */
27 #include <string.h> /* strncpy(),memset() */
32 #include <netinet/in.h> /* htonl(),htons() */
34 /* this code should do the protocol work .... */
36 int focus_oid
= -1; /* initially focus the pid */
37 /* handle an incoming command from the client .. */
39 int prot_com_in(struct t_process
*p
, uint8_t * pbuf
)
43 char name
[S3D_NAME_MAX
];
45 uint8_t *buf
, *cptr
= NULL
;
51 int32_t flags
, mcp_oid
= -1;
54 mcp_oid
= p
->mcp_oid
; /* get mcp-oid if we need to report something to */
56 if ((mcp_oid
== -1) && (command
!= S3D_P_C_INIT
)) {
57 s3dprintf(MED
, "prot_com_in(): commands without beeing initialized ?! no way, kicking ...");
61 length
= ntohs(*((uint16_t *) ((uint8_t *) pbuf
+ 1)));
62 cptr
= buf
= pbuf
+ sizeof(int_least32_t);
65 memset(name
, 0, S3D_NAME_MAX
);
66 if (length
> S3D_NAME_MAX
)
70 strncpy(name
, (char *)buf
, i
);
71 s3dprintf(LOW
, "[%d]\"%s\" logged in", p
->id
, name
);
72 if (NULL
== (np
= process_protinit(p
, name
)))
73 event_quit(p
); /* couldn't get process */
78 oid
= htonl(obj_new(p
));
79 prot_com_out(p
, S3D_P_S_NEWOBJ
, (uint8_t *) & oid
, 4);
83 oid
= ntohl(*((uint32_t *) cptr
));
89 oid
= ntohl(*((uint32_t *) cptr
));
91 toid
= ntohl(*((uint32_t *) cptr
));
92 obj_clone_change(p
, oid
, toid
);
97 oid
= ntohl(*((uint32_t *) cptr
));
101 oid
= ntohl(*((uint32_t *) cptr
));
103 toid
= ntohl(*((uint32_t *) cptr
));
104 obj_link(p
, oid
, toid
);
108 s3dprintf(LOW
, "QUIT issued");
111 case S3D_P_C_PUSH_VERTEX
:
113 oid
= ntohl(*((uint32_t *) cptr
));
115 num
= (length
- 4) / (4 * 3);
116 ntohfb((float *)cptr
, num
* 3);
117 obj_push_vertex(p
, oid
, (float *)cptr
, num
);
120 case S3D_P_C_PUSH_MAT
:
122 oid
= ntohl(*((uint32_t *) cptr
));
124 num
= (length
- 4) / (4 * 12);
125 ntohfb((float *)cptr
, num
* 12);
126 obj_push_mat(p
, oid
, (float *)cptr
, num
);
129 case S3D_P_C_PUSH_POLY
:
131 oid
= ntohl(*((uint32_t *) cptr
));
133 num
= (length
- 4) / (4 * 4);
134 ntohlb((uint32_t *) cptr
, num
* 4);
135 /* convert index names */
136 obj_push_poly(p
, oid
, (uint32_t *) cptr
, num
);
139 case S3D_P_C_PUSH_LINE
:
141 oid
= ntohl(*((uint32_t *) cptr
));
143 num
= (length
- 4) / (4 * 3);
144 s3dprintf(VLOW
, "received %d new lines for object oid...%d", num
, oid
);
145 ntohlb((uint32_t *) cptr
, num
* 3);
146 /* convert index names */
147 obj_push_line(p
, oid
, (uint32_t *) cptr
, num
);
150 case S3D_P_C_PUSH_TEX
:
152 oid
= ntohl(*((uint32_t *) cptr
));
154 num
= (length
- 4) / (2 * 2);
155 s3dprintf(LOW
, "received %d new textures for object oid...%d", num
, oid
);
156 ntohsb((uint16_t *) cptr
, num
* 2);
157 /* convert index names */
158 obj_push_tex(p
, oid
, (uint16_t *) cptr
, num
);
161 case S3D_P_C_PEP_POLY_NORMAL
:
163 oid
= ntohl(*((uint32_t *) cptr
));
165 num
= (length
- 4) / (9 * 4);
166 ntohfb((float *)cptr
, num
* 9);
167 s3dprintf(VLOW
, "PEP_POLY_NORMAL[%d]: oid %d, %f polys", length
, oid
, (length
- 4) / (9.0 * 4.0));
168 obj_pep_poly_normal(p
, oid
, (float *)cptr
, num
);
171 case S3D_P_C_PEP_LINE_NORMAL
:
173 oid
= ntohl(*((uint32_t *) cptr
));
175 num
= (length
- 4) / (6 * 4);
176 ntohfb((float *)cptr
, num
* 6);
177 s3dprintf(VLOW
, "PEP_LINE_NORMAL[%d]: oid %d, %.1f lines", length
, oid
, (length
- 4) / (6.0 * 4.0));
178 obj_pep_line_normal(p
, oid
, (float *)cptr
, num
);
181 case S3D_P_C_PEP_POLY_TEXC
:
183 oid
= ntohl(*((uint32_t *) cptr
));
185 num
= (length
- 4) / (6 * 4);
186 ntohfb((float *)cptr
, num
* 6);
187 s3dprintf(VLOW
, "PEP_POLY_TEXC[%d]: oid %d, %f polys", length
, oid
, (length
- 4) / (6.0 * 4.0));
188 obj_pep_poly_texc(p
, oid
, (float *)cptr
, num
);
191 case S3D_P_C_PEP_MAT
:
193 oid
= ntohl(*((uint32_t *) cptr
));
195 num
= (length
- 4) / (4 * 12);
196 ntohfb((float *)cptr
, num
* 12);
197 s3dprintf(VLOW
, "PEP_MAT[%d]: %d materials for object oid...%d", length
, num
, oid
);
198 obj_pep_mat(p
, oid
, (float *)cptr
, num
);
201 case S3D_P_C_PEP_VERTEX
:
203 oid
= ntohl(*((uint32_t *) cptr
));
205 num
= (length
- 4) / (4 * 3);
206 ntohfb((float *)cptr
, num
* 3);
207 s3dprintf(VLOW
, "pepping %d new vertices for object oid...%d", num
, oid
);
208 obj_pep_vertex(p
, oid
, (float *)cptr
, num
);
212 case S3D_P_C_PEP_MAT_TEX
:
214 oid
= ntohl(*((uint32_t *) cptr
));
216 num
= (length
- 4) / (4);
217 s3dprintf(VLOW
, "PEP_MAT_TEX[%d]: %d materials for object oid...%d", length
, num
, oid
);
218 ntohlb((uint32_t *) cptr
, num
);
219 obj_pep_mat_tex(p
, oid
, (uint32_t *) cptr
, num
);
222 case S3D_P_C_PEP_LINE
:
224 oid
= ntohl(*((uint32_t *) cptr
));
226 num
= (length
- 4) / (4 * 3);
227 s3dprintf(VLOW
, "pepping %d new lines for object oid...%d", num
, oid
);
228 ntohlb((uint32_t *) cptr
, num
* 3);
229 obj_pep_line(p
, oid
, (uint32_t *) cptr
, num
);
232 case S3D_P_C_LOAD_LINE_NORMAL
:
234 oid
= ntohl(*((uint32_t *) cptr
));
236 toid
= ntohl(*((uint32_t *) cptr
));
238 num
= (length
- 8) / (6 * 4);
239 ntohfb((float *)cptr
, num
* 6);
240 s3dprintf(VLOW
, "LOAD_POLY_NORMAL[%d]: oid %d, %.2f lines", length
, oid
, (length
- 8) / (6.0 * 4.0));
241 obj_load_line_normal(p
, oid
, (float *)cptr
, toid
, num
);
244 case S3D_P_C_LOAD_POLY_NORMAL
:
246 oid
= ntohl(*((uint32_t *) cptr
));
248 toid
= ntohl(*((uint32_t *) cptr
));
250 num
= (length
- 8) / (9 * 4);
251 ntohfb((float *)cptr
, num
* 9);
252 s3dprintf(MED
, "LOAD_POLY_NORMAL[%d]: oid %d, %f polys", length
, oid
, (length
- 8) / (9.0 * 4.0));
253 obj_load_poly_normal(p
, oid
, (float *)cptr
, toid
, num
);
256 case S3D_P_C_LOAD_POLY_TEXC
:
258 oid
= ntohl(*((uint32_t *) cptr
));
260 toid
= ntohl(*((uint32_t *) cptr
));
262 num
= (length
- 8) / (6 * 4);
263 ntohfb((float *)cptr
, num
* 6);
264 s3dprintf(MED
, "LOAD_POLY_TEXC[%d]: oid %d, %f polys", length
, oid
, (length
- 8) / (6.0 * 4.0));
265 obj_load_poly_texc(p
, oid
, (float *)cptr
, toid
, num
);
268 case S3D_P_C_LOAD_MAT
:
270 oid
= ntohl(*((uint32_t *) cptr
));
272 toid
= ntohl(*((uint32_t *) cptr
));
274 num
= (length
- 8) / (4 * 12);
275 ntohfb((float *)cptr
, num
* 12);
276 s3dprintf(LOW
, "LOAD_MAT[%d]: %d materials for object oid...%d", length
, num
, oid
);
277 obj_load_mat(p
, oid
, (float *)cptr
, toid
, num
);
280 case S3D_P_C_LOAD_TEX
:
282 oid
= ntohl(*((uint32_t *) cptr
));
284 toid
= ntohl(*((uint32_t *) cptr
));
286 x
= ntohs(*((uint16_t *) cptr
));
288 y
= ntohs(*((uint16_t *) cptr
));
290 w
= ntohs(*((uint16_t *) cptr
));
292 h
= ntohs(*((uint16_t *) cptr
));
295 s3dprintf(MED
, "LOAD_TEX[%d]: oid %d, texture %d, [%d x %d] data at [%d x %d] (%d = %d)", length
, oid
, toid
, w
, h
, x
, y
, num
, w
* h
* 4);
296 if ((w
* h
* 4) == num
) /* check correct size */
297 obj_load_tex(p
, oid
, toid
, x
, y
, w
, h
, cptr
);
300 case S3D_P_C_UPDATE_TEX
:
302 oid
= ntohl(*((uint32_t *) cptr
));
303 cptr
+= sizeof(uint32_t);
304 toid
= ntohl(*((uint32_t *) cptr
));
305 cptr
+= sizeof(uint32_t);
306 x
= ntohs(*((uint16_t *) cptr
));
307 cptr
+= sizeof(uint16_t);
308 y
= ntohs(*((uint16_t *) cptr
));
309 cptr
+= sizeof(uint16_t);
310 w
= ntohs(*((uint16_t *) cptr
));
311 cptr
+= sizeof(uint16_t);
312 h
= ntohs(*((uint16_t *) cptr
));
314 s3dprintf(VLOW
, "UPDATE_TEX[%d]: oid %d, texture %d, [%d x %d] data at [%d x %d] ", length
, oid
, toid
, w
, h
, x
, y
);
315 obj_update_tex(p
, oid
, toid
, x
, y
, w
, h
, NULL
);
319 case S3D_P_C_DEL_VERTEX
:
321 oid
= ntohl(*((uint32_t *) cptr
));
322 cptr
+= sizeof(uint32_t);
323 num
= ntohl(*((uint32_t *) cptr
));
325 obj_del_vertex(p
, oid
, num
);
328 case S3D_P_C_DEL_POLY
:
330 oid
= ntohl(*((uint32_t *) cptr
));
331 cptr
+= sizeof(uint32_t);
332 num
= ntohl(*((uint32_t *) cptr
));
334 obj_del_poly(p
, oid
, num
);
337 case S3D_P_C_DEL_LINE
:
339 oid
= ntohl(*((uint32_t *) cptr
));
340 cptr
+= sizeof(uint32_t);
341 num
= ntohl(*((uint32_t *) cptr
));
343 s3dprintf(VLOW
, "deleting %d lines for object oid...%d", num
, oid
);
344 obj_del_line(p
, oid
, num
);
348 case S3D_P_C_DEL_MAT
:
350 oid
= ntohl(*((uint32_t *) cptr
));
351 cptr
+= sizeof(uint32_t);
352 num
= ntohl(*((uint32_t *) cptr
));
354 obj_del_mat(p
, oid
, num
);
357 case S3D_P_C_DEL_TEX
:
359 oid
= ntohl(*((uint32_t *) cptr
));
360 cptr
+= sizeof(uint32_t);
361 num
= ntohl(*((uint32_t *) cptr
));
363 obj_del_tex(p
, oid
, num
);
366 case S3D_P_C_TOGGLE_FLAGS
:
368 oid
= ntohl(*((uint32_t *) cptr
));
369 cptr
+= sizeof(uint32_t);;
371 cptr
+= sizeof(unsigned char);
372 flags
= ntohl(*((uint32_t *) cptr
));
374 obj_toggle_flags(p
, oid
, type
, flags
);
377 case S3D_P_C_TRANSLATE
:
379 oid
= ntohl(*((uint32_t *) cptr
));
380 cptr
+= sizeof(uint32_t);
381 ntohfb((float *)cptr
, 3);
382 obj_translate(p
, oid
, (float *)cptr
);
387 oid
= ntohl(*((uint32_t *) cptr
));
389 ntohfb((float *)cptr
, 3);
390 obj_rotate(p
, oid
, (float *)cptr
);
395 oid
= ntohl(*((uint32_t *) cptr
));
397 ntohfb((float *)cptr
, 3);
398 obj_scale(p
, oid
, *((float *)cptr
));
401 case S3D_P_MCP_FOCUS
:
402 if ((p
->id
== MCP
) && (length
== 4)) {
403 oid
= ntohl(*((uint32_t *) cptr
));
408 s3dprintf(LOW
, "don't know this command (%d)", command
);
413 /* this pushes some buffer out on the wire... */
414 int prot_com_out(struct t_process
*p
, uint8_t opcode
, uint8_t * buf
, uint16_t length
)
417 if (p
->con_type
!= CON_NULL
) {
420 *((uint16_t *) ptr
) = htons(length
);
422 memcpy(obuf
+ 3, buf
, length
);
423 if (n_writen(p
, obuf
, length
+ 3) < 0) {
424 s3dprintf(LOW
, "prot_com_out():n_writen(): connection seems to be dead (pid %d)", p
->id
);