add late flips
[carveJwlIkooP6JGAAIwe30JlM.git] / world_audio.c
1 #ifndef WORLD_AUDIO_C
2 #define WORLD_AUDIO_C
3
4 #include "audio.h"
5 #include "world_audio.h"
6
7 /* finds any active playing in world and fades them out, we can only do this
8 * while unloading */
9 static void world_fadeout_audio( world_instance *world )
10 {
11 if( world->status != k_world_status_unloading ){
12 vg_fatal_error( "World status must be set to 'unloading', to fadeout"
13 " audio.\n" );
14 }
15
16 u8 world_id = (world - world_static.instances) + 1;
17
18 audio_lock();
19 for( u32 i=0; i<AUDIO_CHANNELS; i++ ){
20 audio_channel *ch = &vg_audio.channels[i];
21
22 if( ch->allocated && (ch->world_id == world_id) ){
23 ch = audio_channel_fadeout( ch, 1.0f );
24 }
25 }
26 audio_unlock();
27 }
28
29 /*
30 * Trace out a random point, near the player to try and determine water areas
31 */
32 static
33 enum audio_sprite_type world_audio_sample_sprite_random(v3f origin, v3f output)
34 {
35 v3f chance = { (vg_randf64()-0.5f) * 30.0f,
36 8.0f,
37 (vg_randf64()-0.5f) * 30.0f };
38
39 v3f pos;
40 v3_add( chance, origin, pos );
41
42 ray_hit contact;
43 contact.dist = vg_minf( 16.0f, pos[1] );
44
45 world_instance *world = world_current_instance();
46
47 if( ray_world( world, pos, (v3f){0.0f,-1.0f,0.0f}, &contact,
48 k_material_flag_ghosts ) ){
49 struct world_surface *mat = ray_hit_surface( world, &contact );
50
51 if( mat->info.surface_prop == k_surface_prop_grass){
52 v3_copy( contact.pos, output );
53 return k_audio_sprite_type_grass;
54 }
55 else{
56 return k_audio_sprite_type_none;
57 }
58 }
59
60 output[0] = pos[0];
61 output[1] = 0.0f;
62 output[2] = pos[2];
63
64 float dist = fabsf(output[1] - origin[1]);
65
66 if( world->water.enabled && dist<=40.0f )
67 return k_audio_sprite_type_water;
68 else
69 return k_audio_sprite_type_none;
70 }
71
72 static void world_audio_sample_distances( v3f co, int *index, float *value )
73 {
74 float inr3 = 0.57735027,
75 inr2 = 0.70710678118;
76
77 v3f sample_directions[] = {
78 { -1.0f, 0.0f, 0.0f },
79 { 1.0f, 0.0f, 0.0f },
80 { 0.0f, 0.0f, 1.0f },
81 { 0.0f, 0.0f, -1.0f },
82 { 0.0f, 1.0f, 0.0f },
83 { 0.0f, -1.0f, 0.0f },
84 { -inr3, inr3, inr3 },
85 { inr3, inr3, inr3 },
86 { -inr3, inr3, -inr3 },
87 { inr3, inr3, -inr3 },
88 { -inr2, 0.0f, inr2 },
89 { inr2, 0.0f, inr2 },
90 { -inr2, 0.0f, -inr2 },
91 { inr2, 0.0f, -inr2 },
92 };
93
94 static int si = 0;
95 static float distances[16];
96
97 ray_hit ray;
98 ray.dist = 5.0f;
99
100 v3f rc, rd, ro;
101 v3_copy( sample_directions[ si ], rd );
102 v3_add( co, (v3f){0.0f,1.5f,0.0f}, ro );
103 v3_copy( ro, rc );
104
105 float dist = 200.0f;
106
107 for( int i=0; i<10; i++ ){
108 if( ray_world( world_current_instance(), rc, rd, &ray,
109 k_material_flag_ghosts ) ){
110 dist = (float)i*5.0f + ray.dist;
111 break;
112 }
113 else{
114 v3_muladds( rc, rd, ray.dist, rc );
115 }
116 }
117
118 distances[si] = dist;
119
120 if( vg_audio.debug_ui && vg_lines.draw ){
121 for( int i=0; i<14; i++ ){
122 if( distances[i] != 200.0f ){
123 u32 colours[] = { VG__RED, VG__BLUE, VG__GREEN,
124 VG__CYAN, VG__YELOW, VG__PINK,
125 VG__WHITE };
126
127 u32 colour = colours[i%7];
128
129 v3f p1;
130 v3_muladds( ro, sample_directions[i], distances[i], p1 );
131 vg_line( ro, p1, colour );
132 vg_line_point( p1, 0.1f, colour );
133 }
134 }
135 }
136
137 *index = si;
138 *value = dist;
139
140 si ++;
141 if( si >= 14 )
142 si = 0;
143 }
144
145 #endif /* WORLD_AUDIO_C */