1.1 --- a/extensions/sdktools/vcallbuilder.cpp Sat Jun 16 15:19:09 2007 +0000
1.2 +++ b/extensions/sdktools/vcallbuilder.cpp Sat Jun 16 15:40:22 2007 +0000
1.3 @@ -32,6 +32,125 @@
1.4 stk.push(ptr);
1.5 }
1.6
1.7 +ValveCall *CreateValveCall(void *addr,
1.8 + ValveCallType vcalltype,
1.9 + const ValvePassInfo *retInfo,
1.10 + const ValvePassInfo *params,
1.11 + unsigned int numParams)
1.12 +{
1.13 + if (numParams > 32)
1.14 + {
1.15 + return NULL;
1.16 + }
1.17 +
1.18 + ValveCall *vc = new ValveCall;
1.19 +
1.20 + size_t size = 0;
1.21 + vc->stackSize = 0;
1.22 +
1.23 + /* Get return information - encode only*/
1.24 + PassInfo retBuf;
1.25 + size_t retBufSize = 0;
1.26 + if (retInfo)
1.27 + {
1.28 + if ((size = ValveParamToBinParam(retInfo->vtype, retInfo->type, retInfo->flags, &retBuf)) == 0)
1.29 + {
1.30 + delete vc;
1.31 + return NULL;
1.32 + }
1.33 + retBufSize = size;
1.34 + }
1.35 +
1.36 + /* Get thisinfo if needed */
1.37 + ValvePassInfo thisbuf;
1.38 + ValvePassInfo *thisinfo = NULL;
1.39 + CallConvention cv = CallConv_Cdecl;
1.40 + if (vcalltype != ValveCall_Static)
1.41 + {
1.42 + thisinfo = &thisbuf;
1.43 + thisinfo->type = PassType_Basic;
1.44 + if (vcalltype == ValveCall_Entity)
1.45 + {
1.46 + thisinfo->vtype = Valve_CBaseEntity;
1.47 + thisinfo->decflags |= VDECODE_FLAG_ALLOWWORLD;
1.48 + } else if (vcalltype == ValveCall_Player) {
1.49 + thisinfo->vtype = Valve_CBasePlayer;
1.50 + thisinfo->decflags = 0;
1.51 + }
1.52 + thisinfo->encflags = 0;
1.53 + thisinfo->flags = PASSFLAG_BYVAL;
1.54 + thisinfo->offset = 0;
1.55 + vc->stackSize += sizeof(void *);
1.56 + cv = CallConv_ThisCall;
1.57 + }
1.58 +
1.59 + /* Get parameter info */
1.60 + PassInfo paramBuf[32];
1.61 + for (unsigned int i=0; i<numParams; i++)
1.62 + {
1.63 + if ((size = ValveParamToBinParam(params[i].vtype, params[i].type, params[i].flags, ¶mBuf[i])) == 0)
1.64 + {
1.65 + delete vc;
1.66 + return NULL;
1.67 + }
1.68 + vc->stackSize += size;
1.69 + }
1.70 +
1.71 + /* Now we can try creating the call */
1.72 + if ((vc->call = g_pBinTools->CreateCall(addr,
1.73 + cv,
1.74 + (retInfo ? &retBuf : NULL),
1.75 + paramBuf,
1.76 + numParams))
1.77 + == NULL)
1.78 + {
1.79 + if (!vc->call)
1.80 + {
1.81 + delete vc;
1.82 + return NULL;
1.83 + }
1.84 + }
1.85 +
1.86 + /* Allocate extra space for thisptr AND ret buffer, even if we don't use it */
1.87 + vc->vparams = new ValvePassInfo[numParams + 2];
1.88 +
1.89 + /* We've got the call and everything is encoded.
1.90 + * It's time to save the valve specific information and helper variables.
1.91 + */
1.92 + if (retInfo)
1.93 + {
1.94 + /* Allocate and copy */
1.95 + vc->retinfo = &(vc->vparams[numParams]);
1.96 + *vc->retinfo = *retInfo;
1.97 + vc->retinfo->offset = 0;
1.98 + /* Allocate stack space */
1.99 + vc->retbuf = new unsigned char[retBufSize];
1.100 + } else {
1.101 + vc->retinfo = NULL;
1.102 + vc->retbuf = NULL;
1.103 + }
1.104 +
1.105 + if (thisinfo)
1.106 + {
1.107 + /* Allocate and copy */
1.108 + vc->thisinfo = &(vc->vparams[numParams + 1]);
1.109 + *vc->thisinfo = *thisinfo;
1.110 + vc->thisinfo->offset = 0;
1.111 + } else {
1.112 + vc->thisinfo = NULL;
1.113 + }
1.114 +
1.115 + /* Now, save info about each parameter. */
1.116 + for (unsigned int i=0; i<numParams; i++)
1.117 + {
1.118 + /* Copy */
1.119 + vc->vparams[i] = params[i];
1.120 + vc->vparams[i].offset = vc->call->GetParamInfo(i)->offset;
1.121 + }
1.122 +
1.123 + return vc;
1.124 +}
1.125 +
1.126 ValveCall *CreateValveVCall(unsigned int vtableIdx,
1.127 ValveCallType vcalltype,
1.128 const ValvePassInfo *retInfo,