Index: lib/netplay/nettypes.c =================================================================== --- lib/netplay/nettypes.c (revision 3983) +++ lib/netplay/nettypes.c (working copy) @@ -34,7 +34,13 @@ #include "nettypes.h" static PACKETDIR NetDir; +static uint16_t PACKETSIZE; //max size is 8K +uint16_t NetGetPacketSize( ) +{ + return PACKETSIZE; +} + static void NETsetPacketDir(PACKETDIR dir) { NetDir = dir; @@ -53,7 +59,7 @@ { NETsetPacketDir(PACKET_ENCODE); NetMsg.type = type; - NetMsg.size = 0; + NetMsg.size = PACKETSIZE = 0; NetMsg.status = TRUE; NetMsg.destination = player; memset(&NetMsg.body, '\0', MaxMsgSize); @@ -82,7 +88,7 @@ { return FALSE; } - + PACKETSIZE = NetMsg.size; // We have sent the packet, so make it invalid (to prevent re-sending) NETsetPacketDir(PACKET_INVALID); Index: lib/netplay/nettypes.h =================================================================== --- lib/netplay/nettypes.h (revision 3983) +++ lib/netplay/nettypes.h (working copy) @@ -34,7 +34,7 @@ PACKET_DECODE, PACKET_INVALID } PACKETDIR; - +uint16_t NetGetPacketSize( void ); void NETbeginEncode(uint8_t type, uint8_t player); void NETbeginDecode(uint8_t type); BOOL NETend(void); Index: src/multisync.c =================================================================== --- src/multisync.c (revision 3983) +++ src/multisync.c (working copy) @@ -56,8 +56,8 @@ static BOOL sendStructureCheck (void); //Structure static void packageCheck (DROID *pD); -static BOOL sendDroidCheck (void); //droids - +static BOOL sendDroidPacket(uint16_t droidcount, uint8_t player); //droids +static uint16_t HandleDroids( void ); static void highLevelDroidUpdate(DROID *psDroid, UDWORD x, UDWORD y, @@ -67,52 +67,36 @@ float experience); -static void onscreenUpdate (DROID *pDroid,UDWORD dam, // the droid and its damage - UDWORD x, UDWORD y, // the ideal position - float fx,float fy, // the ideal fractional position +static void offscreenUpdate (DROID *pDroid,UDWORD dam, // the droid and its damage + UDWORD x, UDWORD y, // the ideal position + float fx,float fy, // the ideal fractional position UWORD dir, // direction it should facing - DROID_ORDER order); // what it should be doing + DROID_ORDER order); // what it should be doing -static void offscreenUpdate (DROID *pDroid,UDWORD dam, - UDWORD x, UDWORD y, - float fx,float fy, - UWORD dir, - DROID_ORDER order); - static BOOL sendPowerCheck(void); static UDWORD averagePing(void); // //////////////////////////////////////////////////////////////////////////// // Defined numeric values -#define AV_PING_FREQUENCY 45000 // how often to update average pingtimes. in approx millisecs. -#define PING_FREQUENCY 12000 // how often to update pingtimes. in approx millisecs. -#define STRUCT_FREQUENCY 700 // how often (ms) to send a structure check. -#define DROID_FREQUENCY 1000 // how ofter (ms) to send droid checks -#define POWER_FREQUENCY 10000 // how often to send power levels -#define SCORE_FREQUENCY 25000 // how often to update global score. +#define AV_PING_FREQUENCY 4500 // how often to update average pingtimes. in approx millisecs. +#define PING_FREQUENCY 1200 // how often to update pingtimes. in approx millisecs. +#define STRUCT_FREQUENCY 59 // how often (ms) to send a structure check. +#define DROID_FREQUENCY 59 // how ofter (ms) to send droid checks +#define POWER_FREQUENCY 59 // how often to send power levels +#define SCORE_FREQUENCY 2500 // how often to update global score. #define SYNC_PANIC 40000 // maximum time before doing a dirty fix. static UDWORD PingSend[MAX_PLAYERS]; //stores the time the ping was called. - +#define MAX_UNITS 300 // see structure.c 2761 300 is max you can make. + // magic # will vanish next patch // //////////////////////////////////////////////////////////////////////////// -// test traffic level. -static BOOL okToSend(void) -{ - //update checks & go no further if any exceeded. - if (NETgetRecentBytesSent() + NETgetRecentBytesRecvd() >= MAX_BYTESPERSEC) - { - return FALSE; - } - - return TRUE; -} - // //////////////////////////////////////////////////////////////////////////// // Droid checking info. keep position and damage in sync. BOOL sendCheck(void) { - UDWORD i; + UDWORD i = 0; + uint16_t totaldroids = 0; NETgetBytesSent(); // update stats. NETgetBytesRecvd(); @@ -128,135 +112,92 @@ } } - sendPing(); + sendPing(); // + debug(LOG_ERROR,"sendPing packet sent size is %u",NetGetPacketSize()); + totaldroids = HandleDroids(); // send droid orders + debug(LOG_ERROR,"HandleDroids[%u] packet sent size is %u",totaldroids,NetGetPacketSize()); +// if (sendStructureCheck() ) // send structure damage +// debug(LOG_ERROR,"sendStructureCheck packet sent size is %u",NetGetPacketSize()); + if ( sendPowerCheck() ) // send power levels + debug(LOG_ERROR,"sendPowerCheck packet sent size is %u",NetGetPacketSize()); + if ( sendScoreCheck() ) // send score + debug(LOG_ERROR,"sendScoreCheck packet sent size is %u",NetGetPacketSize()); - // send Checks. note each send has it's own send criteria, so might not send anything. - - if(okToSend()) - { - sendStructureCheck(); - } - if(okToSend()) - { - sendPowerCheck(); - } - if(okToSend()) - { - sendScoreCheck(); - } - if(okToSend()) - { - sendDroidCheck(); - } return TRUE; } -// //////////////////////////////////////////////////////////////////////////// -// pick a droid to send, NULL otherwise. -static DROID* pickADroid(void) +//////////////////////////////////////////////////////////// +static uint16_t HandleDroids( void ) { - DROID* pD = NULL; // current droid we're checking - unsigned int i; - static UDWORD droidnum=0; // how far down the playerlist to go. - static UDWORD player=0; // current player we're checking - static UDWORD maxtrys=0; + uint8_t player = 0; + uint16_t droidcount = 0, totaldroids = 0; + DROID* playerDroid = NULL; // current droid we're checking + static UDWORD lastsent = 0; // Last time a struct was sent. - // Don't send stuff that isn't our problem - while (!myResponsibility(player)) + if (lastsent > gameTime) { - ++player; - player = player % MAX_PLAYERS; - droidnum = 0; - - // Bail out if we've tried for each available player already - if (++maxtrys >= MAX_PLAYERS) - { - maxtrys = 0; - return NULL; - } + lastsent= 0; } - - // Find the 'droidnum'th droid for the current player - pD = apsDroidLists[player]; - for (i = 0; i < droidnum && pD != NULL; ++i) + + if (gameTime - lastsent < DROID_FREQUENCY) { - pD = pD->psNext; + return TRUE; } + + lastsent = gameTime; - // If we've already dealt with the last droid for this player - if (pD == NULL) // droid is no longer there or list end. - { - // Deal with the next player now - ++player; - player = player % MAX_PLAYERS; - droidnum = 0; - // Bail out if we've tried for each available player already - if (maxtrys >= MAX_PLAYERS) + + // HOST takes care of self, and all AI players, + // client only has to deal with self. + // We need to count how many droids we need to send for each + // player we control/are in charge of. + for( player=0; player < MAX_PLAYERS; player++) + { + if( !myResponsibility(player)) continue; // Not our Responsibility, so skip them. + playerDroid = apsDroidLists[player]; + droidcount = 0; + while (playerDroid != NULL) { - maxtrys = 0; - return NULL; + playerDroid = playerDroid->psNext; + droidcount++; } - - // Invoke ourselves to pick a droid from the next player - return pickADroid(); + // Process all the droids for each player we control + if(droidcount) + { + sendDroidPacket(droidcount, player); //process + totaldroids += droidcount; + } } - - ++droidnum; - maxtrys = 0; - - return pD; + return totaldroids; //how many droids we processed. } - // /////////////////////////////////////////////////////////////////////////// // send a droid info packet. -static BOOL sendDroidCheck(void) +static BOOL sendDroidPacket(uint16_t droidcount, uint8_t player) { - DROID *pD, **ppD; - uint8_t i, count; + DROID *pD = NULL; + uint16_t count = 0; static UDWORD lastSent = 0; // Last time a struct was sent. - UDWORD toSend = 6; - if (lastSent > gameTime) - { - lastSent= 0; - } - - // Only send a struct send if not done recently. - if (gameTime - lastSent < DROID_FREQUENCY) - { - return TRUE; - } + // we *always* want to send droid orders. We do not have heuristics. :P debug(LOG_MULTISYNC, "sendDroidCheck at tick %u", (unsigned int)gameTime); - lastSent = gameTime; + lastSent = gameTime; // perhaps useful for debugging - NETbeginEncode(NET_CHECK_DROID, NET_ALL_PLAYERS); + count = droidcount; + pD = apsDroidLists[player]; - // Allocate space for the list of droids to send - ppD = alloca(sizeof(DROID *) * toSend); + NETbeginEncode(NET_CHECK_DROID, NET_ALL_PLAYERS); + // Send the number of droids to expect + NETuint16_t(&count); - // Get the list of droids to sent - for (i = 0, count = 0; i < toSend; i++) - { - pD = pickADroid(); - - // If the droid is valid add it to the list - if (pD) - { - ppD[count++] = pD; - } - } - - // Send the number of droids to expect - NETuint8_t(&count); - - // Add the droids to the packet - for (i = 0; i < count; i++) - { - packageCheck(ppD[i]); - } + // Add the droids to the packet + while( pD != NULL ) + { + packageCheck(pD); // function name isn't very descriptive. + pD = pD->psNext; + } return NETend(); } @@ -319,7 +260,7 @@ // receive a check and update the local world state accordingly BOOL recvDroidCheck() { - uint8_t count; + uint16_t count; int i; debug(LOG_MULTISYNC, "recvDroidCheck"); @@ -327,7 +268,7 @@ NETbeginDecode(NET_CHECK_DROID); // Get the number of droids to expect - NETuint8_t(&count); + NETuint16_t(&count); for (i = 0; i < count; i++) { @@ -413,27 +354,9 @@ * and the player who owns the droid has a low ping then do an * onscreen update, otherwise do an offscreen one. */ - if (DrawnInLastFrame(pD->sDisplay.frameNumber) - && pD->sDisplay.screenX < pie_GetVideoBufferWidth() - && pD->sDisplay.screenY < pie_GetVideoBufferHeight() - && ingame.PingTimes[player] < PING_LIMIT) - { - onscreen = TRUE; - } - else - { - onscreen = FALSE; - } - // Update the droid - if (onscreen || vtolDroid(pD)) - { - onscreenUpdate(pD, body, x, y, fx, fy, direction, order); - } - else - { - offscreenUpdate(pD, body, x, y, fx, fy, direction, order); - } + offscreenUpdate(pD, body, x, y, fx, fy, direction, order); + debug(LOG_MULTISYNC, "difference in position for droid %u; was (%d, %d); did %s update", (unsigned int)pD->id, (int)x - pD->pos.x, (int)y - pD->pos.y, @@ -498,45 +421,7 @@ } } } - // //////////////////////////////////////////////////////////////////////////// -// droid on screen needs modifying -static void onscreenUpdate(DROID *psDroid, - UDWORD dam, - UDWORD x, - UDWORD y, - float fx, - float fy, - UWORD dir, - DROID_ORDER order) -{ - - BASE_OBJECT *psClickedOn; - BOOL bMouseOver = FALSE; - - psClickedOn = mouseTarget(); - if( psClickedOn != NULL && psClickedOn->type == OBJ_DROID) - { - if(psClickedOn->id == psDroid->id && mouseDown(MOUSE_RMB)) - { - bMouseOver = TRUE; // override, so you dont see the updates. - } - } - - if(!bMouseOver) - { - psDroid->body = dam; // update damage - } - -// if(psDroid->order == DORDER_NONE || (psDroid->order == DORDER_GUARD && psDroid->action == DACTION_NONE) ) -// { -// psDroid->direction = dir %360; //update rotation -// } - - return; -} - -// //////////////////////////////////////////////////////////////////////////// // droid offscreen needs modyfying. static void offscreenUpdate(DROID *psDroid, UDWORD dam, @@ -908,7 +793,6 @@ return TRUE; } - // //////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////// // Power Checking. Send a power level check every now and again.