2004-08-23 01:38:21 +00:00
//qc execution code.
//we have two conditions.
//one allows us to debug and trace through our code, the other doesn't.
//hopefully, the compiler will do a great job at optimising this code for us, where required.
//if it dosn't, then bum.
//the general overhead should be reduced significantly, and I would be supprised if it did run slower.
//run away loops are checked for ONLY on gotos and function calls. This might give a poorer check, but it will run faster overall.
//Appears to work fine.
# if INTSIZE == 16
# define cont cont16
# define reeval reeval16
# define st st16
# define pr_statements pr_statements16
# define fakeop fakeop16
# define dstatement_t dstatement16_t
# define sofs signed short
# define uofs unsigned short
# elif INTSIZE == 32
# define cont cont32
# define reeval reeval32
# define st st32
# define pr_statements pr_statements32
# define fakeop fakeop32
# define dstatement_t dstatement32_t
# define sofs signed int
# define uofs unsigned int
# elif INTSIZE == 24
# error INTSIZE should be set to 32.
# else
# error Bad cont size
# endif
2011-09-03 03:49:43 +00:00
# ifdef DEBUGABLE
# define OPCODE (st->op & ~0x8000)
# else
# define OPCODE (st->op)
# endif
2005-05-17 02:36:54 +00:00
# define ENGINEPOINTER(p) ((char*)(p) - progfuncs->stringtable)
# define QCPOINTER(p) (eval_t *)(p->_int+progfuncs->stringtable)
# define QCPOINTERM(p) (eval_t *)((p)+progfuncs->stringtable)
2004-08-23 01:38:21 +00:00
//rely upon just st
{
# ifdef DEBUGABLE
cont : //last statement may have been a breakpoint
s = st - pr_statements ;
s + = 1 ;
s = ShowStep ( progfuncs , s ) ;
st = pr_statements + s ;
reeval :
# else
st + + ;
2011-05-20 04:10:46 +00:00
# endif
2011-09-03 03:49:43 +00:00
switch ( OPCODE )
2004-08-23 01:38:21 +00:00
{
case OP_ADD_F :
OPC - > _float = OPA - > _float + OPB - > _float ;
break ;
case OP_ADD_V :
2005-11-29 13:30:20 +00:00
OPC - > _vector [ 0 ] = OPA - > _vector [ 0 ] + OPB - > _vector [ 0 ] ;
OPC - > _vector [ 1 ] = OPA - > _vector [ 1 ] + OPB - > _vector [ 1 ] ;
OPC - > _vector [ 2 ] = OPA - > _vector [ 2 ] + OPB - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
break ;
case OP_SUB_F :
OPC - > _float = OPA - > _float - OPB - > _float ;
break ;
case OP_SUB_V :
2005-11-29 13:30:20 +00:00
OPC - > _vector [ 0 ] = OPA - > _vector [ 0 ] - OPB - > _vector [ 0 ] ;
OPC - > _vector [ 1 ] = OPA - > _vector [ 1 ] - OPB - > _vector [ 1 ] ;
OPC - > _vector [ 2 ] = OPA - > _vector [ 2 ] - OPB - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
break ;
case OP_MUL_F :
OPC - > _float = OPA - > _float * OPB - > _float ;
break ;
case OP_MUL_V :
2005-11-29 13:30:20 +00:00
OPC - > _float = OPA - > _vector [ 0 ] * OPB - > _vector [ 0 ]
+ OPA - > _vector [ 1 ] * OPB - > _vector [ 1 ]
+ OPA - > _vector [ 2 ] * OPB - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
break ;
case OP_MUL_FV :
2005-11-29 13:30:20 +00:00
OPC - > _vector [ 0 ] = OPA - > _float * OPB - > _vector [ 0 ] ;
OPC - > _vector [ 1 ] = OPA - > _float * OPB - > _vector [ 1 ] ;
OPC - > _vector [ 2 ] = OPA - > _float * OPB - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
break ;
case OP_MUL_VF :
2005-11-29 13:30:20 +00:00
OPC - > _vector [ 0 ] = OPB - > _float * OPA - > _vector [ 0 ] ;
OPC - > _vector [ 1 ] = OPB - > _float * OPA - > _vector [ 1 ] ;
OPC - > _vector [ 2 ] = OPB - > _float * OPA - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
break ;
case OP_DIV_F :
OPC - > _float = OPA - > _float / OPB - > _float ;
break ;
case OP_DIV_VF :
2005-11-29 13:30:20 +00:00
OPC - > _vector [ 0 ] = OPB - > _float / OPA - > _vector [ 0 ] ;
OPC - > _vector [ 1 ] = OPB - > _float / OPA - > _vector [ 1 ] ;
OPC - > _vector [ 2 ] = OPB - > _float / OPA - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
break ;
2011-07-08 18:59:48 +00:00
case OP_BITAND_F :
2004-08-23 01:38:21 +00:00
OPC - > _float = ( float ) ( ( int ) OPA - > _float & ( int ) OPB - > _float ) ;
break ;
2011-07-08 18:59:48 +00:00
case OP_BITOR_F :
2004-08-23 01:38:21 +00:00
OPC - > _float = ( float ) ( ( int ) OPA - > _float | ( int ) OPB - > _float ) ;
break ;
2011-07-08 18:59:48 +00:00
case OP_GE_F :
2004-08-23 01:38:21 +00:00
OPC - > _float = ( float ) ( OPA - > _float > = OPB - > _float ) ;
break ;
case OP_GE_I :
OPC - > _int = ( int ) ( OPA - > _int > = OPB - > _int ) ;
break ;
case OP_GE_IF :
OPC - > _float = ( float ) ( OPA - > _int > = OPB - > _float ) ;
break ;
case OP_GE_FI :
OPC - > _float = ( float ) ( OPA - > _float > = OPB - > _int ) ;
break ;
2011-07-08 18:59:48 +00:00
case OP_LE_F :
2004-08-23 01:38:21 +00:00
OPC - > _float = ( float ) ( OPA - > _float < = OPB - > _float ) ;
break ;
case OP_LE_I :
OPC - > _int = ( int ) ( OPA - > _int < = OPB - > _int ) ;
break ;
case OP_LE_IF :
OPC - > _float = ( float ) ( OPA - > _int < = OPB - > _float ) ;
break ;
case OP_LE_FI :
OPC - > _float = ( float ) ( OPA - > _float < = OPB - > _int ) ;
break ;
2011-07-08 18:59:48 +00:00
case OP_GT_F :
2004-08-23 01:38:21 +00:00
OPC - > _float = ( float ) ( OPA - > _float > OPB - > _float ) ;
break ;
case OP_GT_I :
OPC - > _int = ( int ) ( OPA - > _int > OPB - > _int ) ;
break ;
case OP_GT_IF :
OPC - > _float = ( float ) ( OPA - > _int > OPB - > _float ) ;
break ;
case OP_GT_FI :
OPC - > _float = ( float ) ( OPA - > _float > OPB - > _int ) ;
break ;
2011-07-08 18:59:48 +00:00
case OP_LT_F :
2004-08-23 01:38:21 +00:00
OPC - > _float = ( float ) ( OPA - > _float < OPB - > _float ) ;
break ;
case OP_LT_I :
OPC - > _int = ( int ) ( OPA - > _int < OPB - > _int ) ;
break ;
case OP_LT_IF :
OPC - > _float = ( float ) ( OPA - > _int < OPB - > _float ) ;
break ;
case OP_LT_FI :
OPC - > _float = ( float ) ( OPA - > _float < OPB - > _int ) ;
break ;
2011-07-08 18:59:48 +00:00
case OP_AND_F :
2004-08-23 01:38:21 +00:00
OPC - > _float = ( float ) ( OPA - > _float & & OPB - > _float ) ;
break ;
2011-07-08 18:59:48 +00:00
case OP_OR_F :
2004-08-23 01:38:21 +00:00
OPC - > _float = ( float ) ( OPA - > _float | | OPB - > _float ) ;
break ;
case OP_NOT_F :
OPC - > _float = ( float ) ( ! OPA - > _float ) ;
break ;
case OP_NOT_V :
2005-11-29 13:30:20 +00:00
OPC - > _float = ( float ) ( ! OPA - > _vector [ 0 ] & & ! OPA - > _vector [ 1 ] & & ! OPA - > _vector [ 2 ] ) ;
2004-08-23 01:38:21 +00:00
break ;
case OP_NOT_S :
2007-03-11 16:51:45 +00:00
OPC - > _float = ( float ) ( ! ( OPA - > string ) | | ! * PR_StringToNative ( progfuncs , OPA - > string ) ) ;
2004-08-23 01:38:21 +00:00
break ;
case OP_NOT_FNC :
OPC - > _float = ( float ) ( ! ( OPA - > function & ~ 0xff000000 ) ) ;
break ;
case OP_NOT_ENT :
2005-03-28 00:11:59 +00:00
OPC - > _float = ( float ) ( PROG_TO_EDICT ( progfuncs , OPA - > edict ) = = ( edictrun_t * ) sv_edicts ) ;
2004-08-23 01:38:21 +00:00
break ;
case OP_EQ_F :
OPC - > _float = ( float ) ( OPA - > _float = = OPB - > _float ) ;
break ;
case OP_EQ_IF :
OPC - > _float = ( float ) ( OPA - > _int = = OPB - > _float ) ;
break ;
case OP_EQ_FI :
OPC - > _float = ( float ) ( OPA - > _float = = OPB - > _int ) ;
break ;
case OP_EQ_V :
2005-11-29 13:30:20 +00:00
OPC - > _float = ( float ) ( ( OPA - > _vector [ 0 ] = = OPB - > _vector [ 0 ] ) & &
( OPA - > _vector [ 1 ] = = OPB - > _vector [ 1 ] ) & &
( OPA - > _vector [ 2 ] = = OPB - > _vector [ 2 ] ) ) ;
2004-08-23 01:38:21 +00:00
break ;
case OP_EQ_S :
if ( OPA - > string = = OPB - > string )
OPC - > _float = true ;
else if ( ! OPA - > string )
{
2007-03-11 16:51:45 +00:00
if ( ! OPB - > string | | ! * PR_StringToNative ( progfuncs , OPB - > string ) )
2004-08-23 01:38:21 +00:00
OPC - > _float = true ;
else
OPC - > _float = false ;
}
else if ( ! OPB - > string )
{
2007-03-11 16:51:45 +00:00
if ( ! OPA - > string | | ! * PR_StringToNative ( progfuncs , OPA - > string ) )
2004-08-23 01:38:21 +00:00
OPC - > _float = true ;
else
OPC - > _float = false ;
}
else
2007-03-11 16:51:45 +00:00
OPC - > _float = ( float ) ( ! strcmp ( PR_StringToNative ( progfuncs , OPA - > string ) , PR_StringToNative ( progfuncs , OPB - > string ) ) ) ;
2004-08-23 01:38:21 +00:00
break ;
case OP_EQ_E :
OPC - > _float = ( float ) ( OPA - > _int = = OPB - > _int ) ;
break ;
case OP_EQ_FNC :
OPC - > _float = ( float ) ( OPA - > function = = OPB - > function ) ;
break ;
case OP_NE_F :
OPC - > _float = ( float ) ( OPA - > _float ! = OPB - > _float ) ;
break ;
case OP_NE_V :
2005-11-29 13:30:20 +00:00
OPC - > _float = ( float ) ( ( OPA - > _vector [ 0 ] ! = OPB - > _vector [ 0 ] ) | |
( OPA - > _vector [ 1 ] ! = OPB - > _vector [ 1 ] ) | |
( OPA - > _vector [ 2 ] ! = OPB - > _vector [ 2 ] ) ) ;
2004-08-23 01:38:21 +00:00
break ;
case OP_NE_S :
if ( OPA - > string = = OPB - > string )
OPC - > _float = false ;
else if ( ! OPA - > string )
{
2007-03-11 16:51:45 +00:00
if ( ! OPB - > string | | ! * ( PR_StringToNative ( progfuncs , OPB - > string ) ) )
2004-08-23 01:38:21 +00:00
OPC - > _float = false ;
else
OPC - > _float = true ;
}
else if ( ! OPB - > string )
{
2007-03-11 16:51:45 +00:00
if ( ! OPA - > string | | ! * PR_StringToNative ( progfuncs , OPA - > string ) )
2004-08-23 01:38:21 +00:00
OPC - > _float = false ;
else
OPC - > _float = true ;
}
else
2007-03-11 16:51:45 +00:00
OPC - > _float = ( float ) ( strcmp ( PR_StringToNative ( progfuncs , OPA - > string ) , PR_StringToNative ( progfuncs , OPB - > string ) ) ) ;
2004-08-23 01:38:21 +00:00
break ;
case OP_NE_E :
OPC - > _float = ( float ) ( OPA - > _int ! = OPB - > _int ) ;
break ;
case OP_NE_FNC :
OPC - > _float = ( float ) ( OPA - > function ! = OPB - > function ) ;
break ;
//==================
case OP_STORE_IF :
OPB - > _float = ( float ) OPA - > _int ;
break ;
case OP_STORE_FI :
OPB - > _int = ( int ) OPA - > _float ;
break ;
2009-08-29 14:56:42 +00:00
2004-08-23 01:38:21 +00:00
case OP_STORE_F :
case OP_STORE_ENT :
case OP_STORE_FLD : // integers
case OP_STORE_S :
2009-08-29 14:56:42 +00:00
case OP_STORE_I :
2004-08-23 01:38:21 +00:00
case OP_STORE_FNC : // pointers
2009-08-29 14:56:42 +00:00
case OP_STORE_P :
2004-08-23 01:38:21 +00:00
OPB - > _int = OPA - > _int ;
break ;
case OP_STORE_V :
2005-11-29 13:30:20 +00:00
OPB - > _vector [ 0 ] = OPA - > _vector [ 0 ] ;
OPB - > _vector [ 1 ] = OPA - > _vector [ 1 ] ;
OPB - > _vector [ 2 ] = OPA - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
break ;
//store a value to a pointer
case OP_STOREP_IF :
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) OPB - > _int > = prinst - > addressableused )
2008-11-09 22:29:28 +00:00
{
pr_xstatement = st - pr_statements ;
2011-10-03 02:45:44 +00:00
PR_RunError ( progfuncs , " bad pointer write in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
2008-11-09 22:29:28 +00:00
}
2005-05-17 02:36:54 +00:00
ptr = QCPOINTER ( OPB ) ;
2004-08-23 01:38:21 +00:00
ptr - > _float = ( float ) OPA - > _int ;
break ;
case OP_STOREP_FI :
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) OPB - > _int > = prinst - > addressableused )
2008-11-09 22:29:28 +00:00
{
pr_xstatement = st - pr_statements ;
2011-10-03 02:45:44 +00:00
PR_RunError ( progfuncs , " bad pointer write in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
2008-11-09 22:29:28 +00:00
}
2005-05-17 02:36:54 +00:00
ptr = QCPOINTER ( OPB ) ;
2004-08-23 01:38:21 +00:00
ptr - > _int = ( int ) OPA - > _float ;
break ;
case OP_STOREP_I :
2012-02-05 01:38:51 +00:00
case OP_GSTOREP_I :
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) OPB - > _int > = prinst - > addressableused )
2008-11-09 22:29:28 +00:00
{
pr_xstatement = st - pr_statements ;
2011-10-03 02:45:44 +00:00
PR_RunError ( progfuncs , " bad pointer write in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
2008-11-09 22:29:28 +00:00
}
2005-05-17 02:36:54 +00:00
ptr = QCPOINTER ( OPB ) ;
2004-08-23 01:38:21 +00:00
ptr - > _int = OPA - > _int ;
break ;
case OP_STOREP_F :
2012-02-05 01:38:51 +00:00
case OP_GSTOREP_F :
2004-08-23 01:38:21 +00:00
case OP_STOREP_ENT :
2012-02-05 01:38:51 +00:00
case OP_GSTOREP_ENT :
2004-08-23 01:38:21 +00:00
case OP_STOREP_FLD : // integers
2012-02-05 01:38:51 +00:00
case OP_GSTOREP_FLD :
2004-08-23 01:38:21 +00:00
case OP_STOREP_S :
2012-02-05 01:38:51 +00:00
case OP_GSTOREP_S :
2004-08-23 01:38:21 +00:00
case OP_STOREP_FNC : // pointers
2012-02-05 01:38:51 +00:00
case OP_GSTOREP_FNC :
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) OPB - > _int > = prinst - > addressableused )
2008-11-09 22:29:28 +00:00
{
pr_xstatement = st - pr_statements ;
2012-03-19 06:30:41 +00:00
PR_RunError ( progfuncs , " bad pointer write in %s (%x >= %x) " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) , OPB - > _int , prinst - > addressableused ) ;
2008-11-09 22:29:28 +00:00
}
2005-05-17 02:36:54 +00:00
ptr = QCPOINTER ( OPB ) ;
2004-08-23 01:38:21 +00:00
ptr - > _int = OPA - > _int ;
break ;
case OP_STOREP_V :
2012-02-05 01:38:51 +00:00
case OP_GSTOREP_V :
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) OPB - > _int > = prinst - > addressableused )
2008-11-09 22:29:28 +00:00
{
pr_xstatement = st - pr_statements ;
2011-10-03 02:45:44 +00:00
PR_RunError ( progfuncs , " bad pointer write in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
2008-11-09 22:29:28 +00:00
}
2005-05-17 02:36:54 +00:00
ptr = QCPOINTER ( OPB ) ;
2005-11-29 13:30:20 +00:00
ptr - > _vector [ 0 ] = OPA - > _vector [ 0 ] ;
ptr - > _vector [ 1 ] = OPA - > _vector [ 1 ] ;
ptr - > _vector [ 2 ] = OPA - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
break ;
case OP_STOREP_C : //store character in a string
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) OPB - > _int > = prinst - > addressableused )
2008-11-09 22:29:28 +00:00
{
pr_xstatement = st - pr_statements ;
2011-10-03 02:45:44 +00:00
PR_RunError ( progfuncs , " bad pointer write in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
2008-11-09 22:29:28 +00:00
}
2005-05-17 02:36:54 +00:00
ptr = QCPOINTER ( OPB ) ;
2004-08-23 01:38:21 +00:00
* ( unsigned char * ) ptr = ( char ) OPA - > _float ;
break ;
case OP_MULSTORE_F : // f *= f
OPB - > _float * = OPA - > _float ;
break ;
2012-01-17 07:57:46 +00:00
case OP_MULSTORE_VF : // v *= f
2005-11-29 13:30:20 +00:00
OPB - > _vector [ 0 ] * = OPA - > _float ;
OPB - > _vector [ 1 ] * = OPA - > _float ;
OPB - > _vector [ 2 ] * = OPA - > _float ;
2004-08-23 01:38:21 +00:00
break ;
case OP_MULSTOREP_F : // e.f *= f
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) OPB - > _int > = prinst - > addressableused )
2008-11-09 22:29:28 +00:00
{
pr_xstatement = st - pr_statements ;
2011-10-03 02:45:44 +00:00
PR_RunError ( progfuncs , " bad pointer write in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
2008-11-09 22:29:28 +00:00
}
2005-05-17 02:36:54 +00:00
ptr = QCPOINTER ( OPB ) ;
2004-08-23 01:38:21 +00:00
OPC - > _float = ( ptr - > _float * = OPA - > _float ) ;
break ;
2012-01-17 07:57:46 +00:00
case OP_MULSTOREP_VF : // e.v *= f
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) OPB - > _int > = prinst - > addressableused )
2011-12-05 15:23:40 +00:00
{
pr_xstatement = st - pr_statements ;
PR_RunError ( progfuncs , " bad pointer write in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
}
2005-05-17 02:36:54 +00:00
ptr = QCPOINTER ( OPB ) ;
2005-11-29 13:30:20 +00:00
OPC - > _vector [ 0 ] = ( ptr - > _vector [ 0 ] * = OPA - > _float ) ;
OPC - > _vector [ 0 ] = ( ptr - > _vector [ 1 ] * = OPA - > _float ) ;
OPC - > _vector [ 0 ] = ( ptr - > _vector [ 2 ] * = OPA - > _float ) ;
2004-08-23 01:38:21 +00:00
break ;
case OP_DIVSTORE_F : // f /= f
OPB - > _float / = OPA - > _float ;
break ;
case OP_DIVSTOREP_F : // e.f /= f
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) OPB - > _int > = prinst - > addressableused )
2011-12-05 15:23:40 +00:00
{
pr_xstatement = st - pr_statements ;
PR_RunError ( progfuncs , " bad pointer write in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
}
2005-05-17 02:36:54 +00:00
ptr = QCPOINTER ( OPB ) ;
2004-08-23 01:38:21 +00:00
OPC - > _float = ( ptr - > _float / = OPA - > _float ) ;
break ;
case OP_ADDSTORE_F : // f += f
OPB - > _float + = OPA - > _float ;
break ;
case OP_ADDSTORE_V : // v += v
2005-11-29 13:30:20 +00:00
OPB - > _vector [ 0 ] + = OPA - > _vector [ 0 ] ;
OPB - > _vector [ 1 ] + = OPA - > _vector [ 1 ] ;
OPB - > _vector [ 2 ] + = OPA - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
break ;
case OP_ADDSTOREP_F : // e.f += f
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) OPB - > _int > = prinst - > addressableused )
2011-12-05 15:23:40 +00:00
{
pr_xstatement = st - pr_statements ;
PR_RunError ( progfuncs , " bad pointer write in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
}
2005-05-17 02:36:54 +00:00
ptr = QCPOINTER ( OPB ) ;
2004-08-23 01:38:21 +00:00
OPC - > _float = ( ptr - > _float + = OPA - > _float ) ;
break ;
case OP_ADDSTOREP_V : // e.v += v
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) OPB - > _int > = prinst - > addressableused )
2011-12-05 15:23:40 +00:00
{
pr_xstatement = st - pr_statements ;
PR_RunError ( progfuncs , " bad pointer write in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
}
2005-05-17 02:36:54 +00:00
ptr = QCPOINTER ( OPB ) ;
2005-11-29 13:30:20 +00:00
OPC - > _vector [ 0 ] = ( ptr - > _vector [ 0 ] + = OPA - > _vector [ 0 ] ) ;
OPC - > _vector [ 1 ] = ( ptr - > _vector [ 1 ] + = OPA - > _vector [ 1 ] ) ;
OPC - > _vector [ 2 ] = ( ptr - > _vector [ 2 ] + = OPA - > _vector [ 2 ] ) ;
2004-08-23 01:38:21 +00:00
break ;
case OP_SUBSTORE_F : // f -= f
OPB - > _float - = OPA - > _float ;
break ;
case OP_SUBSTORE_V : // v -= v
2005-11-29 13:30:20 +00:00
OPB - > _vector [ 0 ] - = OPA - > _vector [ 0 ] ;
OPB - > _vector [ 1 ] - = OPA - > _vector [ 1 ] ;
OPB - > _vector [ 2 ] - = OPA - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
break ;
case OP_SUBSTOREP_F : // e.f -= f
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) OPB - > _int > = prinst - > addressableused )
2011-12-05 15:23:40 +00:00
{
pr_xstatement = st - pr_statements ;
PR_RunError ( progfuncs , " bad pointer write in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
}
2005-05-17 02:36:54 +00:00
ptr = QCPOINTER ( OPB ) ;
2004-08-23 01:38:21 +00:00
OPC - > _float = ( ptr - > _float - = OPA - > _float ) ;
break ;
case OP_SUBSTOREP_V : // e.v -= v
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) OPB - > _int > = prinst - > addressableused )
2011-12-05 15:23:40 +00:00
{
pr_xstatement = st - pr_statements ;
PR_RunError ( progfuncs , " bad pointer write in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
}
2005-05-17 02:36:54 +00:00
ptr = QCPOINTER ( OPB ) ;
2005-11-29 13:30:20 +00:00
OPC - > _vector [ 0 ] = ( ptr - > _vector [ 0 ] - = OPA - > _vector [ 0 ] ) ;
OPC - > _vector [ 1 ] = ( ptr - > _vector [ 1 ] - = OPA - > _vector [ 1 ] ) ;
OPC - > _vector [ 2 ] = ( ptr - > _vector [ 2 ] - = OPA - > _vector [ 2 ] ) ;
2004-08-23 01:38:21 +00:00
break ;
//get a pointer to a field var
case OP_ADDRESS :
2005-10-07 02:14:22 +00:00
if ( ( unsigned ) OPA - > edict > = ( unsigned ) maxedicts )
2008-12-23 02:55:20 +00:00
{
# ifndef DEBUGABLE
pr_trace + + ;
2011-10-03 02:45:44 +00:00
printf ( " OP_ADDRESS references invalid entity in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
2008-12-23 02:55:20 +00:00
st - - ;
goto cont ;
# else
2010-02-06 01:25:04 +00:00
PR_RunError ( progfuncs , " OP_ADDRESS references invalid entity in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
2008-12-23 02:55:20 +00:00
# endif
}
2005-03-28 00:11:59 +00:00
ed = PROG_TO_EDICT ( progfuncs , OPA - > edict ) ;
2004-08-23 01:38:21 +00:00
# ifdef PARANOID
NUM_FOR_EDICT ( ed ) ; // make sure it's in range
# endif
2005-11-30 01:20:53 +00:00
if ( ! ed | | ed - > readonly )
2004-11-08 11:46:34 +00:00
{
pr_xstatement = st - pr_statements ;
2008-12-23 02:55:20 +00:00
# ifndef DEBUGABLE
//boot it over to the debugger
pr_trace + + ;
2011-10-03 02:45:44 +00:00
printf ( " assignment to read-only entity in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
2008-12-23 02:55:20 +00:00
st - - ;
goto cont ;
# else
2010-02-06 01:25:04 +00:00
{
ddef16_t * d16 ;
fdef_t * f ;
d16 = ED_GlobalAtOfs16 ( progfuncs , st - > a ) ;
f = ED_FieldAtOfs ( progfuncs , OPB - > _int + progfuncs - > fieldadjust ) ;
2012-02-17 01:12:37 +00:00
printf ( " assignment to read-only entity in %s (%s.%s) \n " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) , d16 ? PR_StringToNative ( progfuncs , d16 - > s_name ) : NULL , f ? f - > name : NULL ) ;
2010-02-06 01:25:04 +00:00
}
2008-12-23 02:55:20 +00:00
# endif
2004-11-08 11:46:34 +00:00
}
2005-11-26 03:02:55 +00:00
//Whilst the next block would technically be correct, we don't use it as it breaks too many quake mods.
// if (ed->isfree)
// {
// pr_xstatement = st-pr_statements;
2011-10-03 02:45:44 +00:00
// PR_RunError (progfuncs, "assignment to free entitiy in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
2005-11-26 03:02:55 +00:00
// }
2005-05-17 02:36:54 +00:00
OPC - > _int = ENGINEPOINTER ( ( ( ( int * ) edvars ( ed ) ) + OPB - > _int + progfuncs - > fieldadjust ) ) ;
2004-08-23 01:38:21 +00:00
break ;
//load a field to a value
case OP_LOAD_I :
case OP_LOAD_F :
case OP_LOAD_FLD :
case OP_LOAD_ENT :
case OP_LOAD_S :
case OP_LOAD_FNC :
2005-10-07 02:14:22 +00:00
if ( ( unsigned ) OPA - > edict > = ( unsigned ) maxedicts )
2011-10-03 02:45:44 +00:00
PR_RunError ( progfuncs , " OP_LOAD references invalid entity in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
2005-03-28 00:11:59 +00:00
ed = PROG_TO_EDICT ( progfuncs , OPA - > edict ) ;
2004-08-23 01:38:21 +00:00
# ifdef PARANOID
NUM_FOR_EDICT ( ed ) ; // make sure it's in range
# endif
ptr = ( eval_t * ) ( ( ( int * ) edvars ( ed ) ) + OPB - > _int + progfuncs - > fieldadjust ) ;
OPC - > _int = ptr - > _int ;
break ;
case OP_LOAD_V :
2005-10-07 02:14:22 +00:00
if ( ( unsigned ) OPA - > edict > = ( unsigned ) maxedicts )
2011-10-03 02:45:44 +00:00
PR_RunError ( progfuncs , " OP_LOAD_V references invalid entity in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
2005-03-28 00:11:59 +00:00
ed = PROG_TO_EDICT ( progfuncs , OPA - > edict ) ;
2004-08-23 01:38:21 +00:00
# ifdef PARANOID
NUM_FOR_EDICT ( ed ) ; // make sure it's in range
# endif
ptr = ( eval_t * ) ( ( ( int * ) edvars ( ed ) ) + OPB - > _int + progfuncs - > fieldadjust ) ;
2005-11-29 13:30:20 +00:00
OPC - > _vector [ 0 ] = ptr - > _vector [ 0 ] ;
OPC - > _vector [ 1 ] = ptr - > _vector [ 1 ] ;
OPC - > _vector [ 2 ] = ptr - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
break ;
//==================
2009-08-29 14:56:42 +00:00
case OP_IFNOT_S :
2004-08-23 01:38:21 +00:00
RUNAWAYCHECK ( ) ;
2007-03-11 16:51:45 +00:00
if ( ! OPA - > string | | ! PR_StringToNative ( progfuncs , OPA - > string ) )
2004-08-23 01:38:21 +00:00
st + = ( sofs ) st - > b - 1 ; // offset the s++
break ;
2009-08-29 14:56:42 +00:00
case OP_IFNOT_F :
RUNAWAYCHECK ( ) ;
if ( ! OPA - > _float )
st + = ( sofs ) st - > b - 1 ; // offset the s++
break ;
2011-07-08 18:59:48 +00:00
case OP_IFNOT_I :
2004-08-23 01:38:21 +00:00
RUNAWAYCHECK ( ) ;
if ( ! OPA - > _int )
st + = ( sofs ) st - > b - 1 ; // offset the s++
break ;
2009-08-29 14:56:42 +00:00
case OP_IF_S :
2004-08-23 01:38:21 +00:00
RUNAWAYCHECK ( ) ;
2007-03-11 16:51:45 +00:00
if ( OPA - > string & & PR_StringToNative ( progfuncs , OPA - > string ) )
2004-08-23 01:38:21 +00:00
st + = ( sofs ) st - > b - 1 ; // offset the s++
break ;
2009-08-29 14:56:42 +00:00
case OP_IF_F :
RUNAWAYCHECK ( ) ;
if ( OPA - > _int )
st + = ( sofs ) st - > b - 1 ; // offset the s++
break ;
2011-07-08 18:59:48 +00:00
case OP_IF_I :
2004-08-23 01:38:21 +00:00
RUNAWAYCHECK ( ) ;
if ( OPA - > _int )
st + = ( sofs ) st - > b - 1 ; // offset the s++
break ;
case OP_GOTO :
RUNAWAYCHECK ( ) ;
st + = ( sofs ) st - > a - 1 ; // offset the s++
break ;
case OP_CALL8H :
case OP_CALL7H :
case OP_CALL6H :
case OP_CALL5H :
case OP_CALL4H :
case OP_CALL3H :
case OP_CALL2H :
2005-11-29 13:30:20 +00:00
G_VECTOR ( OFS_PARM1 ) [ 0 ] = OPC - > _vector [ 0 ] ;
G_VECTOR ( OFS_PARM1 ) [ 1 ] = OPC - > _vector [ 1 ] ;
G_VECTOR ( OFS_PARM1 ) [ 2 ] = OPC - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
case OP_CALL1H :
2005-11-29 13:30:20 +00:00
G_VECTOR ( OFS_PARM0 ) [ 0 ] = OPB - > _vector [ 0 ] ;
G_VECTOR ( OFS_PARM0 ) [ 1 ] = OPB - > _vector [ 1 ] ;
G_VECTOR ( OFS_PARM0 ) [ 2 ] = OPB - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
case OP_CALL8 :
case OP_CALL7 :
case OP_CALL6 :
case OP_CALL5 :
case OP_CALL4 :
case OP_CALL3 :
case OP_CALL2 :
case OP_CALL1 :
case OP_CALL0 :
RUNAWAYCHECK ( ) ;
pr_xstatement = st - pr_statements ;
2011-09-03 03:49:43 +00:00
if ( OPCODE > OP_CALL8 )
pr_argc = OPCODE - ( OP_CALL1H - 1 ) ;
2004-08-23 01:38:21 +00:00
else
2011-09-03 03:49:43 +00:00
pr_argc = OPCODE - OP_CALL0 ;
2004-08-23 01:38:21 +00:00
fnum = OPA - > function ;
2004-11-04 01:22:18 +00:00
if ( ( fnum & ~ 0xff000000 ) = = 0 )
2004-08-23 01:38:21 +00:00
{
2011-10-03 02:45:44 +00:00
PR_RunError ( progfuncs , " NULL function from qc (%s). \n " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
2004-08-23 01:38:21 +00:00
# ifndef DEBUGABLE
goto cont ;
# endif
break ;
}
/*
{
static char buffer [ 1024 * 1024 * 8 ] ;
int size = sizeof buffer ;
progfuncs - > save_ents ( progfuncs , buffer , & size , 0 ) ;
} */
2011-10-03 02:45:44 +00:00
{
int callerprogs = pr_typecurrent ;
2004-08-23 01:38:21 +00:00
//about to switch. needs caching.
//if it's an external call, switch now (before any function pointers are used)
2011-10-03 02:45:44 +00:00
PR_MoveParms ( progfuncs , ( fnum & 0xff000000 ) > > 24 , callerprogs ) ;
2004-08-23 01:38:21 +00:00
PR_SwitchProgs ( progfuncs , ( fnum & 0xff000000 ) > > 24 ) ;
newf = & pr_functions [ fnum & ~ 0xff000000 ] ;
if ( newf - > first_statement < 0 )
{ // negative statements are built in functions
2011-10-03 02:45:44 +00:00
/*calling a builtin in another progs may affect that other progs' globals instead, is the theory anyway, so args and stuff need to move over*/
if ( pr_typecurrent ! = 0 )
{
PR_MoveParms ( progfuncs , 0 , pr_typecurrent ) ;
PR_SwitchProgs ( progfuncs , 0 ) ;
}
2004-08-23 01:38:21 +00:00
i = - newf - > first_statement ;
// p = pr_typecurrent;
2004-09-01 00:04:02 +00:00
progfuncs - > lastcalledbuiltinnumber = i ;
2004-08-23 01:38:21 +00:00
if ( i < externs - > numglobalbuiltins )
{
2007-03-11 16:51:45 +00:00
prinst - > numtempstringsstack = prinst - > numtempstrings ;
2004-08-23 01:38:21 +00:00
( * externs - > globalbuiltins [ i ] ) ( progfuncs , ( struct globalvars_s * ) current_progstate - > globals ) ;
if ( prinst - > continuestatement ! = - 1 )
{
st = & pr_statements [ prinst - > continuestatement ] ;
prinst - > continuestatement = - 1 ;
break ;
}
}
else
{
i - = externs - > numglobalbuiltins ;
2004-11-23 00:22:04 +00:00
if ( i > = current_progstate - > numbuiltins )
2004-08-23 01:38:21 +00:00
{
2005-05-17 02:36:54 +00:00
// if (newf->first_statement == -0x7fffffff)
// ((builtin_t)newf->profile) (progfuncs, (struct globalvars_s *)current_progstate->globals);
// else
2004-08-23 01:38:21 +00:00
PR_RunError ( progfuncs , " Bad builtin call number - %i " , - newf - > first_statement ) ;
}
else
current_progstate - > builtins [ i ] ( progfuncs , ( struct globalvars_s * ) current_progstate - > globals ) ;
}
2011-10-03 02:45:44 +00:00
PR_MoveParms ( progfuncs , callerprogs , pr_typecurrent ) ;
2004-08-23 01:38:21 +00:00
// memcpy(&pr_progstate[p].globals[OFS_RETURN], ¤t_progstate->globals[OFS_RETURN], sizeof(vec3_t));
2011-10-03 02:45:44 +00:00
PR_SwitchProgs ( progfuncs , ( progsnum_t ) callerprogs ) ;
2004-08-23 01:38:21 +00:00
//#ifndef DEBUGABLE //decide weather non debugger wants to start debugging.
s = st - pr_statements ;
goto restart ;
//#endif
// break;
}
// PR_MoveParms((OPA->function & 0xff000000)>>24, pr_typecurrent);
// PR_SwitchProgs((OPA->function & 0xff000000)>>24);
2011-10-03 02:45:44 +00:00
s = PR_EnterFunction ( progfuncs , newf , callerprogs ) ;
2004-08-23 01:38:21 +00:00
st = & pr_statements [ s ] ;
2011-10-03 02:45:44 +00:00
}
2004-08-23 01:38:21 +00:00
goto restart ;
// break;
case OP_DONE :
case OP_RETURN :
RUNAWAYCHECK ( ) ;
pr_globals [ OFS_RETURN ] = pr_globals [ st - > a ] ;
pr_globals [ OFS_RETURN + 1 ] = pr_globals [ st - > a + 1 ] ;
pr_globals [ OFS_RETURN + 2 ] = pr_globals [ st - > a + 2 ] ;
/*
{
static char buffer [ 1024 * 1024 * 8 ] ;
int size = sizeof buffer ;
progfuncs - > save_ents ( progfuncs , buffer , & size , 0 ) ;
2004-11-23 00:22:04 +00:00
}
*/
2004-08-23 01:38:21 +00:00
s = PR_LeaveFunction ( progfuncs ) ;
st = & pr_statements [ s ] ;
if ( pr_depth = = prinst - > exitdepth )
{
return ; // all done
}
goto restart ;
// break;
case OP_STATE :
externs - > stateop ( progfuncs , OPA - > _float , OPB - > function ) ;
break ;
case OP_ADD_I :
OPC - > _int = OPA - > _int + OPB - > _int ;
break ;
case OP_ADD_FI :
OPC - > _float = OPA - > _float + ( float ) OPB - > _int ;
break ;
case OP_ADD_IF :
OPC - > _float = ( float ) OPA - > _int + OPB - > _float ;
break ;
case OP_SUB_I :
OPC - > _int = OPA - > _int - OPB - > _int ;
break ;
case OP_SUB_FI :
OPC - > _float = OPA - > _float - ( float ) OPB - > _int ;
break ;
case OP_SUB_IF :
OPC - > _float = ( float ) OPA - > _int - OPB - > _float ;
break ;
case OP_CONV_ITOF :
OPC - > _float = ( float ) OPA - > _int ;
break ;
case OP_CONV_FTOI :
OPC - > _int = ( int ) OPA - > _float ;
break ;
case OP_CP_ITOF :
ptr = ( eval_t * ) ( ( ( qbyte * ) sv_edicts ) + OPA - > _int ) ;
OPC - > _float = ( float ) ptr - > _int ;
break ;
case OP_CP_FTOI :
ptr = ( eval_t * ) ( ( ( qbyte * ) sv_edicts ) + OPA - > _int ) ;
OPC - > _int = ( int ) ptr - > _float ;
break ;
case OP_BITAND_I :
OPC - > _int = ( OPA - > _int & OPB - > _int ) ;
break ;
case OP_BITOR_I :
OPC - > _int = ( OPA - > _int | OPB - > _int ) ;
break ;
case OP_MUL_I :
OPC - > _int = OPA - > _int * OPB - > _int ;
break ;
case OP_DIV_I :
if ( OPB - > _int = = 0 ) //no division by zero allowed...
OPC - > _int = 0 ;
else
OPC - > _int = OPA - > _int / OPB - > _int ;
break ;
case OP_EQ_I :
OPC - > _int = ( OPA - > _int = = OPB - > _int ) ;
break ;
case OP_NE_I :
OPC - > _int = ( OPA - > _int ! = OPB - > _int ) ;
break ;
2011-07-08 18:59:48 +00:00
//array/structure reading/writing.
2005-03-28 00:11:59 +00:00
case OP_GLOBALADDRESS :
2011-09-03 03:49:43 +00:00
OPC - > _int = ENGINEPOINTER ( & OPA - > _int + OPB - > _int ) ; /*pointer arithmatic*/
2004-08-23 01:38:21 +00:00
break ;
case OP_POINTER_ADD : //pointer to 32 bit (remember to *3 for vectors)
OPC - > _int = OPA - > _int + OPB - > _int * 4 ;
break ;
2005-08-03 23:14:59 +00:00
2004-08-23 01:38:21 +00:00
case OP_LOADA_I :
case OP_LOADA_F :
case OP_LOADA_FLD :
case OP_LOADA_ENT :
case OP_LOADA_S :
case OP_LOADA_FNC :
2011-09-03 03:49:43 +00:00
ptr = ( eval_t * ) ( & OPA - > _int + OPB - > _int ) ; /*pointer arithmatic*/
2004-08-23 01:38:21 +00:00
OPC - > _int = ptr - > _int ;
break ;
case OP_LOADA_V :
2005-05-04 19:49:48 +00:00
ptr = ( eval_t * ) ( & OPA - > _int + OPB - > _int ) ;
2005-11-29 13:30:20 +00:00
OPC - > _vector [ 0 ] = ptr - > _vector [ 0 ] ;
OPC - > _vector [ 1 ] = ptr - > _vector [ 1 ] ;
OPC - > _vector [ 2 ] = ptr - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
break ;
case OP_ADD_SF : //(char*)c = (char*)a + (float)b
OPC - > _int = OPA - > _int + ( int ) OPB - > _float ;
break ;
case OP_SUB_S : //(float)c = (char*)a - (char*)b
OPC - > _int = OPA - > _int - OPB - > _int ;
break ;
case OP_LOADP_C : //load character from a string
2011-12-05 15:23:40 +00:00
i = ( unsigned int ) OPA - > _int + ( unsigned int ) OPB - > _float ;
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) i > = prinst - > addressableused )
2011-12-05 15:23:40 +00:00
{
2012-01-28 10:30:44 +00:00
i = ( unsigned int ) OPB - > _float ;
ptr = ( eval_t * ) PR_StringToNative ( progfuncs , OPA - > _int ) ;
2012-02-05 01:38:51 +00:00
if ( ( size_t ) i > strlen ( ( char * ) ptr ) )
2012-01-28 10:30:44 +00:00
{
pr_xstatement = st - pr_statements ;
PR_RunError ( progfuncs , " bad pointer read in %s (%i bytes into %s) " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) , i , ptr ) ;
}
ptr = ( eval_t * ) ( ( char * ) ptr + i ) ;
2011-12-05 15:23:40 +00:00
}
2012-01-28 10:30:44 +00:00
else
ptr = QCPOINTERM ( i ) ;
2004-08-23 01:38:21 +00:00
OPC - > _float = * ( unsigned char * ) ptr ;
break ;
case OP_LOADP_I :
case OP_LOADP_F :
case OP_LOADP_FLD :
case OP_LOADP_ENT :
case OP_LOADP_S :
case OP_LOADP_FNC :
2011-12-05 15:23:40 +00:00
i = OPA - > _int + OPB - > _int * 4 ;
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) i > = prinst - > addressableused )
2011-12-05 15:23:40 +00:00
{
pr_xstatement = st - pr_statements ;
PR_RunError ( progfuncs , " bad pointer read in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
}
2011-10-03 02:45:44 +00:00
ptr = QCPOINTERM ( OPA - > _int + OPB - > _int * 4 ) ;
2004-08-23 01:38:21 +00:00
OPC - > _int = ptr - > _int ;
break ;
case OP_LOADP_V :
2011-12-05 15:23:40 +00:00
i = OPA - > _int + OPB - > _int * 4 ;
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) i > = prinst - > addressableused )
2011-12-05 15:23:40 +00:00
{
pr_xstatement = st - pr_statements ;
PR_RunError ( progfuncs , " bad pointer read in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
}
ptr = QCPOINTERM ( i ) ;
2005-11-29 13:30:20 +00:00
OPC - > _vector [ 0 ] = ptr - > _vector [ 0 ] ;
OPC - > _vector [ 1 ] = ptr - > _vector [ 1 ] ;
OPC - > _vector [ 2 ] = ptr - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
break ;
2008-11-09 22:29:28 +00:00
case OP_XOR_I :
2004-08-23 01:38:21 +00:00
OPC - > _int = OPA - > _int ^ OPB - > _int ;
break ;
case OP_RSHIFT_I :
OPC - > _int = OPA - > _int > > OPB - > _int ;
break ;
case OP_LSHIFT_I :
OPC - > _int = OPA - > _int < < OPB - > _int ;
break ;
case OP_FETCH_GBL_F :
case OP_FETCH_GBL_S :
case OP_FETCH_GBL_E :
case OP_FETCH_GBL_FNC :
i = ( int ) OPB - > _float ;
2006-01-28 06:41:20 +00:00
if ( i < 0 | | i > ( ( eval_t * ) & glob [ st - > a - 1 ] ) - > _int )
2004-08-23 01:38:21 +00:00
{
2012-01-17 07:57:46 +00:00
PR_RunError ( progfuncs , " array index out of bounds: %s[%d] (max %d) " , PR_GlobalStringNoContents ( progfuncs , st - > a ) , i , ( ( eval_t * ) & glob [ st - > a - 1 ] ) - > _int ) ;
2004-08-23 01:38:21 +00:00
}
t = ( eval_t * ) & pr_globals [ ( uofs ) st - > a + i ] ;
OPC - > _int = t - > _int ;
break ;
case OP_FETCH_GBL_V :
i = ( int ) OPB - > _float ;
2006-01-28 06:41:20 +00:00
if ( i < 0 | | i > ( ( eval_t * ) & glob [ st - > a - 1 ] ) - > _int )
2004-08-23 01:38:21 +00:00
{
PR_RunError ( progfuncs , " array index out of bounds: %s[%d] " , PR_GlobalStringNoContents ( progfuncs , st - > a ) , i ) ;
}
2011-07-08 18:59:48 +00:00
t = ( eval_t * ) & pr_globals [ ( uofs ) st - > a + i * 3 ] ;
2005-11-29 13:30:20 +00:00
OPC - > _vector [ 0 ] = t - > _vector [ 0 ] ;
OPC - > _vector [ 1 ] = t - > _vector [ 1 ] ;
OPC - > _vector [ 2 ] = t - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
break ;
case OP_CSTATE :
externs - > cstateop ( progfuncs , OPA - > _float , OPB - > _float , fnum ) ;
break ;
case OP_CWSTATE :
externs - > cwstateop ( progfuncs , OPA - > _float , OPB - > _float , fnum ) ;
break ;
case OP_THINKTIME :
2005-03-28 00:11:59 +00:00
externs - > thinktimeop ( progfuncs , ( struct edict_s * ) PROG_TO_EDICT ( progfuncs , OPA - > edict ) , OPB - > _float ) ;
2004-08-23 01:38:21 +00:00
break ;
case OP_BITSET : // b (+) a
OPB - > _float = ( float ) ( ( int ) OPB - > _float | ( int ) OPA - > _float ) ;
break ;
case OP_BITSETP : // .b (+) a
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) OPB - > _int > = prinst - > addressableused )
2011-12-05 15:23:40 +00:00
{
pr_xstatement = st - pr_statements ;
PR_RunError ( progfuncs , " bad pointer write in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
}
2005-05-17 02:36:54 +00:00
ptr = QCPOINTER ( OPB ) ;
2004-08-23 01:38:21 +00:00
ptr - > _float = ( float ) ( ( int ) ptr - > _float | ( int ) OPA - > _float ) ;
break ;
case OP_BITCLR : // b (-) a
OPB - > _float = ( float ) ( ( int ) OPB - > _float & ~ ( ( int ) OPA - > _float ) ) ;
break ;
case OP_BITCLRP : // .b (-) a
2012-03-19 06:30:41 +00:00
if ( ( unsigned int ) OPB - > _int > = prinst - > addressableused )
2011-12-05 15:23:40 +00:00
{
pr_xstatement = st - pr_statements ;
PR_RunError ( progfuncs , " bad pointer write in %s " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
}
2005-05-17 02:36:54 +00:00
ptr = QCPOINTER ( OPB ) ;
2004-08-23 01:38:21 +00:00
ptr - > _float = ( float ) ( ( int ) ptr - > _float & ~ ( ( int ) OPA - > _float ) ) ;
break ;
case OP_RAND0 :
2011-09-03 03:49:43 +00:00
OPC - > _float = ( rand ( ) & 0x7fff ) / ( ( float ) 0x7fff ) ;
2004-08-23 01:38:21 +00:00
break ;
case OP_RAND1 :
2011-09-03 03:49:43 +00:00
OPC - > _float = ( rand ( ) & 0x7fff ) / ( ( float ) 0x7fff ) * OPA - > _float ;
2004-08-23 01:38:21 +00:00
break ;
case OP_RAND2 :
if ( OPA - > _float < OPB - > _float )
{
2011-09-03 03:49:43 +00:00
OPC - > _float = OPA - > _float + ( ( rand ( ) & 0x7fff ) / ( ( float ) 0x7fff )
2004-08-23 01:38:21 +00:00
* ( OPB - > _float - OPA - > _float ) ) ;
}
else
{
2011-09-03 03:49:43 +00:00
OPC - > _float = OPB - > _float + ( ( rand ( ) & 0x7fff ) / ( ( float ) 0x7fff )
2004-08-23 01:38:21 +00:00
* ( OPA - > _float - OPB - > _float ) ) ;
}
break ;
case OP_RANDV0 :
2011-09-03 03:49:43 +00:00
OPC - > _vector [ 0 ] = ( rand ( ) & 0x7fff ) / ( ( float ) 0x7fff ) ;
OPC - > _vector [ 1 ] = ( rand ( ) & 0x7fff ) / ( ( float ) 0x7fff ) ;
OPC - > _vector [ 2 ] = ( rand ( ) & 0x7fff ) / ( ( float ) 0x7fff ) ;
2004-08-23 01:38:21 +00:00
break ;
case OP_RANDV1 :
2011-09-03 03:49:43 +00:00
OPC - > _vector [ 0 ] = ( rand ( ) & 0x7fff ) / ( ( float ) 0x7fff ) * OPA - > _vector [ 0 ] ;
OPC - > _vector [ 1 ] = ( rand ( ) & 0x7fff ) / ( ( float ) 0x7fff ) * OPA - > _vector [ 1 ] ;
OPC - > _vector [ 2 ] = ( rand ( ) & 0x7fff ) / ( ( float ) 0x7fff ) * OPA - > _vector [ 2 ] ;
2004-08-23 01:38:21 +00:00
break ;
case OP_RANDV2 :
for ( i = 0 ; i < 3 ; i + + )
{
2005-11-29 13:30:20 +00:00
if ( OPA - > _vector [ i ] < OPB - > _vector [ i ] )
2004-08-23 01:38:21 +00:00
{
2011-09-03 03:49:43 +00:00
OPC - > _vector [ i ] = OPA - > _vector [ i ] + ( ( rand ( ) & 0x7fff ) / ( ( float ) 0x7fff )
2005-11-29 13:30:20 +00:00
* ( OPB - > _vector [ i ] - OPA - > _vector [ i ] ) ) ;
2004-08-23 01:38:21 +00:00
}
else
{
2011-09-03 03:49:43 +00:00
OPC - > _vector [ i ] = OPB - > _vector [ i ] + ( rand ( ) * ( 1.0f / RAND_MAX )
2005-11-29 13:30:20 +00:00
* ( OPA - > _vector [ i ] - OPB - > _vector [ i ] ) ) ;
2004-08-23 01:38:21 +00:00
}
}
break ;
case OP_SWITCH_F :
case OP_SWITCH_V :
case OP_SWITCH_S :
case OP_SWITCH_E :
case OP_SWITCH_FNC :
swtch = OPA ;
2011-09-03 03:49:43 +00:00
swtchtype = OPCODE ;
2004-08-23 01:38:21 +00:00
RUNAWAYCHECK ( ) ;
st + = ( sofs ) st - > b - 1 ; // offset the st++
break ;
case OP_CASE :
switch ( swtchtype )
{
case OP_SWITCH_F :
if ( swtch - > _float = = OPA - > _float )
{
RUNAWAYCHECK ( ) ;
st + = ( sofs ) st - > b - 1 ; // -1 to offset the s++
}
break ;
case OP_SWITCH_E :
case OP_SWITCH_FNC :
if ( swtch - > _int = = OPA - > _int )
{
RUNAWAYCHECK ( ) ;
st + = ( sofs ) st - > b - 1 ; // -1 to offset the s++
}
break ;
case OP_SWITCH_S :
if ( swtch - > _int = = OPA - > _int )
{
RUNAWAYCHECK ( ) ;
st + = ( sofs ) st - > b - 1 ; // -1 to offset the s++
}
2007-03-11 16:51:45 +00:00
if ( ( ! swtch - > _int & & PR_StringToNative ( progfuncs , OPA - > string ) ) | | ( ! OPA - > _int & & PR_StringToNative ( progfuncs , swtch - > string ) ) ) //one is null (cannot be not both).
2004-08-23 01:38:21 +00:00
break ;
2007-03-11 16:51:45 +00:00
if ( ! strcmp ( PR_StringToNative ( progfuncs , swtch - > string ) , PR_StringToNative ( progfuncs , OPA - > string ) ) )
2004-08-23 01:38:21 +00:00
{
RUNAWAYCHECK ( ) ;
st + = ( sofs ) st - > b - 1 ; // -1 to offset the s++
}
break ;
case OP_SWITCH_V :
2005-11-29 13:30:20 +00:00
if ( swtch - > _vector [ 0 ] = = OPA - > _vector [ 0 ] & & swtch - > _vector [ 1 ] = = OPA - > _vector [ 1 ] & & swtch - > _vector [ 2 ] = = OPA - > _vector [ 2 ] )
2004-08-23 01:38:21 +00:00
{
RUNAWAYCHECK ( ) ;
st + = ( sofs ) st - > b - 1 ; // -1 to offset the s++
}
break ;
default :
PR_RunError ( progfuncs , " OP_CASE with bad/missing OP_SWITCH %i " , swtchtype ) ;
break ;
}
break ;
case OP_CASERANGE :
switch ( swtchtype )
{
case OP_SWITCH_F :
if ( swtch - > _float > = OPA - > _float & & swtch - > _float < = OPB - > _float )
{
RUNAWAYCHECK ( ) ;
st + = ( sofs ) st - > c - 1 ; // -1 to offset the s++
}
break ;
default :
PR_RunError ( progfuncs , " OP_CASERANGE with bad/missing OP_SWITCH %i " , swtchtype ) ;
}
break ;
2005-02-28 07:16:19 +00:00
case OP_BITAND_IF :
OPC - > _int = ( OPA - > _int & ( int ) OPB - > _float ) ;
break ;
case OP_BITOR_IF :
OPC - > _int = ( OPA - > _int | ( int ) OPB - > _float ) ;
break ;
case OP_BITAND_FI :
OPC - > _int = ( ( int ) OPA - > _float & OPB - > _int ) ;
break ;
case OP_BITOR_FI :
OPC - > _int = ( ( int ) OPA - > _float | OPB - > _int ) ;
break ;
2004-08-23 01:38:21 +00:00
2005-02-28 07:16:19 +00:00
case OP_MUL_IF :
OPC - > _float = ( OPA - > _int * OPB - > _float ) ;
break ;
case OP_MUL_FI :
OPC - > _float = ( OPA - > _float * OPB - > _int ) ;
break ;
2004-08-23 01:38:21 +00:00
2005-02-28 07:16:19 +00:00
case OP_MUL_VI :
2005-11-29 13:30:20 +00:00
OPC - > _vector [ 0 ] = OPA - > _vector [ 0 ] * OPB - > _int ;
OPC - > _vector [ 1 ] = OPA - > _vector [ 0 ] * OPB - > _int ;
OPC - > _vector [ 2 ] = OPA - > _vector [ 0 ] * OPB - > _int ;
2005-02-28 07:16:19 +00:00
break ;
case OP_MUL_IV :
2005-11-29 13:30:20 +00:00
OPC - > _vector [ 0 ] = OPB - > _int * OPA - > _vector [ 0 ] ;
OPC - > _vector [ 1 ] = OPB - > _int * OPA - > _vector [ 1 ] ;
OPC - > _vector [ 2 ] = OPB - > _int * OPA - > _vector [ 2 ] ;
2005-02-28 07:16:19 +00:00
break ;
case OP_DIV_IF :
OPC - > _float = ( OPA - > _int / OPB - > _float ) ;
break ;
case OP_DIV_FI :
OPC - > _float = ( OPA - > _float / OPB - > _int ) ;
break ;
case OP_AND_I :
OPC - > _int = ( OPA - > _int & & OPB - > _int ) ;
break ;
case OP_OR_I :
OPC - > _int = ( OPA - > _int | | OPB - > _int ) ;
break ;
case OP_AND_IF :
OPC - > _int = ( OPA - > _int & & OPB - > _float ) ;
break ;
case OP_OR_IF :
OPC - > _int = ( OPA - > _int | | OPB - > _float ) ;
break ;
case OP_AND_FI :
OPC - > _int = ( OPA - > _float & & OPB - > _int ) ;
break ;
case OP_OR_FI :
OPC - > _int = ( OPA - > _float | | OPB - > _int ) ;
break ;
case OP_NOT_I :
OPC - > _int = ! OPA - > _int ;
break ;
case OP_NE_IF :
OPC - > _int = ( OPA - > _int ! = OPB - > _float ) ;
break ;
case OP_NE_FI :
OPC - > _int = ( OPA - > _float ! = OPB - > _int ) ;
break ;
case OP_GADDRESS :
case OP_GLOAD_I :
case OP_GLOAD_F :
case OP_GLOAD_FLD :
case OP_GLOAD_ENT :
case OP_GLOAD_S :
case OP_GLOAD_FNC :
pr_xstatement = st - pr_statements ;
PR_RunError ( progfuncs , " Extra opcode not implemented \n " ) ;
break ;
case OP_BOUNDCHECK :
2005-03-28 00:11:59 +00:00
if ( ( unsigned int ) OPA - > _int < ( unsigned int ) st - > c | | ( unsigned int ) OPA - > _int > = ( unsigned int ) st - > b )
2005-02-28 07:16:19 +00:00
{
pr_xstatement = st - pr_statements ;
2011-09-03 03:49:43 +00:00
PR_RunError ( progfuncs , " Progs boundcheck failed. Value is %i. Must be between %u and %u " , OPA - > _int , st - > c , st - > b ) ;
2005-02-28 07:16:19 +00:00
}
break ;
2005-05-17 02:36:54 +00:00
/* case OP_PUSH:
OPC - > _int = ENGINEPOINTER ( & localstack [ localstack_used + pr_spushed ] ) ;
2005-02-28 07:16:19 +00:00
pr_spushed + = OPA - > _int ;
if ( pr_spushed + localstack_used > = LOCALSTACK_SIZE )
{
pr_spushed = 0 ;
pr_xstatement = st - pr_statements ;
PR_RunError ( progfuncs , " Progs pushed too much " ) ;
}
break ;
case OP_POP :
pr_spushed - = OPA - > _int ;
if ( pr_spushed < 0 )
{
pr_spushed = 0 ;
pr_xstatement = st - pr_statements ;
PR_RunError ( progfuncs , " Progs poped more than it pushed " ) ;
}
break ;
2005-05-17 02:36:54 +00:00
*/
2004-08-23 01:38:21 +00:00
default :
if ( st - > op & 0x8000 ) //break point!
{
pr_xstatement = s = st - pr_statements ;
2011-10-03 02:45:44 +00:00
printf ( " Break point hit in %s. \n " , PR_StringToNative ( progfuncs , pr_xfunction - > s_name ) ) ;
2004-08-23 01:38:21 +00:00
if ( pr_trace < 1 )
pr_trace = 1 ; //this is what it's for
s = ShowStep ( progfuncs , s ) ;
st = & pr_statements [ s ] ; //let the user move execution
pr_xstatement = s = st - pr_statements ;
goto reeval ; //reexecute
}
pr_xstatement = st - pr_statements ;
PR_RunError ( progfuncs , " Bad opcode %i " , st - > op ) ;
}
}
# undef cont
# undef reeval
# undef st
# undef pr_statements
# undef fakeop
# undef dstatement_t
# undef sofs
# undef uofs
2011-09-03 03:49:43 +00:00
# undef OPCODE
2005-05-17 02:36:54 +00:00
# undef ENGINEPOINTER
# undef QCPOINTER
2005-05-17 09:50:54 +00:00
# undef QCPOINTERM