mJoinedSessionDelegate = callback;\r
NetworkSession.BeginCreate(NetworkSessionType.SystemLink, 1, maxGamers, CreateSessionEnd, null);\r
}\r
- private void CreateSessionEnd(IAsyncResult result)\r
+ void CreateSessionEnd(IAsyncResult result)\r
{\r
Debug.Assert(mNetworkSession == null);\r
\r
mNetworkSession = NetworkSession.EndCreate(result);\r
mNetworkSession.AllowHostMigration = true;\r
mNetworkSession.AllowJoinInProgress = false;\r
- mNetworkSession.GameStarted += new EventHandler<GameStartedEventArgs>(mNetworkSession_GameStarted);\r
+ mNetworkSession.GameStarted += new EventHandler<GameStartedEventArgs>(GameStartedEvent);\r
}\r
catch (Exception e)\r
{\r
mJoinedSessionDelegate(mNetworkSession, this);\r
mJoinedSessionDelegate = null;\r
}\r
-\r
-\r
- //gamestarted event\r
- void mNetworkSession_GameStarted(object sender, GameStartedEventArgs e)\r
+ void GameStartedEvent(object sender, GameStartedEventArgs e)\r
{\r
Reset();\r
}\r
mFoundSessionsDelegate = callback;\r
NetworkSession.BeginFind(NetworkSessionType.SystemLink, 1, null, new AsyncCallback(FindSessionsEnd), null);\r
}\r
- private void FindSessionsEnd(IAsyncResult result)\r
+ void FindSessionsEnd(IAsyncResult result)\r
{\r
AvailableNetworkSessionCollection sessions;\r
try\r
mJoinedSessionDelegate = callback;\r
NetworkSession.BeginJoin(availableSession, JoinSessionEnd, null);\r
}\r
- private void JoinSessionEnd(IAsyncResult result)\r
+ void JoinSessionEnd(IAsyncResult result)\r
{\r
Debug.Assert(mNetworkSession == null);\r
\r
try\r
{\r
mNetworkSession = NetworkSession.EndJoin(result);\r
- mNetworkSession.GameStarted += new EventHandler<GameStartedEventArgs>(mNetworkSession_GameStarted);\r
+ mNetworkSession.GameStarted += new EventHandler<GameStartedEventArgs>(GameStartedEvent);\r
}\r
catch (Exception e)\r
{\r
{\r
mNetworkSession.StartGame();\r
mNetworkSession.ResetReady();\r
-\r
- //Reset();\r
}\r
\r
\r
if (IsLatencyAdjustmentFrame)\r
{\r
AdjustLatency();\r
+ mLastStallCount = mStallCount;\r
mStallCount = 0;\r
}\r
mLocalEvents.AddRange(GetEventsFromInput());\r
}\r
else // Stall!\r
{\r
+ if (mStallCount == 0)\r
+ {\r
+ Console.WriteLine("===== STALL =====");\r
+ }\r
+ else if (mStallCount % 60 == 0)\r
+ {\r
+ Console.WriteLine("Stalled for " + mStallCount + " frames.");\r
+ }\r
+\r
mStallCount++;\r
\r
- if (mStallCount % 60 == 0)\r
+ // Send a reliable event packet to each stalled gamer.\r
+ if (mStallCount == 1)\r
{\r
- Console.WriteLine("Stalled for " + mStallCount + " frames.");\r
+ foreach (GamerInfo gamerInfo in GamerArray)\r
+ {\r
+ if (gamerInfo.HighestFrameNumber < mGame.CurrentFrameNumber)\r
+ {\r
+ SendLocalEvents(gamerInfo.Gamer);\r
+ }\r
+ }\r
}\r
\r
/*if (mStallCount > StallTimeout)\r
int mLastMousePositionY;\r
\r
int mLatency;\r
+ long mHighestFrameNumber;\r
long mNextLatencyAdjustmentFrame;\r
int mStallCount;\r
+ int mLastStallCount;\r
int mAverageOwd;\r
\r
+ // DEBUG\r
+ bool mDontSendEvents;\r
+\r
TimeSpan mTargetTimeSpan = new TimeSpan(166666);\r
public TimeSpan TargetTimeSpan\r
{\r
class GamerInfo\r
{\r
public NetworkGamer Gamer;\r
- public long HighestFrameNumber = 0;\r
+ public long HighestFrameNumber = -1;\r
public int StallCount = 0;\r
public int AverageOwd = 0;\r
+ public int NextStallCount = 0;\r
+ public int NextAverageOwd = 0;\r
public bool IsWaitedOn = false;\r
public List<EventInfo>[] Events = new List<EventInfo>[MaximumLatency];\r
\r
void Reset()\r
{\r
mLatency = 1;\r
+ mHighestFrameNumber = -1;\r
mNextLatencyAdjustmentFrame = 1;\r
mStallCount = 0;\r
+ mLastStallCount = 0;\r
mAverageOwd = CurrentAverageOneWayDelay;\r
\r
mGamers = new Dictionary<byte, GamerInfo>();\r
\r
case PacketType.Event:\r
\r
- short stallCount = mPacketReader.ReadInt16();\r
- short averageOwd = mPacketReader.ReadInt16();\r
+ int stallCount = mPacketReader.ReadInt16();\r
+ int averageOwd = mPacketReader.ReadInt16();\r
int frameNumber = mPacketReader.ReadInt32();\r
- byte numEvents = mPacketReader.ReadByte();\r
+ int numEvents = mPacketReader.ReadByte();\r
\r
if (frameNumber <= senderInfo.HighestFrameNumber)\r
{\r
break;\r
}\r
\r
- for (byte i = 0; i < numEvents; ++i)\r
+ for (int i = 0; i < numEvents; i++)\r
{\r
EventInfo eventInfo = ReadEvent(mPacketReader, sender);\r
\r
- if (eventInfo != null && eventInfo.FrameOfApplication < senderInfo.HighestFrameNumber)\r
+ if (eventInfo != null && eventInfo.FrameOfApplication > senderInfo.HighestFrameNumber)\r
{\r
- int index = EventArrayIndex;\r
+ int index = GetEventArrayIndexForFrame(eventInfo.FrameOfApplication);\r
if (senderInfo.Events[index] == null) senderInfo.Events[index] = new List<EventInfo>();\r
senderInfo.Events[index].Add(eventInfo);\r
}\r
}\r
\r
- senderInfo.StallCount = stallCount;\r
- senderInfo.AverageOwd = averageOwd;\r
+ if (frameNumber <= mNextLatencyAdjustmentFrame)\r
+ {\r
+ senderInfo.StallCount = stallCount;\r
+ senderInfo.AverageOwd = averageOwd;\r
+ }\r
+ else\r
+ {\r
+ senderInfo.NextStallCount = stallCount;\r
+ senderInfo.NextAverageOwd = averageOwd;\r
+ }\r
senderInfo.HighestFrameNumber = frameNumber;\r
break;\r
\r
byte[] stalledPeers = mPacketReader.ReadBytes(numStalledPeers);\r
\r
// TODO\r
-\r
break;\r
\r
default:\r
}\r
\r
\r
- int EventArrayIndex\r
+ int CurrentEventArrayIndex\r
+ {\r
+ get { return GetEventArrayIndexForFrame(mGame.CurrentFrameNumber); }\r
+ }\r
+\r
+ int GetEventArrayIndexForFrame(long frame)\r
{\r
- get { return (int)(mGame.CurrentFrameNumber % MaximumLatency); }\r
+ return (int)(frame % MaximumLatency);\r
}\r
\r
EventInfo ReadEvent(PacketReader packetReader, NetworkGamer sender)\r
{\r
case EventType.KeyDown:\r
\r
- int keyCode1 = packetReader.ReadInt32();\r
- return new KeyboardEventInfo(sender, frameNumber, (Keys)keyCode1, true);\r
+ Keys keyCode1 = (Keys)packetReader.ReadInt32();\r
+ return new KeyboardEventInfo(sender, frameNumber, keyCode1, true);\r
\r
case EventType.KeyUp:\r
\r
- int keyCode2 = packetReader.ReadInt32();\r
- return new KeyboardEventInfo(sender, frameNumber, (Keys)keyCode2, false);\r
+ Keys keyCode2 = (Keys)packetReader.ReadInt32();\r
+ return new KeyboardEventInfo(sender, frameNumber, keyCode2, false);\r
\r
case EventType.MouseDown:\r
\r
- byte buttonId1 = packetReader.ReadByte();\r
- return new MouseButtonEventInfo(sender, frameNumber, (MouseButton)buttonId1, true);\r
+ MouseButton buttonId1 = (MouseButton)packetReader.ReadByte();\r
+ return new MouseButtonEventInfo(sender, frameNumber, buttonId1, true);\r
\r
case EventType.MouseUp:\r
\r
- byte buttonId2 = packetReader.ReadByte();\r
- return new MouseButtonEventInfo(sender, frameNumber, (MouseButton)buttonId2, false);\r
+ MouseButton buttonId2 = (MouseButton)packetReader.ReadByte();\r
+ return new MouseButtonEventInfo(sender, frameNumber, buttonId2, false);\r
\r
case EventType.MouseMove:\r
\r
void WriteEventPacket(List<EventInfo> events)\r
{\r
mPacketWriter.Write((byte)PacketType.Event);\r
- mPacketWriter.Write((short)mStallCount);\r
+ mPacketWriter.Write((short)mLastStallCount);\r
mPacketWriter.Write((short)mAverageOwd);\r
mPacketWriter.Write((int)(mGame.CurrentFrameNumber + mLatency));\r
mPacketWriter.Write((byte)events.Count);\r
{\r
if (gamerInfo.StallCount > maxStallCount) maxStallCount = gamerInfo.StallCount;\r
if (gamerInfo.AverageOwd > maxAverageOwd) maxAverageOwd = gamerInfo.AverageOwd;\r
+\r
+ gamerInfo.StallCount = gamerInfo.NextStallCount;\r
+ gamerInfo.AverageOwd = gamerInfo.NextAverageOwd;\r
}\r
\r
// DEBUG\r
{\r
List<EventInfo> events = new List<EventInfo>();\r
\r
+ long frameOfApplication = mGame.CurrentFrameNumber + mLatency;\r
+ if (frameOfApplication <= mHighestFrameNumber) return events;\r
+ else mHighestFrameNumber = frameOfApplication;\r
+\r
// 1. Find the keyboard differences; written by Peter.\r
\r
KeyboardState keyState = Keyboard.GetState();\r
\r
foreach (Keys key in pressedKeys)\r
{\r
- events.Add(new KeyboardEventInfo(LocalGamer, mGame.CurrentFrameNumber, key, true));\r
+ events.Add(new KeyboardEventInfo(LocalGamer, frameOfApplication, key, true));\r
}\r
foreach (Keys key in releasedKeys)\r
{\r
- events.Add(new KeyboardEventInfo(LocalGamer, mGame.CurrentFrameNumber, key, false));\r
+ events.Add(new KeyboardEventInfo(LocalGamer, frameOfApplication, key, false));\r
}\r
\r
+ // DEBUG\r
+ if (pressedKeys.Contains(Keys.Escape)) mDontSendEvents = true;\r
+ if (releasedKeys.Contains(Keys.Escape)) mDontSendEvents = false;\r
+\r
// 2. Find the mouse differences.\r
\r
MouseState mouseState = Mouse.GetState();\r
bool leftButtonPressed = mouseState.LeftButton == ButtonState.Pressed;\r
if (leftButtonPressed != mLastLeftButtonPressed)\r
{\r
- events.Add(new MouseButtonEventInfo(LocalGamer, mGame.CurrentFrameNumber, MouseButton.Left, leftButtonPressed));\r
+ events.Add(new MouseButtonEventInfo(LocalGamer, frameOfApplication, MouseButton.Left, leftButtonPressed));\r
}\r
\r
bool rightButtonPressed = mouseState.LeftButton == ButtonState.Pressed;\r
if (rightButtonPressed != mLastRightButtonPressed)\r
{\r
- events.Add(new MouseButtonEventInfo(LocalGamer, mGame.CurrentFrameNumber, MouseButton.Right, rightButtonPressed));\r
+ events.Add(new MouseButtonEventInfo(LocalGamer, frameOfApplication, MouseButton.Right, rightButtonPressed));\r
}\r
\r
bool middleButtonPressed = mouseState.LeftButton == ButtonState.Pressed;\r
if (middleButtonPressed != mLastMiddleButtonPressed)\r
{\r
- events.Add(new MouseButtonEventInfo(LocalGamer, mGame.CurrentFrameNumber, MouseButton.Middle, middleButtonPressed));\r
+ events.Add(new MouseButtonEventInfo(LocalGamer, frameOfApplication, MouseButton.Middle, middleButtonPressed));\r
}\r
\r
int mousePositionX = mouseState.X;\r
int mousePositionY = mouseState.Y;\r
if (mousePositionX != mLastMousePositionX || mousePositionY != mLastMousePositionY)\r
{\r
- events.Add(new MouseMotionEventInfo(LocalGamer, mGame.CurrentFrameNumber, mousePositionX, mousePositionY));\r
+ events.Add(new MouseMotionEventInfo(LocalGamer, frameOfApplication, mousePositionX, mousePositionY));\r
}\r
\r
// 3. Save the current peripheral state.\r
\r
void SendLocalEvents(NetworkGamer recipient)\r
{\r
+ // DEBUG\r
+ if (mDontSendEvents) return;\r
+\r
List<EventInfo> events = new List<EventInfo>(mLocalEvents);\r
events.AddRange(mLastLocalEvents);\r
\r
WriteEventPacket(events);\r
\r
- if (recipient != null)\r
+ if (recipient != null && !recipient.IsDisposed)\r
{\r
LocalGamer.SendData(mPacketWriter, SendDataOptions.Reliable, recipient);\r
}\r
\r
void ApplyEvents()\r
{\r
- int index = EventArrayIndex;\r
+ int index = CurrentEventArrayIndex;\r
\r
foreach (GamerInfo gamerInfo in GamerArray)\r
{\r
KeyboardEventInfo keyboardEventInfo = eventInfo as KeyboardEventInfo;\r
if (keyboardEventInfo != null)\r
{\r
+ Console.WriteLine(keyboardEventInfo.FrameOfApplication + " KEY: " + keyboardEventInfo.Key + "," + keyboardEventInfo.IsKeyDown);\r
mGame.ApplyKeyInput(gamerInfo, keyboardEventInfo.Key, keyboardEventInfo.IsKeyDown);\r
continue;\r
}\r
if (mouseButtonEventInfo != null)\r
{\r
mGame.ApplyMouseButtonInput(gamerInfo, mouseButtonEventInfo.IsButtonDown);\r
+ Console.WriteLine(mouseButtonEventInfo.FrameOfApplication + " BTN: " + mouseButtonEventInfo.IsButtonDown);\r
continue;\r
}\r
\r
if (mouseMotionEventInfo != null)\r
{\r
mGame.ApplyMouseLocationInput(gamerInfo, mouseMotionEventInfo.X, mouseMotionEventInfo.Y);\r
+ Console.WriteLine(mouseMotionEventInfo.FrameOfApplication + " MMV: " + mouseMotionEventInfo.X + "," + mouseMotionEventInfo.Y);\r
continue;\r
}\r
}\r
averageOwd += timeSpan.TotalMilliseconds;\r
}\r
\r
- return (int)(averageOwd / numRemoteGamersTwice / 16.6666);\r
+ return (int)((averageOwd / numRemoteGamersTwice) / 16.6666);\r
}\r
}\r
\r