1
0
Fork 0
forked from fte/fteqw

Committing this before I break it any more.

Massive terrain system rewrite.
Added a Native Client port (sound is stereo 44khz only, rendering is gles2, networking is websockets only (sv_port_tcp supports acting as a qw websockets server with non-nacl servers, filesystem is downloads-only - no saves/configs). Blame Zalon. Grr.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4013 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2012-04-09 19:12:12 +00:00
parent 9657eb2637
commit 82542ae037
70 changed files with 5297 additions and 1068 deletions

View file

@ -246,6 +246,7 @@ HTTP_DIR=$(BASE_DIR)/http
LIBS_DIR?=.
PROGS_DIR=$(BASE_DIR)/qclib
SNDCODEC_DIR=$(BASE_DIR)/sndcodec
NACL_DIR=$(BASE_DIR)/nacl
BOTLIB_DIR=$(BASE_DIR)/botlib
RELEASE_DIR=$(BASE_DIR)/release
@ -589,6 +590,27 @@ endif
#specific targets override those defaults as needed.
#google native client
ifeq ($(FTE_TARGET),nacl)
ifeq ($(shell uname -o 2>&1 | grep Cygwin),)
CC=$(NACL_SDK_ROOT)/toolchain/linux_x86_newlib/bin/i686-nacl-gcc -DNACL -m$(BITS)
STRIP=$(NACL_SDK_ROOT)/toolchain/linux_x86_newlib/bin/i686-nacl-strip
else
CC=$(NACL_SDK_ROOT)/toolchain/win_x86_newlib/bin/i686-nacl-gcc -DNACL -m$(BITS)
STRIP=$(NACL_SDK_ROOT)/toolchain/win_x86_newlib/bin/i686-nacl-strip
endif
BASELDFLAGS = -lm -lpthread -lppapi_gles2 -lnosys -lppapi
IMAGELDFLAGS =
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) sys_ppapi.o cd_null.o gl_vidppapi.o in_generic.o fs_ppapi.o snd_ppapi.o
GLB_DIR=gl_nacl_x86_$(BITS)
GL_EXE_NAME=../fteqw_x86_$(BITS).nexe
GLCL_EXE_NAME=../fteqwcl_x86_$(BITS).nexe
MINGL_DIR=mingl_nacl_x86_$(BITS)
MINGL_EXE_NAME=../fteqw_mingl_x86_$(BITS).nexe
endif
#FTE_TARGET=win32_SDL | FTE_TARGET=win64_SDL (MinGW32 + SDL | MinGW64 + SDL)
ifeq ($(shell echo $(FTE_TARGET)|grep -E -i -v "win(32|64)_sdl$$"),)
@ -948,7 +970,7 @@ ifneq ($(OUT_DIR),)
endif
VPATH = $(BASE_DIR) : $(CLIENT_DIR) : $(GL_DIR) : $(COMMON_DIR) : $(SERVER_DIR) : $(HTTP_DIR) : $(BASE_DIR)/irc : $(BASE_DIR)/email : $(QUX_DIR) : $(PROGS_DIR) : $(SNDCODEC_DIR) : $(D3D_DIR) : $(BOTLIB_DIR)
VPATH = $(BASE_DIR) : $(CLIENT_DIR) : $(GL_DIR) : $(COMMON_DIR) : $(SERVER_DIR) : $(HTTP_DIR) : $(BASE_DIR)/irc : $(BASE_DIR)/email : $(QUX_DIR) : $(PROGS_DIR) : $(NACL_DIR) : $(SNDCODEC_DIR) : $(D3D_DIR) : $(BOTLIB_DIR)
# This is for linking the FTE icon to the MinGW target
$(OUT_DIR)/resources.o : winquake.rc

View file

@ -162,7 +162,7 @@ extern player_t *mplayers;
void Master_SetupSockets(void);
void CL_QueryServers(void);
int NET_CheckPollSockets(void);
int Master_CheckPollSockets(void);
void MasterInfo_Request(master_t *mast, qboolean evenifwedonthavethefiles);
serverinfo_t *Master_InfoForServer (netadr_t addr);
serverinfo_t *Master_InfoForNum (int num);

View file

@ -764,6 +764,7 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
case UI_CMD_EXECUTETEXT:
{
char *cmdtext = VM_POINTER(arg[1]);
#ifdef CL_MASTER
if (!strncmp(cmdtext, "ping ", 5))
{
int i;
@ -785,10 +786,8 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
{
MasterInfo_Refresh();
}
/* else if (!strncmp(cmdtext, "r_vidmode", 12))
{
}
*/ else
else
#endif
Cbuf_AddText(cmdtext, RESTRICT_SERVER);
}
break;
@ -987,6 +986,7 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
#endif
break;
#ifdef CL_MASTER
case UI_LAN_GETPINGQUEUECOUNT: //these four are master server polling.
{
int i;
@ -1007,7 +1007,7 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
if ((int)arg[3] + sizeof(int) >= mask || VM_POINTER(arg[3]) < offset)
break; //out of bounds.
NET_CheckPollSockets();
Master_CheckPollSockets();
if (VM_LONG(arg[0])>= 0 && VM_LONG(arg[0]) <= MAX_PINGREQUESTS)
{
char *buf = VM_POINTER(arg[1]);
@ -1034,7 +1034,7 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
if ((int)arg[3] + sizeof(int) >= mask || VM_POINTER(arg[3]) < offset)
break; //out of bounds.
NET_CheckPollSockets();
Master_CheckPollSockets();
if (VM_LONG(arg[0])>= 0 && VM_LONG(arg[0]) <= MAX_PINGREQUESTS)
{
char *buf = VM_POINTER(arg[1]);
@ -1062,6 +1062,7 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
strcpy(buf, "");
}
break;
#endif
case UI_CVAR_REGISTER:
if (VM_OOB(arg[0], sizeof(vmcvar_t)))
@ -1100,6 +1101,7 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
VM_FLOAT(ret) = realtime;
break;
#ifdef CL_MASTER
case UI_LAN_GETSERVERCOUNT: //LAN Get server count
//int (int source)
VM_LONG(ret) = Master_TotalCount();
@ -1136,6 +1138,7 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
case UI_LAN_SERVERISVISIBLE:
return 1;
break;
#endif
case UI_VERIFY_CDKEY:
VM_LONG(ret) = true;

View file

@ -923,7 +923,7 @@ int Con_DrawInput (int left, int right, int y)
/*if its getting completed to something, show some help about the command that is going to be used*/
if (!text[1])
con_commandmatch = 0;
if (con_commandmatch && Cmd_IsCommand(text+(text[1] == '/'?2:1)))
if (con_commandmatch && fname && Cmd_IsCommand(text+(text[1] == '/'?2:1)))
{
cvar_t *var;
char *desc = NULL;

365
engine/client/in_generic.c Normal file
View file

@ -0,0 +1,365 @@
#include "quakedef.h"
extern qboolean mouse_active;
cvar_t m_simtouch = CVARF("m_simtouch", "0", CVAR_ARCHIVE);
cvar_t m_filter = CVARF("m_filter", "0", CVAR_ARCHIVE);
cvar_t m_strafeonright = CVARFD("m_strafeonright", "1", CVAR_ARCHIVE, "If 1, touching the right half of the touchscreen will strafe/move, while the left side will turn.");
extern cvar_t _windowed_mouse;
int mousecursor_x, mousecursor_y; /*absolute position*/
extern int mousemove_x, mousemove_y;
static float mouse_x, mouse_y;
static float mousestrafe_x, mousestrafe_y;
static float old_mouse_x, old_mouse_y; /*for smoothing*/
#define EVENTQUEUELENGTH 128
struct eventlist_s
{
enum
{
IEV_KEYDOWN,
IEV_KEYRELEASE,
IEV_MOUSEABS,
IEV_MOUSEDELTA
} type;
int devid;
union
{
struct
{
float x, y;
} mouse;
struct
{
int scancode, unicode;
} keyboard;
};
} eventlist[EVENTQUEUELENGTH];
volatile int events_avail; /*volatile to make sure the cc doesn't try leaving these cached in a register*/
volatile int events_used;
static struct eventlist_s *in_newevent(void)
{
if (events_avail >= events_used + EVENTQUEUELENGTH)
return NULL;
return &eventlist[events_avail & (EVENTQUEUELENGTH-1)];
}
static struct eventlist_s *in_lastevent(void)
{
if (events_avail == events_used)
return NULL;
return &eventlist[(events_avail-1) & (EVENTQUEUELENGTH-1)];
}
static void in_finishevent(void)
{
events_avail++;
}
#define MAXPOINTERS 8
struct
{
vec2_t oldpos;
vec2_t downpos;
float movedist;
vec2_t move;
enum
{
MT_UNPRESSED,
MT_PRESSED,
MT_DELTA
} mtype;
} ptr[MAXPOINTERS];
void IN_Shutdown(void)
{
}
void IN_ReInit()
{
Cvar_Register (&m_simtouch, "input controls");
Cvar_Register (&m_filter, "input controls");
Cvar_Register (&m_strafeonright, "input controls");
}
void IN_Init(void)
{
IN_ReInit();
}
/*on android, each 'pointer' is a separate touch location*/
void IN_Commands(void)
{
struct eventlist_s *ev;
while (events_used != events_avail)
{
ev = &eventlist[events_used & (EVENTQUEUELENGTH-1)];
switch(ev->type)
{
case IEV_KEYDOWN:
case IEV_KEYRELEASE:
if (ev->keyboard.scancode == K_MOUSE1 && ev->devid < MAXPOINTERS && ptr[ev->devid].mtype != MT_DELTA)
{
if (Key_MouseShouldBeFree())
ptr[ev->devid].mtype = MT_UNPRESSED;
else
{
if (ev->type == IEV_KEYDOWN)
{
ptr[ev->devid].mtype = MT_PRESSED;
ptr[ev->devid].movedist = 0;
ptr[ev->devid].downpos[0] = ptr[ev->devid].oldpos[0];
ptr[ev->devid].downpos[1] = ptr[ev->devid].oldpos[1];
ptr[ev->devid].move[0] = 0;
ptr[ev->devid].move[1] = 0;
}
else
{
if (ptr[ev->devid].mtype == MT_PRESSED)
{
if (ptr[ev->devid].movedist < 5)
{
/*if its on the right, make it a mouse2*/
int key = (m_strafeonright.ival && ptr[ev->devid].downpos[0] > vid.pixelwidth/2)?K_MOUSE3:K_MOUSE1;
Key_Event(ev->devid, key, 0, true);
Key_Event(ev->devid, key, 0, false);
}
}
ptr[ev->devid].mtype = MT_UNPRESSED;
}
break;
}
}
Key_Event(ev->devid, ev->keyboard.scancode, ev->keyboard.unicode, ev->type == IEV_KEYDOWN);
break;
case IEV_MOUSEABS:
/*mouse cursors only really work with one pointer*/
if (ev->devid == 0)
{
mousecursor_x = bound(0, ev->mouse.x, vid.width - 1);
mousecursor_y = bound(0, ev->mouse.y, vid.height - 1);
}
if (ev->devid < MAXPOINTERS)
{
if (ptr[ev->devid%MAXPOINTERS].mtype == MT_DELTA)
ptr[ev->devid%MAXPOINTERS].mtype = MT_UNPRESSED;
ptr[ev->devid].move[0] += ev->mouse.x - ptr[ev->devid].oldpos[0];
ptr[ev->devid].move[1] += ev->mouse.y - ptr[ev->devid].oldpos[1];
ptr[ev->devid].movedist += fabs(ev->mouse.x - ptr[ev->devid].oldpos[0]) + fabs(ev->mouse.y - ptr[ev->devid].oldpos[1]);
ptr[ev->devid].oldpos[0] = ev->mouse.x;
ptr[ev->devid].oldpos[1] = ev->mouse.y;
}
break;
case IEV_MOUSEDELTA:
/*unlike abs, we can combine the mice properly*/
mousecursor_x += ev->mouse.x;
mousecursor_y += ev->mouse.y;
mousecursor_x = bound(0, mousecursor_x, vid.width - 1);
mousecursor_y = bound(0, mousecursor_y, vid.height - 1);
ptr[ev->devid%MAXPOINTERS].move[0] += ev->mouse.x;
ptr[ev->devid%MAXPOINTERS].move[1] += ev->mouse.y;
ptr[ev->devid%MAXPOINTERS].movedist += fabs(ev->mouse.x) + fabs(ev->mouse.y);
if (m_simtouch.ival)
{
if (ptr[ev->devid%MAXPOINTERS].mtype == MT_DELTA)
ptr[ev->devid%MAXPOINTERS].mtype = MT_UNPRESSED;
ptr[ev->devid].oldpos[0] = mousecursor_x;
ptr[ev->devid].oldpos[1] = mousecursor_y;
}
else
ptr[ev->devid%MAXPOINTERS].mtype = MT_DELTA;
break;
}
events_used++;
}
}
static void IN_Update(qboolean ingame)
{
int i;
//strafing speed is absolute
mousestrafe_x = 0;
mousestrafe_y = 0;
for (i = 0; i < MAXPOINTERS; i++)
{
/*ignore if no action, to avoid phantom csqc input events*/
if (ptr[i].mtype == MT_UNPRESSED && !ptr[i].move[0] && !ptr[i].move[1])
continue;
if (ptr[i].mtype == MT_DELTA || !CSQC_MousePosition(ptr[i].oldpos[0], ptr[i].oldpos[1], i))
{
if (!CSQC_MouseMove(ptr[i].move[0], ptr[i].move[1], i))
{
switch(ptr[i].mtype)
{
case MT_UNPRESSED:
break;
case MT_PRESSED:
if (m_strafeonright.ival && ptr[i].downpos[0] > vid.pixelwidth/2 && ingame)
{
mousestrafe_x += ptr[i].oldpos[0] - ptr[i].downpos[0];
mousestrafe_y += ptr[i].oldpos[1] - ptr[i].downpos[1];
}
else
{
mouse_x += ptr[i].move[0];
mouse_y += ptr[i].move[1];
}
break;
case MT_DELTA:
mouse_x += ptr[i].move[0];
mouse_y += ptr[i].move[1];
break;
}
}
}
ptr[i].move[0] = 0;
ptr[i].move[1] = 0;
}
}
void IN_Move (float *movements, int pnum)
{
qboolean ingame;
extern int mousecursor_x, mousecursor_y;
if (pnum != 0)
return; //we're lazy today.
ingame = movements != NULL && (key_dest == key_game);
IN_Update(ingame);
if (m_filter.value)
{
mouse_x = (mouse_x + old_mouse_x) * 0.5;
mouse_y = (mouse_y + old_mouse_y) * 0.5;
}
old_mouse_x = mouse_x;
old_mouse_y = mouse_y;
if(in_xflip.value) mouse_x *= -1;
mousemove_x += mouse_x;
mousemove_y += mouse_y;
if (!ingame)
{
mouse_x = mouse_y = 0;
#ifdef VM_UI
UI_MousePosition(mousecursor_x, mousecursor_y);
#endif
}
/*if the look-mouse is set to always strafe instead...*/
if ( (in_strafe.state[pnum] & 1) || (lookstrafe.value && (in_mlook.state[pnum] & 1) ))
{
mousestrafe_x += mouse_x;
mouse_x = 0;
}
if ( (in_strafe.state[pnum] & 1) || !(in_mlook.state[pnum] & 1))
{
mousestrafe_y += mouse_y;
mouse_y = 0;
}
/*handle strafes*/
if (movements)
{
float scale;
scale = m_side.value * sensitivity.value;
movements[1] += mousestrafe_x * scale;
scale = m_forward.value * sensitivity.value;
if ((in_strafe.state[pnum] & 1) && noclip_anglehack)
movements[2] -= mousestrafe_y * scale;
else
movements[0] -= mousestrafe_y * scale;
}
if (in_mlook.state[pnum] & 1)
V_StopPitchDrift (pnum);
/*handle looks*/
cl.viewanglechange[pnum][YAW] -= m_yaw.value * mouse_x * sensitivity.value;
cl.viewanglechange[pnum][PITCH] += m_pitch.value * mouse_y * sensitivity.value;
mouse_x = mouse_y = 0.0;
}
/*regular key event*/
void IN_QueueKey(int down, int keycode, int unicode)
{
struct eventlist_s *ev = in_newevent();
if (!ev)
return;
ev->type = down?IEV_KEYDOWN:IEV_KEYRELEASE;
ev->devid = 0;
ev->keyboard.scancode = keycode;
ev->keyboard.unicode = unicode;
in_finishevent();
}
/*
in ppapi, we have 'keycode' and 'char' events completely separately
this doesn't match the rest of the system very well
so we update the previous key event instead, where possible (IME can still trigger multiple chars at a time)
this is risky and may drop the key in rare situations
*/
void IN_AmmendUnicode(int unicode)
{
struct eventlist_s *ev = in_lastevent();
if (ev && ev->type == IEV_KEYDOWN)
{
if (!ev->keyboard.unicode)
{
ev->keyboard.unicode = unicode;
return;
}
}
/*last command was already used? that makes things painful. maybe noone will notice*/
IN_QueueKey(true, 0, unicode);
IN_QueueKey(false, 0, unicode);
}
void IN_QueueMouse(int act, int ptrid, float x, float y, int button)
{
struct eventlist_s *ev = in_newevent();
if (!ev)
return;
ev->devid = ptrid;
switch(act)
{
case 0:
case 3:
ev->type = (act==0)?IEV_MOUSEABS:IEV_MOUSEDELTA;
ev->mouse.x = x;
ev->mouse.y = y;
break;
case 1:
case 2:
ev->type = (act==1)?IEV_KEYDOWN:IEV_KEYRELEASE;
ev->keyboard.scancode = K_MOUSE1+button;
ev->keyboard.unicode = 0;
break;
}
in_finishevent();
}

View file

@ -674,13 +674,13 @@ void Key_Console (unsigned int unicode, int key)
return;
}
if (((key=='C' || key=='c') && keydown[K_CTRL]) || (keydown[K_CTRL] && key == K_INS))
if (((unicode=='C' || unicode=='c') && keydown[K_CTRL]) || (keydown[K_CTRL] && key == K_INS))
{
Sys_SaveClipboard(key_lines[edit_line]+1);
return;
}
if (((key=='V' || key=='v') && keydown[K_CTRL]) || (keydown[K_SHIFT] && key == K_INS))
if (((unicode=='V' || unicode=='v') && keydown[K_CTRL]) || (keydown[K_SHIFT] && key == K_INS))
{
clipText = Sys_GetClipboard();
if (clipText)
@ -1587,9 +1587,9 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
}
#endif
if ( (key_dest == key_menu && menubound[key])
if (key && ((key_dest == key_menu && menubound[key])
|| (key_dest == key_console && !consolekeys[key])
|| (key_dest == key_game && ( cls.state == ca_active || !consolekeys[key] ) ) )
|| (key_dest == key_game && ( cls.state == ca_active || !consolekeys[key] ) ) ))
{
/*don't auto-repeat binds as it breaks too many scripts*/
if (key_repeats[key] > 1)
@ -1649,7 +1649,7 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
#endif
case key_game:
case key_console:
if ((key >= ' ' && key <= 127) || key == K_ENTER || key == K_TAB)
if ((unicode) || key == K_ENTER || key == K_TAB)
key_dest = key_console;
Key_Console (unicode, key);
break;

View file

@ -337,7 +337,7 @@ joinserver:
static void SL_PreDraw (menu_t *menu)
{
serverlist_t *info = (serverlist_t*)(menu + 1);
NET_CheckPollSockets();
Master_CheckPollSockets();
CL_QueryServers();
@ -692,7 +692,7 @@ static void M_QuickConnect_PreDraw(menu_t *menu)
serverinfo_t *s;
char adr[MAX_ADR_SIZE];
NET_CheckPollSockets(); //see if we were told something important.
Master_CheckPollSockets(); //see if we were told something important.
CL_QueryServers();
if (Sys_DoubleTime() > quickconnecttimeout)

View file

@ -2283,7 +2283,7 @@ static void MSD_SetUnderWater(soundcardinfo_t *sc, qboolean underwater)
{
}
static void *MSD_Lock (soundcardinfo_t *sc)
static void *MSD_Lock (soundcardinfo_t *sc, unsigned int *sampidx)
{
return sc->sn.buffer;
}

View file

@ -860,7 +860,9 @@ void M_Init_Internal (void)
Cmd_AddRemCommand ("menu_download", Menu_DownloadStuff_f);
#endif
#ifdef CL_MASTER
Cmd_AddRemCommand ("quickconnect", M_QuickConnect_f);
#endif
}
void M_DeInit_Internal (void)

View file

@ -862,7 +862,7 @@ void NET_SendPollPacket(int len, void *data, netadr_t to)
}
}
int NET_CheckPollSockets(void)
int Master_CheckPollSockets(void)
{
int sock;
SOCKET usesocket;

View file

@ -645,6 +645,7 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
}
else
{
out->flags |= RF_FORCECOLOURMOD;
out->shaderRGBAf[0] = in->xv->colormod[0];
out->shaderRGBAf[1] = in->xv->colormod[1];
out->shaderRGBAf[2] = in->xv->colormod[2];
@ -2089,9 +2090,16 @@ static void QCBUILTIN PF_cs_getinputstate (progfuncs_t *prinst, struct globalvar
G_FLOAT(OFS_RETURN) = false;
return;
}
if (cl.paused)
f = cls.netchan.outgoing_sequence;
/*outgoing_sequence says how many packets have actually been sent, but there's an extra pending packet which has not been sent yet - be warned though, its data will change in the coming frames*/
if (f == cls.netchan.outgoing_sequence)
{
cmd = &independantphysics[csqc_lplayernum];
for (f=0 ; f<3 ; f++)
cmd->angles[f] = ((int)(cl.viewangles[csqc_lplayernum][f]*65536.0/360)&65535);
}
else
cmd = &cl.frames[f&UPDATE_MASK].cmd[csqc_lplayernum];
@ -4721,7 +4729,17 @@ void CSQC_EntSpawn (struct edict_s *e, int loading)
if (!ent->xv)
ent->xv = (csqcextentvars_t *)(ent->v+1);
#endif
if (1)
{
// ent->xv->dimension_see = 255;
// ent->xv->dimension_seen = 255;
// ent->xv->dimension_ghost = 0;
ent->xv->dimension_solid = 255;
ent->xv->dimension_hit = 255;
}
}
pbool CSQC_EntFree (struct edict_s *e)
{
struct csqcedict_s *ent = (csqcedict_t*)e;

View file

@ -999,12 +999,12 @@ void QCBUILTIN PF_M_gethostcachevalue (progfuncs_t *prinst, struct globalvars_s
{
case SLIST_HOSTCACHEVIEWCOUNT:
CL_QueryServers();
NET_CheckPollSockets();
Master_CheckPollSockets();
G_FLOAT(OFS_RETURN) = Master_NumSorted();
return;
case SLIST_HOSTCACHETOTALCOUNT:
CL_QueryServers();
NET_CheckPollSockets();
Master_CheckPollSockets();
G_FLOAT(OFS_RETURN) = Master_TotalCount();
return;
@ -1653,8 +1653,13 @@ builtin_t menu_builtins[] = {
PF_cl_getresolution,
PF_cl_keynumtostring,
PF_cl_findkeysforcommand,
#ifdef CL_MASTER
PF_M_gethostcachevalue,
PF_M_gethostcachestring,
#else
skip1
skip1
#endif
PF_parseentitydata, //void parseentitydata(entity ent, string data) = #613;
PF_cl_stringtokeynum,
@ -1668,8 +1673,13 @@ builtin_t menu_builtins[] = {
PF_M_gethostcachenumber,
PF_M_gethostcacheindexforkey,
PF_M_addwantedhostcachekey,
#ifdef CL_MASTER
PF_M_getextresponse, // #624
PF_netaddress_resolve,
#else
skip1
skip1
#endif
skip1 /*get gamedir info*/
PF_sprintf, /*sprintf*/
skip1 /*not listed in dp*/

View file

@ -1419,7 +1419,7 @@ start:
if (node->visframe != r_visframecount)
return;
for (c = 0, clipplane = frustum; c < 4; c++, clipplane++)
for (c = 0, clipplane = frustum; c < FRUSTUMPLANES; c++, clipplane++)
{
if (!(clipflags & (1 << c)))
continue; // don't need to clip against it
@ -1640,7 +1640,7 @@ static void Surf_LeafWorldNode (void)
// if (!r_nocull->value)
{
for (i=0,clipplane=frustum ; i<4 ; i++,clipplane++)
for (i=0,clipplane=frustum ; i<5 ; i++,clipplane++)
{
clipped = BoxOnPlaneSide (pleaf->minmaxs, pleaf->minmaxs+3, clipplane);
if (clipped == 2)
@ -2016,7 +2016,7 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent)
b->firstmesh = 0;
b->lightmap = s->lightmaptexturenum;
b->mesh = NULL;
b->vbo = NULL;
b->vbo = &b->texture->vbo;
}
b->surf_count++;
@ -2120,7 +2120,7 @@ void Surf_DrawWorld (void)
if (!(r_novis.ival & 2))
VectorCopy (r_refdef.vieworg, modelorg);
Surf_RecursiveWorldNode (cl.worldmodel->nodes, 0xf);
Surf_RecursiveWorldNode (cl.worldmodel->nodes, 0x1f);
}
}
@ -2154,7 +2154,7 @@ void Surf_DrawWorld (void)
*/
// returns a texture number and the position inside it
static int Surf_LM_AllocBlock (int w, int h, int *x, int *y, shader_t *shader)
int Surf_LM_AllocBlock (int w, int h, int *x, int *y, shader_t *shader)
{
int i, j;
int best, best2;
@ -2711,6 +2711,11 @@ void Surf_BuildLightmaps (void)
batch->mesh = BZ_Malloc(sizeof(*batch->mesh)*batch->maxmeshes*2);
}
BE_GenBrushModelVBO(m);
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
for (batch = m->batches[sortid]; batch != NULL; batch = batch->next)
{
batch->vbo = &batch->texture->vbo;
}
}
BE_UploadAllLightmaps();

View file

@ -38,7 +38,7 @@ struct texture_s;
static const texid_t r_nulltex = {{0}};
#if defined(D3DQUAKE) || defined(ANDROID)
#if 1 || defined(MINIMAL) || defined(D3DQUAKE) || defined(ANDROID)
#define sizeof_index_t 2
#endif
#if sizeof_index_t == 2
@ -412,7 +412,7 @@ extern cvar_t r_fullbright;
extern cvar_t r_lightmap;
extern cvar_t r_glsl_offsetmapping;
extern cvar_t r_shadow_realtime_dlight, r_shadow_realtime_dlight_shadows;
extern cvar_t r_shadow_realtime_world,r_shadow_realtime_world_shadows;
extern cvar_t r_shadow_realtime_world, r_shadow_realtime_world_shadows;
extern cvar_t r_mirroralpha;
extern cvar_t r_wateralpha;
extern cvar_t r_dynamic;

View file

@ -332,6 +332,8 @@ cvar_t vid_hardwaregamma = SCVARF ("vid_hardwaregamma", "1",
cvar_t vid_desktopgamma = SCVARF ("vid_desktopgamma", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH);
cvar_t r_fog_exp2 = CVARD ("r_fog_exp2", "1", "Expresses how fog fades with distance. 0 (matching DarkPlaces) is typically more realistic, while 1 (matching FitzQuake and others) is more common.");
extern cvar_t gl_dither;
cvar_t gl_screenangle = SCVAR("gl_screenangle", "0");
@ -416,6 +418,7 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_overbright, GRAPHICALNICETIES);
Cvar_Register (&gl_overbright_all, GRAPHICALNICETIES);
Cvar_Register (&gl_dither, GRAPHICALNICETIES);
Cvar_Register (&r_fog_exp2, GLRENDEREROPTIONS);
Cvar_Register (&gl_ati_truform, GRAPHICALNICETIES);
Cvar_Register (&gl_ati_truform_type, GRAPHICALNICETIES);
@ -1924,7 +1927,7 @@ qbyte *R_MarkLeaves_Q1 (void)
}
mplane_t frustum[4];
mplane_t frustum[FRUSTUMPLANES];
/*
@ -1938,7 +1941,7 @@ qboolean R_CullBox (vec3_t mins, vec3_t maxs)
{
int i;
for (i=0 ; i<4 ; i++)
for (i=0 ; i<FRUSTUMPLANES ; i++)
if (BOX_ON_PLANE_SIDE (mins, maxs, &frustum[i]) == 2)
return true;
return false;
@ -1950,7 +1953,7 @@ qboolean R_CullSphere (vec3_t org, float radius)
int i;
float d;
for (i=0 ; i<4 ; i++)
for (i=0 ; i<FRUSTUMPLANES ; i++)
{
d = DotProduct(frustum[i].normal, org)-frustum[i].dist;
if (d <= -radius)
@ -2081,6 +2084,67 @@ void R_SetFrustum (float projmat[16], float viewmat[16])
frustum[i].type = PLANE_ANYZ;
frustum[i].signbits = SignbitsForPlane (&frustum[i]);
}
#if FRUSTUMPLANES > 4
//do far plane
//fog will not logically not actually reach 0, though precision issues will force it. we cut off at an exponant of -500
if (r_refdef.gfog_rgbd[3])
{
float culldist;
float fog;
extern cvar_t r_fog_exp2;
/*Documentation: the GLSL/GL will do this maths:
float dist = 1024;
if (r_fog_exp2.ival)
fog = pow(2, -r_refdef.gfog_rgbd[3] * r_refdef.gfog_rgbd[3] * dist * dist * 1.442695);
else
fog = pow(2, -r_refdef.gfog_rgbd[3] * dist * 1.442695);
*/
//the fog factor cut-off where its pointless to allow it to get closer to 0 (0 is technically infinite)
fog = 2/255.0f;
//figure out the eyespace distance required to reach that fog value
culldist = log(fog);
if (r_fog_exp2.ival)
culldist = sqrt(culldist / (-r_refdef.gfog_rgbd[3] * r_refdef.gfog_rgbd[3]));
else
culldist = culldist / (-r_refdef.gfog_rgbd[3]);
//anything drawn beyond this point is fully obscured by fog
frustum[4].normal[0] = mvp[3] - mvp[2];
frustum[4].normal[1] = mvp[7] - mvp[6];
frustum[4].normal[2] = mvp[11] - mvp[10];
frustum[4].dist = mvp[15] - mvp[14];
scale = 1/sqrt(DotProduct(frustum[4].normal, frustum[4].normal));
frustum[4].normal[0] *= scale;
frustum[4].normal[1] *= scale;
frustum[4].normal[2] *= scale;
// frustum[4].dist *= scale;
frustum[4].dist = DotProduct(r_origin, frustum[4].normal)-culldist;
frustum[4].type = PLANE_ANYZ;
frustum[4].signbits = SignbitsForPlane (&frustum[4]);
}
else
{
frustum[4].normal[0] = mvp[3] - mvp[2];
frustum[4].normal[1] = mvp[7] - mvp[6];
frustum[4].normal[2] = mvp[11] - mvp[10];
frustum[4].dist = mvp[15] - mvp[14];
scale = 1/sqrt(DotProduct(frustum[4].normal, frustum[4].normal));
frustum[4].normal[0] *= scale;
frustum[4].normal[1] *= scale;
frustum[4].normal[2] *= scale;
frustum[4].dist *= -scale;
frustum[4].type = PLANE_ANYZ;
frustum[4].signbits = SignbitsForPlane (&frustum[4]);
}
#endif
}
#else
void R_SetFrustum (void)

View file

@ -581,7 +581,7 @@ static void OnChangeALDistanceModel (cvar_t *var, char *value)
}
/*stub should not be called*/
static void *OpenAL_LockBuffer (soundcardinfo_t *sc)
static void *OpenAL_LockBuffer (soundcardinfo_t *sc, unsigned int *sampidx)
{
//Con_Printf("OpenAL: LockBuffer\n");
return NULL;

View file

@ -170,7 +170,7 @@ static void ALSA_Shutdown (soundcardinfo_t *sc)
free(sc->sn.buffer);
}
static void *ALSA_LockBuffer(soundcardinfo_t *sc)
static void *ALSA_LockBuffer(soundcardinfo_t *sc, unsigned int *sampidx)
{
return sc->sn.buffer;
}

View file

@ -87,7 +87,7 @@ static void DSOUND_Restore(soundcardinfo_t *sc)
}
DWORD dwSize;
static void *DSOUND_Lock(soundcardinfo_t *sc)
static void *DSOUND_Lock(soundcardinfo_t *sc, unsigned int *sampidx)
{
void *ret;
int reps;

View file

@ -642,6 +642,7 @@ sounddriver pSDL_InitCard;
sounddriver pWAV_InitCard;
sounddriver pDroid_InitCard;
sounddriver pAHI_InitCard;
sounddriver pPPAPI_InitCard;
typedef struct {
char *name;
@ -655,6 +656,7 @@ sdriver_t drivers[] = {
{"MacOS", &pMacOS_InitCard}, //prefered on mac
{"Droid", &pDroid_InitCard}, //prefered on android (java thread)
{"AHI", &pAHI_InitCard}, //prefered on morphos
{"PPAPI", &pPPAPI_InitCard}, //google's native client
{"SDL", &pSDL_InitCard}, //prefered on linux
{"ALSA", &pALSA_InitCard}, //pure shite
@ -1600,6 +1602,7 @@ static void S_StopAllSounds_f (void)
static void S_ClearBuffer (soundcardinfo_t *sc)
{
void *buffer;
unsigned int dummy;
int clear;
@ -1611,7 +1614,8 @@ static void S_ClearBuffer (soundcardinfo_t *sc)
else
clear = 0;
buffer = sc->Lock(sc);
dummy = 0;
buffer = sc->Lock(sc, &dummy);
if (buffer)
{
Q_memset(buffer, clear, sc->sn.samples * sc->sn.samplebits/8);

View file

@ -76,10 +76,10 @@ static void Droid_UnlockBuffer(soundcardinfo_t *sc, void *buffer)
// pthread_mutex_unlock(&mutex);
}
static void *Droid_LockBuffer(soundcardinfo_t *sc)
static void *Droid_LockBuffer(soundcardinfo_t *sc, unsigned int *sampidx)
{
// pthread_mutex_lock(&mutex);
return sc->sn.buffer;
return sc->sn.buffer;
}
static void Droid_SetUnderWater(soundcardinfo_t *sc, qboolean uw)

View file

@ -110,7 +110,7 @@ static void OSS_Shutdown(soundcardinfo_t *sc)
*sc->name = '\0';
}
static void *OSS_Lock(soundcardinfo_t *sc)
static void *OSS_Lock(soundcardinfo_t *sc, unsigned int *sampidx)
{
return sc->sn.buffer;
}

View file

@ -101,7 +101,7 @@ static void MacOS_Submit(soundcardinfo_t *sc)
{
}
static void *MacOS_Lock(soundcardinfo_t *sc)
static void *MacOS_Lock(soundcardinfo_t *sc, unsigned int *sampidx)
{
return sc->sn.buffer;
}

View file

@ -31,7 +31,7 @@ short *snd_out;
void S_TransferPaintBuffer(soundcardinfo_t *sc, int endtime)
{
unsigned int startidx, out_idx;
unsigned int out_idx;
unsigned int count;
unsigned int outlimit;
int *p;
@ -43,11 +43,11 @@ void S_TransferPaintBuffer(soundcardinfo_t *sc, int endtime)
p = (int *) paintbuffer;
count = (endtime - sc->paintedtime) * sc->sn.numchannels;
outlimit = sc->sn.samples;
startidx = out_idx = (sc->paintedtime * sc->sn.numchannels) % outlimit;
out_idx = (sc->paintedtime * sc->sn.numchannels) % outlimit;
snd_vol = (volume.value*voicevolumemod)*256;
numc = sc->sn.numchannels;
pbuf = sc->Lock(sc);
pbuf = sc->Lock(sc, &out_idx);
if (!pbuf)
return;

View file

@ -106,7 +106,7 @@ static void AHI_UnlockBuffer(soundcardinfo_t *sc, void *buffer)
{
}
static void *AHI_LockBuffer(soundcardinfo_t *sc)
static void *AHI_LockBuffer(soundcardinfo_t *sc, unsigned int *sampidx)
{
return sc->sn.buffer;
}

View file

@ -53,7 +53,7 @@ static void VARGS SSDL_Paint(void *userdata, qbyte *stream, int len)
sc->snd_sent += len;
}
static void *SSDL_LockBuffer(soundcardinfo_t *sc)
static void *SSDL_LockBuffer(soundcardinfo_t *sc, unsigned int *sampidx)
{
SDL_LockAudio();

View file

@ -75,7 +75,7 @@ void S_UnblockSound (void)
}
static void *WAV_Lock (soundcardinfo_t *sc)
static void *WAV_Lock (soundcardinfo_t *sc, unsigned int *sampidx)
{
return sc->sn.buffer;
}

View file

@ -285,7 +285,7 @@ struct soundcardinfo_s { //windows has one defined AFTER directsound
int samplequeue; //this is the number of samples the device can enqueue. if set, DMAPos returns the write point (rather than hardware read point) (in samplepairs).
//callbacks
void *(*Lock) (soundcardinfo_t *sc);
void *(*Lock) (soundcardinfo_t *sc, unsigned int *startoffset);
void (*Unlock) (soundcardinfo_t *sc, void *buffer);
void (*Submit) (soundcardinfo_t *sc, int start, int end);
void (*Shutdown) (soundcardinfo_t *sc);

View file

@ -48,8 +48,9 @@ JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_frame(JNIEnv *env, jobject
}
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_init(JNIEnv *env, jobject obj,
jint width, jint height, jstring path)
jint width, jint height, jstring japkpath, jstring jusrpath)
{
char *tmp;
vid.pixelwidth = width;
vid.pixelheight = height;
if (sys_running)
@ -60,13 +61,14 @@ JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_init(JNIEnv *env, jobject o
{
"ftedroid",
"-basepack",
(*env)->GetStringUTFChars(env, path, NULL),
NULL, /*filled in later*/
"",
""
//we should do this somewhere... (*env)->ReleaseStringUTFChars(env, path, parms.basedir);
};
quakeparms_t parms;
parms.basedir = "/sdcard/fte";
if (sys_memheap)
free(sys_memheap);
parms.basedir = NULL; /*filled in later*/
parms.argc = 3;
parms.argv = args;
parms.memsize = 16*1024*1024;
@ -77,7 +79,23 @@ JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_init(JNIEnv *env, jobject o
return;
}
Sys_Printf("Starting up (%s)\n", args[2]);
args[2] = parms.membase;
tmp = (*env)->GetStringUTFChars(env, japkpath, NULL);
strcpy(args[2], tmp);
(*env)->ReleaseStringUTFChars(env, japkpath, tmp);
parms.membase += strlen(args[2])+1;
parms.memsize -= strlen(args[2])+1;
parms.basedir = parms.membase;
tmp = (*env)->GetStringUTFChars(env, jusrpath, NULL);
strcpy(parms.basedir, tmp);
(*env)->ReleaseStringUTFChars(env, jusrpath, tmp);
parms.membase += strlen(parms.basedir)+1;
parms.memsize -= strlen(parms.basedir)+1;
Sys_Printf("Starting up (apk=%s, usr=%s)\n", args[2], parms.basedir);
COM_InitArgv(parms.argc, parms.argv);
TL_InitLanguages();

View file

@ -51,6 +51,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define NO_OGG
#endif
#ifdef NACL
#define NO_PNG
#define NO_JPEG
#define NO_OGG
#define NO_ZLIB
#endif
#ifdef HAVE_CONFIG_H //if it was configured properly, then we have a more correct list of features we want to use.
#include "config.h"
#else
@ -229,6 +236,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef VOICECHAT
#undef TEXTEDITOR
#endif
#ifdef NACL
#undef CL_MASTER //no sockets support
#undef SV_MASTER //noone uses this anyway
#undef VOICECHAT //not going to compile a speex library - I'm too lazy, but it can be done.
#undef WEBSERVER //no sockets support (certainly no servers)
#undef WEBCLIENT //no sockets support (could use a different method, but that is non-trivial)
#undef TCPCONNECT
#undef IRCCONNECT
#endif
//fix things a little...
@ -272,7 +288,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef WEBCLIENT
#undef TEXTEDITOR
#undef RUNTIMELIGHTING
#undef TERRAIN //not supported
#undef PSET_SCRIPT
#undef PSET_CLASSIC
@ -298,10 +313,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef Q3CLIENT
#endif
#if !defined(GLQUAKE)
#undef TERRAIN
#endif
// undefine things not supported yet for D3D
#if defined(D3DQUAKE) && !defined(GLQUAKE)
#undef DDS // this is dumb

View file

@ -3352,7 +3352,6 @@ void COM_Init (void)
Cmd_AddCommand ("version", COM_Version_f); //prints the pak or whatever where this file can be found.
Cmd_AddCommand ("crashme", (void*)1); //debugging feature, makes it jump to an invalid address
COM_InitFilesystem ();
COM_CheckRegistered ();

View file

@ -364,6 +364,7 @@ enum fs_relative{
FS_GAME, //standard search (not generally valid for save/rename/delete/etc)
FS_ROOT, //./
FS_GAMEONLY, //$gamedir/
FS_GAMEDOWNLOADCACHE, //typically the same as FS_GAMEONLY
FS_CONFIGONLY, //fte/ (should still be part of the game path)
FS_SKINS //qw/skins/
};

View file

@ -2513,7 +2513,7 @@ COM_InitFilesystem
*/
void COM_InitFilesystem (void)
{
FILE *f;
vfsfile_t *f;
int i, j;
char *ev;
@ -2562,10 +2562,10 @@ void COM_InitFilesystem (void)
{
if (!gamemode_info[i].auniquefile[j])
continue; //no more
f = fopen(va("%s%s", com_quakedir, gamemode_info[i].auniquefile[j]), "rb");
f = VFSOS_Open(va("%s%s", com_quakedir, gamemode_info[i].auniquefile[j]), "rb");
if (f)
{
fclose(f);
VFS_CLOSE(f);
gamenum = i;
break;
}
@ -2589,11 +2589,11 @@ void COM_InitFilesystem (void)
{
if (gamemode_info[gamenum].auniquefile[j])
{
f = fopen(va("%s%s", com_quakedir, gamemode_info[i].auniquefile[j]), "rb");
f = VFSOS_Open(va("%s%s", com_quakedir, gamemode_info[i].auniquefile[j]), "rb");
if (f)
{
//we found it, its all okay
fclose(f);
VFS_CLOSE(f);
break;
}
if (autobasedir)

View file

@ -2,6 +2,8 @@
#include "fs.h"
#include "errno.h"
#ifndef NACL
#ifdef WEBSVONLY
#define Z_Free free
#define Z_Malloc malloc
@ -294,3 +296,4 @@ searchpathfuncs_t stdiofilefuncs = {
FSSTDIO_OpenVFS
};
#endif
#endif

View file

@ -21,7 +21,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PORT_ANY -1
typedef enum {NA_INVALID, NA_LOOPBACK, NA_IP, NA_IPV6, NA_IPX, NA_BROADCAST_IP, NA_BROADCAST_IP6, NA_BROADCAST_IPX, NA_TCP, NA_TCPV6, NA_IRC} netadrtype_t;
#ifdef NACL
#define HAVE_WEBSOCKCL
#endif
typedef enum {NA_INVALID, NA_LOOPBACK, NA_IP, NA_IPV6, NA_IPX, NA_BROADCAST_IP, NA_BROADCAST_IP6, NA_BROADCAST_IPX, NA_TCP, NA_TCPV6, NA_IRC, NA_WEBSOCKET} netadrtype_t;
typedef enum {NS_CLIENT, NS_SERVER} netsrc_t;
@ -40,6 +44,9 @@ typedef struct
char user[32];
char channel[12];
} irc;
#endif
#ifdef HAVE_WEBSOCKCL
char websocketurl[64];
#endif
} address;

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,36 @@
#ifdef _WIN32
#ifndef NACL
#define HAVE_IPV4 //says we can set and receive AF_INET ipv4 udp packets.
#define HAVE_TCP //says we can use tcp too (either ipv4 or ipv6)
#define HAVE_PACKET //if we have the socket api at all...
#endif
#ifdef NACL
struct sockaddr
{
short sa_family;
};
/* struct sockaddr_in
{
short sin_family;
unsigned short sin_port;
in_addr sin_addr;
};*/
#define AF_UNSPEC 0
// #define AF_INET 1
/*NaCl engines cannot host servers. Regular FTE servers can use the same listening tcpconnect socket to host a websocket connection*/
#define AF_WEBSOCK 342
struct sockaddr_websocket
{
short sws_family;
char url[64];
};
#elif defined(_WIN32)
#ifdef _MSC_VER
#define USEIPX
#endif

View file

@ -778,6 +778,7 @@ int Plug_NewStreamHandle(plugstream_e type)
return i;
}
#ifndef NACL
//EBUILTIN(int, NET_TCPListen, (char *ip, int port, int maxcount));
//returns a new socket with listen enabled.
qintptr_t VARGS Plug_Net_TCPListen(void *offset, quintptr_t mask, const qintptr_t *arg)
@ -1030,6 +1031,7 @@ qintptr_t VARGS Plug_Net_SetTLSClient(void *offset, unsigned int mask, const qin
return 0;
}
#endif
#endif
qintptr_t VARGS Plug_FS_Open(void *offset, quintptr_t mask, const qintptr_t *arg)
{
@ -1170,6 +1172,7 @@ qintptr_t VARGS Plug_Net_Recv(void *offset, quintptr_t mask, const qintptr_t *ar
return -2;
switch(pluginstreamarray[handle].type)
{
#ifndef NACL
case STREAM_SOCKET:
read = recv(pluginstreamarray[handle].socket, dest, destlen, 0);
if (read < 0)
@ -1182,6 +1185,8 @@ qintptr_t VARGS Plug_Net_Recv(void *offset, quintptr_t mask, const qintptr_t *ar
else if (read == 0)
return -2; //closed by remote connection.
return read;
#endif
#ifdef GNUTLS
case STREAM_TLS:
read = gnutls_record_recv(pluginstreamarray[handle].session, dest, destlen);
@ -1223,6 +1228,7 @@ qintptr_t VARGS Plug_Net_Send(void *offset, quintptr_t mask, const qintptr_t *ar
return -2;
switch(pluginstreamarray[handle].type)
{
#ifndef NACL
case STREAM_SOCKET:
written = send(pluginstreamarray[handle].socket, src, srclen, 0);
if (written < 0)
@ -1235,6 +1241,8 @@ qintptr_t VARGS Plug_Net_Send(void *offset, quintptr_t mask, const qintptr_t *ar
else if (written == 0)
return -2; //closed by remote connection.
return written;
#endif
#ifdef GNUTLS
case STREAM_TLS:
written = gnutls_record_send(pluginstreamarray[handle].session, src, srclen);
@ -1292,6 +1300,7 @@ qintptr_t VARGS Plug_Net_SendTo(void *offset, quintptr_t mask, const qintptr_t *
return -2;
switch(pluginstreamarray[handle].type)
{
#ifndef NACL
case STREAM_SOCKET:
written = sendto(pluginstreamarray[handle].socket, src, srclen, 0, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
if (written < 0)
@ -1304,6 +1313,7 @@ qintptr_t VARGS Plug_Net_SendTo(void *offset, quintptr_t mask, const qintptr_t *
else if (written == 0)
return -2; //closed by remote connection.
return written;
#endif
default:
return -2;
}
@ -1327,7 +1337,9 @@ void Plug_Net_Close_Internal(int handle)
case STREAM_OSFILE:
break;
case STREAM_SOCKET:
#ifndef NACL
closesocket(pluginstreamarray[handle].socket);
#endif
break;
case STREAM_TLS:
#ifdef GNUTLS
@ -1451,6 +1463,7 @@ void Plug_Init(void)
Plug_RegisterBuiltin("Cvar_GetString", Plug_Cvar_GetString, 0);
Plug_RegisterBuiltin("Cvar_GetFloat", Plug_Cvar_GetFloat, 0);
#ifndef NACL
Plug_RegisterBuiltin("Net_TCPListen", Plug_Net_TCPListen, 0);
Plug_RegisterBuiltin("Net_Accept", Plug_Net_Accept, 0);
Plug_RegisterBuiltin("Net_TCPConnect", Plug_Net_TCPConnect, 0);
@ -1462,6 +1475,7 @@ void Plug_Init(void)
Plug_RegisterBuiltin("Net_Send", Plug_Net_Send, 0);
Plug_RegisterBuiltin("Net_SendTo", Plug_Net_SendTo, 0);
Plug_RegisterBuiltin("Net_Close", Plug_Net_Close, 0);
#endif
Plug_RegisterBuiltin("FS_Open", Plug_FS_Open, 0);
Plug_RegisterBuiltin("FS_Read", Plug_Net_Recv, 0);

View file

@ -375,19 +375,18 @@ void QCBUILTIN PF_getsurfaceclippedpoint(progfuncs_t *prinst, struct globalvars_
{
}
#ifndef TERRAIN
void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
G_FLOAT(OFS_RETURN) = false;
world_t *w = prinst->parms->user;
int action = G_FLOAT(OFS_PARM0);
float *pos = G_VECTOR(OFS_PARM1);
float radius = G_FLOAT(OFS_PARM2);
float quant = G_FLOAT(OFS_PARM3);
#if defined(TERRAIN)
G_FLOAT(OFS_RETURN) = Heightmap_Edit(w->worldmodel, action, pos, radius, quant);
#else
G_FLOAT(OFS_RETURN) = false;
#endif
}
#endif
//end model functions
////////////////////////////////////////////////////
@ -3403,7 +3402,7 @@ nolength:
o += strlen(o);
break;
case 'c':
if(flags & PRINTF_ALTERNATE)
// if(flags & PRINTF_ALTERNATE)
{
if(precision < 0) // not set
Q_snprintfz(o, end - o, formatbuf, width, (isfloat ? (unsigned int) GETARG_FLOAT(thisarg) : (unsigned int) GETARG_INT(thisarg)));
@ -3411,20 +3410,20 @@ nolength:
Q_snprintfz(o, end - o, formatbuf, width, precision, (isfloat ? (unsigned int) GETARG_FLOAT(thisarg) : (unsigned int) GETARG_INT(thisarg)));
o += strlen(o);
}
else
/* else
{
unsigned int c = (isfloat ? (unsigned int) GETARG_FLOAT(thisarg) : (unsigned int) GETARG_INT(thisarg));
// char charbuf16[16];
// const char *buf = u8_encodech(c, NULL, charbuf16);
// if(!buf)
// buf = "";
char charbuf16[16];
const char *buf = u8_encodech(c, NULL, charbuf16);
if(!buf)
buf = "";
if(precision < 0) // not set
precision = end - o - 1;
// o += u8_strpad(o, end - o, buf, (flags & PRINTF_LEFT) != 0, width, precision);
o += u8_strpad(o, end - o, buf, (flags & PRINTF_LEFT) != 0, width, precision);
}
break;
*/ break;
case 's':
if(flags & PRINTF_ALTERNATE)
// if(flags & PRINTF_ALTERNATE)
{
if(precision < 0) // not set
Q_snprintfz(o, end - o, formatbuf, width, GETARG_STRING(thisarg));
@ -3432,13 +3431,13 @@ nolength:
Q_snprintfz(o, end - o, formatbuf, width, precision, GETARG_STRING(thisarg));
o += strlen(o);
}
else
/* else
{
if(precision < 0) // not set
precision = end - o - 1;
// o += u8_strpad(o, end - o, GETARG_STRING(thisarg), (flags & PRINTF_LEFT) != 0, width, precision);
o += u8_strpad(o, end - o, GETARG_STRING(thisarg), (flags & PRINTF_LEFT) != 0, width, precision);
}
break;
*/ break;
default:
Con_Printf("PF_sprintf: invalid format string: %s\n", s0);
goto finished;

View file

@ -1014,6 +1014,7 @@ typedef struct q1usercmd_s
#define Q2RF_ADDITIVE 0x00080000
#define RF_NOSHADOW 0x00100000
#define RF_NODEPTHTEST 0x00200000
#define RF_FORCECOLOURMOD 0x00400000
// player_state_t->refdef flags
#define Q2RDF_UNDERWATER 1 // warp the screen as apropriate

190
engine/common/sha1.c Normal file
View file

@ -0,0 +1,190 @@
/*
SHA-1 in C
By Steve Reid <steve@edmweb.com>
100% Public Domain
Test Vectors (from FIPS PUB 180-1)
"abc"
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
A million repetitions of "a"
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
This file came to FTE via EzQuake.
*/
/* #define SHA1HANDSOFF * Copies data before messing with it. */
#include "quakedef.h"
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
#define blk0(i) (block->l[i] = BigLong(block->l[i]))
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
typedef struct
{
unsigned int state[5];
unsigned int count[2];
unsigned char buffer[64];
} SHA1_CTX;
#define DIGEST_SIZE 20
void SHA1Transform(unsigned int state[5], unsigned char buffer[64]);
void SHA1Init(SHA1_CTX* context);
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len);
void SHA1Final(unsigned char digest[DIGEST_SIZE], SHA1_CTX* context);
/* Hash a single 512-bit block. This is the core of the algorithm. */
void SHA1Transform(unsigned int state[5], unsigned char buffer[64])
{
unsigned int a, b, c, d, e;
typedef union
{
unsigned char c[64];
unsigned int l[16];
} CHAR64LONG16;
CHAR64LONG16* block;
#ifdef SHA1HANDSOFF
static unsigned char workspace[64];
block = (CHAR64LONG16*)workspace;
memcpy(block, buffer, 64);
#else
block = (CHAR64LONG16*)buffer;
#endif
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
}
/* SHA1Init - Initialize new context */
void SHA1Init(SHA1_CTX* context)
{
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
}
/* Run your data through this. */
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len)
{
unsigned int i, j;
j = (context->count[0] >> 3) & 63;
if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
context->count[1] += (len >> 29);
if ((j + len) > 63)
{
memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64)
{
SHA1Transform(context->state, &data[i]);
}
j = 0;
}
else
i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
}
/* Add padding and return the message digest. */
void SHA1Final(unsigned char digest[DIGEST_SIZE], SHA1_CTX* context)
{
unsigned int i, j;
unsigned char finalcount[8];
for (i = 0; i < 8; i++)
{
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
}
SHA1Update(context, (unsigned char *)"\200", 1);
while ((context->count[0] & 504) != 448)
{
SHA1Update(context, (unsigned char *)"\0", 1);
}
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
for (i = 0; i < DIGEST_SIZE; i++)
{
digest[i] = (unsigned char)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
/* Wipe variables */
i = j = 0;
memset(context->buffer, 0, 64);
memset(context->state, 0, 20);
memset(context->count, 0, 8);
memset(&finalcount, 0, 8);
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
SHA1Transform(context->state, context->buffer);
#endif
}
int SHA1(char *digest, int maxdigestsize, char *string)
{
SHA1_CTX context;
if (maxdigestsize < DIGEST_SIZE)
return 0;
SHA1Init(&context);
SHA1Update(&context, (unsigned char*) string, strlen(string));
SHA1Final(digest, &context);
return DIGEST_SIZE;
}

View file

@ -99,7 +99,7 @@ typedef struct q2trace_s
#define FL_ONGROUND (1<<9)
#define FL_PARTIALGROUND (1<<10) // not all corners are valid
#define FL_WATERJUMP (1<<11) // player jumping out of water
// FL_JUMPRELEASED //12
#define FL_JUMPRELEASED (1<<12)
//13
#define FL_FINDABLE_NONSOLID (1<<14) //a cpqwsv feature
#define FL_MOVECHAIN_ANGLE (1<<15) // hexen2 - when in a move chain, will update the angle

View file

@ -22,6 +22,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qtvprox", "..\..\fteqtv\dot
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "droid", "droid\droid.vcproj", "{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nacl", "..\nacl\nacl.vcproj", "{4735677B-6D5A-4BE6-A945-CB32A7282F56}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
D3DDebug|Win32 = D3DDebug|Win32
@ -321,6 +323,42 @@ Global
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.Release Dedicated Server|x64.ActiveCfg = Release|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.Release|Win32.ActiveCfg = Release|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.Release|x64.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DDebug|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DDebug|Win32.Build.0 = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DDebug|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DRelease|Win32.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DRelease|Win32.Build.0 = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DRelease|x64.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug|Win32.Build.0 = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLDebug|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLDebug|Win32.Build.0 = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLDebug|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLRelease|Win32.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLRelease|Win32.Build.0 = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLRelease|x64.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MDebug|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MDebug|Win32.Build.0 = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MDebug|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLDebug|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLDebug|Win32.Build.0 = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLDebug|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLRelease|Win32.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLRelease|Win32.Build.0 = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLRelease|x64.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MRelease|Win32.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MRelease|Win32.Build.0 = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MRelease|x64.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release Dedicated Server|Win32.Build.0 = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release Dedicated Server|x64.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release|Win32.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release|Win32.Build.0 = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -1681,7 +1681,7 @@
FavorSizeOrSpeed="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="../libs/speex,..\client,../libs/freetype2/include,../common,../server,../gl,../sw,../qclib,../libs,../libs/dxsdk7/include"
PreprocessorDefinitions="NDEBUG;GLQUAKE;WIN32;_WINDOWS"
PreprocessorDefinitions="NDEBUG;GLQUAKE;WIN32;_WINDOWS;BOTLIB_STATIC"
StringPooling="true"
ExceptionHandling="0"
BufferSecurityCheck="false"
@ -23218,6 +23218,194 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\gl\gl_ngraph.c"
>
<FileConfiguration
Name="MinGLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\common\gl_q2bsp.c"
>
@ -25497,194 +25685,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\gl\gl_ngraph.c"
>
<FileConfiguration
Name="MinGLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\gl\gl_rmain.c"
>
@ -33057,6 +33057,10 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\common\sha1.c"
>
</File>
<File
RelativePath="..\server\sv_move.c"
>

View file

@ -33,7 +33,7 @@ public class FTEDroidActivity extends Activity
private class FTERenderer implements GLSurfaceView.Renderer
{
private boolean inited;
private String basedir;
private String basedir, userdir;
FTEDroidActivity act;
FTERenderer(Context ctx, FTEDroidActivity parent)
@ -48,8 +48,16 @@ public class FTEDroidActivity extends Activity
{
/*oh well, can just use the homedir instead*/
}
// try
// {
userdir = Environment.getExternalStorageDirectory().getPath();
// }
// catch(foo)
// {
// }
android.util.Log.i("FTEDroid", "Base dir is \"" + basedir + "\".");
android.util.Log.i("FTEDroid", "User dir is \"" + userdir + "\".");
}
@Override
@ -64,7 +72,7 @@ public class FTEDroidActivity extends Activity
public void onSurfaceChanged(GL10 gl, int width, int height)
{
android.util.Log.i("FTEDroid", "Surface changed, now " + width + " by " + height + ".");
FTEDroidEngine.init(width, height, basedir);
FTEDroidEngine.init(width, height, basedir, userdir);
inited = true;
}
@Override

View file

@ -2,7 +2,7 @@ package com.fteqw;
public class FTEDroidEngine
{
public static native void init(int w, int h, String basedir); /* init/reinit */
public static native void init(int w, int h, String apkpath, String usrpath); /* init/reinit */
public static native void frame(float ax, float ay, float az);
public static native void keypress(int down, int qkey, int unicode);
public static native void motion(int act, int pointerid, float x, float y);

View file

@ -1021,6 +1021,8 @@ void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches)
b->surf_first = surfnum;
b->flags = 0;
sort = shader->sort;
if (e->flags & RF_FORCECOLOURMOD)
b->flags |= BEF_FORCECOLOURMOD;
if (e->flags & Q2RF_ADDITIVE)
{
b->flags |= BEF_FORCEADDITIVE;
@ -1915,16 +1917,16 @@ void BE_GenModelBatches(batch_t **batches)
for (i = 0; i < SHADER_SORT_COUNT; i++)
batches[i] = NULL;
if (!r_drawentities.ival)
return;
Alias_FlushCache();
#if defined(TERRAIN)
if (cl.worldmodel && cl.worldmodel->type == mod_heightmap)
GL_DrawHeightmapModel(batches, &r_worldentity);
#endif
if (!r_drawentities.ival)
return;
Alias_FlushCache();
// draw sprites seperately, because of alpha blending
for (i=0 ; i<cl_numvisedicts ; i++)
{

View file

@ -17,7 +17,13 @@
#pragma warningmsg("FORCESTATE is active")
#endif
#ifdef ANDROID
/*android appears to have a bug, and requires f and not i*/
#define qglTexEnvi qglTexEnvf
#endif
extern cvar_t gl_overbright;
extern cvar_t gl_ati_truform;
static const char LIGHTPASS_SHADER[] = "\
{\n\
@ -235,12 +241,7 @@ void GL_TexEnv(GLenum mode)
if (mode != shaderstate.texenvmode[shaderstate.currenttmu])
#endif
{
#ifdef ANDROID
/*android appears to have a bug, and requires f and not i*/
qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode);
#else
qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode);
#endif
shaderstate.texenvmode[shaderstate.currenttmu] = mode;
}
}
@ -971,7 +972,7 @@ void GLBE_Init(void)
shaderstate.shaderbits = ~0;
BE_SendPassBlendDepthMask(0);
if (qglEnableClientState)
if (qglEnableClientState && !gl_config.nofixedfunc)
qglEnableClientState(GL_VERTEX_ARRAY);
currententity = &r_worldentity;
@ -2017,6 +2018,7 @@ static void BE_SendPassBlendDepthMask(unsigned int sbits)
qglDisable(GL_BLEND);
}
#ifdef GL_ALPHA_TEST //alpha test doesn't exist in gles2
if (delta & SBITS_ATEST_BITS)
{
switch (sbits & SBITS_ATEST_BITS)
@ -2038,6 +2040,7 @@ static void BE_SendPassBlendDepthMask(unsigned int sbits)
break;
}
}
#endif
if (delta & SBITS_MISC_NODEPTHTEST)
{
@ -2081,6 +2084,13 @@ static void BE_SendPassBlendDepthMask(unsigned int sbits)
(sbits&SBITS_MASK_ALPHA)?GL_FALSE:GL_TRUE
);
}
if ((delta & SBITS_TRUFORM) && qglPNTrianglesiATI)
{
if ((sbits & SBITS_TRUFORM) && gl_ati_truform.ival)
qglEnable(GL_PN_TRIANGLES_ATI);
else
qglDisable(GL_PN_TRIANGLES_ATI);
}
}
static void BE_SubmitMeshChain(void)
@ -2262,16 +2272,10 @@ static unsigned int BE_Program_Set_Attributes(const program_t *prog, unsigned in
if (shaderstate.sourcevbo->colours.gl.addr)
{
GL_SelectVBO(shaderstate.sourcevbo->colours.gl.vbo);
qglVertexAttribPointer(p->handle[perm], 4, shaderstate.colourarraytype, GL_FALSE, 0, shaderstate.sourcevbo->colours.gl.addr);
qglVertexAttribPointer(p->handle[perm], 4, shaderstate.colourarraytype, ((shaderstate.colourarraytype==GL_FLOAT)?GL_FALSE:GL_TRUE), 0, shaderstate.sourcevbo->colours.gl.addr);
attr |= 1u<<p->handle[perm];
break;
}
/* else if (shaderstate.sourcevbo->colours4ub)
{
GL_SelectVBO(shaderstate.sourcevbo->colours.gl.vbo);
qglVertexAttribPointer(p->handle[perm], 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(byte_vec4_t), shaderstate.sourcevbo->colours.gl.addr);
return 1u<<p->handle[perm];
}*/
break;
case SP_ATTR_TEXCOORD:
GL_SelectVBO(shaderstate.sourcevbo->texcoord.gl.vbo);
@ -2582,7 +2586,8 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
BE_SendPassBlendDepthMask(pass->shaderbits);
if (p->nofixedcompat)
{
qglDisableClientState(GL_COLOR_ARRAY);
if (!gl_config.nofixedfunc)
qglDisableClientState(GL_COLOR_ARRAY);
BE_EnableShaderAttributes(attr);
for (i = 0; i < pass->numMergedPasses; i++)
{
@ -3102,9 +3107,9 @@ void GLBE_SubmitBatch(batch_t *batch)
{
int lm;
if (batch->texture)
if (batch->vbo)
{
shaderstate.sourcevbo = &batch->texture->vbo;
shaderstate.sourcevbo = batch->vbo;
shaderstate.colourarraytype = GL_FLOAT;
lm = batch->lightmap;
}
@ -3112,6 +3117,7 @@ void GLBE_SubmitBatch(batch_t *batch)
{
shaderstate.dummyvbo.coord.gl.addr = batch->mesh[0]->xyz_array;
shaderstate.dummyvbo.texcoord.gl.addr = batch->mesh[0]->st_array;
shaderstate.dummyvbo.lmcoord.gl.addr = batch->mesh[0]->lmst_array;
shaderstate.dummyvbo.indicies.gl.addr = batch->mesh[0]->indexes;
shaderstate.dummyvbo.normals.gl.addr = batch->mesh[0]->normals_array;
shaderstate.dummyvbo.svector.gl.addr = batch->mesh[0]->snormals_array;
@ -3540,10 +3546,9 @@ void GLBE_DrawWorld (qbyte *vis)
BE_SelectEntity(&r_worldentity);
BE_UpdateLightmaps();
if (vis)
{
BE_UpdateLightmaps();
if (gl_overbright.modified)
{
int i;

View file

@ -621,19 +621,6 @@ gltexture_t *GL_MatchTexture (char *identifier, int bits, int width, int height)
glt = Hash_GetNext(&gltexturetable, identifier, glt);
}
/*
for (glt=gltextures ; glt ; glt=glt->next)
{
if (glt->bpp == bits && width == glt->width && height == glt->height)
{
if (!strcmp (identifier, glt->identifier))
{
return glt;
}
}
}
*/
return NULL;
}
@ -1138,7 +1125,7 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne
GL_RoundDimensions(&scaled_width, &scaled_height, !(flags & IF_NOMIPMAP));
if (!(flags & IF_NOALPHA))
{ //make sure it does actually have those alpha pixels
{ //make sure it does actually have those alpha pixels (q3 compat)
int i;
flags |= IF_NOALPHA;
for (i = 3; i < width*height*4; i+=4)
@ -1370,7 +1357,7 @@ done:
qglTexParameteri(targ, GL_GENERATE_MIPMAP_SGIS, GL_FALSE);
/*apply this flag after, so that we can safely change the base (to avoid drivers just not uploading lower mips)*/
if (flags & IF_MIPCAP)
if (!gl_config.gles && (flags & IF_MIPCAP))
{
qglTexParameteri(targ, GL_TEXTURE_BASE_LEVEL, gl_mipcap_min);
qglTexParameteri(targ, GL_TEXTURE_MAX_LEVEL, gl_mipcap_max);
@ -1999,7 +1986,7 @@ void GL_Upload8 (char *name, qbyte *data, int width, int height, unsigned int fl
}
for (i=s&~3 ; i<s ; i++) //wow, funky
{
trans[i] = d_8to24rgbtable[data[i]];
trans[i] = d_8to24rgbtable[data[i]]|0xff000000;
}
}
@ -2150,31 +2137,26 @@ GL_LoadTexture
*/
texid_t GL_LoadTexture (char *identifier, int width, int height, qbyte *data, unsigned int flags, unsigned int transtype)
{
gltexture_t *glt;
gltexture_t *glt = NULL;
// see if the texture is already present
if (identifier[0])
{
glt = GL_MatchTexture(identifier, 8, width, height);
if (glt)
{
TRACE(("dbg: GL_LoadTexture: duplicate %s\n", identifier));
if (glt && !(flags & IF_REPLACE))
return glt->texnum;
}
}
if (!glt)
glt = GL_AllocNewGLTexture(identifier, width, height);
TRACE(("dbg: GL_LoadTexture: new %s\n", identifier));
glt = GL_AllocNewGLTexture(identifier, width, height);
glt->bpp = 8;
glt->flags = flags;
checkglerror();
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
GL_Upload8 ("8bit", data, width, height, flags, transtype);
checkglerror();
return glt->texnum;
}

File diff suppressed because it is too large Load diff

View file

@ -359,6 +359,12 @@ void RMod_ClearAll (void)
BE_ClearVBO(&mod->textures[t]->vbo);
}
}
#ifdef TERRAIN
if (mod->type == mod_heightmap)
{
HeightMap_Purge(mod);
}
#endif
if (mod->type != mod_alias
&& mod->type != mod_halflife

View file

@ -172,6 +172,7 @@ void R_NetgraphInit(void)
TEXASSIGN(netgraphtexture, R_AllocNewTexture("***netgraph***", NET_TIMINGS, NET_GRAPHHEIGHT));
netgraphshader = R_RegisterShader("netgraph",
"{\n"
"program default2d\n"
"{\n"
"map $diffuse\n"
"blendfunc blend\n"

View file

@ -850,7 +850,7 @@ static void R_RenderMotionBlur(void)
#ifdef warningmsg
#pragma warningmsg("backend fixme")
#endif
#ifndef ANDROID
#if !defined(ANDROID) && !defined(NACL)
if (gl_config.arb_texture_non_power_of_two)
{ //we can use any size, supposedly
vwidth = vid.pixelwidth;

View file

@ -589,7 +589,8 @@ void GLR_TimeRefresh_f (void)
else
#endif
{
qglDrawBuffer (GL_FRONT);
if (qglDrawBuffer)
qglDrawBuffer (GL_FRONT);
qglFinish ();
start = Sys_DoubleTime ();
@ -606,7 +607,8 @@ void GLR_TimeRefresh_f (void)
time = stop-start;
Con_Printf ("%f seconds (%f fps)\n", time, frames/time);
qglDrawBuffer (GL_BACK);
if (qglDrawBuffer)
qglDrawBuffer (GL_BACK);
GL_EndRendering ();
GL_DoSwap();
}

View file

@ -168,6 +168,7 @@ void GLSCR_UpdateScreen (void)
V_RenderView ();
else
{
GL_DoSwap();
noworld = true;
}
}

View file

@ -299,7 +299,13 @@ static qboolean Shader_EvaluateCondition(char **ptr)
else
{
cv = Cvar_Get(token, "", 0, "Shader Conditions");
if (!cv)
{
Con_Printf("Shader_EvaluateCondition: '%s' is not a cvar\n", token);
return conditiontrue;
}
token = COM_ParseExt ( ptr, false );
cv->flags |= CVAR_SHADERSYSTEM;
if (*token)
{
float rhs;
@ -1078,8 +1084,7 @@ struct sbuiltin_s
"void main ()\n"
"{\n"
" gl_FragColor = fog4blend(texture2D(s_t0, tc) * vc);\n"
" gl_FragColor = gl_FragColor * e_colourident;\n"
" gl_FragColor = fog4blend(texture2D(s_t0, tc) * vc * e_colourident);\n"
"}\n"
"#endif\n"
},
@ -1108,8 +1113,7 @@ struct sbuiltin_s
"void main ()\n"
"{\n"
" gl_FragColor = fog4additive(texture2D(s_t0, tc) * vc);\n"
" gl_FragColor = gl_FragColor * e_colourident;\n"
" gl_FragColor = fog4additive(texture2D(s_t0, tc) * vc * e_colourident);\n"
"}\n"
"#endif\n"
},
@ -1206,10 +1210,42 @@ struct sbuiltin_s
"#ifdef FULLBRIGHT\n"
" gl_FragColor.rgb += texture2D(s_t4, tc).rgb;\n"
"#endif\n"
"gl_FragColor = gl_FragColor * e_colourident;\n"
"#ifdef FOG\n"
"gl_FragColor = fog4(gl_FragColor);\n"
"#endif\n"
"gl_FragColor = gl_FragColor * e_colourident;\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 100, "drawflat_wall",
"!!cvarv r_floorcolor\n"
"!!cvarv r_wallcolor\n"
"!!permu FOG\n"
"#include \"sys/fog.h\"\n"
"varying vec4 col;\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec3 v_normal;\n"
"attribute vec2 v_lmcoord;\n"
"varying vec2 lm;\n"
"uniform vec3 cvar_r_wallcolor;\n"
"uniform vec3 cvar_r_floorcolor;\n"
"uniform vec4 e_lmscale;\n"
"void main ()\n"
"{\n"
" col = vec4(e_lmscale.rgb/255.0 * ((v_normal.z < 0.73)?cvar_r_wallcolor:cvar_r_floorcolor), e_lmscale.a);\n"
" lm = v_lmcoord;\n"
" gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n" /*tex_lightmap*/
"varying vec2 lm;\n"
"void main ()\n"
"{\n"
" gl_FragColor = fog4(col * texture2D(s_t0, lm));\n"
"}\n"
"#endif\n"
},
@ -4370,10 +4406,10 @@ void Shader_Finish (shader_t *s)
if (r_fastsky.ival)
s->flags = 0;
/*or if its purely a skybox and has missing textures*/
if (!s->numpasses)
for (i = 0; i < 6; i++)
if (missing_texture.ref == s->skydome->farbox_textures[i].ref)
s->flags = 0;
// if (!s->numpasses)
// for (i = 0; i < 6; i++)
// if (missing_texture.ref == s->skydome->farbox_textures[i].ref)
// s->flags = 0;
if (!(s->flags & SHADER_SKY))
{
Shader_Reset(s);

View file

@ -468,7 +468,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name), float ver)
Con_DPrintf("Anisotropic filter extension found (%dx max).\n",gl_config.ext_texture_filter_anisotropic);
}
if (GL_CheckExtension("GL_ARB_texture_non_power_of_two"))
if (GL_CheckExtension("GL_ARB_texture_non_power_of_two") || GL_CheckExtension("GL_OES_texture_npot"))
gl_config.arb_texture_non_power_of_two = true;
// if (GL_CheckExtension("GL_SGIS_generate_mipmap")) //a suprising number of implementations have this broken.
// gl_config.sgis_generate_mipmap = true;
@ -479,7 +479,8 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name), float ver)
qglClientActiveTextureARB = (void *) getglext("glClientActiveTexture");
qglSelectTextureSGIS = qglActiveTextureARB;
mtexid0 = GL_TEXTURE0_ARB;
qglGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_mtexarbable);
if (!gl_config.nofixedfunc)
qglGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_mtexarbable);
}
else if (GL_CheckExtension("GL_ARB_multitexture") && !COM_CheckParm("-noamtex"))
{ //ARB multitexture is the popular choice.
@ -584,7 +585,17 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name), float ver)
gl_config.arb_texture_cube_map = GL_CheckExtension("GL_ARB_texture_cube_map");
/*vbos*/
if (GL_CheckExtension("GL_ARB_vertex_buffer_object"))
if (gl_config.gles && gl_config.glversion >= 2)
{
qglGenBuffersARB = (void *)getglext("glGenBuffers");
qglDeleteBuffersARB = (void *)getglext("glDeleteBuffers");
qglBindBufferARB = (void *)getglext("glBindBuffer");
qglBufferDataARB = (void *)getglext("glBufferData");
qglBufferSubDataARB = (void *)getglext("glBufferSubData");
qglMapBufferARB = (void *)getglext("glMapBuffer");
qglUnmapBufferARB = (void *)getglext("glUnmapBuffer");
}
else if (GL_CheckExtension("GL_ARB_vertex_buffer_object"))
{
qglGenBuffersARB = (void *)getglext("glGenBuffersARB");
qglDeleteBuffersARB = (void *)getglext("glDeleteBuffersARB");
@ -799,21 +810,21 @@ static const char *glsl_hdrs[] =
"uniform vec4 w_fog;\n"
"vec3 fog3(in vec3 regularcolour)"
"{"
"float z = gl_FragCoord.z / gl_FragCoord.w;\n"
"float fac = exp2(-("
"w_fog.w * w_fog.w * "
"z * z * "
"1.442695));\n"
"float z = w_fog.w * gl_FragCoord.z / gl_FragCoord.w;\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"#endif\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = clamp(fac, 0.0, 1.0);\n"
"return mix(w_fog.rgb, regularcolour, fac);\n"
"}\n"
"vec3 fog3additive(in vec3 regularcolour)"
"{"
"float z = gl_FragCoord.z / gl_FragCoord.w;\n"
"float fac = exp2(-("
"w_fog.w * w_fog.w * "
"z * z * "
"1.442695));\n"
"float z = w_fog.w * gl_FragCoord.z / gl_FragCoord.w;\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"#endif\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = clamp(fac, 0.0, 1.0);\n"
"return regularcolour * fac;\n"
"}\n"
@ -823,21 +834,21 @@ static const char *glsl_hdrs[] =
"}\n"
"vec4 fog4additive(in vec4 regularcolour)"
"{"
"float z = gl_FragCoord.z / gl_FragCoord.w;\n"
"float fac = exp2(-("
"w_fog.w * w_fog.w * "
"z * z * "
"1.442695));\n"
"float z = w_fog.w * gl_FragCoord.z / gl_FragCoord.w;\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"#endif\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = clamp(fac, 0.0, 1.0);\n"
"return regularcolour * vec4(fac, fac, fac, 1.0);\n"
"}\n"
"vec4 fog4blend(in vec4 regularcolour)"
"{"
"float z = gl_FragCoord.z / gl_FragCoord.w;\n"
"float fac = exp2(-("
"w_fog.w * w_fog.w * "
"z * z * "
"1.442695));\n"
"float z = w_fog.w * gl_FragCoord.z / gl_FragCoord.w;\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"#endif\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = clamp(fac, 0.0, 1.0);\n"
"return regularcolour * vec4(1.0, 1.0, 1.0, fac);\n"
"}\n"
@ -900,25 +911,47 @@ qboolean GLSlang_GenerateIncludes(int maxstrings, int *strings, const GLchar *pr
incline += 8;
incline = COM_ParseOut (incline, incname, sizeof(incname));
for (i = 0; glsl_hdrs[i]; i += 2)
if (!strncmp(incname, "cvar/", 5))
{
if (!strcmp(incname, glsl_hdrs[i]))
cvar_t *var = Cvar_Get(incname+5, "0", 0, "shader cvars");
if (var)
{
if (!GLSlang_GenerateIncludes(maxstrings, strings, prstrings, length, glsl_hdrs[i+1]))
var->flags |= CVAR_SHADERSYSTEM;
if (!GLSlang_GenerateIncludes(maxstrings, strings, prstrings, length, var->string))
return false;
break;
}
else
{
/*dump something if the cvar doesn't exist*/
if (*strings == maxstrings)
return false;
prstrings[*strings] = "0";
length[*strings] = strlen("0");
*strings += 1;
}
}
if (!glsl_hdrs[i])
else
{
if (FS_LoadFile(incname, &inc) >= 0)
for (i = 0; glsl_hdrs[i]; i += 2)
{
if (!GLSlang_GenerateIncludes(maxstrings, strings, prstrings, length, inc))
if (!strcmp(incname, glsl_hdrs[i]))
{
FS_FreeFile(inc);
return false;
if (!GLSlang_GenerateIncludes(maxstrings, strings, prstrings, length, glsl_hdrs[i+1]))
return false;
break;
}
}
if (!glsl_hdrs[i])
{
if (FS_LoadFile(incname, &inc) >= 0)
{
if (!GLSlang_GenerateIncludes(maxstrings, strings, prstrings, length, inc))
{
FS_FreeFile(inc);
return false;
}
FS_FreeFile(inc);
}
FS_FreeFile(inc);
}
}
@ -1357,7 +1390,7 @@ void GL_Init(void *(*getglfunction) (char *name))
Con_Printf ("end of list\n");
}
else
Con_Printf ("GL_EXTENSIONS: %i extensions\n", gl_num_extensions);
Con_DPrintf ("GL_EXTENSIONS: %i extensions\n", gl_num_extensions);
gl_extensions = NULL;
}
else

View file

@ -80,6 +80,32 @@ void ClearBounds (vec3_t mins, vec3_t maxs);
#elif defined(__MACOSX__)
//apple, you suck.
#include <AGL/agl.h>
#elif defined(NACL)
#include <GLES2/gl2.h>
#define GLclampd GLclampf
#define GLdouble GLfloat
#define GL_CLAMP GL_CLAMP_TO_EDGE
#define GL_POLYGON (Con_Printf("GL_POLYGON was used"),0)
#define GL_QUAD_STRIP (Con_Printf("GL_QUAD_STRIP was used"),0)
#define GL_QUADS (Con_Printf("GL_QUADS was used"),0)
#define GL_PROJECTION (Con_Printf("GL_QUADS was used"),0)
#define GL_MODELVIEW (Con_Printf("GL_QUADS was used"),0)
#define GL_CLIP_PLANE0 (Con_Printf("GL_CLIP_PLANE0 was used"),0)
#define GL_MODULATE (Con_Printf("GL_MODULATE was used"),0)
#define GL_FLAT (Con_Printf("GL_FLAT was used"),0)
#define GL_SMOOTH (Con_Printf("GL_SMOOTH was used"),0)
#define GL_DECAL (Con_Printf("GL_DECAL was used"),0)
#define GL_ADD (Con_Printf("GL_ADD was used"),0)
#define GL_FILL (Con_Printf("GL_FILL was used"),0)
#define GL_TEXTURE_ENV (Con_Printf("GL_TEXTURE_ENV was used"),0)
#define GL_TEXTURE_ENV_MODE (Con_Printf("GL_TEXTURE_ENV_MODE was used"),0)
#define GL_COLOR_ARRAY (Con_Printf("GL_COLOR_ARRAY was used"),0)
#define GL_VERTEX_ARRAY (Con_Printf("GL_VERTEX_ARRAY was used"),0)
#define GL_TEXTURE_COORD_ARRAY (Con_Printf("GL_TEXTURE_COORD_ARRAY was used"),0)
#else
#include <GL/gl.h>
#endif
@ -240,7 +266,8 @@ extern vec3_t r_entorigin;
extern entity_t *currententity;
extern int r_visframecount; // ??? what difs?
extern int r_framecount;
extern mplane_t frustum[4];
#define FRUSTUMPLANES 5
extern mplane_t frustum[FRUSTUMPLANES];
extern float r_wateralphaval;
extern qboolean r_loadbumpmapping;
@ -384,6 +411,7 @@ void R_SaveRTLights_f(void);
#ifdef GLQUAKE
void GL_DrawHeightmapModel (batch_t **batch, entity_t *e);
qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer);
void HeightMap_Purge(model_t *mod);
#endif
//doom
@ -844,7 +872,11 @@ void GL_SelectProgram(int program);
#ifdef _DEBUG
#ifdef __GNUC__
#define checkglerror() do {int i=qglGetError(); if (i) Sys_Printf("GL Error %i detected at line %s:%i (caller %p)\n", i, __FILE__, __LINE__, __builtin_return_address(0));}while(0)
#else
#define checkglerror() do {int i=qglGetError(); if (i) Con_Printf("GL Error %i detected at line %s:%i\n", i, __FILE__, __LINE__);}while(0)
#endif
#else
#define checkglerror()
#endif

View file

@ -130,6 +130,8 @@ enum
SBITS_MASK_BLUE = 0x00040000,
SBITS_MASK_ALPHA = 0x00080000,
#define SBITS_MASK_BITS 0x000f0000
SBITS_TRUFORM = 0x00100000,
};

View file

@ -48,7 +48,7 @@ FTPclientconn_t *FTP_CreateConnection(char *addy)
if ((con->controlsock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{
Sys_Error ("FTP_UDP_OpenSocket: socket: %s\n", strerror(qerrno));
Sys_Error ("FTP_CreateConnection: socket: %s\n", strerror(qerrno));
}
@ -158,14 +158,14 @@ int FTP_CL_makeconnectsocket(char *ftpdest)
if ((sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{
IWebWarnPrintf ("FTP_UDP_OpenSocket: socket: %s", strerror(qerrno));
IWebWarnPrintf ("FTP_CL_makeconnectsocket: socket: %s", strerror(qerrno));
return INVALID_SOCKET;
}
if (ioctlsocket (sock, FIONBIO, &_true) == -1)
{
closesocket(sock);
IWebWarnPrintf ("FTTP_UDP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno));
IWebWarnPrintf ("FTP_CL_makeconnectsocket: ioctl FIONBIO: %s", strerror(qerrno));
return INVALID_SOCKET;
}
@ -179,7 +179,7 @@ int FTP_CL_makeconnectsocket(char *ftpdest)
{
closesocket(sock);
IWebWarnPrintf ("FTTP_UDP_OpenSocket: bind: %s", strerror(qerrno));
IWebWarnPrintf ("FTP_CL_makeconnectsocket: bind: %s", strerror(qerrno));
return INVALID_SOCKET;
}
@ -191,7 +191,7 @@ int FTP_CL_makeconnectsocket(char *ftpdest)
/* {
closesocket(sock);
Con_Printf ("FTTP_UDP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno));
Con_Printf ("FTP_CL_makeconnectsocket: ioctl FIONBIO: %s", strerror(qerrno));
return INVALID_SOCKET;
}
*/

View file

@ -485,12 +485,12 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
if ((cl->datasock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{
Sys_Error ("FTP_UDP_OpenSocket: socket: %s", strerror(qerrno));
Sys_Error ("FTP_ServerThinkForConnection: socket: %s", strerror(qerrno));
}
if (ioctlsocket (cl->datasock, FIONBIO, (u_long *)&_true) == -1)
{
Sys_Error ("FTTP_UDP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno));
Sys_Error ("FTP_ServerThinkForConnection: ioctl FIONBIO: %s", strerror(qerrno));
}
from.sin_family = AF_INET;

View file

@ -322,7 +322,7 @@ cont:
if (HTTPmarkup == 3 && !hostspecified) //1.1 requires the host to be specified... we ca,just ignore it as we're not routing or imitating two servers. (for complience we need to encourage the client to send - does nothing for compatability or anything, just compliance to spec. not always the same thing)
{
msg = "HTTP/1.1 400 Bad Request\r\n" "Content-Type: text/plain\r\n" "Content-Length: 69\r\n" "Server: "FULLENGINENAME"/0\r\n" "\r\n" "400 Bad Request\r\nYour client failed to provide the host header line";
msg = "HTTP/1.1 400 Bad Request\r\n" /*"Content-Type: application/octet-stream\r\n"*/ "Content-Length: 69\r\n" "Server: "FULLENGINENAME"/0\r\n" "\r\n" "400 Bad Request\r\nYour client failed to provide the host header line";
ammount = strlen(msg);
ExpandOutBuffer(cl, ammount, true);

858
engine/nacl/fs_ppapi.c Normal file
View file

@ -0,0 +1,858 @@
#include "quakedef.h"
#include "fs.h"
#include <ppapi/c/pp_errors.h>
#include <ppapi/c/ppb_core.h>
#include <ppapi/c/pp_file_info.h>
#include <ppapi/c/ppb_file_system.h>
#include <ppapi/c/ppb_file_ref.h>
#include <ppapi/c/ppb_url_request_info.h>
#include <ppapi/c/ppb_url_response_info.h>
#include <ppapi/c/pp_var.h>
#include <ppapi/c/ppb_var.h>
#include <ppapi/c/ppb_file_io.h>
#include <ppapi/c/ppb_url_loader.h>
extern PPB_FileIO *ppb_fileio;
extern PPB_FileRef *ppb_fileref;
extern PPB_FileSystem *ppb_filesystem;
extern PPB_Core *ppb_core;
extern PPB_URLLoader *urlloader;
extern PPB_URLRequestInfo *urlrequestinfo;
extern PPB_URLResponseInfo *urlresponseinfo;
extern PPB_Var *ppb_var_interface;
extern PP_Instance pp_instance;
#define GOOGLE_DONT_KNOW_HOW_TO_CREATE_USABLE_APIS
#ifdef GOOGLE_DONT_KNOW_HOW_TO_CREATE_USABLE_APIS
//the pepper api is flawed. deeply flawed.
//1: api calls (including various gl calls) may only be made on the main thread).
//2: the main thread may not use non-asyncronous calls.
//the recommendation to get around this is to run everything on a worker thread, but to make calls to the main thread to do the actual call, then signal the worker thread to wake up again in the main thread's callback.
//which is impractical when you have 80+ different sorts of performance-dependant gl calls.
//I can't easily put things requiring file access on another thread, if only because it would make alias/exec console commands non-synchronous
//to get around this, I instead make my own memory-only 'filesystem', populating it at startup with downloads. I *really* hope your browser/server are set to enable file caching.
//at some point I'll periodically write the data back to a persistant store/reload it at startup so saved games/configs can work
#define FSPPAPI_OpenTemp FS_OpenTemp
#define VFSPPAPI_Open VFSOS_Open
typedef struct mfchunk_s
{
struct mfchunk_s *prev;
struct mfchunk_s *next;
unsigned long startpos;
unsigned int len;
char data[64];
} mfchunk_t;
typedef struct mfile_s
{
/*chunks can be trimmed only when there's no refs*/
char name[MAX_QPATH];
int refs;
int unlinked:1;
unsigned long length;
mfchunk_t *chunkhead;
mfchunk_t *chunktail;
struct mfile_s *prev;
struct mfile_s *next;
} mfile_t;
mfile_t *mfiles;
typedef struct
{
vfsfile_t funcs;
mfile_t *file;
unsigned long offset;
mfchunk_t *cchunk;
} vfsmfile_t;
typedef struct
{
PP_Resource dl;
char buffer[65536];
char *fname;
vfsfile_t *out;
} dlfile_t;
static int activedls;
static int availdlslots = 2;
void readfinished(void* user_data, int32_t result)
{
dlfile_t *f = user_data;
/*if there was a prior request that didn't finish yet...*/
struct PP_CompletionCallback ccb = {readfinished, f, PP_COMPLETIONCALLBACK_FLAG_OPTIONAL};
// Sys_Printf("lastresult: %i\n", result);
if (result == PP_OK)
{
Sys_Printf("%s completed\n", f->fname);
if (f->out)
VFS_CLOSE(f->out);
//ppb_core->ReleaseResource(f->dl);
activedls--;
availdlslots++;
free(f);
return;
}
for (; result > 0; result = urlloader->ReadResponseBody(f->dl, f->buffer, sizeof(f->buffer), ccb))
{
if (!f->out)
{
Sys_Printf("Downloading %s\n", f->fname);
f->out = VFSOS_Open(f->fname, "wb");
}
// Sys_Printf("write: %i\n", result);
VFS_WRITE(f->out, f->buffer, result);
}
// Sys_Printf("result: %i\n", result);
if (result != PP_OK_COMPLETIONPENDING)
{
Sys_Printf("file %s failed or something\n", f->fname);
if (f->out)
VFS_CLOSE(f->out);
ppb_core->ReleaseResource(f->dl);
activedls--;
availdlslots++;
free(f);
}
}
void dlstarted(void* user_data, int32_t result)
{
dlfile_t *f = user_data;
struct PP_CompletionCallback ccb = {readfinished, f, PP_COMPLETIONCALLBACK_FLAG_OPTIONAL};
readfinished(user_data, urlloader->ReadResponseBody(f->dl, f->buffer, sizeof(f->buffer), ccb));
}
qboolean FSPPAPI_Init(int *fileid)
{
dlfile_t *dlf;
PP_Resource dlri;
static char *dlnames[] =
{
"id1/pak0.pak",
// "id1/gfx/conback.tga",
// "id1/gfx/conchars.tga",
"id1/pak1.pak",
// "id1/bigass1.dem",
// "id1/overkill.qwd",
"id1/pak2.pak",
"id1/pak3.pak",
"id1/pak4.pak",
NULL
};
if (availdlslots)
{
if (!dlnames[*fileid])
{
if (!activedls)
return true; /*engine has all the content it needs*/
return false; /*still downloading something, don't let it continue just yet*/
}
dlf = malloc(sizeof(*dlf));
if (!dlf)
return false;
dlf->out = NULL;
activedls++;
availdlslots--;
dlf->fname = dlnames[*fileid];
*fileid+=1;
dlf->dl = urlloader->Create(pp_instance);
dlri = urlrequestinfo->Create(pp_instance);
urlrequestinfo->SetProperty(dlri, PP_URLREQUESTPROPERTY_URL, ppb_var_interface->VarFromUtf8(dlf->fname, strlen(dlf->fname)));
struct PP_CompletionCallback ccb = {dlstarted, dlf, PP_COMPLETIONCALLBACK_FLAG_NONE};
urlloader->Open(dlf->dl, dlri, ccb);
ppb_core->ReleaseResource(dlri);
}
return false;
}
static int preparechunk(vfsmfile_t *f, int bytes, void **data)
{
int sz;
mfchunk_t *cnk;
if (!bytes)
{
*data = 0;
return 0;
}
if (!f->cchunk)
cnk = f->file->chunkhead;
else
{
cnk = f->cchunk;
//rewind through the chunks
while (cnk->startpos > f->offset)
cnk = cnk->prev;
}
//find the chunk that contains our start offset
while (!cnk || cnk->startpos+cnk->len <= f->offset)
{
if (!cnk)
{
sz = (bytes + sizeof(*cnk) - sizeof(cnk->data) + 4095) & ~4095;
if (sz < 65536)
sz = 65536;
cnk = malloc(sz);
memset(cnk, 0xcc, sz);
if (!cnk)
{
*data = 0;
return 0;
}
cnk->len = (sz + sizeof(cnk->data) - sizeof(*cnk));
cnk->next = NULL;
if (f->file->chunktail)
{
cnk->prev = f->file->chunktail;
cnk->prev->next = cnk;
cnk->startpos = cnk->prev->startpos + cnk->prev->len;
}
else
{
f->file->chunkhead = cnk;
cnk->prev = NULL;
cnk->startpos = 0;
}
// Sys_Printf("Allocated chunk %p: %u-%u\n", cnk, cnk->startpos, cnk->startpos + cnk->len);
f->file->chunktail = cnk;
}
else
cnk = cnk->next;
}
// Sys_Printf("Returning offset %p, %i\n", cnk, (f->offset - cnk->startpos));
// Sys_Printf("%u %u\n", f->offset, cnk->startpos);
*data = cnk->data + (f->offset - cnk->startpos);
f->cchunk = cnk;
sz = cnk->startpos + cnk->len - f->offset;
if (sz > bytes)
{
// Sys_Printf("Returning len %u\n", bytes);
return bytes;
}
// Sys_Printf("Returning len %u\n", sz);
return sz;
}
static int VFSMEM_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
{
int total = 0;
int chunklen;
void *chunkdat;
vfsmfile_t *f = (vfsmfile_t*)file;
if (bytestoread > f->file->length - f->offset)
bytestoread = f->file->length - f->offset;
while ((chunklen = preparechunk(f, bytestoread, &chunkdat)) > 0)
{
// Sys_Printf("Read %i at %u\n", chunklen, f->offset);
memcpy(buffer, chunkdat, chunklen);
buffer = (char*)buffer + chunklen;
bytestoread -= chunklen;
total += chunklen;
f->offset += chunklen;
}
// Sys_Printf("%s", (char*)buffer-total);
return total;
}
static int VFSMEM_WriteBytes (struct vfsfile_s *file, const void *buffer, int bytestoread)
{
int total = 0;
int chunklen;
void *chunkdat;
vfsmfile_t *f = (vfsmfile_t*)file;
while ((chunklen = preparechunk(f, bytestoread, &chunkdat)) > 0)
{
// Sys_Printf("Write %i at %u\n", chunklen, f->offset);
memcpy(chunkdat, buffer, chunklen);
buffer = (char*)buffer + chunklen;
bytestoread -= chunklen;
total += chunklen;
f->offset += chunklen;
}
if (f->file->length < f->offset)
f->file->length = f->offset;
// Sys_Printf("written: %i, file is now at %i\n", total, f->offset);
return total;
}
static qboolean VFSMEM_Seek (struct vfsfile_s *file, unsigned long pos)
{
vfsmfile_t *f = (vfsmfile_t*)file;
f->offset = pos;
return true;
}
static unsigned long VFSMEM_Tell (struct vfsfile_s *file)
{
vfsmfile_t *f = (vfsmfile_t*)file;
return f->offset;
}
static unsigned long VFSMEM_GetSize (struct vfsfile_s *file)
{
vfsmfile_t *f = (vfsmfile_t*)file;
return f->file->length;
}
static void VFSMEM_Close(vfsfile_t *file)
{
vfsmfile_t *f = (vfsmfile_t*)file;
f->file->refs -= 1;
if (!f->file->refs)
{
if (f->file->unlinked)
{
mfchunk_t *cnk;
while (f->file->chunkhead)
{
cnk = f->file->chunkhead->next;
free(f->file->chunkhead);
f->file->chunkhead = cnk;
}
free(f->file);
}
}
free(f);
}
static void VFSMEM_Flush(struct vfsfile_s *file)
{
// vfsmfile_t *f = (vfsmfile_t*)file;
}
vfsfile_t *FSPPAPI_OpenTemp(void)
{
/*create a file which is already unlinked*/
mfile_t *f;
vfsmfile_t *r;
f = malloc(sizeof(*f));
if (!f)
return NULL;
strcpy(f->name, "some temp file");
f->refs = 0;
f->unlinked = true;
f->length = 0;
f->next = NULL;
f->prev = NULL;
f->chunkhead = NULL;
f->chunktail = NULL;
r = malloc(sizeof(*r));
if (!r)
return NULL;
r->file = f;
r->offset = 0;
r->cchunk = NULL;
f->refs++;
r->funcs.ReadBytes = VFSMEM_ReadBytes;
r->funcs.WriteBytes = VFSMEM_WriteBytes;
r->funcs.Seek = VFSMEM_Seek;
r->funcs.Tell = VFSMEM_Tell;
r->funcs.GetLen = VFSMEM_GetSize;
r->funcs.Close = VFSMEM_Close;
r->funcs.Flush = VFSMEM_Flush;
return &r->funcs;
}
vfsfile_t *VFSPPAPI_Open(const char *osname, const char *mode)
{
mfile_t *f;
vfsmfile_t *r;
if (strlen(osname) >= sizeof(f->name))
return NULL;
for (f = mfiles; f; f = f->next)
{
if (!strcmp(f->name, osname))
break;
}
if (!f && (*mode == 'w' || *mode == 'a'))
{
f = malloc(sizeof(*f));
if (f)
{
strcpy(f->name, osname);
f->refs = 0;
f->unlinked = false;
f->length = 0;
f->next = mfiles;
f->prev = NULL;
if (mfiles)
mfiles->prev = f;
mfiles = f;
f->chunkhead = NULL;
f->chunktail = NULL;
}
}
if (!f)
return NULL;
r = malloc(sizeof(*r));
if (!r)
return NULL;
r->file = f;
r->offset = 0;
r->cchunk = NULL;
f->refs++;
r->funcs.ReadBytes = VFSMEM_ReadBytes;
r->funcs.WriteBytes = VFSMEM_WriteBytes;
r->funcs.Seek = VFSMEM_Seek;
r->funcs.Tell = VFSMEM_Tell;
r->funcs.GetLen = VFSMEM_GetSize;
r->funcs.Close = VFSMEM_Close;
r->funcs.Flush = VFSMEM_Flush;
return &r->funcs;
}
static vfsfile_t *FSPPAPI_OpenVFS(void *handle, flocation_t *loc, const char *mode)
{
char diskname[MAX_OSPATH];
//path is already cleaned, as anything that gets a valid loc needs cleaning up first.
snprintf(diskname, sizeof(diskname), "%s/%s", (char*)handle, loc->rawname);
return VFSPPAPI_Open(diskname, mode);
}
static void FSPPAPI_PrintPath(void *handle)
{
Con_Printf("%s\n", (char*)handle);
}
static void FSPPAPI_ClosePath(void *handle)
{
Z_Free(handle);
}
static int FSPPAPI_RebuildFSHash(const char *filename, int filesize, void *data)
{
if (filename[strlen(filename)-1] == '/')
{ //this is actually a directory
char childpath[256];
Q_snprintfz(childpath, sizeof(childpath), "%s*", filename);
Sys_EnumerateFiles((char*)data, childpath, FSPPAPI_RebuildFSHash, data);
return true;
}
if (!Hash_GetInsensative(&filesystemhash, filename))
{
bucket_t *bucket = (bucket_t*)BZ_Malloc(sizeof(bucket_t) + strlen(filename)+1);
strcpy((char *)(bucket+1), filename);
//#ifdef _WIN32
// Q_strlwr((char *)(bucket+1));
//#endif
Hash_AddInsensative(&filesystemhash, (char *)(bucket+1), data, bucket);
fs_hash_files++;
}
else
fs_hash_dups++;
return true;
}
static void FSPPAPI_BuildHash(void *handle)
{
Sys_EnumerateFiles(handle, "*", FSPPAPI_RebuildFSHash, handle);
}
/*
void debugfs(void)
{
static qboolean firstrun = true;
int len;
FILE *f;
vfsfile_t *v;
char *buf;
if (!firstrun)
return;
firstrun = false;
f = fopen("C:/Games/Quake/fte_trunk/pub/id1/pak0.pak", "rb");
fseek(f, 0, SEEK_END);
len = ftell(f);
fseek(f, 0, SEEK_SET);
buf = malloc(len);
fread(buf, 1, len, f);
fclose(f);
v = VFSPPAPI_Open("C:\\Games\\Quake/id1/pak0.pak", "wb");
VFS_WRITE(v, buf, len);
free(buf);
VFS_CLOSE(v);
}
*/
static qboolean FSPPAPI_FLocate(void *handle, flocation_t *loc, const char *filename, void *hashedresult)
{
int len;
char netpath[MAX_OSPATH];
if (hashedresult && (void *)hashedresult != handle)
return false;
/*
if (!static_registered)
{ // if not a registered version, don't ever go beyond base
if ( strchr (filename, '/') || strchr (filename,'\\'))
continue;
}
*/
// check a file in the directory tree
snprintf (netpath, sizeof(netpath)-1, "%s/%s",(char*)handle, filename);
{
vfsfile_t *f = VFSPPAPI_Open(netpath, "rb");
if (!f)
return false;
len = VFS_GETLEN(f);
VFS_CLOSE(f);
}
if (loc)
{
loc->len = len;
loc->offset = 0;
loc->index = 0;
Q_strncpyz(loc->rawname, filename, sizeof(loc->rawname));
}
return true;
}
static void FSPPAPI_ReadFile(void *handle, flocation_t *loc, char *buffer)
{
vfsfile_t *f;
size_t result;
f = VFSPPAPI_Open(loc->rawname, "rb");
if (!f) //err...
return;
VFS_SEEK(f, loc->offset);
result = VFS_READ(f, buffer, loc->len);
if (result != loc->len)
Con_Printf("FSPPAPI_ReadFile() fread: Filename: %s, expected %i, result was %u\n",loc->rawname,loc->len,(unsigned int)result);
VFS_CLOSE(f);
}
static int FSPPAPI_EnumerateFiles (void *handle, const char *match, int (*func)(const char *, int, void *), void *parm)
{
return Sys_EnumerateFiles(handle, match, func, parm);
}
searchpathfuncs_t osfilefuncs = {
FSPPAPI_PrintPath,
FSPPAPI_ClosePath,
FSPPAPI_BuildHash,
FSPPAPI_FLocate,
FSPPAPI_ReadFile,
FSPPAPI_EnumerateFiles,
NULL,
NULL,
FSPPAPI_OpenVFS
};
#else
#define FSPPAPI_OpenTemp FS_OpenTemp
#define VFSPPAPI_Open VFSOS_Open
extern PPB_FileIO *ppb_fileio;
extern PPB_FileRef *ppb_fileref;
extern PPB_FileSystem *ppb_filesystem;
extern PPB_Core *ppb_core;
extern PP_Instance pp_instance;
static PP_Resource mainfilesystem;
struct PP_CompletionCallback nullccb;
void FSPPAPI_Init(void)
{
mainfilesystem = ppb_filesystem->Create(pp_instance, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
ppb_filesystem->Open(mainfilesystem, 100*1024*1024, nullccb);
}
typedef struct {
vfsfile_t funcs;
PP_Resource handle;
int64_t offset;
} vfsppapifile_t;
static int VFSPPAPI_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
{
int res;
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
res = ppb_fileio->Read(intfile->handle, intfile->offset, buffer, bytestoread, nullccb);
if (res > 0)
intfile->offset += res;
return res;
}
static int VFSPPAPI_WriteBytes (struct vfsfile_s *file, const void *buffer, int bytestoread)
{
int res;
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
res = ppb_fileio->Write(intfile->handle, intfile->offset, buffer, bytestoread, nullccb);
if (res > 0)
intfile->offset += res;
return res;
}
static qboolean VFSPPAPI_Seek (struct vfsfile_s *file, unsigned long pos)
{
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
intfile->offset = pos;
return true;
}
static unsigned long VFSPPAPI_Tell (struct vfsfile_s *file)
{
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
return intfile->offset;
}
static void VFSPPAPI_Flush(struct vfsfile_s *file)
{
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
ppb_fileio->Flush(intfile->handle, nullccb);
}
static unsigned long VFSPPAPI_GetSize (struct vfsfile_s *file)
{
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
struct PP_FileInfo fileinfo;
fileinfo.size = 0;
ppb_fileio->Query(intfile->handle, &fileinfo, nullccb);
return fileinfo.size;
}
static void VFSPPAPI_Close(vfsfile_t *file)
{
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
ppb_fileio->Close(intfile->handle);
ppb_core->ReleaseResource(intfile->handle);
Z_Free(file);
}
#ifdef _WIN32
static void VFSPPAPI_CloseTemp(vfsfile_t *file)
{
vfsppapifile_t *intfile = (vfsppapifile_t*)file;
char *fname = (char*)(intfile+1);
ppb_fileio->Close(intfile->handle);
ppb_core->ReleaseResource(intfile->handle);
/*FIXME: add the remove somewhere*/
// _unlink(fname);
Z_Free(file);
}
#endif
vfsfile_t *FSPPAPI_OpenTemp(void)
{
return NULL;
#if 0
FILE *f;
vfsppapifile_t *file;
f = tmpfile();
if (!f)
return NULL;
file = Z_Malloc(sizeof(vfsppapifile_t));
file->funcs.Close = VFSPPAPI_Close;
file->funcs.ReadBytes = VFSPPAPI_ReadBytes;
file->funcs.WriteBytes = VFSPPAPI_WriteBytes;
file->funcs.Seek = VFSPPAPI_Seek;
file->funcs.Tell = VFSPPAPI_Tell;
file->funcs.GetLen = VFSPPAPI_GetSize;
file->funcs.Flush = VFSPPAPI_Flush;
file->handle = f;
return (vfsfile_t*)file;
#endif
}
vfsfile_t *VFSPPAPI_Open(const char *osname, const char *mode)
{
int e;
PP_Resource f;
PP_Resource fsf;
vfsppapifile_t *file;
qboolean read = !!strchr(mode, 'r');
qboolean write = !!strchr(mode, 'w');
qboolean append = !!strchr(mode, 'a');
int newmode = 0;
if (read)
newmode |= PP_FILEOPENFLAG_READ;
if (write)
newmode |= PP_FILEOPENFLAG_WRITE|PP_FILEOPENFLAG_TRUNCATE|PP_FILEOPENFLAG_CREATE;
if (append)
newmode |= PP_FILEOPENFLAG_WRITE|PP_FILEOPENFLAG_CREATE;
/*should we support w+ or r+ */
fsf = ppb_fileref->Create(mainfilesystem, osname);
f = ppb_fileio->Create(pp_instance);
e = ppb_fileio->Open(f, fsf, newmode, nullccb);
ppb_core->ReleaseResource(fsf);
if (e != PP_OK)
{
Con_Printf("unable to open %s. error %i\n", osname, e);
return NULL;
}
file = Z_Malloc(sizeof(vfsppapifile_t));
file->funcs.ReadBytes = strchr(mode, 'r')?VFSPPAPI_ReadBytes:NULL;
file->funcs.WriteBytes = (strchr(mode, 'w')||strchr(mode, 'a'))?VFSPPAPI_WriteBytes:NULL;
file->funcs.Seek = VFSPPAPI_Seek;
file->funcs.Tell = VFSPPAPI_Tell;
file->funcs.GetLen = VFSPPAPI_GetSize;
file->funcs.Close = VFSPPAPI_Close;
file->funcs.Flush = VFSPPAPI_Flush;
file->handle = f;
if (append)
file->offset = VFSPPAPI_GetSize((vfsfile_t*)file);
else
file->offset = 0;
return (vfsfile_t*)file;
}
static vfsfile_t *FSPPAPI_OpenVFS(void *handle, flocation_t *loc, const char *mode)
{
char diskname[MAX_OSPATH];
//path is already cleaned, as anything that gets a valid loc needs cleaning up first.
snprintf(diskname, sizeof(diskname), "%s/%s", (char*)handle, loc->rawname);
return VFSPPAPI_Open(diskname, mode);
}
static void FSPPAPI_PrintPath(void *handle)
{
Con_Printf("%s\n", (char*)handle);
}
static void FSPPAPI_ClosePath(void *handle)
{
Z_Free(handle);
}
static int FSPPAPI_RebuildFSHash(const char *filename, int filesize, void *data)
{
if (filename[strlen(filename)-1] == '/')
{ //this is actually a directory
char childpath[256];
Q_snprintfz(childpath, sizeof(childpath), "%s*", filename);
Sys_EnumerateFiles((char*)data, childpath, FSPPAPI_RebuildFSHash, data);
return true;
}
if (!Hash_GetInsensative(&filesystemhash, filename))
{
bucket_t *bucket = (bucket_t*)BZ_Malloc(sizeof(bucket_t) + strlen(filename)+1);
strcpy((char *)(bucket+1), filename);
//#ifdef _WIN32
// Q_strlwr((char *)(bucket+1));
//#endif
Hash_AddInsensative(&filesystemhash, (char *)(bucket+1), data, bucket);
fs_hash_files++;
}
else
fs_hash_dups++;
return true;
}
static void FSPPAPI_BuildHash(void *handle)
{
Sys_EnumerateFiles(handle, "*", FSPPAPI_RebuildFSHash, handle);
}
static qboolean FSPPAPI_FLocate(void *handle, flocation_t *loc, const char *filename, void *hashedresult)
{
int len;
char netpath[MAX_OSPATH];
Con_Printf("Locate %s\n", filename);
if (hashedresult && (void *)hashedresult != handle)
return false;
/*
if (!static_registered)
{ // if not a registered version, don't ever go beyond base
if ( strchr (filename, '/') || strchr (filename,'\\'))
continue;
}
*/
// check a file in the directory tree
snprintf (netpath, sizeof(netpath)-1, "%s/%s",(char*)handle, filename);
{
vfsfile_t *f = VFSPPAPI_Open(netpath, "rb");
if (!f)
return false;
len = VFS_GETLEN(f);
VFS_CLOSE(f);
}
if (loc)
{
loc->len = len;
loc->offset = 0;
loc->index = 0;
Q_strncpyz(loc->rawname, filename, sizeof(loc->rawname));
}
return true;
}
static void FSPPAPI_ReadFile(void *handle, flocation_t *loc, char *buffer)
{
vfsfile_t *f;
size_t result;
f = VFSPPAPI_Open(loc->rawname, "rb");
if (!f) //err...
return;
VFS_SEEK(f, loc->offset);
result = VFS_READ(f, buffer, loc->len);
if (result != loc->len)
Con_Printf("FSPPAPI_ReadFile() fread: Filename: %s, expected %i, result was %u\n",loc->rawname,loc->len,(unsigned int)result);
VFS_CLOSE(f);
}
static int FSPPAPI_EnumerateFiles (void *handle, const char *match, int (*func)(const char *, int, void *), void *parm)
{
return Sys_EnumerateFiles(handle, match, func, parm);
}
searchpathfuncs_t osfilefuncs = {
FSPPAPI_PrintPath,
FSPPAPI_ClosePath,
FSPPAPI_BuildHash,
FSPPAPI_FLocate,
FSPPAPI_ReadFile,
FSPPAPI_EnumerateFiles,
NULL,
NULL,
FSPPAPI_OpenVFS
};
#endif

277
engine/nacl/gl_vidppapi.c Normal file
View file

@ -0,0 +1,277 @@
#include "quakedef.h"
#include "glquake.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/gles2/gl2ext_ppapi.h"
#include "ppapi/c/ppb_graphics_3d.h"
#include "ppapi/c/ppb_instance.h"
extern PPB_GetInterface sys_gbi;
extern PPB_Graphics3D* graphics3d_interface;
extern PP_Instance pp_instance;
static PP_Resource glcontext;
extern PPB_Instance* instance_interface;
int delayedswap = false;
void swap_callback(void* user_data, int32_t result)
{
// printf("swap result: %d\n", result);
}
void GL_BeginRendering (void)
{
}
void GL_EndRendering (void)
{
delayedswap = true;
glFlush();
}
void GL_DoSwap(void)
{
if (delayedswap)
{
struct PP_CompletionCallback ccb = { swap_callback, NULL, PP_COMPLETIONCALLBACK_FLAG_OPTIONAL};
graphics3d_interface->SwapBuffers(glcontext, ccb);
delayedswap = false;
}
}
void GLVID_SetPalette (unsigned char *palette)
{
qbyte *pal;
unsigned int r,g,b;
int i;
unsigned *table1;
extern qbyte gammatable[256];
pal = palette;
table1 = d_8to24rgbtable;
for (i=0 ; i<256 ; i++)
{
r = gammatable[pal[0]];
g = gammatable[pal[1]];
b = gammatable[pal[2]];
pal += 3;
*table1++ = LittleLong((255<<24) + (r<<0) + (g<<8) + (b<<16));
}
d_8to24rgbtable[255] &= LittleLong(0xffffff); // 255 is transparent
}
void GLVID_ShiftPalette (unsigned char *palette)
{
}
void *PPAPI_GetGLSymbol(char *symname)
{
int i;
static struct {char *name; void *ptr;} funcs[] =
{
#define f(n) {#n , n},
f(glActiveTexture)
f(glAttachShader)
f(glBindAttribLocation)
f(glBindBuffer)
f(glBindFramebuffer)
f(glBindRenderbuffer)
f(glBindTexture)
f(glBlendColor)
f(glBlendEquation)
f(glBlendEquationSeparate)
f(glBlendFunc)
f(glBlendFuncSeparate)
f(glBufferData)
f(glBufferSubData)
f(glCheckFramebufferStatus)
f(glClear)
f(glClearColor)
f(glClearDepthf)
f(glClearStencil)
f(glColorMask)
f(glCompileShader)
f(glCompressedTexImage2D)
f(glCompressedTexSubImage2D)
f(glCopyTexImage2D)
f(glCopyTexSubImage2D)
f(glCreateProgram)
f(glCreateShader)
f(glCullFace)
f(glDeleteBuffers)
f(glDeleteFramebuffers)
f(glDeleteProgram)
f(glDeleteRenderbuffers)
f(glDeleteShader)
f(glDeleteTextures)
f(glDepthFunc)
f(glDepthMask)
f(glDepthRangef)
f(glDetachShader)
f(glDisable)
f(glDisableVertexAttribArray)
f(glDrawArrays)
f(glDrawElements)
f(glEnable)
f(glEnableVertexAttribArray)
f(glFinish)
f(glFlush)
f(glFramebufferRenderbuffer)
f(glFramebufferTexture2D)
f(glFrontFace)
f(glGenBuffers)
f(glGenerateMipmap)
f(glGenFramebuffers)
f(glGenRenderbuffers)
f(glGenTextures)
f(glGetActiveAttrib)
f(glGetActiveUniform)
f(glGetAttachedShaders)
f(glGetAttribLocation)
f(glGetBooleanv)
f(glGetBufferParameteriv)
f(glGetError)
f(glGetFloatv)
f(glGetFramebufferAttachmentParameteriv)
f(glGetIntegerv)
f(glGetProgramiv)
f(glGetProgramInfoLog)
f(glGetRenderbufferParameteriv)
f(glGetShaderiv)
f(glGetShaderInfoLog)
f(glGetShaderPrecisionFormat)
f(glGetShaderSource)
f(glGetString)
f(glGetTexParameterfv)
f(glGetTexParameteriv)
f(glGetUniformfv)
f(glGetUniformiv)
f(glGetUniformLocation)
f(glGetVertexAttribfv)
f(glGetVertexAttribiv)
f(glGetVertexAttribPointerv)
f(glHint)
f(glIsBuffer)
f(glIsEnabled)
f(glIsFramebuffer)
f(glIsProgram)
f(glIsRenderbuffer)
f(glIsShader)
f(glIsTexture)
f(glLineWidth)
f(glLinkProgram)
f(glPixelStorei)
f(glPolygonOffset)
f(glReadPixels)
f(glReleaseShaderCompiler)
f(glRenderbufferStorage)
f(glSampleCoverage)
f(glScissor)
f(glShaderBinary)
f(glShaderSource)
f(glStencilFunc)
f(glStencilFuncSeparate)
f(glStencilMask)
f(glStencilMaskSeparate)
f(glStencilOp)
f(glStencilOpSeparate)
f(glTexImage2D)
f(glTexParameterf)
f(glTexParameterfv)
f(glTexParameteri)
f(glTexParameteriv)
f(glTexSubImage2D)
f(glUniform1f)
f(glUniform1fv)
f(glUniform1i)
f(glUniform1iv)
f(glUniform2f)
f(glUniform2fv)
f(glUniform2i)
f(glUniform2iv)
f(glUniform3f)
f(glUniform3fv)
f(glUniform3i)
f(glUniform3iv)
f(glUniform4f)
f(glUniform4fv)
f(glUniform4i)
f(glUniform4iv)
f(glUniformMatrix2fv)
f(glUniformMatrix3fv)
f(glUniformMatrix4fv)
f(glUseProgram)
f(glValidateProgram)
f(glVertexAttrib1f)
f(glVertexAttrib1fv)
f(glVertexAttrib2f)
f(glVertexAttrib2fv)
f(glVertexAttrib3f)
f(glVertexAttrib3fv)
f(glVertexAttrib4f)
f(glVertexAttrib4fv)
f(glVertexAttribPointer)
f(glViewport)
{NULL}
};
for (i = 0; funcs[i].name; i++)
{
if (!strcmp(funcs[i].name, symname))
return funcs[i].ptr;
}
return NULL;
}
qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
{
int32_t attribs[] = {PP_GRAPHICS3DATTRIB_WIDTH, info->width,
PP_GRAPHICS3DATTRIB_HEIGHT, info->height,
PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 24,
PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 8,
PP_GRAPHICS3DATTRIB_NONE};
glcontext = graphics3d_interface->Create(pp_instance, 0, attribs);
glSetCurrentContextPPAPI(glcontext);
if (!instance_interface->BindGraphics(pp_instance, glcontext))
{
Con_Printf("failed to bind context\n");
return false;
}
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
GL_EndRendering();
GL_DoSwap();
vid.pixelwidth = info->width;
vid.pixelheight = info->height;
GLVID_SetPalette (palette);
GL_Init(PPAPI_GetGLSymbol);
vid.recalc_refdef = 1;
return true;
}
void GLVID_Shutdown (void)
{
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
GL_EndRendering();
GL_DoSwap();
glTerminatePPAPI();
}
void GLVID_DeInit (void)
{
GLVID_Shutdown();
}
void GLVID_Crashed(void);
void GLVID_Update (vrect_t *rects);
int GLVID_SetMode (rendererstate_t *info, unsigned char *palette);
void GLVID_SetCaption(char *caption)
{
}

115
engine/nacl/snd_ppapi.c Normal file
View file

@ -0,0 +1,115 @@
#include "quakedef.h"
#include <ppapi/c/ppb_core.h>
#include <ppapi/c/ppb_audio.h>
#include <ppapi/c/ppb_audio_config.h>
extern PPB_Core *ppb_core;
extern PPB_Audio *audio_interface;
extern PPB_AudioConfig *audioconfig_interface;
extern PP_Instance pp_instance;
static PPB_Audio_Callback audio_callback;
extern int GetSoundtime(soundcardinfo_t *sc);
static void PPAPI_audio_callback(void *sample_buffer, uint32_t len, void *user_data)
{
soundcardinfo_t *sc = user_data;
unsigned int framesz;
if (sc)
{
int curtime = GetSoundtime(sc);
framesz = sc->sn.numchannels * sc->sn.samplebits/8;
//might as well dump it directly...
sc->sn.buffer = sample_buffer;
sc->sn.samples = len / (sc->sn.samplebits/8);
S_PaintChannels (sc, curtime + (len / framesz));
sc->sn.samples = 0;
sc->sn.buffer = NULL;
sc->snd_sent += len;
}
}
static void PPAPI_Shutdown(soundcardinfo_t *sc)
{
audio_interface->StopPlayback((PP_Resource)sc->handle);
ppb_core->ReleaseResource((PP_Resource)sc->handle);
}
static unsigned int PPAPI_GetDMAPos(soundcardinfo_t *sc)
{
sc->sn.samplepos = sc->snd_sent / (sc->sn.samplebits/8);
return sc->sn.samplepos;
}
static void PPAPI_UnlockBuffer(soundcardinfo_t *sc, void *buffer)
{
}
static void *PPAPI_LockBuffer(soundcardinfo_t *sc, unsigned int *sampidx)
{
*sampidx = 0;
return sc->sn.buffer;
}
static void PPAPI_SetUnderWater(soundcardinfo_t *sc, qboolean uw)
{
}
static void PPAPI_Submit(soundcardinfo_t *sc, int start, int end)
{
}
int PPAPI_InitCard (soundcardinfo_t *sc, int cardnum)
{
PP_Resource config;
int framecount;
/*I'm not aware of any limits on the number of 'devices' we can create, but virtual devices on the same physical device are utterly pointless, so don't load more than one*/
if (cardnum != 0)
return 2;
/*the docs say only two sample rates are allowed*/
if (sc->sn.speed <= 44100)
sc->sn.speed = 44100;
else
sc->sn.speed = 48000;
/*we can't choose these two settings*/
sc->sn.samplebits = 16;
sc->sn.numchannels = 2;
framecount = audioconfig_interface->RecommendSampleFrameCount(sc->sn.speed, 2048);
/*the callback paints directly into the caller's buffer, so we don't need a separate 'dma' buffer*/
sc->selfpainting = true;
sc->sn.samples = 0; /*framecount*/
sc->sn.buffer = NULL;
sc->snd_sent = 0;
sc->sn.samplepos = 0;
sc->Submit = PPAPI_Submit;
sc->GetDMAPos = PPAPI_GetDMAPos;
sc->Lock = PPAPI_LockBuffer;
sc->Unlock = PPAPI_UnlockBuffer;
sc->SetWaterDistortion = PPAPI_SetUnderWater;
sc->Shutdown = PPAPI_Shutdown;
config = audioconfig_interface->CreateStereo16Bit(pp_instance, sc->sn.speed, framecount);
if (config)
{
sc->handle = (void*)audio_interface->Create(pp_instance, config, PPAPI_audio_callback, sc);
ppb_core->ReleaseResource(config);
if (sc->handle)
{
if (audio_interface->StartPlayback((PP_Resource)sc->handle))
return 1;
}
}
return 0;
}
int (*pPPAPI_InitCard) (soundcardinfo_t *sc, int cardnum) = &PPAPI_InitCard;

614
engine/nacl/sys_ppapi.c Normal file
View file

@ -0,0 +1,614 @@
#include "quakedef.h"
#include <ppapi/c/pp_errors.h>
#include <ppapi/c/ppb.h>
#include <ppapi/c/ppb_core.h>
#include <ppapi/c/ppb_graphics_3d.h>
#include <ppapi/c/ppb_instance.h>
#include <ppapi/c/ppp.h>
#include <ppapi/c/ppp_instance.h>
#include <ppapi/c/ppb_input_event.h>
#include <ppapi/c/ppp_input_event.h>
#include <ppapi/c/ppb_var.h>
#include <ppapi/c/ppb_messaging.h>
#include <ppapi/c/ppb_file_system.h>
#include <ppapi/c/ppb_file_ref.h>
#include <ppapi/c/ppb_file_io.h>
#include <ppapi/c/ppb_url_loader.h>
#include <ppapi/c/ppb_url_response_info.h>
#include <ppapi/c/ppb_url_request_info.h>
#include <ppapi/c/ppb_audio.h>
#include <ppapi/c/ppb_audio_config.h>
#include <ppapi/c/ppb_mouse_lock.h>
#include <ppapi/c/ppp_mouse_lock.h>
#include <ppapi/c/ppb_fullscreen.h>
#include <ppapi/c/ppb_websocket.h>
#include <ppapi/c/pp_input_event.h>
#include <ppapi/gles2/gl2ext_ppapi.h>
PPB_Core *ppb_core = NULL;
PPB_Graphics3D *graphics3d_interface = NULL;
PPB_Instance *instance_interface = NULL;
PPB_Messaging *ppb_messaging_interface = NULL;
PPB_Var *ppb_var_interface = NULL;
PPB_InputEvent *ppb_inputevent_interface = NULL;
PPB_KeyboardInputEvent *ppb_keyboardinputevent_interface = NULL;
PPB_MouseInputEvent *ppb_mouseinputevent_interface = NULL;
PPB_WheelInputEvent *ppb_wheelinputevent_interface = NULL;
PPB_FileIO *ppb_fileio = NULL;
PPB_FileRef *ppb_fileref = NULL;
PPB_FileSystem *ppb_filesystem = NULL;
PPB_URLLoader *urlloader = NULL;
PPB_URLRequestInfo *urlrequestinfo = NULL;
PPB_URLResponseInfo *urlresponseinfo = NULL;
PPB_Audio *audio_interface = NULL;
PPB_AudioConfig *audioconfig_interface = NULL;
PPB_MouseLock *ppb_mouselock_interface = NULL;
PPB_Fullscreen *ppb_fullscreen_interface = NULL;
PPB_WebSocket *ppb_websocket_interface = NULL;;
PP_Instance pp_instance;
PPB_GetInterface sys_gbi;
static double lasttime;
static qboolean mouselocked;
static qboolean shuttingdown;
qboolean FSPPAPI_Init(int *filenocookie);
unsigned short htons(unsigned short a)
{
union
{
unsigned char c[2];
unsigned short s;
} u;
u.s = a;
return u.c[0] | (unsigned short)(u.c[1]<<8);
}
unsigned short ntohs(unsigned short a)
{
return htons(a);
}
unsigned int htonl(unsigned int a)
{
union
{
unsigned char c[4];
unsigned int s;
} u;
u.s = a;
return u.c[0] | (unsigned int)(u.c[1]<<8) | (unsigned int)(u.c[2]<<16) | (unsigned int)(u.c[3]<<24);
}
unsigned long ntohl(unsigned long a)
{
return htonl(a);
}
qboolean isDedicated = false;
dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs)
{
return NULL;
}
void Sys_CloseLibrary(dllhandle_t *lib)
{
}
void *Sys_GetAddressForName(dllhandle_t *module, const char *exportname)
{
return NULL;
}
char *Sys_GetNameForAddress(dllhandle_t *module, void *address)
{
return NULL;
}
qboolean Sys_RandomBytes(qbyte *string, int len)
{
return false;
}
//q2...
void Sys_UnloadGame (void)
{
}
//q2...
void *Sys_GetGameAPI (void *parms)
{
return NULL;
}
qboolean Sys_InitTerminal (void)
{
return false;
}
void Sys_CloseTerminal (void)
{
}
char *Sys_GetClipboard(void)
{
return NULL;
}
void Sys_CloseClipboard(char *buf)
{
}
void Sys_SaveClipboard(char *text)
{
}
void Sys_ServerActivity(void)
{
}
char *Sys_ConsoleInput (void)
{
return NULL;
}
void Sys_SendKeyEvents(void)
{
}
void Sys_Init (void)
{
}
void Sys_Shutdown(void)
{
}
//nacl supposedly has no way to implement this (other than us writing a listfile in each directory)
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *), void *parm)
{
return 0;
}
qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate)
{
*width = 1024;
*height = 768;
*bpp = 32;
*refreshrate = 60;
return true;
return false;
}
// an error will cause the entire program to exit
NORETURN void VARGS Sys_Error (const char *error, ...)
{
va_list argptr;
char string[1024];
va_start (argptr, error);
vsnprintf (string, sizeof(string)-1, error, argptr);
va_end (argptr);
Sys_Printf("Sys_Error: ");
Sys_Printf("%s", string);
exit(1);
}
static struct PP_Var CStrToVar(const char* str)
{
if (ppb_var_interface != NULL)
{
return ppb_var_interface->VarFromUtf8(str, strlen(str));
}
return PP_MakeUndefined();
}
void VARGS Sys_Printf (char *fmt, ...)
{
va_list argptr;
char string[1024];
va_start (argptr, fmt);
vsnprintf (string, sizeof(string)-1, fmt, argptr);
va_end (argptr);
//this stuff generally doesn't even get shown
printf("%s", string);
if (pp_instance)
ppb_messaging_interface->PostMessage(pp_instance, CStrToVar(string));
}
void Sys_Quit (void)
{
Sys_Printf("Sys_Quit\n");
shuttingdown = true;
}
void Sys_RecentServer(char *command, char *target, char *title, char *desc)
{
}
void Sys_mkdir (char *path)
{
}
qboolean Sys_remove (char *path)
{
return false;
}
#include <sys/time.h>
static int secbase;
double Sys_DoubleTime(void)
{
struct timeval tp;
struct timezone tzp;
gettimeofday(&tp, &tzp);
if (!secbase)
{
secbase = tp.tv_sec;
return tp.tv_usec/1000000.0;
}
return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
}
unsigned int Sys_Milliseconds (void)
{
return Sys_DoubleTime()*1000;
}
void FrameEvent(void* user_data, int32_t result)
{
if (shuttingdown)
{
if (!mouselocked && ppb_mouselock_interface)
ppb_mouselock_interface->UnlockMouse(pp_instance);
if (ppb_fullscreen_interface)
ppb_fullscreen_interface->SetFullscreen(pp_instance, PP_FALSE);
Host_Shutdown ();
ppb_inputevent_interface->RequestInputEvents(pp_instance, 0);
shuttingdown = false;
return;
}
if (pp_instance)
{
double newtime = Sys_DoubleTime();
Host_Frame(newtime - lasttime);
lasttime = newtime;
// Sys_Printf("Frame %f\n", newtime);
struct PP_CompletionCallback ccb = {FrameEvent, user_data, PP_COMPLETIONCALLBACK_FLAG_NONE};
ppb_core->CallOnMainThread(0, ccb, 0);
}
}
void startquake(void)
{
const char *args [] =
{
"ftedroid",
"",
""
};
quakeparms_t parms;
parms.basedir = ""; /*filled in later*/
parms.argc = 1;
parms.argv = args;
//FIXME: do something with the embed arguments
parms.memsize = 16*1024*1024;
parms.membase = malloc(parms.memsize);
if (!parms.membase)
{
Sys_Printf("Unable to alloc heap\n");
return;
}
Sys_Printf("Starting up\n");
COM_InitArgv(parms.argc, parms.argv);
TL_InitLanguages();
#ifdef SERVERONLY
SV_Init(&parms);
#else
Host_Init(&parms);
#endif
lasttime = Sys_DoubleTime();
FrameEvent(NULL, 0);
}
void trystartquake(void* user_data, int32_t result)
{
if (FSPPAPI_Init(&result))
startquake();
else
{
struct PP_CompletionCallback ccb = {trystartquake, user_data, PP_COMPLETIONCALLBACK_FLAG_NONE};
ppb_core->CallOnMainThread(100, ccb, result);
}
}
static PP_Bool Instance_DidCreate(PP_Instance instance,
uint32_t argc,
const char* argn[],
const char* argv[])
{
pp_instance = instance;
//FIXME: do something with the embed arguments
ppb_inputevent_interface->RequestInputEvents(pp_instance, PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_KEYBOARD | PP_INPUTEVENT_CLASS_WHEEL);
trystartquake(NULL, 0);
return PP_TRUE;
}
static void cb_mouselocked(void* user_data, int32_t result)
{
if (result == PP_OK)
{
mouselocked = true;
}
}
static void ppp_mouseunlocked(PP_Instance instance)
{
mouselocked = false;
}
unsigned int domkeytoquake(unsigned int code)
{
#define K_PRINTSCREEN ' '
unsigned int tab[256] =
{
/* 0*/ 0,0,0,0,0,0,0,0, K_BACKSPACE,K_TAB,0,0,0,K_ENTER,0,0,
/* 16*/ K_SHIFT,K_CTRL,K_ALT,K_PAUSE,K_CAPSLOCK,0,0,0, 0,0,0,K_ESCAPE,0,0,0,0,
/* 32*/ ' ',K_PGUP,K_PGDN,K_END,K_HOME,K_LEFTARROW,K_UPARROW,K_RIGHTARROW, K_DOWNARROW,0,0,0,K_PRINTSCREEN,K_INS,K_DEL,0,
/* 48*/ '0','1','2','3','4','5','6','7', '8','9',0,0,0,0,0,0,
/* 64*/ 0,'a','b','c','d','e','f','g', 'h','i','j','k','l','m','n','o',
/* 80*/ 'p','q','r','s','t','u','v','w', 'x','y','z',K_LWIN,K_RWIN,K_APP,0,0,
/* 96*/ K_KP_INS,K_KP_END,K_KP_DOWNARROW,K_KP_PGDN,K_KP_LEFTARROW,K_KP_5,K_KP_RIGHTARROW,K_KP_HOME, K_KP_UPARROW,K_KP_PGDN,K_KP_STAR,K_KP_PLUS,0,K_KP_MINUS,K_KP_DEL,K_KP_SLASH,
/*112*/ K_F1,K_F2,K_F3,K_F4,K_F5,K_F6,K_F7,K_F8, K_F9,K_F10,K_F11,K_F12,0,0,0,0,
/*128*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
/*144*/ K_KP_NUMLOCK,K_SCRLCK,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
/*160*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
/*176*/ 0,0,0,0,0,0,0,0, 0,0,';','=',',','-','.','/',
/*192*/ '\'',0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
/*208*/ 0,0,0,0,0,0,0,0, 0,0,0,'[','\\',']','#','`',
/*224*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
/*240*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
};
if (code >= sizeof(tab)/sizeof(tab[0]))
{
Con_DPrintf("You just pressed key %u, but I don't know what its meant to be\n", code);
return 0;
}
if (!tab[code])
Con_DPrintf("You just pressed key %u, but I don't know what its meant to be\n", code);
return tab[code];
}
void IN_QueueKey(int down, int keycode, int unicode);
void IN_QueueMouse(int act, int ptrid, float x, float y, int button);
void IN_AmmendUnicode(int unicode);
PP_Bool InputEvent_HandleEvent(PP_Instance pp_instance, PP_Resource resource)
{
extern cvar_t vid_fullscreen;
if (!pp_instance || !host_initialized)
return PP_FALSE;
switch(ppb_inputevent_interface->GetType(resource))
{
case PP_INPUTEVENT_TYPE_MOUSEDOWN:
if (vid_fullscreen.ival)
{
if (ppb_fullscreen_interface)
ppb_fullscreen_interface->SetFullscreen(pp_instance, PP_TRUE);
if (!mouselocked && ppb_mouselock_interface)
{
struct PP_CompletionCallback ccb = {cb_mouselocked, NULL, PP_COMPLETIONCALLBACK_FLAG_NONE};
int res = ppb_mouselock_interface->LockMouse(pp_instance, ccb);
if (res != PP_OK_COMPLETIONPENDING)
cb_mouselocked(NULL, res);
else
return PP_TRUE;
}
}
IN_QueueMouse(1, 0, 0, 0, ppb_mouseinputevent_interface->GetButton(resource));
return PP_TRUE;
case PP_INPUTEVENT_TYPE_MOUSEUP:
IN_QueueMouse(2, 0, 0, 0, ppb_mouseinputevent_interface->GetButton(resource));
return PP_TRUE;
case PP_INPUTEVENT_TYPE_MOUSEMOVE:
{
struct PP_Point p;
if (mouselocked)
{
p = ppb_mouseinputevent_interface->GetMovement(resource);
IN_QueueMouse(3, 0, p.x, p.y, 0);
}
else
{
p = ppb_mouseinputevent_interface->GetPosition(resource);
IN_QueueMouse(0, 0, p.x, p.y, 0);
}
}
return PP_TRUE;
case PP_INPUTEVENT_TYPE_MOUSEENTER:
//we don't really care too much if it leave the window
// Con_Printf("mouseenter\n");
return PP_TRUE;
case PP_INPUTEVENT_TYPE_MOUSELEAVE:
//we don't really care too much if it leave the window (should throttle framerates perhaps, but that's all)
// Con_Printf("mouseleave\n");
return PP_TRUE;
case PP_INPUTEVENT_TYPE_WHEEL:
{
struct PP_FloatPoint p;
p = ppb_wheelinputevent_interface->GetTicks(resource);
//BUG: the value is fractional.
while (p.x >= 1)
{
IN_QueueKey(1, K_MWHEELUP, 0);
IN_QueueKey(0, K_MWHEELUP, 0);
p.x--;
}
while (p.x <= -1)
{
IN_QueueKey(1, K_MWHEELDOWN, 0);
IN_QueueKey(0, K_MWHEELDOWN, 0);
p.x++;
}
}
return PP_TRUE;
case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
// Con_Printf("rawkeydown\n");
return PP_FALSE;
case PP_INPUTEVENT_TYPE_KEYDOWN:
IN_QueueKey(1, domkeytoquake(ppb_keyboardinputevent_interface->GetKeyCode(resource)), 0);
return PP_FALSE;
case PP_INPUTEVENT_TYPE_KEYUP:
IN_QueueKey(0, domkeytoquake(ppb_keyboardinputevent_interface->GetKeyCode(resource)), 0);
return PP_TRUE;
case PP_INPUTEVENT_TYPE_CHAR:
{
const unsigned char *s;
unsigned int c;
unsigned int len;
len = 0;
s = ppb_var_interface->VarToUtf8(ppb_keyboardinputevent_interface->GetCharacterText(resource), &len);
while(len)
{
if (*s & 0x80)
{
if (!(*s & 0x40))
{
//illegal encoding
c = '?';
len -= 1;
}
else if (!(*s & 0x20) && (s[1] & 0xc0) == 0x80)
{
c = ((s[0] & 0x1f)<<6) | ((s[1] & 0x3f)<<0);
if (c < (1<<7))
c = '?';
len -= 2;
}
else if (!(*s & 0x10) && (s[1] & 0xc0) == 0x80 && (s[2] & 0xc0) == 0x80)
{
c = ((s[0] & 0x0f)<<12) | ((s[1] & 0x3f)<<6) | ((s[2] & 0x3f)<<0);
if (c < (1<<13))
c = '?';
len -= 3;
}
else if (!(*s & 0x08) && (s[1] & 0xc0) == 0x80 && (s[2] & 0xc0) == 0x80 && (s[3] & 0xc0) == 0x80)
{
c = ((s[0] & 0x07)<<18) | ((s[1] & 0x3f)<<12) | ((s[2] & 0x3f)<<6) | ((s[3] & 0x3f)<<0);
if (c < (1<<19))
c = '?';
len -= 4;
}
else
{
//too lazy to handle that encoding
c = '?';
len -= 1;
}
}
else
{
c = *s;
len--;
}
IN_AmmendUnicode(c);
}
}
return PP_TRUE;
case PP_INPUTEVENT_TYPE_CONTEXTMENU:
//We don't care about the context menu, we just want to be able to right-click.
return PP_TRUE;
default:
Con_Printf("Unknown input event type\n");
break;
}
return PP_FALSE;
}
static void Instance_DidDestroy(PP_Instance instance)
{
}
static void Instance_DidChangeView(PP_Instance instance, PP_Resource view_resource)
{
}
static void Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus)
{
}
static PP_Bool Instance_HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader)
{
return PP_FALSE;
}
PP_EXPORT int32_t PPP_InitializeModule(PP_Module a_module_id, PPB_GetInterface get_browser)
{
ppb_core = (PPB_Core*)(get_browser(PPB_CORE_INTERFACE));
sys_gbi = get_browser;
graphics3d_interface = (PPB_Graphics3D*)(get_browser(PPB_GRAPHICS_3D_INTERFACE));
ppb_messaging_interface = (PPB_Messaging*)(get_browser(PPB_MESSAGING_INTERFACE));
ppb_var_interface = (PPB_Var*)(get_browser(PPB_VAR_INTERFACE));
instance_interface = (PPB_Instance*)(get_browser(PPB_INSTANCE_INTERFACE));
ppb_inputevent_interface = (PPB_InputEvent*)(get_browser(PPB_INPUT_EVENT_INTERFACE));
ppb_keyboardinputevent_interface = (PPB_KeyboardInputEvent*)(get_browser(PPB_KEYBOARD_INPUT_EVENT_INTERFACE));
ppb_mouseinputevent_interface = (PPB_MouseInputEvent*)(get_browser(PPB_MOUSE_INPUT_EVENT_INTERFACE));
ppb_wheelinputevent_interface = (PPB_WheelInputEvent*)(get_browser(PPB_WHEEL_INPUT_EVENT_INTERFACE));
ppb_fileio = (PPB_FileIO*)(get_browser(PPB_FILEIO_INTERFACE));
ppb_fileref = (PPB_FileRef*)(get_browser(PPB_FILEREF_INTERFACE));
ppb_filesystem = (PPB_FileSystem*)(get_browser(PPB_FILESYSTEM_INTERFACE));
urlloader = (PPB_URLLoader*)(get_browser(PPB_URLLOADER_INTERFACE ));
urlrequestinfo = (PPB_URLRequestInfo*)(get_browser(PPB_URLREQUESTINFO_INTERFACE));
urlresponseinfo = (PPB_URLResponseInfo*)(get_browser(PPB_URLRESPONSEINFO_INTERFACE));
audio_interface = (PPB_Audio*)(get_browser(PPB_AUDIO_INTERFACE));
audioconfig_interface = (PPB_AudioConfig*)(get_browser(PPB_AUDIO_CONFIG_INTERFACE));
ppb_mouselock_interface = (PPB_MouseLock*)(get_browser(PPB_MOUSELOCK_INTERFACE));
ppb_fullscreen_interface = (PPB_Fullscreen*)(get_browser(PPB_FULLSCREEN_INTERFACE));
ppb_websocket_interface = (PPB_WebSocket*)(get_browser(PPB_WEBSOCKET_INTERFACE));
glInitializePPAPI(sys_gbi);
return PP_OK;
}
PP_EXPORT const void* PPP_GetInterface(const char* interface_name)
{
if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0)
{
static PPP_Instance instance_interface =
{
&Instance_DidCreate,
&Instance_DidDestroy,
&Instance_DidChangeView,
&Instance_DidChangeFocus,
&Instance_HandleDocumentLoad,
};
return &instance_interface;
}
if (strcmp(interface_name, PPP_INPUT_EVENT_INTERFACE) == 0)
{
static PPP_InputEvent input_event_interface =
{
&InputEvent_HandleEvent
};
return &input_event_interface;
}
if (strcmp(interface_name, PPP_MOUSELOCK_INTERFACE ) == 0)
{
static PPP_MouseLock mouselock_interface =
{
&ppp_mouseunlocked
};
return &mouselock_interface;
}
return NULL;
}
PP_EXPORT void PPP_ShutdownModule()
{
}

View file

@ -2843,7 +2843,8 @@ PF_ambientsound
*/
void PF_ambientsound_Internal (float *pos, char *samp, float vol, float attenuation)
{
int i, soundnum;
int i, soundnum, j;
sizebuf_t *buf[3] = {&sv.signon, &sv.nqmulticast, &sv.multicast};
// check to see if samp was properly precached
for (soundnum=1 ; *sv.strings.sound_precache[soundnum] ; soundnum++)
@ -2861,17 +2862,17 @@ void PF_ambientsound_Internal (float *pos, char *samp, float vol, float attenuat
if (soundnum > 255)
return;
// add an svc_spawnambient command to the level signon packet
MSG_WriteByte (&sv.signon,svc_spawnstaticsound);
for (i=0 ; i<3 ; i++)
MSG_WriteCoord(&sv.signon, pos[i]);
MSG_WriteByte (&sv.signon, soundnum);
MSG_WriteByte (&sv.signon, vol*255);
MSG_WriteByte (&sv.signon, attenuation*64);
for (j = 0; j < 3; j++)
{
// add an svc_spawnambient command to the level signon packet
MSG_WriteByte (buf[j],svc_spawnstaticsound);
for (i=0 ; i<3 ; i++)
MSG_WriteCoord(buf[j], pos[i]);
MSG_WriteByte (buf[j], soundnum);
MSG_WriteByte (buf[j], vol*255);
MSG_WriteByte (buf[j], attenuation*64);
}
SV_Multicast(pos, MULTICAST_ALL_R);
}
static void QCBUILTIN PF_ambientsound (progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -3329,7 +3330,10 @@ static void QCBUILTIN PF_dropclient (progfuncs_t *prinst, struct globalvars_s *p
// so long and thanks for all the fish
if (cl->netchan.remote_address.type == NA_LOOPBACK)
{
Cbuf_AddText ("disconnect\n", RESTRICT_INSECURE);
return; //don't drop the local client. It looks wrong.
}
cl->drop = true;
return;
}
@ -3511,7 +3515,7 @@ static void QCBUILTIN PF_h2dprintf (progfuncs_t *prinst, struct globalvars_s *pr
sprintf (temp, "%5.1f",v);
Q_strncpyz(printable, PR_GetStringOfs(prinst, OFS_PARM0), sizeof(printable));
while(pct = strstr(printable, "%s"))
while((pct = strstr(printable, "%s")))
{
if ((pct-printable) + strlen(temp) + strlen(pct) > sizeof(printable))
break;
@ -3530,7 +3534,7 @@ static void QCBUILTIN PF_h2dprintv (progfuncs_t *prinst, struct globalvars_s *pr
sprintf (temp, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM1)[0], G_VECTOR(OFS_PARM1)[1], G_VECTOR(OFS_PARM1)[2]);
Q_strncpyz(printable, PR_GetStringOfs(prinst, OFS_PARM0), sizeof(printable));
while(pct = strstr(printable, "%s"))
while((pct = strstr(printable, "%s")))
{
if ((pct-printable) + strlen(temp) + strlen(pct) > sizeof(printable))
break;
@ -8900,15 +8904,15 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"rotatevectorsbytag", PF_Fixme, 0, 0, 0, 244, "vector(entity ent, float tagnum)"}, // #234
#ifdef SQL
{"sqlconnect", PF_sqlconnect, 0, 0, 0, 250, "float([string host], [string user], [string pass], [string defaultdb], [string driver]) sqlconnect (FTE_SQL)
{"sqldisconnect", PF_sqldisconnect, 0, 0, 0, 251, "void(float serveridx) sqldisconnect (FTE_SQL)
{"sqlopenquery", PF_sqlopenquery, 0, 0, 0, 252, "float(float serveridx, void(float serveridx, float queryidx, float rows, float columns, float eof) callback, float querytype, string query) sqlopenquery (FTE_SQL)
{"sqlclosequery", PF_sqlclosequery, 0, 0, 0, 253, "void(float serveridx, float queryidx) sqlclosequery (FTE_SQL)
{"sqlreadfield", PF_sqlreadfield, 0, 0, 0, 254, "string(float serveridx, float queryidx, float row, float column) sqlreadfield (FTE_SQL)
{"sqlerror", PF_sqlerror, 0, 0, 0, 255, "string(float serveridx, [float queryidx]) sqlerror (FTE_SQL)
{"sqlescape", PF_sqlescape, 0, 0, 0, 256, "string(float serveridx, string data) sqlescape (FTE_SQL)
{"sqlversion", PF_sqlversion, 0, 0, 0, 257, "string(float serveridx) sqlversion (FTE_SQL)
{"sqlreadfloat", PF_sqlreadfloat, 0, 0, 0, 258, "float(float serveridx, float queryidx, float row, float column) sqlreadfloat (FTE_SQL)
{"sqlconnect", PF_sqlconnect, 0, 0, 0, 250, "float(optional string host, optional string user, optional string pass, optional string defaultdb, optional string driver)"} // sqlconnect (FTE_SQL)
{"sqldisconnect", PF_sqldisconnect, 0, 0, 0, 251, "void(float serveridx)"} // sqldisconnect (FTE_SQL)
{"sqlopenquery", PF_sqlopenquery, 0, 0, 0, 252, "float(float serveridx, void(float serveridx, float queryidx, float rows, float columns, float eof) callback, float querytype, string query)"} // sqlopenquery (FTE_SQL)
{"sqlclosequery", PF_sqlclosequery, 0, 0, 0, 253, "void(float serveridx, float queryidx)"} // sqlclosequery (FTE_SQL)
{"sqlreadfield", PF_sqlreadfield, 0, 0, 0, 254, "string(float serveridx, float queryidx, float row, float column)"} // sqlreadfield (FTE_SQL)
{"sqlerror", PF_sqlerror, 0, 0, 0, 255, "string(float serveridx, optional float queryidx)"} // sqlerror (FTE_SQL)
{"sqlescape", PF_sqlescape, 0, 0, 0, 256, "string(float serveridx, string data)"} // sqlescape (FTE_SQL)
{"sqlversion", PF_sqlversion, 0, 0, 0, 257, "string(float serveridx)"} // sqlversion (FTE_SQL)
{"sqlreadfloat", PF_sqlreadfloat, 0, 0, 0, 258, "float(float serveridx, float queryidx, float row, float column)"} // sqlreadfloat (FTE_SQL)
#endif
{"stoi", PF_stoi, 0, 0, 0, 259, "int(string)"},
{"itos", PF_itos, 0, 0, 0, 260, "string(int)"},
@ -9227,7 +9231,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
//DP_QC_WHICHPACK
{"whichpack", PF_whichpack, 0, 0, 0, 503, "string(string filename)"},//
//DP_CSQC_QUERYRENDERENTITY
{"getentity", PF_Fixme, 0, 0, 0, 504, "__variant(float entnum, fload fieldnum)"},
{"getentity", PF_Fixme, 0, 0, 0, 504, "__variant(float entnum, float fieldnum)"},
//DP_QC_URI_ESCAPE
{"uri_escape", PF_uri_escape, 0, 0, 0, 510, "string(string in)"},//
@ -9878,6 +9882,7 @@ void PR_DumpPlatform_f(void)
{"FL_ONGROUND", "const float", QW|NQ|CS, FL_ONGROUND},
{"FL_PARTIALGROUND", "const float", QW|NQ|CS, FL_PARTIALGROUND},
{"FL_WATERJUMP", "const float", QW|NQ|CS, FL_WATERJUMP},
{"FL_JUMPRELEASED", "const float", NQ|CS, FL_JUMPRELEASED},
{"FL_FINDABLE_NONSOLID","const float", QW|NQ|CS, FL_FINDABLE_NONSOLID},
// {"FL_MOVECHAIN_ANGLE", "const float", QW|NQ, FL_MOVECHAIN_ANGLE},
{"FL_LAGGEDMOVE", "const float", QW|NQ, FLQW_LAGGEDMOVE},

View file

@ -23,12 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef CLIENTONLY
#define Q2EDICT_NUM(i) (q2edict_t*)((char *)ge->edicts+i*ge->edict_size)
#ifdef _WIN32
#include "winquake.h"
#else
#include <netinet/in.h>
#endif
void SV_Savegame_f (void);
void SV_Loadgame_f (void);
#define INVIS_CHAR1 12
@ -163,7 +157,9 @@ cvar_t sv_port_tcp = CVARC("sv_port_tcp", "", SV_Tcpport_Callback);
cvar_t sv_port_tcp6 = CVARC("sv_port_tcp6", "", SV_Tcpport6_Callback);
#endif
#endif
#ifdef HAVE_IPV4
cvar_t sv_port_ipv4 = CVARC("sv_port", "27500", SV_Port_Callback);
#endif
#ifdef IPPROTO_IPV6
cvar_t sv_port_ipv6 = CVARC("sv_port_ipv6", "", SV_PortIPv6_Callback);
#endif
@ -4117,8 +4113,10 @@ void SV_InitLocal (void)
Cvar_Register (&sv_port_ipx, cvargroup_servercontrol);
sv_port_ipx.restriction = RESTRICT_MAX;
#endif
#ifdef HAVE_IPV4
Cvar_Register (&sv_port_ipv4, cvargroup_servercontrol);
sv_port_ipv4.restriction = RESTRICT_MAX;
#endif
Cvar_Register (&sv_reportheartbeats, cvargroup_servercontrol);
@ -4210,8 +4208,10 @@ void SV_InitLocal (void)
int port = atoi(com_argv[p+1]);
if (!port)
port = PORT_QWSERVER;
#ifdef HAVE_IPV4
if (*sv_port_ipv4.string)
Cvar_SetValue(&sv_port_ipv4, port);
#endif
#ifdef IPPROTO_IPV6
if (*sv_port_ipv6.string)
Cvar_SetValue(&sv_port_ipv6, port);

View file

@ -82,8 +82,10 @@ void DestClose(mvddest_t *d, qboolean destroyfiles)
BZ_Free(d->cache);
if (d->file)
VFS_CLOSE(d->file);
#ifdef HAVE_TCP
if (d->socket)
UDP_CloseSocket(d->socket);
#endif
if (destroyfiles)
{
@ -136,6 +138,9 @@ void DestFlush(qboolean compleate)
break;
case DEST_STREAM:
#ifndef HAVE_TCP
d->error = true;
#else
if (d->cacheused && !d->error)
{
len = send(d->socket, d->cache, d->cacheused, 0);
@ -154,6 +159,7 @@ void DestFlush(qboolean compleate)
d->error = true;
}
}
#endif
break;
case DEST_NONE:
@ -175,6 +181,10 @@ void DestFlush(qboolean compleate)
void SV_MVD_RunPendingConnections(void)
{
#ifndef HAVE_TCP
if (demo.pendingdest)
Sys_Error("demo.pendingdest not null");
#else
unsigned short ushort_result;
char *e;
int len;
@ -547,6 +557,7 @@ void SV_MVD_RunPendingConnections(void)
}
}
}
#endif
}
int DestCloseAllFlush(qboolean destroyfiles, qboolean mvdonly)
@ -2062,6 +2073,9 @@ void SV_MVD_Record_f (void)
void SV_MVD_QTVReverse_f (void)
{
#ifndef HAVE_TCP
Con_Printf ("%s is not supported in this build\n", Cmd_Argv(0));
#else
char *ip;
if (sv.state != ss_active)
{
@ -2142,7 +2156,7 @@ void SV_MVD_QTVReverse_f (void)
}
//SV_MVD_Record (dest);
#endif
}
/*
@ -2355,7 +2369,8 @@ void SV_MVDEasyRecord_f (void)
SV_MVD_Record (SV_InitRecordFile(name2));
}
int MVD_StreamStartListening(int port)
#ifdef HAVE_TCP
static int MVD_StreamStartListening(int port)
{
int sock;
@ -2390,9 +2405,11 @@ int MVD_StreamStartListening(int port)
return sock;
}
#endif
void SV_MVDStream_Poll(void)
{
#ifdef HAVE_TCP
static int listensocket=INVALID_SOCKET;
static int listenport;
int _true = true;
@ -2475,6 +2492,7 @@ void SV_MVDStream_Poll(void)
SV_MVD_InitPendingStream(client, ip);
// SV_MVD_Record (SV_InitStream(client));
#endif
}
void SV_MVDList_f (void)

View file

@ -1168,11 +1168,9 @@ SV_PreSpawn_f
*/
void SVQW_PreSpawn_f (void)
{
unsigned buf, bufs;
unsigned initbuf, buf, start;
unsigned check;
unsigned statics;
if (host_client->state != cs_connected)
{
Con_Printf ("prespawn not valid -- already spawned\n");
@ -1187,22 +1185,7 @@ void SVQW_PreSpawn_f (void)
return;
}
#ifdef SERVER_DEMO_PLAYBACK
if (sv.democausesreconnect)
bufs = sv.num_demosignon_buffers;
else
#endif
bufs = sv.num_signon_buffers;
statics = sv.num_static_entities;
buf = atoi(Cmd_Argv(2));
if (buf >= bufs+statics+sv.world.num_edicts+255)
{
SV_EndRedirect();
Con_Printf ("SV_Modellist_f: %s send an invalid index\n", host_client->name);
SV_DropClient(host_client);
return;
}
buf = initbuf = atoi(Cmd_Argv(2));
if (!buf)
{
@ -1243,186 +1226,210 @@ void SVQW_PreSpawn_f (void)
return;
}
if (buf >= bufs
#ifdef SERVER_DEMO_PLAYBACK
&& !sv.democausesreconnect
if (sv.democausesreconnect)
{
if (host_client->netchan.message.cursize+sv.demosignon_buffer_size[buf]+30 < host_client->netchan.message.maxsize)
{
SZ_Write (&host_client->netchan.message,
sv.demosignon_buffers[buf],
sv.demosignon_buffer_size[buf]);
buf++;
}
start = sv.num_demosignon_buffers;
}
else
#endif
)
{
int i;
entity_state_t from;
entity_state_t *state;
edict_t *ent;
svcustomtents_t *ctent;
start = 0;
memset(&from, 0, sizeof(from));
while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) //static entities
if (buf >= start)
{
if (buf - bufs >= sv.num_static_entities)
break;
state = &sv_staticentities[buf - bufs];
buf++;
if (host_client->fteprotocolextensions & PEXT_SPAWNSTATIC2)
while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) //static entities
{
/*if it uses some new feature, use the updated spawnstatic*/
if (state->hexen2flags || state->trans || state->modelindex >= 256 || state->frame > 255 || state->scale || state->abslight)
i = buf - start;
if (i >= sv.num_signon_buffers)
break;
if (host_client->netchan.message.cursize+sv.signon_buffer_size[i]+30 < host_client->netchan.message.maxsize)
{
MSG_WriteByte(&host_client->netchan.message, svc_spawnstatic2);
SVQW_WriteDelta(&from, state, &host_client->netchan.message, true, host_client->fteprotocolextensions);
SZ_Write (&host_client->netchan.message,
sv.signon_buffers[i],
sv.signon_buffer_size[i]);
buf++;
}
else
break;
}
}
start += sv.num_signon_buffers;
if (buf >= start)
{
memset(&from, 0, sizeof(from));
while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) //static entities
{
if (buf - start >= sv.num_static_entities)
break;
state = &sv_staticentities[buf - start];
buf++;
if (host_client->fteprotocolextensions & PEXT_SPAWNSTATIC2)
{
/*if it uses some new feature, use the updated spawnstatic*/
if (state->hexen2flags || state->trans || state->modelindex >= 256 || state->frame > 255 || state->scale || state->abslight)
{
MSG_WriteByte(&host_client->netchan.message, svc_spawnstatic2);
SVQW_WriteDelta(&from, state, &host_client->netchan.message, true, host_client->fteprotocolextensions);
continue;
}
}
/*couldn't use protocol extensions?
use the fallback, unless the model is invalid as that's silly*/
if (state->modelindex < 256)
{
MSG_WriteByte(&host_client->netchan.message, svc_spawnstatic);
MSG_WriteByte (&host_client->netchan.message, state->modelindex);
MSG_WriteByte (&host_client->netchan.message, state->frame);
MSG_WriteByte (&host_client->netchan.message, (int)state->colormap);
MSG_WriteByte (&host_client->netchan.message, (int)state->skinnum);
for (i=0 ; i<3 ; i++)
{
MSG_WriteCoord(&host_client->netchan.message, state->origin[i]);
MSG_WriteAngle(&host_client->netchan.message, state->angles[i]);
}
continue;
}
}
/*couldn't use protocol extensions?
use the fallback, unless the model is invalid as that's silly*/
if (state->modelindex < 256)
{
MSG_WriteByte(&host_client->netchan.message, svc_spawnstatic);
MSG_WriteByte (&host_client->netchan.message, state->modelindex);
MSG_WriteByte (&host_client->netchan.message, state->frame);
MSG_WriteByte (&host_client->netchan.message, (int)state->colormap);
MSG_WriteByte (&host_client->netchan.message, (int)state->skinnum);
for (i=0 ; i<3 ; i++)
{
MSG_WriteCoord(&host_client->netchan.message, state->origin[i]);
MSG_WriteAngle(&host_client->netchan.message, state->angles[i]);
}
continue;
}
}
while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) //baselines
start += sv.num_static_entities;
if (buf >= start)
{
if (buf - bufs - sv.num_static_entities >= sv.world.num_edicts)
break;
while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2))
{
i = buf - start;
if (i >= 255)
break;
ent = EDICT_NUM(svprogfuncs, buf - bufs - sv.num_static_entities);
ctent = &sv.customtents[i];
state = &ent->baseline;
if (!state->number || !state->modelindex)
{ //ent doesn't have a baseline
buf++;
continue;
}
if (!ent)
{
MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline);
MSG_WriteShort (&host_client->netchan.message, buf - bufs - sv.num_static_entities);
MSG_WriteByte (&host_client->netchan.message, 0);
MSG_WriteByte (&host_client->netchan.message, 0);
MSG_WriteByte (&host_client->netchan.message, 0);
MSG_WriteByte (&host_client->netchan.message, 0);
for (i=0 ; i<3 ; i++)
{
MSG_WriteCoord(&host_client->netchan.message, 0);
MSG_WriteAngle(&host_client->netchan.message, 0);
if (!*ctent->particleeffecttype)
{ //effect isn't registered.
continue;
}
}
else if (state->number >= host_client->max_net_ents || state->modelindex >= host_client->maxmodels)
{
/*can't send this ent*/
}
else if (host_client->fteprotocolextensions & PEXT_SPAWNSTATIC2)
{
MSG_WriteByte(&host_client->netchan.message, svcfte_spawnbaseline2);
SVQW_WriteDelta(&from, state, &host_client->netchan.message, true, host_client->fteprotocolextensions);
}
else if (state->modelindex < 256)
{
MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline);
MSG_WriteShort (&host_client->netchan.message, buf - bufs - sv.num_static_entities);
MSG_WriteByte (&host_client->netchan.message, state->modelindex);
MSG_WriteByte (&host_client->netchan.message, state->frame);
MSG_WriteByte (&host_client->netchan.message, (int)state->colormap);
MSG_WriteByte (&host_client->netchan.message, (int)state->skinnum);
for (i=0 ; i<3 ; i++)
if (host_client->fteprotocolextensions & PEXT_CUSTOMTEMPEFFECTS)
{
MSG_WriteCoord(&host_client->netchan.message, state->origin[i]);
MSG_WriteAngle(&host_client->netchan.message, state->angles[i]);
}
}
buf++;
}
while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2))
{
i = buf - bufs - sv.num_static_entities - sv.world.num_edicts;
if (i >= 255)
break;
ctent = &sv.customtents[i];
buf++;
if (!*ctent->particleeffecttype)
{ //effect isn't registered.
continue;
}
if (host_client->fteprotocolextensions & PEXT_CUSTOMTEMPEFFECTS)
{
MSG_WriteByte(&host_client->netchan.message, svcfte_customtempent);
MSG_WriteByte(&host_client->netchan.message, 255);
MSG_WriteByte(&host_client->netchan.message, i);
MSG_WriteByte(&host_client->netchan.message, ctent->netstyle);
MSG_WriteString(&host_client->netchan.message, ctent->particleeffecttype);
if (ctent->netstyle & CTE_STAINS)
{
MSG_WriteChar(&host_client->netchan.message, ctent->stain[0]);
MSG_WriteChar(&host_client->netchan.message, ctent->stain[0]);
MSG_WriteChar(&host_client->netchan.message, ctent->stain[0]);
MSG_WriteByte(&host_client->netchan.message, ctent->radius);
}
if (ctent->netstyle & CTE_GLOWS)
{
MSG_WriteByte(&host_client->netchan.message, ctent->dlightrgb[0]);
MSG_WriteByte(&host_client->netchan.message, ctent->dlightrgb[1]);
MSG_WriteByte(&host_client->netchan.message, ctent->dlightrgb[2]);
MSG_WriteByte(&host_client->netchan.message, ctent->dlightradius);
MSG_WriteByte(&host_client->netchan.message, ctent->dlighttime);
MSG_WriteByte(&host_client->netchan.message, svcfte_customtempent);
MSG_WriteByte(&host_client->netchan.message, 255);
MSG_WriteByte(&host_client->netchan.message, i);
MSG_WriteByte(&host_client->netchan.message, ctent->netstyle);
MSG_WriteString(&host_client->netchan.message, ctent->particleeffecttype);
if (ctent->netstyle & CTE_STAINS)
{
MSG_WriteChar(&host_client->netchan.message, ctent->stain[0]);
MSG_WriteChar(&host_client->netchan.message, ctent->stain[0]);
MSG_WriteChar(&host_client->netchan.message, ctent->stain[0]);
MSG_WriteByte(&host_client->netchan.message, ctent->radius);
}
if (ctent->netstyle & CTE_GLOWS)
{
MSG_WriteByte(&host_client->netchan.message, ctent->dlightrgb[0]);
MSG_WriteByte(&host_client->netchan.message, ctent->dlightrgb[1]);
MSG_WriteByte(&host_client->netchan.message, ctent->dlightrgb[2]);
MSG_WriteByte(&host_client->netchan.message, ctent->dlightradius);
MSG_WriteByte(&host_client->netchan.message, ctent->dlighttime);
}
}
}
}
}
else if (buf >= bufs)
{
buf = bufs+sv.num_static_entities+sv.world.num_edicts+255;
}
else
{
#ifdef SERVER_DEMO_PLAYBACK
if (sv.democausesreconnect)
start += 255;
if (buf >= start)
{
if (host_client->netchan.message.cursize+sv.signon_buffer_size[buf]+30 < host_client->netchan.message.maxsize)
while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) //baselines
{
SZ_Write (&host_client->netchan.message,
sv.demosignon_buffers[buf],
sv.demosignon_buffer_size[buf]);
buf++;
}
}
else
#endif
{
if (host_client->netchan.message.cursize+sv.signon_buffer_size[buf]+30 < host_client->netchan.message.maxsize)
{
SZ_Write (&host_client->netchan.message,
sv.signon_buffers[buf],
sv.signon_buffer_size[buf]);
if (buf - start >= sv.world.num_edicts)
break;
ent = EDICT_NUM(svprogfuncs, buf - start);
state = &ent->baseline;
if (!state->number || !state->modelindex)
{ //ent doesn't have a baseline
buf++;
continue;
}
if (!ent)
{
MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline);
MSG_WriteShort (&host_client->netchan.message, buf - start);
MSG_WriteByte (&host_client->netchan.message, 0);
MSG_WriteByte (&host_client->netchan.message, 0);
MSG_WriteByte (&host_client->netchan.message, 0);
MSG_WriteByte (&host_client->netchan.message, 0);
for (i=0 ; i<3 ; i++)
{
MSG_WriteCoord(&host_client->netchan.message, 0);
MSG_WriteAngle(&host_client->netchan.message, 0);
}
}
else if (state->number >= host_client->max_net_ents || state->modelindex >= host_client->maxmodels)
{
/*can't send this ent*/
}
else if (host_client->fteprotocolextensions & PEXT_SPAWNSTATIC2)
{
MSG_WriteByte(&host_client->netchan.message, svcfte_spawnbaseline2);
SVQW_WriteDelta(&from, state, &host_client->netchan.message, true, host_client->fteprotocolextensions);
}
else if (state->modelindex < 256)
{
MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline);
MSG_WriteShort (&host_client->netchan.message, buf - start);
MSG_WriteByte (&host_client->netchan.message, state->modelindex);
MSG_WriteByte (&host_client->netchan.message, state->frame);
MSG_WriteByte (&host_client->netchan.message, (int)state->colormap);
MSG_WriteByte (&host_client->netchan.message, (int)state->skinnum);
for (i=0 ; i<3 ; i++)
{
MSG_WriteCoord(&host_client->netchan.message, state->origin[i]);
MSG_WriteAngle(&host_client->netchan.message, state->angles[i]);
}
}
buf++;
}
}
start += sv.world.num_edicts;
}
if (buf == bufs+sv.num_static_entities+sv.world.num_edicts+255)
if (initbuf >= start)
{
SV_EndRedirect();
Con_Printf ("SV_Modellist_f: %s send an invalid index\n", host_client->name);
SV_DropClient(host_client);
return;
}
if (buf == start)
{ // all done prespawning
MSG_WriteByte (&host_client->netchan.message, svc_stufftext);
MSG_WriteString (&host_client->netchan.message, va("cmd spawn %i\n",svs.spawncount) );
@ -4584,6 +4591,20 @@ void SVNQ_PreSpawn_f (void)
}
st = 0;
if (buf >= st)
{
while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2))
{
i = buf-st;
if (i >= sv.num_signon_buffers)
break;
buf++;
SZ_Write (&host_client->netchan.message, sv.signon_buffers[i], sv.signon_buffer_size[i]);
}
}
st += sv.num_signon_buffers;
if (buf >= st)
{
while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) //baselines
@ -4655,19 +4676,6 @@ void SVNQ_PreSpawn_f (void)
}
st += sv.world.max_edicts;
if (buf >= st)
{
while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2))
{
i = buf-st;
if (i >= sv.num_signon_buffers)
break;
buf++;
SZ_Write (&host_client->netchan.message, sv.signon_buffers[i], sv.signon_buffer_size[i]);
}
}
st += sv.num_signon_buffers;
if (st == buf)
{
MSG_WriteByte (&host_client->netchan.message, svc_signonnum);

View file

@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
model_t *loadmodel;
char loadname[32]; // for hunk tags
qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer);
qboolean Mod_LoadBrushModel (model_t *mod, void *buffer);
qboolean Mod_LoadQ2BrushModel (model_t *mod, void *buffer);
qboolean D3_LoadMap_CollisionMap(model_t *mod, char *buf);
@ -479,6 +480,14 @@ model_t *Mod_LoadModel (model_t *mod, qboolean crash)
break;
}
#endif
#ifdef TERRAIN
if (!strcmp(com_token, "terrain")) //custom format, text based.
{
if (!GL_LoadHeightmapModel(mod, buf))
goto couldntload;
break;
}
#endif
Con_Printf (CON_ERROR "Mod_NumForName: %s: format not recognised\n", mod->name);
couldntload: