ref: 1d99e512d8557f2edc1fa0c515f3a52a06e13155
parent: 0e08ced81733310c153e42d88a480cdf01757853
author: cancel <cancel@cancel.fm>
date: Mon Nov 26 02:42:21 EST 2018
Add mark.c and mark.h
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@
debug_flags := $(debug_flags) -Og -feliminate-unused-debug-symbols
tui_library_flags := -lncursesw
endif
-common_source_files := field.c sim.c
+common_source_files := field.c mark.c sim.c
tui_source_files := $(common_source_files) tui_main.c
cli_source_files := $(common_source_files) cli_main.c
--- a/base.h
+++ b/base.h
@@ -8,10 +8,19 @@
#include <string.h>
#include <unistd.h>
+#if defined(__GNUC__) || defined(__clang__)
+#define ORCA_FORCE_INLINE __attribute__((always_inline)) inline
+#elif defined(_MSC_VER)
+#define ORCA_FORCE_INLINE __forceinline
+#else
+#define ORCA_FORCE_INLINE inline
+#endif
+
#define ORCA_Y_MAX UINT16_MAX
#define ORCA_X_MAX UINT16_MAX
-typedef char Glyph;
+typedef uint8_t U8;
+typedef int8_t I8;
typedef uint16_t U16;
typedef int16_t I16;
typedef uint32_t U32;
@@ -20,6 +29,8 @@
typedef int64_t I64;
typedef size_t Usz;
typedef ssize_t Isz;
+
+typedef char Glyph;
typedef struct {
Glyph* buffer;
--- /dev/null
+++ b/mark.c
@@ -1,0 +1,21 @@
+#include "mark.h"
+
+void markmap_init(Markmap* map) {
+ map->buffer = NULL;
+ map->capacity = 0;
+}
+
+void markmap_ensure_capacity(Markmap* map, Usz capacity) {
+ if (map->capacity < capacity) {
+ map->buffer = realloc(map->buffer, capacity);
+ map->capacity = capacity;
+ }
+}
+
+void markmap_clear(Markmap* map) {
+ memset(map->buffer, 0, map->capacity);
+}
+
+void markmap_deinit(Markmap* map) {
+ free(map->buffer);
+}
--- /dev/null
+++ b/mark.h
@@ -1,0 +1,49 @@
+#pragma once
+#include "base.h"
+
+typedef enum {
+ Mark_flag_none = 0,
+ Mark_flag_haste_input = 1 << 0,
+ Mark_flag_input = 1 << 1,
+ Mark_flag_lock = 1 << 2,
+ Mark_flag_output = 1 << 3,
+} Mark_flags;
+
+typedef struct {
+ U8* buffer;
+ Usz capacity;
+} Markmap;
+
+void markmap_init(Markmap* map);
+void markmap_ensure_capacity(Markmap* map, Usz capacity);
+void markmap_clear(Markmap* map);
+void markmap_deinit(Markmap* map);
+
+ORCA_FORCE_INLINE
+Mark_flags markmap_peek_relative(Markmap* map, Usz map_height, Usz map_width,
+ Usz y, Usz x, Isz offs_y, Isz offs_x);
+ORCA_FORCE_INLINE
+void markmap_poke_relative(Markmap* map, Usz map_height, Usz map_width, Usz y,
+ Usz x, Isz offs_y, Isz offs_x, Mark_flags flags);
+
+// Inline implementation
+
+ORCA_FORCE_INLINE
+Mark_flags markmap_peek_relative(Markmap* map, Usz map_height, Usz map_width,
+ Usz y, Usz x, Isz offs_y, Isz offs_x) {
+ Isz y0 = (Isz)y + offs_y;
+ Isz x0 = (Isz)x + offs_x;
+ if (y0 >= (Isz)map_height || x0 >= (Isz)map_width || y0 < 0 || x0 < 0)
+ return Mark_flag_none;
+ return map->buffer[(Usz)y0 * map_width + (Usz)x0];
+}
+
+ORCA_FORCE_INLINE
+void markmap_poke_relative(Markmap* map, Usz map_height, Usz map_width, Usz y,
+ Usz x, Isz offs_y, Isz offs_x, Mark_flags flags) {
+ Isz y0 = (Isz)y + offs_y;
+ Isz x0 = (Isz)x + offs_x;
+ if (y0 >= (Isz)map_height || x0 >= (Isz)map_width || y0 < 0 || x0 < 0)
+ return;
+ map->buffer[(Usz)y0 * map_width + (Usz)x0] = flags;
+}