mirror of
https://github.com/qmk/qmk_firmware.git
synced 2024-11-21 10:59:29 +00:00
Compare commits
20 Commits
e24f7f9035
...
8ae3e7e192
Author | SHA1 | Date | |
---|---|---|---|
|
8ae3e7e192 | ||
|
9bea332a21 | ||
|
8cbcdcac62 | ||
|
10887b796c | ||
|
c298330faf | ||
|
b16bf7e0f5 | ||
|
d856718821 | ||
|
b27f81c9b9 | ||
|
5b9d208ee1 | ||
|
ca78bd7b9f | ||
|
270afe875d | ||
|
37881707b4 | ||
|
4c94a00512 | ||
|
b4ac67cf53 | ||
|
baa99f9ff1 | ||
|
a6a8431444 | ||
|
3b9132d9d2 | ||
|
14946e23e8 | ||
|
27e232c877 | ||
|
bb3af86e1c |
8
keyboards/takashicompany/left_slinger/config.h
Normal file
8
keyboards/takashicompany/left_slinger/config.h
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright 2024 takashicompany (@takashicompany)
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ANALOG_JOYSTICK_X_AXIS_PIN GP28
|
||||
#define ANALOG_JOYSTICK_Y_AXIS_PIN GP29
|
||||
#define ANALOG_JOYSTICK_READ_INTERVAL 1
|
67
keyboards/takashicompany/left_slinger/custom_joystick.c
Normal file
67
keyboards/takashicompany/left_slinger/custom_joystick.c
Normal file
@ -0,0 +1,67 @@
|
||||
// Copyright 2024 takashicompany (@takashicompany)
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include QMK_KEYBOARD_H
|
||||
#include "analog.h"
|
||||
#include "gpio.h"
|
||||
#include "wait.h"
|
||||
#include "timer.h"
|
||||
#include <stdlib.h>
|
||||
#include "print.h"
|
||||
#include "custom_joystick.h"
|
||||
|
||||
int16_t xOrigin, yOrigin;
|
||||
uint16_t lastCursor = 0;
|
||||
int16_t joystick_ratio = 100;
|
||||
int16_t joystick_raw_x = 0;
|
||||
int16_t joystick_raw_y = 0;
|
||||
|
||||
int16_t axisCoordinate_custom(pin_t pin, uint16_t origin) {
|
||||
int8_t direction; // 符号
|
||||
int16_t distanceFromOrigin; // 原点からの距離。負数にはならない
|
||||
|
||||
int16_t position = analogReadPin(pin); // 多分だけどデフォルトだと512が中心に来るようになっている
|
||||
|
||||
if (origin == position) { // 原点と同じなら0とする
|
||||
return 0;
|
||||
} else if (origin > position) { // 原点よりマイナス方向の場合の処理
|
||||
distanceFromOrigin = origin - position;
|
||||
direction = -1;
|
||||
} else { // 原点よりプラス方向の処理
|
||||
distanceFromOrigin = position - origin;
|
||||
direction = 1;
|
||||
}
|
||||
|
||||
return distanceFromOrigin * direction;
|
||||
}
|
||||
|
||||
void pointing_device_driver_init(void) {
|
||||
xOrigin = analogReadPin(ANALOG_JOYSTICK_X_AXIS_PIN);
|
||||
yOrigin = analogReadPin(ANALOG_JOYSTICK_Y_AXIS_PIN);
|
||||
}
|
||||
|
||||
report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) {
|
||||
|
||||
if (timer_elapsed(lastCursor) > ANALOG_JOYSTICK_READ_INTERVAL) { // 多分、指定のミリ秒経過したかを見て処理を走らせている
|
||||
lastCursor = timer_read();
|
||||
|
||||
int16_t jsr = joystick_ratio;
|
||||
if (0 <= jsr && jsr < 10) {
|
||||
jsr = 10;
|
||||
}
|
||||
else if (-10 < jsr && jsr < 0) {
|
||||
jsr = -10;
|
||||
}
|
||||
|
||||
joystick_raw_x = axisCoordinate_custom(ANALOG_JOYSTICK_X_AXIS_PIN, xOrigin);
|
||||
joystick_raw_y = axisCoordinate_custom(ANALOG_JOYSTICK_Y_AXIS_PIN, yOrigin);
|
||||
|
||||
mouse_report.x = joystick_raw_x / jsr;
|
||||
mouse_report.y = joystick_raw_y / jsr;
|
||||
}
|
||||
|
||||
return mouse_report;
|
||||
}
|
||||
|
||||
uint16_t pointing_device_driver_get_cpi(void) { return 0; }
|
||||
void pointing_device_driver_set_cpi(uint16_t cpi) {}
|
11
keyboards/takashicompany/left_slinger/custom_joystick.h
Normal file
11
keyboards/takashicompany/left_slinger/custom_joystick.h
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2024 takashicompany (@takashicompany)
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
extern int16_t joystick_ratio;
|
||||
extern int16_t joystick_raw_x;
|
||||
extern int16_t joystick_raw_y;
|
59
keyboards/takashicompany/left_slinger/keyboard.json
Normal file
59
keyboards/takashicompany/left_slinger/keyboard.json
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"manufacturer": "takashicompany",
|
||||
"keyboard_name": "Left Slinger",
|
||||
"maintainer": "takashicompany",
|
||||
"bootloader": "rp2040",
|
||||
"diode_direction": "COL2ROW",
|
||||
"encoder": {
|
||||
"rotary": [
|
||||
{"pin_a": "GP14", "pin_b": "GP15"}
|
||||
]
|
||||
},
|
||||
"features": {
|
||||
"bootmagic": true,
|
||||
"command": false,
|
||||
"console": false,
|
||||
"encoder": true,
|
||||
"extrakey": true,
|
||||
"mousekey": true,
|
||||
"nkro": true
|
||||
},
|
||||
"matrix_pins": {
|
||||
"cols": ["GP5", "GP6", "GP7"],
|
||||
"rows": ["GP8", "GP9", "GP10", "GP11", "GP12", "GP13", "GP0"]
|
||||
},
|
||||
"processor": "RP2040",
|
||||
"url": "",
|
||||
"usb": {
|
||||
"device_version": "1.0.0",
|
||||
"pid": "0x0061",
|
||||
"vid": "0x7463"
|
||||
},
|
||||
"layouts": {
|
||||
"LAYOUT": {
|
||||
"layout": [
|
||||
{"matrix": [0, 0], "x": 1, "y": 0},
|
||||
{"matrix": [0, 1], "x": 2, "y": 0},
|
||||
{"matrix": [0, 2], "x": 3, "y": 0},
|
||||
{"matrix": [1, 0], "x": 0, "y": 1},
|
||||
{"matrix": [1, 1], "x": 1, "y": 1},
|
||||
{"matrix": [1, 2], "x": 2, "y": 1},
|
||||
{"matrix": [2, 0], "x": 3, "y": 1},
|
||||
{"matrix": [3, 0], "x": 0, "y": 2},
|
||||
{"matrix": [3, 1], "x": 1, "y": 2},
|
||||
{"matrix": [3, 2], "x": 2, "y": 2},
|
||||
{"matrix": [2, 1], "x": 3, "y": 2},
|
||||
{"matrix": [2, 2], "x": 4.25, "y": 2},
|
||||
{"matrix": [4, 0], "x": 1, "y": 3.25},
|
||||
{"matrix": [4, 1], "x": 2, "y": 3.25},
|
||||
{"matrix": [4, 2], "x": 3, "y": 3.25},
|
||||
{"matrix": [6, 0], "x": 4.25, "y": 3.25},
|
||||
{"matrix": [6, 1], "x": 5.25, "y": 3.25},
|
||||
{"matrix": [5, 0], "x": 1, "y": 4.25},
|
||||
{"matrix": [5, 1], "x": 2, "y": 4.25},
|
||||
{"matrix": [5, 2], "x": 3, "y": 4.25},
|
||||
{"matrix": [6, 2], "x": 4.25, "y": 4.25}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
// Copyright 2023 QMK
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include QMK_KEYBOARD_H
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = LAYOUT(
|
||||
KC_Q , KC_W , KC_E ,
|
||||
MY_JSKE, KC_A , KC_S , KC_D ,
|
||||
KC_LSFT, KC_Z , KC_X , KC_C , KC_V ,
|
||||
KC_LCTL, KC_UP , KC_LALT, KC_ESC , KC_ENT ,
|
||||
KC_LEFT, KC_DOWN, KC_RGHT, KC_BSPC
|
||||
),
|
||||
|
||||
[1] = LAYOUT(
|
||||
KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO
|
||||
),
|
||||
|
||||
[2] = LAYOUT(
|
||||
KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO
|
||||
),
|
||||
|
||||
[3] = LAYOUT(
|
||||
KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO
|
||||
),
|
||||
|
||||
[4] = LAYOUT(
|
||||
KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO
|
||||
),
|
||||
|
||||
[5] = LAYOUT(
|
||||
KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO
|
||||
),
|
||||
|
||||
[6] = LAYOUT(
|
||||
KC_NO , KC_NO , KC_NO ,
|
||||
KC_TRNS, MY_BTN2, MY_SCRL, MY_BTN1,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , KC_NO , KC_NO
|
||||
),
|
||||
|
||||
[7] = LAYOUT(
|
||||
KC_NO , KC_NO , KC_NO ,
|
||||
KC_NO , KC_NO , MY_CLKD, MY_CLKI,
|
||||
QK_BOOT, KC_NO , MY_SCDV, MY_SCDH, KC_NO ,
|
||||
MY_JSKD, MY_JSDD, MY_JSDI, KC_NO , KC_NO ,
|
||||
KC_NO , MY_STGE, KC_NO , KC_NO
|
||||
),
|
||||
};
|
||||
|
||||
#if defined(ENCODER_MAP_ENABLE)
|
||||
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
|
||||
[0] = { ENCODER_CCW_CW(MS_WHLD, MS_WHLU) },
|
||||
[1] = { ENCODER_CCW_CW(MS_WHLL, MS_WHLR) },
|
||||
[2] = { ENCODER_CCW_CW(KC_TRNS, KC_TRNS) },
|
||||
[3] = { ENCODER_CCW_CW(KC_TRNS, KC_TRNS) },
|
||||
[4] = { ENCODER_CCW_CW(KC_TRNS, KC_TRNS) },
|
||||
[5] = { ENCODER_CCW_CW(KC_TRNS, KC_TRNS) },
|
||||
[6] = { ENCODER_CCW_CW(KC_TRNS, KC_TRNS) },
|
||||
[7] = { ENCODER_CCW_CW(KC_TRNS, KC_TRNS) }
|
||||
};
|
||||
#endif
|
@ -0,0 +1 @@
|
||||
ENCODER_MAP_ENABLE = yes
|
531
keyboards/takashicompany/left_slinger/left_slinger.c
Normal file
531
keyboards/takashicompany/left_slinger/left_slinger.c
Normal file
@ -0,0 +1,531 @@
|
||||
// #include <stdio.h>
|
||||
#include "quantum.h"
|
||||
#include "left_slinger.h"
|
||||
#include "custom_joystick.h"
|
||||
|
||||
#if CONSOLE_ENABLE
|
||||
#include <print.h>
|
||||
#endif
|
||||
|
||||
/////////////////////////////
|
||||
/// miniZoneの実装 ここから ///
|
||||
////////////////////////////
|
||||
|
||||
#define MOUSE_SCROLL_V_REVERSE_BIT (1 << 0) // 0000 0001
|
||||
#define MOUSE_SCROLL_H_REVERSE_BIT (1 << 1) // 0000 0010
|
||||
#define JOYSTICK_KEY_DEFAULT_ENABLE (1 << 2) // 0000 0100
|
||||
|
||||
enum click_state {
|
||||
NONE = 0,
|
||||
WAITING, // マウスレイヤーが有効になるのを待つ。 Wait for mouse layer to activate.
|
||||
CLICKABLE, // マウスレイヤー有効になりクリック入力が取れる。 Mouse layer is enabled to take click input.
|
||||
CLICKING, // クリック中。 Clicking.
|
||||
SCROLLING // スクロール中。 Scrolling.
|
||||
};
|
||||
|
||||
typedef union {
|
||||
uint32_t raw;
|
||||
|
||||
struct {
|
||||
// int16_t to_clickable_time; // // この秒数(千分の一秒)、WAITING状態ならクリックレイヤーが有効になる。 For this number of seconds (milliseconds), if in WAITING state, the click layer is activated.
|
||||
int16_t joystick_ratio;
|
||||
int8_t to_clickable_movement;
|
||||
uint8_t settings;
|
||||
};
|
||||
} user_config_t;
|
||||
|
||||
user_config_t user_config;
|
||||
|
||||
enum click_state state; // 現在のクリック入力受付の状態 Current click input reception status
|
||||
uint16_t click_timer; // タイマー。状態に応じて時間で判定する。 Timer. Time to determine the state of the system.
|
||||
|
||||
// uint16_t to_clickable_time = 50; // この秒数(千分の一秒)、WAITING状態ならクリックレイヤーが有効になる。 For this number of seconds (milliseconds), if in WAITING state, the click layer is activated.
|
||||
uint16_t to_reset_time = 1000; // この秒数(千分の一秒)、CLICKABLE状態ならクリックレイヤーが無効になる。 For this number of seconds (milliseconds), the click layer is disabled if in CLICKABLE state.
|
||||
|
||||
const uint16_t click_layer = 6; // マウス入力が可能になった際に有効になるレイヤー。Layers enabled when mouse input is enabled
|
||||
const uint16_t setting_layer = 7;
|
||||
|
||||
int16_t scroll_v_mouse_interval_counter; // 垂直スクロールの入力をカウントする。 Counting Vertical Scroll Inputs
|
||||
int16_t scroll_h_mouse_interval_counter; // 水平スクロールの入力をカウントする。 Counts horizontal scrolling inputs.
|
||||
|
||||
int16_t scroll_v_threshold = 50; // この閾値を超える度に垂直スクロールが実行される。 Vertical scrolling is performed each time this threshold is exceeded.
|
||||
int16_t scroll_h_threshold = 50; // この閾値を超える度に水平スクロールが実行される。 Each time this threshold is exceeded, horizontal scrolling is performed.
|
||||
|
||||
int16_t after_click_lock_movement = 0; // クリック入力後の移動量を測定する変数。 Variable that measures the amount of movement after a click input.
|
||||
|
||||
int16_t mouse_record_threshold = 30; // ポインターの動きを一時的に記録するフレーム数。 Number of frames in which the pointer movement is temporarily recorded.
|
||||
int16_t mouse_move_count_ratio = 5; // ポインターの動きを再生する際の移動フレームの係数。 The coefficient of the moving frame when replaying the pointer movement.
|
||||
|
||||
const uint16_t ignore_disable_mouse_layer_keys[] = {KC_LGUI, KC_LCTL}; // この配列で指定されたキーはマウスレイヤー中に押下してもマウスレイヤーを解除しない
|
||||
|
||||
int16_t mouse_movement;
|
||||
|
||||
bool joystick_key_flag = false;
|
||||
|
||||
void eeconfig_init_kb(void) {
|
||||
user_config.raw = 0;
|
||||
user_config.joystick_ratio = 100;
|
||||
user_config.to_clickable_movement = 50;
|
||||
// 新しいビットフィールド設定
|
||||
|
||||
user_config.settings = 0; // 初期化
|
||||
user_config.settings |= MOUSE_SCROLL_V_REVERSE_BIT * false; // ここでfalseなので実際にはセットしない
|
||||
user_config.settings |= MOUSE_SCROLL_H_REVERSE_BIT * false; // 同上
|
||||
user_config.settings |= JOYSTICK_KEY_DEFAULT_ENABLE * false;
|
||||
|
||||
eeconfig_update_kb(user_config.raw);
|
||||
}
|
||||
|
||||
bool get_mouse_scroll_v_reverse(void) {
|
||||
return user_config.settings & MOUSE_SCROLL_V_REVERSE_BIT;
|
||||
}
|
||||
|
||||
bool get_mouse_scroll_h_reverse(void) {
|
||||
return user_config.settings & MOUSE_SCROLL_H_REVERSE_BIT;
|
||||
}
|
||||
|
||||
void set_mouse_scroll_v_reverse(bool value) {
|
||||
if (value) {
|
||||
user_config.settings |= MOUSE_SCROLL_V_REVERSE_BIT;
|
||||
} else {
|
||||
user_config.settings &= ~MOUSE_SCROLL_V_REVERSE_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
void set_mouse_scroll_h_reverse(bool value) {
|
||||
if (value) {
|
||||
user_config.settings |= MOUSE_SCROLL_H_REVERSE_BIT;
|
||||
} else {
|
||||
user_config.settings &= ~MOUSE_SCROLL_H_REVERSE_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
bool get_joystick_key_default_enable(void) {
|
||||
return user_config.settings & JOYSTICK_KEY_DEFAULT_ENABLE;
|
||||
}
|
||||
|
||||
void set_joystick_key_default_enable(bool value) {
|
||||
if (value) {
|
||||
user_config.settings |= JOYSTICK_KEY_DEFAULT_ENABLE;
|
||||
} else {
|
||||
user_config.settings &= ~JOYSTICK_KEY_DEFAULT_ENABLE;
|
||||
}
|
||||
}
|
||||
|
||||
void keyboard_post_init_kb(void) {
|
||||
user_config.raw = eeconfig_read_kb();
|
||||
joystick_ratio = user_config.joystick_ratio;
|
||||
}
|
||||
|
||||
// クリック用のレイヤーを有効にする。 Enable layers for clicks
|
||||
void enable_click_layer(void) {
|
||||
layer_on(click_layer);
|
||||
click_timer = timer_read();
|
||||
state = CLICKABLE;
|
||||
}
|
||||
|
||||
// クリック用のレイヤーを無効にする。 Disable layers for clicks.
|
||||
void disable_click_layer(void) {
|
||||
state = NONE;
|
||||
layer_off(click_layer);
|
||||
scroll_v_mouse_interval_counter = 0;
|
||||
scroll_h_mouse_interval_counter = 0;
|
||||
}
|
||||
|
||||
bool setting_flags[4] = { false, false, false, false };
|
||||
|
||||
void enable_setting_layer(void) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
setting_flags[i] = false;
|
||||
}
|
||||
layer_on(setting_layer);
|
||||
|
||||
SEND_STRING(" Setting Layer Start.");
|
||||
}
|
||||
|
||||
void disable_setting_layer(void) {
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
setting_flags[i] = false;
|
||||
}
|
||||
|
||||
layer_off(setting_layer);
|
||||
SEND_STRING(" Setting Layer End.");
|
||||
}
|
||||
|
||||
// 自前の絶対数を返す関数。 Functions that return absolute numbers.
|
||||
int8_t my_abs(int8_t num) {
|
||||
if (num < 0) {
|
||||
num = -num;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int16_t my_abs_16(int16_t num) {
|
||||
if (num < 0) {
|
||||
num = -num;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
// 現在クリックが可能な状態か。 Is it currently clickable?
|
||||
bool is_clickable_mode(void) {
|
||||
return state == CLICKABLE || state == CLICKING || state == SCROLLING;
|
||||
}
|
||||
|
||||
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
|
||||
|
||||
if (record->event.key.row == 0 && record->event.key.col == 0)
|
||||
{
|
||||
setting_flags[0] = record->event.pressed;
|
||||
}
|
||||
|
||||
if (record->event.key.row == 0 && record->event.key.col == 2)
|
||||
{
|
||||
setting_flags[1] = record->event.pressed;
|
||||
}
|
||||
|
||||
if (record->event.key.row == 5 && record->event.key.col == 0)
|
||||
{
|
||||
setting_flags[2] = record->event.pressed;
|
||||
}
|
||||
|
||||
if (record->event.key.row == 5 && record->event.key.col == 2)
|
||||
{
|
||||
setting_flags[3] = record->event.pressed;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (!setting_flags[i])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == 3)
|
||||
{
|
||||
enable_setting_layer();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch (keycode) {
|
||||
case MY_BTN1:
|
||||
case MY_BTN2:
|
||||
case MY_BTN3:
|
||||
{
|
||||
report_mouse_t currentReport = pointing_device_get_report();
|
||||
|
||||
// どこのビットを対象にするか。 Which bits are to be targeted?
|
||||
uint8_t btn = 1 << (keycode - MY_BTN1);
|
||||
|
||||
if (record->event.pressed) {
|
||||
// ビットORは演算子の左辺と右辺の同じ位置にあるビットを比較して、両方のビットのどちらかが「1」の場合に「1」にします。
|
||||
// Bit OR compares bits in the same position on the left and right sides of the operator and sets them to "1" if either of both bits is "1".
|
||||
currentReport.buttons |= btn;
|
||||
state = CLICKING;
|
||||
after_click_lock_movement = 30;
|
||||
} else {
|
||||
// ビットANDは演算子の左辺と右辺の同じ位置にあるビットを比較して、両方のビットが共に「1」の場合だけ「1」にします。
|
||||
// Bit AND compares the bits in the same position on the left and right sides of the operator and sets them to "1" only if both bits are "1" together.
|
||||
currentReport.buttons &= ~btn;
|
||||
}
|
||||
|
||||
enable_click_layer();
|
||||
|
||||
pointing_device_set_report(currentReport);
|
||||
pointing_device_send();
|
||||
return false;
|
||||
}
|
||||
|
||||
case MY_SCRL:
|
||||
if (record->event.pressed) {
|
||||
state = SCROLLING;
|
||||
} else {
|
||||
enable_click_layer(); // スクロールキーを離した時に再度クリックレイヤーを有効にする。 Enable click layer again when the scroll key is released.
|
||||
}
|
||||
return false;
|
||||
|
||||
case MY_CLKI:
|
||||
if (record->event.pressed) {
|
||||
user_config.to_clickable_movement += 5;
|
||||
eeconfig_update_kb(user_config.raw);
|
||||
}
|
||||
return false;
|
||||
|
||||
case MY_CLKD:
|
||||
if (record->event.pressed) {
|
||||
|
||||
user_config.to_clickable_movement -= 5;
|
||||
|
||||
if (user_config.to_clickable_movement < 5) {
|
||||
user_config.to_clickable_movement = 5;
|
||||
}
|
||||
|
||||
eeconfig_update_kb(user_config.raw);
|
||||
}
|
||||
return false;
|
||||
|
||||
case MY_SCDV:
|
||||
if (record->event.pressed) {
|
||||
set_mouse_scroll_v_reverse(!get_mouse_scroll_v_reverse());
|
||||
eeconfig_update_kb(user_config.raw);
|
||||
}
|
||||
return false;
|
||||
|
||||
case MY_SCDH:
|
||||
if (record->event.pressed) {
|
||||
set_mouse_scroll_h_reverse(!get_mouse_scroll_h_reverse());
|
||||
eeconfig_update_kb(user_config.raw);
|
||||
}
|
||||
return false;
|
||||
|
||||
case MY_JSDI:
|
||||
if (record->event.pressed) {
|
||||
joystick_ratio = joystick_ratio + 5;
|
||||
user_config.joystick_ratio = joystick_ratio;
|
||||
eeconfig_update_kb(user_config.raw);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MY_JSDD:
|
||||
if (record->event.pressed) {
|
||||
joystick_ratio = joystick_ratio - 5;
|
||||
user_config.joystick_ratio = joystick_ratio;
|
||||
eeconfig_update_kb(user_config.raw);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MY_STGE:
|
||||
if (record->event.pressed) {
|
||||
disable_setting_layer();
|
||||
}
|
||||
break;
|
||||
|
||||
case MY_JSKD:
|
||||
if (record->event.pressed) {
|
||||
set_joystick_key_default_enable(!get_joystick_key_default_enable());
|
||||
eeconfig_update_kb(user_config.raw);
|
||||
}
|
||||
break;
|
||||
|
||||
case MY_JSKE:
|
||||
joystick_key_flag = record->event.pressed;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (record->event.pressed) {
|
||||
|
||||
if (state == CLICKING || state == SCROLLING)
|
||||
{
|
||||
enable_click_layer();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(ignore_disable_mouse_layer_keys) / sizeof(ignore_disable_mouse_layer_keys[0]); i++)
|
||||
{
|
||||
if (keycode == ignore_disable_mouse_layer_keys[i])
|
||||
{
|
||||
enable_click_layer();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
disable_click_layer();
|
||||
}
|
||||
}
|
||||
|
||||
return process_record_user(keycode, record);
|
||||
}
|
||||
|
||||
int8_t joystick_key_column = -1;
|
||||
uint16_t joystick_key_timer;
|
||||
|
||||
void reset_joystick_key(void) {
|
||||
if (joystick_key_column >= 0) {
|
||||
action_exec(MAKE_KEYEVENT(6, joystick_key_column, false));
|
||||
}
|
||||
|
||||
joystick_key_column = -1;
|
||||
}
|
||||
|
||||
void press_joystick_key(int8_t column) {
|
||||
|
||||
joystick_key_timer = timer_read();
|
||||
|
||||
if (joystick_key_column == column /* || timer_elapsed(joystick_key_timer) < 200*/) {
|
||||
return;
|
||||
}
|
||||
|
||||
reset_joystick_key();
|
||||
|
||||
joystick_key_column = column;
|
||||
joystick_key_timer = timer_read();
|
||||
action_exec(MAKE_KEYEVENT(6, column, true));
|
||||
}
|
||||
|
||||
report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) {
|
||||
int8_t current_x = mouse_report.x;
|
||||
int8_t current_y = mouse_report.y;
|
||||
int8_t current_h = 0;
|
||||
int8_t current_v = 0;
|
||||
|
||||
if (get_joystick_key_default_enable() != joystick_key_flag) {
|
||||
#ifdef CONSOLE_ENABLE
|
||||
uprintf("x: %d, y: %d, raw_x: %d, raw_y: %d \n", current_x, current_y, joystick_raw_x, joystick_raw_y);
|
||||
#endif
|
||||
if ((current_x != 0 || current_y != 0) &&
|
||||
(joystick_raw_x > 100 || joystick_raw_y > 100) == false &&
|
||||
(my_abs_16(joystick_raw_x) + my_abs_16(joystick_raw_y) > 350)){
|
||||
|
||||
if (joystick_raw_y < joystick_raw_x * 4) {
|
||||
// 上
|
||||
press_joystick_key(1);
|
||||
} else if (joystick_raw_x < joystick_raw_y * 5) {
|
||||
press_joystick_key(2);
|
||||
} else {
|
||||
press_joystick_key(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (timer_elapsed(joystick_key_timer) > 100) {
|
||||
reset_joystick_key();
|
||||
}
|
||||
}
|
||||
|
||||
mouse_report.x = 0;
|
||||
mouse_report.y = 0;
|
||||
mouse_report.h = 0;
|
||||
mouse_report.v = 0;
|
||||
|
||||
return mouse_report;
|
||||
}
|
||||
else {
|
||||
reset_joystick_key();
|
||||
}
|
||||
|
||||
if (current_x != 0 || current_y != 0) {
|
||||
|
||||
switch (state) {
|
||||
case CLICKABLE:
|
||||
click_timer = timer_read();
|
||||
break;
|
||||
|
||||
case CLICKING:
|
||||
after_click_lock_movement -= my_abs(current_x) + my_abs(current_y);
|
||||
|
||||
if (after_click_lock_movement > 0) {
|
||||
current_x = 0;
|
||||
current_y = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SCROLLING:
|
||||
{
|
||||
int8_t rep_v = 0;
|
||||
int8_t rep_h = 0;
|
||||
|
||||
// 垂直スクロールの方の感度を高める。 Increase sensitivity toward vertical scrolling.
|
||||
if (my_abs(current_y) * 2 > my_abs(current_x)) {
|
||||
|
||||
scroll_v_mouse_interval_counter += current_y;
|
||||
while (my_abs(scroll_v_mouse_interval_counter) > scroll_v_threshold) {
|
||||
if (scroll_v_mouse_interval_counter < 0) {
|
||||
scroll_v_mouse_interval_counter += scroll_v_threshold;
|
||||
rep_v += scroll_v_threshold;
|
||||
} else {
|
||||
scroll_v_mouse_interval_counter -= scroll_v_threshold;
|
||||
rep_v -= scroll_v_threshold;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
scroll_h_mouse_interval_counter += current_x;
|
||||
|
||||
while (my_abs(scroll_h_mouse_interval_counter) > scroll_h_threshold) {
|
||||
if (scroll_h_mouse_interval_counter < 0) {
|
||||
scroll_h_mouse_interval_counter += scroll_h_threshold;
|
||||
rep_h += scroll_h_threshold;
|
||||
} else {
|
||||
scroll_h_mouse_interval_counter -= scroll_h_threshold;
|
||||
rep_h -= scroll_h_threshold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
current_h = rep_h / scroll_h_threshold * (get_mouse_scroll_h_reverse() ? -1 : 1);
|
||||
current_v = -rep_v / scroll_v_threshold * (get_mouse_scroll_v_reverse() ? -1 : 1);
|
||||
current_x = 0;
|
||||
current_y = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WAITING:
|
||||
/*
|
||||
if (timer_elapsed(click_timer) > user_config.to_clickable_time) {
|
||||
enable_click_layer();
|
||||
}
|
||||
*/
|
||||
|
||||
mouse_movement += my_abs(current_x) + my_abs(current_y);
|
||||
|
||||
if (mouse_movement >= user_config.to_clickable_movement)
|
||||
{
|
||||
mouse_movement = 0;
|
||||
enable_click_layer();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
click_timer = timer_read();
|
||||
state = WAITING;
|
||||
mouse_movement = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (state) {
|
||||
case CLICKING:
|
||||
case SCROLLING:
|
||||
|
||||
break;
|
||||
|
||||
case CLICKABLE:
|
||||
if (timer_elapsed(click_timer) > to_reset_time) {
|
||||
disable_click_layer();
|
||||
}
|
||||
break;
|
||||
|
||||
case WAITING:
|
||||
if (timer_elapsed(click_timer) > 50) {
|
||||
mouse_movement = 0;
|
||||
state = NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
mouse_movement = 0;
|
||||
state = NONE;
|
||||
}
|
||||
}
|
||||
|
||||
mouse_report.x = current_x;
|
||||
mouse_report.y = current_y;
|
||||
mouse_report.h = current_h;
|
||||
mouse_report.v = current_v;
|
||||
|
||||
return mouse_report;
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
/// miniZoneの実装 ここまで ///
|
||||
////////////////////////////
|
22
keyboards/takashicompany/left_slinger/left_slinger.h
Normal file
22
keyboards/takashicompany/left_slinger/left_slinger.h
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2024 takashicompany (@takashicompany)
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "quantum.h"
|
||||
|
||||
enum custom_keycodes_kb {
|
||||
MY_BTN1 = SAFE_RANGE,
|
||||
MY_BTN2,
|
||||
MY_BTN3,
|
||||
MY_SCRL, // Scroll
|
||||
MY_CLKI, // Click time increase
|
||||
MY_CLKD, // Click time decrease
|
||||
MY_SCDV, // Scroll vertical
|
||||
MY_SCDH, // Scroll horizontal
|
||||
MY_JSDI, // Joy stick movement divisor increase
|
||||
MY_JSDD, // Joy stick movement divisor decrease
|
||||
MY_STGE, // Setting End
|
||||
MY_JSKD, // Joy stick key default
|
||||
MY_JSKE, // Joy stick key enable
|
||||
};
|
27
keyboards/takashicompany/left_slinger/readme.md
Normal file
27
keyboards/takashicompany/left_slinger/readme.md
Normal file
@ -0,0 +1,27 @@
|
||||
# takashicompany/left_slinger
|
||||
|
||||
![takashicompany/left_slinger](https://i.imgur.com/7U0BMuT.jpeg)
|
||||
|
||||
Left Slinger is a left hand only macro pad & gaming device with joystick and rotary encoder.
|
||||
|
||||
* Keyboard Maintainer: [takashicompany](https://github.com/takashicompany)
|
||||
* Hardware Supported: PCB, RP2040-Zero
|
||||
* Hardware Availability: https://github.com/takashicompany/left_slinger
|
||||
|
||||
Make example for this keyboard (after setting up your build environment):
|
||||
|
||||
make takashicompany/left_slinger:default
|
||||
|
||||
Flashing example for this keyboard:
|
||||
|
||||
make takashicompany/left_slinger:default:flash
|
||||
|
||||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
|
||||
|
||||
## Bootloader
|
||||
|
||||
Enter the bootloader in 3 ways:
|
||||
|
||||
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard
|
||||
* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead
|
||||
* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available
|
4
keyboards/takashicompany/left_slinger/rules.mk
Normal file
4
keyboards/takashicompany/left_slinger/rules.mk
Normal file
@ -0,0 +1,4 @@
|
||||
POINTING_DEVICE_ENABLE = yes
|
||||
POINTING_DEVICE_DRIVER = custom
|
||||
ANALOG_DRIVER_REQUIRED = yes
|
||||
SRC += custom_joystick.c
|
@ -1,5 +1,6 @@
|
||||
"""This script automates the copying of the default keymap into your own keymap.
|
||||
"""
|
||||
import re
|
||||
import shutil
|
||||
|
||||
from milc import cli
|
||||
@ -13,6 +14,13 @@ from qmk.keyboard import keyboard_completer, keyboard_folder
|
||||
from qmk.userspace import UserspaceDefs
|
||||
|
||||
|
||||
def validate_keymap_name(name):
|
||||
"""Returns True if the given keymap name contains only a-z, 0-9 and underscore characters.
|
||||
"""
|
||||
regex = re.compile(r'^[a-zA-Z0-9][a-zA-Z0-9_]+$')
|
||||
return bool(regex.match(name))
|
||||
|
||||
|
||||
def prompt_keyboard():
|
||||
prompt = """{fg_yellow}Select Keyboard{style_reset_all}
|
||||
If you`re unsure you can view a full list of supported keyboards with {fg_yellow}qmk list-keyboards{style_reset_all}.
|
||||
@ -60,6 +68,10 @@ def new_keymap(cli):
|
||||
cli.log.error(f'Default keymap {{fg_cyan}}{keymap_path_default}{{fg_reset}} does not exist!')
|
||||
return False
|
||||
|
||||
if not validate_keymap_name(user_name):
|
||||
cli.log.error('Keymap names must contain only {fg_cyan}a-z{fg_reset}, {fg_cyan}0-9{fg_reset} and {fg_cyan}_{fg_reset}! Please choose a different name.')
|
||||
return False
|
||||
|
||||
if keymap_path_new.exists():
|
||||
cli.log.error(f'Keymap {{fg_cyan}}{user_name}{{fg_reset}} already exists! Please choose a different name.')
|
||||
return False
|
||||
|
@ -29,6 +29,7 @@ def _convert_macros(via_macros):
|
||||
if len(via_macros) == 0:
|
||||
return list()
|
||||
split_regex = re.compile(r'(}\,)|(\,{)')
|
||||
macro_group_regex = re.compile(r'({.+?})')
|
||||
macros = list()
|
||||
for via_macro in via_macros:
|
||||
# Split VIA macro to its elements
|
||||
@ -38,13 +39,28 @@ def _convert_macros(via_macros):
|
||||
macro_data = list()
|
||||
for m in macro:
|
||||
if '{' in m or '}' in m:
|
||||
# Found keycode(s)
|
||||
keycodes = m.split(',')
|
||||
# Remove whitespaces and curly braces from around keycodes
|
||||
keycodes = list(map(lambda s: s.strip(' {}'), keycodes))
|
||||
# Remove the KC prefix
|
||||
keycodes = list(map(lambda s: s.replace('KC_', ''), keycodes))
|
||||
macro_data.append({"action": "tap", "keycodes": keycodes})
|
||||
# Split macro groups
|
||||
macro_groups = macro_group_regex.findall(m)
|
||||
for macro_group in macro_groups:
|
||||
# Remove whitespaces and curly braces from around group
|
||||
macro_group = macro_group.strip(' {}')
|
||||
|
||||
macro_action = 'tap'
|
||||
macro_keycodes = []
|
||||
|
||||
if macro_group[0] == '+':
|
||||
macro_action = 'down'
|
||||
macro_keycodes.append(macro_group[1:])
|
||||
elif macro_group[0] == '-':
|
||||
macro_action = 'up'
|
||||
macro_keycodes.append(macro_group[1:])
|
||||
else:
|
||||
macro_keycodes.extend(macro_group.split(',') if ',' in macro_group else [macro_group])
|
||||
|
||||
# Remove the KC prefixes
|
||||
macro_keycodes = list(map(lambda s: s.replace('KC_', ''), macro_keycodes))
|
||||
|
||||
macro_data.append({"action": macro_action, "keycodes": macro_keycodes})
|
||||
else:
|
||||
# Found text
|
||||
macro_data.append(m)
|
||||
@ -54,13 +70,13 @@ def _convert_macros(via_macros):
|
||||
|
||||
|
||||
def _fix_macro_keys(keymap_data):
|
||||
macro_no = re.compile(r'MACRO0?([0-9]{1,2})')
|
||||
macro_no = re.compile(r'MACRO0?\(([0-9]{1,2})\)')
|
||||
for i in range(0, len(keymap_data)):
|
||||
for j in range(0, len(keymap_data[i])):
|
||||
kc = keymap_data[i][j]
|
||||
m = macro_no.match(kc)
|
||||
if m:
|
||||
keymap_data[i][j] = f'MACRO_{m.group(1)}'
|
||||
keymap_data[i][j] = f'MC_{m.group(1)}'
|
||||
return keymap_data
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user