diff options
author | Simon Howard | 2008-09-05 00:02:14 +0000 |
---|---|---|
committer | Simon Howard | 2008-09-05 00:02:14 +0000 |
commit | c7ddc423f67236a99956960cf9fe89abf077839b (patch) | |
tree | 61322034e9d75f1c1a409d1e14ca21ee5c6025c2 /src/hexen/i_ibm.c | |
parent | 0774dce204c2c01622c59819e2a29590a1b50e46 (diff) | |
download | chocolate-doom-c7ddc423f67236a99956960cf9fe89abf077839b.tar.gz chocolate-doom-c7ddc423f67236a99956960cf9fe89abf077839b.tar.bz2 chocolate-doom-c7ddc423f67236a99956960cf9fe89abf077839b.zip |
Reformat (beautify) Raven sources and add GPL headers.
Subversion-branch: /branches/raven-branch
Subversion-revision: 1197
Diffstat (limited to 'src/hexen/i_ibm.c')
-rw-r--r-- | src/hexen/i_ibm.c | 5592 |
1 files changed, 2810 insertions, 2782 deletions
diff --git a/src/hexen/i_ibm.c b/src/hexen/i_ibm.c index 20ed3220..c458d0bf 100644 --- a/src/hexen/i_ibm.c +++ b/src/hexen/i_ibm.c @@ -1,2782 +1,2810 @@ -
-//**************************************************************************
-//**
-//** I_IBM.C
-//**
-//**************************************************************************
-
-#include <dos.h>
-#include <conio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <graph.h>
-#include "h2def.h"
-#include "r_local.h"
-#include "p_local.h" // for P_AproxDistance
-#include "sounds.h"
-#include "i_sound.h"
-#include "soundst.h"
-#include "st_start.h"
-#include "dmx.h"
-#include "dpmiapi.h"
-
-// Macros
-
-#define DEFAULT_ARCHIVEPATH "o:\\sound\\archive\\"
-#define PRIORITY_MAX_ADJUST 10
-#define DIST_ADJUST (MAX_SND_DIST/PRIORITY_MAX_ADJUST)
-
-#define DPMI_INT 0x31
-
-#define SEQ_ADDR 0x3C4
-#define SEQ_DATA 0x3C5
-#define REG_MAPMASK 0x02
-
-#define MASK_PLANE0 0x01
-#define MASK_PLANE1 0x02
-#define MASK_PLANE2 0x04
-#define MASK_PLANE3 0x08
-
-#define P0OFFSET 38400*0
-#define P1OFFSET 38400*1
-#define P2OFFSET 38400*2
-#define P3OFFSET 38400*3
-
-#define VID_INT 0x10
-#define VB_SYNC {while(!(inp(0x3da)&8)); while(inp(0x3da)&8);}
-#define BITPLANE(p) (outp(SEQ_ADDR,REG_MAPMASK),outp(SEQ_DATA,(p)))
-
-//#define NOKBD
-//#define NOTIMER
-
-// Public Data
-
-int DisplayTicker = 0;
-
-// Code
-
-void main(int argc, char **argv)
-{
- myargc = argc;
- myargv = argv;
- H2_Main();
-}
-
-void I_StartupNet (void);
-void I_ShutdownNet (void);
-void I_ReadExternDriver(void);
-
-typedef struct
-{
- unsigned edi, esi, ebp, reserved, ebx, edx, ecx, eax;
- unsigned short flags, es, ds, fs, gs, ip, cs, sp, ss;
-} dpmiregs_t;
-
-extern dpmiregs_t dpmiregs;
-
-void I_ReadMouse (void);
-
-extern int usemouse, usejoystick;
-
-extern void **lumpcache;
-
-int i_Vector;
-externdata_t *i_ExternData;
-boolean useexterndriver;
-
-boolean i_CDMusic;
-int i_CDTrack;
-int i_CDCurrentTrack;
-int i_CDMusicLength;
-int oldTic;
-
-/*
-===============================================================================
-
- MUSIC & SFX API
-
-===============================================================================
-*/
-
-//static channel_t channel[MAX_CHANNELS];
-
-//static int rs; //the current registered song.
-//int mus_song = -1;
-//int mus_lumpnum;
-//void *mus_sndptr;
-//byte *soundCurve;
-
-extern sfxinfo_t S_sfx[];
-extern musicinfo_t S_music[];
-
-static channel_t Channel[MAX_CHANNELS];
-static int RegisteredSong; //the current registered song.
-static int NextCleanup;
-static boolean MusicPaused;
-static int Mus_Song = -1;
-static int Mus_LumpNum;
-static void *Mus_SndPtr;
-static byte *SoundCurve;
-
-static boolean UseSndScript;
-static char ArchivePath[128];
-
-extern int snd_MusicDevice;
-extern int snd_SfxDevice;
-extern int snd_MaxVolume;
-extern int snd_MusicVolume;
-extern int snd_Channels;
-
-extern int startepisode;
-extern int startmap;
-
-// int AmbChan;
-
-//==========================================================================
-//
-// S_Start
-//
-//==========================================================================
-
-void S_Start(void)
-{
- S_StopAllSound();
- S_StartSong(gamemap, true);
-}
-
-//==========================================================================
-//
-// S_StartSong
-//
-//==========================================================================
-
-void S_StartSong(int song, boolean loop)
-{
- char *songLump;
- int track;
-
- if(i_CDMusic)
- { // Play a CD track, instead
- if(i_CDTrack)
- { // Default to the player-chosen track
- track = i_CDTrack;
- }
- else
- {
- track = P_GetMapCDTrack(gamemap);
- }
- if(track == i_CDCurrentTrack && i_CDMusicLength > 0)
- {
- return;
- }
- if(!I_CDMusPlay(track))
- {
- if(loop)
- {
- i_CDMusicLength = 35*I_CDMusTrackLength(track);
- oldTic = gametic;
- }
- else
- {
- i_CDMusicLength = -1;
- }
- i_CDCurrentTrack = track;
- }
- }
- else
- {
- if(song == Mus_Song)
- { // don't replay an old song
- return;
- }
- if(RegisteredSong)
- {
- I_StopSong(RegisteredSong);
- I_UnRegisterSong(RegisteredSong);
- if(UseSndScript)
- {
- Z_Free(Mus_SndPtr);
- }
- else
- {
- Z_ChangeTag(lumpcache[Mus_LumpNum], PU_CACHE);
- }
- #ifdef __WATCOMC__
- _dpmi_unlockregion(Mus_SndPtr, lumpinfo[Mus_LumpNum].size);
- #endif
- RegisteredSong = 0;
- }
- songLump = P_GetMapSongLump(song);
- if(!songLump)
- {
- return;
- }
- if(UseSndScript)
- {
- char name[128];
- sprintf(name, "%s%s.lmp", ArchivePath, songLump);
- M_ReadFile(name, (byte **)&Mus_SndPtr);
- }
- else
- {
- Mus_LumpNum = W_GetNumForName(songLump);
- Mus_SndPtr = W_CacheLumpNum(Mus_LumpNum, PU_MUSIC);
- }
- #ifdef __WATCOMC__
- _dpmi_lockregion(Mus_SndPtr, lumpinfo[Mus_LumpNum].size);
- #endif
- RegisteredSong = I_RegisterSong(Mus_SndPtr);
- I_PlaySong(RegisteredSong, loop); // 'true' denotes endless looping.
- Mus_Song = song;
- }
-}
-
-//==========================================================================
-//
-// S_StartSongName
-//
-//==========================================================================
-
-void S_StartSongName(char *songLump, boolean loop)
-{
- int cdTrack;
-
- if(!songLump)
- {
- return;
- }
- if(i_CDMusic)
- {
- cdTrack = 0;
-
- if(!strcmp(songLump, "hexen"))
- {
- cdTrack = P_GetCDTitleTrack();
- }
- else if(!strcmp(songLump, "hub"))
- {
- cdTrack = P_GetCDIntermissionTrack();
- }
- else if(!strcmp(songLump, "hall"))
- {
- cdTrack = P_GetCDEnd1Track();
- }
- else if(!strcmp(songLump, "orb"))
- {
- cdTrack = P_GetCDEnd2Track();
- }
- else if(!strcmp(songLump, "chess") && !i_CDTrack)
- {
- cdTrack = P_GetCDEnd3Track();
- }
-/* Uncomment this, if Kevin writes a specific song for startup
- else if(!strcmp(songLump, "start"))
- {
- cdTrack = P_GetCDStartTrack();
- }
-*/
- if(!cdTrack || (cdTrack == i_CDCurrentTrack && i_CDMusicLength > 0))
- {
- return;
- }
- if(!I_CDMusPlay(cdTrack))
- {
- if(loop)
- {
- i_CDMusicLength = 35*I_CDMusTrackLength(cdTrack);
- oldTic = gametic;
- }
- else
- {
- i_CDMusicLength = -1;
- }
- i_CDCurrentTrack = cdTrack;
- i_CDTrack = false;
- }
- }
- else
- {
- if(RegisteredSong)
- {
- I_StopSong(RegisteredSong);
- I_UnRegisterSong(RegisteredSong);
- if(UseSndScript)
- {
- Z_Free(Mus_SndPtr);
- }
- else
- {
- Z_ChangeTag(lumpcache[Mus_LumpNum], PU_CACHE);
- }
- #ifdef __WATCOMC__
- _dpmi_unlockregion(Mus_SndPtr, lumpinfo[Mus_LumpNum].size);
- #endif
- RegisteredSong = 0;
- }
- if(UseSndScript)
- {
- char name[128];
- sprintf(name, "%s%s.lmp", ArchivePath, songLump);
- M_ReadFile(name, (byte **)&Mus_SndPtr);
- }
- else
- {
- Mus_LumpNum = W_GetNumForName(songLump);
- Mus_SndPtr = W_CacheLumpNum(Mus_LumpNum, PU_MUSIC);
- }
- #ifdef __WATCOMC__
- _dpmi_lockregion(Mus_SndPtr, lumpinfo[Mus_LumpNum].size);
- #endif
- RegisteredSong = I_RegisterSong(Mus_SndPtr);
- I_PlaySong(RegisteredSong, loop); // 'true' denotes endless looping.
- Mus_Song = -1;
- }
-}
-
-//==========================================================================
-//
-// S_GetSoundID
-//
-//==========================================================================
-
-int S_GetSoundID(char *name)
-{
- int i;
-
- for(i = 0; i < NUMSFX; i++)
- {
- if(!strcmp(S_sfx[i].tagName, name))
- {
- return i;
- }
- }
- return 0;
-}
-
-//==========================================================================
-//
-// S_StartSound
-//
-//==========================================================================
-
-void S_StartSound(mobj_t *origin, int sound_id)
-{
- S_StartSoundAtVolume(origin, sound_id, 127);
-}
-
-//==========================================================================
-//
-// S_StartSoundAtVolume
-//
-//==========================================================================
-
-void S_StartSoundAtVolume(mobj_t *origin, int sound_id, int volume)
-{
- int dist, vol;
- int i;
- int priority;
- int sep;
- int angle;
- int absx;
- int absy;
-
- static int sndcount = 0;
- int chan;
-
- if(sound_id == 0 || snd_MaxVolume == 0)
- return;
- if(origin == NULL)
- {
- origin = players[displayplayer].mo;
- }
- if(volume == 0)
- {
- return;
- }
-
- // calculate the distance before other stuff so that we can throw out
- // sounds that are beyond the hearing range.
- absx = abs(origin->x-players[displayplayer].mo->x);
- absy = abs(origin->y-players[displayplayer].mo->y);
- dist = absx+absy-(absx > absy ? absy>>1 : absx>>1);
- dist >>= FRACBITS;
- if(dist >= MAX_SND_DIST)
- {
- return; // sound is beyond the hearing range...
- }
- if(dist < 0)
- {
- dist = 0;
- }
- priority = S_sfx[sound_id].priority;
- priority *= (PRIORITY_MAX_ADJUST-(dist/DIST_ADJUST));
- if(!S_StopSoundID(sound_id, priority))
- {
- return; // other sounds have greater priority
- }
- for(i=0; i<snd_Channels; i++)
- {
- if(origin->player)
- {
- i = snd_Channels;
- break; // let the player have more than one sound.
- }
- if(origin == Channel[i].mo)
- { // only allow other mobjs one sound
- S_StopSound(Channel[i].mo);
- break;
- }
- }
- if(i >= snd_Channels)
- {
- for(i = 0; i < snd_Channels; i++)
- {
- if(Channel[i].mo == NULL)
- {
- break;
- }
- }
- if(i >= snd_Channels)
- {
- // look for a lower priority sound to replace.
- sndcount++;
- if(sndcount >= snd_Channels)
- {
- sndcount = 0;
- }
- for(chan = 0; chan < snd_Channels; chan++)
- {
- i = (sndcount+chan)%snd_Channels;
- if(priority >= Channel[i].priority)
- {
- chan = -1; //denote that sound should be replaced.
- break;
- }
- }
- if(chan != -1)
- {
- return; //no free channels.
- }
- else //replace the lower priority sound.
- {
- if(Channel[i].handle)
- {
- if(I_SoundIsPlaying(Channel[i].handle))
- {
- I_StopSound(Channel[i].handle);
- }
- if(S_sfx[Channel[i].sound_id].usefulness > 0)
- {
- S_sfx[Channel[i].sound_id].usefulness--;
- }
- }
- }
- }
- }
- if(S_sfx[sound_id].lumpnum == 0)
- {
- S_sfx[sound_id].lumpnum = I_GetSfxLumpNum(&S_sfx[sound_id]);
- }
- if(S_sfx[sound_id].snd_ptr == NULL)
- {
- if(UseSndScript)
- {
- char name[128];
- sprintf(name, "%s%s.lmp", ArchivePath, S_sfx[sound_id].lumpname);
- M_ReadFile(name, (byte **)&S_sfx[sound_id].snd_ptr);
- }
- else
- {
- S_sfx[sound_id].snd_ptr = W_CacheLumpNum(S_sfx[sound_id].lumpnum,
- PU_SOUND);
- }
- #ifdef __WATCOMC__
- _dpmi_lockregion(S_sfx[sound_id].snd_ptr,
- lumpinfo[S_sfx[sound_id].lumpnum].size);
- #endif
- }
-
- vol = (SoundCurve[dist]*(snd_MaxVolume*8)*volume)>>14;
- if(origin == players[displayplayer].mo)
- {
- sep = 128;
-// vol = (volume*(snd_MaxVolume+1)*8)>>7;
- }
- else
- {
- angle = R_PointToAngle2(players[displayplayer].mo->x,
- players[displayplayer].mo->y, Channel[i].mo->x, Channel[i].mo->y);
- angle = (angle-viewangle)>>24;
- sep = angle*2-128;
- if(sep < 64)
- sep = -sep;
- if(sep > 192)
- sep = 512-sep;
-// vol = SoundCurve[dist];
- }
-
- if(S_sfx[sound_id].changePitch)
- {
- Channel[i].pitch = (byte)(127+(M_Random()&7)-(M_Random()&7));
- }
- else
- {
- Channel[i].pitch = 127;
- }
- Channel[i].handle = I_StartSound(sound_id, S_sfx[sound_id].snd_ptr, vol,
- sep, Channel[i].pitch, 0);
- Channel[i].mo = origin;
- Channel[i].sound_id = sound_id;
- Channel[i].priority = priority;
- Channel[i].volume = volume;
- if(S_sfx[sound_id].usefulness < 0)
- {
- S_sfx[sound_id].usefulness = 1;
- }
- else
- {
- S_sfx[sound_id].usefulness++;
- }
-}
-
-//==========================================================================
-//
-// S_StopSoundID
-//
-//==========================================================================
-
-boolean S_StopSoundID(int sound_id, int priority)
-{
- int i;
- int lp; //least priority
- int found;
-
- if(S_sfx[sound_id].numchannels == -1)
- {
- return(true);
- }
- lp = -1; //denote the argument sound_id
- found = 0;
- for(i=0; i<snd_Channels; i++)
- {
- if(Channel[i].sound_id == sound_id && Channel[i].mo)
- {
- found++; //found one. Now, should we replace it??
- if(priority >= Channel[i].priority)
- { // if we're gonna kill one, then this'll be it
- lp = i;
- priority = Channel[i].priority;
- }
- }
- }
- if(found < S_sfx[sound_id].numchannels)
- {
- return(true);
- }
- else if(lp == -1)
- {
- return(false); // don't replace any sounds
- }
- if(Channel[lp].handle)
- {
- if(I_SoundIsPlaying(Channel[lp].handle))
- {
- I_StopSound(Channel[lp].handle);
- }
- if(S_sfx[Channel[lp].sound_id].usefulness > 0)
- {
- S_sfx[Channel[lp].sound_id].usefulness--;
- }
- Channel[lp].mo = NULL;
- }
- return(true);
-}
-
-//==========================================================================
-//
-// S_StopSound
-//
-//==========================================================================
-
-void S_StopSound(mobj_t *origin)
-{
- int i;
-
- for(i=0;i<snd_Channels;i++)
- {
- if(Channel[i].mo == origin)
- {
- I_StopSound(Channel[i].handle);
- if(S_sfx[Channel[i].sound_id].usefulness > 0)
- {
- S_sfx[Channel[i].sound_id].usefulness--;
- }
- Channel[i].handle = 0;
- Channel[i].mo = NULL;
- }
- }
-}
-
-//==========================================================================
-//
-// S_StopAllSound
-//
-//==========================================================================
-
-void S_StopAllSound(void)
-{
- int i;
-
- //stop all sounds
- for(i=0; i < snd_Channels; i++)
- {
- if(Channel[i].handle)
- {
- S_StopSound(Channel[i].mo);
- }
- }
- memset(Channel, 0, 8*sizeof(channel_t));
-}
-
-//==========================================================================
-//
-// S_SoundLink
-//
-//==========================================================================
-
-void S_SoundLink(mobj_t *oldactor, mobj_t *newactor)
-{
- int i;
-
- for(i=0;i<snd_Channels;i++)
- {
- if(Channel[i].mo == oldactor)
- Channel[i].mo = newactor;
- }
-}
-
-//==========================================================================
-//
-// S_PauseSound
-//
-//==========================================================================
-
-void S_PauseSound(void)
-{
- if(i_CDMusic)
- {
- I_CDMusStop();
- }
- else
- {
- I_PauseSong(RegisteredSong);
- }
-}
-
-//==========================================================================
-//
-// S_ResumeSound
-//
-//==========================================================================
-
-void S_ResumeSound(void)
-{
- if(i_CDMusic)
- {
- I_CDMusResume();
- }
- else
- {
- I_ResumeSong(RegisteredSong);
- }
-}
-
-//==========================================================================
-//
-// S_UpdateSounds
-//
-//==========================================================================
-
-void S_UpdateSounds(mobj_t *listener)
-{
- int i, dist, vol;
- int angle;
- int sep;
- int priority;
- int absx;
- int absy;
-
- if(i_CDMusic)
- {
- I_UpdateCDMusic();
- }
- if(snd_MaxVolume == 0)
- {
- return;
- }
-
- // Update any Sequences
- SN_UpdateActiveSequences();
-
- if(NextCleanup < gametic)
- {
- if(UseSndScript)
- {
- for(i = 0; i < NUMSFX; i++)
- {
- if(S_sfx[i].usefulness == 0 && S_sfx[i].snd_ptr)
- {
- S_sfx[i].usefulness = -1;
- }
- }
- }
- else
- {
- for(i = 0; i < NUMSFX; i++)
- {
- if(S_sfx[i].usefulness == 0 && S_sfx[i].snd_ptr)
- {
- if(lumpcache[S_sfx[i].lumpnum])
- {
- if(((memblock_t *)((byte*)
- (lumpcache[S_sfx[i].lumpnum])-
- sizeof(memblock_t)))->id == 0x1d4a11)
- { // taken directly from the Z_ChangeTag macro
- Z_ChangeTag2(lumpcache[S_sfx[i].lumpnum],
- PU_CACHE);
-#ifdef __WATCOMC__
- _dpmi_unlockregion(S_sfx[i].snd_ptr,
- lumpinfo[S_sfx[i].lumpnum].size);
-#endif
- }
- }
- S_sfx[i].usefulness = -1;
- S_sfx[i].snd_ptr = NULL;
- }
- }
- }
- NextCleanup = gametic+35*30; // every 30 seconds
- }
- for(i=0;i<snd_Channels;i++)
- {
- if(!Channel[i].handle || S_sfx[Channel[i].sound_id].usefulness == -1)
- {
- continue;
- }
- if(!I_SoundIsPlaying(Channel[i].handle))
- {
- if(S_sfx[Channel[i].sound_id].usefulness > 0)
- {
- S_sfx[Channel[i].sound_id].usefulness--;
- }
- Channel[i].handle = 0;
- Channel[i].mo = NULL;
- Channel[i].sound_id = 0;
- }
- if(Channel[i].mo == NULL || Channel[i].sound_id == 0
- || Channel[i].mo == listener)
- {
- continue;
- }
- else
- {
- absx = abs(Channel[i].mo->x-listener->x);
- absy = abs(Channel[i].mo->y-listener->y);
- dist = absx+absy-(absx > absy ? absy>>1 : absx>>1);
- dist >>= FRACBITS;
-
- if(dist >= MAX_SND_DIST)
- {
- S_StopSound(Channel[i].mo);
- continue;
- }
- if(dist < 0)
- {
- dist = 0;
- }
- //vol = SoundCurve[dist];
- vol = (SoundCurve[dist]*(snd_MaxVolume*8)*Channel[i].volume)>>14;
- if(Channel[i].mo == listener)
- {
- sep = 128;
- }
- else
- {
- angle = R_PointToAngle2(listener->x, listener->y,
- Channel[i].mo->x, Channel[i].mo->y);
- angle = (angle-viewangle)>>24;
- sep = angle*2-128;
- if(sep < 64)
- sep = -sep;
- if(sep > 192)
- sep = 512-sep;
- }
- I_UpdateSoundParams(Channel[i].handle, vol, sep,
- Channel[i].pitch);
- priority = S_sfx[Channel[i].sound_id].priority;
- priority *= PRIORITY_MAX_ADJUST-(dist/DIST_ADJUST);
- Channel[i].priority = priority;
- }
- }
-}
-
-//==========================================================================
-//
-// S_Init
-//
-//==========================================================================
-
-void S_Init(void)
-{
- SoundCurve = W_CacheLumpName("SNDCURVE", PU_STATIC);
-// SoundCurve = Z_Malloc(MAX_SND_DIST, PU_STATIC, NULL);
- I_StartupSound();
- if(snd_Channels > 8)
- {
- snd_Channels = 8;
- }
- I_SetChannels(snd_Channels);
- I_SetMusicVolume(snd_MusicVolume);
-
- // Attempt to setup CD music
- if(snd_MusicDevice == snd_CDMUSIC)
- {
- ST_Message(" Attempting to initialize CD Music: ");
- if(!cdrom)
- {
- i_CDMusic = (I_CDMusInit() != -1);
- }
- else
- { // The user is trying to use the cdrom for both game and music
- i_CDMusic = false;
- }
- if(i_CDMusic)
- {
- ST_Message("initialized.\n");
- }
- else
- {
- ST_Message("failed.\n");
- }
- }
-}
-
-//==========================================================================
-//
-// S_GetChannelInfo
-//
-//==========================================================================
-
-void S_GetChannelInfo(SoundInfo_t *s)
-{
- int i;
- ChanInfo_t *c;
-
- s->channelCount = snd_Channels;
- s->musicVolume = snd_MusicVolume;
- s->soundVolume = snd_MaxVolume;
- for(i = 0; i < snd_Channels; i++)
- {
- c = &s->chan[i];
- c->id = Channel[i].sound_id;
- c->priority = Channel[i].priority;
- c->name = S_sfx[c->id].lumpname;
- c->mo = Channel[i].mo;
- c->distance = P_AproxDistance(c->mo->x-viewx, c->mo->y-viewy)
- >>FRACBITS;
- }
-}
-
-//==========================================================================
-//
-// S_GetSoundPlayingInfo
-//
-//==========================================================================
-
-boolean S_GetSoundPlayingInfo(mobj_t *mobj, int sound_id)
-{
- int i;
-
- for(i = 0; i < snd_Channels; i++)
- {
- if(Channel[i].sound_id == sound_id && Channel[i].mo == mobj)
- {
- if(I_SoundIsPlaying(Channel[i].handle))
- {
- return true;
- }
- }
- }
- return false;
-}
-
-//==========================================================================
-//
-// S_SetMusicVolume
-//
-//==========================================================================
-
-void S_SetMusicVolume(void)
-{
- if(i_CDMusic)
- {
- I_CDMusSetVolume(snd_MusicVolume*16); // 0-255
- }
- else
- {
- I_SetMusicVolume(snd_MusicVolume);
- }
- if(snd_MusicVolume == 0)
- {
- if(!i_CDMusic)
- {
- I_PauseSong(RegisteredSong);
- }
- MusicPaused = true;
- }
- else if(MusicPaused)
- {
- if(!i_CDMusic)
- {
- I_ResumeSong(RegisteredSong);
- }
- MusicPaused = false;
- }
-}
-
-//==========================================================================
-//
-// S_ShutDown
-//
-//==========================================================================
-
-void S_ShutDown(void)
-{
- extern int tsm_ID;
- if(tsm_ID != -1)
- {
- I_StopSong(RegisteredSong);
- I_UnRegisterSong(RegisteredSong);
- I_ShutdownSound();
- }
- if(i_CDMusic)
- {
- I_CDMusStop();
- }
-}
-
-//==========================================================================
-//
-// S_InitScript
-//
-//==========================================================================
-
-void S_InitScript(void)
-{
- int p;
- int i;
-
- strcpy(ArchivePath, DEFAULT_ARCHIVEPATH);
- if(!(p = M_CheckParm("-devsnd")))
- {
- UseSndScript = false;
- SC_OpenLump("sndinfo");
- }
- else
- {
- UseSndScript = true;
- SC_OpenFile(myargv[p+1]);
- }
- while(SC_GetString())
- {
- if(*sc_String == '$')
- {
- if(!stricmp(sc_String, "$ARCHIVEPATH"))
- {
- SC_MustGetString();
- strcpy(ArchivePath, sc_String);
- }
- else if(!stricmp(sc_String, "$MAP"))
- {
- SC_MustGetNumber();
- SC_MustGetString();
- if(sc_Number)
- {
- P_PutMapSongLump(sc_Number, sc_String);
- }
- }
- continue;
- }
- else
- {
- for(i = 0; i < NUMSFX; i++)
- {
- if(!strcmp(S_sfx[i].tagName, sc_String))
- {
- SC_MustGetString();
- if(*sc_String != '?')
- {
- strcpy(S_sfx[i].lumpname, sc_String);
- }
- else
- {
- strcpy(S_sfx[i].lumpname, "default");
- }
- break;
- }
- }
- if(i == NUMSFX)
- {
- SC_MustGetString();
- }
- }
- }
- SC_Close();
-
- for(i = 0; i < NUMSFX; i++)
- {
- if(!strcmp(S_sfx[i].lumpname, ""))
- {
- strcpy(S_sfx[i].lumpname, "default");
- }
- }
-}
-
-//==========================================================================
-//
-// I_UpdateCDMusic
-//
-// Updates playing time for current track, and restarts the track, if
-// needed
-//
-//==========================================================================
-
-void I_UpdateCDMusic(void)
-{
- extern boolean MenuActive;
-
- if(MusicPaused || i_CDMusicLength < 0
- || (paused && !MenuActive))
- { // Non-looping song/song paused
- return;
- }
- i_CDMusicLength -= gametic-oldTic;
- oldTic = gametic;
- if(i_CDMusicLength <= 0)
- {
- S_StartSong(gamemap, true);
- }
-}
-
-/*
-============================================================================
-
- CONSTANTS
-
-============================================================================
-*/
-
-#define SC_INDEX 0x3C4
-#define SC_RESET 0
-#define SC_CLOCK 1
-#define SC_MAPMASK 2
-#define SC_CHARMAP 3
-#define SC_MEMMODE 4
-
-#define CRTC_INDEX 0x3D4
-#define CRTC_H_TOTAL 0
-#define CRTC_H_DISPEND 1
-#define CRTC_H_BLANK 2
-#define CRTC_H_ENDBLANK 3
-#define CRTC_H_RETRACE 4
-#define CRTC_H_ENDRETRACE 5
-#define CRTC_V_TOTAL 6
-#define CRTC_OVERFLOW 7
-#define CRTC_ROWSCAN 8
-#define CRTC_MAXSCANLINE 9
-#define CRTC_CURSORSTART 10
-#define CRTC_CURSOREND 11
-#define CRTC_STARTHIGH 12
-#define CRTC_STARTLOW 13
-#define CRTC_CURSORHIGH 14
-#define CRTC_CURSORLOW 15
-#define CRTC_V_RETRACE 16
-#define CRTC_V_ENDRETRACE 17
-#define CRTC_V_DISPEND 18
-#define CRTC_OFFSET 19
-#define CRTC_UNDERLINE 20
-#define CRTC_V_BLANK 21
-#define CRTC_V_ENDBLANK 22
-#define CRTC_MODE 23
-#define CRTC_LINECOMPARE 24
-
-
-#define GC_INDEX 0x3CE
-#define GC_SETRESET 0
-#define GC_ENABLESETRESET 1
-#define GC_COLORCOMPARE 2
-#define GC_DATAROTATE 3
-#define GC_READMAP 4
-#define GC_MODE 5
-#define GC_MISCELLANEOUS 6
-#define GC_COLORDONTCARE 7
-#define GC_BITMASK 8
-
-#define ATR_INDEX 0x3c0
-#define ATR_MODE 16
-#define ATR_OVERSCAN 17
-#define ATR_COLORPLANEENABLE 18
-#define ATR_PELPAN 19
-#define ATR_COLORSELECT 20
-
-#define STATUS_REGISTER_1 0x3da
-
-#define PEL_WRITE_ADR 0x3c8
-#define PEL_READ_ADR 0x3c7
-#define PEL_DATA 0x3c9
-#define PEL_MASK 0x3c6
-
-// boolean grmode;
-
-//==================================================
-//
-// joystick vars
-//
-//==================================================
-
-boolean joystickpresent;
-extern unsigned joystickx, joysticky;
-boolean I_ReadJoystick (void); // returns false if not connected
-
-
-//==================================================
-
-#define VBLCOUNTER 34000 // hardware tics to a frame
-
-
-#define TIMERINT 8
-#define KEYBOARDINT 9
-
-#define CRTCOFF (_inbyte(STATUS_REGISTER_1)&1)
-#define CLI _disable()
-#define STI _enable()
-
-#define _outbyte(x,y) (outp(x,y))
-#define _outhword(x,y) (outpw(x,y))
-
-#define _inbyte(x) (inp(x))
-#define _inhword(x) (inpw(x))
-
-#define MOUSEB1 1
-#define MOUSEB2 2
-#define MOUSEB3 4
-
-boolean mousepresent;
-//static int tsm_ID = -1; // tsm init flag
-
-//===============================
-
-int ticcount;
-
-// REGS stuff used for int calls
-union REGS regs;
-struct SREGS segregs;
-
-boolean novideo; // if true, stay in text mode for debugging
-
-#define KBDQUESIZE 32
-byte keyboardque[KBDQUESIZE];
-int kbdtail, kbdhead;
-
-#define KEY_LSHIFT 0xfe
-
-#define KEY_INS (0x80+0x52)
-#define KEY_DEL (0x80+0x53)
-#define KEY_PGUP (0x80+0x49)
-#define KEY_PGDN (0x80+0x51)
-#define KEY_HOME (0x80+0x47)
-#define KEY_END (0x80+0x4f)
-
-#define SC_RSHIFT 0x36
-#define SC_LSHIFT 0x2a
-
-byte scantokey[128] =
- {
-// 0 1 2 3 4 5 6 7
-// 8 9 A B C D E F
- 0 , 27, '1', '2', '3', '4', '5', '6',
- '7', '8', '9', '0', '-', '=', KEY_BACKSPACE, 9, // 0
- 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
- 'o', 'p', '[', ']', 13 , KEY_RCTRL,'a', 's', // 1
- 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
- 39 , '`', KEY_LSHIFT,92, 'z', 'x', 'c', 'v', // 2
- 'b', 'n', 'm', ',', '.', '/', KEY_RSHIFT,'*',
- KEY_RALT,' ', 0 , KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, // 3
- KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10,0 , 0 , KEY_HOME,
- KEY_UPARROW,KEY_PGUP,'-',KEY_LEFTARROW,'5',KEY_RIGHTARROW,'+',KEY_END, //4
- KEY_DOWNARROW,KEY_PGDN,KEY_INS,KEY_DEL,0,0, 0, KEY_F11,
- KEY_F12,0 , 0 , 0 , 0 , 0 , 0 , 0, // 5
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7
- };
-
-//==========================================================================
-
-//--------------------------------------------------------------------------
-//
-// FUNC I_GetTime
-//
-// Returns time in 1/35th second tics.
-//
-//--------------------------------------------------------------------------
-
-int I_GetTime (void)
-{
-#ifdef NOTIMER
- ticcount++;
-#endif
- return(ticcount);
-}
-
-//--------------------------------------------------------------------------
-//
-// PROC I_ColorBorder
-//
-//--------------------------------------------------------------------------
-
-/*
-void I_ColorBorder(void)
-{
- int i;
-
- I_WaitVBL(1);
- _outbyte(PEL_WRITE_ADR, 0);
- for(i = 0; i < 3; i++)
- {
- _outbyte(PEL_DATA, 63);
- }
-}
-*/
-
-//--------------------------------------------------------------------------
-//
-// PROC I_UnColorBorder
-//
-//--------------------------------------------------------------------------
-
-/*
-void I_UnColorBorder(void)
-{
- int i;
-
- I_WaitVBL(1);
- _outbyte(PEL_WRITE_ADR, 0);
- for(i = 0; i < 3; i++)
- {
- _outbyte(PEL_DATA, 0);
- }
-}
-*/
-
-/*
-============================================================================
-
- USER INPUT
-
-============================================================================
-*/
-
-//--------------------------------------------------------------------------
-//
-// PROC I_WaitVBL
-//
-//--------------------------------------------------------------------------
-
-void I_WaitVBL(int vbls)
-{
- int stat;
-
- if(novideo)
- {
- return;
- }
- while(vbls--)
- {
- do
- {
- stat = inp(STATUS_REGISTER_1);
- if(stat&8)
- {
- break;
- }
- } while(1);
- do
- {
- stat = inp(STATUS_REGISTER_1);
- if((stat&8) == 0)
- {
- break;
- }
- } while(1);
- }
-}
-
-//--------------------------------------------------------------------------
-//
-// PROC I_SetPalette
-//
-// Palette source must use 8 bit RGB elements.
-//
-//--------------------------------------------------------------------------
-
-void I_SetPalette(byte *palette)
-{
- int i;
-
- if(novideo)
- {
- return;
- }
- I_WaitVBL(1);
- _outbyte(PEL_WRITE_ADR, 0);
- for(i = 0; i < 768; i++)
- {
- _outbyte(PEL_DATA, (gammatable[usegamma][*palette++])>>2);
- }
-}
-
-/*
-============================================================================
-
- GRAPHICS MODE
-
-============================================================================
-*/
-
-byte *pcscreen, *destscreen, *destview;
-
-
-/*
-==============
-=
-= I_Update
-=
-==============
-*/
-
-int UpdateState;
-extern int screenblocks;
-
-void I_Update (void)
-{
- int i;
- byte *dest;
- int tics;
- static int lasttic;
-
-//
-// blit screen to video
-//
- if(DisplayTicker)
- {
- if(screenblocks > 9 || UpdateState&(I_FULLSCRN|I_MESSAGES))
- {
- dest = (byte *)screen;
- }
- else
- {
- dest = (byte *)pcscreen;
- }
- tics = ticcount-lasttic;
- lasttic = ticcount;
- if(tics > 20)
- {
- tics = 20;
- }
- for(i = 0; i < tics; i++)
- {
- *dest = 0xff;
- dest += 2;
- }
- for(i = tics; i < 20; i++)
- {
- *dest = 0x00;
- dest += 2;
- }
- }
-
- //memset(pcscreen, 255, SCREENHEIGHT*SCREENWIDTH);
-
- if(UpdateState == I_NOUPDATE)
- {
- return;
- }
- if(UpdateState&I_FULLSCRN)
- {
- memcpy(pcscreen, screen, SCREENWIDTH*SCREENHEIGHT);
- UpdateState = I_NOUPDATE; // clear out all draw types
- }
- if(UpdateState&I_FULLVIEW)
- {
- if(UpdateState&I_MESSAGES && screenblocks > 7)
- {
- for(i = 0; i <
- (viewwindowy+viewheight)*SCREENWIDTH; i += SCREENWIDTH)
- {
- memcpy(pcscreen+i, screen+i, SCREENWIDTH);
- }
- UpdateState &= ~(I_FULLVIEW|I_MESSAGES);
- }
- else
- {
- for(i = viewwindowy*SCREENWIDTH+viewwindowx; i <
- (viewwindowy+viewheight)*SCREENWIDTH; i += SCREENWIDTH)
- {
- memcpy(pcscreen+i, screen+i, viewwidth);
- }
- UpdateState &= ~I_FULLVIEW;
- }
- }
- if(UpdateState&I_STATBAR)
- {
- memcpy(pcscreen+SCREENWIDTH*(SCREENHEIGHT-SBARHEIGHT),
- screen+SCREENWIDTH*(SCREENHEIGHT-SBARHEIGHT),
- SCREENWIDTH*SBARHEIGHT);
- UpdateState &= ~I_STATBAR;
- }
- if(UpdateState&I_MESSAGES)
- {
- memcpy(pcscreen, screen, SCREENWIDTH*28);
- UpdateState &= ~I_MESSAGES;
- }
-
-
-// memcpy(pcscreen, screen, SCREENHEIGHT*SCREENWIDTH);
-}
-
-//--------------------------------------------------------------------------
-//
-// PROC I_InitGraphics
-//
-//--------------------------------------------------------------------------
-
-void I_InitGraphics(void)
-{
- if(novideo)
- {
- return;
- }
- //grmode = true;
- regs.w.ax = 0x13;
- int386(0x10, (const union REGS *)®s, ®s);
- pcscreen = destscreen = (byte *)0xa0000;
- I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE));
-}
-
-//--------------------------------------------------------------------------
-//
-// PROC I_ShutdownGraphics
-//
-//--------------------------------------------------------------------------
-
-void I_ShutdownGraphics(void)
-{
- byte mode;
-
- // don't reset mode if it didn't get set
- mode = *(byte *)0x449;
- if(mode == 0x12 || mode == 0x13)
- {
- regs.w.ax = 3;
- int386(0x10, ®s, ®s); // back to text mode
- }
-}
-
-//--------------------------------------------------------------------------
-//
-// PROC I_ReadScreen
-//
-// Reads the screen currently displayed into a linear buffer.
-//
-//--------------------------------------------------------------------------
-
-/*
-void I_ReadScreen(byte *scr)
-{
- memcpy(scr, screen, SCREENWIDTH*SCREENHEIGHT);
-}
-*/
-
-//===========================================================================
-
-/*
-===================
-=
-= I_StartTic
-=
-// called by D_DoomLoop
-// called before processing each tic in a frame
-// can call D_PostEvent
-// asyncronous interrupt functions should maintain private ques that are
-// read by the syncronous functions to be converted into events
-===================
-*/
-
-/*
- OLD STARTTIC STUFF
-
-void I_StartTic (void)
-{
- int k;
- event_t ev;
-
-
- I_ReadMouse ();
-
-//
-// keyboard events
-//
- while (kbdtail < kbdhead)
- {
- k = keyboardque[kbdtail&(KBDQUESIZE-1)];
-
-// if (k==14)
-// I_Error ("exited");
-
- kbdtail++;
-
- // extended keyboard shift key bullshit
- if ( (k&0x7f)==KEY_RSHIFT )
- {
- if ( keyboardque[(kbdtail-2)&(KBDQUESIZE-1)]==0xe0 )
- continue;
- k &= 0x80;
- k |= KEY_RSHIFT;
- }
-
- if (k==0xe0)
- continue; // special / pause keys
- if (keyboardque[(kbdtail-2)&(KBDQUESIZE-1)] == 0xe1)
- continue; // pause key bullshit
-
- if (k==0xc5 && keyboardque[(kbdtail-2)&(KBDQUESIZE-1)] == 0x9d)
- {
- ev.type = ev_keydown;
- ev.data1 = KEY_PAUSE;
- D_PostEvent (&ev);
- continue;
- }
-
- if (k&0x80)
- ev.type = ev_keyup;
- else
- ev.type = ev_keydown;
- k &= 0x7f;
-
- ev.data1 = k;
- //ev.data1 = scantokey[k];
-
- D_PostEvent (&ev);
- }
-}
-*/
-
-#define SC_UPARROW 0x48
-#define SC_DOWNARROW 0x50
-#define SC_LEFTARROW 0x4b
-#define SC_RIGHTARROW 0x4d
-
-void I_StartTic (void)
-{
- int k;
- event_t ev;
-
-
- I_ReadMouse ();
-
-//
-// keyboard events
-//
- while (kbdtail < kbdhead)
- {
- k = keyboardque[kbdtail&(KBDQUESIZE-1)];
- kbdtail++;
-
- // extended keyboard shift key bullshit
- if ( (k&0x7f)==SC_LSHIFT || (k&0x7f)==SC_RSHIFT )
- {
- if ( keyboardque[(kbdtail-2)&(KBDQUESIZE-1)]==0xe0 )
- continue;
- k &= 0x80;
- k |= SC_RSHIFT;
- }
-
- if (k==0xe0)
- continue; // special / pause keys
- if (keyboardque[(kbdtail-2)&(KBDQUESIZE-1)] == 0xe1)
- continue; // pause key bullshit
-
- if (k==0xc5 && keyboardque[(kbdtail-2)&(KBDQUESIZE-1)] == 0x9d)
- {
- ev.type = ev_keydown;
- ev.data1 = KEY_PAUSE;
- H2_PostEvent (&ev);
- continue;
- }
-
- if (k&0x80)
- ev.type = ev_keyup;
- else
- ev.type = ev_keydown;
- k &= 0x7f;
- switch (k)
- {
- case SC_UPARROW:
- ev.data1 = KEY_UPARROW;
- break;
- case SC_DOWNARROW:
- ev.data1 = KEY_DOWNARROW;
- break;
- case SC_LEFTARROW:
- ev.data1 = KEY_LEFTARROW;
- break;
- case SC_RIGHTARROW:
- ev.data1 = KEY_RIGHTARROW;
- break;
- default:
- ev.data1 = scantokey[k];
- break;
- }
- H2_PostEvent (&ev);
- }
-
-}
-
-
-/*
-void I_ReadKeys (void)
-{
- int k;
-
-
- while (1)
- {
- while (kbdtail < kbdhead)
- {
- k = keyboardque[kbdtail&(KBDQUESIZE-1)];
- kbdtail++;
- printf ("0x%x\n",k);
- if (k == 1)
- I_Quit ();
- }
- }
-}
-*/
-
-/*
-===============
-=
-= I_StartFrame
-=
-===============
-*/
-
-void I_StartFrame (void)
-{
- I_JoystickEvents ();
- if(useexterndriver)
- {
- DPMIInt(i_Vector);
- }
-}
-
-/*
-============================================================================
-
- TIMER INTERRUPT
-
-============================================================================
-*/
-
-/*
-void I_ColorBlack (int r, int g, int b)
-{
-_outbyte (PEL_WRITE_ADR,0);
-_outbyte(PEL_DATA,r);
-_outbyte(PEL_DATA,g);
-_outbyte(PEL_DATA,b);
-}
-*/
-
-
-/*
-================
-=
-= I_TimerISR
-=
-================
-*/
-
-int I_TimerISR (void)
-{
- ticcount++;
- return 0;
-}
-
-/*
-============================================================================
-
- KEYBOARD
-
-============================================================================
-*/
-
-void (__interrupt __far *oldkeyboardisr) () = NULL;
-
-int lastpress;
-
-/*
-================
-=
-= I_KeyboardISR
-=
-================
-*/
-
-void __interrupt I_KeyboardISR (void)
-{
-// Get the scan code
-
- keyboardque[kbdhead&(KBDQUESIZE-1)] = lastpress = _inbyte(0x60);
- kbdhead++;
-
-// acknowledge the interrupt
-
- _outbyte(0x20,0x20);
-}
-
-
-
-/*
-===============
-=
-= I_StartupKeyboard
-=
-===============
-*/
-
-void I_StartupKeyboard (void)
-{
-#ifndef NOKBD
- oldkeyboardisr = _dos_getvect(KEYBOARDINT);
- _dos_setvect (0x8000 | KEYBOARDINT, I_KeyboardISR);
-#endif
-
-//I_ReadKeys ();
-}
-
-
-void I_ShutdownKeyboard (void)
-{
- if (oldkeyboardisr)
- _dos_setvect (KEYBOARDINT, oldkeyboardisr);
- *(short *)0x41c = *(short *)0x41a; // clear bios key buffer
-}
-
-
-
-/*
-============================================================================
-
- MOUSE
-
-============================================================================
-*/
-
-
-int I_ResetMouse (void)
-{
- regs.w.ax = 0; // reset
- int386 (0x33, ®s, ®s);
- return regs.w.ax;
-}
-
-
-
-/*
-================
-=
-= StartupMouse
-=
-================
-*/
-
-void I_StartupCyberMan(void);
-
-void I_StartupMouse (void)
-{
- //
- // General mouse detection
- //
- mousepresent = 0;
- if ( M_CheckParm ("-nomouse") || !usemouse )
- return;
-
- if (I_ResetMouse () != 0xffff)
- {
- ST_Message("Mouse: not present\n");
- return;
- }
- ST_Message("Mouse: detected\n");
-
- mousepresent = 1;
-
- I_StartupCyberMan();
-}
-
-
-/*
-================
-=
-= ShutdownMouse
-=
-================
-*/
-
-void I_ShutdownMouse (void)
-{
- if (!mousepresent)
- return;
-
- I_ResetMouse ();
-}
-
-
-/*
-================
-=
-= I_ReadMouse
-=
-================
-*/
-
-void I_ReadMouse (void)
-{
- event_t ev;
-
-//
-// mouse events
-//
- if (!mousepresent)
- return;
-
- ev.type = ev_mouse;
-
- memset (&dpmiregs,0,sizeof(dpmiregs));
- dpmiregs.eax = 3; // read buttons / position
- DPMIInt (0x33);
- ev.data1 = dpmiregs.ebx;
-
- dpmiregs.eax = 11; // read counters
- DPMIInt (0x33);
- ev.data2 = (short)dpmiregs.ecx;
- ev.data3 = -(short)dpmiregs.edx;
-
- H2_PostEvent (&ev);
-}
-
-/*
-============================================================================
-
- JOYSTICK
-
-============================================================================
-*/
-
-int joyxl, joyxh, joyyl, joyyh;
-
-boolean WaitJoyButton (void)
-{
- int oldbuttons, buttons;
-
- oldbuttons = 0;
- do
- {
- I_WaitVBL (1);
- buttons = ((inp(0x201) >> 4)&1)^1;
- if (buttons != oldbuttons)
- {
- oldbuttons = buttons;
- continue;
- }
-
- if ( (lastpress& 0x7f) == 1 )
- {
- joystickpresent = false;
- return false;
- }
- } while ( !buttons);
-
- do
- {
- I_WaitVBL (1);
- buttons = ((inp(0x201) >> 4)&1)^1;
- if (buttons != oldbuttons)
- {
- oldbuttons = buttons;
- continue;
- }
-
- if ( (lastpress& 0x7f) == 1 )
- {
- joystickpresent = false;
- return false;
- }
- } while ( buttons);
-
- return true;
-}
-
-
-
-/*
-===============
-=
-= I_StartupJoystick
-=
-===============
-*/
-
-int basejoyx, basejoyy;
-
-void I_StartupJoystick (void)
-{
- int centerx, centery;
-
- joystickpresent = 0;
- if ( M_CheckParm ("-nojoy") || !usejoystick )
- return;
-
- if (!I_ReadJoystick ())
- {
- joystickpresent = false;
- ST_Message("joystick not found\n ");
- return;
- }
- ST_Message("joystick found\n");
- joystickpresent = true;
-
- ST_RealMessage("CENTER the joystick and press button 1:");
- if (!WaitJoyButton ())
- return;
- I_ReadJoystick ();
- centerx = joystickx;
- centery = joysticky;
-
- ST_RealMessage("\nPush the joystick to the UPPER LEFT corner and press button 1:");
- if (!WaitJoyButton ())
- return;
- I_ReadJoystick ();
- joyxl = (centerx + joystickx)/2;
- joyyl = (centerx + joysticky)/2;
-
- ST_RealMessage("\nPush the joystick to the LOWER RIGHT corner and press button 1:");
- if (!WaitJoyButton ())
- return;
- I_ReadJoystick ();
- joyxh = (centerx + joystickx)/2;
- joyyh = (centery + joysticky)/2;
- ST_RealMessage("\n");
-}
-
-/*
-===============
-=
-= I_JoystickEvents
-=
-===============
-*/
-
-void I_JoystickEvents (void)
-{
- event_t ev;
-
-//
-// joystick events
-//
- if (!joystickpresent)
- return;
-
- I_ReadJoystick ();
- ev.type = ev_joystick;
- ev.data1 = ((inp(0x201) >> 4)&15)^15;
-
- if (joystickx < joyxl)
- ev.data2 = -1;
- else if (joystickx > joyxh)
- ev.data2 = 1;
- else
- ev.data2 = 0;
- if (joysticky < joyyl)
- ev.data3 = -1;
- else if (joysticky > joyyh)
- ev.data3 = 1;
- else
- ev.data3 = 0;
-
- H2_PostEvent (&ev);
-}
-
-
-
-/*
-============================================================================
-
- DPMI STUFF
-
-============================================================================
-*/
-
-#define REALSTACKSIZE 1024
-
-dpmiregs_t dpmiregs;
-
-unsigned realstackseg;
-
-void I_DivException (void);
-int I_SetDivException (void);
-
-/*
-void DPMIFarCall (void)
-{
- segread (&segregs);
- regs.w.ax = 0x301;
- regs.w.bx = 0;
- regs.w.cx = 0;
- regs.x.edi = (unsigned)&dpmiregs;
- segregs.es = segregs.ds;
- int386x( DPMI_INT, ®s, ®s, &segregs );
-}
-*/
-
-void DPMIInt (int i)
-{
- dpmiregs.ss = realstackseg;
- dpmiregs.sp = REALSTACKSIZE-4;
-
- segread (&segregs);
- regs.w.ax = 0x300;
- regs.w.bx = i;
- regs.w.cx = 0;
- regs.x.edi = (unsigned)&dpmiregs;
- segregs.es = segregs.ds;
- int386x( DPMI_INT, ®s, ®s, &segregs );
-}
-
-
-/*
-==============
-=
-= I_StartupDPMI
-=
-==============
-*/
-
-void I_StartupDPMI (void)
-{
-// extern char __begtext;
-// extern char ___argc;
-// int n,d;
-
-//
-// allocate a decent stack for real mode ISRs
-//
- realstackseg = (int)I_AllocLow (1024) >> 4;
-
-//
-// lock the entire program down
-//
-
-// _dpmi_lockregion (&__begtext, &___argc - &__begtext);
-
-
-//
-// catch divide by 0 exception
-//
-#if 0
- segread(&segregs);
- regs.w.ax = 0x0203; // DPMI set processor exception handler vector
- regs.w.bx = 0; // int 0
- regs.w.cx = segregs.cs;
- regs.x.edx = (int)&I_DivException;
- printf ("%x : %x\n",regs.w.cx, regs.x.edx);
- int386( DPMI_INT, ®s, ®s);
-#endif
-
-#if 0
- n = I_SetDivException ();
- printf ("return: %i\n",n);
- n = 100;
- d = 0;
- printf ("100 / 0 = %i\n",n/d);
-
-exit (1);
-#endif
-}
-
-
-
-/*
-============================================================================
-
- TIMER INTERRUPT
-
-============================================================================
-*/
-
-void (__interrupt __far *oldtimerisr) ();
-
-
-/*
-void IO_ColorBlack (int r, int g, int b)
-{
-_outbyte (PEL_WRITE_ADR,0);
-_outbyte(PEL_DATA,r);
-_outbyte(PEL_DATA,g);
-_outbyte(PEL_DATA,b);
-}
-*/
-
-
-/*
-================
-=
-= IO_TimerISR
-=
-================
-*/
-
-//void __interrupt IO_TimerISR (void)
-
-void __interrupt __far IO_TimerISR (void)
-{
- ticcount++;
- _outbyte(0x20,0x20); // Ack the interrupt
-}
-
-/*
-=====================
-=
-= IO_SetTimer0
-=
-= Sets system timer 0 to the specified speed
-=
-=====================
-*/
-
-void IO_SetTimer0(int speed)
-{
- if (speed > 0 && speed < 150)
- I_Error ("INT_SetTimer0: %i is a bad value",speed);
-
- _outbyte(0x43,0x36); // Change timer 0
- _outbyte(0x40,speed);
- _outbyte(0x40,speed >> 8);
-}
-
-
-
-/*
-===============
-=
-= IO_StartupTimer
-=
-===============
-*/
-
-/*
-void IO_StartupTimer (void)
-{
- oldtimerisr = _dos_getvect(TIMERINT);
-
- _dos_setvect (0x8000 | TIMERINT, IO_TimerISR);
- IO_SetTimer0 (VBLCOUNTER);
-}
-*/
-
-void IO_ShutdownTimer (void)
-{
- if (oldtimerisr)
- {
- IO_SetTimer0 (0); // back to 18.4 ips
- _dos_setvect (TIMERINT, oldtimerisr);
- }
-}
-
-//===========================================================================
-
-
-/*
-===============
-=
-= I_Init
-=
-= hook interrupts and set graphics mode
-=
-===============
-*/
-
-void I_Init (void)
-{
- extern void I_StartupTimer(void);
-
- novideo = M_CheckParm("novideo");
- ST_Message(" I_StartupDPMI\n");
- I_StartupDPMI();
- ST_Message(" I_StartupMouse ");
- I_StartupMouse();
-// tprintf("I_StartupJoystick ",1);
-// I_StartupJoystick();
-// tprintf("I_StartupKeyboard ",1);
-// I_StartupKeyboard();
- ST_Message(" S_Init... ");
- S_Init();
- //IO_StartupTimer();
- S_Start();
-}
-
-
-/*
-===============
-=
-= I_Shutdown
-=
-= return to default system state
-=
-===============
-*/
-
-void I_Shutdown (void)
-{
- I_ShutdownGraphics ();
- IO_ShutdownTimer ();
- S_ShutDown ();
- I_ShutdownMouse ();
- I_ShutdownKeyboard ();
-
- IO_SetTimer0 (0);
-}
-
-
-/*
-================
-=
-= I_Error
-=
-================
-*/
-
-void I_Error (char *error, ...)
-{
- union REGS regs;
-
- va_list argptr;
-
- D_QuitNetGame ();
- I_Shutdown ();
- va_start (argptr,error);
- regs.x.eax = 0x3;
- int386(0x10, ®s, ®s);
- vprintf (error,argptr);
- va_end (argptr);
- printf ("\n");
- exit (1);
-}
-
-//--------------------------------------------------------------------------
-//
-// I_Quit
-//
-// Shuts down net game, saves defaults, prints the exit text message,
-// goes to text mode, and exits.
-//
-//--------------------------------------------------------------------------
-
-void I_Quit(void)
-{
- D_QuitNetGame();
- M_SaveDefaults();
- I_Shutdown();
-
-// scr = (byte *)W_CacheLumpName("ENDTEXT", PU_CACHE);
-/*
- memcpy((void *)0xb8000, scr, 80*25*2);
- regs.w.ax = 0x0200;
- regs.h.bh = 0;
- regs.h.dl = 0;
- regs.h.dh = 23;
- int386(0x10, (const union REGS *)®s, ®s); // Set text pos
- _settextposition(24, 1);
-*/
- printf("\nHexen: Beyond Heretic\n");
- exit(0);
-}
-
-/*
-===============
-=
-= I_ZoneBase
-=
-===============
-*/
-
-byte *I_ZoneBase (int *size)
-{
- int meminfo[32];
- int heap;
- byte *ptr;
-
- memset (meminfo,0,sizeof(meminfo));
- segread(&segregs);
- segregs.es = segregs.ds;
- regs.w.ax = 0x500; // get memory info
- regs.x.edi = (int)&meminfo;
- int386x( 0x31, ®s, ®s, &segregs );
-
- heap = meminfo[0];
- ST_Message (" DPMI memory: 0x%x, ",heap);
- ST_Message ("Maxzone: 0x%x\n", maxzone);
-
- do
- {
- heap -= 0x10000; // leave 64k alone
- if (heap > maxzone)
- heap = maxzone;
- ptr = malloc (heap);
- } while (!ptr);
-
- ST_Message (" 0x%x allocated for zone, ", heap);
- ST_Message ("ZoneBase: 0x%X\n", (int)ptr);
-
- if (heap < 0x180000)
- I_Error (" Insufficient DPMI memory!");
-#if 0
- regs.w.ax = 0x501; // allocate linear block
- regs.w.bx = heap>>16;
- regs.w.cx = heap&0xffff;
- int386( 0x31, ®s, ®s);
- if (regs.w.cflag)
- I_Error (" Couldn't allocate DPMI memory!");
-
- block = (regs.w.si << 16) + regs.w.di;
-#endif
-
- *size = heap;
- return ptr;
-}
-
-/*
-=============
-=
-= I_AllocLow
-=
-=============
-*/
-
-byte *I_AllocLow (int length)
-{
- byte *mem;
-
- // DPMI call 100h allocates DOS memory
- segread(&segregs);
- regs.w.ax = 0x0100; // DPMI allocate DOS memory
- regs.w.bx = (length+15) / 16;
- int386( DPMI_INT, ®s, ®s);
-// segment = regs.w.ax;
-// selector = regs.w.dx;
- if (regs.w.cflag != 0)
- I_Error ("I_AllocLow: DOS alloc of %i failed, %i free",
- length, regs.w.bx*16);
-
-
- mem = (void *) ((regs.x.eax & 0xFFFF) << 4);
-
- memset (mem,0,length);
- return mem;
-}
-
-/*
-============================================================================
-
- NETWORKING
-
-============================================================================
-*/
-
-/* // FUCKED LINES
-typedef struct
-{
- char priv[508];
-} doomdata_t;
-*/ // FUCKED LINES
-
-#define DOOMCOM_ID 0x12345678l
-
-/* // FUCKED LINES
-typedef struct
-{
- long id;
- short intnum; // DOOM executes an int to execute commands
-
-// communication between DOOM and the driver
- short command; // CMD_SEND or CMD_GET
- short remotenode; // dest for send, set by get (-1 = no packet)
- short datalength; // bytes in doomdata to be sent
-
-// info common to all nodes
- short numnodes; // console is allways node 0
- short ticdup; // 1 = no duplication, 2-5 = dup for slow nets
- short extratics; // 1 = send a backup tic in every packet
- short deathmatch; // 1 = deathmatch
- short savegame; // -1 = new game, 0-5 = load savegame
- short episode; // 1-3
- short map; // 1-9
- short skill; // 1-5
-
-// info specific to this node
- short consoleplayer;
- short numplayers;
- short angleoffset; // 1 = left, 0 = center, -1 = right
- short drone; // 1 = drone
-
-// packet data to be sent
- doomdata_t data;
-} doomcom_t;
-*/ // FUCKED LINES
-
-extern doomcom_t *doomcom;
-
-/*
-====================
-=
-= I_InitNetwork
-=
-====================
-*/
-
-void I_InitNetwork (void)
-{
- int i;
-
- i = M_CheckParm ("-net");
- if (!i)
- {
- //
- // single player game
- //
- doomcom = malloc (sizeof (*doomcom) );
- memset (doomcom, 0, sizeof(*doomcom) );
- netgame = false;
- doomcom->id = DOOMCOM_ID;
- doomcom->numplayers = doomcom->numnodes = 1;
- doomcom->deathmatch = false;
- doomcom->consoleplayer = 0;
- doomcom->ticdup = 1;
- doomcom->extratics = 0;
- return;
- }
-
- netgame = true;
- doomcom = (doomcom_t *)atoi(myargv[i+1]);
-//DEBUG
-doomcom->skill = startskill;
-doomcom->episode = startepisode;
-doomcom->map = startmap;
-doomcom->deathmatch = deathmatch;
-
-}
-
-void I_NetCmd (void)
-{
- if (!netgame)
- I_Error ("I_NetCmd when not in netgame");
- DPMIInt (doomcom->intnum);
-}
-
-//=========================================================================
-//
-// I_CheckExternDriver
-//
-// Checks to see if a vector, and an address for an external driver
-// have been passed.
-//=========================================================================
-
-void I_CheckExternDriver(void)
-{
- int i;
-
- if(!(i = M_CheckParm("-externdriver")))
- {
- return;
- }
- i_ExternData = (externdata_t *)atoi(myargv[i+1]);
- i_Vector = i_ExternData->vector;
-
- useexterndriver = true;
-}
-
-//=========================================================================
-//=========================================================================
-// Hi-Res (mode 12) stuff
-//=========================================================================
-//=========================================================================
-
-
-//==========================================================================
-//
-// SetVideoModeHR - Set video mode to 640x480x16
-//
-//==========================================================================
-
-
-void SetVideoModeHR(void)
-{
- union REGS regs;
- regs.x.eax = 0x12;
- int386(VID_INT, ®s, ®s);
-}
-
-
-//==========================================================================
-//
-// ClearScreenHR - Clear the screen to color 0
-//
-//==========================================================================
-
-void ClearScreenHR(void)
-{
- BITPLANE(MASK_PLANE0|MASK_PLANE1|MASK_PLANE2|MASK_PLANE3);
- memset((char *)0xa0000,0,38400);
-}
-
-
-//==========================================================================
-//
-// SlamHR - copy 4-plane buffer to screen
-//
-//==========================================================================
-
-void SlamHR(char *buffer)
-{
- BITPLANE(MASK_PLANE0);
- memcpy((char *)0xA0000, buffer+P0OFFSET, 38400);
- BITPLANE(MASK_PLANE1);
- memcpy((char *)0xA0000, buffer+P1OFFSET, 38400);
- BITPLANE(MASK_PLANE2);
- memcpy((char *)0xA0000, buffer+P2OFFSET, 38400);
- BITPLANE(MASK_PLANE3);
- memcpy((char *)0xA0000, buffer+P3OFFSET, 38400);
-}
-
-
-//==========================================================================
-//
-// SlamHR - copy 4-plane buffer to screen
-//
-// X and Width should be a multiple of 8
-// src should be 4 planes of block size, back to back
-//==========================================================================
-
-void SlamBlockHR(int x, int y, int w, int h, char *src)
-{
- int srcwid = w>>3;
- char *dest = ((char *)0xA0000) + (y*(640/8)) + (x>>3);
- char *dst;
- int i;
-
- VB_SYNC;
-
- BITPLANE(MASK_PLANE0);
- dst = dest;
- for ( i=0; i<h; i++ )
- {
- memcpy(dst, src, srcwid);
- dst += 640/8;
- src += srcwid;
- }
- BITPLANE(MASK_PLANE1);
- dst = dest;
- for ( i=0; i<h; i++ )
- {
- memcpy(dst, src, srcwid);
- dst += 640/8;
- src += srcwid;
- }
- BITPLANE(MASK_PLANE2);
- dst = dest;
- for ( i=0; i<h; i++ )
- {
- memcpy(dst, src, srcwid);
- dst += 640/8;
- src += srcwid;
- }
- BITPLANE(MASK_PLANE3);
- dst = dest;
- for ( i=0; i<h; i++ )
- {
- memcpy(dst, src, srcwid);
- dst += 640/8;
- src += srcwid;
- }
-}
-
-//==========================================================================
-//
-// InitPaletteHR
-//
-//==========================================================================
-
-void InitPaletteHR(void)
-{
- int i;
- union REGS regs;
-
- // Set palette registers to point into color registers
- for ( i=0; i<16; i++ )
- {
- regs.x.eax = (0x10<<8)|0x00;
- regs.x.ebx = (i<<8)|i;
- int386(VID_INT, ®s, ®s);
- }
-
-}
-
-
-//==========================================================================
-//
-// SetPaletteHR - Set the HR palette
-//
-//==========================================================================
-
-void SetPaletteHR(byte *palette)
-{
- int i;
- VB_SYNC;
- outp(PEL_WRITE_ADR, 0);
-
- for(i = 0; i < 16*3; i++)
- {
- outp(PEL_DATA, (*palette++));
- }
-}
-
-
-//==========================================================================
-//
-// GetPaletteHR - Get the HR palette
-//
-//==========================================================================
-
-void GetPaletteHR(byte *palette)
-{
- int i;
- outp(PEL_READ_ADR, 0);
- for (i=0; i<16*3; i++)
- {
- *palette++ = inp(PEL_DATA);
- }
-}
-
-
-//==========================================================================
-//
-// FadeToPaletteHR
-//
-//==========================================================================
-
-void FadeToPaletteHR(byte *palette)
-{
- int i,j;
- int steps=140; // two-seconds
- byte basep[16*3];
- byte work[16*3];
- int delta;
-
- GetPaletteHR(basep);
- for(i = 0; i < steps; i++)
- {
- for(j = 0; j < 16*3; j++)
- {
- delta = palette[j]-basep[j];
- work[j] = basep[j]+delta*i/steps;
- }
- SetPaletteHR(work);
- }
- SetPaletteHR(palette);
-}
-
-
-//==========================================================================
-//
-// FadeToBlackHR - Fades the palette out to black
-//
-//==========================================================================
-
-/*
-void FadeToBlackHR(void)
-{
- char work[16*3];
- char base[16*3];
- int i,j,steps=70;
-
- GetPaletteHR(base);
- for (i=0; i<steps; i++)
- {
- for (j=0; j<16*3; j++)
- {
- work[j] = base[j]-(base[j]*i/steps);
- }
- VB_SYNC;
- SetPaletteHR(work);
- }
- memset(work,0,16*3);
- SetPaletteHR(work);
-}
-*/
-
-//==========================================================================
-//
-// BlackPaletteHR - Instantly blacks out the palette
-//
-//==========================================================================
-
-void BlackPaletteHR(void)
-{
- char blackpal[16*3];
-
- memset(blackpal,0,16*3);
- SetPaletteHR(blackpal);
-}
-
-//==========================================================================
-//
-//
-// I_StartupReadKeys
-//
-//
-//==========================================================================
-
-void I_StartupReadKeys(void)
-{
- int k;
-
- while (kbdtail < kbdhead)
- {
- k = keyboardque[kbdtail&(KBDQUESIZE-1)];
- kbdtail++;
- if (k == 1)
- I_Quit ();
- }
-}
+// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 1993-1996 Id Software, Inc. +// Copyright(C) 1993-2008 Raven Software +// +// 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. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// +//----------------------------------------------------------------------------- + + +#include <dos.h> +#include <conio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <graph.h> +#include "h2def.h" +#include "r_local.h" +#include "p_local.h" // for P_AproxDistance +#include "sounds.h" +#include "i_sound.h" +#include "soundst.h" +#include "st_start.h" +#include "dmx.h" +#include "dpmiapi.h" + +// Macros + +#define DEFAULT_ARCHIVEPATH "o:\\sound\\archive\\" +#define PRIORITY_MAX_ADJUST 10 +#define DIST_ADJUST (MAX_SND_DIST/PRIORITY_MAX_ADJUST) + +#define DPMI_INT 0x31 + +#define SEQ_ADDR 0x3C4 +#define SEQ_DATA 0x3C5 +#define REG_MAPMASK 0x02 + +#define MASK_PLANE0 0x01 +#define MASK_PLANE1 0x02 +#define MASK_PLANE2 0x04 +#define MASK_PLANE3 0x08 + +#define P0OFFSET 38400*0 +#define P1OFFSET 38400*1 +#define P2OFFSET 38400*2 +#define P3OFFSET 38400*3 + +#define VID_INT 0x10 +#define VB_SYNC {while(!(inp(0x3da)&8)); while(inp(0x3da)&8);} +#define BITPLANE(p) (outp(SEQ_ADDR,REG_MAPMASK),outp(SEQ_DATA,(p))) + +//#define NOKBD +//#define NOTIMER + +// Public Data + +int DisplayTicker = 0; + +// Code + +void main(int argc, char **argv) +{ + myargc = argc; + myargv = argv; + H2_Main(); +} + +void I_StartupNet(void); +void I_ShutdownNet(void); +void I_ReadExternDriver(void); + +typedef struct +{ + unsigned edi, esi, ebp, reserved, ebx, edx, ecx, eax; + unsigned short flags, es, ds, fs, gs, ip, cs, sp, ss; +} dpmiregs_t; + +extern dpmiregs_t dpmiregs; + +void I_ReadMouse(void); + +extern int usemouse, usejoystick; + +extern void **lumpcache; + +int i_Vector; +externdata_t *i_ExternData; +boolean useexterndriver; + +boolean i_CDMusic; +int i_CDTrack; +int i_CDCurrentTrack; +int i_CDMusicLength; +int oldTic; + +/* +=============================================================================== + + MUSIC & SFX API + +=============================================================================== +*/ + +//static channel_t channel[MAX_CHANNELS]; + +//static int rs; //the current registered song. +//int mus_song = -1; +//int mus_lumpnum; +//void *mus_sndptr; +//byte *soundCurve; + +extern sfxinfo_t S_sfx[]; +extern musicinfo_t S_music[]; + +static channel_t Channel[MAX_CHANNELS]; +static int RegisteredSong; //the current registered song. +static int NextCleanup; +static boolean MusicPaused; +static int Mus_Song = -1; +static int Mus_LumpNum; +static void *Mus_SndPtr; +static byte *SoundCurve; + +static boolean UseSndScript; +static char ArchivePath[128]; + +extern int snd_MusicDevice; +extern int snd_SfxDevice; +extern int snd_MaxVolume; +extern int snd_MusicVolume; +extern int snd_Channels; + +extern int startepisode; +extern int startmap; + +// int AmbChan; + +//========================================================================== +// +// S_Start +// +//========================================================================== + +void S_Start(void) +{ + S_StopAllSound(); + S_StartSong(gamemap, true); +} + +//========================================================================== +// +// S_StartSong +// +//========================================================================== + +void S_StartSong(int song, boolean loop) +{ + char *songLump; + int track; + + if (i_CDMusic) + { // Play a CD track, instead + if (i_CDTrack) + { // Default to the player-chosen track + track = i_CDTrack; + } + else + { + track = P_GetMapCDTrack(gamemap); + } + if (track == i_CDCurrentTrack && i_CDMusicLength > 0) + { + return; + } + if (!I_CDMusPlay(track)) + { + if (loop) + { + i_CDMusicLength = 35 * I_CDMusTrackLength(track); + oldTic = gametic; + } + else + { + i_CDMusicLength = -1; + } + i_CDCurrentTrack = track; + } + } + else + { + if (song == Mus_Song) + { // don't replay an old song + return; + } + if (RegisteredSong) + { + I_StopSong(RegisteredSong); + I_UnRegisterSong(RegisteredSong); + if (UseSndScript) + { + Z_Free(Mus_SndPtr); + } + else + { + Z_ChangeTag(lumpcache[Mus_LumpNum], PU_CACHE); + } +#ifdef __WATCOMC__ + _dpmi_unlockregion(Mus_SndPtr, lumpinfo[Mus_LumpNum].size); +#endif + RegisteredSong = 0; + } + songLump = P_GetMapSongLump(song); + if (!songLump) + { + return; + } + if (UseSndScript) + { + char name[128]; + sprintf(name, "%s%s.lmp", ArchivePath, songLump); + M_ReadFile(name, (byte **) & Mus_SndPtr); + } + else + { + Mus_LumpNum = W_GetNumForName(songLump); + Mus_SndPtr = W_CacheLumpNum(Mus_LumpNum, PU_MUSIC); + } +#ifdef __WATCOMC__ + _dpmi_lockregion(Mus_SndPtr, lumpinfo[Mus_LumpNum].size); +#endif + RegisteredSong = I_RegisterSong(Mus_SndPtr); + I_PlaySong(RegisteredSong, loop); // 'true' denotes endless looping. + Mus_Song = song; + } +} + +//========================================================================== +// +// S_StartSongName +// +//========================================================================== + +void S_StartSongName(char *songLump, boolean loop) +{ + int cdTrack; + + if (!songLump) + { + return; + } + if (i_CDMusic) + { + cdTrack = 0; + + if (!strcmp(songLump, "hexen")) + { + cdTrack = P_GetCDTitleTrack(); + } + else if (!strcmp(songLump, "hub")) + { + cdTrack = P_GetCDIntermissionTrack(); + } + else if (!strcmp(songLump, "hall")) + { + cdTrack = P_GetCDEnd1Track(); + } + else if (!strcmp(songLump, "orb")) + { + cdTrack = P_GetCDEnd2Track(); + } + else if (!strcmp(songLump, "chess") && !i_CDTrack) + { + cdTrack = P_GetCDEnd3Track(); + } +/* Uncomment this, if Kevin writes a specific song for startup + else if(!strcmp(songLump, "start")) + { + cdTrack = P_GetCDStartTrack(); + } +*/ + if (!cdTrack || (cdTrack == i_CDCurrentTrack && i_CDMusicLength > 0)) + { + return; + } + if (!I_CDMusPlay(cdTrack)) + { + if (loop) + { + i_CDMusicLength = 35 * I_CDMusTrackLength(cdTrack); + oldTic = gametic; + } + else + { + i_CDMusicLength = -1; + } + i_CDCurrentTrack = cdTrack; + i_CDTrack = false; + } + } + else + { + if (RegisteredSong) + { + I_StopSong(RegisteredSong); + I_UnRegisterSong(RegisteredSong); + if (UseSndScript) + { + Z_Free(Mus_SndPtr); + } + else + { + Z_ChangeTag(lumpcache[Mus_LumpNum], PU_CACHE); + } +#ifdef __WATCOMC__ + _dpmi_unlockregion(Mus_SndPtr, lumpinfo[Mus_LumpNum].size); +#endif + RegisteredSong = 0; + } + if (UseSndScript) + { + char name[128]; + sprintf(name, "%s%s.lmp", ArchivePath, songLump); + M_ReadFile(name, (byte **) & Mus_SndPtr); + } + else + { + Mus_LumpNum = W_GetNumForName(songLump); + Mus_SndPtr = W_CacheLumpNum(Mus_LumpNum, PU_MUSIC); + } +#ifdef __WATCOMC__ + _dpmi_lockregion(Mus_SndPtr, lumpinfo[Mus_LumpNum].size); +#endif + RegisteredSong = I_RegisterSong(Mus_SndPtr); + I_PlaySong(RegisteredSong, loop); // 'true' denotes endless looping. + Mus_Song = -1; + } +} + +//========================================================================== +// +// S_GetSoundID +// +//========================================================================== + +int S_GetSoundID(char *name) +{ + int i; + + for (i = 0; i < NUMSFX; i++) + { + if (!strcmp(S_sfx[i].tagName, name)) + { + return i; + } + } + return 0; +} + +//========================================================================== +// +// S_StartSound +// +//========================================================================== + +void S_StartSound(mobj_t * origin, int sound_id) +{ + S_StartSoundAtVolume(origin, sound_id, 127); +} + +//========================================================================== +// +// S_StartSoundAtVolume +// +//========================================================================== + +void S_StartSoundAtVolume(mobj_t * origin, int sound_id, int volume) +{ + int dist, vol; + int i; + int priority; + int sep; + int angle; + int absx; + int absy; + + static int sndcount = 0; + int chan; + + if (sound_id == 0 || snd_MaxVolume == 0) + return; + if (origin == NULL) + { + origin = players[displayplayer].mo; + } + if (volume == 0) + { + return; + } + + // calculate the distance before other stuff so that we can throw out + // sounds that are beyond the hearing range. + absx = abs(origin->x - players[displayplayer].mo->x); + absy = abs(origin->y - players[displayplayer].mo->y); + dist = absx + absy - (absx > absy ? absy >> 1 : absx >> 1); + dist >>= FRACBITS; + if (dist >= MAX_SND_DIST) + { + return; // sound is beyond the hearing range... + } + if (dist < 0) + { + dist = 0; + } + priority = S_sfx[sound_id].priority; + priority *= (PRIORITY_MAX_ADJUST - (dist / DIST_ADJUST)); + if (!S_StopSoundID(sound_id, priority)) + { + return; // other sounds have greater priority + } + for (i = 0; i < snd_Channels; i++) + { + if (origin->player) + { + i = snd_Channels; + break; // let the player have more than one sound. + } + if (origin == Channel[i].mo) + { // only allow other mobjs one sound + S_StopSound(Channel[i].mo); + break; + } + } + if (i >= snd_Channels) + { + for (i = 0; i < snd_Channels; i++) + { + if (Channel[i].mo == NULL) + { + break; + } + } + if (i >= snd_Channels) + { + // look for a lower priority sound to replace. + sndcount++; + if (sndcount >= snd_Channels) + { + sndcount = 0; + } + for (chan = 0; chan < snd_Channels; chan++) + { + i = (sndcount + chan) % snd_Channels; + if (priority >= Channel[i].priority) + { + chan = -1; //denote that sound should be replaced. + break; + } + } + if (chan != -1) + { + return; //no free channels. + } + else //replace the lower priority sound. + { + if (Channel[i].handle) + { + if (I_SoundIsPlaying(Channel[i].handle)) + { + I_StopSound(Channel[i].handle); + } + if (S_sfx[Channel[i].sound_id].usefulness > 0) + { + S_sfx[Channel[i].sound_id].usefulness--; + } + } + } + } + } + if (S_sfx[sound_id].lumpnum == 0) + { + S_sfx[sound_id].lumpnum = I_GetSfxLumpNum(&S_sfx[sound_id]); + } + if (S_sfx[sound_id].snd_ptr == NULL) + { + if (UseSndScript) + { + char name[128]; + sprintf(name, "%s%s.lmp", ArchivePath, S_sfx[sound_id].lumpname); + M_ReadFile(name, (byte **) & S_sfx[sound_id].snd_ptr); + } + else + { + S_sfx[sound_id].snd_ptr = W_CacheLumpNum(S_sfx[sound_id].lumpnum, + PU_SOUND); + } +#ifdef __WATCOMC__ + _dpmi_lockregion(S_sfx[sound_id].snd_ptr, + lumpinfo[S_sfx[sound_id].lumpnum].size); +#endif + } + + vol = (SoundCurve[dist] * (snd_MaxVolume * 8) * volume) >> 14; + if (origin == players[displayplayer].mo) + { + sep = 128; +// vol = (volume*(snd_MaxVolume+1)*8)>>7; + } + else + { + angle = R_PointToAngle2(players[displayplayer].mo->x, + players[displayplayer].mo->y, + Channel[i].mo->x, Channel[i].mo->y); + angle = (angle - viewangle) >> 24; + sep = angle * 2 - 128; + if (sep < 64) + sep = -sep; + if (sep > 192) + sep = 512 - sep; +// vol = SoundCurve[dist]; + } + + if (S_sfx[sound_id].changePitch) + { + Channel[i].pitch = (byte) (127 + (M_Random() & 7) - (M_Random() & 7)); + } + else + { + Channel[i].pitch = 127; + } + Channel[i].handle = I_StartSound(sound_id, S_sfx[sound_id].snd_ptr, vol, + sep, Channel[i].pitch, 0); + Channel[i].mo = origin; + Channel[i].sound_id = sound_id; + Channel[i].priority = priority; + Channel[i].volume = volume; + if (S_sfx[sound_id].usefulness < 0) + { + S_sfx[sound_id].usefulness = 1; + } + else + { + S_sfx[sound_id].usefulness++; + } +} + +//========================================================================== +// +// S_StopSoundID +// +//========================================================================== + +boolean S_StopSoundID(int sound_id, int priority) +{ + int i; + int lp; //least priority + int found; + + if (S_sfx[sound_id].numchannels == -1) + { + return (true); + } + lp = -1; //denote the argument sound_id + found = 0; + for (i = 0; i < snd_Channels; i++) + { + if (Channel[i].sound_id == sound_id && Channel[i].mo) + { + found++; //found one. Now, should we replace it?? + if (priority >= Channel[i].priority) + { // if we're gonna kill one, then this'll be it + lp = i; + priority = Channel[i].priority; + } + } + } + if (found < S_sfx[sound_id].numchannels) + { + return (true); + } + else if (lp == -1) + { + return (false); // don't replace any sounds + } + if (Channel[lp].handle) + { + if (I_SoundIsPlaying(Channel[lp].handle)) + { + I_StopSound(Channel[lp].handle); + } + if (S_sfx[Channel[lp].sound_id].usefulness > 0) + { + S_sfx[Channel[lp].sound_id].usefulness--; + } + Channel[lp].mo = NULL; + } + return (true); +} + +//========================================================================== +// +// S_StopSound +// +//========================================================================== + +void S_StopSound(mobj_t * origin) +{ + int i; + + for (i = 0; i < snd_Channels; i++) + { + if (Channel[i].mo == origin) + { + I_StopSound(Channel[i].handle); + if (S_sfx[Channel[i].sound_id].usefulness > 0) + { + S_sfx[Channel[i].sound_id].usefulness--; + } + Channel[i].handle = 0; + Channel[i].mo = NULL; + } + } +} + +//========================================================================== +// +// S_StopAllSound +// +//========================================================================== + +void S_StopAllSound(void) +{ + int i; + + //stop all sounds + for (i = 0; i < snd_Channels; i++) + { + if (Channel[i].handle) + { + S_StopSound(Channel[i].mo); + } + } + memset(Channel, 0, 8 * sizeof(channel_t)); +} + +//========================================================================== +// +// S_SoundLink +// +//========================================================================== + +void S_SoundLink(mobj_t * oldactor, mobj_t * newactor) +{ + int i; + + for (i = 0; i < snd_Channels; i++) + { + if (Channel[i].mo == oldactor) + Channel[i].mo = newactor; + } +} + +//========================================================================== +// +// S_PauseSound +// +//========================================================================== + +void S_PauseSound(void) +{ + if (i_CDMusic) + { + I_CDMusStop(); + } + else + { + I_PauseSong(RegisteredSong); + } +} + +//========================================================================== +// +// S_ResumeSound +// +//========================================================================== + +void S_ResumeSound(void) +{ + if (i_CDMusic) + { + I_CDMusResume(); + } + else + { + I_ResumeSong(RegisteredSong); + } +} + +//========================================================================== +// +// S_UpdateSounds +// +//========================================================================== + +void S_UpdateSounds(mobj_t * listener) +{ + int i, dist, vol; + int angle; + int sep; + int priority; + int absx; + int absy; + + if (i_CDMusic) + { + I_UpdateCDMusic(); + } + if (snd_MaxVolume == 0) + { + return; + } + + // Update any Sequences + SN_UpdateActiveSequences(); + + if (NextCleanup < gametic) + { + if (UseSndScript) + { + for (i = 0; i < NUMSFX; i++) + { + if (S_sfx[i].usefulness == 0 && S_sfx[i].snd_ptr) + { + S_sfx[i].usefulness = -1; + } + } + } + else + { + for (i = 0; i < NUMSFX; i++) + { + if (S_sfx[i].usefulness == 0 && S_sfx[i].snd_ptr) + { + if (lumpcache[S_sfx[i].lumpnum]) + { + if (((memblock_t *) ((byte *) + (lumpcache[S_sfx[i].lumpnum]) - + sizeof(memblock_t)))->id == + 0x1d4a11) + { // taken directly from the Z_ChangeTag macro + Z_ChangeTag2(lumpcache[S_sfx[i].lumpnum], + PU_CACHE); +#ifdef __WATCOMC__ + _dpmi_unlockregion(S_sfx[i].snd_ptr, + lumpinfo[S_sfx[i].lumpnum]. + size); +#endif + } + } + S_sfx[i].usefulness = -1; + S_sfx[i].snd_ptr = NULL; + } + } + } + NextCleanup = gametic + 35 * 30; // every 30 seconds + } + for (i = 0; i < snd_Channels; i++) + { + if (!Channel[i].handle || S_sfx[Channel[i].sound_id].usefulness == -1) + { + continue; + } + if (!I_SoundIsPlaying(Channel[i].handle)) + { + if (S_sfx[Channel[i].sound_id].usefulness > 0) + { + S_sfx[Channel[i].sound_id].usefulness--; + } + Channel[i].handle = 0; + Channel[i].mo = NULL; + Channel[i].sound_id = 0; + } + if (Channel[i].mo == NULL || Channel[i].sound_id == 0 + || Channel[i].mo == listener) + { + continue; + } + else + { + absx = abs(Channel[i].mo->x - listener->x); + absy = abs(Channel[i].mo->y - listener->y); + dist = absx + absy - (absx > absy ? absy >> 1 : absx >> 1); + dist >>= FRACBITS; + + if (dist >= MAX_SND_DIST) + { + S_StopSound(Channel[i].mo); + continue; + } + if (dist < 0) + { + dist = 0; + } + //vol = SoundCurve[dist]; + vol = + (SoundCurve[dist] * (snd_MaxVolume * 8) * + Channel[i].volume) >> 14; + if (Channel[i].mo == listener) + { + sep = 128; + } + else + { + angle = R_PointToAngle2(listener->x, listener->y, + Channel[i].mo->x, Channel[i].mo->y); + angle = (angle - viewangle) >> 24; + sep = angle * 2 - 128; + if (sep < 64) + sep = -sep; + if (sep > 192) + sep = 512 - sep; + } + I_UpdateSoundParams(Channel[i].handle, vol, sep, + Channel[i].pitch); + priority = S_sfx[Channel[i].sound_id].priority; + priority *= PRIORITY_MAX_ADJUST - (dist / DIST_ADJUST); + Channel[i].priority = priority; + } + } +} + +//========================================================================== +// +// S_Init +// +//========================================================================== + +void S_Init(void) +{ + SoundCurve = W_CacheLumpName("SNDCURVE", PU_STATIC); +// SoundCurve = Z_Malloc(MAX_SND_DIST, PU_STATIC, NULL); + I_StartupSound(); + if (snd_Channels > 8) + { + snd_Channels = 8; + } + I_SetChannels(snd_Channels); + I_SetMusicVolume(snd_MusicVolume); + + // Attempt to setup CD music + if (snd_MusicDevice == snd_CDMUSIC) + { + ST_Message(" Attempting to initialize CD Music: "); + if (!cdrom) + { + i_CDMusic = (I_CDMusInit() != -1); + } + else + { // The user is trying to use the cdrom for both game and music + i_CDMusic = false; + } + if (i_CDMusic) + { + ST_Message("initialized.\n"); + } + else + { + ST_Message("failed.\n"); + } + } +} + +//========================================================================== +// +// S_GetChannelInfo +// +//========================================================================== + +void S_GetChannelInfo(SoundInfo_t * s) +{ + int i; + ChanInfo_t *c; + + s->channelCount = snd_Channels; + s->musicVolume = snd_MusicVolume; + s->soundVolume = snd_MaxVolume; + for (i = 0; i < snd_Channels; i++) + { + c = &s->chan[i]; + c->id = Channel[i].sound_id; + c->priority = Channel[i].priority; + c->name = S_sfx[c->id].lumpname; + c->mo = Channel[i].mo; + c->distance = P_AproxDistance(c->mo->x - viewx, c->mo->y - viewy) + >> FRACBITS; + } +} + +//========================================================================== +// +// S_GetSoundPlayingInfo +// +//========================================================================== + +boolean S_GetSoundPlayingInfo(mobj_t * mobj, int sound_id) +{ + int i; + + for (i = 0; i < snd_Channels; i++) + { + if (Channel[i].sound_id == sound_id && Channel[i].mo == mobj) + { + if (I_SoundIsPlaying(Channel[i].handle)) + { + return true; + } + } + } + return false; +} + +//========================================================================== +// +// S_SetMusicVolume +// +//========================================================================== + +void S_SetMusicVolume(void) +{ + if (i_CDMusic) + { + I_CDMusSetVolume(snd_MusicVolume * 16); // 0-255 + } + else + { + I_SetMusicVolume(snd_MusicVolume); + } + if (snd_MusicVolume == 0) + { + if (!i_CDMusic) + { + I_PauseSong(RegisteredSong); + } + MusicPaused = true; + } + else if (MusicPaused) + { + if (!i_CDMusic) + { + I_ResumeSong(RegisteredSong); + } + MusicPaused = false; + } +} + +//========================================================================== +// +// S_ShutDown +// +//========================================================================== + +void S_ShutDown(void) +{ + extern int tsm_ID; + if (tsm_ID != -1) + { + I_StopSong(RegisteredSong); + I_UnRegisterSong(RegisteredSong); + I_ShutdownSound(); + } + if (i_CDMusic) + { + I_CDMusStop(); + } +} + +//========================================================================== +// +// S_InitScript +// +//========================================================================== + +void S_InitScript(void) +{ + int p; + int i; + + strcpy(ArchivePath, DEFAULT_ARCHIVEPATH); + if (!(p = M_CheckParm("-devsnd"))) + { + UseSndScript = false; + SC_OpenLump("sndinfo"); + } + else + { + UseSndScript = true; + SC_OpenFile(myargv[p + 1]); + } + while (SC_GetString()) + { + if (*sc_String == '$') + { + if (!stricmp(sc_String, "$ARCHIVEPATH")) + { + SC_MustGetString(); + strcpy(ArchivePath, sc_String); + } + else if (!stricmp(sc_String, "$MAP")) + { + SC_MustGetNumber(); + SC_MustGetString(); + if (sc_Number) + { + P_PutMapSongLump(sc_Number, sc_String); + } + } + continue; + } + else + { + for (i = 0; i < NUMSFX; i++) + { + if (!strcmp(S_sfx[i].tagName, sc_String)) + { + SC_MustGetString(); + if (*sc_String != '?') + { + strcpy(S_sfx[i].lumpname, sc_String); + } + else + { + strcpy(S_sfx[i].lumpname, "default"); + } + break; + } + } + if (i == NUMSFX) + { + SC_MustGetString(); + } + } + } + SC_Close(); + + for (i = 0; i < NUMSFX; i++) + { + if (!strcmp(S_sfx[i].lumpname, "")) + { + strcpy(S_sfx[i].lumpname, "default"); + } + } +} + +//========================================================================== +// +// I_UpdateCDMusic +// +// Updates playing time for current track, and restarts the track, if +// needed +// +//========================================================================== + +void I_UpdateCDMusic(void) +{ + extern boolean MenuActive; + + if (MusicPaused || i_CDMusicLength < 0 || (paused && !MenuActive)) + { // Non-looping song/song paused + return; + } + i_CDMusicLength -= gametic - oldTic; + oldTic = gametic; + if (i_CDMusicLength <= 0) + { + S_StartSong(gamemap, true); + } +} + +/* +============================================================================ + + CONSTANTS + +============================================================================ +*/ + +#define SC_INDEX 0x3C4 +#define SC_RESET 0 +#define SC_CLOCK 1 +#define SC_MAPMASK 2 +#define SC_CHARMAP 3 +#define SC_MEMMODE 4 + +#define CRTC_INDEX 0x3D4 +#define CRTC_H_TOTAL 0 +#define CRTC_H_DISPEND 1 +#define CRTC_H_BLANK 2 +#define CRTC_H_ENDBLANK 3 +#define CRTC_H_RETRACE 4 +#define CRTC_H_ENDRETRACE 5 +#define CRTC_V_TOTAL 6 +#define CRTC_OVERFLOW 7 +#define CRTC_ROWSCAN 8 +#define CRTC_MAXSCANLINE 9 +#define CRTC_CURSORSTART 10 +#define CRTC_CURSOREND 11 +#define CRTC_STARTHIGH 12 +#define CRTC_STARTLOW 13 +#define CRTC_CURSORHIGH 14 +#define CRTC_CURSORLOW 15 +#define CRTC_V_RETRACE 16 +#define CRTC_V_ENDRETRACE 17 +#define CRTC_V_DISPEND 18 +#define CRTC_OFFSET 19 +#define CRTC_UNDERLINE 20 +#define CRTC_V_BLANK 21 +#define CRTC_V_ENDBLANK 22 +#define CRTC_MODE 23 +#define CRTC_LINECOMPARE 24 + + +#define GC_INDEX 0x3CE +#define GC_SETRESET 0 +#define GC_ENABLESETRESET 1 +#define GC_COLORCOMPARE 2 +#define GC_DATAROTATE 3 +#define GC_READMAP 4 +#define GC_MODE 5 +#define GC_MISCELLANEOUS 6 +#define GC_COLORDONTCARE 7 +#define GC_BITMASK 8 + +#define ATR_INDEX 0x3c0 +#define ATR_MODE 16 +#define ATR_OVERSCAN 17 +#define ATR_COLORPLANEENABLE 18 +#define ATR_PELPAN 19 +#define ATR_COLORSELECT 20 + +#define STATUS_REGISTER_1 0x3da + +#define PEL_WRITE_ADR 0x3c8 +#define PEL_READ_ADR 0x3c7 +#define PEL_DATA 0x3c9 +#define PEL_MASK 0x3c6 + +// boolean grmode; + +//================================================== +// +// joystick vars +// +//================================================== + +boolean joystickpresent; +extern unsigned joystickx, joysticky; +boolean I_ReadJoystick(void); // returns false if not connected + + +//================================================== + +#define VBLCOUNTER 34000 // hardware tics to a frame + + +#define TIMERINT 8 +#define KEYBOARDINT 9 + +#define CRTCOFF (_inbyte(STATUS_REGISTER_1)&1) +#define CLI _disable() +#define STI _enable() + +#define _outbyte(x,y) (outp(x,y)) +#define _outhword(x,y) (outpw(x,y)) + +#define _inbyte(x) (inp(x)) +#define _inhword(x) (inpw(x)) + +#define MOUSEB1 1 +#define MOUSEB2 2 +#define MOUSEB3 4 + +boolean mousepresent; +//static int tsm_ID = -1; // tsm init flag + +//=============================== + +int ticcount; + +// REGS stuff used for int calls +union REGS regs; +struct SREGS segregs; + +boolean novideo; // if true, stay in text mode for debugging + +#define KBDQUESIZE 32 +byte keyboardque[KBDQUESIZE]; +int kbdtail, kbdhead; + +#define KEY_LSHIFT 0xfe + +#define KEY_INS (0x80+0x52) +#define KEY_DEL (0x80+0x53) +#define KEY_PGUP (0x80+0x49) +#define KEY_PGDN (0x80+0x51) +#define KEY_HOME (0x80+0x47) +#define KEY_END (0x80+0x4f) + +#define SC_RSHIFT 0x36 +#define SC_LSHIFT 0x2a + +byte scantokey[128] = { +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F + 0, 27, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', KEY_BACKSPACE, 9, // 0 + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', 13, KEY_RCTRL, 'a', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + 39, '`', KEY_LSHIFT, 92, 'z', 'x', 'c', 'v', // 2 + 'b', 'n', 'm', ',', '.', '/', KEY_RSHIFT, '*', + KEY_RALT, ' ', 0, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, // 3 + KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, 0, 0, KEY_HOME, + KEY_UPARROW, KEY_PGUP, '-', KEY_LEFTARROW, '5', KEY_RIGHTARROW, '+', KEY_END, //4 + KEY_DOWNARROW, KEY_PGDN, KEY_INS, KEY_DEL, 0, 0, 0, KEY_F11, + KEY_F12, 0, 0, 0, 0, 0, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 // 7 +}; + +//========================================================================== + +//-------------------------------------------------------------------------- +// +// FUNC I_GetTime +// +// Returns time in 1/35th second tics. +// +//-------------------------------------------------------------------------- + +int I_GetTime(void) +{ +#ifdef NOTIMER + ticcount++; +#endif + return (ticcount); +} + +//-------------------------------------------------------------------------- +// +// PROC I_ColorBorder +// +//-------------------------------------------------------------------------- + +/* +void I_ColorBorder(void) +{ + int i; + + I_WaitVBL(1); + _outbyte(PEL_WRITE_ADR, 0); + for(i = 0; i < 3; i++) + { + _outbyte(PEL_DATA, 63); + } +} +*/ + +//-------------------------------------------------------------------------- +// +// PROC I_UnColorBorder +// +//-------------------------------------------------------------------------- + +/* +void I_UnColorBorder(void) +{ + int i; + + I_WaitVBL(1); + _outbyte(PEL_WRITE_ADR, 0); + for(i = 0; i < 3; i++) + { + _outbyte(PEL_DATA, 0); + } +} +*/ + +/* +============================================================================ + + USER INPUT + +============================================================================ +*/ + +//-------------------------------------------------------------------------- +// +// PROC I_WaitVBL +// +//-------------------------------------------------------------------------- + +void I_WaitVBL(int vbls) +{ + int stat; + + if (novideo) + { + return; + } + while (vbls--) + { + do + { + stat = inp(STATUS_REGISTER_1); + if (stat & 8) + { + break; + } + } + while (1); + do + { + stat = inp(STATUS_REGISTER_1); + if ((stat & 8) == 0) + { + break; + } + } + while (1); + } +} + +//-------------------------------------------------------------------------- +// +// PROC I_SetPalette +// +// Palette source must use 8 bit RGB elements. +// +//-------------------------------------------------------------------------- + +void I_SetPalette(byte * palette) +{ + int i; + + if (novideo) + { + return; + } + I_WaitVBL(1); + _outbyte(PEL_WRITE_ADR, 0); + for (i = 0; i < 768; i++) + { + _outbyte(PEL_DATA, (gammatable[usegamma][*palette++]) >> 2); + } +} + +/* +============================================================================ + + GRAPHICS MODE + +============================================================================ +*/ + +byte *pcscreen, *destscreen, *destview; + + +/* +============== += += I_Update += +============== +*/ + +int UpdateState; +extern int screenblocks; + +void I_Update(void) +{ + int i; + byte *dest; + int tics; + static int lasttic; + +// +// blit screen to video +// + if (DisplayTicker) + { + if (screenblocks > 9 || UpdateState & (I_FULLSCRN | I_MESSAGES)) + { + dest = (byte *) screen; + } + else + { + dest = (byte *) pcscreen; + } + tics = ticcount - lasttic; + lasttic = ticcount; + if (tics > 20) + { + tics = 20; + } + for (i = 0; i < tics; i++) + { + *dest = 0xff; + dest += 2; + } + for (i = tics; i < 20; i++) + { + *dest = 0x00; + dest += 2; + } + } + + //memset(pcscreen, 255, SCREENHEIGHT*SCREENWIDTH); + + if (UpdateState == I_NOUPDATE) + { + return; + } + if (UpdateState & I_FULLSCRN) + { + memcpy(pcscreen, screen, SCREENWIDTH * SCREENHEIGHT); + UpdateState = I_NOUPDATE; // clear out all draw types + } + if (UpdateState & I_FULLVIEW) + { + if (UpdateState & I_MESSAGES && screenblocks > 7) + { + for (i = 0; i < + (viewwindowy + viewheight) * SCREENWIDTH; i += SCREENWIDTH) + { + memcpy(pcscreen + i, screen + i, SCREENWIDTH); + } + UpdateState &= ~(I_FULLVIEW | I_MESSAGES); + } + else + { + for (i = viewwindowy * SCREENWIDTH + viewwindowx; i < + (viewwindowy + viewheight) * SCREENWIDTH; i += SCREENWIDTH) + { + memcpy(pcscreen + i, screen + i, viewwidth); + } + UpdateState &= ~I_FULLVIEW; + } + } + if (UpdateState & I_STATBAR) + { + memcpy(pcscreen + SCREENWIDTH * (SCREENHEIGHT - SBARHEIGHT), + screen + SCREENWIDTH * (SCREENHEIGHT - SBARHEIGHT), + SCREENWIDTH * SBARHEIGHT); + UpdateState &= ~I_STATBAR; + } + if (UpdateState & I_MESSAGES) + { + memcpy(pcscreen, screen, SCREENWIDTH * 28); + UpdateState &= ~I_MESSAGES; + } + + +// memcpy(pcscreen, screen, SCREENHEIGHT*SCREENWIDTH); +} + +//-------------------------------------------------------------------------- +// +// PROC I_InitGraphics +// +//-------------------------------------------------------------------------- + +void I_InitGraphics(void) +{ + if (novideo) + { + return; + } + //grmode = true; + regs.w.ax = 0x13; + int386(0x10, (const union REGS *) ®s, ®s); + pcscreen = destscreen = (byte *) 0xa0000; + I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE)); +} + +//-------------------------------------------------------------------------- +// +// PROC I_ShutdownGraphics +// +//-------------------------------------------------------------------------- + +void I_ShutdownGraphics(void) +{ + byte mode; + + // don't reset mode if it didn't get set + mode = *(byte *) 0x449; + if (mode == 0x12 || mode == 0x13) + { + regs.w.ax = 3; + int386(0x10, ®s, ®s); // back to text mode + } +} + +//-------------------------------------------------------------------------- +// +// PROC I_ReadScreen +// +// Reads the screen currently displayed into a linear buffer. +// +//-------------------------------------------------------------------------- + +/* +void I_ReadScreen(byte *scr) +{ + memcpy(scr, screen, SCREENWIDTH*SCREENHEIGHT); +} +*/ + +//=========================================================================== + +/* +=================== += += I_StartTic += +// called by D_DoomLoop +// called before processing each tic in a frame +// can call D_PostEvent +// asyncronous interrupt functions should maintain private ques that are +// read by the syncronous functions to be converted into events +=================== +*/ + +/* + OLD STARTTIC STUFF + +void I_StartTic (void) +{ + int k; + event_t ev; + + + I_ReadMouse (); + +// +// keyboard events +// + while (kbdtail < kbdhead) + { + k = keyboardque[kbdtail&(KBDQUESIZE-1)]; + +// if (k==14) +// I_Error ("exited"); + + kbdtail++; + + // extended keyboard shift key bullshit + if ( (k&0x7f)==KEY_RSHIFT ) + { + if ( keyboardque[(kbdtail-2)&(KBDQUESIZE-1)]==0xe0 ) + continue; + k &= 0x80; + k |= KEY_RSHIFT; + } + + if (k==0xe0) + continue; // special / pause keys + if (keyboardque[(kbdtail-2)&(KBDQUESIZE-1)] == 0xe1) + continue; // pause key bullshit + + if (k==0xc5 && keyboardque[(kbdtail-2)&(KBDQUESIZE-1)] == 0x9d) + { + ev.type = ev_keydown; + ev.data1 = KEY_PAUSE; + D_PostEvent (&ev); + continue; + } + + if (k&0x80) + ev.type = ev_keyup; + else + ev.type = ev_keydown; + k &= 0x7f; + + ev.data1 = k; + //ev.data1 = scantokey[k]; + + D_PostEvent (&ev); + } +} +*/ + +#define SC_UPARROW 0x48 +#define SC_DOWNARROW 0x50 +#define SC_LEFTARROW 0x4b +#define SC_RIGHTARROW 0x4d + +void I_StartTic(void) +{ + int k; + event_t ev; + + + I_ReadMouse(); + +// +// keyboard events +// + while (kbdtail < kbdhead) + { + k = keyboardque[kbdtail & (KBDQUESIZE - 1)]; + kbdtail++; + + // extended keyboard shift key bullshit + if ((k & 0x7f) == SC_LSHIFT || (k & 0x7f) == SC_RSHIFT) + { + if (keyboardque[(kbdtail - 2) & (KBDQUESIZE - 1)] == 0xe0) + continue; + k &= 0x80; + k |= SC_RSHIFT; + } + + if (k == 0xe0) + continue; // special / pause keys + if (keyboardque[(kbdtail - 2) & (KBDQUESIZE - 1)] == 0xe1) + continue; // pause key bullshit + + if (k == 0xc5 + && keyboardque[(kbdtail - 2) & (KBDQUESIZE - 1)] == 0x9d) + { + ev.type = ev_keydown; + ev.data1 = KEY_PAUSE; + H2_PostEvent(&ev); + continue; + } + + if (k & 0x80) + ev.type = ev_keyup; + else + ev.type = ev_keydown; + k &= 0x7f; + switch (k) + { + case SC_UPARROW: + ev.data1 = KEY_UPARROW; + break; + case SC_DOWNARROW: + ev.data1 = KEY_DOWNARROW; + break; + case SC_LEFTARROW: + ev.data1 = KEY_LEFTARROW; + break; + case SC_RIGHTARROW: + ev.data1 = KEY_RIGHTARROW; + break; + default: + ev.data1 = scantokey[k]; + break; + } + H2_PostEvent(&ev); + } + +} + + +/* +void I_ReadKeys (void) +{ + int k; + + + while (1) + { + while (kbdtail < kbdhead) + { + k = keyboardque[kbdtail&(KBDQUESIZE-1)]; + kbdtail++; + printf ("0x%x\n",k); + if (k == 1) + I_Quit (); + } + } +} +*/ + +/* +=============== += += I_StartFrame += +=============== +*/ + +void I_StartFrame(void) +{ + I_JoystickEvents(); + if (useexterndriver) + { + DPMIInt(i_Vector); + } +} + +/* +============================================================================ + + TIMER INTERRUPT + +============================================================================ +*/ + +/* +void I_ColorBlack (int r, int g, int b) +{ +_outbyte (PEL_WRITE_ADR,0); +_outbyte(PEL_DATA,r); +_outbyte(PEL_DATA,g); +_outbyte(PEL_DATA,b); +} +*/ + + +/* +================ += += I_TimerISR += +================ +*/ + +int I_TimerISR(void) +{ + ticcount++; + return 0; +} + +/* +============================================================================ + + KEYBOARD + +============================================================================ +*/ + +void (__interrupt __far * oldkeyboardisr) () = NULL; + +int lastpress; + +/* +================ += += I_KeyboardISR += +================ +*/ + +void __interrupt I_KeyboardISR(void) +{ +// Get the scan code + + keyboardque[kbdhead & (KBDQUESIZE - 1)] = lastpress = _inbyte(0x60); + kbdhead++; + +// acknowledge the interrupt + + _outbyte(0x20, 0x20); +} + + + +/* +=============== += += I_StartupKeyboard += +=============== +*/ + +void I_StartupKeyboard(void) +{ +#ifndef NOKBD + oldkeyboardisr = _dos_getvect(KEYBOARDINT); + _dos_setvect(0x8000 | KEYBOARDINT, I_KeyboardISR); +#endif + +//I_ReadKeys (); +} + + +void I_ShutdownKeyboard(void) +{ + if (oldkeyboardisr) + _dos_setvect(KEYBOARDINT, oldkeyboardisr); + *(short *) 0x41c = *(short *) 0x41a; // clear bios key buffer +} + + + +/* +============================================================================ + + MOUSE + +============================================================================ +*/ + + +int I_ResetMouse(void) +{ + regs.w.ax = 0; // reset + int386(0x33, ®s, ®s); + return regs.w.ax; +} + + + +/* +================ += += StartupMouse += +================ +*/ + +void I_StartupCyberMan(void); + +void I_StartupMouse(void) +{ + // + // General mouse detection + // + mousepresent = 0; + if (M_CheckParm("-nomouse") || !usemouse) + return; + + if (I_ResetMouse() != 0xffff) + { + ST_Message("Mouse: not present\n"); + return; + } + ST_Message("Mouse: detected\n"); + + mousepresent = 1; + + I_StartupCyberMan(); +} + + +/* +================ += += ShutdownMouse += +================ +*/ + +void I_ShutdownMouse(void) +{ + if (!mousepresent) + return; + + I_ResetMouse(); +} + + +/* +================ += += I_ReadMouse += +================ +*/ + +void I_ReadMouse(void) +{ + event_t ev; + +// +// mouse events +// + if (!mousepresent) + return; + + ev.type = ev_mouse; + + memset(&dpmiregs, 0, sizeof(dpmiregs)); + dpmiregs.eax = 3; // read buttons / position + DPMIInt(0x33); + ev.data1 = dpmiregs.ebx; + + dpmiregs.eax = 11; // read counters + DPMIInt(0x33); + ev.data2 = (short) dpmiregs.ecx; + ev.data3 = -(short) dpmiregs.edx; + + H2_PostEvent(&ev); +} + +/* +============================================================================ + + JOYSTICK + +============================================================================ +*/ + +int joyxl, joyxh, joyyl, joyyh; + +boolean WaitJoyButton(void) +{ + int oldbuttons, buttons; + + oldbuttons = 0; + do + { + I_WaitVBL(1); + buttons = ((inp(0x201) >> 4) & 1) ^ 1; + if (buttons != oldbuttons) + { + oldbuttons = buttons; + continue; + } + + if ((lastpress & 0x7f) == 1) + { + joystickpresent = false; + return false; + } + } + while (!buttons); + + do + { + I_WaitVBL(1); + buttons = ((inp(0x201) >> 4) & 1) ^ 1; + if (buttons != oldbuttons) + { + oldbuttons = buttons; + continue; + } + + if ((lastpress & 0x7f) == 1) + { + joystickpresent = false; + return false; + } + } + while (buttons); + + return true; +} + + + +/* +=============== += += I_StartupJoystick += +=============== +*/ + +int basejoyx, basejoyy; + +void I_StartupJoystick(void) +{ + int centerx, centery; + + joystickpresent = 0; + if (M_CheckParm("-nojoy") || !usejoystick) + return; + + if (!I_ReadJoystick()) + { + joystickpresent = false; + ST_Message("joystick not found\n "); + return; + } + ST_Message("joystick found\n"); + joystickpresent = true; + + ST_RealMessage("CENTER the joystick and press button 1:"); + if (!WaitJoyButton()) + return; + I_ReadJoystick(); + centerx = joystickx; + centery = joysticky; + + ST_RealMessage + ("\nPush the joystick to the UPPER LEFT corner and press button 1:"); + if (!WaitJoyButton()) + return; + I_ReadJoystick(); + joyxl = (centerx + joystickx) / 2; + joyyl = (centerx + joysticky) / 2; + + ST_RealMessage + ("\nPush the joystick to the LOWER RIGHT corner and press button 1:"); + if (!WaitJoyButton()) + return; + I_ReadJoystick(); + joyxh = (centerx + joystickx) / 2; + joyyh = (centery + joysticky) / 2; + ST_RealMessage("\n"); +} + +/* +=============== += += I_JoystickEvents += +=============== +*/ + +void I_JoystickEvents(void) +{ + event_t ev; + +// +// joystick events +// + if (!joystickpresent) + return; + + I_ReadJoystick(); + ev.type = ev_joystick; + ev.data1 = ((inp(0x201) >> 4) & 15) ^ 15; + + if (joystickx < joyxl) + ev.data2 = -1; + else if (joystickx > joyxh) + ev.data2 = 1; + else + ev.data2 = 0; + if (joysticky < joyyl) + ev.data3 = -1; + else if (joysticky > joyyh) + ev.data3 = 1; + else + ev.data3 = 0; + + H2_PostEvent(&ev); +} + + + +/* +============================================================================ + + DPMI STUFF + +============================================================================ +*/ + +#define REALSTACKSIZE 1024 + +dpmiregs_t dpmiregs; + +unsigned realstackseg; + +void I_DivException(void); +int I_SetDivException(void); + +/* +void DPMIFarCall (void) +{ + segread (&segregs); + regs.w.ax = 0x301; + regs.w.bx = 0; + regs.w.cx = 0; + regs.x.edi = (unsigned)&dpmiregs; + segregs.es = segregs.ds; + int386x( DPMI_INT, ®s, ®s, &segregs ); +} +*/ + +void DPMIInt(int i) +{ + dpmiregs.ss = realstackseg; + dpmiregs.sp = REALSTACKSIZE - 4; + + segread(&segregs); + regs.w.ax = 0x300; + regs.w.bx = i; + regs.w.cx = 0; + regs.x.edi = (unsigned) &dpmiregs; + segregs.es = segregs.ds; + int386x(DPMI_INT, ®s, ®s, &segregs); +} + + +/* +============== += += I_StartupDPMI += +============== +*/ + +void I_StartupDPMI(void) +{ +// extern char __begtext; +// extern char ___argc; +// int n,d; + +// +// allocate a decent stack for real mode ISRs +// + realstackseg = (int) I_AllocLow(1024) >> 4; + +// +// lock the entire program down +// + +// _dpmi_lockregion (&__begtext, &___argc - &__begtext); + + +// +// catch divide by 0 exception +// +#if 0 + segread(&segregs); + regs.w.ax = 0x0203; // DPMI set processor exception handler vector + regs.w.bx = 0; // int 0 + regs.w.cx = segregs.cs; + regs.x.edx = (int) &I_DivException; + printf("%x : %x\n", regs.w.cx, regs.x.edx); + int386(DPMI_INT, ®s, ®s); +#endif + +#if 0 + n = I_SetDivException(); + printf("return: %i\n", n); + n = 100; + d = 0; + printf("100 / 0 = %i\n", n / d); + + exit(1); +#endif +} + + + +/* +============================================================================ + + TIMER INTERRUPT + +============================================================================ +*/ + +void (__interrupt __far * oldtimerisr) (); + + +/* +void IO_ColorBlack (int r, int g, int b) +{ +_outbyte (PEL_WRITE_ADR,0); +_outbyte(PEL_DATA,r); +_outbyte(PEL_DATA,g); +_outbyte(PEL_DATA,b); +} +*/ + + +/* +================ += += IO_TimerISR += +================ +*/ + +//void __interrupt IO_TimerISR (void) + +void __interrupt __far IO_TimerISR(void) +{ + ticcount++; + _outbyte(0x20, 0x20); // Ack the interrupt +} + +/* +===================== += += IO_SetTimer0 += += Sets system timer 0 to the specified speed += +===================== +*/ + +void IO_SetTimer0(int speed) +{ + if (speed > 0 && speed < 150) + I_Error("INT_SetTimer0: %i is a bad value", speed); + + _outbyte(0x43, 0x36); // Change timer 0 + _outbyte(0x40, speed); + _outbyte(0x40, speed >> 8); +} + + + +/* +=============== += += IO_StartupTimer += +=============== +*/ + +/* +void IO_StartupTimer (void) +{ + oldtimerisr = _dos_getvect(TIMERINT); + + _dos_setvect (0x8000 | TIMERINT, IO_TimerISR); + IO_SetTimer0 (VBLCOUNTER); +} +*/ + +void IO_ShutdownTimer(void) +{ + if (oldtimerisr) + { + IO_SetTimer0(0); // back to 18.4 ips + _dos_setvect(TIMERINT, oldtimerisr); + } +} + +//=========================================================================== + + +/* +=============== += += I_Init += += hook interrupts and set graphics mode += +=============== +*/ + +void I_Init(void) +{ + extern void I_StartupTimer(void); + + novideo = M_CheckParm("novideo"); + ST_Message(" I_StartupDPMI\n"); + I_StartupDPMI(); + ST_Message(" I_StartupMouse "); + I_StartupMouse(); +// tprintf("I_StartupJoystick ",1); +// I_StartupJoystick(); +// tprintf("I_StartupKeyboard ",1); +// I_StartupKeyboard(); + ST_Message(" S_Init... "); + S_Init(); + //IO_StartupTimer(); + S_Start(); +} + + +/* +=============== += += I_Shutdown += += return to default system state += +=============== +*/ + +void I_Shutdown(void) +{ + I_ShutdownGraphics(); + IO_ShutdownTimer(); + S_ShutDown(); + I_ShutdownMouse(); + I_ShutdownKeyboard(); + + IO_SetTimer0(0); +} + + +/* +================ += += I_Error += +================ +*/ + +void I_Error(char *error, ...) +{ + union REGS regs; + + va_list argptr; + + D_QuitNetGame(); + I_Shutdown(); + va_start(argptr, error); + regs.x.eax = 0x3; + int386(0x10, ®s, ®s); + vprintf(error, argptr); + va_end(argptr); + printf("\n"); + exit(1); +} + +//-------------------------------------------------------------------------- +// +// I_Quit +// +// Shuts down net game, saves defaults, prints the exit text message, +// goes to text mode, and exits. +// +//-------------------------------------------------------------------------- + +void I_Quit(void) +{ + D_QuitNetGame(); + M_SaveDefaults(); + I_Shutdown(); + +// scr = (byte *)W_CacheLumpName("ENDTEXT", PU_CACHE); +/* + memcpy((void *)0xb8000, scr, 80*25*2); + regs.w.ax = 0x0200; + regs.h.bh = 0; + regs.h.dl = 0; + regs.h.dh = 23; + int386(0x10, (const union REGS *)®s, ®s); // Set text pos + _settextposition(24, 1); +*/ + printf("\nHexen: Beyond Heretic\n"); + exit(0); +} + +/* +=============== += += I_ZoneBase += +=============== +*/ + +byte *I_ZoneBase(int *size) +{ + int meminfo[32]; + int heap; + byte *ptr; + + memset(meminfo, 0, sizeof(meminfo)); + segread(&segregs); + segregs.es = segregs.ds; + regs.w.ax = 0x500; // get memory info + regs.x.edi = (int) &meminfo; + int386x(0x31, ®s, ®s, &segregs); + + heap = meminfo[0]; + ST_Message(" DPMI memory: 0x%x, ", heap); + ST_Message("Maxzone: 0x%x\n", maxzone); + + do + { + heap -= 0x10000; // leave 64k alone + if (heap > maxzone) + heap = maxzone; + ptr = malloc(heap); + } + while (!ptr); + + ST_Message(" 0x%x allocated for zone, ", heap); + ST_Message("ZoneBase: 0x%X\n", (int) ptr); + + if (heap < 0x180000) + I_Error(" Insufficient DPMI memory!"); +#if 0 + regs.w.ax = 0x501; // allocate linear block + regs.w.bx = heap >> 16; + regs.w.cx = heap & 0xffff; + int386(0x31, ®s, ®s); + if (regs.w.cflag) + I_Error(" Couldn't allocate DPMI memory!"); + + block = (regs.w.si << 16) + regs.w.di; +#endif + + *size = heap; + return ptr; +} + +/* +============= += += I_AllocLow += +============= +*/ + +byte *I_AllocLow(int length) +{ + byte *mem; + + // DPMI call 100h allocates DOS memory + segread(&segregs); + regs.w.ax = 0x0100; // DPMI allocate DOS memory + regs.w.bx = (length + 15) / 16; + int386(DPMI_INT, ®s, ®s); +// segment = regs.w.ax; +// selector = regs.w.dx; + if (regs.w.cflag != 0) + I_Error("I_AllocLow: DOS alloc of %i failed, %i free", + length, regs.w.bx * 16); + + + mem = (void *) ((regs.x.eax & 0xFFFF) << 4); + + memset(mem, 0, length); + return mem; +} + +/* +============================================================================ + + NETWORKING + +============================================================================ +*/ + +/* // FUCKED LINES +typedef struct +{ + char priv[508]; + } doomdata_t; +*/// FUCKED LINES + +#define DOOMCOM_ID 0x12345678l + +/* // FUCKED LINES +typedef struct +{ + long id; + short intnum; // DOOM executes an int to execute commands + +// communication between DOOM and the driver + short command; // CMD_SEND or CMD_GET + short remotenode; // dest for send, set by get (-1 = no packet) + short datalength; // bytes in doomdata to be sent + +// info common to all nodes + short numnodes; // console is allways node 0 + short ticdup; // 1 = no duplication, 2-5 = dup for slow nets + short extratics; // 1 = send a backup tic in every packet + short deathmatch; // 1 = deathmatch + short savegame; // -1 = new game, 0-5 = load savegame + short episode; // 1-3 + short map; // 1-9 + short skill; // 1-5 + +// info specific to this node + short consoleplayer; + short numplayers; + short angleoffset; // 1 = left, 0 = center, -1 = right + short drone; // 1 = drone + +// packet data to be sent + doomdata_t data; + } doomcom_t; +*/// FUCKED LINES + +extern doomcom_t *doomcom; + +/* +==================== += += I_InitNetwork += +==================== +*/ + +void I_InitNetwork(void) +{ + int i; + + i = M_CheckParm("-net"); + if (!i) + { + // + // single player game + // + doomcom = malloc(sizeof(*doomcom)); + memset(doomcom, 0, sizeof(*doomcom)); + netgame = false; + doomcom->id = DOOMCOM_ID; + doomcom->numplayers = doomcom->numnodes = 1; + doomcom->deathmatch = false; + doomcom->consoleplayer = 0; + doomcom->ticdup = 1; + doomcom->extratics = 0; + return; + } + + netgame = true; + doomcom = (doomcom_t *) atoi(myargv[i + 1]); +//DEBUG + doomcom->skill = startskill; + doomcom->episode = startepisode; + doomcom->map = startmap; + doomcom->deathmatch = deathmatch; + +} + +void I_NetCmd(void) +{ + if (!netgame) + I_Error("I_NetCmd when not in netgame"); + DPMIInt(doomcom->intnum); +} + +//========================================================================= +// +// I_CheckExternDriver +// +// Checks to see if a vector, and an address for an external driver +// have been passed. +//========================================================================= + +void I_CheckExternDriver(void) +{ + int i; + + if (!(i = M_CheckParm("-externdriver"))) + { + return; + } + i_ExternData = (externdata_t *) atoi(myargv[i + 1]); + i_Vector = i_ExternData->vector; + + useexterndriver = true; +} + +//========================================================================= +//========================================================================= +// Hi-Res (mode 12) stuff +//========================================================================= +//========================================================================= + + +//========================================================================== +// +// SetVideoModeHR - Set video mode to 640x480x16 +// +//========================================================================== + + +void SetVideoModeHR(void) +{ + union REGS regs; + regs.x.eax = 0x12; + int386(VID_INT, ®s, ®s); +} + + +//========================================================================== +// +// ClearScreenHR - Clear the screen to color 0 +// +//========================================================================== + +void ClearScreenHR(void) +{ + BITPLANE(MASK_PLANE0 | MASK_PLANE1 | MASK_PLANE2 | MASK_PLANE3); + memset((char *) 0xa0000, 0, 38400); +} + + +//========================================================================== +// +// SlamHR - copy 4-plane buffer to screen +// +//========================================================================== + +void SlamHR(char *buffer) +{ + BITPLANE(MASK_PLANE0); + memcpy((char *) 0xA0000, buffer + P0OFFSET, 38400); + BITPLANE(MASK_PLANE1); + memcpy((char *) 0xA0000, buffer + P1OFFSET, 38400); + BITPLANE(MASK_PLANE2); + memcpy((char *) 0xA0000, buffer + P2OFFSET, 38400); + BITPLANE(MASK_PLANE3); + memcpy((char *) 0xA0000, buffer + P3OFFSET, 38400); +} + + +//========================================================================== +// +// SlamHR - copy 4-plane buffer to screen +// +// X and Width should be a multiple of 8 +// src should be 4 planes of block size, back to back +//========================================================================== + +void SlamBlockHR(int x, int y, int w, int h, char *src) +{ + int srcwid = w >> 3; + char *dest = ((char *) 0xA0000) + (y * (640 / 8)) + (x >> 3); + char *dst; + int i; + + VB_SYNC; + + BITPLANE(MASK_PLANE0); + dst = dest; + for (i = 0; i < h; i++) + { + memcpy(dst, src, srcwid); + dst += 640 / 8; + src += srcwid; + } + BITPLANE(MASK_PLANE1); + dst = dest; + for (i = 0; i < h; i++) + { + memcpy(dst, src, srcwid); + dst += 640 / 8; + src += srcwid; + } + BITPLANE(MASK_PLANE2); + dst = dest; + for (i = 0; i < h; i++) + { + memcpy(dst, src, srcwid); + dst += 640 / 8; + src += srcwid; + } + BITPLANE(MASK_PLANE3); + dst = dest; + for (i = 0; i < h; i++) + { + memcpy(dst, src, srcwid); + dst += 640 / 8; + src += srcwid; + } +} + +//========================================================================== +// +// InitPaletteHR +// +//========================================================================== + +void InitPaletteHR(void) +{ + int i; + union REGS regs; + + // Set palette registers to point into color registers + for (i = 0; i < 16; i++) + { + regs.x.eax = (0x10 << 8) | 0x00; + regs.x.ebx = (i << 8) | i; + int386(VID_INT, ®s, ®s); + } + +} + + +//========================================================================== +// +// SetPaletteHR - Set the HR palette +// +//========================================================================== + +void SetPaletteHR(byte * palette) +{ + int i; + VB_SYNC; + outp(PEL_WRITE_ADR, 0); + + for (i = 0; i < 16 * 3; i++) + { + outp(PEL_DATA, (*palette++)); + } +} + + +//========================================================================== +// +// GetPaletteHR - Get the HR palette +// +//========================================================================== + +void GetPaletteHR(byte * palette) +{ + int i; + outp(PEL_READ_ADR, 0); + for (i = 0; i < 16 * 3; i++) + { + *palette++ = inp(PEL_DATA); + } +} + + +//========================================================================== +// +// FadeToPaletteHR +// +//========================================================================== + +void FadeToPaletteHR(byte * palette) +{ + int i, j; + int steps = 140; // two-seconds + byte basep[16 * 3]; + byte work[16 * 3]; + int delta; + + GetPaletteHR(basep); + for (i = 0; i < steps; i++) + { + for (j = 0; j < 16 * 3; j++) + { + delta = palette[j] - basep[j]; + work[j] = basep[j] + delta * i / steps; + } + SetPaletteHR(work); + } + SetPaletteHR(palette); +} + + +//========================================================================== +// +// FadeToBlackHR - Fades the palette out to black +// +//========================================================================== + +/* +void FadeToBlackHR(void) +{ + char work[16*3]; + char base[16*3]; + int i,j,steps=70; + + GetPaletteHR(base); + for (i=0; i<steps; i++) + { + for (j=0; j<16*3; j++) + { + work[j] = base[j]-(base[j]*i/steps); + } + VB_SYNC; + SetPaletteHR(work); + } + memset(work,0,16*3); + SetPaletteHR(work); +} +*/ + +//========================================================================== +// +// BlackPaletteHR - Instantly blacks out the palette +// +//========================================================================== + +void BlackPaletteHR(void) +{ + char blackpal[16 * 3]; + + memset(blackpal, 0, 16 * 3); + SetPaletteHR(blackpal); +} + +//========================================================================== +// +// +// I_StartupReadKeys +// +// +//========================================================================== + +void I_StartupReadKeys(void) +{ + int k; + + while (kbdtail < kbdhead) + { + k = keyboardque[kbdtail & (KBDQUESIZE - 1)]; + kbdtail++; + if (k == 1) + I_Quit(); + } +} |