2 // Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "scripting/scripting.hpp"
20 #include <sqstdblob.h>
21 #include <sqstdmath.h>
22 #include <sqstdstring.h>
26 #include "physfs/ifile_stream.hpp"
27 #include "scripting/squirrel_error.hpp"
28 #include "scripting/wrapper.hpp"
29 #include "squirrel_util.hpp"
30 #include "supertux/console.hpp"
31 #include "util/log.hpp"
34 # include "../../external/squirrel/sqdbg/sqrdbg.h"
36 HSQREMOTEDBG debugger = NULL;
43 __attribute__((__format__ (__printf__, 2, 0)))
45 void printfunc(HSQUIRRELVM, const char* fmt, ...)
49 va_start(arglist, fmt);
50 vsnprintf(buf, sizeof(buf), fmt, arglist);
51 ConsoleBuffer::output << "[SQUIRREL] " << (const char*) buf << std::flush;
59 HSQUIRRELVM global_vm = NULL;
61 Scripting::Scripting(bool enable_debugger)
63 global_vm = sq_open(64);
65 throw std::runtime_error("Couldn't initialize squirrel vm");
69 sq_enabledebuginfo(global_vm, SQTrue);
70 debugger = sq_rdbg_init(global_vm, 1234, SQFalse);
72 throw SquirrelError(global_vm, "Couldn't initialize squirrel debugger");
74 sq_enabledebuginfo(global_vm, SQTrue);
75 log_info << "Waiting for debug client..." << std::endl;
76 if(SQ_FAILED(sq_rdbg_waitforconnections(debugger)))
77 throw SquirrelError(global_vm, "Waiting for debug clients failed");
78 log_info << "debug client connected." << std::endl;
82 sq_pushroottable(global_vm);
83 if(SQ_FAILED(sqstd_register_bloblib(global_vm)))
84 throw SquirrelError(global_vm, "Couldn't register blob lib");
85 if(SQ_FAILED(sqstd_register_mathlib(global_vm)))
86 throw SquirrelError(global_vm, "Couldn't register math lib");
87 if(SQ_FAILED(sqstd_register_stringlib(global_vm)))
88 throw SquirrelError(global_vm, "Couldn't register string lib");
90 // remove rand and srand calls from sqstdmath, we'll provide our own
91 sq_pushstring(global_vm, "srand", -1);
92 sq_deleteslot(global_vm, -2, SQFalse);
93 sq_pushstring(global_vm, "rand", -1);
94 sq_deleteslot(global_vm, -2, SQFalse);
96 // register supertux API
97 register_supertux_wrapper(global_vm);
101 // register print function
102 sq_setprintfunc(global_vm, printfunc, printfunc);
103 // register default error handlers
104 sqstd_seterrorhandlers(global_vm);
106 // try to load default script
108 std::string filename = "scripts/default.nut";
109 IFileStream stream(filename);
110 scripting::compile_and_run(global_vm, stream, filename);
111 } catch(std::exception& e) {
112 log_warning << "Couldn't load default.nut: " << e.what() << std::endl;
116 Scripting::~Scripting()
119 if(debugger != NULL) {
120 sq_rdbg_shutdown(debugger);
132 Scripting::update_debugger()
136 sq_rdbg_update(debugger);
140 } // namespace scripting