1 /*
2  * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
3  * It is copyright by its individual contributors, as recorded in the
4  * project's Git history.  See COPYING.txt at the top level for license
5  * terms and a link to the Git history.
6  */
7 /* Console */
8 
9 #pragma once
10 
11 #include <cstddef>
12 #include <cstring>
13 #include <type_traits>
14 #include "pstypes.h"
15 #include "dxxsconf.h"
16 #include "fmtcheck.h"
17 #include "d_srcloc.h"
18 #ifdef dsx
19 #include "kconfig.h"
20 #endif
21 
22 namespace dcx {
23 
24 /* Priority levels */
25 enum con_priority
26 {
27 	CON_CRITICAL = -3,
28 	CON_URGENT,
29 	CON_HUD,
30 	CON_NORMAL,
31 	CON_VERBOSE,
32 	CON_DEBUG
33 };
34 
35 constexpr std::integral_constant<std::size_t, 2048> CON_LINE_LENGTH{};
36 
37 struct console_buffer
38 {
39 	char line[CON_LINE_LENGTH];
40 	int priority;
41 };
42 
43 /* Define to 1 to capture the __FILE__, __LINE__ of callers to
44  * con_printf, con_puts, and show the captured value in `gamelog.txt`.
45  */
46 #ifndef DXX_CONSOLE_SHOW_FILE_LINE
47 #define DXX_CONSOLE_SHOW_FILE_LINE	0
48 #endif
49 
50 using con_priority_wrapper = location_value_wrapper<con_priority, DXX_CONSOLE_SHOW_FILE_LINE>;
51 
52 #undef DXX_CONSOLE_SHOW_FILE_LINE
53 
54 void con_init(void);
55 void con_puts(con_priority_wrapper level, char *str, size_t len) __attribute_nonnull();
56 void con_puts(con_priority_wrapper level, const char *str, size_t len) __attribute_nonnull();
57 
58 template <typename T>
con_puts(const con_priority_wrapper level,T && str)59 static inline void con_puts(const con_priority_wrapper level, T &&str)
60 {
61 	using rr = typename std::remove_reference<T>::type;
62 	constexpr std::size_t len = std::extent<rr>::value;
63 	con_puts(level, str, len && std::is_const<rr>::value ? len - 1 : strlen(str));
64 }
65 
66 void con_printf(con_priority_wrapper level, const char *fmt, ...) __attribute_format_printf(2, 3);
67 #ifdef DXX_CONSTANT_TRUE
68 #define DXX_CON_PRINTF_CHECK_TRAILING_NEWLINE(F)	\
69 	(DXX_CONSTANT_TRUE(sizeof((F)) > 1 && (F)[sizeof((F)) - 2] == '\n') &&	\
70 		(DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_trailing_newline, "trailing literal newline on con_printf"), 0)),
71 #else
72 #define DXX_CON_PRINTF_CHECK_TRAILING_NEWLINE(C)
73 #endif
74 #define con_printf(A1,F,...)	\
75 	DXX_CON_PRINTF_CHECK_TRAILING_NEWLINE(F)	\
76 	dxx_call_printf_checked(con_printf,con_puts,(A1),(F),##__VA_ARGS__)
77 
78 }
79 
80 #ifdef dsx
81 namespace dsx {
82 
83 void con_showup(control_info &Controls);
84 
85 }
86 #endif
87