shithub: orca

Download patch

ref: 59d2bcc057454b7c97dd2c62a72b839bcb2abc22
parent: f79e32b6040ac8febe18a65d264fa9f5f97aa813
author: cancel <cancel@cancel.fm>
date: Mon Nov 26 07:30:06 EST 2018

Add more movement and oper macros

--- a/field.h
+++ b/field.h
@@ -27,3 +27,12 @@
 } Field_load_error;
 
 Field_load_error field_load_file(char const* filepath, Field* field);
+
+inline Glyph gbuffer_peek_relative(Field_buffer gbuffer, Usz height, Usz width,
+                                   Usz y, Usz x, Isz delta_y, Isz delta_x) {
+  Isz y0 = (Isz)y + delta_y;
+  Isz x0 = (Isz)x + delta_x;
+  if (y0 < 0 || x0 < 0 || (Usz)y0 >= height || (Usz)x0 >= width)
+    return '.';
+  return gbuffer[(Usz)y0 * width + (Usz)x0];
+}
--- a/sim.c
+++ b/sim.c
@@ -48,6 +48,14 @@
   return indexed_glyphs[ib == 0 ? 0 : (ia % ib)];
 }
 
+static inline bool oper_has_neighboring_bang(Field_buffer gbuf, Usz h, Usz w,
+                                             Usz y, Usz x) {
+  return gbuffer_peek_relative(gbuf, h, w, y, x, 0, 1) == '*' ||
+         gbuffer_peek_relative(gbuf, h, w, y, x, 0, -1) == '*' ||
+         gbuffer_peek_relative(gbuf, h, w, y, x, 1, 0) == '*' ||
+         gbuffer_peek_relative(gbuf, h, w, y, x, -1, 0) == '*';
+}
+
 static inline void
 oper_move_relative_or_explode(Field_buffer field_buffer, Markmap_buffer markmap,
                               Usz field_height, Usz field_width, Glyph moved,
@@ -98,20 +106,35 @@
   field_poke_relative(field, y, x, _delta_x, _delta_y, _glyph)
 #define OPER_POKE_SELF(_glyph) OPER_POKE_ABSOLUTE(y, x, _glyph)
 
+#define OPER_REQUIRE_BANG()                                                    \
+  if (!oper_has_neighboring_bang(field->buffer, field->height, field->width,   \
+                                 y, x))                                        \
+    return;
+
 #define OPER_MOVE_OR_EXPLODE(_delta_y, _delta_x)                               \
   oper_move_relative_or_explode(field->buffer, markmap, field->height,         \
                                 field->width, This_oper_char, y, x, _delta_y,  \
-                                _delta_x);
+                                _delta_x)
 
 #define OPER_DEFINE_UPPERCASE_DIRECTIONAL(_oper_name, _delta_y, _delta_x)      \
   OPER_PHASE_0(_oper_name)                                                     \
   OPER_END                                                                     \
   OPER_PHASE_1(_oper_name)                                                     \
-    OPER_MOVE_OR_EXPLODE(_delta_y, _delta_x)                                   \
+    OPER_MOVE_OR_EXPLODE(_delta_y, _delta_x);                                  \
   OPER_END                                                                     \
   OPER_PHASE_2(_oper_name)                                                     \
   OPER_END
 
+#define OPER_DEFINE_LOWERCASE_DIRECTIONAL(_oper_name, _delta_y, _delta_x)      \
+  OPER_PHASE_0(_oper_name)                                                     \
+  OPER_END                                                                     \
+  OPER_PHASE_1(_oper_name)                                                     \
+    OPER_REQUIRE_BANG();                                                       \
+    OPER_MOVE_OR_EXPLODE(_delta_y, _delta_x);                                  \
+  OPER_END                                                                     \
+  OPER_PHASE_2(_oper_name)                                                     \
+  OPER_END
+
 //////// Operators
 
 #define ORCA_OPERATORS(_)                                                      \
@@ -121,6 +144,10 @@
   _(East, 'E')                                                                 \
   _(South, 'S')                                                                \
   _(West, 'W')                                                                 \
+  _(north, 'n')                                                                \
+  _(east, 'e')                                                                 \
+  _(south, 's')                                                                \
+  _(west, 'w')                                                                 \
   _(modulo, 'm')
 
 ORCA_DECLARE_OPERATORS(ORCA_OPERATORS)
@@ -131,6 +158,10 @@
 OPER_DEFINE_UPPERCASE_DIRECTIONAL(East, 0, 1)
 OPER_DEFINE_UPPERCASE_DIRECTIONAL(South, 1, 0)
 OPER_DEFINE_UPPERCASE_DIRECTIONAL(West, 0, -1)
+OPER_DEFINE_LOWERCASE_DIRECTIONAL(north, -1, 0)
+OPER_DEFINE_LOWERCASE_DIRECTIONAL(east, 0, 1)
+OPER_DEFINE_LOWERCASE_DIRECTIONAL(south, 1, 0)
+OPER_DEFINE_LOWERCASE_DIRECTIONAL(west, 0, -1)
 
 OPER_PHASE_0(add)
 OPER_END