summaryrefslogtreecommitdiff
path: root/src/script
diff options
context:
space:
mode:
authortruebrain <truebrain@openttd.org>2011-12-19 21:05:57 +0000
committertruebrain <truebrain@openttd.org>2011-12-19 21:05:57 +0000
commitb0ac529a6ff4e087520a14d2a0169f445952e7e0 (patch)
treef545f15ff52b6c1ad6279f7e028f2a058465d672 /src/script
parent2ae87e72131a8e88327dbb0b5b286accddafe05d (diff)
downloadopenttd-b0ac529a6ff4e087520a14d2a0169f445952e7e0.tar.xz
(svn r23635) -Add: introduce GSText, to allow translating GameScript text, even over network
Diffstat (limited to 'src/script')
-rw-r--r--src/script/api/game/game_text.hpp.sq31
-rw-r--r--src/script/api/script_text.cpp167
-rw-r--r--src/script/api/script_text.hpp134
-rw-r--r--src/script/api/squirrel_export.awk15
-rw-r--r--src/script/api/template/template_text.hpp.sq30
5 files changed, 376 insertions, 1 deletions
diff --git a/src/script/api/game/game_text.hpp.sq b/src/script/api/game/game_text.hpp.sq
new file mode 100644
index 000000000..d43506580
--- /dev/null
+++ b/src/script/api/game/game_text.hpp.sq
@@ -0,0 +1,31 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
+
+#include "../script_text.hpp"
+#include "../template/template_text.hpp.sq"
+
+
+template <> const char *GetClassName<ScriptText, ST_GS>() { return "GSText"; }
+
+void SQGSText_Register(Squirrel *engine)
+{
+ DefSQClass<ScriptText, ST_GS> SQGSText("GSText");
+ SQGSText.PreRegister(engine);
+ SQGSText.AddConstructor<void (ScriptText::*)(StringID string), 2>(engine, "xi");
+
+ SQGSText.DefSQConst(engine, ScriptText::SCRIPT_TEXT_MAX_PARAMETERS, "SCRIPT_TEXT_MAX_PARAMETERS");
+
+ SQGSText.DefSQAdvancedMethod(engine, &ScriptText::_set, "_set");
+ SQGSText.DefSQAdvancedMethod(engine, &ScriptText::SetParam, "SetParam");
+ SQGSText.DefSQAdvancedMethod(engine, &ScriptText::AddParam, "AddParam");
+
+ SQGSText.PostRegister(engine);
+}
diff --git a/src/script/api/script_text.cpp b/src/script/api/script_text.cpp
new file mode 100644
index 000000000..10120bcde
--- /dev/null
+++ b/src/script/api/script_text.cpp
@@ -0,0 +1,167 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file script_text.cpp Implementation of ScriptText. */
+
+#include "../../stdafx.h"
+#include "../../string_func.h"
+#include "script_text.hpp"
+#include "../squirrel.hpp"
+#include "../../table/control_codes.h"
+
+ScriptText::ScriptText(StringID string) :
+ ZeroedMemoryAllocator(),
+ string(string)
+{
+}
+
+ScriptText::~ScriptText()
+{
+ for (int i = 0; i < SCRIPT_TEXT_MAX_PARAMETERS; i++) {
+ free(this->params[i]);
+ if (this->paramt[i] != NULL) this->paramt[i]->Release();
+ }
+}
+
+SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm)
+{
+ if (parameter >= SCRIPT_TEXT_MAX_PARAMETERS) return SQ_ERROR;
+
+ free(this->params[parameter]);
+ if (this->paramt[parameter] != NULL) this->paramt[parameter]->Release();
+
+ this->parami[parameter] = 0;
+ this->params[parameter] = NULL;
+ this->paramt[parameter] = NULL;
+
+ switch (sq_gettype(vm, -1)) {
+ case OT_STRING: {
+ const SQChar *value;
+ sq_getstring(vm, -1, &value);
+
+ this->params[parameter] = strdup(SQ2OTTD(value));
+ break;
+ }
+
+ case OT_INTEGER: {
+ SQInteger value;
+ sq_getinteger(vm, -1, &value);
+
+ this->parami[parameter] = value;
+ break;
+ }
+
+ case OT_INSTANCE: {
+ SQUserPointer real_instance = NULL;
+ HSQOBJECT instance;
+
+ sq_getstackobj(vm, -1, &instance);
+
+ /* Validate if it is a GSText instance */
+ sq_pushroottable(vm);
+ sq_pushstring(vm, _SC("GSText"), -1);
+ sq_get(vm, -2);
+ sq_pushobject(vm, instance);
+ if (sq_instanceof(vm) != SQTrue) return SQ_ERROR;
+ sq_pop(vm, 3);
+
+ /* Get the 'real' instance of this class */
+ sq_getinstanceup(vm, -1, &real_instance, 0);
+ if (real_instance == NULL) return SQ_ERROR;
+
+ ScriptText *value = static_cast<ScriptText *>(real_instance);
+ value->AddRef();
+ this->paramt[parameter] = value;
+ break;
+ }
+
+ default: return SQ_ERROR;
+ }
+
+ if (this->paramc <= parameter) this->paramc = parameter + 1;
+ return 0;
+}
+
+SQInteger ScriptText::SetParam(HSQUIRRELVM vm)
+{
+ if (sq_gettype(vm, 2) != OT_INTEGER) return SQ_ERROR;
+
+ SQInteger k;
+ sq_getinteger(vm, 2, &k);
+
+ if (k > SCRIPT_TEXT_MAX_PARAMETERS) return SQ_ERROR;
+ if (k < 1) return SQ_ERROR;
+ k--;
+
+ return this->_SetParam(k, vm);
+}
+
+SQInteger ScriptText::AddParam(HSQUIRRELVM vm)
+{
+ SQInteger res;
+ res = this->_SetParam(this->paramc, vm);
+ if (res != 0) return res;
+
+ /* Push our own instance back on top of the stack */
+ sq_push(vm, 1);
+ return 1;
+}
+
+SQInteger ScriptText::_set(HSQUIRRELVM vm)
+{
+ int32 k;
+
+ if (sq_gettype(vm, 2) == OT_STRING) {
+ const SQChar *key;
+ sq_getstring(vm, 2, &key);
+ const char *key_string = SQ2OTTD(key);
+
+ if (strncmp(key_string, "param_", 6) != 0 || strlen(key_string) > 8) return SQ_ERROR;
+ k = atoi(key_string + 6);
+ } else if (sq_gettype(vm, 2) == OT_INTEGER) {
+ SQInteger key;
+ sq_getinteger(vm, 2, &key);
+ k = (int32)key;
+ } else {
+ return SQ_ERROR;
+ }
+
+ if (k > SCRIPT_TEXT_MAX_PARAMETERS) return SQ_ERROR;
+ if (k < 1) return SQ_ERROR;
+ k--;
+
+ return this->_SetParam(k, vm);
+}
+
+const char *ScriptText::GetEncodedText()
+{
+ static char buf[1024];
+ this->_GetEncodedText(buf, lastof(buf));
+ return buf;
+}
+
+char *ScriptText::_GetEncodedText(char *p, char *lastofp)
+{
+ p += Utf8Encode(p, SCC_ENCODED);
+ p += seprintf(p, lastofp, "%X", this->string);
+ for (int i = 0; i < this->paramc; i++) {
+ if (this->params[i] != NULL) {
+ p += seprintf(p, lastofp, ":\"%s\"", this->params[i]);
+ continue;
+ }
+ if (this->paramt[i] != NULL) {
+ p += seprintf(p, lastofp, ":");
+ p = this->paramt[i]->_GetEncodedText(p, lastofp);
+ continue;
+ }
+ p += seprintf(p, lastofp,":%X", this->parami[i]);
+ }
+
+ return p;
+}
diff --git a/src/script/api/script_text.hpp b/src/script/api/script_text.hpp
new file mode 100644
index 000000000..9f994e1f3
--- /dev/null
+++ b/src/script/api/script_text.hpp
@@ -0,0 +1,134 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/** @file script_text.hpp Everything to handle text which can be translated. */
+
+#ifndef SCRIPT_TEXT_HPP
+#define SCRIPT_TEXT_HPP
+
+#include "script_object.hpp"
+#include "../../core/alloc_type.hpp"
+
+/**
+ * Internal parent object of all Text-like objects.
+ * @api -all
+ */
+class Text : public ScriptObject {
+public:
+ /**
+ * Convert a ScriptText to a normal string.
+ * @return A string (in a static buffer), or NULL.
+ * @api -all
+ */
+ virtual const char *GetEncodedText() = 0;
+};
+
+/**
+ * Interal used class to create a raw text in a Text object.
+ * @api -all
+ */
+class RawText : public Text {
+public:
+ RawText(const char *text) :
+ text(strdup(text)) {}
+ ~RawText() { free(this->text); }
+
+ /* virtual */ const char *GetEncodedText() { return this->text; }
+private:
+ const char *text;
+};
+
+/**
+ * Class that handles all text related functions. You can define a language
+ * file in lang/english.txt, in the same format as OpenTTD does, including
+ * tags like {BLACK}, {STRING1} etc. The name given to this string is made
+ * available to you in ScriptText, for example: ScriptText.STR_NEWS, if your
+ * english.txt contains: STR_NEWS :{BLACK}Welcome {COMPANY}!
+ *
+ * In translation files like lang/dutch.txt you can then translate such
+ * strings, like: STR_NEWS :{BLACK}Hallo {COMPANY}!
+ * When the user has the dutch language selected, it will automatically use
+ * the translated string when available. The fallback language is always
+ * the english language.
+ *
+ * If you use parameters in your strings, you will have to define those
+ * parameters, for example like this:
+ * local text = ScriptText(ScriptText.STR_NEWS); text.AddParam(1);
+ * This will set the {COMPANY} to the name of Company 1.
+ *
+ * @api game
+ */
+class ScriptText : public Text , public ZeroedMemoryAllocator {
+public:
+ static const int SCRIPT_TEXT_MAX_PARAMETERS = 20; ///< The maximum amount of parameters you can give to one object.
+
+ /**
+ * Generate a text from string. You can set parameters to the instance which
+ * can be required for the string.
+ * @param string The string of the text.
+ */
+ ScriptText(StringID string);
+ ~ScriptText();
+
+#ifndef DOXYGEN_API
+ /**
+ * Used for .param_N and [] set from Squirrel.
+ */
+ SQInteger _set(HSQUIRRELVM vm);
+
+ /**
+ * Set the parameter.
+ */
+ SQInteger SetParam(HSQUIRRELVM vm);
+
+ /**
+ * Add an parameter
+ */
+ SQInteger AddParam(HSQUIRRELVM vm);
+#else
+ /**
+ * Set the parameter to a value.
+ * @param parameter Which parameter t oset.
+ * @param value The value of the parameter. Has to be string, integer or an instance of the class ScriptText.
+ */
+ void SetParam(int parameter, Object value);
+
+ /**
+ * Add a value as parameter (appending it).
+ * @param value The value of the parameter. Has to be string, integer or an instance of the class ScriptText.
+ * @return The same object as on which this is called, so you can chain.
+ */
+ ScriptText *AddParam(Object value);
+#endif /* DOXYGEN_API */
+
+ /* virtual */ const char *GetEncodedText();
+
+private:
+ StringID string;
+ char *params[SCRIPT_TEXT_MAX_PARAMETERS];
+ int parami[SCRIPT_TEXT_MAX_PARAMETERS];
+ ScriptText *paramt[SCRIPT_TEXT_MAX_PARAMETERS];
+ int paramc;
+
+ /**
+ * Internal function for recursive calling this function over multiple
+ * instances, while writing in the same buffer.
+ * @param p The current position in the buffer.
+ * @param lastofp The last position valid in the buffer.
+ * @return The new current position in the buffer.
+ */
+ char *_GetEncodedText(char *p, char *lastofp);
+
+ /**
+ * Set a parameter, where the value is the first item on the stack.
+ */
+ SQInteger _SetParam(int k, HSQUIRRELVM vm);
+};
+
+#endif /* SCRIPT_TEXT_HPP */
diff --git a/src/script/api/squirrel_export.awk b/src/script/api/squirrel_export.awk
index ed190deaf..cb9774db7 100644
--- a/src/script/api/squirrel_export.awk
+++ b/src/script/api/squirrel_export.awk
@@ -35,6 +35,17 @@ function dump_class_templates(name)
print " template <> inline const " name " &GetParam(ForceType<const " name " &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(" name " *)instance; }"
if (name == "ScriptEvent") {
print " template <> inline int Return<" name " *>(HSQUIRRELVM vm, " name " *res) { if (res == NULL) { sq_pushnull(vm); return 1; } Squirrel::CreateClassInstanceVM(vm, \"" realname "\", res, NULL, DefSQDestructorCallback<" name ">, true); return 1; }"
+ } else if (name == "ScriptText") {
+ print ""
+ print " template <> inline Text *GetParam(ForceType<Text *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) {"
+ print " if (sq_gettype(vm, index) == OT_INSTANCE) {"
+ print " return GetParam(ForceType<ScriptText *>(), vm, index, ptr);"
+ print " }"
+ print " if (sq_gettype(vm, index) == OT_STRING) {"
+ print " return new RawText(GetParam(ForceType<const char *>(), vm, index, ptr));"
+ print " }"
+ print " return NULL;"
+ print " }"
} else {
print " template <> inline int Return<" name " *>(HSQUIRRELVM vm, " name " *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, \"" realname "\", res, NULL, DefSQDestructorCallback<" name ">, true); return 1; }"
}
@@ -324,7 +335,7 @@ BEGIN {
print "void SQ" api_cls "_Register(Squirrel *engine)"
print "{"
print " DefSQClass<" cls ", ST_" toupper(api) "> SQ" api_cls "(\"" api_cls "\");"
- if (super_cls == "ScriptObject" || super_cls == "AIAbstractList::Valuator") {
+ if (super_cls == "Text" || super_cls == "ScriptObject" || super_cls == "AIAbstractList::Valuator") {
print " SQ" api_cls ".PreRegister(engine);"
} else {
print " SQ" api_cls ".PreRegister(engine, \"" api_super_cls "\");"
@@ -516,6 +527,8 @@ BEGIN {
types = types "a"
} else if (match(params[len], "^struct Array")) {
types = types "a"
+ } else if (match(params[len], "^Text")) {
+ types = types "."
} else {
types = types "x"
}
diff --git a/src/script/api/template/template_text.hpp.sq b/src/script/api/template/template_text.hpp.sq
new file mode 100644
index 000000000..7a44daf16
--- /dev/null
+++ b/src/script/api/template/template_text.hpp.sq
@@ -0,0 +1,30 @@
+/* $Id$ */
+
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */
+
+#include "../script_text.hpp"
+
+namespace SQConvert {
+ /* Allow ScriptText to be used as Squirrel parameter */
+ template <> inline ScriptText *GetParam(ForceType<ScriptText *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptText *)instance; }
+ template <> inline ScriptText &GetParam(ForceType<ScriptText &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptText *)instance; }
+ template <> inline const ScriptText *GetParam(ForceType<const ScriptText *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptText *)instance; }
+ template <> inline const ScriptText &GetParam(ForceType<const ScriptText &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptText *)instance; }
+
+ template <> inline Text *GetParam(ForceType<Text *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) {
+ if (sq_gettype(vm, index) == OT_INSTANCE) {
+ return GetParam(ForceType<ScriptText *>(), vm, index, ptr);
+ }
+ if (sq_gettype(vm, index) == OT_STRING) {
+ return new RawText(GetParam(ForceType<const char *>(), vm, index, ptr));
+ }
+ return NULL;
+ }
+} // namespace SQConvert