added -udp documentation from d1x
[btb/d2x.git] / main / netmisc.c
1 /* $Id: netmisc.c,v 1.9 2003-10-04 19:13:32 btb Exp $ */
2 /*
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14
15 /*
16  *
17  * Misc routines for network.
18  *
19  * Old Log:
20  * Revision 1.1  1995/05/16  15:28:41  allender
21  * Initial revision
22  *
23  * Revision 2.0  1995/02/27  11:27:24  john
24  * New version 2.0, which has no anonymous unions, builds with
25  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
26  *
27  * Revision 1.3  1994/11/19  15:19:34  mike
28  * rip out unused code and data.
29  *
30  * Revision 1.2  1994/08/09  19:31:53  john
31  * Networking changes.
32  *
33  * Revision 1.1  1994/08/08  11:06:07  john
34  * Initial revision
35  *
36  *
37  */
38
39 #ifdef HAVE_CONFIG_H
40 #include <conf.h>
41 #endif
42
43 #ifdef RCS
44 static char rcsid[] = "$Id: netmisc.c,v 1.9 2003-10-04 19:13:32 btb Exp $";
45 #endif
46
47 #include <stdio.h>
48 #include <string.h>
49
50 #include "inferno.h"
51 #include "pstypes.h"
52 #include "mono.h"
53
54 #ifdef WORDS_BIGENDIAN
55
56 #include "byteswap.h"
57 #include "segment.h"
58 #include "gameseg.h"
59
60 // routine to calculate the checksum of the segments.  We add these specialized routines
61 // since the current way is byte order dependent.
62
63 void mac_do_checksum_calc(ubyte *b, int len, unsigned int *s1, unsigned int *s2)
64 {
65
66         while(len--) {
67                 *s1 += *b++;
68                 if (*s1 >= 255) *s1 -= 255;
69                 *s2 += *s1;
70         }
71 }
72
73 ushort mac_calc_segment_checksum()
74 {
75         int i, j, k;
76         unsigned int sum1,sum2;
77         short s;
78         int t;
79
80         sum1 = sum2 = 0;
81         for (i = 0; i < Highest_segment_index + 1; i++) {
82                 for (j = 0; j < MAX_SIDES_PER_SEGMENT; j++) {
83                         mac_do_checksum_calc(&(Segments[i].sides[j].type), 1, &sum1, &sum2);
84                         mac_do_checksum_calc(&(Segments[i].sides[j].pad), 1, &sum1, &sum2);
85                         s = INTEL_SHORT(Segments[i].sides[j].wall_num);
86                         mac_do_checksum_calc((ubyte *)&s, 2, &sum1, &sum2);
87                         s = INTEL_SHORT(Segments[i].sides[j].tmap_num);
88                         mac_do_checksum_calc((ubyte *)&s, 2, &sum1, &sum2);
89                         s = INTEL_SHORT(Segments[i].sides[j].tmap_num2);
90                         mac_do_checksum_calc((ubyte *)&s, 2, &sum1, &sum2);
91                         for (k = 0; k < 4; k++) {
92                                 t = INTEL_INT(((int)Segments[i].sides[j].uvls[k].u));
93                                 mac_do_checksum_calc((ubyte *)&t, 4, &sum1, &sum2);
94                                 t = INTEL_INT(((int)Segments[i].sides[j].uvls[k].v));
95                                 mac_do_checksum_calc((ubyte *)&t, 4, &sum1, &sum2);
96                                 t = INTEL_INT(((int)Segments[i].sides[j].uvls[k].l));
97                                 mac_do_checksum_calc((ubyte *)&t, 4, &sum1, &sum2);
98                         }
99                         for (k = 0; k < 2; k++) {
100                                 t = INTEL_INT(((int)Segments[i].sides[j].normals[k].x));
101                                 mac_do_checksum_calc((ubyte *)&t, 4, &sum1, &sum2);
102                                 t = INTEL_INT(((int)Segments[i].sides[j].normals[k].y));
103                                 mac_do_checksum_calc((ubyte *)&t, 4, &sum1, &sum2);
104                                 t = INTEL_INT(((int)Segments[i].sides[j].normals[k].z));
105                                 mac_do_checksum_calc((ubyte *)&t, 4, &sum1, &sum2);
106                         }
107                 }
108                 for (j = 0; j < MAX_SIDES_PER_SEGMENT; j++) {
109                         s = INTEL_SHORT(Segments[i].children[j]);
110                         mac_do_checksum_calc((ubyte *)&s, 2, &sum1, &sum2);
111                 }
112                 for (j = 0; j < MAX_VERTICES_PER_SEGMENT; j++) {
113                         s = INTEL_SHORT(Segments[i].verts[j]);
114                         mac_do_checksum_calc((ubyte *)&s, 2, &sum1, &sum2);
115                 }
116                 t = INTEL_INT(Segments[i].objects);
117                 mac_do_checksum_calc((ubyte *)&t, 4, &sum1, &sum2);
118         }
119         sum2 %= 255;
120         return ((sum1<<8)+ sum2);
121 }
122
123 // this routine totally and completely relies on the fact that the network
124 //  checksum must be calculated on the segments!!!!!
125
126 ushort netmisc_calc_checksum(void * vptr, int len)
127 {
128         vptr = vptr;
129         len = len;
130         return mac_calc_segment_checksum();
131 }
132
133 // following are routine for macintosh only that will swap the elements of
134 // structures send through the networking code.  The structures and
135 // this code must be kept in total sync
136
137 #include "ipx.h"
138 #include "multi.h"
139 #ifdef NETWORK
140 #include "network.h"
141 #endif
142 #include "object.h"
143 #include "powerup.h"
144 #include "error.h"
145
146 sbyte out_buffer[IPX_MAX_DATA_SIZE];    // used for tmp netgame packets as well as sending object data
147
148 void receive_netplayer_info(ubyte *data, netplayer_info *info)
149 {
150         int loc = 0;
151
152         memcpy(info->callsign, &(data[loc]), CALLSIGN_LEN+1);       loc += CALLSIGN_LEN+1;
153         memcpy(&(info->network.ipx.server), &(data[loc]), 4);       loc += 4;
154         memcpy(&(info->network.ipx.node), &(data[loc]), 6);         loc += 6;
155         info->version_major = data[loc];                            loc++;
156         info->version_minor = data[loc];                            loc++;
157         memcpy(&(info->computer_type), &(data[loc]), 1);            loc++;      // memcpy to avoid compile time warning about enum
158         info->connected = data[loc];                                loc++;
159         memcpy(&(info->socket), &(data[loc]), 2);                   loc += 2;
160         memcpy (&(info->rank),&(data[loc]),1);                      loc++;
161         // MWA don't think we need to swap this because we need it in high
162         // order  info->socket = INTEL_SHORT(info->socket);
163 }
164
165 void send_netplayers_packet(ubyte *server, ubyte *node)
166 {
167         int i, tmpi;
168         int loc = 0;
169         short tmps;
170
171         memset(out_buffer, 0, sizeof(out_buffer));
172         out_buffer[0] = NetPlayers.type;                            loc++;
173         tmpi = INTEL_INT(NetPlayers.Security);
174         memcpy(&(out_buffer[loc]), &tmpi, 4);                       loc += 4;
175         for (i = 0; i < MAX_PLAYERS+4; i++) {
176                 memcpy(&(out_buffer[loc]), NetPlayers.players[i].callsign, CALLSIGN_LEN+1); loc += CALLSIGN_LEN+1;
177                 memcpy(&(out_buffer[loc]), NetPlayers.players[i].network.ipx.server, 4);    loc += 4;
178                 memcpy(&(out_buffer[loc]), NetPlayers.players[i].network.ipx.node, 6);      loc += 6;
179                 memcpy(&(out_buffer[loc]), &(NetPlayers.players[i].version_major), 1);      loc++;
180                 memcpy(&(out_buffer[loc]), &(NetPlayers.players[i].version_minor), 1);      loc++;
181                 memcpy(&(out_buffer[loc]), &(NetPlayers.players[i].computer_type), 1);      loc++;
182                 memcpy(&(out_buffer[loc]), &(NetPlayers.players[i].connected), 1);          loc++;
183                 tmps = INTEL_SHORT(NetPlayers.players[i].socket);
184                 memcpy(&(out_buffer[loc]), &tmps, 2);                                       loc += 2;
185                 memcpy(&(out_buffer[loc]), &(NetPlayers.players[i].rank), 1);               loc++;
186         }
187
188         if ((server == NULL) && (node == NULL))
189                 ipx_send_broadcast_packet_data(out_buffer, loc);
190         else
191                 ipx_send_internetwork_packet_data(out_buffer, loc, server, node);
192
193 }
194
195 void receive_netplayers_packet(ubyte *data, AllNetPlayers_info *pinfo)
196 {
197         int i, loc = 0;
198
199         pinfo->type = data[loc];                            loc++;
200         memcpy(&(pinfo->Security), &(data[loc]), 4);        loc += 4;
201         pinfo->Security = INTEL_INT(pinfo->Security);
202         for (i = 0; i < MAX_PLAYERS+4; i++) {
203                 receive_netplayer_info(&(data[loc]), &(pinfo->players[i]));
204                 loc += 26;          // sizeof(netplayer_info) on the PC
205         }
206 }
207
208 void send_sequence_packet(sequence_packet seq, ubyte *server, ubyte *node, ubyte *net_address)
209 {
210         short tmps;
211         int loc, tmpi;
212
213         loc = 0;
214         memset(out_buffer, 0, sizeof(out_buffer));
215         out_buffer[0] = seq.type;                                       loc++;
216         tmpi = INTEL_INT(seq.Security);
217         memcpy(&(out_buffer[loc]), &tmpi, 4);                           loc += 4;       loc += 3;
218         memcpy(&(out_buffer[loc]), seq.player.callsign, CALLSIGN_LEN+1);loc += CALLSIGN_LEN+1;
219         memcpy(&(out_buffer[loc]), seq.player.network.ipx.server, 4);   loc += 4;
220         memcpy(&(out_buffer[loc]), seq.player.network.ipx.node, 6);     loc += 6;
221         out_buffer[loc] = seq.player.version_major;                     loc++;
222         out_buffer[loc] = seq.player.version_minor;                     loc++;
223         out_buffer[loc] = seq.player.computer_type;                     loc++;
224         out_buffer[loc] = seq.player.connected;                         loc++;
225         tmps = INTEL_SHORT(seq.player.socket);
226         memcpy(&(out_buffer[loc]), &tmps, 2);                           loc += 2;
227         out_buffer[loc]=seq.player.rank;                                loc++;      // for pad byte
228         if (net_address != NULL)
229                 ipx_send_packet_data(out_buffer, loc, server, node, net_address);
230         else if ((server == NULL) && (node == NULL))
231                 ipx_send_broadcast_packet_data(out_buffer, loc);
232         else
233                 ipx_send_internetwork_packet_data(out_buffer, loc, server, node);
234 }
235
236 void receive_sequence_packet(ubyte *data, sequence_packet *seq)
237 {
238         int loc = 0;
239
240         seq->type = data[0];                        loc++;
241         memcpy(&(seq->Security), &(data[loc]), 4);  loc += 4;   loc += 3;   // +3 for pad byte
242         seq->Security = INTEL_INT(seq->Security);
243         receive_netplayer_info(&(data[loc]), &(seq->player));
244 }
245
246 void send_netgame_packet(ubyte *server, ubyte *node, ubyte *net_address, int lite_flag)     // lite says shorter netgame packets
247 {
248         uint tmpi;
249         ushort tmps; // p;
250         int i, j;
251         int loc = 0;
252
253         memset(out_buffer, 0, IPX_MAX_DATA_SIZE);
254         memcpy(&(out_buffer[loc]), &(Netgame.type), 1);                 loc++;
255         tmpi = INTEL_INT(Netgame.Security);
256         memcpy(&(out_buffer[loc]), &tmpi, 4);                           loc += 4;
257         memcpy(&(out_buffer[loc]), Netgame.game_name, NETGAME_NAME_LEN+1);  loc += (NETGAME_NAME_LEN+1);
258         memcpy(&(out_buffer[loc]), Netgame.mission_title, MISSION_NAME_LEN+1);  loc += (MISSION_NAME_LEN+1);
259         memcpy(&(out_buffer[loc]), Netgame.mission_name, 9);            loc += 9;
260         tmpi = INTEL_INT(Netgame.levelnum);
261         memcpy(&(out_buffer[loc]), &tmpi, 4);                           loc += 4;
262         memcpy(&(out_buffer[loc]), &(Netgame.gamemode), 1);             loc++;
263         memcpy(&(out_buffer[loc]), &(Netgame.RefusePlayers), 1);        loc++;
264         memcpy(&(out_buffer[loc]), &(Netgame.difficulty), 1);           loc++;
265         memcpy(&(out_buffer[loc]), &(Netgame.game_status), 1);          loc++;
266         memcpy(&(out_buffer[loc]), &(Netgame.numplayers), 1);           loc++;
267         memcpy(&(out_buffer[loc]), &(Netgame.max_numplayers), 1);       loc++;
268         memcpy(&(out_buffer[loc]), &(Netgame.numconnected), 1);         loc++;
269         memcpy(&(out_buffer[loc]), &(Netgame.game_flags), 1);           loc++;
270         memcpy(&(out_buffer[loc]), &(Netgame.protocol_version), 1);     loc++;
271         memcpy(&(out_buffer[loc]), &(Netgame.version_major), 1);        loc++;
272         memcpy(&(out_buffer[loc]), &(Netgame.version_minor), 1);        loc++;
273         memcpy(&(out_buffer[loc]), &(Netgame.team_vector), 1);          loc++;
274
275         if (lite_flag)
276                 goto do_send;
277
278 // will this work -- damn bitfields -- totally bogus when trying to do
279 // this type of stuff
280 // Watcom makes bitfields from left to right.  CW7 on the mac goes
281 // from right to left.  then they are endian swapped
282
283         tmps = *(ushort *)((ubyte *)(&Netgame.team_vector) + 1);    // get the values for the first short bitfield
284         tmps = INTEL_SHORT(tmps);
285         memcpy(&(out_buffer[loc]), &tmps, 2);                           loc += 2;
286
287         tmps = *(ushort *)((ubyte *)(&Netgame.team_vector) + 3);    // get the values for the second short bitfield
288         tmps = INTEL_SHORT(tmps);
289         memcpy(&(out_buffer[loc]), &tmps, 2);                           loc += 2;
290
291 #if 0       // removed since I reordered bitfields on mac
292         p = *(ushort *)((ubyte *)(&Netgame.team_vector) + 1);       // get the values for the first short bitfield
293         tmps = 0;
294         for (i = 15; i >= 0; i--) {
295                 if (p & (1 << i))
296                         tmps |= (1 << (15 - i));
297         }
298         tmps = INTEL_SHORT(tmps);
299         memcpy(&(out_buffer[loc]), &tmps, 2);                           loc += 2;
300         p = *(ushort *)((ubyte *)(&Netgame.team_vector) + 3);       // get the values for the second short bitfield
301         tmps = 0;
302         for (i = 15; i >= 0; i--) {
303                 if (p & (1 << i))
304                         tmps |= (1 << (15 - i));
305         }
306         tmps = INTEL_SHORT(tmps);
307         memcpy(&(out_buffer[loc]), &tmps, 2);                           loc += 2;
308 #endif
309
310         memcpy(&(out_buffer[loc]), Netgame.team_name, 2*(CALLSIGN_LEN+1)); loc += 2*(CALLSIGN_LEN+1);
311         for (i = 0; i < MAX_PLAYERS; i++) {
312                 tmpi = INTEL_INT(Netgame.locations[i]);
313                 memcpy(&(out_buffer[loc]), &tmpi, 4);       loc += 4;   // SWAP HERE!!!
314         }
315
316         for (i = 0; i < MAX_PLAYERS; i++) {
317                 for (j = 0; j < MAX_PLAYERS; j++) {
318                         tmps = INTEL_SHORT(Netgame.kills[i][j]);
319                         memcpy(&(out_buffer[loc]), &tmps, 2);   loc += 2;   // SWAP HERE!!!
320                 }
321         }
322
323         tmps = INTEL_SHORT(Netgame.segments_checksum);
324         memcpy(&(out_buffer[loc]), &tmps, 2);           loc += 2;   // SWAP_HERE
325         tmps = INTEL_SHORT(Netgame.team_kills[0]);
326         memcpy(&(out_buffer[loc]), &tmps, 2);           loc += 2;   // SWAP_HERE
327         tmps = INTEL_SHORT(Netgame.team_kills[1]);
328         memcpy(&(out_buffer[loc]), &tmps, 2);           loc += 2;   // SWAP_HERE
329         for (i = 0; i < MAX_PLAYERS; i++) {
330                 tmps = INTEL_SHORT(Netgame.killed[i]);
331                 memcpy(&(out_buffer[loc]), &tmps, 2);       loc += 2;   // SWAP HERE!!!
332         }
333         for (i = 0; i < MAX_PLAYERS; i++) {
334                 tmps = INTEL_SHORT(Netgame.player_kills[i]);
335                 memcpy(&(out_buffer[loc]), &tmps, 2);       loc += 2;   // SWAP HERE!!!
336         }
337
338         tmpi = INTEL_INT(Netgame.KillGoal);
339         memcpy(&(out_buffer[loc]), &tmpi, 4);           loc += 4;   // SWAP_HERE
340         tmpi = INTEL_INT(Netgame.PlayTimeAllowed);
341         memcpy(&(out_buffer[loc]), &tmpi, 4);           loc += 4;   // SWAP_HERE
342         tmpi = INTEL_INT(Netgame.level_time);
343         memcpy(&(out_buffer[loc]), &tmpi, 4);           loc += 4;   // SWAP_HERE
344         tmpi = INTEL_INT(Netgame.control_invul_time);
345         memcpy(&(out_buffer[loc]), &tmpi, 4);           loc += 4;   // SWAP_HERE
346         tmpi = INTEL_INT(Netgame.monitor_vector);
347         memcpy(&(out_buffer[loc]), &tmpi, 4);           loc += 4;   // SWAP_HERE
348         for (i = 0; i < MAX_PLAYERS; i++) {
349                 tmpi = INTEL_INT(Netgame.player_score[i]);
350                 memcpy(&(out_buffer[loc]), &tmpi, 4);       loc += 4;   // SWAP_HERE
351         }
352         for (i = 0; i < MAX_PLAYERS; i++) {
353                 memcpy(&(out_buffer[loc]), &(Netgame.player_flags[i]), 1); loc++;
354         }
355         tmps = INTEL_SHORT(Netgame.PacketsPerSec);
356         memcpy(&(out_buffer[loc]), &tmps, 2);                   loc += 2;
357         memcpy(&(out_buffer[loc]), &(Netgame.ShortPackets), 1); loc ++;
358
359 do_send:
360         if (net_address != NULL)
361                 ipx_send_packet_data(out_buffer, loc, server, node, net_address);
362         else if ((server == NULL) && (node == NULL))
363                 ipx_send_broadcast_packet_data(out_buffer, loc);
364         else
365                 ipx_send_internetwork_packet_data(out_buffer, loc, server, node);
366 }
367
368 void receive_netgame_packet(ubyte *data, netgame_info *netgame, int lite_flag)
369 {
370         int i, j;
371         int loc = 0;
372         short bitfield; // new_field;
373
374         memcpy(&(netgame->type), &(data[loc]), 1);                      loc++;
375         memcpy(&(netgame->Security), &(data[loc]), 4);                  loc += 4;
376         netgame->Security = INTEL_INT(netgame->Security);
377         memcpy(netgame->game_name, &(data[loc]), NETGAME_NAME_LEN+1);   loc += (NETGAME_NAME_LEN+1);
378         memcpy(netgame->mission_title, &(data[loc]), MISSION_NAME_LEN+1); loc += (MISSION_NAME_LEN+1);
379         memcpy(netgame->mission_name, &(data[loc]), 9);                 loc += 9;
380         memcpy(&(netgame->levelnum), &(data[loc]), 4);                  loc += 4;
381         netgame->levelnum = INTEL_INT(netgame->levelnum);
382         memcpy(&(netgame->gamemode), &(data[loc]), 1);                  loc++;
383         memcpy(&(netgame->RefusePlayers), &(data[loc]), 1);             loc++;
384         memcpy(&(netgame->difficulty), &(data[loc]), 1);                loc++;
385         memcpy(&(netgame->game_status), &(data[loc]), 1);               loc++;
386         memcpy(&(netgame->numplayers), &(data[loc]), 1);                loc++;
387         memcpy(&(netgame->max_numplayers), &(data[loc]), 1);            loc++;
388         memcpy(&(netgame->numconnected), &(data[loc]), 1);              loc++;
389         memcpy(&(netgame->game_flags), &(data[loc]), 1);                loc++;
390         memcpy(&(netgame->protocol_version), &(data[loc]), 1);          loc++;
391         memcpy(&(netgame->version_major), &(data[loc]), 1);             loc++;
392         memcpy(&(netgame->version_minor), &(data[loc]), 1);             loc++;
393         memcpy(&(netgame->team_vector), &(data[loc]), 1);               loc++;
394
395         if (lite_flag)
396                 return;
397
398         memcpy(&bitfield, &(data[loc]), 2);                             loc += 2;
399         bitfield = INTEL_SHORT(bitfield);
400         memcpy(((ubyte *)(&netgame->team_vector) + 1), &bitfield, 2);
401
402         memcpy(&bitfield, &(data[loc]), 2);                             loc += 2;
403         bitfield = INTEL_SHORT(bitfield);
404         memcpy(((ubyte *)(&netgame->team_vector) + 3), &bitfield, 2);
405
406 #if 0       // not used since reordering mac bitfields
407         memcpy(&bitfield, &(data[loc]), 2);                             loc += 2;
408         new_field = 0;
409         for (i = 15; i >= 0; i--) {
410                 if (bitfield & (1 << i))
411                         new_field |= (1 << (15 - i));
412         }
413         new_field = INTEL_SHORT(new_field);
414         memcpy(((ubyte *)(&netgame->team_vector) + 1), &new_field, 2);
415
416         memcpy(&bitfield, &(data[loc]), 2);                             loc += 2;
417         new_field = 0;
418         for (i = 15; i >= 0; i--) {
419                 if (bitfield & (1 << i))
420                         new_field |= (1 << (15 - i));
421         }
422         new_field = INTEL_SHORT(new_field);
423         memcpy(((ubyte *)(&netgame->team_vector) + 3), &new_field, 2);
424 #endif
425
426         memcpy(netgame->team_name, &(data[loc]), 2*(CALLSIGN_LEN+1));   loc += 2*(CALLSIGN_LEN+1);
427         for (i = 0; i < MAX_PLAYERS; i++) {
428                 memcpy(&(netgame->locations[i]), &(data[loc]), 4);          loc += 4;
429                 netgame->locations[i] = INTEL_INT(netgame->locations[i]);
430         }
431
432         for (i = 0; i < MAX_PLAYERS; i++) {
433                 for (j = 0; j < MAX_PLAYERS; j++) {
434                         memcpy(&(netgame->kills[i][j]), &(data[loc]), 2);       loc += 2;
435                         netgame->kills[i][j] = INTEL_SHORT(netgame->kills[i][j]);
436                 }
437         }
438
439         memcpy(&(netgame->segments_checksum), &(data[loc]), 2);         loc += 2;
440         netgame->segments_checksum = INTEL_SHORT(netgame->segments_checksum);
441         memcpy(&(netgame->team_kills[0]), &(data[loc]), 2);             loc += 2;
442         netgame->team_kills[0] = INTEL_SHORT(netgame->team_kills[0]);
443         memcpy(&(netgame->team_kills[1]), &(data[loc]), 2);             loc += 2;
444         netgame->team_kills[1] = INTEL_SHORT(netgame->team_kills[1]);
445         for (i = 0; i < MAX_PLAYERS; i++) {
446                 memcpy(&(netgame->killed[i]), &(data[loc]), 2);             loc += 2;
447                 netgame->killed[i] = INTEL_SHORT(netgame->killed[i]);
448         }
449         for (i = 0; i < MAX_PLAYERS; i++) {
450                 memcpy(&(netgame->player_kills[i]), &(data[loc]), 2);       loc += 2;
451                 netgame->player_kills[i] = INTEL_SHORT(netgame->player_kills[i]);
452         }
453         memcpy(&(netgame->KillGoal), &(data[loc]), 4);                  loc += 4;
454         netgame->KillGoal = INTEL_INT(netgame->KillGoal);
455         memcpy(&(netgame->PlayTimeAllowed), &(data[loc]), 4);           loc += 4;
456         netgame->PlayTimeAllowed = INTEL_INT(netgame->PlayTimeAllowed);
457
458         memcpy(&(netgame->level_time), &(data[loc]), 4);                loc += 4;
459         netgame->level_time = INTEL_INT(netgame->level_time);
460         memcpy(&(netgame->control_invul_time), &(data[loc]), 4);        loc += 4;
461         netgame->control_invul_time = INTEL_INT(netgame->control_invul_time);
462         memcpy(&(netgame->monitor_vector), &(data[loc]), 4);            loc += 4;
463         netgame->monitor_vector = INTEL_INT(netgame->monitor_vector);
464         for (i = 0; i < MAX_PLAYERS; i++) {
465                 memcpy(&(netgame->player_score[i]), &(data[loc]), 4);       loc += 4;
466                 netgame->player_score[i] = INTEL_INT(netgame->player_score[i]);
467         }
468         for (i = 0; i < MAX_PLAYERS; i++) {
469                 memcpy(&(netgame->player_flags[i]), &(data[loc]), 1);       loc++;
470         }
471         memcpy(&(netgame->PacketsPerSec), &(data[loc]), 2);             loc += 2;
472         netgame->PacketsPerSec = INTEL_SHORT(netgame->PacketsPerSec);
473         memcpy(&(netgame->ShortPackets), &(data[loc]), 1);              loc ++;
474
475 }
476
477 void swap_object(object *obj)
478 {
479         // swap the short and int entries for this object
480         obj->signature     = INTEL_INT(obj->signature);
481         obj->next          = INTEL_SHORT(obj->next);
482         obj->prev          = INTEL_SHORT(obj->prev);
483         obj->segnum        = INTEL_SHORT(obj->segnum);
484         obj->pos.x         = INTEL_INT(obj->pos.x);
485         obj->pos.y         = INTEL_INT(obj->pos.y);
486         obj->pos.z         = INTEL_INT(obj->pos.z);
487
488         obj->orient.rvec.x = INTEL_INT(obj->orient.rvec.x);
489         obj->orient.rvec.y = INTEL_INT(obj->orient.rvec.y);
490         obj->orient.rvec.z = INTEL_INT(obj->orient.rvec.z);
491         obj->orient.fvec.x = INTEL_INT(obj->orient.fvec.x);
492         obj->orient.fvec.y = INTEL_INT(obj->orient.fvec.y);
493         obj->orient.fvec.z = INTEL_INT(obj->orient.fvec.z);
494         obj->orient.uvec.x = INTEL_INT(obj->orient.uvec.x);
495         obj->orient.uvec.y = INTEL_INT(obj->orient.uvec.y);
496         obj->orient.uvec.z = INTEL_INT(obj->orient.uvec.z);
497
498         obj->size          = INTEL_INT(obj->size);
499         obj->shields       = INTEL_INT(obj->shields);
500
501         obj->last_pos.x    = INTEL_INT(obj->last_pos.x);
502         obj->last_pos.y    = INTEL_INT(obj->last_pos.y);
503         obj->last_pos.z    = INTEL_INT(obj->last_pos.z);
504
505         obj->lifeleft      = INTEL_INT(obj->lifeleft);
506
507         switch (obj->movement_type) {
508
509         case MT_PHYSICS:
510
511                 obj->mtype.phys_info.velocity.x = INTEL_INT(obj->mtype.phys_info.velocity.x);
512                 obj->mtype.phys_info.velocity.y = INTEL_INT(obj->mtype.phys_info.velocity.y);
513                 obj->mtype.phys_info.velocity.z = INTEL_INT(obj->mtype.phys_info.velocity.z);
514
515                 obj->mtype.phys_info.thrust.x   = INTEL_INT(obj->mtype.phys_info.thrust.x);
516                 obj->mtype.phys_info.thrust.y   = INTEL_INT(obj->mtype.phys_info.thrust.y);
517                 obj->mtype.phys_info.thrust.z   = INTEL_INT(obj->mtype.phys_info.thrust.z);
518
519                 obj->mtype.phys_info.mass       = INTEL_INT(obj->mtype.phys_info.mass);
520                 obj->mtype.phys_info.drag       = INTEL_INT(obj->mtype.phys_info.drag);
521                 obj->mtype.phys_info.brakes     = INTEL_INT(obj->mtype.phys_info.brakes);
522
523                 obj->mtype.phys_info.rotvel.x   = INTEL_INT(obj->mtype.phys_info.rotvel.x);
524                 obj->mtype.phys_info.rotvel.y   = INTEL_INT(obj->mtype.phys_info.rotvel.y);
525                 obj->mtype.phys_info.rotvel.z   = INTEL_INT(obj->mtype.phys_info.rotvel.z);
526
527                 obj->mtype.phys_info.rotthrust.x = INTEL_INT(obj->mtype.phys_info.rotthrust.x);
528                 obj->mtype.phys_info.rotthrust.y = INTEL_INT(obj->mtype.phys_info.rotthrust.y);
529                 obj->mtype.phys_info.rotthrust.z = INTEL_INT(obj->mtype.phys_info.rotthrust.z);
530
531                 obj->mtype.phys_info.turnroll   = INTEL_INT(obj->mtype.phys_info.turnroll);
532                 obj->mtype.phys_info.flags      = INTEL_SHORT(obj->mtype.phys_info.flags);
533
534                 break;
535
536         case MT_SPINNING:
537
538                 obj->mtype.spin_rate.x = INTEL_INT(obj->mtype.spin_rate.x);
539                 obj->mtype.spin_rate.y = INTEL_INT(obj->mtype.spin_rate.y);
540                 obj->mtype.spin_rate.z = INTEL_INT(obj->mtype.spin_rate.z);
541                 break;
542         }
543
544         switch (obj->control_type) {
545
546         case CT_WEAPON:
547                 obj->ctype.laser_info.parent_type       = INTEL_SHORT(obj->ctype.laser_info.parent_type);
548                 obj->ctype.laser_info.parent_num        = INTEL_SHORT(obj->ctype.laser_info.parent_num);
549                 obj->ctype.laser_info.parent_signature  = INTEL_INT(obj->ctype.laser_info.parent_signature);
550                 obj->ctype.laser_info.creation_time     = INTEL_INT(obj->ctype.laser_info.creation_time);
551                 obj->ctype.laser_info.last_hitobj       = INTEL_SHORT(obj->ctype.laser_info.last_hitobj);
552                 obj->ctype.laser_info.track_goal        = INTEL_SHORT(obj->ctype.laser_info.track_goal);
553                 obj->ctype.laser_info.multiplier        = INTEL_INT(obj->ctype.laser_info.multiplier);
554                 break;
555
556         case CT_EXPLOSION:
557                 obj->ctype.expl_info.spawn_time     = INTEL_INT(obj->ctype.expl_info.spawn_time);
558                 obj->ctype.expl_info.delete_time    = INTEL_INT(obj->ctype.expl_info.delete_time);
559                 obj->ctype.expl_info.delete_objnum  = INTEL_SHORT(obj->ctype.expl_info.delete_objnum);
560                 obj->ctype.expl_info.attach_parent  = INTEL_SHORT(obj->ctype.expl_info.attach_parent);
561                 obj->ctype.expl_info.prev_attach    = INTEL_SHORT(obj->ctype.expl_info.prev_attach);
562                 obj->ctype.expl_info.next_attach    = INTEL_SHORT(obj->ctype.expl_info.next_attach);
563                 break;
564
565         case CT_AI:
566                 obj->ctype.ai_info.hide_segment         = INTEL_SHORT(obj->ctype.ai_info.hide_segment);
567                 obj->ctype.ai_info.hide_index           = INTEL_SHORT(obj->ctype.ai_info.hide_index);
568                 obj->ctype.ai_info.path_length          = INTEL_SHORT(obj->ctype.ai_info.path_length);
569                 obj->ctype.ai_info.danger_laser_num     = INTEL_SHORT(obj->ctype.ai_info.danger_laser_num);
570                 obj->ctype.ai_info.danger_laser_signature = INTEL_INT(obj->ctype.ai_info.danger_laser_signature);
571                 obj->ctype.ai_info.dying_start_time     = INTEL_INT(obj->ctype.ai_info.dying_start_time);
572                 break;
573
574         case CT_LIGHT:
575                 obj->ctype.light_info.intensity = INTEL_INT(obj->ctype.light_info.intensity);
576                 break;
577
578         case CT_POWERUP:
579                 obj->ctype.powerup_info.count = INTEL_INT(obj->ctype.powerup_info.count);
580                 obj->ctype.powerup_info.creation_time = INTEL_INT(obj->ctype.powerup_info.creation_time);
581                 // Below commented out 5/2/96 by Matt.  I asked Allender why it was
582                 // here, and he didn't know, and it looks like it doesn't belong.
583                 // if (obj->id == POW_VULCAN_WEAPON)
584                 // obj->ctype.powerup_info.count = VULCAN_WEAPON_AMMO_AMOUNT;
585                 break;
586
587         }
588
589         switch (obj->render_type) {
590
591         case RT_MORPH:
592         case RT_POLYOBJ: {
593                 int i;
594
595                 obj->rtype.pobj_info.model_num      = INTEL_INT(obj->rtype.pobj_info.model_num);
596
597                 for (i=0;i<MAX_SUBMODELS;i++) {
598                         obj->rtype.pobj_info.anim_angles[i].p = INTEL_INT(obj->rtype.pobj_info.anim_angles[i].p);
599                         obj->rtype.pobj_info.anim_angles[i].b = INTEL_INT(obj->rtype.pobj_info.anim_angles[i].b);
600                         obj->rtype.pobj_info.anim_angles[i].h = INTEL_INT(obj->rtype.pobj_info.anim_angles[i].h);
601                 }
602
603                 obj->rtype.pobj_info.subobj_flags   = INTEL_INT(obj->rtype.pobj_info.subobj_flags);
604                 obj->rtype.pobj_info.tmap_override  = INTEL_INT(obj->rtype.pobj_info.tmap_override);
605                 obj->rtype.pobj_info.alt_textures   = INTEL_INT(obj->rtype.pobj_info.alt_textures);
606                 break;
607         }
608
609         case RT_WEAPON_VCLIP:
610         case RT_HOSTAGE:
611         case RT_POWERUP:
612         case RT_FIREBALL:
613                 obj->rtype.vclip_info.vclip_num = INTEL_INT(obj->rtype.vclip_info.vclip_num);
614                 obj->rtype.vclip_info.frametime = INTEL_INT(obj->rtype.vclip_info.frametime);
615                 break;
616
617         case RT_LASER:
618                 break;
619
620         }
621 //  END OF SWAPPING OBJECT STRUCTURE
622
623 }
624
625 #else /* !WORDS_BIGENDIAN */
626
627
628 // Calculates the checksum of a block of memory.
629 ushort netmisc_calc_checksum(void * vptr, int len)
630 {
631         ubyte *ptr = (ubyte *)vptr;
632         unsigned int sum1,sum2;
633
634         sum1 = sum2 = 0;
635
636         while(len--) {
637                 sum1 += *ptr++;
638                 if (sum1 >= 255) sum1 -= 255;
639                 sum2 += sum1;
640         }
641         sum2 %= 255;
642
643         return ((sum1<<8)+ sum2);
644 }
645
646 #endif /* WORDS_BIGENDIAN */
647
648 //--unused-- //Finds the difference between block1 and block2.  Fills in diff_buffer and
649 //--unused-- //returns the size of diff_buffer.
650 //--unused-- int netmisc_find_diff(void *block1, void *block2, int block_size, void *diff_buffer)
651 //--unused-- {
652 //--unused--    int mode;
653 //--unused--    ushort *c1, *c2, *diff_start, *c3;
654 //--unused--    int i, j, size, diff, n , same;
655 //--unused--
656 //--unused--    size=(block_size+1)/sizeof(ushort);
657 //--unused--    c1 = (ushort *)block1;
658 //--unused--    c2 = (ushort *)block2;
659 //--unused--    c3 = (ushort *)diff_buffer;
660 //--unused--
661 //--unused--    mode = same = diff = n = 0;
662 //--unused--
663 //--unused--    //mprintf(0, "=================================\n");
664 //--unused--
665 //--unused--    for (i=0; i<size; i++, c1++, c2++) {
666 //--unused--            if (*c1 != *c2) {
667 //--unused--                    if (mode==0) {
668 //--unused--                            mode = 1;
669 //--unused--                            //mprintf(0, "%ds ", same);
670 //--unused--                            c3[n++] = same;
671 //--unused--                            same=0; diff=0;
672 //--unused--                            diff_start = c2;
673 //--unused--                    }
674 //--unused--                    *c1 = *c2;
675 //--unused--                    diff++;
676 //--unused--                    if (diff==65535) {
677 //--unused--                            mode = 0;
678 //--unused--                            // send how many diff ones.
679 //--unused--                            //mprintf(0, "%dd ", diff);
680 //--unused--                            c3[n++]=diff;
681 //--unused--                            // send all the diff ones.
682 //--unused--                            for (j=0; j<diff; j++)
683 //--unused--                                    c3[n++] = diff_start[j];
684 //--unused--                            same=0; diff=0;
685 //--unused--                            diff_start = c2;
686 //--unused--                    }
687 //--unused--            } else {
688 //--unused--                    if (mode==1) {
689 //--unused--                            mode=0;
690 //--unused--                            // send how many diff ones.
691 //--unused--                            //mprintf(0, "%dd ", diff);
692 //--unused--                            c3[n++]=diff;
693 //--unused--                            // send all the diff ones.
694 //--unused--                            for (j=0; j<diff; j++)
695 //--unused--                                    c3[n++] = diff_start[j];
696 //--unused--                            same=0; diff=0;
697 //--unused--                            diff_start = c2;
698 //--unused--                    }
699 //--unused--                    same++;
700 //--unused--                    if (same==65535) {
701 //--unused--                            mode=1;
702 //--unused--                            // send how many the same
703 //--unused--                            //mprintf(0, "%ds ", same);
704 //--unused--                            c3[n++] = same;
705 //--unused--                            same=0; diff=0;
706 //--unused--                            diff_start = c2;
707 //--unused--                    }
708 //--unused--            }
709 //--unused--
710 //--unused--    }
711 //--unused--    if (mode==0) {
712 //--unused--            // send how many the same
713 //--unused--            //mprintf(0, "%ds ", same);
714 //--unused--            c3[n++] = same;
715 //--unused--    } else {
716 //--unused--            // send how many diff ones.
717 //--unused--            //mprintf(0, "%dd ", diff);
718 //--unused--            c3[n++]=diff;
719 //--unused--            // send all the diff ones.
720 //--unused--            for (j=0; j<diff; j++)
721 //--unused--                    c3[n++] = diff_start[j];
722 //--unused--    }
723 //--unused--
724 //--unused--    //mprintf(0, "=================================\n");
725 //--unused--
726 //--unused--    return n*2;
727 //--unused-- }
728
729 //--unused-- //Applies diff_buffer to block1 to create a new block1.  Returns the final
730 //--unused-- //size of block1.
731 //--unused-- int netmisc_apply_diff(void *block1, void *diff_buffer, int diff_size)
732 //--unused-- {
733 //--unused--    unsigned int i, j, n, size;
734 //--unused--    ushort *c1, *c2;
735 //--unused--
736 //--unused--    //mprintf(0, "=================================\n");
737 //--unused--    c1 = (ushort *)diff_buffer;
738 //--unused--    c2 = (ushort *)block1;
739 //--unused--
740 //--unused--    size = diff_size/2;
741 //--unused--
742 //--unused--    i=j=0;
743 //--unused--    while (1) {
744 //--unused--            j += c1[i];         // Same
745 //--unused--            //mprintf(0, "%ds ", c1[i]);
746 //--unused--            i++;
747 //--unused--            if (i>=size) break;
748 //--unused--            n = c1[i];          // ndiff
749 //--unused--            //mprintf(0, "%dd ", c1[i]);
750 //--unused--            i++;
751 //--unused--            if (n>0) {
752 //--unused--                    //Assert(n* < 256);
753 //--unused--                    memcpy(&c2[j], &c1[i], n*2);
754 //--unused--                    i += n;
755 //--unused--                    j += n;
756 //--unused--            }
757 //--unused--            if (i>=size) break;
758 //--unused--    }
759 //--unused--    //mprintf(0, "=================================\n");
760 //--unused--
761 //--unused--    return j*2;
762 //--unused-- }