@muhammedaksam/opentui-doom 0.1.2 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/doom/build/doom.js +1 -1
- package/doom/build/doom.wasm +0 -0
- package/doom/doom_js_sound_bridge.c +240 -0
- package/doom/i_sound.c +327 -0
- package/doom/s_sound.c +566 -0
- package/package.json +5 -1
- package/scripts/build-doom.sh +7 -1
- package/sound/d_bunny.mp3 +0 -0
- package/sound/d_e1m1.mp3 +0 -0
- package/sound/d_e1m5.mp3 +0 -0
- package/sound/d_intro.mp3 +0 -0
- package/sound/dsbarexp.wav +0 -0
- package/sound/dsbdcls.wav +0 -0
- package/sound/dsbdopn.wav +0 -0
- package/sound/dsbfg.wav +0 -0
- package/sound/dsbgact.wav +0 -0
- package/sound/dsbgdth1.wav +0 -0
- package/sound/dsbgdth2.wav +0 -0
- package/sound/dsbgsit1.wav +0 -0
- package/sound/dsbgsit2.wav +0 -0
- package/sound/dsboscub.wav +0 -0
- package/sound/dsbosdth.wav +0 -0
- package/sound/dsbospit.wav +0 -0
- package/sound/dsbospn.wav +0 -0
- package/sound/dsbossit.wav +0 -0
- package/sound/dsbrsdth.wav +0 -0
- package/sound/dsbrssit.wav +0 -0
- package/sound/dsbspact.wav +0 -0
- package/sound/dsbspdth.wav +0 -0
- package/sound/dsbspsit.wav +0 -0
- package/sound/dsbspwlk.wav +0 -0
- package/sound/dscacdth.wav +0 -0
- package/sound/dscacsit.wav +0 -0
- package/sound/dsclaw.wav +0 -0
- package/sound/dscybdth.wav +0 -0
- package/sound/dscybsit.wav +0 -0
- package/sound/dsdbcls.wav +0 -0
- package/sound/dsdbload.wav +0 -0
- package/sound/dsdbopn.wav +0 -0
- package/sound/dsdmact.wav +0 -0
- package/sound/dsdmpain.wav +0 -0
- package/sound/dsdorcls.wav +0 -0
- package/sound/dsdoropn.wav +0 -0
- package/sound/dsdshtgn.wav +0 -0
- package/sound/dsfirsht.wav +0 -0
- package/sound/dsfirxpl.wav +0 -0
- package/sound/dsflame.wav +0 -0
- package/sound/dsflamst.wav +0 -0
- package/sound/dsgetpow.wav +0 -0
- package/sound/dshoof.wav +0 -0
- package/sound/dsitemup.wav +0 -0
- package/sound/dsitmbk.wav +0 -0
- package/sound/dskeendt.wav +0 -0
- package/sound/dskeenpn.wav +0 -0
- package/sound/dskntdth.wav +0 -0
- package/sound/dskntsit.wav +0 -0
- package/sound/dsmanatk.wav +0 -0
- package/sound/dsmandth.wav +0 -0
- package/sound/dsmansit.wav +0 -0
- package/sound/dsmetal.wav +0 -0
- package/sound/dsmnpain.wav +0 -0
- package/sound/dsnoway.wav +0 -0
- package/sound/dsoof.wav +0 -0
- package/sound/dspdiehi.wav +0 -0
- package/sound/dspedth.wav +0 -0
- package/sound/dspepain.wav +0 -0
- package/sound/dspesit.wav +0 -0
- package/sound/dspistol.wav +0 -0
- package/sound/dsplasma.wav +0 -0
- package/sound/dspldeth.wav +0 -0
- package/sound/dsplpain.wav +0 -0
- package/sound/dspodth1.wav +0 -0
- package/sound/dspodth2.wav +0 -0
- package/sound/dspodth3.wav +0 -0
- package/sound/dspopain.wav +0 -0
- package/sound/dsposact.wav +0 -0
- package/sound/dsposit1.wav +0 -0
- package/sound/dsposit2.wav +0 -0
- package/sound/dsposit3.wav +0 -0
- package/sound/dspstart.wav +0 -0
- package/sound/dspstop.wav +0 -0
- package/sound/dspunch.wav +0 -0
- package/sound/dsradio.wav +0 -0
- package/sound/dsrlaunc.wav +0 -0
- package/sound/dsrxplod.wav +0 -0
- package/sound/dssawful.wav +0 -0
- package/sound/dssawhit.wav +0 -0
- package/sound/dssawidl.wav +0 -0
- package/sound/dssawup.wav +0 -0
- package/sound/dssgcock.wav +0 -0
- package/sound/dssgtatk.wav +0 -0
- package/sound/dssgtdth.wav +0 -0
- package/sound/dssgtsit.wav +0 -0
- package/sound/dsshotgn.wav +0 -0
- package/sound/dsskeact.wav +0 -0
- package/sound/dsskeatk.wav +0 -0
- package/sound/dsskedth.wav +0 -0
- package/sound/dsskepch.wav +0 -0
- package/sound/dsskesit.wav +0 -0
- package/sound/dsskeswg.wav +0 -0
- package/sound/dssklatk.wav +0 -0
- package/sound/dsskldth.wav +0 -0
- package/sound/dsslop.wav +0 -0
- package/sound/dsspidth.wav +0 -0
- package/sound/dsspisit.wav +0 -0
- package/sound/dsssdth.wav +0 -0
- package/sound/dssssit.wav +0 -0
- package/sound/dsstnmov.wav +0 -0
- package/sound/dsswtchn.wav +0 -0
- package/sound/dsswtchx.wav +0 -0
- package/sound/dstelept.wav +0 -0
- package/sound/dstink.wav +0 -0
- package/sound/dsvilact.wav +0 -0
- package/sound/dsvilatk.wav +0 -0
- package/sound/dsvildth.wav +0 -0
- package/sound/dsvilsit.wav +0 -0
- package/sound/dsvipain.wav +0 -0
- package/sound/dswpnup.wav +0 -0
- package/src/doom-audio.ts +243 -0
- package/src/doom-engine.ts +32 -6
- package/src/doom-input.ts +18 -3
- package/src/index.ts +21 -2
package/doom/s_sound.c
ADDED
|
@@ -0,0 +1,566 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright(C) 1993-1996 Id Software, Inc.
|
|
3
|
+
// Copyright(C) 2005-2014 Simon Howard
|
|
4
|
+
//
|
|
5
|
+
// This program is free software; you can redistribute it and/or
|
|
6
|
+
// modify it under the terms of the GNU General Public License
|
|
7
|
+
// as published by the Free Software Foundation; either version 2
|
|
8
|
+
// of the License, or (at your option) any later version.
|
|
9
|
+
//
|
|
10
|
+
// This program is distributed in the hope that it will be useful,
|
|
11
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
// GNU General Public License for more details.
|
|
14
|
+
//
|
|
15
|
+
// DESCRIPTION: none
|
|
16
|
+
//
|
|
17
|
+
|
|
18
|
+
#include <stdio.h>
|
|
19
|
+
#include <stdlib.h>
|
|
20
|
+
|
|
21
|
+
#include "i_sound.h"
|
|
22
|
+
#include "i_system.h"
|
|
23
|
+
|
|
24
|
+
#include "deh_str.h"
|
|
25
|
+
#include "doomfeatures.h"
|
|
26
|
+
|
|
27
|
+
#include "doomstat.h"
|
|
28
|
+
#include "doomtype.h"
|
|
29
|
+
|
|
30
|
+
#include "s_sound.h"
|
|
31
|
+
#include "sounds.h"
|
|
32
|
+
|
|
33
|
+
#include "m_argv.h"
|
|
34
|
+
#include "m_misc.h"
|
|
35
|
+
#include "m_random.h"
|
|
36
|
+
|
|
37
|
+
#include "p_local.h"
|
|
38
|
+
#include "w_wad.h"
|
|
39
|
+
#include "z_zone.h"
|
|
40
|
+
|
|
41
|
+
// when to clip out sounds
|
|
42
|
+
// Does not fit the large outdoor areas.
|
|
43
|
+
|
|
44
|
+
#define S_CLIPPING_DIST (1200 * FRACUNIT)
|
|
45
|
+
|
|
46
|
+
// Distance tp origin when sounds should be maxed out.
|
|
47
|
+
// This should relate to movement clipping resolution
|
|
48
|
+
// (see BLOCKMAP handling).
|
|
49
|
+
// In the source code release: (160*FRACUNIT). Changed back to the
|
|
50
|
+
// Vanilla value of 200 (why was this changed?)
|
|
51
|
+
|
|
52
|
+
#define S_CLOSE_DIST (200 * FRACUNIT)
|
|
53
|
+
|
|
54
|
+
// The range over which sound attenuates
|
|
55
|
+
|
|
56
|
+
#define S_ATTENUATOR ((S_CLIPPING_DIST - S_CLOSE_DIST) >> FRACBITS)
|
|
57
|
+
|
|
58
|
+
// Stereo separation
|
|
59
|
+
|
|
60
|
+
#define S_STEREO_SWING (96 * FRACUNIT)
|
|
61
|
+
|
|
62
|
+
#define NORM_PITCH 128
|
|
63
|
+
#define NORM_PRIORITY 64
|
|
64
|
+
#define NORM_SEP 128
|
|
65
|
+
|
|
66
|
+
typedef struct {
|
|
67
|
+
// sound information (if null, channel avail.)
|
|
68
|
+
sfxinfo_t *sfxinfo;
|
|
69
|
+
|
|
70
|
+
// origin of sound
|
|
71
|
+
mobj_t *origin;
|
|
72
|
+
|
|
73
|
+
// handle of the sound being played
|
|
74
|
+
int handle;
|
|
75
|
+
|
|
76
|
+
} channel_t;
|
|
77
|
+
|
|
78
|
+
// The set of channels available
|
|
79
|
+
|
|
80
|
+
static channel_t *channels;
|
|
81
|
+
|
|
82
|
+
// Maximum volume of a sound effect.
|
|
83
|
+
// Internal default is max out of 0-15.
|
|
84
|
+
|
|
85
|
+
int sfxVolume = 8;
|
|
86
|
+
|
|
87
|
+
// Maximum volume of music.
|
|
88
|
+
|
|
89
|
+
int musicVolume = 8;
|
|
90
|
+
|
|
91
|
+
// Internal volume level, ranging from 0-127
|
|
92
|
+
|
|
93
|
+
static int snd_SfxVolume;
|
|
94
|
+
|
|
95
|
+
// Whether songs are mus_paused
|
|
96
|
+
|
|
97
|
+
static boolean mus_paused;
|
|
98
|
+
|
|
99
|
+
// Music currently being played
|
|
100
|
+
|
|
101
|
+
static musicinfo_t *mus_playing = NULL;
|
|
102
|
+
|
|
103
|
+
// Number of channels to use
|
|
104
|
+
|
|
105
|
+
int snd_channels = 8;
|
|
106
|
+
|
|
107
|
+
//
|
|
108
|
+
// Initializes sound stuff, including volume
|
|
109
|
+
// Sets channels, SFX and music volume,
|
|
110
|
+
// allocates channel buffer, sets S_sfx lookup.
|
|
111
|
+
//
|
|
112
|
+
|
|
113
|
+
void S_Init(int sfxVolume, int musicVolume) {
|
|
114
|
+
int i;
|
|
115
|
+
|
|
116
|
+
I_PrecacheSounds(S_sfx, NUMSFX);
|
|
117
|
+
|
|
118
|
+
S_SetSfxVolume(sfxVolume);
|
|
119
|
+
S_SetMusicVolume(musicVolume);
|
|
120
|
+
|
|
121
|
+
// Allocating the internal channels for mixing
|
|
122
|
+
// (the maximum numer of sounds rendered
|
|
123
|
+
// simultaneously) within zone memory.
|
|
124
|
+
channels = Z_Malloc(snd_channels * sizeof(channel_t), PU_STATIC, 0);
|
|
125
|
+
|
|
126
|
+
// Free all channels for use
|
|
127
|
+
for (i = 0; i < snd_channels; i++) {
|
|
128
|
+
channels[i].sfxinfo = 0;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// no sounds are playing, and they are not mus_paused
|
|
132
|
+
mus_paused = 0;
|
|
133
|
+
|
|
134
|
+
// Note that sounds have not been cached (yet).
|
|
135
|
+
for (i = 1; i < NUMSFX; i++) {
|
|
136
|
+
S_sfx[i].lumpnum = S_sfx[i].usefulness = -1;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
I_AtExit(S_Shutdown, true);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
void S_Shutdown(void) {
|
|
143
|
+
I_ShutdownSound();
|
|
144
|
+
I_ShutdownMusic();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
static void S_StopChannel(int cnum) {
|
|
148
|
+
int i;
|
|
149
|
+
channel_t *c;
|
|
150
|
+
|
|
151
|
+
c = &channels[cnum];
|
|
152
|
+
|
|
153
|
+
if (c->sfxinfo) {
|
|
154
|
+
// stop the sound playing
|
|
155
|
+
|
|
156
|
+
if (I_SoundIsPlaying(c->handle)) {
|
|
157
|
+
I_StopSound(c->handle);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// check to see if other channels are playing the sound
|
|
161
|
+
|
|
162
|
+
for (i = 0; i < snd_channels; i++) {
|
|
163
|
+
if (cnum != i && c->sfxinfo == channels[i].sfxinfo) {
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// degrade usefulness of sound data
|
|
169
|
+
|
|
170
|
+
c->sfxinfo->usefulness--;
|
|
171
|
+
c->sfxinfo = NULL;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
//
|
|
176
|
+
// Per level startup code.
|
|
177
|
+
// Kills playing sounds at start of level,
|
|
178
|
+
// determines music if any, changes music.
|
|
179
|
+
//
|
|
180
|
+
|
|
181
|
+
void S_Start(void) {
|
|
182
|
+
int cnum;
|
|
183
|
+
int mnum;
|
|
184
|
+
|
|
185
|
+
// kill all playing sounds at start of level
|
|
186
|
+
// (trust me - a good idea)
|
|
187
|
+
for (cnum = 0; cnum < snd_channels; cnum++) {
|
|
188
|
+
if (channels[cnum].sfxinfo) {
|
|
189
|
+
S_StopChannel(cnum);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// start new music for the level
|
|
194
|
+
mus_paused = 0;
|
|
195
|
+
|
|
196
|
+
if (gamemode == commercial) {
|
|
197
|
+
mnum = mus_runnin + gamemap - 1;
|
|
198
|
+
} else {
|
|
199
|
+
int spmus[] = {
|
|
200
|
+
// Song - Who? - Where?
|
|
201
|
+
|
|
202
|
+
mus_e3m4, // American e4m1
|
|
203
|
+
mus_e3m2, // Romero e4m2
|
|
204
|
+
mus_e3m3, // Shawn e4m3
|
|
205
|
+
mus_e1m5, // American e4m4
|
|
206
|
+
mus_e2m7, // Tim e4m5
|
|
207
|
+
mus_e2m4, // Romero e4m6
|
|
208
|
+
mus_e2m6, // J.Anderson e4m7 CHIRON.WAD
|
|
209
|
+
mus_e2m5, // Shawn e4m8
|
|
210
|
+
mus_e1m9, // Tim e4m9
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
if (gameepisode < 4) {
|
|
214
|
+
mnum = mus_e1m1 + (gameepisode - 1) * 9 + gamemap - 1;
|
|
215
|
+
} else {
|
|
216
|
+
mnum = spmus[gamemap - 1];
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
S_ChangeMusic(mnum, true);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
void S_StopSound(mobj_t *origin) {
|
|
224
|
+
int cnum;
|
|
225
|
+
|
|
226
|
+
for (cnum = 0; cnum < snd_channels; cnum++) {
|
|
227
|
+
if (channels[cnum].sfxinfo && channels[cnum].origin == origin) {
|
|
228
|
+
S_StopChannel(cnum);
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
//
|
|
235
|
+
// S_GetChannel :
|
|
236
|
+
// If none available, return -1. Otherwise channel #.
|
|
237
|
+
//
|
|
238
|
+
|
|
239
|
+
static int S_GetChannel(mobj_t *origin, sfxinfo_t *sfxinfo) {
|
|
240
|
+
// channel number to use
|
|
241
|
+
int cnum;
|
|
242
|
+
|
|
243
|
+
channel_t *c;
|
|
244
|
+
|
|
245
|
+
// Find an open channel
|
|
246
|
+
for (cnum = 0; cnum < snd_channels; cnum++) {
|
|
247
|
+
if (!channels[cnum].sfxinfo) {
|
|
248
|
+
break;
|
|
249
|
+
} else if (origin && channels[cnum].origin == origin) {
|
|
250
|
+
S_StopChannel(cnum);
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// None available
|
|
256
|
+
if (cnum == snd_channels) {
|
|
257
|
+
// Look for lower priority
|
|
258
|
+
for (cnum = 0; cnum < snd_channels; cnum++) {
|
|
259
|
+
if (channels[cnum].sfxinfo->priority >= sfxinfo->priority) {
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (cnum == snd_channels) {
|
|
265
|
+
// FUCK! No lower priority. Sorry, Charlie.
|
|
266
|
+
return -1;
|
|
267
|
+
} else {
|
|
268
|
+
// Otherwise, kick out lower priority.
|
|
269
|
+
S_StopChannel(cnum);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
c = &channels[cnum];
|
|
274
|
+
|
|
275
|
+
// channel is decided to be cnum.
|
|
276
|
+
c->sfxinfo = sfxinfo;
|
|
277
|
+
c->origin = origin;
|
|
278
|
+
|
|
279
|
+
return cnum;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
//
|
|
283
|
+
// Changes volume and stereo-separation variables
|
|
284
|
+
// from the norm of a sound effect to be played.
|
|
285
|
+
// If the sound is not audible, returns a 0.
|
|
286
|
+
// Otherwise, modifies parameters and returns 1.
|
|
287
|
+
//
|
|
288
|
+
|
|
289
|
+
static int S_AdjustSoundParams(mobj_t *listener, mobj_t *source, int *vol,
|
|
290
|
+
int *sep) {
|
|
291
|
+
fixed_t approx_dist;
|
|
292
|
+
fixed_t adx;
|
|
293
|
+
fixed_t ady;
|
|
294
|
+
angle_t angle;
|
|
295
|
+
|
|
296
|
+
// calculate the distance to sound origin
|
|
297
|
+
// and clip it if necessary
|
|
298
|
+
adx = abs(listener->x - source->x);
|
|
299
|
+
ady = abs(listener->y - source->y);
|
|
300
|
+
|
|
301
|
+
// From _GG1_ p.428. Appox. eucledian distance fast.
|
|
302
|
+
approx_dist = adx + ady - ((adx < ady ? adx : ady) >> 1);
|
|
303
|
+
|
|
304
|
+
if (gamemap != 8 && approx_dist > S_CLIPPING_DIST) {
|
|
305
|
+
return 0;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// angle of source to listener
|
|
309
|
+
angle = R_PointToAngle2(listener->x, listener->y, source->x, source->y);
|
|
310
|
+
|
|
311
|
+
if (angle > listener->angle) {
|
|
312
|
+
angle = angle - listener->angle;
|
|
313
|
+
} else {
|
|
314
|
+
angle = angle + (0xffffffff - listener->angle);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
angle >>= ANGLETOFINESHIFT;
|
|
318
|
+
|
|
319
|
+
// stereo separation
|
|
320
|
+
*sep = 128 - (FixedMul(S_STEREO_SWING, finesine[angle]) >> FRACBITS);
|
|
321
|
+
|
|
322
|
+
// volume calculation
|
|
323
|
+
if (approx_dist < S_CLOSE_DIST) {
|
|
324
|
+
*vol = snd_SfxVolume;
|
|
325
|
+
} else if (gamemap == 8) {
|
|
326
|
+
if (approx_dist > S_CLIPPING_DIST) {
|
|
327
|
+
approx_dist = S_CLIPPING_DIST;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
*vol = 15 + ((snd_SfxVolume - 15) *
|
|
331
|
+
((S_CLIPPING_DIST - approx_dist) >> FRACBITS)) /
|
|
332
|
+
S_ATTENUATOR;
|
|
333
|
+
} else {
|
|
334
|
+
// distance effect
|
|
335
|
+
*vol = (snd_SfxVolume * ((S_CLIPPING_DIST - approx_dist) >> FRACBITS)) /
|
|
336
|
+
S_ATTENUATOR;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
return (*vol > 0);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
void S_StartSound(void *origin_p, int sfx_id) {
|
|
343
|
+
sfxinfo_t *sfx;
|
|
344
|
+
mobj_t *origin;
|
|
345
|
+
int rc;
|
|
346
|
+
int sep;
|
|
347
|
+
int cnum;
|
|
348
|
+
int volume;
|
|
349
|
+
|
|
350
|
+
origin = (mobj_t *)origin_p;
|
|
351
|
+
volume = snd_SfxVolume;
|
|
352
|
+
|
|
353
|
+
// check for bogus sound #
|
|
354
|
+
if (sfx_id < 1 || sfx_id > NUMSFX) {
|
|
355
|
+
I_Error("Bad sfx #: %d", sfx_id);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
sfx = &S_sfx[sfx_id];
|
|
359
|
+
|
|
360
|
+
// Initialize sound parameters
|
|
361
|
+
if (sfx->link) {
|
|
362
|
+
volume += sfx->volume;
|
|
363
|
+
|
|
364
|
+
if (volume < 1) {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (volume > snd_SfxVolume) {
|
|
369
|
+
volume = snd_SfxVolume;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Check to see if it is audible,
|
|
374
|
+
// and if not, modify the params
|
|
375
|
+
if (origin && origin != players[consoleplayer].mo) {
|
|
376
|
+
rc = S_AdjustSoundParams(players[consoleplayer].mo, origin, &volume, &sep);
|
|
377
|
+
|
|
378
|
+
if (origin->x == players[consoleplayer].mo->x &&
|
|
379
|
+
origin->y == players[consoleplayer].mo->y) {
|
|
380
|
+
sep = NORM_SEP;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (!rc) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
} else {
|
|
387
|
+
sep = NORM_SEP;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// kill old sound
|
|
391
|
+
S_StopSound(origin);
|
|
392
|
+
|
|
393
|
+
// try to find a channel
|
|
394
|
+
cnum = S_GetChannel(origin, sfx);
|
|
395
|
+
|
|
396
|
+
if (cnum < 0) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// increase the usefulness
|
|
401
|
+
if (sfx->usefulness++ < 0) {
|
|
402
|
+
sfx->usefulness = 1;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (sfx->lumpnum < 0) {
|
|
406
|
+
sfx->lumpnum = I_GetSfxLumpNum(sfx);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
channels[cnum].handle = I_StartSound(sfx, cnum, volume, sep);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
//
|
|
413
|
+
// Stop and resume music, during game PAUSE.
|
|
414
|
+
//
|
|
415
|
+
|
|
416
|
+
void S_PauseSound(void) {
|
|
417
|
+
if (mus_playing && !mus_paused) {
|
|
418
|
+
I_PauseSong();
|
|
419
|
+
mus_paused = true;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
void S_ResumeSound(void) {
|
|
424
|
+
if (mus_playing && mus_paused) {
|
|
425
|
+
I_ResumeSong();
|
|
426
|
+
mus_paused = false;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
//
|
|
431
|
+
// Updates music & sounds
|
|
432
|
+
//
|
|
433
|
+
|
|
434
|
+
void S_UpdateSounds(mobj_t *listener) {
|
|
435
|
+
int audible;
|
|
436
|
+
int cnum;
|
|
437
|
+
int volume;
|
|
438
|
+
int sep;
|
|
439
|
+
sfxinfo_t *sfx;
|
|
440
|
+
channel_t *c;
|
|
441
|
+
|
|
442
|
+
I_UpdateSound();
|
|
443
|
+
|
|
444
|
+
for (cnum = 0; cnum < snd_channels; cnum++) {
|
|
445
|
+
c = &channels[cnum];
|
|
446
|
+
sfx = c->sfxinfo;
|
|
447
|
+
|
|
448
|
+
if (c->sfxinfo) {
|
|
449
|
+
if (I_SoundIsPlaying(c->handle)) {
|
|
450
|
+
// initialize parameters
|
|
451
|
+
volume = snd_SfxVolume;
|
|
452
|
+
sep = NORM_SEP;
|
|
453
|
+
|
|
454
|
+
if (sfx->link) {
|
|
455
|
+
volume += sfx->volume;
|
|
456
|
+
if (volume < 1) {
|
|
457
|
+
S_StopChannel(cnum);
|
|
458
|
+
continue;
|
|
459
|
+
} else if (volume > snd_SfxVolume) {
|
|
460
|
+
volume = snd_SfxVolume;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// check non-local sounds for distance clipping
|
|
465
|
+
// or modify their params
|
|
466
|
+
if (c->origin && listener != c->origin) {
|
|
467
|
+
audible = S_AdjustSoundParams(listener, c->origin, &volume, &sep);
|
|
468
|
+
|
|
469
|
+
if (!audible) {
|
|
470
|
+
S_StopChannel(cnum);
|
|
471
|
+
} else {
|
|
472
|
+
I_UpdateSoundParams(c->handle, volume, sep);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
} else {
|
|
476
|
+
// if channel is allocated but sound has stopped,
|
|
477
|
+
// free it
|
|
478
|
+
S_StopChannel(cnum);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
void S_SetMusicVolume(int volume) {
|
|
485
|
+
if (volume < 0 || volume > 127) {
|
|
486
|
+
I_Error("Attempt to set music volume at %d", volume);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
I_SetMusicVolume(volume);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
void S_SetSfxVolume(int volume) {
|
|
493
|
+
if (volume < 0 || volume > 127) {
|
|
494
|
+
I_Error("Attempt to set sfx volume at %d", volume);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
snd_SfxVolume = volume;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
//
|
|
501
|
+
// Starts some music with the music id found in sounds.h.
|
|
502
|
+
//
|
|
503
|
+
|
|
504
|
+
void S_StartMusic(int m_id) { S_ChangeMusic(m_id, false); }
|
|
505
|
+
|
|
506
|
+
void S_ChangeMusic(int musicnum, int looping) {
|
|
507
|
+
musicinfo_t *music = NULL;
|
|
508
|
+
char namebuf[9];
|
|
509
|
+
void *handle;
|
|
510
|
+
|
|
511
|
+
// The Doom IWAD file has two versions of the intro music: d_intro
|
|
512
|
+
// and d_introa. The latter is used for OPL playback.
|
|
513
|
+
|
|
514
|
+
if (musicnum == mus_intro &&
|
|
515
|
+
(snd_musicdevice == SNDDEVICE_ADLIB || snd_musicdevice == SNDDEVICE_SB)) {
|
|
516
|
+
musicnum = mus_introa;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
if (musicnum <= mus_None || musicnum >= NUMMUSIC) {
|
|
520
|
+
I_Error("Bad music number %d", musicnum);
|
|
521
|
+
} else {
|
|
522
|
+
music = &S_music[musicnum];
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
if (mus_playing == music) {
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// shutdown old music
|
|
530
|
+
S_StopMusic();
|
|
531
|
+
|
|
532
|
+
// get lumpnum if neccessary
|
|
533
|
+
if (!music->lumpnum) {
|
|
534
|
+
M_snprintf(namebuf, sizeof(namebuf), "d_%s", DEH_String(music->name));
|
|
535
|
+
music->lumpnum = W_GetNumForName(namebuf);
|
|
536
|
+
} else {
|
|
537
|
+
// Rebuild namebuf if we already have lumpnum
|
|
538
|
+
M_snprintf(namebuf, sizeof(namebuf), "d_%s", DEH_String(music->name));
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// For OpenTUI: Pass the music lump NAME (e.g., "d_e1m1") instead of binary
|
|
542
|
+
// data This allows our JavaScript bridge to find the corresponding MP3 file
|
|
543
|
+
// Still need to cache the lump so S_StopMusic can release it properly
|
|
544
|
+
music->data = W_CacheLumpNum(music->lumpnum, PU_STATIC);
|
|
545
|
+
handle = I_RegisterSong(namebuf, strlen(namebuf));
|
|
546
|
+
music->handle = handle;
|
|
547
|
+
I_PlaySong(handle, looping);
|
|
548
|
+
|
|
549
|
+
mus_playing = music;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
boolean S_MusicPlaying(void) { return I_MusicIsPlaying(); }
|
|
553
|
+
|
|
554
|
+
void S_StopMusic(void) {
|
|
555
|
+
if (mus_playing) {
|
|
556
|
+
if (mus_paused) {
|
|
557
|
+
I_ResumeSong();
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
I_StopSong();
|
|
561
|
+
I_UnRegisterSong(mus_playing->handle);
|
|
562
|
+
W_ReleaseLumpNum(mus_playing->lumpnum);
|
|
563
|
+
mus_playing->data = NULL;
|
|
564
|
+
mus_playing = NULL;
|
|
565
|
+
}
|
|
566
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@muhammedaksam/opentui-doom",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Play DOOM in your terminal using OpenTUI's framebuffer rendering and doomgeneric WASM",
|
|
5
5
|
"module": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
"src",
|
|
12
12
|
"doom/build",
|
|
13
13
|
"doom/doomgeneric_opentui.c",
|
|
14
|
+
"doom/doom_js_sound_bridge.c",
|
|
15
|
+
"doom/i_sound.c",
|
|
16
|
+
"doom/s_sound.c",
|
|
17
|
+
"sound",
|
|
14
18
|
"scripts"
|
|
15
19
|
],
|
|
16
20
|
"author": "Muhammed Mustafa AKŞAM <info@muhammedaksam.com.tr> (https://github.com/muhammedaksam)",
|
package/scripts/build-doom.sh
CHANGED
|
@@ -34,8 +34,11 @@ fi
|
|
|
34
34
|
# Create build directory
|
|
35
35
|
mkdir -p "$BUILD_DIR"
|
|
36
36
|
|
|
37
|
-
# Copy our platform file
|
|
37
|
+
# Copy our platform file, sound bridge, and custom sound files
|
|
38
38
|
cp "$DOOM_DIR/doomgeneric_opentui.c" "$DOOM_DIR/doomgeneric/doomgeneric/"
|
|
39
|
+
cp "$DOOM_DIR/doom_js_sound_bridge.c" "$DOOM_DIR/doomgeneric/doomgeneric/"
|
|
40
|
+
cp "$DOOM_DIR/i_sound.c" "$DOOM_DIR/doomgeneric/doomgeneric/"
|
|
41
|
+
cp "$DOOM_DIR/s_sound.c" "$DOOM_DIR/doomgeneric/doomgeneric/"
|
|
39
42
|
|
|
40
43
|
echo "Compiling DOOM to WebAssembly..."
|
|
41
44
|
cd "$DOOM_DIR/doomgeneric/doomgeneric"
|
|
@@ -43,6 +46,7 @@ cd "$DOOM_DIR/doomgeneric/doomgeneric"
|
|
|
43
46
|
# Compile with Emscripten
|
|
44
47
|
emcc -O2 \
|
|
45
48
|
-s WASM=1 \
|
|
49
|
+
-s USE_SDL=2 \
|
|
46
50
|
-s EXPORTED_FUNCTIONS="['_doomgeneric_Create','_doomgeneric_Tick','_DG_GetFrameBuffer','_DG_PushKeyEvent','_malloc','_free']" \
|
|
47
51
|
-s EXPORTED_RUNTIME_METHODS="['ccall','cwrap','getValue','setValue']" \
|
|
48
52
|
-s ALLOW_MEMORY_GROWTH=1 \
|
|
@@ -56,6 +60,7 @@ emcc -O2 \
|
|
|
56
60
|
-s NO_EXIT_RUNTIME=1 \
|
|
57
61
|
-DDOOMGENERIC_RESX=1280 \
|
|
58
62
|
-DDOOMGENERIC_RESY=800 \
|
|
63
|
+
-DFEATURE_SOUND \
|
|
59
64
|
-I. \
|
|
60
65
|
am_map.c \
|
|
61
66
|
d_event.c \
|
|
@@ -139,6 +144,7 @@ emcc -O2 \
|
|
|
139
144
|
wi_stuff.c \
|
|
140
145
|
z_zone.c \
|
|
141
146
|
dummy.c \
|
|
147
|
+
doom_js_sound_bridge.c \
|
|
142
148
|
-o "$BUILD_DIR/doom.js"
|
|
143
149
|
|
|
144
150
|
echo "Build complete!"
|
|
Binary file
|
package/sound/d_e1m1.mp3
ADDED
|
Binary file
|
package/sound/d_e1m5.mp3
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/sound/dsbfg.wav
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/sound/dsclaw.wav
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|