ref: d0c3b97a8073e70f3ef3e685bd71cb115d0c2daa
parent: fdb138f5a1fe8f5fa9be3f9340c62fa5b0eacc6a
author: cancel <cancel@cancel.fm>
date: Wed Dec 5 12:43:35 EST 2018
Add WIP timing stuff
--- /dev/null
+++ b/thirdparty/sokol_time.h
@@ -1,0 +1,228 @@
+#pragma once
+/*
+ sokol_time.h -- simple cross-platform time measurement
+
+ Do this:
+ #define SOKOL_IMPL
+ before you include this file in *one* C or C++ file to create the
+ implementation.
+
+ Optionally provide the following defines with your own implementations:
+ SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
+ SOKOL_API_DECL - public function declaration prefix (default: extern)
+ SOKOL_API_IMPL - public function implementation prefix (default: -)
+
+ void stm_setup();
+ Call once before any other functions to initialize sokol_time
+ (this calls for instance QueryPerformanceFrequency on Windows)
+
+ uint64_t stm_now();
+ Get current point in time in unspecified 'ticks'. The value that
+ is returned has no relation to the 'wall-clock' time and is
+ not in a specific time unit, it is only useful to compute
+ time differences.
+
+ uint64_t stm_diff(uint64_t new, uint64_t old);
+ Computes the time difference between new and old. This will always
+ return a positive, non-zero value.
+
+ uint64_t stm_since(uint64_t start);
+ Takes the current time, and returns the elapsed time since start
+ (this is a shortcut for "stm_diff(stm_now(), start)")
+
+ uint64_t stm_laptime(uint64_t* last_time);
+ This is useful for measuring frame time and other recurring
+ events. It takes the current time, returns the time difference
+ to the value in last_time, and stores the current time in
+ last_time for the next call. If the value in last_time is 0,
+ the return value will be zero (this usually happens on the
+ very first call).
+
+ Use the following functions to convert a duration in ticks into
+ useful time units:
+
+ double stm_sec(uint64_t ticks);
+ double stm_ms(uint64_t ticks);
+ double stm_us(uint64_t ticks);
+ double stm_ns(uint64_t ticks);
+ Converts a tick value into seconds, milliseconds, microseconds
+ or nanoseconds. Note that not all platforms will have nanosecond
+ or even microsecond precision.
+
+ Uses the following time measurement functions under the hood:
+
+ Windows: QueryPerformanceFrequency() / QueryPerformanceCounter()
+ MacOS/iOS: mach_absolute_time()
+ emscripten: clock_gettime(CLOCK_MONOTONIC)
+ Linux+others: clock_gettime(CLOCK_MONITONIC)
+
+ zlib/libpng license
+
+ Copyright (c) 2018 Andre Weissflog
+
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the
+ use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software in a
+ product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not
+ be misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source
+ distribution.
+*/
+#include <stdint.h>
+
+#ifndef SOKOL_API_DECL
+ #define SOKOL_API_DECL extern
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SOKOL_API_DECL void stm_setup(void);
+SOKOL_API_DECL uint64_t stm_now(void);
+SOKOL_API_DECL uint64_t stm_diff(uint64_t new_ticks, uint64_t old_ticks);
+SOKOL_API_DECL uint64_t stm_since(uint64_t start_ticks);
+SOKOL_API_DECL uint64_t stm_laptime(uint64_t* last_time);
+SOKOL_API_DECL double stm_sec(uint64_t ticks);
+SOKOL_API_DECL double stm_ms(uint64_t ticks);
+SOKOL_API_DECL double stm_us(uint64_t ticks);
+SOKOL_API_DECL double stm_ns(uint64_t ticks);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+/*-- IMPLEMENTATION ----------------------------------------------------------*/
+#ifdef SOKOL_IMPL
+
+#ifndef SOKOL_API_IMPL
+ #define SOKOL_API_IMPL
+#endif
+#ifndef SOKOL_ASSERT
+ #include <assert.h>
+ #define SOKOL_ASSERT(c) assert(c)
+#endif
+#ifndef _SOKOL_PRIVATE
+ #if defined(__GNUC__)
+ #define _SOKOL_PRIVATE __attribute__((unused)) static
+ #else
+ #define _SOKOL_PRIVATE static
+ #endif
+#endif
+
+static int _stm_initialized;
+#if defined(_WIN32)
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+static LARGE_INTEGER _stm_win_freq;
+static LARGE_INTEGER _stm_win_start;
+#elif defined(__APPLE__) && defined(__MACH__)
+#include <mach/mach_time.h>
+static mach_timebase_info_data_t _stm_osx_timebase;
+static uint64_t _stm_osx_start;
+#else /* anything else, this will need more care for non-Linux platforms */
+#include <time.h>
+static uint64_t _stm_posix_start;
+#endif
+
+/* prevent 64-bit overflow when computing relative timestamp
+ see https://gist.github.com/jspohr/3dc4f00033d79ec5bdaf67bc46c813e3
+*/
+#if defined(_WIN32) || (defined(__APPLE__) && defined(__MACH__))
+_SOKOL_PRIVATE int64_t int64_muldiv(int64_t value, int64_t numer, int64_t denom) {
+ int64_t q = value / denom;
+ int64_t r = value % denom;
+ return q * numer + r * numer / denom;
+}
+#endif
+
+
+SOKOL_API_IMPL void stm_setup(void) {
+ SOKOL_ASSERT(0 == _stm_initialized);
+ _stm_initialized = 1;
+ #if defined(_WIN32)
+ QueryPerformanceFrequency(&_stm_win_freq);
+ QueryPerformanceCounter(&_stm_win_start);
+ #elif defined(__APPLE__) && defined(__MACH__)
+ mach_timebase_info(&_stm_osx_timebase);
+ _stm_osx_start = mach_absolute_time();
+ #else
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ _stm_posix_start = (uint64_t)ts.tv_sec*1000000000 + (uint64_t)ts.tv_nsec;
+ #endif
+}
+
+SOKOL_API_IMPL uint64_t stm_now(void) {
+ SOKOL_ASSERT(_stm_initialized);
+ uint64_t now;
+ #if defined(_WIN32)
+ LARGE_INTEGER qpc_t;
+ QueryPerformanceCounter(&qpc_t);
+ now = int64_muldiv(qpc_t.QuadPart - _stm_win_start.QuadPart, 1000000000, _stm_win_freq.QuadPart);
+ #elif defined(__APPLE__) && defined(__MACH__)
+ const uint64_t mach_now = mach_absolute_time() - _stm_osx_start;
+ now = int64_muldiv(mach_now, _stm_osx_timebase.numer, _stm_osx_timebase.denom);
+ #else
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ now = ((uint64_t)ts.tv_sec*1000000000 + (uint64_t)ts.tv_nsec) - _stm_posix_start;
+ #endif
+ return now;
+}
+
+SOKOL_API_IMPL uint64_t stm_diff(uint64_t new_ticks, uint64_t old_ticks) {
+ if (new_ticks > old_ticks) {
+ return new_ticks - old_ticks;
+ }
+ else {
+ /* FIXME: this should be a value that converts to a non-null double */
+ return 1;
+ }
+}
+
+SOKOL_API_IMPL uint64_t stm_since(uint64_t start_ticks) {
+ return stm_diff(stm_now(), start_ticks);
+}
+
+SOKOL_API_IMPL uint64_t stm_laptime(uint64_t* last_time) {
+ SOKOL_ASSERT(last_time);
+ uint64_t dt = 0;
+ uint64_t now = stm_now();
+ if (0 != *last_time) {
+ dt = stm_diff(now, *last_time);
+ }
+ *last_time = now;
+ return dt;
+}
+
+SOKOL_API_IMPL double stm_sec(uint64_t ticks) {
+ return (double)ticks / 1000000000.0;
+}
+
+SOKOL_API_IMPL double stm_ms(uint64_t ticks) {
+ return (double)ticks / 1000000.0;
+}
+
+SOKOL_API_IMPL double stm_us(uint64_t ticks) {
+ return (double)ticks / 1000.0;
+}
+
+SOKOL_API_IMPL double stm_ns(uint64_t ticks) {
+ return (double)ticks;
+}
+#endif /* SOKOL_IMPL */
+
--- a/tool
+++ b/tool
@@ -231,14 +231,22 @@
# if we ever need newer posix stuff
# add cc_flags -D_POSIX_C_SOURCE=200809L
out_exe=orca
- if [[ $os = mac ]]; then
- # prefer homebrew version of ncurses if installed. Will give us better
- # terminfo, so we can use A_DIM in Terminal.app, etc.
- if [[ -d /usr/local/opt/ncurses ]]; then
- add libraries -L/usr/local/opt/ncurses/lib
- add cc_flags -I/usr/local/opt/ncurses/include
- fi
- fi
+ case $os in
+ mac)
+ # prefer homebrew version of ncurses if installed. Will give us
+ # better terminfo, so we can use A_DIM in Terminal.app, etc.
+ if [[ -d /usr/local/opt/ncurses ]]; then
+ add libraries -L/usr/local/opt/ncurses/lib
+ add cc_flags -I/usr/local/opt/ncurses/include
+ fi
+ # todo mach time stuff for mac
+ ;;
+ *)
+ # librt and high-res posix timers on Linux
+ add libraries -lrt
+ add cc_flags -D_POSIX_C_SOURCE=200809L
+ ;;
+ esac
add libraries -lncurses
# If we wanted wide chars, use -lncursesw on Linux, and still just
# -lncurses on Mac.
--- a/tui_main.c
+++ b/tui_main.c
@@ -8,6 +8,10 @@
#include <locale.h>
#include <ncurses.h>
+#define SOKOL_IMPL
+#include "thirdparty/sokol_time.h"
+#undef SOKOL_IMPL
+
#define AND_CTRL(c) ((c)&037)
static void usage() {
@@ -497,6 +501,9 @@
return 1;
}
+ // Set up timer lib
+ stm_setup();
+
Field field;
if (input_file) {
field_init(&field);
@@ -601,6 +608,7 @@
bool is_playing = false;
bool needs_remarking = true;
bool draw_event_list = false;
+ double bpm = 120.0;
for (;;) {
int term_height = getmaxy(stdscr);
int term_width = getmaxx(stdscr);