Ejemplo n.º 1
0
bool getRGBIntoStack (unsigned int x, unsigned int y, stackHandler * sH) {
	if (x >= sceneWidth || y >= sceneHeight) {
		return fatal ("Co-ordinates are outside current scene!");
	}

	variable newValue;

	newValue.varType = SVT_NULL;

	saveTexture (backdropTextureName, backdropTexture);

	GLubyte * target;
	if (! NPOT_textures) {
		target = backdropTexture + 4*getNextPOT(sceneWidth)*y + x*4;
	} else {
		target = backdropTexture + 4*sceneWidth*y + x*4;
	}

	setVariable (newValue, SVT_INT, target[2]);
	if (! addVarToStackQuick (newValue, sH -> first)) return false;
	sH -> last = sH -> first;

	setVariable (newValue, SVT_INT, target[1]);
	if (! addVarToStackQuick (newValue, sH -> first)) return false;

	setVariable (newValue, SVT_INT, target[0]);
	if (! addVarToStackQuick (newValue, sH -> first)) return false;

	return true;
}
Ejemplo n.º 2
0
bool getSoundCacheStack (stackHandler * sH) {
	variable newFileHandle;
	newFileHandle.varType = SVT_NULL;

	for (int a = 0; a < MAX_SAMPLES; a ++) {
		if (soundCache[a].fileLoaded != -1) {
			setVariable (newFileHandle, SVT_FILE, soundCache[a].fileLoaded);
			if (! addVarToStackQuick (newFileHandle, sH -> first)) return false;
			if (sH -> last == NULL) sH -> last = sH -> first;
		}
	}
	return true;
}
Ejemplo n.º 3
0
bool fileToStack(const Common::String &filename, StackHandler *sH) {

	Variable stringVar;
	stringVar.varType = SVT_NULL;
	Common::String checker = saveEncoding ? "[Custom data (encoded)]\r\n" : "[Custom data (ASCII)]\n";

	Common::File fd;

	if (!fd.open(filename)) {
#if 0
		char currentDir[1000];
		if (!getcwd(currentDir, 998)) {
			debugOut("Can't get current directory.\n");
		}

		if (chdir(gamePath)) {
			debugOut("Error: Failed changing to directory %s\n", gamePath);
		}

		if (chdir(currentDir)) {
			debugOut("Error: Failed changing to directory %s\n", currentDir);
		}

		if (!fd.open(filename)) {
			return fatal("No such file", filename);
		}
#endif
		return fatal("No such file", filename); //TODO: false value
	}

	encode1 = (byte)saveEncoding & 255;
	encode2 = (byte)(saveEncoding >> 8);

	for (uint i = 0; i < checker.size(); ++i) {
		if (fd.readByte() != checker[i]) {
			fd.close();
			return fatal(LOAD_ERROR "This isn't a SLUDGE custom data file:", filename);
		}
	}

	if (saveEncoding) {
		checker = readStringEncoded(&fd);
		if (checker == UTF8_CHECKER) {
			fd.close();
			return fatal(
			LOAD_ERROR "The current file encoding setting does not match the encoding setting used when this file was created:", filename);
		}
	}

	for (;;) {
		if (saveEncoding) {
			char i = fd.readByte() ^ encode1;

			if (fd.eos())
				break;
			switch (i) {
				case 0: {
					Common::String g = readStringEncoded(&fd);
					makeTextVar(stringVar, g);
				}
					break;

				case 1:
					setVariable(stringVar, SVT_INT, fd.readUint32LE());
					break;

				case 2:
					setVariable(stringVar, SVT_INT, fd.readByte());
					break;

				default:
					fatal(LOAD_ERROR "Corrupt custom data file:", filename);
					fd.close();
					return false;
			}
		} else {
			char *line = readTextPlain(&fd);
			if (!line)
				break;
			makeTextVar(stringVar, line);
		}

		if (sH->first == NULL) {
			// Adds to the TOP of the array... oops!
			if (!addVarToStackQuick(stringVar, sH->first))
				return false;
			sH->last = sH->first;
		} else {
			// Adds to the END of the array... much better
			if (!addVarToStackQuick(stringVar, sH->last->next))
				return false;
			sH->last = sH->last->next;
		}
	}
	fd.close();

	return true;
}
Ejemplo n.º 4
0
bool continueFunction (loadedFunction * fun) {
	bool keepLooping = true;
	bool advanceNow;
	unsigned int param;
	sludgeCommand com;

	if (fun -> cancelMe) {
		abortFunction (fun);
		return true;
	}

//	if (numBIFNames) newDebug ("*** Function:", allUserFunc[fun -> originalNumber]);

	//debugOut ("SLUDGER: continueFunction\n");

	while (keepLooping) {
		advanceNow = true;
		param = fun -> compiledLines[fun -> runThisLine].param;
		com = fun -> compiledLines[fun -> runThisLine].theCommand;
//		fprintf (stderr, "com: %d param: %d (%s)\n", com, param,
//				(com < numSludgeCommands) ? sludgeText[com] : ERROR_UNKNOWN_MCODE); fflush(stderr);

		if (numBIFNames) {
			setFatalInfo (
				(fun -> originalNumber < numUserFunc) ? allUserFunc[fun -> originalNumber] : "Unknown user function",
				(com < numSludgeCommands) ? sludgeText[com] : ERROR_UNKNOWN_MCODE);
//			newDebug (
//				(com < numSludgeCommands) ? sludgeText[com] : "Unknown SLUDGE machine code",
//				param);
		}

		//debugOut ("SLUDGER: continueFunction - in da loop: %s\n", sludgeText[com]);

		switch (com) {
			case SLU_RETURN:
			if (fun -> calledBy) {
				loadedFunction * returnTo = fun -> calledBy;
				if (fun -> returnSomething) copyVariable (fun -> reg, returnTo -> reg);
				finishFunction (fun);
				fun = returnTo;
				restartFunction (fun);
			} else {
				finishFunction (fun);
				advanceNow = false;		// So we don't do anything else with "fun"
				keepLooping = false;	// So we drop out of the loop
			}
			break;

			case SLU_CALLIT:
			switch (fun -> reg.varType) {
				case SVT_FUNC:
				pauseFunction (fun);
				if (numBIFNames) setFatalInfo (
					(fun -> originalNumber < numUserFunc) ? allUserFunc[fun -> originalNumber] : "Unknown user function",
					(fun -> reg.varData.intValue < numUserFunc) ? allUserFunc[fun -> reg.varData.intValue] : "Unknown user function");

				if (! startNewFunctionNum (fun -> reg.varData.intValue, param, fun, fun -> stack)) return false;
				fun = allRunningFunctions;
				advanceNow = false;		// So we don't do anything else with "fun"
				break;

				case SVT_BUILT:
					{
					builtReturn br = callBuiltIn (fun -> reg.varData.intValue, param, fun);

					switch (br) {
						case BR_ERROR:
							return fatal("Unknown error. This shouldn't happen. Please notify the SLUDGE developers.");

						case BR_PAUSE:
						pauseFunction (fun);
						// No break!

						case BR_KEEP_AND_PAUSE:
						keepLooping = false;
						break;

						case BR_ALREADY_GONE:
						keepLooping = false;
						advanceNow = false;
						break;

						case BR_CALLAFUNC:
						{
							int i = fun -> reg.varData.intValue;
							setVariable (fun -> reg, SVT_INT, 1);
							pauseFunction (fun);
							if (numBIFNames) setFatalInfo (
								(fun -> originalNumber < numUserFunc) ? allUserFunc[fun -> originalNumber] : "Unknown user function",
								(i < numUserFunc) ? allUserFunc[i] : "Unknown user function");
							if (! startNewFunctionNum (i, 0, fun, noStack, false)) return false;
							fun = allRunningFunctions;
							advanceNow = false;		// So we don't do anything else with "fun"
						}
						break;

						default:
						break;
					}
				}
				break;

				default:
				return fatal (ERROR_CALL_NONFUNCTION);
			}
			break;

			// These all grab things and shove 'em into the register

			case SLU_LOAD_NULL:
			setVariable (fun -> reg, SVT_NULL, 0);
			break;

			case SLU_LOAD_FILE:
			setVariable (fun -> reg, SVT_FILE, param);
			break;

			case SLU_LOAD_VALUE:
			setVariable (fun -> reg, SVT_INT, param);
			break;

			case SLU_LOAD_LOCAL:
			if (! copyVariable (fun -> localVars[param], fun -> reg)) return false;
			break;

			case SLU_AND:
			setVariable (fun -> reg, SVT_INT, getBoolean (fun -> reg) && getBoolean (fun -> stack -> thisVar));
			trimStack (fun -> stack);
			break;

			case SLU_OR:
			setVariable (fun -> reg, SVT_INT, getBoolean (fun -> reg) || getBoolean (fun -> stack -> thisVar));
			trimStack (fun -> stack);
			break;

			case SLU_LOAD_FUNC:
			setVariable (fun -> reg, SVT_FUNC, param);
			break;

			case SLU_LOAD_BUILT:
			setVariable (fun -> reg, SVT_BUILT, param);
			break;

			case SLU_LOAD_OBJTYPE:
			setVariable (fun -> reg, SVT_OBJTYPE, param);
			break;

			case SLU_UNREG:
			if (dialogValue != 1) fatal (ERROR_HACKER);
			break;

			case SLU_LOAD_STRING:
				if (! loadStringToVar (fun -> reg, param)) {
					return false;
				}
			break;

			case SLU_INDEXGET:
			case SLU_INCREMENT_INDEX:
			case SLU_DECREMENT_INDEX:
			switch (fun -> stack -> thisVar.varType) {
				case SVT_NULL:
				if (com == SLU_INDEXGET) {
					setVariable (fun -> reg, SVT_NULL, 0);
					trimStack (fun -> stack);
				} else {
					return fatal (ERROR_INCDEC_UNKNOWN);
				}
				break;

				case SVT_FASTARRAY:
				case SVT_STACK:
				if (fun -> stack -> thisVar.varData.theStack -> first == NULL) {
					return fatal (ERROR_INDEX_EMPTY);
				} else {
					int ii;
					if (! getValueType (ii, SVT_INT, fun -> reg)) return false;
					variable * grab = (fun -> stack -> thisVar.varType == SVT_FASTARRAY) ?
						fastArrayGetByIndex (fun -> stack -> thisVar.varData.fastArray, ii)
							:
						stackGetByIndex (fun -> stack -> thisVar.varData.theStack -> first, ii);

					trimStack (fun -> stack);

					if (! grab) {
						setVariable (fun -> reg, SVT_NULL, 0);
					} else {
						int ii;
						switch (com) {
							case SLU_INCREMENT_INDEX:
							if (! getValueType (ii, SVT_INT, * grab)) return false;
							setVariable (fun -> reg, SVT_INT, ii);
							grab -> varData.intValue = ii + 1;
							break;

							case SLU_DECREMENT_INDEX:
							if (! getValueType (ii, SVT_INT, * grab)) return false;
							setVariable (fun -> reg, SVT_INT, ii);
							grab -> varData.intValue = ii - 1;
							break;

							default:
							if (! copyVariable (* grab, fun -> reg)) return false;
						}
					}
				}
				break;

				default:
				return fatal (ERROR_INDEX_NONSTACK);
			}
			break;

			case SLU_INDEXSET:
			switch (fun -> stack -> thisVar.varType) {
				case SVT_STACK:
				if (fun -> stack -> thisVar.varData.theStack -> first == NULL) {
					return fatal (ERROR_INDEX_EMPTY);
				} else {
					int ii;
					if (! getValueType (ii, SVT_INT, fun -> reg)) return false;
					if (! stackSetByIndex (fun -> stack -> thisVar.varData.theStack -> first, ii, fun -> stack -> next -> thisVar)) {
						return false;
					}
					trimStack (fun -> stack);
					trimStack (fun -> stack);
				}
				break;

				case SVT_FASTARRAY:
				{
					int ii;
					if (! getValueType (ii, SVT_INT, fun -> reg)) return false;
					variable * v = fastArrayGetByIndex (fun -> stack -> thisVar.varData.fastArray, ii);
					if (v == NULL) return fatal ("Not within bounds of fast array.");
					if (! copyVariable (fun -> stack -> next -> thisVar, * v)) return false;
					trimStack (fun -> stack);
					trimStack (fun -> stack);
				}
				break;

				default:
				return fatal (ERROR_INDEX_NONSTACK);
			}
			break;

			// What can we do with the register? Well, we can copy it into a local
			// variable, a global or onto the stack...

			case SLU_INCREMENT_LOCAL:
			{
				int ii;
				if (! getValueType (ii, SVT_INT, fun -> localVars[param])) return false;
				setVariable (fun -> reg, SVT_INT, ii);
				setVariable (fun -> localVars[param], SVT_INT, ii + 1);
			}
			break;

			case SLU_INCREMENT_GLOBAL:
			{
				int ii;
				if (! getValueType (ii, SVT_INT, globalVars[param])) return false;
				setVariable (fun -> reg, SVT_INT, ii);
				setVariable (globalVars[param], SVT_INT, ii + 1);
			}
			break;

			case SLU_DECREMENT_LOCAL:
			{
				int ii;
				if (! getValueType (ii, SVT_INT, fun -> localVars[param])) return false;
				setVariable (fun -> reg, SVT_INT, ii);
				setVariable (fun -> localVars[param], SVT_INT, ii - 1);
			}
			break;

			case SLU_DECREMENT_GLOBAL:
			{
				int ii;
				if (! getValueType (ii, SVT_INT, globalVars[param])) return false;
				setVariable (fun -> reg, SVT_INT, ii);
				setVariable (globalVars[param], SVT_INT, ii - 1);
			}
			break;

			case SLU_SET_LOCAL:
			if (! copyVariable (fun -> reg, fun -> localVars[param])) return false;
			break;

			case SLU_SET_GLOBAL:
//			newDebug ("  Copying TO global variable", param);
//			newDebug ("  Global type at the moment", globalVars[param].varType);
			if (! copyVariable (fun -> reg, globalVars[param])) return false;
//			newDebug ("  New type", globalVars[param].varType);
			break;

			case SLU_LOAD_GLOBAL:
//			newDebug ("  Copying FROM global variable", param);
//			newDebug ("  Global type at the moment", globalVars[param].varType);
			if (! copyVariable (globalVars[param], fun -> reg)) return false;
			break;

			case SLU_STACK_PUSH:
			if (! addVarToStack (fun -> reg, fun -> stack)) return false;
			break;

			case SLU_QUICK_PUSH:
			if (! addVarToStackQuick (fun -> reg, fun -> stack)) return false;
			break;

			case SLU_NOT:
			setVariable (fun -> reg, SVT_INT, ! getBoolean (fun -> reg));
			break;

			case SLU_BR_ZERO:
			if (! getBoolean (fun -> reg)) {
				advanceNow = false;
				fun -> runThisLine = param;
			}
			break;

			case SLU_BRANCH:
			advanceNow = false;
			fun -> runThisLine = param;
			break;

			case SLU_NEGATIVE:
			{
				int i;
				if (! getValueType (i, SVT_INT, fun -> reg)) return false;
				setVariable (fun -> reg, SVT_INT, -i);
			}
			break;

			// All these things rely on there being somet' on the stack

			case SLU_MULT:
			case SLU_PLUS:
			case SLU_MINUS:
			case SLU_MODULUS:
			case SLU_DIVIDE:
			case SLU_EQUALS:
			case SLU_NOT_EQ:
			case SLU_LESSTHAN:
			case SLU_MORETHAN:
			case SLU_LESS_EQUAL:
			case SLU_MORE_EQUAL:
			if (fun -> stack) {
				int firstValue, secondValue;

				switch (com) {
					case SLU_PLUS:
					addVariablesInSecond (fun -> stack -> thisVar, fun -> reg);
					trimStack (fun -> stack);
					break;

					case SLU_EQUALS:
					compareVariablesInSecond (fun -> stack -> thisVar, fun -> reg);
					trimStack (fun -> stack);
					break;

					case SLU_NOT_EQ:
					compareVariablesInSecond (fun -> stack -> thisVar, fun -> reg);
					trimStack (fun -> stack);
	               fun -> reg.varData.intValue = ! fun -> reg.varData.intValue;
					break;

					default:
					if (! getValueType (firstValue, SVT_INT, fun -> stack -> thisVar)) return false;
					if (! getValueType (secondValue, SVT_INT, fun -> reg)) return false;
					trimStack (fun -> stack);

					switch (com) {
						case SLU_MULT:
						setVariable (fun -> reg, SVT_INT, firstValue * secondValue);
						break;

						case SLU_MINUS:
						setVariable (fun -> reg, SVT_INT, firstValue - secondValue);
						break;

						case SLU_MODULUS:
						setVariable (fun -> reg, SVT_INT, firstValue % secondValue);
						break;

						case SLU_DIVIDE:
						setVariable (fun -> reg, SVT_INT, firstValue / secondValue);
						break;

						case SLU_LESSTHAN:
						setVariable (fun -> reg, SVT_INT, firstValue < secondValue);
						break;

						case SLU_MORETHAN:
						setVariable (fun -> reg, SVT_INT, firstValue > secondValue);
						break;

						case SLU_LESS_EQUAL:
						setVariable (fun -> reg, SVT_INT, firstValue <= secondValue);
						break;

						case SLU_MORE_EQUAL:
						setVariable (fun -> reg, SVT_INT, firstValue >= secondValue);
						break;

						default:
						break;
					}
				}
			} else {
				return fatal (ERROR_NOSTACK);
			}
			break;

			default:
			return fatal (ERROR_UNKNOWN_CODE);
		}

		if (advanceNow) fun -> runThisLine ++;

	}
	return true;
}