Skip to content

Commit

Permalink
linux support, maybe fix slopes
Browse files Browse the repository at this point in the history
  • Loading branch information
theyareonit committed Sep 14, 2024
1 parent 8c732c3 commit 6dece71
Show file tree
Hide file tree
Showing 11 changed files with 586 additions and 34 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,6 @@ build-*/

# Visual Studio
.vs/

# Geode resources
!resources/*
6 changes: 5 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# v1.1.22
# v1.2.0

* Potentially fix slope bugs
* Potentially improve performance
* Fix keyboard input not working on Linux
* Significantly improve input precision on Linux
* Don't submit CBF completions to leaderboards anymore

# v1.1.21

Expand Down
12 changes: 9 additions & 3 deletions mod.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"geode": "3.4.0",
"geode": "3.5.0",
"gd": {
"win": "2.206"
},
"version": "v1.1.22",
"version": "v1.2.0",
"id": "syzzi.click_between_frames",
"name": "Click Between Frames",
"developer": "syzzi",
Expand Down Expand Up @@ -59,5 +59,11 @@
"default": true
}
},
"repository": "https://github.com/theyareonit/Click-Between-Frames"
"repository": "https://github.com/theyareonit/Click-Between-Frames",
"resources": {
"files": [
"resources/linux-input.exe",
"resources/linux-input.exe.so"
]
}
}
36 changes: 36 additions & 0 deletions resources/linux-input.exe
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/bin/sh

appname="linux-input.exe.so"
# determine the application directory
appdir=''
case "$0" in
*/*)
# $0 contains a path, use it
appdir=`dirname "$0"`
;;
*)
# no directory in $0, search in PATH
saved_ifs=$IFS
IFS=:
for d in $PATH
do
IFS=$saved_ifs
if [ -x "$d/$appname" ]; then appdir="$d"; break; fi
done
;;
esac

# figure out the full app path
if [ -n "$appdir" ]; then
apppath="$appdir/$appname"
WINEDLLPATH="$appdir:$WINEDLLPATH"
export WINEDLLPATH
else
apppath="$appname"
fi

# determine the WINELOADER
if [ ! -x "$WINELOADER" ]; then WINELOADER="wine"; fi

# and try to start the app
exec "$WINELOADER" "$apppath" "$@"
Binary file added resources/linux-input.exe.so
Binary file not shown.
23 changes: 17 additions & 6 deletions src/includes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,23 @@ enum GameAction : int {
p2Right = 5
};

enum Player : bool {
Player1 = 0,
Player2 = 1
};

enum State : bool {
Press = 0,
Release = 1
};

struct __attribute__((packed)) LinuxInputEvent {
LARGE_INTEGER time;
USHORT type;
USHORT code;
int value;
};

struct InputEvent {
LARGE_INTEGER time;
PlayerButton inputType;
bool inputState;
bool player;
bool isPlayer1;
};

struct Step {
Expand All @@ -40,7 +42,12 @@ struct Step {
bool endStep;
};

extern HANDLE hSharedMem;
extern HANDLE hMutex;
extern LPVOID pBuf;

extern std::queue<struct InputEvent> inputQueue;
extern std::queue<struct InputEvent> inputQueueCopy;

extern std::array<std::unordered_set<size_t>, 6> inputBinds;
extern std::unordered_set<USHORT> heldInputs;
Expand All @@ -50,5 +57,9 @@ extern std::mutex keybindsLock;

extern std::atomic<bool> enableRightClick;
extern bool threadPriority;
extern bool isLinux;

constexpr size_t BUFFER_SIZE = 20;

void linuxCheckInputs();
void inputThread();
80 changes: 62 additions & 18 deletions src/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
LARGE_INTEGER time;
PlayerButton inputType;
bool inputState;
bool player;
bool player1;

QueryPerformanceCounter(&time);

Expand Down Expand Up @@ -48,23 +48,21 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
}

bool shouldEmplace = true;
player = Player1;
player1 = true;

std::array<std::unordered_set<size_t>, 6> binds;
{
std::lock_guard lock(keybindsLock);
binds = inputBinds;
}

if (binds[p1Jump].contains(vkey)) inputType = PlayerButton::Jump;
else if (binds[p1Left].contains(vkey)) inputType = PlayerButton::Left;
else if (binds[p1Right].contains(vkey)) inputType = PlayerButton::Right;
else {
player = Player2;
if (binds[p2Jump].contains(vkey)) inputType = PlayerButton::Jump;
else if (binds[p2Left].contains(vkey)) inputType = PlayerButton::Left;
else if (binds[p2Right].contains(vkey)) inputType = PlayerButton::Right;
else shouldEmplace = false;
if (inputBinds[p1Jump].contains(vkey)) inputType = PlayerButton::Jump;
else if (inputBinds[p1Left].contains(vkey)) inputType = PlayerButton::Left;
else if (inputBinds[p1Right].contains(vkey)) inputType = PlayerButton::Right;
else {
player1 = false;
if (inputBinds[p2Jump].contains(vkey)) inputType = PlayerButton::Jump;
else if (inputBinds[p2Left].contains(vkey)) inputType = PlayerButton::Left;
else if (inputBinds[p2Right].contains(vkey)) inputType = PlayerButton::Right;
else shouldEmplace = false;
}
}

if (!inputState) heldInputs.emplace(vkey);
Expand All @@ -76,13 +74,13 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
USHORT flags = raw->data.mouse.usButtonFlags;
bool shouldEmplace = true;

player = Player1;
player1 = true;
inputType = PlayerButton::Jump;

if (flags & RI_MOUSE_BUTTON_1_DOWN) inputState = Press;
else if (flags & RI_MOUSE_BUTTON_1_UP) inputState = Release;
else {
player = Player2;
player1 = false;
if (!enableRightClick.load()) return 0;
if (flags & RI_MOUSE_BUTTON_2_DOWN) inputState = Press;
else if (flags & RI_MOUSE_BUTTON_2_UP) inputState = Release;
Expand All @@ -101,14 +99,13 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{
std::lock_guard lock(inputQueueLock);
inputQueue.emplace(InputEvent{ time, inputType, inputState, player });
inputQueue.emplace(InputEvent{ time, inputType, inputState, player1 });
}

return 0;
}

void inputThread() {

WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = GetModuleHandleA(NULL);
Expand Down Expand Up @@ -144,4 +141,51 @@ void inputThread() {
while (GetMessage(&msg, hwnd, 0, 0)) {
DispatchMessage(&msg);
}
}

void linuxCheckInputs() {
DWORD waitResult = WaitForSingleObject(hMutex, 1);
if (waitResult == WAIT_OBJECT_0) {
LinuxInputEvent* events = static_cast<LinuxInputEvent*>(pBuf);
for (int i = 0; i < BUFFER_SIZE; i++) {
if (events[i].type == 0) break;

InputEvent input;
bool player1 = true;

USHORT scanCode = events[i].code;
if (scanCode == 0x3110) { // left click
input.inputType = PlayerButton::Jump;
}
else if (scanCode == 0x3111) { // right click
if (!enableRightClick.load()) continue;
input.inputType = PlayerButton::Jump;
player1 = false;
}
else {
USHORT keyCode = MapVirtualKeyExA(scanCode, MAPVK_VSC_TO_VK, GetKeyboardLayout(0));
if (inputBinds[p1Jump].contains(keyCode)) input.inputType = PlayerButton::Jump;
else if (inputBinds[p1Left].contains(keyCode)) input.inputType = PlayerButton::Left;
else if (inputBinds[p1Right].contains(keyCode)) input.inputType = PlayerButton::Right;
else {
player1 = false;
if (inputBinds[p2Jump].contains(keyCode)) input.inputType = PlayerButton::Jump;
else if (inputBinds[p2Left].contains(keyCode)) input.inputType = PlayerButton::Left;
else if (inputBinds[p2Right].contains(keyCode)) input.inputType = PlayerButton::Right;
else continue;
}
}

input.inputState = !events[i].value;
input.time = events[i].time;
input.isPlayer1 = player1;

inputQueueCopy.emplace(input);
}
ZeroMemory(events, sizeof(LinuxInputEvent[BUFFER_SIZE]));
ReleaseMutex(hMutex);
}
else if (waitResult != WAIT_TIMEOUT) {
log::error("WaitForSingleObject failed: {}", GetLastError());
}
}
112 changes: 112 additions & 0 deletions src/linux/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
### Generated by Winemaker 0.8.4
###
### Invocation command line was
### /usr/bin/winemaker -iws2_32 -ievdev . --single-target linux-input


SRCDIR = .
SUBDIRS =
DLLS =
LIBS =
EXES = linux-input



### Common settings

CEXTRA =
CXXEXTRA =
RCEXTRA =
DEFINES =
INCLUDE_PATH =
DLL_PATH =
DLL_IMPORTS = ws2_32 \
evdev
LIBRARY_PATH =
LIBRARIES =


### linux-input sources and settings

linux_input_MODULE = linux-input
linux_input_C_SRCS =
linux_input_CXX_SRCS = linux-input.cpp
linux_input_RC_SRCS =
linux_input_LDFLAGS =
linux_input_ARFLAGS =
linux_input_DLL_PATH =
linux_input_DLLS =
linux_input_LIBRARY_PATH=
linux_input_LIBRARIES =

linux_input_OBJS = $(linux_input_C_SRCS:.c=.o) \
$(linux_input_CXX_SRCS:.cpp=.o) \
$(linux_input_RC_SRCS:.rc=.res)



### Global source lists

C_SRCS = $(linux_input_C_SRCS)
CXX_SRCS = $(linux_input_CXX_SRCS)
RC_SRCS = $(linux_input_RC_SRCS)


### Tools

CC = winegcc
CXX = wineg++
RC = wrc
AR = ar


### Generic targets

all: $(SUBDIRS) $(DLLS:%=%.so) $(LIBS) $(EXES)

### Build rules

.PHONY: all clean dummy

$(SUBDIRS): dummy
@cd $@ && $(MAKE)

# Implicit rules

.SUFFIXES: .cpp .cxx .rc .res
DEFINCL = $(INCLUDE_PATH) $(DEFINES) $(OPTIONS)

.c.o:
$(CC) -c $(CFLAGS) $(CEXTRA) $(DEFINCL) -o $@ $<

.cpp.o:
$(CXX) -c $(CXXFLAGS) $(CXXEXTRA) $(DEFINCL) -o $@ $<

.cxx.o:
$(CXX) -c $(CXXFLAGS) $(CXXEXTRA) $(DEFINCL) -o $@ $<

.rc.res:
$(RC) $(RCFLAGS) $(RCEXTRA) $(DEFINCL) -fo$@ $<

# Rules for cleaning

CLEAN_FILES = y.tab.c y.tab.h lex.yy.c core *.orig *.rej \
\\\#*\\\# *~ *% .\\\#*

clean:: $(SUBDIRS:%=%/__clean__) $(EXTRASUBDIRS:%=%/__clean__)
$(RM) $(CLEAN_FILES) $(RC_SRCS:.rc=.res) $(C_SRCS:.c=.o) $(CXX_SRCS:.cpp=.o)
$(RM) $(DLLS:%=%.so) $(LIBS) $(EXES) $(EXES:%=%.so)

$(SUBDIRS:%=%/__clean__): dummy
cd `dirname $@` && $(MAKE) clean

$(EXTRASUBDIRS:%=%/__clean__): dummy
-cd `dirname $@` && $(RM) $(CLEAN_FILES)

### Target specific build rules
DEFLIB = $(LIBRARY_PATH) $(LIBRARIES) $(DLL_PATH) $(DLL_IMPORTS:%=-l%)

$(linux_input_MODULE): $(linux_input_OBJS)
$(CXX) $(linux_input_LDFLAGS) -o $@ $(linux_input_OBJS) $(linux_input_LIBRARY_PATH) $(linux_input_DLL_PATH) $(DEFLIB) $(linux_input_DLLS:%=-l%) $(linux_input_LIBRARIES:%=-l%)


5 changes: 5 additions & 0 deletions src/linux/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# too lazy to make this into a github workflow
winemaker -iws2_32 -ievdev . --single-target linux-input
make
cp linux-input.exe ../../resources/linux-input.exe
cp linux-input.exe.so ../../resources/linux-input.exe.so
Loading

0 comments on commit 6dece71

Please sign in to comment.