bool getSavedGamesStack (stackHandler * sH, char * ext) {
	char * pattern = joinStrings ("*", ext);
	if (! pattern) return false;

	variable newName;
	newName.varType = SVT_NULL;

#ifdef _WIN32

    WCHAR *w_pattern = ConvertToUTF16(pattern);

	WIN32_FIND_DATA theData;
	HANDLE handle = FindFirstFile (w_pattern, & theData);

    delete w_pattern;

	if (handle != INVALID_HANDLE_VALUE) {
		bool keepGoing;
		do {
			theData.cFileName[lstrlen (theData.cFileName) - strlen (ext)] = TEXT('\0');
			char * fileName = ConvertFromUTF16(theData.cFileName);
			char * decoded = decodeFilename (fileName);
			makeTextVar (newName, decoded);
			delete fileName;
			delete decoded;
			if (! addVarToStack (newName, sH -> first)) return false;
			if (sH -> last == NULL) sH -> last = sH -> first;
			keepGoing = FindNextFile (handle, & theData);
		} while (keepGoing);
		FindClose (handle);
	}

#else

		DIR * dir = opendir (".");
		if (! dir) return false;

		struct dirent *d = readdir (dir);
		while (d != NULL) {
			if (! strcmp(d->d_name + strlen (d->d_name) - strlen (ext), ext)) {
				d->d_name[strlen (d->d_name) - strlen (ext)] = 0;
				char * decoded = decodeFilename (d->d_name);
				makeTextVar (newName, decoded);
				delete[] decoded;
				if (! addVarToStack (newName, sH -> first)) return false;
				if (sH -> last == NULL) sH -> last = sH -> first;
			}

			d = readdir (dir);
		}


		closedir (dir);

#endif

	delete[] pattern;
	pattern = NULL;
	return true;
}
Beispiel #2
0
bool getSavedGamesStack(StackHandler *sH, const Common::String &ext) {

	// Make pattern
	uint len = ext.size();
	Common::String pattern = "*";
	pattern += ext;

	// Get all saved files
	Common::StringArray sa = g_system->getSavefileManager()->listSavefiles(pattern);

	// Save file names to stacks
	Variable newName;
	newName.varType = SVT_NULL;
	Common::StringArray::iterator it;
	for (it = sa.begin(); it != sa.end(); ++it) {
		(*it).erase((*it).size() - len, len);
		makeTextVar(newName, (*it));
		if (!addVarToStack(newName, sH->first))
			return false;
		if (sH->last == NULL)
			sH->last = sH->first;
	}

	return true;
}
bool copyStack (const variable & from, variable & to) {
	to.varType = SVT_STACK;
	to.varData.theStack = new stackHandler;
	if (! checkNew (to.varData.theStack)) return false;
	to.varData.theStack -> first = NULL;
	to.varData.theStack -> last = NULL;
	to.varData.theStack -> timesUsed = 1;
	variableStack * a = from.varData.theStack -> first;

#if DEBUG_STACKINESS
	{
		char * str = getTextFromAnyVar(from);
		stackDebug((stackfp, "in copyStack, copying %s\n", str));
		delete[] str;
	}
#endif

	while (a) {
		addVarToStack (a -> thisVar, to.varData.theStack -> first);
		if (to.varData.theStack -> last == NULL)
		{
#if DEBUG_STACKINESS
			stackDebug((stackfp, "LAST"));
#endif
			to.varData.theStack -> last = to.varData.theStack -> first;
		}

#if DEBUG_STACKINESS
		{
			char * str = getTextFromAnyVar(a->thisVar);
			stackDebug((stackfp, "\ta->thisVar = %s (%p)\n", str, to.varData.theStack->first));
			delete[] str;
		}
#endif

		a = a -> next;
	}

#if DEBUG_STACKINESS
	{
		char * str = getTextFromAnyVar(to);
		stackDebug((stackfp, "finished copy, got %s\n", str));
		delete[] str;
		stackDebug((stackfp, "first = %p\n", to.varData.theStack->first));
		stackDebug((stackfp, "last = %p\n", to.varData.theStack->last));
	}
#endif
	return true;
}
Beispiel #4
0
bool copyStack(const Variable &from, Variable &to) {
	to.varType = SVT_STACK;
	to.varData.theStack = new StackHandler;
	if (!checkNew(to.varData.theStack))
		return false;
	to.varData.theStack->first = NULL;
	to.varData.theStack->last = NULL;
	to.varData.theStack->timesUsed = 1;
	VariableStack *a = from.varData.theStack->first;

	while (a) {
		addVarToStack(a->thisVar, to.varData.theStack->first);
		if (to.varData.theStack->last == NULL) {
			to.varData.theStack->last = to.varData.theStack->first;
		}
		a = a->next;
	}

	return true;
}
Beispiel #5
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;
}