attempt to address #534

This commit is contained in:
UnknownShadow200 2018-09-07 16:33:53 +10:00
parent a3cff6eef0
commit efca06111f
16 changed files with 84 additions and 122 deletions

View File

@ -11,7 +11,7 @@ namespace ClassicalSharp.Gui.Screens {
readonly Font titleFont, messageFont;
TextWidget titleWidget, messageWidget;
ButtonWidget reconnect;
DateTime initTime, clearTime;
DateTime initTime;
bool canReconnect;
public DisconnectScreen(Game game, string title, string message) : base(game) {
@ -29,8 +29,10 @@ namespace ClassicalSharp.Gui.Screens {
}
public override void Init() {
game.SkipClear = true;
Events.ContextLost += ContextLost;
game.Graphics.SetVSync(game, false);
game.limitMillis = 1000 / 5f;
Events.ContextLost += ContextLost;
Events.ContextRecreated += ContextRecreated;
ContextRecreated();
@ -38,17 +40,23 @@ namespace ClassicalSharp.Gui.Screens {
lastSecsLeft = delay;
}
readonly PackedCol top = new PackedCol(64, 32, 32), bottom = new PackedCol(80, 16, 16);
public override void Render(double delta) {
if (canReconnect) UpdateDelayLeft(delta);
game.Graphics.Draw2DQuad(0, 0, game.Width, game.Height, top, bottom);
// NOTE: We need to make sure that both the front and back buffers have
// definitely been drawn over, so we redraw the background multiple times.
if (DateTime.UtcNow < clearTime) Redraw(delta);
game.Graphics.Texturing = true;
titleWidget.Render(delta);
messageWidget.Render(delta);
if (canReconnect) reconnect.Render(delta);
game.Graphics.Texturing = false;
}
public override void Dispose() {
game.SkipClear = false;
Events.ContextLost -= ContextLost;
game.SetFpsLimit(game.FpsLimit);
Events.ContextLost -= ContextLost;
Events.ContextRecreated -= ContextRecreated;
ContextLost();
@ -60,7 +68,6 @@ namespace ClassicalSharp.Gui.Screens {
titleWidget.Reposition();
messageWidget.Reposition();
reconnect.Reposition();
clearTime = DateTime.UtcNow.AddSeconds(0.5);
}
public override bool HandlesKeyDown(Key key) { return key < Key.F1 || key > Key.F35; }
@ -88,7 +95,6 @@ namespace ClassicalSharp.Gui.Screens {
}
public override bool HandlesMouseScroll(float delta) { return true; }
int lastSecsLeft;
const int delay = 5;
@ -101,20 +107,8 @@ namespace ClassicalSharp.Gui.Screens {
reconnect.Set(ReconnectMessage(), titleFont);
reconnect.Disabled = secsLeft != 0;
Redraw(delta);
lastSecsLeft = secsLeft;
lastActive = reconnect.Active;
clearTime = DateTime.UtcNow.AddSeconds(0.5);
}
readonly PackedCol top = new PackedCol(64, 32, 32), bottom = new PackedCol(80, 16, 16);
void Redraw(double delta) {
game.Graphics.Draw2DQuad(0, 0, game.Width, game.Height, top, bottom);
game.Graphics.Texturing = true;
titleWidget.Render(delta);
messageWidget.Render(delta);
if (canReconnect) reconnect.Render(delta);
game.Graphics.Texturing = false;
}
string ReconnectMessage() {
@ -133,7 +127,6 @@ namespace ClassicalSharp.Gui.Screens {
protected override void ContextRecreated() {
if (game.Graphics.LostContext) return;
clearTime = DateTime.UtcNow.AddSeconds(0.5);
titleWidget = TextWidget.Create(game, title, titleFont)
.SetLocation(Anchor.Centre, Anchor.Centre, 0, -30);

View File

@ -103,7 +103,7 @@ namespace ClassicalSharp.Gui.Screens {
protected static string GetFPS(Game g) { return g.FpsLimit.ToString(); }
protected void SetFPS(Game g, string v) {
object raw = Enum.Parse(typeof(FpsLimitMethod), v);
g.SetFpsLimitMethod((FpsLimitMethod)raw);
g.SetFpsLimit((FpsLimitMethod)raw);
Options.Set(OptionsKey.FpsLimit, v);
}

View File

@ -285,8 +285,7 @@ namespace ClassicalSharp.Gui.Widgets {
protected bool ControlDown() {
return OpenTK.Configuration.RunningOnMacOS ?
(game.IsKeyDown(Key.WinLeft) || game.IsKeyDown(Key.WinRight))
: (game.IsKeyDown(Key.ControlLeft) || game.IsKeyDown(Key.ControlRight));
game.Input.WinDown : game.Input.ControlDown;
}
public override bool HandlesKeyPress(char key) {

View File

@ -180,7 +180,7 @@ namespace ClassicalSharp {
ViewBobbing = Options.GetBool(OptionsKey.ViewBobbing, true);
FpsLimitMethod method = Options.GetEnum(OptionsKey.FpsLimit, FpsLimitMethod.LimitVSync);
SetFpsLimitMethod(method);
SetFpsLimit(method);
ViewDistance = Options.GetInt(OptionsKey.ViewDist, 16, 4096, 512);
UserViewDistance = ViewDistance;
SmoothLighting = Options.GetBool(OptionsKey.SmoothLighting, false);

View File

@ -66,8 +66,6 @@ namespace ClassicalSharp {
public bool CameraClipping = true;
public bool SkipClear = false;
public IWorldLighting Lighting;
public MapRenderer MapRenderer;

View File

@ -163,9 +163,7 @@ namespace ClassicalSharp {
MapRenderer.GetChunk(cx, cy, cz).AllAir &= BlockInfo.Draw[block] == DrawType.Gas;
MapRenderer.RefreshChunk(cx, cy, cz);
}
public bool IsKeyDown(Key key) { return Input.IsKeyDown(key); }
public bool IsKeyDown(KeyBind binding) { return Input.IsKeyDown(binding); }
public bool IsMousePressed(MouseButton button) { return Input.IsMousePressed(button); }
@ -272,25 +270,23 @@ namespace ClassicalSharp {
}
Stopwatch frameTimer = new Stopwatch();
float limitMilliseconds;
public void SetFpsLimitMethod(FpsLimitMethod method) {
internal float limitMillis;
public void SetFpsLimit(FpsLimitMethod method) {
FpsLimit = method;
limitMilliseconds = 0;
limitMillis = 0;
Graphics.SetVSync(this, method == FpsLimitMethod.LimitVSync);
if (method == FpsLimitMethod.Limit120FPS)
limitMilliseconds = 1000f / 120;
limitMillis = 1000f / 120;
if (method == FpsLimitMethod.Limit60FPS)
limitMilliseconds = 1000f / 60;
limitMillis = 1000f / 60;
if (method == FpsLimitMethod.Limit30FPS)
limitMilliseconds = 1000f / 30;
limitMillis = 1000f / 30;
}
void LimitFPS() {
if (FpsLimit == FpsLimitMethod.LimitVSync) return;
double elapsed = frameTimer.Elapsed.TotalMilliseconds;
double leftOver = limitMilliseconds - elapsed;
double leftOver = limitMillis - elapsed;
if (leftOver > 0.001) // going faster than limit
Thread.Sleep((int)Math.Round(leftOver, MidpointRounding.AwayFromZero));
}
@ -318,7 +314,7 @@ namespace ClassicalSharp {
float t = (float)(entTask.Accumulator / entTask.Interval);
LocalPlayer.SetInterpPosition(t);
if (!SkipClear) Graphics.Clear();
Graphics.Clear();
CurrentCameraPos = Camera.GetPosition(t);
UpdateViewMatrix();
@ -334,7 +330,7 @@ namespace ClassicalSharp {
if (screenshotRequested) TakeScreenshot();
Graphics.EndFrame(this);
LimitFPS();
if (limitMillis != 0) LimitFPS();
}
void UpdateViewMatrix() {

View File

@ -39,14 +39,10 @@ namespace ClassicalSharp {
public bool ShiftDown { get { return IsKeyDown(Key.ShiftLeft) || IsKeyDown(Key.ShiftRight); } }
public KeyMap Keys;
public bool IsKeyDown(Key key) {
return Keyboard.Get(key);
}
public bool IsKeyDown(Key key) { return Keyboard.Get(key); }
/// <summary> Returns whether the key associated with the given key binding is currently held down. </summary>
public bool IsKeyDown(KeyBind binding) {
return Keyboard.Get(Keys[binding]);
}
public bool IsKeyDown(KeyBind binding) { return Keyboard.Get(Keys[binding]); }
public bool IsMousePressed(MouseButton button) {
bool down = Mouse.Get(button);
@ -173,11 +169,13 @@ namespace ClassicalSharp {
}
void HandleHotkey(Key key) {
string text;
bool more;
if (!HotkeyList.IsHotkey(key, game.Input, out text, out more)) return;
int idx = HotkeyList.FindPartial(key, game.Input);
if (idx == -1) return;
if (!more) {
Hotkey hotkey = HotkeyList.Hotkeys[idx];
string text = hotkey.Text;
if (!hotkey.StaysOpen) {
game.Chat.Send(text, false);
} else if (game.Gui.activeScreen == null) {
game.Gui.hudScreen.OpenInput(text);

View File

@ -56,24 +56,18 @@ namespace ClassicalSharp.Hotkeys {
/// <summary> Determines whether a hotkey is active based on the given key,
/// and the currently active control, alt, and shift modifiers </summary>
public static bool IsHotkey(Key key, InputHandler input, out string text, out bool moreInput) {
public static int FindPartial(Key key, InputHandler input) {
byte flags = 0;
if (input.ControlDown) flags |= 1;
if (input.ShiftDown) flags |= 2;
if (input.AltDown) flags |= 4;
if (input.ShiftDown) flags |= 2;
if (input.AltDown) flags |= 4;
for (int i = 0; i < Hotkeys.Count; i++) {
Hotkey hKey = Hotkeys[i];
if ((hKey.Flags & flags) == hKey.Flags && hKey.Trigger == key) {
text = hKey.Text;
moreInput = hKey.StaysOpen;
return true;
}
}
text = null;
moreInput = false;
return false;
// e.g. If holding Ctrl and Shift, a hotkey with only Ctrl flags matches
if ((hKey.Flags & flags) == hKey.Flags && hKey.Trigger == key) return i;
}
return -1;
}
const string prefix = "hotkey-";

View File

@ -337,7 +337,7 @@ static void Game_LoadOptions(void) {
Game_ViewBobbing = Options_GetBool(OPT_VIEW_BOBBING, true);
FpsLimit method = Options_GetEnum(OPT_FPS_LIMIT, 0, FpsLimit_Names, FpsLimit_Count);
Game_SetFpsLimitMethod(method);
Game_SetFpsLimit(method);
Game_ViewDistance = Options_GetInt(OPT_VIEW_DISTANCE, 16, 4096, 512);
Game_UserViewDistance = Game_ViewDistance;
@ -523,8 +523,7 @@ void Game_Load(void) {
}
UInt64 game_frameTimer;
Real32 game_limitMs;
void Game_SetFpsLimitMethod(FpsLimit method) {
void Game_SetFpsLimit(FpsLimit method) {
Game_FpsLimit = method;
game_limitMs = 0.0f;
Gfx_SetVSync(method == FpsLimit_VSync);
@ -535,9 +534,8 @@ void Game_SetFpsLimitMethod(FpsLimit method) {
}
static void Game_LimitFPS(void) {
if (Game_FpsLimit == FpsLimit_VSync) return;
Int32 elapsedMs = Stopwatch_ElapsedMicroseconds(&game_frameTimer) / 1000;
Real32 leftOver = game_limitMs - elapsedMs;
Real32 elapsedMs = Stopwatch_ElapsedMicroseconds(&game_frameTimer) / 1000.0f;
Real32 leftOver = game_limitMs - elapsedMs;
/* going faster than limit */
if (leftOver > 0.001f) {
@ -675,7 +673,7 @@ static void Game_RenderFrame(Real64 delta) {
Real32 t = (Real32)(entTask.Accumulator / entTask.Interval);
LocalPlayer_SetInterpPosition(t);
if (!Game_SkipClear) Gfx_Clear();
Gfx_Clear();
Game_CurrentCameraPos = Camera_Active->GetPosition(t);
Game_UpdateViewMatrix();
@ -691,7 +689,7 @@ static void Game_RenderFrame(Real64 delta) {
if (Game_ScreenshotRequested) Game_TakeScreenshot();
Gfx_EndFrame();
Game_LimitFPS();
if (game_limitMs) Game_LimitFPS();
}
void Game_Free(void* obj) {

View File

@ -15,7 +15,6 @@ Int32 Game_Width, Game_Height;
Real64 Game_Accumulator;
Int32 Game_ChunkUpdates;
bool Game_CameraClipping;
bool Game_SkipClear;
struct PickedPos Game_SelectedPos;
struct PickedPos Game_CameraClipPos;
GfxResourceID Game_DefaultIb;
@ -32,6 +31,7 @@ Int32 Game_UserViewDistance;
Int32 Game_Fov;
Int32 Game_DefaultFov, Game_ZoomFov;
Real32 game_limitMs;
FpsLimit Game_FpsLimit;
bool Game_ShowAxisLines;
bool Game_SimpleArmsAnim;
@ -88,7 +88,7 @@ bool Game_CanPick(BlockID block);
bool Game_UpdateTexture(GfxResourceID* texId, struct Stream* src, STRING_PURE String* file, UInt8* skinType);
bool Game_ValidateBitmap(STRING_PURE String* file, struct Bitmap* bmp);
Int32 Game_CalcRenderType(STRING_PURE String* type);
void Game_SetFpsLimitMethod(FpsLimit method);
void Game_SetFpsLimit(FpsLimit method);
void Game_Run(Int32 width, Int32 height, STRING_REF String* title, struct DisplayDevice* device);
#endif

View File

@ -215,7 +215,7 @@ static void Hotkeys_QuickSort(Int32 left, Int32 right) {
}
}
void Hotkeys_AddNewHotkey(Key trigger, UInt8 flags, STRING_PURE String* text, bool more) {
static void Hotkeys_AddNewHotkey(Key trigger, UInt8 flags, STRING_PURE String* text, bool more) {
struct HotkeyData hKey;
hKey.Trigger = trigger;
hKey.Flags = flags;
@ -233,8 +233,7 @@ void Hotkeys_AddNewHotkey(Key trigger, UInt8 flags, STRING_PURE String* text, bo
Hotkeys_QuickSort(0, HotkeysText.Count - 1);
}
void Hotkeys_RemoveText(Int32 index) {
static void Hotkeys_RemoveText(Int32 index) {
Int32 i; struct HotkeyData* hKey = HotkeysList;
for (i = 0; i < HotkeysText.Count; i++, hKey++) {
@ -243,6 +242,7 @@ void Hotkeys_RemoveText(Int32 index) {
StringsBuffer_Remove(&HotkeysText, index);
}
void Hotkeys_Add(Key trigger, UInt8 flags, STRING_PURE String* text, bool more) {
Int32 i; struct HotkeyData* hKey = HotkeysList;
@ -273,26 +273,19 @@ bool Hotkeys_Remove(Key trigger, UInt8 flags) {
return false;
}
bool Hotkeys_IsHotkey(Key key, STRING_TRANSIENT String* text, bool* moreInput) {
Int32 Hotkeys_FindPartial(Key key) {
UInt8 flags = 0;
if (Key_IsControlPressed()) flags |= HOTKEYS_FLAG_CTRL;
if (Key_IsShiftPressed()) flags |= HOTKEYS_FLAG_SHIFT;
if (Key_IsAltPressed()) flags |= HOTKEYS_FLAG_ALT;
text->length = 0;
*moreInput = false;
Int32 i;
for (i = 0; i < HotkeysText.Count; i++) {
struct HotkeyData hKey = HotkeysList[i];
if ((hKey.Flags & flags) == hKey.Flags && hKey.Trigger == key) {
String hkeyText = StringsBuffer_UNSAFE_Get(&HotkeysText, hKey.TextIndex);
String_AppendString(text, &hkeyText);
*moreInput = hKey.StaysOpen;
return true;
}
/* e.g. if holding Ctrl and Shift, a hotkey with only Ctrl flags matches */
if ((hKey.Flags & flags) == hKey.Flags && hKey.Trigger == key) return i;
}
return false;
return -1;
}
void Hotkeys_Init(void) {

View File

@ -134,7 +134,7 @@ StringsBuffer HotkeysText;
void Hotkeys_Add(Key trigger, UInt8 flags, STRING_PURE String* text, bool more);
bool Hotkeys_Remove(Key trigger, UInt8 flags);
bool Hotkeys_IsHotkey(Key key, STRING_TRANSIENT String* text, bool* moreInput);
Int32 Hotkeys_FindPartial(Key key);
void Hotkeys_Init(void);
void Hotkeys_UserRemovedHotkey(Key trigger, UInt8 flags);
void Hotkeys_UserAddedHotkey(Key trigger, UInt8 flags, bool moreInput, STRING_PURE String* text);

View File

@ -437,12 +437,13 @@ static void InputHandler_KeyDown(void* obj, Int32 key) {
} else if (InputHandler_HandleCoreKey(key)) {
} else if (LocalPlayer_HandlesKey(key)) {
} else {
char textBuffer[STRING_SIZE];
String text = String_FromArray(textBuffer);
bool more;
if (!Hotkeys_IsHotkey(key, &text, &more)) return;
Int32 idx = Hotkeys_FindPartial(key);
if (idx == -1) return;
if (!more) {
struct HotkeyData* hkey = &HotkeysList[idx];
String text = StringsBuffer_UNSAFE_Get(&HotkeysText, hkey->TextIndex);
if (!hkey->StaysOpen) {
Chat_Send(&text, false);
} else if (!Gui_Active) {
HUDScreen_OpenInput(Gui_HUD, &text);

View File

@ -1898,7 +1898,7 @@ static void MenuOptionsScreen_GetFPS(STRING_TRANSIENT String* raw) {
}
static void MenuOptionsScreen_SetFPS(STRING_PURE String* raw) {
UInt32 method = Utils_ParseEnum(raw, FpsLimit_VSync, FpsLimit_Names, Array_Elems(FpsLimit_Names));
Game_SetFpsLimitMethod(method);
Game_SetFpsLimit(method);
String value = String_FromReadonly(FpsLimit_Names[method]);
Options_Set(OPT_FPS_LIMIT, &value);

View File

@ -1259,7 +1259,7 @@ void Platform_Free(void) {
void Platform_SetWorkingDir(void) {
WCHAR dirName[FILENAME_SIZE + 1] = { 0 };
DWORD len = GetModuleFileNameW(NULL, dirName, FILENAME_SIZE);
if (len == 0) return;
if (!len) return;
/* get rid of filename at end of directory*/
for (; len > 0; len--) {

View File

@ -93,7 +93,7 @@ struct ChatScreen {
struct DisconnectScreen {
Screen_Layout
UInt64 InitTime, ClearTime;
UInt64 InitTime;
bool CanReconnect, LastActive;
Int32 LastSecsLeft;
struct ButtonWidget Reconnect;
@ -1373,18 +1373,6 @@ static void DisconnectScreen_ReconnectMessage(struct DisconnectScreen* s, STRING
String_AppendConst(msg, "Reconnect");
}
static void DisconnectScreen_Redraw(struct DisconnectScreen* s, Real64 delta) {
PackedCol top = PACKEDCOL_CONST(64, 32, 32, 255);
PackedCol bottom = PACKEDCOL_CONST(80, 16, 16, 255);
GfxCommon_Draw2DGradient(0, 0, Game_Width, Game_Height, top, bottom);
Gfx_SetTexturing(true);
Elem_Render(&s->Title, delta);
Elem_Render(&s->Message, delta);
if (s->CanReconnect) { Elem_Render(&s->Reconnect, delta); }
Gfx_SetTexturing(false);
}
static void DisconnectScreen_UpdateDelayLeft(struct DisconnectScreen* s, Real64 delta) {
Int32 elapsedMS = (Int32)(DateTime_CurrentUTC_MS() - s->InitTime);
Int32 secsLeft = (DISCONNECT_DELAY_MS - elapsedMS) / DATETIME_MILLIS_PER_SEC;
@ -1398,10 +1386,8 @@ static void DisconnectScreen_UpdateDelayLeft(struct DisconnectScreen* s, Real64
ButtonWidget_Set(&s->Reconnect, &msg, &s->TitleFont);
s->Reconnect.Disabled = secsLeft != 0;
DisconnectScreen_Redraw(s, delta);
s->LastSecsLeft = secsLeft;
s->LastActive = s->Reconnect.Active;
s->ClearTime = DateTime_CurrentUTC_MS() + 500;
}
static void DisconnectScreen_ContextLost(void* screen) {
@ -1413,7 +1399,6 @@ static void DisconnectScreen_ContextLost(void* screen) {
static void DisconnectScreen_ContextRecreated(void* screen) {
struct DisconnectScreen* s = screen;
s->ClearTime = DateTime_CurrentUTC_MS() + 500;
TextWidget_Create(&s->Title, &s->TitleStr, &s->TitleFont);
Widget_SetLocation(&s->Title, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -30);
@ -1436,7 +1421,9 @@ static void DisconnectScreen_Init(void* screen) {
Font_Make(&s->MessageFont, &Game_FontName, 16, FONT_STYLE_NORMAL);
Screen_CommonInit(s);
Game_SkipClear = true;
Gfx_SetVSync(false);
game_limitMs = 1000 / 5.0f;
s->InitTime = DateTime_CurrentUTC_MS();
s->LastSecsLeft = DISCONNECT_DELAY_MS / DATETIME_MILLIS_PER_SEC;
}
@ -1445,11 +1432,16 @@ static void DisconnectScreen_Render(void* screen, Real64 delta) {
struct DisconnectScreen* s = screen;
if (s->CanReconnect) { DisconnectScreen_UpdateDelayLeft(s, delta); }
/* NOTE: We need to make sure that both the front and back buffers have
definitely been drawn over, so we redraw the background multiple times. */
if (DateTime_CurrentUTC_MS() < s->ClearTime) {
DisconnectScreen_Redraw(s, delta);
}
PackedCol top = PACKEDCOL_CONST(64, 32, 32, 255);
PackedCol bottom = PACKEDCOL_CONST(80, 16, 16, 255);
GfxCommon_Draw2DGradient(0, 0, Game_Width, Game_Height, top, bottom);
Gfx_SetTexturing(true);
Elem_Render(&s->Title, delta);
Elem_Render(&s->Message, delta);
if (s->CanReconnect) { Elem_Render(&s->Reconnect, delta); }
Gfx_SetTexturing(false);
}
static void DisconnectScreen_Free(void* screen) {
@ -1457,7 +1449,8 @@ static void DisconnectScreen_Free(void* screen) {
Font_Free(&s->TitleFont);
Font_Free(&s->MessageFont);
Screen_CommonFree(s);
Game_SkipClear = false;
Game_SetFpsLimit(Game_FpsLimit);
}
static void DisconnectScreen_OnResize(void* screen) {
@ -1465,7 +1458,6 @@ static void DisconnectScreen_OnResize(void* screen) {
Widget_Reposition(&s->Title);
Widget_Reposition(&s->Message);
Widget_Reposition(&s->Reconnect);
s->ClearTime = DateTime_CurrentUTC_MS() + 500;
}
static bool DisconnectScreen_KeyDown(void* s, Key key) { return key < Key_F1 || key > Key_F35; }