From 1d0a3d19c870d0fdcf83b5e7ffa8f2e58d49edd0 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 31 Jan 2016 20:45:37 -0600 Subject: [PATCH 1/7] Fix a part in maskwallscan that was missed for right-edge exclusivity --- src/r_segs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_segs.cpp b/src/r_segs.cpp index d55b31bbee..30738e657f 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -1082,7 +1082,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t basecolormapdata = basecolormap->Maps; x = x1; - //while ((umost[x] > dmost[x]) && (x <= x2)) x++; + //while ((umost[x] > dmost[x]) && (x < x2)) x++; bool fixed = (fixedcolormap != NULL || fixedlightlev >= 0); if (fixed) @@ -1439,7 +1439,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixe palookupoffse[3] = dc_colormap; } - for(; (x <= x2) && ((size_t)p & 3); ++x, ++p) + for(; (x < x2) && ((size_t)p & 3); ++x, ++p) { light += rw_lightstep; y1ve[0] = uwal[x];//max(uwal[x],umost[x]); From 0b9aeb33e13418c9049527ec7768cbf101749a1b Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 31 Jan 2016 20:52:56 -0600 Subject: [PATCH 2/7] Fixed potential divide by 0 when drawing voxels - Since voxels can have their origin behind the viewer and still have a portion visible in front of the viewer, they aren't clipped to MINZ like face sprites are. The 3D floor handling in R_DrawSprite() neglected to clamp it when recalculating the diminished light colormap. - Aside, but R_DrawSprite() probably shouldn't be messing with these properties at all. Why isn't this done in R_ProjectSprite() before it ever gets to the drawing part? --- src/r_things.cpp | 5 +++-- zdoom.vcproj | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/r_things.cpp b/src/r_things.cpp index 57a82ebb01..e1e7adcf45 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -673,7 +673,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor fixedvec3 pos = thing->InterpolatedPosition(r_TicFrac); fx = pos.x; fy = pos.y; - fz = pos.z +thing->GetBobOffset(r_TicFrac); + fz = pos.z + thing->GetBobOffset(r_TicFrac); tex = NULL; voxel = NULL; @@ -960,6 +960,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->fakeceiling = fakeceiling; vis->ColormapNum = 0; vis->bInMirror = MirrorFlags & RF_XFLIP; + vis->bSplitSprite = false; if (voxel != NULL) { @@ -1895,7 +1896,7 @@ void R_DrawSprite (vissprite_t *spr) { // diminished light spriteshade = LIGHT2SHADE(sec->lightlevel + r_actualextralight); spr->Style.colormap = mybasecolormap->Maps + (GETPALOOKUP ( - (fixed_t)DivScale12 (r_SpriteVisibility, spr->depth), spriteshade) << COLORMAPSHIFT); + (fixed_t)DivScale12 (r_SpriteVisibility, MAX(MINZ, spr->depth)), spriteshade) << COLORMAPSHIFT); } } } diff --git a/zdoom.vcproj b/zdoom.vcproj index 597b56f2f1..58d8cd4a03 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -292,7 +292,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="src\win32;src\sound;src;zlib;src\g_shared;src\g_doom;src\g_raven;src\g_heretic;src\g_hexen;src\g_strife;"jpeg-6b";"game-music-emu";gdtoa;bzip2;lzma\C" - PreprocessorDefinitions="WIN32,_DEBUG,_WIN32,_WINDOWS,_CRTDBG_MAP_ALLOC,HAVE_STRUPR,HAVE_FILELENGTH;NO_VA_COPY,BACKPATCH,HAVE_FLUIDSYNTH,DYN_FLUIDSYNTH,NO_OPENAL" + PreprocessorDefinitions="NOASM,WIN32,_DEBUG,_WIN32,_WINDOWS,_CRTDBG_MAP_ALLOC,HAVE_STRUPR,HAVE_FILELENGTH;NO_VA_COPY,BACKPATCH,HAVE_FLUIDSYNTH,DYN_FLUIDSYNTH,NO_OPENAL" MinimalRebuild="true" RuntimeLibrary="1" EnableFunctionLevelLinking="true" From 809a9d801cb69aedc0f449604954aaddd08e89f7 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 31 Jan 2016 21:23:45 -0600 Subject: [PATCH 3/7] Got a flag backwards --- src/p_lnspec.cpp | 2 +- zdoom.vcproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index da0c87aa34..192a217d87 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -903,7 +903,7 @@ FUNC(LS_Teleport_NoFog) // Teleport_NoFog (tid, useang, sectortag, keepheight) { int flags = 0; - if (arg1) + if (!arg1) { flags |= TELF_KEEPORIENTATION; } diff --git a/zdoom.vcproj b/zdoom.vcproj index 58d8cd4a03..597b56f2f1 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -292,7 +292,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="src\win32;src\sound;src;zlib;src\g_shared;src\g_doom;src\g_raven;src\g_heretic;src\g_hexen;src\g_strife;"jpeg-6b";"game-music-emu";gdtoa;bzip2;lzma\C" - PreprocessorDefinitions="NOASM,WIN32,_DEBUG,_WIN32,_WINDOWS,_CRTDBG_MAP_ALLOC,HAVE_STRUPR,HAVE_FILELENGTH;NO_VA_COPY,BACKPATCH,HAVE_FLUIDSYNTH,DYN_FLUIDSYNTH,NO_OPENAL" + PreprocessorDefinitions="WIN32,_DEBUG,_WIN32,_WINDOWS,_CRTDBG_MAP_ALLOC,HAVE_STRUPR,HAVE_FILELENGTH;NO_VA_COPY,BACKPATCH,HAVE_FLUIDSYNTH,DYN_FLUIDSYNTH,NO_OPENAL" MinimalRebuild="true" RuntimeLibrary="1" EnableFunctionLevelLinking="true" From 2f4dc1795496ba25217bc0a28325a993039675b0 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 31 Jan 2016 22:05:32 -0600 Subject: [PATCH 4/7] Add support for face sprite Y flipping --- src/r_things.cpp | 61 +++++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/src/r_things.cpp b/src/r_things.cpp index e1e7adcf45..b209fb2842 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -359,11 +359,24 @@ void R_DrawVisSprite (vissprite_t *vis) spryscale = vis->yscale; sprflipvert = false; dc_iscale = 0xffffffffu / (unsigned)vis->yscale; - dc_texturemid = vis->texturemid; frac = vis->startfrac; xiscale = vis->xiscale; + dc_texturemid = vis->texturemid; - sprtopscreen = centeryfrac - FixedMul (dc_texturemid, spryscale); + + if (vis->renderflags & RF_YFLIP) + { + sprflipvert = true; + spryscale = -spryscale; + dc_iscale = -dc_iscale; + dc_texturemid -= (vis->pic->GetHeight() << FRACBITS); + sprtopscreen = centeryfrac + FixedMul(dc_texturemid, spryscale); + } + else + { + sprflipvert = false; + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + } dc_x = vis->x1; x2 = vis->x2; @@ -652,8 +665,6 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor FTexture *tex; FVoxelDef *voxel; - WORD flip; - vissprite_t* vis; fixed_t iscale; @@ -681,6 +692,12 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor int spritenum = thing->sprite; fixed_t spritescaleX = thing->scaleX; fixed_t spritescaleY = thing->scaleY; + int renderflags = thing->renderflags; + if (spritescaleY < 0) + { + spritescaleY = -spritescaleY; + renderflags ^= RF_YFLIP; + } if (thing->player != NULL) { P_CheckPlayerSprite(thing, spritenum, spritescaleX, spritescaleY); @@ -695,7 +712,6 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor { return; } - flip = 0; if (tex->Rotations != 0xFFFF) { @@ -712,7 +728,10 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9-(angle_t)(ANGLE_180/16)) >> 28; } picnum = sprframe->Texture[rot]; - flip = sprframe->Flip & (1 << rot); + if (sprframe->Flip & (1 << rot)) + { + renderflags ^= RF_XFLIP; + } tex = TexMan[picnum]; // Do not animate the rotation } } @@ -748,7 +767,10 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor rot = (ang - thing->angle + (angle_t)(ANGLE_45/2)*9-(angle_t)(ANGLE_180/16)) >> 28; } picnum = sprframe->Texture[rot]; - flip = sprframe->Flip & (1 << rot); + if (sprframe->Flip & (1 << rot)) + { + renderflags ^= RF_XFLIP; + } tex = TexMan[picnum]; // Do not animate the rotation if (r_drawvoxels) { @@ -759,16 +781,16 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor if (spritescaleX < 0) { spritescaleX = -spritescaleX; - flip = !flip; + renderflags ^= RF_XFLIP; } if (voxel == NULL && (tex == NULL || tex->UseType == FTexture::TEX_Null)) { return; } - if ((thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE) + if ((renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE) { - R_ProjectWallSprite(thing, fx, fy, fz, picnum, spritescaleX, spritescaleY, flip); + R_ProjectWallSprite(thing, fx, fy, fz, picnum, spritescaleX, spritescaleY, renderflags); return; } @@ -855,16 +877,13 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor return; } - // [RH] Flip for mirrors and renderflags - if ((MirrorFlags ^ thing->renderflags) & RF_XFLIP) - { - flip = !flip; - } + // [RH] Flip for mirrors + renderflags ^= MirrorFlags & RF_XFLIP; // calculate edges of the shape const fixed_t thingxscalemul = DivScale16(spritescaleX, tex->xScale); - tx -= (flip ? (tex->GetWidth() - tex->LeftOffset - 1) : tex->LeftOffset) * thingxscalemul; + tx -= ((renderflags & RF_XFLIP) ? (tex->GetWidth() - tex->LeftOffset - 1) : tex->LeftOffset) * thingxscalemul; x1 = centerx + MulScale32 (tx, xscale); // off the right side? @@ -895,7 +914,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->x2 = x2 > WindowRight ? WindowRight : x2; vis->angle = thing->angle; - if (flip) + if (renderflags & RF_XFLIP) { vis->startfrac = (tex->GetWidth() << FRACBITS) - 1; vis->xiscale = -iscale; @@ -949,7 +968,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->gzt = gzt; // killough 3/27/98 vis->deltax = fx - viewx; vis->deltay = fy - viewy; - vis->renderflags = thing->renderflags; + vis->renderflags = renderflags; if(thing->flags5 & MF5_BRIGHT) vis->renderflags |= RF_FULLBRIGHT; // kg3D vis->Style.RenderStyle = thing->RenderStyle; vis->FillColor = thing->fillcolor; @@ -1022,7 +1041,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor { vis->Style.colormap = mybasecolormap->Maps + fixedlightlev; } - else if (!foggy && ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT))) + else if (!foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT))) { // full bright vis->Style.colormap = mybasecolormap->Maps; } @@ -1035,7 +1054,7 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor } } -static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t fz, FTextureID picnum, fixed_t xscale, fixed_t yscale, INTBOOL flip) +static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t fz, FTextureID picnum, fixed_t xscale, fixed_t yscale, int renderflags) { FWallCoords wallc; int x1, x2; @@ -1089,7 +1108,7 @@ static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t f vis->gzt = gzt; vis->deltax = fx - viewx; vis->deltay = fy - viewy; - vis->renderflags = thing->renderflags; + vis->renderflags = renderflags; if(thing->flags5 & MF5_BRIGHT) vis->renderflags |= RF_FULLBRIGHT; // kg3D vis->Style.RenderStyle = thing->RenderStyle; vis->FillColor = thing->fillcolor; From fd2828b1fe614f62faa2be91a105f89d17608896 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 1 Feb 2016 10:00:19 +0100 Subject: [PATCH 5/7] - fixed typo in monster movement code. --- src/p_enemy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index fa28045935..3c9cb1e177 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -539,7 +539,7 @@ bool P_Move (AActor *actor) !((actor->flags & MF_NOGRAVITY) || (actor->flags6 & MF6_CANJUMP)) && actor->Z() > actor->floorz && !(actor->flags2 & MF2_ONMOBJ)) { - if (actor->Y() <= actor->floorz + actor->MaxStepHeight) + if (actor->Z() <= actor->floorz + actor->MaxStepHeight) { fixed_t savedz = actor->Z(); actor->SetZ(actor->floorz); From e0608f50d17bee0ccd2e8cb8e3a43428d9a285df Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 1 Feb 2016 10:45:33 +0100 Subject: [PATCH 6/7] - create a separate translation table for Heretic's rain pillar. These objects are supposed to be bright, but the standard translations for player do not take this into account, creating dark and/or invisible projectiles depending on the color being used. The new translation uses hue and saturation from the player color, but combines brightness from the original color with the one for the player in an 8:2 ratio, so that no matter for the player color, these always remain bright and visible. --- src/g_heretic/a_hereticweaps.cpp | 2 +- src/r_data/r_translate.cpp | 33 +++++++++++++++++++++++++++++--- src/r_data/r_translate.h | 1 + 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index 899514139d..c6ccc6ae6a 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -1033,7 +1033,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SkullRodStorm) if (moceiling >= 0) mo->SetZ(newz - mo->height, false); mo->Translation = multiplayer ? - TRANSLATION(TRANSLATION_PlayersExtra,self->special2) : 0; + TRANSLATION(TRANSLATION_RainPillar,self->special2) : 0; mo->target = self->target; mo->velx = 1; // Force collision detection mo->velz = -mo->Speed; diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index d11388e6e3..d25ceb904c 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -700,6 +700,7 @@ void R_InitTranslationTables () { PushIdentityTable(TRANSLATION_Players); PushIdentityTable(TRANSLATION_PlayersExtra); + PushIdentityTable(TRANSLATION_RainPillar); } // The menu player also gets a separate translation table PushIdentityTable(TRANSLATION_Players); @@ -865,6 +866,29 @@ static void SetRemap(FRemapTable *table, int i, float r, float g, float b) table->Palette[i] = PalEntry(255, ir, ig, ib); } +//---------------------------------------------------------------------------- +// +// Sets the translation Heretic's the rain pillar +// This tries to create a translation that preserves the brightness of +// the rain projectiles so that their effect isn't ruined. +// +//---------------------------------------------------------------------------- + +static void SetPillarRemap(FRemapTable *table, int i, float h, float s, float v) +{ + float ph, ps, pv; + float fr = GPalette.BaseColors[i].r / 255.f; + float fg = GPalette.BaseColors[i].g / 255.f; + float fb = GPalette.BaseColors[i].b / 255.f; + RGBtoHSV(fr, fg, fb, &ph, &ps, &pv); + HSVtoRGB(&fr, &fg, &fb, h, s, (v*0.2f + pv*0.8f)); + int ir = clamp (int(fr * 255.f), 0, 255); + int ig = clamp (int(fg * 255.f), 0, 255); + int ib = clamp (int(fb * 255.f), 0, 255); + table->Remap[i] = ColorMatcher.Pick (ir, ig, ib); + table->Palette[i] = PalEntry(255, ir, ig, ib); +} + //---------------------------------------------------------------------------- static bool SetRange(FRemapTable *table, int start, int end, int first, int last) @@ -900,7 +924,7 @@ static bool SetRange(FRemapTable *table, int start, int end, int first, int last //---------------------------------------------------------------------------- static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerColorSet *colorset, - FPlayerSkin *skin, FRemapTable *table, FRemapTable *alttable) + FPlayerSkin *skin, FRemapTable *table, FRemapTable *alttable, FRemapTable *pillartable) { int i; BYTE start = skin->range0start; @@ -1023,6 +1047,7 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC v = MIN (1.f, (0.2102f + 0.0489f*(float)(i - 144)) * basev); HSVtoRGB (&r, &g, &b, h, s, v); SetRemap(alttable, i, r, g, b); + SetPillarRemap(pillartable, i, h, s, v); } alttable->UpdateNative(); } @@ -1103,7 +1128,9 @@ void R_BuildPlayerTranslation (int player) R_CreatePlayerTranslation (h, s, v, colorset, &skins[players[player].userinfo.GetSkin()], translationtables[TRANSLATION_Players][player], - translationtables[TRANSLATION_PlayersExtra][player]); + translationtables[TRANSLATION_PlayersExtra][player], + translationtables[TRANSLATION_RainPillar][player] + ); } //---------------------------------------------------------------------------- @@ -1123,5 +1150,5 @@ void R_GetPlayerTranslation (int color, const FPlayerColorSet *colorset, FPlayer RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f, &h, &s, &v); - R_CreatePlayerTranslation (h, s, v, colorset, skin, table, NULL); + R_CreatePlayerTranslation (h, s, v, colorset, skin, table, NULL, NULL); } diff --git a/src/r_data/r_translate.h b/src/r_data/r_translate.h index 23490cfb81..b469f86168 100644 --- a/src/r_data/r_translate.h +++ b/src/r_data/r_translate.h @@ -18,6 +18,7 @@ enum TRANSLATION_PlayerCorpses, TRANSLATION_Decorate, TRANSLATION_Blood, + TRANSLATION_RainPillar, NUM_TRANSLATION_TABLES }; From ee045371a340a457d85b4b205192c087c84b4403 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 1 Feb 2016 14:02:25 +0100 Subject: [PATCH 7/7] - On Windows, use LoadLibrary/GetProcAddress to load OpenAL function addresses. The reason for this is that on my system, the static or delay loaded method always picks the (obsolete) system-installed OpenAL version (needed for some old games) which is not wanted here if there's another one in the local ZDoom directory. This also removes the dependency on the broken import library that comes with OpenAL Soft which causes compile errors with more modern MSVC compilers on default settings. --- src/sound/oaldef.h | 93 ++++++++++++++++++++++++++++++++ src/sound/oalload.h | 117 +++++++++++++++++++++++++++++++++++++++++ src/sound/oalsound.cpp | 39 ++++++++++---- 3 files changed, 238 insertions(+), 11 deletions(-) create mode 100644 src/sound/oaldef.h create mode 100644 src/sound/oalload.h diff --git a/src/sound/oaldef.h b/src/sound/oaldef.h new file mode 100644 index 0000000000..f51c27b3f0 --- /dev/null +++ b/src/sound/oaldef.h @@ -0,0 +1,93 @@ +DEFINE_ENTRY(LPALENABLE,alEnable) +DEFINE_ENTRY(LPALDISABLE, alDisable) +DEFINE_ENTRY(LPALISENABLED, alIsEnabled) +DEFINE_ENTRY(LPALGETSTRING, alGetString) +DEFINE_ENTRY(LPALGETBOOLEANV, alGetBooleanv) +DEFINE_ENTRY(LPALGETINTEGERV, alGetIntegerv) +DEFINE_ENTRY(LPALGETFLOATV, alGetFloatv) +DEFINE_ENTRY(LPALGETDOUBLEV, alGetDoublev) +DEFINE_ENTRY(LPALGETBOOLEAN, alGetBoolean) +DEFINE_ENTRY(LPALGETINTEGER, alGetInteger) +DEFINE_ENTRY(LPALGETFLOAT, alGetFloat) +DEFINE_ENTRY(LPALGETDOUBLE, alGetDouble) +DEFINE_ENTRY(LPALGETERROR, alGetError) +DEFINE_ENTRY(LPALISEXTENSIONPRESENT, alIsExtensionPresent) +DEFINE_ENTRY(LPALGETPROCADDRESS, alGetProcAddress) +DEFINE_ENTRY(LPALGETENUMVALUE, alGetEnumValue) +DEFINE_ENTRY(LPALLISTENERF, alListenerf) +DEFINE_ENTRY(LPALLISTENER3F, alListener3f) +DEFINE_ENTRY(LPALLISTENERFV, alListenerfv) +DEFINE_ENTRY(LPALLISTENERI, alListeneri) +DEFINE_ENTRY(LPALLISTENER3I, alListener3i) +DEFINE_ENTRY(LPALLISTENERIV, alListeneriv) +DEFINE_ENTRY(LPALGETLISTENERF, alGetListenerf) +DEFINE_ENTRY(LPALGETLISTENER3F, alGetListener3f) +DEFINE_ENTRY(LPALGETLISTENERFV, alGetListenerfv) +DEFINE_ENTRY(LPALGETLISTENERI, alGetListeneri) +DEFINE_ENTRY(LPALGETLISTENER3I, alGetListener3i) +DEFINE_ENTRY(LPALGETLISTENERIV, alGetListeneriv) +DEFINE_ENTRY(LPALGENSOURCES, alGenSources) +DEFINE_ENTRY(LPALDELETESOURCES, alDeleteSources) +DEFINE_ENTRY(LPALISSOURCE, alIsSource) +DEFINE_ENTRY(LPALSOURCEF, alSourcef) +DEFINE_ENTRY(LPALSOURCE3F, alSource3f) +DEFINE_ENTRY(LPALSOURCEFV, alSourcefv) +DEFINE_ENTRY(LPALSOURCEI, alSourcei) +DEFINE_ENTRY(LPALSOURCE3I, alSource3i) +DEFINE_ENTRY(LPALSOURCEIV, alSourceiv) +DEFINE_ENTRY(LPALGETSOURCEF, alGetSourcef) +DEFINE_ENTRY(LPALGETSOURCE3F, alGetSource3f) +DEFINE_ENTRY(LPALGETSOURCEFV, alGetSourcefv) +DEFINE_ENTRY(LPALGETSOURCEI, alGetSourcei) +DEFINE_ENTRY(LPALGETSOURCE3I, alGetSource3i) +DEFINE_ENTRY(LPALGETSOURCEIV, alGetSourceiv) +DEFINE_ENTRY(LPALSOURCEPLAYV, alSourcePlayv) +DEFINE_ENTRY(LPALSOURCESTOPV, alSourceStopv) +DEFINE_ENTRY(LPALSOURCEREWINDV, alSourceRewindv) +DEFINE_ENTRY(LPALSOURCEPAUSEV, alSourcePausev) +DEFINE_ENTRY(LPALSOURCEPLAY, alSourcePlay) +DEFINE_ENTRY(LPALSOURCESTOP, alSourceStop) +DEFINE_ENTRY(LPALSOURCEREWIND, alSourceRewind) +DEFINE_ENTRY(LPALSOURCEPAUSE, alSourcePause) +DEFINE_ENTRY(LPALSOURCEQUEUEBUFFERS, alSourceQueueBuffers) +DEFINE_ENTRY(LPALSOURCEUNQUEUEBUFFERS, alSourceUnqueueBuffers) +DEFINE_ENTRY(LPALGENBUFFERS, alGenBuffers) +DEFINE_ENTRY(LPALDELETEBUFFERS, alDeleteBuffers) +DEFINE_ENTRY(LPALISBUFFER, alIsBuffer) +DEFINE_ENTRY(LPALBUFFERDATA, alBufferData) +DEFINE_ENTRY(LPALBUFFERF, alBufferf) +DEFINE_ENTRY(LPALBUFFER3F, alBuffer3f) +DEFINE_ENTRY(LPALBUFFERFV, alBufferfv) +DEFINE_ENTRY(LPALBUFFERI, alBufferi) +DEFINE_ENTRY(LPALBUFFER3I, alBuffer3i) +DEFINE_ENTRY(LPALBUFFERIV, alBufferiv) +DEFINE_ENTRY(LPALGETBUFFERF, alGetBufferf) +DEFINE_ENTRY(LPALGETBUFFER3F, alGetBuffer3f) +DEFINE_ENTRY(LPALGETBUFFERFV, alGetBufferfv) +DEFINE_ENTRY(LPALGETBUFFERI, alGetBufferi) +DEFINE_ENTRY(LPALGETBUFFER3I, alGetBuffer3i) +DEFINE_ENTRY(LPALGETBUFFERIV, alGetBufferiv) +DEFINE_ENTRY(LPALDOPPLERFACTOR, alDopplerFactor) +DEFINE_ENTRY(LPALDOPPLERVELOCITY, alDopplerVelocity) +DEFINE_ENTRY(LPALSPEEDOFSOUND, alSpeedOfSound) +DEFINE_ENTRY(LPALDISTANCEMODEL, alDistanceModel) +DEFINE_ENTRY(LPALCCREATECONTEXT, alcCreateContext) +DEFINE_ENTRY(LPALCMAKECONTEXTCURRENT, alcMakeContextCurrent) +DEFINE_ENTRY(LPALCPROCESSCONTEXT, alcProcessContext) +DEFINE_ENTRY(LPALCSUSPENDCONTEXT, alcSuspendContext) +DEFINE_ENTRY(LPALCDESTROYCONTEXT, alcDestroyContext) +DEFINE_ENTRY(LPALCGETCURRENTCONTEXT, alcGetCurrentContext) +DEFINE_ENTRY(LPALCGETCONTEXTSDEVICE, alcGetContextsDevice) +DEFINE_ENTRY(LPALCOPENDEVICE, alcOpenDevice) +DEFINE_ENTRY(LPALCCLOSEDEVICE, alcCloseDevice) +DEFINE_ENTRY(LPALCGETERROR, alcGetError) +DEFINE_ENTRY(LPALCISEXTENSIONPRESENT, alcIsExtensionPresent) +DEFINE_ENTRY(LPALCGETPROCADDRESS, alcGetProcAddress) +DEFINE_ENTRY(LPALCGETENUMVALUE, alcGetEnumValue) +DEFINE_ENTRY(LPALCGETSTRING, alcGetString) +DEFINE_ENTRY(LPALCGETINTEGERV, alcGetIntegerv) +DEFINE_ENTRY(LPALCCAPTUREOPENDEVICE, alcCaptureOpenDevice) +DEFINE_ENTRY(LPALCCAPTURECLOSEDEVICE, alcCaptureCloseDevice) +DEFINE_ENTRY(LPALCCAPTURESTART, alcCaptureStart) +DEFINE_ENTRY(LPALCCAPTURESTOP, alcCaptureStop) +DEFINE_ENTRY(LPALCCAPTURESAMPLES, alcCaptureSamples) diff --git a/src/sound/oalload.h b/src/sound/oalload.h new file mode 100644 index 0000000000..a3ed80a225 --- /dev/null +++ b/src/sound/oalload.h @@ -0,0 +1,117 @@ +#ifndef OALDEF_H +#define OALDEF_H + +#ifdef _WIN32 + +#define DEFINE_ENTRY(type, name) static type p_##name; +#include "oaldef.h" +#undef DEFINE_ENTRY +struct oalloadentry +{ + const char *name; + FARPROC *funcaddr; +}; +static oalloadentry oalfuncs[] = { +#define DEFINE_ENTRY(type, name) { #name, (FARPROC*)&p_##name }, +#include "oaldef.h" +#undef DEFINE_ENTRY +{ NULL, 0 } +}; + + +#define alEnable p_alEnable +#define alDisable p_alDisable +#define alIsEnabled p_alIsEnabled +#define alGetString p_alGetString +#define alGetBooleanv p_alGetBooleanv +#define alGetIntegerv p_alGetIntegerv +#define alGetFloatv p_alGetFloatv +#define alGetDoublev p_alGetDoublev +#define alGetBoolean p_alGetBoolean +#define alGetInteger p_alGetInteger +#define alGetFloat p_alGetFloat +#define alGetDouble p_alGetDouble +#define alGetError p_alGetError +#define alIsExtensionPresent p_alIsExtensionPresent +#define alGetProcAddress p_alGetProcAddress +#define alGetEnumValue p_alGetEnumValue +#define alListenerf p_alListenerf +#define alListener3f p_alListener3f +#define alListenerfv p_alListenerfv +#define alListeneri p_alListeneri +#define alListener3i p_alListener3i +#define alListeneriv p_alListeneriv +#define alGetListenerf p_alGetListenerf +#define alGetListener3f p_alGetListener3f +#define alGetListenerfv p_alGetListenerfv +#define alGetListeneri p_alGetListeneri +#define alGetListener3i p_alGetListener3i +#define alGetListeneriv p_alGetListeneriv +#define alGenSources p_alGenSources +#define alDeleteSources p_alDeleteSources +#define alIsSource p_alIsSource +#define alSourcef p_alSourcef +#define alSource3f p_alSource3f +#define alSourcefv p_alSourcefv +#define alSourcei p_alSourcei +#define alSource3i p_alSource3i +#define alSourceiv p_alSourceiv +#define alGetSourcef p_alGetSourcef +#define alGetSource3f p_alGetSource3f +#define alGetSourcefv p_alGetSourcefv +#define alGetSourcei p_alGetSourcei +#define alGetSource3i p_alGetSource3i +#define alGetSourceiv p_alGetSourceiv +#define alSourcePlayv p_alSourcePlayv +#define alSourceStopv p_alSourceStopv +#define alSourceRewindv p_alSourceRewindv +#define alSourcePausev p_alSourcePausev +#define alSourcePlay p_alSourcePlay +#define alSourceStop p_alSourceStop +#define alSourceRewind p_alSourceRewind +#define alSourcePause p_alSourcePause +#define alSourceQueueBuffers p_alSourceQueueBuffers +#define alSourceUnqueueBuffers p_alSourceUnqueueBuffers +#define alGenBuffers p_alGenBuffers +#define alDeleteBuffers p_alDeleteBuffers +#define alIsBuffer p_alIsBuffer +#define alBufferData p_alBufferData +#define alBufferf p_alBufferf +#define alBuffer3f p_alBuffer3f +#define alBufferfv p_alBufferfv +#define alBufferi p_alBufferi +#define alBuffer3i p_alBuffer3i +#define alBufferiv p_alBufferiv +#define alGetBufferf p_alGetBufferf +#define alGetBuffer3f p_alGetBuffer3f +#define alGetBufferfv p_alGetBufferfv +#define alGetBufferi p_alGetBufferi +#define alGetBuffer3i p_alGetBuffer3i +#define alGetBufferiv p_alGetBufferiv +#define alDopplerFactor p_alDopplerFactor +#define alDopplerVelocity p_alDopplerVelocity +#define alSpeedOfSound p_alSpeedOfSound +#define alDistanceModel p_alDistanceModel +#define alcCreateContext p_alcCreateContext +#define alcMakeContextCurrent p_alcMakeContextCurrent +#define alcProcessContext p_alcProcessContext +#define alcSuspendContext p_alcSuspendContext +#define alcDestroyContext p_alcDestroyContext +#define alcGetCurrentContext p_alcGetCurrentContext +#define alcGetContextsDevice p_alcGetContextsDevice +#define alcOpenDevice p_alcOpenDevice +#define alcCloseDevice p_alcCloseDevice +#define alcGetError p_alcGetError +#define alcIsExtensionPresent p_alcIsExtensionPresent +#define alcGetProcAddress p_alcGetProcAddress +#define alcGetEnumValue p_alcGetEnumValue +#define alcGetString p_alcGetString +#define alcGetIntegerv p_alcGetIntegerv +#define alcCaptureOpenDevice p_alcCaptureOpenDevice +#define alcCaptureCloseDevice p_alcCaptureCloseDevice +#define alcCaptureStart p_alcCaptureStart +#define alcCaptureStop p_alcCaptureStop +#define alcCaptureSamples p_alcCaptureSamples + +#endif +#endif \ No newline at end of file diff --git a/src/sound/oalsound.cpp b/src/sound/oalsound.cpp index 5c980a7939..a5ec97f97e 100644 --- a/src/sound/oalsound.cpp +++ b/src/sound/oalsound.cpp @@ -54,34 +54,49 @@ #include "i_musicinterns.h" #include "tempfiles.h" +#include "oalload.h" CVAR (String, snd_aldevice, "Default", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, snd_efx, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +#ifdef _WIN32 +static HMODULE hmodOpenAL; +#endif bool IsOpenALPresent() { #ifdef NO_OPENAL return false; #elif !defined _WIN32 - return true; // on non-Windows we cannot delay load the library so it has to be present. + return true; #else - static bool cached_result; + static bool cached_result = false; static bool done = false; if (!done) { done = true; - - __try + if (hmodOpenAL == NULL) { - // just call one function from the API to force loading the DLL - alcGetError(NULL); - } - __except (CheckException(GetExceptionCode())) - { - // FMod could not be delay loaded - return false; + hmodOpenAL = LoadLibrary(NicePath("$PROGDIR/openal32.dll")); + if (hmodOpenAL == NULL) + { + hmodOpenAL = LoadLibrary("openal32.dll"); + if (hmodOpenAL == NULL) + { + return false; + } + } + for(int i = 0; oalfuncs[i].name != NULL; i++) + { + *oalfuncs[i].funcaddr = GetProcAddress(hmodOpenAL, oalfuncs[i].name); + if (oalfuncs[i].funcaddr == NULL) + { + FreeLibrary(hmodOpenAL); + hmodOpenAL = NULL; + return false; + } + } } cached_result = true; } @@ -89,6 +104,8 @@ bool IsOpenALPresent() #endif } + + void I_BuildALDeviceList(FOptionValues *opt) { opt->mValues.Resize(1);