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