mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-12 08:11:10 +02:00
591 lines
16 KiB
C++
591 lines
16 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
Doom 3 GPL Source Code
|
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
|
|
|
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
|
|
|
|
Doom 3 Source Code is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Doom 3 Source Code is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
|
|
|
===========================================================================
|
|
*/
|
|
|
|
#ifndef __WINDOW_H__
|
|
#define __WINDOW_H__
|
|
|
|
#include "RegExp.h"
|
|
#include "Winvar.h"
|
|
#include "GuiScript.h"
|
|
#include "SimpleWindow.h"
|
|
|
|
const int WIN_CHILD = 0x00000001;
|
|
const int WIN_CAPTION = 0x00000002;
|
|
const int WIN_BORDER = 0x00000004;
|
|
const int WIN_SIZABLE = 0x00000008;
|
|
const int WIN_MOVABLE = 0x00000010;
|
|
const int WIN_FOCUS = 0x00000020;
|
|
const int WIN_CAPTURE = 0x00000040;
|
|
const int WIN_HCENTER = 0x00000080;
|
|
const int WIN_VCENTER = 0x00000100;
|
|
const int WIN_MODAL = 0x00000200;
|
|
const int WIN_INTRANSITION = 0x00000400;
|
|
const int WIN_CANFOCUS = 0x00000800;
|
|
const int WIN_SELECTED = 0x00001000;
|
|
const int WIN_TRANSFORM = 0x00002000;
|
|
const int WIN_HOLDCAPTURE = 0x00004000;
|
|
const int WIN_NOWRAP = 0x00008000;
|
|
const int WIN_NOCLIP = 0x00010000;
|
|
const int WIN_INVERTRECT = 0x00020000;
|
|
const int WIN_NATURALMAT = 0x00040000;
|
|
const int WIN_NOCURSOR = 0x00080000;
|
|
const int WIN_MENUGUI = 0x00100000;
|
|
const int WIN_ACTIVE = 0x00200000;
|
|
const int WIN_SHOWCOORDS = 0x00400000;
|
|
const int WIN_SHOWTIME = 0x00800000;
|
|
const int WIN_WANTENTER = 0x01000000;
|
|
#ifdef QUAKE4
|
|
const int WIN_ALWAYSTHINK = 0x08000000;
|
|
#endif
|
|
|
|
const int WIN_DESKTOP = 0x10000000;
|
|
#ifdef QUAKE4
|
|
const int WIN_CHATWINDOW = 0x20000000;
|
|
#endif
|
|
|
|
const char CAPTION_HEIGHT[] = "16.0";
|
|
const char SCROLLER_SIZE[] = "16.0";
|
|
const int SCROLLBAR_SIZE = 16;
|
|
|
|
const int MAX_WINDOW_NAME = 32;
|
|
const int MAX_LIST_ITEMS = 1024;
|
|
|
|
const char DEFAULT_BACKCOLOR[] = "1 1 1 1";
|
|
const char DEFAULT_FORECOLOR[] = "0 0 0 1";
|
|
const char DEFAULT_BORDERCOLOR[] = "0 0 0 1";
|
|
const char DEFAULT_TEXTSCALE[] = "0.4";
|
|
|
|
typedef enum {
|
|
WOP_TYPE_ADD,
|
|
WOP_TYPE_SUBTRACT,
|
|
WOP_TYPE_MULTIPLY,
|
|
WOP_TYPE_DIVIDE,
|
|
WOP_TYPE_MOD,
|
|
WOP_TYPE_TABLE,
|
|
WOP_TYPE_GT,
|
|
WOP_TYPE_GE,
|
|
WOP_TYPE_LT,
|
|
WOP_TYPE_LE,
|
|
WOP_TYPE_EQ,
|
|
WOP_TYPE_NE,
|
|
WOP_TYPE_AND,
|
|
WOP_TYPE_OR,
|
|
WOP_TYPE_VAR,
|
|
WOP_TYPE_VARS,
|
|
WOP_TYPE_VARF,
|
|
WOP_TYPE_VARI,
|
|
WOP_TYPE_VARB,
|
|
WOP_TYPE_COND
|
|
#ifdef QUAKE4
|
|
, WOP_TYPE_VARFM
|
|
#endif
|
|
} wexpOpType_t;
|
|
|
|
typedef enum {
|
|
WEXP_REG_TIME,
|
|
WEXP_REG_NUM_PREDEFINED
|
|
} wexpRegister_t;
|
|
|
|
typedef struct {
|
|
wexpOpType_t opType;
|
|
intptr_t a, b, c, d;
|
|
} wexpOp_t;
|
|
|
|
struct idRegEntry {
|
|
const char* name;
|
|
idRegister::REGTYPE type;
|
|
int index;
|
|
};
|
|
|
|
class rvGEWindowWrapper;
|
|
class idWindow;
|
|
|
|
struct idTimeLineEvent {
|
|
idTimeLineEvent() {
|
|
event = new idGuiScriptList;
|
|
}
|
|
~idTimeLineEvent() {
|
|
delete event;
|
|
}
|
|
int time;
|
|
idGuiScriptList* event;
|
|
bool pending;
|
|
size_t Size() {
|
|
return sizeof(*this) + event->Size();
|
|
}
|
|
};
|
|
|
|
class rvNamedEvent
|
|
{
|
|
public:
|
|
|
|
rvNamedEvent(const char* name)
|
|
{
|
|
mEvent = new idGuiScriptList;
|
|
mName = name;
|
|
}
|
|
~rvNamedEvent(void)
|
|
{
|
|
delete mEvent;
|
|
}
|
|
size_t Size()
|
|
{
|
|
return sizeof(*this) + mEvent->Size();
|
|
}
|
|
|
|
idStr mName;
|
|
idGuiScriptList* mEvent;
|
|
};
|
|
|
|
struct idTransitionData {
|
|
idWinVar* data;
|
|
int offset;
|
|
idInterpolateAccelDecelLinear<idVec4> interp;
|
|
};
|
|
|
|
|
|
class idUserInterfaceLocal;
|
|
class idWindow {
|
|
public:
|
|
idWindow(idUserInterfaceLocal* gui);
|
|
idWindow(idDeviceContext* d, idUserInterfaceLocal* gui);
|
|
virtual ~idWindow();
|
|
|
|
enum {
|
|
ON_MOUSEENTER = 0,
|
|
ON_MOUSEEXIT,
|
|
ON_ACTION,
|
|
#ifdef QUAKE4
|
|
ON_ACTIONRIGHT, // Q4 secondary / mouse2 action slot
|
|
#endif
|
|
ON_ACTIVATE,
|
|
ON_DEACTIVATE,
|
|
ON_ESC,
|
|
ON_FRAME,
|
|
ON_TRIGGER,
|
|
ON_ACTIONRELEASE,
|
|
ON_ENTER,
|
|
ON_ENTERRELEASE,
|
|
#ifdef QUAKE4
|
|
ON_ESCRELEASE, // reserved Q4 slot
|
|
ON_GAINFOCUS,
|
|
ON_LOSEFOCUS,
|
|
ON_RESERVED15, // reserved Q4 slot
|
|
ON_INIT,
|
|
ON_JOYBUTTON3,
|
|
ON_JOYACTION,
|
|
ON_JOYBACK,
|
|
ON_JOYLSHOULDER,
|
|
ON_JOYRSHOULDER,
|
|
ON_JOYLEFT,
|
|
ON_JOYRIGHT,
|
|
ON_JOYDOWN,
|
|
ON_JOYUP,
|
|
ON_JOYBUTTON1,
|
|
ON_JOYBUTTON2,
|
|
#endif
|
|
SCRIPT_COUNT
|
|
};
|
|
|
|
enum {
|
|
ADJUST_MOVE = 0,
|
|
ADJUST_TOP,
|
|
ADJUST_RIGHT,
|
|
ADJUST_BOTTOM,
|
|
ADJUST_LEFT,
|
|
ADJUST_TOPLEFT,
|
|
ADJUST_BOTTOMRIGHT,
|
|
ADJUST_TOPRIGHT,
|
|
ADJUST_BOTTOMLEFT
|
|
};
|
|
|
|
static const char* ScriptNames[SCRIPT_COUNT];
|
|
|
|
static const idRegEntry RegisterVars[];
|
|
static const int NumRegisterVars;
|
|
|
|
void SetDC(idDeviceContext* d);
|
|
|
|
idDeviceContext* GetDC(void) { return dc; }
|
|
|
|
idWindow* SetFocus(idWindow* w, bool scripts = true);
|
|
|
|
idWindow* SetCapture(idWindow* w);
|
|
void SetParent(idWindow* w);
|
|
void SetFlag(unsigned int f);
|
|
void ClearFlag(unsigned int f);
|
|
unsigned GetFlags() { return flags; };
|
|
void Move(float x, float y);
|
|
void BringToTop(idWindow* w);
|
|
void Adjust(float xd, float yd);
|
|
void SetAdjustMode(idWindow* child);
|
|
void Size(float x, float y, float w, float h);
|
|
void SetupFromState();
|
|
void SetupBackground();
|
|
drawWin_t* FindChildByName(const char* name);
|
|
idSimpleWindow* FindSimpleWinByName(const char* _name);
|
|
idWindow* GetParent() { return parent; }
|
|
idUserInterfaceLocal* GetGui() { return gui; };
|
|
bool Contains(float x, float y);
|
|
size_t Size();
|
|
virtual size_t Allocated();
|
|
idStr* GetStrPtrByName(const char* _name);
|
|
|
|
virtual idWinVar* GetWinVarByName(const char* _name, bool winLookup = false, drawWin_t** owner = NULL);
|
|
|
|
intptr_t GetWinVarOffset(idWinVar* wv, drawWin_t* dw);
|
|
float GetMaxCharHeight();
|
|
float GetMaxCharWidth();
|
|
void SetFont();
|
|
void SetInitialState(const char* _name);
|
|
void AddChild(idWindow* win);
|
|
void DebugDraw(int time, float x, float y);
|
|
void CalcClientRect(float xofs, float yofs);
|
|
void CommonInit();
|
|
void CleanUp();
|
|
void DrawBorderAndCaption(const idRectangle& drawRect);
|
|
void DrawCaption(int time, float x, float y);
|
|
void SetupTransforms(float x, float y);
|
|
bool Contains(const idRectangle& sr, float x, float y);
|
|
const char* GetName() { return name; };
|
|
|
|
virtual bool Parse(idParser* src, bool rebuild = true);
|
|
virtual const char* HandleEvent(const sysEvent_t* event, bool* updateVisuals);
|
|
void CalcRects(float x, float y);
|
|
virtual void Redraw(float x, float y);
|
|
|
|
virtual void ArchiveToDictionary(idDict* dict, bool useNames = true);
|
|
virtual void InitFromDictionary(idDict* dict, bool byName = true);
|
|
virtual void PostParse();
|
|
virtual void Activate(bool activate, idStr& act);
|
|
virtual void Trigger();
|
|
#ifdef QUAKE4
|
|
virtual void Init();
|
|
virtual bool RunControllerScript(int script, const sysEvent_t* event, bool* updateVisuals);
|
|
virtual bool RouteJoystickChange(int xd, int yd);
|
|
#endif
|
|
virtual void GainFocus();
|
|
virtual void LoseFocus();
|
|
virtual void GainCapture();
|
|
virtual void LoseCapture();
|
|
virtual void Sized();
|
|
virtual void Moved();
|
|
virtual void Draw(int time, float x, float y);
|
|
virtual void MouseExit();
|
|
virtual void MouseEnter();
|
|
virtual void DrawBackground(const idRectangle& drawRect);
|
|
virtual const char* RouteMouseCoords(float xd, float yd);
|
|
virtual void SetBuddy(idWindow* buddy) {};
|
|
virtual void HandleBuddyUpdate(idWindow* buddy) {};
|
|
virtual void StateChanged(bool redraw);
|
|
virtual void ReadFromDemoFile(class idDemoFile* f, bool rebuild = true);
|
|
virtual void WriteToDemoFile(class idDemoFile* f);
|
|
|
|
// SaveGame support
|
|
void WriteSaveGameString(const char* string, idFile* savefile);
|
|
void WriteSaveGameTransition(idTransitionData& trans, idFile* savefile);
|
|
virtual void WriteToSaveGame(idFile* savefile);
|
|
void ReadSaveGameString(idStr& string, idFile* savefile);
|
|
void ReadSaveGameTransition(idTransitionData& trans, idFile* savefile);
|
|
virtual void ReadFromSaveGame(idFile* savefile);
|
|
void FixupTransitions();
|
|
virtual void HasAction() {};
|
|
virtual void HasScripts() {};
|
|
|
|
void FixupParms();
|
|
void GetScriptString(const char* name, idStr& out);
|
|
void SetScriptParams();
|
|
bool HasOps() { return (ops.Num() > 0); };
|
|
float EvalRegs(int test = -1, bool force = false);
|
|
void StartTransition();
|
|
void AddTransition(idWinVar* dest, idVec4 from, idVec4 to, int time, float accelTime, float decelTime);
|
|
#ifdef QUAKE4
|
|
void ClearTransitions();
|
|
#endif
|
|
void ResetTime(int time);
|
|
void ResetCinematics();
|
|
#ifdef QUAKE4
|
|
bool IsVisible() const;
|
|
void SetWrapper(int wrapper);
|
|
#endif
|
|
|
|
int NumTransitions();
|
|
|
|
bool ParseScript(idParser* src, idGuiScriptList& list, int* timeParm = NULL, bool allowIf = false);
|
|
bool RunScript(int n);
|
|
bool RunScriptList(idGuiScriptList* src);
|
|
void SetRegs(const char* key, const char* val);
|
|
intptr_t ParseExpression(idParser* src, idWinVar* var = NULL, intptr_t component = 0);
|
|
int ExpressionConstant(float f);
|
|
idRegisterList* RegList() { return ®List; }
|
|
void AddCommand(const char* cmd);
|
|
void AddUpdateVar(idWinVar* var);
|
|
bool Interactive();
|
|
bool ContainsStateVars();
|
|
void SetChildWinVarVal(const char* name, const char* var, const char* val);
|
|
idWindow* GetFocusedChild();
|
|
idWindow* GetCaptureChild();
|
|
const char* GetComment() { return comment; }
|
|
void SetComment(const char* p) { comment = p; }
|
|
|
|
idStr cmd;
|
|
|
|
virtual void RunNamedEvent(const char* eventName);
|
|
|
|
void AddDefinedVar(idWinVar* var);
|
|
|
|
idWindow* FindChildByPoint(float x, float y, idWindow* below = NULL);
|
|
int GetChildIndex(idWindow* window);
|
|
int GetChildCount(void);
|
|
idWindow* GetChild(int index);
|
|
void RemoveChild(idWindow* win);
|
|
bool InsertChild(idWindow* win, idWindow* before);
|
|
|
|
void ScreenToClient(idRectangle* rect);
|
|
void ClientToScreen(idRectangle* rect);
|
|
|
|
bool UpdateFromDictionary(idDict& dict);
|
|
|
|
protected:
|
|
|
|
friend class rvGEWindowWrapper;
|
|
|
|
idWindow* FindChildByPoint(float x, float y, idWindow** below);
|
|
#ifdef QUAKE4
|
|
void FindBestChild_r(int xd, int yd, int& startX, int& startY, int& bestX, int& bestY, idWindow* current, idWindow*& best);
|
|
#endif
|
|
void SetDefaults(void);
|
|
|
|
friend class idSimpleWindow;
|
|
friend class idUserInterfaceLocal;
|
|
bool IsSimple();
|
|
void UpdateWinVars();
|
|
void DisableRegister(const char* _name);
|
|
void Transition();
|
|
void Time();
|
|
bool RunTimeEvents(int time);
|
|
void Dump();
|
|
|
|
int ExpressionTemporary();
|
|
wexpOp_t* ExpressionOp();
|
|
intptr_t EmitOp(intptr_t a, intptr_t b, wexpOpType_t opType, wexpOp_t** opp = NULL);
|
|
intptr_t ParseEmitOp(idParser* src, intptr_t a, wexpOpType_t opType, int priority, wexpOp_t** opp = NULL);
|
|
intptr_t ParseTerm(idParser* src, idWinVar* var = NULL, intptr_t component = 0);
|
|
intptr_t ParseExpressionPriority(idParser* src, int priority, idWinVar* var = NULL, intptr_t component = 0);
|
|
void EvaluateRegisters(float* registers);
|
|
void SaveExpressionParseState();
|
|
void RestoreExpressionParseState();
|
|
void ParseBracedExpression(idParser* src);
|
|
bool ParseScriptEntry(const char* name, idParser* src);
|
|
bool ParseRegEntry(const char* name, idParser* src);
|
|
virtual bool ParseInternalVar(const char* name, idParser* src);
|
|
void ParseString(idParser* src, idStr& out);
|
|
void ParseVec4(idParser* src, idVec4& out);
|
|
void ConvertRegEntry(const char* name, idParser* src, idStr& out, int tabs);
|
|
|
|
float actualX; // physical coords
|
|
float actualY; // ''
|
|
int childID; // this childs id
|
|
unsigned int flags; // visible, focus, mouseover, cursor, border, etc..
|
|
int lastTimeRun; //
|
|
idRectangle drawRect; // overall rect
|
|
idRectangle clientRect; // client area
|
|
idVec2 origin;
|
|
|
|
int timeLine; // time stamp used for various fx
|
|
float xOffset;
|
|
float yOffset;
|
|
float forceAspectWidth;
|
|
float forceAspectHeight;
|
|
float matScalex;
|
|
float matScaley;
|
|
float borderSize;
|
|
float textAlignx;
|
|
float textAligny;
|
|
idStr name;
|
|
idStr comment;
|
|
idVec2 shear;
|
|
|
|
signed char textShadow;
|
|
#ifdef QUAKE4
|
|
signed char textStyle;
|
|
#endif
|
|
unsigned char fontNum;
|
|
unsigned char cursor; //
|
|
signed char textAlign;
|
|
#ifdef QUAKE4
|
|
float textSpacing;
|
|
#endif
|
|
|
|
idWinBool noTime; //
|
|
idWinBool visible; //
|
|
idWinBool noEvents;
|
|
idWinRectangle rect; // overall rect
|
|
idWinVec4 backColor;
|
|
idWinVec4 matColor;
|
|
idWinVec4 foreColor;
|
|
idWinVec4 hoverColor;
|
|
idWinVec4 borderColor;
|
|
idWinFloat textScale;
|
|
idWinFloat rotate;
|
|
idWinStr text;
|
|
idWinBackground backGroundName; //
|
|
|
|
idList<idWinVar*> definedVars;
|
|
idList<idWinVar*> updateVars;
|
|
|
|
idRectangle textRect; // text extented rect
|
|
const idMaterial* background; // background asset
|
|
|
|
idWindow* parent; // parent window
|
|
idList<idWindow*> children; // child windows
|
|
idList<drawWin_t> drawWindows;
|
|
#ifdef QUAKE4
|
|
int startChildSearch; // Q4 child-lookup optimization
|
|
idWindow* currentChild; // controller navigation helper
|
|
#endif
|
|
|
|
idWindow* focusedChild; // if a child window has the focus
|
|
idWindow* captureChild; // if a child window has mouse capture
|
|
idWindow* overChild; // if a child window has mouse capture
|
|
bool hover;
|
|
|
|
idDeviceContext* dc;
|
|
|
|
idUserInterfaceLocal* gui;
|
|
|
|
static idCVar gui_debug;
|
|
static idCVar gui_edit;
|
|
|
|
idGuiScriptList* scripts[SCRIPT_COUNT];
|
|
bool* saveTemps;
|
|
|
|
idList<idTimeLineEvent*> timeLineEvents;
|
|
idList<idTransitionData> transitions;
|
|
#ifdef QUAKE4
|
|
idList<intptr_t> transitionSubs;
|
|
#endif
|
|
|
|
static bool registerIsTemporary[MAX_EXPRESSION_REGISTERS]; // statics to assist during parsing
|
|
|
|
idList<wexpOp_t> ops; // evaluate to make expressionRegisters
|
|
idList<float> expressionRegisters;
|
|
idList<wexpOp_t>* saveOps; // evaluate to make expressionRegisters
|
|
idList<rvNamedEvent*> namedEvents; // added named events
|
|
idList<float>* saveRegs;
|
|
|
|
idRegisterList regList;
|
|
|
|
idWinBool hideCursor;
|
|
};
|
|
|
|
ID_INLINE void idWindow::AddDefinedVar(idWinVar* var) {
|
|
definedVars.AddUnique(var);
|
|
}
|
|
|
|
|
|
#ifdef QUAKE4
|
|
// Quake 4 added synthetic float-member window vars so expressions / transitions
|
|
// can address rect_x, rect_y, forecolor_w, etc. Doom 3 does not ship one, so
|
|
// we keep the helper local to Window.cpp.
|
|
class idWinFloatMember : public idWinVar {
|
|
public:
|
|
idWinFloatMember() : owner(NULL), component(0) {}
|
|
idWinFloatMember(idWinVar* base, int index) : owner(base), component(index) {}
|
|
|
|
virtual void Init(const char* name, idWindow* win) {
|
|
idWinVar::Init(name, win);
|
|
}
|
|
virtual void Update() {
|
|
if (owner) {
|
|
owner->Update();
|
|
}
|
|
}
|
|
virtual void Set(const char* value) {
|
|
if (!owner) {
|
|
return;
|
|
}
|
|
float f = static_cast<float>(atof(value));
|
|
if (idWinVec4* v4 = dynamic_cast<idWinVec4*>(owner)) {
|
|
(*v4)[component] = f;
|
|
}
|
|
else if (idWinRectangle* r = dynamic_cast<idWinRectangle*>(owner)) {
|
|
switch (component) {
|
|
case 0: r->data.x = f; break;
|
|
case 1: r->data.y = f; break;
|
|
case 2: r->data.w = f; break;
|
|
case 3: r->data.h = f; break;
|
|
}
|
|
}
|
|
}
|
|
virtual const char* c_str() const {
|
|
return va("%g", x());
|
|
}
|
|
virtual float x() const {
|
|
if (!owner) {
|
|
return 0.0f;
|
|
}
|
|
if (const idWinVec4* v4 = dynamic_cast<const idWinVec4*>(owner)) {
|
|
return (*v4)[component];
|
|
}
|
|
if (const idWinRectangle* r = dynamic_cast<const idWinRectangle*>(owner)) {
|
|
switch (component) {
|
|
case 0: return r->data.x;
|
|
case 1: return r->data.y;
|
|
case 2: return r->data.w;
|
|
case 3: return r->data.h;
|
|
}
|
|
}
|
|
return 0.0f;
|
|
}
|
|
virtual void WriteToSaveGame(idFile* savefile) {
|
|
idWinFloat temp;
|
|
temp = x();
|
|
temp.WriteToSaveGame(savefile);
|
|
}
|
|
virtual void ReadFromSaveGame(idFile* savefile) {
|
|
idWinFloat temp;
|
|
temp.ReadFromSaveGame(savefile);
|
|
Set(va("%g", temp.data));
|
|
}
|
|
virtual size_t Size() {
|
|
return sizeof(*this);
|
|
}
|
|
|
|
idWinVar* GetOwner() const { return owner; }
|
|
int GetComponent() const { return component; }
|
|
|
|
private:
|
|
idWinVar* owner;
|
|
int component;
|
|
};
|
|
|
|
#endif // QUAKE4
|
|
|
|
|
|
#endif /* !__WINDOW_H__ */ |