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