summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/julia_set.c7
-rw-r--r--examples/ui.c7
-rwxr-xr-xreduced_system_layer.c156
3 files changed, 133 insertions, 37 deletions
diff --git a/examples/julia_set.c b/examples/julia_set.c
index 26e7a7a..90e4b45 100644
--- a/examples/julia_set.c
+++ b/examples/julia_set.c
@@ -82,9 +82,10 @@ i32 main(i32 argc, c8 **argv) {
(void) argv;
g_platform = (Platform) {
- .title = "Julia Set",
- .frame_width = 960,
- .frame_height = 720,
+ .title = "Julia Set",
+ .frame_width = 960,
+ .frame_height = 720,
+ .exact_resolution = 1,
};
time_0 = p_time();
diff --git a/examples/ui.c b/examples/ui.c
index 684b428..389e2b4 100644
--- a/examples/ui.c
+++ b/examples/ui.c
@@ -216,9 +216,10 @@ i32 main(i32 argc, c8 **argv) {
(void) argv;
g_platform = (Platform) {
- .title = "UI",
- .frame_width = 960,
- .frame_height = 720,
+ .title = "UI",
+ .frame_width = 960,
+ .frame_height = 720,
+ .exact_resolution = 1,
};
p_event_loop();
diff --git a/reduced_system_layer.c b/reduced_system_layer.c
index af49453..9eabca9 100755
--- a/reduced_system_layer.c
+++ b/reduced_system_layer.c
@@ -44,6 +44,7 @@
#/ - Networking
#/ - Windows sockets
#/ - Graphics
+#/ - Relative coordinates
#/ - Self-contained impl
#/ - UI
#/ - Icons
@@ -73,6 +74,7 @@
#/ - Testing
#/ - Graphics
#/ - Font
+#/ - Adaptive resolution
#/
#/ ----------------------------------------------------------------
#/
@@ -169,11 +171,15 @@ extern "C" {
#endif
enum {
- MAX_NUM_PIXELS = 10 * 1024 * 1024,
- MAX_INPUT_SIZE = 256,
- MAX_CLIPBOARD_SIZE = 10 * 1024 * 1024,
- MAX_NUM_SOCKETS = 64,
- MAX_NUM_KEYS = 512,
+ MAX_NUM_PIXELS = 10 * 1024 * 1024,
+ MAX_INPUT_SIZE = 256,
+ MAX_CLIPBOARD_SIZE = 10 * 1024 * 1024,
+ MAX_NUM_SOCKETS = 64,
+ MAX_NUM_KEYS = 512,
+ MAX_PIXEL_SIZE = 16,
+
+ MIN_FRAME_DURATION = 9,
+ MAX_FRAME_DURATION = 38,
AUDIO_NUM_CHANNELS = 2,
AUDIO_SAMPLE_RATE = 44100,
@@ -331,6 +337,7 @@ typedef struct {
i64 clipboard_size;
c8 * clipboard;
b8 done;
+ b8 exact_resolution; // TODO
b8 graceful_exit;
b8 has_focus;
b8 has_cursor;
@@ -488,8 +495,6 @@ i32 main(i32 argc, c8 **argv) {
Platform g_platform = {0};
void p_event_loop(void) {
- (void) sqrt; // For the compiler.
-
p_init();
#if !defined(__wasm__)
while (!g_platform.done) update_and_render_frame();
@@ -1064,7 +1069,10 @@ void p_queue_sound(i64 delay_in_samples, i64 num_samples, f32 *frames) {
static i16 _key_table[MAX_NUM_KEYS] = {0};
static b8 _key_repeat[MAX_NUM_KEYS] = {0};
+static i64 _frame_time = 0;
static vec3_f32 _pixels[MAX_NUM_PIXELS] = {0};
+static i32 _pixel_size = 0;
+static u32 _pixels_scaled[MAX_NUM_PIXELS] = {0};
static u32 _pixels_internal[MAX_NUM_PIXELS] = {0};
static Input_Key _input[MAX_INPUT_SIZE] = {0};
static c8 _clipboard_buffer[MAX_CLIPBOARD_SIZE] = {0};
@@ -1246,7 +1254,7 @@ void p_init(void) {
.bitmap_bit_order = LSBFirst,
.bitmap_pad = 32,
.bits_per_pixel = 32,
- .bytes_per_line = 4 * g_platform.frame_width,
+ .bytes_per_line = _image.width * 4,
.red_mask = 0xff0000,
.green_mask = 0x00ff00,
.blue_mask = 0x0000ff,
@@ -1267,7 +1275,7 @@ void p_init(void) {
XMapWindow(_display, _window);
- XPutImage(_display, _window, _gc, &_image, 0, 0, 0, 0, g_platform.frame_width, g_platform.frame_height);
+ XPutImage(_display, _window, _gc, &_image, 0, 0, 0, 0, _image.width, _image.height);
XFlush(_display);
}
@@ -1291,6 +1299,8 @@ i32 p_handle_events(void) {
if (_display == NULL)
return 0;
+ _frame_time = p_time();
+
i32 num_events = 0;
memset(g_platform.key_pressed, 0, sizeof g_platform.key_pressed);
@@ -1550,15 +1560,26 @@ i32 p_handle_events(void) {
XWindowAttributes attrs;
XGetWindowAttributes(_display, _window, &attrs);
- if ((g_platform.frame_width != attrs.width || g_platform.frame_height != attrs.height) && attrs.width * attrs.height * 4 <= (i32) sizeof _pixels_internal) {
- if (attrs.width > 0 && attrs.height > 0) {
- _image.width = attrs.width;
- _image.height = attrs.height;
- _image.bytes_per_line = 4 * attrs.width;
+ if (attrs.width > 0 && attrs.height > 0 && attrs.width * attrs.height <= MAX_NUM_PIXELS) {
+ _image.width = attrs.width;
+ _image.height = attrs.height;
+ _image.bytes_per_line = _image.width * 4;
+
+ i32 width = _image.width;
+ i32 height = _image.height;
+
+ if (_pixel_size <= 1)
+ _pixel_size = 1;
+ else {
+ width = (i32) floor(((f64) _image.width) / _pixel_size + .5);
+ height = (i32) floor(((f64) _image.height) / _pixel_size + .5);
}
- g_platform.frame_width = attrs.width;
- g_platform.frame_height = attrs.height;
+ if (g_platform.frame_width != width || g_platform.frame_height != height) {
+ ++num_events;
+ g_platform.frame_width = width;
+ g_platform.frame_height = height;
+ }
}
return num_events;
@@ -1567,10 +1588,12 @@ i32 p_handle_events(void) {
i32 p_wait_events(void) {
i32 num_events = 0;
- do {
+ for (;;) {
num_events = p_handle_events();
+ if (num_events != 0)
+ break;
usleep(0);
- } while (num_events == 0);
+ }
return num_events;
}
@@ -1579,12 +1602,35 @@ void p_render_frame(void) {
if (g_platform.done)
return;
- i64 size = g_platform.frame_width * g_platform.frame_height;
- for (i64 i = 0; i < size; ++i)
- _pixels_internal[i] = rgb_u32_from_f32(_pixels[i]);
+ if (g_platform.frame_width == _image.width && g_platform.frame_height == _image.height) {
+ i64 size = g_platform.frame_width * g_platform.frame_height;
+ for (i64 i = 0; i < size; ++i)
+ _pixels_internal[i] = rgb_u32_from_f32(_pixels[i]);
+ } else {
+ i64 size = g_platform.frame_width * g_platform.frame_height;
+ for (i64 i = 0; i < size; ++i)
+ _pixels_scaled[i] = rgb_u32_from_f32(_pixels[i]);
+
+ for (i64 j = 0; j < _image.height; ++j) {
+ i64 j0 = (j * g_platform.frame_height) / _image.height;
+ for (i64 i = 0; i < _image.width; ++i) {
+ i64 i0 = (i * g_platform.frame_width) / _image.width;
+ _pixels_internal[j * _image.width + i] = _pixels_scaled[j0 * g_platform.frame_width + i0];
+ }
+ }
+ }
- XPutImage(_display, _window, _gc, &_image, 0, 0, 0, 0, g_platform.frame_width, g_platform.frame_height);
+ XPutImage(_display, _window, _gc, &_image, 0, 0, 0, 0, _image.width, _image.height);
XFlush(_display);
+
+ if (!g_platform.exact_resolution) {
+ i64 frame_duration = p_time() - _frame_time;
+
+ if (_pixel_size < MAX_PIXEL_SIZE && frame_duration > MAX_FRAME_DURATION)
+ ++_pixel_size;
+ else if (_pixel_size > 1 && frame_duration < MIN_FRAME_DURATION)
+ --_pixel_size;
+ }
}
void p_clipboard_write(i64 size, c8 *data) {
@@ -1610,7 +1656,11 @@ void p_clipboard_write(i64 size, c8 *data) {
#ifdef __wasm__
+static i32 _frame_width = 0;
+static i32 _frame_height = 0;
static vec3_f32 _pixels[MAX_NUM_PIXELS] = {0};
+static i32 _pixel_size = 0;
+static u32 _pixels_scaled[MAX_NUM_PIXELS] = {0};
static u32 _pixels_internal[MAX_NUM_PIXELS] = {0};
static Input_Key _input[MAX_INPUT_SIZE] = {0};
static c8 _clipboard_buffer[MAX_CLIPBOARD_SIZE] = {0};
@@ -1645,11 +1695,13 @@ void p_init(void) {
i32 p_handle_events(void) {
g_platform.input_size = _input_size;
- _input_size = 0;
+ _input_size = 0;
+
for (i64 i = 0; i < MAX_NUM_KEYS; ++i)
g_platform.key_pressed[i] = _key_pressed[i];
for (i64 i = 0; i < MAX_NUM_KEYS; ++i)
_key_pressed[i] = 0;
+
i32 n = _num_events;
_num_events = 0;
return n;
@@ -1662,9 +1714,23 @@ i32 p_wait_events(void) {
}
void p_render_frame(void) {
- i64 size = g_platform.frame_width * g_platform.frame_height;
- for (i64 i = 0; i < size; ++i)
- _pixels_internal[i] = 0xff000000u | rgb_u32_from_f32(_pixels[i]);
+ if (_frame_width == g_platform.frame_width && _frame_height == g_platform.frame_height) {
+ i64 size = g_platform.frame_width * g_platform.frame_height;
+ for (i64 i = 0; i < size; ++i)
+ _pixels_internal[i] = 0xff000000u | rgb_u32_from_f32(_pixels[i]);
+ } else {
+ i64 size = g_platform.frame_width * g_platform.frame_height;
+ for (i64 i = 0; i < size; ++i)
+ _pixels_scaled[i] = rgb_u32_from_f32(_pixels[i]);
+
+ for (i64 j = 0; j < _frame_height; ++j) {
+ i64 j0 = (j * g_platform.frame_height) / _frame_height;
+ for (i64 i = 0; i < _frame_width; ++i) {
+ i64 i0 = (i * g_platform.frame_width) / _frame_width;
+ _pixels_internal[j * _frame_width + i] = 0xff000000u | _pixels_scaled[j0 * g_platform.frame_width + i0];
+ }
+ }
+ }
}
void p_clipboard_write_impl(i32 size, c8 *data);
@@ -1735,15 +1801,34 @@ __attribute__((export_name("js_pixels"))) void *js_pixels(void) {
}
__attribute__((export_name("js_frame"))) void js_frame(i32 frame_width, i32 frame_height, i32 num_samples) {
- if (g_platform.frame_width != frame_width || g_platform.frame_height != frame_height) {
- ++_num_events;
- g_platform.frame_width = frame_width;
- g_platform.frame_height = frame_height;
+ i64 frame_time = p_time();
+
+ if (frame_width > 0 && frame_height > 0 && frame_width * frame_height <= MAX_NUM_PIXELS) {
+ _frame_width = frame_width;
+ _frame_height = frame_height;
+
+ i32 width = _frame_width;
+ i32 height = _frame_height;
+
+ if (_pixel_size <= 1)
+ _pixel_size = 1;
+ else {
+ width = (i32) floor(((f64) _frame_width) / _pixel_size + .5);
+ height = (i32) floor(((f64) _frame_height) / _pixel_size + .5);
+ }
+
+ if (g_platform.frame_width != width || g_platform.frame_height != height) {
+ ++_num_events;
+ g_platform.frame_width = width;
+ g_platform.frame_height = height;
+ }
}
g_platform.done = 0;
- if (_num_events > 0 || !_wait_events) {
+ b8 do_render = _num_events > 0 || !_wait_events;
+
+ if (do_render) {
_wait_events = 0;
update_and_render_frame();
}
@@ -1757,6 +1842,15 @@ __attribute__((export_name("js_frame"))) void js_frame(i32 frame_width, i32 fram
}
_sound_read = (_sound_read + num_samples * AUDIO_NUM_CHANNELS) % MAX_NUM_AUDIO_FRAMES;
+
+ if (!g_platform.exact_resolution && do_render) {
+ i64 frame_duration = p_time() - frame_time;
+
+ if (_pixel_size < MAX_PIXEL_SIZE && frame_duration > MAX_FRAME_DURATION)
+ ++_pixel_size;
+ else if (_pixel_size > 1 && frame_duration < MIN_FRAME_DURATION)
+ --_pixel_size;
+ }
}
__attribute__((export_name("js_mousemove"))) void js_mousemove(i32 x, i32 y) {