Initial commit.

This commit is contained in:
Jim Gray
2013-04-04 14:32:05 -07:00
parent ba5c81da32
commit d71d53e8ec
2180 changed files with 1393544 additions and 1 deletions

131
codemp/unix/ftol.nasm Normal file
View File

@@ -0,0 +1,131 @@
;
; qftol -- fast floating point to long conversion.
;
segment .data
temp dd 0.0
fpucw dd 0
; Precision Control Field , 2 bits / 0x0300
; PC24 0x0000 Single precision (24 bits).
; PC53 0x0200 Double precision (53 bits).
; PC64 0x0300 Extended precision (64 bits).
; Rounding Control Field, 2 bits / 0x0C00
; RCN 0x0000 Rounding to nearest (even).
; RCD 0x0400 Rounding down (directed, minus).
; RCU 0x0800 Rounding up (directed plus).
; RC0 0x0C00 Rounding towards zero (chop mode).
; rounding towards nearest (even)
cw027F dd 0x027F ; double precision
cw037F dd 0x037F ; extended precision
; rounding towards zero (chop mode)
cw0E7F dd 0x0E7F ; double precision
cw0F7F dd 0x0F7F ; extended precision
segment .text
;
; int qftol( void ) - default control word
;
global qftol
qftol:
fistp dword [temp]
mov eax, [temp]
ret
;
; int qftol027F( void ) - DirectX FPU
;
global qftol027F
qftol027F:
fnstcw [fpucw]
fldcw [cw027F]
fistp dword [temp]
fldcw [fpucw]
mov eax, [temp]
ret
;
; int qftol037F( void ) - Linux FPU
;
global qftol037F
qftol037F:
fnstcw [fpucw]
fldcw [cw037F]
fistp dword [temp]
fldcw [fpucw]
mov eax, [temp]
ret
;
; int qftol0F7F( void ) - ANSI
;
global qftol0F7F
qftol0F7F:
fnstcw [fpucw]
fldcw [cw0F7F]
fistp dword [temp]
fldcw [fpucw]
mov eax, [temp]
ret
;
; int qftol0E7F( void )
;
global qftol0E7F
qftol0E7F:
fnstcw [fpucw]
fldcw [cw0E7F]
fistp dword [temp]
fldcw [fpucw]
mov eax, [temp]
ret
;
; long Q_ftol( float q )
;
global Q_ftol
Q_ftol:
fld dword [esp+4]
fistp dword [temp]
mov eax, [temp]
ret
;
; long qftol0F7F( float q ) - Linux FPU
;
global Q_ftol0F7F
Q_ftol0F7F:
fnstcw [fpucw]
fld dword [esp+4]
fldcw [cw0F7F]
fistp dword [temp]
fldcw [fpucw]
mov eax, [temp]
ret

323
codemp/unix/linux_common.c Normal file
View File

@@ -0,0 +1,323 @@
/**
* GAS syntax equivalents of the MSVC asm memory calls in common.c
*
* The following changes have been made to the asm:
* 1. Registers are loaded by the inline asm arguments when possible
* 2. Labels have been changed to local label format (0,1,etc.) to allow inlining
*
* HISTORY:
* AH - Created on 08 Dec 2000
*/
#include <unistd.h> // AH - for size_t
#include <string.h>
// bk001207 - we need something under Linux, too. Mac?
#if 1 // defined(C_ONLY) // bk010102 - dedicated?
void Com_Memcpy (void* dest, const void* src, const size_t count) {
memcpy(dest, src, count);
}
void Com_Memset (void* dest, const int val, const size_t count) {
memset(dest, val, count);
}
#else
typedef enum {
PRE_READ, // prefetch assuming that buffer is used for reading only
PRE_WRITE, // prefetch assuming that buffer is used for writing only
PRE_READ_WRITE // prefetch assuming that buffer is used for both reading and writing
} e_prefetch;
void Com_Prefetch (const void *s, const unsigned int bytes, e_prefetch type);
void _copyDWord (unsigned int* dest, const unsigned int constant, const unsigned int count) {
// MMX version not used on standard Pentium MMX
// because the dword version is faster (with
// proper destination prefetching)
__asm__ __volatile__ ("
//mov eax,constant // eax = val
//mov edx,dest // dest
//mov ecx,count
movd %%eax, %%mm0
punpckldq %%mm0, %%mm0
// ensure that destination is qword aligned
testl $7, %%edx // qword padding?
jz 0f
movl %%eax, (%%edx)
decl %%ecx
addl $4, %%edx
0: movl %%ecx, %%ebx
andl $0xfffffff0, %%ecx
jz 2f
jmp 1f
.align 16
// funny ordering here to avoid commands
// that cross 32-byte boundaries (the
// [edx+0] version has a special 3-byte opcode...
1: movq %%mm0, 8(%%edx)
movq %%mm0, 16(%%edx)
movq %%mm0, 24(%%edx)
movq %%mm0, 32(%%edx)
movq %%mm0, 40(%%edx)
movq %%mm0, 48(%%edx)
movq %%mm0, 56(%%edx)
movq %%mm0, (%%edx)
addl $64, %%edx
subl $16, %%ecx
jnz 1b
2:
movl %%ebx, %%ecx // ebx = cnt
andl $0xfffffff0, %%ecx // ecx = cnt&~15
subl %%ecx, %%ebx
jz 6f
cmpl $8, %%ebx
jl 3f
movq %%mm0, (%%edx)
movq %%mm0, 8(%%edx)
movq %%mm0, 16(%%edx)
movq %%mm0, 24(%%edx)
addl $32, %%edx
subl $8, %%ebx
jz 6f
3: cmpl $4, %%ebx
jl 4f
movq %%mm0, (%%edx)
movq %%mm0, 8(%%edx)
addl $16, %%edx
subl $4, %%ebx
4: cmpl $2, %%ebx
jl 5f
movq %%mm0, (%%edx)
addl $8, %%edx
subl $2, %%ebx
5: cmpl $1, %%ebx
jl 6f
movl %%eax, (%%edx)
6:
emms
"
: : "a" (constant), "c" (count), "d" (dest)
: "%ebx", "%edi", "%esi", "cc", "memory");
}
// optimized memory copy routine that handles all alignment
// cases and block sizes efficiently
void Com_Memcpy (void* dest, const void* src, const size_t count) {
Com_Prefetch (src, count, PRE_READ);
__asm__ __volatile__ ("
pushl %%edi
pushl %%esi
//mov ecx,count
cmpl $0, %%ecx // count = 0 check (just to be on the safe side)
je 6f
//mov edx,dest
movl %0, %%ebx
cmpl $32, %%ecx // padding only?
jl 1f
movl %%ecx, %%edi
andl $0xfffffe00, %%edi // edi = count&~31
subl $32, %%edi
.align 16
0:
movl (%%ebx, %%edi, 1), %%eax
movl 4(%%ebx, %%edi, 1), %%esi
movl %%eax, (%%edx, %%edi, 1)
movl %%esi, 4(%%edx, %%edi, 1)
movl 8(%%ebx, %%edi, 1), %%eax
movl 12(%%ebx, %%edi, 1), %%esi
movl %%eax, 8(%%edx, %%edi, 1)
movl %%esi, 12(%%edx, %%edi, 1)
movl 16(%%ebx, %%edi, 1), %%eax
movl 20(%%ebx, %%edi, 1), %%esi
movl %%eax, 16(%%edx, %%edi, 1)
movl %%esi, 20(%%edx, %%edi, 1)
movl 24(%%ebx, %%edi, 1), %%eax
movl 28(%%ebx, %%edi, 1), %%esi
movl %%eax, 24(%%edx, %%edi, 1)
movl %%esi, 28(%%edx, %%edi, 1)
subl $32, %%edi
jge 0b
movl %%ecx, %%edi
andl $0xfffffe00, %%edi
addl %%edi, %%ebx // increase src pointer
addl %%edi, %%edx // increase dst pointer
andl $31, %%ecx // new count
jz 6f // if count = 0, get outta here
1:
cmpl $16, %%ecx
jl 2f
movl (%%ebx), %%eax
movl %%eax, (%%edx)
movl 4(%%ebx), %%eax
movl %%eax, 4(%%edx)
movl 8(%%ebx), %%eax
movl %%eax, 8(%%edx)
movl 12(%%ebx), %%eax
movl %%eax, 12(%%edx)
subl $16, %%ecx
addl $16, %%ebx
addl $16, %%edx
2:
cmpl $8, %%ecx
jl 3f
movl (%%ebx), %%eax
movl %%eax, (%%edx)
movl 4(%%ebx), %%eax
subl $8, %%ecx
movl %%eax, 4(%%edx)
addl $8, %%ebx
addl $8, %%edx
3:
cmpl $4, %%ecx
jl 4f
movl (%%ebx), %%eax // here 4-7 bytes
addl $4, %%ebx
subl $4, %%ecx
movl %%eax, (%%edx)
addl $4, %%edx
4: // 0-3 remaining bytes
cmpl $2, %%ecx
jl 5f
movw (%%ebx), %%ax // two bytes
cmpl $3, %%ecx // less than 3?
movw %%ax, (%%edx)
jl 6f
movb 2(%%ebx), %%al // last byte
movb %%al, 2(%%edx)
jmp 6f
5:
cmpl $1, %%ecx
jl 6f
movb (%%ebx), %%al
movb %%al, (%%edx)
6:
popl %%esi
popl %%edi
"
: : "m" (src), "d" (dest), "c" (count)
: "%eax", "%ebx", "%edi", "%esi", "cc", "memory");
}
void Com_Memset (void* dest, const int val, const size_t count)
{
unsigned int fillval;
if (count < 8)
{
__asm__ __volatile__ ("
//mov edx,dest
//mov eax, val
movb %%al, %%ah
movl %%eax, %%ebx
andl $0xffff, %%ebx
shll $16, %%eax
addl %%ebx, %%eax // eax now contains pattern
//mov ecx,count
cmpl $4, %%ecx
jl 0f
movl %%eax, (%%edx) // copy first dword
addl $4, %%edx
subl $4, %%ecx
0: cmpl $2, %%ecx
jl 1f
movw %%ax, (%%edx) // copy 2 bytes
addl $2, %%edx
subl $2, %%ecx
1: cmpl $0, %%ecx
je 2f
movb %%al, (%%edx) // copy single byte
2:
"
: : "d" (dest), "a" (val), "c" (count)
: "%ebx", "%edi", "%esi", "cc", "memory");
return;
}
fillval = val;
fillval = fillval|(fillval<<8);
fillval = fillval|(fillval<<16); // fill dword with 8-bit pattern
_copyDWord ((unsigned int*)(dest),fillval, count/4);
__asm__ __volatile__ (" // padding of 0-3 bytes
//mov ecx,count
movl %%ecx, %%eax
andl $3, %%ecx
jz 1f
andl $0xffffff00, %%eax
//mov ebx,dest
addl %%eax, %%edx
movl %0, %%eax
cmpl $2, %%ecx
jl 0f
movw %%ax, (%%edx)
cmpl $2, %%ecx
je 1f
movb %%al, 2(%%edx)
jmp 1f
0:
cmpl $0, %%ecx
je 1f
movb %%al, (%%edx)
1:
"
: : "m" (fillval), "c" (count), "d" (dest)
: "%eax", "%ebx", "%edi", "%esi", "cc", "memory");
}
void Com_Prefetch (const void *s, const unsigned int bytes, e_prefetch type)
{
// write buffer prefetching is performed only if
// the processor benefits from it. Read and read/write
// prefetching is always performed.
switch (type)
{
case PRE_WRITE : break;
case PRE_READ:
case PRE_READ_WRITE:
__asm__ __volatile__ ("
//mov ebx,s
//mov ecx,bytes
cmpl $4096, %%ecx // clamp to 4kB
jle 0f
movl $4096, %%ecx
0:
addl $0x1f, %%ecx
shrl $5, %%ecx // number of cache lines
jz 2f
jmp 1f
.align 16
1: testb %%al, (%%edx)
addl $32, %%edx
decl %%ecx
jnz 1b
2:
"
: : "d" (s), "c" (bytes)
: "%eax", "%ebx", "%edi", "%esi", "memory", "cc");
break;
}
}
#endif

1543
codemp/unix/linux_glimp.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,186 @@
/*
** linux_joystick.c
**
** This file contains ALL Linux specific stuff having to do with the
** Joystick input. When a port is being made the following functions
** must be implemented by the port:
**
** Authors: mkv, bk
**
*/
#include <linux/joystick.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h> // bk001204
#include "../client/client.h"
#include "linux_local.h"
/* We translate axes movement into keypresses. */
int joy_keys[16] = {
K_LEFTARROW, K_RIGHTARROW,
K_UPARROW, K_DOWNARROW,
K_JOY16, K_JOY17,
K_JOY18, K_JOY19,
K_JOY20, K_JOY21,
K_JOY22, K_JOY23,
K_JOY24, K_JOY25,
K_JOY26, K_JOY27
};
/* Our file descriptor for the joystick device. */
static int joy_fd = -1;
// bk001130 - from linux_glimp.c
extern cvar_t * in_joystick;
extern cvar_t * in_joystickDebug;
extern cvar_t * joy_threshold;
/**********************************************/
/* Joystick routines. */
/**********************************************/
// bk001130 - from cvs1.17 (mkv), removed from linux_glimp.c
void IN_StartupJoystick( void )
{
int i = 0;
joy_fd = -1;
if( !in_joystick->integer ) {
Com_Printf( "Joystick is not active.\n" );
return;
}
for( i = 0; i < 4; i++ ) {
char filename[PATH_MAX];
snprintf( filename, PATH_MAX, "/dev/js%d", i );
joy_fd = open( filename, O_RDONLY | O_NONBLOCK );
if( joy_fd != -1 ) {
struct js_event event;
char axes = 0;
char buttons = 0;
char name[128];
int n = -1;
Com_Printf( "Joystick %s found\n", filename );
/* Get rid of initialization messages. */
do {
n = read( joy_fd, &event, sizeof( event ) );
if( n == -1 ) {
break;
}
} while( ( event.type & JS_EVENT_INIT ) );
/* Get joystick statistics. */
ioctl( joy_fd, JSIOCGAXES, &axes );
ioctl( joy_fd, JSIOCGBUTTONS, &buttons );
if( ioctl( joy_fd, JSIOCGNAME( sizeof( name ) ), name ) < 0 ) {
strncpy( name, "Unknown", sizeof( name ) );
}
Com_Printf( "Name: %s\n", name );
Com_Printf( "Axes: %d\n", axes );
Com_Printf( "Buttons: %d\n", buttons );
/* Our work here is done. */
return;
}
}
/* No soup for you. */
if( joy_fd == -1 ) {
Com_Printf( "No joystick found.\n" );
return;
}
}
void IN_JoyMove( void )
{
/* Store instantaneous joystick state. Hack to get around
* event model used in Linux joystick driver.
*/
static int axes_state[16];
/* Old bits for Quake-style input compares. */
static unsigned int old_axes = 0;
/* Our current goodies. */
unsigned int axes = 0;
int i = 0;
if( joy_fd == -1 ) {
return;
}
/* Empty the queue, dispatching button presses immediately
* and updating the instantaneous state for the axes.
*/
do {
int n = -1;
struct js_event event;
n = read( joy_fd, &event, sizeof( event ) );
if( n == -1 ) {
/* No error, we're non-blocking. */
break;
}
if( event.type & JS_EVENT_BUTTON ) {
Sys_QueEvent( 0, SE_KEY, K_JOY1 + event.number, event.value, 0, NULL );
} else if( event.type & JS_EVENT_AXIS ) {
if( event.number >= 16 ) {
continue;
}
axes_state[event.number] = event.value;
} else {
Com_Printf( "Unknown joystick event type\n" );
}
} while( 1 );
/* Translate our instantaneous state to bits. */
for( i = 0; i < 16; i++ ) {
float f = ( (float) axes_state[i] ) / 32767.0f;
if( f < -joy_threshold->value ) {
axes |= ( 1 << ( i * 2 ) );
} else if( f > joy_threshold->value ) {
axes |= ( 1 << ( ( i * 2 ) + 1 ) );
}
}
/* Time to update axes state based on old vs. new. */
for( i = 0; i < 16; i++ ) {
if( ( axes & ( 1 << i ) ) && !( old_axes & ( 1 << i ) ) ) {
Sys_QueEvent( 0, SE_KEY, joy_keys[i], qtrue, 0, NULL );
}
if( !( axes & ( 1 << i ) ) && ( old_axes & ( 1 << i ) ) ) {
Sys_QueEvent( 0, SE_KEY, joy_keys[i], qfalse, 0, NULL );
}
}
/* Save for future generations. */
old_axes = axes;
}

29
codemp/unix/linux_local.h Normal file
View File

@@ -0,0 +1,29 @@
// linux_local.h: Linux-specific Quake3 header file
void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr );
qboolean Sys_GetPacket ( netadr_t *net_from, msg_t *net_message );
void Sys_SendKeyEvents (void);
// Input subsystem
void IN_Init (void);
void IN_Frame (void);
void IN_Shutdown (void);
void IN_JoyMove( void );
void IN_StartupJoystick( void );
// GL subsystem
qboolean QGL_Init( const char *dllname );
void QGL_EnableLogging( qboolean enable );
void QGL_Shutdown( void );
// bk001130 - win32
// void IN_JoystickCommands (void);
char *strlwr (char *s);

4132
codemp/unix/linux_qgl.c Normal file

File diff suppressed because it is too large Load Diff

237
codemp/unix/linux_snd.c Normal file
View File

@@ -0,0 +1,237 @@
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/shm.h>
#include <sys/wait.h>
#ifdef __linux__ // rb0101023 - guard this
#include <linux/soundcard.h>
#endif
#ifdef __FreeBSD__ // rb0101023 - added
#include <sys/soundcard.h>
#endif
#include <stdio.h>
#include "../client/snd_local.h"
int audio_fd;
int snd_inited=0;
cvar_t *sndbits;
cvar_t *sndspeed;
cvar_t *sndchannels;
cvar_t *snddevice;
/* Some devices may work only with 48000 */
static int tryrates[] = { 22050, 11025, 44100, 48000, 8000 };
qboolean SNDDMA_Init(void)
{
int rc;
int fmt;
int tmp;
int i;
// char *s; // bk001204 - unused
struct audio_buf_info info;
int caps;
extern uid_t saved_euid;
if (snd_inited)
return 1;
if (!snddevice) {
sndbits = Cvar_Get("sndbits", "16", CVAR_ARCHIVE);
sndspeed = Cvar_Get("sndspeed", "0", CVAR_ARCHIVE);
sndchannels = Cvar_Get("sndchannels", "2", CVAR_ARCHIVE);
snddevice = Cvar_Get("snddevice", "/dev/dsp", CVAR_ARCHIVE);
}
// open /dev/dsp, confirm capability to mmap, and get size of dma buffer
if (!audio_fd) {
seteuid(saved_euid);
audio_fd = open(snddevice->string, O_RDWR);
seteuid(getuid());
if (audio_fd < 0) {
perror(snddevice->string);
Com_Printf("Could not open %s\n", snddevice->string);
return 0;
}
}
if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps) == -1) {
perror(snddevice->string);
Com_Printf("Sound driver too old\n");
close(audio_fd);
return 0;
}
if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP)) {
Com_Printf("Sorry but your soundcard can't do this\n");
close(audio_fd);
return 0;
}
/* SNDCTL_DSP_GETOSPACE moved to be called later */
// set sample bits & speed
dma.samplebits = (int)sndbits->value;
if (dma.samplebits != 16 && dma.samplebits != 8) {
ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt);
if (fmt & AFMT_S16_LE)
dma.samplebits = 16;
else if (fmt & AFMT_U8)
dma.samplebits = 8;
}
dma.speed = (int)sndspeed->value;
if (!dma.speed) {
for (i=0 ; i<sizeof(tryrates)/4 ; i++)
if (!ioctl(audio_fd, SNDCTL_DSP_SPEED, &tryrates[i]))
break;
dma.speed = tryrates[i];
}
dma.channels = (int)sndchannels->value;
if (dma.channels < 1 || dma.channels > 2)
dma.channels = 2;
/* mmap() call moved forward */
tmp = 0;
if (dma.channels == 2)
tmp = 1;
rc = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
if (rc < 0) {
perror(snddevice->string);
Com_Printf("Could not set %s to stereo=%d", snddevice->string, dma.channels);
close(audio_fd);
return 0;
}
if (tmp)
dma.channels = 2;
else
dma.channels = 1;
rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &dma.speed);
if (rc < 0) {
perror(snddevice->string);
Com_Printf("Could not set %s speed to %d", snddevice->string, dma.speed);
close(audio_fd);
return 0;
}
if (dma.samplebits == 16) {
rc = AFMT_S16_LE;
rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
if (rc < 0) {
perror(snddevice->string);
Com_Printf("Could not support 16-bit data. Try 8-bit.\n");
close(audio_fd);
return 0;
}
} else if (dma.samplebits == 8) {
rc = AFMT_U8;
rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
if (rc < 0) {
perror(snddevice->string);
Com_Printf("Could not support 8-bit data.\n");
close(audio_fd);
return 0;
}
} else {
perror(snddevice->string);
Com_Printf("%d-bit sound not supported.", dma.samplebits);
close(audio_fd);
return 0;
}
if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1) {
perror("GETOSPACE");
Com_Printf("Um, can't do GETOSPACE?\n");
close(audio_fd);
return 0;
}
dma.samples = info.fragstotal * info.fragsize / (dma.samplebits/8);
dma.submission_chunk = 1;
// memory map the dma buffer
if (!dma.buffer)
dma.buffer = (unsigned char *) mmap(NULL, info.fragstotal
* info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, audio_fd, 0);
if (!dma.buffer) {
perror(snddevice->string);
Com_Printf("Could not mmap %s\n", snddevice->string);
close(audio_fd);
return 0;
}
// toggle the trigger & start her up
tmp = 0;
rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
if (rc < 0) {
perror(snddevice->string);
Com_Printf("Could not toggle.\n");
close(audio_fd);
return 0;
}
tmp = PCM_ENABLE_OUTPUT;
rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
if (rc < 0) {
perror(snddevice->string);
Com_Printf("Could not toggle.\n");
close(audio_fd);
return 0;
}
snd_inited = 1;
return 1;
}
int SNDDMA_GetDMAPos(void)
{
struct count_info count;
if (!snd_inited) return 0;
if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &count) == -1) {
perror(snddevice->string);
Com_Printf("Uh, sound dead.\n");
close(audio_fd);
snd_inited = 0;
return 0;
}
return count.ptr / (dma.samplebits / 8);
}
void SNDDMA_Shutdown(void)
{
}
/*
==============
SNDDMA_Submit
Send sound to device if buffer isn't really the dma buffer
===============
*/
void SNDDMA_Submit(void)
{
}
void SNDDMA_BeginPainting (void)
{
}

View File

@@ -0,0 +1,75 @@
;
; Sys_SnapVector NASM code (Andrew Henderson)
; See win32/win_shared.c for the Win32 equivalent
; This code is provided to ensure that the
; rounding behavior (and, if necessary, the
; precision) of DLL and QVM code are identical
; e.g. for network-visible operations.
; See ftol.nasm for operations on a single float,
; as used in compiled VM and DLL code that does
; not use this system trap.
;
segment .data
fpucw dd 0
cw037F dd 0x037F ; Rounding to nearest (even).
segment .text
; void Sys_SnapVector( float *v )
global Sys_SnapVector
Sys_SnapVector:
push eax
push ebp
mov ebp, esp
fnstcw [fpucw]
mov eax, dword [ebp + 12]
fldcw [cw037F]
fld dword [eax]
fistp dword [eax]
fild dword [eax]
fstp dword [eax]
fld dword [eax + 4]
fistp dword [eax + 4]
fild dword [eax + 4]
fstp dword [eax + 4]
fld dword [eax + 8]
fistp dword [eax + 8]
fild dword [eax + 8]
fstp dword [eax + 8]
fldcw [fpucw]
pop ebp
pop eax
ret
; void Sys_SnapVectorCW( float *v, unsigned short int cw )
global Sys_SnapVectorCW
Sys_SnapVector_cw:
push eax
push ebp
mov ebp, esp
fnstcw [fpucw]
mov eax, dword [ebp + 12]
fldcw [ebp + 16]
fld dword [eax]
fistp dword [eax]
fild dword [eax]
fstp dword [eax]
fld dword [eax + 4]
fistp dword [eax + 4]
fild dword [eax + 4]
fstp dword [eax + 4]
fld dword [eax + 8]
fistp dword [eax + 8]
fild dword [eax + 8]
fstp dword [eax + 8]
fldcw [fpucw]
pop ebp
pop eax
ret

1164
codemp/unix/unix_main.c Normal file

File diff suppressed because it is too large Load Diff

599
codemp/unix/unix_net.c Normal file
View File

@@ -0,0 +1,599 @@
// unix_net.c
#include "../game/q_shared.h"
#include "../qcommon/qcommon.h"
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h> // bk001204
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <errno.h>
#ifdef MACOS_X
#import <sys/sockio.h>
#import <net/if.h>
#import <net/if_types.h>
#import <arpa/inet.h> // for inet_ntoa()
#import <net/if_dl.h> // for 'struct sockaddr_dl'
#endif
static cvar_t *noudp;
netadr_t net_local_adr;
int ip_socket;
int ipx_socket;
#define MAX_IPS 16
static int numIP;
static byte localIP[MAX_IPS][4];
int NET_Socket (char *net_interface, int port);
char *NET_ErrorString (void);
//=============================================================================
void NetadrToSockadr (netadr_t *a, struct sockaddr_in *s)
{
memset (s, 0, sizeof(*s));
if (a->type == NA_BROADCAST)
{
s->sin_family = AF_INET;
s->sin_port = a->port;
*(int *)&s->sin_addr = -1;
}
else if (a->type == NA_IP)
{
s->sin_family = AF_INET;
*(int *)&s->sin_addr = *(int *)&a->ip;
s->sin_port = a->port;
}
}
void SockadrToNetadr (struct sockaddr_in *s, netadr_t *a)
{
*(int *)&a->ip = *(int *)&s->sin_addr;
a->port = s->sin_port;
a->type = NA_IP;
}
char *NET_BaseAdrToString (netadr_t a)
{
static char s[64];
Com_sprintf (s, sizeof(s), "%i.%i.%i.%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3]);
return s;
}
/*
=============
Sys_StringToAdr
idnewt
192.246.40.70
=============
*/
qboolean Sys_StringToSockaddr (const char *s, struct sockaddr *sadr)
{
struct hostent *h;
//char *colon; // bk001204 - unused
memset (sadr, 0, sizeof(*sadr));
((struct sockaddr_in *)sadr)->sin_family = AF_INET;
((struct sockaddr_in *)sadr)->sin_port = 0;
if ( s[0] >= '0' && s[0] <= '9')
{
*(int *)&((struct sockaddr_in *)sadr)->sin_addr = inet_addr(s);
}
else
{
if (! (h = gethostbyname(s)) )
return qfalse;
*(int *)&((struct sockaddr_in *)sadr)->sin_addr = *(int *)h->h_addr_list[0];
}
return qtrue;
}
/*
=============
Sys_StringToAdr
localhost
idnewt
idnewt:28000
192.246.40.70
192.246.40.70:28000
=============
*/
qboolean Sys_StringToAdr (const char *s, netadr_t *a)
{
struct sockaddr_in sadr;
if (!Sys_StringToSockaddr (s, (struct sockaddr *)&sadr))
return qfalse;
SockadrToNetadr (&sadr, a);
return qtrue;
}
//=============================================================================
qboolean Sys_GetPacket (netadr_t *net_from, msg_t *net_message)
{
int ret;
struct sockaddr_in from;
int fromlen;
int net_socket;
int protocol;
int err;
for (protocol = 0 ; protocol < 2 ; protocol++)
{
if (protocol == 0)
net_socket = ip_socket;
else
net_socket = ipx_socket;
if (!net_socket)
continue;
fromlen = sizeof(from);
ret = recvfrom (net_socket, net_message->data, net_message->maxsize
, 0, (struct sockaddr *)&from,(socklen_t*) &fromlen);
SockadrToNetadr (&from, net_from);
// bk000305: was missing
net_message->readcount = 0;
if (ret == -1)
{
err = errno;
if (err == EWOULDBLOCK || err == ECONNREFUSED)
continue;
Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(),
NET_AdrToString(*net_from));
continue;
}
if (ret == net_message->maxsize)
{
Com_Printf ("Oversize packet from %s\n", NET_AdrToString (*net_from));
continue;
}
net_message->cursize = ret;
return qtrue;
}
return qfalse;
}
//=============================================================================
void Sys_SendPacket( int length, const void *data, netadr_t to )
{
int ret;
struct sockaddr_in addr;
int net_socket;
if (to.type == NA_BROADCAST)
{
net_socket = ip_socket;
}
else if (to.type == NA_IP)
{
net_socket = ip_socket;
}
else if (to.type == NA_IPX)
{
net_socket = ipx_socket;
}
else if (to.type == NA_BROADCAST_IPX)
{
net_socket = ipx_socket;
}
else {
Com_Error (ERR_FATAL, "NET_SendPacket: bad address type");
return;
}
if (!net_socket)
return;
NetadrToSockadr (&to, &addr);
ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );
if (ret == -1)
{
Com_Printf ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(),
NET_AdrToString (to));
}
}
//=============================================================================
/*
==================
Sys_IsLANAddress
LAN clients will have their rate var ignored
==================
*/
qboolean Sys_IsLANAddress (netadr_t adr) {
int i;
if( adr.type == NA_LOOPBACK ) {
return qtrue;
}
if( adr.type == NA_IPX ) {
return qtrue;
}
if( adr.type != NA_IP ) {
return qfalse;
}
// choose which comparison to use based on the class of the address being tested
// any local adresses of a different class than the address being tested will fail based on the first byte
/*
// Class A
if( (adr.ip[0] & 0x80) == 0x00 ) {
for ( i = 0 ; i < numIP ; i++ ) {
if( adr.ip[0] == localIP[i][0] ) {
return qtrue;
}
}
// the RFC1918 class a block will pass the above test
return qfalse;
}
// Class B
if( (adr.ip[0] & 0xc0) == 0x80 ) {
for ( i = 0 ; i < numIP ; i++ ) {
if( adr.ip[0] == localIP[i][0] && adr.ip[1] == localIP[i][1] ) {
return qtrue;
}
// also check against the RFC1918 class b blocks
if( adr.ip[0] == 172 && localIP[i][0] == 172 && (adr.ip[1] & 0xf0) == 16 && (localIP[i][1] & 0xf0) == 16 ) {
return qtrue;
}
}
return qfalse;
}
*/
//we only look at class C since ISPs and Universities are using class A but we don't want to consider them on the same LAN.
// Class C
for ( i = 0 ; i < numIP ; i++ ) {
if( adr.ip[0] == localIP[i][0] && adr.ip[1] == localIP[i][1] && adr.ip[2] == localIP[i][2] ) {
return qtrue;
}
// also check against the RFC1918 class c blocks
if( adr.ip[0] == 192 && localIP[i][0] == 192 && adr.ip[1] == 168 && localIP[i][1] == 168 ) {
return qtrue;
}
}
return qfalse;
}
/*
==================
Sys_ShowIP
==================
*/
void Sys_ShowIP(void) {
int i;
for (i = 0; i < numIP; i++) {
Com_Printf( "IP: %i.%i.%i.%i\n", localIP[i][0], localIP[i][1], localIP[i][2], localIP[i][3] );
}
}
/*
=====================
NET_GetLocalAddress
=====================
*/
#ifdef MACOS_X
// Don't do a forward mapping from the hostname of the machine to the IP. The reason is that we might have obtained an IP address from DHCP and there might not be any name registered for the machine. On Mac OS X, the machine name defaults to 'localhost' and NetInfo has 127.0.0.1 listed for this name. Instead, we want to get a list of all the IP network interfaces on the machine.
// This code adapted from OmniNetworking.
#define IFR_NEXT(ifr) \
((struct ifreq *) ((char *) (ifr) + sizeof(*(ifr)) + \
MAX(0, (int) (ifr)->ifr_addr.sa_len - (int) sizeof((ifr)->ifr_addr))))
void NET_GetLocalAddress( void ) {
struct ifreq requestBuffer[MAX_IPS], *linkInterface, *inetInterface;
struct ifconf ifc;
struct ifreq ifr;
struct sockaddr_dl *sdl;
int interfaceSocket;
int family;
//Com_Printf("NET_GetLocalAddress: Querying for network interfaces\n");
// Set this early so we can just return if there is an error
numIP = 0;
ifc.ifc_len = sizeof(requestBuffer);
ifc.ifc_buf = (caddr_t)requestBuffer;
// Since we get at this info via an ioctl, we need a temporary little socket. This will only get AF_INET interfaces, but we probably don't care about anything else. If we do end up caring later, we should add a ONAddressFamily and at a -interfaces method to it.
family = AF_INET;
if ((interfaceSocket = socket(family, SOCK_DGRAM, 0)) < 0) {
Com_Printf("NET_GetLocalAddress: Unable to create temporary socket, errno = %d\n", errno);
return;
}
if (ioctl(interfaceSocket, SIOCGIFCONF, &ifc) != 0) {
Com_Printf("NET_GetLocalAddress: Unable to get list of network interfaces, errno = %d\n", errno);
return;
}
linkInterface = (struct ifreq *) ifc.ifc_buf;
while ((char *) linkInterface < &ifc.ifc_buf[ifc.ifc_len]) {
unsigned int nameLength;
// The ioctl returns both the entries having the address (AF_INET) and the link layer entries (AF_LINK). The AF_LINK entry has the link layer address which contains the interface type. This is the only way I can see to get this information. We cannot assume that we will get bot an AF_LINK and AF_INET entry since the interface may not be configured. For example, if you have a 10Mb port on the motherboard and a 100Mb card, you may not configure the motherboard port.
// For each AF_LINK entry...
if (linkInterface->ifr_addr.sa_family == AF_LINK) {
// if there is a matching AF_INET entry
inetInterface = (struct ifreq *) ifc.ifc_buf;
while ((char *) inetInterface < &ifc.ifc_buf[ifc.ifc_len]) {
if (inetInterface->ifr_addr.sa_family == AF_INET &&
!strncmp(inetInterface->ifr_name, linkInterface->ifr_name, sizeof(linkInterface->ifr_name))) {
for (nameLength = 0; nameLength < IFNAMSIZ; nameLength++)
if (!linkInterface->ifr_name[nameLength])
break;
sdl = (struct sockaddr_dl *)&linkInterface->ifr_addr;
// Skip loopback interfaces
if (sdl->sdl_type != IFT_LOOP) {
// Get the local interface address
strncpy(ifr.ifr_name, inetInterface->ifr_name, sizeof(ifr.ifr_name));
if (ioctl(interfaceSocket, OSIOCGIFADDR, (caddr_t)&ifr) < 0) {
Com_Printf("NET_GetLocalAddress: Unable to get local address for interface '%s', errno = %d\n", inetInterface->ifr_name, errno);
} else {
struct sockaddr_in *sin;
int ip;
sin = (struct sockaddr_in *)&ifr.ifr_addr;
ip = ntohl(sin->sin_addr.s_addr);
localIP[ numIP ][0] = (ip >> 24) & 0xff;
localIP[ numIP ][1] = (ip >> 16) & 0xff;
localIP[ numIP ][2] = (ip >> 8) & 0xff;
localIP[ numIP ][3] = (ip >> 0) & 0xff;
Com_Printf( "IP: %i.%i.%i.%i (%s)\n", localIP[ numIP ][0], localIP[ numIP ][1], localIP[ numIP ][2], localIP[ numIP ][3], inetInterface->ifr_name);
numIP++;
}
}
// We will assume that there is only one AF_INET entry per AF_LINK entry.
// What happens when we have an interface that has multiple IP addresses, or
// can that even happen?
// break;
}
inetInterface = IFR_NEXT(inetInterface);
}
}
linkInterface = IFR_NEXT(linkInterface);
}
close(interfaceSocket);
}
#else
void NET_GetLocalAddress( void ) {
char hostname[256];
struct hostent *hostInfo;
// int error; // bk001204 - unused
char *p;
int ip;
int n;
// Set this early so we can just return if there is an error
numIP = 0;
if ( gethostname( hostname, 256 ) == -1 ) {
return;
}
hostInfo = gethostbyname( hostname );
if ( !hostInfo ) {
return;
}
Com_Printf( "Hostname: %s\n", hostInfo->h_name );
n = 0;
while( ( p = hostInfo->h_aliases[n++] ) != NULL ) {
Com_Printf( "Alias: %s\n", p );
}
if ( hostInfo->h_addrtype != AF_INET ) {
return;
}
while( ( p = hostInfo->h_addr_list[numIP] ) != NULL && numIP < MAX_IPS ) {
ip = ntohl( *(int *)p );
localIP[ numIP ][0] = p[0];
localIP[ numIP ][1] = p[1];
localIP[ numIP ][2] = p[2];
localIP[ numIP ][3] = p[3];
Com_Printf( "IP: %i.%i.%i.%i\n", ( ip >> 24 ) & 0xff, ( ip >> 16 ) & 0xff, ( ip >> 8 ) & 0xff, ip & 0xff );
numIP++;
}
}
#endif
/*
====================
NET_OpenIP
====================
*/
// bk001204 - prototype needed
int NET_IPSocket (char *net_interface, int port);
void NET_OpenIP (void)
{
cvar_t *ip;
int port;
int i;
ip = Cvar_Get ("net_ip", "localhost", 0);
port = Cvar_Get("net_port", va("%i", PORT_SERVER), 0)->value;
for ( i = 0 ; i < 10 ; i++ ) {
ip_socket = NET_IPSocket (ip->string, port + i);
if ( ip_socket ) {
Cvar_SetValue( "net_port", port + i );
NET_GetLocalAddress();
return;
}
}
Com_Error (ERR_FATAL, "Couldn't allocate IP port");
}
/*
====================
NET_Init
====================
*/
void NET_Init (void)
{
noudp = Cvar_Get ("net_noudp", "0", 0);
// open sockets
if (! noudp->value) {
NET_OpenIP ();
}
}
/*
====================
NET_IPSocket
====================
*/
int NET_IPSocket (char *net_interface, int port)
{
int newsocket;
struct sockaddr_in address;
qboolean _qtrue = qtrue;
int i = 1;
if ( net_interface ) {
Com_Printf("Opening IP socket: %s:%i\n", net_interface, port );
} else {
Com_Printf("Opening IP socket: localhost:%i\n", port );
}
if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
Com_Printf ("ERROR: UDP_OpenSocket: socket: %s", NET_ErrorString());
return 0;
}
// make it non-blocking
if (ioctl (newsocket, FIONBIO, &_qtrue) == -1)
{
Com_Printf ("ERROR: UDP_OpenSocket: ioctl FIONBIO:%s\n", NET_ErrorString());
return 0;
}
// make it broadcast capable
if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) == -1)
{
Com_Printf ("ERROR: UDP_OpenSocket: setsockopt SO_BROADCAST:%s\n", NET_ErrorString());
return 0;
}
if (!net_interface || !net_interface[0] || !Q_stricmp(net_interface, "localhost"))
address.sin_addr.s_addr = INADDR_ANY;
else
Sys_StringToSockaddr (net_interface, (struct sockaddr *)&address);
if (port == PORT_ANY)
address.sin_port = 0;
else
address.sin_port = htons((short)port);
address.sin_family = AF_INET;
if( bind (newsocket, (sockaddr *)&address, sizeof(address)) == -1)
{
Com_Printf ("ERROR: UDP_OpenSocket: bind: %s\n", NET_ErrorString());
close (newsocket);
return 0;
}
return newsocket;
}
/*
====================
NET_Shutdown
====================
*/
void NET_Shutdown (void)
{
if (ip_socket) {
close(ip_socket);
ip_socket = 0;
}
}
/*
====================
NET_ErrorString
====================
*/
char *NET_ErrorString (void)
{
int code;
code = errno;
return strerror (code);
}
// sleeps msec or until net socket is ready
void NET_Sleep(int msec)
{
struct timeval timeout;
fd_set fdset;
extern qboolean stdin_active;
if (!ip_socket || !com_dedicated->integer)
return; // we're not a server, just run full speed
FD_ZERO(&fdset);
if (stdin_active)
FD_SET(0, &fdset); // stdin is processed too
FD_SET(ip_socket, &fdset); // network socket
timeout.tv_sec = msec/1000;
timeout.tv_usec = (msec%1000)*1000;
select(ip_socket+1, &fdset, NULL, NULL, &timeout);
}

350
codemp/unix/unix_shared.c Normal file
View File

@@ -0,0 +1,350 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <pwd.h>
#include "../game/q_shared.h"
#include "../qcommon/qcommon.h"
typedef unsigned short DWORD;
//=============================================================================
// Used to determine CD Path
static char cdPath[MAX_OSPATH];
// Used to determine local installation path
static char installPath[MAX_OSPATH];
// Used to determine where to store user-specific files
static char homePath[MAX_OSPATH];
//DWORD timeGetTime(void)
//{
// return Sys_Milliseconds();
//}
/*
================
Sys_Milliseconds
================
*/
int curtime;
int sys_timeBase;
int Sys_Milliseconds (bool baseTime)
{
struct timeval tp;
struct timezone tzp;
gettimeofday(&tp, &tzp);
if (!sys_timeBase)
{
sys_timeBase = tp.tv_sec;
return tp.tv_usec/1000;
}
curtime = (tp.tv_sec - sys_timeBase)*1000 + tp.tv_usec/1000;
static int sys_timeBase = curtime;
if (!baseTime)
{
curtime -= sys_timeBase;
}
return curtime;
}
//#if 0 // bk001215 - see snapvector.nasm for replacement
#if (defined __APPLE__) // rcg010206 - using this for PPC builds...
long fastftol( float f ) { // bk001213 - from win32/win_shared.c
//static int tmp;
// __asm fld f
//__asm fistp tmp
//__asm mov eax, tmp
return (long)f;
}
void Sys_SnapVector3( float *v ) { // bk001213 - see win32/win_shared.c
// bk001213 - old linux
v[0] = rint(v[0]);
v[1] = rint(v[1]);
v[2] = rint(v[2]);
}
#endif
void Sys_Mkdir( const char *path )
{
mkdir (path, 0777);
}
char *strlwr (char *s) {
if ( s==NULL ) { // bk001204 - paranoia
assert(0);
return s;
}
while (*s) {
*s = tolower(*s);
s++;
}
return s; // bk001204 - duh
}
//============================================
#define MAX_FOUND_FILES 0x1000
// bk001129 - new in 1.26
void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, char **list, int *numfiles ) {
char search[MAX_OSPATH], newsubdirs[MAX_OSPATH];
char filename[MAX_OSPATH];
DIR *fdir;
struct dirent *d;
struct stat st;
if ( *numfiles >= MAX_FOUND_FILES - 1 ) {
return;
}
if (strlen(subdirs)) {
Com_sprintf( search, sizeof(search), "%s/%s", basedir, subdirs );
}
else {
Com_sprintf( search, sizeof(search), "%s", basedir );
}
if ((fdir = opendir(search)) == NULL) {
return;
}
while ((d = readdir(fdir)) != NULL) {
Com_sprintf(filename, sizeof(filename), "%s/%s", search, d->d_name);
if (stat(filename, &st) == -1)
continue;
if (st.st_mode & S_IFDIR) {
if (Q_stricmp(d->d_name, ".") && Q_stricmp(d->d_name, "..")) {
if (strlen(subdirs)) {
Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s/%s", subdirs, d->d_name);
}
else {
Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s", d->d_name);
}
Sys_ListFilteredFiles( basedir, newsubdirs, filter, list, numfiles );
}
}
if ( *numfiles >= MAX_FOUND_FILES - 1 ) {
break;
}
Com_sprintf( filename, sizeof(filename), "%s/%s", subdirs, d->d_name );
if (!Com_FilterPath( filter, filename, qfalse ))
continue;
list[ *numfiles ] = CopyString( filename );
(*numfiles)++;
}
closedir(fdir);
}
// bk001129 - in 1.17 this used to be
// char **Sys_ListFiles( const char *directory, const char *extension, int *numfiles, qboolean wantsubs )
char **Sys_ListFiles( const char *directory, const char *extension, char *filter, int *numfiles, qboolean wantsubs )
{
struct dirent *d;
// char *p; // bk001204 - unused
DIR *fdir;
qboolean dironly = wantsubs;
char search[MAX_OSPATH];
int nfiles;
char **listCopy;
char *list[MAX_FOUND_FILES];
//int flag; // bk001204 - unused
int i;
struct stat st;
int extLen;
if (filter) {
nfiles = 0;
Sys_ListFilteredFiles( directory, "", filter, list, &nfiles );
list[ nfiles ] = 0;
*numfiles = nfiles;
if (!nfiles)
return NULL;
listCopy = (char **)Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ),TAG_FILESYS,qfalse );
for ( i = 0 ; i < nfiles ; i++ ) {
listCopy[i] = list[i];
}
listCopy[i] = NULL;
return listCopy;
}
if ( !extension)
extension = "";
if ( extension[0] == '/' && extension[1] == 0 ) {
extension = "";
dironly = qtrue;
}
extLen = strlen( extension );
// search
nfiles = 0;
if ((fdir = opendir(directory)) == NULL) {
*numfiles = 0;
return NULL;
}
while ((d = readdir(fdir)) != NULL) {
Com_sprintf(search, sizeof(search), "%s/%s", directory, d->d_name);
if (stat(search, &st) == -1)
continue;
if ((dironly && !(st.st_mode & S_IFDIR)) ||
(!dironly && (st.st_mode & S_IFDIR)))
continue;
if (*extension) {
if ( strlen( d->d_name ) < strlen( extension ) ||
Q_stricmp(
d->d_name + strlen( d->d_name ) - strlen( extension ),
extension ) ) {
continue; // didn't match
}
}
if ( nfiles == MAX_FOUND_FILES - 1 )
break;
list[ nfiles ] = CopyString( d->d_name );
nfiles++;
}
list[ nfiles ] = 0;
closedir(fdir);
// return a copy of the list
*numfiles = nfiles;
if ( !nfiles ) {
return NULL;
}
listCopy = (char **)Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ),TAG_FILESYS,qfalse );
for ( i = 0 ; i < nfiles ; i++ ) {
listCopy[i] = list[i];
}
listCopy[i] = NULL;
return listCopy;
}
void Sys_FreeFileList( char **list ) {
int i;
if ( !list ) {
return;
}
for ( i = 0 ; list[i] ; i++ ) {
Z_Free( list[i] );
}
Z_Free( list );
}
char *Sys_Cwd( void )
{
static char cwd[MAX_OSPATH];
getcwd( cwd, sizeof( cwd ) - 1 );
cwd[MAX_OSPATH-1] = 0;
return cwd;
}
void Sys_SetDefaultCDPath(const char *path)
{
Q_strncpyz(cdPath, path, sizeof(cdPath));
}
char *Sys_DefaultCDPath(void)
{
return cdPath;
}
void Sys_SetDefaultInstallPath(const char *path)
{
Q_strncpyz(installPath, path, sizeof(installPath));
}
char *Sys_DefaultInstallPath(void)
{
if (*installPath)
return installPath;
else
return Sys_Cwd();
}
void Sys_SetDefaultHomePath(const char *path)
{
Q_strncpyz(homePath, path, sizeof(homePath));
}
char *Sys_DefaultHomePath(void)
{
char *p;
if (*homePath)
return homePath;
if ((p = getenv("HOME")) != NULL) {
Q_strncpyz(homePath, p, sizeof(homePath));
#ifdef MACOS_X
Q_strcat(homePath, sizeof(homePath), "/Library/Application Support/Quake3");
#else
Q_strcat(homePath, sizeof(homePath), "/.jkii");
#endif
if (mkdir(homePath, 0777)) {
if (errno != EEXIST)
Sys_Error("Unable to create directory \"%s\", error is %s(%d)\n", homePath, strerror(errno), errno);
}
return homePath;
}
return ""; // assume current dir
}
//============================================
int Sys_GetProcessorId( void )
{
return CPUID_GENERIC;
}
void Sys_ShowConsole( int visLevel, qboolean quitOnClose )
{
}
char *Sys_GetCurrentUser( void )
{
struct passwd *p;
if ( (p = getpwuid( getuid() )) == NULL ) {
return "player";
}
return p->pw_name;
}

8
codemp/unix/vm_x86.c Normal file
View File

@@ -0,0 +1,8 @@
#include "../qcommon/vm_local.h"
void VM_Compile( vm_t *vm, vmHeader_t *header ) {}
int VM_CallCompiled( vm_t *vm, int *args ) {}