Browse Source

Add more movement and oper macros

master
cancel 6 years ago
parent
commit
59d2bcc057
  1. 9
      field.h
  2. 35
      sim.c

9
field.h

@ -27,3 +27,12 @@ typedef enum {
} Field_load_error; } Field_load_error;
Field_load_error field_load_file(char const* filepath, Field* field); 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];
}

35
sim.c

@ -48,6 +48,14 @@ static inline Glyph glyphs_mod(Glyph a, Glyph b) {
return indexed_glyphs[ib == 0 ? 0 : (ia % ib)]; 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 static inline void
oper_move_relative_or_explode(Field_buffer field_buffer, Markmap_buffer markmap, oper_move_relative_or_explode(Field_buffer field_buffer, Markmap_buffer markmap,
Usz field_height, Usz field_width, Glyph moved, Usz field_height, Usz field_width, Glyph moved,
@ -98,16 +106,31 @@ oper_move_relative_or_explode(Field_buffer field_buffer, Markmap_buffer markmap,
field_poke_relative(field, y, x, _delta_x, _delta_y, _glyph) field_poke_relative(field, y, x, _delta_x, _delta_y, _glyph)
#define OPER_POKE_SELF(_glyph) OPER_POKE_ABSOLUTE(y, x, _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) \ #define OPER_MOVE_OR_EXPLODE(_delta_y, _delta_x) \
oper_move_relative_or_explode(field->buffer, markmap, field->height, \ oper_move_relative_or_explode(field->buffer, markmap, field->height, \
field->width, This_oper_char, y, x, _delta_y, \ field->width, This_oper_char, y, x, _delta_y, \
_delta_x); _delta_x)
#define OPER_DEFINE_UPPERCASE_DIRECTIONAL(_oper_name, _delta_y, _delta_x) \ #define OPER_DEFINE_UPPERCASE_DIRECTIONAL(_oper_name, _delta_y, _delta_x) \
OPER_PHASE_0(_oper_name) \ OPER_PHASE_0(_oper_name) \
OPER_END \ OPER_END \
OPER_PHASE_1(_oper_name) \ 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_END \
OPER_PHASE_2(_oper_name) \ OPER_PHASE_2(_oper_name) \
OPER_END OPER_END
@ -121,6 +144,10 @@ oper_move_relative_or_explode(Field_buffer field_buffer, Markmap_buffer markmap,
_(East, 'E') \ _(East, 'E') \
_(South, 'S') \ _(South, 'S') \
_(West, 'W') \ _(West, 'W') \
_(north, 'n') \
_(east, 'e') \
_(south, 's') \
_(west, 'w') \
_(modulo, 'm') _(modulo, 'm')
ORCA_DECLARE_OPERATORS(ORCA_OPERATORS) ORCA_DECLARE_OPERATORS(ORCA_OPERATORS)
@ -131,6 +158,10 @@ OPER_DEFINE_UPPERCASE_DIRECTIONAL(North, -1, 0)
OPER_DEFINE_UPPERCASE_DIRECTIONAL(East, 0, 1) OPER_DEFINE_UPPERCASE_DIRECTIONAL(East, 0, 1)
OPER_DEFINE_UPPERCASE_DIRECTIONAL(South, 1, 0) OPER_DEFINE_UPPERCASE_DIRECTIONAL(South, 1, 0)
OPER_DEFINE_UPPERCASE_DIRECTIONAL(West, 0, -1) 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_PHASE_0(add)
OPER_END OPER_END

Loading…
Cancel
Save