Fix some issues with emscripten.

fix some obscure issues with fteqcc.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4954 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2015-08-02 11:36:46 +00:00
parent 9cb8a2d025
commit efc1082d7c
23 changed files with 257 additions and 164 deletions

View file

@ -2285,8 +2285,8 @@ static void Image_LoadTextureMips(void *ctx, void *data, size_t a, size_t b)
texid_t tex = ctx;
struct pendingtextureinfo *mips = data;
tex->width = mips->mip[0].width;
tex->height = mips->mip[0].height;
// tex->width = mips->mip[0].width;
// tex->height = mips->mip[0].height;
if (rf->IMG_LoadTextureMips(tex, mips))
tex->status = TEX_LOADED;
else
@ -2299,6 +2299,7 @@ static void Image_LoadTextureMips(void *ctx, void *data, size_t a, size_t b)
BZ_Free(mips->extrafree);
BZ_Free(mips);
/*
if (!strncmp(tex->ident, "gfx/", 4))
{
qpic_t *pic = W_SafeGetLumpName(tex->ident+4);
@ -2308,6 +2309,7 @@ static void Image_LoadTextureMips(void *ctx, void *data, size_t a, size_t b)
tex->height = pic->height;
}
}
*/
}
#ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT

View file

@ -2758,7 +2758,7 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
{
case MV_NONE:
R_DrawTextField(r_refdef.grect.x, r_refdef.grect.y+y, r_refdef.grect.width, r_refdef.grect.height-y,
"arrows: pitch/rotate\n"
va("arrows: pitch/rotate\n"
"w: zoom in\n"
"s: zoom out\n"
"m: mode\n"
@ -2767,6 +2767,7 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
"end: skin+=1\n"
"pgup: frame+=1\n"
"pgdn: frame-=1\n"
"mins: %g %g %g, maxs: %g %g %g\n", ent.model->mins[0], ent.model->mins[1], ent.model->mins[2], ent.model->maxs[0], ent.model->maxs[1], ent.model->maxs[2])
, CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN, font_default, fs);
break;
case MV_BONES:

View file

@ -70,7 +70,7 @@ void M_ScanSaves (void)
memcpy(m_saves[i].map, line, 22);
m_saves[i].map[22] = 0;
memcpy(m_saves[i].kills, line+22, 39-22);
m_saves[i].kills[22] = 0;
m_saves[i].kills[39-22] = 0;
Q_strncpyz(m_saves[i].time, line+39, sizeof(m_saves[i].time));

View file

@ -164,7 +164,7 @@ char *Mod_GetBoneName(struct model_s *model, int bonenum);
void Draw_FunString(float x, float y, const void *str);
void Draw_AltFunString(float x, float y, const void *str);
void Draw_FunStringWidth(float x, float y, const void *str, int width, qboolean rightalign, qboolean highlight);
void Draw_FunStringWidth(float x, float y, const void *str, int width, int rightalign, qboolean highlight);
extern int r_regsequence;

View file

@ -204,7 +204,7 @@ void Draw_AltFunString(float x, float y, const void *str)
}
//Draws a marked up string no wider than $width virtual pixels.
void Draw_FunStringWidth(float x, float y, const void *str, int width, qboolean rightalign, qboolean highlight)
void Draw_FunStringWidth(float x, float y, const void *str, int width, int rightalign, qboolean highlight)
{
conchar_t buffer[2048];
conchar_t *w;

View file

@ -678,11 +678,16 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, unsigned
}
palSourcef(src, AL_GAIN, min(cvolume, 1)); //openal only supports a max volume of 1. anything above is an error and will be clamped.
if (chan->entnum == -1 || chan->entnum == cl.playerview[0].viewentity)
if ((chan->flags & CF_NOSPACIALISE) || chan->entnum == cl.playerview[0].viewentity || !chan->dist_mult)
{
palSourcefv(src, AL_POSITION, vec3_origin);
else
palSourcefv(src, AL_POSITION, chan->origin);
palSourcefv(src, AL_VELOCITY, vec3_origin);
}
else
{
palSourcefv(src, AL_POSITION, chan->origin);
palSourcefv(src, AL_VELOCITY, vec3_origin); //FIXME
}
if (schanged)
{
@ -697,7 +702,7 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, unsigned
#endif
palSourcei(src, AL_LOOPING, (chan->flags & CF_FORCELOOP)?AL_TRUE:AL_FALSE);
if (chan->entnum == -1 || chan->entnum == cl.playerview[0].viewentity)
if ((chan->flags & CF_NOSPACIALISE) || chan->entnum == cl.playerview[0].viewentity || !chan->dist_mult)
{
palSourcei(src, AL_SOURCE_RELATIVE, AL_TRUE);
// palSourcef(src, AL_ROLLOFF_FACTOR, 0.0f);

View file

@ -2814,6 +2814,11 @@ void S_UpdateAmbientSounds (soundcardinfo_t *sc)
chan->rate = 1<<PITCHSHIFT;
chan->pos = (int)(time * sc->sn.speed) * chan->rate;
changed = true;
chan->master_vol = bound(0, 1, 255);
chan->vol[0] = chan->vol[1] = chan->vol[2] = chan->vol[3] = chan->vol[4] = chan->vol[5] = chan->master_vol;
if (sc->ChannelUpdate)
sc->ChannelUpdate(sc, chan, changed);
}
}
}
@ -2997,7 +3002,8 @@ static void S_UpdateCard(soundcardinfo_t *sc)
for (i=0 ; i<sc->total_chans; i++, ch++)
if (ch->sfx && (ch->vol[0] || ch->vol[1]) )
{
// Con_Printf ("%i, %i %i %i %i %i %i %s\n", i, ch->vol[0], ch->vol[1], ch->vol[2], ch->vol[3], ch->vol[4], ch->vol[5], ch->sfx->name);
if (snd_show.ival > 1)
Con_Printf ("%i, %i %i %i %i %i %i %s\n", i, ch->vol[0], ch->vol[1], ch->vol[2], ch->vol[3], ch->vol[4], ch->vol[5], ch->sfx->name);
total++;
}

View file

@ -67,7 +67,7 @@ typedef struct sfx_s
typedef struct sfxcache_s
{
usamplepos_t length; //sample count
unsigned int loopstart; //-1 or sample index to begin looping at once the sample ends
int loopstart; //-1 or sample index to begin looping at once the sample ends
unsigned int speed;
unsigned int width;
unsigned int numchannels;

View file

@ -32,6 +32,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "pr_common.h"
#include "fs.h"
//#define _MSC_SEH
//#define RESTARTTEST
#ifdef MULTITHREAD
@ -3491,7 +3493,9 @@ qboolean Sys_DoInstall(void)
GetClientRect(wnd, &ca);
sh = GetSystemMetrics(SM_CYVSCROLL);
InitCommonControls();
Sys_LoadLibrary("comctl32.dll", NULL);
// InitCommonControls();
label = CreateWindow("STATIC","", WS_CHILD | WS_VISIBLE | SS_PATHELLIPSIS, sh, ((ca.bottom-ca.top-sh)/3), ca.right-ca.left-2*sh, sh, wnd, NULL, hInstance, NULL);
progress = CreateWindowEx(0, PROGRESS_CLASS, NULL, WS_CHILD | WS_VISIBLE | PBS_SMOOTH, sh, ((ca.bottom-ca.top-sh)/3)*2, ca.right-ca.left-2*sh, sh, wnd, NULL, hInstance, NULL);
@ -3816,6 +3820,9 @@ static void Sys_MakeInstaller(const char *name)
}
#endif
#if defined(_MSC_VER) && defined(_AMD64_)
#pragma optimize( "", off) //64bit msvc sucks and falls over when trying to inline Host_Frame
#endif
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// MSG msg;
@ -3886,7 +3893,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
#ifdef CATCHCRASH
LoadLibraryU ("DBGHELP"); //heap corruption can prevent loadlibrary from working properly, so do this in advance.
#ifdef _MSC_VER
#ifdef _MSC_SEH
__try
#else
{
@ -4199,7 +4206,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
}
}
#ifdef CATCHCRASH
#ifdef _MSC_VER
#ifdef _MSC_SEH
__except (CrashExceptionHandler(false, GetExceptionCode(), GetExceptionInformation()))
{
return 1;
@ -4210,6 +4217,9 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
/* return success of application */
return TRUE;
}
#ifdef _MSC_VER
#pragma optimize( "", on) //revert back to default optimisations again.
#endif
int __cdecl main(void)
{

View file

@ -1882,7 +1882,7 @@ void R_DrawNameTags(void)
isteam = !strcmp(cl.players[i].team, ourteam);
if (!isteam)
if (!cl.spectator && !cls.demoplayback || !scr_autoid.ival)
if ((!cl.spectator && !cls.demoplayback) || !scr_autoid.ival)
continue; //only show our team when playing, too cheaty otherwise.
SCR_DrawAutoID(nametagorg[i], &cl.players[i], isteam);

View file

@ -6801,9 +6801,6 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer, size_t fsize)
maxs[2] = LittleFloat(inbounds[i].bbmax[2]);
AddPointToBounds(maxs, mod->mins, mod->maxs);
}
//fixme: shouldn't really be needed for an animated model
for (i = 0; i < h->num_vertexes; i++)
AddPointToBounds(opos[i], mod->mins, mod->maxs);
for (i = 0; i < h->num_meshes; i++)
{
@ -6882,6 +6879,10 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer, size_t fsize)
IQM_ImportArrayF(buffer, &vnorm, (float*)onorm1, 3, h->num_vertexes, defaultcolour);
IQM_ImportArrayF(buffer, &vpos, (float*)opos, sizeof(opos[0])/sizeof(float), h->num_vertexes, defaultvert);
//fixme: shouldn't really be needed for an animated model
for (i = 0; i < h->num_vertexes; i++)
AddPointToBounds(opos[i], mod->mins, mod->maxs);
if (vnorm.offset && vtang)
{
for (i = 0; i < h->num_vertexes; i++)

View file

@ -74,6 +74,12 @@ typedef struct threadwrap_s
char name[1];
} threadwrap_t;
typedef struct
{
HANDLE handle;
DWORD threadid;
} threadctx_t;
// the thread call is wrapped so we don't need WINAPI everywhere
unsigned int WINAPI threadwrapper(void *args)
{
@ -104,42 +110,48 @@ unsigned int WINAPI threadwrapper(void *args)
void *Sys_CreateThread(char *name, int (*func)(void *), void *args, int priority, int stacksize)
{
threadctx_t *ctx = (threadctx_t *)malloc(sizeof(*ctx));
threadwrap_t *tw = (threadwrap_t *)malloc(sizeof(threadwrap_t)+strlen(name));
HANDLE handle;
unsigned int tid;
if (!tw)
if (!tw || !ctx)
{
free(tw);
free(ctx);
return NULL;
}
stacksize += 128; // wrapper overhead, also prevent default stack size
tw->func = func;
tw->args = args;
strcpy(tw->name, name);
#ifdef WIN32CRTDLL
handle = (HANDLE)CreateThread(NULL, stacksize, &threadwrapper, (void *)tw, 0, &tid);
ctx->handle = (HANDLE)CreateThread(NULL, stacksize, &threadwrapper, (void *)tw, 0, &ctx->threadid);
#else
handle = (HANDLE)_beginthreadex(NULL, stacksize, &threadwrapper, (void *)tw, 0, &tid);
ctx->handle = (HANDLE)_beginthreadex(NULL, stacksize, &threadwrapper, (void *)tw, 0, &ctx->threadid);
#endif
if (!handle)
if (!ctx->handle)
{
free(tw);
free(ctx);
return NULL;
}
return (void *)handle;
return (void *)ctx;
}
void Sys_DetachThread(void *thread)
{
CloseHandle((HANDLE)thread);
threadctx_t *ctx = thread;
CloseHandle(ctx->handle);
free(ctx);
}
void Sys_WaitOnThread(void *thread)
{
WaitForSingleObject((HANDLE)thread, INFINITE);
CloseHandle((HANDLE)thread);
threadctx_t *ctx = thread;
WaitForSingleObject(ctx->handle, INFINITE);
CloseHandle(ctx->handle);
free(ctx);
}
//used on fatal errors.
@ -160,7 +172,8 @@ qboolean Sys_IsMainThread(void)
qboolean Sys_IsThread(void *thread)
{
return GetThreadId(thread) == GetCurrentThreadId();
threadctx_t *ctx = thread;
return ctx->threadid == GetCurrentThreadId();
}

View file

@ -342,8 +342,8 @@ qboolean GL_LoadTextureMips(texid_t tex, struct pendingtextureinfo *mips)
}
}
tex->width = mips->mip[0].width;
tex->height = mips->mip[0].height;
// tex->width = mips->mip[0].width;
// tex->height = mips->mip[0].height;
GL_Texturemode_Apply(targ, tex->flags);
if (targ == GL_TEXTURE_3D)
{

View file

@ -608,22 +608,34 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
Con_DPrintf("Anisotropic filter extension found (%dx max).\n",gl_config.ext_texture_filter_anisotropic);
}
//FIXME: GL_ARB_texture_non_power_of_two is supposed to be mandatory in gl2+ and thus checking for it is redundant and not forwards-compatible
//geforcefx apparently software emulates it, so gl<3 is bad.
if (GL_CheckExtension("GL_ARB_texture_non_power_of_two"))
{
if (!gl_config.gles && gl_config.glversion >= 3)
{ //GL_ARB_texture_non_power_of_two is supposed to be mandatory in gl2+ and thus checking for it is redundant and not forwards-compatible
//geforcefx apparently software emulates it, so only activate it unconditionally on gl3+ hardware.
sh_config.texture_non_power_of_two = true;
//gles2 has limited npot as standard, which is sufficient to make the hud not look like poo. lets use it.
if ((gl_config.gles && gl_config.glversion >= 2) || sh_config.texture_non_power_of_two)
sh_config.texture_non_power_of_two_pic = true;
}
else if (GL_CheckExtension("GL_OES_texture_npot"))
{
else if (GL_CheckExtension("GL_ARB_texture_non_power_of_two"))
{ //gl1 devices might still support npot
sh_config.texture_non_power_of_two = true;
sh_config.texture_non_power_of_two_pic = true;
}
else if (gl_config.gles && GL_CheckExtension("GL_OES_texture_npot"))
{ //gles devices might have full npot too, but with a different extension name. because consistancy is good...
sh_config.texture_non_power_of_two = true;
sh_config.texture_non_power_of_two_pic = true;
}
else if (gl_config.gles && gl_config.glversion >= 2)
{ //gles2 has npot (clamp + no mips) support as base.
sh_config.texture_non_power_of_two = false;
sh_config.texture_non_power_of_two_pic = true;
}
else if (gl_config.gles && GL_CheckExtension("GL_APPLE_texture_2D_limited_npot"))
{ //gles1 MIGHT have SOME npot support.
sh_config.texture_non_power_of_two = false;
sh_config.texture_non_power_of_two_pic = true;
}
else
{
{ //really old hardware/drivers with no npot support at all.
sh_config.texture_non_power_of_two = false;
sh_config.texture_non_power_of_two_pic = false;
}

View file

@ -173,7 +173,7 @@ typedef struct
int targetflags; //weather we need to mark the progs as a newer version
char *name;
char *opname;
int priority; //FIXME: priority should be done differently...
int priority_; //FIXME: priority should be done differently...
enum {ASSOC_LEFT, ASSOC_RIGHT, ASSOC_RIGHT_RESULT} associative;
struct QCC_type_s **type_a, **type_b, **type_c;
@ -556,4 +556,5 @@ void PR_CloseJit(struct jitstate *jit);
char *QCC_COM_Parse (const char *data);
extern char qcc_token[1024];
extern char *basictypenames[];
#endif

View file

@ -454,6 +454,7 @@ const extern unsigned int type_size[];
//extern QCC_def_t *def_for_type[9];
extern QCC_type_t *type_void, *type_string, *type_float, *type_vector, *type_entity, *type_field, *type_function, *type_floatfunction, *type_pointer, *type_floatpointer, *type_intpointer, *type_integer, *type_variant, *type_floatfield;
extern char *basictypenames[];
struct QCC_function_s
{
@ -574,7 +575,7 @@ extern pbool keywords_coexist;
extern pbool output_parms;
extern pbool autoprototype, autoprototyped, parseonly;
extern pbool pr_subscopedlocals;
extern pbool flag_nullemptystr, flag_ifstring, flag_iffloat, flag_ifvector, flag_vectorlogic;
extern pbool flag_nullemptystr, flag_ifstring, flag_brokenifstring, flag_iffloat, flag_ifvector, flag_vectorlogic;
extern pbool flag_acc;
extern pbool flag_caseinsensitive;
extern pbool flag_laxcasts;

View file

@ -33,6 +33,23 @@ const unsigned int type_size[12] = {1, //void
0 //ev_union. variable sized.
};
char *basictypenames[] = {
"void",
"string",
"float",
"vector",
"entity",
"field",
"function",
"pointer",
"integer",
"variant",
"struct",
"union",
"accessor"
};
/*
============================================================================

View file

@ -87,6 +87,7 @@ pbool autoprototyped; //previously autoprototyped. no longer allowed to enable
pbool parseonly; //parse defs and stuff, but don't bother compiling any actual code.
pbool pr_subscopedlocals; //causes locals to be valid ONLY within their statement block. (they simply can't be referenced by name outside of it)
pbool flag_nullemptystr; //null immediates are 0, not 1.
pbool flag_brokenifstring; //break strings even more
pbool flag_ifstring; //makes if (blah) equivelent to if (blah != "") which resolves some issues in multiprogs situations.
pbool flag_iffloat; //use an op_if_f instruction instead of op_if so if(-0) evaluates to false.
pbool flag_ifvector; //use an op_not_v instruction instead of testing only _x.
@ -456,7 +457,7 @@ QCC_opcode_t pr_opcodes[] =
{7, "!", "NOT_I", -1, ASSOC_LEFT, &type_integer, &type_void, &type_integer},
{7, "/", "DIV_VF", 3, ASSOC_LEFT, &type_vector, &type_float, &type_float},
{7, "/", "DIV_VF", 3, ASSOC_LEFT, &type_vector, &type_float, &type_vector},
{7, "^", "BITXOR_I", 3, ASSOC_LEFT, &type_integer, &type_integer, &type_integer},
{7, ">>", "RSHIFT_I", 3, ASSOC_LEFT, &type_integer, &type_integer, &type_integer},
@ -707,12 +708,22 @@ pbool OpAssignsToB(unsigned int op)
*/
#undef ASSOC_RIGHT_RESULT
#define TOP_PRIORITY 7
#define FUNC_PRIORITY 1
#define UNARY_PRIORITY 1
#define NOT_PRIORITY 5
//conditional and/or
#define CONDITION_PRIORITY 7
#define UNARY_PRIORITY 1 //~ !
#define NOT_PRIORITY 5 //UNARY_PRIORITY
#define MULDIV_PRIORITY 3 //* / %
#define ADDSUB_PRIORITY 4 //+ -
#define BITSHIFT_PRIORITY 3 //<< >>
#define COMPARISON_PRIORITY 5 //< <= > >=
#define EQUALITY_PRIORITY 5 //== !=
#define BITAND_PRIORITY 3 //&
#define BITXOR_PRIORITY 3 //^
#define BITOR_PRIORITY 3 //|
#define LOGICAND_PRIORITY 7 //&&
#define LOGICOR_PRIORITY 7 //||
#define TERNARY_PRIORITY 6 //?:
#define ASSIGN_PRIORITY 6 //WRONG compared to C
#define TOP_PRIORITY 7
QCC_opcode_t *opcodes_store[] =
{
@ -2037,7 +2048,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
QCC_UnFreeTemp(var_b);
}
if (op->priority != -1 && op->priority != CONDITION_PRIORITY)
/* if (op->priority != -1 && op->priority != CONDITION_PRIORITY)
{
if (op->associative!=ASSOC_LEFT)
{
@ -2052,7 +2063,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
var_b = QCC_SupplyConversion(var_b, (*op->type_b)->type, false);
}
}
*/
//maths operators
if (opt_constantarithmatic || !pr_scope)
{
@ -3007,6 +3018,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
//v/f === v*(1/f)
op = &pr_opcodes[OP_MUL_VF];
var_b = QCC_PR_Statement(&pr_opcodes[OP_DIV_F], QCC_MakeFloatConst(1), var_b, NULL);
var_b.sym->referenced = true;
break;
case OP_CONV_ITOF:
@ -3614,9 +3626,9 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
case OP_AND_IF:
case OP_AND_ANY:
if (var_a.cast->type == ev_vector && flag_vectorlogic) //we can do a dot-product to test if a vector has a value, instead of a double-not
var_a = QCC_PR_StatementFlags(&pr_opcodes[OP_MUL_V], var_a, var_a, NULL, flags&STFL_PRESERVEA);
var_a = QCC_PR_StatementFlags(&pr_opcodes[OP_MUL_V], var_a, var_a, NULL, STFL_PRESERVEA | (flags&STFL_PRESERVEA?STFL_PRESERVEB:0));
if (var_b.cast->type == ev_vector && flag_vectorlogic)
var_b = QCC_PR_StatementFlags(&pr_opcodes[OP_MUL_V], var_b, var_b, NULL, flags&STFL_PRESERVEB);
var_b = QCC_PR_StatementFlags(&pr_opcodes[OP_MUL_V], var_b, var_b, NULL, STFL_PRESERVEA | (flags&STFL_PRESERVEB?STFL_PRESERVEB:0));
if (((var_a.cast->size != 1 && flag_vectorlogic) || (var_a.cast->type == ev_string && flag_ifstring)) && ((var_b.cast->size != 1 && flag_vectorlogic) || (var_b.cast->type == ev_string && flag_ifstring)))
{ //just 3 extra instructions instead of 4.
@ -3643,9 +3655,9 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
case OP_OR_IF:
case OP_OR_ANY:
if (var_a.cast->type == ev_vector && flag_vectorlogic) //we can do a dot-product to test if a vector has a value, instead of a double-not
var_a = QCC_PR_StatementFlags(&pr_opcodes[OP_MUL_V], var_a, var_a, NULL, flags&STFL_PRESERVEA);
var_a = QCC_PR_StatementFlags(&pr_opcodes[OP_MUL_V], var_a, var_a, NULL, STFL_PRESERVEA | (flags&STFL_PRESERVEA?STFL_PRESERVEB:0));
if (var_b.cast->type == ev_vector && flag_vectorlogic)
var_b = QCC_PR_StatementFlags(&pr_opcodes[OP_MUL_V], var_b, var_b, NULL, flags&STFL_PRESERVEB);
var_b = QCC_PR_StatementFlags(&pr_opcodes[OP_MUL_V], var_b, var_b, NULL, STFL_PRESERVEA | (flags&STFL_PRESERVEB?STFL_PRESERVEB:0));
if (((var_a.cast->size != 1 && flag_vectorlogic) || (var_a.cast->type == ev_string && flag_ifstring)) && ((var_b.cast->size != 1 && flag_vectorlogic) || (var_b.cast->type == ev_string && flag_ifstring)))
{ //just 3 extra instructions instead of 4.
@ -5664,22 +5676,6 @@ QCC_type_t *QCC_PointerTypeTo(QCC_type_t *type)
return newtype;
}
char *basictypenames[] = {
"void",
"string",
"float",
"vector",
"entity",
"field",
"function",
"pointer",
"integer",
"variant",
"struct",
"union",
"accessor"
};
QCC_type_t **basictypes[] =
{
&type_void,
@ -6695,7 +6691,7 @@ QCC_sref_t QCC_PR_GenerateLogicalNot(QCC_sref_t e, const char *errormessage)
if (t == ev_float)
return QCC_PR_Statement (&pr_opcodes[OP_NOT_F], e, nullsref, NULL);
else if (t == ev_string)
return QCC_PR_Statement (&pr_opcodes[OP_NOT_S], e, nullsref, NULL);
return QCC_PR_Statement (&pr_opcodes[flag_brokenifstring?OP_NOT_ENT:OP_NOT_S], e, nullsref, NULL);
else if (t == ev_entity)
return QCC_PR_Statement (&pr_opcodes[OP_NOT_ENT], e, nullsref, NULL);
else if (t == ev_vector)
@ -8042,9 +8038,9 @@ QCC_opcode_t *QCC_PR_ChooseOpcode(QCC_sref_t lhs, QCC_sref_t rhs, QCC_opcode_t *
}
if (bestop == NULL)
{
if (oldop->priority == CONDITION_PRIORITY)
op = oldop;
else
// if (oldop->priority == CONDITION_PRIORITY)
// op = oldop;
// else
{
op = oldop;
QCC_PR_ParseWarning(flag_laxcasts?WARN_LAXCAST:ERR_TYPEMISMATCH, "type mismatch for %s (%s and %s)", oldop->name, lhs.cast->name, rhs.cast->name);
@ -8110,7 +8106,7 @@ QCC_ref_t *QCC_PR_RefExpression (QCC_ref_t *retbuf, int priority, int exprflags)
lhsd = QCC_PR_ParseArrayPointer(lhsd, true, true);
lhsr = QCC_DefToRef(retbuf, lhsd);
}
if (priority == FUNC_PRIORITY && QCC_PR_CheckToken ("?"))
if (priority == TERNARY_PRIORITY && QCC_PR_CheckToken ("?"))
{
//if we have no int types, force all ints to floats here, just to ensure that we don't end up with non-constant ints that we then can't cope with.
@ -8128,7 +8124,7 @@ QCC_ref_t *QCC_PR_RefExpression (QCC_ref_t *retbuf, int priority, int exprflags)
{
fromj = QCC_Generate_OP_IFNOT(QCC_RefToDef(lhsr, true), false);
val = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
val = QCC_PR_Expression(TOP_PRIORITY, 0);
if (val.cast->type == ev_integer && !QCC_OPCodeValid(&pr_opcodes[OP_STORE_I]))
val = QCC_SupplyConversion(val, ev_float, true);
r = QCC_GetTemp(val.cast);
@ -9748,7 +9744,7 @@ void QCC_PR_ParseAsm(void)
if (!STRCMP(pr_token, pr_opcodes[op].opname))
{
QCC_PR_Lex();
if (pr_opcodes[op].priority==-1 && pr_opcodes[op].associative!=ASSOC_LEFT)
if (/*pr_opcodes[op].priority==-1 &&*/ pr_opcodes[op].associative!=ASSOC_LEFT)
{
if (pr_opcodes[op].type_a==NULL)
{

View file

@ -454,6 +454,83 @@ static void QCC_PR_SkipToEndOfLine(pbool errorifnonwhite)
}
}
}
//if hadtrue, then we allow elses, otherwise we skip them.
pbool QCC_PR_FalsePreProcessorIf(pbool hadtrue, int originalline)
{
int eval;
int level = 1;
while (1)
{
while(*pr_file_p && (*pr_file_p==' ' || *pr_file_p == '\t'))
pr_file_p++;
if (!*pr_file_p)
{
pr_source_line = originalline;
QCC_PR_ParseError (ERR_NOENDIF, "#if with no endif");
}
if (*pr_file_p == '#')
{
pr_file_p++;
while(*pr_file_p==' ' || *pr_file_p == '\t')
pr_file_p++;
if (!strncmp(pr_file_p, "endif", 5))
level--;
if (!strncmp(pr_file_p, "if", 2))
level++;
if (!hadtrue && !strncmp(pr_file_p, "else", 4) && level == 1)
{
pr_file_p+=4;
QCC_PR_SkipToEndOfLine(true);
return true;
}
if (!hadtrue && !strncmp(pr_file_p, "elif", 4) && level == 1)
{
// QCC_PR_ParseError(ERR_UNKNOWNPUCTUATION, "#elif not supported\n");
pr_file_p += 4;
if (!strncmp(pr_file_p, "def", 3))
{
eval = 1;
pr_file_p += 3;
}
else if (!strncmp(pr_file_p, "ndef", 4))
{
eval = 0;
pr_file_p += 4;
}
else
eval = 2;
if (*pr_file_p != ' ' && *pr_file_p != '\t')
QCC_PR_ParseError(ERR_UNKNOWNPUCTUATION, "malformed #elif\n");
if (eval == 2)
eval = ParsePrecompilerIf(PPI_TOPLEVEL);
else
{
QCC_PR_SimpleGetToken ();
if (eval)
eval = !!QCC_PR_CheckCompConstDefined(pr_token);
else
eval = !QCC_PR_CheckCompConstDefined(pr_token);
}
if (eval)
{
QCC_PR_SkipToEndOfLine(true);
return true;
}
}
}
QCC_PR_SkipToEndOfLine(false);
if (level <= 0)
return false;
pr_file_p++; //next line
pr_source_line++;
}
}
/*
==============
QCC_PR_Precompiler
@ -467,7 +544,6 @@ pbool QCC_PR_Precompiler(void)
int ifmode;
int a;
static int ifs = 0;
int level; //#if level
pbool eval = false;
if (*pr_file_p == '#')
@ -551,96 +627,29 @@ pbool QCC_PR_Precompiler(void)
}
QCC_PR_SkipToEndOfLine(true);
level = 1;
if (eval)
ifs+=1;
else
{
while (1)
{
while(*pr_file_p && (*pr_file_p==' ' || *pr_file_p == '\t'))
pr_file_p++;
if (!*pr_file_p)
{
pr_source_line = originalline;
QCC_PR_ParseError (ERR_NOENDIF, "#if with no endif");
}
if (*pr_file_p == '#')
{
pr_file_p++;
while(*pr_file_p==' ' || *pr_file_p == '\t')
pr_file_p++;
if (!strncmp(pr_file_p, "endif", 5))
level--;
if (!strncmp(pr_file_p, "if", 2))
level++;
if (!strncmp(pr_file_p, "else", 4) && level == 1)
{
ifs+=1;
pr_file_p+=4;
QCC_PR_SkipToEndOfLine(true);
break;
ifs += QCC_PR_FalsePreProcessorIf(false, originalline);
}
}
QCC_PR_SkipToEndOfLine(false);
if (level <= 0)
break;
pr_file_p++; //next line
pr_source_line++;
}
}
}
}
else if (!strncmp(directive, "else", 4))
else if (!strncmp(directive, "else", 4) || !strncmp(directive, "elif", 4))
{
int originalline = pr_source_line;
if (!ifs)
QCC_PR_ParseError(ERR_UNKNOWNPUCTUATION, "#else outside of #if\n");
ifs -= 1;
level = 1;
pr_file_p = directive+4;
QCC_PR_SkipToEndOfLine(true);
while (1)
{
while(*pr_file_p && (*pr_file_p==' ' || *pr_file_p == '\t'))
pr_file_p++;
if (!*pr_file_p)
{
pr_source_line = originalline;
QCC_PR_ParseError(ERR_NOENDIF, "#if with no endif");
}
if (*pr_file_p == '#')
{
pr_file_p++;
while(*pr_file_p==' ' || *pr_file_p == '\t')
pr_file_p++;
if (!strncmp(pr_file_p, "endif", 5))
level--;
if (!strncmp(pr_file_p, "if", 2))
level++;
if (!strncmp(pr_file_p, "else", 4) && level == 1)
{
ifs+=1;
pr_file_p+=4;
QCC_PR_SkipToEndOfLine(true);
break;
}
}
if (!strncmp(directive, "elif", 4))
QCC_PR_SkipToEndOfLine(false);
if (level <= 0)
break;
pr_file_p++; //go off the end
pr_source_line++;
}
else
QCC_PR_SkipToEndOfLine(true);
ifs += QCC_PR_FalsePreProcessorIf(true, originalline);
}
else if (!strncmp(directive, "endif", 5))
{

View file

@ -3261,7 +3261,7 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
else if (!stricmp(arg, "false-empty-strings"))
flag_ifstring = state;
else if (!stricmp(arg, "true-empty-strings"))
flag_ifstring = flag_nullemptystr = state;
flag_brokenifstring = state;
else
QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Unrecognised flag parameter (%s)", myargv[i]);
}

View file

@ -108,7 +108,7 @@ int main (int argc, char **argv)
funcs.funcs.parms->WriteFile = QCC_WriteFile;
funcs.funcs.parms->Printf = logprintf;
funcs.funcs.parms->Sys_Error = Sys_Error;
logfile = fopen("fteqcc.log", "wt");
logfile = fopen("fteqcc.log", "at");
fputs("Args:", logfile);
for (i = 0; i < argc; i++)
{

View file

@ -255,11 +255,15 @@ void SV_Shutdown (void)
NET_Shutdown ();
#ifdef PLUGINS
Plug_Shutdown(true);
#endif
Mod_Shutdown(true);
COM_DestroyWorkerThread();
FS_Shutdown();
#ifdef PLUGINS
Plug_Shutdown(false);
#endif
Cvar_Shutdown();
Cmd_Shutdown();

View file

@ -4731,9 +4731,12 @@ void Cmd_Join_f (void)
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_DropClient(host_client);
else if (SpectatorDisconnect)
else
#endif
if (SpectatorDisconnect)
PR_ExecuteProgram (svprogfuncs, SpectatorDisconnect);
sv.spawned_observer_slots--;
@ -4746,9 +4749,12 @@ void Cmd_Join_f (void)
// FIXME, bump the client's userid?
// call the progs to get default spawn parms for the new client
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_SetNewParms();
else if (pr_global_ptrs->SetNewParms)
else
#endif
if (pr_global_ptrs->SetNewParms)
PR_ExecuteProgram (svprogfuncs, pr_global_struct->SetNewParms);
for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
{
@ -4758,9 +4764,11 @@ void Cmd_Join_f (void)
host_client->spawn_parms[i] = 0;
}
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_ClientConnect(host_client);
else
#endif
{
// call the spawn function
pr_global_struct->time = sv.world.physicstime;
@ -4861,9 +4869,11 @@ void Cmd_Observe_f (void)
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_DropClient(host_client);
else
#endif
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
@ -4879,9 +4889,12 @@ void Cmd_Observe_f (void)
// FIXME, bump the client's userid?
// call the progs to get default spawn parms for the new client
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_SetNewParms();
else if (pr_global_ptrs->SetNewParms)
else
#endif
if (pr_global_ptrs->SetNewParms)
PR_ExecuteProgram (svprogfuncs, pr_global_struct->SetNewParms);
for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
{
@ -4894,9 +4907,11 @@ void Cmd_Observe_f (void)
SV_SpawnSpectator ();
// call the spawn function
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_ClientConnect(host_client);
else
#endif
{
if (SpectatorConnect)
{