mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-18 20:15:35 -04:00
attempt to address #534
This commit is contained in:
parent
a3cff6eef0
commit
efca06111f
@ -11,7 +11,7 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
readonly Font titleFont, messageFont;
|
readonly Font titleFont, messageFont;
|
||||||
TextWidget titleWidget, messageWidget;
|
TextWidget titleWidget, messageWidget;
|
||||||
ButtonWidget reconnect;
|
ButtonWidget reconnect;
|
||||||
DateTime initTime, clearTime;
|
DateTime initTime;
|
||||||
bool canReconnect;
|
bool canReconnect;
|
||||||
|
|
||||||
public DisconnectScreen(Game game, string title, string message) : base(game) {
|
public DisconnectScreen(Game game, string title, string message) : base(game) {
|
||||||
@ -29,8 +29,10 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override void Init() {
|
public override void Init() {
|
||||||
game.SkipClear = true;
|
game.Graphics.SetVSync(game, false);
|
||||||
Events.ContextLost += ContextLost;
|
game.limitMillis = 1000 / 5f;
|
||||||
|
|
||||||
|
Events.ContextLost += ContextLost;
|
||||||
Events.ContextRecreated += ContextRecreated;
|
Events.ContextRecreated += ContextRecreated;
|
||||||
|
|
||||||
ContextRecreated();
|
ContextRecreated();
|
||||||
@ -38,17 +40,23 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
lastSecsLeft = delay;
|
lastSecsLeft = delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readonly PackedCol top = new PackedCol(64, 32, 32), bottom = new PackedCol(80, 16, 16);
|
||||||
public override void Render(double delta) {
|
public override void Render(double delta) {
|
||||||
if (canReconnect) UpdateDelayLeft(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
|
game.Graphics.Texturing = true;
|
||||||
// definitely been drawn over, so we redraw the background multiple times.
|
titleWidget.Render(delta);
|
||||||
if (DateTime.UtcNow < clearTime) Redraw(delta);
|
messageWidget.Render(delta);
|
||||||
|
|
||||||
|
if (canReconnect) reconnect.Render(delta);
|
||||||
|
game.Graphics.Texturing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Dispose() {
|
public override void Dispose() {
|
||||||
game.SkipClear = false;
|
game.SetFpsLimit(game.FpsLimit);
|
||||||
Events.ContextLost -= ContextLost;
|
|
||||||
|
Events.ContextLost -= ContextLost;
|
||||||
Events.ContextRecreated -= ContextRecreated;
|
Events.ContextRecreated -= ContextRecreated;
|
||||||
|
|
||||||
ContextLost();
|
ContextLost();
|
||||||
@ -60,7 +68,6 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
titleWidget.Reposition();
|
titleWidget.Reposition();
|
||||||
messageWidget.Reposition();
|
messageWidget.Reposition();
|
||||||
reconnect.Reposition();
|
reconnect.Reposition();
|
||||||
clearTime = DateTime.UtcNow.AddSeconds(0.5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool HandlesKeyDown(Key key) { return key < Key.F1 || key > Key.F35; }
|
public override bool HandlesKeyDown(Key key) { return key < Key.F1 || key > Key.F35; }
|
||||||
@ -89,7 +96,6 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
|
|
||||||
public override bool HandlesMouseScroll(float delta) { return true; }
|
public override bool HandlesMouseScroll(float delta) { return true; }
|
||||||
|
|
||||||
|
|
||||||
int lastSecsLeft;
|
int lastSecsLeft;
|
||||||
const int delay = 5;
|
const int delay = 5;
|
||||||
bool lastActive = false;
|
bool lastActive = false;
|
||||||
@ -101,20 +107,8 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
reconnect.Set(ReconnectMessage(), titleFont);
|
reconnect.Set(ReconnectMessage(), titleFont);
|
||||||
reconnect.Disabled = secsLeft != 0;
|
reconnect.Disabled = secsLeft != 0;
|
||||||
|
|
||||||
Redraw(delta);
|
|
||||||
lastSecsLeft = secsLeft;
|
lastSecsLeft = secsLeft;
|
||||||
lastActive = reconnect.Active;
|
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() {
|
string ReconnectMessage() {
|
||||||
@ -133,7 +127,6 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
|
|
||||||
protected override void ContextRecreated() {
|
protected override void ContextRecreated() {
|
||||||
if (game.Graphics.LostContext) return;
|
if (game.Graphics.LostContext) return;
|
||||||
clearTime = DateTime.UtcNow.AddSeconds(0.5);
|
|
||||||
|
|
||||||
titleWidget = TextWidget.Create(game, title, titleFont)
|
titleWidget = TextWidget.Create(game, title, titleFont)
|
||||||
.SetLocation(Anchor.Centre, Anchor.Centre, 0, -30);
|
.SetLocation(Anchor.Centre, Anchor.Centre, 0, -30);
|
||||||
|
@ -103,7 +103,7 @@ namespace ClassicalSharp.Gui.Screens {
|
|||||||
protected static string GetFPS(Game g) { return g.FpsLimit.ToString(); }
|
protected static string GetFPS(Game g) { return g.FpsLimit.ToString(); }
|
||||||
protected void SetFPS(Game g, string v) {
|
protected void SetFPS(Game g, string v) {
|
||||||
object raw = Enum.Parse(typeof(FpsLimitMethod), v);
|
object raw = Enum.Parse(typeof(FpsLimitMethod), v);
|
||||||
g.SetFpsLimitMethod((FpsLimitMethod)raw);
|
g.SetFpsLimit((FpsLimitMethod)raw);
|
||||||
Options.Set(OptionsKey.FpsLimit, v);
|
Options.Set(OptionsKey.FpsLimit, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,8 +285,7 @@ namespace ClassicalSharp.Gui.Widgets {
|
|||||||
|
|
||||||
protected bool ControlDown() {
|
protected bool ControlDown() {
|
||||||
return OpenTK.Configuration.RunningOnMacOS ?
|
return OpenTK.Configuration.RunningOnMacOS ?
|
||||||
(game.IsKeyDown(Key.WinLeft) || game.IsKeyDown(Key.WinRight))
|
game.Input.WinDown : game.Input.ControlDown;
|
||||||
: (game.IsKeyDown(Key.ControlLeft) || game.IsKeyDown(Key.ControlRight));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool HandlesKeyPress(char key) {
|
public override bool HandlesKeyPress(char key) {
|
||||||
|
@ -180,7 +180,7 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
ViewBobbing = Options.GetBool(OptionsKey.ViewBobbing, true);
|
ViewBobbing = Options.GetBool(OptionsKey.ViewBobbing, true);
|
||||||
FpsLimitMethod method = Options.GetEnum(OptionsKey.FpsLimit, FpsLimitMethod.LimitVSync);
|
FpsLimitMethod method = Options.GetEnum(OptionsKey.FpsLimit, FpsLimitMethod.LimitVSync);
|
||||||
SetFpsLimitMethod(method);
|
SetFpsLimit(method);
|
||||||
ViewDistance = Options.GetInt(OptionsKey.ViewDist, 16, 4096, 512);
|
ViewDistance = Options.GetInt(OptionsKey.ViewDist, 16, 4096, 512);
|
||||||
UserViewDistance = ViewDistance;
|
UserViewDistance = ViewDistance;
|
||||||
SmoothLighting = Options.GetBool(OptionsKey.SmoothLighting, false);
|
SmoothLighting = Options.GetBool(OptionsKey.SmoothLighting, false);
|
||||||
|
@ -66,8 +66,6 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
public bool CameraClipping = true;
|
public bool CameraClipping = true;
|
||||||
|
|
||||||
public bool SkipClear = false;
|
|
||||||
|
|
||||||
public IWorldLighting Lighting;
|
public IWorldLighting Lighting;
|
||||||
|
|
||||||
public MapRenderer MapRenderer;
|
public MapRenderer MapRenderer;
|
||||||
|
@ -164,8 +164,6 @@ namespace ClassicalSharp {
|
|||||||
MapRenderer.RefreshChunk(cx, cy, cz);
|
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 IsKeyDown(KeyBind binding) { return Input.IsKeyDown(binding); }
|
||||||
|
|
||||||
public bool IsMousePressed(MouseButton button) { return Input.IsMousePressed(button); }
|
public bool IsMousePressed(MouseButton button) { return Input.IsMousePressed(button); }
|
||||||
@ -272,25 +270,23 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Stopwatch frameTimer = new Stopwatch();
|
Stopwatch frameTimer = new Stopwatch();
|
||||||
float limitMilliseconds;
|
internal float limitMillis;
|
||||||
public void SetFpsLimitMethod(FpsLimitMethod method) {
|
public void SetFpsLimit(FpsLimitMethod method) {
|
||||||
FpsLimit = method;
|
FpsLimit = method;
|
||||||
limitMilliseconds = 0;
|
limitMillis = 0;
|
||||||
Graphics.SetVSync(this, method == FpsLimitMethod.LimitVSync);
|
Graphics.SetVSync(this, method == FpsLimitMethod.LimitVSync);
|
||||||
|
|
||||||
if (method == FpsLimitMethod.Limit120FPS)
|
if (method == FpsLimitMethod.Limit120FPS)
|
||||||
limitMilliseconds = 1000f / 120;
|
limitMillis = 1000f / 120;
|
||||||
if (method == FpsLimitMethod.Limit60FPS)
|
if (method == FpsLimitMethod.Limit60FPS)
|
||||||
limitMilliseconds = 1000f / 60;
|
limitMillis = 1000f / 60;
|
||||||
if (method == FpsLimitMethod.Limit30FPS)
|
if (method == FpsLimitMethod.Limit30FPS)
|
||||||
limitMilliseconds = 1000f / 30;
|
limitMillis = 1000f / 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimitFPS() {
|
void LimitFPS() {
|
||||||
if (FpsLimit == FpsLimitMethod.LimitVSync) return;
|
|
||||||
|
|
||||||
double elapsed = frameTimer.Elapsed.TotalMilliseconds;
|
double elapsed = frameTimer.Elapsed.TotalMilliseconds;
|
||||||
double leftOver = limitMilliseconds - elapsed;
|
double leftOver = limitMillis - elapsed;
|
||||||
if (leftOver > 0.001) // going faster than limit
|
if (leftOver > 0.001) // going faster than limit
|
||||||
Thread.Sleep((int)Math.Round(leftOver, MidpointRounding.AwayFromZero));
|
Thread.Sleep((int)Math.Round(leftOver, MidpointRounding.AwayFromZero));
|
||||||
}
|
}
|
||||||
@ -318,7 +314,7 @@ namespace ClassicalSharp {
|
|||||||
float t = (float)(entTask.Accumulator / entTask.Interval);
|
float t = (float)(entTask.Accumulator / entTask.Interval);
|
||||||
LocalPlayer.SetInterpPosition(t);
|
LocalPlayer.SetInterpPosition(t);
|
||||||
|
|
||||||
if (!SkipClear) Graphics.Clear();
|
Graphics.Clear();
|
||||||
CurrentCameraPos = Camera.GetPosition(t);
|
CurrentCameraPos = Camera.GetPosition(t);
|
||||||
UpdateViewMatrix();
|
UpdateViewMatrix();
|
||||||
|
|
||||||
@ -334,7 +330,7 @@ namespace ClassicalSharp {
|
|||||||
if (screenshotRequested) TakeScreenshot();
|
if (screenshotRequested) TakeScreenshot();
|
||||||
|
|
||||||
Graphics.EndFrame(this);
|
Graphics.EndFrame(this);
|
||||||
LimitFPS();
|
if (limitMillis != 0) LimitFPS();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateViewMatrix() {
|
void UpdateViewMatrix() {
|
||||||
|
@ -39,14 +39,10 @@ namespace ClassicalSharp {
|
|||||||
public bool ShiftDown { get { return IsKeyDown(Key.ShiftLeft) || IsKeyDown(Key.ShiftRight); } }
|
public bool ShiftDown { get { return IsKeyDown(Key.ShiftLeft) || IsKeyDown(Key.ShiftRight); } }
|
||||||
|
|
||||||
public KeyMap Keys;
|
public KeyMap Keys;
|
||||||
public bool IsKeyDown(Key key) {
|
public bool IsKeyDown(Key key) { return Keyboard.Get(key); }
|
||||||
return Keyboard.Get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary> Returns whether the key associated with the given key binding is currently held down. </summary>
|
/// <summary> Returns whether the key associated with the given key binding is currently held down. </summary>
|
||||||
public bool IsKeyDown(KeyBind binding) {
|
public bool IsKeyDown(KeyBind binding) { return Keyboard.Get(Keys[binding]); }
|
||||||
return Keyboard.Get(Keys[binding]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsMousePressed(MouseButton button) {
|
public bool IsMousePressed(MouseButton button) {
|
||||||
bool down = Mouse.Get(button);
|
bool down = Mouse.Get(button);
|
||||||
@ -173,11 +169,13 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HandleHotkey(Key key) {
|
void HandleHotkey(Key key) {
|
||||||
string text;
|
int idx = HotkeyList.FindPartial(key, game.Input);
|
||||||
bool more;
|
if (idx == -1) return;
|
||||||
if (!HotkeyList.IsHotkey(key, game.Input, out text, out more)) return;
|
|
||||||
|
|
||||||
if (!more) {
|
Hotkey hotkey = HotkeyList.Hotkeys[idx];
|
||||||
|
string text = hotkey.Text;
|
||||||
|
|
||||||
|
if (!hotkey.StaysOpen) {
|
||||||
game.Chat.Send(text, false);
|
game.Chat.Send(text, false);
|
||||||
} else if (game.Gui.activeScreen == null) {
|
} else if (game.Gui.activeScreen == null) {
|
||||||
game.Gui.hudScreen.OpenInput(text);
|
game.Gui.hudScreen.OpenInput(text);
|
||||||
|
@ -56,24 +56,18 @@ namespace ClassicalSharp.Hotkeys {
|
|||||||
|
|
||||||
/// <summary> Determines whether a hotkey is active based on the given key,
|
/// <summary> Determines whether a hotkey is active based on the given key,
|
||||||
/// and the currently active control, alt, and shift modifiers </summary>
|
/// 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;
|
byte flags = 0;
|
||||||
if (input.ControlDown) flags |= 1;
|
if (input.ControlDown) flags |= 1;
|
||||||
if (input.ShiftDown) flags |= 2;
|
if (input.ShiftDown) flags |= 2;
|
||||||
if (input.AltDown) flags |= 4;
|
if (input.AltDown) flags |= 4;
|
||||||
|
|
||||||
for (int i = 0; i < Hotkeys.Count; i++) {
|
for (int i = 0; i < Hotkeys.Count; i++) {
|
||||||
Hotkey hKey = Hotkeys[i];
|
Hotkey hKey = Hotkeys[i];
|
||||||
if ((hKey.Flags & flags) == hKey.Flags && hKey.Trigger == key) {
|
// e.g. If holding Ctrl and Shift, a hotkey with only Ctrl flags matches
|
||||||
text = hKey.Text;
|
if ((hKey.Flags & flags) == hKey.Flags && hKey.Trigger == key) return i;
|
||||||
moreInput = hKey.StaysOpen;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
text = null;
|
|
||||||
moreInput = false;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const string prefix = "hotkey-";
|
const string prefix = "hotkey-";
|
||||||
|
14
src/Game.c
14
src/Game.c
@ -337,7 +337,7 @@ static void Game_LoadOptions(void) {
|
|||||||
|
|
||||||
Game_ViewBobbing = Options_GetBool(OPT_VIEW_BOBBING, true);
|
Game_ViewBobbing = Options_GetBool(OPT_VIEW_BOBBING, true);
|
||||||
FpsLimit method = Options_GetEnum(OPT_FPS_LIMIT, 0, FpsLimit_Names, FpsLimit_Count);
|
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_ViewDistance = Options_GetInt(OPT_VIEW_DISTANCE, 16, 4096, 512);
|
||||||
Game_UserViewDistance = Game_ViewDistance;
|
Game_UserViewDistance = Game_ViewDistance;
|
||||||
@ -523,8 +523,7 @@ void Game_Load(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UInt64 game_frameTimer;
|
UInt64 game_frameTimer;
|
||||||
Real32 game_limitMs;
|
void Game_SetFpsLimit(FpsLimit method) {
|
||||||
void Game_SetFpsLimitMethod(FpsLimit method) {
|
|
||||||
Game_FpsLimit = method;
|
Game_FpsLimit = method;
|
||||||
game_limitMs = 0.0f;
|
game_limitMs = 0.0f;
|
||||||
Gfx_SetVSync(method == FpsLimit_VSync);
|
Gfx_SetVSync(method == FpsLimit_VSync);
|
||||||
@ -535,9 +534,8 @@ void Game_SetFpsLimitMethod(FpsLimit method) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void Game_LimitFPS(void) {
|
static void Game_LimitFPS(void) {
|
||||||
if (Game_FpsLimit == FpsLimit_VSync) return;
|
Real32 elapsedMs = Stopwatch_ElapsedMicroseconds(&game_frameTimer) / 1000.0f;
|
||||||
Int32 elapsedMs = Stopwatch_ElapsedMicroseconds(&game_frameTimer) / 1000;
|
Real32 leftOver = game_limitMs - elapsedMs;
|
||||||
Real32 leftOver = game_limitMs - elapsedMs;
|
|
||||||
|
|
||||||
/* going faster than limit */
|
/* going faster than limit */
|
||||||
if (leftOver > 0.001f) {
|
if (leftOver > 0.001f) {
|
||||||
@ -675,7 +673,7 @@ static void Game_RenderFrame(Real64 delta) {
|
|||||||
Real32 t = (Real32)(entTask.Accumulator / entTask.Interval);
|
Real32 t = (Real32)(entTask.Accumulator / entTask.Interval);
|
||||||
LocalPlayer_SetInterpPosition(t);
|
LocalPlayer_SetInterpPosition(t);
|
||||||
|
|
||||||
if (!Game_SkipClear) Gfx_Clear();
|
Gfx_Clear();
|
||||||
Game_CurrentCameraPos = Camera_Active->GetPosition(t);
|
Game_CurrentCameraPos = Camera_Active->GetPosition(t);
|
||||||
Game_UpdateViewMatrix();
|
Game_UpdateViewMatrix();
|
||||||
|
|
||||||
@ -691,7 +689,7 @@ static void Game_RenderFrame(Real64 delta) {
|
|||||||
if (Game_ScreenshotRequested) Game_TakeScreenshot();
|
if (Game_ScreenshotRequested) Game_TakeScreenshot();
|
||||||
|
|
||||||
Gfx_EndFrame();
|
Gfx_EndFrame();
|
||||||
Game_LimitFPS();
|
if (game_limitMs) Game_LimitFPS();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game_Free(void* obj) {
|
void Game_Free(void* obj) {
|
||||||
|
@ -15,7 +15,6 @@ Int32 Game_Width, Game_Height;
|
|||||||
Real64 Game_Accumulator;
|
Real64 Game_Accumulator;
|
||||||
Int32 Game_ChunkUpdates;
|
Int32 Game_ChunkUpdates;
|
||||||
bool Game_CameraClipping;
|
bool Game_CameraClipping;
|
||||||
bool Game_SkipClear;
|
|
||||||
struct PickedPos Game_SelectedPos;
|
struct PickedPos Game_SelectedPos;
|
||||||
struct PickedPos Game_CameraClipPos;
|
struct PickedPos Game_CameraClipPos;
|
||||||
GfxResourceID Game_DefaultIb;
|
GfxResourceID Game_DefaultIb;
|
||||||
@ -32,6 +31,7 @@ Int32 Game_UserViewDistance;
|
|||||||
Int32 Game_Fov;
|
Int32 Game_Fov;
|
||||||
Int32 Game_DefaultFov, Game_ZoomFov;
|
Int32 Game_DefaultFov, Game_ZoomFov;
|
||||||
|
|
||||||
|
Real32 game_limitMs;
|
||||||
FpsLimit Game_FpsLimit;
|
FpsLimit Game_FpsLimit;
|
||||||
bool Game_ShowAxisLines;
|
bool Game_ShowAxisLines;
|
||||||
bool Game_SimpleArmsAnim;
|
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_UpdateTexture(GfxResourceID* texId, struct Stream* src, STRING_PURE String* file, UInt8* skinType);
|
||||||
bool Game_ValidateBitmap(STRING_PURE String* file, struct Bitmap* bmp);
|
bool Game_ValidateBitmap(STRING_PURE String* file, struct Bitmap* bmp);
|
||||||
Int32 Game_CalcRenderType(STRING_PURE String* type);
|
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);
|
void Game_Run(Int32 width, Int32 height, STRING_REF String* title, struct DisplayDevice* device);
|
||||||
#endif
|
#endif
|
||||||
|
21
src/Input.c
21
src/Input.c
@ -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;
|
struct HotkeyData hKey;
|
||||||
hKey.Trigger = trigger;
|
hKey.Trigger = trigger;
|
||||||
hKey.Flags = flags;
|
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);
|
Hotkeys_QuickSort(0, HotkeysText.Count - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Hotkeys_RemoveText(Int32 index) {
|
||||||
void Hotkeys_RemoveText(Int32 index) {
|
|
||||||
Int32 i; struct HotkeyData* hKey = HotkeysList;
|
Int32 i; struct HotkeyData* hKey = HotkeysList;
|
||||||
|
|
||||||
for (i = 0; i < HotkeysText.Count; i++, hKey++) {
|
for (i = 0; i < HotkeysText.Count; i++, hKey++) {
|
||||||
@ -243,6 +242,7 @@ void Hotkeys_RemoveText(Int32 index) {
|
|||||||
StringsBuffer_Remove(&HotkeysText, index);
|
StringsBuffer_Remove(&HotkeysText, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Hotkeys_Add(Key trigger, UInt8 flags, STRING_PURE String* text, bool more) {
|
void Hotkeys_Add(Key trigger, UInt8 flags, STRING_PURE String* text, bool more) {
|
||||||
Int32 i; struct HotkeyData* hKey = HotkeysList;
|
Int32 i; struct HotkeyData* hKey = HotkeysList;
|
||||||
|
|
||||||
@ -273,26 +273,19 @@ bool Hotkeys_Remove(Key trigger, UInt8 flags) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Hotkeys_IsHotkey(Key key, STRING_TRANSIENT String* text, bool* moreInput) {
|
Int32 Hotkeys_FindPartial(Key key) {
|
||||||
UInt8 flags = 0;
|
UInt8 flags = 0;
|
||||||
if (Key_IsControlPressed()) flags |= HOTKEYS_FLAG_CTRL;
|
if (Key_IsControlPressed()) flags |= HOTKEYS_FLAG_CTRL;
|
||||||
if (Key_IsShiftPressed()) flags |= HOTKEYS_FLAG_SHIFT;
|
if (Key_IsShiftPressed()) flags |= HOTKEYS_FLAG_SHIFT;
|
||||||
if (Key_IsAltPressed()) flags |= HOTKEYS_FLAG_ALT;
|
if (Key_IsAltPressed()) flags |= HOTKEYS_FLAG_ALT;
|
||||||
|
|
||||||
text->length = 0;
|
|
||||||
*moreInput = false;
|
|
||||||
|
|
||||||
Int32 i;
|
Int32 i;
|
||||||
for (i = 0; i < HotkeysText.Count; i++) {
|
for (i = 0; i < HotkeysText.Count; i++) {
|
||||||
struct HotkeyData hKey = HotkeysList[i];
|
struct HotkeyData hKey = HotkeysList[i];
|
||||||
if ((hKey.Flags & flags) == hKey.Flags && hKey.Trigger == key) {
|
/* e.g. if holding Ctrl and Shift, a hotkey with only Ctrl flags matches */
|
||||||
String hkeyText = StringsBuffer_UNSAFE_Get(&HotkeysText, hKey.TextIndex);
|
if ((hKey.Flags & flags) == hKey.Flags && hKey.Trigger == key) return i;
|
||||||
String_AppendString(text, &hkeyText);
|
|
||||||
*moreInput = hKey.StaysOpen;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hotkeys_Init(void) {
|
void Hotkeys_Init(void) {
|
||||||
|
@ -134,7 +134,7 @@ StringsBuffer HotkeysText;
|
|||||||
|
|
||||||
void Hotkeys_Add(Key trigger, UInt8 flags, STRING_PURE String* text, bool more);
|
void Hotkeys_Add(Key trigger, UInt8 flags, STRING_PURE String* text, bool more);
|
||||||
bool Hotkeys_Remove(Key trigger, UInt8 flags);
|
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_Init(void);
|
||||||
void Hotkeys_UserRemovedHotkey(Key trigger, UInt8 flags);
|
void Hotkeys_UserRemovedHotkey(Key trigger, UInt8 flags);
|
||||||
void Hotkeys_UserAddedHotkey(Key trigger, UInt8 flags, bool moreInput, STRING_PURE String* text);
|
void Hotkeys_UserAddedHotkey(Key trigger, UInt8 flags, bool moreInput, STRING_PURE String* text);
|
||||||
|
@ -437,12 +437,13 @@ static void InputHandler_KeyDown(void* obj, Int32 key) {
|
|||||||
} else if (InputHandler_HandleCoreKey(key)) {
|
} else if (InputHandler_HandleCoreKey(key)) {
|
||||||
} else if (LocalPlayer_HandlesKey(key)) {
|
} else if (LocalPlayer_HandlesKey(key)) {
|
||||||
} else {
|
} else {
|
||||||
char textBuffer[STRING_SIZE];
|
Int32 idx = Hotkeys_FindPartial(key);
|
||||||
String text = String_FromArray(textBuffer);
|
if (idx == -1) return;
|
||||||
bool more;
|
|
||||||
if (!Hotkeys_IsHotkey(key, &text, &more)) return;
|
|
||||||
|
|
||||||
if (!more) {
|
struct HotkeyData* hkey = &HotkeysList[idx];
|
||||||
|
String text = StringsBuffer_UNSAFE_Get(&HotkeysText, hkey->TextIndex);
|
||||||
|
|
||||||
|
if (!hkey->StaysOpen) {
|
||||||
Chat_Send(&text, false);
|
Chat_Send(&text, false);
|
||||||
} else if (!Gui_Active) {
|
} else if (!Gui_Active) {
|
||||||
HUDScreen_OpenInput(Gui_HUD, &text);
|
HUDScreen_OpenInput(Gui_HUD, &text);
|
||||||
|
@ -1898,7 +1898,7 @@ static void MenuOptionsScreen_GetFPS(STRING_TRANSIENT String* raw) {
|
|||||||
}
|
}
|
||||||
static void MenuOptionsScreen_SetFPS(STRING_PURE String* raw) {
|
static void MenuOptionsScreen_SetFPS(STRING_PURE String* raw) {
|
||||||
UInt32 method = Utils_ParseEnum(raw, FpsLimit_VSync, FpsLimit_Names, Array_Elems(FpsLimit_Names));
|
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]);
|
String value = String_FromReadonly(FpsLimit_Names[method]);
|
||||||
Options_Set(OPT_FPS_LIMIT, &value);
|
Options_Set(OPT_FPS_LIMIT, &value);
|
||||||
|
@ -1259,7 +1259,7 @@ void Platform_Free(void) {
|
|||||||
void Platform_SetWorkingDir(void) {
|
void Platform_SetWorkingDir(void) {
|
||||||
WCHAR dirName[FILENAME_SIZE + 1] = { 0 };
|
WCHAR dirName[FILENAME_SIZE + 1] = { 0 };
|
||||||
DWORD len = GetModuleFileNameW(NULL, dirName, FILENAME_SIZE);
|
DWORD len = GetModuleFileNameW(NULL, dirName, FILENAME_SIZE);
|
||||||
if (len == 0) return;
|
if (!len) return;
|
||||||
|
|
||||||
/* get rid of filename at end of directory*/
|
/* get rid of filename at end of directory*/
|
||||||
for (; len > 0; len--) {
|
for (; len > 0; len--) {
|
||||||
|
@ -93,7 +93,7 @@ struct ChatScreen {
|
|||||||
|
|
||||||
struct DisconnectScreen {
|
struct DisconnectScreen {
|
||||||
Screen_Layout
|
Screen_Layout
|
||||||
UInt64 InitTime, ClearTime;
|
UInt64 InitTime;
|
||||||
bool CanReconnect, LastActive;
|
bool CanReconnect, LastActive;
|
||||||
Int32 LastSecsLeft;
|
Int32 LastSecsLeft;
|
||||||
struct ButtonWidget Reconnect;
|
struct ButtonWidget Reconnect;
|
||||||
@ -1373,18 +1373,6 @@ static void DisconnectScreen_ReconnectMessage(struct DisconnectScreen* s, STRING
|
|||||||
String_AppendConst(msg, "Reconnect");
|
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) {
|
static void DisconnectScreen_UpdateDelayLeft(struct DisconnectScreen* s, Real64 delta) {
|
||||||
Int32 elapsedMS = (Int32)(DateTime_CurrentUTC_MS() - s->InitTime);
|
Int32 elapsedMS = (Int32)(DateTime_CurrentUTC_MS() - s->InitTime);
|
||||||
Int32 secsLeft = (DISCONNECT_DELAY_MS - elapsedMS) / DATETIME_MILLIS_PER_SEC;
|
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);
|
ButtonWidget_Set(&s->Reconnect, &msg, &s->TitleFont);
|
||||||
s->Reconnect.Disabled = secsLeft != 0;
|
s->Reconnect.Disabled = secsLeft != 0;
|
||||||
|
|
||||||
DisconnectScreen_Redraw(s, delta);
|
|
||||||
s->LastSecsLeft = secsLeft;
|
s->LastSecsLeft = secsLeft;
|
||||||
s->LastActive = s->Reconnect.Active;
|
s->LastActive = s->Reconnect.Active;
|
||||||
s->ClearTime = DateTime_CurrentUTC_MS() + 500;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DisconnectScreen_ContextLost(void* screen) {
|
static void DisconnectScreen_ContextLost(void* screen) {
|
||||||
@ -1413,7 +1399,6 @@ static void DisconnectScreen_ContextLost(void* screen) {
|
|||||||
|
|
||||||
static void DisconnectScreen_ContextRecreated(void* screen) {
|
static void DisconnectScreen_ContextRecreated(void* screen) {
|
||||||
struct DisconnectScreen* s = screen;
|
struct DisconnectScreen* s = screen;
|
||||||
s->ClearTime = DateTime_CurrentUTC_MS() + 500;
|
|
||||||
|
|
||||||
TextWidget_Create(&s->Title, &s->TitleStr, &s->TitleFont);
|
TextWidget_Create(&s->Title, &s->TitleStr, &s->TitleFont);
|
||||||
Widget_SetLocation(&s->Title, ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -30);
|
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);
|
Font_Make(&s->MessageFont, &Game_FontName, 16, FONT_STYLE_NORMAL);
|
||||||
Screen_CommonInit(s);
|
Screen_CommonInit(s);
|
||||||
|
|
||||||
Game_SkipClear = true;
|
Gfx_SetVSync(false);
|
||||||
|
game_limitMs = 1000 / 5.0f;
|
||||||
|
|
||||||
s->InitTime = DateTime_CurrentUTC_MS();
|
s->InitTime = DateTime_CurrentUTC_MS();
|
||||||
s->LastSecsLeft = DISCONNECT_DELAY_MS / DATETIME_MILLIS_PER_SEC;
|
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;
|
struct DisconnectScreen* s = screen;
|
||||||
if (s->CanReconnect) { DisconnectScreen_UpdateDelayLeft(s, delta); }
|
if (s->CanReconnect) { DisconnectScreen_UpdateDelayLeft(s, delta); }
|
||||||
|
|
||||||
/* NOTE: We need to make sure that both the front and back buffers have
|
PackedCol top = PACKEDCOL_CONST(64, 32, 32, 255);
|
||||||
definitely been drawn over, so we redraw the background multiple times. */
|
PackedCol bottom = PACKEDCOL_CONST(80, 16, 16, 255);
|
||||||
if (DateTime_CurrentUTC_MS() < s->ClearTime) {
|
GfxCommon_Draw2DGradient(0, 0, Game_Width, Game_Height, top, bottom);
|
||||||
DisconnectScreen_Redraw(s, delta);
|
|
||||||
}
|
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) {
|
static void DisconnectScreen_Free(void* screen) {
|
||||||
@ -1457,7 +1449,8 @@ static void DisconnectScreen_Free(void* screen) {
|
|||||||
Font_Free(&s->TitleFont);
|
Font_Free(&s->TitleFont);
|
||||||
Font_Free(&s->MessageFont);
|
Font_Free(&s->MessageFont);
|
||||||
Screen_CommonFree(s);
|
Screen_CommonFree(s);
|
||||||
Game_SkipClear = false;
|
|
||||||
|
Game_SetFpsLimit(Game_FpsLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DisconnectScreen_OnResize(void* screen) {
|
static void DisconnectScreen_OnResize(void* screen) {
|
||||||
@ -1465,7 +1458,6 @@ static void DisconnectScreen_OnResize(void* screen) {
|
|||||||
Widget_Reposition(&s->Title);
|
Widget_Reposition(&s->Title);
|
||||||
Widget_Reposition(&s->Message);
|
Widget_Reposition(&s->Message);
|
||||||
Widget_Reposition(&s->Reconnect);
|
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; }
|
static bool DisconnectScreen_KeyDown(void* s, Key key) { return key < Key_F1 || key > Key_F35; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user