diff --git a/field.c b/field.c index 1ec979c..73d5c97 100644 --- a/field.c +++ b/field.c @@ -1,4 +1,5 @@ #include "field.h" +#include "gbuffer.h" #include void field_init(Field* f) { @@ -34,57 +35,9 @@ void field_deinit(Field* f) { free(f->buffer); } void field_copy(Field* src, Field* dest) { field_resize_raw_if_necessary(dest, src->height, src->width); - field_copy_subrect(src, dest, 0, 0, 0, 0, src->height, src->width); -} - -void field_copy_subrect(Field* src, Field* dest, Usz src_y, Usz src_x, - Usz dest_y, Usz dest_x, Usz height, Usz width) { - Usz src_height = src->height; - Usz src_width = src->width; - Usz dest_height = dest->height; - Usz dest_width = dest->width; - if (src_height <= src_y || src_width <= src_x || dest_height <= dest_y || - dest_width <= dest_x) - return; - Usz ny_0 = src_height - src_y; - Usz ny_1 = dest_height - dest_y; - Usz ny = height; - if (ny_0 < ny) - ny = ny_0; - if (ny_1 < ny) - ny = ny_1; - if (ny == 0) - return; - Usz row_copy_0 = src_width - src_x; - Usz row_copy_1 = dest_width - dest_x; - Usz row_copy = width; - if (row_copy_0 < row_copy) - row_copy = row_copy_0; - if (row_copy_1 < row_copy) - row_copy = row_copy_1; - Usz copy_bytes = row_copy * sizeof(Glyph); - Glyph* src_p = src->buffer + src_y * src_width + src_x; - Glyph* dest_p = dest->buffer + dest_y * dest_width + dest_x; - Usz src_stride; - Usz dest_stride; - if (src_y >= dest_y) { - src_stride = src_width; - dest_stride = dest_width; - } else { - src_p += (ny - 1) * src_width; - dest_p += (ny - 1) * dest_width; - src_stride = -src_width; - dest_stride = -dest_width; - } - Usz iy = 0; - for (;;) { - memmove(dest_p, src_p, copy_bytes); - ++iy; - if (iy == ny) - break; - src_p += src_stride; - dest_p += dest_stride; - } + gbuffer_copy_subrect(src->buffer, dest->buffer, src->height, src->width, + dest->height, dest->width, 0, 0, 0, 0, src->height, + src->width); } void field_fill_subrect(Field* f, Usz y, Usz x, Usz height, Usz width, diff --git a/field.h b/field.h index d93930b..c169c6b 100644 --- a/field.h +++ b/field.h @@ -7,8 +7,6 @@ void field_resize_raw(Field* field, Usz height, Usz width); void field_resize_raw_if_necessary(Field* field, Usz height, Usz width); void field_deinit(Field* field); void field_copy(Field* src, Field* dest); -void field_copy_subrect(Field* src, Field* dest, Usz src_y, Usz src_x, - Usz dest_y, Usz dest_x, Usz height, Usz width); void field_fill_subrect(Field* field, Usz y, Usz x, Usz height, Usz width, Glyph fill_char); Glyph field_peek(Field* field, Usz y, Usz x); diff --git a/gbuffer.c b/gbuffer.c new file mode 100644 index 0000000..c72a091 --- /dev/null +++ b/gbuffer.c @@ -0,0 +1,49 @@ +#include "gbuffer.h" + +void gbuffer_copy_subrect(Glyph* src, Glyph* dest, Usz src_height, + Usz src_width, Usz dest_height, Usz dest_width, + Usz src_y, Usz src_x, Usz dest_y, Usz dest_x, + Usz height, Usz width) { + if (src_height <= src_y || src_width <= src_x || dest_height <= dest_y || + dest_width <= dest_x) + return; + Usz ny_0 = src_height - src_y; + Usz ny_1 = dest_height - dest_y; + Usz ny = height; + if (ny_0 < ny) + ny = ny_0; + if (ny_1 < ny) + ny = ny_1; + if (ny == 0) + return; + Usz row_copy_0 = src_width - src_x; + Usz row_copy_1 = dest_width - dest_x; + Usz row_copy = width; + if (row_copy_0 < row_copy) + row_copy = row_copy_0; + if (row_copy_1 < row_copy) + row_copy = row_copy_1; + Usz copy_bytes = row_copy * sizeof(Glyph); + Glyph* src_p = src + src_y * src_width + src_x; + Glyph* dest_p = dest + dest_y * dest_width + dest_x; + Usz src_stride; + Usz dest_stride; + if (src_y >= dest_y) { + src_stride = src_width; + dest_stride = dest_width; + } else { + src_p += (ny - 1) * src_width; + dest_p += (ny - 1) * dest_width; + src_stride = -src_width; + dest_stride = -dest_width; + } + Usz iy = 0; + for (;;) { + memmove(dest_p, src_p, copy_bytes); + ++iy; + if (iy == ny) + break; + src_p += src_stride; + dest_p += dest_stride; + } +} diff --git a/gbuffer.h b/gbuffer.h index 03f65bd..6836c17 100644 --- a/gbuffer.h +++ b/gbuffer.h @@ -34,3 +34,9 @@ static inline void gbuffer_poke_relative(Gbuffer gbuf, Usz height, Usz width, return; gbuf[(Usz)y0 * width + (Usz)x0] = g; } + +ORCA_FORCE_NO_INLINE +void gbuffer_copy_subrect(Glyph* src, Glyph* dest, Usz src_grid_h, + Usz src_grid_w, Usz dest_grid_h, Usz dest_grid_w, + Usz src_y, Usz src_x, Usz dest_y, Usz dest_x, + Usz height, Usz width); diff --git a/tool b/tool index 2e7c6fc..b997cd9 100755 --- a/tool +++ b/tool @@ -219,7 +219,7 @@ build_target() { x86_64) add cc_flags -march=nehalem;; esac - add source_files field.c mark.c bank.c sim.c + add source_files gbuffer.c field.c mark.c bank.c sim.c case "$2" in orca|cli) add source_files cli_main.c