mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-14 11:50:49 +00:00
- ImageScroller WIP commit.
This commit is contained in:
parent
15eaf86f5a
commit
6ba06f5ed0
11 changed files with 540 additions and 37 deletions
|
@ -1553,3 +1553,11 @@ void V_CalcCleanFacs(int designwidth, int designheight, int realwidth, int realh
|
|||
*cleanx = *cleany = std::min(realwidth / designwidth, realheight / designheight);
|
||||
}
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Screen, SetOffset)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
ACTION_RETURN_VEC2(twod->SetOffset(DVector2(x, y)));
|
||||
}
|
|
@ -122,6 +122,7 @@ bool OkForLocalization(FTextureID texnum, const char* substitute);
|
|||
IMPLEMENT_CLASS(DMenuDescriptor, false, false)
|
||||
IMPLEMENT_CLASS(DListMenuDescriptor, false, false)
|
||||
IMPLEMENT_CLASS(DOptionMenuDescriptor, false, false)
|
||||
IMPLEMENT_CLASS(DImageScrollerDescriptor, false, false)
|
||||
|
||||
DMenuDescriptor *GetMenuDescriptor(int name)
|
||||
{
|
||||
|
@ -136,6 +137,13 @@ DEFINE_ACTION_FUNCTION_NATIVE(DMenuDescriptor, GetDescriptor, GetMenuDescriptor)
|
|||
ACTION_RETURN_OBJECT(GetMenuDescriptor(name.GetIndex()));
|
||||
}
|
||||
|
||||
size_t DMenuDescriptor::PropagateMark()
|
||||
{
|
||||
for (auto item : mItems) GC::Mark(item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void DListMenuDescriptor::Reset()
|
||||
{
|
||||
// Reset the default settings (ignore all other values in the struct)
|
||||
|
@ -162,12 +170,6 @@ DEFINE_ACTION_FUNCTION(DListMenuDescriptor, Reset)
|
|||
}
|
||||
|
||||
|
||||
size_t DListMenuDescriptor::PropagateMark()
|
||||
{
|
||||
for (auto item : mItems) GC::Mark(item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DOptionMenuDescriptor::Reset()
|
||||
{
|
||||
// Reset the default settings (ignore all other values in the struct)
|
||||
|
@ -178,12 +180,6 @@ void DOptionMenuDescriptor::Reset()
|
|||
mFont = BigUpper;
|
||||
}
|
||||
|
||||
size_t DOptionMenuDescriptor::PropagateMark()
|
||||
{
|
||||
for (auto item : mItems) GC::Mark(item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void M_MarkMenus()
|
||||
{
|
||||
MenuDescriptorList::Iterator it(MenuDescriptors);
|
||||
|
@ -1045,6 +1041,15 @@ DEFINE_FIELD(FOptionMenuSettings, mFontColorHighlight)
|
|||
DEFINE_FIELD(FOptionMenuSettings, mFontColorSelection)
|
||||
DEFINE_FIELD(FOptionMenuSettings, mLinespacing)
|
||||
|
||||
DEFINE_FIELD(DImageScrollerDescriptor, mItems)
|
||||
DEFINE_FIELD(DImageScrollerDescriptor, textBackground)
|
||||
DEFINE_FIELD(DImageScrollerDescriptor, textBackgroundBrightness)
|
||||
DEFINE_FIELD(DImageScrollerDescriptor,textFont)
|
||||
DEFINE_FIELD(DImageScrollerDescriptor, textScale)
|
||||
DEFINE_FIELD(DImageScrollerDescriptor, mAnimatedTransition)
|
||||
DEFINE_FIELD(DImageScrollerDescriptor, virtWidth)
|
||||
DEFINE_FIELD(DImageScrollerDescriptor, virtHeight)
|
||||
|
||||
|
||||
struct IJoystickConfig;
|
||||
// These functions are used by dynamic menu creation.
|
||||
|
|
|
@ -66,7 +66,7 @@ public:
|
|||
bool mProtected = false;
|
||||
TArray<DMenuItemBase *> mItems;
|
||||
|
||||
virtual size_t PropagateMark() { return 0; }
|
||||
size_t PropagateMark() override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -95,7 +95,6 @@ public:
|
|||
int mVirtHeight;
|
||||
|
||||
void Reset();
|
||||
size_t PropagateMark() override;
|
||||
};
|
||||
|
||||
struct FOptionMenuSettings
|
||||
|
@ -128,10 +127,22 @@ public:
|
|||
void CalcIndent();
|
||||
DMenuItemBase *GetItem(FName name);
|
||||
void Reset();
|
||||
size_t PropagateMark() override;
|
||||
~DOptionMenuDescriptor() = default;
|
||||
};
|
||||
|
||||
class DImageScrollerDescriptor : public DMenuDescriptor
|
||||
{
|
||||
DECLARE_CLASS(DOptionMenuDescriptor, DMenuDescriptor)
|
||||
public:
|
||||
FTextureID textBackground;
|
||||
PalEntry textBackgroundBrightness;
|
||||
|
||||
FFont *textFont;
|
||||
double textScale;
|
||||
bool mAnimatedTransition;
|
||||
int virtWidth, virtHeight;
|
||||
|
||||
};
|
||||
|
||||
typedef TMap<FName, DMenuDescriptor *> MenuDescriptorList;
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "texturemanager.h"
|
||||
#include "printf.h"
|
||||
#include "i_interface.h"
|
||||
#include "templates.h"
|
||||
|
||||
|
||||
bool CheckSkipGameOptionBlock(FScanner& sc);
|
||||
|
@ -629,7 +630,7 @@ static bool ReplaceMenu(FScanner &sc, DMenuDescriptor *desc)
|
|||
{
|
||||
// If this tries to replace an option menu with an option menu, let's append all new entries to the old menu.
|
||||
// Otherwise bail out because for list menus it's not that simple.
|
||||
if (desc->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor)) || (*pOld)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor)))
|
||||
if (!desc->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor)) || !(*pOld)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor)))
|
||||
{
|
||||
sc.ScriptMessage("Cannot replace protected menu %s.", desc->mMenuName.GetChars());
|
||||
return true;
|
||||
|
@ -1052,6 +1053,214 @@ static void ParseAddOptionMenu(FScanner &sc)
|
|||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
static void ParseImageScrollerBody(FScanner& sc, DImageScrollerDescriptor* desc)
|
||||
{
|
||||
sc.MustGetStringName("{");
|
||||
while (!sc.CheckString("}"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("else"))
|
||||
{
|
||||
SkipSubBlock(sc);
|
||||
}
|
||||
else if (sc.Compare("ifgame"))
|
||||
{
|
||||
if (!CheckSkipGameBlock(sc))
|
||||
{
|
||||
// recursively parse sub-block
|
||||
ParseImageScrollerBody(sc, desc);
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("ifnotgame"))
|
||||
{
|
||||
if (!CheckSkipGameBlock(sc, true))
|
||||
{
|
||||
// recursively parse sub-block
|
||||
ParseImageScrollerBody(sc, desc);
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("ifoption"))
|
||||
{
|
||||
if (!CheckSkipOptionBlock(sc))
|
||||
{
|
||||
// recursively parse sub-block
|
||||
ParseImageScrollerBody(sc, desc);
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("animatedtransition"))
|
||||
{
|
||||
desc->mAnimatedTransition = true;
|
||||
}
|
||||
else if (sc.Compare("textBackground"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
desc->textBackground = GetMenuTexture(sc.String);
|
||||
}
|
||||
else if (sc.Compare("textBackgroundBrightness"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
int bb = clamp(int(sc.Float * 255), 0, 255);
|
||||
desc->textBackgroundBrightness = PalEntry(255, bb, bb, bb);
|
||||
}
|
||||
else if (sc.Compare("textScale"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
desc->textScale = sc.Float;
|
||||
}
|
||||
else if (sc.Compare("textFont"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
FFont* newfont = V_GetFont(sc.String);
|
||||
if (newfont != nullptr) desc->textFont = newfont;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool success = false;
|
||||
FStringf buildname("ImageScrollerPage%s", sc.String);
|
||||
// Handle one special case: MapControl maps to Control with one parameter different
|
||||
PClass* cls = PClass::FindClass(buildname);
|
||||
if (cls != nullptr && cls->IsDescendantOf("ImageScrollerPage"))
|
||||
{
|
||||
auto func = dyn_cast<PFunction>(cls->FindSymbol("Init", true));
|
||||
if (func != nullptr && !(func->Variants[0].Flags & (VARF_Protected | VARF_Private))) // skip internal classes which have a protected init method.
|
||||
{
|
||||
auto& args = func->Variants[0].Proto->ArgumentTypes;
|
||||
TArray<VMValue> params;
|
||||
|
||||
int start = 1;
|
||||
|
||||
params.Push(0);
|
||||
if (args.Size() > 1 && args[1] == NewPointer(PClass::FindClass("ImageScrollerDescriptor")))
|
||||
{
|
||||
params.Push(desc);
|
||||
start = 2;
|
||||
}
|
||||
auto TypeCVar = NewPointer(NewStruct("CVar", nullptr, true));
|
||||
|
||||
// Note that this array may not be reallocated so its initial size must be the maximum possible elements.
|
||||
TArray<FString> strings(args.Size());
|
||||
for (unsigned i = start; i < args.Size(); i++)
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (args[i] == TypeString)
|
||||
{
|
||||
strings.Push(sc.String);
|
||||
params.Push(&strings.Last());
|
||||
}
|
||||
else if (args[i] == TypeName)
|
||||
{
|
||||
params.Push(FName(sc.String).GetIndex());
|
||||
}
|
||||
else if (args[i] == TypeColor)
|
||||
{
|
||||
params.Push(V_GetColor(nullptr, sc));
|
||||
}
|
||||
else if (args[i]->isIntCompatible())
|
||||
{
|
||||
char* endp;
|
||||
int v = (int)strtoll(sc.String, &endp, 0);
|
||||
if (*endp != 0)
|
||||
{
|
||||
// special check for font color ranges.
|
||||
v = V_FindFontColor(sc.String);
|
||||
if (v == CR_UNTRANSLATED && !sc.Compare("untranslated"))
|
||||
{
|
||||
// todo: check other data types that may get used.
|
||||
sc.ScriptError("Integer expected, got %s", sc.String);
|
||||
}
|
||||
}
|
||||
if (args[i] == TypeBool) v = !!v;
|
||||
params.Push(v);
|
||||
}
|
||||
else if (args[i]->isFloat())
|
||||
{
|
||||
char* endp;
|
||||
double v = strtod(sc.String, &endp);
|
||||
if (*endp != 0)
|
||||
{
|
||||
sc.ScriptError("Float expected, got %s", sc.String);
|
||||
}
|
||||
params.Push(v);
|
||||
}
|
||||
else if (args[i] == TypeCVar)
|
||||
{
|
||||
auto cv = FindCVar(sc.String, nullptr);
|
||||
if (cv == nullptr && *sc.String)
|
||||
{
|
||||
if (func->Variants[0].ArgFlags[i] & VARF_Optional)
|
||||
sc.ScriptMessage("Unknown CVar %s", sc.String);
|
||||
else
|
||||
sc.ScriptError("Unknown CVar %s", sc.String);
|
||||
}
|
||||
params.Push(cv);
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptError("Invalid parameter type %s for image page", args[i]->DescriptiveName());
|
||||
}
|
||||
if (sc.CheckString(","))
|
||||
{
|
||||
if (i == args.Size() - 1)
|
||||
{
|
||||
sc.ScriptError("Too many parameters for %s", cls->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i < args.Size() - 1 && !(func->Variants[0].ArgFlags[i + 1] & VARF_Optional))
|
||||
{
|
||||
sc.ScriptError("Insufficient parameters for %s", cls->TypeName.GetChars());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DMenuItemBase* item = (DMenuItemBase*)cls->CreateNew();
|
||||
params[0] = item;
|
||||
VMCallWithDefaults(func->Variants[0].Implementation, params, nullptr, 0);
|
||||
desc->mItems.Push((DMenuItemBase*)item);
|
||||
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
if (!success)
|
||||
{
|
||||
sc.ScriptError("Unknown keyword '%s'", sc.String);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
static void ParseImageScroller(FScanner& sc)
|
||||
{
|
||||
sc.MustGetString();
|
||||
|
||||
DImageScrollerDescriptor* desc = Create<DImageScrollerDescriptor>();
|
||||
|
||||
desc->textBackground.SetInvalid();
|
||||
desc->textBackgroundBrightness = 0xffffffff;
|
||||
desc->textFont = SmallFont;
|
||||
desc->textScale = 1;
|
||||
desc->mAnimatedTransition = false;
|
||||
|
||||
ParseImageScrollerBody(sc, desc);
|
||||
bool scratch = ReplaceMenu(sc, desc);
|
||||
if (scratch) delete desc;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
|
@ -1118,6 +1327,10 @@ void M_ParseMenuDefs()
|
|||
I_FatalError("You cannot add menu items to the menu default settings.");
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("IMAGESCROLLER"))
|
||||
{
|
||||
ParseImageScroller(sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptError("Unknown keyword '%s'", sc.String);
|
||||
|
|
|
@ -137,8 +137,6 @@ bool AppActive = true;
|
|||
|
||||
FString currentGame;
|
||||
FString LumpFilter;
|
||||
TMap<FName, int32_t> NameToTileIndex; // for assigning names to tiles. The menu accesses this list. By default it gets everything from the dynamic tile map in Duke Nukem and Redneck Rampage.
|
||||
// Todo: Add additional definition file for the other games or textures not in that list so that the menu does not have to rely on indices.
|
||||
|
||||
CVAR(Bool, queryiwad, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
CVAR(String, defaultiwad, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
|
@ -1822,6 +1820,7 @@ static const gamefilter games[] = {
|
|||
{ "Blood", GAMEFLAG_BLOOD},
|
||||
{ "ShadowWarrior", GAMEFLAG_SW},
|
||||
{ "Exhumed", GAMEFLAG_POWERSLAVE | GAMEFLAG_EXHUMED},
|
||||
{ "Plutopak", GAMEFLAG_PLUTOPAK},
|
||||
{ "Worldtour", GAMEFLAG_WORLDTOUR},
|
||||
{ "Shareware", GAMEFLAG_SHAREWARE},
|
||||
};
|
||||
|
|
|
@ -27,8 +27,6 @@ extern int g_nextskill;
|
|||
|
||||
extern FMemArena dump; // this is for memory blocks than cannot be deallocated without some huge effort. Put them in here so that they do not register on shutdown.
|
||||
|
||||
extern TMap<FName, int32_t> NameToTileIndex;
|
||||
|
||||
int CONFIG_Init();
|
||||
|
||||
// I am not sure if anything below will survive for long...
|
||||
|
|
|
@ -518,6 +518,9 @@ x(INGAMEDUKETHREEDEE, 2499)
|
|||
x(TENSCREEN, 2500)
|
||||
x(PLUTOPAKSPRITE, 2501)
|
||||
x(MENUPLUTOPAKSPRITE, 2503)
|
||||
x(CREDITPAGE1, 2504)
|
||||
x(CREDITPAGE2, 2505)
|
||||
x(CREDITPAGE3, 2506)
|
||||
x(DEVISTATOR, 2510)
|
||||
x(KNEE, 2521)
|
||||
x(CROSSHAIR, 2523)
|
||||
|
|
|
@ -199,19 +199,15 @@ LISTMENU "SkillMenu"
|
|||
//
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
ImageScroller "HelpMenu"
|
||||
{
|
||||
ifgame(Duke, Nam, WW2GI)
|
||||
{
|
||||
ImageItem "#3280"
|
||||
ImageItem "#2445"
|
||||
class "$.ImageScrollerMenu"
|
||||
ifgame(Duke, Nam, WW2GI)
|
||||
{
|
||||
animatedtransition
|
||||
}
|
||||
ImageItem "TEXTSTORY"
|
||||
ImageItem "F1HELP"
|
||||
animatedtransition
|
||||
}
|
||||
/*
|
||||
ifgame(Redneck, RedneckRides)
|
||||
{
|
||||
ImageItem "#2541"
|
||||
|
@ -242,8 +238,8 @@ ImageScroller "HelpMenu"
|
|||
ImageItem "#5261"
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
*/
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -256,17 +252,16 @@ ImageScroller "HelpMenu"
|
|||
//
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
ImageScroller "CreditsMenu"
|
||||
{
|
||||
ifgame(Duke, Nam, WW2GI)
|
||||
{
|
||||
ImageItem "#2504"
|
||||
ImageItem "#2505"
|
||||
ImageItem "#2506"
|
||||
ImageItem "CREDITPAGE1"
|
||||
ImageItem "CREDITPAGE2"
|
||||
ImageItem "CREDITPAGE3"
|
||||
animatedtransition
|
||||
class "Duke.ImageScrollerMenu"
|
||||
}
|
||||
/*
|
||||
ifgame(Redneck)
|
||||
{
|
||||
// no point putting this into the string table.
|
||||
|
@ -346,8 +341,8 @@ ImageScroller "CreditsMenu"
|
|||
ImageItem "#4979"
|
||||
ImageItem "#5113"
|
||||
}
|
||||
*/
|
||||
}
|
||||
*/
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
//
|
||||
|
|
|
@ -20,6 +20,7 @@ version "4.3"
|
|||
#include "zscript/ui/menu/reverbedit.zs"
|
||||
#include "zscript/ui/menu/textentermenu.zs"
|
||||
#include "zscript/ui/menu/menucustomize.zs"
|
||||
#include "zscript/ui/menu/imagescroller.zs"
|
||||
|
||||
#include "zscript/games/duke/ui/menu.zs"
|
||||
#include "zscript/games/blood/ui/menu.zs"
|
||||
|
|
|
@ -399,6 +399,7 @@ struct Screen native
|
|||
native static int, int, int, int GetClipRect();
|
||||
native static int, int, int, int GetViewWindow();
|
||||
native static double, double, double, double GetFullscreenRect(double vwidth, double vheight, int fsmode);
|
||||
native static Vector2 SetOffset(double x, double y);
|
||||
}
|
||||
|
||||
struct Font native
|
||||
|
|
269
wadsrc/static/zscript/ui/menu/imagescroller.zs
Normal file
269
wadsrc/static/zscript/ui/menu/imagescroller.zs
Normal file
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
** imagescroller.cpp
|
||||
** Scrolls through multiple fullscreen image pages,
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2019-220 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
class ImageScrollerDescriptor : MenuDescriptor native
|
||||
{
|
||||
native Array<ImageScrollerPage> mItems;
|
||||
native Font textFont;
|
||||
native TextureID textBackground;
|
||||
native Color textBackgroundBrightness;
|
||||
native double textScale;
|
||||
native bool mAnimatedTransition;
|
||||
native int virtWidth, virtHeight;
|
||||
}
|
||||
|
||||
class ImageScrollerPage : MenuItemBase
|
||||
{
|
||||
int virtWidth, virtHeight;
|
||||
|
||||
protected void DrawText(Font fnt, int color, double x, double y, String text)
|
||||
{
|
||||
screen.DrawText(fnt, color, x, y, text, DTA_VirtualWidth, virtWidth, DTA_VirtualHeight, virtHeight, DTA_FullscreenScale, FSMode_ScaleToFit43);
|
||||
}
|
||||
|
||||
protected void DrawTexture(TextureID tex, double x, double y)
|
||||
{
|
||||
screen.DrawTexture(tex, true, x, y, DTA_VirtualWidth, virtWidth, DTA_VirtualHeight, virtHeight, DTA_FullscreenScale, FSMode_ScaleToFit43);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// an image page
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class ImageScrollerPageImageItem : ImageScrollerPage
|
||||
{
|
||||
TextureID mTexture;
|
||||
|
||||
void Init(ImageScrollerDescriptor desc, String patch)
|
||||
{
|
||||
Super.Init();
|
||||
mTexture = TexMan.CheckForTexture(patch);
|
||||
}
|
||||
|
||||
override void Drawer(bool selected)
|
||||
{
|
||||
Screen.DrawTexture(mTexture, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// a simple text page
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class ImageScrollerPageTextItem : ImageScrollerPage
|
||||
{
|
||||
Font mFont;
|
||||
BrokenLines mText;
|
||||
TextureID mTexture;
|
||||
Color mBrightness;
|
||||
double mTextScale;
|
||||
|
||||
void Init(ImageScrollerDescriptor desc, String txt, int y = -1)
|
||||
{
|
||||
Super.Init();
|
||||
mTexture = desc.textBackground;
|
||||
mBrightness = desc.textBackgroundBrightness;
|
||||
mFont = desc.textFont;
|
||||
mTextScale = desc.textScale;
|
||||
virtWidth = desc.virtWidth;
|
||||
virtHeight = desc.virtHeight;
|
||||
mText = mFont.BreakLines(Stringtable.Localize(txt), virtWidth / mTextScale);
|
||||
mYpos = y >= 0? y : virtHeight / 2 - mText.Count() * mFont.GetHeight() / 2;
|
||||
|
||||
}
|
||||
|
||||
override void Drawer(bool selected)
|
||||
{
|
||||
Screen.DrawTexture(mTexture, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal, DTA_Color, mBrightness);
|
||||
|
||||
int fontheight = mFont.GetHeight() * mTextScale;
|
||||
let y = mYpos;
|
||||
let c = mText.Count();
|
||||
for (int i = 0; i < c; i++)
|
||||
{
|
||||
screen.DrawText (mFont, Font.CR_UNTRANSLATED, virtWidth/2 - mText.StringWidth(i) * mTextScale / 2, y, mText.StringAt(i), DTA_ScaleX, mTextScale, DTA_ScaleY, mTextScale,
|
||||
DTA_VirtualWidth, virtWidth, DTA_VirtualHeight, virtHeight, DTA_FullscreenScale, FSMode_ScaleToFit43);
|
||||
y += fontheight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// The main class
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class ImageScrollerMenu : Menu
|
||||
{
|
||||
ImageScrollerPage previous;
|
||||
ImageScrollerPage current;
|
||||
|
||||
double start;
|
||||
int length;
|
||||
int dir;
|
||||
int index;
|
||||
ImageScrollerDescriptor mDesc;
|
||||
|
||||
|
||||
private void StartTransition(ImageScrollerPage to, int animtype)
|
||||
{
|
||||
if (AnimatedTransition)
|
||||
{
|
||||
start = MSTime() * (120. / 1000.);
|
||||
length = 30;
|
||||
dir = animtype;
|
||||
previous = current;
|
||||
}
|
||||
current = to;
|
||||
}
|
||||
|
||||
void Init(Menu parent, ImageScrollerDescriptor desc)
|
||||
{
|
||||
mParentMenu = parent;
|
||||
index = 0;
|
||||
mDesc = desc;
|
||||
AnimatedTransition = desc.mAnimatedTransition;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MenuEvent(int mkey, bool fromcontroller)
|
||||
{
|
||||
if (mDesc.mItems.Size() <= 1)
|
||||
{
|
||||
if (mkey == MKEY_Enter) mkey = MKEY_Back;
|
||||
else if (mkey == MKEY_Right || mkey == MKEY_Left) return true;
|
||||
}
|
||||
switch (mkey)
|
||||
{
|
||||
case MKEY_Back:
|
||||
// Before going back the currently running transition must be terminated.
|
||||
previous = null;
|
||||
return Super.MenuEvent(mkey, fromcontroller);
|
||||
|
||||
|
||||
case MKEY_Left:
|
||||
if (previous == null)
|
||||
{
|
||||
if (--index < 0) index = mDesc.mItems.Size() - 1;
|
||||
let next = mDesc.mItems[index];
|
||||
StartTransition(next, -1);
|
||||
MenuSound("menu/choose");
|
||||
}
|
||||
return true;
|
||||
|
||||
case MKEY_Right:
|
||||
case MKEY_Enter:
|
||||
if (previous == null)
|
||||
{
|
||||
int oldindex = index;
|
||||
if (++index >= mDesc.mItems.Size()) index = 0;
|
||||
let next = mDesc.mItems[index];
|
||||
StartTransition(next, 1);
|
||||
MenuSound("menu/choose");
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
return Super.MenuEvent(mkey, fromcontroller);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override bool MouseEvent(int type, int x, int y)
|
||||
{
|
||||
// Todo: Implement some form of drag event to switch between pages.
|
||||
if (type == MOUSE_Release)
|
||||
{
|
||||
return MenuEvent(MKEY_Enter, false);
|
||||
}
|
||||
return Super.MouseEvent(type, x, y);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
private bool DrawTransition()
|
||||
{
|
||||
double now = MSTime() * (120. / 1000.);
|
||||
if (now < start + length)
|
||||
{
|
||||
double factor = screen.GetWidth()/2;
|
||||
double phase = (now - start) / length * 180. + 90.;
|
||||
|
||||
screen.SetOffset(0, factor * dir * (sin(phase) - 1.));
|
||||
previous.Drawer(false);
|
||||
screen.SetOffset(0, factor * dir * (sin(phase) + 1.));
|
||||
current.Drawer(false);
|
||||
screen.SetOffset(0, 0);
|
||||
return true;
|
||||
}
|
||||
previous = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
override void Drawer()
|
||||
{
|
||||
if (previous != null)
|
||||
{
|
||||
if (DrawTransition()) return;
|
||||
previous = null;
|
||||
}
|
||||
current.Drawer(false);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue