You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+/*#define MINIGLUT_GCC_NO_BUILTIN*/
+
#ifdef MINIGLUT_USE_LIBC
#define _GNU_SOURCE
#include <stdlib.h>
#include <math.h>
+#else
+
+#if defined(__GNUC__) && !defined(MINIGLUT_GCC_NO_BUILTIN)
+#define mglut_sincosf(a, s, c) __builtin_sincosf(a, s, c)
+#define mglut_atan(x) __builtin_atan(x)
+#else
+static void mglut_sincosf(float angle, float *sptr, float *cptr);
+static float mglut_atan(float x);
+#endif
+
#endif
#define PI 3.1415926536f
};
static void create_window(const char *title);
-static void get_window_pos(Window win, int *x, int *y);
-static void get_window_size(Window win, int *w, int *h);
-static void get_screen_size(Window win, int *scrw, int *scrh);
+static void get_window_pos(int *x, int *y);
+static void get_window_size(int *w, int *h);
+static void get_screen_size(int *scrw, int *scrh);
static long get_msec(void);
static void panic(const char *msg);
int x, y;
switch(s) {
case GLUT_WINDOW_X:
- get_window_pos(win, &x, &y);
+ get_window_pos(&x, &y);
return x;
case GLUT_WINDOW_Y:
- get_window_pos(win, &x, &y);
+ get_window_pos(&x, &y);
return y;
case GLUT_WINDOW_WIDTH:
- get_window_size(win, &x, &y);
+ get_window_size(&x, &y);
return x;
case GLUT_WINDOW_HEIGHT:
- get_window_size(win, &x, &y);
+ get_window_size(&x, &y);
return y;
case GLUT_WINDOW_BUFFER_SIZE:
return ctx_info.rsize + ctx_info.gsize + ctx_info.bsize + ctx_info.asize;
case GLUT_WINDOW_CURSOR:
return cur_cursor;
case GLUT_SCREEN_WIDTH:
- get_screen_size(win, &x, &y);
+ get_screen_size(&x, &y);
return x;
case GLUT_SCREEN_HEIGHT:
- get_screen_size(win, &x, &y);
+ get_screen_size(&x, &y);
return y;
case GLUT_INIT_DISPLAY_MODE:
return init_mode;
t = gray & 2 ? v + dv : v;
theta = s * PI * 2.0f;
phi = t * PI;
- sincosf(theta, &sintheta, &costheta);
- sincosf(phi, &sinphi, &cosphi);
+ mglut_sincosf(theta, &sintheta, &costheta);
+ mglut_sincosf(phi, &sinphi, &cosphi);
x = sintheta * sinphi;
y = costheta * sinphi;
z = cosphi;
float du = 1.0f / (float)slices;
float dv = 1.0f / (float)stacks;
- phi = atan(fabs(rbot - rtop) / height);
- sincosf(phi, &sinphi, &cosphi);
+ rad = rbot - rtop;
+ phi = mglut_atan((rad < 0 ? -rad : rad) / height);
+ mglut_sincosf(phi, &sinphi, &cosphi);
glBegin(GL_QUADS);
for(i=0; i<stacks; i++) {
t = gray & 1 ? v + dv : v;
rad = rbot + (rtop - rbot) * t;
theta = s * PI * 2.0f;
- sincosf(theta, &sintheta, &costheta);
+ mglut_sincosf(theta, &sintheta, &costheta);
x = sintheta * cosphi;
y = costheta * cosphi;
t = gray & 2 ? v + dv : v;
theta = s * PI * 2.0f;
phi = t * PI * 2.0f;
- sincosf(theta, &sintheta, &costheta);
- sincosf(phi, &sinphi, &cosphi);
+ mglut_sincosf(theta, &sintheta, &costheta);
+ mglut_sincosf(phi, &sinphi, &cosphi);
x = sintheta * sinphi;
y = costheta * sinphi;
z = cosphi;
glXMakeCurrent(dpy, win, ctx);
}
-static void get_window_pos(Window win, int *x, int *y)
+static void get_window_pos(int *x, int *y)
{
XWindowAttributes wattr;
XGetWindowAttributes(dpy, win, &wattr);
*y = wattr.y;
}
-static void get_window_size(Window win, int *w, int *h)
+static void get_window_size(int *w, int *h)
{
XWindowAttributes wattr;
XGetWindowAttributes(dpy, win, &wattr);
*h = wattr.height;
}
-static void get_screen_size(Window win, int *scrw, int *scrh)
+static void get_screen_size(int *scrw, int *scrh)
{
XWindowAttributes wattr;
XGetWindowAttributes(dpy, root, &wattr);
{
return write(fd, buf, count);
}
+
#else /* !MINIGLUT_USE_LIBC */
+#if defined(__GNUC__) && defined(MINIGLUT_GCC_NO_BUILTIN)
+static void mglut_sincosf(float angle, float *sptr, float *cptr)
+{
+ asm volatile(
+ "flds %2\n\t"
+ "fsincos\n\t"
+ "fstps %1\n\t"
+ "fstps %0\n\t"
+ : "=m"(*sptr), "=m"(*cptr)
+ : "m"(angle)
+ );
+}
+
+static float mglut_atan(float x)
+{
+ float res;
+ asm volatile(
+ "flds %1\n\t"
+ "fld1\n\t"
+ "fpatan\n\t"
+ "fstps %0\n\t"
+ : "=m"(res)
+ : "m"(x)
+ );
+ return res;
+}
+#endif
+
+#ifdef _MSC_VER
+static void mglut_sincosf(float angle, float *sptr, float *cptr)
+{
+ float s, c;
+ __asm {
+ fld angle
+ fsincos
+ fstp c
+ fstp s
+ }
+ *sptr = s;
+ *cptr = c;
+}
+
+static float mglut_atan(float x)
+{
+ float res;
+ __asm {
+ fld x
+ fld1
+ fpatan
+ fstp res
+ }
+ return res;
+}
+#endif
+
+#ifdef __WATCOMC__
+#pragma aux mglut_sincosf = \
+ "fsincos" \
+ "fstp dword ptr [edx]" \
+ "fstp dword ptr [eax]" \
+ parm[8087][eax][edx] \
+ modify[8087];
+
+#pragma aux mglut_atan = \
+ "fld1" \
+ "fpatan" \
+ parm[8087] \
+ value[8087] \
+ modify [8087];
+#endif
+
#ifdef __linux__
#ifdef __x86_64__