From 12d9715a1c0eb31ac4aa7c8f3b0991848f872851 Mon Sep 17 00:00:00 2001 From: Sergey Isakov Date: Mon, 13 Apr 2020 22:01:40 +0300 Subject: [PATCH] a template for refactoring ANIME Signed-off-by: Sergey Isakov --- rEFIt_UEFI/gui/REFIT_MENU_SCREEN.h | 67 ++++++++++++++++++++++-------- rEFIt_UEFI/libeg/XCinema.cpp | 61 ++++++++++++++++++++++++++- rEFIt_UEFI/libeg/XCinema.h | 28 +++++++------ rEFIt_UEFI/libeg/XTheme.h | 4 ++ rEFIt_UEFI/libeg/libeg.h | 2 + rEFIt_UEFI/refit.inf | 2 + rEFIt_UEFI/refit/IO.cpp | 7 +++- rEFIt_UEFI/refit/screen.cpp | 14 ++++++- 8 files changed, 150 insertions(+), 35 deletions(-) diff --git a/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.h b/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.h index 2ec1d85512..ff800e76f9 100644 --- a/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.h +++ b/rEFIt_UEFI/gui/REFIT_MENU_SCREEN.h @@ -43,6 +43,7 @@ #include "../cpp_foundation/XStringWArray.h" #include "../cpp_foundation/XStringW.h" #include "../libeg/XPointer.h" +#include "../libeg/XCinema.h" #include "menu_items/menu_items.h" @@ -72,30 +73,38 @@ class REFIT_MENU_SCREEN static XPointer mPointer; // XPointer mPointer; UINTN ID; - XStringW Title; - XImage TitleImage; + XStringW Title; + XImage TitleImage; XStringWArray InfoLines; + XObjArray Entries; + INTN TimeoutSeconds; - XStringW TimeoutText; - XStringW ThemeName; //? - EG_RECT OldTextBufferRect; - XImage OldTextBufferImage; - BOOLEAN isBootScreen; + XStringW TimeoutText; + XStringW ThemeName; //? + EG_RECT OldTextBufferRect; + XImage OldTextBufferImage; + BOOLEAN isBootScreen; BOOLEAN AnimeRun; BOOLEAN Once; + //same for xcinema UINT64 LastDraw; INTN CurrentFrame; INTN Frames; UINTN FrameTime; //ms EG_RECT FilmPlace; + +#if XCINEMA + FILM *FilmX; +#else EG_IMAGE **Film; +#endif - ACTION mAction; - UINTN mItemID; - SCROLL_STATE ScrollState; - BOOLEAN ScrollEnabled; - INTN TextStyle; + ACTION mAction; + UINTN mItemID; + SCROLL_STATE ScrollState; + BOOLEAN ScrollEnabled; + INTN TextStyle; // MENU_STYLE_FUNC StyleFunc; //TODO scroll positions should depends on REFIT_SCREEN? @@ -120,7 +129,12 @@ class REFIT_MENU_SCREEN OldTextBufferRect(), OldTextBufferImage(), isBootScreen(false), AnimeRun(0), Once(0), LastDraw(0), CurrentFrame(0), Frames(0), FrameTime(0), - Film(0), mAction(ActionNone), mItemID(0)//, mPointer(NULL) //, StyleFunc(&REFIT_MENU_SCREEN::TextMenuStyle) +#if XCINEMA + FilmX(), +#else + Film(0), +#endif + mAction(ActionNone), mItemID(0)//, mPointer(NULL) //, StyleFunc(&REFIT_MENU_SCREEN::TextMenuStyle) {}; REFIT_MENU_SCREEN(UINTN ID, XStringW TTitle, XStringW TTimeoutText) : ID(ID), Title(TTitle), TitleImage(), @@ -128,14 +142,24 @@ class REFIT_MENU_SCREEN OldTextBufferRect(), OldTextBufferImage(), isBootScreen(false), AnimeRun(0), Once(0), LastDraw(0), CurrentFrame(0), Frames(0), FrameTime(0), - Film(0), mAction(ActionNone), mItemID(0)//, mPointer(NULL) //, StyleFunc(&REFIT_MENU_SCREEN::TextMenuStyle) +#if XCINEMA + FilmX(), +#else + Film(0), +#endif + mAction(ActionNone), mItemID(0)//, mPointer(NULL) //, StyleFunc(&REFIT_MENU_SCREEN::TextMenuStyle) {}; REFIT_MENU_SCREEN(UINTN ID, CONST CHAR16* TitleC, CONST CHAR16* TimeoutTextC) : ID(ID), Title(), TitleImage(), TimeoutSeconds(0), TimeoutText(), ThemeName(), AnimeRun(0), Once(0), LastDraw(0), CurrentFrame(0), Frames(0), FrameTime(0), - Film(0), mAction(ActionNone), mItemID(0)//, mPointer(NULL) //, StyleFunc(&REFIT_MENU_SCREEN::TextMenuStyle) +#if XCINEMA + FilmX(), +#else + Film(0), +#endif + mAction(ActionNone), mItemID(0)//, mPointer(NULL) //, StyleFunc(&REFIT_MENU_SCREEN::TextMenuStyle) { Title.takeValueFrom(TitleC); TimeoutText.takeValueFrom(TimeoutTextC); @@ -147,7 +171,12 @@ class REFIT_MENU_SCREEN OldTextBufferRect(), OldTextBufferImage(), isBootScreen(false), AnimeRun(0), Once(0), LastDraw(0), CurrentFrame(0), Frames(0), FrameTime(0), - Film(0), mAction(ActionNone), mItemID(0)//, mPointer(NULL) //, StyleFunc(&REFIT_MENU_SCREEN::TextMenuStyle) +#if XCINEMA + FilmX(), +#else + Film(0), +#endif + mAction(ActionNone), mItemID(0)//, mPointer(NULL) //, StyleFunc(&REFIT_MENU_SCREEN::TextMenuStyle) { Entries.AddReference(entry1, false); Entries.AddReference(entry2, false); @@ -192,9 +221,11 @@ class REFIT_MENU_SCREEN VOID DrawBCSText(IN CONST CHAR16 *Text, IN INTN XPos, IN INTN YPos, IN UINT8 XAlign); VOID CountItems(); VOID InitAnime(); - BOOLEAN GetAnime(); + BOOLEAN GetAnime(); //same for xcinema VOID UpdateAnime(); - +#if XCINEMA + VOID UpdateFilm(); // for future use instead of UpdateAnime +#endif //Style functions diff --git a/rEFIt_UEFI/libeg/XCinema.cpp b/rEFIt_UEFI/libeg/XCinema.cpp index f2726dadc5..d57628d949 100644 --- a/rEFIt_UEFI/libeg/XCinema.cpp +++ b/rEFIt_UEFI/libeg/XCinema.cpp @@ -6,9 +6,66 @@ // Copyright © 2020 Slice. All rights reserved. // + +#include "libegint.h" #include "XCinema.h" +#include "../gui/REFIT_MENU_SCREEN.h" + +//Screen.UpdateAnime(); called from Menu cycle wait for event +//Now = AsmReadTsc(); +//if (TimeDiff(LastDraw, Now) < FrameTime) return; +//if (Film[CurrentFrame]) { Draw } +// else skip draw +// CurrentFrame++; +//if (CurrentFrame >= Frames) { +// AnimeRun = !Once; +// CurrentFrame = 0; +//} +//LastDraw = Now; + +// object XCinema::Cinema is a part of Theme +// object FILM::FilmX is a part or current Screen. Must be initialized from Cinema somewhere on Screen init +#if XCINEMA +VOID REFIT_MENU_SCREEN::UpdateFilm() +{ + // here we propose each screen has own link to a Film + UINT64 Now = AsmReadTsc(); + + if (LastDraw == 0) { + //save background into last frame + } + + if (TimeDiff(LastDraw, Now) < FrameTime) return; + XImage *Frame = nullptr; // a link to frame needed +// EFI_STATUS Status = ThemeX.Cinema.GetFrame(CurrentFrame); + EFI_STATUS Status = FilmX->GetFrame(CurrentFrame, Frame); //get a pointer to existing frame + if (!EFI_ERROR(Status) && Frame != nullptr) { + Frame->Draw(FilmPlace.XPos, FilmPlace.YPos); + } + FilmX->Advance(CurrentFrame); //next frame no matter if previous was not found + if (CurrentFrame == 0) { //first loop finished + AnimeRun = !Once; //will stop anime + } + LastDraw = Now; +} +#endif +FILM* XCinema::GetFilm(INTN Id) +{ + for (size_t i = 0; i < Cinema.size(); ++i) { + if (Cinema[i].Id == Id) { + return &Cinema[i]; + } + } + return nullptr; +} -void FILM::Advance() +EFI_STATUS FILM::GetFrame(IN INTN Index, OUT XImage *Image) { - CurrentFrame = ++CurrentFrame % Count; + for (size_t i = 0; i < Frames.size(); ++i) { + if (Frames[i].Index == Index) { + Image = &Frames[i].Image; + return EFI_SUCCESS; + } + } + return EFI_NOT_FOUND; } diff --git a/rEFIt_UEFI/libeg/XCinema.h b/rEFIt_UEFI/libeg/XCinema.h index 11c261c9f2..a1ca3065d1 100644 --- a/rEFIt_UEFI/libeg/XCinema.h +++ b/rEFIt_UEFI/libeg/XCinema.h @@ -27,20 +27,22 @@ class FILM { public: bool RunOnce; + INTN Id; //ScreenID, enumeration value but keep it to be int for extensibility protected: - INTN Id; //enumeration value but keep it to be int for extensibility + INTN FrameTime; //usually 50, 100, 200 ms XString Path; //user defined name for folder and files Path/Path_002.png etc XObjArray Frames; //Frames can be not sorted INTN LastIndex; // it is not Frames.size(), it is last index inclusive, so frames 0,1,2,5,8 be LastIndex = 8 EG_RECT FilmPlace; - INTN CurrentFrame; // like a static value will be increase between 0..LastIndex +// INTN CurrentFrame; // like a static value will be increased between 0..LastIndex, no it's a part of Screen public: - FILM(); + FILM(): RunOnce(false), Id(0), FrameTime(0), Path(), Frames(), LastIndex(0), FilmPlace() + {} FILM(INTN Id) : RunOnce(false), Id(Id), FrameTime(0), Path(), Frames(), - LastIndex(0), FilmPlace(), CurrentFrame(0) {}; - ~FILM(); + LastIndex(0), FilmPlace() {} + ~FILM() {} const XImage& GetImage(INTN Index); void AddFrame(const FRAME& Frame, INTN Index); @@ -48,18 +50,20 @@ class FILM INTN LastFrame() { return LastIndex; } void GetFilm(const XStringW& Path); //read from Theme void SetPlace(const EG_RECT& Rect); - void Advance() { ++CurrentFrame %= (LastIndex + 1); } + void Advance(INTN& Current) { ++Current %= (LastIndex + 1); } + EFI_STATUS GetFrame(IN INTN Index, OUT XImage *Frame); //usually Index=CurrentFrame + EFI_STATUS GetFrame(OUT XImage *Frame); }; //initially it was supposed to be one anime per one REFIT_SCREEN // but this leads to large delays switching screens to initialize Film sequence again and again -// otherwise anime depends on theme and should be a member or XTheme +// otherwise anime depends on theme and should be a member of XTheme // then it should contain Screen->ID for each film -// but for next future we want to have other animated images except screen->titleimage +// but for next future we want to have other animated images in addition to screen->titleimage // so let it be frames arrays each with own purpose (Id) -// XTheme contains Cinema -// Each Screen contains a pointer to FILM. And moreover titleFilm, or BackgroundFilm or even entryFilm +// XTheme contains Cinema which is an array of FILMs +// Each Screen contains a pointer to a FILM. And moreover titleFilm, or BackgroundFilm or even entryFilm // Next problem is a timeout between frames. // A theme contains images with indexes 1,2,5,6 for one Id. // This Id contains fixed timeout between frames. Then next updateAnime Index will be compared with current tick @@ -76,8 +80,8 @@ class XCinema public: - XCinema(); - ~XCinema(); + XCinema() {} + ~XCinema() {} FILM* GetFilm(INTN Id); void AddFilm(const FILM& NewFilm, INTN Id); diff --git a/rEFIt_UEFI/libeg/XTheme.h b/rEFIt_UEFI/libeg/XTheme.h index bbd4f71ba2..606c6ba0a7 100644 --- a/rEFIt_UEFI/libeg/XTheme.h +++ b/rEFIt_UEFI/libeg/XTheme.h @@ -7,6 +7,7 @@ #include "libeg.h" //#include "nanosvg.h" #include "XImage.h" +#include "XCinema.h" #define INDICATOR_SIZE (52) @@ -118,6 +119,9 @@ class XTheme XImage FontImage; EG_RECT BannerPlace; +#if XCINEMA + XCinema Cinema; +#endif //fill the theme // const XImage& GetIcon(const char* Name); diff --git a/rEFIt_UEFI/libeg/libeg.h b/rEFIt_UEFI/libeg/libeg.h index 3a867e5c6a..b3aee559e4 100755 --- a/rEFIt_UEFI/libeg/libeg.h +++ b/rEFIt_UEFI/libeg/libeg.h @@ -37,6 +37,8 @@ #ifndef __LIBEG_LIBEG_H__ #define __LIBEG_LIBEG_H__ +#define XCINEMA 0 + #ifdef __cplusplus extern "C" { #endif diff --git a/rEFIt_UEFI/refit.inf b/rEFIt_UEFI/refit.inf index ef24da929f..59c69b0caa 100644 --- a/rEFIt_UEFI/refit.inf +++ b/rEFIt_UEFI/refit.inf @@ -103,6 +103,8 @@ libeg/XPointer.h libeg/XTheme.cpp libeg/XTheme.h + libeg/XCinema.cpp + libeg/XCinema.h Platform/Posix/posix.h Platform/Posix/limits.h Platform/Posix/stdarg.h diff --git a/rEFIt_UEFI/refit/IO.cpp b/rEFIt_UEFI/refit/IO.cpp index 1f1e379593..bc47e58ec1 100644 --- a/rEFIt_UEFI/refit/IO.cpp +++ b/rEFIt_UEFI/refit/IO.cpp @@ -1077,8 +1077,11 @@ EFI_STATUS WaitForInputEventPoll(REFIT_MENU_SCREEN* ScreenPtr, UINTN TimeoutDefa if (Status != EFI_TIMEOUT) { break; } - - Screen.UpdateAnime(); //should be moved to REFIT_MENU_SCREEN class +#if XCINEMA + Screen.UpdateFilm(); +#else + Screen.UpdateAnime(); +#endif if (gSettings.PlayAsync) { CheckSyncSound(); } diff --git a/rEFIt_UEFI/refit/screen.cpp b/rEFIt_UEFI/refit/screen.cpp index 778e3fe8a4..305f068e9d 100644 --- a/rEFIt_UEFI/refit/screen.cpp +++ b/rEFIt_UEFI/refit/screen.cpp @@ -478,6 +478,18 @@ INTN HybridRepositioning(INTN Edge, INTN Value, INTN ImageDimension, INTN Screen } return pos; } +#if XCINEMA +BOOLEAN REFIT_MENU_SCREEN::GetAnime() +{ + FilmX = ThemeX.Cinema.GetFilm(ID); + return FilmX != nullptr; +} + +VOID REFIT_MENU_SCREEN::InitAnime() +{ + //something +} +#else static EG_IMAGE *AnimeImage = NULL; @@ -672,7 +684,7 @@ BOOLEAN REFIT_MENU_SCREEN::GetAnime() return TRUE; } - +#endif // // Sets next/previous available screen resolution, according to specified offset //