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