scummvm/engines/sword25/gfx/graphicengine_script.cpp
2011-05-12 01:16:22 +02:00

1204 lines
34 KiB
C++
Raw Blame History

/* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
/*
* This code is based on Broken Sword 2.5 engine
*
* Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
*
* Licensed under GNU GPL v2
*
*/
#include "sword25/kernel/common.h"
#include "sword25/kernel/kernel.h"
#include "sword25/script/script.h"
#include "sword25/script/luabindhelper.h"
#include "sword25/script/luacallback.h"
#include "sword25/math/vertex.h"
#include "sword25/gfx/graphicengine.h"
#include "sword25/gfx/renderobject.h"
#include "sword25/gfx/bitmap.h"
#include "sword25/gfx/animation.h"
#include "sword25/gfx/panel.h"
#include "sword25/gfx/text.h"
#include "sword25/gfx/animationtemplate.h"
#include "sword25/gfx/animationtemplateregistry.h"
namespace Sword25 {
static bool animationDeleteCallback(uint Data);
static bool animationActionCallback(uint Data);
static bool animationLoopPointCallback(uint Data);
namespace {
class ActionCallback : public LuaCallback {
public:
ActionCallback(lua_State *L) : LuaCallback(L) {}
Common::String Action;
protected:
virtual int PreFunctionInvokation(lua_State *L) {
lua_pushstring(L, Action.c_str());
return 1;
}
};
static LuaCallback *loopPointCallbackPtr = 0; // FIXME: should be turned into GraphicEngine member var
static ActionCallback *actionCallbackPtr = 0; // FIXME: should be turned into GraphicEngine member var
}
// Die Strings werden als #defines definiert um Stringkomposition zur Compilezeit zu erm<72>glichen.
#define RENDEROBJECT_CLASS_NAME "Gfx.RenderObject"
#define BITMAP_CLASS_NAME "Gfx.Bitmap"
#define PANEL_CLASS_NAME "Gfx.Panel"
#define TEXT_CLASS_NAME "Gfx.Text"
#define ANIMATION_CLASS_NAME "Gfx.Animation"
#define ANIMATION_TEMPLATE_CLASS_NAME "Gfx.AnimationTemplate"
static const char *GFX_LIBRARY_NAME = "Gfx";
static void newUintUserData(lua_State *L, uint value) {
void *userData = lua_newuserdata(L, sizeof(value));
memcpy(userData, &value, sizeof(value));
}
static AnimationTemplate *checkAnimationTemplate(lua_State *L, int idx = 1) {
// Der erste Parameter muss vom Typ userdata sein und die Metatable der Klasse Gfx.AnimationTemplate
uint animationTemplateHandle = *reinterpret_cast<uint *>(LuaBindhelper::my_checkudata(L, idx, ANIMATION_TEMPLATE_CLASS_NAME));
if (animationTemplateHandle != 0) {
AnimationTemplate *animationTemplatePtr = AnimationTemplateRegistry::instance().resolveHandle(animationTemplateHandle);
if (!animationTemplatePtr)
luaL_error(L, "The animation template with the handle %d does no longer exist.", animationTemplateHandle);
return animationTemplatePtr;
} else {
luaL_argcheck(L, 0, idx, "'" ANIMATION_TEMPLATE_CLASS_NAME "' expected");
return 0;
}
}
static int newAnimationTemplate(lua_State *L) {
uint animationTemplateHandle = AnimationTemplate::create(luaL_checkstring(L, 1));
AnimationTemplate *animationTemplatePtr = AnimationTemplateRegistry::instance().resolveHandle(animationTemplateHandle);
if (animationTemplatePtr && animationTemplatePtr->isValid()) {
newUintUserData(L, animationTemplateHandle);
//luaL_getmetatable(L, ANIMATION_TEMPLATE_CLASS_NAME);
LuaBindhelper::getMetatable(L, ANIMATION_TEMPLATE_CLASS_NAME);
assert(!lua_isnil(L, -1));
lua_setmetatable(L, -2);
} else {
lua_pushnil(L);
}
return 1;
}
static int at_addFrame(lua_State *L) {
AnimationTemplate *pAT = checkAnimationTemplate(L);
pAT->addFrame(static_cast<int>(luaL_checknumber(L, 2)));
return 0;
}
static int at_setFrame(lua_State *L) {
AnimationTemplate *pAT = checkAnimationTemplate(L);
pAT->setFrame(static_cast<int>(luaL_checknumber(L, 2)), static_cast<int>(luaL_checknumber(L, 3)));
return 0;
}
static bool animationTypeStringToNumber(const char *typeString, Animation::ANIMATION_TYPES &result) {
if (strcmp(typeString, "jojo") == 0) {
result = Animation::AT_JOJO;
return true;
} else if (strcmp(typeString, "loop") == 0) {
result = Animation::AT_LOOP;
return true;
} else if (strcmp(typeString, "oneshot") == 0) {
result = Animation::AT_ONESHOT;
return true;
} else
return false;
}
static int at_setAnimationType(lua_State *L) {
AnimationTemplate *pAT = checkAnimationTemplate(L);
Animation::ANIMATION_TYPES animationType;
if (animationTypeStringToNumber(luaL_checkstring(L, 2), animationType)) {
pAT->setAnimationType(animationType);
} else {
luaL_argcheck(L, 0, 2, "Invalid animation type");
}
return 0;
}
static int at_setFPS(lua_State *L) {
AnimationTemplate *pAT = checkAnimationTemplate(L);
pAT->setFPS(static_cast<int>(luaL_checknumber(L, 2)));
return 0;
}
static int at_finalize(lua_State *L) {
AnimationTemplate *pAT = checkAnimationTemplate(L);
delete pAT;
return 0;
}
static const luaL_reg ANIMATION_TEMPLATE_METHODS[] = {
{"AddFrame", at_addFrame},
{"SetFrame", at_setFrame},
{"SetAnimationType", at_setAnimationType},
{"SetFPS", at_setFPS},
{"__gc", at_finalize},
{0, 0}
};
static GraphicEngine *getGE() {
Kernel *pKernel = Kernel::getInstance();
assert(pKernel);
GraphicEngine *pGE = pKernel->getGfx();
assert(pGE);
return pGE;
}
static int init(lua_State *L) {
GraphicEngine *pGE = getGE();
switch (lua_gettop(L)) {
case 0:
lua_pushbooleancpp(L, pGE->init());
break;
case 1:
lua_pushbooleancpp(L, pGE->init(static_cast<int>(luaL_checknumber(L, 1))));
break;
case 2:
lua_pushbooleancpp(L, pGE->init(static_cast<int>(luaL_checknumber(L, 1)), static_cast<int>(luaL_checknumber(L, 2))));
break;
case 3:
lua_pushbooleancpp(L, pGE->init(static_cast<int>(luaL_checknumber(L, 1)), static_cast<int>(luaL_checknumber(L, 2)),
static_cast<int>(luaL_checknumber(L, 3))));
break;
case 4:
default:
lua_pushbooleancpp(L, pGE->init(static_cast<int>(luaL_checknumber(L, 1)), static_cast<int>(luaL_checknumber(L, 2)),
static_cast<int>(luaL_checknumber(L, 3)), static_cast<int>(luaL_checknumber(L, 4))));
break;
}
#ifdef DEBUG
int __startStackDepth = lua_gettop(L);
#endif
// Main-Panel zum Gfx-Modul hinzuf<75>gen
RenderObjectPtr<Panel> mainPanelPtr(getGE()->getMainPanel());
assert(mainPanelPtr.isValid());
lua_pushstring(L, GFX_LIBRARY_NAME);
lua_gettable(L, LUA_GLOBALSINDEX);
assert(!lua_isnil(L, -1));
newUintUserData(L, mainPanelPtr->getHandle());
assert(!lua_isnil(L, -1));
// luaL_getmetatable(L, PANEL_CLASS_NAME);
LuaBindhelper::getMetatable(L, PANEL_CLASS_NAME);
assert(!lua_isnil(L, -1));
lua_setmetatable(L, -2);
lua_pushstring(L, "MainPanel");
lua_insert(L, -2);
lua_settable(L, -3);
lua_pop(L, 1);
#ifdef DEBUG
assert(__startStackDepth == lua_gettop(L));
#endif
return 1;
}
static int startFrame(lua_State *L) {
GraphicEngine *pGE = getGE();
if (lua_gettop(L) == 0)
lua_pushbooleancpp(L, pGE->startFrame());
else
lua_pushbooleancpp(L, pGE->startFrame(lua_tobooleancpp(L, 1)));
return 1;
}
static int endFrame(lua_State *L) {
GraphicEngine *pGE = getGE();
lua_pushbooleancpp(L, pGE->endFrame());
return 1;
}
static int getBitDepth(lua_State *L) {
GraphicEngine *pGE = getGE();
lua_pushnumber(L, pGE->getBitDepth());
return 1;
}
static int setVsync(lua_State *L) {
GraphicEngine *pGE = getGE();
pGE->setVsync(lua_tobooleancpp(L, 1));
return 0;
}
static int isVsync(lua_State *L) {
GraphicEngine *pGE = getGE();
lua_pushbooleancpp(L, pGE->getVsync());
return 1;
}
static int getLastFrameDuration(lua_State *L) {
GraphicEngine *pGE = getGE();
lua_pushnumber(L, pGE->getLastFrameDuration());
return 1;
}
static int stopMainTimer(lua_State *L) {
GraphicEngine *pGE = getGE();
pGE->stopMainTimer();
return 0;
}
static int resumeMainTimer(lua_State *L) {
GraphicEngine *pGE = getGE();
pGE->resumeMainTimer();
return 0;
}
static int getSecondaryFrameDuration(lua_State *L) {
GraphicEngine *pGE = getGE();
lua_pushnumber(L, pGE->getSecondaryFrameDuration());
return 1;
}
static int saveThumbnailScreenshot(lua_State *L) {
GraphicEngine *pGE = getGE();
lua_pushbooleancpp(L, pGE->saveThumbnailScreenshot(luaL_checkstring(L, 1)));
return 1;
}
// Marks a function that should never be used
static int dummyFuncError(lua_State *L) {
error("Dummy function invoked by LUA");
return 1;
}
static const luaL_reg GFX_FUNCTIONS[] = {
{"Init", init},
{"StartFrame", startFrame},
{"EndFrame", endFrame},
{"DrawDebugLine", dummyFuncError},
{"SetVsync", setVsync},
{"GetDisplayWidth", dummyFuncError},
{"GetDisplayHeight", dummyFuncError},
{"GetBitDepth", getBitDepth},
{"IsVsync", isVsync},
{"IsWindowed", dummyFuncError},
{"GetFPSCount", dummyFuncError},
{"GetLastFrameDuration", getLastFrameDuration},
{"StopMainTimer", stopMainTimer},
{"ResumeMainTimer", resumeMainTimer},
{"GetSecondaryFrameDuration", getSecondaryFrameDuration},
{"SaveScreenshot", dummyFuncError},
{"NewAnimationTemplate", newAnimationTemplate},
{"GetRepaintedPixels", dummyFuncError},
{"SaveThumbnailScreenshot", saveThumbnailScreenshot},
{0, 0}
};
static RenderObjectPtr<RenderObject> checkRenderObject(lua_State *L, bool errorIfRemoved = true) {
// Der erste Parameter muss vom Typ userdata sein und die Metatable einer Klasse haben, die von Gfx.RenderObject "erbt".
uint *userDataPtr;
if ((userDataPtr = (uint *)LuaBindhelper::my_checkudata(L, 1, BITMAP_CLASS_NAME)) != 0 ||
(userDataPtr = (uint *)LuaBindhelper::my_checkudata(L, 1, ANIMATION_CLASS_NAME)) != 0 ||
(userDataPtr = (uint *)LuaBindhelper::my_checkudata(L, 1, PANEL_CLASS_NAME)) != 0 ||
(userDataPtr = (uint *)LuaBindhelper::my_checkudata(L, 1, TEXT_CLASS_NAME)) != 0) {
RenderObjectPtr<RenderObject> roPtr(*userDataPtr);
if (roPtr.isValid())
return roPtr;
else {
if (errorIfRemoved)
luaL_error(L, "The renderobject with the handle %d does no longer exist.", *userDataPtr);
}
} else {
luaL_argcheck(L, 0, 1, "'" RENDEROBJECT_CLASS_NAME "' expected");
}
return RenderObjectPtr<RenderObject>();
}
static int ro_setPos(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
Vertex pos;
Vertex::luaVertexToVertex(L, 2, pos);
roPtr->setPos(pos.x, pos.y);
return 0;
}
static int ro_setX(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
roPtr->setX(static_cast<int>(luaL_checknumber(L, 2)));
return 0;
}
static int ro_setY(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
roPtr->setY(static_cast<int>(luaL_checknumber(L, 2)));
return 0;
}
static int ro_setZ(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
roPtr->setZ(static_cast<int>(luaL_checknumber(L, 2)));
return 0;
}
static int ro_setVisible(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
roPtr->setVisible(lua_tobooleancpp(L, 2));
return 0;
}
static int ro_getX(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
lua_pushnumber(L, roPtr->getX());
return 1;
}
static int ro_getY(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
lua_pushnumber(L, roPtr->getY());
return 1;
}
static int ro_getZ(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
lua_pushnumber(L, roPtr->getZ());
return 1;
}
static int ro_getAbsoluteX(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
lua_pushnumber(L, roPtr->getAbsoluteX());
return 1;
}
static int ro_getAbsoluteY(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
lua_pushnumber(L, roPtr->getAbsoluteY());
return 1;
}
static int ro_getWidth(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
lua_pushnumber(L, roPtr->getWidth());
return 1;
}
static int ro_getHeight(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
lua_pushnumber(L, roPtr->getHeight());
return 1;
}
static int ro_isVisible(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
lua_pushbooleancpp(L, roPtr->isVisible());
return 1;
}
static int ro_addPanel(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
RenderObjectPtr<Panel> panelPtr = roPtr->addPanel(static_cast<int>(luaL_checknumber(L, 2)),
static_cast<int>(luaL_checknumber(L, 3)),
GraphicEngine::luaColorToARGBColor(L, 4));
if (panelPtr.isValid()) {
newUintUserData(L, panelPtr->getHandle());
// luaL_getmetatable(L, PANEL_CLASS_NAME);
LuaBindhelper::getMetatable(L, PANEL_CLASS_NAME);
assert(!lua_isnil(L, -1));
lua_setmetatable(L, -2);
} else
lua_pushnil(L);
return 1;
}
static int ro_addBitmap(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
RenderObjectPtr<Bitmap> bitmaPtr = roPtr->addBitmap(luaL_checkstring(L, 2));
if (bitmaPtr.isValid()) {
newUintUserData(L, bitmaPtr->getHandle());
// luaL_getmetatable(L, BITMAP_CLASS_NAME);
LuaBindhelper::getMetatable(L, BITMAP_CLASS_NAME);
assert(!lua_isnil(L, -1));
lua_setmetatable(L, -2);
} else
lua_pushnil(L);
return 1;
}
static int ro_addText(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
RenderObjectPtr<Text> textPtr;
if (lua_gettop(L) >= 3)
textPtr = roPtr->addText(luaL_checkstring(L, 2), luaL_checkstring(L, 3));
else
textPtr = roPtr->addText(luaL_checkstring(L, 2));
if (textPtr.isValid()) {
newUintUserData(L, textPtr->getHandle());
// luaL_getmetatable(L, TEXT_CLASS_NAME);
LuaBindhelper::getMetatable(L, TEXT_CLASS_NAME);
assert(!lua_isnil(L, -1));
lua_setmetatable(L, -2);
} else
lua_pushnil(L);
return 1;
}
static int ro_addAnimation(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
RenderObjectPtr<Animation> animationPtr;
if (lua_type(L, 2) == LUA_TUSERDATA)
animationPtr = roPtr->addAnimation(*checkAnimationTemplate(L, 2));
else
animationPtr = roPtr->addAnimation(luaL_checkstring(L, 2));
if (animationPtr.isValid()) {
newUintUserData(L, animationPtr->getHandle());
// luaL_getmetatable(L, ANIMATION_CLASS_NAME);
LuaBindhelper::getMetatable(L, ANIMATION_CLASS_NAME);
assert(!lua_isnil(L, -1));
lua_setmetatable(L, -2);
// Alle Animationscallbacks registrieren.
animationPtr->setCallbacks();
} else
lua_pushnil(L);
return 1;
}
void Animation::setCallbacks() {
_actionCallback = animationActionCallback;
_loopPointCallback = animationLoopPointCallback;
_deleteCallback = animationDeleteCallback;
}
static const luaL_reg RENDEROBJECT_METHODS[] = {
{"AddAnimation", ro_addAnimation},
{"AddText", ro_addText},
{"AddBitmap", ro_addBitmap},
{"AddPanel", ro_addPanel},
{"SetPos", ro_setPos},
{"SetX", ro_setX},
{"SetY", ro_setY},
{"SetZ", ro_setZ},
{"SetVisible", ro_setVisible},
{"GetX", ro_getX},
{"GetY", ro_getY},
{"GetZ", ro_getZ},
{"GetAbsoluteX", ro_getAbsoluteX},
{"GetAbsoluteY", ro_getAbsoluteY},
{"GetWidth", ro_getWidth},
{"GetHeight", ro_getHeight},
{"IsVisible", ro_isVisible},
{0, 0}
};
static RenderObjectPtr<Panel> checkPanel(lua_State *L) {
// Der erste Parameter muss vom Typ userdata sein und die Metatable der Klasse Gfx.Panel
uint *userDataPtr;
if ((userDataPtr = (uint *)LuaBindhelper::my_checkudata(L, 1, PANEL_CLASS_NAME)) != 0) {
RenderObjectPtr<RenderObject> roPtr(*userDataPtr);
if (roPtr.isValid())
return roPtr->toPanel();
else
luaL_error(L, "The panel with the handle %d does no longer exist.", *userDataPtr);
} else {
luaL_argcheck(L, 0, 1, "'" PANEL_CLASS_NAME "' expected");
}
return RenderObjectPtr<Panel>();
}
static int p_getColor(lua_State *L) {
RenderObjectPtr<Panel> PanelPtr = checkPanel(L);
assert(PanelPtr.isValid());
GraphicEngine::ARGBColorToLuaColor(L, PanelPtr->getColor());
return 1;
}
static int p_setColor(lua_State *L) {
RenderObjectPtr<Panel> PanelPtr = checkPanel(L);
assert(PanelPtr.isValid());
PanelPtr->setColor(GraphicEngine::luaColorToARGBColor(L, 2));
return 0;
}
static int p_remove(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
roPtr.erase();
return 0;
}
static const luaL_reg PANEL_METHODS[] = {
{"GetColor", p_getColor},
{"SetColor", p_setColor},
{"Remove", p_remove},
{0, 0}
};
static RenderObjectPtr<Bitmap> checkBitmap(lua_State *L) {
// Der erste Parameter muss vom Typ userdata sein und die Metatable der Klasse Gfx.Bitmap
uint *userDataPtr;
if ((userDataPtr = (uint *)LuaBindhelper::my_checkudata(L, 1, BITMAP_CLASS_NAME)) != 0) {
RenderObjectPtr<RenderObject> roPtr(*userDataPtr);
if (roPtr.isValid())
return roPtr->toBitmap();
else
luaL_error(L, "The bitmap with the handle %d does no longer exist.", *userDataPtr);
} else {
luaL_argcheck(L, 0, 1, "'" BITMAP_CLASS_NAME "' expected");
}
return RenderObjectPtr<Bitmap>();
}
static int b_setAlpha(lua_State *L) {
RenderObjectPtr<Bitmap> bitmapPtr = checkBitmap(L);
assert(bitmapPtr.isValid());
bitmapPtr->setAlpha(static_cast<uint>(luaL_checknumber(L, 2)));
return 0;
}
static int b_setTintColor(lua_State *L) {
RenderObjectPtr<Bitmap> bitmapPtr = checkBitmap(L);
assert(bitmapPtr.isValid());
bitmapPtr->setModulationColor(GraphicEngine::luaColorToARGBColor(L, 2));
return 0;
}
static int b_setScaleFactor(lua_State *L) {
RenderObjectPtr<Bitmap> bitmapPtr = checkBitmap(L);
assert(bitmapPtr.isValid());
bitmapPtr->setScaleFactor(static_cast<float>(luaL_checknumber(L, 2)));
return 0;
}
static int b_setScaleFactorX(lua_State *L) {
RenderObjectPtr<Bitmap> bitmapPtr = checkBitmap(L);
assert(bitmapPtr.isValid());
bitmapPtr->setScaleFactorX(static_cast<float>(luaL_checknumber(L, 2)));
return 0;
}
static int b_setScaleFactorY(lua_State *L) {
RenderObjectPtr<Bitmap> bitmapPtr = checkBitmap(L);
assert(bitmapPtr.isValid());
bitmapPtr->setScaleFactorY(static_cast<float>(luaL_checknumber(L, 2)));
return 0;
}
static int b_setFlipH(lua_State *L) {
RenderObjectPtr<Bitmap> bitmapPtr = checkBitmap(L);
assert(bitmapPtr.isValid());
bitmapPtr->setFlipH(lua_tobooleancpp(L, 2));
return 0;
}
static int b_setFlipV(lua_State *L) {
RenderObjectPtr<Bitmap> bitmapPtr = checkBitmap(L);
assert(bitmapPtr.isValid());
bitmapPtr->setFlipV(lua_tobooleancpp(L, 2));
return 0;
}
static int b_getAlpha(lua_State *L) {
RenderObjectPtr<Bitmap> bitmapPtr = checkBitmap(L);
assert(bitmapPtr.isValid());
lua_pushnumber(L, bitmapPtr->getAlpha());
return 1;
}
static int b_getTintColor(lua_State *L) {
RenderObjectPtr<Bitmap> bitmapPtr = checkBitmap(L);
assert(bitmapPtr.isValid());
GraphicEngine::ARGBColorToLuaColor(L, bitmapPtr->getModulationColor());
return 1;
}
static int b_getScaleFactorX(lua_State *L) {
RenderObjectPtr<Bitmap> bitmapPtr = checkBitmap(L);
assert(bitmapPtr.isValid());
lua_pushnumber(L, bitmapPtr->getScaleFactorX());
return 1;
}
static int b_getScaleFactorY(lua_State *L) {
RenderObjectPtr<Bitmap> bitmapPtr = checkBitmap(L);
assert(bitmapPtr.isValid());
lua_pushnumber(L, bitmapPtr->getScaleFactorY());
return 1;
}
static int b_isFlipH(lua_State *L) {
RenderObjectPtr<Bitmap> bitmapPtr = checkBitmap(L);
assert(bitmapPtr.isValid());
lua_pushbooleancpp(L, bitmapPtr->isFlipH());
return 1;
}
static int b_isFlipV(lua_State *L) {
RenderObjectPtr<Bitmap> bitmapPtr = checkBitmap(L);
assert(bitmapPtr.isValid());
lua_pushbooleancpp(L, bitmapPtr->isFlipV());
return 1;
}
static int b_getPixel(lua_State *L) {
RenderObjectPtr<Bitmap> bitmapPtr = checkBitmap(L);
assert(bitmapPtr.isValid());
Vertex Pos;
Vertex::luaVertexToVertex(L, 2, Pos);
GraphicEngine::ARGBColorToLuaColor(L, bitmapPtr->getPixel(Pos.x, Pos.y));
return 1;
}
static int b_remove(lua_State *L) {
RenderObjectPtr<RenderObject> roPtr = checkRenderObject(L);
assert(roPtr.isValid());
roPtr.erase();
return 0;
}
static const luaL_reg BITMAP_METHODS[] = {
{"SetAlpha", b_setAlpha},
{"SetTintColor", b_setTintColor},
{"SetScaleFactor", b_setScaleFactor},
{"SetScaleFactorX", b_setScaleFactorX},
{"SetScaleFactorY", b_setScaleFactorY},
{"SetFlipH", b_setFlipH},
{"SetFlipV", b_setFlipV},
{"GetAlpha", b_getAlpha},
{"GetTintColor", b_getTintColor},
{"GetScaleFactorX", b_getScaleFactorX},
{"GetScaleFactorY", b_getScaleFactorY},
{"IsFlipH", b_isFlipH},
{"IsFlipV", b_isFlipV},
{"GetPixel", b_getPixel},
{"IsScalingAllowed", dummyFuncError},
{"IsAlphaAllowed", dummyFuncError},
{"IsTintingAllowed", dummyFuncError},
{"Remove", b_remove},
{0, 0}
};
static RenderObjectPtr<Animation> checkAnimation(lua_State *L) {
// Der erste Parameter muss vom Typ userdata sein und die Metatable der Klasse Gfx.Animation
uint *userDataPtr;
if ((userDataPtr = (uint *)LuaBindhelper::my_checkudata(L, 1, ANIMATION_CLASS_NAME)) != 0) {
RenderObjectPtr<RenderObject> roPtr(*userDataPtr);
if (roPtr.isValid())
return roPtr->toAnimation();
else
luaL_error(L, "The animation with the handle %d does no longer exist.", *userDataPtr);
} else {
luaL_argcheck(L, 0, 1, "'" ANIMATION_CLASS_NAME "' expected");
}
return RenderObjectPtr<Animation>();
}
static int a_play(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
animationPtr->play();
return 0;
}
static int a_pause(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
animationPtr->pause();
return 0;
}
static int a_stop(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
animationPtr->stop();
return 0;
}
static int a_setFrame(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
animationPtr->setFrame(static_cast<uint>(luaL_checknumber(L, 2)));
return 0;
}
static int a_setAlpha(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
animationPtr->setAlpha(static_cast<int>(luaL_checknumber(L, 2)));
return 0;
}
static int a_setTintColor(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
animationPtr->setModulationColor(GraphicEngine::luaColorToARGBColor(L, 2));
return 0;
}
static int a_setScaleFactor(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
animationPtr->setScaleFactor(static_cast<float>(luaL_checknumber(L, 2)));
return 0;
}
static int a_setScaleFactorX(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
animationPtr->setScaleFactorX(static_cast<float>(luaL_checknumber(L, 2)));
return 0;
}
static int a_setScaleFactorY(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
animationPtr->setScaleFactorY(static_cast<float>(luaL_checknumber(L, 2)));
return 0;
}
static int a_getScaleFactorX(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
lua_pushnumber(L, animationPtr->getScaleFactorX());
return 1;
}
static int a_getScaleFactorY(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
lua_pushnumber(L, animationPtr->getScaleFactorY());
return 1;
}
static int a_getAnimationType(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
switch (animationPtr->getAnimationType()) {
case Animation::AT_JOJO:
lua_pushstring(L, "jojo");
break;
case Animation::AT_LOOP:
lua_pushstring(L, "loop");
break;
case Animation::AT_ONESHOT:
lua_pushstring(L, "oneshot");
break;
default:
assert(false);
}
return 1;
}
static int a_getFPS(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
lua_pushnumber(L, animationPtr->getFPS());
return 1;
}
static int a_getFrameCount(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
lua_pushnumber(L, animationPtr->getFrameCount());
return 1;
}
static int a_isScalingAllowed(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
lua_pushbooleancpp(L, animationPtr->isScalingAllowed());
return 1;
}
static int a_isAlphaAllowed(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
lua_pushbooleancpp(L, animationPtr->isAlphaAllowed());
return 1;
}
static int a_isTintingAllowed(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
lua_pushbooleancpp(L, animationPtr->isColorModulationAllowed());
return 1;
}
static int a_getCurrentFrame(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
lua_pushnumber(L, animationPtr->getCurrentFrame());
return 1;
}
static int a_getCurrentAction(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
lua_pushstring(L, animationPtr->getCurrentAction().c_str());
return 1;
}
static int a_isPlaying(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
lua_pushbooleancpp(L, animationPtr->isRunning());
return 1;
}
static bool animationLoopPointCallback(uint handle) {
lua_State *L = static_cast<lua_State *>(Kernel::getInstance()->getScript()->getScriptObject());
loopPointCallbackPtr->invokeCallbackFunctions(L, handle);
return true;
}
static int a_registerLoopPointCallback(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
luaL_checktype(L, 2, LUA_TFUNCTION);
lua_pushvalue(L, 2);
loopPointCallbackPtr->registerCallbackFunction(L, animationPtr->getHandle());
return 0;
}
static int a_unregisterLoopPointCallback(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
luaL_checktype(L, 2, LUA_TFUNCTION);
lua_pushvalue(L, 2);
loopPointCallbackPtr->unregisterCallbackFunction(L, animationPtr->getHandle());
return 0;
}
static bool animationActionCallback(uint Handle) {
RenderObjectPtr<Animation> animationPtr(Handle);
if (animationPtr.isValid()) {
actionCallbackPtr->Action = animationPtr->getCurrentAction();
lua_State *L = static_cast<lua_State *>(Kernel::getInstance()->getScript()->getScriptObject());
actionCallbackPtr->invokeCallbackFunctions(L, animationPtr->getHandle());
}
return true;
}
static int a_registerActionCallback(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
luaL_checktype(L, 2, LUA_TFUNCTION);
lua_pushvalue(L, 2);
actionCallbackPtr->registerCallbackFunction(L, animationPtr->getHandle());
return 0;
}
static int a_unregisterActionCallback(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
luaL_checktype(L, 2, LUA_TFUNCTION);
lua_pushvalue(L, 2);
actionCallbackPtr->unregisterCallbackFunction(L, animationPtr->getHandle());
return 0;
}
static bool animationDeleteCallback(uint Handle) {
lua_State *L = static_cast<lua_State *>(Kernel::getInstance()->getScript()->getScriptObject());
loopPointCallbackPtr->removeAllObjectCallbacks(L, Handle);
return true;
}
static int a_remove(lua_State *L) {
RenderObjectPtr<Animation> animationPtr = checkAnimation(L);
assert(animationPtr.isValid());
animationPtr.erase();
return 0;
}
static const luaL_reg ANIMATION_METHODS[] = {
{"Play", a_play},
{"Pause", a_pause},
{"Stop", a_stop},
{"SetFrame", a_setFrame},
{"SetAlpha", a_setAlpha},
{"SetTintColor", a_setTintColor},
{"SetScaleFactor", a_setScaleFactor},
{"SetScaleFactorX", a_setScaleFactorX},
{"SetScaleFactorY", a_setScaleFactorY},
{"GetScaleFactorX", a_getScaleFactorX},
{"GetScaleFactorY", a_getScaleFactorY},
{"GetAnimationType", a_getAnimationType},
{"GetFPS", a_getFPS},
{"GetFrameCount", a_getFrameCount},
{"IsScalingAllowed", a_isScalingAllowed},
{"IsAlphaAllowed", a_isAlphaAllowed},
{"IsTintingAllowed", a_isTintingAllowed},
{"GetCurrentFrame", a_getCurrentFrame},
{"GetCurrentAction", a_getCurrentAction},
{"IsPlaying", a_isPlaying},
{"RegisterLoopPointCallback", a_registerLoopPointCallback},
{"UnregisterLoopPointCallback", a_unregisterLoopPointCallback},
{"RegisterActionCallback", a_registerActionCallback},
{"UnregisterActionCallback", a_unregisterActionCallback},
{"Remove", a_remove},
{0, 0}
};
static RenderObjectPtr<Text> checkText(lua_State *L) {
// Der erste Parameter muss vom Typ userdata sein und die Metatable der Klasse Gfx.Text
uint *userDataPtr;
if ((userDataPtr = (uint *)LuaBindhelper::my_checkudata(L, 1, TEXT_CLASS_NAME)) != 0) {
RenderObjectPtr<RenderObject> roPtr(*userDataPtr);
if (roPtr.isValid())
return roPtr->toText();
else
luaL_error(L, "The text with the handle %d does no longer exist.", *userDataPtr);
} else {
luaL_argcheck(L, 0, 1, "'" TEXT_CLASS_NAME "' expected");
}
return RenderObjectPtr<Text>();
}
static int t_setFont(lua_State *L) {
RenderObjectPtr<Text> textPtr = checkText(L);
assert(textPtr.isValid());
textPtr->setFont(luaL_checkstring(L, 2));
return 0;
}
static int t_setText(lua_State *L) {
RenderObjectPtr<Text> textPtr = checkText(L);
assert(textPtr.isValid());
textPtr->setText(luaL_checkstring(L, 2));
return 0;
}
static int t_setAlpha(lua_State *L) {
RenderObjectPtr<Text> textPtr = checkText(L);
assert(textPtr.isValid());
textPtr->setAlpha(static_cast<int>(luaL_checknumber(L, 2)));
return 0;
}
static int t_setColor(lua_State *L) {
RenderObjectPtr<Text> textPtr = checkText(L);
assert(textPtr.isValid());
textPtr->setColor(GraphicEngine::luaColorToARGBColor(L, 2));
return 0;
}
static int t_setAutoWrap(lua_State *L) {
RenderObjectPtr<Text> textPtr = checkText(L);
assert(textPtr.isValid());
textPtr->setAutoWrap(lua_tobooleancpp(L, 2));
return 0;
}
static int t_setAutoWrapThreshold(lua_State *L) {
RenderObjectPtr<Text> textPtr = checkText(L);
assert(textPtr.isValid());
textPtr->setAutoWrapThreshold(static_cast<uint>(luaL_checknumber(L, 2)));
return 0;
}
static int t_getText(lua_State *L) {
RenderObjectPtr<Text> textPtr = checkText(L);
assert(textPtr.isValid());
lua_pushstring(L, textPtr->getText().c_str());
return 1;
}
static int t_getFont(lua_State *L) {
RenderObjectPtr<Text> textPtr = checkText(L);
assert(textPtr.isValid());
lua_pushstring(L, textPtr->getFont().c_str());
return 1;
}
static int t_getAlpha(lua_State *L) {
RenderObjectPtr<Text> textPtr = checkText(L);
assert(textPtr.isValid());
lua_pushnumber(L, textPtr->getAlpha());
return 1;
}
static int t_getColor(lua_State *L) {
RenderObjectPtr<Text> textPtr = checkText(L);
assert(textPtr.isValid());
lua_pushnumber(L, textPtr->getColor());
return 1;
}
static int t_isAutoWrap(lua_State *L) {
RenderObjectPtr<Text> textPtr = checkText(L);
assert(textPtr.isValid());
lua_pushbooleancpp(L, textPtr->isAutoWrapActive());
return 1;
}
static int t_getAutoWrapThreshold(lua_State *L) {
RenderObjectPtr<Text> textPtr = checkText(L);
assert(textPtr.isValid());
lua_pushnumber(L, textPtr->getAutoWrapThreshold());
return 1;
}
static int t_remove(lua_State *L) {
RenderObjectPtr<Text> textPtr = checkText(L);
assert(textPtr.isValid());
textPtr.erase();
return 0;
}
static const luaL_reg TEXT_METHODS[] = {
{"SetFont", t_setFont},
{"SetText", t_setText},
{"SetAlpha", t_setAlpha},
{"SetColor", t_setColor},
{"SetAutoWrap", t_setAutoWrap},
{"SetAutoWrapThreshold", t_setAutoWrapThreshold},
{"GetText", t_getText},
{"GetFont", t_getFont},
{"GetAlpha", t_getAlpha},
{"GetColor", t_getColor},
{"IsAutoWrap", t_isAutoWrap},
{"GetAutoWrapThreshold", t_getAutoWrapThreshold},
{"Remove", t_remove},
{0, 0}
};
bool GraphicEngine::registerScriptBindings() {
Kernel *pKernel = Kernel::getInstance();
assert(pKernel);
ScriptEngine *pScript = pKernel->getScript();
assert(pScript);
lua_State *L = static_cast<lua_State *>(pScript->getScriptObject());
assert(L);
if (!LuaBindhelper::addMethodsToClass(L, BITMAP_CLASS_NAME, RENDEROBJECT_METHODS)) return false;
if (!LuaBindhelper::addMethodsToClass(L, ANIMATION_CLASS_NAME, RENDEROBJECT_METHODS)) return false;
if (!LuaBindhelper::addMethodsToClass(L, PANEL_CLASS_NAME, RENDEROBJECT_METHODS)) return false;
if (!LuaBindhelper::addMethodsToClass(L, TEXT_CLASS_NAME, RENDEROBJECT_METHODS)) return false;
if (!LuaBindhelper::addMethodsToClass(L, PANEL_CLASS_NAME, PANEL_METHODS)) return false;
if (!LuaBindhelper::addMethodsToClass(L, BITMAP_CLASS_NAME, BITMAP_METHODS)) return false;
if (!LuaBindhelper::addMethodsToClass(L, TEXT_CLASS_NAME, TEXT_METHODS)) return false;
if (!LuaBindhelper::addMethodsToClass(L, ANIMATION_CLASS_NAME, ANIMATION_METHODS)) return false;
if (!LuaBindhelper::addMethodsToClass(L, ANIMATION_TEMPLATE_CLASS_NAME, ANIMATION_TEMPLATE_METHODS)) return false;
if (!LuaBindhelper::addFunctionsToLib(L, GFX_LIBRARY_NAME, GFX_FUNCTIONS)) return false;
assert(loopPointCallbackPtr == 0);
loopPointCallbackPtr = new LuaCallback(L);
assert(actionCallbackPtr == 0);
actionCallbackPtr = new ActionCallback(L);
return true;
}
void GraphicEngine::unregisterScriptBindings() {
delete loopPointCallbackPtr;
loopPointCallbackPtr = 0;
delete actionCallbackPtr;
actionCallbackPtr = 0;
}
} // End of namespace Sword25