1 //**************************************************************************
5 //**************************************************************************
13 #include "p_local.h" // for P_AproxDistance
22 #define stricmp strcasecmp
23 #define DEFAULT_ARCHIVEPATH "o:\\sound\\archive\\"
24 #define PRIORITY_MAX_ADJUST 10
25 #define DIST_ADJUST (MAX_SND_DIST/PRIORITY_MAX_ADJUST)
27 #define KEY_LSHIFT 0xfe
29 #define KEY_INS (0x80+0x52)
30 #define KEY_DEL (0x80+0x53)
31 #define KEY_PGUP (0x80+0x49)
32 #define KEY_PGDN (0x80+0x51)
33 #define KEY_HOME (0x80+0x47)
34 #define KEY_END (0x80+0x4f)
36 extern void **lumpcache;
38 extern void I_StartupMouse(void);
39 extern void I_ShutdownGraphics(void);
42 externdata_t *i_ExternData;
43 boolean useexterndriver;
51 extern boolean cdaudio;
53 extern void I_CDMusShutdown(void);
54 extern void I_CDMusUpdate(void);
57 ===============================================================================
61 ===============================================================================
64 //static channel_t channel[MAX_CHANNELS];
66 //static int rs; //the current registered song.
72 extern sfxinfo_t S_sfx[];
73 extern musicinfo_t S_music[];
75 static channel_t Channel[MAX_CHANNELS];
76 static int RegisteredSong; //the current registered song.
77 static int NextCleanup;
78 static boolean MusicPaused;
79 static int Mus_Song = -1;
80 static int Mus_LumpNum;
81 static void *Mus_SndPtr;
82 static byte *SoundCurve;
84 static boolean UseSndScript;
85 static char ArchivePath[128];
87 extern int snd_MusicDevice;
88 extern int snd_SfxDevice;
89 extern int snd_MaxVolume;
90 extern int snd_MusicVolume;
91 extern int snd_Channels;
93 extern int startepisode;
98 boolean S_StopSoundID(int sound_id, int priority);
100 //==========================================================================
104 //==========================================================================
109 S_StartSong(gamemap, true);
112 //==========================================================================
116 //==========================================================================
118 void S_StartSong(int song, boolean loop)
124 { // Play a CD track, instead
126 { // Default to the player-chosen track
131 track = P_GetMapCDTrack(gamemap);
133 if(track == i_CDCurrentTrack && i_CDMusicLength > 0)
137 if(!I_CDMusPlay(track))
141 // i_CDMusicLength = 35*I_CDMusTrackLength(track);
146 i_CDMusicLength = -1;
149 i_CDCurrentTrack = track;
155 { // don't replay an old song
160 I_StopSong(RegisteredSong);
161 I_UnRegisterSong(RegisteredSong);
168 Z_ChangeTag(lumpcache[Mus_LumpNum], PU_CACHE);
172 songLump = P_GetMapSongLump(song);
180 sprintf(name, "%s%s.lmp", ArchivePath, songLump);
181 M_ReadFile(name, (byte **)&Mus_SndPtr);
185 Mus_LumpNum = W_GetNumForName(songLump);
186 Mus_SndPtr = W_CacheLumpNum(Mus_LumpNum, PU_MUSIC);
188 RegisteredSong = I_RegisterSong(Mus_SndPtr);
189 I_PlaySong(RegisteredSong, loop); // 'true' denotes endless looping.
194 //==========================================================================
198 //==========================================================================
200 void S_StartSongName(char *songLump, boolean loop)
212 if(!strcmp(songLump, "hexen"))
214 cdTrack = P_GetCDTitleTrack();
216 else if(!strcmp(songLump, "hub"))
218 cdTrack = P_GetCDIntermissionTrack();
220 else if(!strcmp(songLump, "hall"))
222 cdTrack = P_GetCDEnd1Track();
224 else if(!strcmp(songLump, "orb"))
226 cdTrack = P_GetCDEnd2Track();
228 else if(!strcmp(songLump, "chess") && !i_CDTrack)
230 cdTrack = P_GetCDEnd3Track();
232 /* Uncomment this, if Kevin writes a specific song for startup
233 else if(!strcmp(songLump, "start"))
235 cdTrack = P_GetCDStartTrack();
238 if(!cdTrack || (cdTrack == i_CDCurrentTrack && i_CDMusicLength > 0))
242 if(!I_CDMusPlay(cdTrack))
246 i_CDMusicLength = 35*I_CDMusTrackLength(cdTrack);
251 i_CDMusicLength = -1;
254 i_CDCurrentTrack = cdTrack;
262 I_StopSong(RegisteredSong);
263 I_UnRegisterSong(RegisteredSong);
270 Z_ChangeTag(lumpcache[Mus_LumpNum], PU_CACHE);
277 sprintf(name, "%s%s.lmp", ArchivePath, songLump);
278 M_ReadFile(name, (byte **)&Mus_SndPtr);
282 Mus_LumpNum = W_GetNumForName(songLump);
283 Mus_SndPtr = W_CacheLumpNum(Mus_LumpNum, PU_MUSIC);
285 RegisteredSong = I_RegisterSong(Mus_SndPtr);
286 I_PlaySong(RegisteredSong, loop); // 'true' denotes endless looping.
291 //==========================================================================
295 //==========================================================================
297 int S_GetSoundID(char *name)
301 for(i = 0; i < NUMSFX; i++)
303 if(!strcmp(S_sfx[i].tagName, name))
311 //==========================================================================
315 //==========================================================================
317 void S_StartSound(mobj_t *origin, int sound_id)
319 S_StartSoundAtVolume(origin, sound_id, 127);
322 //==========================================================================
324 // S_StartSoundAtVolume
326 //==========================================================================
328 void S_StartSoundAtVolume(mobj_t *origin, int sound_id, int volume)
331 int i = 0; /* jim - initialise to avoid gcc warning */
338 static int sndcount = 0;
341 //printf( "S_StartSoundAtVolume: %d\n", sound_id );
343 if(sound_id == 0 || snd_MaxVolume == 0)
347 origin = players[displayplayer].mo;
354 // How does the DOS version work without this check?
355 // players[0].mo does not get set until P_SpawnPlayer. - KR
359 // calculate the distance before other stuff so that we can throw out
360 // sounds that are beyond the hearing range.
361 absx = abs(origin->x-players[displayplayer].mo->x);
362 absy = abs(origin->y-players[displayplayer].mo->y);
363 dist = absx+absy-(absx > absy ? absy>>1 : absx>>1);
365 if(dist >= MAX_SND_DIST)
367 return; // sound is beyond the hearing range...
373 priority = S_sfx[sound_id].priority;
374 priority *= (PRIORITY_MAX_ADJUST-(dist/DIST_ADJUST));
375 if(!S_StopSoundID(sound_id, priority))
377 return; // other sounds have greater priority
379 for(i = 0; i<snd_Channels; i++)
384 break; // let the player have more than one sound.
386 if(origin == Channel[i].mo)
387 { // only allow other mobjs one sound
388 S_StopSound(Channel[i].mo);
396 priority = S_sfx[sound_id].priority;
397 if( ! S_StopSoundID( sound_id, priority ) )
399 return; // other sounds have greater priority
403 if(i >= snd_Channels)
405 for(i = 0; i < snd_Channels; i++)
407 if(Channel[i].mo == NULL)
412 if(i >= snd_Channels)
414 // look for a lower priority sound to replace.
416 if(sndcount >= snd_Channels)
420 for(chan = 0; chan < snd_Channels; chan++)
422 i = (sndcount+chan)%snd_Channels;
423 if(priority >= Channel[i].priority)
425 chan = -1; //denote that sound should be replaced.
431 return; //no free channels.
433 else //replace the lower priority sound.
435 if(Channel[i].handle)
437 if(I_SoundIsPlaying(Channel[i].handle))
439 I_StopSound(Channel[i].handle);
441 if(S_sfx[Channel[i].sound_id].usefulness > 0)
443 S_sfx[Channel[i].sound_id].usefulness--;
449 if(S_sfx[sound_id].lumpnum == 0)
451 S_sfx[sound_id].lumpnum = I_GetSfxLumpNum(&S_sfx[sound_id]);
453 if(S_sfx[sound_id].snd_ptr == NULL)
458 sprintf(name, "%s%s.lmp", ArchivePath, S_sfx[sound_id].lumpname);
459 M_ReadFile(name, (byte **)&S_sfx[sound_id].snd_ptr);
463 S_sfx[sound_id].snd_ptr = W_CacheLumpNum(S_sfx[sound_id].lumpnum,
468 vol = (SoundCurve[dist]*(snd_MaxVolume*8)*volume)>>14;
469 if(origin == players[displayplayer].mo)
472 // vol = (volume*(snd_MaxVolume+1)*8)>>7;
477 // KR - Channel[i].mo = 0 here!
478 if( Channel[i].mo == NULL )
481 //printf( " Channel[i].mo not set\n" );
486 angle = R_PointToAngle2(players[displayplayer].mo->x,
487 players[displayplayer].mo->y, Channel[i].mo->x, Channel[i].mo->y);
488 angle = (angle-viewangle)>>24;
494 // vol = SoundCurve[dist];
500 if(S_sfx[sound_id].changePitch)
502 Channel[i].pitch = (byte)(127+(M_Random()&7)-(M_Random()&7));
506 Channel[i].pitch = 127;
508 Channel[i].handle = I_StartSound( sound_id, S_sfx[sound_id].snd_ptr, vol,
509 sep, Channel[i].pitch, 0 );
510 Channel[i].mo = origin;
511 Channel[i].sound_id = sound_id;
512 Channel[i].priority = priority;
513 Channel[i].volume = volume;
514 if(S_sfx[sound_id].usefulness < 0)
516 S_sfx[sound_id].usefulness = 1;
520 S_sfx[sound_id].usefulness++;
524 void S_StartSoundAtVolume(mobj_t *origin, int sound_id, int volume)
534 static int sndcount = 0;
537 if(sound_id == 0 || snd_MaxVolume == 0)
542 // origin = players[displayplayer].mo; bug -- can be uninitialized
550 // calculate the distance before other stuff so that we can throw out
551 // sounds that are beyond the hearing range.
554 absx = abs(origin->x-players[displayplayer].mo->x);
555 absy = abs(origin->y-players[displayplayer].mo->y);
559 dist = absx+absy-(absx > absy ? absy>>1 : absx>>1);
561 if(dist >= MAX_SND_DIST)
563 return; // sound is beyond the hearing range...
569 priority = S_sfx[sound_id].priority;
570 priority *= (PRIORITY_MAX_ADJUST-(dist/DIST_ADJUST));
571 if(!S_StopSoundID(sound_id, priority))
573 return; // other sounds have greater priority
575 for(i=0; i<snd_Channels; i++)
577 if(!origin || origin->player)
580 break; // let the player have more than one sound.
582 if(origin == Channel[i].mo)
583 { // only allow other mobjs one sound
584 S_StopSound(Channel[i].mo);
588 if(i >= snd_Channels)
590 for(i = 0; i < snd_Channels; i++)
592 if(Channel[i].mo == NULL)
597 if(i >= snd_Channels)
599 // look for a lower priority sound to replace.
601 if(sndcount >= snd_Channels)
605 for(chan = 0; chan < snd_Channels; chan++)
607 i = (sndcount+chan)%snd_Channels;
608 if(priority >= Channel[i].priority)
610 chan = -1; //denote that sound should be replaced.
616 return; //no free channels.
618 else //replace the lower priority sound.
620 if(Channel[i].handle)
622 if(I_SoundIsPlaying(Channel[i].handle))
624 I_StopSound(Channel[i].handle);
626 if(S_sfx[Channel[i].sound_id].usefulness > 0)
628 S_sfx[Channel[i].sound_id].usefulness--;
634 if(S_sfx[sound_id].lumpnum == 0)
636 S_sfx[sound_id].lumpnum = I_GetSfxLumpNum(&S_sfx[sound_id]);
638 if(S_sfx[sound_id].snd_ptr == NULL)
643 sprintf(name, "%s%s.lmp", ArchivePath, S_sfx[sound_id].lumpname);
644 M_ReadFile(name, (byte **)&S_sfx[sound_id].snd_ptr);
648 S_sfx[sound_id].snd_ptr = W_CacheLumpNum(S_sfx[sound_id].lumpnum,
652 // _dpmi_lockregion(S_sfx[sound_id].snd_ptr,
653 // lumpinfo[S_sfx[sound_id].lumpnum].size);
657 vol = (SoundCurve[dist]*(snd_MaxVolume*8)*volume)>>14;
658 if (!origin || origin == players[displayplayer].mo)
661 // vol = (volume*(snd_MaxVolume+1)*8)>>7;
665 angle = R_PointToAngle2(players[displayplayer].mo->x,
666 // bug! players[displayplayer].mo->y, Channel[i].mo->x, Channel[i].mo->y);
667 players[displayplayer].mo->y, origin->x, origin->y);
668 angle = (angle-viewangle)>>24;
674 // vol = SoundCurve[dist];
677 if(S_sfx[sound_id].changePitch)
679 Channel[i].pitch = (byte)(127+(M_Random()&7)-(M_Random()&7));
683 Channel[i].pitch = 127;
685 Channel[i].handle = I_StartSound(sound_id, S_sfx[sound_id].snd_ptr, vol,
686 sep, Channel[i].pitch, 0);
687 Channel[i].mo = origin;
688 Channel[i].sound_id = sound_id;
689 Channel[i].priority = priority;
690 Channel[i].volume = volume;
691 if(S_sfx[sound_id].usefulness < 0)
693 S_sfx[sound_id].usefulness = 1;
697 S_sfx[sound_id].usefulness++;
700 //==========================================================================
704 //==========================================================================
706 boolean S_StopSoundID(int sound_id, int priority)
709 int lp; //least priority
712 if(S_sfx[sound_id].numchannels == -1)
716 lp = -1; //denote the argument sound_id
718 for(i=0; i<snd_Channels; i++)
720 if(Channel[i].sound_id == sound_id && Channel[i].mo)
722 found++; //found one. Now, should we replace it??
723 if(priority >= Channel[i].priority)
724 { // if we're gonna kill one, then this'll be it
726 priority = Channel[i].priority;
730 if(found < S_sfx[sound_id].numchannels)
736 return(false); // don't replace any sounds
738 if(Channel[lp].handle)
740 if(I_SoundIsPlaying(Channel[lp].handle))
742 I_StopSound(Channel[lp].handle);
744 if(S_sfx[Channel[lp].sound_id].usefulness > 0)
746 S_sfx[Channel[lp].sound_id].usefulness--;
748 Channel[lp].mo = NULL;
753 //==========================================================================
757 //==========================================================================
759 void S_StopSound(mobj_t *origin)
763 for(i=0;i<snd_Channels;i++)
765 if(Channel[i].mo == origin)
767 I_StopSound(Channel[i].handle);
768 if(S_sfx[Channel[i].sound_id].usefulness > 0)
770 S_sfx[Channel[i].sound_id].usefulness--;
772 Channel[i].handle = 0;
773 Channel[i].mo = NULL;
778 //==========================================================================
782 //==========================================================================
784 void S_StopAllSound(void)
789 for(i=0; i < snd_Channels; i++)
791 if(Channel[i].handle)
793 S_StopSound(Channel[i].mo);
796 memset(Channel, 0, 8*sizeof(channel_t));
799 //==========================================================================
803 //==========================================================================
805 void S_SoundLink(mobj_t *oldactor, mobj_t *newactor)
809 for(i=0;i<snd_Channels;i++)
811 if(Channel[i].mo == oldactor)
812 Channel[i].mo = newactor;
816 //==========================================================================
820 //==========================================================================
822 void S_PauseSound(void)
830 I_PauseSong(RegisteredSong);
834 //==========================================================================
838 //==========================================================================
840 void S_ResumeSound(void)
848 I_ResumeSong(RegisteredSong);
852 //==========================================================================
856 //==========================================================================
858 void S_UpdateSounds(mobj_t *listener)
871 if(snd_MaxVolume == 0)
876 // Update any Sequences
877 SN_UpdateActiveSequences();
879 if(NextCleanup < gametic)
883 for(i = 0; i < NUMSFX; i++)
885 if(S_sfx[i].usefulness == 0 && S_sfx[i].snd_ptr)
887 S_sfx[i].usefulness = -1;
893 for(i = 0; i < NUMSFX; i++)
895 if(S_sfx[i].usefulness == 0 && S_sfx[i].snd_ptr)
897 if(lumpcache[S_sfx[i].lumpnum])
899 if(((memblock_t *)((byte*)
900 (lumpcache[S_sfx[i].lumpnum])-
901 sizeof(memblock_t)))->id == 0x1d4a11)
902 { // taken directly from the Z_ChangeTag macro
903 Z_ChangeTag2(lumpcache[S_sfx[i].lumpnum],
907 S_sfx[i].usefulness = -1;
908 S_sfx[i].snd_ptr = NULL;
912 NextCleanup = gametic+35*30; // every 30 seconds
914 for(i=0;i<snd_Channels;i++)
916 if(!Channel[i].handle || S_sfx[Channel[i].sound_id].usefulness == -1)
920 if(!I_SoundIsPlaying(Channel[i].handle))
922 if(S_sfx[Channel[i].sound_id].usefulness > 0)
924 S_sfx[Channel[i].sound_id].usefulness--;
926 Channel[i].handle = 0;
927 Channel[i].mo = NULL;
928 Channel[i].sound_id = 0;
930 if(Channel[i].mo == NULL || Channel[i].sound_id == 0
931 || Channel[i].mo == listener)
937 absx = abs(Channel[i].mo->x-listener->x);
938 absy = abs(Channel[i].mo->y-listener->y);
939 dist = absx+absy-(absx > absy ? absy>>1 : absx>>1);
942 if(dist >= MAX_SND_DIST)
944 S_StopSound(Channel[i].mo);
951 //vol = SoundCurve[dist];
952 vol = (SoundCurve[dist]*(snd_MaxVolume*8)*Channel[i].volume)>>14;
953 if(Channel[i].mo == listener)
959 angle = R_PointToAngle2(listener->x, listener->y,
960 Channel[i].mo->x, Channel[i].mo->y);
961 angle = (angle-viewangle)>>24;
968 I_UpdateSoundParams(Channel[i].handle, vol, sep,
970 priority = S_sfx[Channel[i].sound_id].priority;
971 priority *= PRIORITY_MAX_ADJUST-(dist/DIST_ADJUST);
972 Channel[i].priority = priority;
977 //==========================================================================
981 //==========================================================================
985 SoundCurve = W_CacheLumpName("SNDCURVE", PU_STATIC);
986 // SoundCurve = Z_Malloc(MAX_SND_DIST, PU_STATIC, NULL);
992 I_SetChannels(snd_Channels);
993 I_SetMusicVolume(snd_MusicVolume);
995 // Attempt to setup CD music
998 ST_Message(" Attempting to initialize CD Music: ");
1001 i_CDMusic = (I_CDMusInit() != -1);
1004 { // The user is trying to use the cdrom for both game and music
1009 ST_Message("initialized.\n");
1013 ST_Message("failed.\n");
1018 //==========================================================================
1022 //==========================================================================
1024 void S_GetChannelInfo(SoundInfo_t *s)
1029 s->channelCount = snd_Channels;
1030 s->musicVolume = snd_MusicVolume;
1031 s->soundVolume = snd_MaxVolume;
1032 for(i = 0; i < snd_Channels; i++)
1035 c->id = Channel[i].sound_id;
1036 c->priority = Channel[i].priority;
1037 c->name = S_sfx[c->id].lumpname;
1038 c->mo = Channel[i].mo;
1039 c->distance = P_AproxDistance(c->mo->x-viewx, c->mo->y-viewy)
1044 //==========================================================================
1046 // S_GetSoundPlayingInfo
1048 //==========================================================================
1050 boolean S_GetSoundPlayingInfo(mobj_t *mobj, int sound_id)
1054 for(i = 0; i < snd_Channels; i++)
1056 if(Channel[i].sound_id == sound_id && Channel[i].mo == mobj)
1058 if(I_SoundIsPlaying(Channel[i].handle))
1067 //==========================================================================
1071 //==========================================================================
1073 void S_SetMusicVolume(void)
1077 I_CDMusSetVolume(snd_MusicVolume*16); // 0-255
1081 I_SetMusicVolume(snd_MusicVolume);
1083 if(snd_MusicVolume == 0)
1087 I_PauseSong(RegisteredSong);
1091 else if(MusicPaused)
1095 I_ResumeSong(RegisteredSong);
1097 MusicPaused = false;
1101 //==========================================================================
1105 //==========================================================================
1107 void S_ShutDown(void)
1112 I_StopSong(RegisteredSong);
1113 I_UnRegisterSong(RegisteredSong);
1123 //==========================================================================
1127 //==========================================================================
1129 void S_InitScript(void)
1134 strcpy(ArchivePath, DEFAULT_ARCHIVEPATH);
1135 if(!(p = M_CheckParm("-devsnd")))
1137 UseSndScript = false;
1138 SC_OpenLump("sndinfo");
1142 UseSndScript = true;
1143 SC_OpenFile(myargv[p+1]);
1145 while(SC_GetString())
1147 if(*sc_String == '$')
1149 if(!stricmp(sc_String, "$ARCHIVEPATH"))
1152 strcpy(ArchivePath, sc_String);
1154 else if(!stricmp(sc_String, "$MAP"))
1160 P_PutMapSongLump(sc_Number, sc_String);
1167 for(i = 0; i < NUMSFX; i++)
1169 if(!strcmp(S_sfx[i].tagName, sc_String))
1172 if(*sc_String != '?')
1174 strcpy(S_sfx[i].lumpname, sc_String);
1178 strcpy(S_sfx[i].lumpname, "default");
1191 for(i = 0; i < NUMSFX; i++)
1193 if(!strcmp(S_sfx[i].lumpname, ""))
1195 strcpy(S_sfx[i].lumpname, "default");
1201 //==================================================
1206 boolean novideo; // if true, stay in text mode for debugging
1209 //==========================================================================
1212 static long _startSec;
1214 void I_StartupTimer(void)
1217 gettimeofday( &tv, 0 );
1218 _startSec = tv.tv_sec;
1221 //--------------------------------------------------------------------------
1225 // Returns time in 1/35th second tics.
1227 //--------------------------------------------------------------------------
1229 int I_GetTime (void)
1232 gettimeofday( &tv, 0 );
1234 //printf( "GT: %lx %lx\n", tv.tv_sec, tv.tv_usec );
1236 // ticcount = ((tv.tv_sec * 1000000) + tv.tv_usec) / 28571;
1237 ticcount = ((tv.tv_sec - _startSec) * 35) + (tv.tv_usec / 28571);
1243 ============================================================================
1247 ============================================================================
1250 //==================================================
1254 //==================================================
1256 extern int usejoystick;
1257 boolean joystickpresent;
1258 unsigned joystickx, joysticky;
1260 // returns false if not connected
1261 boolean I_ReadJoystick (void)
1267 int joyxl, joyxh, joyyl, joyyh;
1269 boolean WaitJoyButton (void)
1272 int oldbuttons, buttons;
1278 buttons = ((inp(0x201) >> 4)&1)^1;
1279 if (buttons != oldbuttons)
1281 oldbuttons = buttons;
1285 if ( (lastpress& 0x7f) == 1 )
1287 joystickpresent = false;
1290 } while ( !buttons);
1295 buttons = ((inp(0x201) >> 4)&1)^1;
1296 if (buttons != oldbuttons)
1298 oldbuttons = buttons;
1302 if ( (lastpress& 0x7f) == 1 )
1304 joystickpresent = false;
1323 int basejoyx, basejoyy;
1325 void I_StartupJoystick (void)
1327 int centerx, centery;
1329 joystickpresent = 0;
1330 if ( M_CheckParm ("-nojoy") || !usejoystick )
1333 if (!I_ReadJoystick ())
1335 joystickpresent = false;
1336 ST_Message("joystick not found\n ");
1339 ST_Message("joystick found\n");
1340 joystickpresent = true;
1342 ST_RealMessage("CENTER the joystick and press button 1:");
1343 if (!WaitJoyButton ())
1346 centerx = joystickx;
1347 centery = joysticky;
1349 ST_RealMessage("\nPush the joystick to the UPPER LEFT corner and press button 1:");
1350 if (!WaitJoyButton ())
1353 joyxl = (centerx + joystickx)/2;
1354 joyyl = (centerx + joysticky)/2;
1356 ST_RealMessage("\nPush the joystick to the LOWER RIGHT corner and press button 1:");
1357 if (!WaitJoyButton ())
1360 joyxh = (centerx + joystickx)/2;
1361 joyyh = (centery + joysticky)/2;
1362 ST_RealMessage("\n");
1373 void I_JoystickEvents (void)
1380 if (!joystickpresent)
1384 ev.type = ev_joystick;
1385 ev.data1 = 0; //((inp(0x201) >> 4)&15)^15;
1387 if (joystickx < joyxl)
1389 else if (joystickx > joyxh)
1393 if (joysticky < joyyl)
1395 else if (joysticky > joyyh)
1412 void I_StartFrame (void)
1419 ============================================================================
1423 ============================================================================
1426 void I_DivException (void);
1427 int I_SetDivException (void);
1432 ============================================================================
1436 ============================================================================
1445 = hook interrupts and set graphics mode
1452 void I_StartupTimer(void);
1454 novideo = M_CheckParm("novideo");
1455 //ST_Message(" I_StartupMouse ");
1457 // tprintf("I_StartupJoystick ",1);
1458 // I_StartupJoystick();
1459 ST_Message(" S_Init... ");
1472 = return to default system state
1477 void I_Shutdown (void)
1479 I_ShutdownGraphics ();
1492 void I_Error (char *error, ...)
1498 va_start (argptr,error);
1499 vprintf (error, argptr);
1505 //--------------------------------------------------------------------------
1509 // Shuts down net game, saves defaults, prints the exit text message,
1510 // goes to text mode, and exits.
1512 //--------------------------------------------------------------------------
1520 // scr = (byte *)W_CacheLumpName("ENDTEXT", PU_CACHE);
1522 memcpy((void *)0xb8000, scr, 80*25*2);
1527 int386(0x10, (const union REGS *)®s, ®s); // Set text pos
1528 _settextposition(24, 1);
1530 printf("\nHexen: Beyond Heretic\n");
1542 byte *I_ZoneBase (int *size)
1545 int heap = 0x800000;
1547 ptr = malloc ( heap );
1549 ST_Message (" 0x%x allocated for zone, ", heap);
1550 ST_Message ("ZoneBase: 0x%X\n", (int)ptr);
1553 I_Error (" Insufficient DPMI memory!");
1567 byte *I_AllocLow (int length)
1569 return malloc( length );
1573 ============================================================================
1577 ============================================================================
1587 #define DOOMCOM_ID 0x12345678l
1593 short intnum; // DOOM executes an int to execute commands
1595 // communication between DOOM and the driver
1596 short command; // CMD_SEND or CMD_GET
1597 short remotenode; // dest for send, set by get (-1 = no packet)
1598 short datalength; // bytes in doomdata to be sent
1600 // info common to all nodes
1601 short numnodes; // console is allways node 0
1602 short ticdup; // 1 = no duplication, 2-5 = dup for slow nets
1603 short extratics; // 1 = send a backup tic in every packet
1604 short deathmatch; // 1 = deathmatch
1605 short savegame; // -1 = new game, 0-5 = load savegame
1606 short episode; // 1-3
1610 // info specific to this node
1611 short consoleplayer;
1613 short angleoffset; // 1 = left, 0 = center, -1 = right
1614 short drone; // 1 = drone
1616 // packet data to be sent
1621 extern doomcom_t *doomcom;
1624 ====================
1628 ====================
1631 void I_InitNetwork (void)
1635 i = M_CheckParm ("-net");
1639 // single player game
1641 doomcom = malloc (sizeof (*doomcom) );
1642 memset (doomcom, 0, sizeof(*doomcom) );
1644 doomcom->id = DOOMCOM_ID;
1645 doomcom->numplayers = doomcom->numnodes = 1;
1646 doomcom->deathmatch = false;
1647 doomcom->consoleplayer = 0;
1648 doomcom->ticdup = 1;
1649 doomcom->extratics = 0;
1653 doomcom = (doomcom_t *)atoi(myargv[i+1]);
1655 doomcom->skill = startskill;
1656 doomcom->episode = startepisode;
1657 doomcom->map = startmap;
1658 doomcom->deathmatch = deathmatch;
1661 void I_NetCmd (void)
1664 I_Error ("I_NetCmd when not in netgame");
1667 //=========================================================================
1669 // I_CheckExternDriver
1671 // Checks to see if a vector, and an address for an external driver
1672 // have been passed.
1673 //=========================================================================
1675 void I_CheckExternDriver(void)
1679 if(!(i = M_CheckParm("-externdriver")))
1683 i_ExternData = (externdata_t *)atoi(myargv[i+1]);
1684 i_Vector = i_ExternData->vector;
1686 useexterndriver = true;
1689 void PrintHelp(char *name)
1691 printf ("HHexen (%s %d.%d)\n", VERSION_PLATFORM,
1692 VERSION_MAJ,VERSION_MIN);
1693 printf ("http://icculus.org/hast/\n");
1694 printf ("Please send bug reports or patches to:\n");
1695 printf (" Dan Olson <theoddone33@icculus.org>\n");
1697 printf ("Usage: %s [options]\n", name);
1698 printf (" [ -h | --help] Display this help message\n");
1699 printf (" [ -v | --version] Display the game version\n");
1700 printf (" [ -f | --fullscreen] Run the game fullscreen\n");
1701 printf (" [ -w | --windowed] Run the game windowed\n");
1702 printf (" [ -s | --nosound] Run the game without sound\n");
1703 printf (" [ -g | --nograb] Disable mouse grabbing\n");
1705 //printf (" [ -l | --gllibrary] Select 3D rendering library\n");
1708 printf ("You can use the HHEXEN_DATA environment variable to force the\n");
1709 printf ("HHexen data directory.\n");
1713 void PrintVersion (void)
1715 printf ("HHexen (%s %d.%d)\n", VERSION_PLATFORM,
1716 VERSION_MAJ,VERSION_MIN);
1719 int main( int argc, char** argv )
1723 if (M_CheckParm("--help") || M_CheckParm("-h"))
1725 PrintHelp (argv[0]);
1728 if (M_CheckParm("--version") || M_CheckParm("-v"))
1739 fixed_t FixedMul (fixed_t a, fixed_t b)
1742 __asm__ __volatile__(
1744 "shrdl $16, %%edx, %%eax \n\t"
1751 fixed_t FixedDiv2 (fixed_t a, fixed_t b)
1754 __asm__ __volatile__(
1756 "shldl $16, %%eax, %%edx \n\t"
1757 "sall $16, %%eax \n\t"