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 697 : void writelog(FILE *file, const char *buf)
24 : {
25 : static std::array<uchar, logstrlen> ubuf;
26 697 : size_t len = std::strlen(buf),
27 697 : carry = 0;
28 1393 : while(carry < len)
29 : {
30 2088 : size_t numu = encodeutf8(ubuf.data(), ubuf.size() - 1, &(reinterpret_cast<const uchar*>(buf))[carry], len - carry, &carry);
31 696 : if(carry >= len)
32 : {
33 696 : ubuf[numu++] = '\n';
34 : }
35 696 : fwrite(ubuf.data(), 1, numu, file);
36 : }
37 697 : }
38 :
39 697 : void writelogv(FILE *file, const char *fmt, va_list args)
40 : {
41 : static std::array<char, logstrlen> buf;
42 1394 : vformatstring(buf.data(), fmt, args, buf.size());
43 697 : writelog(file, buf.data());
44 697 : }
45 :
46 : int clockrealbase = 0,
47 : clockvirtbase = 0;
48 :
49 0 : void clockreset()
50 : {
51 0 : clockrealbase = SDL_GetTicks();
52 0 : clockvirtbase = totalmillis;
53 0 : }
54 :
55 0 : VARFP(clockerror, 990000, 1000000, 1010000, clockreset()); //used by getclockmillis()
56 0 : VARFP(clockfix, 0, 0, 1, clockreset()); //whether to use clockerror, used by getclockmillis()
57 :
58 697 : void logoutfv(const char *fmt, va_list args, FILE *f)
59 : {
60 697 : if(f)
61 : {
62 697 : writelogv(f, fmt, args);
63 : }
64 697 : }
65 : }
66 :
67 : FILE *logfile = nullptr; //used in iengine.h
68 :
69 697 : FILE *getlogfile() //used in iengine.h
70 : {
71 : #ifdef WIN32
72 : return logfile;
73 : #else
74 697 : return logfile ? logfile : stdout;
75 : #endif
76 : }
77 :
78 : /**
79 : * @brief calls the SDL 2 init procedure
80 : *
81 : * returns false on failure, true on success
82 : * used in iengine.h
83 : */
84 0 : bool initsdl()
85 : {
86 0 : return (SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_GAMECONTROLLER) < 0 ? false : true);
87 : }
88 :
89 697 : void logoutf(const char *fmt, ...) //used in iengine.h
90 : {
91 : va_list args;
92 697 : va_start(args, fmt);
93 697 : logoutfv(fmt, args, getlogfile());
94 697 : va_end(args);
95 697 : }
96 :
97 : //error handling
98 :
99 0 : void fatal(const char *s, ...) // failure exit
100 : {
101 : static int errors = 0;
102 0 : errors++;
103 :
104 0 : if(errors <= 2) // print up to one extra recursive error
105 : {
106 0 : DEFV_FORMAT_STRING(msg,s,s);
107 0 : logoutf("%s", msg);
108 :
109 0 : if(errors <= 1) // avoid recursion
110 : {
111 0 : if(SDL_WasInit(SDL_INIT_VIDEO))
112 : {
113 0 : SDL_ShowCursor(SDL_TRUE);
114 0 : SDL_SetRelativeMouseMode(SDL_FALSE);
115 0 : if(screen)
116 : {
117 0 : SDL_SetWindowGrab(screen, SDL_FALSE);
118 : }
119 0 : cleargamma();
120 : }
121 0 : SDL_Quit();
122 0 : SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Libprimis engine fatal error", msg, nullptr);
123 : }
124 : }
125 :
126 0 : exit(EXIT_FAILURE);
127 : }
128 :
129 : //all four used in iengine
130 : int curtime = 0,
131 : lastmillis = 1,
132 : elapsedtime = 0,
133 : totalmillis = 1;
134 :
135 : //used in iengine
136 : dynent *player = nullptr;
137 :
138 : //used in iengine
139 : int initing = Init_Not;
140 :
141 1 : bool initwarning(const char *desc, int level, int type)
142 : {
143 1 : if(initing < level)
144 : {
145 1 : addchange(desc, type);
146 1 : return true;
147 : }
148 0 : return false;
149 : }
150 :
151 : //used in iengine
152 0 : int getclockmillis()
153 : {
154 0 : int millis = SDL_GetTicks() - clockrealbase;
155 0 : if(clockfix)
156 : {
157 0 : millis = static_cast<int>(millis*(static_cast<double>(clockerror)/1000000));
158 : }
159 0 : millis += clockvirtbase;
160 0 : return std::max(millis, totalmillis);
161 : }
162 :
163 : //identification info about engine
164 0 : std::string enginestr()
165 : {
166 0 : return "Libprimis v0.65a";
167 : }
168 :
169 0 : std::string enginebuilddate()
170 : {
171 0 : return __DATE__;
172 : }
|