mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 03:25:14 -04:00
Fix /client model being broken
This commit is contained in:
parent
1513a20cd3
commit
40cadd9316
@ -129,7 +129,11 @@ namespace ClassicalSharp.Commands {
|
||||
}
|
||||
|
||||
public override void Execute(string[] args) {
|
||||
foreach (IGameComponent comp in game.Components) { comp.Dispose(); }
|
||||
if (args.Length == 1) {
|
||||
game.Chat.Add("&e/client model: &cYou didn't specify a model name.");
|
||||
} else {
|
||||
game.LocalPlayer.SetModel(args[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,6 +210,8 @@
|
||||
<ClInclude Include="Gui.h" />
|
||||
<ClInclude Include="HeldBlockRenderer.h" />
|
||||
<ClInclude Include="Launcher.h" />
|
||||
<ClInclude Include="LScreens.h" />
|
||||
<ClInclude Include="LWeb.h" />
|
||||
<ClInclude Include="LWidgets.h" />
|
||||
<ClInclude Include="Model.h" />
|
||||
<ClInclude Include="Input.h" />
|
||||
@ -273,6 +275,8 @@
|
||||
<ClCompile Include="InputHandler.c" />
|
||||
<ClCompile Include="Inventory.c" />
|
||||
<ClCompile Include="Launcher.c" />
|
||||
<ClCompile Include="LScreens.c" />
|
||||
<ClCompile Include="LWeb.c" />
|
||||
<ClCompile Include="LWidgets.c" />
|
||||
<ClCompile Include="MapGenerator.c" />
|
||||
<ClCompile Include="Deflate.c" />
|
||||
|
@ -312,6 +312,12 @@
|
||||
<ClInclude Include="LWidgets.h">
|
||||
<Filter>Header Files\Launcher</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="LWeb.h">
|
||||
<Filter>Header Files\Launcher</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="LScreens.h">
|
||||
<Filter>Header Files\Launcher</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="String.c">
|
||||
@ -557,5 +563,11 @@
|
||||
<ClCompile Include="LWidgets.c">
|
||||
<Filter>Source Files\Launcher</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="LWeb.c">
|
||||
<Filter>Source Files\Launcher</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="LScreens.c">
|
||||
<Filter>Source Files\Launcher</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
149
src/LScreens.c
Normal file
149
src/LScreens.c
Normal file
@ -0,0 +1,149 @@
|
||||
#include "LScreens.h"
|
||||
#include "LWidgets.h"
|
||||
#include "Launcher.h"
|
||||
#include "Gui.h"
|
||||
|
||||
static void LScreen_NullFunc(struct LScreen* s) { }
|
||||
static void LScreen_DrawAll(struct LScreen* s) {
|
||||
struct LWidget* widget;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < s->NumWidgets; i++) {
|
||||
widget = s->Widgets[i];
|
||||
widget->VTABLE->Redraw(widget);
|
||||
}
|
||||
}
|
||||
|
||||
static void LScreen_HoverWidget(struct LScreen* s, struct LWidget* w) {
|
||||
if (!w) return;
|
||||
w->Hovered = true;
|
||||
if (w->VTABLE->OnHover) w->VTABLE->OnHover(w);
|
||||
}
|
||||
|
||||
static void LScreen_UnhoverWidget(struct LScreen* s, struct LWidget* w) {
|
||||
if (!w) return;
|
||||
w->Hovered = false;
|
||||
if (w->VTABLE->OnUnhover) w->VTABLE->OnUnhover(w);
|
||||
}
|
||||
|
||||
CC_NOINLINE static void LScreen_Reset(struct LScreen* s) {
|
||||
int i;
|
||||
|
||||
s->Init = NULL; /* screens should always override this */
|
||||
s->Free = LScreen_NullFunc;
|
||||
s->DrawAll = LScreen_DrawAll;
|
||||
s->Tick = LScreen_NullFunc;
|
||||
s->OnDisplay = LScreen_NullFunc;
|
||||
s->HoverWidget = LScreen_HoverWidget;
|
||||
s->UnhoverWidget = LScreen_UnhoverWidget;
|
||||
|
||||
/* reset all widgets to unselected */
|
||||
for (i = 0; i < s->NumWidgets; i++) {
|
||||
s->Widgets[i]->Hovered = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Widget init-----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
CC_NOINLINE static void LScreen_Button(struct LScreen* s, struct LButton* w, int width, int height, const char* text,
|
||||
uint8_t horAnchor, uint8_t verAnchor, int xOffset, int yOffset) {
|
||||
String str = String_FromReadonly(text);
|
||||
LButton_Init(w, width, height);
|
||||
LButton_SetText(w, &str, &Launcher_TitleFont);
|
||||
|
||||
w->Hovered = false;
|
||||
s->Widgets[s->NumWidgets++] = (struct LWidget*)w;
|
||||
LWidget_SetLocation(w, horAnchor, verAnchor, xOffset, yOffset);
|
||||
}
|
||||
|
||||
CC_NOINLINE static void LScreen_Label(struct LScreen* s, struct LLabel* w, const char* text,
|
||||
uint8_t horAnchor, uint8_t verAnchor, int xOffset, int yOffset) {
|
||||
String str = String_FromReadonly(text);
|
||||
LLabel_Init(w);
|
||||
LLabel_SetText(w, &str, &Launcher_TextFont);
|
||||
|
||||
w->Hovered = false;
|
||||
s->Widgets[s->NumWidgets++] = (struct LWidget*)w;
|
||||
LWidget_SetLocation(w, horAnchor, verAnchor, xOffset, yOffset);
|
||||
}
|
||||
|
||||
CC_NOINLINE static void LScreen_Slider(struct LScreen* s, struct LSlider* w, int width, int height,
|
||||
int initValue, int maxValue, BitmapCol progressCol,
|
||||
uint8_t horAnchor, uint8_t verAnchor, int xOffset, int yOffset) {
|
||||
LSlider_Init(w, width, height);
|
||||
w->Value = initValue; w->MaxValue = maxValue;
|
||||
w->ProgressCol = progressCol;
|
||||
|
||||
w->Hovered = false;
|
||||
s->Widgets[s->NumWidgets++] = (struct LWidget*)w;
|
||||
LWidget_SetLocation(w, horAnchor, verAnchor, xOffset, yOffset);
|
||||
}
|
||||
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------------SettingsScreen---------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
/*static struct SettingsScreen {
|
||||
LScreen_Layout
|
||||
struct LWidget* Widgets[7];
|
||||
struct LButton BtnUpdates, BtnMode, BtnColours, BtnBack;
|
||||
struct LLabel LblUpdates, LblMode, LblColours;
|
||||
} SettingsScreen_Instance;
|
||||
|
||||
static void SettingsScreen_InitWidgets(struct SettingsScreen* s) {
|
||||
struct LScreen* s_ = (struct LScreen*)s;
|
||||
|
||||
LScreen_Button(s_, &s->BtnUpdates, 110, 35, "Updates",
|
||||
ANCHOR_CENTRE, ANCHOR_CENTRE, -135, -120);
|
||||
LScreen_Label(s_, &s->LblUpdates, "&eGet the latest stuff",
|
||||
ANCHOR_CENTRE, ANCHOR_CENTRE, 10, -120);
|
||||
|
||||
LScreen_Button(s_, &s->BtnMode, 110, 35, "Mode",
|
||||
ANCHOR_CENTRE, ANCHOR_CENTRE, -135, -70);
|
||||
LScreen_Label(s_, &s->LblMode, "&eChange the enabled features",
|
||||
ANCHOR_CENTRE, ANCHOR_CENTRE, 55, -70);
|
||||
|
||||
LScreen_Button(s_, &s->BtnColours, 110, 35, "Colours",
|
||||
ANCHOR_CENTRE, ANCHOR_CENTRE, -135, -20);
|
||||
LScreen_Label(s_, &s->LblColours, "&eChange how the launcher looks",
|
||||
ANCHOR_CENTRE, ANCHOR_CENTRE, 65, -20);
|
||||
|
||||
LScreen_Button(s_, &s->BtnBack, 80, 35, "Back",
|
||||
ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 170);
|
||||
}
|
||||
|
||||
static void SwitchToChooseMode(void* w, int x, int y) {
|
||||
Launcher_SetScreen(ChooseModeScreen_MakeInstance(false));
|
||||
}
|
||||
static void SwitchToUpdates(void* w, int x, int y) {
|
||||
Launcher_SetScreen(UpdatesScreen_MakeInstance());
|
||||
}
|
||||
static void SwitchToColours(void* w, int x, int y) {
|
||||
Launcher_SetScreen(ColoursScreen_MakeInstance());
|
||||
}
|
||||
static void SwitchToMain(void* w, int x, int y) {
|
||||
Launcher_SetScreen(MainScreen_MakeInstance());
|
||||
}
|
||||
|
||||
static void SettingsScreen_Init(struct LScreen* s_) {
|
||||
struct SettingsScreen* s = (struct SettingsScreen*)s_;
|
||||
if (!s->NumWidgets) SettingsScreen_InitWidgets(s);
|
||||
|
||||
s->BtnColours.Hidden = Launcher_ClassicBackground;
|
||||
s->LblColours.Hidden = Launcher_ClassicBackground;
|
||||
|
||||
s->BtnMode.OnClick = SwitchToChooseMode;
|
||||
s->BtnUpdates.OnClick = SwitchToUpdates;
|
||||
s->BtnColours.OnClick = SwitchToColours;
|
||||
s->BtnBack.OnClick = SwitchToMain;
|
||||
s->DrawAll(s);
|
||||
}
|
||||
|
||||
struct LScreen* SettingsScreen_MakeInstance(void) {
|
||||
struct SettingsScreen* s = &SettingsScreen_Instance;
|
||||
LScreen_Reset((struct LScreen*)s);
|
||||
s->Init = SettingsScreen_Init;
|
||||
return (struct LScreen*)s;
|
||||
}
|
||||
*/
|
41
src/LScreens.h
Normal file
41
src/LScreens.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef CC_LSCREENS_H
|
||||
#define CC_LSCREENS_H
|
||||
#include "AsyncDownloader.h"
|
||||
#include "String.h"
|
||||
/* Implements screens/menus for the launcher.
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
struct LWidget;
|
||||
struct LScreen;
|
||||
|
||||
typedef void (*LScreen_Func)(struct LScreen* s);
|
||||
typedef void (*LWidget_Func)(struct LScreen* s, struct LWidget* w);
|
||||
|
||||
#define LScreen_Layout \
|
||||
LScreen_Func Init; /* Initialises widgets and other data. */ \
|
||||
LScreen_Func Free; /* Cleans up all native resources. */ \
|
||||
LScreen_Func DrawAll; /* Redraws all widgets. */ \
|
||||
LScreen_Func Tick; /* Repeatedly called multiple times every second. */ \
|
||||
LScreen_Func OnDisplay; /* Called when framebuffer is about to be displayed. */ \
|
||||
LWidget_Func HoverWidget; /* Called when mouse is moved over a given widget. */ \
|
||||
LWidget_Func UnhoverWidget; /* Called when the mouse is moved away from a previously hovered widget. */ \
|
||||
struct LWidget* HoveredWidget; /* Widget the mouse is currently hovering over. */ \
|
||||
int NumWidgets; /* Number of widgets actually used. */
|
||||
|
||||
struct LScreen {
|
||||
LScreen_Layout
|
||||
/* All widgets in the screen. */
|
||||
/* NOTE: This is vriable sized, so must be the last member. */
|
||||
/* (e.g. derived screens might use: struct LWidget* Widgets[10];) */
|
||||
struct LWidget** Widgets;
|
||||
};
|
||||
|
||||
struct LScreen* ChooseModeScreen_MakeInstance(void);
|
||||
struct LScreen* ColoursScreen_MakeInstance(void);
|
||||
struct LScreen* DirectConnectScreen_MakeInstance(void);
|
||||
struct LScreen* MainScreen_MakeInstance(void);
|
||||
struct LScreen* ResourcesScreen_MakeInstance(void);
|
||||
struct LScreen* ServersScreen_MakeInstance(void);
|
||||
struct LScreen* SettingsScreen_MakeInstance(void);
|
||||
struct LScreen* UpdateScreen_MakeInstance(void);
|
||||
#endif
|
277
src/LWeb.c
Normal file
277
src/LWeb.c
Normal file
@ -0,0 +1,277 @@
|
||||
#include "LWeb.h"
|
||||
#include "Platform.h"
|
||||
|
||||
static void LWebTask_Reset(struct LWebTask* task) {
|
||||
task->Completed = false;
|
||||
task->Success = false;
|
||||
task->Start = DateTime_CurrentUTC_MS();
|
||||
}
|
||||
|
||||
void LWebTask_StartAsync(struct LWebTask* task) {
|
||||
LWebTask_Reset(task);
|
||||
task->Begin(task);
|
||||
}
|
||||
|
||||
void LWebTask_Tick(struct LWebTask* task) {
|
||||
struct AsyncRequest req;
|
||||
int delta;
|
||||
if (task->Completed) return;
|
||||
|
||||
if (!AsyncDownloader_Get(&task->Identifier, &req)) return;
|
||||
delta = (int)(DateTime_CurrentUTC_MS() - task->Start);
|
||||
Platform_Log2("%s took %i", &task->Identifier, &delta);
|
||||
|
||||
task->Completed = true;
|
||||
task->Success = req.ResultData && req.ResultSize;
|
||||
if (task->Success) task->Handle(task, req.ResultData, req.ResultSize);
|
||||
}
|
||||
|
||||
static void LWebTask_DefaultBegin(struct LWebTask* task) {
|
||||
AsyncDownloader_GetData(&task->URL, false, &task->Identifier);
|
||||
}
|
||||
|
||||
/*protected static JsonObject ParseJson(Request req) {
|
||||
JsonContext ctx = new JsonContext();
|
||||
ctx.Val = (string)req.Data;
|
||||
return (JsonObject)Json.ParseStream(ctx);
|
||||
}
|
||||
|
||||
public sealed class GetCSRFTokenTask : WebTask {
|
||||
public GetCSRFTokenTask() {
|
||||
identifier = "CC get login";
|
||||
uri = "https://www.classicube.net/api/login/";
|
||||
}
|
||||
public string Token;
|
||||
|
||||
protected override void Handle(Request req) {
|
||||
JsonObject data = ParseJson(req);
|
||||
Token = (string)data["token"];
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SignInTask : WebTask {
|
||||
public SignInTask() {
|
||||
identifier = "CC post login";
|
||||
uri = "https://www.classicube.net/api/login/";
|
||||
}
|
||||
public string Username, Password, Token, Error;
|
||||
|
||||
protected override void Begin() {
|
||||
string data = String.Format(
|
||||
"username={0}&password={1}&token={2}",
|
||||
Uri.EscapeDataString(Username),
|
||||
Uri.EscapeDataString(Password),
|
||||
Uri.EscapeDataString(Token)
|
||||
);
|
||||
Game.Downloader.AsyncPostString(uri, false, identifier, data);
|
||||
}
|
||||
|
||||
protected override void Handle(Request req) {
|
||||
JsonObject data = ParseJson(req);
|
||||
Error = GetLoginError(data);
|
||||
Username = (string)data["username"];
|
||||
}
|
||||
|
||||
static string GetLoginError(JsonObject obj) {
|
||||
List<object> errors = (List<object>)obj["errors"];
|
||||
if (errors.Count == 0) return null;
|
||||
|
||||
string err = (string)errors[0];
|
||||
if (err == "username" || err == "password") return "Wrong username or password";
|
||||
if (err == "verification") return "Account verification required";
|
||||
return "Unknown error occurred";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ServerListEntry {
|
||||
public string Hash, Name, Players, MaxPlayers, Flag;
|
||||
public string Uptime, IPAddress, Port, Mppass, Software;
|
||||
public bool Featured;
|
||||
}
|
||||
|
||||
public sealed class FetchServerTask : WebTask {
|
||||
public FetchServerTask(string user, string hash) {
|
||||
Username = user;
|
||||
identifier = "CC get servers";
|
||||
uri = "https://www.classicube.net/api/server/" + hash;
|
||||
}
|
||||
|
||||
public static ServerListEntry ParseEntry(JsonObject obj) {
|
||||
ServerListEntry entry = new ServerListEntry();
|
||||
entry.Hash = (string)obj["hash"];
|
||||
entry.Name = (string)obj["name"];
|
||||
entry.Players = (string)obj["players"];
|
||||
entry.MaxPlayers = (string)obj["maxplayers"];
|
||||
entry.Uptime = (string)obj["uptime"];
|
||||
entry.Mppass = (string)obj["mppass"];
|
||||
entry.IPAddress = (string)obj["ip"];
|
||||
entry.Port = (string)obj["port"];
|
||||
entry.Software = (string)obj["software"];
|
||||
|
||||
if (obj.ContainsKey("featured")) {
|
||||
entry.Featured = (bool)obj["featured"];
|
||||
}
|
||||
if (obj.ContainsKey("country_abbr")) {
|
||||
entry.Flag = Utils.ToLower((string)obj["country_abbr"]);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
public string Username;
|
||||
public ClientStartData Info;
|
||||
|
||||
protected override void Handle(Request req) {
|
||||
JsonObject root = ParseJson(req);
|
||||
List<object> list = (List<object>)root["servers"];
|
||||
|
||||
JsonObject obj = (JsonObject)list[0];
|
||||
ServerListEntry entry = ParseEntry(obj);
|
||||
Info = new ClientStartData(Username, entry.Mppass, entry.IPAddress, entry.Port, entry.Name);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class FetchServersTask : WebTask {
|
||||
public FetchServersTask() {
|
||||
identifier = "CC get servers";
|
||||
uri = "https://www.classicube.net/api/servers";
|
||||
}
|
||||
|
||||
public List<ServerListEntry> Servers;
|
||||
protected override void Reset() {
|
||||
base.Reset();
|
||||
Servers = new List<ServerListEntry>();
|
||||
}
|
||||
|
||||
protected override void Handle(Request req) {
|
||||
JsonObject root = ParseJson(req);
|
||||
List<object> list = (List<object>)root["servers"];
|
||||
|
||||
for (int i = 0; i < list.Count; i++) {
|
||||
JsonObject obj = (JsonObject)list[i];
|
||||
ServerListEntry entry = FetchServerTask.ParseEntry(obj);
|
||||
Servers.Add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class Build {
|
||||
public DateTime TimeBuilt;
|
||||
public string DirectXPath, OpenGLPath;
|
||||
public int DirectXSize, OpenGLSize;
|
||||
public string Version;
|
||||
}
|
||||
|
||||
public sealed class UpdateCheckTask : WebTask {
|
||||
public UpdateCheckTask() {
|
||||
identifier = "CC update check";
|
||||
uri = "http://cs.classicube.net/builds.json";
|
||||
}
|
||||
|
||||
public Build LatestDev, LatestStable;
|
||||
|
||||
protected override void Handle(Request req) {
|
||||
JsonObject data = ParseJson(req);
|
||||
JsonObject latest = (JsonObject)data["latest"];
|
||||
|
||||
LatestDev = MakeBuild(latest, false);
|
||||
JsonObject releases = (JsonObject)data["releases"];
|
||||
|
||||
DateTime releaseTime = DateTime.MinValue;
|
||||
foreach(KeyValuePair<string, object> pair in releases) {
|
||||
Build build = MakeBuild((JsonObject)pair.Value, true);
|
||||
if (build.TimeBuilt < releaseTime) continue;
|
||||
|
||||
LatestStable = build;
|
||||
releaseTime = build.TimeBuilt;
|
||||
}
|
||||
}
|
||||
|
||||
static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
Build MakeBuild(JsonObject obj, bool release) {
|
||||
Build build = new Build();
|
||||
string timeKey = release ? "release_ts" : "ts";
|
||||
double rawTime = Double.Parse((string)obj[timeKey], CultureInfo.InvariantCulture);
|
||||
build.TimeBuilt = epoch.AddSeconds(rawTime).ToLocalTime();
|
||||
|
||||
build.DirectXSize = Int32.Parse((string)obj["dx_size"]);
|
||||
build.DirectXPath = (string)obj["dx_file"];
|
||||
build.OpenGLSize = Int32.Parse((string)obj["ogl_size"]);
|
||||
build.OpenGLPath = (string)obj["ogl_file"];
|
||||
if (obj.ContainsKey("version"))
|
||||
build.Version = (string)obj["version"];
|
||||
return build;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class UpdateDownloadTask : WebTask {
|
||||
public UpdateDownloadTask(string dir) {
|
||||
identifier = "CC update download";
|
||||
uri = "http://cs.classicube.net/" + dir;
|
||||
}
|
||||
|
||||
public byte[] ZipFile;
|
||||
|
||||
protected override void Begin() {
|
||||
Game.Downloader.AsyncGetData(uri, false, identifier);
|
||||
}
|
||||
|
||||
protected override void Handle(Request req) {
|
||||
ZipFile = (byte[])req.Data;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class UpdateCClientTask : WebTask {
|
||||
public UpdateCClientTask(string file) {
|
||||
identifier = "CC CClient download";
|
||||
uri = "http://cs.classicube.net/c_client/latest/" + file;
|
||||
}
|
||||
|
||||
public byte[] File;
|
||||
|
||||
protected override void Begin() {
|
||||
Game.Downloader.AsyncGetData(uri, false, identifier);
|
||||
}
|
||||
|
||||
protected override void Handle(Request req) {
|
||||
File = (byte[])req.Data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public sealed class FetchFlagsTask : WebTask {
|
||||
public FetchFlagsTask() {
|
||||
identifier = "CC get flag";
|
||||
}
|
||||
|
||||
public bool PendingRedraw;
|
||||
public static int DownloadedCount;
|
||||
public static List<string> Flags = new List<string>();
|
||||
public static List<FastBitmap> Bitmaps = new List<FastBitmap>();
|
||||
|
||||
public void AsyncGetFlag(string flag) {
|
||||
for (int i = 0; i < Flags.Count; i++) {
|
||||
if (Flags[i] == flag) return;
|
||||
}
|
||||
Flags.Add(flag);
|
||||
}
|
||||
|
||||
protected override void Begin() {
|
||||
if (Flags.Count == DownloadedCount) return;
|
||||
uri = "http://static.classicube.net/img/flags/" + Flags[DownloadedCount] + ".png";
|
||||
Game.Downloader.AsyncGetImage(uri, false, identifier);
|
||||
}
|
||||
|
||||
protected override void Handle(Request req) {
|
||||
Bitmap bmp = (Bitmap)req.Data;
|
||||
FastBitmap fast = new FastBitmap(bmp, true, true);
|
||||
Bitmaps.Add(fast);
|
||||
DownloadedCount++;
|
||||
PendingRedraw = true;
|
||||
|
||||
Reset();
|
||||
Begin();
|
||||
}
|
||||
}
|
||||
}*/
|
30
src/LWeb.h
Normal file
30
src/LWeb.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef CC_LWEB_H
|
||||
#define CC_LWEB_H
|
||||
#include "AsyncDownloader.h"
|
||||
#include "String.h"
|
||||
/* Implements asynchronous web tasks for the launcher.
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
|
||||
struct LWebTask;
|
||||
struct LWebTask {
|
||||
/* Whether the task has finished executing. */
|
||||
bool Completed;
|
||||
/* Whether the task completed successfully. */
|
||||
bool Success;
|
||||
ReturnCode Res;
|
||||
/* Unique identifier for this web task. */
|
||||
String Identifier;
|
||||
/* URL this task is downloading from/uploading to. */
|
||||
String URL;
|
||||
/* Point in time this task was started at. */
|
||||
TimeMS Start;
|
||||
/* Function called to begin downloading/uploading. */
|
||||
void (*Begin)(struct LWebTask* task);
|
||||
/* Called when task successfully downloaded/uploaded data. */
|
||||
void (*Handle)(struct LWebTask* task, uint8_t* data, uint32_t len);
|
||||
};
|
||||
|
||||
void LWebTask_StartAsync(struct LWebTask* task);
|
||||
void LWebTask_Tick(struct LWebTask* task);
|
||||
#endif
|
@ -20,7 +20,7 @@ void LWidget_CalcPosition(void* widget) {
|
||||
|
||||
void LWidget_Reset(void* widget) {
|
||||
struct LWidget* w = widget;
|
||||
w->Active = false;
|
||||
w->Hovered = false;
|
||||
w->Hidden = false;
|
||||
w->X = 0; w->Y = 0;
|
||||
w->Width = 0; w->Height = 0;
|
||||
@ -30,7 +30,7 @@ void LWidget_Reset(void* widget) {
|
||||
|
||||
w->TabSelectable = false;
|
||||
w->OnClick = NULL;
|
||||
w->Redraw = NULL;
|
||||
w->VTABLE = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -52,12 +52,12 @@ static void LButton_DrawBackground(struct LButton* w) {
|
||||
BitmapCol col;
|
||||
|
||||
if (Launcher_ClassicBackground) {
|
||||
col = w->Active ? activeCol : inactiveCol;
|
||||
col = w->Hovered ? activeCol : inactiveCol;
|
||||
Gradient_Noise(&Launcher_Framebuffer, col, 8,
|
||||
w->X + BTN_BORDER, w->Y + BTN_BORDER,
|
||||
w->Width - 2 * BTN_BORDER, w->Height - 2 * BTN_BORDER);
|
||||
} else {
|
||||
col = w->Active ? Launcher_ButtonForeActiveCol : Launcher_ButtonForeCol;
|
||||
col = w->Hovered ? Launcher_ButtonForeActiveCol : Launcher_ButtonForeCol;
|
||||
Gradient_Vertical(&Launcher_Framebuffer, LButton_Expand(col, 8), LButton_Expand(col, -8),
|
||||
w->X + BTN_BORDER, w->Y + BTN_BORDER,
|
||||
w->Width - 2 * BTN_BORDER, w->Height - 2 * BTN_BORDER);
|
||||
@ -88,14 +88,14 @@ static void LButton_DrawHighlight(struct LButton* w) {
|
||||
BitmapCol highlightCol;
|
||||
|
||||
if (Launcher_ClassicBackground) {
|
||||
highlightCol = w->Active ? activeCol : inactiveCol;
|
||||
highlightCol = w->Hovered ? activeCol : inactiveCol;
|
||||
Drawer2D_Clear(&Launcher_Framebuffer, highlightCol,
|
||||
w->X + BTN_BORDER * 2, w->Y + BTN_BORDER,
|
||||
w->Width - BTN_BORDER * 4, BTN_BORDER);
|
||||
Drawer2D_Clear(&Launcher_Framebuffer, highlightCol,
|
||||
w->X + BTN_BORDER, w->Y + BTN_BORDER * 2,
|
||||
BTN_BORDER, w->Height - BTN_BORDER * 4);
|
||||
} else if (!w->Active) {
|
||||
} else if (!w->Hovered) {
|
||||
Drawer2D_Clear(&Launcher_Framebuffer, Launcher_ButtonHighlightCol,
|
||||
w->X + BTN_BORDER * 2, w->Y + BTN_BORDER,
|
||||
w->Width - BTN_BORDER * 4, BTN_BORDER);
|
||||
@ -116,17 +116,22 @@ static void LButton_Redraw(void* widget) {
|
||||
LButton_DrawBorder(w);
|
||||
LButton_DrawHighlight(w);
|
||||
|
||||
if (!w->Active) Drawer2D_Cols['f'] = Drawer2D_Cols['7'];
|
||||
if (!w->Hovered) Drawer2D_Cols['f'] = Drawer2D_Cols['7'];
|
||||
Drawer2D_DrawText(&Launcher_Framebuffer, &args,
|
||||
w->X + xOffset / 2, w->Y + yOffset / 2);
|
||||
if (!w->Active) Drawer2D_Cols['f'] = Drawer2D_Cols['F'];
|
||||
|
||||
if (!w->Hovered) Drawer2D_Cols['f'] = Drawer2D_Cols['F'];
|
||||
Launcher_Dirty = true;
|
||||
}
|
||||
|
||||
static struct LWidgetVTABLE lbutton_VTABLE = {
|
||||
LButton_Redraw, LButton_Redraw, LButton_Redraw, NULL, NULL
|
||||
};
|
||||
void LButton_Init(struct LButton* w, int width, int height) {
|
||||
Widget_Reset(w);
|
||||
w->VTABLE = &lbutton_VTABLE;
|
||||
w->TabSelectable = true;
|
||||
w->Width = width; w->Height = height;
|
||||
w->Redraw = LButton_Redraw;
|
||||
String_InitArray(w->Text, w->__TextBuffer);
|
||||
}
|
||||
|
||||
@ -186,7 +191,7 @@ bool LInput_Backspace(struct LInput* w) {
|
||||
if (w->CaretPos == -1) w->CaretPos = 0;
|
||||
}
|
||||
|
||||
if (w->TextChanged) TextChanged(w);
|
||||
if (w->TextChanged) w->TextChanged(w);
|
||||
if (w->CaretPos >= w->Text.length) w->CaretPos = -1;
|
||||
return true;
|
||||
}
|
||||
@ -225,11 +230,15 @@ static void LLabel_Redraw(void* widget) {
|
||||
|
||||
DrawTextArgs_Make(&args, &w->Text, &w->Font, true);
|
||||
Drawer2D_DrawText(&Launcher_Framebuffer, &args, w->X, w->Y);
|
||||
Launcher_Dirty = true;
|
||||
}
|
||||
|
||||
static struct LWidgetVTABLE llabel_VTABLE = {
|
||||
LLabel_Redraw, NULL, NULL, NULL, NULL
|
||||
};
|
||||
void LLabel_Init(struct LLabel* w) {
|
||||
Widget_Reset(w);
|
||||
w->Redraw = LLabel_Redraw;
|
||||
w->VTABLE = &llabel_VTABLE;
|
||||
String_InitArray(w->Text, w->__TextBuffer);
|
||||
}
|
||||
|
||||
@ -287,11 +296,15 @@ static void LSlider_Redraw(void* widget) {
|
||||
|
||||
Drawer2D_Clear(&Launcher_Framebuffer, w->ProgressCol,
|
||||
w->X, w->Y, (int)(w->Width * w->Value / w->MaxValue), w->Height);
|
||||
Launcher_Dirty = true;
|
||||
}
|
||||
|
||||
static struct LWidgetVTABLE lslider_VTABLE = {
|
||||
LSlider_Redraw, NULL, NULL, NULL, NULL
|
||||
};
|
||||
void LSlider_Init(struct LSlider* w, int width, int height) {
|
||||
Widget_Reset(w);
|
||||
w->VTABLE = &lslider_VTABLE;
|
||||
w->Width = width; w->Height = height;
|
||||
w->Redraw = LSlider_Redraw;
|
||||
w->MaxValue = 100;
|
||||
}
|
||||
|
@ -7,15 +7,30 @@
|
||||
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
|
||||
struct LWidgetVTABLE {
|
||||
/* Called to redraw contents of this widget */
|
||||
void (*Redraw)(void* widget);
|
||||
/* Called when mouse hovers over this widget. */
|
||||
void (*OnHover)(void* widget);
|
||||
/* Called when mouse moves away from this widget. */
|
||||
void (*OnUnhover)(void* widget);
|
||||
/* Called when mouse clicks on this widget. */
|
||||
/* NOTE: This function is just for general widget behaviour. */
|
||||
/* OnClick callback is for per-widget instance behaviour. */
|
||||
void (*OnSelected)(void* widget);
|
||||
/* Called when mouse clicks on another widget. */
|
||||
void (*OnUnselected)(void* widget);
|
||||
};
|
||||
|
||||
#define LWidget_Layout \
|
||||
struct LWidgetVTABLE* VTABLE; /* General widget functions */ \
|
||||
int X, Y, Width, Height; /* Top left corner, and dimensions, of this widget */ \
|
||||
bool Active; /* Whether this widget is currently being moused over*/ \
|
||||
bool Hovered; /* Whether this widget is currently being moused over*/ \
|
||||
bool Hidden; /* Whether this widget is hidden from view */ \
|
||||
bool TabSelectable; /* Whether this widget gets selected when pressing tab */ \
|
||||
uint8_t HorAnchor, VerAnchor; /* Specifies the reference point for when this widget is resized */ \
|
||||
int XOffset, YOffset; /* Offset from the reference point */ \
|
||||
void (*OnClick)(void* widget, int x, int y); /* Called when widget is clicked */ \
|
||||
void (*Redraw)(void* widget); /* Called to redraw contents of this widget */
|
||||
|
||||
/* Represents an individual 2D gui component in the launcher. */
|
||||
struct LWidget { LWidget_Layout };
|
||||
|
@ -17,6 +17,8 @@ extern Rect2D Launcher_DirtyArea;
|
||||
extern Bitmap Launcher_Framebuffer;
|
||||
/* Whether to use stone tile background like minecraft.net. */
|
||||
extern bool Launcher_ClassicBackground;
|
||||
/* Default font for buttons and labels. */
|
||||
extern FontDesc Launcher_TitleFont, Launcher_TextFont;
|
||||
|
||||
/* Whether at the next tick, the launcher window should proceed to stop displaying frames and subsequently exit. */
|
||||
extern bool Launcher_ShouldExit;
|
||||
|
Loading…
x
Reference in New Issue
Block a user