diff --git a/ClassicalSharp/Network/Utils/AsyncDownloader.cs b/ClassicalSharp/Network/Utils/AsyncDownloader.cs index c66be8f58..50f4a33c3 100644 --- a/ClassicalSharp/Network/Utils/AsyncDownloader.cs +++ b/ClassicalSharp/Network/Utils/AsyncDownloader.cs @@ -120,7 +120,7 @@ public interface IGameComponent { } } public void Clear() { - lock (pendingLocker) { + lock (pendingLocker) { pending.Clear(); } handle.Set(); diff --git a/src/AsyncDownloader.c b/src/AsyncDownloader.c index d1fa32eaa..8df13611a 100644 --- a/src/AsyncDownloader.c +++ b/src/AsyncDownloader.c @@ -190,6 +190,15 @@ bool AsyncDownloader_GetCurrent(struct AsyncRequest* request, int* progress) { return request->ID[0]; } +void AsyncDownloader_Clear(void) { + Mutex_Lock(async_pendingMutex); + { + AsyncRequestList_Free(&async_pending); + } + Mutex_Unlock(async_pendingMutex); + Waitable_Signal(async_waitable); +} + static void AsyncDownloader_ProcessRequest(struct AsyncRequest* request) { String url = String_FromRawArray(request->URL); uint64_t beg, end; @@ -304,18 +313,9 @@ static void AsyncDownloader_Init(void) { async_workerThread = Thread_Start(AsyncDownloader_WorkerFunc, false); } -static void AsyncDownloader_Reset(void) { - Mutex_Lock(async_pendingMutex); - { - AsyncRequestList_Free(&async_pending); - } - Mutex_Unlock(async_pendingMutex); - Waitable_Signal(async_waitable); -} - static void AsyncDownloader_Free(void) { async_terminate = true; - AsyncDownloader_Reset(); + AsyncDownloader_Clear(); Thread_Join(async_workerThread); AsyncRequestList_Free(&async_pending); @@ -331,5 +331,5 @@ static void AsyncDownloader_Free(void) { struct IGameComponent AsyncDownloader_Component = { AsyncDownloader_Init, /* Init */ AsyncDownloader_Free, /* Free */ - AsyncDownloader_Reset /* Reset */ + AsyncDownloader_Clear /* Reset */ }; diff --git a/src/AsyncDownloader.h b/src/AsyncDownloader.h index 46ef83410..414922fed 100644 --- a/src/AsyncDownloader.h +++ b/src/AsyncDownloader.h @@ -45,7 +45,13 @@ void AsyncDownloader_GetContentLength(const String* url, bool priority, const St void AsyncDownloader_UNSAFE_PostData(const String* url, bool priority, const String* id, const void* data, const uint32_t size); void AsyncDownloader_GetDataEx(const String* url, bool priority, const String* id, TimeMS* lastModified, const String* etag); +/* Attempts to retrieve a fully completed request. */ +/* Returns whether a request with a matching id was retrieved. */ bool AsyncDownloader_Get(const String* id, struct AsyncRequest* item); +/* Retrieves information about the request currently being processed. */ +/* Returns whether there is actually a request being currently processed. */ bool AsyncDownloader_GetCurrent(struct AsyncRequest* request, int* progress); +/* Clears the list of pending requests. */ +void AsyncDownloader_Clear(void); void AsyncDownloader_PurgeOldEntriesTask(struct ScheduledTask* task); #endif diff --git a/src/LScreens.c b/src/LScreens.c index e5ccf7445..2ed20179c 100644 --- a/src/LScreens.c +++ b/src/LScreens.c @@ -9,6 +9,7 @@ #include "Platform.h" #include "Stream.h" #include "Funcs.h" +#include "Resources.h" /*########################################################################################################################* *---------------------------------------------------------Screen base-----------------------------------------------------* @@ -916,6 +917,137 @@ struct LScreen* MainScreen_MakeInstance(void) { } +/*########################################################################################################################* +*-------------------------------------------------------ResourcesScreen---------------------------------------------------* +*#########################################################################################################################*/ +static struct ResourcesScreen { + LScreen_Layout + struct LLabel LblLine1, LblLine2, LblStatus; + struct LButton BtnYes, BtnNo, BtnCancel; + struct LSlider SdrProgress; + struct LWidget* _widgets[7]; +} ResourcesScreen_Instance; + +/*static void ResourcesScreen_Download(void* w, int x, int y) { + struct ResourcesScreen* s = &ResourcesScreen_Instance; + if (FetchResourcesTask.Base.Working) return; + + FetchResourcesTask_Run(SetStatus); + s->SelectedWidget = NULL; + + s->BtnYes.Hidden = true; + s->BtnNo.Hidden = true; + s->LblLine1.Hidden = true; + s->LblLine2.Hidden = true; + s->BtnCancel.Hidden = false; + s->SdrProgress.Hidden = false; + s->Draw((struct LScreen*)s); +} + +static void ResourcesScreen_Next(void* w, int x, int y) { + const static String optionsTxt = String_FromConst("options.txt"); + AsyncDownloader_Clear(); + + if (File_Exists(&optionsTxt)) { + Launcher_SetScreen(MainScreen_MakeInstance()); + } else { + Launcher_SetScreen(ChooseModeScreen_MakeInstance(true)); + } +} + +static void ResourcesScreen_Init(struct LScreen* s_) { + String str; char buffer[STRING_SIZE]; + BitmapCol progressCol = BITMAPCOL_CONST(0, 220, 0, 255); + struct ResourcesScreen* s = (struct ResourcesScreen*)s_; + float size; + + if (s->NumWidgets) return; + s->Widgets = s->_widgets; + + LScreen_Label(s_, &s->LblLine1, "Some required resources weren't found"); + LScreen_Label(s_, &s->LblLine2, "Okay to download?"); + LScreen_Label(s_, &s->LblStatus, ""); + + LScreen_Button(s_, &s->BtnYes, 70, 35, "Yes"); + LScreen_Button(s_, &s->BtnNo, 70, 35, "No"); + + LScreen_Button(s_, &s->BtnCancel, 120, 35, "Cancel"); + LScreen_Slider(s_, &s->SdrProgress, 200, 10, 0, 100, progressCol); + + s->BtnCancel.Hidden = true; + s->SdrProgress.Hidden = true; + + /* TODO: Size 13 italic font?? does it matter?? */ + /*String_InitArray(str, buffer); + size = Resources_Size / 1024.0f; + + s->LblStatus.Font = Launcher_HintFont; + String_Format1(&str, "&eDownload size: %f2 megabytes", &size); + LLabel_SetText(&s->LblStatus, &str); + + s->BtnYes.OnClick = ResourcesScreen_Download; + s->BtnNo.OnClick = ResourcesScreen_Next; + s->BtnCancel.OnClick = ResourcesScreen_Next; +} + +#define RESOURCES_XSIZE 190 +#define RESOURCES_YSIZE 70 +static void ResourcesScreen_Draw(struct LScreen* s) { + BitmapCol backCol = BITMAPCOL_CONST( 12, 12, 12, 255); + BitmapCol boxCol = BITMAPCOL_CONST(120, 85, 151, 255); + + Drawer2D_Clear(&Launcher_Framebuffer, backCol, + 0, 0, Game_Width, Game_Height); + Gradient_Noise(&Launcher_Framebuffer, boxCol, 4, + Game_Width - RESOURCES_XSIZE, Game_Height - RESOURCES_YSIZE, + RESOURCES_XSIZE * 2, RESOURCES_YSIZE * 2); + LScreen_Draw(s); +} + +/*void SetStatus(string text) { + LabelWidget widget = (LabelWidget)widgets[0]; + using (drawer) { + drawer.SetBitmap(game.Framebuffer); + drawer.Clear(backCol, widget.X, widget.Y, widget.Width, widget.Height); + widget.SetDrawData(drawer, text); + widget.SetLocation(Anchor.Centre, Anchor.Centre, 0, -10); + widget.Redraw(drawer); + } + game.Dirty = true; +} + +static void ResourcesScreen_Tick(struct LScreen* s) { + if (!FetchResourcesTask.Base.Working || failed) return; + CheckCurrentProgress(); + + if (!fetcher.Check(SetStatus)) + failed = true; + + if (!fetcher.Done) return; + if (Resources_GetFetchFlags()) { + ResourcePatcher patcher = new ResourcePatcher(fetcher, drawer); + patcher.Run(); + } + + Launcher_TryLoadTexturePack(); + ResourcesScreen_Next(NULL, 0, 0); +} + +void CheckCurrentProgress(struct ResourcesScreen* s) { + struct AsyncRequest req; + int progress; + + if (!AsyncDownloader_GetCurrent(&req, &progress)) return; + /* making request still, haven't started download yet */ + /*if (progress < 0 || progress > 100) return; + + if (progress == s->SdrProgress.Value) return; + s->SdrProgress.Value = progress; + s->SdrProgress.Hidden = false; + s->SdrProgress.VTABLE->Draw(&s->SdrProgress); +}*/ + + /*########################################################################################################################* *--------------------------------------------------------ServersScreen----------------------------------------------------* *#########################################################################################################################*/ diff --git a/src/Program.c b/src/Program.c index b0b1264c0..4a5f20d31 100644 --- a/src/Program.c +++ b/src/Program.c @@ -4,12 +4,12 @@ #include "Constants.h" #include "Game.h" #include "Funcs.h" -#include "ExtMath.h" #include "Utils.h" #include "Launcher.h" /*#define CC_TEST_VORBIS*/ #ifdef CC_TEST_VORBIS +#include "ExtMath.h" #include "Vorbis.h" #define VORBIS_N 1024 diff --git a/src/Resources.h b/src/Resources.h index 3fb695208..9436fcc45 100644 --- a/src/Resources.h +++ b/src/Resources.h @@ -1,6 +1,6 @@ #ifndef CC_RESOURCES_H #define CC_RESOURCES_H -#include "Core.h" +#include "LWeb.h" /* Implements checking, fetching, and patching the default game assets. Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 */ @@ -36,4 +36,11 @@ extern struct ResourceMusic { bool Exists; } Resources_Music[7]; +typedef void (*FetchResourcesStatus)(const String* status); +extern struct FetchResourcesData { + struct LWebTask Base; + FetchResourcesStatus SetStatus; +} FetchResourcesTask; +void FetchResourcesTask_Run(FetchResourcesStatus setStatus); + #endif diff --git a/src/Widgets.c b/src/Widgets.c index 8445ed3ac..54928ab71 100644 --- a/src/Widgets.c +++ b/src/Widgets.c @@ -1482,20 +1482,15 @@ static void MenuInputWidget_RemakeTexture(void* widget) { Bitmap bmp; DrawTextArgs_Make(&args, &w->Base.Lines[0], &w->Base.Font, false); - size = Drawer2D_MeasureText(&args); + size.Width = Drawer2D_TextWidth(&args); + /* Text may be empty, but don't want 0 height if so */ + size.Height = Drawer2D_FontHeight(&w->Base.Font, false); w->Base.CaretAccumulator = 0.0; String_InitArray(range, rangeBuffer); v = &w->Validator; v->VTABLE->GetRange(v, &range); - /* Ensure we don't have 0 text height */ - if (size.Height == 0) { - args.Text = range; - size.Height = Drawer2D_MeasureText(&args).Height; - args.Text = w->Base.Lines[0]; - } - w->Base.Width = max(size.Width, w->MinWidth); w->Base.Height = max(size.Height, w->MinHeight); adjSize = size; adjSize.Width = w->Base.Width;