Split SOL data structures into base, varying and rendering parts
[neverball] / share / geom.c
index 1b758d3..0dd3694 100644 (file)
 #include "geom.h"
 #include "part.h"
 #include "vec3.h"
-#include "solid.h"
 #include "image.h"
 #include "config.h"
+#include "video.h"
 
 #define PI 3.1415926535897932
 
 /*---------------------------------------------------------------------------*/
 
-static GLuint ball_list;
-static GLuint ball_text;
-
-void ball_init(int b)
-{
-    char name[MAXSTR];
-    int i, slices = b ? 32 : 16;
-    int j, stacks = b ? 16 :  8;
-
-    config_get_s(CONFIG_BALL, name, MAXSTR);
-
-    ball_text = make_image_from_file(NULL, NULL, NULL, NULL, name);
-
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
-    ball_list = glGenLists(1);
-
-    glNewList(ball_list, GL_COMPILE);
-    {
-        for (i = 0; i < stacks; i++)
-        {
-            float k0 = (float)  i      / stacks;
-            float k1 = (float) (i + 1) / stacks;
-
-            float s0 = fsinf(V_PI * (k0 - 0.5));
-            float c0 = fcosf(V_PI * (k0 - 0.5));
-            float s1 = fsinf(V_PI * (k1 - 0.5));
-            float c1 = fcosf(V_PI * (k1 - 0.5));
-
-            glBegin(GL_QUAD_STRIP);
-            {
-                for (j = 0; j <= slices; j++)
-                {
-                    float k = (float) j / slices;
-                    float s = fsinf(V_PI * k * 2.0);
-                    float c = fcosf(V_PI * k * 2.0);
-
-                    glTexCoord2f(k, k0);
-                    glNormal3f(s * c0, c * c0, s0);
-                    glVertex3f(s * c0, c * c0, s0);
-
-                    glTexCoord2f(k, k1);
-                    glNormal3f(s * c1, c * c1, s1);
-                    glVertex3f(s * c1, c * c1, s1);
-                }
-            }
-            glEnd();
-        }
-    }
-    glEndList();
-}
-
-void ball_free(void)
-{
-    if (glIsList(ball_list))
-        glDeleteLists(ball_list, 1);
-
-    if (glIsTexture(ball_text))
-        glDeleteTextures(1, &ball_text);
-
-    ball_list = 0;
-    ball_text = 0;
-}
-
-void ball_draw(void)
-{
-    glPushAttrib(GL_POLYGON_BIT |
-                 GL_LIGHTING_BIT |
-                 GL_DEPTH_BUFFER_BIT);
-    {
-        static const float  s[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
-        static const float  e[4] = { 0.2f, 0.2f, 0.2f, 1.0f };
-        static const float  h[1] = { 64.0f };
-
-        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,  s);
-        glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION,  e);
-        glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, h);
-
-        glEnable(GL_COLOR_MATERIAL);
-
-        glBindTexture(GL_TEXTURE_2D, ball_text);
-
-        /* Render the ball back to front in case it is translucent. */
-
-        glDepthMask(GL_FALSE);
-
-        glCullFace(GL_FRONT);
-        glCallList(ball_list);
-        glCullFace(GL_BACK);
-        glCallList(ball_list);
-
-        /* Render the ball into the depth buffer. */
-
-        glDepthMask(GL_TRUE);
-        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-        {
-            glCallList(ball_list);
-        }
-        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-
-        /* Ensure the ball is visible even when obscured by geometry. */
-
-        glDisable(GL_DEPTH_TEST);
-
-        glColor4f(1.0f, 1.0f, 1.0f, 0.1f);
-        glCallList(ball_list);
-    }
-    glPopAttrib();
-}
-
-/*---------------------------------------------------------------------------*/
-
 static GLuint mark_list;
 
-void mark_init(int b)
+void mark_init(void)
 {
-    int i, slices = b ? 32 : 16;
+    int i, slices = 32;
 
     mark_list = glGenLists(1);
 
@@ -171,19 +58,15 @@ void mark_init(int b)
 
 void mark_draw(void)
 {
-    glPushAttrib(GL_TEXTURE_BIT);
-    glPushAttrib(GL_LIGHTING_BIT);
-    glPushAttrib(GL_DEPTH_BUFFER_BIT);
+    glEnable(GL_COLOR_MATERIAL);
+    glDisable(GL_TEXTURE_2D);
+    glDepthMask(GL_FALSE);
     {
-        glEnable(GL_COLOR_MATERIAL);
-        glDisable(GL_TEXTURE_2D);
-        glDepthMask(GL_FALSE);
-
         glCallList(mark_list);
     }
-    glPopAttrib();
-    glPopAttrib();
-    glPopAttrib();
+    glDepthMask(GL_TRUE);
+    glEnable(GL_TEXTURE_2D);
+    glDisable(GL_COLOR_MATERIAL);
 }
 
 void mark_free(void)
@@ -196,238 +79,31 @@ void mark_free(void)
 
 /*---------------------------------------------------------------------------*/
 
-static void coin_head(int n, float radius, float thick)
-{
-    int i;
-
-    glBegin(GL_TRIANGLE_FAN);
-    {
-        glNormal3f(0.f, 0.f, +1.f);
-
-        for (i = 0; i < n; i++)
-        {
-            float x = fcosf(+2.f * PI * i / n);
-            float y = fsinf(+2.f * PI * i / n);
-
-            glTexCoord2f(-x * 0.5f + 0.5f, +y * 0.5f + 0.5f);
-            glVertex3f(radius * x, radius * y, +thick);
-        }
-    }
-    glEnd();
-}
-
-static void coin_tail(int n, float radius, float thick)
-{
-    int i;
-
-    glBegin(GL_TRIANGLE_FAN);
-    {
-        glNormal3f(0.f, 0.f, -1.f);
-
-        for (i = 0; i < n; i++)
-        {
-            float x = fcosf(-2.f * PI * i / n);
-            float y = fsinf(-2.f * PI * i / n);
-
-            glTexCoord2f(+x * 0.5f + 0.5f, +y * 0.5f + 0.5f);
-            glVertex3f(radius * x, radius * y, -thick);
-        }
-    }
-    glEnd();
-}
-
-static void coin_edge(int n, float radius, float thick)
-{
-    int i;
-
-    glBegin(GL_QUAD_STRIP);
-    {
-        for (i = 0; i <= n; i++)
-        {
-            float x = fcosf(2.f * PI * i / n);
-            float y = fsinf(2.f * PI * i / n);
-
-            glNormal3f(x, y, 0.f);
-            glVertex3f(radius * x, radius * y, +thick);
-            glVertex3f(radius * x, radius * y, -thick);
-        }
-    }
-    glEnd();
-}
-
-/*---------------------------------------------------------------------------*/
-
-static GLuint item_coin_text;
-static GLuint item_grow_text;
-static GLuint item_shrink_text;
-static GLuint item_list;
-
-void item_color(const struct s_item *hp, float *c)
-{
-    switch (hp->t)
-    {
-
-    case ITEM_COIN:
-
-        if (hp->n >= 1)
-        {
-            c[0] = 1.0f;
-            c[1] = 1.0f;
-            c[2] = 0.2f;
-        }
-        if (hp->n >= 5)
-        {
-            c[0] = 1.0f;
-            c[1] = 0.2f;
-            c[2] = 0.2f;
-        }
-        if (hp->n >= 10)
-        {
-            c[0] = 0.2f;
-            c[1] = 0.2f;
-            c[2] = 1.0f;
-        }
-        break;
-
-    case ITEM_GROW:
-    case ITEM_SHRINK:
-
-    default:
-
-        c[0] = 1.0f;
-        c[1] = 1.0f;
-        c[2] = 1.0f;
-
-        break;
-    }
-}
-
-void item_init(int b)
-{
-    int n = b ? 32 : 8;
-
-    item_coin_text = make_image_from_file(NULL, NULL, NULL, NULL,
-                                          IMG_ITEM_COIN);
-    item_grow_text = make_image_from_file(NULL, NULL, NULL, NULL,
-                                          IMG_ITEM_GROW);
-    item_shrink_text = make_image_from_file(NULL, NULL, NULL, NULL,
-                                            IMG_ITEM_SHRINK);
-    item_list = glGenLists(1);
-
-    glNewList(item_list, GL_COMPILE);
-    {
-        coin_edge(n, COIN_RADIUS, COIN_THICK);
-        coin_head(n, COIN_RADIUS, COIN_THICK);
-        coin_tail(n, COIN_RADIUS, COIN_THICK);
-    }
-    glEndList();
-}
-
-void item_free(void)
-{
-    if (glIsList(item_list))
-        glDeleteLists(item_list, 1);
-
-    if (glIsTexture(item_coin_text))
-        glDeleteTextures(1, &item_coin_text);
-
-    if (glIsTexture(item_grow_text))
-        glDeleteTextures(1, &item_grow_text);
-
-    if (glIsTexture(item_shrink_text))
-        glDeleteTextures(1, &item_shrink_text);
-
-    item_list = 0;
-    item_coin_text = 0;
-    item_grow_text = 0;
-    item_shrink_text = 0;
-}
-
-void item_push(int type)
-{
-    static const float  a[4] = { 0.2f, 0.2f, 0.2f, 1.0f };
-    static const float  s[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
-    static const float  e[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
-    static const float  h[1] = { 32.0f };
-
-    glPushAttrib(GL_LIGHTING_BIT);
-
-    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,   a);
-    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,  s);
-    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION,  e);
-    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, h);
-
-    glEnable(GL_COLOR_MATERIAL);
-
-    switch (type)
-    {
-    case ITEM_COIN:
-        glBindTexture(GL_TEXTURE_2D, item_coin_text);
-        break;
-
-    case ITEM_GROW:
-        glBindTexture(GL_TEXTURE_2D, item_grow_text);
-        break;
-
-    case ITEM_SHRINK:
-        glBindTexture(GL_TEXTURE_2D, item_shrink_text);
-        break;
-    }
-}
-
-void item_draw(const struct s_item *hp, float r)
-{
-    float c[3];
-
-    item_color(hp, c);
-
-    glColor3fv(c);
-    glCallList(item_list);
-}
-
-void item_pull(void)
-{
-    glPopAttrib();
-}
-
-/*---------------------------------------------------------------------------*/
-
 static GLuint goal_list;
 
-void goal_init(int b)
+void goal_init(void)
 {
-    int i, n = b ? 32 : 8;
+    int i, n = 32;
 
     goal_list = glGenLists(1);
 
     glNewList(goal_list, GL_COMPILE);
     {
-        glPushAttrib(GL_TEXTURE_BIT  |
-                     GL_LIGHTING_BIT |
-                     GL_DEPTH_BUFFER_BIT);
+        glBegin(GL_QUAD_STRIP);
         {
-            glEnable(GL_COLOR_MATERIAL);
-            glDisable(GL_LIGHTING);
-            glDisable(GL_TEXTURE_2D);
-            glDepthMask(GL_FALSE);
-
-            glBegin(GL_QUAD_STRIP);
+            for (i = 0; i <= n; i++)
             {
-                for (i = 0; i <= n; i++)
-                {
-                    float x = fcosf(2.f * PI * i / n);
-                    float y = fsinf(2.f * PI * i / n);
+                float x = fcosf(2.f * PI * i / n);
+                float y = fsinf(2.f * PI * i / n);
 
-                    glColor4f(1.0f, 1.0f, 0.0f, 0.5f);
-                    glVertex3f(x, 0.0f, y);
+                glColor4f(1.0f, 1.0f, 0.0f, 0.5f);
+                glVertex3f(x, 0.0f, y);
 
-                    glColor4f(1.0f, 1.0f, 0.0f, 0.0f);
-                    glVertex3f(x, GOAL_HEIGHT, y);
-                }
+                glColor4f(1.0f, 1.0f, 0.0f, 0.0f);
+                glVertex3f(x, GOAL_HEIGHT, y);
             }
-            glEnd();
         }
-        glPopAttrib();
+        glEnd();
     }
     glEndList();
 }
@@ -449,9 +125,9 @@ void goal_draw(void)
 
 static GLuint jump_list;
 
-void jump_init(int b)
+void jump_init(void)
 {
-    int k, i, n = b ? 32 : 8;
+    int k, i, n = 32;
 
     jump_list = glGenLists(2);
 
@@ -459,32 +135,21 @@ void jump_init(int b)
     {
         glNewList(jump_list + k, GL_COMPILE);
         {
-            glPushAttrib(GL_TEXTURE_BIT  |
-                         GL_LIGHTING_BIT |
-                         GL_DEPTH_BUFFER_BIT);
+            glBegin(GL_QUAD_STRIP);
             {
-                glEnable(GL_COLOR_MATERIAL);
-                glDisable(GL_LIGHTING);
-                glDisable(GL_TEXTURE_2D);
-                glDepthMask(GL_FALSE);
-
-                glBegin(GL_QUAD_STRIP);
+                for (i = 0; i <= n; i++)
                 {
-                    for (i = 0; i <= n; i++)
-                    {
-                        float x = fcosf(2.f * PI * i / n);
-                        float y = fsinf(2.f * PI * i / n);
+                    float x = fcosf(2.f * PI * i / n);
+                    float y = fsinf(2.f * PI * i / n);
 
-                        glColor4f(1.0f, 1.0f, 1.0f, (k == 0 ? 0.5f : 0.8f));
-                        glVertex3f(x, 0.0f, y);
+                    glColor4f(0.75f, 0.5f, 1.0f, (k == 0 ? 0.5f : 0.8f));
+                    glVertex3f(x, 0.0f, y);
 
-                        glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
-                        glVertex3f(x, JUMP_HEIGHT, y);
-                    }
+                    glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
+                    glVertex3f(x, JUMP_HEIGHT, y);
                 }
-                glEnd();
             }
-            glPopAttrib();
+            glEnd();
         }
         glEndList();
     }
@@ -506,18 +171,18 @@ void jump_draw(int highlight)
 static GLuint swch_list;
 
 static GLfloat swch_colors[8][4] = {
-    {1.0f, 0.0f, 0.0f, 0.5f}, /* red out */
-    {1.0f, 0.0f, 0.0f, 0.0f},
-    {1.0f, 0.0f, 0.0f, 0.8f}, /* red in */
-    {1.0f, 0.0f, 0.0f, 0.0f},
-    {0.0f, 1.0f, 0.0f, 0.5f}, /* green out */
-    {0.0f, 1.0f, 0.0f, 0.0f},
-    {0.0f, 1.0f, 0.0f, 0.8f}, /* green in */
-    {0.0f, 1.0f, 0.0f, 0.0f}};
-
-void swch_init(int b)
+    { 1.0f, 0.0f, 0.0f, 0.5f }, /* red out */
+    { 1.0f, 0.0f, 0.0f, 0.0f },
+    { 1.0f, 0.0f, 0.0f, 0.8f }, /* red in */
+    { 1.0f, 0.0f, 0.0f, 0.0f },
+    { 0.0f, 1.0f, 0.0f, 0.5f }, /* green out */
+    { 0.0f, 1.0f, 0.0f, 0.0f },
+    { 0.0f, 1.0f, 0.0f, 0.8f }, /* green in */
+    { 0.0f, 1.0f, 0.0f, 0.0f }};
+
+void swch_init(void)
 {
-    int k, i, n = b ? 32 : 8;
+    int k, i, n = 32;
 
     swch_list = glGenLists(4);
 
@@ -527,30 +192,21 @@ void swch_init(int b)
     {
         glNewList(swch_list + k, GL_COMPILE);
         {
-            glPushAttrib(GL_TEXTURE_BIT | GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT);
+            glBegin(GL_QUAD_STRIP);
             {
-                glEnable(GL_COLOR_MATERIAL);
-                glDisable(GL_LIGHTING);
-                glDisable(GL_TEXTURE_2D);
-                glDepthMask(GL_FALSE);
-
-                glBegin(GL_QUAD_STRIP);
+                for (i = 0; i <= n; i++)
                 {
-                    for (i = 0; i <= n; i++)
-                    {
-                        float x = fcosf(2.f * PI * i / n);
-                        float y = fsinf(2.f * PI * i / n);
+                    float x = fcosf(2.f * PI * i / n);
+                    float y = fsinf(2.f * PI * i / n);
 
-                        glColor4fv(swch_colors[2 * k]);
-                        glVertex3f(x, 0.0f, y);
+                    glColor4fv(swch_colors[2 * k + 0]);
+                    glVertex3f(x, 0.0f, y);
 
-                        glColor4fv(swch_colors[2 * k + 1]);
-                        glVertex3f(x, SWCH_HEIGHT, y);
-                    }
+                    glColor4fv(swch_colors[2 * k + 1]);
+                    glVertex3f(x, SWCH_HEIGHT, y);
                 }
-                glEnd();
             }
-            glPopAttrib();
+            glEnd();
         }
         glEndList();
     }
@@ -559,7 +215,7 @@ void swch_init(int b)
 void swch_free(void)
 {
     if (glIsList(swch_list))
-        glDeleteLists(swch_list, 2);
+        glDeleteLists(swch_list, 4);
 
     swch_list = 0;
 }
@@ -573,19 +229,31 @@ void swch_draw(int b, int e)
 
 static GLuint flag_list;
 
-void flag_init(int b)
+void flag_init(void)
 {
-    int i, n = b ? 8 : 4;
+    int i, n = 8;
 
     flag_list = glGenLists(1);
 
     glNewList(flag_list, GL_COMPILE);
     {
-        glPushAttrib(GL_TEXTURE_BIT | GL_LIGHTING_BIT);
+        glEnable(GL_COLOR_MATERIAL);
+        glDisable(GL_LIGHTING);
+        glDisable(GL_TEXTURE_2D);
         {
-            glEnable(GL_COLOR_MATERIAL);
-            glDisable(GL_LIGHTING);
-            glDisable(GL_TEXTURE_2D);
+            glBegin(GL_TRIANGLES);
+            {
+                glColor3f(1.0f, 0.0f, 0.0f);
+
+                glVertex3f(              0.0f, GOAL_HEIGHT,        0.0f);
+                glVertex3f(GOAL_HEIGHT * 0.2f, GOAL_HEIGHT * 0.9f, 0.0f);
+                glVertex3f(              0.0f, GOAL_HEIGHT * 0.8f, 0.0f);
+
+                glVertex3f(              0.0f, GOAL_HEIGHT,        0.0f);
+                glVertex3f(              0.0f, GOAL_HEIGHT * 0.8f, 0.0f);
+                glVertex3f(GOAL_HEIGHT * 0.2f, GOAL_HEIGHT * 0.9f, 0.0f);
+            }
+            glEnd();
 
             glBegin(GL_QUAD_STRIP);
             {
@@ -600,22 +268,10 @@ void flag_init(int b)
                 }
             }
             glEnd();
-
-            glBegin(GL_TRIANGLES);
-            {
-                glColor3f(1.0f, 0.0f, 0.0f);
-
-                glVertex3f(              0.0f, GOAL_HEIGHT,        0.0f);
-                glVertex3f(GOAL_HEIGHT * 0.2f, GOAL_HEIGHT * 0.9f, 0.0f);
-                glVertex3f(              0.0f, GOAL_HEIGHT * 0.8f, 0.0f);
-
-                glVertex3f(              0.0f, GOAL_HEIGHT,        0.0f);
-                glVertex3f(              0.0f, GOAL_HEIGHT * 0.8f, 0.0f);
-                glVertex3f(GOAL_HEIGHT * 0.2f, GOAL_HEIGHT * 0.9f, 0.0f);
-            }
-            glEnd();
         }
-        glPopAttrib();
+        glEnable(GL_TEXTURE_2D);
+        glEnable(GL_LIGHTING);
+        glDisable(GL_COLOR_MATERIAL);
     }
     glEndList();
 }
@@ -651,7 +307,7 @@ static GLuint shad_text;
 
 void shad_init(void)
 {
-    shad_text = make_image_from_file(NULL, NULL, NULL, NULL, IMG_SHAD);
+    shad_text = make_image_from_file(IMG_SHAD);
 
     if (config_get_d(CONFIG_SHADOW) == 2)
     {
@@ -695,16 +351,12 @@ void shad_draw_clr(void)
 
 void fade_draw(float k)
 {
-    int w = config_get_d(CONFIG_WIDTH);
-    int h = config_get_d(CONFIG_HEIGHT);
-
     if (k > 0.0f)
     {
-        config_push_ortho();
-        glPushAttrib(GL_TEXTURE_BIT  |
-                     GL_LIGHTING_BIT |
-                     GL_COLOR_BUFFER_BIT |
-                     GL_DEPTH_BUFFER_BIT);
+        int w = config_get_d(CONFIG_WIDTH);
+        int h = config_get_d(CONFIG_HEIGHT);
+
+        video_push_ortho();
         {
             glEnable(GL_COLOR_MATERIAL);
             glDisable(GL_LIGHTING);
@@ -721,9 +373,15 @@ void fade_draw(float k)
                 glVertex2i(0, h);
             }
             glEnd();
+
+            glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+
+            glEnable(GL_TEXTURE_2D);
+            glEnable(GL_DEPTH_TEST);
+            glEnable(GL_LIGHTING);
+            glDisable(GL_COLOR_MATERIAL);
         }
-        glPopAttrib();
-        config_pop_matrix();
+        video_pop_matrix();
     }
 }