--- /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 */