mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-18 03:55:19 -04:00
fix issues with sometimes being invisible when it should be visible, and vice versa
This commit is contained in:
parent
b72e5e3aaf
commit
f15ee65018
@ -43,7 +43,7 @@ namespace ClassicalSharp.Gui {
|
|||||||
public abstract class Screen : GuiElement {
|
public abstract class Screen : GuiElement {
|
||||||
public Screen(Game game) : base(game) { }
|
public Screen(Game game) : base(game) { }
|
||||||
|
|
||||||
public bool HandlesAllInput, BlocksWorld, HidesHud, RenderHudOver;
|
public bool HandlesAllInput = true, BlocksWorld, HidesHud, RenderHudOver;
|
||||||
|
|
||||||
public abstract void OnResize();
|
public abstract void OnResize();
|
||||||
protected abstract void ContextLost();
|
protected abstract void ContextLost();
|
||||||
|
@ -14,6 +14,7 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
public ChatScreen(Game game, HudScreen hud) : base(game) {
|
public ChatScreen(Game game, HudScreen hud) : base(game) {
|
||||||
chatLines = game.ChatLines;
|
chatLines = game.ChatLines;
|
||||||
this.hud = hud;
|
this.hud = hud;
|
||||||
|
HandlesAllInput = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
HudScreen hud;
|
HudScreen hud;
|
||||||
@ -275,7 +276,6 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
protected override void ContextLost() {
|
protected override void ContextLost() {
|
||||||
if (HandlesAllInput) {
|
if (HandlesAllInput) {
|
||||||
chatInInputBuffer = input.Text.ToString();
|
chatInInputBuffer = input.Text.ToString();
|
||||||
game.CursorVisible = false;
|
|
||||||
} else {
|
} else {
|
||||||
chatInInputBuffer = null;
|
chatInInputBuffer = null;
|
||||||
}
|
}
|
||||||
@ -330,7 +330,6 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void OpenInput(string initialText) {
|
public void OpenInput(string initialText) {
|
||||||
game.CursorVisible = true;
|
|
||||||
suppressNextPress = true;
|
suppressNextPress = true;
|
||||||
SetHandlesAllInput(true);
|
SetHandlesAllInput(true);
|
||||||
Keyboard.KeyRepeat = true;
|
Keyboard.KeyRepeat = true;
|
||||||
@ -350,9 +349,6 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
if (HandlesAllInput) { // text input bar
|
if (HandlesAllInput) { // text input bar
|
||||||
if (key == game.Mapping(KeyBind.SendChat) || key == Key.KeypadEnter || key == game.Mapping(KeyBind.PauseOrExit)) {
|
if (key == game.Mapping(KeyBind.SendChat) || key == Key.KeypadEnter || key == game.Mapping(KeyBind.PauseOrExit)) {
|
||||||
SetHandlesAllInput(false);
|
SetHandlesAllInput(false);
|
||||||
// when underlying screen is HUD, user is interacting with the world normally
|
|
||||||
game.CursorVisible = game.Gui.UnderlyingScreen != game.Gui.hudScreen;
|
|
||||||
game.Camera.RegrabMouse();
|
|
||||||
Keyboard.KeyRepeat = false;
|
Keyboard.KeyRepeat = false;
|
||||||
|
|
||||||
if (key == game.Mapping(KeyBind.PauseOrExit))
|
if (key == game.Mapping(KeyBind.PauseOrExit))
|
||||||
@ -466,6 +462,7 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
void SetHandlesAllInput(bool handles) {
|
void SetHandlesAllInput(bool handles) {
|
||||||
HandlesAllInput = handles;
|
HandlesAllInput = handles;
|
||||||
game.Gui.hudScreen.HandlesAllInput = handles;
|
game.Gui.hudScreen.HandlesAllInput = handles;
|
||||||
|
game.Gui.CalcCursorVisible();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -25,7 +25,6 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
messageFont = new Font(game.FontName, 16);
|
messageFont = new Font(game.FontName, 16);
|
||||||
BlocksWorld = true;
|
BlocksWorld = true;
|
||||||
HidesHud = true;
|
HidesHud = true;
|
||||||
HandlesAllInput = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Init() {
|
public override void Init() {
|
||||||
|
@ -8,7 +8,9 @@ using OpenTK.Input;
|
|||||||
namespace ClassicalSharp.Gui.Screens {
|
namespace ClassicalSharp.Gui.Screens {
|
||||||
public class HudScreen : Screen, IGameComponent {
|
public class HudScreen : Screen, IGameComponent {
|
||||||
|
|
||||||
public HudScreen(Game game) : base(game) { }
|
public HudScreen(Game game) : base(game) {
|
||||||
|
HandlesAllInput = false;
|
||||||
|
}
|
||||||
|
|
||||||
ChatScreen chat;
|
ChatScreen chat;
|
||||||
internal Widget hotbar;
|
internal Widget hotbar;
|
||||||
|
@ -5,13 +5,24 @@ using ClassicalSharp.Gui.Widgets;
|
|||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
|
||||||
namespace ClassicalSharp.Gui.Screens {
|
namespace ClassicalSharp.Gui.Screens {
|
||||||
public partial class InventoryScreen : Screen {
|
public class InventoryScreen : Screen {
|
||||||
|
|
||||||
TableWidget table;
|
TableWidget table;
|
||||||
Font font;
|
Font font;
|
||||||
|
bool deferredSelect;
|
||||||
public InventoryScreen(Game game) : base(game) {
|
public InventoryScreen(Game game) : base(game) {
|
||||||
font = new Font(game.FontName, 16);
|
font = new Font(game.FontName, 16);
|
||||||
HandlesAllInput = true;
|
}
|
||||||
|
|
||||||
|
void MoveToSelected() {
|
||||||
|
table.SetBlockTo(game.Inventory.Selected);
|
||||||
|
table.Recreate();
|
||||||
|
deferredSelect = false;
|
||||||
|
|
||||||
|
// User is holding invalid block
|
||||||
|
if (table.SelectedIndex == -1) {
|
||||||
|
table.MakeDescTex(game.Inventory.Selected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Init() {
|
public override void Init() {
|
||||||
@ -20,19 +31,22 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
table.ElementsPerRow = game.PureClassic ? 9 : 10;
|
table.ElementsPerRow = game.PureClassic ? 9 : 10;
|
||||||
table.Init();
|
table.Init();
|
||||||
|
|
||||||
// User is holding invalid block
|
// Can't immediately move to selected here, because cursor visibility
|
||||||
if (table.SelectedIndex == -1) {
|
// might be toggled after Init() is called. This causes the cursor to
|
||||||
table.MakeDescTex(game.Inventory.Selected);
|
// be moved back to the middle of the window.
|
||||||
}
|
deferredSelect = true;
|
||||||
|
|
||||||
game.Events.BlockPermissionsChanged += OnBlockChanged;
|
game.Events.BlockPermissionsChanged += OnBlockChanged;
|
||||||
game.Events.BlockDefinitionChanged += OnBlockChanged;
|
game.Events.BlockDefinitionChanged += OnBlockChanged;
|
||||||
Keyboard.KeyRepeat = true;
|
Keyboard.KeyRepeat = true;
|
||||||
game.Graphics.ContextLost += ContextLost;
|
game.Graphics.ContextLost += ContextLost;
|
||||||
game.Graphics.ContextRecreated += ContextRecreated;
|
game.Graphics.ContextRecreated += ContextRecreated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Render(double delta) { table.Render(delta); }
|
public override void Render(double delta) {
|
||||||
|
if (deferredSelect) MoveToSelected();
|
||||||
|
table.Render(delta);
|
||||||
|
}
|
||||||
|
|
||||||
public override void Dispose() {
|
public override void Dispose() {
|
||||||
font.Dispose();
|
font.Dispose();
|
||||||
|
@ -21,7 +21,6 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
font = new Font(game.FontName, 16);
|
font = new Font(game.FontName, 16);
|
||||||
BlocksWorld = true;
|
BlocksWorld = true;
|
||||||
RenderHudOver = true;
|
RenderHudOver = true;
|
||||||
HandlesAllInput = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string title, message;
|
string title, message;
|
||||||
|
@ -7,9 +7,7 @@ using OpenTK.Input;
|
|||||||
namespace ClassicalSharp.Gui.Screens {
|
namespace ClassicalSharp.Gui.Screens {
|
||||||
public abstract class ListScreen : ClickableScreen {
|
public abstract class ListScreen : ClickableScreen {
|
||||||
|
|
||||||
public ListScreen(Game game) : base(game) {
|
public ListScreen(Game game) : base(game) { }
|
||||||
HandlesAllInput = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Font font;
|
protected Font font;
|
||||||
protected string[] entries;
|
protected string[] entries;
|
||||||
|
@ -1,67 +1,65 @@
|
|||||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
|
||||||
namespace ClassicalSharp.Gui.Screens {
|
namespace ClassicalSharp.Gui.Screens {
|
||||||
public abstract class MenuScreen : ClickableScreen {
|
public abstract class MenuScreen : ClickableScreen {
|
||||||
|
|
||||||
public MenuScreen(Game game) : base(game) {
|
public MenuScreen(Game game) : base(game) { }
|
||||||
HandlesAllInput = true;
|
|
||||||
}
|
protected Widget[] widgets;
|
||||||
|
protected Font titleFont, textFont;
|
||||||
protected Widget[] widgets;
|
protected int IndexWidget(Widget w) { return IndexWidget(widgets, w); }
|
||||||
protected Font titleFont, textFont;
|
|
||||||
protected int IndexWidget(Widget w) { return IndexWidget(widgets, w); }
|
public override void Render(double delta) {
|
||||||
|
RenderMenuBounds();
|
||||||
public override void Render(double delta) {
|
game.Graphics.Texturing = true;
|
||||||
RenderMenuBounds();
|
RenderWidgets(widgets, delta);
|
||||||
game.Graphics.Texturing = true;
|
game.Graphics.Texturing = false;
|
||||||
RenderWidgets(widgets, delta);
|
}
|
||||||
game.Graphics.Texturing = false;
|
|
||||||
}
|
public override void Init() {
|
||||||
|
if (titleFont == null) titleFont = new Font(game.FontName, 16, FontStyle.Bold);
|
||||||
public override void Init() {
|
if (textFont == null) textFont = new Font(game.FontName, 16);
|
||||||
if (titleFont == null) titleFont = new Font(game.FontName, 16, FontStyle.Bold);
|
|
||||||
if (textFont == null) textFont = new Font(game.FontName, 16);
|
game.Graphics.ContextLost += ContextLost;
|
||||||
|
game.Graphics.ContextRecreated += ContextRecreated;
|
||||||
game.Graphics.ContextLost += ContextLost;
|
}
|
||||||
game.Graphics.ContextRecreated += ContextRecreated;
|
|
||||||
}
|
public override void Dispose() {
|
||||||
|
ContextLost();
|
||||||
public override void Dispose() {
|
if (titleFont != null) { titleFont.Dispose(); titleFont = null; }
|
||||||
ContextLost();
|
if (textFont != null) { textFont.Dispose(); textFont = null; }
|
||||||
if (titleFont != null) { titleFont.Dispose(); titleFont = null; }
|
|
||||||
if (textFont != null) { textFont.Dispose(); textFont = null; }
|
game.Graphics.ContextLost -= ContextLost;
|
||||||
|
game.Graphics.ContextRecreated -= ContextRecreated;
|
||||||
game.Graphics.ContextLost -= ContextLost;
|
}
|
||||||
game.Graphics.ContextRecreated -= ContextRecreated;
|
|
||||||
}
|
protected override void ContextLost() { DisposeWidgets(widgets); }
|
||||||
|
|
||||||
protected override void ContextLost() { DisposeWidgets(widgets); }
|
public override void OnResize() {
|
||||||
|
RepositionWidgets(widgets);
|
||||||
public override void OnResize() {
|
}
|
||||||
RepositionWidgets(widgets);
|
|
||||||
}
|
|
||||||
|
public override bool HandlesMouseDown(int mouseX, int mouseY, MouseButton button) {
|
||||||
|
return HandleMouseDown(widgets, mouseX, mouseY, button) >= 0;
|
||||||
public override bool HandlesMouseDown(int mouseX, int mouseY, MouseButton button) {
|
}
|
||||||
return HandleMouseDown(widgets, mouseX, mouseY, button) >= 0;
|
|
||||||
}
|
public override bool HandlesMouseMove(int mouseX, int mouseY) {
|
||||||
|
return HandleMouseMove(widgets, mouseX, mouseY) >= 0;
|
||||||
public override bool HandlesMouseMove(int mouseX, int mouseY) {
|
}
|
||||||
return HandleMouseMove(widgets, mouseX, mouseY) >= 0;
|
public override bool HandlesMouseScroll(float delta) { return true; }
|
||||||
}
|
|
||||||
public override bool HandlesMouseScroll(float delta) { return true; }
|
public override bool HandlesKeyDown(Key key) {
|
||||||
|
if (key == Key.Escape) {
|
||||||
public override bool HandlesKeyDown(Key key) {
|
game.Gui.SetNewScreen(null);
|
||||||
if (key == Key.Escape) {
|
return true;
|
||||||
game.Gui.SetNewScreen(null);
|
}
|
||||||
return true;
|
return key < Key.F1 || key > Key.F35;
|
||||||
}
|
}
|
||||||
return key < Key.F1 || key > Key.F35;
|
public override bool HandlesKeyPress(char key) { return true; }
|
||||||
}
|
public override bool HandlesKeyUp(Key key) { return true; }
|
||||||
public override bool HandlesKeyPress(char key) { return true; }
|
}
|
||||||
public override bool HandlesKeyUp(Key key) { return true; }
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -19,6 +19,7 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
|
|
||||||
public StatusScreen(Game game) : base(game) {
|
public StatusScreen(Game game) : base(game) {
|
||||||
statusBuffer = new StringBuffer(128);
|
statusBuffer = new StringBuffer(128);
|
||||||
|
HandlesAllInput = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IGameComponent.Init(Game game) { }
|
void IGameComponent.Init(Game game) { }
|
||||||
|
@ -106,8 +106,6 @@ namespace ClassicalSharp.Gui.Widgets {
|
|||||||
scroll = new ScrollbarWidget(game);
|
scroll = new ScrollbarWidget(game);
|
||||||
RecreateElements();
|
RecreateElements();
|
||||||
Reposition();
|
Reposition();
|
||||||
SetBlockTo(game.Inventory.Selected);
|
|
||||||
Recreate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Dispose() {
|
public override void Dispose() {
|
||||||
@ -177,7 +175,7 @@ namespace ClassicalSharp.Gui.Widgets {
|
|||||||
|
|
||||||
void MoveCursorToSelected() {
|
void MoveCursorToSelected() {
|
||||||
if (SelectedIndex == -1) return;
|
if (SelectedIndex == -1) return;
|
||||||
game.DesktopCursorPos = GetMouseCoords(SelectedIndex);
|
game.window.DesktopCursorPos = GetMouseCoords(SelectedIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateBlockInfoString(BlockID block) {
|
void UpdateBlockInfoString(BlockID block) {
|
||||||
|
@ -97,15 +97,12 @@ namespace ClassicalSharp.Entities {
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Gets the brightness colour of this entity. </summary>
|
|
||||||
public virtual PackedCol Colour() {
|
public virtual PackedCol Colour() {
|
||||||
Vector3I P = Vector3I.Floor(EyePosition);
|
Vector3I P = Vector3I.Floor(EyePosition);
|
||||||
return game.World.IsValidPos(P) ? game.Lighting.LightCol(P.X, P.Y, P.Z) : game.Lighting.Outside;
|
return game.World.IsValidPos(P) ? game.Lighting.LightCol(P.X, P.Y, P.Z) : game.Lighting.Outside;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary> Sets the model associated with this entity. </summary>
|
|
||||||
/// <param name="model"> Can be either 'name' or 'name'|'scale'. </param>
|
|
||||||
public void SetModel(string model) {
|
public void SetModel(string model) {
|
||||||
ModelScale = new Vector3(1.0f);
|
ModelScale = new Vector3(1.0f);
|
||||||
int sep = model.IndexOf('|');
|
int sep = model.IndexOf('|');
|
||||||
|
@ -204,31 +204,7 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public INativeWindow window;
|
public INativeWindow window;
|
||||||
|
|
||||||
public int Width, Height;
|
public int Width, Height;
|
||||||
|
|
||||||
public bool Focused { get { return window.Focused; } }
|
|
||||||
|
|
||||||
bool visible = true;
|
|
||||||
internal bool realVisible = true;
|
|
||||||
public bool CursorVisible {
|
|
||||||
get { return visible; }
|
|
||||||
set {
|
|
||||||
// Defer mouse visibility changes.
|
|
||||||
realVisible = value;
|
|
||||||
if (Gui.overlays.Count > 0) return;
|
|
||||||
|
|
||||||
// Only set the value when it has changes.
|
|
||||||
if (visible == value) return;
|
|
||||||
window.CursorVisible = value;
|
|
||||||
visible = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Point DesktopCursorPos {
|
|
||||||
get { return window.DesktopCursorPos; }
|
|
||||||
set { window.DesktopCursorPos = value; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -306,7 +306,7 @@ namespace ClassicalSharp {
|
|||||||
Vertices = 0;
|
Vertices = 0;
|
||||||
|
|
||||||
Camera.UpdateMouse();
|
Camera.UpdateMouse();
|
||||||
if (!Focused && !Gui.ActiveScreen.HandlesAllInput) {
|
if (!window.Focused && !Gui.ActiveScreen.HandlesAllInput) {
|
||||||
Gui.SetNewScreen(new PauseScreen(this));
|
Gui.SetNewScreen(new PauseScreen(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,41 +84,28 @@ namespace ClassicalSharp {
|
|||||||
if (activeScreen != null && disposeOld)
|
if (activeScreen != null && disposeOld)
|
||||||
activeScreen.Dispose();
|
activeScreen.Dispose();
|
||||||
|
|
||||||
if (screen == null) {
|
if (screen != null) screen.Init();
|
||||||
game.CursorVisible = false;
|
|
||||||
if (game.Focused) game.Camera.RegrabMouse();
|
|
||||||
} else if (activeScreen == null) {
|
|
||||||
game.CursorVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (screen != null)
|
|
||||||
screen.Init();
|
|
||||||
activeScreen = screen;
|
activeScreen = screen;
|
||||||
|
CalcCursorVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RefreshHud() { hudScreen.Recreate(); }
|
public void RefreshHud() { hudScreen.Recreate(); }
|
||||||
|
|
||||||
public void ShowOverlay(Overlay overlay, bool inFront) {
|
public void ShowOverlay(Overlay overlay, bool inFront) {
|
||||||
bool cursorVis = game.CursorVisible;
|
|
||||||
if (overlays.Count == 0) game.CursorVisible = true;
|
|
||||||
|
|
||||||
if (inFront) {
|
if (inFront) {
|
||||||
overlays.Insert(0, overlay);
|
overlays.Insert(0, overlay);
|
||||||
} else {
|
} else {
|
||||||
overlays.Add(overlay);
|
overlays.Add(overlay);
|
||||||
}
|
}
|
||||||
if (overlays.Count == 1) game.CursorVisible = cursorVis;
|
|
||||||
// Save cursor visibility state
|
|
||||||
overlay.Init();
|
overlay.Init();
|
||||||
|
CalcCursorVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DisposeOverlay(Overlay overlay) {
|
public void DisposeOverlay(Overlay overlay) {
|
||||||
overlay.Dispose();
|
overlay.Dispose();
|
||||||
overlays.Remove(overlay);
|
overlays.Remove(overlay);
|
||||||
|
CalcCursorVisible();
|
||||||
if (overlays.Count == 0)
|
|
||||||
game.CursorVisible = game.realVisible;
|
|
||||||
game.Camera.RegrabMouse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -144,5 +131,16 @@ namespace ClassicalSharp {
|
|||||||
overlays[i].OnResize();
|
overlays[i].OnResize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cursorVisible = true;
|
||||||
|
public void CalcCursorVisible() {
|
||||||
|
bool vis = ActiveScreen.HandlesAllInput;
|
||||||
|
if (vis == cursorVisible) return;
|
||||||
|
cursorVisible = vis;
|
||||||
|
|
||||||
|
game.window.CursorVisible = vis;
|
||||||
|
if (game.window.Focused)
|
||||||
|
game.Camera.RegrabMouse();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,7 +32,7 @@ using OpenTK;
|
|||||||
namespace OpenTK.Graphics.OpenGL {
|
namespace OpenTK.Graphics.OpenGL {
|
||||||
|
|
||||||
[InteropPatch]
|
[InteropPatch]
|
||||||
public unsafe static partial class GL {
|
public unsafe static class GL {
|
||||||
|
|
||||||
public static void AlphaFunc(Compare func, float value) {
|
public static void AlphaFunc(Compare func, float value) {
|
||||||
Interop.Calli((int)func, value, AlphaFuncAddress);
|
Interop.Calli((int)func, value, AlphaFuncAddress);
|
||||||
@ -243,6 +243,83 @@ namespace OpenTK.Graphics.OpenGL {
|
|||||||
public static void Viewport(int x, int y, int width, int height) {
|
public static void Viewport(int x, int y, int width, int height) {
|
||||||
Interop.Calli(x, y, width, height, ViewportAddress);
|
Interop.Calli(x, y, width, height, ViewportAddress);
|
||||||
} static IntPtr ViewportAddress;
|
} static IntPtr ViewportAddress;
|
||||||
|
|
||||||
|
|
||||||
|
internal static void LoadEntryPoints(IGraphicsContext context) {
|
||||||
|
Debug.Print("Loading OpenGL function pointers... ");
|
||||||
|
AlphaFuncAddress = context.GetAddress("glAlphaFunc");
|
||||||
|
|
||||||
|
BeginAddress = context.GetAddress("glBegin");
|
||||||
|
BindBufferAddress = context.GetAddress("glBindBuffer");
|
||||||
|
BindBufferARBAddress = context.GetAddress("glBindBufferARB");
|
||||||
|
BindTextureAddress = context.GetAddress("glBindTexture");
|
||||||
|
BlendFuncAddress = context.GetAddress("glBlendFunc");
|
||||||
|
BufferDataAddress = context.GetAddress("glBufferData");
|
||||||
|
BufferDataARBAddress = context.GetAddress("glBufferDataARB");
|
||||||
|
BufferSubDataAddress = context.GetAddress("glBufferSubData");
|
||||||
|
BufferSubDataARBAddress = context.GetAddress("glBufferSubDataARB");
|
||||||
|
|
||||||
|
CallListAddress = context.GetAddress("glCallList");
|
||||||
|
ClearAddress = context.GetAddress("glClear");
|
||||||
|
ClearColorAddress = context.GetAddress("glClearColor");
|
||||||
|
Color4ubAddress = context.GetAddress("glColor4ub");
|
||||||
|
ColorMaskAddress = context.GetAddress("glColorMask");
|
||||||
|
ColorPointerAddress = context.GetAddress("glColorPointer");
|
||||||
|
CullFaceAddress = context.GetAddress("glCullFace");
|
||||||
|
|
||||||
|
DeleteBuffersAddress = context.GetAddress("glDeleteBuffers");
|
||||||
|
DeleteBuffersARBAddress = context.GetAddress("glDeleteBuffersARB");
|
||||||
|
DeleteListsAddress = context.GetAddress("glDeleteLists");
|
||||||
|
DeleteTexturesAddress = context.GetAddress("glDeleteTextures");
|
||||||
|
DepthFuncAddress = context.GetAddress("glDepthFunc");
|
||||||
|
DepthMaskAddress = context.GetAddress("glDepthMask");
|
||||||
|
DisableAddress = context.GetAddress("glDisable");
|
||||||
|
DisableClientStateAddress = context.GetAddress("glDisableClientState");
|
||||||
|
DrawArraysAddress = context.GetAddress("glDrawArrays");
|
||||||
|
DrawElementsAddress = context.GetAddress("glDrawElements");
|
||||||
|
|
||||||
|
EnableAddress = context.GetAddress("glEnable");
|
||||||
|
EnableClientStateAddress = context.GetAddress("glEnableClientState");
|
||||||
|
EndAddress = context.GetAddress("glEnd");
|
||||||
|
EndListAddress = context.GetAddress("glEndList");
|
||||||
|
FogfAddress = context.GetAddress("glFogf");
|
||||||
|
FogfvAddress = context.GetAddress("glFogfv");
|
||||||
|
FogiAddress = context.GetAddress("glFogi");
|
||||||
|
|
||||||
|
GenBuffersAddress = context.GetAddress("glGenBuffers");
|
||||||
|
GenBuffersARBAddress = context.GetAddress("glGenBuffersARB");
|
||||||
|
GenListsAddress = context.GetAddress("glGenLists");
|
||||||
|
GenTexturesAddress = context.GetAddress("glGenTextures");
|
||||||
|
GetErrorAddress = context.GetAddress("glGetError");
|
||||||
|
GetIntegervAddress = context.GetAddress("glGetIntegerv");
|
||||||
|
GetStringAddress = context.GetAddress("glGetString");
|
||||||
|
GetTexImageAddress = context.GetAddress("glGetTexImage");
|
||||||
|
|
||||||
|
HintAddress = context.GetAddress("glHint");
|
||||||
|
LoadIdentityAddress = context.GetAddress("glLoadIdentity");
|
||||||
|
LoadMatrixfAddress = context.GetAddress("glLoadMatrixf");
|
||||||
|
MatrixModeAddress = context.GetAddress("glMatrixMode");
|
||||||
|
MultMatrixfAddress = context.GetAddress("glMultMatrixf");
|
||||||
|
NewListAddress = context.GetAddress("glNewList");
|
||||||
|
ReadPixelsAddress = context.GetAddress("glReadPixels");
|
||||||
|
|
||||||
|
TexCoord2fAddress = context.GetAddress("glTexCoord2f");
|
||||||
|
TexCoordPointerAddress = context.GetAddress("glTexCoordPointer");
|
||||||
|
TexImage2DAddress = context.GetAddress("glTexImage2D");
|
||||||
|
TexParameteriAddress = context.GetAddress("glTexParameteri");
|
||||||
|
TexSubImage2DAddress = context.GetAddress("glTexSubImage2D");
|
||||||
|
Vertex3fAddress = context.GetAddress("glVertex3f");
|
||||||
|
VertexPointerAddress = context.GetAddress("glVertexPointer");
|
||||||
|
ViewportAddress = context.GetAddress("glViewport");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UseArbVboAddresses() {
|
||||||
|
BindBufferAddress = BindBufferARBAddress;
|
||||||
|
BufferDataAddress = BufferDataARBAddress;
|
||||||
|
BufferSubDataAddress = BufferSubDataARBAddress;
|
||||||
|
DeleteBuffersAddress = DeleteBuffersARBAddress;
|
||||||
|
GenBuffersAddress = GenBuffersARBAddress;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ArrayCap : int {
|
public enum ArrayCap : int {
|
||||||
@ -418,83 +495,5 @@ namespace OpenTK.Graphics.OpenGL {
|
|||||||
public enum TextureTarget : int {
|
public enum TextureTarget : int {
|
||||||
Texture2D = 0x0DE1,
|
Texture2D = 0x0DE1,
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe static partial class GL {
|
|
||||||
internal static void LoadEntryPoints(IGraphicsContext context) {
|
|
||||||
Debug.Print("Loading OpenGL function pointers... ");
|
|
||||||
AlphaFuncAddress = context.GetAddress("glAlphaFunc");
|
|
||||||
|
|
||||||
BeginAddress = context.GetAddress("glBegin");
|
|
||||||
BindBufferAddress = context.GetAddress("glBindBuffer");
|
|
||||||
BindBufferARBAddress = context.GetAddress("glBindBufferARB");
|
|
||||||
BindTextureAddress = context.GetAddress("glBindTexture");
|
|
||||||
BlendFuncAddress = context.GetAddress("glBlendFunc");
|
|
||||||
BufferDataAddress = context.GetAddress("glBufferData");
|
|
||||||
BufferDataARBAddress = context.GetAddress("glBufferDataARB");
|
|
||||||
BufferSubDataAddress = context.GetAddress("glBufferSubData");
|
|
||||||
BufferSubDataARBAddress = context.GetAddress("glBufferSubDataARB");
|
|
||||||
|
|
||||||
CallListAddress = context.GetAddress("glCallList");
|
|
||||||
ClearAddress = context.GetAddress("glClear");
|
|
||||||
ClearColorAddress = context.GetAddress("glClearColor");
|
|
||||||
Color4ubAddress = context.GetAddress("glColor4ub");
|
|
||||||
ColorMaskAddress = context.GetAddress("glColorMask");
|
|
||||||
ColorPointerAddress = context.GetAddress("glColorPointer");
|
|
||||||
CullFaceAddress = context.GetAddress("glCullFace");
|
|
||||||
|
|
||||||
DeleteBuffersAddress = context.GetAddress("glDeleteBuffers");
|
|
||||||
DeleteBuffersARBAddress = context.GetAddress("glDeleteBuffersARB");
|
|
||||||
DeleteListsAddress = context.GetAddress("glDeleteLists");
|
|
||||||
DeleteTexturesAddress = context.GetAddress("glDeleteTextures");
|
|
||||||
DepthFuncAddress = context.GetAddress("glDepthFunc");
|
|
||||||
DepthMaskAddress = context.GetAddress("glDepthMask");
|
|
||||||
DisableAddress = context.GetAddress("glDisable");
|
|
||||||
DisableClientStateAddress = context.GetAddress("glDisableClientState");
|
|
||||||
DrawArraysAddress = context.GetAddress("glDrawArrays");
|
|
||||||
DrawElementsAddress = context.GetAddress("glDrawElements");
|
|
||||||
|
|
||||||
EnableAddress = context.GetAddress("glEnable");
|
|
||||||
EnableClientStateAddress = context.GetAddress("glEnableClientState");
|
|
||||||
EndAddress = context.GetAddress("glEnd");
|
|
||||||
EndListAddress = context.GetAddress("glEndList");
|
|
||||||
FogfAddress = context.GetAddress("glFogf");
|
|
||||||
FogfvAddress = context.GetAddress("glFogfv");
|
|
||||||
FogiAddress = context.GetAddress("glFogi");
|
|
||||||
|
|
||||||
GenBuffersAddress = context.GetAddress("glGenBuffers");
|
|
||||||
GenBuffersARBAddress = context.GetAddress("glGenBuffersARB");
|
|
||||||
GenListsAddress = context.GetAddress("glGenLists");
|
|
||||||
GenTexturesAddress = context.GetAddress("glGenTextures");
|
|
||||||
GetErrorAddress = context.GetAddress("glGetError");
|
|
||||||
GetIntegervAddress = context.GetAddress("glGetIntegerv");
|
|
||||||
GetStringAddress = context.GetAddress("glGetString");
|
|
||||||
GetTexImageAddress = context.GetAddress("glGetTexImage");
|
|
||||||
|
|
||||||
HintAddress = context.GetAddress("glHint");
|
|
||||||
LoadIdentityAddress = context.GetAddress("glLoadIdentity");
|
|
||||||
LoadMatrixfAddress = context.GetAddress("glLoadMatrixf");
|
|
||||||
MatrixModeAddress = context.GetAddress("glMatrixMode");
|
|
||||||
MultMatrixfAddress = context.GetAddress("glMultMatrixf");
|
|
||||||
NewListAddress = context.GetAddress("glNewList");
|
|
||||||
ReadPixelsAddress = context.GetAddress("glReadPixels");
|
|
||||||
|
|
||||||
TexCoord2fAddress = context.GetAddress("glTexCoord2f");
|
|
||||||
TexCoordPointerAddress = context.GetAddress("glTexCoordPointer");
|
|
||||||
TexImage2DAddress = context.GetAddress("glTexImage2D");
|
|
||||||
TexParameteriAddress = context.GetAddress("glTexParameteri");
|
|
||||||
TexSubImage2DAddress = context.GetAddress("glTexSubImage2D");
|
|
||||||
Vertex3fAddress = context.GetAddress("glVertex3f");
|
|
||||||
VertexPointerAddress = context.GetAddress("glVertexPointer");
|
|
||||||
ViewportAddress = context.GetAddress("glViewport");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void UseArbVboAddresses() {
|
|
||||||
BindBufferAddress = BindBufferARBAddress;
|
|
||||||
BufferDataAddress = BufferDataARBAddress;
|
|
||||||
BufferSubDataAddress = BufferSubDataARBAddress;
|
|
||||||
DeleteBuffersAddress = DeleteBuffersARBAddress;
|
|
||||||
GenBuffersAddress = GenBuffersARBAddress;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,355 +1,350 @@
|
|||||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||||
using System;
|
using System;
|
||||||
using ClassicalSharp.Gui;
|
using ClassicalSharp.Gui;
|
||||||
using ClassicalSharp.Gui.Screens;
|
using ClassicalSharp.Gui.Screens;
|
||||||
using ClassicalSharp.Entities;
|
using ClassicalSharp.Entities;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
#if __MonoCS__
|
#if __MonoCS__
|
||||||
using Ionic.Zlib;
|
using Ionic.Zlib;
|
||||||
#else
|
#else
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
#endif
|
#endif
|
||||||
using BlockID = System.UInt16;
|
using BlockID = System.UInt16;
|
||||||
|
|
||||||
namespace ClassicalSharp.Network.Protocols {
|
namespace ClassicalSharp.Network.Protocols {
|
||||||
|
|
||||||
/// <summary> Implements the packets for the original classic. </summary>
|
/// <summary> Implements the packets for the original classic. </summary>
|
||||||
public sealed class ClassicProtocol : IProtocol {
|
public sealed class ClassicProtocol : IProtocol {
|
||||||
|
|
||||||
public ClassicProtocol(Game game) : base(game) { }
|
public ClassicProtocol(Game game) : base(game) { }
|
||||||
bool receivedFirstPosition;
|
bool receivedFirstPosition;
|
||||||
DateTime mapReceiveStart;
|
DateTime mapReceiveStart;
|
||||||
DeflateStream gzipStream;
|
DeflateStream gzipStream;
|
||||||
GZipHeaderReader gzipHeader;
|
GZipHeaderReader gzipHeader;
|
||||||
int mapSizeIndex, mapIndex, mapVolume;
|
int mapSizeIndex, mapIndex, mapVolume;
|
||||||
byte[] mapSize = new byte[4], map;
|
byte[] mapSize = new byte[4], map;
|
||||||
FixedBufferStream mapPartStream;
|
FixedBufferStream mapPartStream;
|
||||||
Screen prevScreen;
|
Screen prevScreen;
|
||||||
bool prevCursorVisible;
|
|
||||||
|
public override void Reset() {
|
||||||
public override void Reset() {
|
if (mapPartStream == null) mapPartStream = new FixedBufferStream(net.reader.buffer);
|
||||||
if (mapPartStream == null) mapPartStream = new FixedBufferStream(net.reader.buffer);
|
receivedFirstPosition = false;
|
||||||
receivedFirstPosition = false;
|
|
||||||
|
net.Set(Opcode.Handshake, HandleHandshake, 131);
|
||||||
net.Set(Opcode.Handshake, HandleHandshake, 131);
|
net.Set(Opcode.Ping, HandlePing, 1);
|
||||||
net.Set(Opcode.Ping, HandlePing, 1);
|
net.Set(Opcode.LevelInit, HandleLevelInit, 1);
|
||||||
net.Set(Opcode.LevelInit, HandleLevelInit, 1);
|
net.Set(Opcode.LevelDataChunk, HandleLevelDataChunk, 1028);
|
||||||
net.Set(Opcode.LevelDataChunk, HandleLevelDataChunk, 1028);
|
net.Set(Opcode.LevelFinalise, HandleLevelFinalise, 7);
|
||||||
net.Set(Opcode.LevelFinalise, HandleLevelFinalise, 7);
|
net.Set(Opcode.SetBlock, HandleSetBlock, 8);
|
||||||
net.Set(Opcode.SetBlock, HandleSetBlock, 8);
|
|
||||||
|
net.Set(Opcode.AddEntity, HandleAddEntity, 74);
|
||||||
net.Set(Opcode.AddEntity, HandleAddEntity, 74);
|
net.Set(Opcode.EntityTeleport, HandleEntityTeleport, 10);
|
||||||
net.Set(Opcode.EntityTeleport, HandleEntityTeleport, 10);
|
net.Set(Opcode.RelPosAndOrientationUpdate, HandleRelPosAndOrientationUpdate, 7);
|
||||||
net.Set(Opcode.RelPosAndOrientationUpdate, HandleRelPosAndOrientationUpdate, 7);
|
net.Set(Opcode.RelPosUpdate, HandleRelPositionUpdate, 5);
|
||||||
net.Set(Opcode.RelPosUpdate, HandleRelPositionUpdate, 5);
|
net.Set(Opcode.OrientationUpdate, HandleOrientationUpdate, 4);
|
||||||
net.Set(Opcode.OrientationUpdate, HandleOrientationUpdate, 4);
|
net.Set(Opcode.RemoveEntity, HandleRemoveEntity, 2);
|
||||||
net.Set(Opcode.RemoveEntity, HandleRemoveEntity, 2);
|
|
||||||
|
net.Set(Opcode.Message, HandleMessage, 66);
|
||||||
net.Set(Opcode.Message, HandleMessage, 66);
|
net.Set(Opcode.Kick, HandleKick, 65);
|
||||||
net.Set(Opcode.Kick, HandleKick, 65);
|
net.Set(Opcode.SetPermission, HandleSetPermission, 2);
|
||||||
net.Set(Opcode.SetPermission, HandleSetPermission, 2);
|
}
|
||||||
}
|
|
||||||
|
public override void Tick() {
|
||||||
public override void Tick() {
|
if (receivedFirstPosition) {
|
||||||
if (receivedFirstPosition) {
|
LocalPlayer player = game.LocalPlayer;
|
||||||
LocalPlayer player = game.LocalPlayer;
|
WritePosition(player.Position, player.HeadY, player.HeadX);
|
||||||
WritePosition(player.Position, player.HeadY, player.HeadX);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
#if !ONLY_8BIT
|
||||||
#if !ONLY_8BIT
|
DeflateStream gzipStream2;
|
||||||
DeflateStream gzipStream2;
|
byte[] map2;
|
||||||
byte[] map2;
|
int mapIndex2;
|
||||||
int mapIndex2;
|
#endif
|
||||||
#endif
|
|
||||||
|
#region Read
|
||||||
#region Read
|
|
||||||
|
void HandleHandshake() {
|
||||||
void HandleHandshake() {
|
byte protocolVer = reader.ReadUInt8();
|
||||||
byte protocolVer = reader.ReadUInt8();
|
net.ServerName = reader.ReadString();
|
||||||
net.ServerName = reader.ReadString();
|
net.ServerMotd = reader.ReadString();
|
||||||
net.ServerMotd = reader.ReadString();
|
game.Chat.SetLogName(net.ServerName);
|
||||||
game.Chat.SetLogName(net.ServerName);
|
|
||||||
|
game.LocalPlayer.Hacks.SetUserType(reader.ReadUInt8(), !net.cpeData.blockPerms);
|
||||||
game.LocalPlayer.Hacks.SetUserType(reader.ReadUInt8(), !net.cpeData.blockPerms);
|
game.LocalPlayer.Hacks.HacksFlags = net.ServerName + net.ServerMotd;
|
||||||
game.LocalPlayer.Hacks.HacksFlags = net.ServerName + net.ServerMotd;
|
game.LocalPlayer.Hacks.UpdateHacksState();
|
||||||
game.LocalPlayer.Hacks.UpdateHacksState();
|
}
|
||||||
}
|
|
||||||
|
void HandlePing() { }
|
||||||
void HandlePing() { }
|
|
||||||
|
void HandleLevelInit() {
|
||||||
void HandleLevelInit() {
|
if (gzipStream == null) StartLoadingState();
|
||||||
if (gzipStream == null) StartLoadingState();
|
|
||||||
|
// Fast map puts volume in header, doesn't bother with gzip
|
||||||
// Fast map puts volume in header, doesn't bother with gzip
|
if (net.cpeData.fastMap) {
|
||||||
if (net.cpeData.fastMap) {
|
mapVolume = reader.ReadInt32();
|
||||||
mapVolume = reader.ReadInt32();
|
gzipHeader.done = true;
|
||||||
gzipHeader.done = true;
|
mapSizeIndex = 4;
|
||||||
mapSizeIndex = 4;
|
map = new byte[mapVolume];
|
||||||
map = new byte[mapVolume];
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
void StartLoadingState() {
|
||||||
void StartLoadingState() {
|
game.World.Reset();
|
||||||
game.World.Reset();
|
game.WorldEvents.RaiseOnNewMap();
|
||||||
game.WorldEvents.RaiseOnNewMap();
|
|
||||||
|
prevScreen = game.Gui.activeScreen;
|
||||||
prevScreen = game.Gui.activeScreen;
|
if (prevScreen is LoadingScreen) prevScreen = null;
|
||||||
if (prevScreen is LoadingScreen)
|
|
||||||
prevScreen = null;
|
game.Gui.SetNewScreen(new LoadingScreen(game, net.ServerName, net.ServerMotd), false);
|
||||||
prevCursorVisible = game.CursorVisible;
|
net.wom.CheckMotd();
|
||||||
|
receivedFirstPosition = false;
|
||||||
game.Gui.SetNewScreen(new LoadingScreen(game, net.ServerName, net.ServerMotd), false);
|
gzipHeader = new GZipHeaderReader();
|
||||||
net.wom.CheckMotd();
|
|
||||||
receivedFirstPosition = false;
|
// Workaround because built in mono stream assumes that the end of stream
|
||||||
gzipHeader = new GZipHeaderReader();
|
// has been reached the first time a read call returns 0. (MS.NET doesn't)
|
||||||
|
#if __MonoCS__
|
||||||
// Workaround because built in mono stream assumes that the end of stream
|
gzipStream = new DeflateStream(mapPartStream, true);
|
||||||
// has been reached the first time a read call returns 0. (MS.NET doesn't)
|
#else
|
||||||
#if __MonoCS__
|
gzipStream = new DeflateStream(mapPartStream, CompressionMode.Decompress);
|
||||||
gzipStream = new DeflateStream(mapPartStream, true);
|
if (OpenTK.Configuration.RunningOnMono) {
|
||||||
#else
|
throw new InvalidOperationException("You must compile ClassicalSharp with __MonoCS__ defined " +
|
||||||
gzipStream = new DeflateStream(mapPartStream, CompressionMode.Decompress);
|
"to run on Mono, due to a limitation in Mono.");
|
||||||
if (OpenTK.Configuration.RunningOnMono) {
|
}
|
||||||
throw new InvalidOperationException("You must compile ClassicalSharp with __MonoCS__ defined " +
|
#endif
|
||||||
"to run on Mono, due to a limitation in Mono.");
|
|
||||||
}
|
#if !ONLY_8BIT
|
||||||
#endif
|
#if __MonoCS__
|
||||||
|
gzipStream2 = new DeflateStream(mapPartStream, true);
|
||||||
#if !ONLY_8BIT
|
#else
|
||||||
#if __MonoCS__
|
gzipStream2 = new DeflateStream(mapPartStream, CompressionMode.Decompress);
|
||||||
gzipStream2 = new DeflateStream(mapPartStream, true);
|
#endif
|
||||||
#else
|
#endif
|
||||||
gzipStream2 = new DeflateStream(mapPartStream, CompressionMode.Decompress);
|
|
||||||
#endif
|
mapSizeIndex = 0;
|
||||||
#endif
|
mapIndex = 0;
|
||||||
|
#if !ONLY_8BIT
|
||||||
mapSizeIndex = 0;
|
mapIndex2 = 0;
|
||||||
mapIndex = 0;
|
#endif
|
||||||
#if !ONLY_8BIT
|
mapReceiveStart = DateTime.UtcNow;
|
||||||
mapIndex2 = 0;
|
}
|
||||||
#endif
|
|
||||||
mapReceiveStart = DateTime.UtcNow;
|
void HandleLevelDataChunk() {
|
||||||
}
|
// Workaround for some servers that send LevelDataChunk before LevelInit
|
||||||
|
// due to their async packet sending behaviour.
|
||||||
void HandleLevelDataChunk() {
|
if (gzipStream == null) StartLoadingState();
|
||||||
// Workaround for some servers that send LevelDataChunk before LevelInit
|
|
||||||
// due to their async packet sending behaviour.
|
int usedLength = reader.ReadUInt16();
|
||||||
if (gzipStream == null) StartLoadingState();
|
mapPartStream.pos = 0;
|
||||||
|
mapPartStream.bufferPos = reader.index;
|
||||||
int usedLength = reader.ReadUInt16();
|
mapPartStream.len = usedLength;
|
||||||
mapPartStream.pos = 0;
|
|
||||||
mapPartStream.bufferPos = reader.index;
|
reader.Skip(1024);
|
||||||
mapPartStream.len = usedLength;
|
byte value = reader.ReadUInt8(); // progress in original classic, but we ignore it
|
||||||
|
|
||||||
reader.Skip(1024);
|
if (gzipHeader.done || gzipHeader.ReadHeader(mapPartStream)) {
|
||||||
byte value = reader.ReadUInt8(); // progress in original classic, but we ignore it
|
if (mapSizeIndex < 4) {
|
||||||
|
mapSizeIndex += gzipStream.Read(mapSize, mapSizeIndex, 4 - mapSizeIndex);
|
||||||
if (gzipHeader.done || gzipHeader.ReadHeader(mapPartStream)) {
|
}
|
||||||
if (mapSizeIndex < 4) {
|
|
||||||
mapSizeIndex += gzipStream.Read(mapSize, mapSizeIndex, 4 - mapSizeIndex);
|
if (mapSizeIndex == 4) {
|
||||||
}
|
if (map == null) {
|
||||||
|
mapVolume = mapSize[0] << 24 | mapSize[1] << 16 | mapSize[2] << 8 | mapSize[3];
|
||||||
if (mapSizeIndex == 4) {
|
map = new byte[mapVolume];
|
||||||
if (map == null) {
|
}
|
||||||
mapVolume = mapSize[0] << 24 | mapSize[1] << 16 | mapSize[2] << 8 | mapSize[3];
|
|
||||||
map = new byte[mapVolume];
|
#if !ONLY_8BIT
|
||||||
}
|
if (reader.ExtendedBlocks && value != 0) {
|
||||||
|
// Only allocate map2 when needed
|
||||||
#if !ONLY_8BIT
|
if (map2 == null) map2 = new byte[mapVolume];
|
||||||
if (reader.ExtendedBlocks && value != 0) {
|
mapIndex2 += gzipStream2.Read(map2, mapIndex2, map2.Length - mapIndex2);
|
||||||
// Only allocate map2 when needed
|
} else {
|
||||||
if (map2 == null) map2 = new byte[mapVolume];
|
mapIndex += gzipStream.Read(map, mapIndex, map.Length - mapIndex);
|
||||||
mapIndex2 += gzipStream2.Read(map2, mapIndex2, map2.Length - mapIndex2);
|
}
|
||||||
} else {
|
#else
|
||||||
mapIndex += gzipStream.Read(map, mapIndex, map.Length - mapIndex);
|
mapIndex += gzipStream.Read(map, mapIndex, map.Length - mapIndex);
|
||||||
}
|
#endif
|
||||||
#else
|
}
|
||||||
mapIndex += gzipStream.Read(map, mapIndex, map.Length - mapIndex);
|
}
|
||||||
#endif
|
|
||||||
}
|
float progress = map == null ? 0 : (float)mapIndex / map.Length;
|
||||||
}
|
game.WorldEvents.RaiseLoading(progress);
|
||||||
|
}
|
||||||
float progress = map == null ? 0 : (float)mapIndex / map.Length;
|
|
||||||
game.WorldEvents.RaiseLoading(progress);
|
void HandleLevelFinalise() {
|
||||||
}
|
game.Gui.SetNewScreen(null);
|
||||||
|
game.Gui.activeScreen = prevScreen;
|
||||||
void HandleLevelFinalise() {
|
game.Gui.CalcCursorVisible();
|
||||||
game.Gui.SetNewScreen(null);
|
prevScreen = null;
|
||||||
game.Gui.activeScreen = prevScreen;
|
|
||||||
if (prevScreen != null && prevCursorVisible != game.CursorVisible) {
|
int mapWidth = reader.ReadUInt16();
|
||||||
game.CursorVisible = prevCursorVisible;
|
int mapHeight = reader.ReadUInt16();
|
||||||
}
|
int mapLength = reader.ReadUInt16();
|
||||||
prevScreen = null;
|
|
||||||
|
double loadingMs = (DateTime.UtcNow - mapReceiveStart).TotalMilliseconds;
|
||||||
int mapWidth = reader.ReadUInt16();
|
Utils.LogDebug("map loading took: " + loadingMs);
|
||||||
int mapHeight = reader.ReadUInt16();
|
|
||||||
int mapLength = reader.ReadUInt16();
|
game.World.SetNewMap(map, mapWidth, mapHeight, mapLength);
|
||||||
|
#if !ONLY_8BIT
|
||||||
double loadingMs = (DateTime.UtcNow - mapReceiveStart).TotalMilliseconds;
|
if (reader.ExtendedBlocks) {
|
||||||
Utils.LogDebug("map loading took: " + loadingMs);
|
// defer allocation of scond map array if possible
|
||||||
|
game.World.blocks2 = map2 == null ? map : map2;
|
||||||
game.World.SetNewMap(map, mapWidth, mapHeight, mapLength);
|
BlockInfo.SetMaxUsed(map2 == null ? 255 : 767);
|
||||||
#if !ONLY_8BIT
|
}
|
||||||
if (reader.ExtendedBlocks) {
|
#endif
|
||||||
// defer allocation of scond map array if possible
|
game.WorldEvents.RaiseOnNewMapLoaded();
|
||||||
game.World.blocks2 = map2 == null ? map : map2;
|
net.wom.CheckSendWomID();
|
||||||
BlockInfo.SetMaxUsed(map2 == null ? 255 : 767);
|
|
||||||
}
|
map = null;
|
||||||
#endif
|
gzipStream.Dispose();
|
||||||
game.WorldEvents.RaiseOnNewMapLoaded();
|
gzipStream = null;
|
||||||
net.wom.CheckSendWomID();
|
#if !ONLY_8BIT
|
||||||
|
map2 = null;
|
||||||
map = null;
|
gzipStream2.Dispose();
|
||||||
gzipStream.Dispose();
|
gzipStream2 = null;
|
||||||
gzipStream = null;
|
#endif
|
||||||
#if !ONLY_8BIT
|
GC.Collect();
|
||||||
map2 = null;
|
}
|
||||||
gzipStream2.Dispose();
|
|
||||||
gzipStream2 = null;
|
void HandleSetBlock() {
|
||||||
#endif
|
int x = reader.ReadUInt16();
|
||||||
GC.Collect();
|
int y = reader.ReadUInt16();
|
||||||
}
|
int z = reader.ReadUInt16();
|
||||||
|
BlockID block = reader.ReadBlock();
|
||||||
void HandleSetBlock() {
|
if (game.World.IsValidPos(x, y, z)) {
|
||||||
int x = reader.ReadUInt16();
|
game.UpdateBlock(x, y, z, block);
|
||||||
int y = reader.ReadUInt16();
|
}
|
||||||
int z = reader.ReadUInt16();
|
}
|
||||||
BlockID block = reader.ReadBlock();
|
|
||||||
if (game.World.IsValidPos(x, y, z)) {
|
void HandleAddEntity() {
|
||||||
game.UpdateBlock(x, y, z, block);
|
byte id = reader.ReadUInt8();
|
||||||
}
|
string name = reader.ReadString();
|
||||||
}
|
string skin = name;
|
||||||
|
CheckName(id, ref name, ref skin);
|
||||||
void HandleAddEntity() {
|
AddEntity(id, name, skin, true);
|
||||||
byte id = reader.ReadUInt8();
|
|
||||||
string name = reader.ReadString();
|
// Workaround for some servers that declare they support ExtPlayerList,
|
||||||
string skin = name;
|
// but doesn't send ExtAddPlayerName packets.
|
||||||
CheckName(id, ref name, ref skin);
|
AddTablistEntry(id, name, name, "Players", 0);
|
||||||
AddEntity(id, name, skin, true);
|
classicTabList[id >> 3] |= (byte)(1 << (id & 0x7));
|
||||||
|
}
|
||||||
// Workaround for some servers that declare they support ExtPlayerList,
|
|
||||||
// but doesn't send ExtAddPlayerName packets.
|
void HandleEntityTeleport() {
|
||||||
AddTablistEntry(id, name, name, "Players", 0);
|
byte id = reader.ReadUInt8();
|
||||||
classicTabList[id >> 3] |= (byte)(1 << (id & 0x7));
|
ReadAbsoluteLocation(id, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleEntityTeleport() {
|
void HandleRelPosAndOrientationUpdate() {
|
||||||
byte id = reader.ReadUInt8();
|
byte id = reader.ReadUInt8();
|
||||||
ReadAbsoluteLocation(id, true);
|
Vector3 v;
|
||||||
}
|
v.X = reader.ReadInt8() / 32f;
|
||||||
|
v.Y = reader.ReadInt8() / 32f;
|
||||||
void HandleRelPosAndOrientationUpdate() {
|
v.Z = reader.ReadInt8() / 32f;
|
||||||
byte id = reader.ReadUInt8();
|
|
||||||
Vector3 v;
|
float rotY = (float)Utils.PackedToDegrees(reader.ReadUInt8());
|
||||||
v.X = reader.ReadInt8() / 32f;
|
float headX = (float)Utils.PackedToDegrees(reader.ReadUInt8());
|
||||||
v.Y = reader.ReadInt8() / 32f;
|
LocationUpdate update = LocationUpdate.MakePosAndOri(v, rotY, headX, true);
|
||||||
v.Z = reader.ReadInt8() / 32f;
|
UpdateLocation(id, update, true);
|
||||||
|
}
|
||||||
float rotY = (float)Utils.PackedToDegrees(reader.ReadUInt8());
|
|
||||||
float headX = (float)Utils.PackedToDegrees(reader.ReadUInt8());
|
void HandleRelPositionUpdate() {
|
||||||
LocationUpdate update = LocationUpdate.MakePosAndOri(v, rotY, headX, true);
|
byte id = reader.ReadUInt8();
|
||||||
UpdateLocation(id, update, true);
|
Vector3 v;
|
||||||
}
|
v.X = reader.ReadInt8() / 32f;
|
||||||
|
v.Y = reader.ReadInt8() / 32f;
|
||||||
void HandleRelPositionUpdate() {
|
v.Z = reader.ReadInt8() / 32f;
|
||||||
byte id = reader.ReadUInt8();
|
|
||||||
Vector3 v;
|
LocationUpdate update = LocationUpdate.MakePos(v, true);
|
||||||
v.X = reader.ReadInt8() / 32f;
|
UpdateLocation(id, update, true);
|
||||||
v.Y = reader.ReadInt8() / 32f;
|
}
|
||||||
v.Z = reader.ReadInt8() / 32f;
|
|
||||||
|
void HandleOrientationUpdate() {
|
||||||
LocationUpdate update = LocationUpdate.MakePos(v, true);
|
byte id = reader.ReadUInt8();
|
||||||
UpdateLocation(id, update, true);
|
float rotY = (float)Utils.PackedToDegrees(reader.ReadUInt8());
|
||||||
}
|
float headX = (float)Utils.PackedToDegrees(reader.ReadUInt8());
|
||||||
|
|
||||||
void HandleOrientationUpdate() {
|
LocationUpdate update = LocationUpdate.MakeOri(rotY, headX);
|
||||||
byte id = reader.ReadUInt8();
|
UpdateLocation(id, update, true);
|
||||||
float rotY = (float)Utils.PackedToDegrees(reader.ReadUInt8());
|
}
|
||||||
float headX = (float)Utils.PackedToDegrees(reader.ReadUInt8());
|
|
||||||
|
void HandleRemoveEntity() {
|
||||||
LocationUpdate update = LocationUpdate.MakeOri(rotY, headX);
|
byte id = reader.ReadUInt8();
|
||||||
UpdateLocation(id, update, true);
|
RemoveEntity(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleRemoveEntity() {
|
void HandleMessage() {
|
||||||
byte id = reader.ReadUInt8();
|
byte type = reader.ReadUInt8();
|
||||||
RemoveEntity(id);
|
// Original vanilla server uses player ids in message types, 255 for server messages.
|
||||||
}
|
bool prepend = !net.cpeData.useMessageTypes && type == 0xFF;
|
||||||
|
|
||||||
void HandleMessage() {
|
if (!net.cpeData.useMessageTypes) type = (byte)MessageType.Normal;
|
||||||
byte type = reader.ReadUInt8();
|
string text = reader.ReadChatString(ref type);
|
||||||
// Original vanilla server uses player ids in message types, 255 for server messages.
|
if (prepend) text = "&e" + text;
|
||||||
bool prepend = !net.cpeData.useMessageTypes && type == 0xFF;
|
|
||||||
|
if (!Utils.CaselessStarts(text, "^detail.user")) {
|
||||||
if (!net.cpeData.useMessageTypes) type = (byte)MessageType.Normal;
|
game.Chat.Add(text, (MessageType)type);
|
||||||
string text = reader.ReadChatString(ref type);
|
}
|
||||||
if (prepend) text = "&e" + text;
|
}
|
||||||
|
|
||||||
if (!Utils.CaselessStarts(text, "^detail.user")) {
|
void HandleKick() {
|
||||||
game.Chat.Add(text, (MessageType)type);
|
string reason = reader.ReadString();
|
||||||
}
|
game.Disconnect("&eLost connection to the server", reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleKick() {
|
void HandleSetPermission() {
|
||||||
string reason = reader.ReadString();
|
game.LocalPlayer.Hacks.SetUserType(reader.ReadUInt8(), !net.cpeData.blockPerms);
|
||||||
game.Disconnect("&eLost connection to the server", reason);
|
game.LocalPlayer.Hacks.UpdateHacksState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleSetPermission() {
|
internal void ReadAbsoluteLocation(byte id, bool interpolate) {
|
||||||
game.LocalPlayer.Hacks.SetUserType(reader.ReadUInt8(), !net.cpeData.blockPerms);
|
Vector3 P = reader.ReadPosition(id);
|
||||||
game.LocalPlayer.Hacks.UpdateHacksState();
|
float rotY = (float)Utils.PackedToDegrees(reader.ReadUInt8());
|
||||||
}
|
float headX = (float)Utils.PackedToDegrees(reader.ReadUInt8());
|
||||||
|
|
||||||
internal void ReadAbsoluteLocation(byte id, bool interpolate) {
|
if (id == EntityList.SelfID) receivedFirstPosition = true;
|
||||||
Vector3 P = reader.ReadPosition(id);
|
LocationUpdate update = LocationUpdate.MakePosAndOri(P, rotY, headX, false);
|
||||||
float rotY = (float)Utils.PackedToDegrees(reader.ReadUInt8());
|
UpdateLocation(id, update, interpolate);
|
||||||
float headX = (float)Utils.PackedToDegrees(reader.ReadUInt8());
|
}
|
||||||
|
#endregion
|
||||||
if (id == EntityList.SelfID) receivedFirstPosition = true;
|
|
||||||
LocationUpdate update = LocationUpdate.MakePosAndOri(P, rotY, headX, false);
|
#region Write
|
||||||
UpdateLocation(id, update, interpolate);
|
|
||||||
}
|
internal void WriteChat(string text, bool partial) {
|
||||||
#endregion
|
int payload = !net.SupportsPartialMessages ? EntityList.SelfID : (partial ? 1 : 0);
|
||||||
|
writer.WriteUInt8((byte)Opcode.Message);
|
||||||
#region Write
|
writer.WriteUInt8((byte)payload);
|
||||||
|
writer.WriteString(text);
|
||||||
internal void WriteChat(string text, bool partial) {
|
}
|
||||||
int payload = !net.SupportsPartialMessages ? EntityList.SelfID : (partial ? 1 : 0);
|
|
||||||
writer.WriteUInt8((byte)Opcode.Message);
|
internal void WritePosition(Vector3 pos, float rotY, float headX) {
|
||||||
writer.WriteUInt8((byte)payload);
|
int payload = net.cpeData.sendHeldBlock ? game.Inventory.Selected : EntityList.SelfID;
|
||||||
writer.WriteString(text);
|
writer.WriteUInt8((byte)Opcode.EntityTeleport);
|
||||||
}
|
|
||||||
|
writer.WriteBlock((BlockID)payload); // held block when using HeldBlock, otherwise just 255
|
||||||
internal void WritePosition(Vector3 pos, float rotY, float headX) {
|
writer.WritePosition(pos);
|
||||||
int payload = net.cpeData.sendHeldBlock ? game.Inventory.Selected : EntityList.SelfID;
|
writer.WriteUInt8(Utils.DegreesToPacked(rotY));
|
||||||
writer.WriteUInt8((byte)Opcode.EntityTeleport);
|
writer.WriteUInt8(Utils.DegreesToPacked(headX));
|
||||||
|
}
|
||||||
writer.WriteBlock((BlockID)payload); // held block when using HeldBlock, otherwise just 255
|
|
||||||
writer.WritePosition(pos);
|
internal void WriteSetBlock(int x, int y, int z, bool place, BlockID block) {
|
||||||
writer.WriteUInt8(Utils.DegreesToPacked(rotY));
|
writer.WriteUInt8((byte)Opcode.SetBlockClient);
|
||||||
writer.WriteUInt8(Utils.DegreesToPacked(headX));
|
writer.WriteInt16((short)x);
|
||||||
}
|
writer.WriteInt16((short)y);
|
||||||
|
writer.WriteInt16((short)z);
|
||||||
internal void WriteSetBlock(int x, int y, int z, bool place, BlockID block) {
|
writer.WriteUInt8(place ? (byte)1 : (byte)0);
|
||||||
writer.WriteUInt8((byte)Opcode.SetBlockClient);
|
writer.WriteBlock(block);
|
||||||
writer.WriteInt16((short)x);
|
}
|
||||||
writer.WriteInt16((short)y);
|
|
||||||
writer.WriteInt16((short)z);
|
internal void WriteLogin(string username, string verKey) {
|
||||||
writer.WriteUInt8(place ? (byte)1 : (byte)0);
|
byte payload = game.UseCPE ? (byte)0x42 : (byte)0x00;
|
||||||
writer.WriteBlock(block);
|
writer.WriteUInt8((byte)Opcode.Handshake);
|
||||||
}
|
|
||||||
|
writer.WriteUInt8(7); // protocol version
|
||||||
internal void WriteLogin(string username, string verKey) {
|
writer.WriteString(username);
|
||||||
byte payload = game.UseCPE ? (byte)0x42 : (byte)0x00;
|
writer.WriteString(verKey);
|
||||||
writer.WriteUInt8((byte)Opcode.Handshake);
|
writer.WriteUInt8(payload);
|
||||||
|
}
|
||||||
writer.WriteUInt8(7); // protocol version
|
|
||||||
writer.WriteString(username);
|
#endregion
|
||||||
writer.WriteString(verKey);
|
}
|
||||||
writer.WriteUInt8(payload);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -67,9 +67,9 @@ namespace ClassicalSharp {
|
|||||||
int cenX = topLeft.X + game.Width / 2;
|
int cenX = topLeft.X + game.Width / 2;
|
||||||
int cenY = topLeft.Y + game.Height / 2;
|
int cenY = topLeft.Y + game.Height / 2;
|
||||||
|
|
||||||
game.DesktopCursorPos = new Point(cenX, cenY);
|
game.window.DesktopCursorPos = new Point(cenX, cenY);
|
||||||
// Fixes issues with large DPI displays on Windows >= 8.0.
|
// Fixes issues with large DPI displays on Windows >= 8.0.
|
||||||
previous = game.DesktopCursorPos;
|
previous = game.window.DesktopCursorPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void RegrabMouse() {
|
public override void RegrabMouse() {
|
||||||
@ -127,8 +127,8 @@ namespace ClassicalSharp {
|
|||||||
public override void UpdateMouse() {
|
public override void UpdateMouse() {
|
||||||
if (game.Gui.ActiveScreen.HandlesAllInput) {
|
if (game.Gui.ActiveScreen.HandlesAllInput) {
|
||||||
delta = Point.Empty;
|
delta = Point.Empty;
|
||||||
} else if (game.Focused) {
|
} else if (game.window.Focused) {
|
||||||
Point pos = game.DesktopCursorPos;
|
Point pos = game.window.DesktopCursorPos;
|
||||||
delta = new Point(pos.X - previous.X, pos.Y - previous.Y);
|
delta = new Point(pos.X - previous.X, pos.Y - previous.Y);
|
||||||
CentreMousePosition();
|
CentreMousePosition();
|
||||||
}
|
}
|
||||||
|
@ -120,21 +120,6 @@ void Game_SetDefaultTexturePack(STRING_PURE String* texPack) {
|
|||||||
Options_Set(OPT_DEFAULT_TEX_PACK, texPack);
|
Options_Set(OPT_DEFAULT_TEX_PACK, texPack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool game_CursorVisible = true, game_realCursorVisible = true;
|
|
||||||
bool Game_GetCursorVisible(void) { return game_CursorVisible; }
|
|
||||||
bool Game_GetRealCursorVisible(void) { return game_realCursorVisible; }
|
|
||||||
void Game_SetCursorVisible(bool visible) {
|
|
||||||
/* Defer mouse visibility changes */
|
|
||||||
game_realCursorVisible = visible;
|
|
||||||
if (Gui_OverlaysCount > 0) return;
|
|
||||||
|
|
||||||
/* Only set the value when it has changed */
|
|
||||||
if (game_CursorVisible == visible) return;
|
|
||||||
Window_SetCursorVisible(visible);
|
|
||||||
game_CursorVisible = visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Game_ChangeTerrainAtlas(struct Bitmap* atlas) {
|
bool Game_ChangeTerrainAtlas(struct Bitmap* atlas) {
|
||||||
String terrain = String_FromConst("terrain.png");
|
String terrain = String_FromConst("terrain.png");
|
||||||
if (!Game_ValidateBitmap(&terrain, atlas)) return false;
|
if (!Game_ValidateBitmap(&terrain, atlas)) return false;
|
||||||
|
@ -76,9 +76,6 @@ Real32 Game_GetChatScale(void);
|
|||||||
|
|
||||||
void Game_GetDefaultTexturePack(STRING_TRANSIENT String* texPack);
|
void Game_GetDefaultTexturePack(STRING_TRANSIENT String* texPack);
|
||||||
void Game_SetDefaultTexturePack(STRING_PURE String* texPack);
|
void Game_SetDefaultTexturePack(STRING_PURE String* texPack);
|
||||||
bool Game_GetCursorVisible(void);
|
|
||||||
bool Game_GetRealCursorVisible(void);
|
|
||||||
void Game_SetCursorVisible(bool visible);
|
|
||||||
|
|
||||||
bool Game_ChangeTerrainAtlas(struct Bitmap* atlas);
|
bool Game_ChangeTerrainAtlas(struct Bitmap* atlas);
|
||||||
void Game_SetViewDistance(Int32 distance, bool userDist);
|
void Game_SetViewDistance(Int32 distance, bool userDist);
|
||||||
|
@ -42,7 +42,7 @@ void GuiElement_Reset(struct GuiElem* elem) {
|
|||||||
|
|
||||||
void Screen_Reset(struct Screen* screen) {
|
void Screen_Reset(struct Screen* screen) {
|
||||||
GuiElement_Reset((struct GuiElem*)screen);
|
GuiElement_Reset((struct GuiElem*)screen);
|
||||||
screen->HandlesAllInput = false;
|
screen->HandlesAllInput = true;
|
||||||
screen->BlocksWorld = false;
|
screen->BlocksWorld = false;
|
||||||
screen->HidesHUD = false;
|
screen->HidesHUD = false;
|
||||||
screen->RenderHUDOver = false;
|
screen->RenderHUDOver = false;
|
||||||
@ -147,16 +147,10 @@ void Gui_FreeActive(void) {
|
|||||||
|
|
||||||
void Gui_SetActive(struct Screen* screen) {
|
void Gui_SetActive(struct Screen* screen) {
|
||||||
InputHandler_ScreenChanged(Gui_Active, screen);
|
InputHandler_ScreenChanged(Gui_Active, screen);
|
||||||
|
|
||||||
if (!screen) {
|
|
||||||
Game_SetCursorVisible(false);
|
|
||||||
if (Window_Focused) { Camera_Active->RegrabMouse(); }
|
|
||||||
} else if (!Gui_Active) {
|
|
||||||
Game_SetCursorVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (screen) { Elem_Init(screen); }
|
if (screen) { Elem_Init(screen); }
|
||||||
|
|
||||||
Gui_Active = screen;
|
Gui_Active = screen;
|
||||||
|
Gui_CalcCursorVisible();
|
||||||
}
|
}
|
||||||
void Gui_RefreshHud(void) { Elem_Recreate(Gui_HUD); }
|
void Gui_RefreshHud(void) { Elem_Recreate(Gui_HUD); }
|
||||||
|
|
||||||
@ -164,8 +158,6 @@ void Gui_ShowOverlay(struct Screen* overlay, bool atFront) {
|
|||||||
if (Gui_OverlaysCount == GUI_MAX_OVERLAYS) {
|
if (Gui_OverlaysCount == GUI_MAX_OVERLAYS) {
|
||||||
ErrorHandler_Fail("Cannot have more than 6 overlays");
|
ErrorHandler_Fail("Cannot have more than 6 overlays");
|
||||||
}
|
}
|
||||||
bool visible = Game_GetCursorVisible();
|
|
||||||
if (!Gui_OverlaysCount) Game_SetCursorVisible(true);
|
|
||||||
|
|
||||||
if (atFront) {
|
if (atFront) {
|
||||||
Int32 i;
|
Int32 i;
|
||||||
@ -179,8 +171,8 @@ void Gui_ShowOverlay(struct Screen* overlay, bool atFront) {
|
|||||||
}
|
}
|
||||||
Gui_OverlaysCount++;
|
Gui_OverlaysCount++;
|
||||||
|
|
||||||
if (Gui_OverlaysCount == 1) Game_SetCursorVisible(visible); /* Save cursor visibility state */
|
|
||||||
Elem_Init(overlay);
|
Elem_Init(overlay);
|
||||||
|
Gui_CalcCursorVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
Int32 Gui_IndexOverlay(struct Screen* overlay) {
|
Int32 Gui_IndexOverlay(struct Screen* overlay) {
|
||||||
@ -202,9 +194,7 @@ void Gui_FreeOverlay(struct Screen* overlay) {
|
|||||||
|
|
||||||
Gui_OverlaysCount--;
|
Gui_OverlaysCount--;
|
||||||
Gui_Overlays[Gui_OverlaysCount] = NULL;
|
Gui_Overlays[Gui_OverlaysCount] = NULL;
|
||||||
|
Gui_CalcCursorVisible();
|
||||||
if (!Gui_OverlaysCount) { Game_SetCursorVisible(Game_GetRealCursorVisible()); }
|
|
||||||
Camera_Active->RegrabMouse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gui_RenderGui(Real64 delta) {
|
void Gui_RenderGui(Real64 delta) {
|
||||||
@ -233,6 +223,17 @@ void Gui_OnResize(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool gui_cursorVisible = true;
|
||||||
|
void Gui_CalcCursorVisible(void) {
|
||||||
|
bool vis = Gui_GetActiveScreen()->HandlesAllInput;
|
||||||
|
if (vis == gui_cursorVisible) return;
|
||||||
|
gui_cursorVisible = vis;
|
||||||
|
|
||||||
|
Window_SetCursorVisible(vis);
|
||||||
|
if (Window_Focused)
|
||||||
|
Camera_Active->RegrabMouse();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void TextAtlas_Make(struct TextAtlas* atlas, STRING_PURE String* chars, struct FontDesc* font, STRING_PURE String* prefix) {
|
void TextAtlas_Make(struct TextAtlas* atlas, STRING_PURE String* chars, struct FontDesc* font, STRING_PURE String* prefix) {
|
||||||
struct DrawTextArgs args; DrawTextArgs_Make(&args, prefix, font, true);
|
struct DrawTextArgs args; DrawTextArgs_Make(&args, prefix, font, true);
|
||||||
|
@ -87,7 +87,7 @@ Int32 Gui_IndexOverlay(struct Screen* overlay);
|
|||||||
void Gui_FreeOverlay(struct Screen* overlay);
|
void Gui_FreeOverlay(struct Screen* overlay);
|
||||||
void Gui_RenderGui(Real64 delta);
|
void Gui_RenderGui(Real64 delta);
|
||||||
void Gui_OnResize(void);
|
void Gui_OnResize(void);
|
||||||
|
void Gui_CalcCursorVisible(void);
|
||||||
|
|
||||||
#define TEXTATLAS_MAX_WIDTHS 16
|
#define TEXTATLAS_MAX_WIDTHS 16
|
||||||
struct TextAtlas {
|
struct TextAtlas {
|
||||||
|
@ -523,7 +523,6 @@ struct ListScreen* ListScreen_MakeInstance(void) {
|
|||||||
screen->VTABLE->Init = ListScreen_Init;
|
screen->VTABLE->Init = ListScreen_Init;
|
||||||
screen->VTABLE->Render = ListScreen_Render;
|
screen->VTABLE->Render = ListScreen_Render;
|
||||||
screen->VTABLE->Free = ListScreen_Free;
|
screen->VTABLE->Free = ListScreen_Free;
|
||||||
screen->HandlesAllInput = true;
|
|
||||||
return screen;
|
return screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -622,7 +621,6 @@ static void MenuScreen_MakeInstance(struct MenuScreen* screen, struct Widget** w
|
|||||||
screen->VTABLE->Render = MenuScreen_Render;
|
screen->VTABLE->Render = MenuScreen_Render;
|
||||||
screen->VTABLE->Free = MenuScreen_Free;
|
screen->VTABLE->Free = MenuScreen_Free;
|
||||||
|
|
||||||
screen->HandlesAllInput = true;
|
|
||||||
screen->Widgets = widgets;
|
screen->Widgets = widgets;
|
||||||
screen->WidgetsCount = count;
|
screen->WidgetsCount = count;
|
||||||
screen->ContextLost = MenuScreen_ContextLost;
|
screen->ContextLost = MenuScreen_ContextLost;
|
||||||
|
@ -312,7 +312,7 @@ UInt8 mapSize[4];
|
|||||||
UInt8* map;
|
UInt8* map;
|
||||||
struct Stream mapPartStream;
|
struct Stream mapPartStream;
|
||||||
struct Screen* prevScreen;
|
struct Screen* prevScreen;
|
||||||
bool prevCursorVisible, receivedFirstPosition;
|
bool receivedFirstPosition;
|
||||||
|
|
||||||
void Classic_WriteChat(struct Stream* stream, STRING_PURE String* text, bool partial) {
|
void Classic_WriteChat(struct Stream* stream, STRING_PURE String* text, bool partial) {
|
||||||
Int32 payload = !ServerConnection_SupportsPartialMessages ? ENTITIES_SELF_ID : (partial ? 1 : 0);
|
Int32 payload = !ServerConnection_SupportsPartialMessages ? ENTITIES_SELF_ID : (partial ? 1 : 0);
|
||||||
@ -385,7 +385,6 @@ static void Classic_StartLoading(struct Stream* stream) {
|
|||||||
Gui_FreeActive();
|
Gui_FreeActive();
|
||||||
prevScreen = NULL;
|
prevScreen = NULL;
|
||||||
}
|
}
|
||||||
prevCursorVisible = Game_GetCursorVisible();
|
|
||||||
|
|
||||||
Gui_SetActive(LoadingScreen_MakeInstance(&ServerConnection_ServerName, &ServerConnection_ServerMOTD));
|
Gui_SetActive(LoadingScreen_MakeInstance(&ServerConnection_ServerName, &ServerConnection_ServerMOTD));
|
||||||
WoM_CheckMotd();
|
WoM_CheckMotd();
|
||||||
@ -458,10 +457,8 @@ static void Classic_LevelDataChunk(struct Stream* stream) {
|
|||||||
static void Classic_LevelFinalise(struct Stream* stream) {
|
static void Classic_LevelFinalise(struct Stream* stream) {
|
||||||
Gui_ReplaceActive(NULL);
|
Gui_ReplaceActive(NULL);
|
||||||
Gui_Active = prevScreen;
|
Gui_Active = prevScreen;
|
||||||
if (prevScreen && prevCursorVisible != Game_GetCursorVisible()) {
|
|
||||||
Game_SetCursorVisible(prevCursorVisible);
|
|
||||||
}
|
|
||||||
prevScreen = NULL;
|
prevScreen = NULL;
|
||||||
|
Gui_CalcCursorVisible();
|
||||||
|
|
||||||
Int32 mapWidth = Stream_ReadU16_BE(stream);
|
Int32 mapWidth = Stream_ReadU16_BE(stream);
|
||||||
Int32 mapHeight = Stream_ReadU16_BE(stream);
|
Int32 mapHeight = Stream_ReadU16_BE(stream);
|
||||||
|
@ -25,7 +25,7 @@ struct InventoryScreen {
|
|||||||
Screen_Layout
|
Screen_Layout
|
||||||
struct FontDesc Font;
|
struct FontDesc Font;
|
||||||
struct TableWidget Table;
|
struct TableWidget Table;
|
||||||
bool ReleasedInv;
|
bool ReleasedInv, DeferredSelect;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StatusScreen {
|
struct StatusScreen {
|
||||||
@ -126,6 +126,18 @@ static void InventoryScreen_ContextRecreated(void* obj) {
|
|||||||
Elem_Recreate(&screen->Table);
|
Elem_Recreate(&screen->Table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void InventoryScreen_MoveToSelected(struct InventoryScreen* screen) {
|
||||||
|
struct TableWidget* table = &screen->Table;
|
||||||
|
TableWidget_SetBlockTo(table, Inventory_SelectedBlock);
|
||||||
|
Elem_Recreate(table);
|
||||||
|
screen->DeferredSelect = false;
|
||||||
|
|
||||||
|
/* User is holding invalid block */
|
||||||
|
if (table->SelectedIndex == -1) {
|
||||||
|
TableWidget_MakeDescTex(table, Inventory_SelectedBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void InventoryScreen_Init(struct GuiElem* elem) {
|
static void InventoryScreen_Init(struct GuiElem* elem) {
|
||||||
struct InventoryScreen* screen = (struct InventoryScreen*)elem;
|
struct InventoryScreen* screen = (struct InventoryScreen*)elem;
|
||||||
Font_Make(&screen->Font, &Game_FontName, 16, FONT_STYLE_NORMAL);
|
Font_Make(&screen->Font, &Game_FontName, 16, FONT_STYLE_NORMAL);
|
||||||
@ -135,10 +147,10 @@ static void InventoryScreen_Init(struct GuiElem* elem) {
|
|||||||
screen->Table.ElementsPerRow = Game_PureClassic ? 9 : 10;
|
screen->Table.ElementsPerRow = Game_PureClassic ? 9 : 10;
|
||||||
Elem_Init(&screen->Table);
|
Elem_Init(&screen->Table);
|
||||||
|
|
||||||
/* User is holding invalid block */
|
/* Can't immediately move to selected here, because cursor visibility
|
||||||
if (screen->Table.SelectedIndex == -1) {
|
might be toggled after Init() is called. This causes the cursor to
|
||||||
TableWidget_MakeDescTex(&screen->Table, Inventory_SelectedBlock);
|
be moved back to the middle of the window. */
|
||||||
}
|
screen->DeferredSelect = true;
|
||||||
|
|
||||||
Key_KeyRepeat = true;
|
Key_KeyRepeat = true;
|
||||||
Event_RegisterVoid(&BlockEvents_PermissionsChanged, screen, InventoryScreen_OnBlockChanged);
|
Event_RegisterVoid(&BlockEvents_PermissionsChanged, screen, InventoryScreen_OnBlockChanged);
|
||||||
@ -149,6 +161,7 @@ static void InventoryScreen_Init(struct GuiElem* elem) {
|
|||||||
|
|
||||||
static void InventoryScreen_Render(struct GuiElem* elem, Real64 delta) {
|
static void InventoryScreen_Render(struct GuiElem* elem, Real64 delta) {
|
||||||
struct InventoryScreen* screen = (struct InventoryScreen*)elem;
|
struct InventoryScreen* screen = (struct InventoryScreen*)elem;
|
||||||
|
if (screen->DeferredSelect) InventoryScreen_MoveToSelected(screen);
|
||||||
Elem_Render(&screen->Table, delta);
|
Elem_Render(&screen->Table, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +251,6 @@ struct Screen* InventoryScreen_MakeInstance(void) {
|
|||||||
Mem_Set(screen, 0, sizeof(struct InventoryScreen));
|
Mem_Set(screen, 0, sizeof(struct InventoryScreen));
|
||||||
screen->VTABLE = &InventoryScreen_VTABLE;
|
screen->VTABLE = &InventoryScreen_VTABLE;
|
||||||
Screen_Reset((struct Screen*)screen);
|
Screen_Reset((struct Screen*)screen);
|
||||||
screen->HandlesAllInput = true;
|
|
||||||
|
|
||||||
screen->VTABLE->HandlesKeyDown = InventoryScreen_HandlesKeyDown;
|
screen->VTABLE->HandlesKeyDown = InventoryScreen_HandlesKeyDown;
|
||||||
screen->VTABLE->HandlesKeyUp = InventoryScreen_HandlesKeyUp;
|
screen->VTABLE->HandlesKeyUp = InventoryScreen_HandlesKeyUp;
|
||||||
@ -424,6 +436,7 @@ struct Screen* StatusScreen_MakeInstance(void) {
|
|||||||
Mem_Set(screen, 0, sizeof(struct StatusScreen));
|
Mem_Set(screen, 0, sizeof(struct StatusScreen));
|
||||||
screen->VTABLE = &StatusScreen_VTABLE;
|
screen->VTABLE = &StatusScreen_VTABLE;
|
||||||
Screen_Reset((struct Screen*)screen);
|
Screen_Reset((struct Screen*)screen);
|
||||||
|
screen->HandlesAllInput = false;
|
||||||
|
|
||||||
screen->OnResize = StatusScreen_OnResize;
|
screen->OnResize = StatusScreen_OnResize;
|
||||||
screen->VTABLE->Init = StatusScreen_Init;
|
screen->VTABLE->Init = StatusScreen_Init;
|
||||||
@ -592,7 +605,6 @@ static void LoadingScreen_Make(struct LoadingScreen* screen, struct GuiElementVT
|
|||||||
Mem_Set(screen, 0, sizeof(struct LoadingScreen));
|
Mem_Set(screen, 0, sizeof(struct LoadingScreen));
|
||||||
screen->VTABLE = vtable;
|
screen->VTABLE = vtable;
|
||||||
Screen_Reset((struct Screen*)screen);
|
Screen_Reset((struct Screen*)screen);
|
||||||
screen->HandlesAllInput = true;
|
|
||||||
|
|
||||||
screen->VTABLE->HandlesKeyDown = LoadingScreen_HandlesKeyDown;
|
screen->VTABLE->HandlesKeyDown = LoadingScreen_HandlesKeyDown;
|
||||||
screen->VTABLE->HandlesKeyPress = LoadingScreen_HandlesKeyPress;
|
screen->VTABLE->HandlesKeyPress = LoadingScreen_HandlesKeyPress;
|
||||||
@ -721,10 +733,10 @@ static void ChatScreen_UpdateAltTextY(struct ChatScreen* screen) {
|
|||||||
static void ChatScreen_SetHandlesAllInput(struct ChatScreen* screen, bool handles) {
|
static void ChatScreen_SetHandlesAllInput(struct ChatScreen* screen, bool handles) {
|
||||||
screen->HandlesAllInput = handles;
|
screen->HandlesAllInput = handles;
|
||||||
Gui_HUD->HandlesAllInput = handles;
|
Gui_HUD->HandlesAllInput = handles;
|
||||||
|
Gui_CalcCursorVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ChatScreen_OpenInput(struct ChatScreen* screen, STRING_PURE String* initialText) {
|
static void ChatScreen_OpenInput(struct ChatScreen* screen, STRING_PURE String* initialText) {
|
||||||
Game_SetCursorVisible(true);
|
|
||||||
screen->SuppressNextPress = true;
|
screen->SuppressNextPress = true;
|
||||||
ChatScreen_SetHandlesAllInput(screen, true);
|
ChatScreen_SetHandlesAllInput(screen, true);
|
||||||
Key_KeyRepeat = true;
|
Key_KeyRepeat = true;
|
||||||
@ -908,9 +920,6 @@ static bool ChatScreen_HandlesKeyDown(struct GuiElem* elem, Key key) {
|
|||||||
if (screen->HandlesAllInput) { /* text input bar */
|
if (screen->HandlesAllInput) { /* text input bar */
|
||||||
if (key == KeyBind_Get(KeyBind_SendChat) || key == Key_KeypadEnter || key == KeyBind_Get(KeyBind_PauseOrExit)) {
|
if (key == KeyBind_Get(KeyBind_SendChat) || key == Key_KeypadEnter || key == KeyBind_Get(KeyBind_PauseOrExit)) {
|
||||||
ChatScreen_SetHandlesAllInput(screen, false);
|
ChatScreen_SetHandlesAllInput(screen, false);
|
||||||
/* when underlying screen is HUD, user is interacting with the world normally */
|
|
||||||
Game_SetCursorVisible(Gui_GetUnderlyingScreen() != Gui_HUD);
|
|
||||||
Camera_Active->RegrabMouse();
|
|
||||||
Key_KeyRepeat = false;
|
Key_KeyRepeat = false;
|
||||||
|
|
||||||
if (key == KeyBind_Get(KeyBind_PauseOrExit)) {
|
if (key == KeyBind_Get(KeyBind_PauseOrExit)) {
|
||||||
@ -1064,7 +1073,7 @@ static void ChatScreen_ContextLost(void* obj) {
|
|||||||
|
|
||||||
if (screen->HandlesAllInput) {
|
if (screen->HandlesAllInput) {
|
||||||
String_AppendString(&chatInInput, &screen->Input.Base.Text);
|
String_AppendString(&chatInInput, &screen->Input.Base.Text);
|
||||||
Game_SetCursorVisible(false);
|
Gui_CalcCursorVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
Elem_TryFree(&screen->Chat);
|
Elem_TryFree(&screen->Chat);
|
||||||
@ -1181,6 +1190,7 @@ struct Screen* ChatScreen_MakeInstance(void) {
|
|||||||
Mem_Set(screen, 0, sizeof(struct ChatScreen));
|
Mem_Set(screen, 0, sizeof(struct ChatScreen));
|
||||||
screen->VTABLE = &ChatScreen_VTABLE;
|
screen->VTABLE = &ChatScreen_VTABLE;
|
||||||
Screen_Reset((struct Screen*)screen);
|
Screen_Reset((struct Screen*)screen);
|
||||||
|
screen->HandlesAllInput = false;
|
||||||
|
|
||||||
screen->InputOldHeight = -1;
|
screen->InputOldHeight = -1;
|
||||||
screen->LastDownloadStatus = Int32_MinValue;
|
screen->LastDownloadStatus = Int32_MinValue;
|
||||||
@ -1378,6 +1388,7 @@ struct Screen* HUDScreen_MakeInstance(void) {
|
|||||||
Mem_Set(screen, 0, sizeof(struct HUDScreen));
|
Mem_Set(screen, 0, sizeof(struct HUDScreen));
|
||||||
screen->VTABLE = &HUDScreenVTABLE;
|
screen->VTABLE = &HUDScreenVTABLE;
|
||||||
Screen_Reset((struct Screen*)screen);
|
Screen_Reset((struct Screen*)screen);
|
||||||
|
screen->HandlesAllInput = false;
|
||||||
|
|
||||||
screen->OnResize = HUDScreen_OnResize;
|
screen->OnResize = HUDScreen_OnResize;
|
||||||
screen->VTABLE->Init = HUDScreen_Init;
|
screen->VTABLE->Init = HUDScreen_Init;
|
||||||
@ -1577,7 +1588,6 @@ struct Screen* DisconnectScreen_MakeInstance(STRING_PURE String* title, STRING_P
|
|||||||
Mem_Set(screen, 0, sizeof(struct DisconnectScreen));
|
Mem_Set(screen, 0, sizeof(struct DisconnectScreen));
|
||||||
screen->VTABLE = &DisconnectScreen_VTABLE;
|
screen->VTABLE = &DisconnectScreen_VTABLE;
|
||||||
Screen_Reset((struct Screen*)screen);
|
Screen_Reset((struct Screen*)screen);
|
||||||
screen->HandlesAllInput = true;
|
|
||||||
|
|
||||||
String titleScreen = String_InitAndClearArray(screen->TitleBuffer);
|
String titleScreen = String_InitAndClearArray(screen->TitleBuffer);
|
||||||
String_AppendString(&titleScreen, title);
|
String_AppendString(&titleScreen, title);
|
||||||
|
@ -658,8 +658,6 @@ static void TableWidget_Init(struct GuiElem* elem) {
|
|||||||
ScrollbarWidget_Create(&widget->Scroll);
|
ScrollbarWidget_Create(&widget->Scroll);
|
||||||
TableWidget_RecreateElements(widget);
|
TableWidget_RecreateElements(widget);
|
||||||
Widget_Reposition(widget);
|
Widget_Reposition(widget);
|
||||||
TableWidget_SetBlockTo(widget, Inventory_SelectedBlock);
|
|
||||||
Elem_Recreate(widget);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TableWidget_Render(struct GuiElem* elem, Real64 delta) {
|
static void TableWidget_Render(struct GuiElem* elem, Real64 delta) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user