Release s3d 0.2.2
[s3d.git] / server / proto.c
blob55514943d73d760f54d4844748abe3284402d44d
1 /*
2 * proto.c
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
24 #include "global.h"
25 #include "proto.h"
26 #include <stdlib.h> /* malloc() */
27 #include <string.h> /* strncpy(),memset() */
28 #include <stdint.h>
29 #ifdef WIN32
30 #include <winsock2.h>
31 #else
32 #include <netinet/in.h> /* htonl(),htons() */
33 #endif
34 /* this code should do the protocol work .... */
35 /* */
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)
41 uint8_t command;
42 int i;
43 char name[S3D_NAME_MAX];
44 struct t_process *np;
45 uint8_t *buf, *cptr = NULL;
46 uint16_t length;
47 uint16_t num;
48 uint16_t w, h, x, y;
49 uint32_t oid, toid;
50 uint8_t type;
51 int32_t flags, mcp_oid = -1;
52 command = pbuf[0];
53 if (p->id != 0) {
54 mcp_oid = p->mcp_oid; /* get mcp-oid if we need to report something to */
55 /* the mcp */
56 if ((mcp_oid == -1) && (command != S3D_P_C_INIT)) {
57 s3dprintf(MED, "prot_com_in(): commands without beeing initialized ?! no way, kicking ...");
58 event_quit(p);
61 length = ntohs(*((uint16_t *) ((uint8_t *) pbuf + 1)));
62 cptr = buf = pbuf + sizeof(int_least32_t);
63 switch (command) {
64 case S3D_P_C_INIT:
65 memset(name, 0, S3D_NAME_MAX);
66 if (length > S3D_NAME_MAX)
67 i = S3D_NAME_MAX;
68 else
69 i = length;
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 */
74 else
75 event_init(np);
76 break;
77 case S3D_P_C_NEW_OBJ:
78 oid = htonl(obj_new(p));
79 prot_com_out(p, S3D_P_S_NEWOBJ, (uint8_t *) & oid, 4);
80 break;
81 case S3D_P_C_DEL_OBJ:
82 if (length == 4) {
83 oid = ntohl(*((uint32_t *) cptr));
84 obj_del(p, oid);
86 break;
87 case S3D_P_C_CLONE:
88 if (length == 8) {
89 oid = ntohl(*((uint32_t *) cptr));
90 cptr += 4;
91 toid = ntohl(*((uint32_t *) cptr));
92 obj_clone_change(p, oid, toid);
94 break;
95 case S3D_P_C_LINK:
96 if (length == 4) {
97 oid = ntohl(*((uint32_t *) cptr));
98 obj_unlink(p, oid);
100 if (length == 8) {
101 oid = ntohl(*((uint32_t *) cptr));
102 cptr += 4;
103 toid = ntohl(*((uint32_t *) cptr));
104 obj_link(p, oid, toid);
106 break;
107 case S3D_P_C_QUIT:
108 s3dprintf(LOW, "QUIT issued");
109 event_quit(p);
110 break;
111 case S3D_P_C_PUSH_VERTEX:
112 if (length > 4) {
113 oid = ntohl(*((uint32_t *) cptr));
114 cptr += 4;
115 num = (length - 4) / (4 * 3);
116 ntohfb((float *)cptr, num * 3);
117 obj_push_vertex(p, oid, (float *)cptr, num);
119 break;
120 case S3D_P_C_PUSH_MAT:
121 if (length > 4) {
122 oid = ntohl(*((uint32_t *) cptr));
123 cptr += 4;
124 num = (length - 4) / (4 * 12);
125 ntohfb((float *)cptr, num * 12);
126 obj_push_mat(p, oid, (float *)cptr, num);
128 break;
129 case S3D_P_C_PUSH_POLY:
130 if (length > 4) {
131 oid = ntohl(*((uint32_t *) cptr));
132 cptr += 4;
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);
138 break;
139 case S3D_P_C_PUSH_LINE:
140 if (length > 4) {
141 oid = ntohl(*((uint32_t *) cptr));
142 cptr += 4;
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);
149 break;
150 case S3D_P_C_PUSH_TEX:
151 if (length > 4) {
152 oid = ntohl(*((uint32_t *) cptr));
153 cptr += 4;
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);
160 break;
161 case S3D_P_C_PEP_POLY_NORMAL:
162 if (length > 4) {
163 oid = ntohl(*((uint32_t *) cptr));
164 cptr += 4;
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);
170 break;
171 case S3D_P_C_PEP_LINE_NORMAL:
172 if (length > 4) {
173 oid = ntohl(*((uint32_t *) cptr));
174 cptr += 4;
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);
180 break;
181 case S3D_P_C_PEP_POLY_TEXC:
182 if (length > 4) {
183 oid = ntohl(*((uint32_t *) cptr));
184 cptr += 4;
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);
190 break;
191 case S3D_P_C_PEP_MAT:
192 if (length > 4) {
193 oid = ntohl(*((uint32_t *) cptr));
194 cptr += 4;
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);
200 break;
201 case S3D_P_C_PEP_VERTEX:
202 if (length > 4) {
203 oid = ntohl(*((uint32_t *) cptr));
204 cptr += 4;
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);
210 break;
212 case S3D_P_C_PEP_MAT_TEX:
213 if (length > 4) {
214 oid = ntohl(*((uint32_t *) cptr));
215 cptr += 4;
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);
221 break;
222 case S3D_P_C_PEP_LINE:
223 if (length > 4) {
224 oid = ntohl(*((uint32_t *) cptr));
225 cptr += 4;
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);
231 break;
232 case S3D_P_C_LOAD_LINE_NORMAL:
233 if (length > 8) {
234 oid = ntohl(*((uint32_t *) cptr));
235 cptr += 4;
236 toid = ntohl(*((uint32_t *) cptr));
237 cptr += 4;
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);
243 break;
244 case S3D_P_C_LOAD_POLY_NORMAL:
245 if (length > 8) {
246 oid = ntohl(*((uint32_t *) cptr));
247 cptr += 4;
248 toid = ntohl(*((uint32_t *) cptr));
249 cptr += 4;
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);
255 break;
256 case S3D_P_C_LOAD_POLY_TEXC:
257 if (length > 8) {
258 oid = ntohl(*((uint32_t *) cptr));
259 cptr += 4;
260 toid = ntohl(*((uint32_t *) cptr));
261 cptr += 4;
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);
267 break;
268 case S3D_P_C_LOAD_MAT:
269 if (length > 8) {
270 oid = ntohl(*((uint32_t *) cptr));
271 cptr += 4;
272 toid = ntohl(*((uint32_t *) cptr));
273 cptr += 4;
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);
279 break;
280 case S3D_P_C_LOAD_TEX:
281 if (length > 16) {
282 oid = ntohl(*((uint32_t *) cptr));
283 cptr += 4;
284 toid = ntohl(*((uint32_t *) cptr));
285 cptr += 4;
286 x = ntohs(*((uint16_t *) cptr));
287 cptr += 2;
288 y = ntohs(*((uint16_t *) cptr));
289 cptr += 2;
290 w = ntohs(*((uint16_t *) cptr));
291 cptr += 2;
292 h = ntohs(*((uint16_t *) cptr));
293 cptr += 2;
294 num = length - 16;
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);
299 break;
300 case S3D_P_C_UPDATE_TEX:
301 if (length == 16) {
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);
317 break;
319 case S3D_P_C_DEL_VERTEX:
320 if (length == 8) {
321 oid = ntohl(*((uint32_t *) cptr));
322 cptr += sizeof(uint32_t);
323 num = ntohl(*((uint32_t *) cptr));
325 obj_del_vertex(p, oid, num);
327 break;
328 case S3D_P_C_DEL_POLY:
329 if (length == 8) {
330 oid = ntohl(*((uint32_t *) cptr));
331 cptr += sizeof(uint32_t);
332 num = ntohl(*((uint32_t *) cptr));
334 obj_del_poly(p, oid, num);
336 break;
337 case S3D_P_C_DEL_LINE:
338 if (length == 8) {
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);
346 break;
348 case S3D_P_C_DEL_MAT:
349 if (length == 8) {
350 oid = ntohl(*((uint32_t *) cptr));
351 cptr += sizeof(uint32_t);
352 num = ntohl(*((uint32_t *) cptr));
354 obj_del_mat(p, oid, num);
356 break;
357 case S3D_P_C_DEL_TEX:
358 if (length == 8) {
359 oid = ntohl(*((uint32_t *) cptr));
360 cptr += sizeof(uint32_t);
361 num = ntohl(*((uint32_t *) cptr));
363 obj_del_tex(p, oid, num);
365 break;
366 case S3D_P_C_TOGGLE_FLAGS:
367 if (length == 9) {
368 oid = ntohl(*((uint32_t *) cptr));
369 cptr += sizeof(uint32_t);;
370 type = *cptr;
371 cptr += sizeof(unsigned char);
372 flags = ntohl(*((uint32_t *) cptr));
374 obj_toggle_flags(p, oid, type, flags);
376 break;
377 case S3D_P_C_TRANSLATE:
378 if (length >= 16) {
379 oid = ntohl(*((uint32_t *) cptr));
380 cptr += sizeof(uint32_t);
381 ntohfb((float *)cptr, 3);
382 obj_translate(p, oid, (float *)cptr);
384 break;
385 case S3D_P_C_ROTATE:
386 if (length >= 16) {
387 oid = ntohl(*((uint32_t *) cptr));
388 cptr += 4;
389 ntohfb((float *)cptr, 3);
390 obj_rotate(p, oid, (float *)cptr);
392 break;
393 case S3D_P_C_SCALE:
394 if (length >= 8) {
395 oid = ntohl(*((uint32_t *) cptr));
396 cptr += 4;
397 ntohfb((float *)cptr, 3);
398 obj_scale(p, oid, *((float *)cptr));
400 break;
401 case S3D_P_MCP_FOCUS:
402 if ((p->id == MCP) && (length == 4)) {
403 oid = ntohl(*((uint32_t *) cptr));
404 mcp_focus(oid);
406 break;
407 default:
408 s3dprintf(LOW, "don't know this command (%d)", command);
410 return 0;
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)
416 uint8_t *ptr;
417 if (p->con_type != CON_NULL) {
418 *(obuf) = opcode;
419 ptr = obuf + 1;
420 *((uint16_t *) ptr) = htons(length);
421 if (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);
425 process_del(p->id);
427 return 0;
429 return -1;