1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19*/
20
21// Based on sys_linux.c
22
23#include <unistd.h>
24#include <signal.h>
25#include <stdlib.h>
26#include <limits.h>
27#include <sys/time.h>
28#include <sys/types.h>
29#include <unistd.h>
30#include <fcntl.h>
31#include <stdarg.h>
32#include <stdio.h>
33// #include <sys/ipc.h>
34// #include <sys/shm.h>
35#include <sys/stat.h>
36#include <string.h>
37#include <ctype.h>
38#include <sys/wait.h>
39#include <sys/mman.h>
40#include <errno.h>
41
42#include "quakedef.h"
43
44int noconinput = 0;
45int nostdout = 0;
46
47char *basedir = "/sdcard/data/quake";
48char *cachedir = "/tmp";
49
50cvar_t  sys_linerefresh = CVAR2("sys_linerefresh","0");// set for entity display
51
52// =======================================================================
53// General routines
54// =======================================================================
55
56void Sys_DebugNumber(int y, int val)
57{
58}
59
60/*
61void Sys_Printf (char *fmt, ...)
62{
63	va_list		argptr;
64	char		text[1024];
65
66	va_start (argptr,fmt);
67	vsprintf (text,fmt,argptr);
68	va_end (argptr);
69	fprintf(stderr, "%s", text);
70
71	Con_Print (text);
72}
73
74void Sys_Printf (char *fmt, ...)
75{
76
77    va_list     argptr;
78    char        text[1024], *t_p;
79    int         l, r;
80
81    if (nostdout)
82        return;
83
84    va_start (argptr,fmt);
85    vsprintf (text,fmt,argptr);
86    va_end (argptr);
87
88    l = strlen(text);
89    t_p = text;
90
91// make sure everything goes through, even though we are non-blocking
92    while (l)
93    {
94        r = write (1, text, l);
95        if (r != l)
96            sleep (0);
97        if (r > 0)
98        {
99            t_p += r;
100            l -= r;
101        }
102    }
103
104}
105*/
106
107void Sys_Printf (char *fmt, ...)
108{
109	va_list		argptr;
110	char		text[2048];
111	unsigned char		*p;
112
113	va_start (argptr,fmt);
114	vsprintf (text,fmt,argptr);
115	va_end (argptr);
116
117	if (strlen(text) > sizeof(text))
118		Sys_Error("memory overwrite in Sys_Printf");
119
120    if (nostdout)
121        return;
122
123	for (p = (unsigned char *)text; *p; p++)
124		if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9)
125			printf("[%02x]", *p);
126		else
127			putc(*p, stdout);
128}
129
130void Sys_Quit (void)
131{
132	Host_Shutdown();
133	printf("Sys_Quit - exiting.");
134    // fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
135	exit(0);
136}
137
138void Sys_Init(void)
139{
140#if id386
141	Sys_SetFPCW();
142#endif
143}
144
145void Sys_Error (char *error, ...)
146{
147    va_list     argptr;
148    char        string[1024];
149
150// change stdin to non blocking
151    // fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
152
153    va_start (argptr,error);
154    vsprintf (string,error,argptr);
155    va_end (argptr);
156	fprintf(stderr, "Error: %s\n", string);
157
158	Host_Shutdown ();
159	printf("Sys_Error - exiting.");
160	exit (1);
161
162}
163
164void Sys_Warn (char *warning, ...)
165{
166    va_list     argptr;
167    char        string[1024];
168
169    va_start (argptr,warning);
170    vsprintf (string,warning,argptr);
171    va_end (argptr);
172	fprintf(stderr, "Warning: %s", string);
173}
174
175/*
176============
177Sys_FileTime
178
179returns -1 if not present
180============
181*/
182int	Sys_FileTime (char *path)
183{
184	struct	stat	buf;
185
186	if (stat (path,&buf) == -1)
187		return -1;
188
189	return buf.st_mtime;
190}
191
192
193void Sys_mkdir (char *path)
194{
195    mkdir (path, 0777);
196}
197
198int Sys_FileOpenRead (char *path, int *handle)
199{
200	int	h;
201	struct stat	fileinfo;
202
203
204	h = open (path, O_RDONLY, 0666);
205	*handle = h;
206	if (h == -1)
207		return -1;
208
209	if (fstat (h,&fileinfo) == -1)
210		Sys_Error ("Error fstating %s", path);
211
212	return fileinfo.st_size;
213}
214
215int Sys_FileOpenWrite (char *path)
216{
217	int     handle;
218
219	umask (0);
220
221	handle = open(path,O_RDWR | O_CREAT | O_TRUNC
222	, 0666);
223
224	if (handle == -1)
225		Sys_Error ("Error opening %s: %s", path,strerror(errno));
226
227	return handle;
228}
229
230int Sys_FileWrite (int handle, void *src, int count)
231{
232	return write (handle, src, count);
233}
234
235void Sys_FileClose (int handle)
236{
237	close (handle);
238}
239
240void Sys_FileSeek (int handle, int position)
241{
242	lseek (handle, position, SEEK_SET);
243}
244
245int Sys_FileRead (int handle, void *dest, int count)
246{
247    return read (handle, dest, count);
248}
249
250void Sys_DebugLog(char *file, char *fmt, ...)
251{
252    va_list argptr;
253    static char data[1024];
254    int fd;
255
256    va_start(argptr, fmt);
257    vsprintf(data, fmt, argptr);
258    va_end(argptr);
259//    fd = open(file, O_WRONLY | O_BINARY | O_CREAT | O_APPEND, 0666);
260    fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666);
261    write(fd, data, strlen(data));
262    close(fd);
263}
264
265void Sys_EditFile(char *filename)
266{
267
268	char cmd[256];
269	char *term;
270	char *editor;
271
272	term = getenv("TERM");
273	if (term && !strcmp(term, "xterm"))
274	{
275		editor = getenv("VISUAL");
276		if (!editor)
277			editor = getenv("EDITOR");
278		if (!editor)
279			editor = getenv("EDIT");
280		if (!editor)
281			editor = "vi";
282		sprintf(cmd, "xterm -e %s %s", editor, filename);
283		system(cmd);
284	}
285
286}
287
288double Sys_DoubleTime (void)
289{
290    struct timeval tp;
291    struct timezone tzp;
292    static int      secbase;
293
294    gettimeofday(&tp, &tzp);
295
296    if (!secbase)
297    {
298        secbase = tp.tv_sec;
299        return tp.tv_usec/1000000.0;
300    }
301
302    return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
303}
304
305// =======================================================================
306// Sleeps for microseconds
307// =======================================================================
308
309static volatile int oktogo;
310
311void alarm_handler(int x)
312{
313	oktogo=1;
314}
315
316void Sys_LineRefresh(void)
317{
318}
319
320void floating_point_exception_handler(int whatever)
321{
322//	Sys_Warn("floating point exception\n");
323	signal(SIGFPE, floating_point_exception_handler);
324}
325
326char *Sys_ConsoleInput(void)
327{
328#if 0
329    static char text[256];
330    int     len;
331
332	if (cls.state == ca_dedicated) {
333		len = read (0, text, sizeof(text));
334		if (len < 1)
335			return NULL;
336		text[len-1] = 0;    // rip off the /n and terminate
337
338		return text;
339	}
340#endif
341	return NULL;
342}
343
344#if !id386
345void Sys_HighFPPrecision (void)
346{
347}
348
349void Sys_LowFPPrecision (void)
350{
351}
352#endif
353
354int		skipframes;
355
356// The following APIs are called from the Java activity
357
358int gAndroidQuitting = 0;
359
360double g_oldtime;
361
362extern int scr_width;
363extern int scr_height;
364
365void AndroidInit(int width, int height)
366{
367	quakeparms_t parms;
368	int j;
369	int c = 0;
370	char* v[] = {"quake", (char*) 0};
371
372	scr_width = width;
373	scr_height = height;
374
375//	static char cwd[1024];
376
377//	signal(SIGFPE, floating_point_exception_handler);
378//  signal(SIGFPE, SIG_IGN);
379
380	memset(&parms, 0, sizeof(parms));
381
382	COM_InitArgv(c, v);
383	parms.argc = com_argc;
384	parms.argv = com_argv;
385
386	parms.memsize = 16*1024*1024;
387
388	j = COM_CheckParm("-mem");
389	if (j)
390		parms.memsize = (int) (Q_atof(com_argv[j+1]) * 1024 * 1024);
391	parms.membase = malloc (parms.memsize);
392
393	parms.basedir = basedir;
394// caching is disabled by default, use -cachedir to enable
395//	parms.cachedir = cachedir;
396
397#if 0 // FNDELAY not implemented
398	noconinput = COM_CheckParm("-noconinput");
399	if (!noconinput)
400		fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
401#endif
402
403	if (COM_CheckParm("-nostdout"))
404		nostdout = 1;
405
406	Sys_Init();
407
408    Host_Init(&parms);
409
410    g_oldtime = Sys_DoubleTime ();
411}
412
413void AndroidStep()
414{
415	double time, newtime;
416	// find time spent rendering last frame
417	newtime = Sys_DoubleTime ();
418	time = newtime - g_oldtime;
419
420	Host_Frame(time);
421	g_oldtime = newtime;
422}
423
424int AndroidQuiting()
425{
426	return gAndroidQuitting;
427}
428