This commit is contained in:
Rachael Alexanderson 2017-05-10 05:15:49 -04:00
commit ac244b3229
21 changed files with 125 additions and 64 deletions

View file

@ -21,8 +21,6 @@ before_build:
- cd build
- if "%PLATFORM%"=="Win32" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015
- if "%PLATFORM%"=="x64" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015 Win64
- set DEPS_INCLUDE_DIR=%APPVEYOR_BUILD_FOLDER%\ci_deps_win\include
- set DEPS_LIB_DIR=%APPVEYOR_BUILD_FOLDER%\ci_deps_win\lib\%PLATFORM%
- cmake -G "%CMAKE_GENERATOR_NAME%" -T "v140_xp"
-DCMAKE_BUILD_TYPE="%CONFIGURATION%"
..
@ -32,6 +30,13 @@ build:
parallel: true
verbosity: minimal
after_build:
- set OUTPUT_DIR=%APPVEYOR_BUILD_FOLDER%\build\%CONFIGURATION%\
- 7z a ..\gzdoom.zip "%OUTPUT_DIR%gzdoom.exe" "%OUTPUT_DIR%*.pk3"
artifacts:
- path: gzdoom.zip
notifications:
- provider: Email
on_build_success: false

View file

@ -1265,12 +1265,13 @@ if( CMAKE_COMPILER_IS_GNUCXX )
set_source_files_properties( oplsynth/fmopl.cpp PROPERTIES COMPILE_FLAGS "-fno-tree-dominator-opts -fno-tree-fre" )
endif()
if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE )
# Need to enable intrinsics for this file.
# Need to enable intrinsics for these files.
if( SSE_MATTERS )
set_source_files_properties(
x86.cpp
swrenderer/r_all.cpp
gl/system/gl_swframebuffer.cpp
polyrenderer/poly_all.cpp
swrenderer/r_all.cpp
x86.cpp
PROPERTIES COMPILE_FLAGS "-msse2 -mmmx" )
endif()
endif()

View file

@ -132,6 +132,7 @@ extern void M_SetDefaultMode ();
extern void G_NewInit ();
extern void SetupPlayerClasses ();
extern void HUD_InitHud();
void gl_PatchMenu(); // remove modern OpenGL options on old hardware.
void DeinitMenus();
const FIWADInfo *D_FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad);
@ -2639,6 +2640,7 @@ void D_DoomMain (void)
}
V_Init2();
gl_PatchMenu();
UpdateJoystickMenu(NULL);
v = Args->CheckValue ("-loadgame");

View file

@ -53,6 +53,7 @@
CVAR(Bool, gl_lights_additive, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Bool, gl_legacy_mode, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET)
//==========================================================================
//
@ -64,6 +65,7 @@ CVAR(Bool, gl_lights_additive, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
void gl_PatchMenu()
{
// Radial fog and Doom lighting are not available without full shader support.
if (!gl_legacy_mode) return;
FOptionValues **opt = OptionValues.CheckKey("LightingModes");
if (opt != NULL)

View file

@ -69,6 +69,7 @@ public:
void InitClipper(angle_t a1, angle_t a2)
{
clipper.Clear();
clipper.SafeAddClipRangeRealAngles(a1, a2);
}

View file

@ -338,6 +338,7 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
{
RenderStyle = rs.first;
}
if (RenderStyle.BlendOp == STYLEOP_None) continue;
if (vis.Invert)
{

View file

@ -42,6 +42,8 @@ void gl_PatchMenu();
static TArray<FString> m_Extensions;
RenderContext gl;
EXTERN_CVAR(Bool, gl_legacy_mode)
//==========================================================================
//
//
@ -311,8 +313,8 @@ void gl_LoadExtensions()
FUDGE_FUNC(glRenderbufferStorage, EXT);
FUDGE_FUNC(glBindRenderbuffer, EXT);
FUDGE_FUNC(glCheckFramebufferStatus, EXT);
gl_PatchMenu();
}
gl_legacy_mode = gl.legacyMode;
}
//==========================================================================

View file

@ -92,6 +92,7 @@ EXTERN_CVAR(Float, Gamma)
EXTERN_CVAR(Bool, vid_vsync)
EXTERN_CVAR(Float, transsouls)
EXTERN_CVAR(Int, vid_refreshrate)
EXTERN_CVAR(Bool, gl_legacy_mode)
CVAR(Int, vid_max_width, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Int, vid_max_height, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
@ -205,6 +206,13 @@ OpenGLSWFrameBuffer::OpenGLSWFrameBuffer(void *hMonitor, int width, int height,
const char *glversion = (const char*)glGetString(GL_VERSION);
bool isGLES = (glversion && strlen(glversion) > 10 && memcmp(glversion, "OpenGL ES ", 10) == 0);
// GL 3.0 is mostly broken on MESA drivers which really are the only relevant case here that doesn't fulfill the requirements based on version number alone.
#ifdef _WIN32
gl_legacy_mode = !ogl_IsVersionGEQ(3, 0);
#else
gl_legacy_mode = !ogl_IsVersionGEQ(3, 1);
#endif
if (!isGLES && ogl_IsVersionGEQ(3, 0) == 0)
{
Printf("OpenGL acceleration requires at least OpenGL 3.0. No Acceleration will be used.\n");

View file

@ -187,6 +187,7 @@ void SexMessage (const char *from, char *to, int gender, const char *victim, con
void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgflags)
{
FName mod;
FString ret;
const char *message;
const char *messagename;
char gendermessage[1024];
@ -218,17 +219,17 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf
}
FString obit = DamageTypeDefinition::GetObituary(mod);
if (attacker == nullptr) messagename = obit;
if (attacker == nullptr && obit.IsNotEmpty()) messagename = obit;
else
{
switch (mod)
{
case NAME_Suicide: message = "$OB_SUICIDE"; break;
case NAME_Falling: message = "$OB_FALLING"; break;
case NAME_Crush: message = "$OB_CRUSH"; break;
case NAME_Exit: message = "$OB_EXIT"; break;
case NAME_Drowning: message = "$OB_WATER"; break;
case NAME_Slime: message = "$OB_SLIME"; break;
case NAME_Suicide: messagename = "$OB_SUICIDE"; break;
case NAME_Falling: messagename = "$OB_FALLING"; break;
case NAME_Crush: messagename = "$OB_CRUSH"; break;
case NAME_Exit: messagename = "$OB_EXIT"; break;
case NAME_Drowning: messagename = "$OB_WATER"; break;
case NAME_Slime: messagename = "$OB_SLIME"; break;
case NAME_Fire: messagename = "$OB_LAVA"; break;
}
}
@ -250,7 +251,6 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf
IFVIRTUALPTR(attacker, AActor, GetObituary)
{
VMValue params[] = { attacker, self, inflictor, mod.GetIndex(), !!(dmgflags & DMG_PLAYERATTACK) };
FString ret;
VMReturn rett(&ret);
VMCall(func, params, countof(params), &rett, 1);
if (ret.IsNotEmpty()) message = ret;

View file

@ -3823,28 +3823,22 @@ DEFINE_ACTION_FUNCTION(AActor, PlayActiveSound)
bool AActor::IsOkayToAttack (AActor *link)
{
if (!(player // Original AActor::IsOkayToAttack was only for players
// || (flags & MF_FRIENDLY) // Maybe let friendly monsters use the function as well?
|| (flags5 & MF5_SUMMONEDMONSTER) // AMinotaurFriend has its own version, generalized to other summoned monsters
|| (flags2 & MF2_SEEKERMISSILE))) // AHolySpirit and AMageStaffFX2 as well, generalized to other seeker missiles
{ // Normal monsters and other actors always return false.
return false;
}
// Standard things to eliminate: an actor shouldn't attack itself,
// or a non-shootable, dormant, non-player-and-non-monster actor.
if (link == this) return false;
if (!(link->player||(link->flags3 & MF3_ISMONSTER)))return false;
if (!(link->flags & MF_SHOOTABLE)) return false;
if (link->flags2 & MF2_DORMANT) return false;
if (link->flags7 & MF7_NEVERTARGET) return false; // NEVERTARGET means just that.
// An actor shouldn't attack friendly actors. The reference depends
// on the type of actor: for a player's actor, itself; for a projectile,
// its target; and for a summoned minion, its tracer.
AActor * Friend = NULL;
if (player) Friend = this;
else if (flags5 & MF5_SUMMONEDMONSTER) Friend = tracer;
AActor * Friend;
if (flags5 & MF5_SUMMONEDMONSTER) Friend = tracer;
else if (flags2 & MF2_SEEKERMISSILE) Friend = target;
else if ((flags & MF_FRIENDLY) && FriendPlayer) Friend = players[FriendPlayer-1].mo;
else Friend = this;
// Friend checks
if (link == Friend) return false;

View file

@ -152,8 +152,28 @@ ShadedTriVertex PolyTriangleDrawer::shade_vertex(const TriMatrix &objectToClip,
return sv;
}
bool PolyTriangleDrawer::is_degenerate(const ShadedTriVertex *vert)
{
// A degenerate triangle has a zero cross product for two of its sides.
float ax = vert[1].x - vert[0].x;
float ay = vert[1].y - vert[0].y;
float az = vert[1].w - vert[0].w;
float bx = vert[2].x - vert[0].x;
float by = vert[2].y - vert[0].y;
float bz = vert[2].w - vert[0].w;
float crossx = ay * bz - az * by;
float crossy = az * bx - ax * bz;
float crossz = ax * by - ay * bx;
float crosslengthsqr = crossx * crossx + crossy * crossy + crossz * crossz;
return crosslengthsqr <= 1.e-6f;
}
void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread)
{
// Reject triangle if degenerate
if (is_degenerate(vert))
return;
// Cull, clip and generate additional vertices as needed
TriVertex clippedvert[max_additional_vertices];
int numclipvert = clipedge(vert, clippedvert);
@ -224,13 +244,12 @@ void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool
// Draw screen triangles
if (ccw)
{
for (int i = numclipvert; i > 1; i--)
for (int i = numclipvert - 1; i > 1; i--)
{
args->v1 = &clippedvert[numclipvert - 1];
args->v2 = &clippedvert[i - 1];
args->v3 = &clippedvert[i - 2];
args->CalculateGradients();
if (args->CalculateGradients())
ScreenTriangle::Draw(args, thread);
}
}
@ -241,8 +260,7 @@ void PolyTriangleDrawer::draw_shaded_triangle(const ShadedTriVertex *vert, bool
args->v1 = &clippedvert[0];
args->v2 = &clippedvert[i - 1];
args->v3 = &clippedvert[i];
args->CalculateGradients();
if (args->CalculateGradients())
ScreenTriangle::Draw(args, thread);
}
}

View file

@ -47,6 +47,7 @@ private:
static ShadedTriVertex shade_vertex(const TriMatrix &objectToClip, const float *clipPlane, const TriVertex &v);
static void draw_arrays(const PolyDrawArgs &args, WorkerThreadData *thread);
static void draw_shaded_triangle(const ShadedTriVertex *vertices, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread);
static bool is_degenerate(const ShadedTriVertex *vertices);
static int clipedge(const ShadedTriVertex *verts, TriVertex *clippedvert);

View file

@ -66,29 +66,31 @@ struct TriDrawTriangleArgs
ScreenTriangleStepVariables gradientX;
ScreenTriangleStepVariables gradientY;
void CalculateGradients()
bool CalculateGradients()
{
gradientX.W = FindGradientX(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->w, v2->w, v3->w);
gradientY.W = FindGradientY(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->w, v2->w, v3->w);
gradientX.U = FindGradientX(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->u * v1->w, v2->u * v2->w, v3->u * v3->w);
gradientY.U = FindGradientY(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->u * v1->w, v2->u * v2->w, v3->u * v3->w);
gradientX.V = FindGradientX(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->v * v1->w, v2->v * v2->w, v3->v * v3->w);
gradientY.V = FindGradientY(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y, v1->v * v1->w, v2->v * v2->w, v3->v * v3->w);
float bottomX = (v2->x - v3->x) * (v1->y - v3->y) - (v1->x - v3->x) * (v2->y - v3->y);
float bottomY = (v1->x - v3->x) * (v2->y - v3->y) - (v2->x - v3->x) * (v1->y - v3->y);
if ((bottomX >= -FLT_EPSILON && bottomX <= FLT_EPSILON) || (bottomY >= -FLT_EPSILON && bottomY <= FLT_EPSILON))
return false;
gradientX.W = FindGradientX(bottomX, v1->w, v2->w, v3->w);
gradientY.W = FindGradientY(bottomY, v1->w, v2->w, v3->w);
gradientX.U = FindGradientX(bottomX, v1->u * v1->w, v2->u * v2->w, v3->u * v3->w);
gradientY.U = FindGradientY(bottomY, v1->u * v1->w, v2->u * v2->w, v3->u * v3->w);
gradientX.V = FindGradientX(bottomX, v1->v * v1->w, v2->v * v2->w, v3->v * v3->w);
gradientY.V = FindGradientY(bottomY, v1->v * v1->w, v2->v * v2->w, v3->v * v3->w);
return true;
}
private:
static float FindGradientX(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2)
float FindGradientX(float bottomX, float c0, float c1, float c2)
{
float top = (c1 - c2) * (y0 - y2) - (c0 - c2) * (y1 - y2);
float bottom = (x1 - x2) * (y0 - y2) - (x0 - x2) * (y1 - y2);
return top / bottom;
return ((c1 - c2) * (v1->y - v3->y) - (c0 - c2) * (v2->y - v3->y)) / bottomX;
}
static float FindGradientY(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2)
float FindGradientY(float bottomY, float c0, float c1, float c2)
{
float top = (c1 - c2) * (x0 - x2) - (c0 - c2) * (x1 - x2);
float bottom = (x0 - x2) * (y1 - y2) - (x1 - x2) * (y0 - y2);
return top / bottom;
return ((c1 - c2) * (v1->x - v3->x) - (c0 - c2) * (v2->x - v3->x)) / bottomY;
}
};

View file

@ -77,7 +77,12 @@ void I_WaitVBL(const int count)
{
// I_WaitVBL is never used to actually synchronize to the
// vertical blank. Instead, it's used for delay purposes.
usleep(1000000 * count / 70);
struct timespec delay, rem;
delay.tv_sec = count / 70;
/* Avoid overflow. Microsec res should be good enough. */
delay.tv_nsec = (count%70)*1000000/70 * 1000;
while(nanosleep(&delay, &rem) == -1 && errno == EINTR)
delay = rem;
}

View file

@ -113,7 +113,12 @@ void I_WaitVBL (int count)
{
// I_WaitVBL is never used to actually synchronize to the
// vertical blank. Instead, it's used for delay purposes.
usleep (1000000 * count / 70);
struct timespec delay, rem;
delay.tv_sec = count / 70;
/* Avoid overflow. Microsec res should be good enough. */
delay.tv_nsec = (count%70)*1000000/70 * 1000;
while(nanosleep(&delay, &rem) == -1 && errno == EINTR)
delay = rem;
}
//

View file

@ -593,16 +593,15 @@ void S_CacheSound (sfxinfo_t *sfx)
//==========================================================================
void S_UnloadSound (sfxinfo_t *sfx)
{
if (sfx->data.isValid())
{
if (sfx->data3d.isValid() && sfx->data != sfx->data3d)
GSnd->UnloadSound(sfx->data3d);
if (sfx->data.isValid())
GSnd->UnloadSound(sfx->data);
if (sfx->data.isValid() || sfx->data3d.isValid())
DPrintf(DMSG_NOTIFY, "Unloaded sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]);
sfx->data.Clear();
sfx->data3d.Clear();
DPrintf(DMSG_NOTIFY, "Unloaded sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]);
}
}
//==========================================================================

View file

@ -38,10 +38,7 @@
#include "c_cvars.h"
#include "critsec.h"
#include "v_text.h"
#include "files.h"
#include "templates.h"
#include "sndfile_decoder.h"
#include "mpg123_decoder.h"
#include "m_fixed.h"
// MACROS ------------------------------------------------------------------
@ -82,6 +79,18 @@ protected:
// PUBLIC DATA DEFINITIONS -------------------------------------------------
CUSTOM_CVAR(Int, snd_streambuffersize, 64, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
if (self < 16)
{
self = 16;
}
else if (self > 1024)
{
self = 1024;
}
}
// PRIVATE DATA DEFINITIONS ------------------------------------------------
// CODE --------------------------------------------------------------------
@ -121,7 +130,7 @@ void FindLoopTags(FileReader *fr, uint32_t *start, bool *startass, uint32_t *end
}
c -= 3;
int len = c[0] + 256*c[1] + 65536*c[2];
if (c[3] || len > 1000000 || len <= (eqp - c + 1))
if (c[3] || len > 1000000 || len < (eqp - c - 3))
{
// length looks fishy so retry with the next '='
continue;
@ -209,7 +218,7 @@ SndFileSong::SndFileSong(FileReader *reader, SoundDecoder *decoder, uint32_t loo
Reader = reader;
Decoder = decoder;
Channels = iChannels == ChannelConfig_Stereo? 2:1;
m_Stream = GSnd->CreateStream(Read, 32*1024, iChannels == ChannelConfig_Stereo? 0 : SoundStream::Mono, SampleRate, this);
m_Stream = GSnd->CreateStream(Read, snd_streambuffersize * 1024, iChannels == ChannelConfig_Stereo? 0 : SoundStream::Mono, SampleRate, this);
}
//==========================================================================
@ -330,7 +339,7 @@ bool SndFileSong::Read(SoundStream *stream, void *vbuff, int ilen, void *userdat
if (currentpos + framestoread > song->Loop_End)
{
size_t endblock = (song->Loop_End - currentpos) * song->Channels * 2;
size_t endlen = song->Decoder->read(buff, endblock);
size_t endlen = song->Decoder->read(buff, 0 == endblock ? len : endblock);
if (endlen != 0)
{
buff = buff + endlen;

View file

@ -1585,7 +1585,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int
else
{
if((chanflags&SNDF_ABSTIME))
alSourcef(source, AL_SAMPLE_OFFSET, reuse_chan->StartTime.Lo);
alSourcei(source, AL_SAMPLE_OFFSET, reuse_chan->StartTime.Lo);
else
{
float offset = std::chrono::duration_cast<std::chrono::duration<float>>(
@ -1793,7 +1793,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
else
{
if((chanflags&SNDF_ABSTIME))
alSourcef(source, AL_SAMPLE_OFFSET, reuse_chan->StartTime.Lo);
alSourcei(source, AL_SAMPLE_OFFSET, reuse_chan->StartTime.Lo);
else
{
float offset = std::chrono::duration_cast<std::chrono::duration<float>>(

View file

@ -420,7 +420,7 @@ void OPLio::WriteTremolo(uint32_t channel, struct GenMidiVoice *voice, bool vibr
val2 |= 0x40;
}
WriteOperator(OPL_REGS_TREMOLO, channel, 1, val2);
WriteOperator(OPL_REGS_TREMOLO, channel, 0, val2);
WriteOperator(OPL_REGS_TREMOLO, channel, 0, val1);
}
//----------------------------------------------------------------------------

View file

@ -1222,7 +1222,11 @@ LONG WINAPI CatchAllExceptions (LPEXCEPTION_POINTERS info)
// Otherwise, put the crashing thread to sleep and signal the main thread to clean up.
if (GetCurrentThreadId() == MainThreadID)
{
#ifdef _M_X64
*info->ContextRecord = MainThreadContext;
#else
info->ContextRecord->Eip = (DWORD_PTR)ExitFatally;
#endif // _M_X64
}
else
{
@ -1315,6 +1319,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n
{
SetUnhandledExceptionFilter (CatchAllExceptions);
#ifdef _M_X64
static bool setJumpResult = false;
RtlCaptureContext(&MainThreadContext);
if (setJumpResult)
@ -1323,6 +1328,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n
return 0;
}
setJumpResult = true;
#endif // _M_X64
}
#endif

View file

@ -817,7 +817,7 @@ class PlayerPawn : Actor native
double factor = 1.;
for(let it = Inv; it != null; it = it.Inv)
{
factor *= Inv.GetSpeedFactor ();
factor *= it.GetSpeedFactor ();
}
forward *= factor;
side *= factor;