When joystick support is not present, `event_joystick_get_button` is not
declared in joy.h.
Fixes: c24864b180 ("make menus controllable with joystick")
Define separate enum values for rotation data in both the high bits,
where it is usually kept, and the low bits, where it is sometimes used
for math or comparisons.
Define an enum value to represent the composite of the index and the
rotation, since the composite is not suitable for use as an array
subscript. Add helper functions to extract the component pieces.
segment inherits unique_segment, so unique_segment members can be
referenced from an instance of segment. Eventually, segment will be
removed. Adjust references to go through unique_segment to support this
change.
If axes!=0 and buttons==0 and hats==0, then the build fails because some
button-related functionality is missing. Move the joystick axis->button
bridge into a conditional to exclude it in this case.
Fixes: 74ef8b02e6 ("Added axis buttons")
This makes the alignment data structure `chunk` private to interp.cpp,
and allows most files to ignore whether DXX_WORDS_NEED_ALIGNMENT is
enabled, thus improving the ccache hit rate.
lengthof was added to provide the size of C arrays. C++17 std::size is
now available, and can serve the same purpose. Remove the custom
lengthof.
The generated code is the same in both cases, other than the change in
line numbers caused by removal of the #include directives.
Instead of parsing the button name string,
an explicit button-to-key mapping table
is now built and used.
Also fixes a few minor inconsistencies
that were introduced in c24864b1.
In most menus, keyboard commands are synthesized
from controller buttons, leveraging the existing
axis-to-button translation.
Menu controls are currently fixed:
- button 0 (A) is confirm (Enter)
- button 1 (B) is cancel (Esc)
- button 2 (X) is switch (Space)
- button 3 (Y) is delete (Delete)
- axes 0 and 1 (main analog pad) maps to cursor keys
- all hats (D-pads) map to cursor keys
Title screens and credits can be confirmed
with any joystick button or axis motion too.
This was once a compatibility shim, but compiler support for std::begin
has been required since 5e434cbe95 and no
issues have been reported. Flatten the include tree by removing this
header and using the STL names directly.
A declaration is useful if it declares an external function. A static
inline declaration, if not followed by the definition later in the same
translation unit, will not be useful. Remove such declarations, and
rely on using the definition as a declaration for those files that
actually call partial_range() or similar functions.
This field is used in the SDL build for rendering. In the GL build, its
only purpose is for the editor to write it to a PIG file. Change that
one use to compute the value as needed. Move all other references
behind a preprocessor test for !DXX_USE_OGL. This shrinks the size of
grs_bitmap by 1 pointer, since the compiler added padding after
avg_color up to the size of the next aligned pointer.
gcc has a special case to devolve to memset if both the pointed-at data
and the value to fill are considered a byte. All uses of
DXX_POISON_MEMORY pass a value that fits in a byte, so change the
signature to be a byte, to encourage gcc to activate the special case.
This adds a new dependency, but most systems likely already have
SDL_image installed. Use of SDL_image can be disabled, but this is
discouraged, because various in-game interfaces assume the use of the
original background.
The old implementation automatically corrected for filename case. The
new implementation expects that the supplied filename can be passed to
PYHSFS_openRead as-is. All known uses in-game have been corrected to
satisfy this requirement. If the new stricter match requirement becomes
a problem, a variant of PHYSFSRWOPS_openRead that adjusts filename case
could be created for use here.
- Update install instructions
- Update ebuild
- Update Arch PKGBUILD
Switch valptridx error style dispatching from using macro pasting to
using C++11 user-defined literals. This makes the code a bit easier to
read, and removes the need for a C99-conforming preprocessor here, which
should help anyone trying to port to Microsoft Visual Studio.
The new implementation also fixes a limitation of the previous
implementation. Before, an override that referenced an invalid name
could be silently ignored. Now, incorrect overrides cause an attempt to
use an undefined instantiation, which fails with a compilation error.
The minimum supported compiler versions now provide a depth-efficient
implementation of std::make_index_sequence, which removes the last
reason to carry a private implementation. In the case of clang, it
appears to have a special compiler intrinsic used to implement its
std::make_index_sequence.
Switch to the compiler-provided version for both gcc and clang.
Commit d355ef4030 removed a seemingly unnecessary modification of the
global variable grd_curcanv->cv_font, after eliminating all local reads
of it. However, a non-local read, buried in listbox_mouse, depended on
grd_curcanv->cv_font being set to a MEDIUM font. After that commit,
grd_curcanv->cv_font retained its prior value, which is not a MEDIUM
font. This caused listbox_mouse to compute an incorrect height of the
lines in the listbox, which manifested as the game choosing the wrong
line when the mouse is clicked in the listbox.
Fix the problem by explicitly using MEDIUM3_FONT, since that was
usually the value left in grd_curcanv->cv_font prior to that commit. In
some cases, a different MEDIUM font would be left there, but all the
MEDIUM fonts have the same height, so they are interchangeable for this
purpose.
Reported-by: Q3BFG10K <https://github.com/dxx-rebirth/dxx-rebirth/issues/498>
Fixes: d355ef4030 ("Pass font to various drawing functions")
gcc before gcc-7 failed to build valptridx:
```
common/include/valptridx.h: In instantiation of 'valptridx<managed_type>::ptridx<policy>::ptridx(const valptridx<managed_type>::ptridx<rpolicy>&) [with rpolicy =
valptridx<dcx::segment>::vm; typename std::enable_if<(policy:: allow_nullptr || (! rpolicy:: allow_nullptr)), int>::type <anonymous> = 0; policy = valptridx<dcx::segment>::vc; managed_type = dcx::segment]':
similar/main/endlevel.cpp:586:105: required from here
common/include/valptridx.h:686:14: error: 'using vptr_type = class valptridx<dcx::segment>::ptr<valptridx<dcx::segment>::vm>' is protected within this context
vptr_type(static_cast<const typename ptridx<rpolicy>::vptr_type &>(rhs)),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
common/include/valptridx.h:666:31: note: declared protected here
using vptr_type = ptr<policy>;
```
This cannot be fixed in the obvious way because the error message is
wrong:
```
664 using containing_type = valptridx<managed_type>;
665 public:
666 using vptr_type = ptr<policy>;
667 using vidx_type = idx<policy>;
668 using typename vidx_type::array_managed_type;
```
The type declarations _already are_ *public*, not *protected* as the
message states. Relaxing the protection on the containing class
resolves the error. This looks bad from an encapsulation perspective,
but does not make the code incorrect.
arch_close calls various library shutdown routines, some of which may
not be in good order after atexit hooks begin executing. Call it before
returning from main, so that the libraries are still fully initialized.
gcc considers strong_typedef to be POD both with and without the
explicit default. clang considers it to be POD only if the constructor
is explicitly defaulted.
For correctness, valptridx::ptridx instances must not be sliced down to
their component ::ptr or ::idx base classes. Previously, this was done
with a dummy template parameter to ensure that a bare ::idx had a
different type than the idx base of a ::ptridx. This extra distinction
complicates analysis of the code, and is not needed when the code is
already correct. Add the ability to build without slice checking.
Fix a bug where the ptridx converting move constructor delegated to the
ptr converting copy constructor, since the ptr copy constructor had
filename/line arguments, the ptr move constructor did not, and the
ptridx move constructor always passed filename/line.
clang-9 reports:
```
similar/main/mglobal.cpp:210:44: error: 'report_error_uses_exception' is a protected member of 'valptridx_specialized_type_parameters<unsigned char, 90, valptridx_untyped_utilities::report_error_style::exception, valptridx_untyped_utilities::report_error_style::exception>'
template <typename T, bool = valptridx<T>::report_error_uses_exception::value>
^
similar/main/mglobal.cpp:229:16: note: in instantiation of default argument for 'instantiation_guard<dcx::active_door>' required here
template class instantiation_guard<dcx::active_door>::type::index_range_exception;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
common/include/fwd-valptridx.h:42:2: note: constrained by protected inheritance here
protected valptridx_specialized_types<managed_type>::type
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
common/include/cpp-valptridx.h:175:8: note: member is declared here
using report_error_uses_exception = std::integral_constant<bool,
```
Add a `using` statement to switch `report_error_uses_exception` to
`public` access. Nothing else uses it, and there is no design purpose
served by keeping it `protected`.
Each axis can act as two buttons in both ways.
For example, a player might map slide left and slide right to J1 -A1 and J1 +A1 as button presses instead of the slide L/R axis.
This is mostly to fix XBox 360 Controller Left and Right triggers. But it can work on every axis if the player wishes to bind them.
The subcanvas is positioned based on the dimensions of the containing
window, so it must be repositioned if the outer window is resized.
Reported-by: vLKp <https://github.com/dxx-rebirth/dxx-rebirth/issues/394>
Fixes: f491059ed7 ("Enable building with SDL2")
This removes the need to walk all objects when creating a new one, since
each object can have a private generation counter, unaware of other
objects. For compatibility with demos, mix in the object's index when
writing the signature value.
Remove the fallback to Boost.Begin. C++14 is now the minimum supported
standard, and any conforming C++14 compiler should have a working C++11
std::begin.
Descent 1 mangles colors during `g3_init_polygon_model`, so this must
not be called on polygons not designed for mangling. Rearrange the
logic to allow Descent 1 to verify that polygon models are well-formed
without using the functions that mangle the colors.
Fixes: 42a2e3ab0b ("Avoid crash loading polymodels with invalid subcalls")
Reported-by: derhass <https://github.com/dxx-rebirth/dxx-rebirth/issues/416>
Bitmaps based on grs_main_bitmap own their data. Bitmaps based on
grs_bitmap do not. Adjust prototypes to prevent initializing a
grs_main_bitmap with data it will not own.
Processing sharepath in SConf is incorrect, because targets can share a
build directory (and therefore an SConf run), but not share a sharepath.
Move sharepath handling out of SConf. Move DXX_USE_SHAREPATH handling
from CGameArg to GameArg, since one game can be built with a sharepath
while the other is built without.
For each link given as http://, verify that the site is accessible over
https:// and, if so, switch to it. These domains were converted:
* llvm.org
* clang.llvm.org
* en.cppreference.com
* www.dxx-rebirth.com
* www.libsdl.org
* www.scons.org
Add macro cf_assert ("control flow" assert) to hint to gcc that certain
conditions are impossible. Use it to avoid generating range checks for
situations that never happen. If the event did happen, the only
consequence would be truncated UI text, rather than a correctness
problem.
This commit enables Rebirth to build with SDL2, but the result is not
perfect.
- SDL2 removed some sticky key support. Rebirth may behave differently
now in this area.
- SDL2 removed some key-repeat related support. Rebirth may behave
differently now in this area.
- SDL2 gained the ability to make a window fullscreen by sizing it to
the desktop instead of by changing the desktop resolution. Rebirth
uses this, and it mostly works.
- Resizing while in the automap does not notify the automap code, so
the view is wrong until the player switches out of automap mode and
back in.
- SDL2 changed how to enumerate available resolutions. Since
fitting the window to the desktop is generally more useful than
fitting the desktop to the window, I chose to drop support for
enumerating resolutions instead of porting to the new API. Users can
now enter an arbitrary window dimension and Rebirth will make an
attempt to use it.
- It might be useful to cap the window dimension at the desktop
dimension, but that is not done yet.
- Entering fullscreen mode through the Controls->Graphics submenu
failed to notify the relevant subsystems, causing the rendered
content not to rescale. For now, compile out the option to toggle
full screen through that menu. Toggling through Alt+Enter works
properly.
Despite these quirks, this is a substantial improvement over the prior
commit, where SDL2 cannot be used at all. The remaining issues can be
resolved in future work.
References: <https://github.com/dxx-rebirth/dxx-rebirth/issues/82>
GCC std::remove_if overwrites removed elements using:
*dstiter = move(*srciter);
This is fine for normal containers, but produces incorrect results when
*dstiter returns a proxy object instead of a reference. In that case,
the proxy object is move-assigned from the source, then goes out of
scope. If the move assignment did not write to underlying storage, as
valptridx proxy objects do not, then incorrect results occur. This
broke ActiveDoor handling (fixed in 4a01fab66d98[1]) and has been a trap
waiting to recur. Apply reference-qualifiers to valptridx objects so
that move-assignment requires an lvalue for the left-hand side. This
permits normal use of move-assignment, but forces a compile error if
std::remove_if or similar are used on valptridx proxy objects.
[1]: 4a01fab66d
Future work is simpler without this, and the stringified name is only
visible in debug output, which is in turn rarely used due to its
verbosity and lack of filtering controls.
Various files included compiler-static_assert.h to use the compatibility
macros for compilers that lacked a working C++11 static_assert.
However, some source files used static_assert without this inclusion,
and no one ever reported problems. From this, assume that no one uses a
compiler which lacks C++11 static_assert. Remove the inclusions that
were only for the compatibility macro. Keep the inclusions that use the
assert_equal helper.
- Remove the one test that clang-5 still fails.
- Require all remaining tests to pass using only C++11 native
static_assert.
- Remove preprocessor-based alternative static_assert implementations.
gcc-8 adds calls to static_assert with a comma inside its first
argument in the implementation of std::vector. This is legal within the
standard, but conflicts with Rebirth's use of static_assert as a
two argument preprocessor macro. The macro is not substantially useful,
and was only present to compensate for the clang limitation removed in
the previous commit. Remove the macro.
References: <https://github.com/dxx-rebirth/dxx-rebirth/issues/388>
valptridx contains `static_assert` statements of the form:
static_assert(var.m, "");
where `var` is a non-`constexpr` reference and `m` is a `static
constexpr` member of a base type of `var`. gcc recognizes that a
`static constexpr` member is a constant expression and permits this.
clang rejects this, presumably because `var` is not a `constexpr`
variable. In the almost 3 years since this was added, clang has not
improved to permit this usage. Rather than continuing to suppress
static_assert in clang, rewrite this expression to be less clear, but be
compatible with clang.
gcc-8 has special cases in its std::advance that require the target to
support `operator++` and `operator--`. These are easy to support, so
add them.
References: <https://github.com/dxx-rebirth/dxx-rebirth/issues/388>
gcc-8 warns that static_cast<dt &>(d) is useless. In general, it is
useless. It is present to force a compile error in cases when `d` is
not convertible to `dt &`. Switch to a compound statement that declares
a local reference to `d` of type `dt &`. This achieves the same
checking effect, but does not provoke the -Wuseless-cast warning.
References: <https://github.com/dxx-rebirth/dxx-rebirth/issues/388>
- Enable display of subsecond (Linux: microseconds; Windows:
milliseconds) precision on gamelog timestamps.
- Add disabled support for YYYY-MM-DD leaders on gamelog timestamps.
Activate it by defining DXX_CONSOLE_TIME_FORMAT_YMD to true.
- Add disabled support for capturing caller __FILE__, __LINE__ in calls
to con_printf, con_puts. Activate it by defining
DXX_CONSOLE_SHOW_FILE_LINE to true. If captured, write those to
gamelog after the timestamp and before the text. This feature (and
only this feature) requires that DXX_HAVE_CXX_BUILTIN_FILE_LINE be
defined, which is conditional on if the compiler has __builtin_FILE()
and __builtin_LINE(). If the compiler lacks this support, attempts to
enable this feature are ignored.
- Switch to using GetLocalTime on Windows.
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();:'
Only one caller exists, and that caller alway passes a non-nullptr
value. Switch to a reference and remove the unused special case to
handle a nullptr input.
Most uses pass an orientation matrix. All sites are deterministic about
whether a matrix is passed. Make the matrix mandatory for sites that
passed it, and split out a separate version of g3_start_instance_matrix
for the 2 sites which do not provide orientation.
Remove the `basic_` prefix from valptridx<T>::basic_ptr, ::basic_idx,
and ::basic_ptridx. Since the public names are typedef aliases of these
classes, these class names appear frequently in debug information and
error messages. The `basic_` prefix is unnecessary. Remove it.
git grep -lz '\<basic_\(ptr\|ptridx\|idx\)\>' -- common/include/ | xargs -0 sed -i -e 's/\<basic_\(ptr\|ptridx\|idx\)\>/\1/g'
Early implementations of integer_sequence used a naive implementation
that required one level of template depth per additional integer in the
sequence. Rebirth uses a private alternate implementation named
make_tree_index_sequence that requires only log(N) steps for an
N-element index_sequence. Recent versions of gcc ship a log(N) version
of integer_sequence. Probe for that version and, if found, use it
instead of the private implementation, on the theory that the compiler
writers did at least as good a job as I did, and possibly better if they
were able to leverage compiler implementation details.
Future work will introduce uses of d1x/d2x in the other game when the
types can be usefully shared. Extend the anti-nesting guards to cover
mistakes that might arise when referring to the namespaces by their
real name, rather than the alias name dsx.
Delete stub "compiler-type_traits.h" header. Redirect all uses to the
standard <type_traits> header.
git grep -wlz 'compiler-type_traits.h' -- '*.cpp' '*.h' | xargs -0 perl -p -i <<EOF
BEGIN {
$i = 0;
}
if (($i == 1 && $_ eq "\n") || ($i < 2 && /^#include "/)) {
# First blank line or first user-include after a system-include.
# Print, then never again for this file.
print "#include <type_traits>\n";
$i = 2;
} elsif ($i == 0) {
$i = 1 if (/^#include </);
} elsif ($_ eq "#include \"compiler-type_traits.h\"\n") {
# Remove this line if found.
$_ = '';
}
# Reset state machine when moving to next file.
$i = 0 if eof;
EOF
All supported compilers have an acceptable <type_traits>. Commit
4cb3d46148 ("Move <type_traits> test to Cxx11RequiredFeature") made
<type_traits> support mandatory in August and no one has objected.
Remove the indirection and use namespace std directly for type_traits
members.
Previously, valptridx used PREFIX for allow-invalid+mutable, c#PREFIX
for allow-invalid+const, v#PREFIX for require-valid+mutable, vc#PREFIX
for require-valid+const. Convert the types, factories, and all usage
sites to specify a qualifier for all four combinations:
im#PREFIX -> allow-invalid+mutable
ic#PREFIX -> allow-invalid+const
vm#PREFIX -> require-valid+mutable
vc#PREFIX -> require-valid+const
Changes to common/include/valptridx.h and common/include/fwd-valptridx.h
are manual. All other changes are generated by:
git grep -lz -e '\(obj\|seg\|clwall\|wall\|actdoor\|trg\)\(ptridx\|ptr\|idx\)\(_t\)\?\>' | xargs -0 sed -i -e 's/\<\(v\?\)\(\(obj\|seg\|clwall\|wall\|actdoor\|trg\)\(ptridx\|ptr\|idx\)\(_t\)\?\)\>/\1m\2/g'
for the 'm' prefix and:
git grep -lz -e '\(obj\|seg\|clwall\|wall\|actdoor\|trg\)\(ptridx\|ptr\|idx\)\(_t\)\?\>' | xargs -0 sed -i -e 's/\<\([cm]\(obj\|seg\|clwall\|wall\|actdoor\|trg\)\(ptridx\|ptr\|idx\)\(_t\)\?\)\>/i&/g'
for the 'i' prefix.
Past releases had a debug-only assertion that 25 was sufficient, but
then dynamically allocated enough storage for larger models as needed.
Commit 22a34809ee ("Move interpreter g3s_lrgb onto stack") added a
hard limit of 25, but did not detect attempts to exceed this. Custom
models that exceeded 25 would cause a stack buffer overwrite and likely
crash. Raise the limit to 64 and add sanity checking to refuse to
render models that exceed MAX_POINTS_PER_POLY.
Fixes: 22a34809ee ("Move interpreter g3s_lrgb onto stack")
Type `SyncGLMethod` was defined conditional on DXX_USE_OGL, but header
`common/include/ogl_sync.h` used `SyncGLMethod` unconditionally. This
works fine in the normal build since SDL builds never include
`common/include/ogl_sync.h`, but broke the check_header_includes=1 test
since that compiles `common/include/ogl_sync.h` even for SDL builds.
Wrap type `ogl_sync` in `#if DXX_USE_OGL` to hide it from the
check_header_includes=1 test in SDL mode.
clang becomes confused trying to determine which vm_distance_squared
constructor to use for a literal input of 0x7fffffffffffffff, even
though the size of the input requires it to be `long` and only one
constructor can take a `long`. Switch from an explicit
0x7fffffffffffffff to the symbolic constant INT64_MAX, which has the
same value, but a platform-appropriate suffix to force the compiler to
pick the right type.
For general clarity, switch some other instances of integer maximum
literals to symbolic constants of the same value.
This commit has no effect on the generated code (except for changes to
line numbers).
Reported-by: kreatordxx <https://github.com/dxx-rebirth/dxx-rebirth/pull/324>
Fixes: 17208cca79 ("Disallow int for vm_distance_squared")
When using `gcc -fsanitize=undefined`, the compiler proves trivial
results, so `DXX_CONSTANT_TRUE` is defined. It then fails to prove that
`DXX_CONSTANT_TRUE(m_state == checked)` is false, causing a compile-time
error. Relax the check to occur only when it can prove `m_state` equal
to a disallowed value, rather than when it cannot prove `m_state` equal
to an allowed value.
Move the preprocessor guard so that the runtime check is always visible.
Optimizing compilers can still eliminate that check at compile-time when
it provably never fails.
As a macro, it always refers to the global grd_curcanv. This interferes
with converting canvas handling to be an argument. Expand GHEIGHT so
that uses of grd_curcanv can be changed individually.
As a macro, it always refers to the global grd_curcanv. This interferes
with converting canvas handling to be an argument. Expand GWIDTH so
that uses of grd_curcanv can be changed individually.