share/gui: don't use less of widget width for truncation than available
[neverball] / share / solid_gl.c
index a35abbe..5a04d3f 100644 (file)
@@ -25,7 +25,9 @@
 #include "image.h"
 #include "base_image.h"
 #include "solid_gl.h"
+#include "solid_phys.h"
 #include "base_config.h"
+#include "lang.h"
 
 /*---------------------------------------------------------------------------*/
 
@@ -71,15 +73,30 @@ static int sol_enum_body(const struct s_file *fp,
 
 /*---------------------------------------------------------------------------*/
 
-#define color_cmp(a, b) ((a)[0] == (b)[0] && \
-                         (a)[1] == (b)[1] && \
-                         (a)[2] == (b)[2] && \
-                         (a)[3] == (b)[3])
+int sol_reflective(const struct s_file *fp)
+{
+    int bi;
+
+    for (bi = 0; bi < fp->bc; bi++)
+        if (fp->bv[bi].rl)
+            return 1;
+
+    return 0;
+}
+
+/*---------------------------------------------------------------------------*/
+
+#define tobyte(f) ((GLubyte) (f * 255.0f))
+
+#define color_cmp(a, b) (tobyte((a)[0]) == tobyte((b)[0]) && \
+                         tobyte((a)[1]) == tobyte((b)[1]) && \
+                         tobyte((a)[2]) == tobyte((b)[2]) && \
+                         tobyte((a)[3]) == tobyte((b)[3]))
 
 static struct s_mtrl default_mtrl =
 {
-    { 0.2f, 0.2f, 0.2f, 1.0f },
     { 0.8f, 0.8f, 0.8f, 1.0f },
+    { 0.2f, 0.2f, 0.2f, 1.0f },
     { 0.0f, 0.0f, 0.0f, 1.0f },
     { 0.0f, 0.0f, 0.0f, 1.0f },
     { 0.0f, }, 0.0f, M_OPAQUE, 0, ""
@@ -99,7 +116,7 @@ static const struct s_mtrl *sol_draw_mtrl(const struct s_file *fp,
         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,  mp->s);
     if (!color_cmp(mp->e, mq->e))
         glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION,  mp->e);
-    if (mp->h[0] != mq->h[0])
+    if (tobyte(mp->h[0]) != tobyte(mq->h[0]))
         glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mp->h);
 
     /* Bind the texture. */
@@ -124,8 +141,6 @@ static const struct s_mtrl *sol_draw_mtrl(const struct s_file *fp,
     {
         glDisable(GL_TEXTURE_GEN_S);
         glDisable(GL_TEXTURE_GEN_T);
-
-        glBindTexture(GL_TEXTURE_2D, mp->o);
     }
 
     /* Enable additive blending. */
@@ -138,6 +153,22 @@ static const struct s_mtrl *sol_draw_mtrl(const struct s_file *fp,
     if ((mq->fl & M_ADDITIVE) && !(mp->fl & M_ADDITIVE))
         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
+    /* Enable visibility-from-behind. */
+
+    if ((mp->fl & M_TWO_SIDED) && !(mq->fl & M_TWO_SIDED))
+    {
+        glDisable(GL_CULL_FACE);
+        glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
+    }
+
+    /* Disable visibility-from-behind. */
+
+    if ((mq->fl & M_TWO_SIDED) && !(mp->fl & M_TWO_SIDED))
+    {
+        glEnable(GL_CULL_FACE);
+        glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
+    }
+
     /* Enable decal offset. */
 
     if ((mp->fl & M_DECAL) && !(mq->fl & M_DECAL))
@@ -158,7 +189,7 @@ static const struct s_mtrl *sol_back_bill(const struct s_file *fp,
                                           const struct s_bill *rp,
                                           const struct s_mtrl *mp, float t)
 {
-    float T = rp->t ? (fmodf(t, rp->t) - rp->t / 2) : 0.0f;
+    float T = (rp->t > 0.0f) ? (fmodf(t, rp->t) - rp->t / 2) : 0.0f;
 
     float w = rp->w[0] + rp->w[1] * T + rp->w[2] * T * T;
     float h = rp->h[0] + rp->h[1] * T + rp->h[2] * T * T;
@@ -192,10 +223,10 @@ static const struct s_mtrl *sol_back_bill(const struct s_file *fp,
 
             glBegin(GL_QUADS);
             {
-                glTexCoord2f(0.0f, 1.0f); glVertex2f(-w / 2, y0);
-                glTexCoord2f(1.0f, 1.0f); glVertex2f(+w / 2, y0);
-                glTexCoord2f(1.0f, 0.0f); glVertex2f(+w / 2, y1);
-                glTexCoord2f(0.0f, 0.0f); glVertex2f(-w / 2, y1);
+                glTexCoord2f(0.0f, 0.0f); glVertex2f(-w / 2, y0);
+                glTexCoord2f(1.0f, 0.0f); glVertex2f(+w / 2, y0);
+                glTexCoord2f(1.0f, 1.0f); glVertex2f(+w / 2, y1);
+                glTexCoord2f(0.0f, 1.0f); glVertex2f(-w / 2, y1);
             }
             glEnd();
         }
@@ -334,7 +365,7 @@ static void sol_draw_list(const struct s_file *fp,
     glPopMatrix();
 }
 
-void sol_draw(const struct s_file *fp, float rx, float ry)
+void sol_draw(const struct s_file *fp, int depthmask, int depthtest)
 {
     int bi;
 
@@ -346,17 +377,18 @@ void sol_draw(const struct s_file *fp, float rx, float ry)
 
     /* Render all translucent geometry into only the color buffer. */
 
-    glDepthMask(GL_FALSE);
+    if (depthtest == 0) glDisable(GL_DEPTH_TEST);
+    if (depthmask == 0) glDepthMask(GL_FALSE);
     {
         for (bi = 0; bi < fp->bc; bi++)
             if (fp->bv[bi].tl)
                 sol_draw_list(fp, fp->bv + bi, fp->bv[bi].tl);
     }
-    glDepthMask(GL_TRUE);
-
+    if (depthmask == 0) glDepthMask(GL_TRUE);
+    if (depthtest == 0) glEnable(GL_DEPTH_TEST);
 }
 
-void sol_bill(const struct s_file *fp, float rx, float ry)
+void sol_bill(const struct s_file *fp, const float *M, float t)
 {
     const struct s_mtrl *mp = &default_mtrl;
 
@@ -366,23 +398,33 @@ void sol_bill(const struct s_file *fp, float rx, float ry)
     {
         const struct s_bill *rp = fp->rv + ri;
 
-        float w = (float) rp->w[0];
-        float h = (float) rp->h[0];
+        float T = rp->t * t;
+        float S = fsinf(T);
+
+        float w  = rp->w [0] + rp->w [1] * T + rp->w [2] * S;
+        float h  = rp->h [0] + rp->h [1] * T + rp->h [2] * S;
+        float rx = rp->rx[0] + rp->rx[1] * T + rp->rx[2] * S;
+        float ry = rp->ry[0] + rp->ry[1] * T + rp->ry[2] * S;
+        float rz = rp->rz[0] + rp->rz[1] * T + rp->rz[2] * S;
 
         mp = sol_draw_mtrl(fp, fp->mv + rp->mi, mp);
 
         glPushMatrix();
         {
             glTranslatef(rp->p[0], rp->p[1], rp->p[2]);
-            glRotatef(ry, 0.f, 1.f, 0.f);
-            glRotatef(rx, 1.f, 0.f, 0.f);
+
+            if (M && ((rp->fl & B_NOFACE) == 0)) glMultMatrixf(M);
+
+            if (fabsf(rx) > 0.0f) glRotatef(rx, 1.0f, 0.0f, 0.0f);
+            if (fabsf(ry) > 0.0f) glRotatef(ry, 0.0f, 1.0f, 0.0f);
+            if (fabsf(rz) > 0.0f) glRotatef(rz, 0.0f, 0.0f, 1.0f);
 
             glBegin(GL_QUADS);
             {
-                glTexCoord2f(0.0f, 1.0f); glVertex2f(-w / 2, -h / 2);
-                glTexCoord2f(1.0f, 1.0f); glVertex2f(+w / 2, -h / 2);
-                glTexCoord2f(1.0f, 0.0f); glVertex2f(+w / 2, +h / 2);
-                glTexCoord2f(0.0f, 0.0f); glVertex2f(-w / 2, +h / 2);
+                glTexCoord2f(0.0f, 0.0f); glVertex2f(-w / 2, -h / 2);
+                glTexCoord2f(1.0f, 0.0f); glVertex2f(+w / 2, -h / 2);
+                glTexCoord2f(1.0f, 1.0f); glVertex2f(+w / 2, +h / 2);
+                glTexCoord2f(0.0f, 1.0f); glVertex2f(-w / 2, +h / 2);
             }
             glEnd();
         }
@@ -635,7 +677,7 @@ static void sol_load_textures(struct s_file *fp, int k)
     /* Load the image referenced by each material. */
 
     for (i = 0; i < fp->mc; i++)
-        if ((fp->mv[i].o = sol_find_texture(fp->mv[i].f)))
+        if ((fp->mv[i].o = sol_find_texture(_(fp->mv[i].f))))
         {
             /* Set the texture to clamp or repeat based on material type. */