(svn r9151) [NoAI] -Add: added squirrel module that loads squirrel scripts and noai
authortruelight
Tue, 13 Mar 2007 21:55:22 +0000
branchnoai
changeset 9365 c3d08e0b1083
parent 9364 dde316c28f1d
child 9366 d30036300fe7
(svn r9151) [NoAI] -Add: added squirrel module that loads squirrel scripts and
executes them. For now it only spams the consule with "gameLoop"
bin/ai/SQNoAI/main.sq
projects/openttd.vcproj
projects/openttd_vs80.vcproj
source.list
src/ai/core/ai.cpp
src/ai/squirrel/squirrel.cpp
src/ai/squirrel/squirrel.hpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/ai/SQNoAI/main.sq	Tue Mar 13 21:55:22 2007 +0000
@@ -0,0 +1,6 @@
+function gameLoop()
+{
+	print("gameLoop");
+}
+
+print("Called init");
--- a/projects/openttd.vcproj	Tue Mar 13 21:41:05 2007 +0000
+++ b/projects/openttd.vcproj	Tue Mar 13 21:55:22 2007 +0000
@@ -921,6 +921,12 @@
 			<File
 				RelativePath=".\..\src\ai\NoAI\NoAI.hpp">
 			</File>
+			<File
+				RelativePath=".\..\src\ai\squirrel\squirrel.cpp">
+			</File>
+			<File
+				RelativePath=".\..\src\ai\squirrel\squirrel.hpp">
+			</File>
 		</Filter>
 		<Filter
 			Name="NewGRF"
--- a/projects/openttd_vs80.vcproj	Tue Mar 13 21:41:05 2007 +0000
+++ b/projects/openttd_vs80.vcproj	Tue Mar 13 21:55:22 2007 +0000
@@ -1451,6 +1451,14 @@
 				RelativePath=".\..\src\ai\NoAI\NoAI.hpp"
 				>
 			</File>
+			<File
+				RelativePath=".\..\src\ai\squirrel\squirrel.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\..\src\ai\squirrel\squirrel.hpp"
+				>
+			</File>
 		</Filter>
 		<Filter
 			Name="NewGRF"
--- a/source.list	Tue Mar 13 21:41:05 2007 +0000
+++ b/source.list	Tue Mar 13 21:55:22 2007 +0000
@@ -277,6 +277,8 @@
 ai/core/object/commands.cpp
 ai/NoAI/NoAI.cpp
 ai/NoAI/NoAI.hpp
+ai/squirrel/squirrel.cpp
+ai/squirrel/squirrel.hpp
 
 # NewGRF
 newgrf.cpp
--- a/src/ai/core/ai.cpp	Tue Mar 13 21:41:05 2007 +0000
+++ b/src/ai/core/ai.cpp	Tue Mar 13 21:55:22 2007 +0000
@@ -10,7 +10,7 @@
 #include "../../helpers.hpp"
 #include "ai.h"
 #include "ai_base.hpp"
-#include "../NoAI/NoAI.hpp"
+#include "../squirrel/squirrel.hpp"
 
 static AIController *_ai_player[MAX_PLAYERS];
 static uint _ai_frame_counter;
@@ -73,7 +73,7 @@
 	if (_networking && !_network_server) return;
 
 	/* Called if a new AI is booted */
-	_ai_player[player] = new NoAI();
+	_ai_player[player] = new Squirrel("SQNoAI");
 }
 
 /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/squirrel/squirrel.cpp	Tue Mar 13 21:55:22 2007 +0000
@@ -0,0 +1,89 @@
+/* $Id$ */
+
+/** @file squirrel.cpp allows loading squirrel scripts to control an AI */
+
+#include "squirrel.hpp"
+#include <sqstdio.h>
+#include <sqstdaux.h>
+#include <stdarg.h>
+#include "../../debug.h"
+
+/**
+ * Here we handle errors that come from squirrel.
+ */
+static void Squirrel_PrintError(HSQUIRRELVM vm, const SQChar *desc, const SQChar *source, SQInteger line, SQInteger column)
+{
+#ifdef _SQ64
+	printf("Error %s:%ld/%ld: %s\n", source, line, column, desc);
+#else
+	printf("Error %s:%d/%d: %s\n", source, line, column, desc);
+#endif
+}
+
+/**
+ * Here we handle 'print' command within squirrel script.
+ */
+static void Squirrel_PrintFunc(HSQUIRRELVM vm, const SQChar *s, ...)
+{
+	va_list arglist;
+	va_start(arglist, s);
+	vprintf(s, arglist);
+	va_end(arglist);
+	printf("\n");
+}
+
+Squirrel::Squirrel(const char *script_dir)
+{
+	char filename[1024];
+
+	this->vm = sq_open(1024);
+
+	/* Handle compile-errors ourself, so we can display it nicely */
+	sq_seterrorhandler(this->vm);
+	sq_setcompilererrorhandler(this->vm, Squirrel_PrintError);
+	sq_notifyallexceptions(this->vm, SQTrue);
+	/* Set a good print-function */
+	sq_setprintfunc(this->vm, Squirrel_PrintFunc);
+
+	/* TODO -- This is ugly! */
+	strcpy(filename, "ai/");
+	strcat(filename, script_dir);
+	strcat(filename, PATHSEP);
+	strcat(filename, "main.sq");
+
+	DEBUG(ai, 1, "[squirrel] Starting AI with script in '%s'", filename);
+
+	/* Load and run the script */
+	sq_pushroottable(this->vm);
+	if (!SQ_SUCCEEDED(sqstd_dofile(this->vm, filename, SQFalse, SQTrue))) {
+		DEBUG(ai, 0, "[squirrel] Failed to compile '%s'", filename);
+		return;
+	}
+}
+
+Squirrel::~Squirrel()
+{
+	/* Clean up the stuff */
+	sq_pop(this->vm, 1);
+	sq_close(this->vm);
+}
+
+/* virtual */ void Squirrel::GameLoop()
+{
+	/* Store the current top */
+	int top = sq_gettop(this->vm);
+	/* Go back to root-table */
+	sq_pushroottable(this->vm);
+	/* Find the function-name inside the script */
+	sq_pushstring(this->vm,_SC("gameLoop"), -1);
+	if (!SQ_SUCCEEDED(sq_get(this->vm, -2))) {
+		DEBUG(ai, 0, "[squirrel] Failed to run gameLoop");
+		sq_settop(this->vm, top);
+		return;
+	}
+	/* Call the function */
+	sq_pushroottable(this->vm);
+	sq_call(this->vm, 1, 0, 0);
+	/* Reset the top */
+	sq_settop(this->vm, top);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/squirrel/squirrel.hpp	Tue Mar 13 21:55:22 2007 +0000
@@ -0,0 +1,23 @@
+/* $Id$ */
+
+/** @file squirrel.hpp declarations of the class for squirrel loader */
+
+#ifndef SQUIRREL_HPP
+#define SQUIRREL_HPP
+
+#include "../core/ai_controller.hpp"
+#include "../core/ai_base.hpp"
+#include <squirrel.h>
+
+class Squirrel: public AIController {
+private:
+	HSQUIRRELVM vm;  ///< The Virtual Machine for squirrel
+
+public:
+	Squirrel(const char *script_dir);
+	~Squirrel();
+
+	/* virtual */ void GameLoop();
+};
+
+#endif /* SQUIRREL_HPP */