Advertisement
Guest User

Untitled

a guest
May 1st, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.94 KB | None | 0 0
  1. // Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
  2. using System;
  3. using System.Diagnostics;
  4. using System.Drawing;
  5. using System.IO;
  6. using System.Net;
  7. using System.Threading;
  8. using ClassicalSharp.Audio;
  9. using ClassicalSharp.Commands;
  10. using ClassicalSharp.Entities;
  11. using ClassicalSharp.Events;
  12. using ClassicalSharp.GraphicsAPI;
  13. using ClassicalSharp.Gui.Screens;
  14. using ClassicalSharp.Map;
  15. using ClassicalSharp.Model;
  16. using ClassicalSharp.Network;
  17. using ClassicalSharp.Particles;
  18. using ClassicalSharp.Renderers;
  19. using ClassicalSharp.Selections;
  20. using ClassicalSharp.Textures;
  21. using OpenTK;
  22. using OpenTK.Input;
  23. #if ANDROID
  24. using Android.Graphics;
  25. #endif
  26. using PathIO = System.IO.Path; // Android.Graphics.Path clash otherwise
  27. using BlockID = System.UInt16;
  28.  
  29. namespace ClassicalSharp {
  30.  
  31. public partial class Game : IDisposable {
  32.  
  33. void LoadAtlas(Bitmap bmp) {
  34. TerrainAtlas1D.Dispose();
  35. TerrainAtlas2D.Dispose();
  36.  
  37. TerrainAtlas2D.UpdateState(bmp);
  38. TerrainAtlas1D.UpdateState();
  39. }
  40.  
  41. public bool ChangeTerrainAtlas(Bitmap atlas) {
  42. if (!ValidateBitmap("terrain.png", atlas)) return false;
  43. if (atlas.Width != atlas.Height) {
  44. Chat.Add("&cUnable to use terrain.png from the texture pack.");
  45. Chat.Add("&c Its width is not the same as its height.");
  46. return false;
  47. }
  48. if (Graphics.LostContext) return false;
  49.  
  50. LoadAtlas(atlas);
  51. Events.RaiseTerrainAtlasChanged();
  52. return true;
  53. }
  54.  
  55. public void Run() { window.Run(); }
  56.  
  57. public void Exit() { window.Exit(); }
  58.  
  59. void OnNewMapCore(object sender, EventArgs e) {
  60. for (int i = 0; i < Components.Count; i++)
  61. Components[i].OnNewMap(this);
  62. }
  63.  
  64. void OnNewMapLoadedCore(object sender, EventArgs e) {
  65. for (int i = 0; i < Components.Count; i++)
  66. Components[i].OnNewMapLoaded(this);
  67. }
  68.  
  69. public void SetViewDistance(float distance, bool userDist) {
  70. if (userDist) {
  71. UserViewDistance = distance;
  72. Options.Set(OptionsKey.ViewDist, (int)distance);
  73. }
  74.  
  75. distance = Math.Min(distance, MaxViewDistance);
  76. if (distance == ViewDistance) return;
  77. ViewDistance = distance;
  78.  
  79. Events.RaiseViewDistanceChanged();
  80. UpdateProjection();
  81. }
  82.  
  83. Stopwatch frameTimer = new Stopwatch();
  84. internal void RenderFrame(double delta) {
  85. frameTimer.Reset();
  86. frameTimer.Start();
  87.  
  88. Graphics.BeginFrame(this);
  89. Graphics.BindIb(defaultIb);
  90. accumulator += delta;
  91. Vertices = 0;
  92. Mode.BeginFrame(delta);
  93.  
  94. Camera.UpdateMouse();
  95. if (!Focused && !Gui.ActiveScreen.HandlesAllInput)
  96. Gui.SetNewScreen(new PauseScreen(this));
  97. CheckZoomFov();
  98.  
  99. DoScheduledTasks(delta);
  100. float t = (float)(entTask.Accumulator / entTask.Interval);
  101. LocalPlayer.SetInterpPosition(t);
  102.  
  103. if (!SkipClear) Graphics.Clear();
  104. CurrentCameraPos = Camera.GetCameraPos(t);
  105. UpdateViewMatrix();
  106.  
  107. bool visible = Gui.activeScreen == null || !Gui.activeScreen.BlocksWorld;
  108. if (!World.HasBlocks) visible = false;
  109. if (visible) {
  110. Render3D(delta, t);
  111. } else {
  112. SelectedPos.SetAsInvalid();
  113. }
  114.  
  115. Gui.Render(delta);
  116. if (screenshotRequested) TakeScreenshot();
  117.  
  118. Mode.EndFrame(delta);
  119. Graphics.EndFrame(this);
  120. LimitFPS();
  121. }
  122.  
  123. void CheckZoomFov() {
  124. bool allowZoom = Gui.activeScreen == null && !Gui.hudScreen.HandlesAllInput;
  125. if (allowZoom && IsKeyDown(KeyBind.ZoomScrolling))
  126. Input.SetFOV(ZoomFov, false);
  127. }
  128.  
  129. void UpdateViewMatrix() {
  130. Graphics.SetMatrixMode(MatrixType.Modelview);
  131. Camera.GetView(out Graphics.View);
  132. Graphics.LoadMatrix(ref Graphics.View);
  133. Culling.CalcFrustumEquations(ref Graphics.Projection, ref Graphics.View);
  134. }
  135.  
  136. void Render3D(double delta, float t) {
  137. if (SkyboxRenderer.ShouldRender)
  138. SkyboxRenderer.Render(delta);
  139. AxisLinesRenderer.Render(delta);
  140. Entities.RenderModels(Graphics, delta, t);
  141. Entities.RenderNames(Graphics, delta);
  142.  
  143. ParticleManager.Render(delta, t);
  144. Camera.GetPickedBlock(SelectedPos); // TODO: only pick when necessary
  145. EnvRenderer.Render(delta);
  146. MapRenderer.Update(delta);
  147. MapRenderer.RenderNormal(delta);
  148. MapRenderer.RenderLiquid(delta);
  149. MapBordersRenderer.RenderSides(delta);
  150.  
  151. Entities.DrawShadows();
  152. if (SelectedPos.Valid && !HideGui) {
  153. Picking.UpdateState(SelectedPos);
  154. Picking.Render(delta);
  155. }
  156.  
  157. // Render water over translucent blocks when underwater for proper alpha blending
  158. Vector3 pos = LocalPlayer.Position;
  159. if (CurrentCameraPos.Y < World.Env.EdgeHeight
  160. && (pos.X < 0 || pos.Z < 0 || pos.X > World.Width || pos.Z > World.Length)) {
  161. MapRenderer.RenderTranslucent(delta);
  162. MapBordersRenderer.RenderEdges(delta);
  163. } else {
  164. MapBordersRenderer.RenderEdges(delta);
  165. MapRenderer.RenderTranslucent(delta);
  166. }
  167.  
  168. // Need to render again over top of translucent block, as the selection outline
  169. // is drawn without writing to the depth buffer
  170. if (SelectedPos.Valid && !HideGui && BlockInfo.Draw[SelectedPos.Block] == DrawType.Translucent) {
  171. Picking.Render(delta);
  172. }
  173.  
  174. SelectionManager.Render(delta);
  175. Entities.RenderHoveredNames(Graphics, delta);
  176.  
  177. bool left = IsMousePressed(MouseButton.Left);
  178. bool middle = IsMousePressed(MouseButton.Middle);
  179. bool right = IsMousePressed(MouseButton.Right);
  180. Input.PickBlocks(true, left, middle, right);
  181. if (!HideGui)
  182. HeldBlockRenderer.Render(delta);
  183. }
  184.  
  185. void DoScheduledTasks(double time) {
  186. for (int i = 0; i < Tasks.Count; i++) {
  187. ScheduledTask task = Tasks[i];
  188. task.Accumulator += time;
  189.  
  190. while (task.Accumulator >= task.Interval) {
  191. task.Callback(task);
  192. task.Accumulator -= task.Interval;
  193. }
  194. }
  195. }
  196.  
  197. public ScheduledTask AddScheduledTask(double interval,
  198. ScheduledTaskCallback callback) {
  199. ScheduledTask task = new ScheduledTask();
  200. task.Interval = interval; task.Callback = callback;
  201. Tasks.Add(task);
  202. return task;
  203. }
  204.  
  205. void TakeScreenshot() {
  206. string path = PathIO.Combine(Program.AppDirectory, "screenshots");
  207. if (!Directory.Exists(path))
  208. Directory.CreateDirectory(path);
  209.  
  210. string timestamp = DateTime.Now.ToString("dd-MM-yyyy-HH-mm-ss");
  211. string file = "screenshot_" + timestamp + ".png";
  212. path = PathIO.Combine(path, file);
  213. Graphics.TakeScreenshot(path, Width, Height);
  214. Chat.Add("&eTaken screenshot as: " + file);
  215. screenshotRequested = false;
  216. }
  217.  
  218. public void UpdateProjection() {
  219. DefaultFov = Options.GetInt(OptionsKey.FieldOfView, 1, 150, 70);
  220. Camera.GetProjection(out Graphics.Projection);
  221.  
  222. Graphics.SetMatrixMode(MatrixType.Projection);
  223. Graphics.LoadMatrix(ref Graphics.Projection);
  224. Graphics.SetMatrixMode(MatrixType.Modelview);
  225. Events.RaiseProjectionChanged();
  226. }
  227.  
  228. internal void OnResize() {
  229. Width = window.Width; Height = window.Height;
  230. Graphics.OnWindowResize(this);
  231. UpdateProjection();
  232. Gui.OnResize();
  233. }
  234.  
  235. public void Disconnect(string title, string reason) {
  236. Events.RaiseDisconnected(title, reason);
  237.  
  238. Gui.Reset(this);
  239. World.Reset();
  240. WorldEvents.RaiseOnNewMap();
  241.  
  242. IDrawer2D.InitCols();
  243. BlockInfo.Reset();
  244. TexturePack.ExtractDefault(this);
  245. Gui.SetNewScreen(new DisconnectScreen(this, title, reason));
  246. GC.Collect();
  247. }
  248.  
  249. public void CycleCamera() {
  250. if (ClassicMode) return;
  251.  
  252. int i = Cameras.IndexOf(Camera);
  253. i = (i + 1) % Cameras.Count;
  254. Camera = Cameras[i];
  255. if (!LocalPlayer.Hacks.CanUseThirdPersonCamera || !LocalPlayer.Hacks.Enabled)
  256. Camera = Cameras[0];
  257. UpdateProjection();
  258. }
  259.  
  260. public void UpdateBlock(int x, int y, int z, BlockID block) {
  261. BlockID oldBlock = World.GetBlock(x, y, z);
  262. World.SetBlock(x, y, z, block);
  263.  
  264. WeatherRenderer weather = WeatherRenderer;
  265. if (weather.heightmap != null)
  266. weather.OnBlockChanged(x, y, z, oldBlock, block);
  267. Lighting.OnBlockChanged(x, y, z, oldBlock, block);
  268.  
  269. // Refresh the chunk the block was located in.
  270. int cx = x >> 4, cy = y >> 4, cz = z >> 4;
  271. MapRenderer.GetChunk(cx, cy, cz).AllAir &= BlockInfo.Draw[block] == DrawType.Gas;
  272. MapRenderer.RefreshChunk(cx, cy, cz);
  273. }
  274.  
  275. float limitMilliseconds;
  276. public void SetFpsLimitMethod(FpsLimitMethod method) {
  277. FpsLimit = method;
  278. limitMilliseconds = 0;
  279. Graphics.SetVSync(this, method == FpsLimitMethod.LimitVSync);
  280.  
  281. if (method == FpsLimitMethod.Limit120FPS)
  282. limitMilliseconds = 1000f / 120;
  283. if (method == FpsLimitMethod.Limit60FPS)
  284. limitMilliseconds = 1000f / 60;
  285. if (method == FpsLimitMethod.Limit30FPS)
  286. limitMilliseconds = 1000f / 30;
  287. }
  288.  
  289. void LimitFPS() {
  290. if (FpsLimit == FpsLimitMethod.LimitVSync) return;
  291.  
  292. double elapsed = frameTimer.Elapsed.TotalMilliseconds;
  293. double leftOver = limitMilliseconds - elapsed;
  294. if (leftOver > 0.001) // going faster than limit
  295. Thread.Sleep((int)Math.Round(leftOver, MidpointRounding.AwayFromZero));
  296. }
  297.  
  298. public bool IsKeyDown(Key key) { return Input.IsKeyDown(key); }
  299.  
  300. public bool IsKeyDown(KeyBind binding) { return Input.IsKeyDown(binding); }
  301.  
  302. public bool IsMousePressed(MouseButton button) { return Input.IsMousePressed(button); }
  303.  
  304. public Key Mapping(KeyBind mapping) { return Input.Keys[mapping]; }
  305.  
  306. public void Dispose() {
  307. MapRenderer.Dispose();
  308. TerrainAtlas2D.Dispose();
  309. TerrainAtlas1D.Dispose();
  310. ModelCache.Dispose();
  311. Entities.Dispose();
  312. WorldEvents.OnNewMap -= OnNewMapCore;
  313. WorldEvents.OnNewMapLoaded -= OnNewMapLoadedCore;
  314. Events.TextureChanged -= TextureChangedCore;
  315.  
  316. for (int i = 0; i < Components.Count; i++)
  317. Components[i].Dispose();
  318.  
  319. Graphics.DeleteIb(ref defaultIb);
  320. Drawer2D.DisposeInstance();
  321. Graphics.DeleteTexture(ref CloudsTex);
  322. Graphics.Dispose();
  323.  
  324. if (Options.OptionsChanged.Count == 0) return;
  325. Options.Load();
  326. Options.Save();
  327. }
  328.  
  329. public bool CanPick(BlockID block) {
  330. if (BlockInfo.Draw[block] == DrawType.Gas) return false;
  331. if (BlockInfo.Draw[block] == DrawType.Sprite) return true;
  332.  
  333. if (BlockInfo.Collide[block] != CollideType.Liquid) return true;
  334. return ModifiableLiquids && BlockInfo.CanPlace[block] && BlockInfo.CanDelete[block];
  335. }
  336.  
  337.  
  338. /// <summary> Reads a bitmap from the stream (converting it to 32 bits per pixel if necessary),
  339. /// and updates the native texture for it. </summary>
  340. public bool UpdateTexture(ref int texId, string file, byte[] data, bool setSkinType) {
  341. using (Bitmap bmp = Platform.ReadBmp32Bpp(Drawer2D, data)) {
  342. if (!ValidateBitmap(file, bmp)) return false;
  343.  
  344. Graphics.DeleteTexture(ref texId);
  345. if (setSkinType) SetDefaultSkinType(bmp);
  346.  
  347. texId = Graphics.CreateTexture(bmp, true, false);
  348. return true;
  349. }
  350. }
  351.  
  352. void SetDefaultSkinType(Bitmap bmp) {
  353. DefaultPlayerSkinType = Utils.GetSkinType(bmp);
  354. if (DefaultPlayerSkinType == SkinType.Invalid)
  355. throw new NotSupportedException("char.png has invalid dimensions");
  356.  
  357. Entity[] entities = Entities.List;
  358. for (int i = 0; i < EntityList.MaxCount; i++) {
  359. if (entities[i] == null || entities[i].TextureId != -1) continue;
  360. entities[i].SkinType = DefaultPlayerSkinType;
  361. }
  362. }
  363.  
  364. public bool ValidateBitmap(string file, Bitmap bmp) {
  365. if (bmp == null) {
  366. Chat.Add("&cError loading " + file + " from the texture pack.");
  367. return false;
  368. }
  369.  
  370. int maxSize = Graphics.MaxTextureDimensions;
  371. if (bmp.Width > maxSize || bmp.Height > maxSize) {
  372. Chat.Add("&cUnable to use " + file + " from the texture pack.");
  373. Chat.Add("&c Its size is (" + bmp.Width + "," + bmp.Height
  374. + "), your GPU supports (" + maxSize + "," + maxSize + ") at most.");
  375. return false;
  376. }
  377.  
  378. if (!Utils.IsPowerOf2(bmp.Width) || !Utils.IsPowerOf2(bmp.Height)) {
  379. Chat.Add("&cUnable to use " + file + " from the texture pack.");
  380. Chat.Add("&c Its size is (" + bmp.Width + "," + bmp.Height
  381. + "), which is not power of two dimensions.");
  382. return false;
  383. }
  384. return true;
  385. }
  386.  
  387. public bool SetRenderType(string type) {
  388. if (Utils.CaselessEquals(type, "legacyfast")) {
  389. SetNewRenderType(true, true);
  390. } else if (Utils.CaselessEquals(type, "legacy")) {
  391. SetNewRenderType(true, false);
  392. } else if (Utils.CaselessEquals(type, "normal")) {
  393. SetNewRenderType(false, false);
  394. } else if (Utils.CaselessEquals(type, "normalfast")) {
  395. SetNewRenderType(false, true);
  396. } else {
  397. return false;
  398. }
  399. Options.Set(OptionsKey.RenderType, type);
  400. return true;
  401. }
  402.  
  403. void SetNewRenderType(bool legacy, bool minimal) {
  404. if (MapBordersRenderer == null) {
  405. MapBordersRenderer = new MapBordersRenderer(); Components.Add(MapBordersRenderer);
  406. MapBordersRenderer.legacy = legacy;
  407. } else {
  408. MapBordersRenderer.UseLegacyMode(legacy);
  409. }
  410.  
  411. if (EnvRenderer == null) {
  412. EnvRenderer = new StandardEnvRenderer(); Components.Add(EnvRenderer);
  413. EnvRenderer.legacy = legacy;
  414. EnvRenderer.minimal = minimal;
  415. } else {
  416. EnvRenderer.UseLegacyMode(legacy);
  417. EnvRenderer.UseMinimalMode(minimal);
  418. }
  419. }
  420.  
  421. void TextureChangedCore(object sender, TextureEventArgs e) {
  422. byte[] data = e.Data;
  423. if (e.Name == "terrain.png") {
  424. Bitmap atlas = Platform.ReadBmp32Bpp(Drawer2D, data);
  425. if (ChangeTerrainAtlas(atlas)) return;
  426. atlas.Dispose();
  427. } else if (e.Name == "cloud.png" || e.Name == "clouds.png") {
  428. UpdateTexture(ref CloudsTex, e.Name, data, false);
  429. } else if (e.Name == "default.png") {
  430. Bitmap bmp = Platform.ReadBmp32Bpp(Drawer2D, data);
  431. Drawer2D.SetFontBitmap(bmp);
  432. Events.RaiseChatFontChanged();
  433. }
  434. }
  435.  
  436.  
  437. public Game(string username, string mppass, string skinServer,
  438. bool nullContext, int width, int height) {
  439. window = new DesktopWindow(this, username, nullContext, width, height);
  440. Username = username;
  441. Mppass = mppass;
  442. this.skinServer = skinServer;
  443. }
  444. }
  445. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement