qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

keymap.c (3497B)


      1 /* Copyright 2023 Tom Parker-Shemilt <palfrey@tevp.net>
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, version 3 of the License.
      6  *
      7  * This program is distributed in the hope that it will be useful,
      8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     10  * GNU General Public License for more details.
     11  *
     12  * You should have received a copy of the GNU General Public License
     13  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     14  */
     15 
     16 #include <stdlib.h>
     17 
     18 #include QMK_KEYBOARD_H
     19 
     20 // clang-format off
     21 
     22 // Exact keymap is irrelevant as we're using rows/cols
     23 // but we need _something_ set so we're using no-ops
     24 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
     25     [0] = LAYOUT(
     26         KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
     27         KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
     28         KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
     29         KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
     30         KC_NO, KC_NO, KC_NO, KC_NO, KC_NO
     31     )};
     32 
     33 bool tiles[5][5] = {
     34     {false, false, false, false, false},
     35     {false, false, false, false, false},
     36     {false, false, false, false, false},
     37     {false, false, false, false, false},
     38     {false, false, false, false, false},
     39 };
     40 
     41 /* Because snake pattern of leds */
     42 const uint8_t remap[25] = {
     43     20,21,22,23,24,
     44     19,6,7,8,9,
     45     18,5,0,1,10,
     46     17,4,3,2,11,
     47     16,15,14,13,12,
     48 };
     49 
     50 // clang-format on
     51 
     52 bool is_blank(void) {
     53     for (uint8_t y = 0; y < 5; y++) {
     54         for (uint8_t x = 0; x < 5; x++) {
     55             if (tiles[x][y]) {
     56                 return false;
     57             }
     58         }
     59     }
     60     return true;
     61 }
     62 
     63 void do_move(uint8_t x, uint8_t y) {
     64     tiles[x][y] ^= true;
     65     if (x > 0) {
     66         tiles[x - 1][y] ^= true;
     67     }
     68     if (y > 0) {
     69         tiles[x][y - 1] ^= true;
     70     }
     71     if (x < 4) {
     72         tiles[x + 1][y] ^= true;
     73     }
     74     if (y < 4) {
     75         tiles[x][y + 1] ^= true;
     76     }
     77 }
     78 
     79 void refresh_leds(void) {
     80     for (uint8_t y = 0; y < 5; y++) {
     81         for (uint8_t x = 0; x < 5; x++) {
     82             uint8_t tile  = tiles[x][y];
     83             uint8_t index = (y * 5) + x;
     84             if (tile) {
     85                 rgblight_setrgb_at(RGB_RED, remap[index]);
     86             } else {
     87                 rgblight_setrgb_at(RGB_WHITE, remap[index]);
     88             }
     89         }
     90     }
     91     rgblight_set();
     92 }
     93 
     94 uint8_t initial_moves = 1;
     95 
     96 void start_game(void) {
     97     rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
     98     srand(timer_read32());
     99     while (true) {
    100         for (uint8_t i = 0; i < initial_moves; i++) {
    101             do_move(rand() % 5, rand() % 5);
    102         }
    103         if (!is_blank()) {
    104             // Catch the "we picked the same location 2*N times" case
    105             break;
    106         }
    107     }
    108     refresh_leds();
    109 }
    110 
    111 void keyboard_post_init_user(void) {
    112     rgblight_enable_noeeprom();
    113     start_game();
    114 }
    115 
    116 bool won = false;
    117 
    118 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    119     if (record->event.pressed) {
    120         if (won) {
    121             initial_moves++;
    122             won = false;
    123             start_game();
    124         } else {
    125             uint8_t x = record->event.key.col;
    126             uint8_t y = record->event.key.row;
    127             do_move(x, y);
    128             if (is_blank()) {
    129                 rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL);
    130                 won = true;
    131             }
    132         }
    133     }
    134     refresh_leds();
    135     return true;
    136 }