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