Line data Source code
1 : /**
2 : * @file control.cpp
3 : * @brief misc engine utilities for program control
4 : *
5 : * control.cpp defines a handful of useful utilities for creating a useful program
6 : * using the library, including logging (to file), program crash handling, engine
7 : * timestate information, and engine version information
8 : */
9 : #include "../libprimis-headers/cube.h"
10 : #include "../../shared/stream.h"
11 :
12 : #include "console.h"
13 : #include "control.h"
14 : #include "menus.h"
15 :
16 : #include "render/renderwindow.h"
17 :
18 : namespace
19 : {
20 : // logging
21 : constexpr int logstrlen = 512;
22 :
23 : /**
24 : * @brief Writes the specified string to the specified file.
25 : *
26 : * @param file the file to write to
27 : * @param buf string to write to file
28 : */
29 695 : void writelog(FILE *file, const char *buf)
30 : {
31 : static std::array<uchar, logstrlen> ubuf;
32 695 : size_t len = std::strlen(buf),
33 695 : carry = 0;
34 1389 : while(carry < len)
35 : {
36 2082 : size_t numu = encodeutf8(ubuf.data(), ubuf.size() - 1, &(reinterpret_cast<const uchar*>(buf))[carry], len - carry, &carry);
37 694 : if(carry >= len)
38 : {
39 694 : ubuf[numu++] = '\n';
40 : }
41 694 : fwrite(ubuf.data(), 1, numu, file);
42 : }
43 695 : }
44 :
45 : /**
46 : * @brief Writes the formatted string to the specified file.
47 : *
48 : * Assumes that the file exists.
49 : *
50 : * @param file file to write to
51 : * @param fmt string containing printf-style formatting
52 : * @param args variadic arguments to use in printf fmt string
53 : */
54 695 : void writelogv(FILE *file, const char *fmt, va_list args)
55 : {
56 : static std::array<char, logstrlen> buf;
57 1390 : vformatstring(buf.data(), fmt, args, buf.size());
58 695 : writelog(file, buf.data());
59 695 : }
60 :
61 : int clockrealbase = 0,
62 : clockvirtbase = 0;
63 :
64 0 : void clockreset()
65 : {
66 0 : clockrealbase = SDL_GetTicks();
67 0 : clockvirtbase = totalmillis;
68 0 : }
69 :
70 0 : VARFP(clockerror, 990000, 1000000, 1010000, clockreset()); //used by getclockmillis()
71 0 : VARFP(clockfix, 0, 0, 1, clockreset()); //whether to use clockerror, used by getclockmillis()
72 :
73 : /**
74 : * @brief Writes the formatted string to the specified file.
75 : *
76 : * Checks whether the file exists. If it does not, no action is performed.
77 : *
78 : * @param file file to write to
79 : * @param fmt string containing printf-style formatting
80 : * @param args variadic arguments to use in printf fmt string
81 : */
82 695 : void logoutfv(const char *fmt, va_list args, FILE *f)
83 : {
84 695 : if(f)
85 : {
86 695 : writelogv(f, fmt, args);
87 : }
88 695 : }
89 : }
90 :
91 : FILE *logfile = nullptr; //used in iengine.h
92 :
93 695 : FILE *getlogfile() //used in iengine.h
94 : {
95 : #ifdef WIN32
96 : return logfile;
97 : #else
98 695 : return logfile ? logfile : stdout;
99 : #endif
100 : }
101 :
102 : /**
103 : * @brief calls the SDL 2 init procedure
104 : *
105 : * returns false on failure, true on success
106 : * used in iengine.h
107 : *
108 : * @return true if SDL inited, false otherwise
109 : */
110 0 : bool initsdl()
111 : {
112 0 : return (SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_GAMECONTROLLER) < 0 ? false : true);
113 : }
114 :
115 695 : void logoutf(const char *fmt, ...) //used in iengine.h
116 : {
117 : va_list args;
118 695 : va_start(args, fmt);
119 695 : logoutfv(fmt, args, getlogfile());
120 695 : va_end(args);
121 695 : }
122 :
123 : //error handling
124 :
125 0 : void fatal(const char *s, ...) // failure exit
126 : {
127 : static int errors = 0;
128 0 : errors++;
129 :
130 0 : if(errors <= 2) // print up to one extra recursive error
131 : {
132 0 : DEFV_FORMAT_STRING(msg,s,s);
133 0 : logoutf("%s", msg);
134 :
135 0 : if(errors <= 1) // avoid recursion
136 : {
137 0 : if(SDL_WasInit(SDL_INIT_VIDEO))
138 : {
139 0 : SDL_ShowCursor(SDL_TRUE);
140 0 : SDL_SetRelativeMouseMode(SDL_FALSE);
141 0 : if(screen)
142 : {
143 0 : SDL_SetWindowGrab(screen, SDL_FALSE);
144 : }
145 0 : cleargamma();
146 : }
147 0 : SDL_Quit();
148 0 : SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Libprimis engine fatal error", msg, nullptr);
149 : }
150 : }
151 :
152 0 : exit(EXIT_FAILURE);
153 : }
154 :
155 : //all four used in iengine
156 : int curtime = 0,
157 : lastmillis = 1,
158 : elapsedtime = 0,
159 : totalmillis = 1;
160 :
161 : //used in iengine
162 : dynent *player = nullptr;
163 :
164 : //used in iengine
165 : int initing = Init_Not;
166 :
167 1 : bool initwarning(const char *desc, int level, int type)
168 : {
169 1 : if(initing < level)
170 : {
171 1 : addchange(desc, type);
172 1 : return true;
173 : }
174 0 : return false;
175 : }
176 :
177 : //used in iengine
178 0 : int getclockmillis()
179 : {
180 0 : int millis = SDL_GetTicks() - clockrealbase;
181 0 : if(clockfix)
182 : {
183 0 : millis = static_cast<int>(millis*(static_cast<double>(clockerror)/1000000));
184 : }
185 0 : millis += clockvirtbase;
186 0 : return std::max(millis, totalmillis);
187 : }
188 :
189 : //identification info about engine
190 0 : std::string enginestr()
191 : {
192 0 : return "Libprimis v0.69a";
193 : }
194 :
195 0 : std::string enginebuilddate()
196 : {
197 0 : return __DATE__;
198 : }
|