mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
963 lines
31 KiB
C++
963 lines
31 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program 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, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "common/lua/lua.h"
|
|
#include "common/textconsole.h"
|
|
#include "tetraedge/te/te_lua_gui_lua_callbacks.h"
|
|
#include "tetraedge/te/te_layout.h"
|
|
#include "tetraedge/te/te_lua_gui.h"
|
|
#include "tetraedge/te/te_3d_object2.h"
|
|
#include "tetraedge/te/te_object.h"
|
|
|
|
namespace Tetraedge {
|
|
|
|
template <typename T> static T TeLuaTo(lua_State *L, int index) {
|
|
void *ptr = lua_touserdata(L, index);
|
|
if (!ptr)
|
|
return nullptr;
|
|
T obj = reinterpret_cast<T>(ptr);
|
|
return dynamic_cast<T>(obj);
|
|
}
|
|
|
|
static Common::String TeLuaToTeString(lua_State *L, int index) {
|
|
if (!lua_isstring(L, index)) {
|
|
warning("TeLuaToTeString:: not a string");
|
|
return "";
|
|
} else {
|
|
return lua_tolstring(L, index, nullptr);
|
|
}
|
|
}
|
|
|
|
static long TeLuaToS32(lua_State *L, int index) {
|
|
if (!lua_isnumber(L, index)) {
|
|
warning("TeLuaToS32:: not a number");
|
|
return 0;
|
|
} else {
|
|
return lua_tointeger(L, index);
|
|
}
|
|
}
|
|
|
|
static long TeLuaToU32(lua_State *L, int index) {
|
|
if (!lua_isnumber(L, index)) {
|
|
warning("TeLuaToU32:: not a number");
|
|
return 0;
|
|
} else {
|
|
return lua_tointeger(L, index);
|
|
}
|
|
}
|
|
|
|
static float TeLuaToF32(lua_State *L, int index) {
|
|
if (!lua_isnumber(L, index)) {
|
|
warning("TeLuaToF32:: not a number");
|
|
return 0.0f;
|
|
} else {
|
|
return lua_tonumber(L, index);
|
|
}
|
|
}
|
|
|
|
static bool TeLuaToBool(lua_State *L, int index) {
|
|
if (lua_type(L, index) != LUA_TBOOLEAN) {
|
|
warning("TeLuaToBool:: not a bool");
|
|
return false;
|
|
} else {
|
|
return lua_toboolean(L, index);
|
|
}
|
|
}
|
|
|
|
static TeColor TeLuaToTeColor(lua_State *L, int index) {
|
|
TeColor retval(255, 255, 255, 255);
|
|
if (lua_type(L, index) != LUA_TTABLE) {
|
|
warning("TeLuaToTeColor:: not a table");
|
|
return retval;
|
|
}
|
|
|
|
lua_pushinteger(L, 1);
|
|
index--;
|
|
lua_gettable(L, index);
|
|
if (lua_isnumber(L, -1)) {
|
|
retval.r() = TeLuaToU32(L, -1);
|
|
}
|
|
lua_settop(L, -2);
|
|
lua_pushinteger(L, 2);
|
|
lua_gettable(L, index);
|
|
|
|
if (lua_isnumber(L, -1)) {
|
|
retval.g() = TeLuaToU32(L, -1);
|
|
}
|
|
|
|
lua_settop(L, -2);
|
|
lua_pushinteger(L, 3);
|
|
lua_gettable(L, index);
|
|
if (lua_isnumber(L, -1)) {
|
|
retval.b() = TeLuaToU32(L, -1);
|
|
}
|
|
|
|
lua_settop(L, -2);
|
|
lua_pushinteger(L, 4);
|
|
lua_gettable(L, index);
|
|
if (lua_isnumber(L, -1)) {
|
|
retval.a() = TeLuaToU32(L, -1);
|
|
}
|
|
|
|
lua_settop(L, -2);
|
|
|
|
return retval;
|
|
}
|
|
|
|
static TeVector3f32 TeLuaToTeVector3f32(lua_State *L, int index, TeVector3f32 defaultVal) {
|
|
TeVector3f32 retval = defaultVal;
|
|
if (lua_type(L, index) != LUA_TTABLE) {
|
|
warning("TeLuaToTeVector3f32:: not a table");
|
|
} else {
|
|
lua_pushinteger(L, 1);
|
|
index--;
|
|
lua_gettable(L, index);
|
|
if (lua_isnumber(L, -1)) {
|
|
retval.x() = TeLuaToF32(L, -1);
|
|
}
|
|
|
|
lua_settop(L, -2);
|
|
lua_pushinteger(L, 2);
|
|
lua_gettable(L, index);
|
|
if (lua_isnumber(L, -1)) {
|
|
retval.y() = TeLuaToF32(L, -1);
|
|
}
|
|
|
|
lua_settop(L, -2);
|
|
lua_pushinteger(L, 3);
|
|
lua_gettable(L, index);
|
|
if (lua_isnumber(L, -1)) {
|
|
retval.z() = TeLuaToF32(L, -1);
|
|
}
|
|
lua_settop(L, -2);
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
static Common::Array<float> TeLuaToFloatArray(lua_State *L, int index) {
|
|
Common::Array<float> result;
|
|
int type = lua_type(L, index);
|
|
if (type == LUA_TTABLE) {
|
|
lua_pushnil(L);
|
|
while (true) {
|
|
int next = lua_next(L, index - 1);
|
|
if (next == 0)
|
|
break;
|
|
result.push_back(TeLuaToF32(L, -1));
|
|
lua_settop(L, -2);
|
|
}
|
|
} else {
|
|
warning("TeLuaToF32TeArray:: the lua value is not a table");
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
static bool loadCommonLayoutItems(lua_State *L, const char *s, TeLayout *layout) {
|
|
if (!strcmp(s, "name")) {
|
|
layout->setName(TeLuaToTeString(L, -1));
|
|
} else if (!strcmp(s, "sizeType")) {
|
|
layout->setSizeType(static_cast<TeILayout::CoordinatesType>(TeLuaToS32(L, -1)));
|
|
} else if (!strcmp(s, "size")) {
|
|
TeVector3f32 lastSize = layout->userSize();
|
|
TeVector3f32 size = TeLuaToTeVector3f32(L, -1, lastSize);
|
|
layout->setSize(size);
|
|
} else if (!strcmp(s, "ratio")) {
|
|
layout->setRatio(TeLuaToF32(L, -1));
|
|
} else if (!strcmp(s, "ratioMode")) {
|
|
layout->setRatioMode(static_cast<TeILayout::RatioMode>(TeLuaToS32(L, -1)));
|
|
} else if (!strcmp(s, "safeAreaRatio")) {
|
|
layout->setSafeAreaRatio(TeLuaToF32(L, -1));
|
|
} else if (!strcmp(s, "anchor")) {
|
|
TeVector3f32 lastAnchor = layout->anchor();
|
|
TeVector3f32 anchor = TeLuaToTeVector3f32(L, -1, lastAnchor);
|
|
layout->setAnchor(anchor);
|
|
} else if (!strcmp(s, "positionType")) {
|
|
layout->setPositionType(static_cast<TeILayout::CoordinatesType>(TeLuaToS32(L, -1)));
|
|
} else if (!strcmp(s, "position")) {
|
|
TeVector3f32 lastPos = layout->userPosition();
|
|
TeVector3f32 pos = TeLuaToTeVector3f32(L, -1, lastPos);
|
|
layout->setPosition(pos);
|
|
} else if (!strcmp(s, "visible")) {
|
|
layout->setVisible(TeLuaToBool(L, -1));
|
|
} else if (!strcmp(s, "color")) {
|
|
layout->setColor(TeLuaToTeColor(L, -1));
|
|
} else {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
// TODO: Fix this widescreen flag
|
|
static bool _g_bWidescreen = false;
|
|
|
|
int layoutBindings(lua_State *L) {
|
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
|
warning("layoutBindings:: the lua value is not a table");
|
|
return 0;
|
|
}
|
|
|
|
TeLayout *layout = new TeLayout();
|
|
lua_pushnil(L);
|
|
while (lua_next(L, -2) != 0) {
|
|
int type = lua_type(L, -2);
|
|
if (type == LUA_TSTRING) {
|
|
const char *s = lua_tolstring(L, -2, nullptr);
|
|
if (loadCommonLayoutItems(L, s, layout)) {
|
|
// do nothing.
|
|
} else if (!strcmp(s, "consoleNoStretch")) {
|
|
warning("TODO: Handle _g_bWidescreen");
|
|
if (_g_bWidescreen) {
|
|
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
|
}
|
|
} else {
|
|
warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s", s);
|
|
}
|
|
} else if (type == LUA_TNUMBER) {
|
|
Te3DObject2 *obj = TeLuaTo<Te3DObject2*>(L, -1);
|
|
layout->addChild(obj);
|
|
}
|
|
lua_settop(L, -2);
|
|
}
|
|
|
|
if (layout->name().empty()) {
|
|
layout->setName(Common::String::format("%p", (void *)layout));
|
|
}
|
|
lua_pushstring(L, "__TeLuaGUIThis");
|
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
|
TeLuaGUI::StringMap<TeLayout *> &layouts = gui->layouts();
|
|
if (!layouts.contains(layout->name())) {
|
|
layouts.setVal(layout->name(), layout);
|
|
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
|
return true;
|
|
} else {
|
|
warning("layoutBindings:: multiple objects with name %s", layout->name().c_str());
|
|
delete layout;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int listLayoutBindings(lua_State *L) {
|
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
|
warning("listLayoutBindings:: the lua value is not a table");
|
|
return 0;
|
|
}
|
|
|
|
TeListLayout *layout = new TeListLayout();
|
|
lua_pushnil(L);
|
|
|
|
while (lua_next(L, -2) != 0) {
|
|
int type = lua_type(L, -2);
|
|
if (type == LUA_TSTRING) {
|
|
const char *s = lua_tolstring(L, -2, nullptr);
|
|
if (loadCommonLayoutItems(L, s, layout)) {
|
|
// do nothing.
|
|
} else if (!strcmp(s, "direction")) {
|
|
const TeVector3f32 lastDirection = layout->direction();
|
|
const TeVector3f32 direction = TeLuaToTeVector3f32(L, -1, lastDirection);
|
|
layout->setDirection(direction);
|
|
} else if (!strcmp(s, "minimumMargin")) {
|
|
const TeVector3f32 lastMinimumMargin = layout->minimumMargin();
|
|
const TeVector3f32 minimumMargin = TeLuaToTeVector3f32(L, -1, lastMinimumMargin);
|
|
layout->setMinimumMargin(minimumMargin);
|
|
} else if (!strcmp(s, "maximumMargin")) {
|
|
const TeVector3f32 lastMaximumMargin = layout->maximumMargin();
|
|
const TeVector3f32 maximumMargin = TeLuaToTeVector3f32(L, -1, lastMaximumMargin);
|
|
layout->setMaximumMargin(maximumMargin);
|
|
} else if (!strcmp(s, "consoleNoStretch")) {
|
|
warning("TODO: Handle _g_bWidescreen");
|
|
if (_g_bWidescreen) {
|
|
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
|
}
|
|
} else {
|
|
warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s", s);
|
|
}
|
|
} else if (type == LUA_TNUMBER) {
|
|
Te3DObject2 *obj = TeLuaTo<Te3DObject2*>(L, -1);
|
|
layout->addChild(obj);
|
|
}
|
|
lua_settop(L, -2);
|
|
}
|
|
|
|
if (layout->name().empty()) {
|
|
layout->setName(Common::String::format("%p", (void *)layout));
|
|
}
|
|
lua_pushstring(L, "__TeLuaGUIThis");
|
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
|
TeLuaGUI::StringMap<TeListLayout *> &layouts = gui->listLayouts();
|
|
if (!layouts.contains(layout->name())) {
|
|
layouts.setVal(layout->name(), layout);
|
|
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
|
return true;
|
|
} else {
|
|
warning("listLayoutBindings:: multiple objects with name %s", layout->name().c_str());
|
|
delete layout;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int spriteLayoutBindings(lua_State *L) {
|
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
|
warning("spriteLayoutBindings:: the lua value is not a table");
|
|
return 0;
|
|
}
|
|
|
|
lua_pushstring(L, "__TeLuaGUIThis");
|
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
|
lua_settop(L, -2);
|
|
TeSpriteLayout *layout = new TeSpriteLayout();
|
|
lua_pushnil(L);
|
|
|
|
bool playNow = layout->_tiledSurfacePtr->_frameAnim._runTimer.running();
|
|
int startingFrame = 0;
|
|
int endingFrame = -1;
|
|
Common::Path imgFullPath;
|
|
while (lua_next(L, -2) != 0) {
|
|
int type = lua_type(L, -2);
|
|
if (type == LUA_TSTRING) {
|
|
const char *s = lua_tolstring(L, -2, 0);
|
|
if (loadCommonLayoutItems(L, s, layout)) {
|
|
// do nothing.
|
|
} else if (!strcmp(s, "image")) {
|
|
Common::String imgPath = TeLuaToTeString(L, -1);
|
|
// Slight hack.. fix double-slash that appears in some script files
|
|
uint32 loc = imgPath.find("//");
|
|
if (loc != Common::String::npos) {
|
|
imgPath.replace(loc, 2, "/");
|
|
}
|
|
if (imgPath.substr(0, 2) == "./") {
|
|
imgPath = imgPath.substr(0, 2);
|
|
// NOTE: This is bad.. the scriptPath is a system-local path so the
|
|
// separator may not be '/', we can't just make a Path from it like
|
|
// this. Fortunately it seems this is never actually used? No sprites
|
|
// use './' in their data.
|
|
warning("Taking non-portable code path to load image in spriteLayoutBindings");
|
|
imgFullPath = Common::Path(gui->scriptPath()).getParent().join(imgPath);
|
|
} else {
|
|
imgFullPath = imgPath;
|
|
}
|
|
} else if (!strcmp(s, "leftCropping")) {
|
|
layout->_tiledSurfacePtr->setLeftCropping(TeLuaToF32(L, -1));
|
|
} else if (!strcmp(s, "rightCropping")) {
|
|
layout->_tiledSurfacePtr->setRightCropping(TeLuaToF32(L, -1));
|
|
} else if (!strcmp(s, "topCropping")) {
|
|
layout->_tiledSurfacePtr->setTopCropping(TeLuaToF32(L, -1));
|
|
} else if (!strcmp(s, "bottomCropping")) {
|
|
layout->_tiledSurfacePtr->setBottomCropping(TeLuaToF32(L, -1));
|
|
} else if (!strcmp(s, "loopCount")) {
|
|
layout->_tiledSurfacePtr->_frameAnim.setLoopCount(TeLuaToS32(L, -1));
|
|
} else if (!strcmp(s, "play")) {
|
|
playNow = TeLuaToBool(L, -1);
|
|
} else if (!strcmp(s, "reversed")) {
|
|
layout->_tiledSurfacePtr->_frameAnim.setReversed(TeLuaToBool(L, -1));
|
|
} else if (!strcmp(s, "startingFrame")) {
|
|
startingFrame = TeLuaToU32(L, -1);
|
|
} else if (!strcmp(s, "endingFrame")) {
|
|
endingFrame = TeLuaToU32(L, -1);
|
|
} else if (!strcmp(s, "consoleNoStretch")) {
|
|
warning("TODO: Handle _g_bWidescreen");
|
|
if (_g_bWidescreen) {
|
|
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
|
}
|
|
} else {
|
|
warning("[TeLuaGUI.layoutBindings] Unreconized attribute : %s", s);
|
|
}
|
|
}
|
|
lua_settop(L, -2);
|
|
}
|
|
|
|
if (!imgFullPath.empty())
|
|
layout->load(imgFullPath);
|
|
|
|
lua_pushnil(L);
|
|
while (lua_next(L, -2) != 0) {
|
|
if (lua_type(L, -2) == LUA_TNUMBER) {
|
|
Te3DObject2 *object = TeLuaTo<Te3DObject2*>(L, -1);
|
|
layout->addChild(object);
|
|
}
|
|
lua_settop(L, -2);
|
|
}
|
|
|
|
if (layout->name().empty()) {
|
|
layout->setName(Common::String::format("%p", (void *)layout));
|
|
}
|
|
|
|
// WORKAROUND: ValStreet scene 11070 has a misnamed animation in the script.
|
|
// All references to it in script refer to it with the "ab".
|
|
// This scene is broken in the original game too.
|
|
if (layout->name() == "11070-1")
|
|
layout->setName("ab11070-1");
|
|
|
|
TeICodec *codec = layout->_tiledSurfacePtr->codec();
|
|
if (codec) {
|
|
float frameRate = codec->frameRate();
|
|
layout->_tiledSurfacePtr->_frameAnim.setStartTime((startingFrame / frameRate) * 1000.0 * 1000.0);
|
|
if (endingFrame == -1) {
|
|
layout->_tiledSurfacePtr->_frameAnim.setEndTime(FLT_MAX);
|
|
} else {
|
|
layout->_tiledSurfacePtr->_frameAnim.setEndTime((endingFrame / frameRate) * 1000.0 * 1000.0);
|
|
}
|
|
}
|
|
|
|
// Slight divergence from original.. start playing only after setting
|
|
// start/end values above as it makes more sense that way.
|
|
if (playNow) {
|
|
layout->play();
|
|
} else {
|
|
layout->stop();
|
|
}
|
|
|
|
if (!gui->spriteLayout(layout->name())) {
|
|
TeLuaGUI::StringMap<TeSpriteLayout *> &spriteLayouts = gui->spriteLayouts();
|
|
spriteLayouts.setVal(layout->name(), layout);
|
|
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
|
return true;
|
|
} else {
|
|
warning("layoutBindings:: multiple objects with name %s", layout->name().c_str());
|
|
delete layout;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int buttonLayoutBindings(lua_State *L) {
|
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
|
warning("buttonLayoutBindings:: the lua value is not a table");
|
|
return 0;
|
|
}
|
|
|
|
TeButtonLayout *layout = new TeButtonLayout();
|
|
lua_pushnil(L);
|
|
while (lua_next(L, -2) != 0) {
|
|
int type = lua_type(L, -2);
|
|
if (type == LUA_TSTRING) {
|
|
const char *s = lua_tolstring(L, -2, nullptr);
|
|
if (loadCommonLayoutItems(L, s, layout)) {
|
|
// do nothing.
|
|
} else if (!strcmp(s, "upLayout")) {
|
|
layout->setUpLayout(TeLuaTo<TeLayout*>(L, -1));
|
|
} else if (!strcmp(s, "downLayout")) {
|
|
layout->setDownLayout(TeLuaTo<TeLayout*>(L, -1));
|
|
} else if (!strcmp(s, "disabledLayout")) {
|
|
layout->setDisabledLayout(TeLuaTo<TeLayout*>(L, -1));
|
|
} else if (!strcmp(s, "rollOverLayout")) {
|
|
layout->setRollOverLayout(TeLuaTo<TeLayout*>(L, -1));
|
|
} else if (!strcmp(s, "hitZone")) {
|
|
layout->setHitZone(TeLuaTo<TeLayout*>(L, -1));
|
|
} else if (!strcmp(s, "enable")) {
|
|
layout->setEnable(TeLuaToBool(L, -1));
|
|
} else if (!strcmp(s, "clickPassThrough")) {
|
|
layout->setClickPassThrough(TeLuaToBool(L, -1));
|
|
} else if (!strcmp(s, "validationSound")) {
|
|
layout->setValidationSound(Common::Path(TeLuaToTeString(L, -1)));
|
|
} else if (!strcmp(s, "validationSoundVolume")) {
|
|
layout->setValidationSoundVolume(TeLuaToF32(L, -1));
|
|
} else if (!strcmp(s, "consoleNoStretch")) {
|
|
warning("TODO: Handle _g_bWidescreen");
|
|
if (_g_bWidescreen) {
|
|
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
|
}
|
|
} else {
|
|
warning("[TeLuaGUI.buttonLayoutBindings] Unreconized attribute : %s", s);
|
|
}
|
|
}
|
|
lua_settop(L, -2);
|
|
}
|
|
|
|
lua_pushnil(L);
|
|
while (lua_next(L, -2) != 0) {
|
|
if (lua_type(L, -2) == LUA_TNUMBER) {
|
|
Te3DObject2 *object = TeLuaTo<Te3DObject2*>(L, -1);
|
|
layout->addChild(object);
|
|
}
|
|
lua_settop(L, -2);
|
|
}
|
|
|
|
lua_pushstring(L, "__TeLuaGUIThis");
|
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
|
TeLuaGUI::StringMap<TeButtonLayout *> &blayouts = gui->buttonLayouts();
|
|
if (!blayouts.contains(layout->name())) {
|
|
blayouts.setVal(layout->name(), layout);
|
|
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
|
return true;
|
|
} else {
|
|
warning("buttonLayoutBindings:: multiple objects with name %s", layout->name().c_str());
|
|
delete layout;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int checkboxLayoutBindings(lua_State *L) {
|
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
|
warning("checkboxLayoutBindings:: the lua value is not a table");
|
|
return 0;
|
|
}
|
|
|
|
TeCheckboxLayout *layout = new TeCheckboxLayout();
|
|
lua_pushnil(L);
|
|
while (lua_next(L, -2) != 0) {
|
|
int type = lua_type(L, -2);
|
|
if (type == LUA_TSTRING) {
|
|
const char *s = lua_tolstring(L, -2, nullptr);
|
|
if (loadCommonLayoutItems(L, s, layout)) {
|
|
// do nothing.
|
|
} else if (!strcmp(s, "activeLayout")) {
|
|
layout->setActiveLayout(TeLuaTo<TeLayout*>(L, -1));
|
|
} else if (!strcmp(s, "unactiveLayout")) {
|
|
layout->setUnactiveLayout(TeLuaTo<TeLayout*>(L, -1));
|
|
} else if (!strcmp(s, "activeDisabledLayout")) {
|
|
layout->setActiveDisabledLayout(TeLuaTo<TeLayout*>(L, -1));
|
|
} else if (!strcmp(s, "unactiveDisabledLayout")) {
|
|
layout->setUnactiveDisabledLayout(TeLuaTo<TeLayout*>(L, -1));
|
|
} else if (!strcmp(s, "activeRollOverLayout")) {
|
|
layout->setActiveRollOverLayout(TeLuaTo<TeLayout*>(L, -1));
|
|
} else if (!strcmp(s, "unactiveRollOverLayout")) {
|
|
layout->setUnactiveRollOverLayout(TeLuaTo<TeLayout*>(L, -1));
|
|
} else if (!strcmp(s, "hitZone")) {
|
|
layout->setHitZone(TeLuaTo<TeLayout*>(L, -1));
|
|
} else if (!strcmp(s, "clickPassThrough")) {
|
|
layout->setClickPassThrough(TeLuaToBool(L, -1));
|
|
} else if (!strcmp(s, "activationSound")) {
|
|
layout->setActivationSound(TeLuaToTeString(L, -1));
|
|
} else if (!strcmp(s, "unactivationSound")) {
|
|
layout->setUnactivationSound(TeLuaToTeString(L, -1));
|
|
} else if (!strcmp(s, "consoleNoStretch")) {
|
|
warning("TODO: Handle _g_bWidescreen");
|
|
if (_g_bWidescreen) {
|
|
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
|
}
|
|
} else {
|
|
warning("[TeLuaGUI.checkboxLayoutBindings] Unreconized attribute : %s", s);
|
|
}
|
|
}
|
|
lua_settop(L, -2);
|
|
}
|
|
|
|
lua_pushnil(L);
|
|
while (lua_next(L, -2) != 0) {
|
|
if (lua_type(L, -2) == LUA_TNUMBER) {
|
|
Te3DObject2 *object = TeLuaTo<Te3DObject2*>(L, -1);
|
|
layout->addChild(object);
|
|
}
|
|
lua_settop(L, -2);
|
|
}
|
|
|
|
lua_pushstring(L, "__TeLuaGUIThis");
|
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
|
TeLuaGUI::StringMap<TeCheckboxLayout *> &blayouts = gui->checkboxLayouts();
|
|
if (!blayouts.contains(layout->name())) {
|
|
blayouts.setVal(layout->name(), layout);
|
|
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
|
return true;
|
|
} else {
|
|
warning("checkboxLayoutBindings:: multiple objects with name %s", layout->name().c_str());
|
|
delete layout;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int layoutPositionLinearAnimationBindings(lua_State *L) {
|
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
|
warning("layoutPositionLinearAnimationBindings:: the lua value is not a table");
|
|
return 0;
|
|
}
|
|
|
|
TeCurveAnim2<TeLayout, TeVector3f32> *anim = new TeCurveAnim2<TeLayout, TeVector3f32>();
|
|
lua_pushnil(L);
|
|
Common::String name;
|
|
while (lua_next(L, -2) != 0) {
|
|
int type = lua_type(L, -2);
|
|
if (type == LUA_TSTRING) {
|
|
const char *s = lua_tolstring(L, -2, nullptr);
|
|
if (!strcmp(s, "name")) {
|
|
name = TeLuaToTeString(L, -1);
|
|
} else if (!strcmp(s, "duration")) {
|
|
anim->_duration = TeLuaToF32(L, -1);
|
|
} else if (!strcmp(s, "startValue")) {
|
|
static const TeVector3f32 defaultStart(0.0f, 0.0f, 0.0f);
|
|
anim->_startVal = TeLuaToTeVector3f32(L, -1, defaultStart);
|
|
} else if (!strcmp(s, "endValue")) {
|
|
static const TeVector3f32 defaultEnd(0.0f, 0.0f, 0.0f);
|
|
anim->_endVal = TeLuaToTeVector3f32(L, -1, defaultEnd);
|
|
} else if (!strcmp(s, "layout")) {
|
|
// skip.
|
|
} else if (!strcmp(s, "curve")) {
|
|
const Common::Array<float> curve = TeLuaToFloatArray(L, -1);
|
|
anim->setCurve(curve);
|
|
} else {
|
|
error("[TeLuaGUI.layoutPositionLinearAnimationBindings] Unreconized attribute : %s", s);
|
|
}
|
|
lua_settop(L, -2);
|
|
}
|
|
}
|
|
|
|
if (name.empty()) {
|
|
name = Common::String::format("%p", (void *)anim);
|
|
}
|
|
anim->_callbackMethod = &TeLayout::setPosition;
|
|
lua_pushstring(L, "__TeLuaGUIThis");
|
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
|
TeLuaGUI::StringMap<TeCurveAnim2<TeLayout, TeVector3f32> *> &anims = gui->layoutPositionLinearAnimations();
|
|
if (!anims.contains(name)) {
|
|
anims.setVal(name, anim);
|
|
lua_pushlightuserdata(L, (void *)(anim));
|
|
return true;
|
|
} else {
|
|
warning("layoutPositionLinearAnimationBindings:: multiple objects with name %s", name.c_str());
|
|
delete anim;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int layoutAnchorLinearAnimationBindings(lua_State *L) {
|
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
|
warning("layoutAnchorLinearAnimationBindings:: the lua value is not a table");
|
|
return 0;
|
|
}
|
|
|
|
TeCurveAnim2<TeLayout, TeVector3f32> *anim = new TeCurveAnim2<TeLayout, TeVector3f32>();
|
|
lua_pushnil(L);
|
|
Common::String name;
|
|
while (lua_next(L, -2) != 0) {
|
|
int type = lua_type(L, -2);
|
|
if (type == LUA_TSTRING) {
|
|
const char *s = lua_tolstring(L, -2, nullptr);
|
|
if (!strcmp(s, "name")) {
|
|
name = TeLuaToTeString(L, -1);
|
|
} else if (!strcmp(s, "duration")) {
|
|
anim->_duration = TeLuaToF32(L, -1);
|
|
} else if (!strcmp(s, "startValue")) {
|
|
static const TeVector3f32 defaultStart(0.0f, 0.0f, 0.0f);
|
|
anim->_startVal = TeLuaToTeVector3f32(L, -1, defaultStart);
|
|
} else if (!strcmp(s, "endValue")) {
|
|
static const TeVector3f32 defaultEnd(0.0f, 0.0f, 0.0f);
|
|
anim->_endVal = TeLuaToTeVector3f32(L, -1, defaultEnd);
|
|
} else if (!strcmp(s, "layout")) {
|
|
// skip.
|
|
} else if (!strcmp(s, "curve")) {
|
|
const Common::Array<float> curve = TeLuaToFloatArray(L, -1);
|
|
anim->setCurve(curve);
|
|
} else {
|
|
error("[TeLuaGUI.layoutAnchorLinearAnimationBindings] Unreconized attribute : %s", s);
|
|
}
|
|
lua_settop(L, -2);
|
|
}
|
|
}
|
|
|
|
if (name.empty()) {
|
|
name = Common::String::format("%p", (void *)anim);
|
|
}
|
|
anim->_callbackMethod = &TeLayout::setAnchor;
|
|
lua_pushstring(L, "__TeLuaGUIThis");
|
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
|
TeLuaGUI::StringMap<TeCurveAnim2<TeLayout, TeVector3f32> *> &anims = gui->layoutAnchorLinearAnimations();
|
|
if (!anims.contains(name)) {
|
|
anims.setVal(name, anim);
|
|
lua_pushlightuserdata(L, (void *)(anim));
|
|
return true;
|
|
} else {
|
|
warning("layoutAnchorLinearAnimationBindings:: multiple objects with name %s", name.c_str());
|
|
delete anim;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int textLayoutBindings(lua_State *L) {
|
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
|
warning("textLayoutBindings:: the lua value is not a table");
|
|
return 0;
|
|
}
|
|
|
|
TeTextLayout *layout = new TeTextLayout();
|
|
lua_pushnil(L);
|
|
while (lua_next(L, -2) != 0) {
|
|
int type = lua_type(L, -2);
|
|
if (type == LUA_TSTRING) {
|
|
const char *s = lua_tolstring(L, -2, nullptr);
|
|
if (loadCommonLayoutItems(L, s, layout)) {
|
|
// do nothing.
|
|
} else if (!strcmp(s, "text")) {
|
|
layout->setText(TeLuaToTeString(L, -1));
|
|
} else if (!strcmp(s, "interLine") || !strcmp(s, "interline")) {
|
|
layout->setInterLine(TeLuaToF32(L, -1));
|
|
} else if (!strcmp(s, "wrapMode")) {
|
|
layout->setWrapMode(static_cast<TeTextBase2::WrapMode>(TeLuaToS32(L, -1)));
|
|
} else if (!strcmp(s, "textSizeType")) {
|
|
layout->setTextSizeType(TeLuaToS32(L, -1));
|
|
} else if (!strcmp(s, "textSizeProportionalToWidth")) {
|
|
layout->setTextSizeProportionalToWidth(TeLuaToS32(L, -1));
|
|
} else if (!strcmp(s, "consoleNoStretch")) {
|
|
warning("TODO: Handle _g_bWidescreen");
|
|
if (_g_bWidescreen) {
|
|
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
|
}
|
|
} else {
|
|
warning("[TeLuaGUI.textLayoutBindings] Unreconized attribute : %s", s);
|
|
}
|
|
} else if (type == LUA_TNUMBER) {
|
|
Te3DObject2 *obj = TeLuaTo<Te3DObject2*>(L, -1);
|
|
layout->addChild(obj);
|
|
}
|
|
lua_settop(L, -2);
|
|
}
|
|
|
|
if (layout->name().empty()) {
|
|
layout->setName(Common::String::format("%p", (void *)layout));
|
|
}
|
|
lua_pushstring(L, "__TeLuaGUIThis");
|
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
|
|
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
|
TeLuaGUI::StringMap<TeTextLayout *> &layouts = gui->textLayouts();
|
|
if (!layouts.contains(layout->name())) {
|
|
layouts.setVal(layout->name(), layout);
|
|
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
|
return true;
|
|
} else {
|
|
warning("textLayoutBindings:: multiple objects with name %s", layout->name().c_str());
|
|
delete layout;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int clipLayoutBindings(lua_State *L) {
|
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
|
warning("clipLayoutBindings:: the lua value is not a table");
|
|
return 0;
|
|
}
|
|
|
|
error("TODO: Implement clipLayoutBindings.");
|
|
}
|
|
|
|
int colorLinearAnimationBindings(lua_State *L) {
|
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
|
warning("colorLinearAnimationBindings:: the lua value is not a table");
|
|
return 0;
|
|
}
|
|
|
|
TeCurveAnim2<Te3DObject2, TeColor> *anim = new TeCurveAnim2<Te3DObject2, TeColor>();
|
|
lua_pushnil(L);
|
|
Common::String name;
|
|
while (lua_next(L, -2) != 0) {
|
|
int type = lua_type(L, -2);
|
|
if (type == LUA_TSTRING) {
|
|
const char *s = lua_tolstring(L, -2, nullptr);
|
|
if (!strcmp(s, "name")) {
|
|
name = TeLuaToTeString(L, -1);
|
|
} else if (!strcmp(s, "duration")) {
|
|
anim->_duration = TeLuaToF32(L, -1);
|
|
} else if (!strcmp(s, "startValue")) {
|
|
anim->_startVal = TeLuaToTeColor(L, -1);
|
|
} else if (!strcmp(s, "endValue")) {
|
|
anim->_endVal = TeLuaToTeColor(L, -1);
|
|
} else if (!strcmp(s, "layout")) {
|
|
} else if (!strcmp(s, "curve")) {
|
|
const Common::Array<float> curve = TeLuaToFloatArray(L, -1);
|
|
anim->setCurve(curve);
|
|
} else {
|
|
error("[TeLuaGUI.colorLinearAnimationBindings] Unreconized attribute : %s", s);
|
|
}
|
|
lua_settop(L, -2);
|
|
}
|
|
}
|
|
|
|
if (name.empty()) {
|
|
name = Common::String::format("%p", (void *)anim);
|
|
}
|
|
anim->_callbackMethod = &Te3DObject2::setColor;
|
|
lua_pushstring(L, "__TeLuaGUIThis");
|
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
|
TeLuaGUI::StringMap<TeCurveAnim2<Te3DObject2, TeColor> *> &anims = gui->colorLinearAnimations();
|
|
if (!anims.contains(name)) {
|
|
anims.setVal(name, anim);
|
|
lua_pushlightuserdata(L, (void *)(anim));
|
|
return true;
|
|
} else {
|
|
warning("colorLinearAnimationBindings:: multiple objects with name %s", name.c_str());
|
|
delete anim;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int rotationLinearAnimationBindings(lua_State *L) {
|
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
|
warning("rotationLinearAnimationBindings:: the lua value is not a table");
|
|
return 0;
|
|
}
|
|
|
|
error("TODO: Implement rotationLinearAnimationBindings.");
|
|
}
|
|
|
|
int scrollingLayoutBindings(lua_State *L) {
|
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
|
warning("scrollingLayoutBindings:: the lua value is not a table");
|
|
return 0;
|
|
}
|
|
|
|
TeScrollingLayout *layout = new TeScrollingLayout();
|
|
lua_pushnil(L);
|
|
while (lua_next(L, -2) != 0) {
|
|
int type = lua_type(L, -2);
|
|
if (type == LUA_TSTRING) {
|
|
const char *s = lua_tolstring(L, -2, nullptr);
|
|
if (loadCommonLayoutItems(L, s, layout)) {
|
|
// do nothing.
|
|
} else if (!strcmp(s, "inertiaAnimationDuration")) {
|
|
layout->setInertiaAnimationDuration(TeLuaToU32(L, -1));
|
|
} else if (!strcmp(s, "inertiaAnimationCurve")) {
|
|
layout->setInertiaAnimationCurve(TeLuaToFloatArray(L, -1));
|
|
} else if (!strcmp(s, "direction")) {
|
|
TeVector3f32 newdir = TeLuaToTeVector3f32(L, -1, layout->direction());
|
|
layout->setDirection(newdir);
|
|
} else if (!strcmp(s, "contentLayout")) {
|
|
layout->setContentLayout(TeLuaTo<TeLayout*>(L, -1));
|
|
} else if (!strcmp(s, "enclose")) {
|
|
layout->setEnclose(TeLuaToBool(L, -1));
|
|
} else if (!strcmp(s, "mouseControl")) {
|
|
layout->setMouseControl(TeLuaToBool(L, -1));
|
|
} else if (!strcmp(s, "autoScrollLoop")) {
|
|
layout->setAutoScrollLoop(TeLuaToS32(L, -1));
|
|
} else if (!strcmp(s, "autoScrollDelay")) {
|
|
layout->setAutoScrollDelay(TeLuaToS32(L, -1));
|
|
} else if (!strcmp(s, "autoScrollAnimation1Enabled")) {
|
|
layout->setAutoScrollAnimation1Enabled(TeLuaToBool(L, -1));
|
|
} else if (!strcmp(s, "autoScrollAnimation1Delay")) {
|
|
layout->setAutoScrollAnimation1Delay(TeLuaToS32(L, -1));
|
|
} else if (!strcmp(s, "autoScrollAnimation1Speed")) {
|
|
layout->setAutoScrollAnimation1Speed(TeLuaToF32(L, -1));
|
|
} else if (!strcmp(s, "autoScrollAnimation1Curve")) {
|
|
layout->setAutoScrollAnimation1Curve(TeLuaToFloatArray(L, -1));
|
|
} else if (!strcmp(s, "autoScrollAnimation2Enabled")) {
|
|
layout->setAutoScrollAnimation2Enabled(TeLuaToBool(L, -1));
|
|
} else if (!strcmp(s, "autoScrollAnimation2Delay")) {
|
|
layout->setAutoScrollAnimation2Delay(TeLuaToS32(L, -1));
|
|
} else if (!strcmp(s, "autoScrollAnimation2Speed")) {
|
|
layout->setAutoScrollAnimation2Speed(TeLuaToF32(L, -1));
|
|
} else if (!strcmp(s, "autoScrollAnimation2Curve")) {
|
|
layout->setAutoScrollAnimation2Curve(TeLuaToFloatArray(L, -1));
|
|
} else if (!strcmp(s, "consoleNoStretch")) {
|
|
warning("TODO: Handle _g_bWidescreen");
|
|
if (_g_bWidescreen) {
|
|
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
|
}
|
|
} else {
|
|
warning("[TeLuaGUI.scrollingLayoutBindings] Unreconized attribute : %s", s);
|
|
}
|
|
} else if (type == LUA_TNUMBER) {
|
|
Te3DObject2 *obj = TeLuaTo<Te3DObject2*>(L, -1);
|
|
layout->addChild(obj);
|
|
}
|
|
lua_settop(L, -2);
|
|
}
|
|
|
|
if (layout->name().empty()) {
|
|
layout->setName(Common::String::format("%p", (void *)layout));
|
|
}
|
|
lua_pushstring(L, "__TeLuaGUIThis");
|
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
|
|
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
|
TeLuaGUI::StringMap<TeScrollingLayout *> &layouts = gui->scrollingLayouts();
|
|
if (!layouts.contains(layout->name())) {
|
|
layouts.setVal(layout->name(), layout);
|
|
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
|
return true;
|
|
} else {
|
|
warning("scrollingLayoutBindings:: multiple objects with name %s", layout->name().c_str());
|
|
delete layout;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int extendedTextLayoutBindings(lua_State *L) {
|
|
if (lua_type(L, -1) != LUA_TTABLE) {
|
|
warning("extendedTextLayoutBindings:: the lua value is not a table");
|
|
return 0;
|
|
}
|
|
|
|
TeExtendedTextLayout *layout = new TeExtendedTextLayout();
|
|
lua_pushnil(L);
|
|
while (lua_next(L, -2) != 0) {
|
|
int type = lua_type(L, -2);
|
|
if (type == LUA_TSTRING) {
|
|
const char *s = lua_tolstring(L, -2, nullptr);
|
|
if (loadCommonLayoutItems(L, s, layout)) {
|
|
// do nothing.
|
|
} else if (!strcmp(s, "text")) {
|
|
layout->setText(TeLuaToTeString(L, -1));
|
|
} else if (!strcmp(s, "interLine") || !strcmp(s, "interline")) {
|
|
layout->setInterLine(TeLuaToF32(L, -1));
|
|
} else if (!strcmp(s, "wrapMode")) {
|
|
layout->setWrapMode(static_cast<TeTextBase2::WrapMode>(TeLuaToS32(L, -1)));
|
|
} else if (!strcmp(s, "autoScrollDelay")) {
|
|
layout->setAutoScrollDelay(TeLuaToS32(L, -1));
|
|
} else if (!strcmp(s, "autoScrollSpeed")) {
|
|
layout->setAutoScrollSpeed(TeLuaToF32(L, -1));
|
|
} else if (!strcmp(s, "textSizeType")) {
|
|
layout->setTextSizeType(TeLuaToS32(L, -1));
|
|
} else if (!strcmp(s, "textSizeProportionalToWidth")) {
|
|
layout->setTextSizeProportionalToWidth(TeLuaToS32(L, -1));
|
|
} else if (!strcmp(s, "consoleNoStretch")) {
|
|
warning("TODO: Handle _g_bWidescreen");
|
|
if (_g_bWidescreen) {
|
|
layout->setScale(TeVector3f32(0.75f, 1.0f, 1.0f));
|
|
}
|
|
} else {
|
|
warning("[TeLuaGUI.textLayoutBindings] Unreconized attribute : %s", s);
|
|
}
|
|
} else if (type == LUA_TNUMBER) {
|
|
Te3DObject2 *obj = TeLuaTo<Te3DObject2*>(L, -1);
|
|
layout->addChild(obj);
|
|
}
|
|
lua_settop(L, -2);
|
|
}
|
|
|
|
if (layout->name().empty()) {
|
|
layout->setName(Common::String::format("%p", (void *)layout));
|
|
}
|
|
lua_pushstring(L, "__TeLuaGUIThis");
|
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
|
|
TeLuaGUI *gui = TeLuaTo<TeLuaGUI*>(L, -1);
|
|
TeLuaGUI::StringMap<TeExtendedTextLayout *> &layouts = gui->extendedTextLayouts();
|
|
if (!layouts.contains(layout->name())) {
|
|
layouts.setVal(layout->name(), layout);
|
|
lua_pushlightuserdata(L, static_cast<Te3DObject2*>(layout));
|
|
return true;
|
|
} else {
|
|
warning("extendedTextLayoutBindings:: multiple objects with name %s", layout->name().c_str());
|
|
delete layout;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
} // end namespace Tetraedge
|