]> git.xonotic.org Git - xonotic/darkplaces.git/blob - sys_sdl.c
Remove Con_Warnf and Errorf. Use macros to change color and identify the message
[xonotic/darkplaces.git] / sys_sdl.c
1
2 #ifdef WIN32
3 #include <io.h>
4 #include "conio.h"
5 #else
6 #include <unistd.h>
7 #include <fcntl.h>
8 #include <sys/time.h>
9 #endif
10
11 #ifdef __ANDROID__
12 #include <android/log.h>
13
14 #ifndef FNDELAY
15 #define FNDELAY         O_NDELAY
16 #endif
17 #endif
18
19 #include <signal.h>
20
21 #include <SDL.h>
22
23 #ifdef WIN32
24 #ifdef _MSC_VER
25 #pragma comment(lib, "sdl2.lib")
26 #pragma comment(lib, "sdl2main.lib")
27 #endif
28 #endif
29
30 #include "quakedef.h"
31
32 sys_t sys;
33
34 // =======================================================================
35 // General routines
36 // =======================================================================
37
38 void Sys_Shutdown (void)
39 {
40 #ifdef __ANDROID__
41         Sys_AllowProfiling(false);
42 #endif
43 #ifndef WIN32
44         fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
45 #endif
46         fflush(stdout);
47         SDL_Quit();
48 }
49
50 static qboolean nocrashdialog;
51 void Sys_Error (const char *error, ...)
52 {
53         va_list argptr;
54         char string[MAX_INPUTLINE];
55
56 // change stdin to non blocking
57 #ifndef WIN32
58         fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
59 #endif
60
61         va_start (argptr,error);
62         dpvsnprintf (string, sizeof (string), error, argptr);
63         va_end (argptr);
64
65         Con_Printf(CON_ERROR "Engine Error: %s\n", string);
66         
67         if(!nocrashdialog)
68                 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Engine Error", string, NULL);
69
70         Host_Shutdown ();
71         exit (1);
72 }
73
74 void Sys_PrintToTerminal(const char *text)
75 {
76 #ifdef __ANDROID__
77         if (developer.integer > 0)
78         {
79                 __android_log_write(ANDROID_LOG_DEBUG, sys.argv[0], text);
80         }
81 #else
82         if(sys.outfd < 0)
83                 return;
84 #ifdef FNDELAY
85         // BUG: for some reason, NDELAY also affects stdout (1) when used on stdin (0).
86         // this is because both go to /dev/tty by default!
87         {
88                 int origflags = fcntl (sys.outfd, F_GETFL, 0);
89                 fcntl (sys.outfd, F_SETFL, origflags & ~FNDELAY);
90 #endif
91 #ifdef WIN32
92 #define write _write
93 #endif
94                 while(*text)
95                 {
96                         fs_offset_t written = (fs_offset_t)write(sys.outfd, text, (int)strlen(text));
97                         if(written <= 0)
98                                 break; // sorry, I cannot do anything about this error - without an output
99                         text += written;
100                 }
101 #ifdef FNDELAY
102                 fcntl (sys.outfd, F_SETFL, origflags);
103         }
104 #endif
105         //fprintf(stdout, "%s", text);
106 #endif
107 }
108
109 char *Sys_ConsoleInput(void)
110 {
111 //      if (cls.state == ca_dedicated)
112         {
113                 static char text[MAX_INPUTLINE];
114                 int len = 0;
115 #ifdef WIN32
116                 int c;
117
118                 // read a line out
119                 while (_kbhit ())
120                 {
121                         c = _getch ();
122                         _putch (c);
123                         if (c == '\r')
124                         {
125                                 text[len] = 0;
126                                 _putch ('\n');
127                                 len = 0;
128                                 return text;
129                         }
130                         if (c == 8)
131                         {
132                                 if (len)
133                                 {
134                                         _putch (' ');
135                                         _putch (c);
136                                         len--;
137                                         text[len] = 0;
138                                 }
139                                 continue;
140                         }
141                         text[len] = c;
142                         len++;
143                         text[len] = 0;
144                         if (len == sizeof (text))
145                                 len = 0;
146                 }
147 #else
148                 fd_set fdset;
149                 struct timeval timeout;
150                 FD_ZERO(&fdset);
151                 FD_SET(0, &fdset); // stdin
152                 timeout.tv_sec = 0;
153                 timeout.tv_usec = 0;
154                 if (select (1, &fdset, NULL, NULL, &timeout) != -1 && FD_ISSET(0, &fdset))
155                 {
156                         len = read (0, text, sizeof(text));
157                         if (len >= 1)
158                         {
159                                 // rip off the \n and terminate
160                                 text[len-1] = 0;
161                                 return text;
162                         }
163                 }
164 #endif
165         }
166         return NULL;
167 }
168
169 char *Sys_GetClipboardData (void)
170 {
171         char *data = NULL;
172         char *cliptext;
173
174         cliptext = SDL_GetClipboardText();
175         if (cliptext != NULL) {
176                 size_t allocsize;
177                 allocsize = min(MAX_INPUTLINE, strlen(cliptext) + 1);
178                 data = (char *)Z_Malloc (allocsize);
179                 strlcpy (data, cliptext, allocsize);
180                 SDL_free(cliptext);
181         }
182
183         return data;
184 }
185
186 void Sys_InitConsole (void)
187 {
188 }
189
190 int main (int argc, char *argv[])
191 {
192         signal(SIGFPE, SIG_IGN);
193
194 #ifdef __ANDROID__
195         Sys_AllowProfiling(true);
196 #endif
197
198         sys.selffd = -1;
199         sys.argc = argc;
200         sys.argv = (const char **)argv;
201
202         // Sys_Error this early in startup might screw with automated
203         // workflows or something if we show the dialog by default.
204         nocrashdialog = true;
205
206         Sys_ProvideSelfFD();
207
208         // COMMANDLINEOPTION: -nocrashdialog disables "Engine Error" crash dialog boxes
209         if(!COM_CheckParm("-nocrashdialog"))
210                 nocrashdialog = false;
211         // COMMANDLINEOPTION: sdl: -noterminal disables console output on stdout
212         if(COM_CheckParm("-noterminal"))
213                 sys.outfd = -1;
214         // COMMANDLINEOPTION: sdl: -stderr moves console output to stderr
215         else if(COM_CheckParm("-stderr"))
216                 sys.outfd = 2;
217         else
218                 sys.outfd = 1;
219
220 #ifndef WIN32
221         fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
222 #endif
223
224         // we don't know which systems we'll want to init, yet...
225         SDL_Init(0);
226
227         Host_Main();
228
229         return 0;
230 }
231
232 qboolean sys_supportsdlgetticks = true;
233 unsigned int Sys_SDL_GetTicks (void)
234 {
235         return SDL_GetTicks();
236 }
237 void Sys_SDL_Delay (unsigned int milliseconds)
238 {
239         SDL_Delay(milliseconds);
240 }