From a9f65b760a49744b13d822ab359876a52779bd9e Mon Sep 17 00:00:00 2001
From: rupa <rdeadwyler@ns1.com>
Date: Tue, 10 Nov 2020 00:04:46 -0500
Subject: [PATCH] userspace and keymap changes for rupa (#10489)

* userspace and keymap changes for rupa

* remove layout wrappers and blocker rows from wrappers

handle this in keymaps for now
---
 keyboards/tada68/keymaps/rupa/config.h  |   7 -
 keyboards/tada68/keymaps/rupa/keymap.c  |  73 +++++------
 keyboards/tada68/keymaps/rupa/readme.md |   8 +-
 keyboards/tada68/keymaps/rupa/rules.mk  |   1 -
 users/rupa/config.h                     |   3 +
 users/rupa/process_records.c            | 118 ++++++++++++-----
 users/rupa/process_records.h            |   0
 users/rupa/readme.md                    |   7 +
 users/rupa/rules.mk                     |   2 +
 users/rupa/rupa.c                       |  43 +++++-
 users/rupa/rupa.h                       |  50 +++++--
 users/rupa/unicode.c                    | 167 +++++++++++++++++++++---
 users/rupa/unicode.h                    |  52 ++++++--
 users/rupa/wrappers.h                   | 122 +++++++++++++++++
 14 files changed, 520 insertions(+), 133 deletions(-)
 mode change 100755 => 100644 users/rupa/process_records.c
 mode change 100755 => 100644 users/rupa/process_records.h
 create mode 100644 users/rupa/readme.md
 mode change 100755 => 100644 users/rupa/rupa.c
 mode change 100755 => 100644 users/rupa/rupa.h
 mode change 100755 => 100644 users/rupa/unicode.c
 mode change 100755 => 100644 users/rupa/unicode.h
 create mode 100644 users/rupa/wrappers.h

diff --git a/keyboards/tada68/keymaps/rupa/config.h b/keyboards/tada68/keymaps/rupa/config.h
index ddbf0ab667..e1a6eb1a2b 100644
--- a/keyboards/tada68/keymaps/rupa/config.h
+++ b/keyboards/tada68/keymaps/rupa/config.h
@@ -1,10 +1,3 @@
 #pragma once
 
 #define GRAVE_ESC_ALT_OVERRIDE
-
-/* disable features */
-//#define NO_ACTION_LAYER
-//#define NO_ACTION_TAPPING
-//#define NO_ACTION_ONESHOT
-#define NO_ACTION_MACRO
-#define NO_ACTION_FUNCTION
diff --git a/keyboards/tada68/keymaps/rupa/keymap.c b/keyboards/tada68/keymaps/rupa/keymap.c
index 3a8a550561..ce95673af4 100755
--- a/keyboards/tada68/keymaps/rupa/keymap.c
+++ b/keyboards/tada68/keymaps/rupa/keymap.c
@@ -1,45 +1,38 @@
 #include "rupa.h"
 
-const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
-    /* Keymap _QWERTY: (Base Layer) Default Layer
-     * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───┐
-     * │Esc│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ Backsp│~ `│
-     * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
-     * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │  \  │Del│
-     * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
-     * │  Fn  │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │  Enter │PgU│
-     * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
-     * │ Shift  │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shift│ ↑ │PgD│
-     * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬┴──┬───┼───┼───┤
-     * │Ctrl│Alt │Gui │        Space           │Fn │Alt│Ctl│ ← │ ↓ │ → │
-     * └────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┴───┘
-     */
-    [_QWERTY] = LAYOUT_65_ansi(
-        KC_GESC, KC_1,    KC_2,    KC_3,  KC_4,  KC_5,  KC_6,    KC_7,  KC_8,  KC_9,    KC_0,    KC_MINS, KC_EQL,  KC_BSPC, KC_GRV,
-        KC_TAB,  KC_Q,    KC_W,    KC_E,  KC_R,  KC_T,  KC_Y,    KC_U,  KC_I,  KC_O,    KC_P,    KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL,
-        RAISE,   KC_A,    KC_S,    KC_D,  KC_F,  KC_G,  KC_H,    KC_J,  KC_K,  KC_L,    KC_SCLN, KC_QUOT,          KC_ENT,  KC_PGUP,
-        KC_LSFT,          KC_Z,    KC_X,  KC_C,  KC_V,  KC_B,    KC_N,  KC_M,  KC_COMM, KC_DOT,  KC_SLSH, KC_RSFT, KC_UP,   KC_PGDN,
-        KC_LCTL, KC_LALT, KC_LGUI,                      KC_SPC,                RAISE,   KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
-    ),
+#define LAYOUT_65_ansi_wrapper(...) LAYOUT_65_ansi(__VA_ARGS__)
 
-    /* Keymap _RAISE: Function Layer
-     * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───┐
-     * │LOD│F1 │F2 │F3 │F4 │F5 │F6 │F7 │F8 │F9 │F10│F11│F12│  Del  │Hme│
-     * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
-     * │     │VSN│U_s│U_f│U_m│   │   │uni│   │ ॐ │   │♩ ♪│♫ ♬│★  ☆ │Ins│
-     * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
-     * │      │   │   │   │   │   │   │   │   │   │   │   │    ✓   │End│
-     * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
-     * │ RShift │ ⸮ │Rup│Brt│Bls│Blt│   │Mut│V- │V+ │‽ ☭│   McL│M↑ │McR│
-     * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬┴──┬───┼───┼───┤
-     * │RCtl│RAlt│RGui│                        │   │   │CAP│M← │M↓ │M→ │
-     * └────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┴───┘
-     */
-    [_RAISE] = LAYOUT_65_ansi(
-        LOD,     KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,       KC_F12,      KC_DEL,       KC_HOME,
-        _______, VRSN,    U_SCRPT, U_FRACT, U_MONOS, _______, _______, UC_MOD,  _______, X(OM),   _______, XP(M4,M8),    XP(M8B,M16), XP(STB, STW), KC_INS,
-        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,                   X(CHEK),      KC_END,
-        OS_RSFT,          X(IRNY), RUPA,    BL_BRTG, BL_STEP, BL_TOGG, _______, KC_MUTE, KC_VOLD, KC_VOLU, XP(IBNG,HAS), KC_BTN1,     KC_MS_U,      KC_BTN2,
-        OS_RCTL, OS_RALT, OS_RGUI,                            _______,                   _______, _______, KC_CAPS,      KC_MS_L,     KC_MS_D,      KC_MS_R
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+    [_QWERTY] = LAYOUT_65_ansi_wrapper(
+        ____65_QWERTY______________ROW1,
+        ____65_QWERTY______________ROW2,
+        ____65_QWERTY______________ROW3,
+        ____65_QWERTY______________ROW4,
+        ____65_QWERTY______________ROW5
+    ),
+    [_RAISE] = LAYOUT_65_ansi_wrapper(
+        ____65_RAISE_______________ROW1,
+        ____65_RAISE_______________ROW2,
+        ____65_RAISE_______________ROW3,
+        ____65_RAISE_______________ROW4,
+        ____65_RAISE_______________ROW5
+    ),
+    [_LOWER] = LAYOUT_65_ansi_wrapper(
+        ____65_LOWER_______________ROW1,
+        ____65_LOWER_______________ROW2,
+        ____65_LOWER_______________ROW3,
+        ____65_LOWER_______________ROW4,
+        ____65_LOWER_______________ROW5
+    ),
+    [_ADJUST] = LAYOUT_65_ansi_wrapper(
+        ____65_ADJUST______________ROW1,
+        ____65_ADJUST___________BL_ROW2,
+        ____65_ADJUST______________ROW3,
+        ____65_ADJUST______________ROW4,
+        ____65_ADJUST______________ROW5
     ),
 };
+
+layer_state_t layer_state_set_user(layer_state_t state) {
+    return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
+}
diff --git a/keyboards/tada68/keymaps/rupa/readme.md b/keyboards/tada68/keymaps/rupa/readme.md
index 77629131a0..eea966fdb9 100755
--- a/keyboards/tada68/keymaps/rupa/readme.md
+++ b/keyboards/tada68/keymaps/rupa/readme.md
@@ -2,9 +2,7 @@
 
 i've swapped the lufa-ms bootloader for caterina
 
-most everything is in my userspace dir
-
-console mode is on, and there's barely any room left!
+most everything is in my [userspace](../../../../users/rupa/)
 
 * win/alt -> alt/cmd
 * alt/fn -> fn/alt
@@ -16,6 +14,6 @@ fn layer:
   * rotate mute/vol
   * backlight -> breathing, step, toggle
   * swap home and ins
-  * unicode chars sprinkled around
-  * script mode!
+  * unicode chars and strings sprinkled around
+  * script modes!
   * (one-shot) right versions of shift/ctl/alt/gui (not working quite right yet)
diff --git a/keyboards/tada68/keymaps/rupa/rules.mk b/keyboards/tada68/keymaps/rupa/rules.mk
index df6f5674b5..1777fc10a2 100644
--- a/keyboards/tada68/keymaps/rupa/rules.mk
+++ b/keyboards/tada68/keymaps/rupa/rules.mk
@@ -1,4 +1,3 @@
 BOOTLOADER = caterina
 
-UNICODEMAP_ENABLE = yes
 CONSOLE_ENABLE = yes
diff --git a/users/rupa/config.h b/users/rupa/config.h
index 9024052042..723d9b3b5f 100644
--- a/users/rupa/config.h
+++ b/users/rupa/config.h
@@ -5,4 +5,7 @@
 #define ONESHOT_TAP_TOGGLE 5
 #define ONESHOT_TIMEOUT 5000
 
+#undef TAP_CODE_DELAY
 #define TAP_CODE_DELAY 5 //DEFAULT: 100
+
+//#define UNICODE_SCRIPT_MODE_ENABLE
diff --git a/users/rupa/process_records.c b/users/rupa/process_records.c
old mode 100755
new mode 100644
index 2d72310100..2d23e34017
--- a/users/rupa/process_records.c
+++ b/users/rupa/process_records.c
@@ -17,7 +17,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #include "rupa.h"
 
-font_t *translator = NULL;
+uint16_t processed_keycode;
 
 __attribute__((weak))
 bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
@@ -25,47 +25,93 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
 }
 
 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
-    bool is_shifted = get_mods()&MOD_MASK_SHIFT;
-    bool is_pressed = record->event.pressed;
+    if (record->event.pressed) {
 
-    switch(keycode) {
-        case VRSN:
-            if (is_pressed) {
+        processed_keycode = keycode;
+        // mask out mod taps
+        if (
+            (keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) ||
+            (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)
+        ) {
+            processed_keycode &= 0xFF;
+        }
+
+        bool is_shifted = (get_mods() | get_oneshot_mods() | get_weak_mods()) & MOD_MASK_SHIFT;
+        switch(processed_keycode) {
+            case VRSN:
                 send_string_with_delay_P(PSTR(
-                  "# " QMK_KEYBOARD "/" QMK_KEYMAP ":" QMK_VERSION " " QMK_BUILDDATE "\n"
+                    "# " QMK_KEYBOARD "/" QMK_KEYMAP ":" QMK_VERSION " " QMK_BUILDDATE "\n"
                 ), TAP_CODE_DELAY);
-            }
-            return false;
+                return false;
 
-        case LOD:
-        case RUPA:
-            if (is_pressed) {
-                if (keycode == LOD) {
-                    send_unicode_string((is_shifted ? "¯\\_(ツ)_/¯" : "ಠ_ಠ"));
-                } else if (keycode == RUPA) {
-                    send_unicode_string((is_shifted ? "Śrīrūpa" : "rūpa"));
+            case BUGS:
+                return u_xp(is_shifted, "ᙙᙖ", "ଳ");
+            case CATS:
+                return u_xp(is_shifted, "ⓛ ᆽ ⓛ ", "ㅇㅅㅇ");
+            case DANCE:
+                return u_x(dance(is_shifted));
+            case DICE:
+                return u_x(d6());
+            case DOMO:
+                return u_xp(is_shifted, "(シ_ _)シ", "m(_ _)m");
+            case FART:
+                return u_x("⊥ʶ∀Ⅎ");
+            case FLIP:
+                return u_x(flip(is_shifted));
+            case HUGS:
+                return u_xp(is_shifted, "(づ ̄ ³ ̄)づ", "(っಠ‿ಠ)っ");
+            case JOY:
+                return u_x(joy(is_shifted));
+            case RNDM:
+                return false;
+            case KISS:
+                return u_xp(is_shifted, "꒒ ০ ⌵ ୧ ♡", "( ˘ ³˘)♥");
+            case LOD:
+                return u_xp(is_shifted, "( ͡ಠ ʖ̯ ͡ಠ)", "ಠ_ಠ");
+            case MUSIC:
+                return u_xp(is_shifted, "(˳˘ ɜ˘)˳ ♬ ♪♫", "(´▽`)ノ♫");
+            case RUPA:
+                return u_xp(is_shifted, "Śrīrūpa", "rūpa");
+            case SHRUG:
+                return u_xp(is_shifted, "⋌ ༼ •̀ ⌂ •́ ༽⋋", "¯\\_(ツ)_/¯");
+            case TADA:
+                return u_xp(is_shifted, "☆ *・゜゚・*(^O^)/*・゜゚・*☆", "\\(゜ロ\\)Ξ(//ロ゜)//");
+            case WAT:
+                return u_xp(is_shifted, "༼  ຶཽཀ  ຶཽ༽", "ヽ༼⊙_⊙༽ノ");
+            case YUNO:
+                return u_xp(is_shifted, "o(^^o)", "щ(゜ロ゜щ)");
+            case ZALGO:
+                set_combined_mode(CM_ZALGO);
+                break;
+            case ZZZZZ:
+                cycle_combined_mode();
+                break;
+
+#if defined(UNICODE_SCRIPT_MODE_ENABLE)
+            // script modes
+            case U_FRACT:
+                return set_script_mode(F_FRACT);
+            case U_ITALI:
+                return set_script_mode(F_ITALI);
+            case U_MONOS:
+                return set_script_mode(F_MONOS);
+            case U_NORML:
+                return set_script_mode(F_NORML);
+            case U_SANSI:
+                return set_script_mode(F_SANSI);
+            case U_SANSN:
+                return set_script_mode(F_SANSN);
+            case U_SCRPT:
+                return set_script_mode(F_SCRPT);
+
+            default:
+                if (get_script_mode() != NULL) {
+                    return script_mode_translate(is_shifted, processed_keycode);
                 }
-            }
-            return false;
-
-        // script modes
-        case U_FRACT:
-        case U_MONOS:
-        case U_SCRPT:
-            if (is_pressed) {
-                if (keycode == U_SCRPT) {
-                    translator = (translator == &script_bold ? NULL : &script_bold);
-                } else if (keycode == U_FRACT) {
-                    translator = (translator == &fraktu_bold ? NULL : &fraktu_bold);
-                } else if (keycode == U_MONOS) {
-                    translator = (translator == &monosp_bold ? NULL : &monosp_bold);
+                if (combined_mode != CM_NULL && combined_text(processed_keycode)) {
+                    return false;
                 }
-            }
-            return true;
-
-        default:
-            if (is_pressed && translator != NULL) {
-                return script_mode_translate(translator, is_shifted, keycode);
+#endif
             }
     }
     return process_record_keymap(keycode, record);
diff --git a/users/rupa/process_records.h b/users/rupa/process_records.h
old mode 100755
new mode 100644
diff --git a/users/rupa/readme.md b/users/rupa/readme.md
new file mode 100644
index 0000000000..b6c2dd1f7f
--- /dev/null
+++ b/users/rupa/readme.md
@@ -0,0 +1,7 @@
+# rupa's userspace
+
+* rupa.c has some unicode script mode stuff
+* unicode.c has my unicode map
+* process_record.c has my keycode handler
+
+my keymap is in [keyboards/tada68](../../keyboards/tada68/keymaps/rupa/)
diff --git a/users/rupa/rules.mk b/users/rupa/rules.mk
index c4f147d913..ed33e85f3a 100644
--- a/users/rupa/rules.mk
+++ b/users/rupa/rules.mk
@@ -1,3 +1,5 @@
+UNICODEMAP_ENABLE = yes
+LTO_ENABLE = yes
 SRC += rupa.c \
        process_records.c \
        unicode.c
diff --git a/users/rupa/rupa.c b/users/rupa/rupa.c
old mode 100755
new mode 100644
index 60fec3caf0..85de5c16fd
--- a/users/rupa/rupa.c
+++ b/users/rupa/rupa.c
@@ -18,14 +18,46 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include <print.h>
 #include "rupa.h"
 
+#if defined(UNICODE_SCRIPT_MODE_ENABLE)
+const font_t * translator = NULL;
+
 // https://en.wikipedia.org/wiki/Mathematical_Alphanumeric_Symbols
-font_t script_bold = {0x1D4D0, 0x1D4EA, 0x1D7CE}; // with bold numbers
-font_t fraktu_bold = {0x1D56C, 0x1D586, 0x1D7D8}; // with doublestruck numbers
-font_t monosp_bold = {0x1D670, 0x1D68A, 0x1D7F6};
+static const font_t *fonts_map[] = {
+    [F_FRACT] = &(font_t){0x1D56C, 0x1D586, 0x1D7D8}, // fraktur/doublestruck numbers
+    [F_ITALI] = &(font_t){0x1D468, 0x1D482, 0x1D7CE}, // italic/bold numbers
+    [F_MONOS] = &(font_t){0x1D670, 0x1D68A, 0x1D7F6}, // monospace
+    [F_NORML] = &(font_t){0x1D400, 0x1D41A, 0x00030}, // normal!
+    [F_SANSI] = &(font_t){0x1D63C, 0x1D656, 0x1D7EC}, // sans 1talic/sans bold numbers
+    [F_SANSN] = &(font_t){0x1D5D4, 0x1D5EE, 0x1D7E2}, // sans normal/sans numbers
+    [F_SCRPT] = &(font_t){0x1D4D0, 0x1D4EA, 0x1D7CE}, // script/bold numbers
+};
+
+/*
+font_t doublestruc = {0x1D538, 0x1D552, 0x1D7D8};
+uint_32 []snowflakes = {
+  // doublestruck
+  0x1D53B, // C
+  0x1D540, // H
+  0x1D546, // N
+  0x1D548, // P
+  0x1D549, // Q
+  0x1D54A, // R
+  0x1D552, // Z
+};
+*/
+
+const font_t *get_script_mode(void) {
+    return translator;
+}
+bool set_script_mode(int fc) {
+    translator = translator == fonts_map[fc] ? NULL : fonts_map[fc];
+    dprintf("set_script_mode: %u %b\n", fc, translator != NULL);
+    return true;
+}
 
 // Maps A-Z, a-z, and 0-9 to other unicode ranges. We also map space to EN
 // SPACE for some reason :)
-uint32_t map_alnum(font_t *f, bool is_shifted, uint32_t keycode) {
+uint32_t map_alnum(const font_t *f, bool is_shifted, uint32_t keycode) {
     switch (keycode) {
         case KC_SPACE:
             return (is_shifted ? 0 : 0x2002); // EN SPACE
@@ -40,10 +72,11 @@ uint32_t map_alnum(font_t *f, bool is_shifted, uint32_t keycode) {
     }
 }
 
-bool script_mode_translate(font_t *translator, bool is_shifted, uint32_t keycode) {
+bool script_mode_translate(bool is_shifted, uint32_t keycode) {
     uint32_t translated = map_alnum(translator, is_shifted, keycode);
     if (translated == 0) return true;
     dprintf("script_mode_translate: %u => %d\n", keycode, translated);
     register_unicode(translated);
     return false;
 }
+#endif
diff --git a/users/rupa/rupa.h b/users/rupa/rupa.h
old mode 100755
new mode 100644
index 9be3a2d62f..cfe873ffc6
--- a/users/rupa/rupa.h
+++ b/users/rupa/rupa.h
@@ -20,19 +20,55 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "version.h"
 #include "process_records.h"
 #include "unicode.h"
+#include "wrappers.h"
 
 enum userspace_layers {
     _QWERTY = 0,
+    _LOWER,
     _RAISE,
+    _ADJUST
 };
 
 enum userspace_custom_keycodes {
     VRSN = SAFE_RANGE,
+    BUGS,
+    CATS,
+    DANCE,
+    DICE,
+    DOMO,
+    FART,
+    FLIP,
+    HUGS,
+    JOY,
+    KISS,
     LOD,
+    MUSIC,
+    RNDM,
     RUPA,
+    SHRUG,
+    TADA,
     U_FRACT,
+    U_ITALI,
     U_MONOS,
+    U_NORML,
+    U_SANSI,
+    U_SANSN,
     U_SCRPT,
+    WAT,
+    YUNO,
+    ZALGO,
+    ZZZZZ,
+    NEXT_SAFE_RANGE
+};
+
+enum userspace_font_choices {
+    F_FRACT = 0,
+    F_ITALI,
+    F_MONOS,
+    F_NORML,
+    F_SANSI,
+    F_SANSN,
+    F_SCRPT
 };
 
 typedef struct font_t {
@@ -41,14 +77,6 @@ typedef struct font_t {
     uint32_t zero_glyph;
 } font_t;
 
-font_t fraktu_bold;
-font_t monosp_bold;
-font_t script_bold;
-
-bool script_mode_translate(font_t *translator, bool is_shifted, uint32_t keycode);
-
-#define RAISE   MO(_RAISE)
-#define OS_RGUI OSM(MOD_RGUI)
-#define OS_RALT OSM(MOD_RALT)
-#define OS_RCTL OSM(MOD_RCTL)
-#define OS_RSFT OSM(MOD_RSFT)
+const font_t* get_script_mode(void);
+bool set_script_mode(int fc);
+bool script_mode_translate(bool is_shifted, uint32_t keycode);
diff --git a/users/rupa/unicode.c b/users/rupa/unicode.c
old mode 100755
new mode 100644
index 89a0d47665..2302a95552
--- a/users/rupa/unicode.c
+++ b/users/rupa/unicode.c
@@ -17,26 +17,155 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #include "unicode.h"
 
+combined_mode_t combined_mode = CM_NULL;
+bool _seeded = false;
+
 #if defined(UNICODEMAP_ENABLE)
 const uint32_t PROGMEM unicode_map[] = {
-    [CHEK] = 0x2713, // ✓
-    /*
-    [DI1]  = 0x2680, // ⚀
-    [DI2]  = 0x2681, // ⚁
-    [DI3]  = 0x2682, // ⚂
-    [DI4]  = 0x2683, // ⚃
-    [DI5]  = 0x2684, // ⚄
-    [DI6]  = 0x2685, // ⚅
-    */
-    [HAS]  = 0x262D, // ☭
-    [IBNG] = 0x203D, // ‽
-    [IRNY] = 0x2E2E, // ⸮
-    [M4]   = 0x2669, // ♩
-    [M8]   = 0x266A, // ♪
-    [M8B]  = 0x266B, // ♫
-    [M16]  = 0x266C, // ♬
-    [OM]   = 0x0950, // ॐ
-    [STB]  = 0x2605, // ★
-    [STW]  = 0x2606, // ☆
+    [CCIR] = 0x20DD,  // COMBINING CIRCLE  ⃝
+    [CENT] = 0x00A2,  // ¢
+    [CHEK] = 0x2713,  // ✓
+    [CKEY] = 0x20E3,  // COMBINING KEYCAP  ⃣
+    [CUI]  = 0x26A0,  // ⚠
+    [ECKS] = 0x2716,  // ✖
+    [EFF]  = 0x017F,  // ſ
+    [HAS]  = 0x262D,  // ☭
+    [HUN]  = 0x1F4AF, // 💯
+    [IBNG] = 0x203D,  // ‽
+    [IRNY] = 0x2E2E,  // ⸮
+    [LALL] = 0x2200,  // ∀
+    [LELM] = 0x2208,  // ∈
+    [LEXI] = 0x2203,  // ∃
+    [LPRO] = 0x22A2,  // ⊢
+    [M4]   = 0x2669,  // ♩
+    [M8]   = 0x266A,  // ♪
+    [M8B]  = 0x266B,  // ♫
+    [M16]  = 0x266C,  // ♬
+    [NEG]  = 0x20E0,  // COMBINING NO  ⃠
+    [NOPE] = 0x1F6AB, // 🚫
+    [NUM]  = 0x2116,  // №
+    [OM]   = 0x0950,  // ॐ
+    [SMB]  = 0x263A,  // ☻
+    [SMW]  = 0x263B,  // ☺
+    [STB]  = 0x2605,  // ★
+    [STOP] = 0x26D4,  // ⛔
+    [STW]  = 0x2606,  // ☆
 };
 #endif
+
+const char *d6_map[] = {
+    "⚀", "⚁", "⚂", "⚃", "⚄", "⚅"
+};
+const char *dance_map[] = {
+    "〜( ̄▽ ̄〜)",
+    "(〜 ̄▽ ̄)〜"
+};
+const char *dance_more_map[] = {
+    "ƪ(˘⌣˘)┐",
+    "┌(˘⌣˘)ʃ"
+};
+const char *flip_map[] = {
+    "(╯°□°)╯︵ ┻━━┻",
+    "(ノ-_-)ノ・・ ┻━━┻",
+    "(ノꐦ⊙曲ఠ)ノ彡┻━┻"
+};
+const char *flip_back_map[] = {
+    "┬──┬◡ノ(° -°ノ)",
+    "┬──┬ノ( ゜-゜ノ)",
+    "┬──┬ノ(ಠ_ಠノ)"
+};
+const char *joy_map[] = {
+    "ᕕ( ᐛ )ᕗ ",
+    "٩(ˊᗜˋ*)و",
+    "٩( ᐛ )و"
+};
+const char *joy_harder_map[] = {
+    "\\\ ٩( ᐛ )و //",
+    "✧*。٩(ˊᗜˋ*)و✧*。"
+};
+
+const char *choice(const char *choices[], int size) {
+    if (_seeded == false) {
+        srand(timer_read32());
+        dprintf("_seeded the roll\n");
+        _seeded = true;
+    }
+    return choices[rand() % size];
+}
+
+const char *d6(void) {
+    return choice(d6_map, 6);
+}
+const char *dance(bool more) {
+    if (more) {
+        return choice(dance_more_map, 2);
+    }
+    return choice(dance_map, 2);
+}
+const char *flip(bool flip_back) {
+    if (flip_back) {
+        return choice(flip_back_map, 3);
+    }
+    return choice(flip_map, 3);
+}
+const char *joy(bool harder) {
+    if (harder) {
+        return choice(joy_harder_map, 2);
+    }
+    return choice(joy_map, 3);
+}
+
+bool u_x(const char *text) {
+    send_unicode_string(text);
+    return false;
+};
+bool u_xp(bool is_shifted, const char *shifted, const char *plain) {
+    send_unicode_string(is_shifted ? shifted : plain);
+    return false;
+};
+
+void zalgo(void) {
+    int number = (rand() % (8 + 1 - 2)) + 2;
+    unsigned int index;
+    for (index=0; index<number; index++) {
+        uint16_t hex = (rand() % (0x036F + 1 - 0x0300)) + 0x0300;
+        register_hex(hex);
+    }
+}
+
+bool combined_text(uint16_t keycode) {
+    if (keycode < KC_A || (keycode > KC_0 && keycode < KC_MINUS) || keycode > KC_SLASH) {
+        return false;
+    }
+    tap_code(keycode);
+    unicode_input_start();
+    switch (combined_mode) {
+        case CM_CIRCLE:
+          register_hex(0x20DD);
+          break;
+        case CM_NO:
+          register_hex(0x20E0);
+          break;
+        case CM_KEYCAP:
+          register_hex(0x20E3);
+          break;
+        case CM_ZALGO:
+          zalgo();
+          break;
+        default:
+          break;
+    }
+    unicode_input_finish();
+    return true;
+}
+
+void cycle_combined_mode(void) {
+    if (combined_mode++ >= CM_MAX - 1) {
+        combined_mode = CM_NULL;
+    }
+}
+
+combined_mode_t set_combined_mode(combined_mode_t mode) {
+    combined_mode = combined_mode == mode ? CM_NULL : mode;
+    return combined_mode;
+}
diff --git a/users/rupa/unicode.h b/users/rupa/unicode.h
old mode 100755
new mode 100644
index 0c067bd913..92303b13f5
--- a/users/rupa/unicode.h
+++ b/users/rupa/unicode.h
@@ -20,24 +20,58 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #if defined(UNICODEMAP_ENABLE)
 enum unicode_names {
-    CHEK,
-    /*
-    DI1, // ⚀
-    DI2, // ⚁
-    DI3, // ⚂
-    DI4, // ⚃
-    DI5, // ⚄
-    DI6, // ⚅
-    */
+    CCIR, // COMBINING  ⃝
+    CENT, // ¢
+    CHEK, // ✓
+    CKEY, // COMBINING  ⃣
+    CUI,  // ⚠
+    ECKS, // ✖
+    EFF,  // ſ
     HAS,  // ☭
+    HUN,  // 💯
     IBNG, // ‽
     IRNY, // ⸮
+    LALL, // ∀
+    LELM, // ∈
+    LEXI, // ∃
+    LPRO, // ⊢
     M4,   // ♩
     M8,   // ♪
     M8B,  // ♫
     M16,  // ♬
+    NEG,  // COMBINING  ⃠
+    NOPE, // 🚫
+    NUM,  // №
     OM,   // ॐ
+    SMB,  // ☻
+    SMW,  // ☺
     STB,  // ★
+    STOP, // ⛔
     STW,  // ☆
 };
 #endif
+
+typedef enum combined_modes {
+    CM_NULL = 0,
+    CM_CIRCLE,
+    CM_NO,
+    CM_KEYCAP,
+    CM_ZALGO,
+    CM_MAX
+} combined_mode_t;
+
+combined_mode_t combined_mode;
+
+// random choices
+const char * d6(void);
+const char * dance(bool more);
+const char * flip(bool back);
+const char * joy(bool harder);
+
+// like X and XP
+bool u_x(const char *text);
+bool u_xp(bool is_shifted, const char * shifted, const char *plain);
+
+bool combined_text(uint16_t keycode);
+void cycle_combined_mode(void);
+combined_mode_t set_combined_mode(combined_mode_t mode);
diff --git a/users/rupa/wrappers.h b/users/rupa/wrappers.h
new file mode 100644
index 0000000000..c5cae464b8
--- /dev/null
+++ b/users/rupa/wrappers.h
@@ -0,0 +1,122 @@
+/*
+Copyright 2020 rupa <rupa@lrrr.us> @rupa
+
+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 "rupa.h"
+
+#define LOWER   MO(_LOWER)
+#define RAISE   MO(_RAISE)
+#define OS_RGUI OSM(MOD_RGUI)
+#define OS_RALT OSM(MOD_RALT)
+#define OS_RCTL OSM(MOD_RCTL)
+#define OS_RSFT OSM(MOD_RSFT)
+
+#define G_LWR   LT(_LOWER, KC_G)
+
+#if defined(UNICODEMAP_ENABLE)
+#    define CSHAPES XP(CCIR,CKEY)
+#    define CUIDADO XP(CUI,HAS)
+#    define NOPENAH XP(NOPE,STOP)
+#    define MUSIC_A XP(M4,M8)
+#    define MUSIC_B XP(M8B,M16)
+#    define SMILE   XP(SMB,SMW)
+#    define STARS   XP(STB,STW)
+#    define YEPYEP  XP(CHEK,HUN)
+#endif
+
+/* _QWERTY
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───┐
+ * │Es~│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ Backsp│~ `│
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │  \  │Del│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │RAISE │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │  Enter │PgU│
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │ Shift  │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shift│ ↑ │PgD│
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬┴──┬───┼───┼───┤
+ * │Ctrl│Alt │Gui │        Space           │RAI│LOW│CAP│ ← │ ↓ │ → │
+ * └────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┴───┘
+ */
+#define ____65_QWERTY______________ROW1    KC_GESC, KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_MINS, KC_EQL,  KC_BSPC, KC_GRV
+#define ____65_QWERTY______________ROW2    KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL
+#define ____65_QWERTY______________ROW3    RAISE,   KC_A,    KC_S,    KC_D,    KC_F,    G_LWR,   KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT,          KC_ENT,  KC_PGUP
+#define ____65_QWERTY______________ROW4    KC_LSFT,          KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_RSFT, KC_UP,   KC_PGDN
+#define ____65_QWERTY______________ROW5    KC_LCTL, KC_LALT, KC_LGUI,                            KC_SPC,                    RAISE,   LOWER,   KC_CAPS, KC_LEFT, KC_DOWN, KC_RGHT
+
+/* _RAISE
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───┐
+ * │ ` │ ‽ │ ⸮ │   │ ¢ │   │   │   │★  │   │ ☻ │  ⃠ │CSH│  Del  │Hme│
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │     │   │WAT│ ∃ │Rup│TAD│YUN│   │ ∈ │ ॐ │   │♩ ♪│♫ ♬│     │Ins│
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │      │ ∀ │ ſ │ ⚂ │FRT│   │HUG│JOY│KSS│LOD│   │NO!│ ✓  💯  │End│
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │ RShift │⚠ ☭│ ✖ │CAT│BOW│BUG│ № │MUS│DNC│ ⊢ │SHR│   McL│M↑ │McR│
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬┴──┬───┼───┼───┤
+ * │RCtl│RAlt│RGui│          FLIP          │   │   │   │M← │M↓ │M→ │
+ * └────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┴───┘
+ */
+#define ____65_RAISE_______________ROW1    KC_GRV,  X(IBNG), X(IRNY), _______, X(CENT), _______, _______, _______, STARS,   _______, SMILE,   X(NEG),  CSHAPES, KC_DEL,  KC_HOME
+#define ____65_RAISE_______________ROW2    _______, _______, WAT,     X(LEXI), RUPA,    TADA,    YUNO,    _______, X(LELM), X(OM),   _______, MUSIC_A, MUSIC_B, _______, KC_INS
+#define ____65_RAISE_______________ROW3    _______, X(LALL), X(EFF),  DICE,    FART,    _______, HUGS,    JOY,     KISS,    LOD,     _______, NOPENAH,          YEPYEP,  KC_END
+#define ____65_RAISE_______________ROW4    OS_RSFT,          CUIDADO, X(ECKS), CATS,    DOMO,    BUGS,    X(NUM),  MUSIC,   DANCE,   X(LPRO), SHRUG,   KC_BTN1, KC_MS_U, KC_BTN2
+#define ____65_RAISE_______________ROW5    OS_RCTL, OS_RALT, OS_RGUI,                            FLIP,                      _______, _______, _______, KC_MS_L, KC_MS_D, KC_MS_R
+
+/* _LOWER
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───┐
+ * │   │   │   │   │   │   │   │   │   │   │   │   │zzz│       │   │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │     │u_f│u_i│u_m│u_n│usi│usn│u_s│   │   │PRT│   │   │     │   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │      │   │SLK│PAU│   │   │   │   │   │   │   │   │        │   │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │        │ZAL│   │CAP│VSN│   │NLK│   │   │   │   │      │   │   │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬┴──┬───┼───┼───┤
+ * │    │    │    │                        │   │   │   │ ← │ ↓ │ → │
+ * └────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┴───┘
+ */
+#define ____65_LOWER_______________ROW1    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, ZZZZZ,   _______, _______
+#define ____65_LOWER_______________ROW2    _______, U_FRACT, U_ITALI, U_MONOS, U_NORML, U_SANSI, U_SANSN, U_SCRPT, _______, _______, KC_PSCR, _______, _______, _______, _______
+#define ____65_LOWER_______________ROW3    _______, _______, KC_SLCK, KC_PAUS, _______, _______, _______, _______, _______, _______, _______, _______,          _______, _______
+#define ____65_LOWER_______________ROW4    _______,          ZALGO  , _______, KC_CAPS, VRSN,    _______, KC_NLCK, _______, _______, _______, _______, _______, _______, _______
+#define ____65_LOWER_______________ROW5    _______, _______, _______,                            _______,                   _______, _______, _______, _______, _______, _______
+
+/* _ADJUST
+ * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┬───┐
+ * │   │F1 │F2 │F3 │F4 │F5 │F6 │F7 │F8 │F9 │F10│F11│F12│       │   │
+ * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┤
+ * │     │r x│r m│rh+│rh-│rs+│rs-│rv+│rv-│ra+│ra-│   │   │RESET│   │
+ * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤
+ * │      │   │   │   │   │   │   │   │   │   │   │   │EEP RSET│   │
+ * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤
+ * │        │   │   │   │   │   │   │Mut│V- │V+ │   │U MODE│   │   │
+ * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬┴──┬───┼───┼───┤
+ * │    │    │    │                        │   │   │   │   │   │   │
+ * └────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┴───┘
+ */
+#define ____65_ADJUST______________ROW1    _______, KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,  _______, _______
+#define ____65_ADJUST______________ROW2    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET,   _______
+#define ____65_ADJUST______________ROW3    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          EEP_RST, _______
+#define ____65_ADJUST______________ROW4    _______,          _______, _______, _______, _______, _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, _______, UC_MOD,  _______, _______
+#define ____65_ADJUST______________ROW5    _______, _______, _______,                            _______,                   _______, _______, _______, _______, _______, _______
+
+#define ____65_ADJUST__________RGB_ROW2    _______, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, RGB_SPI, RGB_SPD, _______, _______, RESET,   _______
+#define ____65_ADJUST__________RGB_ROW3    _______, RGB_M_P, RGB_M_B, _______, _______, _______, _______, _______, _______, _______, _______, _______,          EEP_RST, _______
+
+#define ____65_ADJUST___________BL_ROW2    _______, BL_TOGG, BL_BRTG, BL_STEP, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET,   _______
+
+// clang-format on