summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2024-12-31 23:38:11 +1100
committerquou <quou@disroot.org>2024-12-31 23:38:11 +1100
commit96b27fe9841e537614962e273ef9f0802365ea6d (patch)
treed1373862f700a83dd476555913b50c969159a836
parentae7824be86ecc53752a3bee1038c0677ac203cf7 (diff)
ui stuf and things hmm m mmm m シ
-rw-r--r--app.cpp4
-rw-r--r--app.hpp3
-rw-r--r--c2.cpp9
-rw-r--r--debugger.cpp34
-rw-r--r--qstd/Makefile2
-rw-r--r--qstd/plat.c40
-rw-r--r--qstd/plat.h5
-rw-r--r--ui.cpp97
-rw-r--r--ui.hpp5
9 files changed, 166 insertions, 33 deletions
diff --git a/app.cpp b/app.cpp
index 95f730b..0f57a71 100644
--- a/app.cpp
+++ b/app.cpp
@@ -515,6 +515,7 @@ int WinMain(
#endif
void App::init(const char* name) {
+ dt = 0.0f;
internal = (App_Internal*)arena_alloc(
arena,
sizeof *internal
@@ -536,6 +537,7 @@ void App::destroy() {
void App::begin() {
int j;
+ begin_t = get_time();
for (j = 0; j < key_count; j++)
key_states[j] &= ~(
key_state_just_pressed | key_state_just_released
@@ -548,6 +550,8 @@ void App::begin() {
}
void App::end() {
+ end_t = get_time();
+ dt = (float)((double)(end_t - begin_t) / 1000000000.0);
internal->end(this);
}
diff --git a/app.hpp b/app.hpp
index 3e2ef23..9a660cf 100644
--- a/app.hpp
+++ b/app.hpp
@@ -4,6 +4,7 @@
#define app_memory_size (1024 * 1024 * 32)
#include <new>
+#include <stdint.h>
struct Arena;
@@ -102,11 +103,13 @@ struct App_Internal;
struct App {
Arena* arena;
+ float dt;
int running, w, h;
int mx, my;
int scrollx, scrolly;
unsigned char key_states[key_count];
unsigned char mbtn_states[mbtn_count];
+ uint64_t begin_t, end_t;
App_Internal* internal;
template <typename T>
diff --git a/c2.cpp b/c2.cpp
index d356ada..fb2aa38 100644
--- a/c2.cpp
+++ b/c2.cpp
@@ -9,6 +9,7 @@ extern "C" {
}
#include <string.h>
#include <math.h>
+#include <stdio.h>
#define video_arena_size (1024 * 1024 * 16)
#define asset_arena_size (1024 * 1024 * 4)
@@ -138,6 +139,7 @@ extern "C" int entrypoint() {
ui->layout(app->w, app->h);
auto toolbar = ui->create_element<UI::Toolbar>(ui->root);
register_debuggers(ui, toolbar);
+ auto fps_label = ui->create_element<UI::Label>(ui->root, "");
while (app->running) {
Arena frame_arena;
init_arena(&frame_arena, per_frame, per_frame_memory_size);
@@ -145,6 +147,11 @@ extern "C" int entrypoint() {
app->begin();
dev->begin_frame();
+ if (frame % 10 == 0) {
+ char buf[32];
+ sprintf(buf, "FPS: %g", 1.0f / app->dt);
+ fps_label->set_text(buf);
+ }
ui->update(&frame_arena);
{
@@ -246,7 +253,7 @@ extern "C" int entrypoint() {
ctx.debug_pop();
r += 10;
- rot += 0.05f;
+ rot += 5.0f * app->dt;
frame++;
dev->present();
app->end();
diff --git a/debugger.cpp b/debugger.cpp
index 6a71e15..6cda856 100644
--- a/debugger.cpp
+++ b/debugger.cpp
@@ -11,6 +11,14 @@ struct Vram_Debugger : UI::Modal {
}
};
+struct Device_Debugger : UI::Modal {
+ UI::Element* enable_btn;
+
+ Device_Debugger(UI* ui, UI::Element* parent):
+ UI::Modal(ui, parent, "Device debugger") {
+ }
+};
+
void create_vram_debugger(
UI* ui,
UI::Element* parent,
@@ -28,6 +36,23 @@ void create_vram_debugger(
ui->create_element<UI::Label>(window->contents, "Hello, I'm the VRAM debugger!");
}
+void create_device_debugger(
+ UI* ui,
+ UI::Element* parent,
+ UI::Element* button
+) {
+ auto window = ui->create_element<Device_Debugger>(parent);
+ window->enable_btn = button;
+ window->handler = [](UI::Element* e, const UI::Message& m) {
+ if (m.type == UI::Message::Type::destroy) {
+ auto window = (Device_Debugger*)e;
+ window->enable_btn->enable();
+ }
+ return 0;
+ };
+ ui->create_element<UI::Label>(window->contents, "Hello, I'm the device debugger!");
+}
+
void register_debuggers(UI* ui, UI::Toolbar* toolbar) {
auto btnvram = ui->create_element<UI::Button>(toolbar, "VRAM Debugger");
btnvram->handler = [](UI::Element* e, const UI::Message& m) {
@@ -37,4 +62,13 @@ void register_debuggers(UI* ui, UI::Toolbar* toolbar) {
}
return 0;
};
+ auto btndevice = ui->create_element<UI::Button>(toolbar, "Device Debugger");
+ btndevice->handler = [](UI::Element* e, const UI::Message& m) {
+ if (m.type == UI::Message::Type::click) {
+ e->disable();
+ create_device_debugger(e->ui, e->ui->root, e);
+ }
+ return 0;
+ };
}
+
diff --git a/qstd/Makefile b/qstd/Makefile
index c4b088b..7e3f0f1 100644
--- a/qstd/Makefile
+++ b/qstd/Makefile
@@ -2,7 +2,7 @@
target = libqstd.a
includes = -I../qstd
defines = -Dplat_x86 -Dplat_posix -Dallocation_default_alignment=8
-cflags = -std=c90 -pedantic -Wall -Wextra $(DEBUG_COMPILE_FLAG) $(includes) $(defines)
+cflags = -std=gnu90 -pedantic -Wall -Wextra $(DEBUG_COMPILE_FLAG) $(includes) $(defines)
lflags = $(DEBUG_LINK_FLAG)
objects = plat.o memory.o str.o pack.o
diff --git a/qstd/plat.c b/qstd/plat.c
index 7f07b96..15e0265 100644
--- a/qstd/plat.c
+++ b/qstd/plat.c
@@ -1,15 +1,21 @@
#include "plat.h"
#ifdef plat_posix
+#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE
+#endif
+#ifndef _GNU_SOURCE
#define _GNU_SOURCE
+#endif
+#include <aio.h>
#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
+#include <sys/types.h>
#include <time.h>
-#include <stdarg.h>
-#include <stdio.h>
extern int isatty(int);
extern int fileno(FILE*);
@@ -83,6 +89,34 @@ void pbreak(int code) {
#endif
}
+static clockid_t global_clock;
+static unsigned long global_freq;
+static int time_init = 0;
+
+void init_timer(void) {
+ struct timespec ts;
+ global_clock = CLOCK_REALTIME;
+ global_freq = 1000000000;
+ time_init = 1;
+#if defined(_POSIX_MONOTONIC_CLOCK)
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
+ global_clock = CLOCK_MONOTONIC;
+ }
+#else
+ (void)ts;
+#endif
+}
+
+uint64_t get_time(void) {
+ struct timespec ts;
+ if (!time_init)
+ init_timer();
+ clock_gettime(global_clock, &ts);
+ return
+ (uint64_t)ts.tv_sec * global_freq +
+ (uint64_t)ts.tv_nsec;
+}
+
#endif
#ifdef plat_win
@@ -153,4 +187,4 @@ void pbreak(int code) {
}
-#endif \ No newline at end of file
+#endif
diff --git a/qstd/plat.h b/qstd/plat.h
index 27521fa..b3715a3 100644
--- a/qstd/plat.h
+++ b/qstd/plat.h
@@ -1,6 +1,8 @@
#ifndef plat_h
#define plat_h
+#include <stdint.h>
+
#ifdef assert
#undef assert
#endif
@@ -29,4 +31,7 @@ void print_err(const char* fmt, ...);
void print_war(const char* fmt, ...);
void pbreak(int code);
+uint64_t get_time(void);
+
+
#endif
diff --git a/ui.cpp b/ui.cpp
index 2ed1c7b..8a292c7 100644
--- a/ui.cpp
+++ b/ui.cpp
@@ -644,7 +644,7 @@ UI::Element* UI::alloc_element(size_t size) {
UI::Element::Element(UI* ui, Element* parent):
ui(ui),
- parent(parent),
+ parent(0),
children(0),
next(0),
handler(0),
@@ -723,6 +723,8 @@ void UI::Element::enable() {
}
void UI::Element::add_child(Element* ch) {
+ assert(ch->parent == 0);
+ assert(ch->next == 0);
if (!children)
children = ch;
else {
@@ -730,6 +732,7 @@ void UI::Element::add_child(Element* ch) {
for (; child && child->next; child = child->next);
child->next = ch;
}
+ ch->parent = this;
ui->layout_dirty = true;
}
@@ -743,6 +746,8 @@ void UI::Element::remove_child(Element* ch) {
prev->next = ch->next;
else
children = ch->next;
+ ch->next = 0;
+ ch->parent = 0;
}
void UI::Element::message(const Message& msg) {
@@ -760,8 +765,6 @@ UI::Rect UI::Container::layout(const Rect& avail) {
Rect used = avail;
used.w = used.h = 0;
bound = avail;
- clip = avail;
- clip.clip(ui->area);
for (child = children; child; child = child->next) {
int h;
Rect r = child->layout(area);
@@ -772,7 +775,17 @@ UI::Rect UI::Container::layout(const Rect& avail) {
used.h += h;
}
bound = used;
- return used;
+ bound.clip(avail);
+ clip = bound;
+ clip.clip(ui->area);
+ if (clip.x == 0 && clip.y == 0 && clip.w == 300 && clip.h == 80) {
+ return bound;
+ }
+ return bound;
+}
+
+void UI::Container::on_render() {
+ ui->mesh.set_clip(clip);
}
UI::Toolbar::Toolbar(UI* ui, Element* parent):
@@ -801,12 +814,8 @@ UI::Rect UI::Toolbar::layout(const Rect& avail) {
void UI::Toolbar::on_render() {
ui->mesh.set_clip(clip);
- ui->mesh.add_rect(
- ui,
- bound.x,
- bound.y,
- bound.w,
- bound.h,
+ ui->draw_container(
+ bound,
0xa7a7a7
);
}
@@ -837,19 +846,20 @@ UI::Rect UI::Button::layout(const Rect& avail) {
void UI::Button::on_render() {
Colour tc = 0x000000;
+ int toff[] = { 0, 0 };
if (flags & Flags::disabled)
tc = 0x4f4f4f;
- if (this == ui->hovered)
- ui->draw_container(bound, 0xf0f8ff);
- else if (this == ui->hot)
+ if (this == ui->hot) {
+ toff[0] = 1;
+ toff[1] = 1;
ui->draw_containeri(bound, 0xffffff);
- else
+ } else
ui->draw_container(bound, 0xffffff);
ui->mesh.set_clip(clip);
ui->mesh.add_text(
ui,
- bound.x + ui_padding,
- bound.y + ui_padding,
+ bound.x + ui_padding + toff[0],
+ bound.y + ui_padding + toff[1],
text,
tc
);
@@ -890,30 +900,43 @@ void UI::Label::on_render() {
);
}
-static int drag_handler(UI::Modal* modal, const UI::Message& msg) {
- if (msg.type == UI::Message::Type::activate) {
- const App& app = *modal->ui->app;
- const UI::Rect& tb = modal->title_bar->bound;
- modal->dragging = true;
- modal->drag_offset[0] = app.mx - tb.x;
- modal->drag_offset[1] = app.my - tb.y;
+void UI::Label::set_text(const char* s) {
+ heap_free(ui->heap, text);
+ text = dup_stringh(ui->heap, s);
+ ui->layout_dirty = 1;
+}
+
+static int title_handler(UI::Modal* modal, const UI::Message& msg) {
+ switch (msg.type) {
+ case UI::Message::Type::activate: {
+ const App& app = *modal->ui->app;
+ const UI::Rect& tb = modal->title_bar->bound;
+ modal->dragging = true;
+ modal->drag_offset[0] = app.mx - tb.x;
+ modal->drag_offset[1] = app.my - tb.y;
+ modal->bring_to_front();
+ } break;
+ case UI::Message::Type::deactivate:
+ modal->dragging = false;
+ break;
+ default: return 0;
}
- if (msg.type == UI::Message::Type::deactivate)
- modal->dragging = false;
return 0;
};
UI::Modal::Modal(UI* ui, Element* parent, const char* text):
Element(ui, parent), dragging(false) {
+ pos[0] = 0;
+ pos[1] = 0;
contents = ui->create_element<Container>(this);
title_bar = ui->create_element<Toolbar>(contents);
title_bar->handler = [](Element* e, const Message& m) {
- return drag_handler((Modal*)e->parent->parent, m);
+ return title_handler((Modal*)e->parent->parent, m);
};
close = ui->create_element<Button>(title_bar, "x");
title = ui->create_element<Label>(title_bar, text);
title->handler = [](Element* e, const Message& m) {
- return drag_handler((Modal*)e->parent->parent->parent, m);
+ return title_handler((Modal*)e->parent->parent->parent, m);
};
close->handler = [](Element* e, const Message& m) {
if (m.type == Message::Type::click)
@@ -923,15 +946,25 @@ UI::Modal::Modal(UI* ui, Element* parent, const char* text):
}
UI::Rect UI::Modal::layout(const Rect& avail) {
- UI::Rect content_size = contents->layout(avail);
+ Rect r = avail;
+ if (pos[0] && pos[1]) {
+ r.x = pos[0];
+ r.y = pos[1];
+ }
+ UI::Rect content_size = contents->layout(r);
title_bar->layout(content_size);
bound = content_size;
clip = content_size;
clip.clip(ui->area);
+ if (!pos[0] && !pos[1]) {
+ pos[0] = bound.x;
+ pos[1] = bound.y;
+ }
return content_size;
}
void UI::Modal::on_render() {
+ ui->mesh.set_clip(clip);
ui->draw_container(
contents->bound,
Colour(0xffffff, 0x80)
@@ -944,6 +977,14 @@ void UI::Modal::on_update() {
Rect avail = bound;
avail.x = app.mx - drag_offset[0];
avail.y = app.my - drag_offset[1];
+ pos[0] = avail.x;
+ pos[1] = avail.y;
layout(avail);
}
}
+
+void UI::Modal::bring_to_front() {
+ Element* p = parent;
+ p->remove_child(this);
+ p->add_child(this);
+}
diff --git a/ui.hpp b/ui.hpp
index c11cd8f..adb1ba8 100644
--- a/ui.hpp
+++ b/ui.hpp
@@ -194,6 +194,7 @@ struct UI {
Container(UI* ui, Element* parent);
Rect layout(const Rect& avail) override;
+ void on_render() override;
};
struct Toolbar : Element {
@@ -217,6 +218,8 @@ struct UI {
~Label();
Rect layout(const Rect& avail) override;
void on_render() override;
+
+ void set_text(const char* s);
};
struct Modal : Element {
@@ -225,11 +228,13 @@ struct UI {
Label* title;
Button* close;
int drag_offset[2];
+ int pos[2];
bool dragging;
Modal(UI* ui, Element* parent, const char* title);
Rect layout(const Rect& avail) override;
void on_render() override;
void on_update() override;
+ void bring_to_front();
};
};