This commit is contained in:
nashmuhandes 2017-02-12 00:32:22 +08:00
commit d2c49cccd5
38 changed files with 1231 additions and 827 deletions

View file

@ -998,6 +998,7 @@ set (PCH_SOURCES
textures/pngtexture.cpp
textures/rawpagetexture.cpp
textures/emptytexture.cpp
textures/backdroptexture.cpp
textures/texture.cpp
textures/texturemanager.cpp
textures/tgatexture.cpp

View file

@ -418,7 +418,8 @@ enum ActorRenderFlag
RF_FLATSPRITE = 0x2000, // Flat sprite
RF_VOXELSPRITE = 0x3000, // Voxel object
RF_INVISIBLE = 0x8000, // Don't bother drawing this actor
RF_MAYBEINVISIBLE = 0x10000,
RF_FORCEYBILLBOARD = 0x10000, // [BB] OpenGL only: draw with y axis billboard, i.e. anchored to the floor (overrides gl_billboard_mode setting)
RF_FORCEXYBILLBOARD = 0x20000, // [BB] OpenGL only: draw with xy axis billboard, i.e. unanchored (overrides gl_billboard_mode setting)
RF_ROLLSPRITE = 0x40000, //[marrub]roll the sprite billboard
RF_DONTFLIP = 0x80000, // Don't flip it when viewed from behind.
RF_ROLLCENTER = 0x00100000, // Rotate from the center of sprite instead of offsets
@ -426,9 +427,7 @@ enum ActorRenderFlag
RF_ABSMASKANGLE = 0x00400000, // [MC] The mask rotation does not offset by the actor's angle.
RF_ABSMASKPITCH = 0x00800000, // [MC] The mask rotation does not offset by the actor's pitch.
RF_INTERPOLATEANGLES = 0x01000000, // [MC] Allow interpolation of the actor's angle, pitch and roll.
RF_FORCEYBILLBOARD = 0x10000, // [BB] OpenGL only: draw with y axis billboard, i.e. anchored to the floor (overrides gl_billboard_mode setting)
RF_FORCEXYBILLBOARD = 0x20000, // [BB] OpenGL only: draw with xy axis billboard, i.e. unanchored (overrides gl_billboard_mode setting)
RF_MAYBEINVISIBLE = 0x02000000,
};
// This translucency value produces the closest match to Heretic's TINTTAB.

View file

@ -1902,7 +1902,6 @@ void AM_drawSubsectors()
PalEntry flatcolor;
mpoint_t originpt;
screen->StartSimplePolys();
for (int i = 0; i < numsubsectors; ++i)
{
if (subsectors[i].flags & SSECF_POLYORG)
@ -2059,7 +2058,6 @@ void AM_drawSubsectors()
);
}
}
screen->FinishSimplePolys();
}
//=============================================================================

View file

@ -181,6 +181,27 @@ void FBaseCVar::SetGenericRep (UCVarValue value, ECVarType type)
}
}
DEFINE_ACTION_FUNCTION(_CVar, GetInt)
{
PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar);
auto v = self->GetGenericRep(CVAR_Int);
ACTION_RETURN_INT(v.Int);
}
DEFINE_ACTION_FUNCTION(_CVar, GetFloat)
{
PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar);
auto v = self->GetGenericRep(CVAR_Float);
ACTION_RETURN_FLOAT(v.Int);
}
DEFINE_ACTION_FUNCTION(_CVar, GetString)
{
PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar);
auto v = self->GetGenericRep(CVAR_String);
ACTION_RETURN_STRING(v.String);
}
bool FBaseCVar::ToBool (UCVarValue value, ECVarType type)
{
switch (type)

View file

@ -616,6 +616,10 @@ DEFINE_ACTION_FUNCTION(DObject, GetClassName)
ACTION_RETURN_INT(self->GetClass()->TypeName);
}
DEFINE_ACTION_FUNCTION(DObject, MSTime)
{
ACTION_RETURN_INT(I_MSTime());
}
void *DObject::ScriptVar(FName field, PType *type)
{

View file

@ -254,14 +254,6 @@ static DObject **SweepList(DObject **p, size_t count, size_t *finalize_count)
curr->Destroy();
}
/*
if (curr->IsKindOf(RUNTIME_CLASS(PSymbol)))
Printf("Collecting %s, name = %s\n", curr->GetClass()->TypeName.GetChars(), static_cast<PSymbol*>(curr)->SymbolName.GetChars());
else if (curr->IsKindOf(RUNTIME_CLASS(PType)))
Printf("Collecting %s, name = %s\n", curr->GetClass()->TypeName.GetChars(), static_cast<PType*>(curr)->DescriptiveName());
else
Printf("Collecting %s\n", curr->GetClass()->TypeName.GetChars());
*/
curr->ObjectFlags |= OF_Cleanup;
delete curr;
finalized++;

View file

@ -211,9 +211,6 @@ public:
bool StartOffscreen();
void EndOffscreen();
void StartSimplePolys();
void FinishSimplePolys();
void FillSimplePoly(FTexture *texture, FVector2 *points, int npoints,
double originx, double originy, double scalex, double scaley,
DAngle rotation, FDynamicColormap *colormap, PalEntry flatcolor, int lightlevel, int bottomclip);

View file

@ -1052,6 +1052,11 @@ void FGLInterface::PrecacheTexture(FTexture *tex, int cache)
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
if (gltex) gltex->Precache();
}
else
{
// make sure that software pixel buffers do not stick around for unneeded textures.
tex->Unload();
}
}
//==========================================================================

View file

@ -55,6 +55,8 @@ class DColorPickerMenu : public DOptionMenu
{
DECLARE_CLASS(DColorPickerMenu, DOptionMenu)
public:
float mRed;
float mGreen;
float mBlue;
@ -66,9 +68,7 @@ class DColorPickerMenu : public DOptionMenu
FColorCVar *mCVar;
public:
DColorPickerMenu(DMenu *parent, const char *name, FOptionMenuDescriptor *desc, FColorCVar *cvar)
DColorPickerMenu(DMenu *parent, const char *name, DOptionMenuDescriptor *desc, FColorCVar *cvar)
{
mStartItem = desc->mItems.Size();
mRed = (float)RPART(DWORD(*cvar));
@ -118,217 +118,6 @@ public:
mBlue = (float)BPART(DWORD(*mCVar));
}
//=============================================================================
//
//
//
//=============================================================================
bool MenuEvent (int mkey, bool fromcontroller)
{
int &mSelectedItem = mDesc->mSelectedItem;
switch (mkey)
{
case MKEY_Down:
if (mSelectedItem == mStartItem+6) // last valid item
{
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE);
mGridPosY = 0;
// let it point to the last static item so that the super class code still has a valid item
mSelectedItem = mStartItem+7;
return true;
}
else if (mSelectedItem == mStartItem+7)
{
if (mGridPosY < 15)
{
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE);
mGridPosY++;
}
return true;
}
break;
case MKEY_Up:
if (mSelectedItem == mStartItem+7)
{
if (mGridPosY > 0)
{
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE);
mGridPosY--;
}
else
{
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE);
mSelectedItem = mStartItem+6;
}
return true;
}
break;
case MKEY_Left:
if (mSelectedItem == mStartItem+7)
{
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE);
if (--mGridPosX < 0) mGridPosX = 15;
return true;
}
break;
case MKEY_Right:
if (mSelectedItem == mStartItem+7)
{
S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE);
if (++mGridPosX > 15) mGridPosX = 0;
return true;
}
break;
case MKEY_Enter:
if (mSelectedItem == mStartItem+7)
{
// Choose selected palette entry
int index = mGridPosX + mGridPosY * 16;
mRed = GPalette.BaseColors[index].r;
mGreen = GPalette.BaseColors[index].g;
mBlue = GPalette.BaseColors[index].b;
S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE);
return true;
}
break;
}
if (mSelectedItem >= 0 && mSelectedItem < mStartItem+7)
{
if (mDesc->mItems[mDesc->mSelectedItem]->MenuEvent(mkey, fromcontroller)) return true;
}
return Super::MenuEvent(mkey, fromcontroller);
}
//=============================================================================
//
//
//
//=============================================================================
bool MouseEvent(int type, int mx, int my)
{
int olditem = mDesc->mSelectedItem;
bool res = Super::MouseEvent(type, mx, my);
if (mDesc->mSelectedItem == -1 || mDesc->mSelectedItem == mStartItem+7)
{
int y = (-mDesc->mPosition + BigFont->GetHeight() + mDesc->mItems.Size() * OptionSettings.mLinespacing) * CleanYfac_1;
int h = (screen->GetHeight() - y) / 16;
int fh = OptionSettings.mLinespacing * CleanYfac_1;
int w = fh;
int yy = y + 2 * CleanYfac_1;
int indent = (screen->GetWidth() / 2);
if (h > fh) h = fh;
else if (h < 4) return res; // no space to draw it.
int box_y = y - 2 * CleanYfac_1;
int box_x = indent - 16*w;
if (mx >= box_x && mx < box_x + 16*w && my >= box_y && my < box_y + 16*h)
{
int cell_x = (mx - box_x) / w;
int cell_y = (my - box_y) / h;
if (olditem != mStartItem+7 || cell_x != mGridPosX || cell_y != mGridPosY)
{
mGridPosX = cell_x;
mGridPosY = cell_y;
//S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE);
}
mDesc->mSelectedItem = mStartItem+7;
if (type == MOUSE_Release)
{
MenuEvent(MKEY_Enter, true);
if (m_use_mouse == 2) mDesc->mSelectedItem = -1;
}
res = true;
}
}
return res;
}
//=============================================================================
//
//
//
//=============================================================================
void Drawer()
{
Super::Drawer();
if (mCVar == NULL) return;
int y = (-mDesc->mPosition + BigFont->GetHeight() + mDesc->mItems.Size() * OptionSettings.mLinespacing) * CleanYfac_1;
int h = (screen->GetHeight() - y) / 16;
int fh = OptionSettings.mLinespacing * CleanYfac_1;
int w = fh;
int yy = y;
if (h > fh) h = fh;
else if (h < 4) return; // no space to draw it.
int indent = (screen->GetWidth() / 2);
int p = 0;
for(int i = 0; i < 16; i++, y += h)
{
int box_x, box_y;
int x1;
box_y = y - 2 * CleanYfac_1;
box_x = indent - 16*w;
for (x1 = 0; x1 < 16; ++x1, p++)
{
screen->Clear (box_x, box_y, box_x + w, box_y + h, p, 0);
if ((mDesc->mSelectedItem == mStartItem+7) &&
(/*p == CurrColorIndex ||*/ (i == mGridPosY && x1 == mGridPosX)))
{
int r, g, b;
DWORD col;
double blinky;
if (i == mGridPosY && x1 == mGridPosX)
{
r = 255, g = 128, b = 0;
}
else
{
r = 200, g = 200, b = 255;
}
// Make sure the cursors stand out against similar colors
// by pulsing them.
blinky = fabs(sin(I_MSTime()/1000.0)) * 0.5 + 0.5;
col = MAKEARGB(255,int(r*blinky),int(g*blinky),int(b*blinky));
screen->Clear (box_x, box_y, box_x + w, box_y + 1, -1, col);
screen->Clear (box_x, box_y + h-1, box_x + w, box_y + h, -1, col);
screen->Clear (box_x, box_y, box_x + 1, box_y + h, -1, col);
screen->Clear (box_x + w - 1, box_y, box_x + w, box_y + h, -1, col);
}
box_x += w;
}
}
y = yy;
DWORD newColor = MAKEARGB(255, int(mRed), int(mGreen), int(mBlue));
DWORD oldColor = DWORD(*mCVar) | 0xFF000000;
int x = screen->GetWidth()*2/3;
screen->Clear (x, y, x + 48*CleanXfac_1, y + 48*CleanYfac_1, -1, oldColor);
screen->Clear (x + 48*CleanXfac_1, y, x + 48*2*CleanXfac_1, y + 48*CleanYfac_1, -1, newColor);
y += 49*CleanYfac_1;
screen->DrawText (SmallFont, CR_GRAY, x+(24-SmallFont->StringWidth("Old")/2)*CleanXfac_1, y,
"Old", DTA_CleanNoMove_1, true, TAG_DONE);
screen->DrawText (SmallFont, CR_WHITE, x+(48+24-SmallFont->StringWidth("New")/2)*CleanXfac_1, y,
"New", DTA_CleanNoMove_1, true, TAG_DONE);
}
};
IMPLEMENT_CLASS(DColorPickerMenu, true, false)
@ -344,10 +133,10 @@ CCMD(undocolorpic)
DMenu *StartPickerMenu(DMenu *parent, const char *name, FColorCVar *cvar)
{
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Colorpickermenu);
if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu)
DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Colorpickermenu);
if (desc != NULL && (*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor)))
{
return new DColorPickerMenu(parent, name, (FOptionMenuDescriptor*)(*desc), cvar);
return new DColorPickerMenu(parent, name, (DOptionMenuDescriptor*)(*desc), cvar);
}
else
{
@ -355,3 +144,11 @@ DMenu *StartPickerMenu(DMenu *parent, const char *name, FColorCVar *cvar)
}
}
DEFINE_FIELD(DColorPickerMenu, mRed);
DEFINE_FIELD(DColorPickerMenu, mGreen);
DEFINE_FIELD(DColorPickerMenu, mBlue);
DEFINE_FIELD(DColorPickerMenu, mGridPosX);
DEFINE_FIELD(DColorPickerMenu, mGridPosY);
DEFINE_FIELD(DColorPickerMenu, mStartItem);
DEFINE_FIELD(DColorPickerMenu, mCVar);

View file

@ -58,7 +58,7 @@
static TArray<IJoystickConfig *> Joysticks;
IJoystickConfig *SELECTED_JOYSTICK;
FOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy);
DOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy);
//=============================================================================
//
@ -271,12 +271,12 @@ IMPLEMENT_CLASS(DOptionMenuItemJoyConfigMenu, false, false)
*
*=======================================*/
FOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy)
DOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy)
{
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_JoystickConfigMenu);
if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu)
DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_JoystickConfigMenu);
if (desc != NULL && (*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor)))
{
FOptionMenuDescriptor *opt = (FOptionMenuDescriptor *)*desc;
DOptionMenuDescriptor *opt = (DOptionMenuDescriptor *)*desc;
DOptionMenuItem *it;
opt->mItems.Clear();
if (joy == NULL)
@ -340,10 +340,10 @@ FOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy)
void UpdateJoystickMenu(IJoystickConfig *selected)
{
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_JoystickOptions);
if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu)
DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_JoystickOptions);
if (desc != NULL && (*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor)))
{
FOptionMenuDescriptor *opt = (FOptionMenuDescriptor *)*desc;
DOptionMenuDescriptor *opt = (DOptionMenuDescriptor *)*desc;
DOptionMenuItem *it;
opt->mItems.Clear();

View file

@ -54,7 +54,7 @@ IMPLEMENT_POINTERS_END
//
//=============================================================================
DListMenu::DListMenu(DMenu *parent, FListMenuDescriptor *desc)
DListMenu::DListMenu(DMenu *parent, DListMenuDescriptor *desc)
: DMenu(parent)
{
mDesc = NULL;
@ -67,7 +67,7 @@ DListMenu::DListMenu(DMenu *parent, FListMenuDescriptor *desc)
//
//=============================================================================
void DListMenu::Init(DMenu *parent, FListMenuDescriptor *desc)
void DListMenu::Init(DMenu *parent, DListMenuDescriptor *desc)
{
mParentMenu = parent;
GC::WriteBarrier(this, parent);
@ -359,6 +359,15 @@ bool DMenuItemBase::MenuEvent(int mkey, bool fromcontroller)
return false;
}
DEFINE_ACTION_FUNCTION(DMenuItemBase, MenuEvent)
{
PARAM_SELF_PROLOGUE(DMenuItemBase);
PARAM_INT(key);
PARAM_BOOL(fromcontroller);
ACTION_RETURN_BOOL(self->MenuEvent(key, fromcontroller));
}
bool DMenuItemBase::MouseEvent(int type, int x, int y)
{
return false;

View file

@ -102,7 +102,7 @@ protected:
bool mEntering;
char savegamestring[SAVESTRINGSIZE];
DLoadSaveMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL);
DLoadSaveMenu(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL);
void OnDestroy() override;
int RemoveSaveSlot (int index);
@ -432,7 +432,7 @@ void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave)
//
//=============================================================================
DLoadSaveMenu::DLoadSaveMenu(DMenu *parent, FListMenuDescriptor *desc)
DLoadSaveMenu::DLoadSaveMenu(DMenu *parent, DListMenuDescriptor *desc)
: DListMenu(parent, desc)
{
ReadSaveStrings();
@ -927,7 +927,7 @@ class DSaveMenu : public DLoadSaveMenu
public:
DSaveMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL);
DSaveMenu(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL);
void OnDestroy() override;
void DoSave (FSaveGameNode *node);
bool Responder (event_t *ev);
@ -944,7 +944,7 @@ IMPLEMENT_CLASS(DSaveMenu, false, false)
//
//=============================================================================
DSaveMenu::DSaveMenu(DMenu *parent, FListMenuDescriptor *desc)
DSaveMenu::DSaveMenu(DMenu *parent, DListMenuDescriptor *desc)
: DLoadSaveMenu(parent, desc)
{
strcpy (NewSaveNode.Title, GStrings["NEWSAVE"]);
@ -1099,7 +1099,7 @@ class DLoadMenu : public DLoadSaveMenu
public:
DLoadMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL);
DLoadMenu(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL);
bool MenuEvent (int mkey, bool fromcontroller);
};
@ -1113,7 +1113,7 @@ IMPLEMENT_CLASS(DLoadMenu, false, false)
//
//=============================================================================
DLoadMenu::DLoadMenu(DMenu *parent, FListMenuDescriptor *desc)
DLoadMenu::DLoadMenu(DMenu *parent, DListMenuDescriptor *desc)
: DLoadSaveMenu(parent, desc)
{
TopItem = 0;

View file

@ -55,6 +55,7 @@
#include "r_utility.h"
#include "menu/menu.h"
#include "textures/textures.h"
#include "virtual.h"
//
// Todo: Move these elsewhere
@ -91,13 +92,18 @@ static bool MenuEnabled = true;
//
//============================================================================
size_t FListMenuDescriptor::PropagateMark()
IMPLEMENT_CLASS(DMenuDescriptor, false, false)
IMPLEMENT_CLASS(DListMenuDescriptor, false, false)
IMPLEMENT_CLASS(DOptionMenuDescriptor, false, false)
size_t DListMenuDescriptor::PropagateMark()
{
for (auto item : mItems) GC::Mark(item);
return 0;
}
size_t FOptionMenuDescriptor::PropagateMark()
size_t DOptionMenuDescriptor::PropagateMark()
{
for (auto item : mItems) GC::Mark(item);
return 0;
@ -109,8 +115,7 @@ void M_MarkMenus()
MenuDescriptorList::Pair *pair;
while (it.NextPair(pair))
{
//GC::Mark(pair->Value); // once the descriptors have been made objects.
pair->Value->PropagateMark();
GC::Mark(pair->Value);
}
GC::Mark(DMenu::CurrentMenu);
}
@ -144,7 +149,7 @@ bool DMenu::Responder (event_t *ev)
res = MouseEventBack(MOUSE_Click, ev->data1, ev->data2);
// make the menu's mouse handler believe that the current coordinate is outside the valid range
if (res) ev->data2 = -1;
res |= MouseEvent(MOUSE_Click, ev->data1, ev->data2);
res |= CallMouseEvent(MOUSE_Click, ev->data1, ev->data2);
if (res)
{
SetCapture();
@ -158,7 +163,7 @@ bool DMenu::Responder (event_t *ev)
{
res = MouseEventBack(MOUSE_Move, ev->data1, ev->data2);
if (res) ev->data2 = -1;
res |= MouseEvent(MOUSE_Move, ev->data1, ev->data2);
res |= CallMouseEvent(MOUSE_Move, ev->data1, ev->data2);
}
}
else if (ev->subtype == EV_GUI_LButtonUp)
@ -168,7 +173,7 @@ bool DMenu::Responder (event_t *ev)
ReleaseCapture();
res = MouseEventBack(MOUSE_Release, ev->data1, ev->data2);
if (res) ev->data2 = -1;
res |= MouseEvent(MOUSE_Release, ev->data1, ev->data2);
res |= CallMouseEvent(MOUSE_Release, ev->data1, ev->data2);
}
}
}
@ -189,13 +194,33 @@ bool DMenu::MenuEvent (int mkey, bool fromcontroller)
{
Close();
S_Sound (CHAN_VOICE | CHAN_UI,
DMenu::CurrentMenu != NULL? "menu/backup" : "menu/clear", snd_menuvolume, ATTN_NONE);
DMenu::CurrentMenu != nullptr? "menu/backup" : "menu/clear", snd_menuvolume, ATTN_NONE);
return true;
}
}
return false;
}
DEFINE_ACTION_FUNCTION(DMenu, MenuEvent)
{
PARAM_SELF_PROLOGUE(DMenu);
PARAM_INT(key);
PARAM_BOOL(fromcontroller);
ACTION_RETURN_BOOL(self->MenuEvent(key, fromcontroller));
}
bool DMenu::CallMenuEvent(int mkey, bool fromcontroller)
{
IFVIRTUAL(DMenu, MenuEvent)
{
VMValue params[] = { (DObject*)this, mkey, fromcontroller };
int retval;
VMReturn ret(&retval);
GlobalVMStack.Call(func, params, 3, &ret, 1, nullptr);
return !!retval;
}
else return MenuEvent(mkey, fromcontroller);
}
//=============================================================================
//
//
@ -207,7 +232,7 @@ void DMenu::Close ()
assert(DMenu::CurrentMenu == this);
DMenu::CurrentMenu = mParentMenu;
Destroy();
if (DMenu::CurrentMenu != NULL)
if (DMenu::CurrentMenu != nullptr)
{
GC::WriteBarrier(DMenu::CurrentMenu);
}
@ -228,6 +253,28 @@ bool DMenu::MouseEvent(int type, int x, int y)
return true;
}
DEFINE_ACTION_FUNCTION(DMenu, MouseEvent)
{
PARAM_SELF_PROLOGUE(DMenu);
PARAM_INT(type);
PARAM_INT(x);
PARAM_INT(y);
ACTION_RETURN_BOOL(self->MouseEvent(type, x, y));
}
bool DMenu::CallMouseEvent(int type, int x, int y)
{
IFVIRTUAL(DMenu, MouseEvent)
{
VMValue params[] = { (DObject*)this, type, x, y };
int retval;
VMReturn ret(&retval);
GlobalVMStack.Call(func, params, 4, &ret, 1, nullptr);
return !!retval;
}
else return MouseEvent (type, x, y);
}
//=============================================================================
//
//
@ -239,7 +286,7 @@ bool DMenu::MouseEventBack(int type, int x, int y)
if (m_show_backbutton >= 0)
{
FTexture *tex = TexMan(gameinfo.mBackButton);
if (tex != NULL)
if (tex != nullptr)
{
if (m_show_backbutton&1) x -= screen->GetWidth() - tex->GetScaledWidth() * CleanXfac;
if (m_show_backbutton&2) y -= screen->GetHeight() - tex->GetScaledHeight() * CleanYfac;
@ -248,7 +295,7 @@ bool DMenu::MouseEventBack(int type, int x, int y)
if (mBackbuttonSelected && type == MOUSE_Release)
{
if (m_use_mouse == 2) mBackbuttonSelected = false;
MenuEvent(MKEY_Back, true);
CallMenuEvent(MKEY_Back, true);
}
return mBackbuttonSelected;
}
@ -310,6 +357,26 @@ void DMenu::Drawer ()
}
}
DEFINE_ACTION_FUNCTION(DMenu, Drawer)
{
PARAM_SELF_PROLOGUE(DMenu);
self->Drawer();
return 0;
}
void DMenu::CallDrawer()
{
IFVIRTUAL(DMenu, Drawer)
{
VMValue params[] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
}
else Drawer();
}
bool DMenu::DimAllowed()
{
return true;
@ -329,7 +396,7 @@ bool DMenu::TranslateKeyboardEvents()
void M_StartControlPanel (bool makeSound)
{
// intro might call this repeatedly
if (DMenu::CurrentMenu != NULL)
if (DMenu::CurrentMenu != nullptr)
return;
ResetButtonStates ();
@ -361,7 +428,7 @@ void M_StartControlPanel (bool makeSound)
void M_ActivateMenu(DMenu *menu)
{
if (menuactive == MENU_Off) menuactive = MENU_On;
if (DMenu::CurrentMenu != NULL) DMenu::CurrentMenu->ReleaseCapture();
if (DMenu::CurrentMenu != nullptr) DMenu::CurrentMenu->ReleaseCapture();
DMenu::CurrentMenu = menu;
GC::WriteBarrier(DMenu::CurrentMenu);
}
@ -382,7 +449,7 @@ void M_SetMenu(FName menu, int param)
GameStartupInfo.Skill = -1;
GameStartupInfo.Episode = -1;
GameStartupInfo.PlayerClass =
param == -1000? NULL :
param == -1000? nullptr :
param == -1? "Random" : GetPrintableDisplayName(PlayerClasses[param].Type).GetChars();
break;
@ -437,8 +504,8 @@ void M_SetMenu(FName menu, int param)
// End of special checks
FMenuDescriptor **desc = MenuDescriptors.CheckKey(menu);
if (desc != NULL)
DMenuDescriptor **desc = MenuDescriptors.CheckKey(menu);
if (desc != nullptr)
{
if ((*desc)->mNetgameMessage.IsNotEmpty() && netgame && !demoplayback)
{
@ -446,9 +513,9 @@ void M_SetMenu(FName menu, int param)
return;
}
if ((*desc)->mType == MDESC_ListMenu)
if ((*desc)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor)))
{
FListMenuDescriptor *ld = static_cast<FListMenuDescriptor*>(*desc);
DListMenuDescriptor *ld = static_cast<DListMenuDescriptor*>(*desc);
if (ld->mAutoselect >= 0 && ld->mAutoselect < (int)ld->mItems.Size())
{
// recursively activate the autoselected item without ever creating this menu.
@ -456,17 +523,17 @@ void M_SetMenu(FName menu, int param)
}
else
{
const PClass *cls = ld->mClass == NULL? RUNTIME_CLASS(DListMenu) : ld->mClass;
const PClass *cls = ld->mClass == nullptr? RUNTIME_CLASS(DListMenu) : ld->mClass;
DListMenu *newmenu = (DListMenu *)cls->CreateNew();
newmenu->Init(DMenu::CurrentMenu, ld);
M_ActivateMenu(newmenu);
}
}
else if ((*desc)->mType == MDESC_OptionsMenu)
else if ((*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor)))
{
FOptionMenuDescriptor *ld = static_cast<FOptionMenuDescriptor*>(*desc);
const PClass *cls = ld->mClass == NULL? RUNTIME_CLASS(DOptionMenu) : ld->mClass;
DOptionMenuDescriptor *ld = static_cast<DOptionMenuDescriptor*>(*desc);
const PClass *cls = ld->mClass == nullptr? RUNTIME_CLASS(DOptionMenu) : ld->mClass;
DOptionMenu *newmenu = (DOptionMenu *)cls->CreateNew();
newmenu->Init(DMenu::CurrentMenu, ld);
@ -477,7 +544,7 @@ void M_SetMenu(FName menu, int param)
else
{
const PClass *menuclass = PClass::FindClass(menu);
if (menuclass != NULL)
if (menuclass != nullptr)
{
if (menuclass->IsDescendantOf(RUNTIME_CLASS(DMenu)))
{
@ -510,7 +577,7 @@ bool M_Responder (event_t *ev)
return false;
}
if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off)
if (DMenu::CurrentMenu != nullptr && menuactive != MENU_Off)
{
// There are a few input sources we are interested in:
//
@ -649,7 +716,7 @@ bool M_Responder (event_t *ev)
{
MenuButtonTickers[mkey] = KEY_REPEAT_DELAY;
}
DMenu::CurrentMenu->MenuEvent(mkey, fromcontroller);
DMenu::CurrentMenu->CallMenuEvent(mkey, fromcontroller);
return true;
}
}
@ -670,7 +737,7 @@ bool M_Responder (event_t *ev)
// what it's bound to. (for those who don't bother to read the docs)
if (devparm && ev->data1 == KEY_F1)
{
G_ScreenShot(NULL);
G_ScreenShot(nullptr);
return true;
}
return false;
@ -695,7 +762,7 @@ bool M_Responder (event_t *ev)
void M_Ticker (void)
{
DMenu::MenuTime++;
if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off)
if (DMenu::CurrentMenu != nullptr && menuactive != MENU_Off)
{
DMenu::CurrentMenu->Ticker();
@ -736,9 +803,9 @@ void M_Drawer (void)
AActor *camera = player->camera;
PalEntry fade = 0;
if (!screen->Accel2D && camera != NULL && (gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL))
if (!screen->Accel2D && camera != nullptr && (gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL))
{
if (camera->player != NULL)
if (camera->player != nullptr)
{
player = camera->player;
}
@ -746,14 +813,14 @@ void M_Drawer (void)
}
if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off)
if (DMenu::CurrentMenu != nullptr && menuactive != MENU_Off)
{
if (DMenu::CurrentMenu->DimAllowed())
{
screen->Dim(fade);
V_SetBorderNeedRefresh();
}
DMenu::CurrentMenu->Drawer();
DMenu::CurrentMenu->CallDrawer();
}
}
@ -766,10 +833,10 @@ void M_Drawer (void)
void M_ClearMenus ()
{
M_DemoNoPlay = false;
if (DMenu::CurrentMenu != NULL)
if (DMenu::CurrentMenu != nullptr)
{
DMenu::CurrentMenu->Destroy();
DMenu::CurrentMenu = NULL;
DMenu::CurrentMenu = nullptr;
}
V_SetBorderNeedRefresh();
menuactive = MENU_Off;
@ -1002,3 +1069,46 @@ CCMD(reset2saved)
GameConfig->DoModSetup (gameinfo.ConfigName);
R_SetViewSize (screenblocks);
}
//native void OptionMenuDescriptor.CalcIndent();
//native OptionMenuItem OptionMenuDescriptor.GetItem(Name iname);
//native void OptionMenuItem.drawLabel(int indent, int y, EColorRange color, bool grayed = false);
DEFINE_FIELD(DMenuDescriptor, mMenuName)
DEFINE_FIELD(DMenuDescriptor, mNetgameMessage)
DEFINE_FIELD(DMenuDescriptor, mClass)
DEFINE_FIELD(DMenuItemBase, mXpos)
DEFINE_FIELD(DMenuItemBase, mYpos)
DEFINE_FIELD(DMenuItemBase, mAction)
DEFINE_FIELD(DMenuItemBase, mEnabled)
DEFINE_FIELD(DOptionMenuDescriptor, mItems)
DEFINE_FIELD(DOptionMenuDescriptor, mTitle)
DEFINE_FIELD(DOptionMenuDescriptor, mSelectedItem)
DEFINE_FIELD(DOptionMenuDescriptor, mDrawTop)
DEFINE_FIELD(DOptionMenuDescriptor, mScrollTop)
DEFINE_FIELD(DOptionMenuDescriptor, mScrollPos)
DEFINE_FIELD(DOptionMenuDescriptor, mIndent)
DEFINE_FIELD(DOptionMenuDescriptor, mPosition)
DEFINE_FIELD(DOptionMenuDescriptor, mDontDim)
DEFINE_FIELD(DOptionMenuItem, mLabel)
DEFINE_FIELD(DOptionMenuItem, mCentered)
DEFINE_FIELD(DOptionMenu, CanScrollUp)
DEFINE_FIELD(DOptionMenu, CanScrollDown)
DEFINE_FIELD(DOptionMenu, VisBottom)
DEFINE_FIELD(DOptionMenu, mFocusControl)
DEFINE_FIELD(DOptionMenu, mDesc)
DEFINE_FIELD(FOptionMenuSettings, mTitleColor)
DEFINE_FIELD(FOptionMenuSettings, mFontColor)
DEFINE_FIELD(FOptionMenuSettings, mFontColorValue)
DEFINE_FIELD(FOptionMenuSettings, mFontColorMore)
DEFINE_FIELD(FOptionMenuSettings, mFontColorHeader)
DEFINE_FIELD(FOptionMenuSettings, mFontColorHighlight)
DEFINE_FIELD(FOptionMenuSettings, mFontColorSelection)
DEFINE_FIELD(FOptionMenuSettings, mLinespacing)

View file

@ -19,7 +19,7 @@ EXTERN_CVAR(Int, m_use_mouse);
struct event_t;
class FTexture;
class FFont;
enum EColorRange;
enum EColorRange : int;
class FPlayerClass;
class FKeyBindings;
@ -75,28 +75,25 @@ struct FSaveGameNode
//
//=============================================================================
enum EMenuDescriptorType
{
MDESC_ListMenu,
MDESC_OptionsMenu,
};
struct FMenuDescriptor
class DMenuDescriptor : public DObject
{
DECLARE_CLASS(DMenuDescriptor, DObject)
public:
FName mMenuName;
FString mNetgameMessage;
int mType;
const PClass *mClass;
virtual ~FMenuDescriptor() {}
virtual size_t PropagateMark() { return 0; }
};
class DMenuItemBase;
class DOptionMenuItem;
struct FListMenuDescriptor : public FMenuDescriptor
class DListMenuDescriptor : public DMenuDescriptor
{
DECLARE_CLASS(DListMenuDescriptor, DMenuDescriptor)
public:
TArray<DMenuItemBase *> mItems;
int mSelectedItem;
int mSelectOfsX;
@ -110,7 +107,6 @@ struct FListMenuDescriptor : public FMenuDescriptor
FFont *mFont;
EColorRange mFontColor;
EColorRange mFontColor2;
FMenuDescriptor *mRedirect; // used to redirect overlong skill and episode menus to option menu based alternatives
bool mCenter;
void Reset()
@ -144,8 +140,11 @@ struct FOptionMenuSettings
int mLinespacing;
};
struct FOptionMenuDescriptor : public FMenuDescriptor
class DOptionMenuDescriptor : public DMenuDescriptor
{
DECLARE_CLASS(DOptionMenuDescriptor, DMenuDescriptor)
public:
TArray<DOptionMenuItem *> mItems;
FString mTitle;
int mSelectedItem;
@ -167,10 +166,13 @@ struct FOptionMenuDescriptor : public FMenuDescriptor
mDontDim = 0;
}
size_t PropagateMark() override;
~DOptionMenuDescriptor()
{
}
};
typedef TMap<FName, FMenuDescriptor *> MenuDescriptorList;
typedef TMap<FName, DMenuDescriptor *> MenuDescriptorList;
extern FOptionMenuSettings OptionSettings;
extern MenuDescriptorList MenuDescriptors;
@ -240,6 +242,11 @@ public:
virtual bool TranslateKeyboardEvents();
virtual void Close();
virtual bool MouseEvent(int type, int x, int y);
bool CallMenuEvent(int mkey, bool fromcontroller);
bool CallMouseEvent(int type, int x, int y);
void CallDrawer();
bool MouseEventBack(int type, int x, int y);
void SetCapture();
void ReleaseCapture();
@ -258,11 +265,10 @@ public:
class DMenuItemBase : public DObject
{
DECLARE_CLASS(DMenuItemBase, DObject)
protected:
public:
int mXpos, mYpos;
FName mAction;
public:
bool mEnabled;
DMenuItemBase(int xpos = 0, int ypos = 0, FName action = NAME_None)
@ -333,7 +339,7 @@ class DListMenuItemPlayerDisplay : public DMenuItemBase
{
DECLARE_CLASS(DListMenuItemPlayerDisplay, DMenuItemBase)
FListMenuDescriptor *mOwner;
DListMenuDescriptor *mOwner;
FTexture *mBackdrop;
FRemapTable mRemap;
FPlayerClass *mPlayerClass;
@ -365,7 +371,7 @@ public:
PDF_TRANSLATE = 0x10005,
};
DListMenuItemPlayerDisplay(FListMenuDescriptor *menu, int x, int y, PalEntry c1, PalEntry c2, bool np, FName action);
DListMenuItemPlayerDisplay(DListMenuDescriptor *menu, int x, int y, PalEntry c1, PalEntry c2, bool np, FName action);
void OnDestroy() override;
virtual void Ticker();
virtual void Drawer(bool selected);
@ -513,7 +519,7 @@ public:
//=============================================================================
//
// list menu class runs a menu described by a FListMenuDescriptor
// list menu class runs a menu described by a DListMenuDescriptor
//
//=============================================================================
@ -523,12 +529,12 @@ class DListMenu : public DMenu
HAS_OBJECT_POINTERS;
protected:
FListMenuDescriptor *mDesc;
DListMenuDescriptor *mDesc;
DMenuItemBase *mFocusControl;
public:
DListMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL);
virtual void Init(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL);
DListMenu(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL);
virtual void Init(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL);
DMenuItemBase *GetItem(FName name);
bool Responder (event_t *ev);
bool MenuEvent (int mkey, bool fromcontroller);
@ -559,12 +565,11 @@ public:
class DOptionMenuItem : public DMenuItemBase
{
DECLARE_ABSTRACT_CLASS(DOptionMenuItem, DMenuItemBase)
protected:
public:
FString mLabel;
bool mCentered;
void drawLabel(int indent, int y, EColorRange color, bool grayed = false);
public:
DOptionMenuItem(const char *text = nullptr, FName action = NAME_None, bool center = false)
: DMenuItemBase(0, 0, action)
@ -573,7 +578,7 @@ public:
mCentered = center;
}
virtual int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected);
virtual int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected);
virtual bool Selectable();
virtual int GetIndent();
virtual bool MouseEvent(int type, int x, int y);
@ -603,7 +608,7 @@ extern FOptionMap OptionValues;
//=============================================================================
//
// Option menu class runs a menu described by a FOptionMenuDescriptor
// Option menu class runs a menu described by a DOptionMenuDescriptor
//
//=============================================================================
@ -612,25 +617,24 @@ class DOptionMenu : public DMenu
DECLARE_CLASS(DOptionMenu, DMenu)
HAS_OBJECT_POINTERS;
public: // needs to be public for script access
bool CanScrollUp;
bool CanScrollDown;
int VisBottom;
DOptionMenuItem *mFocusControl;
DOptionMenuDescriptor *mDesc;
protected:
FOptionMenuDescriptor *mDesc;
public:
//public:
DOptionMenuItem *GetItem(FName name);
DOptionMenu(DMenu *parent = NULL, FOptionMenuDescriptor *desc = NULL);
virtual void Init(DMenu *parent = NULL, FOptionMenuDescriptor *desc = NULL);
DOptionMenu(DMenu *parent = NULL, DOptionMenuDescriptor *desc = NULL);
virtual void Init(DMenu *parent = NULL, DOptionMenuDescriptor *desc = NULL);
int FirstSelectable();
bool Responder (event_t *ev);
bool MenuEvent (int mkey, bool fromcontroller);
bool MouseEvent(int type, int x, int y);
void Ticker ();
void Drawer ();
const FOptionMenuDescriptor *GetDescriptor() const { return mDesc; }
const DOptionMenuDescriptor *GetDescriptor() const { return mDesc; }
void SetFocus(DOptionMenuItem *fc)
{
mFocusControl = fc;
@ -706,4 +710,4 @@ void M_InitVideoModesMenu ();
void M_MarkMenus();
#endif
#endif

View file

@ -57,8 +57,8 @@
void ClearSaveGames();
MenuDescriptorList MenuDescriptors;
static FListMenuDescriptor DefaultListMenuSettings; // contains common settings for all list menus
static FOptionMenuDescriptor DefaultOptionMenuSettings; // contains common settings for all Option menus
static DListMenuDescriptor *DefaultListMenuSettings; // contains common settings for all list menus
static DOptionMenuDescriptor *DefaultOptionMenuSettings; // contains common settings for all Option menus
FOptionMenuSettings OptionSettings;
FOptionMap OptionValues;
bool mustPrintErrors;
@ -67,18 +67,6 @@ void I_BuildALDeviceList(FOptionValues *opt);
static void DeinitMenus()
{
{
MenuDescriptorList::Iterator it(MenuDescriptors);
MenuDescriptorList::Pair *pair;
while (it.NextPair(pair))
{
delete pair->Value;
pair->Value = NULL;
}
}
{
FOptionMap::Iterator it(OptionValues);
@ -87,13 +75,12 @@ static void DeinitMenus()
while (it.NextPair(pair))
{
delete pair->Value;
pair->Value = NULL;
pair->Value = nullptr;
}
}
MenuDescriptors.Clear();
OptionValues.Clear();
DMenu::CurrentMenu = NULL;
DefaultListMenuSettings.mItems.Clear();
DMenu::CurrentMenu = nullptr;
ClearSaveGames();
}
@ -206,7 +193,7 @@ static bool CheckSkipOptionBlock(FScanner &sc)
//
//=============================================================================
static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
@ -236,7 +223,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
{
sc.MustGetString();
const PClass *cls = PClass::FindClass(sc.String);
if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(DListMenu)))
if (cls == nullptr || !cls->IsDescendantOf(RUNTIME_CLASS(DListMenu)))
{
sc.ScriptError("Unknown menu class '%s'", sc.String);
}
@ -363,7 +350,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
{
sc.MustGetString();
FFont *newfont = V_GetFont(sc.String);
if (newfont != NULL) desc->mFont = newfont;
if (newfont != nullptr) desc->mFont = newfont;
if (sc.CheckString(","))
{
sc.MustGetString();
@ -396,10 +383,10 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
int y = sc.Number;
sc.MustGetStringName(",");
sc.MustGetString();
PalEntry c1 = V_GetColor(NULL, sc);
PalEntry c1 = V_GetColor(nullptr, sc);
sc.MustGetStringName(",");
sc.MustGetString();
PalEntry c2 = V_GetColor(NULL, sc);
PalEntry c2 = V_GetColor(nullptr, sc);
if (sc.CheckString(","))
{
sc.MustGetNumber();
@ -483,28 +470,25 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
//
//=============================================================================
static bool CheckCompatible(FMenuDescriptor *newd, FMenuDescriptor *oldd)
static bool CheckCompatible(DMenuDescriptor *newd, DMenuDescriptor *oldd)
{
if (oldd->mClass == NULL) return true;
if (oldd->mClass == nullptr) return true;
return oldd->mClass == newd->mClass;
}
static bool ReplaceMenu(FScanner &sc, FMenuDescriptor *desc)
static bool ReplaceMenu(FScanner &sc, DMenuDescriptor *desc)
{
FMenuDescriptor **pOld = MenuDescriptors.CheckKey(desc->mMenuName);
if (pOld != NULL && *pOld != NULL)
DMenuDescriptor **pOld = MenuDescriptors.CheckKey(desc->mMenuName);
if (pOld != nullptr && *pOld != nullptr)
{
if (CheckCompatible(desc, *pOld))
{
delete *pOld;
}
else
if (!CheckCompatible(desc, *pOld))
{
sc.ScriptMessage("Tried to replace menu '%s' with a menu of different type", desc->mMenuName.GetChars());
return true;
}
}
MenuDescriptors[desc->mMenuName] = desc;
GC::WriteBarrier(desc);
return false;
}
@ -518,31 +502,28 @@ static void ParseListMenu(FScanner &sc)
{
sc.MustGetString();
FListMenuDescriptor *desc = new FListMenuDescriptor;
desc->mType = MDESC_ListMenu;
DListMenuDescriptor *desc = new DListMenuDescriptor;
desc->mMenuName = sc.String;
desc->mSelectedItem = -1;
desc->mAutoselect = -1;
desc->mSelectOfsX = DefaultListMenuSettings.mSelectOfsX;
desc->mSelectOfsY = DefaultListMenuSettings.mSelectOfsY;
desc->mSelector = DefaultListMenuSettings.mSelector;
desc->mDisplayTop = DefaultListMenuSettings.mDisplayTop;
desc->mXpos = DefaultListMenuSettings.mXpos;
desc->mYpos = DefaultListMenuSettings.mYpos;
desc->mLinespacing = DefaultListMenuSettings.mLinespacing;
desc->mNetgameMessage = DefaultListMenuSettings.mNetgameMessage;
desc->mFont = DefaultListMenuSettings.mFont;
desc->mFontColor = DefaultListMenuSettings.mFontColor;
desc->mFontColor2 = DefaultListMenuSettings.mFontColor2;
desc->mClass = NULL;
desc->mRedirect = NULL;
desc->mSelectOfsX = DefaultListMenuSettings->mSelectOfsX;
desc->mSelectOfsY = DefaultListMenuSettings->mSelectOfsY;
desc->mSelector = DefaultListMenuSettings->mSelector;
desc->mDisplayTop = DefaultListMenuSettings->mDisplayTop;
desc->mXpos = DefaultListMenuSettings->mXpos;
desc->mYpos = DefaultListMenuSettings->mYpos;
desc->mLinespacing = DefaultListMenuSettings->mLinespacing;
desc->mNetgameMessage = DefaultListMenuSettings->mNetgameMessage;
desc->mFont = DefaultListMenuSettings->mFont;
desc->mFontColor = DefaultListMenuSettings->mFontColor;
desc->mFontColor2 = DefaultListMenuSettings->mFontColor2;
desc->mClass = nullptr;
desc->mWLeft = 0;
desc->mWRight = 0;
desc->mCenter = false;
ParseListMenuBody(sc, desc);
bool scratch = ReplaceMenu(sc, desc);
if (scratch) delete desc;
ReplaceMenu(sc, desc);
}
//=============================================================================
@ -569,7 +550,7 @@ static void ParseOptionValue(FScanner &sc)
pair.Text = strbin1(sc.String);
}
FOptionValues **pOld = OptionValues.CheckKey(optname);
if (pOld != NULL && *pOld != NULL)
if (pOld != nullptr && *pOld != nullptr)
{
delete *pOld;
}
@ -602,7 +583,7 @@ static void ParseOptionString(FScanner &sc)
pair.Text = strbin1(sc.String);
}
FOptionValues **pOld = OptionValues.CheckKey(optname);
if (pOld != NULL && *pOld != NULL)
if (pOld != nullptr && *pOld != nullptr)
{
delete *pOld;
}
@ -657,7 +638,7 @@ static void ParseOptionSettings(FScanner &sc)
//
//=============================================================================
static EColorRange ParseOptionColor(FScanner &sc, FOptionMenuDescriptor *desc)
static EColorRange ParseOptionColor(FScanner &sc, DOptionMenuDescriptor *desc)
{
EColorRange cr = OptionSettings.mFontColor;
if (sc.CheckString(","))
@ -666,13 +647,13 @@ static EColorRange ParseOptionColor(FScanner &sc, FOptionMenuDescriptor *desc)
cr = V_FindFontColor(sc.String);
if (cr == CR_UNTRANSLATED && !sc.Compare("untranslated") && isdigit(sc.String[0]))
{
if (strtoll(sc.String, NULL, 0)) cr = OptionSettings.mFontColorHeader;
if (strtoll(sc.String, nullptr, 0)) cr = OptionSettings.mFontColorHeader;
}
}
return cr;
}
static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc)
static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc)
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
@ -702,7 +683,7 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc)
{
sc.MustGetString();
const PClass *cls = PClass::FindClass(sc.String);
if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(DOptionMenu)))
if (cls == nullptr || !cls->IsDescendantOf(RUNTIME_CLASS(DOptionMenu)))
{
sc.ScriptError("Unknown menu class '%s'", sc.String);
}
@ -943,21 +924,19 @@ static void ParseOptionMenu(FScanner &sc)
{
sc.MustGetString();
FOptionMenuDescriptor *desc = new FOptionMenuDescriptor;
desc->mType = MDESC_OptionsMenu;
DOptionMenuDescriptor *desc = new DOptionMenuDescriptor;
desc->mMenuName = sc.String;
desc->mSelectedItem = -1;
desc->mScrollPos = 0;
desc->mClass = NULL;
desc->mPosition = DefaultOptionMenuSettings.mPosition;
desc->mScrollTop = DefaultOptionMenuSettings.mScrollTop;
desc->mIndent = DefaultOptionMenuSettings.mIndent;
desc->mDontDim = DefaultOptionMenuSettings.mDontDim;
desc->mClass = nullptr;
desc->mPosition = DefaultOptionMenuSettings->mPosition;
desc->mScrollTop = DefaultOptionMenuSettings->mScrollTop;
desc->mIndent = DefaultOptionMenuSettings->mIndent;
desc->mDontDim = DefaultOptionMenuSettings->mDontDim;
ParseOptionMenuBody(sc, desc);
bool scratch = ReplaceMenu(sc, desc);
ReplaceMenu(sc, desc);
if (desc->mIndent == 0) desc->CalcIndent();
if (scratch) delete desc;
}
@ -978,8 +957,11 @@ void M_ParseMenuDefs()
OptionSettings.mFontColorHeader = V_FindFontColor(gameinfo.mFontColorHeader);
OptionSettings.mFontColorHighlight = V_FindFontColor(gameinfo.mFontColorHighlight);
OptionSettings.mFontColorSelection = V_FindFontColor(gameinfo.mFontColorSelection);
DefaultListMenuSettings.Reset();
DefaultOptionMenuSettings.Reset();
// these are supposed to get GC'd after parsing is complete.
DefaultListMenuSettings = new DListMenuDescriptor;
DefaultOptionMenuSettings = new DOptionMenuDescriptor;
DefaultListMenuSettings->Reset();
DefaultOptionMenuSettings->Reset();
atterm( DeinitMenus);
DeinitMenus();
@ -1000,8 +982,8 @@ void M_ParseMenuDefs()
}
else if (sc.Compare("DEFAULTLISTMENU"))
{
ParseListMenuBody(sc, &DefaultListMenuSettings);
if (DefaultListMenuSettings.mItems.Size() > 0)
ParseListMenuBody(sc, DefaultListMenuSettings);
if (DefaultListMenuSettings->mItems.Size() > 0)
{
I_FatalError("You cannot add menu items to the menu default settings.");
}
@ -1024,8 +1006,8 @@ void M_ParseMenuDefs()
}
else if (sc.Compare("DEFAULTOPTIONMENU"))
{
ParseOptionMenuBody(sc, &DefaultOptionMenuSettings);
if (DefaultOptionMenuSettings.mItems.Size() > 0)
ParseOptionMenuBody(sc, DefaultOptionMenuSettings);
if (DefaultOptionMenuSettings->mItems.Size() > 0)
{
I_FatalError("You cannot add menu items to the menu default settings.");
}
@ -1036,6 +1018,8 @@ void M_ParseMenuDefs()
}
}
}
DefaultListMenuSettings = nullptr;
DefaultOptionMenuSettings = nullptr;
}
@ -1050,12 +1034,12 @@ static void BuildEpisodeMenu()
{
// Build episode menu
bool success = false;
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Episodemenu);
if (desc != NULL)
DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Episodemenu);
if (desc != nullptr)
{
if ((*desc)->mType == MDESC_ListMenu)
if ((*desc)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor)))
{
FListMenuDescriptor *ld = static_cast<FListMenuDescriptor*>(*desc);
DListMenuDescriptor *ld = static_cast<DListMenuDescriptor*>(*desc);
int posy = ld->mYpos;
int topy = posy;
@ -1107,7 +1091,7 @@ static void BuildEpisodeMenu()
success = true;
for (auto &p : ld->mItems)
{
GC::WriteBarrier(p);
GC::WriteBarrier(*desc, p);
}
}
}
@ -1116,24 +1100,23 @@ static void BuildEpisodeMenu()
{
// Couldn't create the episode menu, either because there's too many episodes or some error occured
// Create an option menu for episode selection instead.
FOptionMenuDescriptor *od = new FOptionMenuDescriptor;
if (desc != NULL) delete *desc;
DOptionMenuDescriptor *od = new DOptionMenuDescriptor;
MenuDescriptors[NAME_Episodemenu] = od;
od->mType = MDESC_OptionsMenu;
od->mMenuName = NAME_Episodemenu;
od->mTitle = "$MNU_EPISODE";
od->mSelectedItem = 0;
od->mScrollPos = 0;
od->mClass = NULL;
od->mClass = nullptr;
od->mPosition = -15;
od->mScrollTop = 0;
od->mIndent = 160;
od->mDontDim = false;
GC::WriteBarrier(od);
for(unsigned i = 0; i < AllEpisodes.Size(); i++)
{
DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(AllEpisodes[i].mEpisodeName, "Skillmenu", i);
od->mItems.Push(it);
GC::WriteBarrier(it);
GC::WriteBarrier(od, it);
}
}
}
@ -1149,12 +1132,12 @@ static void BuildPlayerclassMenu()
bool success = false;
// Build player class menu
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Playerclassmenu);
if (desc != NULL)
DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Playerclassmenu);
if (desc != nullptr)
{
if ((*desc)->mType == MDESC_ListMenu)
if ((*desc)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor)))
{
FListMenuDescriptor *ld = static_cast<FListMenuDescriptor*>(*desc);
DListMenuDescriptor *ld = static_cast<DListMenuDescriptor*>(*desc);
// add player display
ld->mSelectedItem = ld->mItems.Size();
@ -1175,7 +1158,7 @@ static void BuildPlayerclassMenu()
if (!(PlayerClasses[i].Flags & PCF_NOMENU))
{
const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type);
if (pname != NULL)
if (pname != nullptr)
{
numclassitems++;
}
@ -1212,7 +1195,7 @@ static void BuildPlayerclassMenu()
if (!(PlayerClasses[i].Flags & PCF_NOMENU))
{
const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type);
if (pname != NULL)
if (pname != nullptr)
{
DListMenuItemText *it = new DListMenuItemText(ld->mXpos, ld->mYpos, ld->mLinespacing, *pname,
pname, ld->mFont,ld->mFontColor,ld->mFontColor2, NAME_Episodemenu, i);
@ -1231,7 +1214,7 @@ static void BuildPlayerclassMenu()
if (n == 0)
{
const char *pname = GetPrintableDisplayName(PlayerClasses[0].Type);
if (pname != NULL)
if (pname != nullptr)
{
DListMenuItemText *it = new DListMenuItemText(ld->mXpos, ld->mYpos, ld->mLinespacing, *pname,
pname, ld->mFont,ld->mFontColor,ld->mFontColor2, NAME_Episodemenu, 0);
@ -1241,7 +1224,7 @@ static void BuildPlayerclassMenu()
success = true;
for (auto &p : ld->mItems)
{
GC::WriteBarrier(p);
GC::WriteBarrier(ld, p);
}
}
}
@ -1250,37 +1233,35 @@ static void BuildPlayerclassMenu()
{
// Couldn't create the playerclass menu, either because there's too many episodes or some error occured
// Create an option menu for class selection instead.
FOptionMenuDescriptor *od = new FOptionMenuDescriptor;
if (desc != NULL) delete *desc;
DOptionMenuDescriptor *od = new DOptionMenuDescriptor;
MenuDescriptors[NAME_Playerclassmenu] = od;
od->mType = MDESC_OptionsMenu;
od->mMenuName = NAME_Playerclassmenu;
od->mTitle = "$MNU_CHOOSECLASS";
od->mSelectedItem = 0;
od->mScrollPos = 0;
od->mClass = NULL;
od->mClass = nullptr;
od->mPosition = -15;
od->mScrollTop = 0;
od->mIndent = 160;
od->mDontDim = false;
od->mNetgameMessage = "$NEWGAME";
GC::WriteBarrier(od);
for (unsigned i = 0; i < PlayerClasses.Size (); i++)
{
if (!(PlayerClasses[i].Flags & PCF_NOMENU))
{
const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type);
if (pname != NULL)
if (pname != nullptr)
{
DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(pname, "Episodemenu", i);
od->mItems.Push(it);
GC::WriteBarrier(it);
GC::WriteBarrier(od, it);
}
}
}
DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu("Random", "Episodemenu", -1);
od->mItems.Push(it);
GC::WriteBarrier(it);
GC::WriteBarrier(od, it);
}
}
@ -1298,7 +1279,7 @@ static void InitCrosshairsList()
lastlump = 0;
FOptionValues **opt = OptionValues.CheckKey(NAME_Crosshairs);
if (opt == NULL)
if (opt == nullptr)
{
return; // no crosshair value list present. No need to go on.
}
@ -1349,12 +1330,12 @@ static void InitCrosshairsList()
static void InitKeySections()
{
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_CustomizeControls);
if (desc != NULL)
DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_CustomizeControls);
if (desc != nullptr)
{
if ((*desc)->mType == MDESC_OptionsMenu)
if ((*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor)))
{
FOptionMenuDescriptor *menu = static_cast<FOptionMenuDescriptor*>(*desc);
DOptionMenuDescriptor *menu = static_cast<DOptionMenuDescriptor*>(*desc);
for (unsigned i = 0; i < KeySections.Size(); i++)
{
@ -1372,7 +1353,7 @@ static void InitKeySections()
}
for (auto &p : menu->mItems)
{
GC::WriteBarrier(p);
GC::WriteBarrier(*desc, p);
}
}
}
@ -1392,12 +1373,12 @@ void M_CreateMenus()
InitKeySections();
FOptionValues **opt = OptionValues.CheckKey(NAME_Mididevices);
if (opt != NULL)
if (opt != nullptr)
{
I_BuildMIDIMenuList(*opt);
}
opt = OptionValues.CheckKey(NAME_Aldevices);
if (opt != NULL)
if (opt != nullptr)
{
I_BuildALDeviceList(*opt);
}
@ -1414,19 +1395,19 @@ void M_StartupSkillMenu(FGameStartup *gs)
{
static int done = -1;
bool success = false;
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Skillmenu);
if (desc != NULL)
DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Skillmenu);
if (desc != nullptr)
{
if ((*desc)->mType == MDESC_ListMenu)
if ((*desc)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor)))
{
FListMenuDescriptor *ld = static_cast<FListMenuDescriptor*>(*desc);
DListMenuDescriptor *ld = static_cast<DListMenuDescriptor*>(*desc);
int x = ld->mXpos;
int y = ld->mYpos;
// Delete previous contents
for(unsigned i=0; i<ld->mItems.Size(); i++)
{
FName n = ld->mItems[i]->GetAction(NULL);
FName n = ld->mItems[i]->GetAction(nullptr);
if (n == NAME_Startgame || n == NAME_StartgameConfirm)
{
ld->mItems.Resize(i);
@ -1473,8 +1454,7 @@ void M_StartupSkillMenu(FGameStartup *gs)
else
{
// too large
delete ld;
desc = NULL;
desc = nullptr;
done = false;
goto fail;
}
@ -1488,13 +1468,13 @@ void M_StartupSkillMenu(FGameStartup *gs)
// Using a different name for skills that must be confirmed makes handling this easier.
FName action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ?
NAME_StartgameConfirm : NAME_Startgame;
FString *pItemText = NULL;
if (gs->PlayerClass != NULL)
FString *pItemText = nullptr;
if (gs->PlayerClass != nullptr)
{
pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass);
}
if (skill.PicName.Len() != 0 && pItemText == NULL)
if (skill.PicName.Len() != 0 && pItemText == nullptr)
{
FTextureID tex = GetMenuTexture(skill.PicName);
li = new DListMenuItemPatch(ld->mXpos, y, ld->mLinespacing, skill.Shortcut, tex, action, i);
@ -1507,7 +1487,7 @@ void M_StartupSkillMenu(FGameStartup *gs)
pItemText? *pItemText : skill.MenuName, ld->mFont, color,ld->mFontColor2, action, i);
}
ld->mItems.Push(li);
GC::WriteBarrier(li);
GC::WriteBarrier(*desc, li);
y += ld->mLinespacing;
}
if (AllEpisodes[gs->Episode].mNoSkill || AllSkills.Size() == 1)
@ -1524,26 +1504,25 @@ void M_StartupSkillMenu(FGameStartup *gs)
if (success) return;
fail:
// Option menu fallback for overlong skill lists
FOptionMenuDescriptor *od;
if (desc == NULL)
DOptionMenuDescriptor *od;
if (desc == nullptr)
{
od = new FOptionMenuDescriptor;
if (desc != NULL) delete *desc;
od = new DOptionMenuDescriptor;
MenuDescriptors[NAME_Skillmenu] = od;
od->mType = MDESC_OptionsMenu;
od->mMenuName = NAME_Skillmenu;
od->mTitle = "$MNU_CHOOSESKILL";
od->mSelectedItem = 0;
od->mScrollPos = 0;
od->mClass = NULL;
od->mClass = nullptr;
od->mPosition = -15;
od->mScrollTop = 0;
od->mIndent = 160;
od->mDontDim = false;
GC::WriteBarrier(od);
}
else
{
od = static_cast<FOptionMenuDescriptor*>(*desc);
od = static_cast<DOptionMenuDescriptor*>(*desc);
od->mItems.Clear();
}
for(unsigned int i = 0; i < AllSkills.Size(); i++)
@ -1554,14 +1533,14 @@ fail:
const char *action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ?
"StartgameConfirm" : "Startgame";
FString *pItemText = NULL;
if (gs->PlayerClass != NULL)
FString *pItemText = nullptr;
if (gs->PlayerClass != nullptr)
{
pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass);
}
li = new DOptionMenuItemSubmenu(pItemText? *pItemText : skill.MenuName, action, i);
od->mItems.Push(li);
GC::WriteBarrier(li);
GC::WriteBarrier(od, li);
if (!done)
{
done = true;

View file

@ -138,7 +138,7 @@ bool DTextEnterMenu::Responder(event_t *ev)
{
DMenu *parent = mParentMenu;
Close();
parent->MenuEvent(MKEY_Abort, false);
parent->CallMenuEvent(MKEY_Abort, false);
return true;
}
else if (ch == '\r')
@ -151,7 +151,7 @@ bool DTextEnterMenu::Responder(event_t *ev)
DMenu *parent = mParentMenu;
Close();
parent->MenuEvent(MKEY_Input, false);
parent->CallMenuEvent(MKEY_Input, false);
return true;
}
}
@ -183,7 +183,7 @@ bool DTextEnterMenu::MouseEvent(int type, int x, int y)
InputGridY = (y - screen_y) / cell_height;
if (type == DMenu::MOUSE_Release)
{
if (MenuEvent(MKEY_Enter, true))
if (CallMenuEvent(MKEY_Enter, true))
{
S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE);
if (m_use_mouse == 2) InputGridX = InputGridY = -1;
@ -210,7 +210,7 @@ bool DTextEnterMenu::MenuEvent (int key, bool fromcontroller)
{
if (key == MKEY_Back)
{
mParentMenu->MenuEvent(MKEY_Abort, false);
mParentMenu->CallMenuEvent(MKEY_Abort, false);
return Super::MenuEvent(key, fromcontroller);
}
if (fromcontroller)
@ -262,7 +262,7 @@ bool DTextEnterMenu::MenuEvent (int key, bool fromcontroller)
{
DMenu *parent = mParentMenu;
Close();
parent->MenuEvent(MKEY_Input, false);
parent->CallMenuEvent(MKEY_Input, false);
return true;
}
}
@ -297,7 +297,7 @@ bool DTextEnterMenu::MenuEvent (int key, bool fromcontroller)
void DTextEnterMenu::Drawer ()
{
mParentMenu->Drawer();
mParentMenu->CallDrawer();
if (mInputGridOkay)
{
const int cell_width = 18 * CleanXfac;

View file

@ -157,7 +157,7 @@ void DMessageBoxMenu::HandleResult(bool res)
{
if (mAction == NAME_None)
{
mParentMenu->MenuEvent(res? MKEY_MBYes : MKEY_MBNo, false);
mParentMenu->CallMenuEvent(res? MKEY_MBYes : MKEY_MBNo, false);
Close();
}
else

View file

@ -76,7 +76,7 @@ IMPLEMENT_POINTERS_END
//
//=============================================================================
DOptionMenu::DOptionMenu(DMenu *parent, FOptionMenuDescriptor *desc)
DOptionMenu::DOptionMenu(DMenu *parent, DOptionMenuDescriptor *desc)
: DMenu(parent)
{
CanScrollUp = false;
@ -92,7 +92,7 @@ DOptionMenu::DOptionMenu(DMenu *parent, FOptionMenuDescriptor *desc)
//
//=============================================================================
void DOptionMenu::Init(DMenu *parent, FOptionMenuDescriptor *desc)
void DOptionMenu::Init(DMenu *parent, DOptionMenuDescriptor *desc)
{
mParentMenu = parent;
GC::WriteBarrier(this, parent);
@ -482,7 +482,7 @@ void DOptionMenu::Drawer ()
//
//=============================================================================
int DOptionMenuItem::Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
int DOptionMenuItem::Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected)
{
return indent;
}
@ -496,7 +496,7 @@ bool DOptionMenuItem::MouseEvent(int type, int x, int y)
{
if (Selectable() && type == DMenu::MOUSE_Release)
{
return DMenu::CurrentMenu->MenuEvent(MKEY_Enter, true);
return DMenu::CurrentMenu->CallMenuEvent(MKEY_Enter, true);
}
return false;
}
@ -528,7 +528,7 @@ void DOptionMenuItem::drawLabel(int indent, int y, EColorRange color, bool graye
void FOptionMenuDescriptor::CalcIndent()
void DOptionMenuDescriptor::CalcIndent()
{
// calculate the menu indent
int widest = 0, thiswidth;
@ -547,7 +547,7 @@ void FOptionMenuDescriptor::CalcIndent()
//
//=============================================================================
DOptionMenuItem *FOptionMenuDescriptor::GetItem(FName name)
DOptionMenuItem *DOptionMenuDescriptor::GetItem(FName name)
{
for(unsigned i=0;i<mItems.Size(); i++)
{

View file

@ -60,7 +60,7 @@ public:
mParam = param;
}
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected)
{
drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColorMore);
return indent;
@ -221,7 +221,7 @@ public:
virtual void SetSelection(int Selection) = 0;
//=============================================================================
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected)
{
bool grayed = mGrayCheck != NULL && !(mGrayCheck->GetGenericRep(CVAR_Bool).Bool);
@ -418,7 +418,7 @@ public:
menuactive = MENU_On;
SetMenuMessage(0);
Close();
mParentMenu->MenuEvent((ev->data1 == KEY_ESCAPE)? MKEY_Abort : MKEY_Input, 0);
mParentMenu->CallMenuEvent((ev->data1 == KEY_ESCAPE)? MKEY_Abort : MKEY_Input, 0);
return true;
}
return false;
@ -426,7 +426,7 @@ public:
void Drawer()
{
mParentMenu->Drawer();
mParentMenu->CallDrawer();
}
};
@ -459,7 +459,7 @@ public:
//=============================================================================
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected)
{
drawLabel(indent, y, mWaiting? OptionSettings.mFontColorHighlight:
(selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor));
@ -541,7 +541,7 @@ public:
mColor = cr;
}
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected)
{
drawLabel(indent, y, mColor);
return -1;
@ -581,7 +581,7 @@ public:
mCurrent = 0;
}
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected)
{
const char *txt = mCurrent? mAltText.GetChars() : mLabel.GetChars();
if (*txt == '$') txt = GStrings(txt + 1);
@ -700,7 +700,7 @@ public:
//=============================================================================
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected)
{
drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor);
mDrawX = indent + CURSORSPACE;
@ -883,7 +883,7 @@ public:
}
//=============================================================================
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected)
{
drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor);
@ -1038,7 +1038,7 @@ public:
return true;
}
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected)
{
int colwidth = screen->GetWidth() / 3;
EColorRange color;
@ -1108,7 +1108,7 @@ public:
return GetCVarString();
}
int Draw ( FOptionMenuDescriptor*, int y, int indent, bool selected )
int Draw ( DOptionMenuDescriptor*, int y, int indent, bool selected )
{
bool grayed = mGrayCheck != NULL && !( mGrayCheck->GetGenericRep( CVAR_Bool ).Bool );
drawLabel( indent, y, selected ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed );
@ -1186,7 +1186,7 @@ public:
return text;
}
int Draw(FOptionMenuDescriptor*desc, int y, int indent, bool selected)
int Draw(DOptionMenuDescriptor*desc, int y, int indent, bool selected)
{
if (mEntering)
{

View file

@ -49,313 +49,13 @@
#include "r_data/r_translate.h"
//=============================================================================
//
// Used by the player display
//
//=============================================================================
struct FBackdropTexture : public FTexture
{
enum
{
COS_SIZE = 256,
ANGLESHIFT = 24
};
static constexpr uint32_t DEGREES(double v)
{
return uint32_t((v)*(0x40000000 / 90.0));
}
static double TORAD(uint32_t x)
{
return x*(M_PI / 0x80000000);
}
public:
FBackdropTexture();
const BYTE *GetColumn(unsigned int column, const Span **spans_out);
const BYTE *GetPixels();
void Unload();
bool CheckModified();
protected:
uint32_t costab[COS_SIZE];
BYTE Pixels[144*160];
static const Span DummySpan[2];
int LastRenderTic;
uint32_t time1, time2, time3, time4;
uint32_t t1ang, t2ang, z1ang, z2ang;
void Render();
};
// A 32x32 cloud rendered with Photoshop, plus some other filters
static BYTE pattern1[1024] =
{
5, 9, 7,10, 9,15, 9, 7, 8,10, 5, 3, 5, 7, 9, 8,14, 8, 4, 7, 8, 9, 5, 7,14, 7, 0, 7,13,13, 9, 6,
2, 7, 9, 7, 7,10, 8, 8,11,10, 6, 7,10, 7, 5, 6, 6, 4, 7,13,15,16,11,15,11, 8, 0, 4,13,22,17,11,
5, 9, 9, 7, 9,10, 4, 3, 6, 7, 8, 6, 5, 4, 2, 2, 1, 4, 6,11,15,15,14,13,17, 9, 5, 9,11,12,17,20,
9,16, 9, 8,12,13, 7, 3, 7, 9, 5, 4, 2, 5, 5, 5, 7,11, 6, 7, 6,13,17,10,10, 9,12,17,14,12,16,15,
15,13, 5, 3, 9,10, 4,10,12,12, 7, 9, 8, 8, 8,10, 7, 6, 5, 5, 5, 6,11, 9, 3,13,16,18,21,16,23,18,
23,13, 0, 0, 0, 0, 0,12,18,14,15,16,13, 7, 7, 5, 9, 6, 6, 8, 4, 0, 0, 0, 0,14,19,17,14,20,21,25,
19,20,14,13, 7, 5,13,19,14,13,17,15,14, 7, 3, 5, 6,11, 7, 7, 8, 8,10, 9, 9,18,17,15,14,15,18,16,
16,29,24,23,18, 9,17,20,11, 5,12,15,15,12, 6, 3, 4, 6, 7,10,13,18,18,19,16,12,17,19,23,16,14,14,
9,18,20,26,19, 5,18,18,10, 5,12,15,14,17,11, 6,11, 9,10,13,10,20,24,20,21,20,14,18,15,22,20,19,
0, 6,16,18, 8, 7,15,18,10,13,17,17,13,11,15,11,19,12,13,10, 4,15,19,21,21,24,14, 9,17,20,24,17,
18,17, 7, 7,16,21,22,15, 5,14,20,14,13,21,13, 8,12,14, 7, 8,11,15,13,11,16,17, 7, 5,12,17,19,14,
25,23,17,16,23,18,15, 7, 0, 6,11, 6,11,15,11, 7,12, 7, 4,10,16,13, 7, 7,15,13, 9,15,21,14, 5, 0,
18,22,21,21,21,22,12, 6,14,20,15, 6,10,19,13, 8, 7, 3, 7,12,14,16, 9,12,22,15,12,18,24,19,17, 9,
0,15,18,21,17,25,14,13,19,21,21,11, 6,13,16,16,12,10,12,11,13,20,14,13,18,13, 9,15,16,25,31,20,
5,20,24,16, 7,14,14,11,18,19,19, 6, 0, 5,11,14,17,16,19,14,15,21,19,15,14,14, 8, 0, 7,24,18,16,
9,17,15, 7, 6,14,12, 7,14,16,11, 4, 7, 6,13,16,15,13,12,20,21,20,21,17,18,26,14, 0,13,23,21,11,
9,12,18,11,15,21,13, 8,13,13,10, 7,13, 8, 8,19,13, 7, 4,15,19,18,14,12,14,15, 8, 6,16,22,22,15,
9,17,14,19,15,14,15, 9,11, 9, 6, 8,14,13,13,12, 5, 0, 0, 6,12,13, 7, 7, 9, 7, 0,12,21,16,15,18,
15,16,18,11, 6, 8,15, 9, 2, 0, 5,10,10,16, 9, 0, 4,12,15, 9,12, 9, 7, 7,12, 7, 0, 6,12, 6, 9,13,
12,19,15,14,11, 7, 8, 9,12,10, 5, 5, 7,12,12,10,14,16,16,11, 8,12,10,12,10, 8,10,10,14,12,16,16,
16,17,20,22,12,15,12,14,19,11, 6, 5,10,13,17,17,21,19,15, 9, 6, 9,15,18,10,10,18,14,20,15,16,17,
11,19,19,18,19,14,17,13,12,12, 7,11,18,17,16,15,19,19,10, 2, 0, 8,15,12, 8,11,12,10,19,20,19,19,
6,14,18,13,13,16,16,12, 5, 8,10,12,10,13,18,12, 9,10, 7, 6, 5,11, 8, 6, 7,13,16,13,10,15,20,14,
0, 5,12,12, 4, 0, 9,16, 9,10,12, 8, 0, 9,13, 9, 0, 2, 4, 7,10, 6, 7, 3, 4,11,16,18,10,11,21,21,
16,13,11,15, 8, 0, 5, 9, 8, 7, 6, 3, 0, 9,17, 9, 0, 0, 0, 3, 5, 4, 3, 5, 7,15,16,16,17,14,22,22,
24,14,15,12, 9, 0, 5,10, 8, 4, 7,12,10,11,12, 7, 6, 8, 6, 5, 7, 8, 8,11,13,10,15,14,12,18,20,16,
16,17,17,18,12, 9,12,16,10, 5, 6,20,13,15, 8, 4, 8, 9, 8, 7, 9,11,12,17,16,16,11,10, 9,10, 5, 0,
0,14,18,18,15,16,14, 9,10, 9, 9,15,14,10, 4, 6,10, 8, 8, 7,10, 9,10,16,18,10, 0, 0, 7,12,10, 8,
0,14,19,14, 9,11,11, 8, 8,10,15, 9,10, 7, 4,10,13, 9, 7, 5, 5, 7, 7, 7,13,13, 5, 5,14,22,18,16,
0,10,14,10, 3, 6, 5, 6, 8, 9, 8, 9, 5, 9, 8, 9, 6, 8, 8, 8, 1, 0, 0, 0, 9,17,12,12,17,19,20,13,
6,11,17,11, 5, 5, 8,10, 6, 5, 6, 6, 3, 7, 9, 7, 6, 8,12,10, 4, 8, 6, 6,11,16,16,15,16,17,17,16,
11, 9,10,10, 5, 6,12,10, 5, 1, 6,10, 5, 3, 3, 5, 4, 7,15,10, 7,13, 7, 8,15,11,15,15,15, 8,11,15,
};
// Just a 32x32 cloud rendered with the standard Photoshop filter
static BYTE pattern2[1024] =
{
9, 9, 8, 8, 8, 8, 6, 6,13,13,11,21,19,21,23,18,23,24,19,19,24,17,18,12, 9,14, 8,12,12, 5, 8, 6,
11,10, 6, 7, 8, 8, 9,13,10,11,17,15,23,22,23,22,20,26,27,26,17,21,20,14,12, 8,11, 8,11, 7, 8, 7,
6, 9,13,13,10, 9,13, 7,12,13,16,19,16,20,22,25,22,25,27,22,21,23,15,10,14,14,15,13,12, 8,12, 6,
6, 7,12,12,12,16, 9,12,12,15,16,11,21,24,19,24,23,26,28,27,26,21,14,15, 7, 7,10,15,12,11,10, 9,
7,14,11,16,12,18,16,14,16,14,11,14,15,21,23,17,20,18,26,24,27,18,20,11,11,14,10,17,17,10, 6,10,
13, 9,14,10,13,11,14,15,18,15,15,12,19,19,20,18,22,20,19,22,19,19,19,20,17,15,15,11,16,14,10, 8,
13,16,12,16,17,19,17,18,15,19,14,18,15,14,15,17,21,19,23,18,23,22,18,18,17,15,15,16,12,12,15,10,
10,12,14,10,16,11,18,15,21,20,20,17,18,19,16,19,14,20,19,14,19,25,22,21,22,24,18,12, 9, 9, 8, 6,
10,10,13, 9,15,13,20,19,22,18,18,17,17,21,21,13,13,12,19,18,16,17,27,26,22,23,20,17,12,11, 8, 9,
7,13,14,15,11,13,18,22,19,23,23,20,22,24,21,14,12,16,17,19,18,18,22,18,24,23,19,17,16,14, 8, 7,
12,12, 8, 8,16,20,26,25,28,28,22,29,23,22,21,18,13,16,15,15,20,17,25,24,19,17,17,17,15,10, 8, 9,
7,12,15,11,17,20,25,25,25,29,30,31,28,26,18,16,17,18,20,21,22,20,23,19,18,19,10,16,16,11,11, 8,
5, 6, 8,14,14,17,17,21,27,23,27,31,27,22,23,21,19,19,21,19,20,19,17,22,13,17,12,15,10,10,12, 6,
8, 9, 8,14,15,16,15,18,27,26,23,25,23,22,18,21,20,17,19,20,20,16,20,14,15,13,12, 8, 8, 7,11,13,
7, 6,11,11,11,13,15,22,25,24,26,22,24,26,23,18,24,24,20,18,20,16,17,12,12,12,10, 8,11, 9, 6, 8,
9,10, 9, 6, 5,14,16,19,17,21,26,20,23,19,19,17,20,21,26,25,23,21,17,13,12, 5,13,11, 7,12,10,12,
6, 5, 4,10,11, 9,10,13,17,20,20,18,23,26,27,20,21,24,20,19,24,20,18,10,11, 3, 6,13, 9, 6, 8, 8,
1, 2, 2,11,13,13,11,16,16,16,19,21,20,23,22,28,21,20,19,18,23,16,18, 7, 5, 9, 7, 6, 5,10, 8, 8,
0, 0, 6, 9,11,15,12,12,19,18,19,26,22,24,26,30,23,22,22,16,20,19,12,12, 3, 4, 6, 5, 4, 7, 2, 4,
2, 0, 0, 7,11, 8,14,13,15,21,26,28,25,24,27,26,23,24,22,22,15,17,12, 8,10, 7, 7, 4, 0, 5, 0, 1,
1, 2, 0, 1, 9,14,13,10,19,24,22,29,30,28,30,30,31,23,24,19,17,14,13, 8, 8, 8, 1, 4, 0, 0, 0, 3,
5, 2, 4, 2, 9, 8, 8, 8,18,23,20,27,30,27,31,25,28,30,28,24,24,15,11,14,10, 3, 4, 3, 0, 0, 1, 3,
9, 3, 4, 3, 5, 6, 8,13,14,23,21,27,28,27,28,27,27,29,30,24,22,23,13,15, 8, 6, 2, 0, 4, 3, 4, 1,
6, 5, 5, 3, 9, 3, 6,14,13,16,23,26,28,23,30,31,28,29,26,27,21,20,15,15,13, 9, 1, 0, 2, 0, 5, 8,
8, 4, 3, 7, 2, 0,10, 7,10,14,21,21,29,28,25,27,30,28,25,24,27,22,19,13,10, 5, 0, 0, 0, 0, 0, 7,
7, 6, 7, 0, 2, 2, 5, 6,15,11,19,24,22,29,27,31,30,30,31,28,23,18,14,14, 7, 5, 0, 0, 1, 0, 1, 0,
5, 5, 5, 0, 0, 4, 5,11, 7,10,13,20,21,21,28,31,28,30,26,28,25,21, 9,12, 3, 3, 0, 2, 2, 2, 0, 1,
3, 3, 0, 2, 0, 3, 5, 3,11,11,16,19,19,27,26,26,30,27,28,26,23,22,16, 6, 2, 2, 3, 2, 0, 2, 4, 0,
0, 0, 0, 3, 3, 1, 0, 4, 5, 9,11,16,24,20,28,26,28,24,28,25,22,21,16, 5, 7, 5, 7, 3, 2, 3, 3, 6,
0, 0, 2, 0, 2, 0, 4, 3, 8,12, 9,17,16,23,23,27,27,22,26,22,21,21,13,14, 5, 3, 7, 3, 2, 4, 6, 1,
2, 5, 6, 4, 0, 1, 5, 8, 7, 6,15,17,22,20,24,28,23,25,20,21,18,16,13,15,13,10, 8, 5, 5, 9, 3, 7,
7, 7, 0, 5, 1, 6, 7, 9,12, 9,12,21,22,25,24,22,23,25,24,18,24,22,17,13,10, 9,10, 9, 6,11, 6, 5,
};
const FTexture::Span FBackdropTexture::DummySpan[2] = { { 0, 160 }, { 0, 0 } };
//=============================================================================
//
//
//
//=============================================================================
FBackdropTexture::FBackdropTexture()
{
Width = 144;
Height = 160;
WidthBits = 8;
HeightBits = 8;
WidthMask = 255;
LastRenderTic = 0;
for (int i = 0; i < COS_SIZE; ++i)
{
costab[i] = uint32_t(cos(i * (M_PI / (COS_SIZE / 2))) * 65536);
}
time1 = DEGREES(180);
time2 = DEGREES(56);
time3 = DEGREES(99);
time4 = DEGREES(1);
t1ang = DEGREES(90);
t2ang = 0;
z1ang = 0;
z2ang = DEGREES(45);
}
//=============================================================================
//
//
//
//=============================================================================
bool FBackdropTexture::CheckModified()
{
return LastRenderTic != gametic;
}
void FBackdropTexture::Unload()
{
}
//=============================================================================
//
//
//
//=============================================================================
const BYTE *FBackdropTexture::GetColumn(unsigned int column, const Span **spans_out)
{
if (LastRenderTic != gametic)
{
Render();
}
column = clamp(column, 0u, 143u);
if (spans_out != NULL)
{
*spans_out = DummySpan;
}
return Pixels + column*160;
}
//=============================================================================
//
//
//
//=============================================================================
const BYTE *FBackdropTexture::GetPixels()
{
if (LastRenderTic != gametic)
{
Render();
}
return Pixels;
}
//=============================================================================
//
// This is one plasma and two rotozoomers. I think it turned out quite awesome.
//
//=============================================================================
void FBackdropTexture::Render()
{
BYTE *from;
int width, height, pitch;
width = 160;
height = 144;
pitch = width;
int x, y;
const DWORD a1add = DEGREES(0.5);
const DWORD a2add = DEGREES(359);
const DWORD a3add = DEGREES(5 / 7.f);
const DWORD a4add = DEGREES(358.66666);
const DWORD t1add = DEGREES(358);
const DWORD t2add = DEGREES(357.16666);
const DWORD t3add = DEGREES(2.285);
const DWORD t4add = DEGREES(359.33333);
const DWORD x1add = 5 * 524288;
const DWORD x2add = 0u - 13 * 524288;
const DWORD z1add = 3 * 524288;
const DWORD z2add = 4 * 524288;
DWORD a1, a2, a3, a4;
SDWORD c1, c2, c3, c4;
DWORD tx, ty, tc, ts;
DWORD ux, uy, uc, us;
DWORD ltx, lty, lux, luy;
from = Pixels;
a3 = time3;
a4 = time4;
double z1 = (cos(TORAD(z2ang)) / 4 + 0.5) * (0x8000000);
double z2 = (cos(TORAD(z1ang)) / 4 + 0.75) * (0x8000000);
tc = SDWORD(cos(TORAD(t1ang)) * z1);
ts = SDWORD(sin(TORAD(t1ang)) * z1);
uc = SDWORD(cos(TORAD(t2ang)) * z2);
us = SDWORD(sin(TORAD(t2ang)) * z2);
ltx = -width / 2 * tc;
lty = -width / 2 * ts;
lux = -width / 2 * uc;
luy = -width / 2 * us;
for (y = 0; y < height; ++y)
{
a1 = time1;
a2 = time2;
c3 = SDWORD(cos(TORAD(a3)) * 65536.0);
c4 = SDWORD(cos(TORAD(a4)) * 65536.0);
tx = ltx - (y - height / 2)*ts;
ty = lty + (y - height / 2)*tc;
ux = lux - (y - height / 2)*us;
uy = luy + (y - height / 2)*uc;
for (x = 0; x < width; ++x)
{
c1 = costab[a1 >> ANGLESHIFT];
c2 = costab[a2 >> ANGLESHIFT];
from[x] = ((c1 + c2 + c3 + c4) >> (16 + 3 - 7)) + 128 // plasma
+ pattern1[(tx >> 27) + ((ty >> 22) & 992)] // rotozoomer 1
+ pattern2[(ux >> 27) + ((uy >> 22) & 992)]; // rotozoomer 2
tx += tc;
ty += ts;
ux += uc;
uy += us;
a1 += a1add;
a2 += a2add;
}
a3 += a3add;
a4 += a4add;
from += pitch;
}
time1 += t1add;
time2 += t2add;
time3 += t3add;
time4 += t4add;
t1ang += x1add;
t2ang += x2add;
z1ang += z1add;
z2ang += z2add;
LastRenderTic = gametic;
}
//=============================================================================
//
//
//
//=============================================================================
IMPLEMENT_CLASS(DListMenuItemPlayerDisplay, false, false)
DListMenuItemPlayerDisplay::DListMenuItemPlayerDisplay(FListMenuDescriptor *menu, int x, int y, PalEntry c1, PalEntry c2, bool np, FName action)
DListMenuItemPlayerDisplay::DListMenuItemPlayerDisplay(DListMenuDescriptor *menu, int x, int y, PalEntry c1, PalEntry c2, bool np, FName action)
: DMenuItemBase(x, y, action)
{
mOwner = menu;
@ -369,7 +69,8 @@ DListMenuItemPlayerDisplay::DListMenuItemPlayerDisplay(FListMenuDescriptor *menu
bdremap->Remap[i] = ColorMatcher.Pick (r, g, b);
bdremap->Palette[i] = PalEntry(255, r, g, b);
}
mBackdrop = new FBackdropTexture;
auto id = TexMan.CheckForTexture("PlayerBackdrop", FTexture::TEX_MiscPatch);
mBackdrop = TexMan[id];
mPlayerClass = NULL;
mPlayerState = NULL;
mNoportrait = np;
@ -391,7 +92,6 @@ DListMenuItemPlayerDisplay::DListMenuItemPlayerDisplay(FListMenuDescriptor *menu
void DListMenuItemPlayerDisplay::OnDestroy()
{
delete mBackdrop;
}
//=============================================================================

View file

@ -509,7 +509,7 @@ class DPlayerMenu : public DListMenu
public:
DPlayerMenu() {}
void Init(DMenu *parent, FListMenuDescriptor *desc);
void Init(DMenu *parent, DListMenuDescriptor *desc);
bool Responder (event_t *ev);
bool MenuEvent (int mkey, bool fromcontroller);
bool MouseEvent(int type, int x, int y);
@ -525,7 +525,7 @@ IMPLEMENT_CLASS(DPlayerMenu, false, false)
//
//=============================================================================
void DPlayerMenu::Init(DMenu *parent, FListMenuDescriptor *desc)
void DPlayerMenu::Init(DMenu *parent, DListMenuDescriptor *desc)
{
DMenuItemBase *li;

View file

@ -66,7 +66,7 @@
static void BuildModesList (int hiwidth, int hiheight, int hi_id);
static bool GetSelectedSize (int *width, int *height);
static void SetModesMenu (int w, int h, int bits);
FOptionMenuDescriptor *GetVideoModeMenu();
DOptionMenuDescriptor *GetVideoModeMenu();
extern bool setmodeneeded;
extern int NewWidth, NewHeight, NewBits;
@ -101,7 +101,7 @@ CUSTOM_CVAR (Int, menu_screenratios, -1, CVAR_ARCHIVE)
CUSTOM_CVAR (Bool, vid_tft, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{
FOptionMenuDescriptor *opt = GetVideoModeMenu();
DOptionMenuDescriptor *opt = GetVideoModeMenu();
if (opt != NULL)
{
DOptionMenuItem *it = opt->GetItem("menu_screenratios");
@ -192,12 +192,12 @@ IMPLEMENT_CLASS(DVideoModeMenu, false, false)
//
//=============================================================================
FOptionMenuDescriptor *GetVideoModeMenu()
DOptionMenuDescriptor *GetVideoModeMenu()
{
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_VideoModeMenu);
if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu)
DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_VideoModeMenu);
if (desc != NULL && (*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor)))
{
return (FOptionMenuDescriptor *)*desc;
return (DOptionMenuDescriptor *)*desc;
}
return NULL;
}
@ -231,7 +231,7 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_bits)
Video->StartModeIterator (showbits, screen->IsFullscreen());
}
FOptionMenuDescriptor *opt = GetVideoModeMenu();
DOptionMenuDescriptor *opt = GetVideoModeMenu();
if (opt != NULL)
{
for (i = NAME_res_0; i<= NAME_res_9; i++)
@ -354,7 +354,7 @@ void M_InitVideoModesMenu ()
static bool GetSelectedSize (int *width, int *height)
{
FOptionMenuDescriptor *opt = GetVideoModeMenu();
DOptionMenuDescriptor *opt = GetVideoModeMenu();
if (opt != NULL && (unsigned)opt->mSelectedItem < opt->mItems.Size())
{
int line = opt->mSelectedItem;
@ -420,7 +420,7 @@ static void SetModesMenu (int w, int h, int bits)
{
DummyDepthCvar = FindBits (bits);
FOptionMenuDescriptor *opt = GetVideoModeMenu();
DOptionMenuDescriptor *opt = GetVideoModeMenu();
if (opt != NULL)
{
DOptionMenuItem *it;

View file

@ -145,8 +145,6 @@ IMPLEMENT_POINTERS_START(AActor)
IMPLEMENT_POINTER(Poisoner)
IMPLEMENT_POINTER(DamageFunc)
IMPLEMENT_POINTER(alternative)
IMPLEMENT_POINTER(TeleFogSourceType)
IMPLEMENT_POINTER(TeleFogDestType)
IMPLEMENT_POINTERS_END
AActor::~AActor ()

View file

@ -680,7 +680,10 @@ void ProcessMouseButtonEvent(NSEvent* theEvent)
void ProcessMouseWheelEvent(NSEvent* theEvent)
{
const CGFloat delta = [theEvent deltaY];
const SWORD modifiers = ModifierFlagsToGUIKeyModifiers(theEvent);
const CGFloat delta = (modifiers & GKM_SHIFT)
? [theEvent deltaX]
: [theEvent deltaY];
const bool isZeroDelta = fabs(delta) < 1.0E-5;
if (isZeroDelta && GUICapture)
@ -694,7 +697,7 @@ void ProcessMouseWheelEvent(NSEvent* theEvent)
{
event.type = EV_GUI_Event;
event.subtype = delta > 0.0f ? EV_GUI_WheelUp : EV_GUI_WheelDown;
event.data3 = ModifierFlagsToGUIKeyModifiers(theEvent);
event.data3 = modifiers;
}
else
{

View file

@ -7747,6 +7747,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
if (MethodName == NAME_Size)
{
FxExpression *x = new FxMemberIdentifier(Self, NAME_Size, ScriptPosition); // todo: obfuscate the name to prevent direct access.
Self->ValueType = static_cast<PDynArray*>(Self->ValueType)->BackingType;
Self = nullptr;
delete this;
return x->Resolve(ctx);

View file

@ -54,6 +54,8 @@
#include "p_checkposition.h"
#include "r_sky.h"
#include "v_font.h"
#include "v_video.h"
#include "menu/menu.h"
static TArray<FPropertyInfo*> properties;
static TArray<AFuncDesc> AFTable;
@ -841,6 +843,34 @@ void InitThingdef()
fieldptr = new PField("intermissionfont", fontptr, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&IntermissionFont);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("CleanXFac", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanXfac);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("CleanYFac", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanYfac);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("CleanWidth", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanWidth);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("CleanHeight", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanHeight);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("CleanXFac_1", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanXfac_1);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("CleanYFac_1", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanYfac_1);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("CleanWidth_1", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanWidth_1);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("CleanHeight_1", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&CleanHeight_1);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
fieldptr = new PField("OptionMenuSettings", NewStruct("FOptionMenuSettings", nullptr), VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&OptionSettings);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
// Argh. It sucks when bad hacks need to be supported. WP_NOCHANGE is just a bogus pointer but it used everywhere as a special flag.
// It cannot be defined as constant because constants can either be numbers or strings but nothing else, so the only 'solution'
// is to create a static variable from it and reference that in the script. Yuck!!!

View file

@ -69,7 +69,7 @@ static FString GetStringConst(FxExpression *ex, FCompileContext &ctx)
{
ex = new FxStringCast(ex);
ex = ex->Resolve(ctx);
return static_cast<FxConstant*>(ex)->GetValue().GetString();
return ex ? static_cast<FxConstant*>(ex)->GetValue().GetString() : FString();
}
int ZCCCompiler::IntConstFromNode(ZCC_TreeNode *node, PStruct *cls)

View file

@ -0,0 +1,361 @@
/*
** backdroptexture.cpp
** The player display background for the player setup and class selection screen
**
**---------------------------------------------------------------------------
** Copyright 1999-2010 Randy Heit
** Copyright 2010 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.
**---------------------------------------------------------------------------
**
*/
#include "doomtype.h"
#include "doomstat.h"
#include "d_player.h"
#include "templates.h"
#include "menu/menu.h"
#include "colormatcher.h"
#include "textures/textures.h"
#include "w_wad.h"
#include "v_font.h"
#include "v_video.h"
#include "g_level.h"
#include "gi.h"
#include "r_defs.h"
#include "r_state.h"
#include "r_data/r_translate.h"
//=============================================================================
//
// Used by the player display
//
//=============================================================================
struct FBackdropTexture : public FTexture
{
enum
{
COS_SIZE = 256,
ANGLESHIFT = 24
};
static constexpr uint32_t DEGREES(double v)
{
return uint32_t((v)*(0x40000000 / 90.0));
}
static double TORAD(uint32_t x)
{
return x*(M_PI / 0x80000000);
}
public:
FBackdropTexture();
const uint8_t *GetColumn(unsigned int column, const Span **spans_out);
const uint8_t *GetPixels();
void Unload();
bool CheckModified();
protected:
uint32_t costab[COS_SIZE];
uint8_t *Pixels;
static const Span DummySpan[2];
int LastRenderTic;
uint32_t time1, time2, time3, time4;
uint32_t t1ang, t2ang, z1ang, z2ang;
void Render();
};
// A 32x32 cloud rendered with Photoshop, plus some other filters
static uint8_t pattern1[1024] =
{
5, 9, 7,10, 9,15, 9, 7, 8,10, 5, 3, 5, 7, 9, 8,14, 8, 4, 7, 8, 9, 5, 7,14, 7, 0, 7,13,13, 9, 6,
2, 7, 9, 7, 7,10, 8, 8,11,10, 6, 7,10, 7, 5, 6, 6, 4, 7,13,15,16,11,15,11, 8, 0, 4,13,22,17,11,
5, 9, 9, 7, 9,10, 4, 3, 6, 7, 8, 6, 5, 4, 2, 2, 1, 4, 6,11,15,15,14,13,17, 9, 5, 9,11,12,17,20,
9,16, 9, 8,12,13, 7, 3, 7, 9, 5, 4, 2, 5, 5, 5, 7,11, 6, 7, 6,13,17,10,10, 9,12,17,14,12,16,15,
15,13, 5, 3, 9,10, 4,10,12,12, 7, 9, 8, 8, 8,10, 7, 6, 5, 5, 5, 6,11, 9, 3,13,16,18,21,16,23,18,
23,13, 0, 0, 0, 0, 0,12,18,14,15,16,13, 7, 7, 5, 9, 6, 6, 8, 4, 0, 0, 0, 0,14,19,17,14,20,21,25,
19,20,14,13, 7, 5,13,19,14,13,17,15,14, 7, 3, 5, 6,11, 7, 7, 8, 8,10, 9, 9,18,17,15,14,15,18,16,
16,29,24,23,18, 9,17,20,11, 5,12,15,15,12, 6, 3, 4, 6, 7,10,13,18,18,19,16,12,17,19,23,16,14,14,
9,18,20,26,19, 5,18,18,10, 5,12,15,14,17,11, 6,11, 9,10,13,10,20,24,20,21,20,14,18,15,22,20,19,
0, 6,16,18, 8, 7,15,18,10,13,17,17,13,11,15,11,19,12,13,10, 4,15,19,21,21,24,14, 9,17,20,24,17,
18,17, 7, 7,16,21,22,15, 5,14,20,14,13,21,13, 8,12,14, 7, 8,11,15,13,11,16,17, 7, 5,12,17,19,14,
25,23,17,16,23,18,15, 7, 0, 6,11, 6,11,15,11, 7,12, 7, 4,10,16,13, 7, 7,15,13, 9,15,21,14, 5, 0,
18,22,21,21,21,22,12, 6,14,20,15, 6,10,19,13, 8, 7, 3, 7,12,14,16, 9,12,22,15,12,18,24,19,17, 9,
0,15,18,21,17,25,14,13,19,21,21,11, 6,13,16,16,12,10,12,11,13,20,14,13,18,13, 9,15,16,25,31,20,
5,20,24,16, 7,14,14,11,18,19,19, 6, 0, 5,11,14,17,16,19,14,15,21,19,15,14,14, 8, 0, 7,24,18,16,
9,17,15, 7, 6,14,12, 7,14,16,11, 4, 7, 6,13,16,15,13,12,20,21,20,21,17,18,26,14, 0,13,23,21,11,
9,12,18,11,15,21,13, 8,13,13,10, 7,13, 8, 8,19,13, 7, 4,15,19,18,14,12,14,15, 8, 6,16,22,22,15,
9,17,14,19,15,14,15, 9,11, 9, 6, 8,14,13,13,12, 5, 0, 0, 6,12,13, 7, 7, 9, 7, 0,12,21,16,15,18,
15,16,18,11, 6, 8,15, 9, 2, 0, 5,10,10,16, 9, 0, 4,12,15, 9,12, 9, 7, 7,12, 7, 0, 6,12, 6, 9,13,
12,19,15,14,11, 7, 8, 9,12,10, 5, 5, 7,12,12,10,14,16,16,11, 8,12,10,12,10, 8,10,10,14,12,16,16,
16,17,20,22,12,15,12,14,19,11, 6, 5,10,13,17,17,21,19,15, 9, 6, 9,15,18,10,10,18,14,20,15,16,17,
11,19,19,18,19,14,17,13,12,12, 7,11,18,17,16,15,19,19,10, 2, 0, 8,15,12, 8,11,12,10,19,20,19,19,
6,14,18,13,13,16,16,12, 5, 8,10,12,10,13,18,12, 9,10, 7, 6, 5,11, 8, 6, 7,13,16,13,10,15,20,14,
0, 5,12,12, 4, 0, 9,16, 9,10,12, 8, 0, 9,13, 9, 0, 2, 4, 7,10, 6, 7, 3, 4,11,16,18,10,11,21,21,
16,13,11,15, 8, 0, 5, 9, 8, 7, 6, 3, 0, 9,17, 9, 0, 0, 0, 3, 5, 4, 3, 5, 7,15,16,16,17,14,22,22,
24,14,15,12, 9, 0, 5,10, 8, 4, 7,12,10,11,12, 7, 6, 8, 6, 5, 7, 8, 8,11,13,10,15,14,12,18,20,16,
16,17,17,18,12, 9,12,16,10, 5, 6,20,13,15, 8, 4, 8, 9, 8, 7, 9,11,12,17,16,16,11,10, 9,10, 5, 0,
0,14,18,18,15,16,14, 9,10, 9, 9,15,14,10, 4, 6,10, 8, 8, 7,10, 9,10,16,18,10, 0, 0, 7,12,10, 8,
0,14,19,14, 9,11,11, 8, 8,10,15, 9,10, 7, 4,10,13, 9, 7, 5, 5, 7, 7, 7,13,13, 5, 5,14,22,18,16,
0,10,14,10, 3, 6, 5, 6, 8, 9, 8, 9, 5, 9, 8, 9, 6, 8, 8, 8, 1, 0, 0, 0, 9,17,12,12,17,19,20,13,
6,11,17,11, 5, 5, 8,10, 6, 5, 6, 6, 3, 7, 9, 7, 6, 8,12,10, 4, 8, 6, 6,11,16,16,15,16,17,17,16,
11, 9,10,10, 5, 6,12,10, 5, 1, 6,10, 5, 3, 3, 5, 4, 7,15,10, 7,13, 7, 8,15,11,15,15,15, 8,11,15,
};
// Just a 32x32 cloud rendered with the standard Photoshop filter
static uint8_t pattern2[1024] =
{
9, 9, 8, 8, 8, 8, 6, 6,13,13,11,21,19,21,23,18,23,24,19,19,24,17,18,12, 9,14, 8,12,12, 5, 8, 6,
11,10, 6, 7, 8, 8, 9,13,10,11,17,15,23,22,23,22,20,26,27,26,17,21,20,14,12, 8,11, 8,11, 7, 8, 7,
6, 9,13,13,10, 9,13, 7,12,13,16,19,16,20,22,25,22,25,27,22,21,23,15,10,14,14,15,13,12, 8,12, 6,
6, 7,12,12,12,16, 9,12,12,15,16,11,21,24,19,24,23,26,28,27,26,21,14,15, 7, 7,10,15,12,11,10, 9,
7,14,11,16,12,18,16,14,16,14,11,14,15,21,23,17,20,18,26,24,27,18,20,11,11,14,10,17,17,10, 6,10,
13, 9,14,10,13,11,14,15,18,15,15,12,19,19,20,18,22,20,19,22,19,19,19,20,17,15,15,11,16,14,10, 8,
13,16,12,16,17,19,17,18,15,19,14,18,15,14,15,17,21,19,23,18,23,22,18,18,17,15,15,16,12,12,15,10,
10,12,14,10,16,11,18,15,21,20,20,17,18,19,16,19,14,20,19,14,19,25,22,21,22,24,18,12, 9, 9, 8, 6,
10,10,13, 9,15,13,20,19,22,18,18,17,17,21,21,13,13,12,19,18,16,17,27,26,22,23,20,17,12,11, 8, 9,
7,13,14,15,11,13,18,22,19,23,23,20,22,24,21,14,12,16,17,19,18,18,22,18,24,23,19,17,16,14, 8, 7,
12,12, 8, 8,16,20,26,25,28,28,22,29,23,22,21,18,13,16,15,15,20,17,25,24,19,17,17,17,15,10, 8, 9,
7,12,15,11,17,20,25,25,25,29,30,31,28,26,18,16,17,18,20,21,22,20,23,19,18,19,10,16,16,11,11, 8,
5, 6, 8,14,14,17,17,21,27,23,27,31,27,22,23,21,19,19,21,19,20,19,17,22,13,17,12,15,10,10,12, 6,
8, 9, 8,14,15,16,15,18,27,26,23,25,23,22,18,21,20,17,19,20,20,16,20,14,15,13,12, 8, 8, 7,11,13,
7, 6,11,11,11,13,15,22,25,24,26,22,24,26,23,18,24,24,20,18,20,16,17,12,12,12,10, 8,11, 9, 6, 8,
9,10, 9, 6, 5,14,16,19,17,21,26,20,23,19,19,17,20,21,26,25,23,21,17,13,12, 5,13,11, 7,12,10,12,
6, 5, 4,10,11, 9,10,13,17,20,20,18,23,26,27,20,21,24,20,19,24,20,18,10,11, 3, 6,13, 9, 6, 8, 8,
1, 2, 2,11,13,13,11,16,16,16,19,21,20,23,22,28,21,20,19,18,23,16,18, 7, 5, 9, 7, 6, 5,10, 8, 8,
0, 0, 6, 9,11,15,12,12,19,18,19,26,22,24,26,30,23,22,22,16,20,19,12,12, 3, 4, 6, 5, 4, 7, 2, 4,
2, 0, 0, 7,11, 8,14,13,15,21,26,28,25,24,27,26,23,24,22,22,15,17,12, 8,10, 7, 7, 4, 0, 5, 0, 1,
1, 2, 0, 1, 9,14,13,10,19,24,22,29,30,28,30,30,31,23,24,19,17,14,13, 8, 8, 8, 1, 4, 0, 0, 0, 3,
5, 2, 4, 2, 9, 8, 8, 8,18,23,20,27,30,27,31,25,28,30,28,24,24,15,11,14,10, 3, 4, 3, 0, 0, 1, 3,
9, 3, 4, 3, 5, 6, 8,13,14,23,21,27,28,27,28,27,27,29,30,24,22,23,13,15, 8, 6, 2, 0, 4, 3, 4, 1,
6, 5, 5, 3, 9, 3, 6,14,13,16,23,26,28,23,30,31,28,29,26,27,21,20,15,15,13, 9, 1, 0, 2, 0, 5, 8,
8, 4, 3, 7, 2, 0,10, 7,10,14,21,21,29,28,25,27,30,28,25,24,27,22,19,13,10, 5, 0, 0, 0, 0, 0, 7,
7, 6, 7, 0, 2, 2, 5, 6,15,11,19,24,22,29,27,31,30,30,31,28,23,18,14,14, 7, 5, 0, 0, 1, 0, 1, 0,
5, 5, 5, 0, 0, 4, 5,11, 7,10,13,20,21,21,28,31,28,30,26,28,25,21, 9,12, 3, 3, 0, 2, 2, 2, 0, 1,
3, 3, 0, 2, 0, 3, 5, 3,11,11,16,19,19,27,26,26,30,27,28,26,23,22,16, 6, 2, 2, 3, 2, 0, 2, 4, 0,
0, 0, 0, 3, 3, 1, 0, 4, 5, 9,11,16,24,20,28,26,28,24,28,25,22,21,16, 5, 7, 5, 7, 3, 2, 3, 3, 6,
0, 0, 2, 0, 2, 0, 4, 3, 8,12, 9,17,16,23,23,27,27,22,26,22,21,21,13,14, 5, 3, 7, 3, 2, 4, 6, 1,
2, 5, 6, 4, 0, 1, 5, 8, 7, 6,15,17,22,20,24,28,23,25,20,21,18,16,13,15,13,10, 8, 5, 5, 9, 3, 7,
7, 7, 0, 5, 1, 6, 7, 9,12, 9,12,21,22,25,24,22,23,25,24,18,24,22,17,13,10, 9,10, 9, 6,11, 6, 5,
};
const FTexture::Span FBackdropTexture::DummySpan[2] = { { 0, 160 }, { 0, 0 } };
//=============================================================================
//
//
//
//=============================================================================
FBackdropTexture::FBackdropTexture()
{
Pixels = nullptr;
Width = 144;
Height = 160;
WidthBits = 8;
HeightBits = 8;
WidthMask = 255;
LastRenderTic = 0;
for (int i = 0; i < COS_SIZE; ++i)
{
costab[i] = uint32_t(cos(i * (M_PI / (COS_SIZE / 2))) * 65536);
}
time1 = DEGREES(180);
time2 = DEGREES(56);
time3 = DEGREES(99);
time4 = DEGREES(1);
t1ang = DEGREES(90);
t2ang = 0;
z1ang = 0;
z2ang = DEGREES(45);
}
//=============================================================================
//
//
//
//=============================================================================
bool FBackdropTexture::CheckModified()
{
return LastRenderTic != gametic;
}
void FBackdropTexture::Unload()
{
if (Pixels != nullptr) delete[] Pixels;
Pixels = nullptr;
}
//=============================================================================
//
//
//
//=============================================================================
const uint8_t *FBackdropTexture::GetColumn(unsigned int column, const Span **spans_out)
{
if (LastRenderTic != gametic)
{
Render();
}
column = clamp(column, 0u, 143u);
if (spans_out != nullptr)
{
*spans_out = DummySpan;
}
return Pixels + column*160;
}
//=============================================================================
//
//
//
//=============================================================================
const uint8_t *FBackdropTexture::GetPixels()
{
if (LastRenderTic != gametic)
{
Render();
}
return Pixels;
}
//=============================================================================
//
// This is one plasma and two rotozoomers. I think it turned out quite awesome.
//
//=============================================================================
void FBackdropTexture::Render()
{
uint8_t *from;
int width, height, pitch;
if (Pixels == nullptr) Pixels = new uint8_t[160 * 144];
width = 160;
height = 144;
pitch = width;
int x, y;
const DWORD a1add = DEGREES(0.5);
const DWORD a2add = DEGREES(359);
const DWORD a3add = DEGREES(5 / 7.f);
const DWORD a4add = DEGREES(358.66666);
const DWORD t1add = DEGREES(358);
const DWORD t2add = DEGREES(357.16666);
const DWORD t3add = DEGREES(2.285);
const DWORD t4add = DEGREES(359.33333);
const DWORD x1add = 5 * 524288;
const DWORD x2add = 0u - 13 * 524288;
const DWORD z1add = 3 * 524288;
const DWORD z2add = 4 * 524288;
DWORD a1, a2, a3, a4;
SDWORD c1, c2, c3, c4;
DWORD tx, ty, tc, ts;
DWORD ux, uy, uc, us;
DWORD ltx, lty, lux, luy;
from = Pixels;
a3 = time3;
a4 = time4;
double z1 = (cos(TORAD(z2ang)) / 4 + 0.5) * (0x8000000);
double z2 = (cos(TORAD(z1ang)) / 4 + 0.75) * (0x8000000);
tc = SDWORD(cos(TORAD(t1ang)) * z1);
ts = SDWORD(sin(TORAD(t1ang)) * z1);
uc = SDWORD(cos(TORAD(t2ang)) * z2);
us = SDWORD(sin(TORAD(t2ang)) * z2);
ltx = -width / 2 * tc;
lty = -width / 2 * ts;
lux = -width / 2 * uc;
luy = -width / 2 * us;
for (y = 0; y < height; ++y)
{
a1 = time1;
a2 = time2;
c3 = SDWORD(cos(TORAD(a3)) * 65536.0);
c4 = SDWORD(cos(TORAD(a4)) * 65536.0);
tx = ltx - (y - height / 2)*ts;
ty = lty + (y - height / 2)*tc;
ux = lux - (y - height / 2)*us;
uy = luy + (y - height / 2)*uc;
for (x = 0; x < width; ++x)
{
c1 = costab[a1 >> ANGLESHIFT];
c2 = costab[a2 >> ANGLESHIFT];
from[x] = ((c1 + c2 + c3 + c4) >> (16 + 3 - 7)) + 128 // plasma
+ pattern1[(tx >> 27) + ((ty >> 22) & 992)] // rotozoomer 1
+ pattern2[(ux >> 27) + ((uy >> 22) & 992)]; // rotozoomer 2
tx += tc;
ty += ts;
ux += uc;
uy += us;
a1 += a1add;
a2 += a2add;
}
a3 += a3add;
a4 += a4add;
from += pitch;
}
time1 += t1add;
time2 += t2add;
time3 += t3add;
time4 += t4add;
t1ang += x1add;
t2ang += x2add;
z1ang += z1add;
z2ang += z2add;
LastRenderTic = gametic;
}
FTexture *GetBackdropTexture()
{
auto t = new FBackdropTexture;
t->Name = "PlayerBackdrop";
return t;
}

View file

@ -976,6 +976,7 @@ void FTextureManager::SortTexturesByType(int start, int end)
// FTextureManager :: Init
//
//==========================================================================
FTexture *GetBackdropTexture();
void FTextureManager::Init()
{
@ -987,6 +988,7 @@ void FTextureManager::Init()
// Texture 0 is a dummy texture used to indicate "no texture"
AddTexture (new FDummyTexture);
AddTexture(GetBackdropTexture());
int wadcnt = Wads.GetNumWads();
for(int i = 0; i< wadcnt; i++)

View file

@ -98,6 +98,15 @@ DEFINE_ACTION_FUNCTION(_Screen, GetHeight)
ACTION_RETURN_INT(screen->GetHeight());
}
DEFINE_ACTION_FUNCTION(_Screen, PaletteColor)
{
PARAM_PROLOGUE;
PARAM_INT(index);
if (index < 0 || index > 255) index = 0;
else index = GPalette.BaseColors[index];
ACTION_RETURN_INT(index);
}
static int PalFromRGB(uint32 rgb)
{
if (LastPal >= 0 && LastRGB == rgb)
@ -484,12 +493,15 @@ static void ListEnd(VMVa_List &tags)
int ListGetInt(VMVa_List &tags)
{
if (tags.curindex < tags.numargs && tags.args[tags.curindex].Type == REGT_INT)
if (tags.curindex < tags.numargs)
{
return tags.args[tags.curindex++].i;
if (tags.args[tags.curindex].Type == REGT_INT)
{
return tags.args[tags.curindex++].i;
}
ThrowAbortException(X_OTHER, "Invalid parameter in draw function, int expected");
}
ThrowAbortException(X_OTHER, "Invalid parameter in draw function, int expected");
return 0;
return TAG_DONE;
}
static inline double ListGetDouble(VMVa_List &tags)
@ -1336,18 +1348,18 @@ void DCanvas::Clear (int left, int top, int right, int bottom, int palcolor, uin
}
}
//==========================================================================
//
// no-ops. This is so that renderer backends can better manage the
// processing of the subsector drawing in the automap
//
//==========================================================================
void DCanvas::StartSimplePolys()
{}
void DCanvas::FinishSimplePolys()
{}
DEFINE_ACTION_FUNCTION(_Screen, Clear)
{
PARAM_PROLOGUE;
PARAM_INT(x1);
PARAM_INT(y1);
PARAM_INT(x2);
PARAM_INT(y2);
PARAM_INT(color);
PARAM_INT_DEF(palcol);
screen->Clear(x1, y1, x2, y2, palcol, color);
return 0;
}
//==========================================================================
//

View file

@ -853,6 +853,12 @@ DEFINE_ACTION_FUNCTION(FFont, GetCharWidth)
ACTION_RETURN_INT(self->GetCharWidth(code));
}
DEFINE_ACTION_FUNCTION(FFont, GetHeight)
{
PARAM_SELF_STRUCT_PROLOGUE(FFont);
ACTION_RETURN_INT(self->GetHeight());
}
//==========================================================================
//
// Find string width using this font

View file

@ -40,7 +40,7 @@ class DCanvas;
struct FRemapTable;
class FTexture;
enum EColorRange
enum EColorRange : int
{
CR_UNDEFINED = -1,
CR_BRICK,
@ -67,7 +67,6 @@ enum EColorRange
CR_DARKGRAY,
CR_CYAN,
NUM_TEXT_COLORS,
FORCE_DWORD = 0x7fffffff // required for script access.
};
extern int NumTextColors;

View file

@ -46,6 +46,7 @@
#include "doomstat.h"
#include "templates.h"
#include "gstrings.h"
int ListGetInt(VMVa_List &tags);
@ -239,7 +240,8 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawText)
PARAM_STRING(chr);
VMVa_List args = { param + 5, 0, numparam - 5 };
screen->DrawText(font, cr, x, y, chr, args);
const char *txt = chr[0] == '$' ? GStrings(chr) : chr.GetChars();
screen->DrawText(font, cr, x, y, txt, args);
return 0;
}

View file

@ -228,9 +228,6 @@ public:
// Fill an area with a texture
virtual void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin=false);
virtual void StartSimplePolys();
virtual void FinishSimplePolys();
// Fill a simple polygon with a texture
virtual void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints,
double originx, double originy, double scalex, double scaley, DAngle rotation,

View file

@ -7,7 +7,8 @@
#include "zscript/actor_checks.txt"
#include "zscript/menu/menu.txt"
#include "zscript/menu/menuitembase.txt"
//#include "zscript/menu/menuitembase.txt"
#include "zscript/menu/colorpickermenu.txt"
#include "zscript/inventory/inventory.txt"
#include "zscript/inventory/inv_misc.txt"

View file

@ -103,6 +103,32 @@ enum DrawTextureTags
};
struct Screen native
{
int CleanWidth, CleanHeight;
int CleanXFac, CleanYFac;
int CleanWidth_1, CleanHeight_1;
int CleanXFac_1, CleanYFac_1;
native static Color PaletteColor(int index);
native static int GetWidth();
native static int GetHeight();
native static void Clear(int left, int top, int right, int bottom, Color color, int palcolor = -1);
native static void DrawHUDTexture(TextureID tex, double x, double y);
native static vararg void DrawTexture(TextureID tex, bool animate, double x, double y, ...);
native static vararg void DrawChar(Font font, int normalcolor, double x, double y, int character, ...);
native static vararg void DrawText(Font font, int normalcolor, double x, double y, String text, ...);
}
class BrokenLines : Object native
{
native int Count();
native int StringWidth(int line);
native String StringAt(int line);
}
struct Font native
{
enum EColorRange
{
@ -133,26 +159,10 @@ struct Screen native
NUM_TEXT_COLORS
};
native static int GetWidth();
native static int GetHeight();
native static void DrawHUDTexture(TextureID tex, double x, double y);
native static vararg void DrawTexture(TextureID tex, bool animate, double x, double y, ...);
native static vararg void DrawChar(Font font, int normalcolor, double x, double y, int character, ...);
native static vararg void DrawText(Font font, int normalcolor, double x, double y, String text, ...);
}
class BrokenLines : Object native
{
native int Count();
native int StringWidth(int line);
native String StringAt(int line);
}
struct Font native
{
native int GetCharWidth(int code);
native int StringWidth(String code);
native int GetHeight();
native static int FindFontColor(Name color);
native static Font FindFont(Name fontname);
native static Font GetFont(Name fontname);
@ -170,6 +180,13 @@ struct DamageTypeDefinition native
native static bool IgnoreArmor(Name type);
}
struct CVar native
{
native int GetInt();
native double GetFloat();
native String GetString();
}
struct GameInfoStruct native
{
// will be extended as needed.
@ -195,6 +212,7 @@ class Object native
native static bool S_ChangeMusic(String music_name, int order = 0, bool looping = true, bool force = false);
native static uint BAM(double angle);
native static void SetMusicVolume(float vol);
native static uint MSTime();
native Name GetClassName();
native void Destroy();

View file

@ -0,0 +1,260 @@
/*
** colorpickermenu.txt
** The color picker menu
**
**---------------------------------------------------------------------------
** Copyright 2010-2017 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 ColorpickerMenu : Menu native
{
native float mRed;
native float mGreen;
native float mBlue;
native int mGridPosX;
native int mGridPosY;
native int mStartItem;
native CVar mCVar;
//=============================================================================
//
//
//
//=============================================================================
override bool MenuEvent (int mkey, bool fromcontroller)
{
switch (mkey)
{
case MKEY_Down:
if (mDesc.mSelectedItem == mStartItem+6) // last valid item
{
MenuSound ("menu/cursor");
mGridPosY = 0;
// let it point to the last static item so that the super class code still has a valid item
mDesc.mSelectedItem = mStartItem+7;
return true;
}
else if (mDesc.mSelectedItem == mStartItem+7)
{
if (mGridPosY < 15)
{
MenuSound ("menu/cursor");
mGridPosY++;
}
return true;
}
break;
case MKEY_Up:
if (mDesc.mSelectedItem == mStartItem+7)
{
if (mGridPosY > 0)
{
MenuSound ("menu/cursor");
mGridPosY--;
}
else
{
MenuSound ("menu/cursor");
mDesc.mSelectedItem = mStartItem+6;
}
return true;
}
break;
case MKEY_Left:
if (mDesc.mSelectedItem == mStartItem+7)
{
MenuSound ("menu/cursor");
if (--mGridPosX < 0) mGridPosX = 15;
return true;
}
break;
case MKEY_Right:
if (mDesc.mSelectedItem == mStartItem+7)
{
MenuSound ("menu/cursor");
if (++mGridPosX > 15) mGridPosX = 0;
return true;
}
break;
case MKEY_Enter:
if (mDesc.mSelectedItem == mStartItem+7)
{
// Choose selected palette entry
int index = mGridPosX + mGridPosY * 16;
color col = Screen.PaletteColor(index);
mRed = col.r;
mGreen = col.g;
mBlue = col.b;
MenuSound ("menu/choose");
return true;
}
break;
}
if (mDesc.mSelectedItem >= 0 && mDesc.mSelectedItem < mStartItem+7)
{
if (mDesc.mItems[mDesc.mSelectedItem].MenuEvent(mkey, fromcontroller)) return true;
}
return Super.MenuEvent(mkey, fromcontroller);
}
//=============================================================================
//
//
//
//=============================================================================
override bool MouseEvent(int type, int mx, int my)
{
int olditem = mDesc.mSelectedItem;
bool res = Super.MouseEvent(type, mx, my);
if (mDesc.mSelectedItem == -1 || mDesc.mSelectedItem == mStartItem+7)
{
int y = (-mDesc.mPosition + BigFont.GetHeight() + mDesc.mItems.Size() * OptionMenuSettings.mLinespacing) * CleanYfac_1;
int h = (screen.GetHeight() - y) / 16;
int fh = OptionMenuSettings.mLinespacing * CleanYfac_1;
int w = fh;
int yy = y + 2 * CleanYfac_1;
int indent = (screen.GetWidth() / 2);
if (h > fh) h = fh;
else if (h < 4) return res; // no space to draw it.
int box_y = y - 2 * CleanYfac_1;
int box_x = indent - 16*w;
if (mx >= box_x && mx < box_x + 16*w && my >= box_y && my < box_y + 16*h)
{
int cell_x = (mx - box_x) / w;
int cell_y = (my - box_y) / h;
if (olditem != mStartItem+7 || cell_x != mGridPosX || cell_y != mGridPosY)
{
mGridPosX = cell_x;
mGridPosY = cell_y;
//S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE);
}
mDesc.mSelectedItem = mStartItem+7;
if (type == MOUSE_Release)
{
MenuEvent(MKEY_Enter, true);
if (m_use_mouse == 2) mDesc.mSelectedItem = -1;
}
res = true;
}
}
return res;
}
//=============================================================================
//
//
//
//=============================================================================
override void Drawer()
{
Super.Drawer();
if (mCVar == null) return;
int y = (-mDesc.mPosition + BigFont.GetHeight() + mDesc.mItems.Size() * OptionMenuSettings.mLinespacing) * CleanYfac_1;
int fh = OptionMenuSettings.mLinespacing * CleanYfac_1;
int h = (screen.GetHeight() - y) / 16;
int w = fh;
int yy = y;
if (h > fh) h = fh;
else if (h < 4) return; // no space to draw it.
int indent = (screen.GetWidth() / 2);
int p = 0;
for(int i = 0; i < 16; i++)
{
int box_x, box_y;
int x1;
box_y = y - 2 * CleanYfac_1;
box_x = indent - 16*w;
for (x1 = 0; x1 < 16; ++x1)
{
screen.Clear (box_x, box_y, box_x + w, box_y + h, 0, p);
if ((mDesc.mSelectedItem == mStartItem+7) &&
(/*p == CurrColorIndex ||*/ (i == mGridPosY && x1 == mGridPosX)))
{
int r, g, b;
Color col;
double blinky;
if (i == mGridPosY && x1 == mGridPosX)
{
r = 255; g = 128; b = 0;
}
else
{
r = 200; g = 200; b = 255;
}
// Make sure the cursors stand out against similar colors
// by pulsing them.
blinky = abs(sin(MSTime()/1000.0)) * 0.5 + 0.5;
col = Color(255, int(r*blinky), int(g*blinky), int(b*blinky));
screen.Clear (box_x, box_y, box_x + w, box_y + 1, col);
screen.Clear (box_x, box_y + h-1, box_x + w, box_y + h, col);
screen.Clear (box_x, box_y, box_x + 1, box_y + h, col);
screen.Clear (box_x + w - 1, box_y, box_x + w, box_y + h, col);
}
box_x += w;
p++;
}
y += h;
}
y = yy;
color newColor = Color(255, int(mRed), int(mGreen), int(mBlue));
color oldColor = mCVar.GetInt() | 0xFF000000;
int x = screen.GetWidth()*2/3;
screen.Clear (x, y, x + 48*CleanXfac_1, y + 48*CleanYfac_1, oldColor);
screen.Clear (x + 48*CleanXfac_1, y, x + 48*2*CleanXfac_1, y + 48*CleanYfac_1, newColor);
y += 49*CleanYfac_1;
screen.DrawText (SmallFont, Font.CR_GRAY, x+(24-SmallFont.StringWidth("Old")/2)*CleanXfac_1, y, "Old", DTA_CleanNoMove_1, true);
screen.DrawText (SmallFont, Font.CR_WHITE, x+(48+24-SmallFont.StringWidth("New")/2)*CleanXfac_1, y, "New", DTA_CleanNoMove_1, true);
}
}

View file

@ -1,7 +1,63 @@
class Menu : Object native
{
enum EMenuKey
{
MKEY_Up,
MKEY_Down,
MKEY_Left,
MKEY_Right,
MKEY_PageUp,
MKEY_PageDown,
MKEY_Enter,
MKEY_Back,
MKEY_Clear,
NUM_MKEYS,
// These are not buttons but events sent from other menus
MKEY_Input,
MKEY_Abort,
MKEY_MBYes,
MKEY_MBNo,
}
enum EMenuMouse
{
MOUSE_Click,
MOUSE_Move,
MOUSE_Release
};
//native static int MenuTime();
native virtual bool MenuEvent (int mkey, bool fromcontroller);
native virtual bool MouseEvent(int type, int mx, int my);
native virtual void Drawer();
void MenuSound(Sound snd)
{
S_Sound (snd, CHAN_VOICE | CHAN_UI, snd_menuvolume, ATTN_NONE);
}
}
class MenuDescriptor : Object native
{
native Name mMenuName;
native String mNetgameMessage;
native Class<Menu> mClass;
}
class MenuItemBase : object native
{
native int mXpos, mYpos;
native Name mAction;
native bool mEnabled;
// making this virtual now would require exporting all classes at once.
native /*virtual*/ bool MenuEvent (int mkey, bool fromcontroller);
}
struct FOptionMenuSettings
@ -15,3 +71,45 @@ struct FOptionMenuSettings
int mFontColorSelection;
int mLinespacing;
}
class OptionMenuDescriptor : MenuDescriptor native
{
native Array<OptionMenuItem> mItems;
native String mTitle;
native int mSelectedItem;
native int mDrawTop;
native int mScrollTop;
native int mScrollPos;
native int mIndent;
native int mPosition;
native bool mDontDim;
//native void CalcIndent();
//native OptionMenuItem GetItem(Name iname);
void Reset()
{
// Reset the default settings (ignore all other values in the struct)
mPosition = 0;
mScrollTop = 0;
mIndent = 0;
mDontDim = 0;
}
}
class OptionMenuItem : MenuItemBase native
{
native String mLabel;
native bool mCentered;
//native void drawLabel(int indent, int y, EColorRange color, bool grayed = false);
}
class OptionMenu : Menu native
{
native bool CanScrollUp;
native bool CanScrollDown;
native int VisBottom;
native OptionMenuItem mFocusControl;
native OptionMenuDescriptor mDesc;
}