digi_play_sample_once is supposed to cancel prior instances of the
sound, but that functionality was lost in
21082c6db2. As a result, the sound can be
stacked up to the limit of the engine. Even when the functionality
existed, its implementation was wrong.
- Change these sounds to be attached to the player generating them.
- Pass the cancellation flag to other players when sending a sound.
- Send the full value of `volume`, rather than truncating it.
- Implement cancellation by killing and restarting the earlier version of a cancelled sound.
- Delete an ugly hack that prevented the patched logic from ever running.
- Fix an ancient quirk in digi_mixer that caused it to report all sounds as not playing, which then caused digi_sync_sounds to instantly cancel the new sound.
Reported-by: Mako88 <https://github.com/dxx-rebirth/dxx-rebirth/issues/88>
Reported-by: ryusei117 <https://github.com/dxx-rebirth/dxx-rebirth/issues/88#issuecomment-269597361>
Fixes: 21082c6db2 ("Added own channel management to SDL_mixer sound interface since the builtin channel management of this lib cannot handle our needs; Little code cleanup")
[Kp: as discussed in pull #377
<https://github.com/dxx-rebirth/dxx-rebirth/pull/377>, the previous
implementation requested a parameter combination not permitted by
OpenGL. At best, this error was silently ignored. Fix the error by
falling through to a switch case statement that sets valid parameters.]
Global variable `grd_curcanv` is set to a variety of canvases, some of
which are local stack variables. Use of global variables in this way is
fragile, but works as long as the global is not used beyond the life of
the backing local.
Unfortunately, some existing uses do access the canvas beyond the
lifetime of the backing local. Playing movies sets the font of the
current canvas. If the current canvas is an expired stack variable,
setting the font overwrites other stack data. This data corruption
causes various symptoms, such as inability to play the escape tunnel
movie.
Prior to 03cca2b3dc, the corruption on
playing the endlevel movie had no user-visible effect. That commit
created a large local variable, which changed stack layout. Starting
with that commit, the corruption causes the movie to play as all black.
Fix this, and protect against some other data corruption possiblities,
by clearing the global when the local goes out of scope.
Reported-by: Havner <https://github.com/dxx-rebirth/dxx-rebirth/issues/345> (only as cutscene failure to play, not as the underlying corruption issue)
Rather than use an inline wrapper and rely on the compiler optimizer to
redirect gr_set_current_canvas(nullptr) to gr_set_default_canvas,
rewrite all relevant calls directly in the source.
git grep -l 'gr_set_current_canvas' | xargs sed -i -e 's:gr_set_current_canvas(\s*NULL\|nullptr\s*);:gr_set_default_canvas();:'
When reporting use of SDL_mixer, report its loaded version. When
running in verbose mode, report both the compile-time and load-time
versions of PhysFS, libSDL, and SDL_mixer.
Some Linux libraries print their own messages to stdout/stderr,
particularly in case of severe errors. Decorate messages generated by
Rebirth to distinguish them from library generated messages.
For specific blacklisted renderers, add a message informing the user
that the blacklist matched and changed settings.
x86_64-pc-linux-gnu-g++-6.3 issues a -Wodr diagnostic for the mismatch
between
common/include/3d.h: void _g3_draw_poly(grs_canvas &, uint_fast32_t nv, cg3s_point *const *pointlist, uint8_t color);
similar/arch/ogl/ogl.cpp: void _g3_draw_poly(grs_canvas &canvas, const uint_fast32_t nv, const g3s_point *const *const pointlist, const uint8_t palette_color_index)
The declaration and definition are compatible because `cg3s_point` is a
type alias for `const g3s_point`, so the code worked as it was. Switch
the definition to use `cg3s_point` like the declaration to prevent this
warning and to protect against any future (unlikely) changes to the
definition of `cg3s_point`.
Macro LINE_SPACING previously used global grd_curcanv implicitly.
Change it to take a canvas argument. Change all callers to pass
grd_curcanv, so that usage is explicit.
Split ogl_get_verinfo() into ogl_tune_for_current() and
ogl_extensions_init(), and consolidate all the OpenGL extension handling
into ogl_extensions.cpp. Unify the code paths for texture anisotropy and
GPU synchronization for OpenGL and OpenGL ES.
Currently, our renderer only uses GLES 1.0, so no real world implementation
will support sync objects for such an old context, but the logic is valid,
and this way, the GLES specific code paths are reduced.
This patch also fixes an issue where the old ogl_get_verinfo() did modify
the texture filtering mode if no anisotropic filter was available. This
was some leftover from the time when the anisotropic filter was a just
a specific CGameConfig.TexFilt mode, and not a separate, orthogonal setting
CGameCfg.TexAnisotropy that it is now.
derhass reports that OpenGL ES builds warn for unused parameter
`texanis`. This parameter controls a feature that is not available in
current Rebirth OpenGL ES builds. Cast the parameter to void to silence
the warning. Long term, the code ought to be changed to advise the user
when their platform lacks this feature. In the short term, merge this
fix so that the build will succeed.
https://github.com/dxx-rebirth/dxx-rebirth/pull/256
Some custom levels attempt to use texture overrides that reference
textures that are not yet paged in. It is not legal to access the data
of a paged-out texture, but ogl_loadbmtexture_f attempted to access it
anyway, causing a crash. Page in the texture before calling
ogl_loadbmtexture_f. Old versions of the engine would have cached
garbage data when this happened.
Reported-by: kreator <https://github.com/dxx-rebirth/dxx-rebirth/issues/228>
Fixes: 3c20c24ac0 ("Disable piggy_bitmap_page_out_all")
_g3_draw_poly uses type cg3s_point which is const in OGL and non-const
in SDL. gcc-6 with LTO reports a One Definition Rule violation for this
mismatch:
typedef const int cint;
void f(cint *);
void f(const int *) {}
The code ran correctly as it was, but the fix is trivial and has no
effect on the generated code, so fix it to satisfy the compiler.
Rename symbol OGLES to DXX_USE_OGLES to show that it is a DXX
symbol, not one inherited from a library. Move it to dxxsconf.h to
shorten the command line.
This is a mostly automated transform, but the changes to SConstruct were
manual.
git grep -lzw OGLES -- '*.h' '*.cpp' | xargs -0 sed -i -e 's/\(\s*#\s*if\)def\s*OGLES/\1 DXX_USE_OGLES/' -e 's/\(\s*#\s*if\)ndef OGLES/\1 !DXX_USE_OGLES/'
Rename symbol USE_SDLMIXER to DXX_USE_SDLMIXER to show that it is a DXX
symbol, not one inherited from a library. Move it to dxxsconf.h to
shorten the command line.
This is a mostly automated transform, but the changes to SConstruct and
inferno.cpp were manual.
git grep -l USE_SDLMIXER -- '*.h' '*.cpp' | xargs sed -i -e 's/^#ifdef \(USE_SDLMIXER\)$/#if DXX_\1/' -e 's/#\(el\)\?if \(.*\)defined(\(USE_SDLMIXER\))/#\1if \2DXX_\3/'
The compiler may or may not recognize that the temporary T{} passed to
make_unique can be omitted. Help it by passing nothing, then explicitly
clearing the returned data as a separate step.
This pass only targets commonly used standard types.
s/(\(\s*\(\(un\)\?signed\|int\|char\|short\|long\|float\|double\|s\?size_t\|\(u\?int[[:digit:]]\+_t\)\)\)\s*)\s*(/static_cast<\1>(/g
C casts do not require parentheses. C++ casts require grouping around
the target. Prepare for conversion to C++ casts by adding otherwise
unnecessary parentheses around the target of some C casts.
This pass attempts to process expressions that involve parenthesized or
bracketed subexpressions, but only if those subexpressions do not
themselves contain parenthesized or bracketed subexpressions.
(int) f(1); // changed
(int) f(g()); // not changed
perl -p -i -e 's/(\(\s*((?:un)?signed|int|char|short|long|float|double|s?size_t|(?:u?int[[:digit:]]+_t))\s*\**\s*\)\s*)([&+-]?)([[:alnum:]_.]+\s*->\s*)*([[:alnum:]_.]+)((?:\s*(?:\[[^][]*\])*|(?:\([^()]*\))*))(\s*([;+>*\/^%,|&<>])|$|(\s*-\s*[^>]))/\1\(\3\4\5\6\)\7/g'
This pass only targets commonly used standard types.
s/(\(\s*\(\(un\)\?signed\|int\|char\|short\|long\|float\|double\|s\?size_t\|\(u\?int[[:digit:]]\+_t\)\)\)\s*)\s*(/static_cast<\1>(/g
C casts do not require parentheses. C++ casts require grouping around
the target. Prepare for conversion to C++ casts by adding otherwise
unnecessary parentheses around the target of simple C casts.
This pass does not attempt to process expressions that involve
any subexpression that can nest arbitrarily, such as parentheses or
brackets. It also works only on commonly used standard types.
(int) a->b; // changed
(int) a[b]; // not changed
s/\((\s*\(\(un\)\?signed\|int\|char\|short\|long\|float\|double\|s\?size_t\|\(u\?int[[:digit:]]\+_t\)\)\s*\**\s*)\s*\)\([&+-]\?\)\([[:alnum:]_.]\+\s*->\s*\)*\([[:alnum:]_.]\+\)\(\s*\([];+>)*\/^%,|&<>]\)\|$\|\(\s*-\s*[^>]\)\)/\1(\5\6\7)\8/g
gr_remap_mono_fonts searches for fonts with !(font->ft_flags & FT_COLOR)
and calls gr_remap_font on any it finds.
gr_remap_font starts with:
if (!(font->ft_flags & FT_COLOR))
return;