Skip to content
This repository was archived by the owner on Jan 5, 2024. It is now read-only.

Commit 91eeb50

Browse files
committed
Merge branch 'pre4-testing' into 4zk-content-source
2 parents e236645 + a74cd2a commit 91eeb50

File tree

4 files changed

+204
-4
lines changed

4 files changed

+204
-4
lines changed

.github/workflows/meson.yml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,75 @@ jobs:
8181
with:
8282
name: CortexCommand.AppImage
8383
path: CortexCommand.AppImage
84+
85+
86+
build-debug-linux:
87+
# The type of runner that the job will run on
88+
runs-on: ubuntu-20.04
89+
90+
91+
# Steps represent a sequence of tasks that will be executed as part of the job
92+
steps:
93+
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
94+
- uses: actions/checkout@v2
95+
- uses: actions/setup-python@v2
96+
97+
- name: Install Dependencies
98+
run: |
99+
sudo apt-get update -yq
100+
sudo apt-get install --no-install-recommends wget liballegro4-dev libloadpng4-dev libflac++-dev luajit-5.1-dev libminizip-dev liblz4-dev libpng++-dev libx11-dev libboost-dev
101+
102+
- name: Install Clang
103+
# You may pin to the exact commit or the version.
104+
# uses: egor-tensin/setup-clang@d16e36d5f8a7eb00aa6627c1a536d94dfc4a913d
105+
uses: egor-tensin/setup-clang@v1
106+
with:
107+
# Set up cc/c++ executables
108+
cc: 1 # optional, default is 1
109+
110+
- name: Setup ccache
111+
uses: hendrikmuhs/ccache-action@v1
112+
with:
113+
key: build-release-${{runner.os}}
114+
max-size: 5G
115+
116+
- name: Build
117+
# You may pin to the exact commit or the version.
118+
# uses: BSFishy/meson-build@6f1930d878fd3eed3853c1c91285ec604c37f3a5
119+
uses: BSFishy/[email protected]
120+
env:
121+
CC: "clang"
122+
CXX: "clang++"
123+
CCACHE_SLOPPINESS: pch_defines,time_macros,include_file_mtime,include_file_ctime
124+
with:
125+
# The action to run
126+
setup-options: -Ddebug=true --optimization=g -Dinstall_data=false -Dinstall_runner=false -Dfmod_dir=/usr/lib/ --prefix=/usr/ -Ddebug_type=release
127+
meson-version: 0.55.3
128+
ninja-version: 1.10.0
129+
action: build
130+
131+
- name: Create AppDir
132+
run: |
133+
echo "Setting output prefix"
134+
DESTDIR=${GITHUB_WORKSPACE}/build/AppDir meson install -C $GITHUB_WORKSPACE"/build"
135+
136+
- name: Download linuxdeploy
137+
working-directory: ${{env.GITHUB_WORKSPACE}}
138+
run: |
139+
wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage -O lindeploy
140+
chmod +x lindeploy
141+
142+
- name: Create AppImage
143+
working-directory: ${{env.GITHUB_WORKSPACE}}
144+
env:
145+
LD_LIBRARY_PATH: ./external/lib/linux/x86_64/
146+
OUTPUT: CortexCommand-debug.AppImage
147+
run: |
148+
echo ${LD_LIBRARY_PATH}
149+
./lindeploy --appdir=build/AppDir --output appimage
150+
151+
- name: Upload Appimage
152+
uses: actions/upload-artifact@v2
153+
with:
154+
name: CortexCommand-debug.AppImage
155+
path: CortexCommand-debug.AppImage

Managers/UInputMan.cpp

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313

1414
#ifdef _WIN32
1515
#include "joystickapi.h"
16-
#endif
17-
#ifdef __unix__
16+
#elif __unix__
1817
#include <fcntl.h>
18+
#include "allegro/internal/aintern.h"
19+
#include "allegro/platform/aintunix.h"
20+
#include "xalleg.h"
1921
#endif
2022

2123
namespace RTE {
@@ -97,6 +99,11 @@ namespace RTE {
9799
m_NetworkAccumulatedElementState[element][inputState] = false;
98100
}
99101
}
102+
103+
#ifdef __unix__
104+
m_AllegroMousePreviousX = 0;
105+
m_AllegroMousePreviousY = 0;
106+
#endif
100107
}
101108

102109
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -115,6 +122,10 @@ namespace RTE {
115122
if (install_joystick(JOY_TYPE_AUTODETECT) != 0) { RTEAbort("Failed to initialize joysticks!"); }
116123
poll_joystick();
117124

125+
#ifdef __unix__
126+
_xwin_input_handler = XWinInputHandlerOverride;
127+
#endif
128+
118129
return 0;
119130
}
120131

@@ -377,7 +388,11 @@ namespace RTE {
377388
void UInputMan::SetMousePos(Vector &newPos, int whichPlayer) const {
378389
// Only mess with the mouse if the original mouse position is not above the screen and may be grabbing the title bar of the game window
379390
if (!m_DisableMouseMoving && !m_TrapMousePos && (whichPlayer == Players::NoPlayer || m_ControlScheme.at(whichPlayer).GetDevice() == InputDevice::DEVICE_MOUSE_KEYB)) {
391+
#ifndef __unix__
380392
position_mouse(static_cast<int>(newPos.GetX()), static_cast<int>(newPos.GetY()));
393+
#else
394+
WarpMouse(newPos.m_X * g_FrameMan.GetResMultiplier(), newPos.m_Y * g_FrameMan.GetResMultiplier());
395+
#endif
381396
}
382397
}
383398

@@ -396,7 +411,19 @@ namespace RTE {
396411

397412
void UInputMan::TrapMousePos(bool trap, int whichPlayer) {
398413
if (whichPlayer == Players::NoPlayer || m_ControlScheme.at(whichPlayer).GetDevice() == InputDevice::DEVICE_MOUSE_KEYB) {
414+
#ifdef __unix__
415+
bool prevTrapStatus = m_TrapMousePos;
416+
#endif
399417
m_TrapMousePos = trap;
418+
#ifdef __unix__
419+
if (m_TrapMousePos != prevTrapStatus) {
420+
WarpMouse(_xwin.window_width / 2, _xwin.window_height / 2);
421+
// Note - Discard mickeys after this warp otherwise mouse will probably jump.
422+
int discard;
423+
get_mouse_mickeys(&discard, &discard);
424+
WarpMouse(_xwin.window_width / 2, _xwin.window_height / 2);
425+
}
426+
#endif
400427
}
401428
m_TrapMousePosPerPlayer[whichPlayer] = trap;
402429
}
@@ -406,7 +433,11 @@ namespace RTE {
406433
void UInputMan::ForceMouseWithinBox(int x, int y, int width, int height, int whichPlayer) const {
407434
// Only mess with the mouse if the original mouse position is not above the screen and may be grabbing the title bar of the game window
408435
if (!m_DisableMouseMoving && !m_TrapMousePos && (whichPlayer == Players::NoPlayer || m_ControlScheme.at(whichPlayer).GetDevice() == InputDevice::DEVICE_MOUSE_KEYB)) {
436+
#ifndef __unix__
409437
position_mouse(Limit(mouse_x, x + width * g_FrameMan.GetResMultiplier(), x), Limit(mouse_y, y + height * g_FrameMan.GetResMultiplier(), y));
438+
#else
439+
WarpMouse(Limit(mouse_x, x + width * g_FrameMan.GetResMultiplier(), x), Limit(mouse_y, y + height * g_FrameMan.GetResMultiplier(), y));
440+
#endif
410441
}
411442
}
412443

@@ -868,7 +899,10 @@ namespace RTE {
868899
if (!m_DisableMouseMoving && !IsInMultiplayerMode()) {
869900
if (m_TrapMousePos) {
870901
// Trap the (invisible) mouse cursor in the middle of the screen, so it doesn't fly out in windowed mode and some other window gets clicked
902+
// Note - on linux the centering is done in the event loop.
903+
#ifndef __unix__
871904
position_mouse(g_FrameMan.GetResX() / 2, g_FrameMan.GetResY() / 2);
905+
#endif
872906
} else if (g_ActivityMan.IsInActivity()) {
873907
// The mouse cursor is visible and can move about the screen/window, but it should still be contained within the mouse player's part of the window
874908
ForceMouseWithinPlayerScreen(mousePlayer);
@@ -981,4 +1015,68 @@ namespace RTE {
9811015
}
9821016
}
9831017
}
1018+
1019+
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1020+
1021+
#ifdef __unix__
1022+
void UInputMan::HandleAllegroMouseInput() {
1023+
if (_xwin.display == 0) {
1024+
return;
1025+
}
1026+
1027+
std::vector<XEvent> events;
1028+
events.reserve(XPending(_xwin.display) + 10);
1029+
while(XPending(_xwin.display) > 0) {
1030+
XEvent e;
1031+
XNextEvent(_xwin.display, &e);
1032+
events.push_back(e);
1033+
}
1034+
1035+
m_AllegroMousePreviousX = mouse_x;
1036+
m_AllegroMousePreviousY = mouse_y;
1037+
int mouseDeltaX = 0;
1038+
int mouseDeltaY = 0;
1039+
1040+
int halfResX = _xwin.window_width / 2;
1041+
int halfResY = _xwin.window_height / 2;
1042+
for (std::vector<XEvent>::reverse_iterator event = events.rbegin(); event < events.rend(); ++event) {
1043+
switch (event->type) {
1044+
case MotionNotify: {
1045+
mouseDeltaX = event->xmotion.x - m_AllegroMousePreviousX;
1046+
mouseDeltaY = event->xmotion.y - m_AllegroMousePreviousY;
1047+
_xwin_mouse_interrupt(mouseDeltaX, mouseDeltaY, 0, 0, mouse_b);
1048+
_mouse_x = m_AllegroMousePreviousX = !m_TrapMousePos ? event->xmotion.x : halfResX;
1049+
_mouse_y = m_AllegroMousePreviousY = !m_TrapMousePos ? event->xmotion.y : halfResY;
1050+
1051+
if (m_TrapMousePos && (mouseDeltaX != 0 || mouseDeltaY != 0)) {
1052+
XWarpPointer(_xwin.display, _xwin.window, _xwin.window, 0, 0, 0, 0, halfResX, halfResY);
1053+
}
1054+
break;
1055+
}
1056+
default:
1057+
XPutBackEvent(_xwin.display, &(*event));
1058+
break;
1059+
}
1060+
}
1061+
XFlush(_xwin.display);
1062+
1063+
_xwin.mouse_warped = 0;
1064+
_xwin_private_handle_input();
1065+
1066+
if (m_TrapMousePos) {
1067+
mouse_x = _xwin.window_width / 2;
1068+
mouse_y = _xwin.window_height / 2;
1069+
}
1070+
_mouse_x = mouse_x;
1071+
_mouse_y = mouse_y;
1072+
}
1073+
1074+
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1075+
1076+
void UInputMan::WarpMouse(int x, int y) const {
1077+
if (mouse_x != x || mouse_y != y) { XWarpPointer(_xwin.display, _xwin.window, _xwin.window, 0, 0, 0, 0, x, y); }
1078+
_mouse_x = mouse_x = x;
1079+
_mouse_y = mouse_y = y;
1080+
}
1081+
#endif
9841082
}

Managers/UInputMan.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,31 @@ namespace RTE {
795795
// Disallow the use of some implicit methods.
796796
UInputMan(const UInputMan &reference) = delete;
797797
UInputMan & operator=(const UInputMan &rhs) = delete;
798+
799+
#ifdef __unix__
800+
int m_AllegroMousePreviousX; //!< Stored mouse x position for the allegro event handler.
801+
int m_AllegroMousePreviousY; //!< Stored mouse y position for the allegro event handler.
802+
803+
/// <summary>
804+
/// Necessary static handler method ensuring mouse inputs work well on Linux. Must be applied to _xwin_input_handler when manager is initialized.
805+
/// </summary>
806+
static void XWinInputHandlerOverride() { g_UInputMan.HandleAllegroMouseInput(); }
807+
808+
/// <summary>
809+
/// Mouse input handler to circumvent the input drops that Allegro does regularly, by replacing and disabling the default warping behavior.
810+
/// Motion events that are generated while the handler is working are offset such that the Allegro driver doesn't mess up the mickeys.
811+
/// This also handles the centering warp for relative mouse motion. Might not run in the main thread, depending on how Allegro was built.
812+
/// </summary>
813+
void HandleAllegroMouseInput();
814+
815+
/// <summary>
816+
/// Position the mouse on the screen in window coordinates. Generates MouseMotion events if the requested position is different from the actual mouse position.
817+
/// Replaces position_mouse and sets the Allegro internal mouse position to the requested coordinates.
818+
/// </summary>
819+
/// <param name="x"> The x coordinate to warp to. </param>
820+
/// <param name="y"> The y coordinate to warp to. </param>
821+
void WarpMouse(int x, int y) const;
822+
#endif
798823
};
799824
}
800825
#endif

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ The Linux build uses the meson build system, and builds against system libraries
6262
* `libX11`
6363
* [`meson`](https://www.mesonbuild.com)`>= 0.53` (If your distro doesn't have a recent version of meson, use the pip version instead)
6464
* `boost>=1.55`
65+
* (optional) `xmessage`
6566

6667
## Building
6768

@@ -97,13 +98,17 @@ If you want to change the buildtype afterwards, you can use `meson configure --b
9798
## Installing Dependencies
9899

99100
**Arch Linux:**
100-
`# pacman -S allegro4 boost flac luajit minizip lz4 libpng libx11 meson ninja base-devel`
101+
`# pacman -S allegro4 boost flac luajit minizip lz4 libpng libx11 xorg-xmessage meson ninja base-devel`
101102

102103
**Ubuntu >=20.04:**
103104
`# apt-get install build-essential libboost-dev liballegro4-dev libloadpng4-dev libflac++-dev luajit-5.1-dev libminizip-dev liblz4-dev libpng++-dev libx11-dev ninja-build meson`
104105
## Troubleshooting
105106

106-
On some distros some keyboards and mice are recognized as controllers, to fix this follow these instructions: [https://github.com/denilsonsa/udev-joystick-blacklist](https://github.com/denilsonsa/udev-joystick-blacklist)
107+
* On some distros some keyboards and mice are recognized as controllers, to fix this follow these instructions: [https://github.com/denilsonsa/udev-joystick-blacklist](https://github.com/denilsonsa/udev-joystick-blacklist)
108+
109+
* `pipewire(-alsa)` and fmod don't work well together, so the game might [not close, have no sound or crash](https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1514). Workaround by `ln -s /bin/true /usr/bin/pulseaudio`
110+
111+
* Gamepad triggers may be inverted, to work around that: Hold down the trigger, select the input you want it assigned to and release to assign it, then it will be correct in use.
107112

108113
***
109114

0 commit comments

Comments
 (0)