scummvm/engines/grim/lua_v1_graphics.cpp
Paweł Kołodziejski 06902574b4
GRIM: Janitorial
2022-06-08 01:12:00 +02:00

561 lines
15 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 "engines/grim/grim.h"
#include "engines/grim/lua_v1.h"
#include "engines/grim/resource.h"
#include "engines/grim/bitmap.h"
#include "engines/grim/primitives.h"
#include "engines/grim/iris.h"
#include "engines/grim/gfx_base.h"
#include "engines/grim/set.h"
#include "engines/grim/actor.h"
#include "engines/grim/movie/movie.h"
#include "engines/grim/lua/lua.h"
namespace Grim {
void Lua_V1::GetImage() {
lua_Object nameObj = lua_getparam(1);
if (!lua_isstring(nameObj)) {
lua_pushnil();
return;
}
const char *bitmapName = lua_getstring(nameObj);
Bitmap *b = Bitmap::create(bitmapName);
lua_pushusertag(b->getId(), MKTAG('V','B','U','F'));
}
void Lua_V1::FreeImage() {
lua_Object param = lua_getparam(1);
if (!lua_isuserdata(param) || lua_tag(param) != MKTAG('V','B','U','F'))
return;
Bitmap *bitmap = getbitmap(param);
delete bitmap;
}
void Lua_V1::BlastImage() {
lua_Object param = lua_getparam(1);
if (!lua_isuserdata(param) || lua_tag(param) != MKTAG('V','B','U','F'))
return;
Bitmap *bitmap = getbitmap(param);
lua_Object xObj = lua_getparam(2);
lua_Object yObj = lua_getparam(3);
if (!lua_isnumber(xObj) || !lua_isnumber(yObj))
return;
int x = (int)lua_getnumber(xObj);
int y = (int)lua_getnumber(yObj);
//bool transparent = getbool(4); // TODO transparent/masked copy into display
bitmap->draw(x, y);
}
void Lua_V1::CleanBuffer() {
g_driver->copyStoredToDisplay();
}
void Lua_V1::StartFullscreenMovie() {
lua_Object name = lua_getparam(1);
if (!lua_isstring(name)) {
lua_pushnil();
return;
}
Lua_V1::CleanBuffer();
GrimEngine::EngineMode prevEngineMode = g_grim->getMode();
g_grim->setMode(GrimEngine::SmushMode);
g_grim->setMovieSubtitle(nullptr);
bool looping = getbool(2);
bool result = g_movie->play(lua_getstring(name), looping, 0, 0);
if (!result)
g_grim->setMode(prevEngineMode);
pushbool(result);
}
void Lua_V1::StartMovie() {
lua_Object name = lua_getparam(1);
if (!lua_isstring(name)) {
lua_pushnil();
return;
}
int x = 0, y = 0;
if (!lua_isnil(lua_getparam(3)))
x = (int)lua_getnumber(lua_getparam(3));
if (!lua_isnil(lua_getparam(4)))
y = (int)lua_getnumber(lua_getparam(4));
GrimEngine::EngineMode prevEngineMode = g_grim->getMode();
g_grim->setMode(GrimEngine::NormalMode);
bool looping = getbool(2);
bool result = g_movie->play(lua_getstring(name), looping, x, y);
g_grim->setMovieSetup();
if (!result)
g_grim->setMode(prevEngineMode);
pushbool(result);
}
/* Fullscreen movie playing query and normal movie
* query should actually detect correctly and not
* just return true whenever ANY movie is playing
*/
void Lua_V1::IsFullscreenMoviePlaying() {
pushbool(g_movie->isPlaying());
}
void Lua_V1::IsMoviePlaying() {
// Previously, if the game was *not* the demo, this checked also if the mode
// was GrimEngine::NormalMode. This doesn't seem to be what original does, and causes
// bug #301 because the movie eldepot.snm is played before legslide.snm ends.
pushbool(g_movie->isPlaying());
}
void Lua_V1::StopMovie() {
g_movie->stop();
// Delete subtitles that may have not expired.
g_grim->setMovieSubtitle(nullptr);
}
void Lua_V1::PauseMovie() {
g_movie->pause(lua_isnil(lua_getparam(1)) == 0);
}
void Lua_V1::PurgePrimitiveQueue() {
PrimitiveObject::getPool().deleteObjects();
}
void Lua_V1::DrawPolygon() {
lua_Object tableObj1 = lua_getparam(1);
if (!lua_istable(tableObj1)) {
lua_pushnil();
return;
}
//int layer = 2;
Color color;
lua_Object tableObj2 = lua_getparam(2);
if (lua_istable(tableObj2)) {
lua_pushobject(tableObj2);
lua_pushstring("color");
lua_Object colorObj = lua_gettable();
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKTAG('C','O','L','R')) {
color = getcolor(colorObj);
}
lua_pushobject(tableObj2);
lua_pushstring("layer");
lua_Object layerObj = lua_gettable();
if (lua_isnumber(layerObj))
/*layer = (int)*/lua_getnumber(layerObj);
}
// This code only supports 4 point polygons because the game doesn't
// use other than that. However, the original engine can support
// many points per polygon
lua_Object pointObj;
Common::Point p[4];
for (int i = 0; i < 4; i++) {
// Get X
lua_pushobject(tableObj1);
lua_pushnumber(i * 2 + 1);
pointObj = lua_gettable();
if (!lua_isnumber(pointObj)) {
warning("Lua_V1::DrawPolygon: %i Point Parameter X isn't a number!", i * 2 + 1);
return;
}
if (g_grim->getGameType() == GType_GRIM)
p[i].x = (int)lua_getnumber(pointObj);
else
p[i].x = (int)((lua_getnumber(pointObj) + 1) * 320);
// Get Y
lua_pushobject(tableObj1);
lua_pushnumber(i * 2 + 2);
pointObj = lua_gettable();
if (!lua_isnumber(pointObj)) {
warning("Lua_V1::DrawPolygon: %i Point Parameter Y isn't a number!", i * 2 + 2);
return;
}
if (g_grim->getGameType() == GType_GRIM)
p[i].y = (int)lua_getnumber(pointObj);
else
p[i].y = (int)((1 - lua_getnumber(pointObj)) * 240);
}
PrimitiveObject *prim = new PrimitiveObject();
prim->createPolygon(p[0], p[1], p[2], p[3], color);
lua_pushusertag(prim->getId(), MKTAG('P','R','I','M'));
}
void Lua_V1::DrawLine() {
Common::Point p1, p2;
Color color;
lua_Object x1Obj = lua_getparam(1);
lua_Object y1Obj = lua_getparam(2);
lua_Object x2Obj = lua_getparam(3);
lua_Object y2Obj = lua_getparam(4);
lua_Object tableObj = lua_getparam(5);
if (!lua_isnumber(x1Obj) || !lua_isnumber(y1Obj) || !lua_isnumber(x2Obj) || !lua_isnumber(y2Obj)) {
lua_pushnil();
return;
}
if (g_grim->getGameType() == GType_GRIM) {
p1.x = (int)lua_getnumber(x1Obj);
p1.y = (int)lua_getnumber(y1Obj);
p2.x = (int)lua_getnumber(x2Obj);
p2.y = (int)lua_getnumber(y2Obj);
} else {
p1.x = (int)((lua_getnumber(x1Obj) + 1) * 320);
p1.y = (int)((1 - lua_getnumber(y1Obj)) * 240);
p2.x = (int)((lua_getnumber(x2Obj) + 1) * 320);
p2.y = (int)((1 - lua_getnumber(y2Obj)) * 240);
}
//int layer = 2;
if (lua_istable(tableObj)) {
lua_pushobject(tableObj);
lua_pushstring("color");
lua_Object colorObj = lua_gettable();
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKTAG('C','O','L','R')) {
color = getcolor(colorObj);
}
lua_pushobject(tableObj);
lua_pushstring("layer");
lua_Object layerObj = lua_gettable();
if (lua_isnumber(layerObj))
/*layer = (int)*/lua_getnumber(layerObj);
}
PrimitiveObject *p = new PrimitiveObject();
p->createLine(p1, p2, color); // TODO Add layer support
lua_pushusertag(p->getId(), MKTAG('P','R','I','M'));
}
void Lua_V1::ChangePrimitive() {
lua_Object param1 = lua_getparam(1);
if (!lua_isuserdata(param1) || lua_tag(param1) != MKTAG('P','R','I','M'))
return;
lua_Object tableObj = lua_getparam(2);
if (!lua_istable(tableObj))
return;
PrimitiveObject *pmodify = getprimitive(param1);
assert(pmodify);
Color color;
lua_pushobject(tableObj);
lua_pushstring("color");
lua_Object colorObj = lua_gettable();
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKTAG('C','O','L','R')) {
color = getcolor(colorObj);
pmodify->setColor(color);
}
lua_pushobject(tableObj);
lua_pushstring("layer");
lua_Object layer = lua_gettable();
if (lua_isnumber(layer)) {
// TODO pmodify->setLayer(lua_getnumber(layer));
warning("Not implemented: PrimitiveObject::setLayer. Layer: %d", (int)lua_getnumber(layer));
}
lua_pushobject(tableObj);
lua_pushstring("xoffset");
lua_Object xObj = lua_gettable();
lua_pushobject(tableObj);
lua_pushstring("yoffset");
lua_Object yObj = lua_gettable();
if (lua_isnumber(xObj) || lua_isnumber(yObj)) {
//int x = 0;
//int y = 0;
if (lua_isnumber(xObj))
/*x = (int)*/lua_getnumber(xObj);
if (lua_isnumber(yObj))
/*y = (int)*/lua_getnumber(yObj);
// TODO pmodify->setOffets(x, y);
assert(0);
}
lua_pushobject(tableObj);
lua_pushstring("x");
xObj = lua_gettable();
lua_pushobject(tableObj);
lua_pushstring("y");
yObj = lua_gettable();
if (lua_isnumber(xObj) || lua_isnumber(yObj)) {
int x = -1;
int y = -1;
if (lua_isnumber(xObj)) {
if (g_grim->getGameType() == GType_GRIM)
x = (int)lua_getnumber(xObj);
else
x = (int)((lua_getnumber(xObj) + 1) * 320);
}
if (lua_isnumber(yObj)) {
if (g_grim->getGameType() == GType_GRIM)
y = (int)lua_getnumber(yObj);
else
y = (int)((1 - lua_getnumber(yObj)) * 240);
}
pmodify->setPos(x, y);
}
lua_pushobject(tableObj);
lua_pushstring("x2");
xObj = lua_gettable();
lua_pushobject(tableObj);
lua_pushstring("y2");
yObj = lua_gettable();
if (lua_isnumber(xObj) || lua_isnumber(yObj)) {
int x = -1;
int y = -1;
if (lua_isnumber(xObj)) {
if (g_grim->getGameType() == GType_GRIM)
x = (int)lua_getnumber(xObj);
else
x = (int)((lua_getnumber(xObj) + 1) * 320);
}
if (lua_isnumber(yObj)) {
if (g_grim->getGameType() == GType_GRIM)
y = (int)lua_getnumber(yObj);
else
y = (int)((1 - lua_getnumber(yObj)) * 240);
}
pmodify->setEndpoint(x, y);
}
lua_pushobject(tableObj);
lua_pushstring("width");
lua_Object width = lua_gettable();
lua_pushobject(tableObj);
lua_pushstring("height");
lua_Object height = lua_gettable();
if (lua_isnumber(width) || lua_isnumber(height)) {
//int x = -1;
//int y = -1;
if (lua_isnumber(width))
/*x = (int)*/lua_getnumber(width);
if (lua_isnumber(height))
/*y = (int)*/lua_getnumber(height);
// TODO pmodify->setSize(x, y);
}
}
void Lua_V1::DrawRectangle() {
Common::Point p1, p2;
Color color;
lua_Object x1Obj = lua_getparam(1);
lua_Object y1Obj = lua_getparam(2);
lua_Object x2Obj = lua_getparam(3);
lua_Object y2Obj = lua_getparam(4);
lua_Object tableObj = lua_getparam(5);
if (!lua_isnumber(x1Obj) || !lua_isnumber(y1Obj) || !lua_isnumber(x2Obj) || !lua_isnumber(y2Obj)) {
lua_pushnil();
return;
}
if (g_grim->getGameType() == GType_GRIM) {
p1.x = (int)lua_getnumber(x1Obj);
p1.y = (int)lua_getnumber(y1Obj);
p2.x = (int)lua_getnumber(x2Obj);
p2.y = (int)lua_getnumber(y2Obj);
} else {
p1.x = (int)((lua_getnumber(x1Obj) + 1) * 320);
p1.y = (int)((1 - lua_getnumber(y1Obj)) * 240);
p2.x = (int)((lua_getnumber(x2Obj) + 1) * 320);
p2.y = (int)((1 - lua_getnumber(y2Obj)) * 240);
}
bool filled = false;
if (lua_istable(tableObj)) {
lua_pushobject(tableObj);
lua_pushstring("color");
lua_Object colorObj = lua_gettable();
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKTAG('C','O','L','R')) {
color = getcolor(colorObj);
}
lua_pushobject(tableObj);
lua_pushstring("filled");
lua_Object objFilled = lua_gettable();
if (!lua_isnil(objFilled))
filled = true;
}
PrimitiveObject *p = new PrimitiveObject();
p->createRectangle(p1, p2, color, filled);
lua_pushusertag(p->getId(), MKTAG('P','R','I','M')); // FIXME: we use PRIM usetag here
}
void Lua_V1::BlastRect() {
Common::Point p1, p2;
Color color;
lua_Object x1Obj = lua_getparam(1);
lua_Object y1Obj = lua_getparam(2);
lua_Object x2Obj = lua_getparam(3);
lua_Object y2Obj = lua_getparam(4);
lua_Object tableObj = lua_getparam(5);
if (!lua_isnumber(x1Obj) || !lua_isnumber(y1Obj) || !lua_isnumber(x2Obj) || !lua_isnumber(y2Obj)) {
lua_pushnil();
return;
}
if (g_grim->getGameType() == GType_GRIM) {
p1.x = (int)lua_getnumber(x1Obj);
p1.y = (int)lua_getnumber(y1Obj);
p2.x = (int)lua_getnumber(x2Obj);
p2.y = (int)lua_getnumber(y2Obj);
} else {
p1.x = (int)((lua_getnumber(x1Obj) + 1) * 320);
p1.y = (int)((1 - lua_getnumber(y1Obj)) * 240);
p2.x = (int)((lua_getnumber(x2Obj) + 1) * 320);
p2.y = (int)((1 - lua_getnumber(y2Obj)) * 240);
}
bool filled = false;
if (lua_istable(tableObj)) {
lua_pushobject(tableObj);
lua_pushstring("color");
lua_Object colorObj = lua_gettable();
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKTAG('C','O','L','R')) {
color = getcolor(colorObj);
}
lua_pushobject(tableObj);
lua_pushstring("filled");
lua_Object objFilled = lua_gettable();
if (!lua_isnil(objFilled))
filled = true;
}
PrimitiveObject *p = new PrimitiveObject();
p->createRectangle(p1, p2, color, filled);
p->draw();
delete p;
}
void Lua_V1::KillPrimitive() {
lua_Object primObj = lua_getparam(1);
if (!lua_isuserdata(primObj) || lua_tag(primObj) != MKTAG('P','R','I','M'))
return;
PrimitiveObject *prim = getprimitive(primObj);
delete prim;
}
void Lua_V1::DimScreen() {
g_driver->storeDisplay();
g_driver->dimScreen();
}
void Lua_V1::DimRegion() {
int x = (int)lua_getnumber(lua_getparam(1));
int y = (int)lua_getnumber(lua_getparam(2));
int w = (int)lua_getnumber(lua_getparam(3));
int h = (int)lua_getnumber(lua_getparam(4));
float level = lua_getnumber(lua_getparam(5));
g_driver->dimRegion(x, y, w, h, level);
}
void Lua_V1::ScreenShot() {
int width = (int)lua_getnumber(lua_getparam(1));
int height = (int)lua_getnumber(lua_getparam(2));
GrimEngine::EngineMode mode = g_grim->getMode();
g_grim->setMode(GrimEngine::NormalMode);
g_grim->updateDisplayScene();
Bitmap *screenshot = g_driver->getScreenshot(width, height, false);
g_grim->setMode(mode);
if (screenshot) {
lua_pushusertag(screenshot->getId(), MKTAG('V','B','U','F'));
} else {
lua_pushnil();
}
}
void Lua_V1::SetGamma() {
lua_Object levelObj = lua_getparam(1);
if (!lua_isnumber(levelObj))
return;
double level = lua_getnumber(levelObj);
// FIXME: func(level)
warning("Lua_V1::SetGamma, implement opcode, level: %f", level);
}
void Lua_V1::Display() {
if (g_grim->getFlipEnable()) {
g_driver->flipBuffer();
}
}
void Lua_V1::EngineDisplay() {
// it enable/disable updating display
g_grim->setFlipEnable((bool)lua_getnumber(lua_getparam(1)));
}
void Lua_V1::ForceRefresh() {
// Nothing to do, no off-screen buffers
}
void Lua_V1::RenderModeUser() {
lua_Object param1 = lua_getparam(1);
if (!lua_isnil(param1) && g_grim->getMode() != GrimEngine::DrawMode) {
g_grim->setPreviousMode(g_grim->getMode());
g_movie->pause(true);
g_grim->setMode(GrimEngine::DrawMode);
} else if (lua_isnil(param1) && g_grim->getMode() == GrimEngine::DrawMode) {
g_movie->pause(false);
g_grim->setMode(g_grim->getPreviousMode());
}
}
void Lua_V1::IrisUp() {
lua_Object xObj = lua_getparam(1);
lua_Object yObj = lua_getparam(2);
lua_Object timeObj = lua_getparam(3);
g_grim->playIrisAnimation(Iris::Open, (int)lua_getnumber(xObj), (int)lua_getnumber(yObj), (int)lua_getnumber(timeObj));
}
void Lua_V1::IrisDown() {
lua_Object xObj = lua_getparam(1);
lua_Object yObj = lua_getparam(2);
lua_Object timeObj = lua_getparam(3);
g_grim->playIrisAnimation(Iris::Close, (int)lua_getnumber(xObj), (int)lua_getnumber(yObj), (int)lua_getnumber(timeObj));
}
void Lua_V1::PreRender() {
g_driver->renderBitmaps(getbool(1));
g_driver->renderZBitmaps(getbool(2));
}
void Lua_V1::ResetTextures() {
// nothing to implement here
}
} // end of namespace Grim