diff --git a/src/g_doom/a_painelemental.cpp b/src/g_doom/a_painelemental.cpp index b52224c0c..f361fb78d 100644 --- a/src/g_doom/a_painelemental.cpp +++ b/src/g_doom/a_painelemental.cpp @@ -103,7 +103,7 @@ void A_PainShootSkull (AActor *self, angle_t angle, const PClass *spawntype, int box.Top() < ld->bbox[BOXBOTTOM] || box.Bottom() > ld->bbox[BOXTOP])) { - if (P_PointOnLineSide(self->x,self->y,ld) != P_PointOnLineSide(x,y,ld)) + if (P_PointOnLineSidePrecise(self->x,self->y,ld) != P_PointOnLineSidePrecise(x,y,ld)) return; // line blocks trajectory // ^ } } diff --git a/src/p_local.h b/src/p_local.h index fd5064f3c..e8cc5fde0 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -249,6 +249,12 @@ inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) : DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; } +inline int P_PointOnLineSidePrecise (fixed_t x, fixed_t y, const line_t *line) +{ + return DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; +} + + //========================================================================== // // P_PointOnDivlineSide @@ -267,6 +273,12 @@ inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_t *line) : (DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0); } +inline int P_PointOnDivlineSidePrecise (fixed_t x, fixed_t y, const divline_t *line) +{ + return DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0; +} + + //========================================================================== // // P_MakeDivline diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index e6d5a99e6..1d806d044 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -1056,13 +1056,13 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it break; } // Check if this side is facing the trace origin - if (P_PointOnDivlineSide (trace.x, trace.y, &line) == 0) + if (P_PointOnDivlineSidePrecise (trace.x, trace.y, &line) == 0) { numfronts++; // If it is, see if the trace crosses it - if (P_PointOnDivlineSide (line.x, line.y, &trace) != - P_PointOnDivlineSide (line.x + line.dx, line.y + line.dy, &trace)) + if (P_PointOnDivlineSidePrecise (line.x, line.y, &trace) != + P_PointOnDivlineSidePrecise (line.x + line.dx, line.y + line.dy, &trace)) { // It's a hit fixed_t frac = P_InterceptVector (&trace, &line); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 750cc18fb..bcaa77855 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1284,7 +1284,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target) if (line != NULL && cl_missiledecals) { - int side = P_PointOnLineSide (mo->x, mo->y, line); + int side = P_PointOnLineSidePrecise (mo->x, mo->y, line); if (line->sidedef[side] == NULL) side ^= 1; if (line->sidedef[side] != NULL) diff --git a/src/p_sight.cpp b/src/p_sight.cpp index 135698b8b..2d465aab5 100644 --- a/src/p_sight.cpp +++ b/src/p_sight.cpp @@ -132,7 +132,7 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in) { int frontflag; - frontflag = P_PointOnLineSide(sightthing->x, sightthing->y, li); + frontflag = P_PointOnLineSidePrecise(sightthing->x, sightthing->y, li); //Check 3D FLOORS! for(int i=1;i<=2;i++) @@ -241,14 +241,14 @@ bool SightCheck::P_SightCheckLine (line_t *ld) return true; } ld->validcount = validcount; - if (P_PointOnDivlineSide (ld->v1->x, ld->v1->y, &trace) == - P_PointOnDivlineSide (ld->v2->x, ld->v2->y, &trace)) + if (P_PointOnDivlineSidePrecise (ld->v1->x, ld->v1->y, &trace) == + P_PointOnDivlineSidePrecise (ld->v2->x, ld->v2->y, &trace)) { return true; // line isn't crossed } P_MakeDivline (ld, &dl); - if (P_PointOnDivlineSide (trace.x, trace.y, &dl) == - P_PointOnDivlineSide (trace.x+trace.dx, trace.y+trace.dy, &dl)) + if (P_PointOnDivlineSidePrecise (trace.x, trace.y, &dl) == + P_PointOnDivlineSidePrecise (trace.x+trace.dx, trace.y+trace.dy, &dl)) { return true; // line isn't crossed } diff --git a/src/p_slopes.cpp b/src/p_slopes.cpp index c0b9b5ef0..a3db26526 100644 --- a/src/p_slopes.cpp +++ b/src/p_slopes.cpp @@ -54,7 +54,7 @@ static void P_SlopeLineToPoint (int lineid, fixed_t x, fixed_t y, fixed_t z, boo sector_t *sec; secplane_t *plane; - if (P_PointOnLineSide (x, y, line) == 0) + if (P_PointOnLineSidePrecise (x, y, line) == 0) { sec = line->frontsector; } @@ -363,7 +363,7 @@ static void P_SetSlopesFromVertexHeights(FMapThing *firstmt, FMapThing *lastmt, z3 = h3? *h3 : j==0? sec->GetPlaneTexZ(sector_t::floor) : sec->GetPlaneTexZ(sector_t::ceiling); vt3.Z = FIXED2FLOAT(z3); - if (P_PointOnLineSide(vertexes[vi3].x, vertexes[vi3].y, sec->lines[0]) == 0) + if (P_PointOnLineSidePrecise(vertexes[vi3].x, vertexes[vi3].y, sec->lines[0]) == 0) { vec1 = vt2 - vt3; vec2 = vt1 - vt3; diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index 040aca9f4..380f5572d 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -530,7 +530,7 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO int fudge = FUDGEFACTOR; // Make sure we are on correct side of exit linedef. - while (P_PointOnLineSide(x, y, l) != side && --fudge >= 0) + while (P_PointOnLineSidePrecise(x, y, l) != side && --fudge >= 0) { if (abs(l->dx) > abs(l->dy)) y -= (l->dx < 0) != side ? -1 : 1; diff --git a/src/po_man.cpp b/src/po_man.cpp index 727591bd5..98fbbcbcb 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -1231,7 +1231,7 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd) // Best use the one facing the player and ignore the back side. if (ld->sidedef[1] != NULL) { - int side = P_PointOnLineSide(mobj->x, mobj->y, ld); + int side = P_PointOnLineSidePrecise(mobj->x, mobj->y, ld); if (ld->sidedef[side] != sd) { continue; diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 8cab34230..96a77930a 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1280,6 +1280,7 @@ void R_DrawSkyBoxes () ds_p->sprtopclip = R_NewOpening (pl->maxx - pl->minx + 1); ds_p->maskedtexturecol = ds_p->swall = -1; ds_p->bFogBoundary = false; + ds_p->fake = 0; memcpy (openings + ds_p->sprbottomclip, floorclip + pl->minx, (pl->maxx - pl->minx + 1)*sizeof(short)); memcpy (openings + ds_p->sprtopclip, ceilingclip + pl->minx, (pl->maxx - pl->minx + 1)*sizeof(short)); diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 4042ca421..e7a617f5a 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -462,14 +462,12 @@ public: Stream->release(); Channel = NULL; Stream = NULL; - Owner->Sys->setStreamBufferSize(64*1024, FMOD_TIMEUNIT_RAWBYTES); // Open the stream asynchronously, so we don't hang the game while trying to reconnect. // (It would be nice to do the initial open asynchronously as well, but I'd need to rethink // the music system design to pull that off.) result = Owner->Sys->createSound(URL, (Loop ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF) | FMOD_SOFTWARE | FMOD_2D | FMOD_CREATESTREAM | FMOD_NONBLOCKING, NULL, &Stream); JustStarted = true; - Owner->Sys->setStreamBufferSize(16*1024, FMOD_TIMEUNIT_RAWBYTES); return result != FMOD_OK; } if (JustStarted && openstate == FMOD_OPENSTATE_PLAYING) @@ -1170,6 +1168,9 @@ bool FMODSoundRenderer::Init() } Sys->set3DSettings(0.5f, 96.f, 1.f); Sys->set3DRolloffCallback(RolloffCallback); + // The default is 16k, which periodically starves later FMOD versions + // when streaming FLAC files. + Sys->setStreamBufferSize(64*1024, FMOD_TIMEUNIT_RAWBYTES); snd_sfxvolume.Callback (); return true; } @@ -1733,10 +1734,6 @@ SoundStream *FMODSoundRenderer::OpenStream(const char *url, int flags) exinfo.dlsname = patches; } - // Use a larger buffer for URLs so that it's less likely to be effected - // by hiccups in the data rate from the remote server. - Sys->setStreamBufferSize(64*1024, FMOD_TIMEUNIT_RAWBYTES); - result = Sys->createSound(url, mode, &exinfo, &stream); if(result == FMOD_ERR_FORMAT && exinfo.dlsname != NULL) { @@ -1748,9 +1745,6 @@ SoundStream *FMODSoundRenderer::OpenStream(const char *url, int flags) } } - // Restore standard buffer size. - Sys->setStreamBufferSize(16*1024, FMOD_TIMEUNIT_RAWBYTES); - if(result != FMOD_OK) return NULL; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index b6575ee19..8343b79b8 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2439,7 +2439,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeIn) if (flags & FTF_CLAMP) self->alpha = (FRACUNIT * 1); if (flags & FTF_REMOVE) - self->Destroy(); + P_RemoveThing(self); } } @@ -2467,7 +2467,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeOut) if (flags & FTF_CLAMP) self->alpha = 0; if (flags & FTF_REMOVE) - self->Destroy(); + P_RemoveThing(self); } } @@ -2515,7 +2515,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FadeTo) } if (self->alpha == target && (flags & FTF_REMOVE)) { - self->Destroy(); + P_RemoveThing(self); } } diff --git a/src/timidity/instrum_dls.cpp b/src/timidity/instrum_dls.cpp index 286fcb1a3..02b8e59c0 100644 --- a/src/timidity/instrum_dls.cpp +++ b/src/timidity/instrum_dls.cpp @@ -1126,7 +1126,7 @@ static void load_region_dls(Renderer *song, Sample *sample, DLS_Instrument *ins, sample->key_group = (SBYTE)rgn->header->usKeyGroup; sample->low_freq = note_to_freq(rgn->header->RangeKey.usLow); sample->high_freq = note_to_freq(rgn->header->RangeKey.usHigh); - sample->root_freq = note_to_freq(rgn->wsmp->usUnityNote); + sample->root_freq = note_to_freq(rgn->wsmp->usUnityNote + rgn->wsmp->sFineTune * .01f); sample->low_vel = (BYTE)rgn->header->RangeVelocity.usLow; sample->high_vel = (BYTE)rgn->header->RangeVelocity.usHigh; @@ -1137,15 +1137,17 @@ static void load_region_dls(Renderer *song, Sample *sample, DLS_Instrument *ins, convert_sample_data(sample, wave->data); if (rgn->wsmp->cSampleLoops) { - sample->modes |= (PATCH_LOOPEN | PATCH_SUSTAIN); + sample->modes |= (PATCH_LOOPEN | PATCH_SUSTAIN/* | PATCH_NO_SRELEASE*/); sample->loop_start = rgn->wsmp_loop->ulStart / 2; sample->loop_end = sample->loop_start + (rgn->wsmp_loop->ulLength / 2); } + sample->scale_factor = 1024; + sample->scale_note = rgn->wsmp->usUnityNote; if (sample->modes & PATCH_SUSTAIN) { int value; - double attack, hold, decay, release; int sustain; + int attack, hold, decay, release; int sustain; CONNECTIONLIST *art = NULL; CONNECTION *artList = NULL; @@ -1157,16 +1159,11 @@ static void load_region_dls(Renderer *song, Sample *sample, DLS_Instrument *ins, artList = rgn->artList; } - value = load_connection(art->cConnections, artList, CONN_DST_EG1_ATTACKTIME); - attack = to_msec(value); - value = load_connection(art->cConnections, artList, CONN_DST_EG1_HOLDTIME); - hold = to_msec(value); - value = load_connection(art->cConnections, artList, CONN_DST_EG1_DECAYTIME); - decay = to_msec(value); - value = load_connection(art->cConnections, artList, CONN_DST_EG1_RELEASETIME); - release = to_msec(value); - value = load_connection(art->cConnections, artList, CONN_DST_EG1_SUSTAINLEVEL); - sustain = (int)((1.0 - to_normalized_percent(value)) * 250.0); + attack = load_connection(art->cConnections, artList, CONN_DST_EG1_ATTACKTIME); + hold = load_connection(art->cConnections, artList, CONN_DST_EG1_HOLDTIME); + decay = load_connection(art->cConnections, artList, CONN_DST_EG1_DECAYTIME); + release = load_connection(art->cConnections, artList, CONN_DST_EG1_RELEASETIME); + sustain = load_connection(art->cConnections, artList, CONN_DST_EG1_SUSTAINLEVEL); value = load_connection(art->cConnections, artList, CONN_DST_PAN); sample->panning = (int)((0.5 + to_normalized_percent(value)) * 16383.f); @@ -1174,12 +1171,12 @@ static void load_region_dls(Renderer *song, Sample *sample, DLS_Instrument *ins, printf("%d, Rate=%d LV=%d HV=%d Low=%d Hi=%d Root=%d Pan=%d Attack=%f Hold=%f Sustain=%d Decay=%f Release=%f\n", index, sample->sample_rate, rgn->header->RangeVelocity.usLow, rgn->header->RangeVelocity.usHigh, sample->low_freq, sample->high_freq, sample->root_freq, sample->panning, attack, hold, sustain, decay, release); */ - sample->envelope.sf2.decay_vol = 0; - sample->envelope.sf2.attack_vol = (short)attack; - sample->envelope.sf2.hold_vol = (short)hold; - sample->envelope.sf2.decay_vol = (short)decay; - sample->envelope.sf2.release_vol = (short)release; - sample->envelope.sf2.sustain_vol = (short)sustain; + sample->envelope.sf2.delay_vol = -32768; + sample->envelope.sf2.attack_vol = (short)(attack >> 16); + sample->envelope.sf2.hold_vol = (short)(hold >> 16); + sample->envelope.sf2.decay_vol = (short)(decay >> 16); + sample->envelope.sf2.release_vol = (short)(release >> 16); + sample->envelope.sf2.sustain_vol = (short)(sustain >> 16); } sample->data_length <<= FRACTION_BITS; diff --git a/src/timidity/mix.cpp b/src/timidity/mix.cpp index f97710326..beda91e16 100644 --- a/src/timidity/mix.cpp +++ b/src/timidity/mix.cpp @@ -231,6 +231,10 @@ bool SF2Envelope::Update(Voice *v) double sec; double newvolume = 0; + // NOTE! The volume scale is different for different stages of the + // envelope generator: + // Attack stage goes from 0.0 -> 1.0, multiplied directly to the output. + // The following stages go from 0 -> -1000 cB (but recorded positively) switch (stage) { case SF2_DELAY: @@ -333,6 +337,11 @@ bool SF2Envelope::Update(Voice *v) #define FLUID_ATTEN_POWER_FACTOR (-531.509) #define atten2amp(x) pow(10.0, (x) / FLUID_ATTEN_POWER_FACTOR) +static double cb_to_amp(double x) // centibels to amp +{ + return pow(10, x / -200.f); +} + void SF2Envelope::ApplyToAmp(Voice *v) { double amp; @@ -343,13 +352,21 @@ void SF2Envelope::ApplyToAmp(Voice *v) v->right_mix = 0; return; } - else if (stage == SF2_ATTACK) + + amp = v->sample->type == INST_SF2 ? atten2amp(v->attenuation) : cb_to_amp(v->attenuation); + + switch (stage) { - amp = atten2amp(v->attenuation) * volume; - } - else - { - amp = atten2amp(v->attenuation) * cb_to_amp(volume); + case SF2_ATTACK: + amp *= volume; + break; + + case SF2_HOLD: + break; + + default: + amp *= cb_to_amp(volume); + break; } amp *= FINAL_MIX_SCALE * 0.5; v->left_mix = float(amp * v->left_offset); diff --git a/src/timidity/timidity.cpp b/src/timidity/timidity.cpp index 440db9211..267edbb7e 100644 --- a/src/timidity/timidity.cpp +++ b/src/timidity/timidity.cpp @@ -678,6 +678,9 @@ int LoadDMXGUS() return 0; } +DLS_Data *LoadDLS(FILE *src); +void FreeDLS(DLS_Data *data); + Renderer::Renderer(float sample_rate, const char *args) { // 'args' should be used to load a custom config or DMXGUS, but since setup currently requires a snd_reset call, this will need some refactoring first @@ -701,6 +704,11 @@ Renderer::Renderer(float sample_rate, const char *args) voices = MAX(*midi_voices, 16); voice = new Voice[voices]; drumchannels = DEFAULT_DRUMCHANNELS; +#if 0 + FILE *f = fopen("c:\\windows\\system32\\drivers\\gm.dls", "rb"); + patches = LoadDLS(f); + fclose(f); +#endif } Renderer::~Renderer() @@ -713,6 +721,10 @@ Renderer::~Renderer() { delete[] voice; } + if (patches != NULL) + { + FreeDLS(patches); + } } void Renderer::ComputeOutput(float *buffer, int count) diff --git a/src/timidity/timidity.h b/src/timidity/timidity.h index 45e23a9f9..ac423c1e2 100644 --- a/src/timidity/timidity.h +++ b/src/timidity/timidity.h @@ -445,7 +445,7 @@ struct Channel struct MinEnvelope { - int stage; + BYTE stage; BYTE bUpdating; }; @@ -599,7 +599,6 @@ const double log_of_2 = 0.69314718055994529; #define freq_to_note(x) (log((x) / 8175.7989473096690661233836992789) * (12.0 / log_of_2)) #define calc_gf1_amp(x) (pow(2.0,((x)*16.0 - 16.0))) // Actual GUS equation -#define cb_to_amp(x) (pow(10.0, (x) * (1 / -200.0))) // centibels to amp /* timidity.h