shithub: orca

Download patch

ref: b6f69b19b3392d9c77eb5bcdbc0f49dd99eb46fb
parent: 1d4937d2bd9303bb09f5e49b4bb99bc86bd53fb4
author: cancel <cancel@cancel.fm>
date: Mon Dec 3 07:39:24 EST 2018

Cleanup movement operator declarations

--- a/sim.c
+++ b/sim.c
@@ -71,8 +71,8 @@
   return indexed_glyphs[ib == 0 ? 0 : (ia % ib)];
 }
 
-ORCA_PURE static bool
-oper_has_neighboring_bang(Glyph const* gbuf, Usz h, Usz w, Usz y, Usz x) {
+ORCA_PURE static bool oper_has_neighboring_bang(Glyph const* gbuf, Usz h, Usz w,
+                                                Usz y, Usz x) {
   Glyph const* gp = gbuf + w * y + x;
   if (x < w - 1 && gp[1] == '*')
     return true;
@@ -87,10 +87,18 @@
   return false;
 }
 
-ORCA_FORCE_NO_INLINE static void
-oper_move_relative_or_explode(Gbuffer gbuf, Mbuffer mbuf, Usz height, Usz width,
-                              Glyph moved, Usz y, Usz x, Isz delta_y,
-                              Isz delta_x) {
+ORCA_FORCE_NO_INLINE
+static void oper_movement_phase0(Gbuffer gbuf, Mbuffer mbuf, Usz const height,
+                                 Usz const width, Usz const y, Usz const x,
+                                 Mark const cell_flags,
+                                 Glyph const uppercase_char,
+                                 Glyph const actual_char, Isz const delta_y,
+                                 Isz const delta_x) {
+  if (cell_flags & (Mark_flag_lock | Mark_flag_sleep))
+    return;
+  if ((actual_char != uppercase_char) &&
+      !oper_has_neighboring_bang(gbuf, height, width, y, x))
+    return;
   Isz y0 = (Isz)y + delta_y;
   Isz x0 = (Isz)x + delta_x;
   if (y0 >= (Isz)height || x0 >= (Isz)width || y0 < 0 || x0 < 0) {
@@ -103,7 +111,7 @@
     mbuffer_poke_flags_or(mbuf, height, width, y, x, Mark_flag_sleep);
     return;
   }
-  *at_dest = moved;
+  *at_dest = actual_char;
   mbuffer_poke_flags_or(mbuf, height, width, (Usz)y0, (Usz)x0, Mark_flag_sleep);
   gbuf[y * width + x] = '.';
 }
@@ -150,13 +158,18 @@
                                     _oper_name)                                \
   Orca_oper_upper_char_##_oper_name = _upper_oper_char,                        \
   Orca_oper_lower_char_##_oper_name = _lower_oper_char,
-#define ORCA_DEFINE_OPER_CHARS(_solo_defs, _dual_defs)                         \
+#define ORCA_EXPAND_MOVM_OPER_CHARS(_upper_oper_char, _lower_oper_char,        \
+                                    _oper_name, _delta_y, _delta_x)            \
+  Orca_oper_upper_char_##_oper_name = _upper_oper_char,                        \
+  Orca_oper_lower_char_##_oper_name = _lower_oper_char,
+#define ORCA_DEFINE_OPER_CHARS(_solo_defs, _dual_defs, _movm_defs)             \
   enum Orca_oper_chars {                                                       \
     _solo_defs(ORCA_EXPAND_SOLO_OPER_CHARS)                                    \
         _dual_defs(ORCA_EXPAND_DUAL_OPER_CHARS)                                \
+            _movm_defs(ORCA_EXPAND_MOVM_OPER_CHARS)                            \
   };
-#define ORCA_DECLARE_OPERATORS(_solo_defs, _dual_defs)                         \
-  ORCA_DEFINE_OPER_CHARS(_solo_defs, _dual_defs)
+#define ORCA_DECLARE_OPERATORS(_solo_defs, _dual_defs, _movm_defs)             \
+  ORCA_DEFINE_OPER_CHARS(_solo_defs, _dual_defs, _movm_defs)
 
 #define OPER_PHASE_COMMON_ARGS                                                 \
   Gbuffer const gbuffer, Mbuffer const mbuffer, Usz const height,              \
@@ -265,18 +278,6 @@
                                  _delta_x, OPER_PORT_FLIP_LOCK_BIT(_flags))
 #define END_PORTS }
 
-#define MOVING_OPERATOR(_oper_name, _delta_y, _delta_x)                        \
-  BEGIN_DUAL_PHASE_0(_oper_name)                                               \
-    if (IS_AWAKE) {                                                            \
-      REALIZE_DUAL;                                                            \
-      STOP_IF_DUAL_INACTIVE;                                                   \
-      oper_move_relative_or_explode(gbuffer, mbuffer, height, width,           \
-                                    This_oper_char, y, x, _delta_y, _delta_x); \
-    }                                                                          \
-  END_PHASE                                                                    \
-  BEGIN_DUAL_PHASE_1(_oper_name)                                               \
-  END_PHASE
-
 //////// Operators
 
 #define ORCA_SOLO_OPERATORS(_)                                                 \
@@ -284,11 +285,6 @@
   _('*', bang)
 
 #define ORCA_DUAL_OPERATORS(_)                                                 \
-  _('N', 'n', north)                                                           \
-  _('E', 'e', east)                                                            \
-  _('S', 's', south)                                                           \
-  _('W', 'w', west)                                                            \
-  _('Z', 'z', southeast)                                                       \
   _('A', 'a', add)                                                             \
   _('B', 'b', banger)                                                          \
   _('C', 'c', clock)                                                           \
@@ -310,13 +306,15 @@
   _('V', 'v', beam)                                                            \
   _('X', 'x', teleport)
 
-ORCA_DECLARE_OPERATORS(ORCA_SOLO_OPERATORS, ORCA_DUAL_OPERATORS)
+#define ORCA_MOVEMENT_OPERATORS(_)                                             \
+  _('N', 'n', north, -1, 0)                                                    \
+  _('E', 'e', east, 0, 1)                                                      \
+  _('S', 's', south, 1, 0)                                                     \
+  _('W', 'w', west, 0, -1)                                                     \
+  _('Z', 'z', southeast, 1, 1)
 
-MOVING_OPERATOR(north, -1, 0)
-MOVING_OPERATOR(east, 0, 1)
-MOVING_OPERATOR(south, 1, 0)
-MOVING_OPERATOR(west, 0, -1)
-MOVING_OPERATOR(southeast, 1, 1)
+ORCA_DECLARE_OPERATORS(ORCA_SOLO_OPERATORS, ORCA_DUAL_OPERATORS,
+                       ORCA_MOVEMENT_OPERATORS)
 
 #define MOVEMENT_CASES                                                         \
   'N' : case 'n' : case 'E' : case 'e' : case 'S' : case 's' : case 'W'        \
@@ -872,6 +870,14 @@
                              bank_params, glyph_char);                         \
     break;
 
+#define SIM_EXPAND_MOVM_PHASE_0(_upper_oper_char, _lower_oper_char,            \
+                                _oper_name, _delta_y, _delta_x)                \
+  case _upper_oper_char:                                                       \
+  case _lower_oper_char:                                                       \
+    oper_movement_phase0(gbuf, mbuf, height, width, iy, ix, cell_flags,        \
+                         _upper_oper_char, glyph_char, _delta_y, _delta_x);    \
+    break;
+
 static void sim_phase_0(Gbuffer gbuf, Mbuffer mbuf, Usz height, Usz width,
                         Usz tick_number, Oper_bank_write_params* bank_params) {
   for (Usz iy = 0; iy < height; ++iy) {
@@ -885,6 +891,7 @@
       switch (glyph_char) {
         ORCA_SOLO_OPERATORS(SIM_EXPAND_SOLO_PHASE_0)
         ORCA_DUAL_OPERATORS(SIM_EXPAND_DUAL_PHASE_0)
+        ORCA_MOVEMENT_OPERATORS(SIM_EXPAND_MOVM_PHASE_0)
       }
     }
   }