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