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// sys_sun.h -- Sun system driver
21
22#include "quakedef.h"
23#include "errno.h"
24#include <sys/types.h>
25#include <sys/time.h>
26#include <sys/stat.h>
27#include <sys/mman.h>
28#include <sys/param.h>
29#include <fcntl.h>
30#include <stddef.h>
31#include <sys/types.h>
32#include <fcntl.h>
33#include <sys/mman.h>
34#include <stdio.h>
35
36qboolean			isDedicated;
37
38/*
39===============================================================================
40
41FILE IO
42
43===============================================================================
44*/
45
46#define MAX_HANDLES             10
47
48typedef struct
49{
50    FILE	    *hFile;
51    char	    *pMap;
52    int		    nLen;
53    int		    nPos;
54} MEMFILE;
55
56MEMFILE		    sys_handles[MAX_HANDLES];
57
58int findhandle (void)
59{
60    int             i;
61
62    for (i=1 ; i<MAX_HANDLES ; i++)
63	    if (!sys_handles[i].hFile)
64		    return i;
65    Sys_Error ("out of handles");
66    return -1;
67}
68
69/*
70================
71filelength
72================
73*/
74int filelength (FILE *f)
75{
76    int             pos;
77    int             end;
78
79    pos = ftell (f);
80    fseek (f, 0, SEEK_END);
81    end = ftell (f);
82    fseek (f, pos, SEEK_SET);
83
84    return end;
85}
86
87int Sys_FileOpenRead (char *path, int *hndl)
88{
89    FILE    *f;
90    int             i;
91
92    i = findhandle ();
93
94    f = fopen(path, "rb");
95    if (!f)
96    {
97	*hndl = -1;
98	return -1;
99    }
100    sys_handles[i].hFile = f;
101    sys_handles[i].nLen = filelength(f);
102    sys_handles[i].nPos = 0;
103    sys_handles[i].pMap = mmap( 0, sys_handles[i].nLen, PROT_READ, MAP_SHARED, fileno( sys_handles[i].hFile ), 0 );
104    if (!sys_handles[i].pMap || (sys_handles[i].pMap == (char *)-1))
105    {
106	printf( "mmap %s failed!", path );
107	sys_handles[i].pMap = NULL;
108    }
109
110    *hndl = i;
111
112    return( sys_handles[i].nLen );
113}
114
115int Sys_FileOpenWrite (char *path)
116{
117    FILE    *f;
118    int             i;
119
120    i = findhandle ();
121
122    f = fopen(path, "wb");
123    if (!f)
124	Sys_Error ("Error opening %s: %s", path,strerror(errno));
125    sys_handles[i].hFile = f;
126    sys_handles[i].nLen = 0;
127    sys_handles[i].nPos = 0;
128    sys_handles[i].pMap = NULL;
129
130    return i;
131}
132
133void Sys_FileClose (int handle)
134{
135    if (sys_handles[handle].pMap)
136	if (munmap( sys_handles[handle].pMap, sys_handles[handle].nLen ) != 0)
137	    printf( "failed to unmap handle %d\n", handle );
138
139    fclose (sys_handles[handle].hFile);
140    sys_handles[handle].hFile = NULL;
141}
142
143void Sys_FileSeek (int handle, int position)
144{
145    if (sys_handles[handle].pMap)
146    {
147	sys_handles[handle].nPos = position;
148    }
149    else fseek (sys_handles[handle].hFile, position, SEEK_SET);
150}
151
152int Sys_FileRead (int handle, void *dest, int count)
153{
154    if (sys_handles[handle].pMap)
155    {
156	int nPos = sys_handles[handle].nPos;
157	if (count < 0) count = 0;
158	if (nPos + count > sys_handles[handle].nLen)
159	    count = sys_handles[handle].nLen - nPos;
160	memcpy( dest, &sys_handles[handle].pMap[nPos], count );
161	sys_handles[handle].nPos = nPos + count;
162	return( count );
163    }
164    else return fread (dest, 1, count, sys_handles[handle].hFile);
165}
166
167int Sys_FileWrite (int handle, void *data, int count)
168{
169    if (sys_handles[handle].pMap)
170	Sys_Error( "Attempted to write to read-only file %d!\n", handle );
171    return fwrite (data, 1, count, sys_handles[handle].hFile);
172}
173
174int Sys_FileTime (char *path)
175{
176    FILE    *f;
177
178    f = fopen(path, "rb");
179    if (f)
180    {
181	fclose(f);
182	return 1;
183    }
184
185    return -1;
186}
187
188void Sys_mkdir (char *path)
189{
190    mkdir( path, 0777 );
191}
192
193/*
194===============================================================================
195
196SYSTEM IO
197
198===============================================================================
199*/
200
201void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
202{
203
204	int r;
205	unsigned long addr;
206	int psize = getpagesize();
207
208	addr = (startaddr & ~(psize-1)) - psize;
209
210//	fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr,
211//			addr, startaddr+length, length);
212
213	r = mprotect((char*)addr, length + startaddr - addr + psize, 7);
214
215	if (r < 0)
216    		Sys_Error("Protection change failed\n");
217
218}
219
220
221void Sys_Error (char *error, ...)
222{
223    va_list         argptr;
224
225    printf ("Sys_Error: ");
226    va_start (argptr,error);
227    vprintf (error,argptr);
228    va_end (argptr);
229    printf ("\n");
230    Host_Shutdown();
231    exit (1);
232}
233
234void Sys_Printf (char *fmt, ...)
235{
236    va_list         argptr;
237
238    va_start (argptr,fmt);
239    vprintf (fmt,argptr);
240    va_end (argptr);
241}
242
243void Sys_Quit (void)
244{
245    Host_Shutdown();
246    exit (0);
247}
248
249double Sys_FloatTime (void)
250{
251    struct timeval tp;
252    struct timezone tzp;
253    static int      secbase;
254
255    gettimeofday(&tp, &tzp);
256
257    if (!secbase)
258    {
259        secbase = tp.tv_sec;
260        return tp.tv_usec/1000000.0;
261    }
262
263    return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
264}
265
266char *Sys_ConsoleInput (void)
267{
268    static char	text[256];
269    int		len;
270    fd_set	readfds;
271    int		ready;
272    struct timeval timeout;
273
274    timeout.tv_sec = 0;
275    timeout.tv_usec = 0;
276    FD_ZERO(&readfds);
277    FD_SET(0, &readfds);
278    ready = select(1, &readfds, 0, 0, &timeout);
279
280    if (ready>0)
281    {
282	len = read (0, text, sizeof(text));
283	if (len >= 1)
284	{
285		text[len-1] = 0;	// rip off the /n and terminate
286		return text;
287	}
288    }
289
290    return 0;
291}
292
293void Sys_Sleep (void)
294{
295}
296
297#if !id386
298void Sys_HighFPPrecision (void)
299{
300}
301
302void Sys_LowFPPrecision (void)
303{
304}
305#endif
306
307void Sys_Init(void)
308{
309#if id386
310	Sys_SetFPCW();
311#endif
312}
313
314//=============================================================================
315
316int main (int argc, char **argv)
317{
318    static quakeparms_t    parms;
319    float time, oldtime, newtime;
320
321    parms.memsize = 16*1024*1024;
322    parms.membase = malloc (parms.memsize);
323    parms.basedir = ".";
324    parms.cachedir = NULL;
325
326    COM_InitArgv (argc, argv);
327
328    parms.argc = com_argc;
329    parms.argv = com_argv;
330
331    printf ("Host_Init\n");
332    Host_Init (&parms);
333
334	Sys_Init();
335
336    // unroll the simulation loop to give the video side a chance to see _vid_default_mode
337    Host_Frame( 0.1 );
338    VID_SetDefaultMode();
339
340    oldtime = Sys_FloatTime();
341    while (1)
342    {
343		newtime = Sys_FloatTime();
344		Host_Frame (newtime - oldtime);
345		oldtime = newtime;
346    }
347	return 0;
348}
349
350
351
352
353