00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "multiplay.h"
00026
00027 MULTIPLAY::MULTIPLAY()
00028 {
00029 remote_players = 0;
00030 remote_playernum = 0;
00031
00032 int i;
00033 for (i = 0; i < MAX_PLAYERS; i++)
00034 {
00035 funcmems[i] = NULL;
00036 fnums[i] = 0;
00037 }
00038
00039 for (i = 0; i < MAX_PLAYERS; i++)
00040 {
00041 timeindex[i] = 0.0;
00042 loadstates[i].time = 0.0;
00043 loadstatenow[i] = false;
00044 numpackets[i] = 0;
00045
00046 packetarrays[i] = NULL;
00047
00048
00049 nooptime[i] = 0;
00050 noopvalid[i] = false;
00051 tickthisframe[i] = false;
00052
00053 nooptick[i] = false;
00054 }
00055
00056 tx = 0;
00057 rx = 0;
00058
00059 dbgnumstates = 0;
00060 dbgnumpackets = 0;
00061 }
00062
00063 void MULTIPLAY::UpdateSettings()
00064 {
00065 settings.Get( "network.server_port", port );
00066 }
00067
00068 bool MULTIPLAY::Server()
00069 {
00070 return net.Server();
00071 }
00072
00073 bool MULTIPLAY::Connect(string host)
00074 {
00075 Disconnect();
00076
00077 replay.BuildFuncMem(funcmems[0], fnums[0]);
00078
00079 bool ret = net.Connect(host, port);
00080 if (!Server() && ret)
00081 {
00082 remote_players = 0;
00083 remote_players++;
00084
00085 ret = ExchangeWorldInfo();
00086 int i;
00087 for (i = 0; i < MAX_PLAYERS; i++)
00088 {
00089 timeindex[i] = 0.0;
00090 loadstates[i].time = 0.0;
00091 loadstatenow[i] = false;
00092 numpackets[i] = 0;
00093
00094
00095
00096 nooptime[i] = 0;
00097 noopvalid[i] = false;
00098 tickthisframe[i] = false;
00099 nooptick[i] = false;
00100 }
00101
00102 dbgnumstates = 0;
00103 dbgnumpackets = 0;
00104
00105 mq1.Clear();
00106 mq1.AddMessage("Successfully connected to server");
00107 }
00108 return ret;
00109 }
00110
00111 bool MULTIPLAY::Host()
00112 {
00113 Disconnect();
00114
00115 replay.BuildFuncMem(funcmems[0], fnums[0]);
00116
00117 remote_playernum = 0;
00118 return net.Connect("Server", port);
00119 }
00120
00121 extern float FrameTime();
00122
00123 void MULTIPLAY::Update(double inc)
00124 {
00125 if (MP_DBGDEEP)
00126 cout << "multiplay update" << endl;
00127
00128
00129 int i;
00130 for (i = 0; i < NumConnected() + 1; i++)
00131 {
00132 if (packetarrays[i] == NULL)
00133 {
00134 packetarrays[i] = new REPLAY_PACKET [PACKET_ARRAY_SIZE];
00135 }
00136 }
00137
00138 if (MP_DBGDEEP)
00139 cout << "packet mem allocated" << endl;
00140
00141 bool oldc = Connected();
00142 net.Update();
00143 if (!oldc && Connected())
00144 {
00145
00146 if (Server())
00147 remote_players++;
00148
00149 ExchangeWorldInfo();
00150
00151 int i;
00152 for (i = 0; i < MAX_PLAYERS; i++)
00153 {
00154 timeindex[i] = 0.0;
00155 loadstates[i].time = 0.0;
00156 loadstatenow[i] = false;
00157 numpackets[i] = 0;
00158
00159
00160
00161 nooptime[i] = 0;
00162 noopvalid[i] = false;
00163 tickthisframe[i] = false;
00164 nooptick[i] = false;
00165 }
00166
00167 dbgnumstates = 0;
00168 dbgnumpackets = 0;
00169
00170 mq1.Clear();
00171 mq1.AddMessage("A client successfully connected");
00172 }
00173
00174 if (MP_DBGDEEP)
00175 cout << "net updated" << endl;
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 if (Connected())
00188 {
00189 if (!MP_DISABLEGET)
00190 {
00191 ReceiveState();
00192
00193 if (MP_DBGDEEP)
00194 cout << "state receive" << endl;
00195
00196 ReceivePacketArray();
00197
00198 if (MP_DBGDEEP)
00199 cout << "packet array receive" << endl;
00200 }
00201
00202 if (!MP_DISABLEFUNCUPDATE)
00203 {
00204 double tval = 0;
00205 string ticktype = "packet array";
00206 nooptick[1] = false;
00207 if (PacketArrayValid(1))
00208 tval = GetPacketArrayTime(1);
00209 if (noopvalid[1] && nooptime[1] > tval)
00210 {
00211 tval = nooptime[1];
00212 ticktype = "noop";
00213 nooptick[1] = true;
00214 }
00215 if ((noopvalid[1] || PacketArrayValid(1)) && timeindex[1] < tval + PACKET_ARRAY_FREQUENCY - FrameTime()/2.0)
00216 {
00217 tickthisframe[1] = true;
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 timeindex[1] += inc;
00228
00229
00230
00231 int i;
00232 for (i = 0; i < fnums[1]; i++)
00233 {
00234 if (!GetFuncMem(1)[i].held && GetFuncMem(1)[i].active)
00235 GetFuncMem(1)[i].active = false;
00236 }
00237
00238 UpdateFuncmem(1);
00239 }
00240 else
00241 {
00242 tickthisframe[1] = false;
00243
00244 }
00245 }
00246
00247 if (MP_DBGDEEP)
00248 cout << "ticked" << endl;
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 }
00260
00261
00262
00263
00264 if (GetLatency(1) > CLIENT_DISCONNECT_TIMEOUT)
00265 {
00266 Disconnect();
00267 }
00268
00269
00270 UpdateStats();
00271
00272 if (MP_DBGDEEP)
00273 cout << "multiplay update done" << endl;
00274 }
00275
00276 void MULTIPLAY::Disconnect()
00277 {
00278 bool wasconnected = Connected();
00279
00280 net.Disconnect();
00281 remote_players = 0;
00282 remote_playernum = 0;
00283
00284 int i;
00285 for (i = 0; i < MAX_PLAYERS; i++)
00286 timeindex[i] = 0.0;
00287
00288 if (MP_RECORD && dbgnumpackets > 0)
00289 {
00290 int slot = 0;
00291
00292 if (MP_REMOTE_RECORD)
00293 slot = 1;
00294
00295 FILE * dbgout = fopen("replays/mpdebug.vdr", "wb");
00296 if (dbgout)
00297 {
00298 replay.WriteHeader(dbgout, GetFuncMem(slot), NumFuncs(slot), slot);
00299 replay.WritePackets(dbgout, dbgpacket, dbgnumpackets, dbgstate, dbgnumstates);
00300 fclose(dbgout);
00301 }
00302
00303 dbgnumpackets = 0;
00304 dbgnumstates = 0;
00305 }
00306
00307 if (wasconnected)
00308 mq1.AddMessage("Disconnected");
00309 }
00310
00311 extern bool LoadWorld();
00312 extern void SelectCar(string cfile, bool trim);
00313
00314 MULTIPLAY::~MULTIPLAY()
00315 {
00316 int i;
00317 for (i = 0; i < MAX_PLAYERS; i++)
00318 {
00319 if (funcmems[i] != NULL)
00320 delete [] funcmems[i];
00321
00322 funcmems[i] = NULL;
00323
00324 if (packetarrays[i] != NULL)
00325 delete [] packetarrays[i];
00326
00327 packetarrays[i] = NULL;
00328 }
00329 }
00330
00331 bool MULTIPLAY::ExchangeWorldInfo()
00332 {
00333 char tc[32767];
00334 sprintf(tc, "%c%c %s\n%i\n%s\n%i\n%i", (char) (replay.Get_FuncNetControl()), (char) CONTROL_WORLDINFO, state.GetCarName(0).c_str(), state.GetCarPaint(0), state.GetTrackName().c_str(), NumConnected(), NumConnected());
00335
00336
00337 tc[2] = (char) ((Uint8) strlen(tc));
00338
00339
00340 int tclen = strlen(tc);
00341 int opos = tclen;
00342
00343
00344 opos = AddToData(tc, &(fnums[0]), sizeof(int), opos);
00345 int f;
00346 for (f = 0; f < fnums[0]; f++)
00347 {
00348 char fout[FUNCTION_CHARS];
00349 strcpy(fout, GetFuncMem(0)[f].func_name.c_str());
00350
00351 opos = AddToData(tc, fout, FUNCTION_CHARS, opos);
00352 }
00353
00354 net.Send(tc, opos);
00355
00356 int ret = net.RecvBlock(tc, 32767, GENERIC_TIMEOUT);
00357 if (ret > 0)
00358 {
00359 int pos = 0;
00360 int err = 0;
00361
00362 if (tc[pos] == (char) (replay.Get_FuncNetControl()))
00363 {
00364 pos++;
00365 if (tc[pos] == (char) (CONTROL_WORLDINFO))
00366 {
00367 pos++;
00368
00369
00370 int slen = tc[2];
00371 pos++;
00372
00373 string car;
00374 string carpaint;
00375 string track;
00376 string numplayers;
00377 string myplayernum;
00378 char sc[2];
00379 sc[1] = '\0';
00380
00381 while (pos < slen && tc[pos] != '\n')
00382 {
00383 sc[0] = tc[pos];
00384 car.append(sc);
00385
00386 pos++;
00387 }
00388
00389 pos++;
00390
00391 while (pos < slen && tc[pos] != '\n')
00392 {
00393 sc[0] = tc[pos];
00394 carpaint.append(sc);
00395
00396 pos++;
00397 }
00398
00399 pos++;
00400
00401 while (pos < slen && tc[pos] != '\n')
00402 {
00403 sc[0] = tc[pos];
00404 track.append(sc);
00405
00406 pos++;
00407 }
00408
00409 pos++;
00410
00411 while (pos < slen && tc[pos] != '\n')
00412 {
00413 sc[0] = tc[pos];
00414 numplayers.append(sc);
00415
00416 pos++;
00417 }
00418
00419 pos++;
00420
00421 while (pos < slen && tc[pos] != '\n')
00422 {
00423 sc[0] = tc[pos];
00424 myplayernum.append(sc);
00425
00426 pos++;
00427 }
00428
00429 int icarpaint = atoi(carpaint.c_str());
00430 int inumplayers = atoi(numplayers.c_str());
00431 int imyplayernum = atoi(myplayernum.c_str());
00432
00433 if (MP_DEBUG)
00434 {
00435
00436
00437 cout << "worldinfo size: " << ret << endl;
00438 cout << "got worldinfo: " << car << "," << icarpaint << "," << track << "," << inumplayers << "," << imyplayernum << endl;
00439 }
00440
00441
00442
00443 int newpnum = NumConnected();
00444 if (funcmems[newpnum] != NULL)
00445 {
00446 delete [] funcmems[newpnum];
00447 funcmems[newpnum] = NULL;
00448 }
00449 pos = slen;
00450 pos = GetFromData(tc, &(fnums[newpnum]), sizeof(int), pos);
00451 funcmems[newpnum] = new FUNCTION_MEMORY [fnums[newpnum]];
00452 for (f = 0; f < fnums[newpnum]; f++)
00453 {
00454 char fin[FUNCTION_CHARS];
00455 pos = GetFromData(tc, fin, FUNCTION_CHARS, pos);
00456 GetFuncMem(newpnum)[f].func_name = fin;
00457 GetFuncMem(newpnum)[f].oldval = 0.0;
00458 GetFuncMem(newpnum)[f].held = false;
00459 GetFuncMem(newpnum)[f].active = false;
00460 }
00461
00462 if (NET_DEBUG)
00463 {
00464 cout << "got functions: " << fnums[newpnum];
00465 cout << " (" << fnums[0] << " local)" << endl;
00466
00467
00468
00469
00470
00471
00472 }
00473
00474 if (!Server())
00475 {
00476 state.SetTrackName(track);
00477 state.SetCarName(1, car);
00478 state.SetCarPaint(1, icarpaint);
00479 remote_players = inumplayers;
00480 remote_playernum = imyplayernum;
00481
00482 LoadWorld();
00483 }
00484 else
00485 {
00486 state.SetCarName(1, car);
00487 state.SetCarPaint(1, icarpaint);
00488
00489 SelectCar(state.GetCarName(0), true);
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 }
00509 }
00510 else
00511 err = 2;
00512 }
00513 else
00514 err = 1;
00515
00516 if (err)
00517 {
00518
00519
00520
00521 net.Disconnect();
00522 if (MP_DEBUG)
00523 {
00524 cout << "multiplay: Update: error parsing world info: error " << err << endl;
00525 }
00526 return false;
00527 }
00528 }
00529 else
00530 {
00531
00532
00533
00534 net.Disconnect();
00535 if (MP_DEBUG)
00536 {
00537 cout << "multiplay: Update: didn't receive world info: error " << ret << endl;
00538 }
00539
00540 return false;
00541 }
00542
00543 return true;
00544 }
00545
00546 int MULTIPLAY::NumConnected()
00547 {
00548 return remote_players;
00549 }
00550
00551
00552 int MULTIPLAY::AddToData(void * dest, void * source, int len, int start)
00553 {
00554 int i;
00555 for (i = 0; i < len; i++)
00556 {
00557 ((char *) dest)[i+start] = ((char *) source)[i];
00558 }
00559
00560 return start + len;
00561 }
00562
00563
00564 int MULTIPLAY::GetFromData(void * source, void * dest, int len, int start)
00565 {
00566 int i;
00567 for (i = 0; i < len; i++)
00568 {
00569 ((char *) dest)[i] = ((char *) source)[i+start];
00570 }
00571
00572 return start + len;
00573 }
00574
00575 void MULTIPLAY::AddRecord(string newdofunction, float newval, int newstate)
00576 {
00577 if (MP_DISABLEADDRECORD)
00578 return;
00579
00580
00581 if (NumConnected() > 0 && GetFuncMem(0) != NULL)
00582 {
00583
00584
00585 int funcidx = 0;
00586 int i;
00587 for (i = 0; i < fnums[0]; i++)
00588 {
00589 if (GetFuncMem(0)[i].func_name == newdofunction)
00590 funcidx = i;
00591 }
00592
00593
00594
00595
00596 if (newstate != 2)
00597 {
00598 GetFuncMem(0)[funcidx].lastupdateat = timeindex[0];
00599 GetFuncMem(0)[funcidx].newval = newval;
00600 if (newstate == 1)
00601 GetFuncMem(0)[funcidx].held = true;
00602 else
00603 GetFuncMem(0)[funcidx].held = false;
00604 GetFuncMem(0)[funcidx].active = true;
00605
00606
00607 }
00608 }
00609 else
00610 {
00611 if (NET_DEBUG)
00612 {
00613 cout << "net: AddRecord: wrong state for addrecord or funcmems not created" << endl;
00614 }
00615 }
00616 }
00617
00618 void MULTIPLAY::ProcessPacket(PBUFFER * p)
00619 {
00620 int pos = 0;
00621
00622 Uint8 ptype;
00623
00624 pos = GetFromData(p->data, &ptype, sizeof(Uint8), pos);
00625
00626 if (NET_DEBUG)
00627 cout << "net: ProcessPacket: got packet, size " << p->len << endl;
00628
00629 if (ptype == replay.Get_FuncStateInfo())
00630 {
00631 if (NET_DEBUG)
00632 cout << "net: ProcessPacket: packet type is State Info" << endl;
00633
00634 double ptime;
00635 pos = GetFromData(p->data, &ptime, sizeof(double), pos);
00636
00637 if (NET_DEBUG)
00638 cout << "net: ProcessPacket: packet time is " << ptime << endl;
00639 }
00640 else if (ptype == replay.Get_FuncNetControl())
00641 {
00642 if (NET_DEBUG)
00643 cout << "net: ProcessPacket: packet type is unexpected control sequence" << endl;
00644 }
00645 else
00646 {
00647 if (NET_DEBUG)
00648 cout << "net: ProcessPacket: packet type is unknown" << endl;
00649 }
00650
00651 p->Clear();
00652 }
00653
00654 void MULTIPLAY::SendState()
00655 {
00656
00657
00658 float remain;
00659 int mult;
00660 mult = (int) ((timeindex[0]+FrameTime()/2.0) / STATE_FREQUENCY);
00661 remain = (timeindex[0] + FrameTime()/2.0) - (float)(mult * STATE_FREQUENCY);
00662
00663 if (remain < FrameTime())
00664 {
00665 if (NET_DEBUG)
00666 {
00667 cout << "net: SendState: sending state at time " << GetCurState(0)->time << endl;
00668 cout << "used buffers: " << net.NumBufferedPackets() << endl;
00669 }
00670
00671
00672 curstates[0].fnum = fnums[0];
00673 if (curstates[0].funcmem != NULL)
00674 {
00675 delete [] curstates[0].funcmem;
00676 curstates[0].funcmem = NULL;
00677 }
00678 curstates[0].funcmem = new FUNCTION_MEMORY_SYNC [fnums[0]];
00679 int i;
00680 for (i = 0; i < fnums[0]; i++)
00681 {
00682 curstates[0].funcmem[i].oldval = GetFuncMem(0)[i].oldval;
00683 curstates[0].funcmem[i].newval = GetFuncMem(0)[i].newval;
00684 curstates[0].funcmem[i].held = GetFuncMem(0)[i].held;
00685 curstates[0].funcmem[i].active = GetFuncMem(0)[i].active;
00686 curstates[0].funcmem[i].lastupdateat = GetFuncMem(0)[i].lastupdateat;
00687 }
00688
00689
00690
00691 Uint8 tp[MAX_PACKET_SIZE];
00692 int tplen = 0;
00693 Uint8 tempchar;
00694 tempchar = replay.Get_FuncStateInfo();
00695 tplen = AddToData(tp, &tempchar, sizeof(Uint8), tplen);
00696 tplen = AddToData(tp, &GetCurState(0)->time, sizeof(double), tplen);
00697
00698 tplen = WriteVector(GetCurState(0)->chassispos, tp, tplen);
00699 tplen = WriteMatrix(GetCurState(0)->chassisorientation, tp, tplen);
00700 tplen = WriteVector(GetCurState(0)->chassisvel, tp, tplen);
00701 tplen = WriteVector(GetCurState(0)->chassisangvel, tp, tplen);
00702
00703 for (i = 0; i < 4; i++)
00704 {
00705 tplen = AddToData(tp, &GetCurState(0)->suspdisp[i], sizeof(double), tplen);
00706 tplen = AddToData(tp, &GetCurState(0)->suspcompvel[i], sizeof(double), tplen);
00707 tplen = WriteVector(GetCurState(0)->whlangvel[i], tp, tplen);
00708 tplen = AddToData(tp, &GetCurState(0)->tirespeed[i], sizeof(double), tplen);
00709 }
00710
00711 tplen = AddToData(tp, &GetCurState(0)->gear, sizeof(int), tplen);
00712 tplen = AddToData(tp, &GetCurState(0)->enginespeed, sizeof(double), tplen);
00713 tplen = AddToData(tp, &GetCurState(0)->clutchspeed, sizeof(double), tplen);
00714 tplen = AddToData(tp, &GetCurState(0)->enginedrag, sizeof(double), tplen);
00715
00716 tplen = AddToData(tp, &GetCurState(0)->segment, sizeof(int), tplen);
00717
00718
00719 tplen = AddToData(tp, &(fnums[0]), sizeof(int), tplen);
00720
00721 for (i = 0; i < fnums[0]; i++)
00722 {
00723
00724 tplen = AddToData(tp, &(GetCurState(0)->funcmem[i]), sizeof(struct FUNCTION_MEMORY_SYNC), tplen);
00725 }
00726
00727 net.Send(tp, tplen);
00728
00729 if (MP_RECORD && !MP_REMOTE_RECORD)
00730 {
00731 dbgstate[dbgnumstates].CopyFrom(curstates[0]);
00732 dbgnumstates++;
00733 }
00734 }
00735
00736 }
00737
00738 int MULTIPLAY::WriteVector(Vamos_Geometry::Three_Vector wv, Uint8 * dest, int start)
00739 {
00740
00741
00742 int len = start;
00743
00744 len = AddToData(dest, &wv[0], sizeof(double), len);
00745 len = AddToData(dest, &wv[1], sizeof(double), len);
00746 len = AddToData(dest, &wv[2], sizeof(double), len);
00747
00748 return len;
00749 }
00750
00751 int MULTIPLAY::WriteMatrix(Vamos_Geometry::Three_Matrix wv, Uint8 * dest, int start)
00752 {
00753 int len = start;
00754
00755
00756
00757
00758 len = AddToData(dest, &wv[0][0], sizeof(double), len);
00759 len = AddToData(dest, &wv[0][1], sizeof(double), len);
00760 len = AddToData(dest, &wv[0][2], sizeof(double), len);
00761
00762 len = AddToData(dest, &wv[1][0], sizeof(double), len);
00763 len = AddToData(dest, &wv[1][1], sizeof(double), len);
00764 len = AddToData(dest, &wv[1][2], sizeof(double), len);
00765
00766 len = AddToData(dest, &wv[2][0], sizeof(double), len);
00767 len = AddToData(dest, &wv[2][1], sizeof(double), len);
00768 len = AddToData(dest, &wv[2][2], sizeof(double), len);
00769
00770 return len;
00771 }
00772
00773 void MULTIPLAY::ReadState(Uint8 * s, int slot)
00774 {
00775
00776
00777
00778 loadstates[slot].fnum = fnums[slot];
00779 if (loadstates[slot].funcmem != NULL)
00780 {
00781 delete [] loadstates[slot].funcmem;
00782 loadstates[slot].funcmem = NULL;
00783 }
00784
00785
00786 int len = 0;
00787 Uint8 tempchar;
00788 len = GetFromData(s, &tempchar, sizeof(Uint8), len);
00789 if (tempchar != replay.Get_FuncStateInfo())
00790 {
00791 if (NET_DEBUG)
00792 cout << "net: ReadState: packet is not a state" << endl;
00793 return;
00794 }
00795
00796 len = GetFromData(s, &loadstates[slot].time, sizeof(double), len);
00797
00798
00799 len = ReadVector(loadstates[slot].chassispos, s, len);
00800 len = ReadMatrix(loadstates[slot].chassisorientation, s, len);
00801 len = ReadVector(loadstates[slot].chassisvel, s, len);
00802 len = ReadVector(loadstates[slot].chassisangvel, s, len);
00803
00804 int i;
00805 for (i = 0; i < 4; i++)
00806 {
00807 len = GetFromData(s, &loadstates[slot].suspdisp[i], sizeof(double), len);
00808 len = GetFromData(s, &loadstates[slot].suspcompvel[i], sizeof(double), len);
00809 len = ReadVector(loadstates[slot].whlangvel[i], s, len);
00810 len = GetFromData(s, &loadstates[slot].tirespeed[i], sizeof(double), len);
00811 }
00812
00813 len = GetFromData(s, &loadstates[slot].gear, sizeof(int), len);
00814 len = GetFromData(s, &loadstates[slot].enginespeed, sizeof(double), len);
00815 len = GetFromData(s, &loadstates[slot].clutchspeed, sizeof(double), len);
00816 len = GetFromData(s, &loadstates[slot].enginedrag, sizeof(double), len);
00817
00818 len = GetFromData(s, &loadstates[slot].segment, sizeof(int), len);
00819
00820
00821 len = GetFromData(s, &(fnums[slot]), sizeof(int), len);
00822 loadstates[slot].funcmem = new FUNCTION_MEMORY_SYNC [fnums[slot]];
00823
00824 if (MP_DEBUG)
00825 cout << "net: ReadState: " << fnums[slot] << " functions, active: ";
00826
00827 for (i = 0; i < fnums[slot]; i++)
00828 {
00829
00830
00831 len = GetFromData(s, &loadstates[slot].funcmem[i], sizeof(struct FUNCTION_MEMORY_SYNC), len);
00832
00833 if (MP_DEBUG && loadstates[slot].funcmem[i].active)
00834 cout << GetFuncMem(slot)[i].func_name << "(" << i << ") ";
00835 }
00836
00837 if (MP_DEBUG)
00838 cout << endl;
00839 }
00840
00841 int MULTIPLAY::ReadVector(Vamos_Geometry::Three_Vector &wv, Uint8 * source, int start)
00842 {
00843
00844
00845 int len = start;
00846
00847 len = GetFromData(source, &wv[0], sizeof(double), len);
00848 len = GetFromData(source, &wv[1], sizeof(double), len);
00849 len = GetFromData(source, &wv[2], sizeof(double), len);
00850
00851 return len;
00852 }
00853
00854 int MULTIPLAY::ReadMatrix(Vamos_Geometry::Three_Matrix &wv, Uint8 * source, int start)
00855 {
00856 int len = start;
00857
00858
00859
00860
00861 len = GetFromData(source, &wv[0][0], sizeof(double), len);
00862 len = GetFromData(source, &wv[0][1], sizeof(double), len);
00863 len = GetFromData(source, &wv[0][2], sizeof(double), len);
00864
00865 len = GetFromData(source, &wv[1][0], sizeof(double), len);
00866 len = GetFromData(source, &wv[1][1], sizeof(double), len);
00867 len = GetFromData(source, &wv[1][2], sizeof(double), len);
00868
00869 len = GetFromData(source, &wv[2][0], sizeof(double), len);
00870 len = GetFromData(source, &wv[2][1], sizeof(double), len);
00871 len = GetFromData(source, &wv[2][2], sizeof(double), len);
00872 return len;
00873 }
00874
00875 void MULTIPLAY::Send(double inc)
00876 {
00877 if (MP_DBGDEEP)
00878 cout << "multiplay send start" << endl;
00879
00880
00881 if (Connected() && !MP_DISABLESEND)
00882 {
00883 if (!in_menu)
00884 {
00885 SendState();
00886
00887 QueuePacket();
00888 SendPacketArray();
00889 }
00890 }
00891
00892 if (!in_menu)
00893 {
00894 timeindex[0] += inc;
00895 }
00896
00897 if (MP_DBGDEEP)
00898 cout << "multiplay send done" << endl;
00899 }
00900
00901 void MULTIPLAY::ReceiveState()
00902 {
00903
00904 int i;
00905 float remain;
00906 int mult;
00907 mult = (int) ((timeindex[1]+FrameTime()/2.0) / STATE_FREQUENCY);
00908 remain = (timeindex[1] + FrameTime()/2.0) - (float)(mult * STATE_FREQUENCY);
00909
00910
00911
00912 bool found = false;
00913
00914 if (remain < FrameTime())
00915 {
00916
00917
00918 int count = 0;
00919 for (i = 0; i < net.GetMaxBuffers(); i++)
00920 {
00921 if (net.GetBuffer(i)->Valid())
00922 {
00923
00924 Uint8 ptype;
00925 GetFromData(net.GetBuffer(i)->data, &ptype, sizeof(Uint8), 0);
00926 double ptime;
00927 GetFromData(net.GetBuffer(i)->data, &ptime, sizeof(double), 1);
00928 if (ptype == replay.Get_FuncStateInfo())
00929 {
00930
00931 if (ptime < timeindex[1] - STATE_FREQUENCY)
00932 {
00933 net.GetBuffer(i)->Clear();
00934
00935 if (NET_DEBUG)
00936 cout << "net: Update: cleaned out old state packet with time " << ptime << endl;
00937 }
00938
00939 if (ptime > timeindex[1] - FrameTime()/2.0 && ptime < timeindex[1] + FrameTime()/2.0)
00940 {
00941
00942 net.GetBuffer(i)->Clear();
00943
00944 if (NET_DEBUG)
00945 cout << "net: Update: received state with time " << ptime << endl;
00946
00947 loadstates[1].time = ptime;
00948
00949
00950 ReadState(net.GetBuffer(i)->data, 1);
00951 loadstatenow[1] = true;
00952
00953
00954 for (i = 0; i < fnums[1]; i++)
00955 {
00956 GetFuncMem(1)[i].oldval = loadstates[1].funcmem[i].oldval;
00957 GetFuncMem(1)[i].newval = loadstates[1].funcmem[i].newval;
00958 GetFuncMem(1)[i].held = loadstates[1].funcmem[i].held;
00959 GetFuncMem(1)[i].active = loadstates[1].funcmem[i].active;
00960 GetFuncMem(1)[i].lastupdateat = loadstates[1].funcmem[i].lastupdateat;
00961 }
00962
00963 if (MP_RECORD && MP_REMOTE_RECORD)
00964 {
00965 dbgstate[dbgnumstates].CopyFrom(loadstates[1]);
00966 dbgnumstates++;
00967 }
00968
00969 found = true;
00970 }
00971 else
00972 {
00973
00974
00975
00976 count++;
00977 }
00978 }
00979
00980 }
00981 }
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005 int scount = 0;
01006 double highesttime = 0;
01007 for (i = 0; i < net.GetMaxBuffers(); i++)
01008 {
01009 if (net.GetBuffer(i)->Valid())
01010 {
01011
01012 Uint8 ptype;
01013 GetFromData(net.GetBuffer(i)->data, &ptype, sizeof(Uint8), 0);
01014 double ptime;
01015 GetFromData(net.GetBuffer(i)->data, &ptime, sizeof(double), 1);
01016 if (ptype == replay.Get_FuncStateInfo())
01017 {
01018 scount++;
01019
01020 if (ptime > highesttime)
01021 highesttime = ptime;
01022 }
01023 }
01024 }
01025
01026 if (!found && scount >= STATE_TIMEOUT_COUNT)
01027 {
01028 double newt;
01029
01030 newt = (double)((mult+1) * STATE_FREQUENCY);
01031
01032
01033 if (NET_DEBUG)
01034 {
01035 cout << "net: Update: timeout waiting for state at time " << timeindex[1] << " skipping to " << newt << endl;
01036 }
01037
01038
01039 timeindex[1] = newt;
01040 }
01041 }
01042 }
01043
01044 void MULTIPLAY::QueuePacket()
01045 {
01046 int i;
01047 for (i = 0; i < fnums[0]; i++)
01048 {
01049
01050 if (GetFuncMem(0)[i].active && (!GetFuncMem(0)[i].held || (GetFuncMem(0)[i].held && GetFuncMem(0)[i].oldval != GetFuncMem(0)[i].newval)))
01051 {
01052 GetPacketArray(0)[numpackets[0]].time = timeindex[0];
01053 GetPacketArray(0)[numpackets[0]].val = GetFuncMem(0)[i].newval;
01054 GetPacketArray(0)[numpackets[0]].chardata[CHAR_FUNCNUM] = i;
01055
01056 int newstate = 0;
01057 if (GetFuncMem(0)[i].held)
01058 newstate = 1;
01059 GetPacketArray(0)[numpackets[0]].chardata[CHAR_STATE] = newstate;
01060
01061 numpackets[0]++;
01062
01063