 
        
        Iskhodnyy_kod_Doom
.pdf//Wait till all pending sounds are finished. int done = 0;
int i;
//FIXME (below).
fprintf( stderr, "I_ShutdownSound: NOT finishing pending sounds\n"); fflush( stderr );
while ( !done )
{
for( i=0 ; i<8 && !channels[i] ; i++);
// FIXME. No proper channel output. //if (i==8)
done=1;
}
#ifdef SNDINTR I_SoundDelTimer();
#endif
// Cleaning up -releasing the DSP device. close ( audio_fd );
#endif
// Done. return;
}
void I_InitSound()
{
#ifdef SNDSERV
char buffer[256];
if (getenv("DOOMWADDIR")) sprintf(buffer, "%s/%s",
getenv("DOOMWADDIR"), sndserver_filename);
else
sprintf(buffer, "%s", sndserver_filename);
// start sound process
if ( !access(buffer, X_OK) )
{
strcat(buffer, " -quiet"); sndserver = popen(buffer, "w");
}
else
fprintf(stderr, "Could not start sound server [%s]\n", buffer); #else
int i;
#ifdef SNDINTR
fprintf( stderr, "I_SoundSetTimer: %d microsecs\n", SOUND_INTERVAL ); I_SoundSetTimer( SOUND_INTERVAL );
#endif
// Secure and configure sound device first.
191
fprintf( stderr, "I_InitSound: ");
audio_fd = open("/dev/dsp", O_WRONLY); if (audio_fd<0)
fprintf(stderr, "Could not open /dev/dsp\n");
i = 11 | (2<<16);
myioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &i); myioctl(audio_fd, SNDCTL_DSP_RESET, 0);
i=SAMPLERATE;
myioctl(audio_fd, SNDCTL_DSP_SPEED, &i);
i=1;
myioctl(audio_fd, SNDCTL_DSP_STEREO, &i);
myioctl(audio_fd, SNDCTL_DSP_GETFMTS, &i);
if (i&=AFMT_S16_LE)
myioctl(audio_fd, SNDCTL_DSP_SETFMT, &i); else
fprintf(stderr, "Could not play signed 16 data\n");
fprintf(stderr, " configured audio device\n" );
// Initialize external data (all sounds) at start, keep static. fprintf( stderr, "I_InitSound: ");
for (i=1 ; i<NUMSFX ; i++)
{
// Alias? Example is the chaingun sound linked to pistol. if (!S_sfx[i].link)
{
// Load data from WAD file.
S_sfx[i].data = getsfx( S_sfx[i].name, &lengths[i] );
}
else
{
// Previously loaded already? S_sfx[i].data = S_sfx[i].link->data;
lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)];
}
}
fprintf( stderr, " pre-cached all sound data\n");
//Now initialize mixbuffer with zero. for ( i = 0; i< MIXBUFFERSIZE; i++ )
mixbuffer[i] = 0;
//Finished initialization.
fprintf(stderr, "I_InitSound: sound module ready\n");
#endif
}
//
//MUSIC API.
//Still no music done.
192
| // Remains. Dummies. | 
 | |
| // | 
 | 
 | 
| void I_InitMusic(void) | { } | |
| void I_ShutdownMusic(void) | { } | |
| static int | looping=0; | 
 | 
| static int | musicdies=-1; | 
 | 
void I_PlaySong(int handle, int looping)
{
// UNUSED.
handle = looping = 0;
musicdies = gametic + TICRATE*30;
}
void I_PauseSong (int handle)
{
// UNUSED. handle = 0;
}
void I_ResumeSong (int handle)
{
// UNUSED. handle = 0;
}
void I_StopSong(int handle)
{
// UNUSED. handle = 0;
looping = 0; musicdies = 0;
}
void I_UnRegisterSong(int handle)
{
// UNUSED. handle = 0;
}
int I_RegisterSong(void* data)
{
// UNUSED. data = NULL;
return 1;
}
// Is the song playing?
int I_QrySongPlaying(int handle)
{
// UNUSED. handle = 0;
return looping || musicdies > gametic;
}
//
//Experimental stuff.
//A Linux timer interrupt, for asynchronous
//sound output.
//I ripped this out of the Timer class in
193
//our Difference Engine, including a few
//SUN remains...
| // | 
 | 
 | 
| #ifdef sun | 
 | 
 | 
| typedef | sigset_t | tSigSet; | 
| #else | 
 | 
 | 
| typedef | int | tSigSet; | 
| #endif | 
 | 
 | 
//We might use SIGVTALRM and ITIMER_VIRTUAL, if the process
//time independend timer happens to get lost due to heavy load.
//SIGALRM and ITIMER_REAL doesn’t really work well.
//There are issues with profiling as well.
static int /*__itimer_which*/ itimer = ITIMER_REAL;
static int sig = SIGALRM;
// Interrupt handler.
void I_HandleSoundTimer( int ignore )
{
// Debug.
//fprintf( stderr, "%c", ’+’ ); fflush( stderr );
// Feed sound device if necesary. if ( flag )
{
//See I_SubmitSound().
//Write it to DSP device.
write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL);
// Reset flag counter. flag = 0;
}
else return;
// UNUSED, but required. ignore = 0;
return;
}
// Get the interrupt. Set duration in millisecs. int I_SoundSetTimer( int duration_of_tick )
{
// Needed for gametick clockwork.
| struct itimerval | value; | |
| struct itimerval | ovalue; | |
| struct | sigaction | act; | 
| struct | sigaction | oact; | 
int res;
//This sets to SA_ONESHOT and SA_NOMASK, thus we can not use it.
//signal( _sig, handle_SIG_TICK );
//Now we have to change this attribute for repeated calls. act.sa_handler = I_HandleSoundTimer;
| #ifndef sun | 
 | 
| //ac | t.sa_mask = _sig; | 
#endif
act.sa_flags = SA_RESTART;
sigaction( sig, &act, &oact );
194
 
| value.it_interval.tv_sec | = 0; | |
| value.it_interval.tv_usec | = duration_of_tick; | |
| value.it_value.tv_sec | = | 0; | 
| value.it_value.tv_usec | = | duration_of_tick; | 
// Error is -1.
res = setitimer( itimer, &value, &ovalue );
// Debug.
if ( res == -1 )
fprintf( stderr, "I_SoundSetTimer: interrupt n.a.\n");
return res;
}
// Remove the interrupt. Set duration to zero. void I_SoundDelTimer()
{
// Debug.
if ( I_SoundSetTimer( 0 ) == -1)
fprintf( stderr, "I_SoundDelTimer: failed to remove interrupt. Doh!\n");
}
7.5i sound.h
// Emacs style mode select -*- C++ -*- //-----------------------------------------------------------------------------
//
//$Id:$
//Copyright (C) 1993-1996 by id Software, Inc.
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//
//DESCRIPTION:
//System interface, sound.
//-----------------------------------------------------------------------------
#ifndef __I_SOUND__ #define __I_SOUND__
#include "doomdef.h"
// UNIX hack, to be removed. #ifdef SNDSERV
#include <stdio.h> extern FILE* sndserver;
extern char* sndserver_filename; #endif
#include "doomstat.h" #include "sounds.h"
195
//Init at program start...
void I_InitSound();
//... update sound buffer and audio device at runtime...
void I_UpdateSound(void); void I_SubmitSound(void);
//... shut down and relase at program termination.
void I_ShutdownSound(void);
//
//SFX I/O
//Initialize channels? void I_SetChannels();
//Get raw data lump index for sound descriptor. int I_GetSfxLumpNum (sfxinfo_t* sfxinfo );
//Starts a sound in a particular sound channel.
int I_StartSound
| ( int | id, | 
| int | vol, | 
| int | sep, | 
| int | pitch, | 
| int | priority ); | 
//Stops a sound channel. void I_StopSound(int handle);
//Called by S_*() functions
//to see if a channel is still playing.
//Returns 0 if no longer playing, 1 if playing. int I_SoundIsPlaying(int handle);
//Updates the volume, separation,
//and pitch of a sound channel.
| void | 
 | 
| I_UpdateSoundParams | 
 | 
| ( int | handle, | 
| int | vol, | 
| int | sep, | 
| int | pitch ); | 
//
//MUSIC I/O
void I_InitMusic(void); void I_ShutdownMusic(void);
//Volume.
void I_SetMusicVolume(int volume); // PAUSE game handling.
void I_PauseSong(int handle); void I_ResumeSong(int handle);
//Registers a song handle to song data. int I_RegisterSong(void *data);
//Called by anything that wishes to start music.
//plays a song, and when the song is done,
196
 
//starts playing it again in an endless loop.
//Horrible thing to do, considering.
| void | 
 | 
| I_PlaySong | 
 | 
| ( int | handle, | 
| int | looping ); | 
//Stops a song over 3 seconds. void I_StopSong(int handle);
//See above (register), then think backwards void I_UnRegisterSong(int handle);
#endif //-----------------------------------------------------------------------------
//
// $Log:$
//
//-----------------------------------------------------------------------------
7.6 i system.c
// Emacs style mode select -*- C++ -*- //-----------------------------------------------------------------------------
//
//$Id:$
//Copyright (C) 1993-1996 by id Software, Inc.
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//$Log:$
//DESCRIPTION:
//-----------------------------------------------------------------------------
static const char
rcsid[] = "$Id: m_bbox.c,v 1.1 1997/02/03 22:45:10 b1 Exp $";
#include <stdlib.h> #include <stdio.h> #include <string.h>
#include <stdarg.h> #include <sys/time.h> #include <unistd.h>
#include "doomdef.h" #include "m_misc.h" #include "i_video.h" #include "i_sound.h"
#include "d_net.h" #include "g_game.h"
197
#ifdef __GNUG__
#pragma implementation "i_system.h" #endif
#include "i_system.h"
| int | mb_used = 6; | 
 | 
| void | 
 | 
 | 
| I_Tactile | 
 | 
 | 
| ( int | on, | 
 | 
| int | off, | 
 | 
| int | total ) | 
 | 
| { | 
 | 
 | 
| // UNUSED. | 
 | |
| on = off = total = 0; | 
 | |
| } | 
 | 
 | 
| ticcmd_t | emptycmd; | 
 | 
| ticcmd_t* | I_BaseTiccmd(void) | |
| { | 
 | 
 | 
| return &emptycmd; | 
 | |
| } | 
 | 
 | 
| int I_GetHeapSize (void) | 
 | |
| { | 
 | 
 | 
| return mb_used*1024*1024; | 
 | |
| } | 
 | 
 | 
| byte* I_ZoneBase (int* | size) | |
| { | 
 | 
 | 
*size = mb_used*1024*1024; return (byte *) malloc (*size);
}
//
//I_GetTime
//returns time in 1/70th second tics
| int I_GetTime (void) | 
 | 
| { | 
 | 
| struct timeval | tp; | 
| struct timezone | tzp; | 
| int | newtics; | 
| static int | basetime=0; | 
gettimeofday(&tp, &tzp); if (!basetime)
basetime = tp.tv_sec;
newtics = (tp.tv_sec-basetime)*TICRATE + tp.tv_usec*TICRATE/1000000; return newtics;
}
//
// I_Init
//
void I_Init (void)
198
{
I_InitSound();
//I_InitGraphics();
}
//
// I_Quit
//
void I_Quit (void)
{
D_QuitNetGame (); I_ShutdownSound(); I_ShutdownMusic(); M_SaveDefaults (); I_ShutdownGraphics(); exit(0);
}
void I_WaitVBL(int count)
{
#ifdef SGI sginap(1);
#else #ifdef SUN
sleep(0);
#else
usleep (count * (1000000/70) ); #endif
#endif
}
void I_BeginRead(void)
{
}
void I_EndRead(void)
{
}
| byte* | I_AllocLow(int length) | 
| { | 
 | 
| byte* | mem; | 
mem = (byte *)malloc (length); memset (mem,0,length);
return mem;
}
//
// I_Error
//
extern boolean demorecording;
void I_Error (char *error, ...)
{
va_list argptr;
// Message first. va_start (argptr,error);
fprintf (stderr, "Error: "); vfprintf (stderr,error,argptr); fprintf (stderr, "\n");
va_end (argptr);
199
 
fflush( stderr );
// Shutdown. Here might be other errors. if (demorecording)
G_CheckDemoStatus();
D_QuitNetGame ();
I_ShutdownGraphics();
exit(-1);
}
7.7i system.h
// Emacs style mode select -*- C++ -*- //-----------------------------------------------------------------------------
//
//$Id:$
//Copyright (C) 1993-1996 by id Software, Inc.
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//DESCRIPTION:
//System specific interface stuff.
//-----------------------------------------------------------------------------
#ifndef __I_SYSTEM__ #define __I_SYSTEM__
#include "d_ticcmd.h" #include "d_event.h"
#ifdef __GNUG__ #pragma interface #endif
//Called by DoomMain. void I_Init (void);
//Called by startup code
//to get the ammount of memory to malloc
//for the zone management.
| byte* | I_ZoneBase (int *size); | 
//Called by D_DoomLoop,
//returns current time in tics. int I_GetTime (void);
//
//Called by D_DoomLoop,
//called before processing any tics in a frame
200
