1 | /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ |
2 | /* If you are missing that file, acquire a complete release at teeworlds.com. */ |
3 | #ifndef GAME_CLIENT_COMPONENTS_CONSOLE_H |
4 | #define GAME_CLIENT_COMPONENTS_CONSOLE_H |
5 | |
6 | #include <base/lock.h> |
7 | |
8 | #include <engine/console.h> |
9 | #include <engine/shared/ringbuffer.h> |
10 | |
11 | #include <game/client/component.h> |
12 | #include <game/client/lineinput.h> |
13 | |
14 | enum |
15 | { |
16 | CONSOLE_CLOSED, |
17 | CONSOLE_OPENING, |
18 | CONSOLE_OPEN, |
19 | CONSOLE_CLOSING, |
20 | }; |
21 | |
22 | class CConsoleLogger; |
23 | |
24 | class CGameConsole : public CComponent |
25 | { |
26 | friend class CConsoleLogger; |
27 | class CInstance |
28 | { |
29 | public: |
30 | struct CBacklogEntry |
31 | { |
32 | float m_YOffset; |
33 | int m_LineCount; |
34 | ColorRGBA m_PrintColor; |
35 | size_t m_Length; |
36 | char m_aText[1]; |
37 | }; |
38 | CStaticRingBuffer<CBacklogEntry, 1024 * 1024, CRingBufferBase::FLAG_RECYCLE> m_Backlog; |
39 | CLock m_BacklogPendingLock; |
40 | CStaticRingBuffer<CBacklogEntry, 1024 * 1024, CRingBufferBase::FLAG_RECYCLE> m_BacklogPending GUARDED_BY(m_BacklogPendingLock); |
41 | CStaticRingBuffer<char, 64 * 1024, CRingBufferBase::FLAG_RECYCLE> m_History; |
42 | char *m_pHistoryEntry; |
43 | |
44 | CLineInputBuffered<IConsole::CMDLINE_LENGTH> m_Input; |
45 | const char *m_pName; |
46 | int m_Type; |
47 | int m_BacklogCurLine; |
48 | int m_BacklogLastActiveLine = -1; |
49 | int m_LinesRendered; |
50 | |
51 | STextBoundingBox m_BoundingBox = {.m_X: 0.0f, .m_Y: 0.0f, .m_W: 0.0f, .m_H: 0.0f}; |
52 | float m_LastInputHeight = 0.0f; |
53 | |
54 | bool m_MouseIsPress = false; |
55 | vec2 m_MousePress = vec2(0.0f, 0.0f); |
56 | vec2 m_MouseRelease = vec2(0.0f, 0.0f); |
57 | int m_CurSelStart = 0; |
58 | int m_CurSelEnd = 0; |
59 | bool m_HasSelection = false; |
60 | int m_NewLineCounter = 0; |
61 | |
62 | CGameConsole *m_pGameConsole; |
63 | |
64 | char m_aCompletionBuffer[IConsole::CMDLINE_LENGTH]; |
65 | int m_CompletionChosen; |
66 | char m_aCompletionBufferArgument[IConsole::CMDLINE_LENGTH]; |
67 | int m_CompletionChosenArgument; |
68 | int m_CompletionFlagmask; |
69 | float m_CompletionRenderOffset; |
70 | float m_CompletionRenderOffsetChange; |
71 | int m_CompletionArgumentPosition; |
72 | |
73 | char m_aUser[32]; |
74 | bool m_UserGot; |
75 | bool m_UsernameReq; |
76 | |
77 | bool m_IsCommand; |
78 | const char *m_pCommandName; |
79 | const char *m_pCommandHelp; |
80 | const char *m_pCommandParams; |
81 | |
82 | bool m_Searching = false; |
83 | struct SSearchMatch |
84 | { |
85 | int m_Pos; |
86 | int m_StartLine; |
87 | int m_EndLine; |
88 | int m_EntryLine; |
89 | |
90 | SSearchMatch(int Pos, int StartLine, int EndLine, int EntryLine) : |
91 | m_Pos(Pos), m_StartLine(StartLine), m_EndLine(EndLine), m_EntryLine(EntryLine) {} |
92 | }; |
93 | int m_CurrentMatchIndex; |
94 | char m_aCurrentSearchString[IConsole::CMDLINE_LENGTH]; |
95 | std::vector<SSearchMatch> m_vSearchMatches; |
96 | |
97 | CInstance(int t); |
98 | void Init(CGameConsole *pGameConsole); |
99 | |
100 | void ClearBacklog() REQUIRES(!m_BacklogPendingLock); |
101 | void UpdateBacklogTextAttributes(); |
102 | void PumpBacklogPending() REQUIRES(!m_BacklogPendingLock); |
103 | void ClearHistory(); |
104 | void Reset(); |
105 | |
106 | void ExecuteLine(const char *pLine); |
107 | |
108 | bool OnInput(const IInput::CEvent &Event); |
109 | void PrintLine(const char *pLine, int Len, ColorRGBA PrintColor) REQUIRES(!m_BacklogPendingLock); |
110 | int GetLinesToScroll(int Direction, int LinesToScroll); |
111 | void ScrollToCenter(int StartLine, int EndLine); |
112 | void ClearSearch(); |
113 | void Dump() REQUIRES(!m_BacklogPendingLock); |
114 | |
115 | const char *GetString() const { return m_Input.GetString(); } |
116 | static void PossibleCommandsCompleteCallback(int Index, const char *pStr, void *pUser); |
117 | static void PossibleArgumentsCompleteCallback(int Index, const char *pStr, void *pUser); |
118 | |
119 | void UpdateEntryTextAttributes(CBacklogEntry *pEntry) const; |
120 | |
121 | private: |
122 | void UpdateSearch(); |
123 | |
124 | friend class CGameConsole; |
125 | }; |
126 | |
127 | class IConsole *m_pConsole; |
128 | CConsoleLogger *m_pConsoleLogger = nullptr; |
129 | |
130 | CInstance m_LocalConsole; |
131 | CInstance m_RemoteConsole; |
132 | |
133 | CInstance *CurrentConsole(); |
134 | |
135 | int m_ConsoleType; |
136 | int m_ConsoleState; |
137 | float m_StateChangeEnd; |
138 | float m_StateChangeDuration; |
139 | |
140 | bool m_WantsSelectionCopy = false; |
141 | |
142 | static const ColorRGBA ms_SearchHighlightColor; |
143 | static const ColorRGBA ms_SearchSelectedColor; |
144 | |
145 | void Toggle(int Type); |
146 | |
147 | static void PossibleCommandsRenderCallback(int Index, const char *pStr, void *pUser); |
148 | static void ConToggleLocalConsole(IConsole::IResult *pResult, void *pUserData); |
149 | static void ConToggleRemoteConsole(IConsole::IResult *pResult, void *pUserData); |
150 | static void ConClearLocalConsole(IConsole::IResult *pResult, void *pUserData); |
151 | static void ConClearRemoteConsole(IConsole::IResult *pResult, void *pUserData); |
152 | static void ConDumpLocalConsole(IConsole::IResult *pResult, void *pUserData); |
153 | static void ConDumpRemoteConsole(IConsole::IResult *pResult, void *pUserData); |
154 | static void ConConsolePageUp(IConsole::IResult *pResult, void *pUserData); |
155 | static void ConConsolePageDown(IConsole::IResult *pResult, void *pUserData); |
156 | static void ConchainConsoleOutputLevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); |
157 | |
158 | public: |
159 | enum |
160 | { |
161 | CONSOLETYPE_LOCAL = 0, |
162 | CONSOLETYPE_REMOTE, |
163 | }; |
164 | |
165 | CGameConsole(); |
166 | ~CGameConsole(); |
167 | virtual int Sizeof() const override { return sizeof(*this); } |
168 | |
169 | void PrintLine(int Type, const char *pLine); |
170 | void RequireUsername(bool UsernameReq); |
171 | |
172 | virtual void OnStateChange(int NewState, int OldState) override; |
173 | virtual void OnConsoleInit() override; |
174 | virtual void OnInit() override; |
175 | virtual void OnReset() override; |
176 | virtual void OnRender() override; |
177 | virtual void OnMessage(int MsgType, void *pRawMsg) override; |
178 | virtual bool OnInput(const IInput::CEvent &Event) override; |
179 | void Prompt(char (&aPrompt)[32]); |
180 | |
181 | bool IsClosed() { return m_ConsoleState == CONSOLE_CLOSED; } |
182 | }; |
183 | #endif |
184 | |