RU

Функция запросов к плееру

Nex Moderator 09.12.2012 10:16 9 comments 6914 views

Нужна функция, которая позволит спрашивать у плеера параметры среды выполнения, во время выполнения игры.

В настоящий момент из игры никак нельзя узнать, на каком из плееров игра выполняется(AeroQSP или классический Windows-плеер, или Android-плеер, или Quest Navigator, или плеер для покетбука), а также на какой платформе (Windows, Linux, MacOS, Android, iOS, WinPhone8).

Это было бы крайне удобным для создания универсальных игр, совместимых с максимально возможным количеством плееров и платформ. Например, в настоящий момент для создания игры, которая была бы играбельна на AeroQSP и классическом плеере, приходится держать две разные версии файла .qsp, не говоря уже о Quest Navigator. Даже в пределах одного плеера, Quest Navigator, мне приходится держать две разные версии файла - одну для Android, другую для iOS, из-за того, что нужно выводить разные ссылки и разные тексты для Google Play и App Store соответственно. А когда будет поддерживаться WindowsPhone8, то ещё одна добавится, и так далее.

Есть вариант задавать переменные средствами плеера, в которых будут содержаться необходимые сведения. Но это противоречит общей концепции “переменные обнулены в начале игры”.

Поэтому, самым практичным и универсальным решением мне видится создание функции в библиотеке, которая обращается к плееру и выдаёт игре результат.

В таком духе:

$platform = GETPLAYER("platform")
IF $platform = 'iOS':
    ...
ELSEIF $platform = 'Android':
    ...
END

Начать можно с предоставления версии операционной системы и плеера, в дальнейшем можно по необходимости расширять список характеристик. Можно будет даже добавлять параметры для уточнения. Что самое приятное - вся обработка этой функции будет лежать на плеере, поэтому при дальнейшем совершенствовании списка характеристик никаких изменений в библиотеке не потребуется.

Конечно, можно “костылями” присобачить такую возможность к плееру и на существующей версии библиотеки, например вызывать INPUT с определённым текстовым тегом. Но хотелось бы чтобы это был официальный функционал, т.к. вещь полезная и нужная.

Edited at 09.12.2012 10:19 (13 years ago)

Для проблемы со ссылками могу добавить такое предложение обработки: делать одну ссылку, а в отдельном файле автоматически пересылать её куда нужно в зависимости уже от параметров среды. Конечно можно сделать то же самое и в самой игре, но не все догадаются.

Baz,
я же написал, что не только ссылки нужно разные сделать, но и текст описания. К игрокам, открывшим игру с Google Play, у меня одно обращение, к игрокам с App Store - другое. Запихивать текст во внешний файл - уже не комильфо.

Патч для библиотеки:

Spoiler
Index: bindings/default/default_callbacks.c
===================================================================
--- bindings/default/default_callbacks.c	(revision 685)
+++ bindings/default/default_callbacks.c	(working copy)
@@ -290,4 +290,24 @@
 	return buffer;
 }
 
+QSP_CHAR *qspCallPlayerVersion(QSP_CHAR *text)
+{
+	/* Здесь получаем строку по заданному параметру */
+	QSPCallState state;
+	QSP_CHAR *buffer;
+	int maxLen = 511;
+	if (qspCallBacks[QSP_CALL_PLAYERVERSION])
+	{
+		qspSaveCallState(&state, QSP_TRUE, QSP_FALSE);
+		buffer = (QSP_CHAR *)malloc((maxLen + 1) * sizeof(QSP_CHAR));
+		*buffer = 0;
+		qspCallBacks[QSP_CALL_PLAYERVERSION](text, buffer, maxLen);
+		buffer[maxLen] = 0;
+		qspRestoreCallState(&state);
+	}
+	else
+		buffer = qspGetNewText(QSP_FMT(""), 0);
+	return buffer; 
+}
+
 #endif
Index: callbacks.h
===================================================================
--- callbacks.h	(revision 685)
+++ callbacks.h	(working copy)
@@ -61,5 +61,6 @@
 	void qspCallCloseFile(QSP_CHAR *);
 	void qspCallDeleteMenu();
 	QSP_CHAR *qspCallInputBox(QSP_CHAR *);
+	QSP_CHAR *qspCallPlayerVersion(QSP_CHAR *);
 
 #endif
Index: mathops.c
===================================================================
--- mathops.c	(revision 685)
+++ mathops.c	(working copy)
@@ -195,6 +195,7 @@
 	qspAddOperation(qspOpMainText, 30, 0, 1, 0, 0);
 	qspAddOperation(qspOpStatText, 30, 0, 1, 0, 0);
 	qspAddOperation(qspOpCurActs, 30, 0, 1, 0, 0);
+	qspAddOperation(qspOpPlayerVer, 30, 0, 1, 1, 1, 1);
 	/* Names */
 	qspAddOpName(qspOpCloseBracket, QSP_RRBRACK, 1);
 	qspAddOpName(qspOpAdd, QSP_ADD, 1);
@@ -281,6 +282,8 @@
 	qspAddOpName(qspOpStatText, QSP_STRCHAR QSP_FMT("STATTXT"), 1);
 	qspAddOpName(qspOpCurActs, QSP_FMT("CURACTS"), 1);
 	qspAddOpName(qspOpCurActs, QSP_STRCHAR QSP_FMT("CURACTS"), 1);
+	qspAddOpName(qspOpPlayerVer, QSP_FMT("GETPLAYER"), 1);
+	qspAddOpName(qspOpPlayerVer, QSP_STRCHAR QSP_FMT("GETPLAYER"), 1);
 	for (i = 0; i < QSP_OPSLEVELS; ++i)
 		qsort(qspOpsNames[i], qspOpsNamesCounts[i], sizeof(QSPMathOpName), qspMathOpsCompare);
 }
@@ -596,6 +599,9 @@
 			case qspOpCurActs:
 				QSP_STR(tos) = qspGetAllActionsAsCode();
 				break;
+			case qspOpPlayerVer:
+				QSP_STR(tos) = qspCallPlayerVersion(QSP_STR(args[0]));
+				break;
 			/* External functions -------------------------------------------------------------- */
 			default:
 				qspOps[opCode].Func(args, argsCount, &tos);
Index: mathops.h
===================================================================
--- mathops.h	(revision 685)
+++ mathops.h	(working copy)
@@ -114,6 +114,7 @@
 		qspOpMainText,
 		qspOpStatText,
 		qspOpCurActs,
+		qspOpPlayerVer,
 
 		qspOpLast_Operation
 	};
Index: qsp.h
===================================================================
--- qsp.h	(revision 685)
+++ qsp.h	(working copy)
@@ -88,6 +88,7 @@
 		QSP_CALL_SLEEP, /* void func(int msecs) */
 		QSP_CALL_GETMSCOUNT, /* int func() */
 		QSP_CALL_INPUTBOX, /* void func(const QSP_CHAR *text, QSP_CHAR *buffer, int maxLen) */
+		QSP_CALL_PLAYERVERSION, /* void func(const QSP_CHAR *text, QSP_CHAR *buffer, int maxLen) */
 		QSP_CALL_DUMMY
 	};

Пример для классического плеера:

Spoiler
Index: callbacks_gui.cpp
===================================================================
--- callbacks_gui.cpp	(revision 685)
+++ callbacks_gui.cpp	(working copy)
@@ -58,6 +58,7 @@
 	QSPSetCallBack(QSP_CALL_SHOWWINDOW, (QSP_CALLBACK)&ShowPane);
 	QSPSetCallBack(QSP_CALL_OPENGAMESTATUS, (QSP_CALLBACK)&OpenGameStatus);
 	QSPSetCallBack(QSP_CALL_SAVEGAMESTATUS, (QSP_CALLBACK)&SaveGameStatus);
+	QSPSetCallBack(QSP_CALL_PLAYERVERSION, (QSP_CALLBACK)&PlayerVersion);
 }
 
 void QSPCallBacks::DeInit()
@@ -425,3 +426,24 @@
 		}
 	}
 }
+
+void QSPCallBacks::PlayerVersion(const QSP_CHAR *text, QSP_CHAR *buffer, int maxLen)
+{
+	wxString parm = wxString(text);
+	if (parm == _("os")) 
+	{
+#ifdef _UNICODE
+		wcsncpy(buffer, _("windows"), maxLen);
+#else
+		strncpy(buffer, _("windows"), maxLen);
+#endif
+	} else if (parm == _("platform"))
+	{
+#ifdef _UNICODE
+		wcsncpy(buffer, _("classic"), maxLen);
+#else
+		strncpy(buffer, _("classic"), maxLen);
+#endif
+	}
+
+}
Index: callbacks_gui.h
===================================================================
--- callbacks_gui.h	(revision 685)
+++ callbacks_gui.h	(working copy)
@@ -64,6 +64,7 @@
 		static void ShowImage(const QSP_CHAR *file);
 		static void OpenGameStatus(const QSP_CHAR *file);
 		static void SaveGameStatus(const QSP_CHAR *file);
+		static void PlayerVersion(const QSP_CHAR *text, QSP_CHAR *buffer, int maxLen);
 	private:
 		// Internal methods
 		static void UpdateGamePath();
Index: qsp.h
===================================================================
--- qsp.h	(revision 685)
+++ qsp.h	(working copy)
@@ -88,6 +88,7 @@
 		QSP_CALL_SLEEP, /* void func(int msecs) */
 		QSP_CALL_GETMSCOUNT, /* int func() */
 		QSP_CALL_INPUTBOX, /* void func(const QSP_CHAR *text, QSP_CHAR *buffer, int maxLen) */
+		QSP_CALL_PLAYERVERSION, /* void func(const QSP_CHAR *text, QSP_CHAR *buffer, int maxLen) */
 		QSP_CALL_DUMMY
 	};

Проверялось на:

Spoiler
$ОС = GETPLAYER('os')
'ОС: <<$ОС>>'
$Платформа = GETPLAYER('platform')
'Платформа: <<$Платформа>>'

Результат:

Spoiler

rrock.ru,
спасибо большое! Осталось только добавить это в библиотеку.

Кстати QSP_CALL_PLAYERVERSION не очень подходит, скорее уж QSP_CALL_PLAYERINFO - т.к. информация может быть разная.

Nex:

Кстати QSP_CALL_PLAYERVERSION не очень подходит, скорее уж QSP_CALL_PLAYERINFO - т.к. информация может быть разная.

Ну это уже дело вкуса :)
Я думал над PLAYERINFO, ну уж как-то смахивает на информацию об игроке..

P.S. Добавил бы сам, но у меня доступ только к репе редактора.

Есть 2 варианта реализации этого без модификации библиотеки:
1. GUI устанавливает соответствующую переменную (API библиотеки это предусматривает)
2. Использовать готовую callback функцию SYSTEM - она также предусмотрена в библиотеке.

Например, SYSTEM(”PLATFORM”) может возвращать платформу.
Я еще подумаю как лучше сделать.

PS: Возможно, SYSTEM сейчас не возвращает значение - уже забыл.

  1. GUI устанавливает соответствующую переменную (API библиотеки это предусматривает)

Я согласен, это можно сделать, но как я писал выше, это поведение будет отличаться от общепринятого. Того, что в начале игры все переменные обнулены, а параметры среды запрашиваются функциями. Помнится, когда-то ты настаивал на соблюдении этого принципа.

  1. Использовать готовую callback функцию SYSTEM - она также предусмотрена в библиотеке.

“SYSTEM” не возвращает значение. К тому же не очень понятно, как она вообще должна себя вести - никакой документации по ней нет.

Да, я вспомнил - SYSTEM сейчас зарезервирован для оператора. Вообще, этот оператор задумывался для выполнения различных служебных действий, которые могут предоставлять плееры.

Byte,
это хорошо. Я как раз его собираюсь заюзать для выполнения яваскрипта из Quest Navigator.

Учитывая, что поведение SYSTEM зависит от плеера, тем нужнее функция запросов к плееру.

Log in or Register to post comments.