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