]> git.lizzy.rs Git - nothing.git/commitdiff
(#134) make sound_medium respect the position
authorrexim <reximkut@gmail.com>
Sun, 8 Apr 2018 19:09:10 +0000 (02:09 +0700)
committerrexim <reximkut@gmail.com>
Sun, 8 Apr 2018 19:09:10 +0000 (02:09 +0700)
src/algo.h [new file with mode: 0644]
src/point.c
src/point.h
src/sound_medium.c

diff --git a/src/algo.h b/src/algo.h
new file mode 100644 (file)
index 0000000..46eaf04
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef ALGO_H_
+#define ALGO_H_
+
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MAX(a,b) (((a)>(b))?(a):(b))
+
+#endif  // ALGO_H_
index 4925e888c80d94031a0350885f69fca094b21139..da8fadca14643b3763c0a3d1b098e5b6b21a78e7 100644 (file)
@@ -1,3 +1,4 @@
+#include <assert.h>
 #include <math.h>
 #include "./point.h"
 
@@ -10,6 +11,25 @@ vec_t vec(float x, float y)
     return result;
 }
 
+vec_t vec_from_ps(point_t p1, point_t p2)
+{
+    vec_t result = {
+        .x = p2.x - p1.x,
+        .y = p2.y - p1.y
+    };
+    return result;
+}
+
+float vec_arg(vec_t v)
+{
+    return atan2f(v.y, v.x);
+}
+
+float vec_mag(vec_t v)
+{
+    return sqrtf(v.x * v.x + v.y * v.y);
+}
+
 vec_t vec_sum(vec_t v1, vec_t v2)
 {
     vec_t result = {
index dcdb1ac89472c9c4c95d865901b442e51fedf0b4..24d0538fb5945c5f9de7b85d1cf501ebc5a7a8fa 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef POINT_H_
 #define POINT_H_
 
+#include "./pi.h"
+
 typedef struct point_t {
     float x, y;
 } point_t;
@@ -8,6 +10,16 @@ typedef struct point_t {
 typedef point_t vec_t;
 
 vec_t vec(float x, float y);
+vec_t vec_from_ps(point_t p1, point_t p2);
+
+float vec_arg(vec_t v);
+float vec_mag(vec_t v);
+
+inline float rad_to_deg(float a)
+{
+    return 180 / PI * a;
+}
+
 vec_t vec_sum(vec_t v1, vec_t v2);
 vec_t vec_neg(vec_t v);
 void vec_add(vec_t *v1, vec_t v2);
index 18802217159d7aa7f8640d25feb8a9527e85a806..6580f18f16e064e7f7957641b962b41a9891d73c 100644 (file)
@@ -8,12 +8,17 @@
 #include "./sound_medium.h"
 #include "./lt.h"
 #include "./error.h"
+#include "./pi.h"
+#include "./algo.h"
+
+#define SOUND_THRESHOLD_DISTANCE 200.0f
 
 struct sound_medium_t
 {
     lt_t *lt;
     Mix_Chunk **samples;
     size_t samples_count;
+    point_t *channel_positions;
 };
 
 static int mix_get_free_channel(void)
@@ -43,6 +48,12 @@ sound_medium_t *create_sound_medium(Mix_Chunk **samples, size_t samples_count)
         RETURN_LT(lt, NULL);
     }
 
+    sound_medium->channel_positions = PUSH_LT(lt, malloc(sizeof(point_t) * MIX_CHANNELS), free);
+    if (sound_medium->channel_positions == NULL) {
+        throw_error(ERROR_TYPE_LIBC);
+        RETURN_LT(lt, NULL);
+    }
+
     sound_medium->samples = samples;
     sound_medium->samples_count = samples_count;
 
@@ -57,7 +68,6 @@ void destroy_sound_medium(sound_medium_t *sound_medium)
     RETURN_LT0(sound_medium->lt);
 }
 
-/* TODO(#134): sound_medium doesn't take into account the positions of the sound and the listener */
 int sound_medium_play_sound(sound_medium_t *sound_medium,
                             size_t sound_index,
                             point_t position)
@@ -70,6 +80,7 @@ int sound_medium_play_sound(sound_medium_t *sound_medium,
         const int free_channel = mix_get_free_channel();
 
         if (free_channel >= 0) {
+            sound_medium->channel_positions[free_channel] = position;
             return Mix_PlayChannel(free_channel, sound_medium->samples[sound_index], 0);
         }
     }
@@ -81,6 +92,15 @@ int sound_medium_listen_sounds(sound_medium_t *sound_medium,
                                point_t position)
 {
     assert(sound_medium);
-    (void) position;
+
+    for (int i = 0; i < MIX_CHANNELS; ++i) {
+        if (Mix_Playing(i)) {
+            const vec_t v = vec_from_ps(position, sound_medium->channel_positions[i]);
+            const Sint16 angle = (Sint16) roundf(rad_to_deg(vec_arg(v)));
+            const Uint8 distance = (Uint8) roundf(MIN(vec_mag(v), SOUND_THRESHOLD_DISTANCE) / SOUND_THRESHOLD_DISTANCE * 255.0f);
+            Mix_SetPosition(i, angle, distance);
+        }
+    }
+
     return 0;
 }