Subversion Repositories eduke32

Rev

Rev 4948 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1247 helixhorne 1
//-------------------------------------------------------------------------
2
/*
1652 terminx 3
Copyright (C) 2010 EDuke32 developers and contributors
1247 helixhorne 4
 
1652 terminx 5
This file is part of EDuke32.
1247 helixhorne 6
 
7
EDuke32 is free software; you can redistribute it and/or
8
modify it under the terms of the GNU General Public License version 2
9
as published by the Free Software Foundation.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 
15
See the GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
4541 hendricks2 19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
1247 helixhorne 20
*/
21
//-------------------------------------------------------------------------
22
 
23
// Stripped sounds.c for use in Mapster32, breaks all ties to game & music
24
 
25
#include <stdio.h>
26
#include <string.h>
1346 terminx 27
 
1468 terminx 28
#include "compat.h"
1886 helixhorne 29
#include "baselayer.h"
1468 terminx 30
 
1247 helixhorne 31
#include "fx_man.h"
32
#include "osd.h"
33
 
34
#include "cache1d.h"
35
#include "build.h"  // vec3_t
1886 helixhorne 36
#include "editor.h"
1247 helixhorne 37
 
3224 helixhorne 38
#include "macros.h"
5197 hendricks2 39
#include "common.h"
3224 helixhorne 40
 
3839 hendricks2 41
#ifdef _WIN32
1672 terminx 42
#include "winlayer.h"
43
#endif
44
 
1247 helixhorne 45
#include "sounds_mapster32.h"
4668 terminx 46
#include "common.h"
47
#include "common_game.h"
1247 helixhorne 48
 
49
#define LOUDESTVOLUME 150
50
#define MUSICANDSFX 5
51
 
52
static char SM32_havesound = 0;
1454 terminx 53
 
2439 helixhorne 54
static char SoundToggle = 1;
1251 helixhorne 55
int32_t NumVoices = 32;
1697 helixhorne 56
int32_t MixRate = 44100;
1247 helixhorne 57
 
2439 helixhorne 58
int32_t g_numEnvSoundsPlaying;
1247 helixhorne 59
 
60
void MUSIC_Update(void) {}  // needed when linking
61
 
1599 terminx 62
void S_Callback(uint32_t);
1247 helixhorne 63
 
64
/*
65
===================
66
=
67
= SoundStartup
68
=
69
===================
70
*/
71
 
1468 terminx 72
 
1247 helixhorne 73
int32_t S_SoundStartup(void)
74
{
1468 terminx 75
    int32_t status;
76
    int32_t fxdevicetype;
1677 terminx 77
    void *initdata = 0;
1247 helixhorne 78
 
79
    // TODO: read config
1697 helixhorne 80
    int32_t FXVolume=220, /*NumVoices=32,*/ NumChannels=2, NumBits=16, ReverseStereo=0;
81
 
1468 terminx 82
    fxdevicetype = ASS_AutoDetect;
1247 helixhorne 83
 
4084 hendricks2 84
#ifdef MIXERTYPEWIN
3221 hendricks2 85
    initdata = (void *) win_gethwnd(); // used for DirectSound
1468 terminx 86
#endif
1247 helixhorne 87
 
1468 terminx 88
    status = FX_Init(fxdevicetype, NumVoices, NumChannels, NumBits, MixRate, initdata);
1247 helixhorne 89
    if (status == FX_Ok)
90
    {
91
        FX_SetVolume(FXVolume);
1468 terminx 92
        FX_SetReverseStereo(ReverseStereo);
1599 terminx 93
        status = FX_SetCallBack(S_Callback);
1247 helixhorne 94
    }
95
 
96
    if (status != FX_Ok)
97
    {
3668 hendricks2 98
        initprintf("Sound startup error: %s\n", FX_ErrorString(FX_Error));
1247 helixhorne 99
        return -2;
100
    }
101
 
102
    SM32_havesound = 1;
1468 terminx 103
 
1247 helixhorne 104
    return 0;
105
}
106
 
107
/*
108
===================
109
=
110
= SoundShutdown
111
=
112
===================
113
*/
114
 
115
void S_SoundShutdown(void)
116
{
117
    int32_t status;
118
 
119
    if (!SM32_havesound)
120
        return;
121
 
122
    status = FX_Shutdown();
123
    if (status != FX_Ok)
3668 hendricks2 124
        initprintf("Sound shutdown error: %s\n", FX_ErrorString(FX_Error));
1247 helixhorne 125
}
126
 
127
int32_t S_LoadSound(uint32_t num)
128
{
129
    int32_t   fp = -1, l;
130
 
131
    if (!SM32_havesound) return 0;
132
    if (num >= MAXSOUNDS || SoundToggle == 0) return 0;
133
 
134
    if (g_sounds[num].filename == NULL)
135
    {
136
        OSD_Printf(OSD_ERROR "Sound (#%d) not defined!\n",num);
137
        return 0;
138
    }
139
 
4948 hendricks2 140
#if defined HAVE_FLAC || defined HAVE_VORBIS
141
    fp = S_UpgradeFormat(g_sounds[num].filename, 0);
1247 helixhorne 142
    if (fp == -1)
4948 hendricks2 143
#endif
144
        fp = kopen4loadfrommod(g_sounds[num].filename,0);
145
    if (fp == -1)
1247 helixhorne 146
    {
147
        OSD_Printf(OSDTEXT_RED "Sound %s(#%d) not found!\n",g_sounds[num].filename,num);
148
        return 0;
149
    }
150
 
151
    l = kfilelength(fp);
152
    g_sounds[num].soundsiz = l;
153
 
154
    g_sounds[num].lock = 200;
155
 
156
    allocache((intptr_t *)&g_sounds[num].ptr,l,(char *)&g_sounds[num].lock);
157
    kread(fp, g_sounds[num].ptr , l);
158
    kclose(fp);
159
    return 1;
160
}
161
 
1487 terminx 162
int32_t S_PlaySound3D(int32_t num, int32_t i, const vec3_t *pos)
1247 helixhorne 163
{
1251 helixhorne 164
    int32_t sndist, cx, cy, cz, j/*,k*/;
1247 helixhorne 165
    int32_t pitche,pitchs,cs;
166
    int32_t voice, sndang, ca, pitch;
167
 
168
    //    if(num != 358) return 0;
169
 
170
    if (num >= MAXSOUNDS ||
1316 terminx 171
            !SM32_havesound ||
4055 helixhorne 172
//        ((g_sounds[num].m & SF_ADULT) && ud.lockout) ||
1316 terminx 173
            SoundToggle == 0 ||
174
            g_sounds[num].num > 3 ||
175
            FX_VoiceAvailable(g_sounds[num].pr) == 0)
176
        return -1;
1247 helixhorne 177
 
4055 helixhorne 178
    if (g_sounds[num].m & SF_DTAG)
1247 helixhorne 179
    {
180
        S_PlaySound(num);
181
        return 0;
182
    }
183
 
4055 helixhorne 184
    if (g_sounds[num].m & SF_TALK)
1247 helixhorne 185
    {
186
        for (j=0; j<MAXSOUNDS; j++)
187
//            for (k=0; k<g_sounds[j].num; k++)
4055 helixhorne 188
            if ((g_sounds[j].num > 0) && (g_sounds[j].m & SF_TALK))
1316 terminx 189
                return -1;
1247 helixhorne 190
    }
191
 
192
    cx = pos->x;
193
    cy = pos->y;
194
    cz = pos->z;
195
    cs = cursectnum;
196
    ca = ang;
197
 
4659 terminx 198
    sndist = FindDistance3D((cx-pos->x),(cy-pos->y),(cz-pos->z));
1247 helixhorne 199
 
4055 helixhorne 200
    if (i >= 0 && (g_sounds[num].m & SF_GLOBAL) == 0 && PN == MUSICANDSFX && SLT < 999 && (sector[SECT].lotag&0xff) < 9)
1247 helixhorne 201
        sndist = divscale14(sndist,(SHT+1));
202
 
203
    pitchs = g_sounds[num].ps;
204
    pitche = g_sounds[num].pe;
205
    cx = klabs(pitche-pitchs);
206
 
207
    if (cx)
208
    {
209
        if (pitchs < pitche)
210
            pitch = pitchs + (rand()%cx);
211
        else pitch = pitche + (rand()%cx);
212
    }
213
    else pitch = pitchs;
214
 
215
    sndist += g_sounds[num].vo;
216
    if (sndist < 0) sndist = 0;
217
    if (cs > -1 && sndist && PN != MUSICANDSFX && !cansee(cx,cy,cz-(24<<8),cs,SX,SY,SZ-(24<<8),SECT))
218
        sndist += sndist>>5;
1316 terminx 219
    /*
220
        switch (num)
221
        {
222
        case PIPEBOMB_EXPLODE:
223
        case LASERTRIP_EXPLODE:
224
        case RPG_EXPLODE:
225
            if (sndist > (6144))
226
                sndist = 6144;
227
            if (g_player[screenpeek].ps->cursectnum > -1 && sector[g_player[screenpeek].ps->cursectnum].lotag == 2)
228
                pitch -= 1024;
229
            break;
230
        default:
231
    */
4055 helixhorne 232
    if (cursectnum > -1 && sector[cursectnum].lotag == 2 && (g_sounds[num].m & SF_TALK) == 0)
1316 terminx 233
        pitch = -768;
234
    if (sndist > 31444 && PN != MUSICANDSFX)
235
        return -1;
1247 helixhorne 236
//        break;
237
//    }
238
 
239
    if (g_sounds[num].num > 0 && PN != MUSICANDSFX)
240
    {
2442 helixhorne 241
        if (g_sounds[num].SoundOwner[0].ow == i) S_StopSound(num);
1247 helixhorne 242
        else if (g_sounds[num].num > 1) S_StopSound(num);
243
//        else if (A_CheckEnemySprite(&sprite[i]) && sprite[i].extra <= 0) S_StopSound(num);
244
    }
245
 
246
    sndang = 2048 + ca - getangle(cx-pos->x,cy-pos->y);
247
    sndang &= 2047;
248
 
249
    if (g_sounds[num].ptr == 0)
250
    {
251
        if (S_LoadSound(num) == 0) return 0;
252
    }
253
    else
254
    {
255
        if (g_sounds[num].lock < 200)
256
            g_sounds[num].lock = 200;
257
        else g_sounds[num].lock++;
258
    }
259
 
4055 helixhorne 260
    if (g_sounds[num].m & SF_GLOBAL) sndist = 0;
1247 helixhorne 261
 
262
    if (sndist < ((255-LOUDESTVOLUME)<<6))
263
        sndist = ((255-LOUDESTVOLUME)<<6);
264
 
4055 helixhorne 265
    if (g_sounds[num].m & SF_LOOP)
1247 helixhorne 266
    {
3631 helixhorne 267
        if (g_sounds[num].num > 0)
268
            return -1;
1247 helixhorne 269
 
1468 terminx 270
        voice = FX_PlayLoopedAuto(g_sounds[num].ptr, g_sounds[num].soundsiz, 0, -1,
3631 helixhorne 271
                                  pitch, sndist>>6, sndist>>6, 0, g_sounds[num].pr, num);
1247 helixhorne 272
    }
273
    else
274
    {
3631 helixhorne 275
        voice = FX_PlayAuto3D(g_sounds[num].ptr, g_sounds[num].soundsiz, FX_ONESHOT,
276
                              pitch, sndang>>4, sndist>>6, g_sounds[num].pr, num);
1247 helixhorne 277
    }
278
 
1465 terminx 279
    if (voice >= FX_Ok)
1247 helixhorne 280
    {
2442 helixhorne 281
        g_sounds[num].SoundOwner[g_sounds[num].num].ow = i;
1247 helixhorne 282
        g_sounds[num].SoundOwner[g_sounds[num].num].voice = voice;
283
        g_sounds[num].num++;
284
    }
285
    else g_sounds[num].lock--;
286
    return (voice);
287
}
288
 
289
void S_PlaySound(int32_t num)
290
{
291
    int32_t pitch,pitche,pitchs,cx;
292
    int32_t voice;
293
 
294
    if (!SM32_havesound) return;
295
    if (SoundToggle==0) return;
2278 helixhorne 296
    if ((unsigned)num >= MAXSOUNDS || !g_sounds[num].filename)
1247 helixhorne 297
    {
298
        OSD_Printf("WARNING: invalid sound #%d\n",num);
299
        return;
300
    }
4055 helixhorne 301
//    if ((g_sounds[num].m & SF_ADULT) && ud.lockout) return;
2278 helixhorne 302
    if (FX_VoiceAvailable(g_sounds[num].pr) == 0) return;
1247 helixhorne 303
 
304
    pitchs = g_sounds[num].ps;
305
    pitche = g_sounds[num].pe;
306
    cx = klabs(pitche-pitchs);
307
 
308
    if (cx)
309
    {
310
        if (pitchs < pitche)
311
            pitch = pitchs + (rand()%cx);
312
        else pitch = pitche + (rand()%cx);
313
    }
314
    else pitch = pitchs;
315
 
316
    if (g_sounds[num].ptr == 0)
317
    {
318
        if (S_LoadSound(num) == 0) return;
319
    }
320
    else
321
    {
322
        if (g_sounds[num].lock < 200)
323
            g_sounds[num].lock = 200;
324
        else g_sounds[num].lock++;
325
    }
326
 
4055 helixhorne 327
    if (g_sounds[num].m & SF_LOOP)
1247 helixhorne 328
    {
1468 terminx 329
        voice = FX_PlayLoopedAuto(g_sounds[num].ptr, g_sounds[num].soundsiz, 0, -1,
330
                                  pitch,LOUDESTVOLUME,LOUDESTVOLUME,LOUDESTVOLUME,g_sounds[num].soundsiz,num);
1247 helixhorne 331
    }
332
    else
333
    {
3631 helixhorne 334
        voice = FX_PlayAuto3D(g_sounds[num].ptr, g_sounds[num].soundsiz, FX_ONESHOT,
2278 helixhorne 335
                              pitch,0,255-LOUDESTVOLUME,g_sounds[num].pr, num);
1247 helixhorne 336
    }
337
 
2278 helixhorne 338
    if (voice >= FX_Ok)
1247 helixhorne 339
    {
2442 helixhorne 340
        g_sounds[num].SoundOwner[g_sounds[num].num].ow = -1;
1247 helixhorne 341
        g_sounds[num].SoundOwner[g_sounds[num].num].voice = voice;
342
        g_sounds[num].num++;
343
        return;
344
    }
345
    g_sounds[num].lock--;
346
}
347
 
348
int32_t A_PlaySound(uint32_t num, int32_t i)
349
{
350
    if (num >= MAXSOUNDS) return -1;
351
    if (i < 0)
352
    {
353
        S_PlaySound(num);
354
        return 0;
355
    }
356
 
1487 terminx 357
    return S_PlaySound3D(num,i, (vec3_t *)&sprite[i]);
1247 helixhorne 358
}
359
 
360
void S_StopSound(int32_t num)
361
{
362
    if (num >= 0 && num < MAXSOUNDS)
363
        if (g_sounds[num].num > 0)
364
        {
365
            FX_StopSound(g_sounds[num].SoundOwner[g_sounds[num].num-1].voice);
1599 terminx 366
            S_Callback(num);
1247 helixhorne 367
        }
368
}
369
 
370
void S_StopEnvSound(int32_t num,int32_t i)
371
{
372
    int32_t j, k;
373
 
374
    if (num >= 0 && num < MAXSOUNDS)
375
        if (g_sounds[num].num > 0)
376
        {
377
            k = g_sounds[num].num;
378
            for (j=0; j<k; j++)
2442 helixhorne 379
                if (g_sounds[num].SoundOwner[j].ow == i)
1247 helixhorne 380
                {
381
                    FX_StopSound(g_sounds[num].SoundOwner[j].voice);
382
                    break;
383
                }
384
        }
385
}
386
 
1625 terminx 387
void S_Update(void)
1247 helixhorne 388
{
389
    int32_t sndist, sx, sy, sz, cx, cy, cz;
390
    int32_t sndang,ca,j,k,i,cs;
391
 
392
    g_numEnvSoundsPlaying = 0;
393
 
394
    cx = pos.x;
395
    cy = pos.y;
396
    cz = pos.z;
397
    cs = cursectnum;
398
    ca = ang;
399
 
400
    for (j=0; j<MAXSOUNDS; j++)
401
        for (k=0; k<g_sounds[j].num; k++)
402
        {
2442 helixhorne 403
            i = g_sounds[j].SoundOwner[k].ow;
1247 helixhorne 404
 
405
            sx = sprite[i].x;
406
            sy = sprite[i].y;
407
            sz = sprite[i].z;
408
 
409
            sndang = 2048 + ca - getangle(cx-sx,cy-sy);
410
            sndang &= 2047;
4659 terminx 411
            sndist = FindDistance3D((cx-sx),(cy-sy),(cz-sz));
4055 helixhorne 412
            if (i >= 0 && (g_sounds[j].m & SF_GLOBAL) == 0 && PN == MUSICANDSFX && SLT < 999 && (sector[SECT].lotag&0xff) < 9)
1247 helixhorne 413
                sndist = divscale14(sndist,(SHT+1));
414
 
415
            sndist += g_sounds[j].vo;
416
            if (sndist < 0) sndist = 0;
417
 
418
            if (cs > -1 && sndist && PN != MUSICANDSFX && !cansee(cx,cy,cz-(24<<8),cs,sx,sy,sz-(24<<8),SECT))
419
                sndist += sndist>>5;
420
 
421
            if (PN == MUSICANDSFX && SLT < 999)
422
                g_numEnvSoundsPlaying++;
1316 terminx 423
            /*
424
                        switch (j)
425
                        {
426
                        case PIPEBOMB_EXPLODE:
427
                        case LASERTRIP_EXPLODE:
428
                        case RPG_EXPLODE:
429
                            if (sndist > (6144)) sndist = (6144);
430
                            break;
431
                        default:
432
            */
433
            if (sndist > 31444 && PN != MUSICANDSFX)
1247 helixhorne 434
            {
1316 terminx 435
                S_StopSound(j);
436
                continue;
437
            }
1247 helixhorne 438
//            }
439
 
440
            if (g_sounds[j].ptr == 0 && S_LoadSound(j) == 0) continue;
4055 helixhorne 441
            if (g_sounds[j].m & SF_GLOBAL) sndist = 0;
1247 helixhorne 442
 
443
            if (sndist < ((255-LOUDESTVOLUME)<<6))
444
                sndist = ((255-LOUDESTVOLUME)<<6);
445
 
1467 helixhorne 446
            FX_Pan3D(g_sounds[j].SoundOwner[k].voice,sndang>>4,sndist>>6);
1247 helixhorne 447
        }
448
}
449
 
1599 terminx 450
void S_Callback(uint32_t num)
1247 helixhorne 451
{
452
    int32_t i,j,k;
453
 
454
    k = g_sounds[num].num;
455
 
456
    if (k > 0)
457
    {
4055 helixhorne 458
        if ((g_sounds[num].m & SF_GLOBAL) == 0)
1247 helixhorne 459
            for (j=0; j<k; j++)
460
            {
2442 helixhorne 461
                i = g_sounds[num].SoundOwner[j].ow;
2278 helixhorne 462
                if (i < 0)
463
                    continue;
464
 
1247 helixhorne 465
                if (sprite[i].picnum == MUSICANDSFX && sector[sprite[i].sectnum].lotag < 3 && sprite[i].lotag < 999)
466
                {
4305 helixhorne 467
                    extern uint8_t g_ambiencePlaying[MAXSPRITES>>3];
468
 
469
                    g_ambiencePlaying[i>>3] &= ~(1<<(i&7));
470
 
2278 helixhorne 471
                    if (j < k-1)
1247 helixhorne 472
                    {
473
                        g_sounds[num].SoundOwner[j].voice = g_sounds[num].SoundOwner[k-1].voice;
2442 helixhorne 474
                        g_sounds[num].SoundOwner[j].ow     = g_sounds[num].SoundOwner[k-1].ow;
1247 helixhorne 475
                    }
476
                    break;
477
                }
478
            }
479
 
480
        g_sounds[num].num--;
2442 helixhorne 481
        g_sounds[num].SoundOwner[k-1].ow = -1;
1247 helixhorne 482
    }
483
 
484
    g_sounds[num].lock--;
485
}
486
 
487
void S_ClearSoundLocks(void)
488
{
489
    int32_t i;
490
 
491
    for (i=0; i<MAXSOUNDS; i++)
492
        if (g_sounds[i].lock >= 200)
493
            g_sounds[i].lock = 199;
494
}
495
 
496
int32_t A_CheckSoundPlaying(int32_t i, int32_t num)
497
{
498
    UNREFERENCED_PARAMETER(i);
499
    if (num < 0) num=0; // FIXME
500
    return (g_sounds[num].num > 0);
501
}
502
 
503
int32_t S_CheckSoundPlaying(int32_t i, int32_t num)
504
{
505
    if (i == -1)
506
    {
1492 terminx 507
        if (g_sounds[num].lock >= 200)
1247 helixhorne 508
            return 1;
509
        return 0;
510
    }
511
    return(g_sounds[num].num);
512
}
4563 hendricks2 513
 
514
int32_t S_SoundsPlaying(int32_t i)
515
{
516
    int32_t j = MAXSOUNDS-1;
517
    for (; j>=0; j--)
518
        if (g_sounds[j].SoundOwner[0].ow == i)
519
            break;
520
 
521
    return j;
522
}
523
 
524
int32_t S_InvalidSound(int32_t num)
525
{
526
    return (unsigned) num >= MAXSOUNDS;
527
}
528
 
529
int32_t S_SoundFlags(int32_t num)
530
{
531
    return g_sounds[num].m;
532
}