array macros

main
Patrick Cleavelin 2024-03-16 17:05:23 -05:00
parent 11a53fa087
commit 92aa0af44c
3 changed files with 56 additions and 42 deletions

34
src/ed_array.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef ED_ARRAY_INCLUDED
#define ED_ARRAY_INCLUDED
#include <stdlib.h>
#include <assert.h>
#define array(T) struct T ## Array
#define arrayTemplate(T) array(T) {\
size_t size, capacity;\
T *data;\
};\
array(T) T ## ArrayConstruct(size_t size) {\
array(T) this;\
this.size = 0;\
this.capacity = size;\
this.data = malloc(size * sizeof(T));\
if (!this.data) {\
assert("failed to allocate memory for array");\
}\
return this;\
};\
void T ## PushArray(array(T) *arr, T value) {\
if (arr->size+1 <= arr->capacity) {\
arr->data[arr->size] = value;\
arr->size += 1;\
} else {\
// TODO: resize array
fprintf(stderr, "failed to push to u8 array, size+num > capacity\n");\
}\
};
#define newArray(T, size) T ## ArrayConstruct(size)
#define pushArray(T, arr, value) T ## PushArray(arr, (value))
#endif

View File

@ -32,6 +32,7 @@
#include "string.h"
#include "ht.h"
#include "ui.h"
#include "ed_array.h"
// static Arena default_arena = {0};
@ -49,6 +50,7 @@ typedef struct {
float size[2];
float border_size[2];
} GpuUiRect;
arrayTemplate(GpuUiRect);
typedef struct {
float atlas_position[2];
@ -56,38 +58,12 @@ typedef struct {
float position[2];
float y_offset;
} GpuGlyph;
arrayTemplate(GpuGlyph);
typedef struct {
float screen_size[4];
} GpuUniformParams;
typedef struct {
size_t size;
size_t capacity;
uint8_t *data;
} U8Array;
U8Array new_u8array(size_t capacity) {
return (U8Array) {
.size = 0,
.capacity = capacity,
.data = context_alloc(capacity),
};
}
void push_u8array(U8Array *array, uint8_t *items, size_t num) {
if (array->size + num <= array->capacity) {
memcpy(array->data + array->size, items, num);
array->size += num;
} else {
fprintf(stderr, "failed to push to u8 array, size+num > capacity\n");
}
}
void clear_u8array(U8Array *array) {
array->size = 0;
}
static struct {
sg_pass_action pass_action;
sg_pipeline pip;
@ -98,9 +74,9 @@ static struct {
sg_shader_desc scratch_shader_desc;
U8Array gpu_ui_rects;
U8Array gpu_glyphs;
U8Array glyph_cache;
array(GpuUiRect) gpu_ui_rects;
array(GpuGlyph) gpu_glyphs;
array(GpuGlyph) glyph_cache;
bool should_exit;
@ -111,13 +87,14 @@ void queue_text(string text, float position[2]) {
float x = 0;
for (size_t i=0; i < text.len; ++i) {
if (text.data[i] >= 32) {
GpuGlyph glyph = *((GpuGlyph *)(state.glyph_cache.data+((text.data[i] - 32) * sizeof(GpuGlyph))));
//GpuGlyph glyph = *((GpuGlyph *)(state.glyph_cache.data+((text.data[i] - 32) * sizeof(GpuGlyph))));
GpuGlyph glyph = state.glyph_cache.data[text.data[i] - 32];
glyph.position[0] = x+position[0];
glyph.position[1] = position[1];
x += glyph.size[0]/2;
push_u8array(&state.gpu_glyphs, (uint8_t *)(&glyph), sizeof(GpuGlyph));
pushArray(GpuGlyph, &state.gpu_glyphs, glyph);
}
}
}
@ -230,9 +207,9 @@ void ed_init() {
const int rasterized_font_height = 64;
uint8_t *font_bitmap = context_alloc(font_bitmap_size*font_bitmap_size * sizeof(uint8_t));
state.gpu_ui_rects = new_u8array(sizeof(GpuUiRect) * 2000);
state.gpu_glyphs = new_u8array(sizeof(GpuGlyph) * 1024);
state.glyph_cache = new_u8array(sizeof(GpuGlyph) * 97);
state.gpu_ui_rects = newArray(GpuUiRect, 2000);
state.gpu_glyphs = newArray(GpuGlyph, 1024);
state.glyph_cache = newArray(GpuGlyph, 97);
int ascent, descent, line_gap;
float scale = stbtt_ScaleForPixelHeight(&font, rasterized_font_height);
@ -244,12 +221,12 @@ void ed_init() {
}
}
// manually add glyph for SPACE
push_u8array(&state.glyph_cache, (uint8_t *)(&(GpuGlyph){
pushArray(GpuGlyph, &state.glyph_cache, ((GpuGlyph){
.atlas_position = { 0 },
.size = { rasterized_font_height/4, rasterized_font_height },
.position = { 0 },
.y_offset = -rasterized_font_height,
}), 1 * sizeof(GpuGlyph));
}));
int x = rasterized_font_height/4;
int y = 0;
@ -274,18 +251,18 @@ void ed_init() {
xxx += 1;
}
push_u8array(&state.glyph_cache, (uint8_t *)(&(GpuGlyph){
pushArray(GpuGlyph, &state.glyph_cache, ((GpuGlyph){
.atlas_position = { (float)(x), (float)(y) },
.size = { (float)width, (float)height },
.position = { (float)x, (float)y },
.y_offset = (float)(yoff),
}), 1 * sizeof(GpuGlyph));
}));
x += width;
}
state.bind.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc) {
.size = state.gpu_glyphs.capacity,
.size = state.gpu_glyphs.capacity * sizeof(GpuGlyph),
.usage = SG_USAGE_STREAM,
.label = "glyph buffer"
});
@ -354,7 +331,7 @@ void ed_frame() {
if (state.gpu_glyphs.size > 0) {
sg_update_buffer(state.bind.vertex_buffers[1], &(sg_range) {
.ptr = state.gpu_glyphs.data,
.size = state.gpu_glyphs.size
.size = state.gpu_glyphs.size * sizeof(GpuGlyph)
});
}
@ -372,7 +349,7 @@ void ed_frame() {
sg_apply_pipeline(state.pip);
sg_apply_bindings(&state.bind);
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, &(sg_range) { .ptr = &gpu_uniform_params, .size = sizeof(GpuUniformParams) });
sg_draw(0, 6, state.gpu_glyphs.size/sizeof(GpuGlyph));
sg_draw(0, 6, state.gpu_glyphs.size);
}
sg_end_pass();
sg_commit();

View File

@ -8,6 +8,7 @@
#include <stdbool.h>
#include "ht.h"
#include "ed_array.h"
typedef enum {
UI_AXIS_HORIZONTAL,
@ -71,9 +72,11 @@ typedef struct {
size_t prev;
size_t parent;
} ui_element_frame_data;
arrayTemplate(ui_element_frame_data);
typedef struct {
ed_ht cached_elements;
array(ui_element_frame_data) frame_elements;
} ui_context;