/// <summary> /// Instructs the manager to dispose no longer needed areas. /// </summary> protected override void CleanAreas() { List <Tuple <int, int> > columns = GetEntityColumns(_Player); // flag nonlisted areas for removal List <ClientArea> areas = new List <ClientArea>(Areas.Values); foreach (ClientArea area in areas) { if (!area.IsInitialized || columns.Contains(new Tuple <int, int>(area.X, area.Z))) { // this area has not been initialize yet or is an active area continue; } if (area.Key < 0) { // now this is a problem... DiagnosticsManager.WriteMessage("WARNING: attempt to remove an area without a key!"); continue; } area.IsFlaggedForRemoval = true; lock (CollectionsLock) { // lock the collections to prevent conflicts int segmentCount = area.GetSegmentCount(); int boxesCount = 0; // save changed if (area.IsChanged) { SaveArea(area); } for (int i = 0; i < segmentCount; i++) { ClientSegment segment = area.GetSegment <ClientSegment>(ref i); boxesCount += segment.GetBoxCount(); foreach (ClientBox box in segment.GetBoxesSynchronized()) { _PooledBoxes.Enqueue(box); } segment.Unload(); Segments.Remove(segment.Key); _PooledSegments.Enqueue(segment); } area.Unload(); Areas.Remove(area.Key); DiagnosticsManager.BoxesLoaded -= boxesCount; DiagnosticsManager.SegmentsLoaded -= segmentCount; DiagnosticsManager.AreasLoaded--; } } }
/// <summary> /// Starts listening to the input events. /// </summary> public void Start() { // no need to re-init OpenGL as this was already done by OnReset // Reshape(); if (IsSinglePlayer) { Load(false); // lookup player foreach (Entity entity in Entities.Values) { if (entity is Player) { Player = entity as Player; break; } } #if DIAG DiagnosticsManager.WriteMessage("Retrieved player entity"); #endif } else { _MultiPlayerTerrainThread = new Thread(MultiPlayerTerrainLoader); _MultiPlayerTerrainThread.Priority = ThreadPriority.Lowest; _MultiPlayerTerrainThread.Start(); _Client = new ClientConnection(); _Client.Start(Configuration.MessagingConfigurationNode, Configuration.Network.GetRemoteEndPointUdp()); } _StartWait.WaitOne(); #if DIAG DiagnosticsManager.WriteMessage("Client ready"); #endif Events.Run(); }
private void PrepareClientSegments(int messageId, List <ClientSegment> segments) { #if DIAG int time = Environment.TickCount; #endif foreach (ClientSegment segment in segments) { segment.CheckEnclosed(); DiagnosticsManager.BoxesLoaded += segment.GetBoxCount(); } #if DIAG DiagnosticsManager.WriteMessage("Segment enclosed check done in {0} ms", (Environment.TickCount - time)); #endif #if DIAG time = Environment.TickCount; #endif _SegmentsForVisRefresh.Add(messageId, new List <ClientSegment>()); foreach (ClientSegment segment in segments) { segment.CheckHidden(ref messageId); segment.SortBoxesByMaterial(); } // update visibility for segments that have new neighbours foreach (ClientSegment segment in _SegmentsForVisRefresh[messageId]) { segment.CheckHidden(ref messageId); } _SegmentsForVisRefresh.Remove(messageId); #if DIAG DiagnosticsManager.WriteMessage("Hidden segment/face elimination done in {0} ms", (Environment.TickCount - time)); #endif }
private void KeyDown(object sender, KeyboardEventArgs e) { if (_ChatBoxActive) { if (e.Key == Key.Backspace && _CurrentChatMessage.Length > 0) { _CurrentChatMessage = _CurrentChatMessage.Substring(0, _CurrentChatMessage.Length - 1); } else if (e.Key == Key.Escape) { _ChatBoxActive = false; _CurrentChatMessage = string.Empty; } else if (e.Key == Key.Return) { _ChatBoxActive = false; if (!string.IsNullOrEmpty(_CurrentChatMessage)) { _ChatHistory.Add(Player.PlayerName + ": " + _CurrentChatMessage); WorldHelper.ClientToServerProvider.ChatMessage(Client.Connection, _CurrentChatMessage); _CurrentChatMessage = string.Empty; } } else if ((int)e.Key >= 32 && (int)e.Key <= 126 && _CurrentChatMessage.Length < 200) { _CurrentChatMessage += HandleTextKey(e); } } else { switch (e.Key) { case Key.W: _Player.MoveZ = -1; break; case Key.S: _Player.MoveZ = 1; break; case Key.A: _Player.MoveX = -1; break; case Key.D: _Player.MoveX = 1; break; case Key.G: _MouseGrab = !_MouseGrab; Mouse.ShowCursor = !_MouseGrab; #if DIAG DiagnosticsManager.WriteMessage("Mousegrab set to {0}", _MouseGrab); #endif break; case Key.F: ToggleFog(); break; case Key.R: NextMaterial(false); break; case Key.T: NextMaterial(true); break; case Key.One: case Key.Two: case Key.Three: case Key.Four: case Key.Five: case Key.Six: case Key.Seven: case Key.Eight: case Key.Nine: case Key.Zero: _Player.SelectedMaterial = (ushort)((int)e.Key - 46); break; case Key.Space: _Player.MoveY = 1; break; case Key.LeftControl: _Player.MoveY = -1; break; case Key.Return: _ChatBoxActive = true; break; case Key.Escape: StopTimer(); TextureManager.Instance.UnloadTextures(false); if (IsSinglePlayer) { Stop(); } else { WorldHelper.ClientToServerProvider.DisconnectingNotification(_Client.Connection); _Client.Connection.Disconnect("Player is quitting the client"); } break; case Key.F1: _ShowHud = !_ShowHud; break; case Key.F3: DiagnosticsManager.ShowHideDiagnosticsWindow(); break; case Key.F6: Save(false); break; case Key.F9: // load break; case Key.F11: StopTimer(); // Toggle fullscreen if (!_Screen.FullScreen) { _Screen = Video.SetVideoMode(_Width, _Height, true, true, true); WindowAttributes(); } else { _Screen = Video.SetVideoMode(_Width, _Height, true, true); WindowAttributes(); } Reshape(); #if DIAG DiagnosticsManager.WriteMessage("Fullscreen set to {0}", _Screen.FullScreen); #endif break; } } }
private void DrawGLScene() { if (Player == null) { return; } // Clear Screen And Depth Buffer Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); // Reset The Current Modelview Matrix Gl.glLoadIdentity(); // select all areas List <ClientArea> areas = new List <ClientArea>(); bool loaded = false; do { try { areas.AddRange(Areas.Values); loaded = true; } catch (Exception ex) { areas.Clear(); DiagnosticsManager.WriteMessage("WARNING: Exception while selecting areas " + ex.Message); } } while (!loaded); HandlePlayerMovement(); // set viewport _EyeLocation = new Point3D(_Player.Location, 0.0f, Player.EyeHeightFromCenter, 0.0f); Glu.gluLookAt(_EyeLocation.X, _EyeLocation.Y, _EyeLocation.Z, _Player.NewDirection.X, _Player.NewDirection.Y, _Player.NewDirection.Z, 0.0, 512.0, 0.0); Gl.glEnable(Gl.GL_DEPTH_TEST); Gl.glEnable(Gl.GL_LIGHTING); Gl.glEnable(Gl.GL_LIGHT0); Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, new float[] { -512.0f, 512.0f, -512.0f, 0.0f }); Gl.glEnable(Gl.GL_TEXTURE_2D); Gl.glTexEnvf(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_MODULATE); Gl.glColor3f(1.0f, 1.0f, 1.0f); // draw terrain Gl.glBegin(Gl.GL_QUADS); //Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY); //Gl.glEnableClientState(Gl.GL_COLOR_ARRAY); foreach (ClientArea area in areas) { if (area != null && area.IsReady && !area.IsFlaggedForRemoval /* && * area.VisibleSegments.Count > 0 */) { area.Draw(_EyeLocation, _Player.NewDirection); } } Gl.glEnd(); //Gl.glDisableClientState(Gl.GL_COLOR_ARRAY); //Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY); // draw entities Gl.glBegin(Gl.GL_QUADS); foreach (Entity entity in new List <Entity>(Entities.Values)) { if (entity != null) { entity.Draw(Player); } } Gl.glEnd(); Gl.glDisable(Gl.GL_LIGHTING); Gl.glDisable(Gl.GL_LIGHT0); Gl.glDisable(Gl.GL_DEPTH_TEST); Gl.glBegin(Gl.GL_QUADS); // higlight surface under crosshair Gl.glEnd(); if (_ShowHud) { // draw HUD DrawHud(); } Gl.glFlush(); //Gl.glFinish(); _Frame++; if (_Frame == 50) { _Frame = 0; int endTime = Environment.TickCount; DiagnosticsManager.WriteStatistics(endTime - _DiagTime); _DiagTime = endTime; } _CurrentTime = Environment.TickCount; #if DIAG DiagnosticsManager.GlGetErrorResult = Gl.glGetError(); DiagnosticsManager.ResetRendered(); #endif }