Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add vial support for replicazeron #798

Merged
merged 2 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions keyboards/handwired/replicazeron/common/leds.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* Copyright 2023 9R
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "leds.h"
#include <stdbool.h>
#include "gpio.h"

//////////// Status LEDs //////////////
void init_leds(void) {
// Both LEDs off, they have inverted logic
gpio_set_pin_output(STATUS_LED_A_PIN);
gpio_set_pin_output(STATUS_LED_B_PIN);
gpio_write_pin_high(STATUS_LED_A_PIN);
gpio_write_pin_high(STATUS_LED_B_PIN);
}

void set_leds(uint8_t highest_active_layer) {
// any layer other than 0-3, quit and LEDs off
if (highest_active_layer > 3) {
gpio_write_pin_high(STATUS_LED_A_PIN);
gpio_write_pin_high(STATUS_LED_B_PIN);
return;
}

// use bitwise operations to display active layer in binary
bool bit1 = !(highest_active_layer & 1);
bool bit2 = !(highest_active_layer & 2);
gpio_write_pin(STATUS_LED_A_PIN, bit1);
gpio_write_pin(STATUS_LED_B_PIN, bit2);
}
23 changes: 23 additions & 0 deletions keyboards/handwired/replicazeron/common/leds.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* Copyright 2023 9R
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <stdint.h>

void init_leds(void);

void set_leds(uint8_t active_layer);
96 changes: 96 additions & 0 deletions keyboards/handwired/replicazeron/common/oled.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/* Copyright 2023 9R
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "oled.h"
#include "oled_driver.h"
#include "progmem.h"
#include "util.h"

uint8_t shiftbits =32 ;

//////////// OLED output helpers //////////////
void draw_mode(controller_state_t controller_state) {
//draw oled row showing thumbstick mode
oled_write_P(PSTR("Mode: "), false);
if (controller_state.wasdShiftMode) {
oled_write_ln_P(PSTR("WASD + Shift"), false);
} else if (controller_state.wasdMode) {
oled_write_ln_P(PSTR("WASD"), false);
} else {
oled_write_ln_P(PSTR("JoyStick"), false);
}
}

void draw_wasd_key(wasd_state_t wasd_state) {
//draw oled row showing active keypresses emulated from thumbstick
const char* keys = "wasd";
bool keystates [] = { wasd_state.w, wasd_state.a, wasd_state.s, wasd_state.d };
// iterate over keystates
for (uint8_t i = 0 ; i < ARRAY_SIZE(keystates); ++i) {
if (keystates[i]) {
char k = keys[i] ;
//bitshift char to upper case
if (wasd_state.shift) {
k &= ~shiftbits;
}
oled_write_char(k, false);
} else {
oled_write_P(PSTR(" "), false);
}
}
}

void draw_thumb_debug(thumbstick_polar_position_t thumbstick_polar_position) {
//draw oled row showing thumbstick direction and distance from center
oled_write_P(PSTR("Dir:"), false);
oled_write(get_u16_str(thumbstick_polar_position.angle, ' '), false);
oled_write_P(PSTR(" Dist:"), false);
oled_write_ln(get_u16_str(thumbstick_polar_position.distance, ' '), false);
//print registered key codes
oled_write_P(PSTR("Keycodes: "), false);
draw_wasd_key( wasd_state );
}

//////////// draw OLED output //////////////
void draw_oled(controller_state_t controller_state) {
oled_write_P(PSTR("Layer: "), false);

switch (controller_state.highestActiveLayer) {
case _SHOOTER:
oled_write_ln_P(PSTR("Shooter"), false);
break;

case _MISC:
oled_write_ln_P(PSTR("Misc"), false);
break;

case _SETTINGS:
oled_write_ln_P(PSTR("Settings"), false);
break;

default:
oled_write_ln_P(PSTR("Default"), false);
}

draw_mode(controller_state);
if (controller_state.highestActiveLayer == _SETTINGS ) {
draw_thumb_debug(thumbstick_polar_position);
}
else {
oled_write_ln_P(PSTR(" "), false);
}
oled_write_ln_P(PSTR(" "), false);
}
34 changes: 34 additions & 0 deletions keyboards/handwired/replicazeron/common/oled.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/* Copyright 2023 9R
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once

#include "replicazeron.h"

#include <stdint.h>
#include "state.h"
#include "thumbstick.h"

uint8_t shiftbits;

char stringbuffer[8];

void draw_oled(controller_state_t controller_state);

void draw_mode(controller_state_t controller_state);

void draw_thumb_debug(thumbstick_polar_position_t thumbstick_polar_position);

void draw_wasd_key(wasd_state_t wasd_state);
28 changes: 28 additions & 0 deletions keyboards/handwired/replicazeron/common/state.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* Copyright 2023 9R
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "state.h"

controller_state_t init_state (void) {
controller_state_t controller_state = {
.wasdMode = true,
.wasdShiftMode = false,
.autoRun = false,
.highestActiveLayer = 0,
};

return controller_state;
}
28 changes: 28 additions & 0 deletions keyboards/handwired/replicazeron/common/state.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* Copyright 2023 9R
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once

#include <stdbool.h>
#include <stdint.h>

typedef struct {
bool wasdMode;
bool wasdShiftMode;
bool autoRun;
uint8_t highestActiveLayer;
} controller_state_t;

controller_state_t init_state(void);
111 changes: 111 additions & 0 deletions keyboards/handwired/replicazeron/common/thumbstick.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/* Copyright 2023 9R
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "thumbstick.h"
#include <math.h>
#include "action.h"
#include "keycode.h"
#include "debug.h"

void init_wasd_state (void) {
wasd_state.w = wasd_state.a = wasd_state.s = wasd_state.d = false;
last_wasd_state = wasd_state;
wasd_state.shift = false;
}

thumbstick_polar_position_t get_thumbstick_polar_position(int16_t x, int16_t y) {
static thumbstick_polar_position_t position;

#ifdef THUMBSTICK_DEBUG
dprintf("xN: %4d yN: %4d\n", x, y);
#endif

//transform to carthesian coordinates to polar coordinates
//get distance from center as int in range [0-600]
position.distance = (double)sqrt((double)x * (double)x + (double)y * (double)y);
//get direction as int in range [0 to 359]
position.angle = (double)atan2(y, x) * (180 /M_PI) + 180;

//apply thumbstick rotation const to modify forward direction
position.angle = (position.angle + _THUMBSTICK_ROTATION) % 360;

return position;
}

bool update_keystate(uint16_t angle_from, uint16_t angle_to, uint16_t angle) {
return (angle_from < angle && angle <= angle_to);
}

void update_keycode(uint16_t keycode, bool keystate, bool last_keystate) {
if (keystate && keystate != last_keystate) {
register_code16(keycode);
} else if (!keystate) {
unregister_code16(keycode);
}
}

void thumbstick(controller_state_t controller_state) {
xPos = joystick_state.axes[0];
yPos = joystick_state.axes[1];

thumbstick_polar_position = get_thumbstick_polar_position(xPos, yPos);

#ifdef THUMBSTICK_DEBUG
dprintf("distance: %5d angle: %5d\n", thumbstick_polar_position.distance, thumbstick_polar_position.angle);
#endif

// Update WASD state depending on thumbstick position
// if thumbstick out of of deadzone
if (thumbstick_polar_position.distance >= _DEADZONE) {
wasd_state.w = update_keystate( 0, 90, thumbstick_polar_position.angle);
// A angle: 45 - 180
wasd_state.a = update_keystate( 45, 181, thumbstick_polar_position.angle);
// S angle: 135 - 270
wasd_state.s = update_keystate(135, 270, thumbstick_polar_position.angle);
// D angle: 225 - 359
wasd_state.d = update_keystate(225, 359, thumbstick_polar_position.angle);

if (!wasd_state.w ) {
wasd_state.w = update_keystate(315, 360, thumbstick_polar_position.angle);
}
} else {
//reset WASD state when in _DEADZONE
init_wasd_state();
}

#ifdef THUMBSTICK_DEBUG
dprintf("w: %2d a: %2d s: %2d d: %2d\n", wasd_state.w, wasd_state.a, wasd_state.s, wasd_state.d);
#endif

update_keycode(KC_W, wasd_state.w, last_wasd_state.w);
update_keycode(KC_A, wasd_state.a, last_wasd_state.a);
update_keycode(KC_S, wasd_state.s, last_wasd_state.s);
update_keycode(KC_D, wasd_state.d, last_wasd_state.d);

last_wasd_state = wasd_state ;

// handle WASD-Shift mode
if (controller_state.wasdShiftMode) {
bool Shifted = thumbstick_polar_position.distance > _SHIFTZONE;
if (!wasd_state.shift && Shifted) {
register_code(KC_LSFT);
wasd_state.shift = true;
} else if (wasd_state.shift && !Shifted) {
unregister_code(KC_LSFT);
wasd_state.shift = false;
}
}
}
Loading
Loading