void SendFrameData(int connectionID)
        {
            ConnectionResponse responseToSend = responses[connectionID].Peek();
            // Use up to 190 bytes from the response
            MIDIFrame mf = new MIDIFrame();

            // nullref here due to response queue being emptied on other thread
            mf.AddHeader2(responseToSend.connectionID, responseToSend.data[responseToSend.bytesSent++], flipFlop);
            totalBytesCount--;
            flipFlop = !flipFlop;

            // Add up to 199 bytes from the active response to an array of data to send
            byte[] bytesToAdd      = new byte[199];
            int    bytesLeftToSend = responseToSend.data.Length - responseToSend.bytesSent;
            int    bytesToAddCount = Math.Min(bytesLeftToSend, 199); // In case there's less than 199 bytes left to send

            Array.Copy(responseToSend.data, responseToSend.bytesSent, bytesToAdd, 0, bytesToAddCount);
            mf.Add199Bytes(bytesToAdd);
            responseToSend.bytesSent += bytesToAddCount;
            totalBytesCount          -= bytesToAddCount;

            // Remove response if all bytes have been sent
            if (responseToSend.bytesSent == responseToSend.data.Length)
            {
                responses[connectionID].Dequeue();
                responsesCount--;
            }

            mf.Send(port);
            GameIsReady = false;
            lastFrame   = mf;
        }
        public void SendFrameIfDataAvailable(bool ACK)
        {
            // If RDY was received when an ACK was expected, it means the frame was dropped
            // and needs to be retransmitted.  Otherwise, mark the last frame as received.
            if (lastFrame != null)
            {
                if (ACK)
                {
                    lastFrame = null;
                }
                else
                {
                    lastFrame.Send(port);
                    GameIsReady = false;
                    return;
                }
            }

            // Send priority ping response if available, or a frame if a connection response is ready
            if (pong != null)
            {
                ConnectionResponse responseToSend = pong;
                MIDIFrame          mf             = new MIDIFrame();
                mf.AddHeader2(responseToSend.connectionID, responseToSend.data[responseToSend.bytesSent++], flipFlop);
                flipFlop = !flipFlop;
                // Add up to 199 bytes from the active response to an array of data to send
                byte[] bytesToAdd      = new byte[199];
                int    bytesLeftToSend = responseToSend.data.Length - responseToSend.bytesSent;
                int    bytesToAddCount = Math.Min(bytesLeftToSend, 199); // In case there's less than 199 bytes left to send
                Array.Copy(responseToSend.data, responseToSend.bytesSent, bytesToAdd, 0, bytesToAddCount);
                mf.Add199Bytes(bytesToAdd);
                pong = null;
                mf.Send(port);
                GameIsReady = false;
                lastFrame   = mf;
            }
            else if (responses[255].Count > 0)
            {
                // Prioritize the loopback connection second
                SendFrameData(255);
            }
            else if (responsesCount > 0)
            {
                // Round robin the rest of the responses
                do
                {
                    connectionIndex++;
                    if (connectionIndex == MAX_USABLE_CONNECTIONS)
                    {
                        connectionIndex = 0;
                    }
                }while (responses[connectionIndex].Count == 0);

                SendFrameData(connectionIndex);
            }
        }
 public void Reset()
 {
     GameIsReady     = true;
     responsesCount  = 0;
     totalBytesCount = 0;
     connectionIndex = 0;
     lastFrame       = null;
     flipFlop        = false;
     for (int i = 0; i < responses.Length; i++)
     {
         responses[i] = new Queue <ConnectionResponse>();
     }
 }