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);
|
*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(DMenuDescriptor, false, false)
|
||||||
IMPLEMENT_CLASS(DListMenuDescriptor, false, false)
|
IMPLEMENT_CLASS(DListMenuDescriptor, false, false)
|
||||||
IMPLEMENT_CLASS(DOptionMenuDescriptor, false, false)
|
IMPLEMENT_CLASS(DOptionMenuDescriptor, false, false)
|
||||||
|
IMPLEMENT_CLASS(DImageScrollerDescriptor, false, false)
|
||||||
|
|
||||||
DMenuDescriptor *GetMenuDescriptor(int name)
|
DMenuDescriptor *GetMenuDescriptor(int name)
|
||||||
{
|
{
|
||||||
|
@ -136,6 +137,13 @@ DEFINE_ACTION_FUNCTION_NATIVE(DMenuDescriptor, GetDescriptor, GetMenuDescriptor)
|
||||||
ACTION_RETURN_OBJECT(GetMenuDescriptor(name.GetIndex()));
|
ACTION_RETURN_OBJECT(GetMenuDescriptor(name.GetIndex()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t DMenuDescriptor::PropagateMark()
|
||||||
|
{
|
||||||
|
for (auto item : mItems) GC::Mark(item);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DListMenuDescriptor::Reset()
|
void DListMenuDescriptor::Reset()
|
||||||
{
|
{
|
||||||
// Reset the default settings (ignore all other values in the struct)
|
// 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()
|
void DOptionMenuDescriptor::Reset()
|
||||||
{
|
{
|
||||||
// Reset the default settings (ignore all other values in the struct)
|
// Reset the default settings (ignore all other values in the struct)
|
||||||
|
@ -178,12 +180,6 @@ void DOptionMenuDescriptor::Reset()
|
||||||
mFont = BigUpper;
|
mFont = BigUpper;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DOptionMenuDescriptor::PropagateMark()
|
|
||||||
{
|
|
||||||
for (auto item : mItems) GC::Mark(item);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void M_MarkMenus()
|
void M_MarkMenus()
|
||||||
{
|
{
|
||||||
MenuDescriptorList::Iterator it(MenuDescriptors);
|
MenuDescriptorList::Iterator it(MenuDescriptors);
|
||||||
|
@ -1045,6 +1041,15 @@ DEFINE_FIELD(FOptionMenuSettings, mFontColorHighlight)
|
||||||
DEFINE_FIELD(FOptionMenuSettings, mFontColorSelection)
|
DEFINE_FIELD(FOptionMenuSettings, mFontColorSelection)
|
||||||
DEFINE_FIELD(FOptionMenuSettings, mLinespacing)
|
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;
|
struct IJoystickConfig;
|
||||||
// These functions are used by dynamic menu creation.
|
// These functions are used by dynamic menu creation.
|
||||||
|
|
|
@ -66,7 +66,7 @@ public:
|
||||||
bool mProtected = false;
|
bool mProtected = false;
|
||||||
TArray<DMenuItemBase *> mItems;
|
TArray<DMenuItemBase *> mItems;
|
||||||
|
|
||||||
virtual size_t PropagateMark() { return 0; }
|
size_t PropagateMark() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,7 +95,6 @@ public:
|
||||||
int mVirtHeight;
|
int mVirtHeight;
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
size_t PropagateMark() override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FOptionMenuSettings
|
struct FOptionMenuSettings
|
||||||
|
@ -128,10 +127,22 @@ public:
|
||||||
void CalcIndent();
|
void CalcIndent();
|
||||||
DMenuItemBase *GetItem(FName name);
|
DMenuItemBase *GetItem(FName name);
|
||||||
void Reset();
|
void Reset();
|
||||||
size_t PropagateMark() override;
|
|
||||||
~DOptionMenuDescriptor() = default;
|
~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;
|
typedef TMap<FName, DMenuDescriptor *> MenuDescriptorList;
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
#include "i_interface.h"
|
#include "i_interface.h"
|
||||||
|
#include "templates.h"
|
||||||
|
|
||||||
|
|
||||||
bool CheckSkipGameOptionBlock(FScanner& sc);
|
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.
|
// 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.
|
// 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());
|
sc.ScriptMessage("Cannot replace protected menu %s.", desc->mMenuName.GetChars());
|
||||||
return true;
|
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.");
|
I_FatalError("You cannot add menu items to the menu default settings.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (sc.Compare("IMAGESCROLLER"))
|
||||||
|
{
|
||||||
|
ParseImageScroller(sc);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sc.ScriptError("Unknown keyword '%s'", sc.String);
|
sc.ScriptError("Unknown keyword '%s'", sc.String);
|
||||||
|
|
|
@ -137,8 +137,6 @@ bool AppActive = true;
|
||||||
|
|
||||||
FString currentGame;
|
FString currentGame;
|
||||||
FString LumpFilter;
|
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(Bool, queryiwad, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||||
CVAR(String, defaultiwad, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
CVAR(String, defaultiwad, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||||
|
@ -1822,6 +1820,7 @@ static const gamefilter games[] = {
|
||||||
{ "Blood", GAMEFLAG_BLOOD},
|
{ "Blood", GAMEFLAG_BLOOD},
|
||||||
{ "ShadowWarrior", GAMEFLAG_SW},
|
{ "ShadowWarrior", GAMEFLAG_SW},
|
||||||
{ "Exhumed", GAMEFLAG_POWERSLAVE | GAMEFLAG_EXHUMED},
|
{ "Exhumed", GAMEFLAG_POWERSLAVE | GAMEFLAG_EXHUMED},
|
||||||
|
{ "Plutopak", GAMEFLAG_PLUTOPAK},
|
||||||
{ "Worldtour", GAMEFLAG_WORLDTOUR},
|
{ "Worldtour", GAMEFLAG_WORLDTOUR},
|
||||||
{ "Shareware", GAMEFLAG_SHAREWARE},
|
{ "Shareware", GAMEFLAG_SHAREWARE},
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,12 +23,10 @@ extern bool r_NoInterpolate;
|
||||||
|
|
||||||
struct MapRecord;
|
struct MapRecord;
|
||||||
extern MapRecord* g_nextmap;
|
extern MapRecord* g_nextmap;
|
||||||
extern int g_nextskill;
|
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 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();
|
int CONFIG_Init();
|
||||||
|
|
||||||
// I am not sure if anything below will survive for long...
|
// I am not sure if anything below will survive for long...
|
||||||
|
|
|
@ -518,6 +518,9 @@ x(INGAMEDUKETHREEDEE, 2499)
|
||||||
x(TENSCREEN, 2500)
|
x(TENSCREEN, 2500)
|
||||||
x(PLUTOPAKSPRITE, 2501)
|
x(PLUTOPAKSPRITE, 2501)
|
||||||
x(MENUPLUTOPAKSPRITE, 2503)
|
x(MENUPLUTOPAKSPRITE, 2503)
|
||||||
|
x(CREDITPAGE1, 2504)
|
||||||
|
x(CREDITPAGE2, 2505)
|
||||||
|
x(CREDITPAGE3, 2506)
|
||||||
x(DEVISTATOR, 2510)
|
x(DEVISTATOR, 2510)
|
||||||
x(KNEE, 2521)
|
x(KNEE, 2521)
|
||||||
x(CROSSHAIR, 2523)
|
x(CROSSHAIR, 2523)
|
||||||
|
|
|
@ -199,19 +199,15 @@ LISTMENU "SkillMenu"
|
||||||
//
|
//
|
||||||
//-------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
/*
|
|
||||||
ImageScroller "HelpMenu"
|
ImageScroller "HelpMenu"
|
||||||
{
|
{
|
||||||
ifgame(Duke, Nam, WW2GI)
|
ifgame(Duke, Nam, WW2GI)
|
||||||
{
|
{
|
||||||
ImageItem "#3280"
|
ImageItem "TEXTSTORY"
|
||||||
ImageItem "#2445"
|
ImageItem "F1HELP"
|
||||||
class "$.ImageScrollerMenu"
|
animatedtransition
|
||||||
ifgame(Duke, Nam, WW2GI)
|
|
||||||
{
|
|
||||||
animatedtransition
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
ifgame(Redneck, RedneckRides)
|
ifgame(Redneck, RedneckRides)
|
||||||
{
|
{
|
||||||
ImageItem "#2541"
|
ImageItem "#2541"
|
||||||
|
@ -242,8 +238,8 @@ ImageScroller "HelpMenu"
|
||||||
ImageItem "#5261"
|
ImageItem "#5261"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
@ -256,17 +252,16 @@ ImageScroller "HelpMenu"
|
||||||
//
|
//
|
||||||
//-------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
/*
|
|
||||||
ImageScroller "CreditsMenu"
|
ImageScroller "CreditsMenu"
|
||||||
{
|
{
|
||||||
ifgame(Duke, Nam, WW2GI)
|
ifgame(Duke, Nam, WW2GI)
|
||||||
{
|
{
|
||||||
ImageItem "#2504"
|
ImageItem "CREDITPAGE1"
|
||||||
ImageItem "#2505"
|
ImageItem "CREDITPAGE2"
|
||||||
ImageItem "#2506"
|
ImageItem "CREDITPAGE3"
|
||||||
animatedtransition
|
animatedtransition
|
||||||
class "Duke.ImageScrollerMenu"
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
ifgame(Redneck)
|
ifgame(Redneck)
|
||||||
{
|
{
|
||||||
// no point putting this into the string table.
|
// no point putting this into the string table.
|
||||||
|
@ -346,8 +341,8 @@ ImageScroller "CreditsMenu"
|
||||||
ImageItem "#4979"
|
ImageItem "#4979"
|
||||||
ImageItem "#5113"
|
ImageItem "#5113"
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
|
|
@ -20,6 +20,7 @@ version "4.3"
|
||||||
#include "zscript/ui/menu/reverbedit.zs"
|
#include "zscript/ui/menu/reverbedit.zs"
|
||||||
#include "zscript/ui/menu/textentermenu.zs"
|
#include "zscript/ui/menu/textentermenu.zs"
|
||||||
#include "zscript/ui/menu/menucustomize.zs"
|
#include "zscript/ui/menu/menucustomize.zs"
|
||||||
|
#include "zscript/ui/menu/imagescroller.zs"
|
||||||
|
|
||||||
#include "zscript/games/duke/ui/menu.zs"
|
#include "zscript/games/duke/ui/menu.zs"
|
||||||
#include "zscript/games/blood/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 GetClipRect();
|
||||||
native static int, int, int, int GetViewWindow();
|
native static int, int, int, int GetViewWindow();
|
||||||
native static double, double, double, double GetFullscreenRect(double vwidth, double vheight, int fsmode);
|
native static double, double, double, double GetFullscreenRect(double vwidth, double vheight, int fsmode);
|
||||||
|
native static Vector2 SetOffset(double x, double y);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Font native
|
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