diff --git a/driver.h b/driver.h index fc3f3d10afd..804fe77a655 100644 --- a/driver.h +++ b/driver.h @@ -103,6 +103,7 @@ public: virtual void drawRectangle(PrimitiveObject *primitive) = 0; virtual void drawLine(PrimitiveObject *primitive) = 0; + virtual void drawPolygon(PrimitiveObject *primitive) = 0; virtual void prepareSmushFrame(int width, int height, byte *bitmap) = 0; virtual void drawSmushFrame(int offsetX, int offsetY) = 0; diff --git a/driver_gl.cpp b/driver_gl.cpp index 2aa5fe6a73d..930aa380342 100644 --- a/driver_gl.cpp +++ b/driver_gl.cpp @@ -903,9 +903,48 @@ void DriverGL::drawLine(PrimitiveObject *primitive) { glBegin(GL_LINES); glVertex2f(x1, y1); - glVertex2f(x2, y1); glVertex2f(x2, y2); - glVertex2f(x1, y2); + glEnd(); + + glColor3f(1.0f, 1.0f, 1.0f); + + glDepthMask(GL_TRUE); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); +} + +void DriverGL::drawPolygon(PrimitiveObject *primitive) { + int x1 = primitive->getX1(); + int y1 = primitive->getY1(); + int x2 = primitive->getX2(); + int y2 = primitive->getY2(); + int x3 = primitive->getX3(); + int y3 = primitive->getY3(); + int x4 = primitive->getX4(); + int y4 = primitive->getY4(); + + Color color = primitive->getColor(); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, _screenWidth, _screenHeight, 0, 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + + glColor3f(color.red() / 255.0f, color.green() / 255.0f, color.blue() / 255.0f); + + glBegin(GL_LINES); + glVertex2f(x1, y1); + glVertex2f(x2, y2); + glEnd(); + + glBegin(GL_LINES); + glVertex2f(x3, y3); + glVertex2f(x4, y4); glEnd(); glColor3f(1.0f, 1.0f, 1.0f); diff --git a/driver_gl.h b/driver_gl.h index d0d7e1944c8..e42eb39afab 100644 --- a/driver_gl.h +++ b/driver_gl.h @@ -89,6 +89,7 @@ public: void drawRectangle(PrimitiveObject *primitive); void drawLine(PrimitiveObject *primitive); + void drawPolygon(PrimitiveObject *primitive); void prepareSmushFrame(int width, int height, byte *bitmap); void drawSmushFrame(int offsetX, int offsetY); diff --git a/driver_tinygl.cpp b/driver_tinygl.cpp index 6612990b9a0..9f1681b88a3 100644 --- a/driver_tinygl.cpp +++ b/driver_tinygl.cpp @@ -610,7 +610,37 @@ void DriverTinyGL::drawLine(PrimitiveObject *primitive) { uint16 c = ((color.red() & 0xF8) << 8) | ((color.green() & 0xFC) << 3) | (color.blue() >> 3); for (int x = x1; x <= x2; x++) { - int y = (int) (m * x) + b; + int y = (int)(m * x) + b; + WRITE_LE_UINT16(dst + 640 * y + x, c); + } +} + +void DriverTinyGL::drawPolygon(PrimitiveObject *primitive) { + uint16 *dst = (uint16 *)_zb->pbuf; + int x1 = primitive->getX1(); + int y1 = primitive->getY1(); + int x2 = primitive->getX2(); + int y2 = primitive->getY2(); + int x3 = primitive->getX3(); + int y3 = primitive->getY3(); + int x4 = primitive->getX4(); + int y4 = primitive->getY4(); + float m; + int b; + + Color color = primitive->getColor(); + uint16 c = ((color.red() & 0xF8) << 8) | ((color.green() & 0xFC) << 3) | (color.blue() >> 3); + + m = (y2 - y1) / (x2 - x1); + b = (int)(-m * x1 + y1); + for (int x = x1; x <= x2; x++) { + int y = (int)(m * x) + b; + WRITE_LE_UINT16(dst + 640 * y + x, c); + } + m = (y4 - y3) / (x4 - x3); + b = (int)(-m * x3 + y3); + for (int x = x3; x <= x4; x++) { + int y = (int)(m * x) + b; WRITE_LE_UINT16(dst + 640 * y + x, c); } } diff --git a/driver_tinygl.h b/driver_tinygl.h index b4845ceaed9..e090fcce04f 100644 --- a/driver_tinygl.h +++ b/driver_tinygl.h @@ -90,6 +90,7 @@ public: void drawRectangle(PrimitiveObject *primitive); void drawLine(PrimitiveObject *primitive); + void drawPolygon(PrimitiveObject *primitive); void prepareSmushFrame(int width, int height, byte *bitmap); void drawSmushFrame(int offsetX, int offsetY); diff --git a/lua.cpp b/lua.cpp index 1179f33d1e8..20b1f1334c9 100644 --- a/lua.cpp +++ b/lua.cpp @@ -125,7 +125,7 @@ static inline PrimitiveObject *check_primobject(int num) { lua_Object param = lua_getparam(num); if (lua_isuserdata(param) && lua_tag(param) == MKID('PRIM')) return static_cast(lua_getuserdata(param)); - luaL_argerror(num, "primitive (rectangle) expected"); + luaL_argerror(num, "primitive expected"); return NULL; } @@ -2530,7 +2530,67 @@ static void PurgePrimitiveQueue() { } static void DrawPolygon() { - stubWarning("DrawPolygon"); + lua_Object tableObj1, tableObj2, pointObj; + int x1, y1, x2, y2, x3, y3, x4, y4; + Color color; + + color._vals[0] = 255; + color._vals[1] = 255; + color._vals[2] = 255; + + tableObj1 = lua_getparam(1); + tableObj2 = lua_getparam(2); + + if (lua_istable(tableObj1)) { + lua_pushobject(tableObj1); + lua_pushnumber(1); + pointObj = lua_gettable(); + x1 = lua_getnumber(pointObj); + lua_pushobject(tableObj1); + lua_pushnumber(2); + pointObj = lua_gettable(); + y1 = lua_getnumber(pointObj); + lua_pushobject(tableObj1); + lua_pushnumber(3); + pointObj = lua_gettable(); + x2 = lua_getnumber(pointObj); + lua_pushobject(tableObj1); + lua_pushnumber(4); + pointObj = lua_gettable(); + y2 = lua_getnumber(pointObj); + lua_pushobject(tableObj1); + lua_pushnumber(5); + pointObj = lua_gettable(); + x3 = lua_getnumber(pointObj); + lua_pushobject(tableObj1); + lua_pushnumber(6); + pointObj = lua_gettable(); + y3 = lua_getnumber(pointObj); + lua_pushobject(tableObj1); + lua_pushnumber(7); + pointObj = lua_gettable(); + x4 = lua_getnumber(pointObj); + lua_pushobject(tableObj1); + lua_pushnumber(8); + pointObj = lua_gettable(); + y4 = lua_getnumber(pointObj); + } else { + lua_pushnil(); + } + + if (lua_istable(tableObj2)) { + lua_pushobject(tableObj2); + lua_pushstring("color"); + lua_Object colorObj = lua_gettable(); + if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID('COLR')) { + color = static_cast(lua_getuserdata(colorObj)); + } + } + + PrimitiveObject *p = new PrimitiveObject(); + p->createPolygon(x1, y1, x2, y2, x3, y3, x4, y4, color); + g_engine->registerPrimitiveObject(p); + lua_pushusertag(p, MKID('PRIM')); } static void DrawLine() { @@ -2548,7 +2608,7 @@ static void DrawLine() { color._vals[1] = 255; color._vals[2] = 255; - if (lua_istable(tableObj)){ + if (lua_istable(tableObj)) { lua_pushobject(tableObj); lua_pushstring("color"); lua_Object colorObj = lua_gettable(); @@ -2600,12 +2660,26 @@ static void ChangePrimitive() { color = static_cast(lua_getuserdata(colorObj)); pmodify->setColor(color); } + lua_pushobject(tableObj); lua_pushstring("y"); lua_Object yObj = lua_gettable(); if (!lua_isnil(yObj)) { - pmodify->setY1(atoi(lua_getstring(yObj))); - pmodify->setY2(atoi(lua_getstring(yObj))); + int y = atoi(lua_getstring(yObj)); + if (pmodify->getType() == 4) { + int y1 = pmodify->getY1(); + int y2 = pmodify->getY2(); + int y3 = pmodify->getY3(); + int y4 = pmodify->getY4(); + int dy = y - y1; + pmodify->setY1(y1 + dy); + pmodify->setY2(y2 + dy); + pmodify->setY3(y3 + dy); + pmodify->setY4(y4 + dy); + } else { + pmodify->setY1(y); + pmodify->setY2(y); + } } } diff --git a/primitives.cpp b/primitives.cpp index 9de375bdf94..6ed09bac478 100644 --- a/primitives.cpp +++ b/primitives.cpp @@ -75,6 +75,19 @@ void PrimitiveObject::createLine(int x1, int x2, int y1, int y2, Color color) { _type = 3; } +void PrimitiveObject::createPolygon(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, Color color) { + _x1 = x1; + _y1 = y1; + _x2 = x2; + _y2 = y2; + _x3 = x3; + _y3 = y3; + _x4 = x4; + _y4 = y4; + _color = color; + _type = 4; +} + void PrimitiveObject::draw() { assert(_type); @@ -84,4 +97,6 @@ void PrimitiveObject::draw() { g_driver->drawBitmap(_bitmap); else if (_type == 3) g_driver->drawLine(this); + else if (_type == 4) + g_driver->drawPolygon(this); } diff --git a/primitives.h b/primitives.h index 468b9b8a717..3fa573c0e6d 100644 --- a/primitives.h +++ b/primitives.h @@ -39,12 +39,20 @@ public: void createRectangle(int x1, int x2, int y1, int y2, Color color, bool filled); void createBitmap(Bitmap *bitmap, int x, int y, bool transparent); void createLine(int x1, int x2, int y1, int y2, Color color); + void createPolygon(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, Color color); int getX1() { return _x1; } - int getX2() { return _x2; } int getY1() { return _y1; } + int getX2() { return _x2; } int getY2() { return _y2; } + int getX3() { return _x3; } + int getY3() { return _y3; } + int getX4() { return _x4; } + int getY4() { return _y4; } void setY1(int coord) { _y1 = coord; } void setY2(int coord) { _y2 = coord; } + void setY3(int coord) { _y3 = coord; } + void setY4(int coord) { _y4 = coord; } + int getType() { return _type; } void setColor(Color color) { _color = color; } Color getColor() { return _color; } bool isFilled() { return _filled; } @@ -53,7 +61,7 @@ public: Bitmap *getBitmapHandle() { assert(_bitmap); return _bitmap; } private: - int _x1, _x2, _y1, _y2; + int _x1, _y1, _x2, _y2, _x3, _y3, _x4, _y4; Color _color; bool _filled; int _type;