Example #1
0
// load the context information for the script system
static BOOL eventLoadContext(const SDWORD version, char *pBuffer, UDWORD *pSize, BOOL bHashed)
{
	UDWORD				size, valSize,stringLen;
	SDWORD				numVars, i, numContext, context;
	SCRIPT_CONTEXT		*psCCont;
	INTERP_TYPE			type;
	SCR_VAL_LOAD		loadFunc;
	char				*pPos;
	char				*pScriptID = NULL;
	UDWORD				hashedName;
	SCRIPT_CODE			*psCode;
	CONTEXT_RELEASE			release;
	INTERP_VAL			*psVal, data;

	size = 0;
	pPos = pBuffer;

	// get the number of contexts in the save file
	endian_sword((SWORD*)pPos);
	numContext = *((SWORD *)pPos);
	pPos += sizeof(SWORD);
	size += sizeof(SWORD);

	// go through the contexts
	for(context=0; context < numContext; context += 1)
	{
	    if(bHashed) {
    		endian_udword((UDWORD*)pPos);
    		hashedName = *((UDWORD*)pPos);
    		psCode = (SCRIPT_CODE*)resGetDataFromHash("SCRIPT", hashedName);
    		pPos += sizeof(UDWORD);
	    } else {
    		// get the script code
    		pScriptID = (char *)pPos;
    		psCode = (SCRIPT_CODE*)resGetData("SCRIPT", pScriptID);
    		pPos += strlen(pScriptID) + 1;
    	}
		// check the number of variables
		endian_sword((SWORD*)pPos);
   		numVars = psCode->numGlobals + psCode->arraySize;
        
		if (numVars != *((SWORD*)pPos))
		{
			ASSERT(false, "Context %d of %d: Number of context variables (%d) does not match the script code (%d)", 
			       context, numContext, numVars, *((SWORD*)pPos));
			return false;
		}
		pPos += sizeof(SWORD);

		release = (CONTEXT_RELEASE)*pPos;
		pPos += sizeof(UBYTE);

		// create the context
		if (!eventNewContext(psCode, release, &psCCont))
		{
			return false;
		}

		// bit of a hack this - note the id of the context to link it to the triggers
		psContList->id = (SWORD)context;

        if(bHashed) {
            size += sizeof(UDWORD) + sizeof(SWORD) + sizeof(UBYTE);
        } else {
		    size += strlen(pScriptID) + 1 + sizeof(SWORD) + sizeof(UBYTE);
		}

		// set the context variables
		for(i=0; i < numVars; i+= 1)
		{
			// get the variable type
			endian_sword((SWORD*)pPos);
			type = (INTERP_TYPE) *((SWORD*)pPos);
			pPos += sizeof(SWORD);
			size += sizeof(SWORD);

			// get the variable value
			if (type < VAL_USERTYPESTART)
			{
				data.type = type;

				endian_udword((UDWORD*)pPos);

				switch (type) {
				case VAL_BOOL:
					data.v.bval = *((BOOL*)pPos);
					pPos += sizeof(BOOL);
					size += sizeof(BOOL);
					break;
				case VAL_FLOAT:
					data.v.fval = *((float*)pPos);
					pPos += sizeof(float);
					size += sizeof(float);
					break;
				case VAL_INT:
				case VAL_TRIGGER:
				case VAL_EVENT:
				case VAL_VOID:
				case VAL_OPCODE:
				case VAL_PKOPCODE:
					data.v.ival = *((UDWORD *)pPos);
					pPos += sizeof(UDWORD);
					size += sizeof(UDWORD);
					break;
				case VAL_STRING:
					data.v.sval = (char*)malloc(MAXSTRLEN);
					strcpy(data.v.sval, "\0");

					stringLen = *((UDWORD *)pPos);	//read string length
					
					pPos += sizeof(UDWORD);
					size += sizeof(UDWORD);

					//load string
					if(stringLen > 0)
					{
						strlcpy(data.v.sval, (char *)pPos, MIN(stringLen + 1, MAXSTRLEN));
						pPos += stringLen;
						size += stringLen;
					}
					break;
				case VAL_OBJ_GETSET:
/* FIXME: saving pointer on disk! */
					data.v.pObjGetSet = *((SCRIPT_VARFUNC*)pPos);
					pPos += sizeof(SCRIPT_VARFUNC);
					size += sizeof(SCRIPT_VARFUNC);
					break;
				case VAL_FUNC_EXTERN:
/* FIXME: saving pointer on disk! */
					data.v.pFuncExtern = *((SCRIPT_FUNC*)pPos);
					pPos += sizeof(SCRIPT_FUNC);
					size += sizeof(SCRIPT_FUNC);
					break;
				default:
					ASSERT( false, "eventLoadContext: invalid internal type" );
				}

				// set the value in the context
				if (!eventSetContextVar(psCCont, (UDWORD)i, &data))
				{
					debug( LOG_FATAL, "eventLoadContext: couldn't set variable value" );
					abort();
					return false;
				}
			}
			else
			{
				// user defined type
				loadFunc = asScrTypeTab[type - VAL_USERTYPESTART].loadFunc;

				ASSERT( loadFunc != NULL,
					"eventLoadContext: no load function for type %d\n", type );

				endian_uword((UWORD*)pPos);
				valSize = *((UWORD *)pPos);

				pPos += sizeof(UWORD);
				size += sizeof(UWORD);

				// get the value pointer so that the loadFunc can write directly
				// into the variables data space.
				if (!eventGetContextVal(psCCont, (UDWORD)i, &psVal))
				{
					debug( LOG_FATAL, "eventLoadContext: couldn't find variable in context" );
					abort();
					return false;
				}

				if (!loadFunc(version, psVal, pPos, valSize))
				{
					debug( LOG_FATAL, "eventLoadContext: couldn't get variable value" );
					abort();
					return false;
				}

				pPos += valSize;
				size += valSize;
			}
		}
	}

	*pSize = size;

	return true;
}
Example #2
0
// load the context information for the script system
static bool eventLoadContext(WzConfig &ini)
{
    SDWORD				numVars, numContext;
    SCRIPT_CONTEXT		*psCCont;
    SCR_VAL_LOAD		loadFunc;
    UDWORD				hashedName;
    SCRIPT_CODE			*psCode;
    CONTEXT_RELEASE			release;
    INTERP_VAL			*psVal, data;

    // get the number of contexts in the save file
    numContext = ini.value("general/contexts", 0).toInt();

    if (numContext == 0)
    {
        debug(LOG_FATAL, "No script contexts found -- failed to load script data");
        return false;
    }

    // go through the contexts
    for (int context = 0; context < numContext; context++)
    {
        ini.beginGroup("context_" + QString::number(context));
        hashedName = ini.value("context").toUInt();
        numVars = ini.value("numVars").toInt();
        release = (CONTEXT_RELEASE)ini.value("release").toInt();

        psCode = (SCRIPT_CODE*)resGetDataFromHash("SCRIPT", hashedName);

        // create the context
        if (!eventNewContext(psCode, release, &psCCont))
        {
            debug(LOG_FATAL, "Failed to create new context");
            return false;
        }
        if (numVars != psCode->numGlobals + psCode->arraySize)
        {
            ASSERT(false, "Context %d of %d: Number of context variables (%d) does not match the script code (%d)",
                   context, numContext, numVars, psCode->numGlobals + psCode->arraySize);
            return false;
        }

        // bit of a hack this - note the id of the context to link it to the triggers
        psContList->id = context;
        ini.beginGroup("var");

        // set the context variables
        for (int i = 0; i < numVars; i++)
        {
            ini.beginGroup(QString::number(i));
            // get the variable type
            INTERP_TYPE type = (INTERP_TYPE)ini.value("type").toInt();

            // get the variable value
            if (type < VAL_USERTYPESTART)
            {
                data.type = type;

                switch (type)
                {
                case VAL_BOOL:
                    data.v.bval = ini.value("data").toBool();
                    break;
                case VAL_FLOAT:
                    data.v.fval = ini.value("data").toFloat();
                    break;
                case VAL_INT:
                case VAL_TRIGGER:
                case VAL_EVENT:
                case VAL_VOID:
                case VAL_OPCODE:
                case VAL_PKOPCODE:
                    data.v.ival = ini.value("data").toInt();
                    break;
                case VAL_STRING:
                    data.v.sval = (char*)malloc(MAXSTRLEN);
                    strcpy(data.v.sval, ini.value("var/" + QString::number(i) + "/data").toString().toAscii().constData());
                    break;
                case VAL_OBJ_GETSET:
                case VAL_FUNC_EXTERN:
                    // do nothing
                    break;
                default:
                    ASSERT(false, "Invalid internal type");
                }

                // set the value in the context
                if (!eventSetContextVar(psCCont, i, &data))
                {
                    debug(LOG_FATAL, "Could not set variable value");
                    return false;
                }
            }
            else
            {
                // user defined type
                loadFunc = asScrTypeTab[type - VAL_USERTYPESTART].loadFunc;

                ASSERT(loadFunc, "No load function for type %d", type);

                // get the value pointer so that the loadFunc can write directly
                // into the variables data space.
                if (!eventGetContextVal(psCCont, i, &psVal))
                {
                    debug(LOG_FATAL, "Could not find variable %d in context %d", i, context);
                    return false;
                }
                if (!loadFunc(psVal, ini))
                {
                    debug(LOG_FATAL, "Could not get variable value context %d, variable %d", context, i);
                    return false;
                }
            }
            ini.endGroup();
        }
        ini.endGroup();
        ini.endGroup();
    }
    return true;
}