Browse Source

Change sim to only use gbuffer, not field

master
cancel 6 years ago
parent
commit
050ed29126
  1. 2
      cli_main.c
  2. 26
      gbuffer.h
  3. 77
      sim.c
  4. 2
      sim.h

2
cli_main.c

@ -98,7 +98,7 @@ int main(int argc, char** argv) {
markmap_reusable_init(&markmap_r);
markmap_reusable_ensure_size(&markmap_r, field.height, field.width);
for (int i = 0; i < ticks; ++i) {
orca_run(&field, markmap_r.buffer);
orca_run(field.buffer, markmap_r.buffer, field.height, field.width);
}
markmap_reusable_deinit(&markmap_r);
field_fput(&field, stdout);

26
gbuffer.h

@ -1,11 +1,31 @@
#pragma once
#include "base.h"
inline Glyph gbuffer_peek_relative(Gbuffer gbuffer, Usz height, Usz width,
Usz y, Usz x, Isz delta_y, Isz delta_x) {
inline Glyph gbuffer_peek(Gbuffer gbuf, Usz height, Usz width, Usz y, Usz x) {
assert(y < height && x < width);
return gbuf[y + width + x];
}
inline Glyph gbuffer_peek_relative(Gbuffer gbuf, 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];
return gbuf[(Usz)y0 * width + (Usz)x0];
}
inline void gbuffer_poke(Gbuffer gbuf, Usz height, Usz width, Usz y, Usz x,
Glyph g) {
assert(y < height && x < width);
gbuf[y * width + x] = g;
}
inline void gbuffer_poke_relative(Gbuffer gbuf, Usz height, Usz width, Usz y,
Usz x, Isz delta_y, Isz delta_x, Glyph g) {
Isz y0 = (Isz)y + delta_y;
Isz x0 = (Isz)x + delta_x;
if (y0 < 0 || x0 < 0 || (Usz)y0 >= height || (Usz)x0 >= width)
return;
gbuf[(Usz)y0 * width + (Usz)x0] = g;
}

77
sim.c

@ -1,6 +1,5 @@
#include "field.h"
#include "mark.h"
#include "gbuffer.h"
#include "mark.h"
#include "sim.h"
//////// Utilities
@ -57,27 +56,27 @@ static inline bool oper_has_neighboring_bang(Gbuffer gbuf, Usz h, Usz w, Usz y,
gbuffer_peek_relative(gbuf, h, w, y, x, -1, 0) == '*';
}
static inline void
oper_move_relative_or_explode(Gbuffer field_buffer, Markmap_buffer markmap,
Usz field_height, Usz field_width, Glyph moved,
Usz y, Usz x, Isz delta_y, Isz delta_x) {
static inline void oper_move_relative_or_explode(Gbuffer gbuf,
Markmap_buffer markmap,
Usz height, Usz width,
Glyph moved, Usz y, Usz x,
Isz delta_y, Isz delta_x) {
Isz y0 = (Isz)y + delta_y;
Isz x0 = (Isz)x + delta_x;
if (y0 >= (Isz)field_height || x0 >= (Isz)field_width || y0 < 0 || x0 < 0) {
field_buffer[y * field_width + x] = '*';
if (y0 >= (Isz)height || x0 >= (Isz)width || y0 < 0 || x0 < 0) {
gbuf[y * width + x] = '*';
return;
}
Glyph* at_dest = field_buffer + (Usz)y0 * field_width + (Usz)x0;
Glyph* at_dest = gbuf + (Usz)y0 * width + (Usz)x0;
if (*at_dest != '.') {
field_buffer[y * field_width + x] = '*';
markmap_poke_flags_or(markmap, field_height, field_width, y, x,
Mark_flag_sleep);
gbuf[y * width + x] = '*';
markmap_poke_flags_or(markmap, height, width, y, x, Mark_flag_sleep);
return;
}
*at_dest = moved;
markmap_poke_flags_or(markmap, field_height, field_width, (Usz)y0, (Usz)x0,
markmap_poke_flags_or(markmap, height, width, (Usz)y0, (Usz)x0,
Mark_flag_sleep);
field_buffer[y * field_width + x] = '.';
gbuf[y * width + x] = '.';
}
#define ORCA_EXPAND_OPER_CHARS(_oper_name, _oper_char) \
@ -88,9 +87,12 @@ oper_move_relative_or_explode(Gbuffer field_buffer, Markmap_buffer markmap,
#define OPER_PHASE_N(_phase_number, _oper_name) \
static inline void oper_phase##_phase_number##_##_oper_name( \
Field* field, Markmap_buffer markmap, Usz y, Usz x) { \
(void)field; \
Gbuffer gbuffer, Markmap_buffer markmap, Usz height, Usz width, Usz y, \
Usz x) { \
(void)gbuffer; \
(void)markmap; \
(void)height; \
(void)width; \
(void)y; \
(void)x; \
enum { This_oper_char = Orca_oper_char_##_oper_name };
@ -100,22 +102,22 @@ oper_move_relative_or_explode(Gbuffer field_buffer, Markmap_buffer markmap,
#define OPER_PHASE_2(_oper_name) OPER_PHASE_N(2, _oper_name)
#define OPER_END }
#define OPER_POKE_ABSOLUTE(_y, _x, _glyph) field_poke(field, _y, _x, _glyph)
#define OPER_POKE_ABSOLUTE(_y, _x, _glyph) \
gbuffer_poke(gbuffer, height, width, _y, _x, _glyph)
#define OPER_PEEK_RELATIVE(_delta_y, _delta_x) \
field_peek_relative(field, y, x, _delta_y, _delta_x)
gbuffer_peek_relative(gbuffer, height, width, y, x, _delta_y, _delta_x)
#define OPER_POKE_RELATIVE(_delta_y, _delta_x, _glyph) \
field_poke_relative(field, y, x, _delta_x, _delta_y, _glyph)
gbuffer_poke_relative(gbuffer, height, width, 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)) \
if (!oper_has_neighboring_bang(gbuffer, height, 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)
oper_move_relative_or_explode(gbuffer, markmap, height, width, \
This_oper_char, y, x, _delta_y, _delta_x)
#define OPER_DEFINE_UPPERCASE_DIRECTIONAL(_oper_name, _delta_y, _delta_x) \
OPER_PHASE_0(_oper_name) \
@ -198,22 +200,19 @@ OPER_END
OPER_PHASE_2(bang)
OPER_END
void orca_run(Field* field, Markmap_buffer markmap) {
Usz ny = field->height;
Usz nx = field->width;
markmap_clear(markmap, ny, nx);
Glyph* field_buffer = field->buffer;
void orca_run(Gbuffer gbuf, Markmap_buffer markmap, Usz height, Usz width) {
markmap_clear(markmap, height, width);
// Phase 0
for (Usz iy = 0; iy < ny; ++iy) {
Glyph* glyph_row = field_buffer + iy * nx;
for (Usz ix = 0; ix < nx; ++ix) {
for (Usz iy = 0; iy < height; ++iy) {
Glyph* glyph_row = gbuf + iy * width;
for (Usz ix = 0; ix < width; ++ix) {
Glyph c = glyph_row[ix];
if (markmap_peek(markmap, ny, nx, iy, ix) & Mark_flag_sleep)
if (markmap_peek(markmap, height, width, iy, ix) & Mark_flag_sleep)
continue;
switch (c) {
#define X(_oper_name, _oper_char) \
case _oper_char: \
oper_phase0_##_oper_name(field, markmap, iy, ix); \
oper_phase0_##_oper_name(gbuf, markmap, height, width, iy, ix); \
break;
ORCA_OPERATORS(X)
#undef X
@ -221,16 +220,16 @@ void orca_run(Field* field, Markmap_buffer markmap) {
}
}
// Phase 1
for (Usz iy = 0; iy < ny; ++iy) {
Glyph* glyph_row = field_buffer + iy * nx;
for (Usz ix = 0; ix < nx; ++ix) {
if (markmap_peek(markmap, ny, nx, iy, ix) & Mark_flag_sleep)
for (Usz iy = 0; iy < height; ++iy) {
Glyph* glyph_row = gbuf + iy * width;
for (Usz ix = 0; ix < width; ++ix) {
if (markmap_peek(markmap, height, width, iy, ix) & Mark_flag_sleep)
continue;
Glyph c = glyph_row[ix];
switch (c) {
#define X(_oper_name, _oper_char) \
case _oper_char: \
oper_phase1_##_oper_name(field, markmap, iy, ix); \
oper_phase1_##_oper_name(gbuf, markmap, height, width, iy, ix); \
break;
ORCA_OPERATORS(X)
#undef X

2
sim.h

@ -2,4 +2,4 @@
#include "base.h"
#include "mark.h"
void orca_run(Field* field, Markmap_buffer markmap);
void orca_run(Gbuffer gbuf, Markmap_buffer markmap, Usz height, Usz width);

Loading…
Cancel
Save