shithub: orca

Download patch

ref: 2eeb52c125842593fd8340af8deb268f286e1ce6
parent: d94a0eaa3b19e2ae41afb4c0514d17db664d8a4c
author: cancel <cancel@cancel.fm>
date: Tue Dec 4 10:22:33 EST 2018

Add start of piano input

--- a/cli_main.c
+++ b/cli_main.c
@@ -104,7 +104,7 @@
   Usz max_ticks = (Usz)ticks;
   for (Usz i = 0; i < max_ticks; ++i) {
     orca_run(field.buffer, markmap_r.buffer, field.height, field.width, i,
-             &bank);
+             &bank, ORCA_PIANO_BITS_NONE);
   }
   markmap_reusable_deinit(&markmap_r);
   bank_deinit(&bank);
--- a/sim.c
+++ b/sim.c
@@ -825,7 +825,8 @@
     return;
   }
   Glyph result = bank_params->vars_slots[var_idx];
-  if (result == '.') return;
+  if (result == '.')
+    return;
   POKE(1, 0, result);
   STUN(1, 0);
 END_PHASE
@@ -932,7 +933,8 @@
 }
 
 void orca_run(Gbuffer gbuf, Mbuffer mbuf, Usz height, Usz width,
-              Usz tick_number, Bank* bank) {
+              Usz tick_number, Bank* bank, Piano_bits piano_bits) {
+  (void)piano_bits;
   Glyph vars_slots[('Z' - 'A' + 1) + ('z' - 'a' + 1)];
   memset(vars_slots, '.', sizeof(vars_slots));
   mbuffer_clear(mbuf, height, width);
--- a/sim.h
+++ b/sim.h
@@ -3,5 +3,17 @@
 #include "base.h"
 #include "mark.h"
 
+#define ORCA_PIANO_KEYS_COUNT ((size_t)(('9' - '0') + 1 + ('z' - 'a') + 1))
+#define ORCA_PIANO_BITS_NONE UINT64_C(0)
+typedef U64 Piano_bits;
+
+static inline Piano_bits piano_bits_of(Glyph g) {
+  if (g >= '0' && g <= '9')
+    return UINT64_C(1) << (U64)((Usz)('9' - g));
+  if (g >= 'a' && g <= 'z')
+    return UINT64_C(1) << (U64)(((Usz)('z' - g)) + ((Usz)('9' - '0')) + 1);
+  return UINT64_C(0);
+}
+
 void orca_run(Gbuffer gbuf, Mbuffer markmap, Usz height, Usz width,
-              Usz tick_number, Bank* bank);
+              Usz tick_number, Bank* bank, Piano_bits piano_bits);
--- a/tui_main.c
+++ b/tui_main.c
@@ -355,6 +355,11 @@
 
 enum { Argopt_margins = UCHAR_MAX + 1 };
 
+typedef enum {
+  Tui_input_mode_normal = 0,
+  Tui_input_mode_piano = 1,
+} Tui_input_mode;
+
 int main(int argc, char** argv) {
   static struct option tui_options[] = {
       {"margins", required_argument, 0, Argopt_margins},
@@ -491,6 +496,7 @@
 
   Tui_cursor tui_cursor;
   tui_cursor_init(&tui_cursor);
+  Tui_input_mode input_mode = Tui_input_mode_normal;
   Usz tick_num = 0;
   Usz ruler_spacing_y = 8;
   Usz ruler_spacing_x = 8;
@@ -516,7 +522,7 @@
       field_resize_raw_if_necessary(&scratch_field, field.height, field.width);
       field_copy(&field, &scratch_field);
       orca_run(field.buffer, markmap_r.buffer, field.height, field.width,
-               tick_num, &bank);
+               tick_num, &bank, ORCA_PIANO_BITS_NONE);
       field_copy(&scratch_field, &field);
       needs_remarking = false;
     }
@@ -559,6 +565,7 @@
     }
     wrefresh(cont_win);
 
+    Piano_bits piano_bits = ORCA_PIANO_BITS_NONE;
     int key;
     // ncurses gives us ERR if there was no user input. We'll sleep for 0
     // seconds, so that we'll yield CPU time to the OS instead of looping as
@@ -632,23 +639,40 @@
       tui_resize_grid(&field, &markmap_r, 1, 0, tick_num, &scratch_field,
                       &undo_hist, &tui_cursor, &needs_remarking);
       break;
+    case '\\':
+      if (input_mode == Tui_input_mode_piano) {
+        input_mode = Tui_input_mode_normal;
+      } else {
+        input_mode = Tui_input_mode_piano;
+      }
+      break;
     case ' ':
       undo_history_push(&undo_hist, &field, tick_num);
       orca_run(field.buffer, markmap_r.buffer, field.height, field.width,
-               tick_num, &bank);
+               tick_num, &bank, piano_bits);
       ++tick_num;
       needs_remarking = true;
       break;
     default:
-      if (key >= '!' && key <= '~') {
-        undo_history_push(&undo_hist, &field, tick_num);
-        gbuffer_poke(field.buffer, field.height, field.width, tui_cursor.y,
-                     tui_cursor.x, (char)key);
-        // Indicate we want the next simulation step to be run predictavely, so
-        // that we can use the reulsting mark buffer for UI visualization. This
-        // is "expensive", so it could be skipped for non-interactive input in
-        // situations where max throughput is necessary.
-        needs_remarking = true;
+      switch (input_mode) {
+      case Tui_input_mode_normal: {
+        if (key >= '!' && key <= '~') {
+          undo_history_push(&undo_hist, &field, tick_num);
+          gbuffer_poke(field.buffer, field.height, field.width, tui_cursor.y,
+                       tui_cursor.x, (char)key);
+          // Indicate we want the next simulation step to be run predictavely,
+          // so that we can use the reulsting mark buffer for UI visualization.
+          // This is "expensive", so it could be skipped for non-interactive
+          // input in situations where max throughput is necessary.
+          needs_remarking = true;
+        }
+      } break;
+      case Tui_input_mode_piano: {
+        if (key >= '!' && key <= '~') {
+          Piano_bits added_bits = piano_bits_of((Glyph)key);
+          piano_bits |= added_bits;
+        }
+      } break;
       }
 #if 0
       else {