shithub: zelda3

Download patch

ref: d5d918c8df0bbc5758c48f33cc8203df6714d874
parent: e8ea536320ebd84885edd5c4adb57b1d009c6044
author: Snesrev <snesrev@protonmail.com>
date: Sun Sep 4 10:07:02 EDT 2022

Remove atan2f

--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@
 CFLAGS:=$(if $(CFLAGS),$(CFLAGS),-O2)
 
 CFLAGS:=${CFLAGS} $(shell sdl2-config --cflags)
-LDFLAGS:=${LDFLAGS} -lm $(shell sdl2-config --libs)
+LDFLAGS:=${LDFLAGS} $(shell sdl2-config --libs)
 
 .PHONY: all clean clean_obj clean_gen
 
--- a/main.c
+++ b/main.c
@@ -462,6 +462,26 @@
   }
 }
 
+// Approximates atan2(y, x) normalized to the [0,4) range
+// with a maximum error of 0.1620 degrees
+// normalized_atan(x) ~ (b x + x^2) / (1 + 2 b x + x^2)
+static float ApproximateAtan2(float y, float x) {
+  uint32 sign_mask = 0x80000000;
+  float b = 0.596227f;
+  // Extract the sign bits
+  uint32 ux_s = sign_mask & *(uint32 *)&x;
+  uint32 uy_s = sign_mask & *(uint32 *)&y;
+  // Determine the quadrant offset
+  float q = (float)((~ux_s & uy_s) >> 29 | ux_s >> 30);
+  // Calculate the arctangent in the first quadrant
+  float bxy_a = fabs(b * x * y);
+  float num = bxy_a + y * y;
+  float atan_1q = num / (x * x + bxy_a + num + 0.000001f);
+  // Translate it to the proper quadrant
+  uint32_t uatan_2q = (ux_s ^ uy_s) | *(uint32 *)&atan_1q;
+  return q + *(float *)&uatan_2q;
+}
+
 static void HandleGamepadAxisInput(int gamepad_id, int axis, int value) {
   static int last_gamepad_id, last_x, last_y;
   if (axis == SDL_CONTROLLER_AXIS_LEFTX || axis == SDL_CONTROLLER_AXIS_LEFTY) {
@@ -486,7 +506,7 @@
         1 << 6,           // 6 = left
         1 << 6 | 1 << 4,  // 7 = left, up
       };
-      int angle = (int)(atan2f(last_y, last_x) * (float)(128 / M_PI) + 0.5f);
+      uint8 angle = (uint8)(int)(ApproximateAtan2(last_y, last_x) * 64.0f + 0.5f);
       buttons = kSegmentToButtons[(uint8)(angle + 16 + 64) >> 5];
     }
     g_gamepad_buttons = buttons;