mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-24 21:21:04 +00:00
This commit is contained in:
commit
ac244b3229
21 changed files with 125 additions and 64 deletions
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
|
||||
void InitClipper(angle_t a1, angle_t a2)
|
||||
{
|
||||
clipper.Clear();
|
||||
clipper.SafeAddClipRangeRealAngles(a1, a2);
|
||||
}
|
||||
|
||||
|
|
|
@ -338,6 +338,7 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
{
|
||||
RenderStyle = rs.first;
|
||||
}
|
||||
if (RenderStyle.BlendOp == STYLEOP_None) continue;
|
||||
|
||||
if (vis.Invert)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>>(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue