ref: 29d6a62b7536f0e023f588076cfc7b7175617c71
parent: 373a5aadf3814e5c433787d419a218a9061f5c3d
author: qwx <>
date: Wed Dec 12 01:20:24 EST 2018
qw: align video, sound and input code with qk1 note that sound will cut up by default unless devaudio delay is increased, or cl_maxfps or rate are adjusted for a maximum framerate of 72 (hardcoded). the latter is recommended. no idea why one would want a lower framerate. video code also essentially assumes that the screen is always updated in its entirety. even if this is not always true, it matters only ingame, where it (currently) is.
--- a/qw/cd.c
+++ /dev/null
@@ -1,393 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <stdio.h>
-#include "quakedef.h"
-
-static qboolean cdValid;
-static qboolean playing;
-static qboolean wasPlaying;
-static qboolean initialized;
-static qboolean enabled = true;
-static qboolean playLooping;
-static float cdvolume;
-static byte remap[100];
-static byte playTrack;
-static byte maxTrack;
-static int cdfile = -1;
-static char cd_dev[64] = "/dev/cdrom";
-
-
-static void CDAudio_Eject(void)
-{
- if (cdfile == -1 || !enabled)
- return; // no cd init'd
-/*
- if ( ioctl(cdfile, CDROMEJECT) == -1 )
- Con_DPrintf("ioctl cdromeject failed\n");
-*/
-}
-
-static void CDAudio_CloseDoor(void)
-{
- if (cdfile == -1 || !enabled)
- return; // no cd init'd
-/*
- if ( ioctl(cdfile, CDROMCLOSETRAY) == -1 )
- Con_DPrintf("ioctl cdromclosetray failed\n");
-*/
-}
-
-static int CDAudio_GetAudioDiskInfo(void)
-{
- cdValid = false;
- return -1;
-
-/*
- struct cdrom_tochdr tochdr;
-
- if ( ioctl(cdfile, CDROMREADTOCHDR, &tochdr) == -1 )
- {
- Con_DPrintf("ioctl cdromreadtochdr failed\n");
- return -1;
- }
-
- if (tochdr.cdth_trk0 < 1)
- {
- Con_DPrintf("CDAudio: no music tracks\n");
- return -1;
- }
-
- cdValid = true;
- maxTrack = tochdr.cdth_trk1;
-
- return 0;
-*/
-}
-
-
-void CDAudio_Play(byte track, qboolean looping)
-{
- if (cdfile == -1 || !enabled)
- return;
-
- if (!cdValid)
- {
- CDAudio_GetAudioDiskInfo();
- if (!cdValid)
- return;
- }
-
- track = remap[track];
-
- if (track < 1 || track > maxTrack)
- {
- Con_DPrintf("CDAudio: Bad track number %u.\n", track);
- return;
- }
-
- USED(looping);
-/*
- struct cdrom_tocentry entry;
- struct cdrom_ti ti;
-
- // don't try to play a non-audio track
- entry.cdte_track = track;
- entry.cdte_format = CDROM_MSF;
- if ( ioctl(cdfile, CDROMREADTOCENTRY, &entry) == -1 )
- {
- Con_DPrintf("ioctl cdromreadtocentry failed\n");
- return;
- }
- if (entry.cdte_ctrl == CDROM_DATA_TRACK)
- {
- Con_Printf("CDAudio: track %i is not audio\n", track);
- return;
- }
-
- if (playing)
- {
- if (playTrack == track)
- return;
- CDAudio_Stop();
- }
-
- ti.cdti_trk0 = track;
- ti.cdti_trk1 = track;
- ti.cdti_ind0 = 1;
- ti.cdti_ind1 = 99;
-
- if ( ioctl(cdfile, CDROMPLAYTRKIND, &ti) == -1 )
- {
- Con_DPrintf("ioctl cdromplaytrkind failed\n");
- return;
- }
-
- if ( ioctl(cdfile, CDROMRESUME) == -1 )
- Con_DPrintf("ioctl cdromresume failed\n");
-
- playLooping = looping;
- playTrack = track;
- playing = true;
-
- if (cdvolume == 0.0)
- CDAudio_Pause ();
-*/
-}
-
-
-void CDAudio_Stop(void)
-{
- if (cdfile == -1 || !enabled)
- return;
-
- if (!playing)
- return;
-
-/*
- if ( ioctl(cdfile, CDROMSTOP) == -1 )
- Con_DPrintf("ioctl cdromstop failed (%d)\n", errno);
- wasPlaying = false;
- playing = false;
-*/
-}
-
-void CDAudio_Pause(void)
-{
- if (cdfile == -1 || !enabled)
- return;
-
- if (!playing)
- return;
-
-/*
- if ( ioctl(cdfile, CDROMPAUSE) == -1 )
- Con_DPrintf("ioctl cdrompause failed\n");
- wasPlaying = playing;
- playing = false;
-*/
-}
-
-
-void CDAudio_Resume(void)
-{
- if (cdfile == -1 || !enabled)
- return;
-
- if (!cdValid)
- return;
-
- if (!wasPlaying)
- return;
-/*
- if ( ioctl(cdfile, CDROMRESUME) == -1 )
- Con_DPrintf("ioctl cdromresume failed\n");
- playing = true;
-*/
-}
-
-static void CD_f (void)
-{
- char *command;
- int ret;
- int n;
-
- if (Cmd_Argc() < 2)
- return;
-
- command = Cmd_Argv (1);
-
- if (cistrcmp(command, "on") == 0)
- {
- enabled = true;
- return;
- }
-
- if (cistrcmp(command, "off") == 0)
- {
- if (playing)
- CDAudio_Stop();
- enabled = false;
- return;
- }
-
- if (cistrcmp(command, "reset") == 0)
- {
- enabled = true;
- if (playing)
- CDAudio_Stop();
- for (n = 0; n < 100; n++)
- remap[n] = n;
- CDAudio_GetAudioDiskInfo();
- return;
- }
-
- if (cistrcmp(command, "remap") == 0)
- {
- ret = Cmd_Argc() - 2;
- if (ret <= 0)
- {
- for (n = 1; n < 100; n++)
- if (remap[n] != n)
- Con_Printf(" %u -> %u\n", n, remap[n]);
- return;
- }
- for (n = 1; n <= ret; n++)
- remap[n] = Q_atoi(Cmd_Argv (n+1));
- return;
- }
-
- if (cistrcmp(command, "close") == 0)
- {
- CDAudio_CloseDoor();
- return;
- }
-
- if (!cdValid)
- {
- CDAudio_GetAudioDiskInfo();
- if (!cdValid)
- {
- Con_Printf("No CD in player.\n");
- return;
- }
- }
-
- if (cistrcmp(command, "play") == 0)
- {
- CDAudio_Play((byte)Q_atoi(Cmd_Argv (2)), false);
- return;
- }
-
- if (cistrcmp(command, "loop") == 0)
- {
- CDAudio_Play((byte)Q_atoi(Cmd_Argv (2)), true);
- return;
- }
-
- if (cistrcmp(command, "stop") == 0)
- {
- CDAudio_Stop();
- return;
- }
-
- if (cistrcmp(command, "pause") == 0)
- {
- CDAudio_Pause();
- return;
- }
-
- if (cistrcmp(command, "resume") == 0)
- {
- CDAudio_Resume();
- return;
- }
-
- if (cistrcmp(command, "eject") == 0)
- {
- if (playing)
- CDAudio_Stop();
- CDAudio_Eject();
- cdValid = false;
- return;
- }
-
- if (cistrcmp(command, "info") == 0)
- {
- Con_Printf("%u tracks\n", maxTrack);
- if (playing)
- Con_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack);
- else if (wasPlaying)
- Con_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack);
- Con_Printf("Volume is %f\n", cdvolume);
- return;
- }
-}
-
-void CDAudio_Update(void)
-{
- if (!enabled)
- return;
-
- if (bgmvolume.value != cdvolume)
- {
- if (cdvolume)
- {
- Cvar_SetValue ("bgmvolume", 0.0);
- cdvolume = bgmvolume.value;
- CDAudio_Pause ();
- }
- else
- {
- Cvar_SetValue ("bgmvolume", 1.0);
- cdvolume = bgmvolume.value;
- CDAudio_Resume ();
- }
- }
-
-/*
- struct cdrom_subchnl subchnl;
- static time_t lastchk;
- if (playing && lastchk < time(NULL)) {
- lastchk = time(NULL) + 2; //two seconds between chks
-
- subchnl.cdsc_format = CDROM_MSF;
- if (ioctl(cdfile, CDROMSUBCHNL, &subchnl) == -1 ) {
- Con_DPrintf("ioctl cdromsubchnl failed\n");
- playing = false;
- return;
- }
- if (subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY &&
- subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED) {
- playing = false;
- if (playLooping)
- CDAudio_Play(playTrack, true);
- }
- }
-*/
-}
-
-int CDAudio_Init(void)
-{
- int i;
-
- if (COM_CheckParm("-nocdaudio"))
- return -1;
-
- if ((i = COM_CheckParm("-cddev")) != 0 && i < com_argc - 1) {
- strncpy(cd_dev, com_argv[i + 1], sizeof(cd_dev));
- cd_dev[sizeof(cd_dev) - 1] = 0;
- }
-
- if ((cdfile = open(cd_dev, OREAD)) == -1) {
- fprint(2, "CDAudio_Init:open: %r\n");
- cdfile = -1;
- return -1;
- }
-
- for (i = 0; i < 100; i++)
- remap[i] = i;
- initialized = true;
- enabled = true;
-
- if (CDAudio_GetAudioDiskInfo())
- {
- Con_Printf("CDAudio_Init: No CD in player.\n");
- cdValid = false;
- }
-
- Cmd_AddCommand ("cd", CD_f);
-
- Con_Printf("CD Audio Initialized\n");
-
- return 0;
-}
-
-
-void CDAudio_Shutdown(void)
-{
- if (!initialized)
- return;
- CDAudio_Stop();
- close(cdfile);
- cdfile = -1;
-}
--- a/qw/cdaudio.h
+++ b/qw/cdaudio.h
@@ -1,7 +1,6 @@
-int CDAudio_Init(void);
-void CDAudio_Play(byte track, qboolean looping);
-void CDAudio_Stop(void);
-void CDAudio_Pause(void);
-void CDAudio_Resume(void);
-void CDAudio_Shutdown(void);
-void CDAudio_Update(void);
+int initcd(void);
+void startcd(int, int);
+void pausecd(void);
+void resumecd(void);
+void shutcd(void);
+void stepcd(void);
--- a/qw/cl_main.c
+++ b/qw/cl_main.c
@@ -326,7 +326,7 @@
{
int i;
- S_StopAllSounds (true);
+ stopallsfx();
Con_DPrintf ("Clearing memory\n");
D_FlushCaches ();
@@ -370,7 +370,7 @@
connect_time = -1;
// stop sounds (especially looping!)
- S_StopAllSounds (true);
+ stopallsfx();
// if running a local server, shut it down
if (cls.demoplayback)
@@ -709,7 +709,7 @@
if (cls.download) // don't change when downloading
return;
- S_StopAllSounds (true);
+ stopallsfx();
cl.intermission = 0;
cls.state = ca_connected; // not active anymore, but not disconnected
Con_Printf ("\nChanging map...\n");
@@ -728,7 +728,7 @@
if (cls.download) // don't change when downloading
return;
- S_StopAllSounds (true);
+ stopallsfx();
if (cls.state == ca_connected) {
Con_Printf ("reconnecting...\n");
@@ -1185,38 +1185,8 @@
}
}
-
-//============================================================================
-
/*
==================
-Host_SimulationTime
-
-This determines if enough time has passed to run a simulation frame
-==================
-*/
-/*
-qboolean Host_SimulationTime(float time)
-{
- float fps;
-
- if (oldrealtime > realtime)
- oldrealtime = 0;
-
- if (cl_maxfps.value)
- fps = Max(30.0, Min(cl_maxfps.value, 72.0));
- else
- fps = Max(30.0, Min(rate.value/80.0, 72.0));
-
- if (!cls.timedemo && (realtime + time) - oldrealtime < 1.0/fps)
- return false; // framerate is too high
- return true;
-}
-*/
-
-
-/*
-==================
Host_Frame
Runs all active servers
@@ -1294,13 +1264,13 @@
// update audio
if (cls.state == ca_active)
{
- S_Update (r_origin, vpn, vright, vup);
+ stepsnd (r_origin, vpn, vright, vup);
CL_DecayLights ();
}
else
- S_Update (vec3_origin, vec3_origin, vec3_origin, vec3_origin);
+ stepsnd (vec3_origin, vec3_origin, vec3_origin, vec3_origin);
- CDAudio_Update();
+ stepcd();
if (host_speeds.value)
{
@@ -1382,12 +1352,12 @@
Sys_Error ("Couldn't load gfx/colormap.lmp");
IN_Init ();
- CDAudio_Init ();
+ initcd ();
VID_Init (host_basepal);
Draw_Init ();
SCR_Init ();
R_Init ();
- S_Init ();
+ initsnd (parms);
cls.state = ca_disconnected;
Sbar_Init ();
CL_Init ();
@@ -1428,9 +1398,9 @@
Host_WriteConfiguration ();
- CDAudio_Shutdown ();
+ shutcd ();
NET_Shutdown ();
- S_Shutdown();
+ shutsnd();
IN_Shutdown ();
if (host_basepal)
VID_Shutdown();
--- a/qw/cl_parse.c
+++ b/qw/cl_parse.c
@@ -267,7 +267,7 @@
{
if (!cl.sound_name[i][0])
break;
- cl.sound_precache[i] = S_PrecacheSound (cl.sound_name[i]);
+ cl.sound_precache[i] = precachesfx(cl.sound_name[i]);
}
// done with sounds, request models now
@@ -762,7 +762,7 @@
vol = MSG_ReadByte ();
atten = MSG_ReadByte ();
- S_StaticSound (cl.sound_precache[sound_num], org, vol, atten);
+ staticsfx (cl.sound_precache[sound_num], org, vol, atten);
}
@@ -812,7 +812,7 @@
if (ent > MAX_EDICTS)
Host_EndGame ("CL_ParseStartSoundPacket: ent = %i", ent);
- S_StartSound (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
+ startsfx (ent, channel, cl.sound_precache[sound_num], pos, volume/255.0, attenuation);
}
@@ -1139,7 +1139,7 @@
i = MSG_ReadByte ();
if (i == PRINT_CHAT)
{
- S_LocalSound ("misc/talk.wav");
+ localsfx ("misc/talk.wav");
con_ormask = 128;
}
Con_Printf ("%s", MSG_ReadString ());
@@ -1186,7 +1186,7 @@
case svc_stopsound:
i = MSG_ReadShort();
- S_StopSound(i>>3, i&7);
+ stopsfx(i>>3, i&7);
break;
case svc_updatefrags:
@@ -1255,7 +1255,7 @@
case svc_cdtrack:
cl.cdtrack = MSG_ReadByte ();
- CDAudio_Play ((byte)cl.cdtrack, true);
+ startcd ((byte)cl.cdtrack, true);
break;
case svc_intermission:
@@ -1348,9 +1348,9 @@
case svc_setpause:
cl.paused = MSG_ReadByte ();
if (cl.paused)
- CDAudio_Pause ();
+ pausecd ();
else
- CDAudio_Resume ();
+ resumecd ();
break;
}
--- a/qw/cl_tent.c
+++ b/qw/cl_tent.c
@@ -43,13 +43,13 @@
*/
void CL_InitTEnts (void)
{
- cl_sfx_wizhit = S_PrecacheSound ("wizard/hit.wav");
- cl_sfx_knighthit = S_PrecacheSound ("hknight/hit.wav");
- cl_sfx_tink1 = S_PrecacheSound ("weapons/tink1.wav");
- cl_sfx_ric1 = S_PrecacheSound ("weapons/ric1.wav");
- cl_sfx_ric2 = S_PrecacheSound ("weapons/ric2.wav");
- cl_sfx_ric3 = S_PrecacheSound ("weapons/ric3.wav");
- cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav");
+ cl_sfx_wizhit = precachesfx ("wizard/hit.wav");
+ cl_sfx_knighthit = precachesfx ("hknight/hit.wav");
+ cl_sfx_tink1 = precachesfx ("weapons/tink1.wav");
+ cl_sfx_ric1 = precachesfx ("weapons/ric1.wav");
+ cl_sfx_ric2 = precachesfx ("weapons/ric2.wav");
+ cl_sfx_ric3 = precachesfx ("weapons/ric3.wav");
+ cl_sfx_r_exp3 = precachesfx ("weapons/r_exp3.wav");
}
/*
@@ -162,7 +162,7 @@
pos[1] = MSG_ReadCoord ();
pos[2] = MSG_ReadCoord ();
R_RunParticleEffect (pos, vec3_origin, 20, 30);
- S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
+ startsfx (-1, 0, cl_sfx_wizhit, pos, 1, 1);
break;
case TE_KNIGHTSPIKE: // spike hitting wall
@@ -170,7 +170,7 @@
pos[1] = MSG_ReadCoord ();
pos[2] = MSG_ReadCoord ();
R_RunParticleEffect (pos, vec3_origin, 226, 20);
- S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
+ startsfx (-1, 0, cl_sfx_knighthit, pos, 1, 1);
break;
case TE_SPIKE: // spike hitting wall
@@ -180,16 +180,16 @@
R_RunParticleEffect (pos, vec3_origin, 0, 10);
if ( rand() % 5 )
- S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
+ startsfx (-1, 0, cl_sfx_tink1, pos, 1, 1);
else
{
rnd = rand() & 3;
if (rnd == 1)
- S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
+ startsfx (-1, 0, cl_sfx_ric1, pos, 1, 1);
else if (rnd == 2)
- S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
+ startsfx (-1, 0, cl_sfx_ric2, pos, 1, 1);
else
- S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
+ startsfx (-1, 0, cl_sfx_ric3, pos, 1, 1);
}
break;
case TE_SUPERSPIKE: // super spike hitting wall
@@ -199,16 +199,16 @@
R_RunParticleEffect (pos, vec3_origin, 0, 20);
if ( rand() % 5 )
- S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
+ startsfx (-1, 0, cl_sfx_tink1, pos, 1, 1);
else
{
rnd = rand() & 3;
if (rnd == 1)
- S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
+ startsfx (-1, 0, cl_sfx_ric1, pos, 1, 1);
else if (rnd == 2)
- S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
+ startsfx (-1, 0, cl_sfx_ric2, pos, 1, 1);
else
- S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
+ startsfx (-1, 0, cl_sfx_ric3, pos, 1, 1);
}
break;
@@ -231,7 +231,7 @@
dl->color[3] = 0.7;
// sound
- S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
+ startsfx (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
// sprite
ex = CL_AllocExplosion ();
@@ -246,7 +246,7 @@
pos[2] = MSG_ReadCoord ();
R_BlobExplosion (pos);
- S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
+ startsfx (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
break;
case TE_LIGHTNING1: // lightning bolts
--- a/qw/client.h
+++ b/qw/client.h
@@ -121,7 +121,8 @@
ca_demostart, // starting up a demo
ca_connected, // netchan_t established, waiting for svc_serverdata
ca_onserver, // processing data lists, donwloading, etc
-ca_active // everything is in, so frames can be rendered
+ca_active, // everything is in, so frames can be rendered
+ca_dedicated
} cactive_t;
typedef enum {
@@ -300,7 +301,6 @@
extern cvar_t m_side;
extern cvar_t m_windowed;
-
extern cvar_t name;
--- a/qw/d_sprite.c
+++ b/qw/d_sprite.c
@@ -416,5 +416,4 @@
D_SpriteScanLeftEdge ();
D_SpriteScanRightEdge ();
D_SpriteDrawSpans (sprite_spans);
- print("D_DrawSprite: ok\n");
}
--- a/qw/draw.c
+++ b/qw/draw.c
@@ -116,7 +116,6 @@
{
byte *dest;
byte *source;
- unsigned short *pusdest;
int drawline;
int row, col;
@@ -142,63 +141,19 @@
}
else
drawline = 8;
-
-
- if (r_pixbytes == 1)
- {
- dest = vid.conbuffer + y*vid.conrowbytes + x;
-
- while (drawline--)
- {
- if (source[0])
- dest[0] = source[0];
- if (source[1])
- dest[1] = source[1];
- if (source[2])
- dest[2] = source[2];
- if (source[3])
- dest[3] = source[3];
- if (source[4])
- dest[4] = source[4];
- if (source[5])
- dest[5] = source[5];
- if (source[6])
- dest[6] = source[6];
- if (source[7])
- dest[7] = source[7];
- source += 128;
- dest += vid.conrowbytes;
- }
+ dest = vid.conbuffer + y*vid.conrowbytes + x;
+ while(drawline--){
+ if(source[0]) dest[0] = source[0];
+ if(source[1]) dest[1] = source[1];
+ if(source[2]) dest[2] = source[2];
+ if(source[3]) dest[3] = source[3];
+ if(source[4]) dest[4] = source[4];
+ if(source[5]) dest[5] = source[5];
+ if(source[6]) dest[6] = source[6];
+ if(source[7]) dest[7] = source[7];
+ source += 128;
+ dest += vid.conrowbytes;
}
- else
- {
- // FIXME: pre-expand to native format?
- pusdest = (unsigned short *)
- ((byte *)vid.conbuffer + y*vid.conrowbytes + (x<<1));
-
- while (drawline--)
- {
- if (source[0])
- pusdest[0] = d_8to16table[source[0]];
- if (source[1])
- pusdest[1] = d_8to16table[source[1]];
- if (source[2])
- pusdest[2] = d_8to16table[source[2]];
- if (source[3])
- pusdest[3] = d_8to16table[source[3]];
- if (source[4])
- pusdest[4] = d_8to16table[source[4]];
- if (source[5])
- pusdest[5] = d_8to16table[source[5]];
- if (source[6])
- pusdest[6] = d_8to16table[source[6]];
- if (source[7])
- pusdest[7] = d_8to16table[source[7]];
-
- source += 128;
- pusdest += (vid.conrowbytes >> 1);
- }
- }
}
/*
@@ -234,20 +189,9 @@
void Draw_Pixel(int x, int y, byte color)
{
byte *dest;
- unsigned short *pusdest;
- if (r_pixbytes == 1)
- {
- dest = vid.conbuffer + y*vid.conrowbytes + x;
- *dest = color;
- }
- else
- {
- // FIXME: pre-expand to native format?
- pusdest = (unsigned short *)
- ((byte *)vid.conbuffer + y*vid.conrowbytes + (x<<1));
- *pusdest = d_8to16table[color];
- }
+ dest = vid.conbuffer + y*vid.conrowbytes + x;
+ *dest = color;
}
void Draw_Crosshair(void)
@@ -326,8 +270,7 @@
void Draw_Pic (int x, int y, qpic_t *pic)
{
byte *dest, *source;
- unsigned short *pusdest;
- int v, u;
+ int v;
if ((x < 0) ||
(x + pic->width > vid.width) ||
@@ -338,34 +281,12 @@
}
source = pic->data;
-
- if (r_pixbytes == 1)
- {
- dest = vid.buffer + y * vid.rowbytes + x;
-
- for (v=0 ; v<pic->height ; v++)
- {
- memcpy (dest, source, pic->width);
- dest += vid.rowbytes;
- source += pic->width;
- }
+ dest = vid.buffer + y * vid.rowbytes + x;
+ for(v=0; v<pic->height; v++){
+ memcpy(dest, source, pic->width);
+ dest += vid.rowbytes;
+ source += pic->width;
}
- else
- {
- // FIXME: pretranslate at load time?
- pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
-
- for (v=0 ; v<pic->height ; v++)
- {
- for (u=0 ; u<pic->width ; u++)
- {
- pusdest[u] = d_8to16table[source[u]];
- }
-
- pusdest += vid.rowbytes >> 1;
- source += pic->width;
- }
- }
}
@@ -377,8 +298,7 @@
void Draw_SubPic(int x, int y, qpic_t *pic, int srcx, int srcy, int width, int height)
{
byte *dest, *source;
- unsigned short *pusdest;
- int v, u;
+ int v;
if ((x < 0) ||
(x + width > vid.width) ||
@@ -389,34 +309,12 @@
}
source = pic->data + srcy * pic->width + srcx;
-
- if (r_pixbytes == 1)
- {
- dest = vid.buffer + y * vid.rowbytes + x;
-
- for (v=0 ; v<height ; v++)
- {
- memcpy (dest, source, width);
- dest += vid.rowbytes;
- source += pic->width;
- }
+ dest = vid.buffer + y * vid.rowbytes + x;
+ for(v=0; v<height; v++){
+ memcpy(dest, source, width);
+ dest += vid.rowbytes;
+ source += pic->width;
}
- else
- {
- // FIXME: pretranslate at load time?
- pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
-
- for (v=0 ; v<height ; v++)
- {
- for (u=srcx ; u<(srcx+width) ; u++)
- {
- pusdest[u] = d_8to16table[source[u]];
- }
-
- pusdest += vid.rowbytes >> 1;
- source += pic->width;
- }
- }
}
@@ -428,7 +326,6 @@
void Draw_TransPic (int x, int y, qpic_t *pic)
{
byte *dest, *source, tbyte;
- unsigned short *pusdest;
int v, u;
if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 ||
@@ -438,69 +335,36 @@
}
source = pic->data;
-
- if (r_pixbytes == 1)
- {
- dest = vid.buffer + y * vid.rowbytes + x;
-
- if (pic->width & 7)
- { // general
- for (v=0 ; v<pic->height ; v++)
- {
- for (u=0 ; u<pic->width ; u++)
- if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
- dest[u] = tbyte;
-
- dest += vid.rowbytes;
- source += pic->width;
- }
+ dest = vid.buffer + y * vid.rowbytes + x;
+ if(pic->width & 7){ // general
+ for(v=0; v<pic->height; v++){
+ for(u=0; u<pic->width; u++)
+ if((tbyte = source[u]) != TRANSPARENT_COLOR)
+ dest[u] = tbyte;
+ dest += vid.rowbytes;
+ source += pic->width;
}
- else
- { // unwound
- for (v=0 ; v<pic->height ; v++)
- {
- for (u=0 ; u<pic->width ; u+=8)
- {
- if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
- dest[u] = tbyte;
- if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR)
- dest[u+1] = tbyte;
- if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR)
- dest[u+2] = tbyte;
- if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR)
- dest[u+3] = tbyte;
- if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR)
- dest[u+4] = tbyte;
- if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR)
- dest[u+5] = tbyte;
- if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR)
- dest[u+6] = tbyte;
- if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR)
- dest[u+7] = tbyte;
- }
- dest += vid.rowbytes;
- source += pic->width;
+ }else{ // unwound
+ for(v=0; v<pic->height; v++){
+ for(u=0; u<pic->width; u+=8){
+ if((tbyte = source[u]) != TRANSPARENT_COLOR)
+ dest[u] = tbyte;
+ if((tbyte = source[u+1]) != TRANSPARENT_COLOR)
+ dest[u+1] = tbyte;
+ if((tbyte = source[u+2]) != TRANSPARENT_COLOR)
+ dest[u+2] = tbyte;
+ if((tbyte = source[u+3]) != TRANSPARENT_COLOR)
+ dest[u+3] = tbyte;
+ if((tbyte = source[u+4]) != TRANSPARENT_COLOR)
+ dest[u+4] = tbyte;
+ if((tbyte = source[u+5]) != TRANSPARENT_COLOR)
+ dest[u+5] = tbyte;
+ if((tbyte = source[u+6]) != TRANSPARENT_COLOR)
+ dest[u+6] = tbyte;
+ if((tbyte = source[u+7]) != TRANSPARENT_COLOR)
+ dest[u+7] = tbyte;
}
- }
- }
- else
- {
- // FIXME: pretranslate at load time?
- pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
-
- for (v=0 ; v<pic->height ; v++)
- {
- for (u=0 ; u<pic->width ; u++)
- {
- tbyte = source[u];
-
- if (tbyte != TRANSPARENT_COLOR)
- {
- pusdest[u] = d_8to16table[tbyte];
- }
- }
-
- pusdest += vid.rowbytes >> 1;
+ dest += vid.rowbytes;
source += pic->width;
}
}
@@ -515,7 +379,6 @@
void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation)
{
byte *dest, *source, tbyte;
- unsigned short *pusdest;
int v, u;
if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 ||
@@ -525,69 +388,37 @@
}
source = pic->data;
+ dest = vid.buffer + y * vid.rowbytes + x;
+ if(pic->width & 7){ // general
+ for(v=0; v<pic->height; v++){
+ for(u=0; u<pic->width; u++)
+ if((tbyte = source[u]) != TRANSPARENT_COLOR)
+ dest[u] = translation[tbyte];
- if (r_pixbytes == 1)
- {
- dest = vid.buffer + y * vid.rowbytes + x;
-
- if (pic->width & 7)
- { // general
- for (v=0 ; v<pic->height ; v++)
- {
- for (u=0 ; u<pic->width ; u++)
- if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
- dest[u] = translation[tbyte];
-
- dest += vid.rowbytes;
- source += pic->width;
- }
+ dest += vid.rowbytes;
+ source += pic->width;
}
- else
- { // unwound
- for (v=0 ; v<pic->height ; v++)
- {
- for (u=0 ; u<pic->width ; u+=8)
- {
- if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
- dest[u] = translation[tbyte];
- if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR)
- dest[u+1] = translation[tbyte];
- if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR)
- dest[u+2] = translation[tbyte];
- if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR)
- dest[u+3] = translation[tbyte];
- if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR)
- dest[u+4] = translation[tbyte];
- if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR)
- dest[u+5] = translation[tbyte];
- if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR)
- dest[u+6] = translation[tbyte];
- if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR)
- dest[u+7] = translation[tbyte];
- }
- dest += vid.rowbytes;
- source += pic->width;
+ }else{ // unwound
+ for(v=0; v<pic->height; v++){
+ for(u=0; u<pic->width; u+=8){
+ if((tbyte = source[u]) != TRANSPARENT_COLOR)
+ dest[u] = translation[tbyte];
+ if((tbyte = source[u+1]) != TRANSPARENT_COLOR)
+ dest[u+1] = translation[tbyte];
+ if((tbyte = source[u+2]) != TRANSPARENT_COLOR)
+ dest[u+2] = translation[tbyte];
+ if((tbyte = source[u+3]) != TRANSPARENT_COLOR)
+ dest[u+3] = translation[tbyte];
+ if((tbyte = source[u+4]) != TRANSPARENT_COLOR)
+ dest[u+4] = translation[tbyte];
+ if((tbyte = source[u+5]) != TRANSPARENT_COLOR)
+ dest[u+5] = translation[tbyte];
+ if((tbyte = source[u+6]) != TRANSPARENT_COLOR)
+ dest[u+6] = translation[tbyte];
+ if((tbyte = source[u+7]) != TRANSPARENT_COLOR)
+ dest[u+7] = translation[tbyte];
}
- }
- }
- else
- {
- // FIXME: pretranslate at load time?
- pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
-
- for (v=0 ; v<pic->height ; v++)
- {
- for (u=0 ; u<pic->width ; u++)
- {
- tbyte = source[u];
-
- if (tbyte != TRANSPARENT_COLOR)
- {
- pusdest[u] = d_8to16table[tbyte];
- }
- }
-
- pusdest += vid.rowbytes >> 1;
+ dest += vid.rowbytes;
source += pic->width;
}
}
@@ -628,7 +459,6 @@
{
int x, y, v;
byte *src, *dest;
- unsigned short *pusdest;
int f, fstep;
qpic_t *conback;
char ver[100];
@@ -653,56 +483,20 @@
Draw_CharToConback (ver[x], dest+(x<<3));
// draw the pic
- if (r_pixbytes == 1)
- {
- dest = vid.conbuffer;
-
- for (y=0 ; y<lines ; y++, dest += vid.conrowbytes)
- {
- v = (vid.conheight - lines + y)*200/vid.conheight;
- src = conback->data + v*320;
- if (vid.conwidth == 320)
- memcpy (dest, src, vid.conwidth);
- else
- {
- f = 0;
- fstep = 320*0x10000/vid.conwidth;
- for (x=0 ; x<vid.conwidth ; x+=4)
- {
- dest[x] = src[f>>16];
- f += fstep;
- dest[x+1] = src[f>>16];
- f += fstep;
- dest[x+2] = src[f>>16];
- f += fstep;
- dest[x+3] = src[f>>16];
- f += fstep;
- }
- }
- }
- }
- else
- {
- pusdest = (unsigned short *)vid.conbuffer;
-
- for (y=0 ; y<lines ; y++, pusdest += (vid.conrowbytes >> 1))
- {
- // FIXME: pre-expand to native format?
- // FIXME: does the endian switching go away in production?
- v = (vid.conheight - lines + y)*200/vid.conheight;
- src = conback->data + v*320;
+ dest = vid.conbuffer;
+ for(y=0; y<lines; y++, dest += vid.conrowbytes){
+ v = (vid.conheight - lines + y) * 200 / vid.conheight;
+ src = conback->data + v * 320;
+ if(vid.conwidth == 320)
+ memcpy(dest, src, vid.conwidth);
+ else{
f = 0;
- fstep = 320*0x10000/vid.conwidth;
- for (x=0 ; x<vid.conwidth ; x+=4)
- {
- pusdest[x] = d_8to16table[src[f>>16]];
- f += fstep;
- pusdest[x+1] = d_8to16table[src[f>>16]];
- f += fstep;
- pusdest[x+2] = d_8to16table[src[f>>16]];
- f += fstep;
- pusdest[x+3] = d_8to16table[src[f>>16]];
- f += fstep;
+ fstep = 320 * 0x10000 / vid.conwidth;
+ for(x=0; x<vid.conwidth; x+=4){
+ dest[x] = src[f>>16]; f += fstep;
+ dest[x+1] = src[f>>16]; f += fstep;
+ dest[x+2] = src[f>>16]; f += fstep;
+ dest[x+3] = src[f>>16]; f += fstep;
}
}
}
@@ -759,66 +553,7 @@
}
}
-
/*
-==============
-R_DrawRect16
-==============
-*/
-void R_DrawRect16 (vrect_t *prect, int rowbytes, byte *psrc,
- int transparent)
-{
- byte t;
- int i, j, srcdelta, destdelta;
- unsigned short *pdest;
-
-// FIXME: would it be better to pre-expand native-format versions?
-
- pdest = (unsigned short *)vid.buffer +
- (prect->y * (vid.rowbytes >> 1)) + prect->x;
-
- srcdelta = rowbytes - prect->width;
- destdelta = (vid.rowbytes >> 1) - prect->width;
-
- if (transparent)
- {
- for (i=0 ; i<prect->height ; i++)
- {
- for (j=0 ; j<prect->width ; j++)
- {
- t = *psrc;
- if (t != TRANSPARENT_COLOR)
- {
- *pdest = d_8to16table[t];
- }
-
- psrc++;
- pdest++;
- }
-
- psrc += srcdelta;
- pdest += destdelta;
- }
- }
- else
- {
- for (i=0 ; i<prect->height ; i++)
- {
- for (j=0 ; j<prect->width ; j++)
- {
- *pdest = d_8to16table[*psrc];
- psrc++;
- pdest++;
- }
-
- psrc += srcdelta;
- pdest += destdelta;
- }
- }
-}
-
-
-/*
=============
Draw_TileClear
@@ -869,16 +604,7 @@
psrc = r_rectdesc.ptexbytes +
(tileoffsety * r_rectdesc.rowbytes) + tileoffsetx;
-
- if (r_pixbytes == 1)
- {
- R_DrawRect8 (&vr, r_rectdesc.rowbytes, psrc, 0);
- }
- else
- {
- R_DrawRect16 (&vr, r_rectdesc.rowbytes, psrc, 0);
- }
-
+ R_DrawRect8 (&vr, r_rectdesc.rowbytes, psrc, 0);
vr.x += vr.width;
width -= vr.width;
tileoffsetx = 0; // only the left tile can be left-clipped
@@ -901,8 +627,6 @@
void Draw_Fill (int x, int y, int w, int h, int c)
{
byte *dest;
- unsigned short *pusdest;
- unsigned uc;
int u, v;
if (x < 0 || x + w > vid.width ||
@@ -912,22 +636,10 @@
return;
}
- if (r_pixbytes == 1)
- {
- dest = vid.buffer + y*vid.rowbytes + x;
- for (v=0 ; v<h ; v++, dest += vid.rowbytes)
- for (u=0 ; u<w ; u++)
- dest[u] = c;
- }
- else
- {
- uc = d_8to16table[c];
-
- pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
- for (v=0 ; v<h ; v++, pusdest += (vid.rowbytes >> 1))
- for (u=0 ; u<w ; u++)
- pusdest[u] = uc;
- }
+ dest = vid.buffer + y*vid.rowbytes + x;
+ for(v=0; v<h; v++, dest+=vid.rowbytes)
+ for(u=0; u<w; u++)
+ dest[u] = c;
}
//=============================================================================
@@ -942,10 +654,6 @@
int x,y;
byte *pbuf;
- VID_UnlockBuffer ();
- S_ExtraUpdate ();
- VID_LockBuffer ();
-
for (y=0 ; y<vid.height ; y++)
{
int t;
@@ -959,10 +667,6 @@
pbuf[x] = 0;
}
}
-
- VID_UnlockBuffer ();
- S_ExtraUpdate ();
- VID_LockBuffer ();
}
//=============================================================================
--- a/qw/in.c
+++ b/qw/in.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <stdio.h>
+#include <bio.h>
#include <draw.h>
#include <thread.h>
#include <mouse.h>
@@ -7,47 +8,60 @@
#include <keyboard.h>
#include "quakedef.h"
-/* vid_9.c */
+/* vid.c */
extern int resized;
extern Point center;
+extern Rectangle grabr;
-cvar_t m_windowed = {"m_windowed", "0", true};
-
-static cvar_t m_filter = {"m_filter", "0", true};
-
-static int mouseon, oldmwin;
-static float mx, my, oldmx, oldmy;
-static int mb, oldmb;
-
typedef struct Kev Kev;
+
+enum{
+ Nbuf = 20
+};
struct Kev{
int key;
int down;
};
-enum{
- Nbuf = 64
-};
-static Channel *kchan;
+static Channel *inchan;
+static QLock mlck;
+cvar_t m_windowed = {"m_windowed", "0", true};
+static cvar_t m_filter = {"m_filter", "0", true};
+static int mouseon, fixms;
+static int oldmwin;
+static float olddx, olddy;
+static int mΔx, mΔy, mb, oldmb;
void
-IN_Grabm(int on)
+conscmd(void)
{
- static char nocurs[2*4+2*2*16];
- static int fd = -1;
+ char *p;
- if(mouseon == on)
+ if(cls.state != ca_dedicated)
return;
- if(mouseon = on && m_windowed.value){
- if((fd = open("/dev/cursor", ORDWR|OCEXEC)) < 0){
- fprint(2, "IN_Grabm:open: %r\n");
- return;
+ while(p = nbrecvp(inchan), p != nil){
+ Cbuf_AddText(p);
+ free(p);
+ }
+}
+
+static void
+cproc(void *)
+{
+ char *s;
+ Biobuf *bf;
+
+ if(bf = Bfdopen(0, OREAD), bf == nil)
+ sysfatal("Bfdopen: %r");
+ for(;;){
+ if(s = Brdstr(bf, '\n', 1), s == nil)
+ break;
+ if(sendp(inchan, s) < 0){
+ free(s);
+ break;
}
- write(fd, nocurs, sizeof nocurs);
- }else if(fd >= 0){
- close(fd);
- fd = -1;
}
+ Bterm(bf);
}
void
@@ -56,62 +70,69 @@
Kev ev;
int r;
- if(kchan == nil)
+ if(cls.state == ca_dedicated)
return;
-
if(oldmwin != (int)m_windowed.value){
oldmwin = (int)m_windowed.value;
IN_Grabm(oldmwin);
}
- while((r = nbrecv(kchan, &ev)) > 0)
+ while(r = nbrecv(inchan, &ev), r > 0)
Key_Event(ev.key, ev.down);
if(r < 0)
- fprint(2, "Sys_SendKeyEvents:nbrecv: %r\n");
+ fprint(2, "Sys_SendKeyEvents: %r\n");
}
void
IN_Commands(void)
{
- int i;
+ int b, i, k, r;
- if(!mouseon)
+ if(!mouseon || cls.state == ca_dedicated)
return;
-
- /* FIXMEGASHIT */
- for(i = 0; i < 3; i++){
- if(mb & 1<<i && ~oldmb & 1<<i)
- Key_Event(K_MOUSE1+i, true);
- if (~mb & 1<<i && oldmb & 1<<i)
- Key_Event(K_MOUSE1+i, false);
+ qlock(&mlck);
+ b = mb;
+ qunlock(&mlck);
+ b = b & 0x19 | (b & 2) << 1 | (b & 4) >> 1;
+ for(i=0, k=K_MOUSE1; i<5; i++, k++){
+ if(i == 3)
+ k = K_MWHEELUP;
+ r = b & 1<<i;
+ if(r ^ oldmb & 1<<i)
+ Key_Event(k, r);
}
- oldmb = mb;
+ oldmb = b & 7;
}
void
IN_Move(usercmd_t *cmd)
{
+ float dx, dy;
+
if(!mouseon)
return;
-
+ qlock(&mlck);
+ dx = mΔx;
+ dy = mΔy;
+ mΔx = 0;
+ mΔy = 0;
+ qunlock(&mlck);
if(m_filter.value){
- mx = (mx + oldmx) * 0.5;
- my = (my + oldmy) * 0.5;
+ dx = (dx + olddx) * 0.5;
+ dy = (dy + olddy) * 0.5;
}
- oldmx = mx;
- oldmy = my;
- mx *= sensitivity.value;
- my *= sensitivity.value;
-
+ olddx = dx;
+ olddy = dy;
+ dx *= sensitivity.value;
+ dy *= sensitivity.value;
if(in_strafe.state & 1 || lookstrafe.value && in_mlook.state & 1)
- cmd->sidemove += m_side.value * mx;
+ cmd->sidemove += m_side.value * dx;
else
- cl.viewangles[YAW] -= m_yaw.value * mx;
+ cl.viewangles[YAW] -= m_yaw.value * dx;
if(in_mlook.state & 1)
V_StopPitchDrift();
-
if(in_mlook.state & 1 && ~in_strafe.state & 1){
- cl.viewangles[PITCH] += m_pitch.value * my;
+ cl.viewangles[PITCH] += m_pitch.value * dy;
if(cl.viewangles[PITCH] > 80)
cl.viewangles[PITCH] = 80;
if(cl.viewangles[PITCH] < -70)
@@ -118,11 +139,10 @@
cl.viewangles[PITCH] = -70;
}else{
if(in_strafe.state & 1 && noclip_anglehack)
- cmd->upmove -= m_forward.value * my;
+ cmd->upmove -= m_forward.value * dy;
else
- cmd->forwardmove -= m_forward.value * my;
+ cmd->forwardmove -= m_forward.value * dy;
}
- mx = my = 0.0;
}
static int
@@ -173,15 +193,17 @@
kproc(void *)
{
int n, k, fd;
- char buf[128], kdown[128], *s;
+ char buf[256], kdown[128], *s, *p;
Rune r;
- Kev ev;
+ Kev ev, evc;
- threadsetgrp(THin);
-
- if((fd = open("/dev/kbd", OREAD)) < 0)
+ fd = open("/dev/kbd", OREAD);
+ if(fd < 0)
sysfatal("open /dev/kbd: %r");
- kdown[0] = kdown[1] = buf[0] = 0;
+ memset(buf, 0, sizeof buf);
+ memset(kdown, 0, sizeof kdown);
+ evc.key = K_ENTER;
+ evc.down = true;
for(;;){
if(buf[0] != 0){
n = strlen(buf)+1;
@@ -188,48 +210,43 @@
memmove(buf, buf+n, sizeof(buf)-n);
}
if(buf[0] == 0){
- n = read(fd, buf, sizeof(buf)-1);
- if(n <= 0)
+ if(n = read(fd, buf, sizeof(buf)-1), n <= 0)
break;
buf[n-1] = 0;
buf[n] = 0;
}
- switch(*buf){
+ switch(buf[0]){
case 'c':
+ if(send(inchan, &evc) < 0)
+ threadexits(nil);
default:
continue;
case 'k':
+ ev.down = true;
s = buf+1;
- while(*s){
- s += chartorune(&r, s);
- if(utfrune(kdown+1, r) == nil){
- if(k = runetokey(r)){
- ev.key = k;
- ev.down = true;
- if(nbsend(kchan, &ev) < 0)
- fprint(2, "kproc:nbsend: %r\n");
- }
- }
- }
+ p = kdown+1;
break;
case 'K':
+ ev.down = false;
s = kdown+1;
- while(*s){
- s += chartorune(&r, s);
- if(utfrune(buf+1, r) == nil){
- if(k = runetokey(r)){
- ev.key = k;
- ev.down = false;
- if(nbsend(kchan, &ev) < 0)
- fprint(2, "kproc:nbsend: %r\n");
- }
- }
- }
+ p = buf+1;
break;
}
+ while(*s != 0){
+ s += chartorune(&r, s);
+ if(utfrune(p, r) == nil){
+ k = runetokey(r);
+ if(k == 0)
+ continue;
+ ev.key = k;
+ if(send(inchan, &ev) < 0)
+ threadexits(nil);
+ if(ev.down)
+ evc.key = k;
+ }
+ }
strcpy(kdown, buf);
}
- close(fd);
}
static void
@@ -237,19 +254,18 @@
{
int b, n, nerr, fd;
char buf[1+5*12];
- float x, y;
+ Point p, o;
- threadsetgrp(THin);
-
- if((fd = open("/dev/mouse", ORDWR)) < 0)
+ fd = open("/dev/mouse", ORDWR);
+ if(fd < 0)
sysfatal("open /dev/mouse: %r");
-
nerr = 0;
+ o = center;
for(;;){
- if((n = read(fd, buf, sizeof buf)) != 1+4*12){
- fprint(2, "mproc:read: bad count %d not 49: %r\n", n);
+ if(n = read(fd, buf, sizeof buf), n != 1+4*12){
if(n < 0 || ++nerr > 10)
break;
+ fprint(2, "mproc: bad count %d not 49: %r\n", n);
continue;
}
nerr = 0;
@@ -260,47 +276,75 @@
case 'm':
if(!mouseon)
break;
-
- x = atoi(buf+1+0*12) - center.x;
- y = atoi(buf+1+1*12) - center.y;
+ if(fixms){
+ fixms = 0;
+ goto res;
+ }
+ p.x = atoi(buf+1+0*12);
+ p.y = atoi(buf+1+1*12);
b = atoi(buf+1+2*12);
-
- mx += x;
- my += y;
- if(x != 0.0 || y != 0.0)
+ qlock(&mlck);
+ mΔx += p.x - o.x;
+ mΔy += p.y - o.y;
+ mb = b;
+ qunlock(&mlck);
+ if(!ptinrect(p, grabr)){
+ res:
fprint(fd, "m%d %d", center.x, center.y);
-
- mb = b&1 | (b&2)<<1 | (b&4)>>1;
+ p = center;
+ }
+ o = p;
break;
}
}
- close(fd);
}
void
+IN_Grabm(int on)
+{
+ static char nocurs[2*4+2*2*16];
+ static int fd = -1;
+
+ if(mouseon == on)
+ return;
+ if(mouseon = on && m_windowed.value){
+ fd = open("/dev/cursor", ORDWR|OCEXEC);
+ if(fd < 0){
+ fprint(2, "IN_Grabm:open: %r\n");
+ return;
+ }
+ write(fd, nocurs, sizeof nocurs);
+ fixms++;
+ }else if(fd >= 0){
+ close(fd);
+ fd = -1;
+ }
+}
+
+void
IN_Shutdown(void)
{
- threadkillgrp(THin);
+ if(inchan != nil)
+ chanfree(inchan);
IN_Grabm(0);
- if(kchan != nil){
- chanfree(kchan);
- kchan = nil;
- }
}
void
IN_Init(void)
{
+ if(cls.state == ca_dedicated){
+ if(inchan = chancreate(sizeof(void *), 2), inchan == nil)
+ sysfatal("chancreate: %r");
+ if(proccreate(cproc, nil, 8192) < 0)
+ sysfatal("proccreate iproc: %r");
+ return;
+ }
Cvar_RegisterVariable(&m_windowed);
Cvar_RegisterVariable(&m_filter);
- if((kchan = chancreate(sizeof(Kev), Nbuf)) == nil)
- sysfatal("chancreate kchan: %r");
+ if(inchan = chancreate(sizeof(Kev), Nbuf), inchan == nil)
+ sysfatal("chancreate: %r");
if(proccreate(kproc, nil, 8192) < 0)
sysfatal("proccreate kproc: %r");
- if(COM_CheckParm("-nomouse"))
- return;
if(proccreate(mproc, nil, 8192) < 0)
sysfatal("proccreate mproc: %r");
- mx = my = 0.0;
- IN_Grabm(0);
}
--- a/qw/keys.c
+++ b/qw/keys.c
@@ -639,14 +639,14 @@
// update auto-repeat status
if (down)
{
- key_repeats[key]++;
- if (key != K_BACKSPACE
- && key != K_PAUSE
- && key != K_PGUP
- && key != K_PGDN
- && key_repeats[key] > 1)
- return; // ignore most autorepeats
-
+ if(key != K_MWHEELUP && key != K_MWHEELDOWN)
+ key_repeats[key]++;
+ /* ignore cons event immediately following kbd down event */
+ if(key_repeats[key] == 2)
+ return;
+ if(key_repeats[key] > 2 && (key == K_ESCAPE || key == K_ENTER
+ || key == '`' || key_dest == key_game))
+ return;
if (key >= 200 && !keybindings[key])
Con_Printf ("%s is unbound, hit F4 to set.\n", Key_KeynumToString (key) );
}
--- a/qw/menu.c
+++ b/qw/menu.c
@@ -299,13 +299,13 @@
break;
case K_DOWNARROW:
- S_LocalSound ("misc/menu1.wav");
+ localsfx ("misc/menu1.wav");
if (++m_main_cursor >= MAIN_ITEMS)
m_main_cursor = 0;
break;
case K_UPARROW:
- S_LocalSound ("misc/menu1.wav");
+ localsfx ("misc/menu1.wav");
if (--m_main_cursor < 0)
m_main_cursor = MAIN_ITEMS - 1;
break;
@@ -358,7 +358,7 @@
void M_AdjustSliders (int dir)
{
- S_LocalSound ("misc/menu3.wav");
+ localsfx ("misc/menu3.wav");
switch (options_cursor)
{
@@ -561,7 +561,7 @@
return;
case K_UPARROW:
- S_LocalSound ("misc/menu1.wav");
+ localsfx ("misc/menu1.wav");
options_cursor--;
if (options_cursor < 0)
options_cursor = OPTIONS_ITEMS-1;
@@ -568,7 +568,7 @@
break;
case K_DOWNARROW:
- S_LocalSound ("misc/menu1.wav");
+ localsfx ("misc/menu1.wav");
options_cursor++;
if (options_cursor >= OPTIONS_ITEMS)
options_cursor = 0;
@@ -726,7 +726,7 @@
if (bind_grab)
{ // defining a key
- S_LocalSound ("misc/menu1.wav");
+ localsfx ("misc/menu1.wav");
if (k != '`')
{
sprintf (cmd, "bind %s \"%s\"\n", Key_KeynumToString (k), bindnames[keys_cursor][0]);
@@ -745,7 +745,7 @@
case K_LEFTARROW:
case K_UPARROW:
- S_LocalSound ("misc/menu1.wav");
+ localsfx ("misc/menu1.wav");
keys_cursor--;
if (keys_cursor < 0)
keys_cursor = NUMCOMMANDS-1;
@@ -753,7 +753,7 @@
case K_DOWNARROW:
case K_RIGHTARROW:
- S_LocalSound ("misc/menu1.wav");
+ localsfx ("misc/menu1.wav");
keys_cursor++;
if (keys_cursor >= NUMCOMMANDS)
keys_cursor = 0;
@@ -761,7 +761,7 @@
case K_ENTER: // go into bind mode
M_FindKeysForCommand (bindnames[keys_cursor][0], keys);
- S_LocalSound ("misc/menu2.wav");
+ localsfx ("misc/menu2.wav");
if (keys[1] != -1)
M_UnbindCommand (bindnames[keys_cursor][0]);
bind_grab = true;
@@ -769,7 +769,7 @@
case K_BACKSPACE: // delete bindings
case K_DEL: // delete bindings
- S_LocalSound ("misc/menu2.wav");
+ localsfx ("misc/menu2.wav");
M_UnbindCommand (bindnames[keys_cursor][0]);
break;
}
@@ -1055,12 +1055,7 @@
scr_copyeverything = 1;
if (scr_con_current)
- {
Draw_ConsoleBackground (vid.height);
- VID_UnlockBuffer ();
- S_ExtraUpdate ();
- VID_LockBuffer ();
- }
else
Draw_FadeScreen ();
@@ -1147,13 +1142,9 @@
if (m_entersound)
{
- S_LocalSound ("misc/menu2.wav");
+ localsfx ("misc/menu2.wav");
m_entersound = false;
}
-
- VID_UnlockBuffer ();
- S_ExtraUpdate ();
- VID_LockBuffer ();
}
--- a/qw/mkfile
+++ b/qw/mkfile
@@ -6,7 +6,6 @@
qwsv\
CLOBJ=\
- cd.$O\
cl_cam.$O\
cl_demo.$O\
cl_ents.$O\
@@ -63,9 +62,6 @@
screen.$O\
skin.$O\
snd.$O\
- snd_dma.$O\
- snd_mem.$O\
- snd_mix.$O\
sys.$O\
vid.$O\
view.$O\
--- a/qw/model.c
+++ b/qw/model.c
@@ -1325,33 +1325,13 @@
void * Mod_LoadAliasSkin (void * pin, int *pskinindex, int skinsize,
aliashdr_t *pheader)
{
- int i;
byte *pskin, *pinskin;
- unsigned short *pusskin;
pskin = Hunk_AllocName (skinsize * r_pixbytes, loadname);
pinskin = (byte *)pin;
*pskinindex = (byte *)pskin - (byte *)pheader;
-
- if (r_pixbytes == 1)
- {
- memcpy (pskin, pinskin, skinsize);
- }
- else if (r_pixbytes == 2)
- {
- pusskin = (unsigned short *)pskin;
-
- for (i=0 ; i<skinsize ; i++)
- pusskin[i] = d_8to16table[pinskin[i]];
- }
- else
- {
- Sys_Error ("Mod_LoadAliasSkin: driver set invalid r_pixbytes: %d\n",
- r_pixbytes);
- }
-
+ memcpy (pskin, pinskin, skinsize);
pinskin += skinsize;
-
return ((void *)pinskin);
}
@@ -1673,9 +1653,7 @@
{
dspriteframe_t *pinframe;
mspriteframe_t *pspriteframe;
- int i, width, height, size, origin[2];
- unsigned short *ppixout;
- byte *ppixin;
+ int width, height, size, origin[2];
pinframe = (dspriteframe_t *)pin;
@@ -1698,25 +1676,7 @@
pspriteframe->down = origin[1] - height;
pspriteframe->left = origin[0];
pspriteframe->right = width + origin[0];
-
- if (r_pixbytes == 1)
- {
- memcpy (&pspriteframe->pixels[0], (byte *)(pinframe + 1), size);
- }
- else if (r_pixbytes == 2)
- {
- ppixin = (byte *)(pinframe + 1);
- ppixout = (unsigned short *)&pspriteframe->pixels[0];
-
- for (i=0 ; i<size ; i++)
- ppixout[i] = d_8to16table[ppixin[i]];
- }
- else
- {
- Sys_Error ("Mod_LoadSpriteFrame: driver set invalid r_pixbytes: %d\n",
- r_pixbytes);
- }
-
+ memcpy (&pspriteframe->pixels[0], (byte *)(pinframe + 1), size);
return (void *)((byte *)pinframe + sizeof (dspriteframe_t) + size);
}
--- a/qw/qwcl.c
+++ b/qw/qwcl.c
@@ -19,11 +19,8 @@
static void
croak(void *, char *note)
{
- if(!strncmp(note, "sys:", 4)){
- IN_Shutdown();
- SNDDMA_Shutdown();
- NET_Shutdown();
- }
+ if(!strncmp(note, "sys:", 4))
+ IN_Grabm(0);
noted(NDFLT);
}
--- a/qw/r_edge.c
+++ b/qw/r_edge.c
@@ -688,10 +688,6 @@
// the next scan
if (span_p > max_span_p)
{
- VID_UnlockBuffer ();
- S_ExtraUpdate (); // don't let sound get messed up if going slow
- VID_LockBuffer ();
-
if (r_drawculledpolys)
R_DrawCulledPolys ();
else
--- a/qw/r_main.c
+++ b/qw/r_main.c
@@ -900,13 +900,6 @@
db_time2 = Sys_DoubleTime ();
se_time1 = db_time2;
}
-
- if (!r_dspeeds.value)
- {
- VID_UnlockBuffer ();
- S_ExtraUpdate (); // don't let sound get messed up if going slow
- VID_LockBuffer ();
- }
if (!(r_drawpolys | r_drawculledpolys))
R_ScanEdges ();
@@ -945,22 +938,8 @@
if (!r_worldentity.model || !cl.worldmodel)
Sys_Error ("R_RenderView: NULL worldmodel");
-
- if (!r_dspeeds.value)
- {
- VID_UnlockBuffer ();
- S_ExtraUpdate (); // don't let sound get messed up if going slow
- VID_LockBuffer ();
- }
R_EdgeDrawing ();
-
- if (!r_dspeeds.value)
- {
- VID_UnlockBuffer ();
- S_ExtraUpdate (); // don't let sound get messed up if going slow
- VID_LockBuffer ();
- }
if (r_dspeeds.value)
{
--- a/qw/r_sky.c
+++ b/qw/r_sky.c
@@ -180,48 +180,6 @@
}
}
-
-/*
-=================
-R_GenSkyTile16
-=================
-*/
-void R_GenSkyTile16 (void *pdest)
-{
- int x, y;
- int ofs, baseofs;
- int xshift, yshift;
- byte *pnewsky;
- unsigned short *pd;
-
- xshift = skytime * skyspeed;
- yshift = skytime * skyspeed;
-
- pnewsky = (byte *)&newsky[0];
- pd = (unsigned short *)pdest;
-
- for (y=0 ; y<SKYSIZE ; y++)
- {
- baseofs = ((y+yshift) & SKYMASK) * 131;
-
-// FIXME: clean this up
-// FIXME: do faster unaligned version?
- for (x=0 ; x<SKYSIZE ; x++)
- {
- ofs = baseofs + ((x+xshift) & SKYMASK);
-
- *pd = d_8to16table[(*(pnewsky + 128) &
- *(byte *)&bottommask[ofs]) |
- *(byte *)&bottomsky[ofs]];
- pnewsky++;
- pd++;
- }
-
- pnewsky += TILE_SIZE;
- }
-}
-
-
/*
=============
R_SetSkyFrame
--- a/qw/r_surf.c
+++ b/qw/r_surf.c
@@ -575,35 +575,8 @@
}
}
-
/*
================
-R_GenTurbTile16
-================
-*/
-void R_GenTurbTile16 (pixel_t *pbasetex, void *pdest)
-{
- int *turb;
- int i, j, s, t;
- unsigned short *pd;
-
- turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
- pd = (unsigned short *)pdest;
-
- for (i=0 ; i<TILE_SIZE ; i++)
- {
- for (j=0 ; j<TILE_SIZE ; j++)
- {
- s = (((j << 16) + turb[i & (CYCLE-1)]) >> 16) & 63;
- t = (((i << 16) + turb[j & (CYCLE-1)]) >> 16) & 63;
- *pd++ = d_8to16table[*(pbasetex + (t<<6) + s)];
- }
- }
-}
-
-
-/*
-================
R_GenTile
================
*/
@@ -611,27 +584,12 @@
{
if (psurf->flags & SURF_DRAWTURB)
{
- if (r_pixbytes == 1)
- {
- R_GenTurbTile ((pixel_t *)
- ((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest);
- }
- else
- {
- R_GenTurbTile16 ((pixel_t *)
- ((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest);
- }
+ R_GenTurbTile((pixel_t *)
+ ((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest);
}
else if (psurf->flags & SURF_DRAWSKY)
{
- if (r_pixbytes == 1)
- {
- R_GenSkyTile (pdest);
- }
- else
- {
- R_GenSkyTile16 (pdest);
- }
+ R_GenSkyTile(pdest);
}
else
{
--- a/qw/screen.c
+++ b/qw/screen.c
@@ -930,8 +930,6 @@
scr_drawdialog = true;
SCR_UpdateScreen ();
scr_drawdialog = false;
-
- S_ClearBuffer (); // so dma doesn't loop current sound
do
{
@@ -1128,7 +1126,7 @@
vrect.pnext = 0;
VID_Update (&vrect);
- }
+ }
}
/*
--- a/qw/snd.c
+++ b/qw/snd.c
@@ -1,113 +1,987 @@
#include <u.h>
#include <libc.h>
#include <stdio.h>
-#include <thread.h>
#include "quakedef.h"
-static int afd, sndon;
-static uint wpos;
+cvar_t bgmvolume = {"bgmvolume", "1", 1};
+cvar_t volume = {"volume", "0.7", 1};
+
+typedef struct Chan Chan;
+
enum{
- Nbuf = 16
+ Te9 = 1000000000,
+ Fpsmin = 10,
+ Fpsmax = 72,
+ Srate = 44100,
+ Ssize = 2,
+ Sch = 2,
+ Sblk = Ssize * Sch,
+ Ssamp = Srate / Fpsmin,
+ Snbuf = Ssamp * Sblk,
+ Nchan = 128,
+ Ndyn = 8,
+ Sstat = Ndyn + NUM_AMBIENTS
};
-static Channel *schan;
-static QLock sndlock;
+static float Clipdist = 1000.0;
+struct Chan{
+ sfx_t *sfx;
+ int chvol;
+ int lvol;
+ int rvol;
+ vec_t attf;
+ vec3_t zp;
+ int entn;
+ int entch;
+ int p;
+ int n;
+};
+static Chan chans[Nchan], *che;
+static int afd = -1;
+static uchar mixbuf[Snbuf];
+static vlong sndt;
+static int nsamp;
+static int sampbuf[Ssamp*Sch*sizeof(int)];
+static int scalt[32][256];
+
+static sfx_t *ambsfx[NUM_AMBIENTS];
+
+static char cdfile[13];
+static int ntrk;
+static int cdfd = -1;
+static int cdread, cdloop, cdvol;
+
+typedef struct
+{
+ int length;
+ int speed;
+ int width;
+ int stereo;
+ int loop;
+ byte data[1]; // variable sized
+} sfxcache_t;
+
+typedef struct
+{
+ int rate;
+ int width;
+ int channels;
+ int loopofs;
+ int samples;
+ int dataofs;
+} wavinfo_t;
+
+static vec3_t listener_origin;
+static vec3_t listener_forward;
+static vec3_t listener_right;
+static vec3_t listener_up;
+#define MAX_SFX 512
+static sfx_t *known_sfx; // hunk allocated [MAX_SFX]
+static int num_sfx;
+
+static cvar_t precache = {"precache", "1"};
+static cvar_t loadas8bit = {"loadas8bit", "0"};
+static cvar_t ambient_level = {"ambient_level", "0.3"};
+static cvar_t ambient_fade = {"ambient_fade", "100"};
+
+static byte *data_p;
+static byte *iff_end;
+static byte *last_chunk;
+static byte *iff_data;
+
+// QuakeWorld hack...
+#define viewentity playernum+1
+
+/* TODO: refuctor wav loading */
static void
-sproc(void *)
+resample(sfxcache_t *sc, byte *data, float stepscale)
{
- int n;
+ int inwidth;
+ int outcount;
+ int srcsample;
+ int i;
+ int sample, samplefrac, fracstep;
- threadsetgrp(THsnd);
+ inwidth = sc->width;
+ outcount = sc->length / stepscale;
+ sc->length = outcount;
+ sc->speed = Srate;
+ if (loadas8bit.value)
+ sc->width = 1;
+ else
+ sc->width = inwidth;
+ sc->stereo = 0;
- for(;;){
- if(recv(schan, nil) < 0)
- break;
- if((n = write(afd, shm->buffer, shm->samplebits/8 * shm->samples)) < 0)
- break;
- qlock(&sndlock);
- wpos += n;
- qunlock(&sndlock);
+ if (stepscale == 1 && inwidth == 1 && sc->width == 1)
+ {
+// fast special case
+ for (i=0 ; i<outcount ; i++)
+ ((signed char *)sc->data)[i]
+ = (int)( (unsigned char)(data[i]) - 128);
}
- fprint(2, "sproc %d: %r\n", threadpid(threadid()));
+ else
+ {
+// general case
+ samplefrac = 0;
+ fracstep = stepscale*256;
+ for (i=0 ; i<outcount ; i++)
+ {
+ srcsample = samplefrac >> 8;
+ samplefrac += fracstep;
+ if (inwidth == 2)
+ sample = LittleShort ( ((short *)data)[srcsample] );
+ else
+ sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8;
+ if (sc->width == 2)
+ ((short *)sc->data)[i] = sample;
+ else
+ ((signed char *)sc->data)[i] = sample >> 8;
+ }
+ }
}
-qboolean
-SNDDMA_Init(void)
+static short
+GetLittleShort(void)
{
- int i;
+ short val;
- sndon = 0;
+ val = *data_p;
+ val = val + (*(data_p+1)<<8);
+ data_p += 2;
+ return val;
+}
- if((afd = open("/dev/audio", OWRITE)) < 0){
- fprint(2, "open: %r\n");
- return 0;
+static int
+GetLittleLong(void)
+{
+ int val;
+
+ val = *data_p;
+ val = val + (*(data_p+1)<<8);
+ val = val + (*(data_p+2)<<16);
+ val = val + (*(data_p+3)<<24);
+ data_p += 4;
+ return val;
+}
+
+static void
+FindNextChunk(char *name)
+{
+ int iff_chunk_len;
+
+ while (1)
+ {
+ data_p=last_chunk;
+
+ if (data_p >= iff_end)
+ { // didn't find the chunk
+ data_p = nil;
+ return;
+ }
+
+ data_p += 4;
+ iff_chunk_len = GetLittleLong();
+ if (iff_chunk_len < 0)
+ {
+ data_p = nil;
+ return;
+ }
+// if (iff_chunk_len > 1024*1024)
+// Sys_Error ("FindNextChunk: %d length is past the 1 meg sanity limit", iff_chunk_len);
+ data_p -= 8;
+ last_chunk = data_p + 8 + ( (iff_chunk_len + 1) & ~1 );
+ if(strncmp((char *)data_p, name, 4) == 0)
+ return;
}
+}
- shm = &sn;
- shm->splitbuffer = 0;
+static void
+FindChunk(char *name)
+{
+ last_chunk = iff_data;
+ FindNextChunk (name);
+}
- if((i = COM_CheckParm("-sndbits")) != 0)
- shm->samplebits = atoi(com_argv[i+1]);
- if(shm->samplebits != 16 && shm->samplebits != 8)
- shm->samplebits = 16;
+static wavinfo_t
+GetWavinfo(char *name, byte *wav, vlong wavlength)
+{
+ wavinfo_t info;
+ int i;
+ int format;
+ int samples;
- if((i = COM_CheckParm("-sndspeed")) != 0)
- shm->speed = atoi(com_argv[i+1]);
+ memset(&info, 0, sizeof info);
+
+ if (!wav)
+ return info;
+
+ iff_data = wav;
+ iff_end = wav + wavlength;
+
+// find "RIFF" chunk
+ FindChunk("RIFF");
+ if(!(data_p && strncmp((char *)data_p+8, "WAVE", 4) == 0))
+ {
+ Con_Printf("Missing RIFF/WAVE chunks\n");
+ return info;
+ }
+
+// get "fmt " chunk
+ iff_data = data_p + 12;
+
+ FindChunk("fmt ");
+ if (!data_p)
+ {
+ Con_Printf("Missing fmt chunk\n");
+ return info;
+ }
+ data_p += 8;
+ format = GetLittleShort();
+ if (format != 1)
+ {
+ Con_Printf("Microsoft PCM format only\n");
+ return info;
+ }
+
+ info.channels = GetLittleShort();
+ info.rate = GetLittleLong();
+ data_p += 4+2;
+ info.width = GetLittleShort() / 8;
+
+// get cue chunk
+ FindChunk("cue ");
+ if (data_p)
+ {
+ data_p += 32;
+ info.loopofs = GetLittleLong();
+
+ // if the next chunk is a LIST chunk, look for a cue length marker
+ FindNextChunk ("LIST");
+ if (data_p)
+ {
+ if(strncmp((char *)data_p+28, "mark", 4) == 0)
+ { // this is not a proper parse, but it works with cooledit...
+ data_p += 24;
+ i = GetLittleLong (); // samples in loop
+ info.samples = info.loopofs + i;
+// Con_Printf("looped length: %d\n", i);
+ }
+ }
+ }
else
- shm->speed = 44100;
+ info.loopofs = -1;
- shm->channels = 2;
- if(COM_CheckParm("-sndmono") != 0)
- shm->channels = 1;
+// find data chunk
+ FindChunk("data");
+ if (!data_p)
+ {
+ Con_Printf("Missing data chunk\n");
+ return info;
+ }
- shm->samples = 4096;
- shm->submission_chunk = 1;
+ data_p += 4;
+ samples = GetLittleLong () / info.width;
- if((shm->buffer = mallocz(shm->samplebits/8 * shm->samples, 1)) == nil)
- sysfatal("SNDDMA_Init:mallocz: %r\n");
- shm->samplepos = 0;
- sndon = 1;
- wpos = 0;
- if((schan = chancreate(sizeof(int), Nbuf)) == nil)
- sysfatal("SNDDMA_Init:chancreate: %r");
- if(proccreate(sproc, nil, 8192) < 0)
- sysfatal("SNDDMA_Init:proccreate: %r");
- return 1;
+ if (info.samples)
+ {
+ if (samples < info.samples)
+ Sys_Error ("Sound %s has a bad loop length", name);
+ }
+ else
+ info.samples = samples;
+
+ info.dataofs = data_p - wav;
+
+ return info;
}
-int
-SNDDMA_GetDMAPos(void)
+static sfxcache_t *
+loadsfx(sfx_t *sfx)
{
- if(!sndon)
- return 0;
- qlock(&sndlock);
- shm->samplepos = wpos / (shm->samplebits/8);
- qunlock(&sndlock);
- return shm->samplepos;
+ wavinfo_t info;
+ int len;
+ float stepscale;
+ sfxcache_t *sc;
+ uchar *u, buf[1024]; /* avoid dirtying the cache heap */
+
+ if(sc = Cache_Check(&sfx->cache), sc != nil)
+ return sc;
+ u = COM_LoadStackFile(va("sound/%s", sfx->name), buf, sizeof buf);
+ if(u == nil){
+ fprint(2, "loadsfx: %r\n");
+ return nil;
+ }
+ info = GetWavinfo(sfx->name, u, com_filesize);
+ if(info.channels != 1){
+ fprint(2, "loadsfx: non mono wave %s\n", sfx->name);
+ return nil;
+ }
+ stepscale = (float)info.rate / Srate;
+ len = info.samples / stepscale;
+ len *= info.width * info.channels;
+ if(sc = Cache_Alloc(&sfx->cache, len + sizeof *sc, sfx->name), sc == nil)
+ return nil;
+ sc->length = info.samples;
+ sc->loop = info.loopofs;
+ if(info.loopofs >= 0)
+ sc->loop /= stepscale;
+ sc->speed = info.rate;
+ sc->width = info.width;
+ sc->stereo = info.channels;
+ resample(sc, u + info.dataofs, stepscale);
+ return sc;
}
void
-SNDDMA_Shutdown(void)
+stepcd(void)
{
- if(!sndon)
+ cdvol = bgmvolume.value * 256;
+ cdread = cdfd >= 0 && cdvol > 0;
+}
+
+static void
+sndout(void)
+{
+ int v, vol, *pb, *pe;
+ uchar *p;
+
+ vol = volume.value * 256;
+ p = mixbuf;
+ pb = sampbuf;
+ pe = sampbuf + nsamp * 2;
+ while(pb < pe){
+ v = (short)(p[1] << 8 | p[0]) * cdvol >> 8;
+ v += *pb++ * vol >> 8;
+ if(v > 0x7fff)
+ v = 0x7fff;
+ else if(v < -0x8000)
+ v = -0x8000;
+ p[0] = v;
+ p[1] = v >> 8;
+ p += 2;
+ }
+}
+
+static void
+sample8(Chan *c, void *d, int n)
+{
+ int v, *pb, *pe, *ls, *rs;
+ uchar *p;
+
+ if(c->lvol > 255)
+ c->lvol = 255;
+ if(c->rvol > 255)
+ c->rvol = 255;
+ ls = scalt[c->lvol >> 3];
+ rs = scalt[c->rvol >> 3];
+ p = (uchar *)d + c->p;
+ pb = sampbuf;
+ pe = sampbuf + n * 2;
+ while(pb < pe){
+ v = *p++;
+ *pb++ += ls[v];
+ *pb++ += rs[v];
+ }
+}
+
+static void
+sample16(Chan *c, void *d, int n)
+{
+ int v, *pb, *pe, lv, rv;
+ short *p;
+
+ lv = c->lvol;
+ rv = c->rvol;
+ p = (short *)d + c->p;
+ pb = sampbuf;
+ pe = sampbuf + n * 2;
+ while(pb < pe){
+ v = *p++;
+ *pb++ += v * lv >> 8;
+ *pb++ += v * rv >> 8;
+ }
+}
+
+static void
+samplesfx(void)
+{
+ int n, m;
+ Chan *c;
+ sfxcache_t *sc;
+ void (*sf)(Chan *, void *, int);
+
+ memset(sampbuf, 0, sizeof sampbuf);
+ for(c=chans; c<che; c++){
+ if(c->sfx == nil)
+ continue;
+ if(c->lvol == 0 && c->rvol == 0)
+ continue;
+ if(sc = loadsfx(c->sfx), sc == nil)
+ continue;
+ sf = sc->width == 1 ? sample8 : sample16;
+ n = nsamp;
+ while(n > 0){
+ m = n < c->n ? n : c->n;
+ if(m > 0)
+ sf(c, sc->data, m);
+ c->p += m;
+ c->n -= m;
+ n -= m;
+ if(c->n <= 0){
+ if(sc->loop >= 0){
+ c->p = sc->loop;
+ c->n = sc->length - c->p;
+ }else{
+ c->sfx = nil;
+ break;
+ }
+ }
+ }
+ }
+ sndout();
+}
+
+void
+stopcd(void)
+{
+ if(cdfd >= 0)
+ close(cdfd);
+ cdread = 0;
+ cdloop = 0;
+}
+
+void
+pausecd(void)
+{
+ cdread = 0;
+}
+
+void
+resumecd(void)
+{
+ cdread = 1;
+}
+
+static void
+readcd(int ns)
+{
+ int n;
+
+ if(cdfd < 0 || !cdread)
return;
+ if(n = readn(cdfd, mixbuf, ns), n != ns){
+ if(n < 0 || !cdloop)
+ stopcd();
+ else{
+ seek(cdfd, 0, 0);
+ ns -= n;
+ if(n = readn(cdfd, mixbuf+n, ns), n != ns)
+ stopcd();
+ }
+ }
+}
- threadkillgrp(THsnd);
- close(afd);
- free(shm->buffer);
- if(schan != nil){
- chanfree(schan);
- schan = nil;
+static void
+spatialize(Chan *c)
+{
+ vec_t Δr, m;
+ vec3_t src;
+
+ if(c->entn == cl.viewentity){
+ c->lvol = c->chvol;
+ c->rvol = c->chvol;
+ return;
}
- sndon = 0;
+ VectorSubtract(c->zp, listener_origin, src);
+ Δr = 1.0 - VectorNormalize(src) * c->attf;
+ m = DotProduct(listener_right, src);
+ c->rvol = Δr * (1.0 + m) * c->chvol;
+ if(c->rvol < 0)
+ c->rvol = 0;
+ c->lvol = Δr * (1.0 - m) * c->chvol;
+ if(c->lvol < 0)
+ c->lvol = 0;
}
+static void
+ambs(void)
+{
+ uchar *av;
+ float vol;
+ Chan *c, *e;
+ mleaf_t *l;
+ sfx_t **sfx;
+
+ if(cl.worldmodel == nil)
+ return;
+ c = chans;
+ e = chans + NUM_AMBIENTS;
+ l = Mod_PointInLeaf(listener_origin, cl.worldmodel);
+ if(l == nil || !ambient_level.value){
+ while(c < e)
+ c++->sfx = nil;
+ return;
+ }
+ sfx = ambsfx;
+ av = l->ambient_sound_level;
+ while(c < e){
+ c->sfx = *sfx++;
+ vol = ambient_level.value * *av++;
+ if(vol < 8)
+ vol = 0;
+ if(c->chvol < vol){
+ c->chvol += host_frametime * ambient_fade.value;
+ if(c->chvol > vol)
+ c->chvol = vol;
+ }else if(c->chvol > vol){
+ c->chvol -= host_frametime * ambient_fade.value;
+ if(c->chvol < vol)
+ c->chvol = vol;
+ }
+ c->lvol = c->chvol;
+ c->rvol = c->chvol;
+ c++;
+ }
+}
+
void
-SNDDMA_Submit(void)
+stepsnd(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
{
- if(nbsend(schan, nil) < 0){
- fprint(2, "SNDDMA_Submit:nbsend: %r\n");
- SNDDMA_Shutdown();
+ int ns;
+ Chan *c, *sum;
+
+ if(afd < 0)
+ return;
+ VectorCopy(origin, listener_origin);
+ VectorCopy(forward, listener_forward);
+ VectorCopy(right, listener_right);
+ VectorCopy(up, listener_up);
+ ambs();
+ sum = nil;
+ for(c=chans+NUM_AMBIENTS; c<che; c++){
+ if(c->sfx == nil)
+ continue;
+ spatialize(c);
+ if(c->lvol == 0 && c->rvol == 0)
+ continue;
+ /* sum static sounds to avoid useless remixing */
+ if(c >= chans + Sstat){
+ if(sum != nil && sum->sfx == c->sfx){
+ sum->lvol += c->lvol;
+ sum->rvol += c->rvol;
+ c->lvol = c->rvol = 0;
+ continue;
+ }
+ for(sum=chans + Sstat; sum<c; sum++)
+ if(sum->sfx == c->sfx)
+ break;
+ if(sum == che)
+ sum = nil;
+ else if(sum != c){
+ sum->lvol += c->lvol;
+ sum->rvol += c->rvol;
+ c->lvol = c->rvol = 0;
+ }
+ }
}
+ if(sndt == 0)
+ sndt = nsec() - Te9 / Fpsmax;
+ nsamp = (nsec() - sndt) / (Te9 / Srate);
+ if(!cls.timedemo)
+ nsamp = nsamp + 15 & ~15;
+ if(nsamp > Ssamp)
+ nsamp = Ssamp;
+ ns = nsamp * Sblk;
+ memset(mixbuf, 0, ns);
+ readcd(ns);
+ samplesfx();
+ if(write(afd, mixbuf, ns) != ns){
+ fprint(2, "sndwrite: %r\n");
+ shutsnd();
+ }
+ sndt = nsec();
+}
+
+void
+startcd(int nt, int loop)
+{
+ if(ntrk < 1)
+ return;
+ nt -= 1; /* d001 assumed part of track list */
+ if(nt < 1 || nt > ntrk){
+ fprint(2, "startcd: invalid track number %d\n", nt);
+ return;
+ }
+ if(cdfd = open(va("%s%03d", cdfile, nt), OREAD), cdfd < 0){
+ fprint(2, "startcd: open: %r\n");
+ return;
+ }
+ cdloop = loop;
+ if(cdvol > 0)
+ cdread = 1;
+}
+
+void
+stopallsfx(void)
+{
+ if(afd < 0)
+ return;
+ memset(chans, 0, sizeof chans);
+ che = chans + Sstat;
+}
+
+void
+stopsfx(int n, int ch)
+{
+ Chan *c, *e;
+
+ if(afd < 0)
+ return;
+ c = chans;
+ e = chans + Ndyn;
+ while(c < e){
+ if(c->entn == n && c->entch == ch){
+ c->sfx = nil;
+ return;
+ }
+ c++;
+ }
+}
+
+static Chan *
+pickchan(int entn, int entch)
+{
+ int Δt;
+ Chan *c, *p, *e;
+
+ p = nil;
+ Δt = 0x7fffffff;
+ for(c=chans+NUM_AMBIENTS, e=c+Ndyn; c<e; c++){
+ if(entch != 0 && c->entn == entn
+ && (c->entch == entch || entch == -1)){
+ p = c;
+ break;
+ }
+ if(c->entn == cl.viewentity && entn != cl.viewentity && c->sfx != nil)
+ continue;
+ if(c->n < Δt){
+ Δt = c->n;
+ p = c;
+ }
+ }
+ if(p != nil)
+ p->sfx = nil;
+ return p;
+}
+
+void
+startsfx(int entn, int entch, sfx_t *sfx, vec3_t zp, float vol, float att)
+{
+ int skip;
+ Chan *c, *c2, *e;
+ sfxcache_t *sc;
+
+ if(afd < 0 || sfx == nil)
+ return;
+ if(c = pickchan(entn, entch), c == nil)
+ return;
+ memset(c, 0, sizeof *c);
+ VectorCopy(zp, c->zp);
+ c->attf = att / Clipdist;
+ c->chvol = vol * 255;
+ c->entn = entn;
+ c->entch = entch;
+ spatialize(c);
+ if(c->lvol == 0 && c->rvol == 0)
+ return;
+ if(sc = loadsfx(sfx), sc == nil)
+ return;
+ c->sfx = sfx;
+ c->p = 0;
+ c->n = sc->length;
+ /* don't sum identical sfx started on the same frame */
+ for(c2=chans+NUM_AMBIENTS, e=chans+Sstat; c2<e; c2++){
+ if(c2 == c || c2->sfx != sfx || c2->p != 0)
+ continue;
+ skip = nrand(Srate / Fpsmin);
+ if(skip >= c->n)
+ skip = c->n - 1;
+ c->p += skip;
+ c->n -= skip;
+ break;
+ }
+}
+
+void
+localsfx(char *s)
+{
+ sfx_t *sfx;
+
+ if(afd < 0)
+ return;
+ sfx = precachesfx(s);
+ startsfx(cl.viewentity, -1, sfx, vec3_origin, 1, 1);
+}
+
+void
+staticsfx(sfx_t *sfx, vec3_t zp, float vol, float att)
+{
+ Chan *c;
+ sfxcache_t *sc;
+
+ if(sfx == nil)
+ return;
+ if(che >= chans + nelem(chans)){
+ fprint(2, "staticsfx: channel overflow\n");
+ return;
+ }
+ c = che++;
+ if(sc = loadsfx(sfx), sc == nil)
+ return;
+ if(sc->loop < 0){
+ fprint(2, "staticsfx %s: nonlooped static sound\n", sfx->name);
+ return;
+ }
+ c->sfx = sfx;
+ VectorCopy(zp, c->zp);
+ c->chvol = vol;
+ c->attf = (att / 64) / Clipdist;
+ c->n = sc->length;
+ spatialize(c);
+}
+
+static sfx_t *
+findsfx(char *s)
+{
+ sfx_t *sfx, *e;
+
+ if(s == nil)
+ Sys_Error("findsfx: nil pointer\n");
+ if(strlen(s) >= MAX_QPATH)
+ Sys_Error("findsfx: path too long %s", s);
+ sfx = known_sfx;
+ e = known_sfx + num_sfx;
+ while(sfx < e){
+ if(strcmp(sfx->name, s) == 0)
+ return sfx;
+ sfx++;
+ }
+ if(num_sfx == MAX_SFX)
+ Sys_Error("findsfx: sfx list overflow");
+ strcpy(sfx->name, s);
+ num_sfx++;
+ return sfx;
+}
+
+void
+touchsfx(char *s)
+{
+ sfx_t *sfx;
+
+ if(afd < 0)
+ return;
+ sfx = findsfx(s);
+ Cache_Check(&sfx->cache);
+}
+
+sfx_t *
+precachesfx(char *s)
+{
+ sfx_t *sfx;
+
+ if(afd < 0)
+ return nil;
+ sfx = findsfx(s);
+ if(precache.value)
+ loadsfx(sfx);
+ return sfx;
+}
+
+static void
+cdcmd(void)
+{
+ char *c;
+
+ if(Cmd_Argc() < 2){
+usage:
+ Con_Printf("cd (play|loop|stop|pause|resume|info) [track]\n");
+ return;
+ }
+ c = Cmd_Argv(1);
+ if(cistrcmp(c, "play") == 0){
+ if(Cmd_Argc() < 2)
+ goto usage;
+ startcd(atoi(Cmd_Argv(2)), 0);
+ }else if(cistrcmp(c, "loop") == 0){
+ if(Cmd_Argc() < 2)
+ goto usage;
+ startcd(atoi(Cmd_Argv(2)), 1);
+ }else if(cistrcmp(c, "stop") == 0)
+ stopcd();
+ else if(cistrcmp(c, "pause") == 0)
+ pausecd();
+ else if(cistrcmp(c, "resume") == 0)
+ resumecd();
+}
+
+static void
+playsfx(void)
+{
+ static int hash = 345;
+ int i;
+ char *s;
+ sfx_t *sfx;
+
+ if(Cmd_Argc() < 2){
+ Con_Printf("play wav [wav..]: play a wav lump\n");
+ return;
+ }
+ i = 1;
+ while(i < Cmd_Argc()){
+ if(strrchr(Cmd_Argv(i), '.') == nil)
+ s = va("%s.wav", Cmd_Argv(i));
+ else
+ s = Cmd_Argv(i);
+ sfx = precachesfx(s);
+ startsfx(hash++, 0, sfx, listener_origin, 1.0, 1.0);
+ i++;
+ }
+}
+
+static void
+playvolsfx(void)
+{
+ static int hash = 543;
+ int i;
+ float vol;
+ char *s;
+ sfx_t *sfx;
+
+ if(Cmd_Argc() < 3){
+ Con_Printf("play wav vol [wav vol]..: play an amplified wav lump\n");
+ return;
+ }
+ i = 1;
+ while(i < Cmd_Argc()){
+ if(strrchr(Cmd_Argv(i), '.') == nil)
+ s = va("%s.wav", Cmd_Argv(i));
+ else
+ s = Cmd_Argv(i);
+ sfx = precachesfx(s);
+ vol = atof(Cmd_Argv(++i));
+ startsfx(hash++, 0, sfx, listener_origin, vol, 1.0);
+ i++;
+ }
+}
+
+static void
+sfxlist(void)
+{
+ char c;
+ int sz, sum;
+ sfx_t *sfx, *e;
+ sfxcache_t *sc;
+
+ sum = 0;
+ for(sfx=known_sfx, e=known_sfx+num_sfx; sfx<e; sfx++){
+ if(sc = Cache_Check(&sfx->cache), sc == nil)
+ continue;
+ sz = sc->length * sc->width * (sc->stereo + 1);
+ sum += sz;
+ c = sc->loop >= 0 ? 'L' : ' ';
+ Con_Printf("%c(%2db) %6d : %s\n", c, sc->width * 8, sz, sfx->name);
+ }
+ Con_Printf("Total resident: %d\n", sum);
+}
+
+void
+shutcd(void)
+{
+ stopcd();
+}
+
+void
+shutsnd(void)
+{
+ if(afd < 0)
+ return;
+ close(afd);
+}
+
+static int
+cdinfo(void)
+{
+ int fd, i, n, nt;
+ char *t, types[] = {'a', 'u', 0};
+ Dir *d;
+
+ ntrk = 0;
+ if(fd = open("/mnt/cd", OREAD), fd < 0)
+ return -1;
+ if(n = dirreadall(fd, &d), n < 0){
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ t = types;
+ for(;;){
+ for(nt=0, i=0; i<n; i++)
+ if(strcmp(d[i].name, va("%c%03d", *t, ntrk+1)) == 0){
+ ntrk++;
+ nt = 1;
+ }
+ if(ntrk < 1){
+ if(*++t == 0){
+ werrstr("cdinfo: no tracks found");
+ break;
+ }
+ }else if(nt == 0){
+ snprint(cdfile, sizeof cdfile, "/mnt/cd/%c", *t);
+ break;
+ }
+ }
+ free(d);
+ return ntrk < 1 ? -1 : 0;
+}
+
+int
+initcd(void)
+{
+ if(cdinfo() < 0)
+ return -1;
+ Cmd_AddCommand("cd", cdcmd);
+ return 0;
+}
+
+int
+initsnd(quakeparms_t *q)
+{
+ int i, j, *p;
+
+ if(afd = open("/dev/audio", OWRITE), afd < 0)
+ return -1;
+ for(p=scalt[1], i=8; i<8*nelem(scalt); i+=8)
+ for(j=0; j<256; j++)
+ *p++ = (char)j * i;
+ Cmd_AddCommand("play", playsfx);
+ Cmd_AddCommand("playvol", playvolsfx);
+ Cmd_AddCommand("stopsound", stopallsfx);
+ Cmd_AddCommand("soundlist", sfxlist);
+ Cvar_RegisterVariable(&volume);
+ Cvar_RegisterVariable(&precache);
+ Cvar_RegisterVariable(&loadas8bit);
+ Cvar_RegisterVariable(&bgmvolume);
+ Cvar_RegisterVariable(&ambient_level);
+ Cvar_RegisterVariable(&ambient_fade);
+ if(q->memsize < 0x800000){
+ Cvar_Set("loadas8bit", "1");
+ fprint(2, "initsnd: forcing 8bit width\n");
+ }
+ known_sfx = Hunk_AllocName(MAX_SFX * sizeof *known_sfx, "sfx_t");
+ num_sfx = 0;
+ ambsfx[AMBIENT_WATER] = precachesfx("ambience/water1.wav");
+ ambsfx[AMBIENT_SKY] = precachesfx("ambience/wind2.wav");
+ stopallsfx();
+ return 0;
}
--- a/qw/snd_dma.c
+++ /dev/null
@@ -1,924 +1,0 @@
-// snd_dma.c -- main control for any streaming sound output device
-
-#include <u.h>
-#include <libc.h>
-#include <stdio.h>
-#include "quakedef.h"
-
-void S_Play(void);
-void S_PlayVol(void);
-void S_SoundList(void);
-void S_Update_(void);
-void S_StopAllSounds(qboolean clear);
-void S_StopAllSoundsC(void);
-
-// QuakeWorld hack...
-#define viewentity playernum+1
-
-// =======================================================================
-// Internal sound data & structures
-// =======================================================================
-
-channel_t channels[MAX_CHANNELS];
-int total_channels;
-
-int snd_blocked = 0;
-static qboolean snd_ambient = 1;
-qboolean snd_initialized = false;
-
-// pointer should go away
-volatile dma_t *shm = 0;
-volatile dma_t sn;
-
-vec3_t listener_origin;
-vec3_t listener_forward;
-vec3_t listener_right;
-vec3_t listener_up;
-vec_t sound_nominal_clip_dist=1000.0;
-
-int soundtime; // sample PAIRS
-int paintedtime; // sample PAIRS
-
-
-#define MAX_SFX 512
-sfx_t *known_sfx; // hunk allocated [MAX_SFX]
-int num_sfx;
-
-sfx_t *ambient_sfx[NUM_AMBIENTS];
-
-int desired_speed = 11025;
-int desired_bits = 16;
-
-int sound_started=0;
-
-cvar_t bgmvolume = {"bgmvolume", "1", true};
-cvar_t volume = {"volume", "0.7", true};
-
-cvar_t nosound = {"nosound", "0"};
-cvar_t precache = {"precache", "1"};
-cvar_t loadas8bit = {"loadas8bit", "0"};
-cvar_t bgmbuffer = {"bgmbuffer", "4096"};
-cvar_t ambient_level = {"ambient_level", "0.3"};
-cvar_t ambient_fade = {"ambient_fade", "100"};
-cvar_t snd_noextraupdate = {"snd_noextraupdate", "0"};
-cvar_t snd_show = {"snd_show", "0"};
-cvar_t _snd_mixahead = {"_snd_mixahead", "0.1", true};
-
-
-// ====================================================================
-// User-setable variables
-// ====================================================================
-
-
-//
-// Fake dma is a synchronous faking of the DMA progress used for
-// isolating performance in the renderer. The fakedma_updates is
-// number of times S_Update() is called per second.
-//
-
-qboolean fakedma = false;
-int fakedma_updates = 15;
-
-
-void S_AmbientOff (void)
-{
- snd_ambient = false;
-}
-
-
-void S_AmbientOn (void)
-{
- snd_ambient = true;
-}
-
-
-void S_SoundInfo_f(void)
-{
- if (!sound_started || !shm)
- {
- Con_Printf ("sound system not started\n");
- return;
- }
-
- Con_Printf("%5d stereo\n", shm->channels - 1);
- Con_Printf("%5d samples\n", shm->samples);
- Con_Printf("%5d samplepos\n", shm->samplepos);
- Con_Printf("%5d samplebits\n", shm->samplebits);
- Con_Printf("%5d submission_chunk\n", shm->submission_chunk);
- Con_Printf("%5d speed\n", shm->speed);
- Con_Printf("0x%x dma buffer\n", shm->buffer);
- Con_Printf("%5d total_channels\n", total_channels);
-}
-
-
-/*
-================
-S_Startup
-================
-*/
-
-void S_Startup (void)
-{
- int rc;
-
- if (!snd_initialized)
- return;
-
- if (!fakedma)
- {
- rc = SNDDMA_Init();
-
- if (!rc)
- {
- Con_Printf("S_Startup: SNDDMA_Init failed.\n");
- sound_started = 0;
- return;
- }
- }
-
- sound_started = 1;
-}
-
-
-/*
-================
-S_Init
-================
-*/
-void S_Init (void)
-{
-
-// Con_Printf("\nSound Initialization\n");
-
- if (COM_CheckParm("-nosound"))
- return;
-
- if (COM_CheckParm("-simsound"))
- fakedma = true;
-
- Cmd_AddCommand("play", S_Play);
- Cmd_AddCommand("playvol", S_PlayVol);
- Cmd_AddCommand("stopsound", S_StopAllSoundsC);
- Cmd_AddCommand("soundlist", S_SoundList);
- Cmd_AddCommand("soundinfo", S_SoundInfo_f);
-
- Cvar_RegisterVariable(&nosound);
- Cvar_RegisterVariable(&volume);
- Cvar_RegisterVariable(&precache);
- Cvar_RegisterVariable(&loadas8bit);
- Cvar_RegisterVariable(&bgmvolume);
- Cvar_RegisterVariable(&bgmbuffer);
- Cvar_RegisterVariable(&ambient_level);
- Cvar_RegisterVariable(&ambient_fade);
- Cvar_RegisterVariable(&snd_noextraupdate);
- Cvar_RegisterVariable(&snd_show);
- Cvar_RegisterVariable(&_snd_mixahead);
-
- if (host_parms.memsize < 0x800000)
- {
- Cvar_Set ("loadas8bit", "1");
- Con_Printf ("loading all sounds as 8bit\n");
- }
-
-
-
- snd_initialized = true;
-
- S_Startup ();
-
- SND_InitScaletable ();
-
- known_sfx = Hunk_AllocName (MAX_SFX*sizeof(sfx_t), "sfx_t");
- num_sfx = 0;
-
-// create a piece of DMA memory
-
- if (fakedma)
- {
- shm = (void *) Hunk_AllocName(sizeof(*shm), "shm");
- shm->splitbuffer = 0;
- shm->samplebits = 16;
- shm->speed = 22050;
- shm->channels = 2;
- shm->samples = 32768;
- shm->samplepos = 0;
- shm->soundalive = true;
- shm->gamealive = true;
- shm->submission_chunk = 1;
- shm->buffer = Hunk_AllocName(1<<16, "shmbuf");
- }
-
-// Con_Printf ("Sound sampling rate: %i\n", shm->speed);
-
- // provides a tick sound until washed clean
-
-// if (shm->buffer)
-// shm->buffer[4] = shm->buffer[5] = 0x7f; // force a pop for debugging
-
- ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav");
- ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav");
-
- S_StopAllSounds (true);
-}
-
-
-// =======================================================================
-// Shutdown sound engine
-// =======================================================================
-
-void S_Shutdown(void)
-{
-
- if(!sound_started)
- return;
-
- if(shm != nil)
- shm->gamealive = 0;
-
- if(!fakedma)
- SNDDMA_Shutdown();
- shm = 0;
- sound_started = 0;
-}
-
-
-// =======================================================================
-// Load a sound
-// =======================================================================
-
-/*
-==================
-S_FindName
-
-==================
-*/
-sfx_t *S_FindName (char *name)
-{
- int i;
- sfx_t *sfx;
-
- if(name == nil)
- Sys_Error ("S_FindName: NULL\n");
-
- if(strlen(name) >= MAX_QPATH)
- Sys_Error ("Sound name too long: %s", name);
-
-// see if already loaded
- for (i=0 ; i < num_sfx ; i++)
- if(!strcmp(known_sfx[i].name, name))
- return &known_sfx[i];
-
- if (num_sfx == MAX_SFX)
- Sys_Error ("S_FindName: out of sfx_t");
-
- sfx = &known_sfx[i];
- strcpy (sfx->name, name);
-
- num_sfx++;
-
- return sfx;
-}
-
-
-/*
-==================
-S_TouchSound
-
-==================
-*/
-void S_TouchSound (char *name)
-{
- sfx_t *sfx;
-
- if (!sound_started)
- return;
-
- sfx = S_FindName (name);
- Cache_Check (&sfx->cache);
-}
-
-/*
-==================
-S_PrecacheSound
-
-==================
-*/
-sfx_t *S_PrecacheSound (char *name)
-{
- sfx_t *sfx;
-
- if (!sound_started || nosound.value)
- return NULL;
-
- sfx = S_FindName (name);
-
-// cache it in
- if (precache.value)
- S_LoadSound (sfx);
-
- return sfx;
-}
-
-
-//=============================================================================
-
-/*
-=================
-SND_PickChannel
-=================
-*/
-channel_t *SND_PickChannel(int entnum, int entchannel)
-{
- int ch_idx;
- int first_to_die;
- int life_left;
-
-// Check for replacement sound, or find the best one to replace
- first_to_die = -1;
- life_left = 0x7fffffff;
- for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++)
- {
- if (entchannel != 0 // channel 0 never overrides
- && channels[ch_idx].entnum == entnum
- && (channels[ch_idx].entchannel == entchannel || entchannel == -1) )
- { // allways override sound from same entity
- first_to_die = ch_idx;
- break;
- }
-
- // don't let monster sounds override player sounds
- if (channels[ch_idx].entnum == cl.viewentity && entnum != cl.viewentity && channels[ch_idx].sfx)
- continue;
-
- if (channels[ch_idx].end - paintedtime < life_left)
- {
- life_left = channels[ch_idx].end - paintedtime;
- first_to_die = ch_idx;
- }
- }
-
- if (first_to_die == -1)
- return NULL;
-
- if (channels[first_to_die].sfx)
- channels[first_to_die].sfx = NULL;
-
- return &channels[first_to_die];
-}
-
-/*
-=================
-SND_Spatialize
-=================
-*/
-void SND_Spatialize(channel_t *ch)
-{
- vec_t dot;
- vec_t dist;
- vec_t lscale, rscale, scale;
- vec3_t source_vec;
-
-// anything coming from the view entity will allways be full volume
- if (ch->entnum == cl.viewentity)
- {
- ch->leftvol = ch->master_vol;
- ch->rightvol = ch->master_vol;
- return;
- }
-
-// calculate stereo seperation and distance attenuation
-
- VectorSubtract(ch->origin, listener_origin, source_vec);
-
- dist = VectorNormalize(source_vec) * ch->dist_mult;
-
- dot = DotProduct(listener_right, source_vec);
-
- if (shm->channels == 1)
- {
- rscale = 1.0;
- lscale = 1.0;
- }
- else
- {
- rscale = 1.0 + dot;
- lscale = 1.0 - dot;
- }
-
-// add in distance effect
- scale = (1.0 - dist) * rscale;
- ch->rightvol = (int) (ch->master_vol * scale);
- if (ch->rightvol < 0)
- ch->rightvol = 0;
-
- scale = (1.0 - dist) * lscale;
- ch->leftvol = (int) (ch->master_vol * scale);
- if (ch->leftvol < 0)
- ch->leftvol = 0;
-}
-
-
-// =======================================================================
-// Start a sound effect
-// =======================================================================
-
-void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation)
-{
- channel_t *target_chan, *check;
- sfxcache_t *sc;
- int vol;
- int ch_idx;
- int skip;
-
- if (!sound_started)
- return;
-
- if (!sfx)
- return;
-
- if (nosound.value)
- return;
-
- vol = fvol*255;
-
-// pick a channel to play on
- target_chan = SND_PickChannel(entnum, entchannel);
- if (!target_chan)
- return;
-
-// spatialize
- memset (target_chan, 0, sizeof(*target_chan));
- VectorCopy(origin, target_chan->origin);
- target_chan->dist_mult = attenuation / sound_nominal_clip_dist;
- target_chan->master_vol = vol;
- target_chan->entnum = entnum;
- target_chan->entchannel = entchannel;
- SND_Spatialize(target_chan);
-
- if (!target_chan->leftvol && !target_chan->rightvol)
- return; // not audible at all
-
-// new channel
- sc = S_LoadSound (sfx);
- if (!sc)
- {
- target_chan->sfx = NULL;
- return; // couldn't load the sound's data
- }
-
- target_chan->sfx = sfx;
- target_chan->pos = 0.0;
- target_chan->end = paintedtime + sc->length;
-
-// if an identical sound has also been started this frame, offset the pos
-// a bit to keep it from just making the first one louder
- check = &channels[NUM_AMBIENTS];
- for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++, check++)
- {
- if (check == target_chan)
- continue;
- if (check->sfx == sfx && !check->pos)
- {
- skip = rand () % (int)(0.1*shm->speed);
- if (skip >= target_chan->end)
- skip = target_chan->end - 1;
- target_chan->pos += skip;
- target_chan->end -= skip;
- break;
- }
-
- }
-}
-
-void S_StopSound(int entnum, int entchannel)
-{
- int i;
-
- for (i=0 ; i<MAX_DYNAMIC_CHANNELS ; i++)
- {
- if (channels[i].entnum == entnum
- && channels[i].entchannel == entchannel)
- {
- channels[i].end = 0;
- channels[i].sfx = NULL;
- return;
- }
- }
-}
-
-void S_StopAllSounds(qboolean clear)
-{
- int i;
-
- if (!sound_started)
- return;
-
- total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; // no statics
-
- for (i=0 ; i<MAX_CHANNELS ; i++)
- if (channels[i].sfx)
- channels[i].sfx = NULL;
-
- memset(channels, 0, MAX_CHANNELS * sizeof(channel_t));
-
- if (clear)
- S_ClearBuffer ();
-}
-
-void S_StopAllSoundsC (void)
-{
- S_StopAllSounds (true);
-}
-
-void S_ClearBuffer (void)
-{
- int clear;
-
- if (!sound_started || !shm || !shm->buffer)
- return;
-
- if (shm->samplebits == 8)
- clear = 0x80;
- else
- clear = 0;
-
- memset(shm->buffer, clear, shm->samples * shm->samplebits/8);
-}
-
-
-/*
-=================
-S_StaticSound
-=================
-*/
-void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
-{
- channel_t *ss;
- sfxcache_t *sc;
-
- if (!sfx)
- return;
-
- if (total_channels == MAX_CHANNELS)
- {
- Con_Printf ("total_channels == MAX_CHANNELS\n");
- return;
- }
-
- ss = &channels[total_channels];
- total_channels++;
-
- sc = S_LoadSound (sfx);
- if (!sc)
- return;
-
- if (sc->loopstart == -1)
- {
- Con_Printf ("Sound %s not looped\n", sfx->name);
- return;
- }
-
- ss->sfx = sfx;
- VectorCopy (origin, ss->origin);
- ss->master_vol = vol;
- ss->dist_mult = (attenuation/64) / sound_nominal_clip_dist;
- ss->end = paintedtime + sc->length;
-
- SND_Spatialize (ss);
-}
-
-
-//=============================================================================
-
-/*
-===================
-S_UpdateAmbientSounds
-===================
-*/
-void S_UpdateAmbientSounds (void)
-{
- mleaf_t *l;
- float vol;
- int ambient_channel;
- channel_t *chan;
-
- if (!snd_ambient)
- return;
-
-// calc ambient sound levels
- if (!cl.worldmodel)
- return;
-
- l = Mod_PointInLeaf (listener_origin, cl.worldmodel);
- if (!l || !ambient_level.value)
- {
- for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++)
- channels[ambient_channel].sfx = NULL;
- return;
- }
-
- for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++)
- {
- chan = &channels[ambient_channel];
- chan->sfx = ambient_sfx[ambient_channel];
-
- vol = ambient_level.value * l->ambient_sound_level[ambient_channel];
- if (vol < 8)
- vol = 0;
-
- // don't adjust volume too fast
- if (chan->master_vol < vol)
- {
- chan->master_vol += host_frametime * ambient_fade.value;
- if (chan->master_vol > vol)
- chan->master_vol = vol;
- }
- else if (chan->master_vol > vol)
- {
- chan->master_vol -= host_frametime * ambient_fade.value;
- if (chan->master_vol < vol)
- chan->master_vol = vol;
- }
-
- chan->leftvol = chan->rightvol = chan->master_vol;
- }
-}
-
-
-/*
-============
-S_Update
-
-Called once each time through the main loop
-============
-*/
-void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
-{
- int i, j;
- int total;
- channel_t *ch;
- channel_t *combine;
-
- if (!sound_started || (snd_blocked > 0))
- return;
-
- VectorCopy(origin, listener_origin);
- VectorCopy(forward, listener_forward);
- VectorCopy(right, listener_right);
- VectorCopy(up, listener_up);
-
-// update general area ambient sound sources
- S_UpdateAmbientSounds ();
-
- combine = NULL;
-
-// update spatialization for static and dynamic sounds
- ch = channels+NUM_AMBIENTS;
- for (i=NUM_AMBIENTS ; i<total_channels; i++, ch++)
- {
- if (!ch->sfx)
- continue;
- SND_Spatialize(ch); // respatialize channel
- if (!ch->leftvol && !ch->rightvol)
- continue;
-
- // try to combine static sounds with a previous channel of the same
- // sound effect so we don't mix five torches every frame
-
- if (i >= MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS)
- {
- // see if it can just use the last one
- if (combine && combine->sfx == ch->sfx)
- {
- combine->leftvol += ch->leftvol;
- combine->rightvol += ch->rightvol;
- ch->leftvol = ch->rightvol = 0;
- continue;
- }
- // search for one
- combine = channels+MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS;
- for (j=MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS ; j<i; j++, combine++)
- if (combine->sfx == ch->sfx)
- break;
-
- if (j == total_channels)
- {
- combine = NULL;
- }
- else
- {
- if (combine != ch)
- {
- combine->leftvol += ch->leftvol;
- combine->rightvol += ch->rightvol;
- ch->leftvol = ch->rightvol = 0;
- }
- continue;
- }
- }
-
-
- }
-
-//
-// debugging output
-//
- if (snd_show.value)
- {
- total = 0;
- ch = channels;
- for (i=0 ; i<total_channels; i++, ch++)
- if (ch->sfx && (ch->leftvol || ch->rightvol) )
- {
- //Con_Printf ("%3i %3i %s\n", ch->leftvol, ch->rightvol, ch->sfx->name);
- total++;
- }
-
- Con_Printf ("----(%i)----\n", total);
- }
-
-// mix some sound
- S_Update_();
-}
-
-void GetSoundtime(void)
-{
- int samplepos;
- static int buffers;
- static int oldsamplepos;
- int fullsamples;
-
- fullsamples = shm->samples / shm->channels;
-
-// it is possible to miscount buffers if it has wrapped twice between
-// calls to S_Update. Oh well.
- samplepos = SNDDMA_GetDMAPos();
-
- if (samplepos < oldsamplepos)
- {
- buffers++; // buffer wrapped
-
- if (paintedtime > 0x40000000)
- { // time to chop things off to avoid 32 bit limits
- buffers = 0;
- paintedtime = fullsamples;
- S_StopAllSounds (true);
- }
- }
- oldsamplepos = samplepos;
-
- soundtime = buffers*fullsamples + samplepos/shm->channels;
-}
-
-void S_ExtraUpdate (void)
-{
- if (snd_noextraupdate.value)
- return; // don't pollute timings
- S_Update_();
-}
-
-
-
-void S_Update_(void)
-{
- unsigned endtime;
- int samps;
-
- if (!sound_started || (snd_blocked > 0))
- return;
-
-// Updates DMA time
- GetSoundtime();
-
-// check to make sure that we haven't overshot
- if (paintedtime < soundtime)
- {
- //Con_Printf ("S_Update_ : overflow\n");
- paintedtime = soundtime;
- }
-
-// mix ahead of current position
- endtime = soundtime + _snd_mixahead.value * shm->speed;
- samps = shm->samples >> (shm->channels-1);
- if (endtime - soundtime > samps)
- endtime = soundtime + samps;
-
- S_PaintChannels (endtime);
-
- SNDDMA_Submit ();
-}
-
-/*
-===============================================================================
-
-console functions
-
-===============================================================================
-*/
-
-void S_Play(void)
-{
- static int hash=345;
- int i;
- char name[256];
- sfx_t *sfx;
-
- i = 1;
- while (i<Cmd_Argc())
- {
- if(strrchr(Cmd_Argv(i), '.') == nil)
- {
- strcpy(name, Cmd_Argv(i));
- strcat(name, ".wav");
- }
- else
- strcpy(name, Cmd_Argv(i));
- sfx = S_PrecacheSound(name);
- S_StartSound(hash++, 0, sfx, listener_origin, 1.0, 1.0);
- i++;
- }
-}
-
-void S_PlayVol(void)
-{
- static int hash=543;
- int i;
- float vol;
- char name[256];
- sfx_t *sfx;
-
- i = 1;
- while (i<Cmd_Argc())
- {
- if(strrchr(Cmd_Argv(i), '.') == nil)
- {
- strcpy(name, Cmd_Argv(i));
- strcat(name, ".wav");
- }
- else
- strcpy(name, Cmd_Argv(i));
- sfx = S_PrecacheSound(name);
- vol = Q_atof(Cmd_Argv(i+1));
- S_StartSound(hash++, 0, sfx, listener_origin, vol, 1.0);
- i+=2;
- }
-}
-
-void S_SoundList(void)
-{
- int i;
- sfx_t *sfx;
- sfxcache_t *sc;
- int size, total;
-
- total = 0;
- for (sfx=known_sfx, i=0 ; i<num_sfx ; i++, sfx++)
- {
- sc = Cache_Check (&sfx->cache);
- if (!sc)
- continue;
- size = sc->length*sc->width*(sc->stereo+1);
- total += size;
- if (sc->loopstart >= 0)
- Con_Printf ("L");
- else
- Con_Printf (" ");
- Con_Printf("(%2db) %6i : %s\n",sc->width*8, size, sfx->name);
- }
- Con_Printf ("Total resident: %i\n", total);
-}
-
-
-void S_LocalSound (char *sound)
-{
- sfx_t *sfx;
-
- if (nosound.value)
- return;
- if (!sound_started)
- return;
-
- sfx = S_PrecacheSound (sound);
- if (!sfx)
- {
- Con_Printf ("S_LocalSound: can't cache %s\n", sound);
- return;
- }
- S_StartSound (cl.viewentity, -1, sfx, vec3_origin, 1, 1);
-}
-
-
-void S_ClearPrecache (void)
-{
-}
-
-
-void S_BeginPrecaching (void)
-{
-}
-
-
-void S_EndPrecaching (void)
-{
-}
-
--- a/qw/snd_mem.c
+++ /dev/null
@@ -1,327 +1,0 @@
-// snd_mem.c: sound caching
-
-#include <u.h>
-#include <libc.h>
-#include <stdio.h>
-#include "quakedef.h"
-
-int cache_full_cycle;
-
-byte *S_Alloc (int size);
-
-/*
-================
-ResampleSfx
-================
-*/
-void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte *data)
-{
- int outcount;
- int srcsample;
- float stepscale;
- int i;
- int sample, samplefrac, fracstep;
- sfxcache_t *sc;
-
- sc = Cache_Check (&sfx->cache);
- if (!sc)
- return;
-
- stepscale = (float)inrate / shm->speed; // this is usually 0.5, 1, or 2
-
- outcount = sc->length / stepscale;
- sc->length = outcount;
- if (sc->loopstart != -1)
- sc->loopstart = sc->loopstart / stepscale;
-
- sc->speed = shm->speed;
- if (loadas8bit.value)
- sc->width = 1;
- else
- sc->width = inwidth;
- sc->stereo = 0;
-
-// resample / decimate to the current source rate
-
- if (stepscale == 1 && inwidth == 1 && sc->width == 1)
- {
-// fast special case
- for (i=0 ; i<outcount ; i++)
- ((signed char *)sc->data)[i]
- = (int)( (unsigned char)(data[i]) - 128);
- }
- else
- {
-// general case
- samplefrac = 0;
- fracstep = stepscale*256;
- for (i=0 ; i<outcount ; i++)
- {
- srcsample = samplefrac >> 8;
- samplefrac += fracstep;
- if (inwidth == 2)
- sample = LittleShort ( ((short *)data)[srcsample] );
- else
- sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8;
- if (sc->width == 2)
- ((short *)sc->data)[i] = sample;
- else
- ((signed char *)sc->data)[i] = sample >> 8;
- }
- }
-}
-
-//=============================================================================
-
-/*
-==============
-S_LoadSound
-==============
-*/
-sfxcache_t *S_LoadSound (sfx_t *s)
-{
- char namebuffer[256];
- byte *data;
- wavinfo_t info;
- int len;
- float stepscale;
- sfxcache_t *sc;
- byte stackbuf[1*1024]; // avoid dirtying the cache heap
-
-// see if still in memory
- sc = Cache_Check (&s->cache);
- if (sc)
- return sc;
-
-// Con_Printf ("S_LoadSound: %x\n", (int)stackbuf);
- // load it in
- strcpy(namebuffer, "sound/");
- strcat(namebuffer, s->name);
-
-// Con_Printf ("loading %s\n",namebuffer);
-
- data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf));
-
- if (!data)
- {
- Con_Printf ("Couldn't load %s\n", namebuffer);
- return NULL;
- }
-
- info = GetWavinfo (s->name, data, com_filesize);
- if (info.channels != 1)
- {
- Con_Printf ("%s is a stereo sample\n",s->name);
- return NULL;
- }
-
- stepscale = (float)info.rate / shm->speed;
- len = info.samples / stepscale;
-
- len = len * info.width * info.channels;
-
- sc = Cache_Alloc ( &s->cache, len + sizeof(sfxcache_t), s->name);
- if (!sc)
- return NULL;
-
- sc->length = info.samples;
- sc->loopstart = info.loopstart;
- sc->speed = info.rate;
- sc->width = info.width;
- sc->stereo = info.channels;
-
- ResampleSfx (s, sc->speed, sc->width, data + info.dataofs);
-
- return sc;
-}
-
-
-
-/*
-===============================================================================
-
-WAV loading
-
-===============================================================================
-*/
-
-
-byte *data_p;
-byte *iff_end;
-byte *last_chunk;
-byte *iff_data;
-int iff_chunk_len;
-
-
-short GetLittleShort(void)
-{
- short val;
- val = *data_p;
- val = val + (*(data_p+1)<<8);
- data_p += 2;
- return val;
-}
-
-int GetLittleLong(void)
-{
- int val;
- val = *data_p;
- val = val + (*(data_p+1)<<8);
- val = val + (*(data_p+2)<<16);
- val = val + (*(data_p+3)<<24);
- data_p += 4;
- return val;
-}
-
-void FindNextChunk(char *name)
-{
- while (1)
- {
- data_p=last_chunk;
-
- if (data_p >= iff_end)
- { // didn't find the chunk
- data_p = NULL;
- return;
- }
-
- data_p += 4;
- iff_chunk_len = GetLittleLong();
- if (iff_chunk_len < 0)
- {
- data_p = NULL;
- return;
- }
-// if (iff_chunk_len > 1024*1024)
-// Sys_Error ("FindNextChunk: %i length is past the 1 meg sanity limit", iff_chunk_len);
- data_p -= 8;
- last_chunk = data_p + 8 + ( (iff_chunk_len + 1) & ~1 );
- if (!strncmp((char *)data_p, name, 4))
- return;
- }
-}
-
-void FindChunk(char *name)
-{
- last_chunk = iff_data;
- FindNextChunk (name);
-}
-
-
-/*
-void DumpChunks(void)
-{
- char str[5];
-
- str[4] = 0;
- data_p=iff_data;
- do
- {
- memcpy (str, data_p, 4);
- data_p += 4;
- iff_chunk_len = GetLittleLong();
- Con_Printf ("0x%x : %s (%d)\n", (int)(data_p - 4), str, iff_chunk_len);
- data_p += (iff_chunk_len + 1) & ~1;
- } while (data_p < iff_end);
-}
-*/
-
-/*
-============
-GetWavinfo
-============
-*/
-wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
-{
- wavinfo_t info;
- int i;
- int format;
- int samples;
-
- memset (&info, 0, sizeof(info));
-
- if (!wav)
- return info;
-
- iff_data = wav;
- iff_end = wav + wavlength;
-
-// find "RIFF" chunk
- FindChunk("RIFF");
- if (!(data_p != nil && !strncmp((char *)data_p+8, "WAVE", 4)))
- {
- Con_Printf("Missing RIFF/WAVE chunks\n");
- return info;
- }
-
-// get "fmt " chunk
- iff_data = data_p + 12;
-// DumpChunks ();
-
- FindChunk("fmt ");
- if (!data_p)
- {
- Con_Printf("Missing fmt chunk\n");
- return info;
- }
- data_p += 8;
- format = GetLittleShort();
- if (format != 1)
- {
- Con_Printf("Microsoft PCM format only\n");
- return info;
- }
-
- info.channels = GetLittleShort();
- info.rate = GetLittleLong();
- data_p += 4+2;
- info.width = GetLittleShort() / 8;
-
-// get cue chunk
- FindChunk("cue ");
- if (data_p)
- {
- data_p += 32;
- info.loopstart = GetLittleLong();
-// Con_Printf("loopstart=%d\n", sfx->loopstart);
-
- // if the next chunk is a LIST chunk, look for a cue length marker
- FindNextChunk ("LIST");
- if (data_p)
- {
- if(!strncmp((char *)data_p+28, "mark", 4))
- { // this is not a proper parse, but it works with cooledit...
- data_p += 24;
- i = GetLittleLong (); // samples in loop
- info.samples = info.loopstart + i;
-// Con_Printf("looped length: %i\n", i);
- }
- }
- }
- else
- info.loopstart = -1;
-
-// find data chunk
- FindChunk("data");
- if (!data_p)
- {
- Con_Printf("Missing data chunk\n");
- return info;
- }
-
- data_p += 4;
- samples = GetLittleLong () / info.width;
-
- if (info.samples)
- {
- if (samples < info.samples)
- Sys_Error ("Sound %s has a bad loop length", name);
- }
- else
- info.samples = samples;
-
- info.dataofs = data_p - wav;
-
- return info;
-}
-
--- a/qw/snd_mix.c
+++ /dev/null
@@ -1,279 +1,0 @@
-// snd_mix.c -- portable code to mix sounds for snd_dma.c
-
-#include <u.h>
-#include <libc.h>
-#include <stdio.h>
-#include "quakedef.h"
-
-#define DWORD unsigned long
-
-#define PAINTBUFFER_SIZE 512
-portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE];
-int snd_scaletable[32][256];
-int *snd_p, snd_linear_count, snd_vol;
-short *snd_out;
-
-void Snd_WriteLinearBlastStereo16 (void);
-
-void Snd_WriteLinearBlastStereo16 (void)
-{
- int i;
- int val;
-
- for (i=0 ; i<snd_linear_count ; i+=2)
- {
- val = (snd_p[i]*snd_vol)>>8;
- if (val > 0x7fff)
- snd_out[i] = 0x7fff;
- else if (val < (short)0x8000)
- snd_out[i] = (short)0x8000;
- else
- snd_out[i] = val;
-
- val = (snd_p[i+1]*snd_vol)>>8;
- if (val > 0x7fff)
- snd_out[i+1] = 0x7fff;
- else if (val < (short)0x8000)
- snd_out[i+1] = (short)0x8000;
- else
- snd_out[i+1] = val;
- }
-}
-
-void S_TransferStereo16 (int endtime)
-{
- int lpos;
- int lpaintedtime;
- DWORD *pbuf;
-
- snd_vol = volume.value*256;
-
- snd_p = (int *) paintbuffer;
- lpaintedtime = paintedtime;
-
- pbuf = (DWORD *)shm->buffer;
-
- while (lpaintedtime < endtime)
- {
- // handle recirculating buffer issues
- lpos = lpaintedtime & ((shm->samples>>1)-1);
-
- snd_out = (short *) pbuf + (lpos<<1);
-
- snd_linear_count = (shm->samples>>1) - lpos;
- if (lpaintedtime + snd_linear_count > endtime)
- snd_linear_count = endtime - lpaintedtime;
-
- snd_linear_count <<= 1;
-
- // write a linear blast of samples
- Snd_WriteLinearBlastStereo16 ();
-
- snd_p += snd_linear_count;
- lpaintedtime += (snd_linear_count>>1);
- }
-}
-
-void S_TransferPaintBuffer(int endtime)
-{
- int out_idx;
- int count;
- int out_mask;
- int *p;
- int step;
- int val;
- int snd_vol;
- DWORD *pbuf;
-
- if (shm->samplebits == 16 && shm->channels == 2)
- {
- S_TransferStereo16 (endtime);
- return;
- }
-
- p = (int *) paintbuffer;
- count = (endtime - paintedtime) * shm->channels;
- out_mask = shm->samples - 1;
- out_idx = paintedtime * shm->channels & out_mask;
- step = 3 - shm->channels;
- snd_vol = volume.value*256;
-
- pbuf = (DWORD *)shm->buffer;
-
- if (shm->samplebits == 16)
- {
- short *out = (short *) pbuf;
- while (count--)
- {
- val = (*p * snd_vol) >> 8;
- p+= step;
- if (val > 0x7fff)
- val = 0x7fff;
- else if (val < (short)0x8000)
- val = (short)0x8000;
- out[out_idx] = val;
- out_idx = (out_idx + 1) & out_mask;
- }
- }
- else if (shm->samplebits == 8)
- {
- unsigned char *out = (unsigned char *) pbuf;
- while (count--)
- {
- val = (*p * snd_vol) >> 8;
- p+= step;
- if (val > 0x7fff)
- val = 0x7fff;
- else if (val < (short)0x8000)
- val = (short)0x8000;
- out[out_idx] = (val>>8) + 128;
- out_idx = (out_idx + 1) & out_mask;
- }
- }
-}
-
-
-/*
-===============================================================================
-
-CHANNEL MIXING
-
-===============================================================================
-*/
-
-void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int endtime);
-void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int endtime);
-
-void S_PaintChannels(int endtime)
-{
- int i;
- int end;
- channel_t *ch;
- sfxcache_t *sc;
- int ltime, count;
-
- while (paintedtime < endtime)
- {
- // if paintbuffer is smaller than DMA buffer
- end = endtime;
- if (endtime - paintedtime > PAINTBUFFER_SIZE)
- end = paintedtime + PAINTBUFFER_SIZE;
-
- // clear the paint buffer
- memset(paintbuffer, 0, (end - paintedtime) * sizeof(portable_samplepair_t));
-
- // paint in the channels.
- ch = channels;
- for (i=0; i<total_channels ; i++, ch++)
- {
- if (!ch->sfx)
- continue;
- if (!ch->leftvol && !ch->rightvol)
- continue;
- sc = S_LoadSound (ch->sfx);
- if (!sc)
- continue;
-
- ltime = paintedtime;
-
- while (ltime < end)
- { // paint up to end
- if (ch->end < end)
- count = ch->end - ltime;
- else
- count = end - ltime;
-
- if (count > 0)
- {
- if (sc->width == 1)
- SND_PaintChannelFrom8(ch, sc, count);
- else
- SND_PaintChannelFrom16(ch, sc, count);
-
- ltime += count;
- }
-
- // if at end of loop, restart
- if (ltime >= ch->end)
- {
- if (sc->loopstart >= 0)
- {
- ch->pos = sc->loopstart;
- ch->end = ltime + sc->length - ch->pos;
- }
- else
- { // channel just stopped
- ch->sfx = NULL;
- break;
- }
- }
- }
-
- }
-
- // transfer out according to DMA format
- S_TransferPaintBuffer(end);
- paintedtime = end;
- }
-}
-
-void SND_InitScaletable (void)
-{
- int i, j;
-
- for (i=0 ; i<32 ; i++)
- for (j=0 ; j<256 ; j++)
- snd_scaletable[i][j] = ((signed char)j) * i * 8;
-}
-
-
-void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count)
-{
- int data;
- int *lscale, *rscale;
- unsigned char *sfx;
- int i;
-
- if (ch->leftvol > 255)
- ch->leftvol = 255;
- if (ch->rightvol > 255)
- ch->rightvol = 255;
-
- lscale = snd_scaletable[ch->leftvol >> 3];
- rscale = snd_scaletable[ch->rightvol >> 3];
- sfx = (uchar *)sc->data + ch->pos;
-
- for (i=0 ; i<count ; i++)
- {
- data = sfx[i];
- paintbuffer[i].left += lscale[data];
- paintbuffer[i].right += rscale[data];
- }
-
- ch->pos += count;
-}
-
-
-void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count)
-{
- int data;
- int left, right;
- int leftvol, rightvol;
- signed short *sfx;
- int i;
-
- leftvol = ch->leftvol;
- rightvol = ch->rightvol;
- sfx = (signed short *)sc->data + ch->pos;
-
- for (i=0 ; i<count ; i++)
- {
- data = sfx[i];
- left = (data * leftvol) >> 8;
- right = (data * rightvol) >> 8;
- paintbuffer[i].left += left;
- paintbuffer[i].right += right;
- }
-
- ch->pos += count;
-}
--- a/qw/sound.h
+++ b/qw/sound.h
@@ -64,24 +64,22 @@
int dataofs; // chunk starts this many bytes from file start
} wavinfo_t;
-void S_Init (void);
+int initsnd(quakeparms_t*);
void S_Startup (void);
-void S_Shutdown (void);
-void S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation);
-void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation);
-void S_StopSound (int entnum, int entchannel);
-void S_StopAllSounds(qboolean clear);
-void S_ClearBuffer (void);
-void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up);
-void S_ExtraUpdate (void);
+void shutsnd (void);
+void startsfx (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation);
+void staticsfx (sfx_t *sfx, vec3_t origin, float vol, float attenuation);
+void stopsfx (int entnum, int entchannel);
+void stopallsfx(void);
+void stepsnd (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up);
-sfx_t *S_PrecacheSound (char *sample);
+sfx_t* precachesfx(char*);
void S_TouchSound (char *sample);
void S_ClearPrecache (void);
void S_BeginPrecaching (void);
void S_EndPrecaching (void);
void S_PaintChannels(int endtime);
-void S_InitPaintChannels (void);
+void initsndPaintChannels (void);
// picks a channel based on priorities, empty slots, number of channels
channel_t *SND_PickChannel(int entnum, int entchannel);
@@ -116,21 +114,16 @@
//
// Fake dma is a synchronous faking of the DMA progress used for
// isolating performance in the renderer. The fakedma_updates is
-// number of times S_Update() is called per second.
+// number of times stepsnd() is called per second.
//
extern qboolean fakedma;
extern int fakedma_updates;
extern int paintedtime;
-extern vec3_t listener_origin;
-extern vec3_t listener_forward;
-extern vec3_t listener_right;
-extern vec3_t listener_up;
extern volatile dma_t *shm;
extern volatile dma_t sn;
extern vec_t sound_nominal_clip_dist;
-extern cvar_t loadas8bit;
extern cvar_t bgmvolume;
extern cvar_t volume;
@@ -138,10 +131,8 @@
extern int snd_blocked;
-void S_LocalSound (char *s);
+void localsfx (char *s);
sfxcache_t *S_LoadSound (sfx_t *s);
-
-wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength);
void SND_InitScaletable (void);
void SNDDMA_Submit(void);
--- a/qw/sys.c
+++ b/qw/sys.c
@@ -6,6 +6,16 @@
int svonly;
+void *
+emalloc(ulong n)
+{
+ void *p;
+
+ if(p = mallocz(n, 1), p == nil)
+ sysfatal("emalloc %r");
+ setmalloctag(p, getcallerpc(&n));
+ return p;
+}
void
Sys_Printf(char *fmt, ...)
--- a/qw/sys.h
+++ b/qw/sys.h
@@ -27,3 +27,4 @@
void initparm(quakeparms_t *);
void killiop(void);
+void* emalloc(ulong);
--- a/qw/vid.c
+++ b/qw/vid.c
@@ -4,95 +4,80 @@
#include <stdio.h>
#include "quakedef.h"
-viddef_t vid;
-ushort d_8to16table[256];
+viddef_t vid; /* global video state */
int resized;
-Point center;
+int dumpwin, scaleon;
+Point center; /* of window */
+Rectangle grabr;
-void (*vid_menudrawfn)(void);
-void (*vid_menukeyfn)(int);
+static int scale = 1;
+static s32int fbpal[256];
+static uchar *fb, *fbs;
+static Image *fbi;
+static Rectangle fbr;
-typedef ulong PIXEL;
-
-enum{
- Rmask = 0xff0000,
- Gmask = 0xff00,
- Bmask = 0xff
-};
-static int shifton, rshift, gshift, bshift;
-static uchar *framebuf; /* draw buffer */
-static Image *fbim; /* framebuf image */
-
-static PIXEL st2d_8to16table[256];
-
-static void mkmasks(void);
-static PIXEL rgb24(int, int, int);
-static void st2_fixup(uchar *, int, int, int, int);
-static void resetfb(void);
-
-
static void
-mkmasks(void)
+scalefb(void)
{
- uint x;
+ int *p, c, *s, dy;
- for(rshift = -8, x = 1; x < Rmask; x <<= 1)
- rshift++;
- for(gshift = -8, x = 1; x < Gmask; x <<= 1)
- gshift++;
- for(bshift = -8, x = 1; x < Bmask; x <<= 1)
- bshift++;
- shifton = 1;
+ if(scale < 2)
+ return;
+ p = (s32int *)fbs;
+ s = (s32int *)fb;
+ dy = vid.height * vid.width;
+ while(dy-- > 0){
+ c = *s++;
+ switch(scale){
+ case 16: p[15] = c;
+ case 15: p[14] = c;
+ case 14: p[13] = c;
+ case 13: p[12] = c;
+ case 12: p[11] = c;
+ case 11: p[10] = c;
+ case 10: p[9] = c;
+ case 9: p[8] = c;
+ case 8: p[7] = c;
+ case 7: p[6] = c;
+ case 6: p[5] = c;
+ case 5: p[4] = c;
+ case 4: p[3] = c;
+ case 3: p[2] = c;
+ case 2: p[1] = c; p[0] = c;
+ }
+ p += scale;
+ }
}
-static PIXEL
-rgb24(int r, int g, int b)
-{
- PIXEL p = 0;
-
- if(!shifton)
- mkmasks();
-
- if(rshift > 0)
- p = r<<rshift & Rmask;
- else if(rshift < 0)
- p = r>>-rshift & Rmask;
- else
- p |= r & Rmask;
- if(gshift > 0)
- p |= g<<gshift & Gmask;
- else if(gshift < 0)
- p |= g>>-gshift & Gmask;
- else
- p |= g & Gmask;
- if(bshift > 0)
- p |= b<<bshift & Bmask;
- else if(bshift < 0)
- p |= b>>-bshift & Bmask;
- else
- p |= b & Bmask;
- return p;
-}
-
static void
-st2_fixup(uchar *data, int x, int y, int width, int height)
+drawfb(void)
{
- int xi, yi;
- uchar *src;
- PIXEL *dest;
+ uchar *s;
+ int n, dy, we, w8, wr, *d;
- if(x < 0 || y < 0)
- return;
-
- for (yi = y; yi < y+height; yi++){
- src = &data[yi*vid.rowbytes];
- dest = (PIXEL *)src;
- for(xi = x+width-1; xi >= x; xi--)
- dest[xi] = st2d_8to16table[src[xi]];
+ we = vid.width - 1;
+ w8 = vid.width + 7 >> 3;
+ wr = vid.width % 8;
+ dy = vid.height * vid.rowbytes;
+ while((dy -= vid.rowbytes) >= 0){
+ s = fb + dy;
+ d = ((int *)s) + we;
+ s += we;
+ n = w8;
+ switch(wr){
+ case 0: do{ *d-- = fbpal[*s--];
+ case 7: *d-- = fbpal[*s--];
+ case 6: *d-- = fbpal[*s--];
+ case 5: *d-- = fbpal[*s--];
+ case 4: *d-- = fbpal[*s--];
+ case 3: *d-- = fbpal[*s--];
+ case 2: *d-- = fbpal[*s--];
+ case 1: *d-- = fbpal[*s--];
+ }while(--n > 0);
+ }
}
}
-/* vid.height and vid.width must be set correctly before this call */
static void
resetfb(void)
{
@@ -100,11 +85,19 @@
void *surfcache;
int hunkvbuf, scachesz;
- if(framebuf != nil){
- free(framebuf);
- framebuf = nil;
+ Point p;
+
+ if(scaleon){
+ scale = Dx(screen->r) / vid.width;
+ if(scale <= 0)
+ scale = 1;
+ else if(scale > 16)
+ scale = 16;
+ }else{
+ vid.width = Dx(screen->r);
+ vid.height = Dy(screen->r);
}
- if(d_pzbuffer){
+ if(d_pzbuffer != nil){
D_FlushCaches();
Hunk_FreeToHighMark(highhunk);
d_pzbuffer = nil;
@@ -112,48 +105,64 @@
highhunk = Hunk_HighMark();
// alloc an extra line in case we want to wrap, and allocate the z-buffer
- hunkvbuf = vid.width * vid.height * sizeof(*d_pzbuffer);
+ hunkvbuf = vid.width * vid.height * sizeof *d_pzbuffer;
scachesz = D_SurfaceCacheForRes(vid.width, vid.height);
hunkvbuf += scachesz;
if((d_pzbuffer = Hunk_HighAllocName(hunkvbuf, "video")) == nil)
sysfatal("Not enough memory for video mode\n");
- surfcache = (byte *)d_pzbuffer + vid.width * vid.height * sizeof(*d_pzbuffer);
+ surfcache = (byte *)d_pzbuffer + vid.width * vid.height * sizeof *d_pzbuffer;
D_InitCaches(surfcache, scachesz);
- framebuf = malloc(sizeof *framebuf * Dx(screen->r) * Dy(screen->r) * screen->depth/8);
- vid.buffer = framebuf;
- vid.rowbytes = Dx(screen->r) * screen->depth/8;
- vid.aspect = (float)vid.height / (float)vid.width * (320.0/240.0); /* FIXME */
- vid.conbuffer = vid.buffer;
+ vid.rowbytes = vid.width * sizeof *fbpal;
+ vid.aspect = (float)vid.height / (float)vid.width * (320.0/240.0);
vid.conrowbytes = vid.rowbytes;
vid.conwidth = vid.width;
vid.conheight = vid.height;
- center = addpt(screen->r.min, Pt(Dx(screen->r)/2, Dy(screen->r)/2));
- if(fbim != nil)
- freeimage(fbim);
- fbim = allocimage(display, Rect(0, 0, vid.width, vid.height), screen->chan, 1, DNofill);
+
+ center = divpt(addpt(screen->r.min, screen->r.max), 2);
+ p = Pt(scale * vid.width/2, scale * vid.height/2);
+ fbr = Rpt(subpt(center, p), addpt(center, p));
+ p = Pt(vid.width/4, vid.height/4);
+ grabr = Rpt(subpt(center, p), addpt(center, p));
+ freeimage(fbi);
+ free(fb);
+ fbi = allocimage(display,
+ Rect(0, 0, vid.width * scale, scale > 1 ? 1 : vid.height),
+ XRGB32, scale > 1, 0);
+ if(fbi == nil)
+ sysfatal("resetfb: %r (%d %d)", vid.width, vid.height);
+ fb = emalloc(vid.rowbytes * vid.height);
+ if(scaleon){
+ free(fbs);
+ fbs = emalloc(vid.rowbytes * scale * vid.height);
+ }
+ vid.buffer = fb;
+ vid.conbuffer = fb;
+ draw(screen, screen->r, display->black, nil, ZP);
}
-// Called at startup to set up translation tables, takes 256 8 bit RGB values
-// the palette data will go away after the call, so it must be copied off if
-// the video driver will need it again
void
-VID_Init(uchar */*palette*/)
+VID_Init(uchar *)
{
+ int n;
+
+ n = COM_CheckParm("-scale");
+ if(n && n < com_argc-2){
+ scaleon = 1;
+ vid.width = strtol(com_argv[n+1], nil, 0);
+ vid.height = strtol(com_argv[n+2], nil, 0);
+ if(vid.width < 320 || vid.height < 200)
+ sysfatal("invalid scale resolution");
+ }
vid.maxwarpwidth = WARP_WIDTH;
vid.maxwarpheight = WARP_HEIGHT;
vid.numpages = 2;
vid.colormap = host_colormap;
vid.fullbright = 256 - LittleLong(*((int *)vid.colormap + 2048));
-
srand(getpid());
-
if(initdraw(nil, nil, "quake") < 0)
- sysfatal("VID_Init:initdraw: %r\n");
- vid.width = Dx(screen->r);
- vid.height = Dy(screen->r);
+ sysfatal("initdraw: %r\n");
resetfb();
- vid.direct = 0;
}
void
@@ -163,46 +172,53 @@
}
void
-VID_SetPalette(uchar *palette)
+VID_SetPalette(uchar *p)
{
- int i;
+ int *fp;
- for(i = 0; i < 256; i++)
- st2d_8to16table[i] = rgb24(palette[i*3], palette[i*3+1], palette[i*3+2]);
+ for(fp=fbpal; fp<fbpal+nelem(fbpal); p+=3)
+ *fp++ = p[0] << 16 | p[1] << 8 | p[2];
+ scr_fullupdate = 0;
}
void
VID_Shutdown(void)
{
- Con_Printf("VID_Shutdown\n");
- free(framebuf);
- freeimage(fbim);
+ free(fb);
+ free(fbs);
+ freeimage(fbi);
}
void
-VID_Update(vrect_t *rects)
+VID_Update(vrect_t *)
{
if(resized){ /* skip this frame if window resize */
resized = 0;
if(getwindow(display, Refnone) < 0)
sysfatal("VID_Update:getwindow: %r\n");
- vid.width = Dx(screen->r);
- vid.height = Dy(screen->r);
resetfb();
vid.recalc_refdef = 1; /* force a surface cache flush */
Con_CheckResize();
Con_Clear_f();
- return;
}
+ drawfb();
+ scalefb();
+ if(scale == 1){
+ loadimage(fbi, Rect(0,0,vid.width,vid.height), fb, vid.height * vid.rowbytes);
+ draw(screen, fbr, fbi, nil, ZP);
+ }else{
+ Rectangle r;
+ uchar *p;
- scr_fullupdate = 0; /* force full update if not 8bit (cf. screen.h) */
-
- while(rects){
- st2_fixup(framebuf, rects->x, rects->y, rects->width, rects->height);
- rects = rects->pnext;
+ p = fbs;
+ r = fbr;
+ while(r.min.y < fbr.max.y){
+ r.max.y = r.min.y + scale;
+ p += loadimage(fbi, fbi->r, p, vid.rowbytes * scale);
+ draw(screen, r, fbi, nil, ZP);
+ r.min.y = r.max.y;
+ }
}
- loadimage(fbim, fbim->r, framebuf, vid.height * vid.rowbytes);
- draw(screen, screen->r, fbim, nil, ZP);
flushimage(display, 1);
}
--- a/qw/vid.h
+++ b/qw/vid.h
@@ -35,8 +35,6 @@
} viddef_t;
extern viddef_t vid; // global video state
-extern unsigned short d_8to16table[256];
-extern unsigned d_8to24table[256];
void VID_SetPalette (unsigned char *palette);
// called at startup and after any gamma correction