1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <time.h>
5 #include <sys/time.h>
6 #include <SDL2/SDL.h>
7 #include <SDL2/SDL_platform.h>
8 #include <SDL2/SDL_rwops.h>
9 #include <SDL2/SDL_video.h>
10 #include <SDL2/SDL_audio.h>
11
12 #include <lua.h>
13 #include <lualib.h>
14 #include <lauxlib.h>
15
16 #include "system.h"
17 #include "console.h"
18 #include "gl_util.h"
19
20 #define INIT_TEMP_MEM_SIZE (4096 * 1024)
21
22 screen_info_t screen_info;
23
24 extern lua_State *engine_lua;
25
26 static uint8_t *engine_mem_buffer = NULL;
27 static size_t engine_mem_buffer_size = 0;
28 static size_t engine_mem_buffer_size_left = 0;
29
30 // =======================================================================
31 // General routines
32 // =======================================================================
33
Sys_Init()34 void Sys_Init()
35 {
36 engine_mem_buffer = (uint8_t*)malloc(INIT_TEMP_MEM_SIZE);
37 engine_mem_buffer_size = INIT_TEMP_MEM_SIZE;
38 engine_mem_buffer_size_left = INIT_TEMP_MEM_SIZE;
39 }
40
41
Sys_InitGlobals()42 void Sys_InitGlobals()
43 {
44 screen_info.x = 50;
45 screen_info.y = 20;
46 screen_info.w = 800;
47 screen_info.h = 600;
48 screen_info.debug_view_state = 0;
49 screen_info.fullscreen = 0;
50 screen_info.crosshair = 0;
51 screen_info.fov = 75.0;
52 screen_info.scale_factor = 1.0f;
53 screen_info.fps = 0.0f;
54 }
55
56
Sys_Destroy()57 void Sys_Destroy()
58 {
59 if(engine_mem_buffer)
60 {
61 free(engine_mem_buffer);
62 }
63 engine_mem_buffer = NULL;
64 engine_mem_buffer_size = 0;
65 engine_mem_buffer_size_left = 0;
66 }
67
68
Sys_GetTempMem(size_t size)69 void *Sys_GetTempMem(size_t size)
70 {
71 void *ret = NULL;
72
73 if(engine_mem_buffer_size_left >= size)
74 {
75 ret = engine_mem_buffer + engine_mem_buffer_size - engine_mem_buffer_size_left;
76 engine_mem_buffer_size_left -= size;
77 }
78 else
79 {
80 engine_mem_buffer_size_left = engine_mem_buffer_size; // glitch generator, but not crash
81 ret = engine_mem_buffer;
82 }
83
84 return ret;
85 }
86
87
Sys_ReturnTempMem(size_t size)88 void Sys_ReturnTempMem(size_t size)
89 {
90 if(engine_mem_buffer_size_left + size <= engine_mem_buffer_size)
91 {
92 engine_mem_buffer_size_left += size;
93 }
94 }
95
96
Sys_ResetTempMem()97 void Sys_ResetTempMem()
98 {
99 engine_mem_buffer_size_left = engine_mem_buffer_size;
100 }
101
102
103 /*
104 ===============================================================================
105 SYS TIME
106 ===============================================================================
107 */
Sys_FloatTime(void)108 float Sys_FloatTime (void)
109 {
110 struct timeval tp;
111 static long int secbase = 0;
112
113 gettimeofday(&tp, NULL);
114
115 if (!secbase)
116 {
117 secbase = tp.tv_sec;
118 return tp.tv_usec * 1.0e-6;
119 }
120
121 return (float)(tp.tv_sec - secbase) + (float)tp.tv_usec * 1.0e-6;
122 }
123
124
Sys_Strtime(char * buf,size_t buf_size)125 void Sys_Strtime(char *buf, size_t buf_size)
126 {
127 struct tm *tm_;
128 static time_t t_;
129
130 time(&t_);
131 tm_=gmtime(&t_);
132
133 snprintf(buf, buf_size, "%02d:%02d:%02d",tm_->tm_hour,tm_->tm_min,tm_->tm_sec);
134 }
135
136 /*
137 ===============================================================================
138 SYS PRINT FUNCTIONS
139 ===============================================================================
140 */
Sys_Error(const char * error,...)141 void Sys_Error(const char *error, ...)
142 {
143 va_list argptr;
144 char string[4096];
145
146 va_start (argptr,error);
147 vsnprintf (string, 4096, error, argptr);
148 va_end (argptr);
149
150 Sys_DebugLog(SYS_LOG_FILENAME, "System error: %s", string);
151 //Engine_Shutdown(1);
152 exit(1);
153 }
154
155
Sys_Warn(const char * warning,...)156 void Sys_Warn(const char *warning, ...)
157 {
158 va_list argptr;
159 char string[4096];
160
161 va_start (argptr, warning);
162 vsnprintf (string, 4096, warning, argptr);
163 va_end (argptr);
164 Sys_DebugLog(SYS_LOG_FILENAME, "Warning: %s", string);
165 Con_Warning("Warning: %s", string);
166 }
167
168
Sys_DebugLog(const char * file,const char * fmt,...)169 void Sys_DebugLog(const char *file, const char *fmt, ...)
170 {
171 va_list argptr;
172 static char data[4096];
173 int32_t written;
174
175 va_start(argptr, fmt);
176 written = vsnprintf(data, sizeof(data), fmt, argptr);
177 va_end(argptr);
178
179 if(written > 0)
180 {
181 SDL_RWops *fp;
182 // Add newline at end (if possible)
183 if((written + 1) < sizeof(data))
184 {
185 data[written + 0] = '\n';
186 data[written + 1] = 0;
187 written += 1;
188 }
189
190 fp = SDL_RWFromFile(file, "a");
191 if(fp == NULL)
192 {
193 fp = SDL_RWFromFile(file, "w");
194 }
195 if(fp != NULL)
196 {
197 SDL_RWwrite(fp, data, written, 1);
198 SDL_RWclose(fp);
199 }
200 fwrite(data, written, 1, stderr);
201 }
202 }
203
204
Sys_WriteTGAfile(const char * filename,const uint8_t * data,const int width,const int height,int bpp,char invY)205 void Sys_WriteTGAfile(const char *filename, const uint8_t *data, const int width, const int height, int bpp, char invY)
206 {
207 uint8_t c;
208 uint16_t s;
209 SDL_RWops *st;
210
211 st = SDL_RWFromFile(filename, "wb");
212 if(st)
213 {
214 // write the header
215 // id_length
216 c = 0;
217 SDL_RWwrite(st, &c, sizeof(c), 1);
218 // colormap_type
219 c = 0;
220 SDL_RWwrite(st, &c, sizeof(c), 1);
221 // image_type
222 c = 2;
223 SDL_RWwrite(st, &c, sizeof(c), 1);
224 // colormap_index
225 s = 0;
226 SDL_RWwrite(st, &s, sizeof(s), 1);
227 // colormap_length
228 s = 0;
229 SDL_RWwrite(st, &s, sizeof(s), 1);
230 // colormap_size
231 c = 0;
232 SDL_RWwrite(st, &c, sizeof(c), 1);
233 // x_origin
234 s = 0;
235 SDL_RWwrite(st, &s, sizeof(s), 1);
236 // y_origin
237 s = 0;
238 SDL_RWwrite(st, &s, sizeof(s), 1);
239 // width
240 s = SDL_SwapLE16(width);
241 SDL_RWwrite(st, &s, sizeof(s), 1);
242 // height
243 s = SDL_SwapLE16(height);
244 SDL_RWwrite(st, &s, sizeof(s), 1);
245 // bits_per_pixel
246 c = 0xFF & bpp;
247 SDL_RWwrite(st, &c, sizeof(c), 1);
248 // attributes
249 c = 0;
250 SDL_RWwrite(st, &c, sizeof(c), 1);
251
252 if(invY)
253 {
254 int y;
255 for (y = 0; y < height; y++)
256 {
257 SDL_RWwrite(st, &data[y * 4 * width], width * 4, 1);
258 }
259 }
260 else
261 {
262 int y;
263 for (y = height-1; y >= 0; y--)
264 {
265 SDL_RWwrite(st, &data[y * 4 * width], width * 4, 1);
266 }
267 }
268 SDL_RWclose(st);
269 }
270 }
271
272
Sys_TakeScreenShot()273 void Sys_TakeScreenShot()
274 {
275 static int screenshot_cnt = 0;
276 GLint ViewPort[4];
277 char fname[128];
278 GLubyte *pixels;
279 uint32_t str_size;
280
281 qglGetIntegerv(GL_VIEWPORT, ViewPort);
282 snprintf(fname, 128, "screen_%.5d.tga", screenshot_cnt);
283 str_size = ViewPort[2] * 4;
284 pixels = (GLubyte*)malloc(str_size * ViewPort[3]);
285 qglReadPixels(0, 0, ViewPort[2], ViewPort[3], GL_BGRA, GL_UNSIGNED_BYTE, pixels);
286 Sys_WriteTGAfile(fname, (const uint8_t*)pixels, ViewPort[2], ViewPort[3], 32, 1);
287
288 free(pixels);
289 screenshot_cnt++;
290 }
291
292
Sys_FileFound(const char * name,int checkWrite)293 int Sys_FileFound(const char *name, int checkWrite)
294 {
295 SDL_RWops *ff;
296
297 if(checkWrite)
298 {
299 ff = SDL_RWFromFile(name, "ab");
300 }
301 else
302 {
303 ff = SDL_RWFromFile(name, "rb");
304 }
305
306 if(ff)
307 {
308 SDL_RWclose(ff);
309 return 1;
310 }
311 return 0;
312 }
313