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