Compare commits

...

3 Commits

9 changed files with 212 additions and 18 deletions

View File

@ -97,7 +97,8 @@ if(Azur_FOUND)
set_target_properties(Azur::Azur PROPERTIES
IMPORTED_LOCATION "${AZUR_LIB}"
INTERFACE_INCLUDE_DIRECTORIES "${AZUR_INCLUDE}"
INTERFACE_COMPILE_OPTIONS "-DAZUR_PLATFORM=${AZUR_PLATFORM}")
INTERFACE_COMPILE_OPTIONS "-DAZUR_PLATFORM=${AZUR_PLATFORM}"
INTERFACE_LINK_LIBRARIES -lnum)
if(AZUR_PLATFORM STREQUAL linux)
pkg_check_modules(sdl2 REQUIRED sdl2 IMPORTED_TARGET)

View File

@ -35,6 +35,11 @@ if(AZUR_TOOLKIT_SDL AND AZUR_GRAPHICS_OPENGL)
DEPENDS gen_glsl.py ${ASSETS})
endif()
if(AZUR_TOOLKIT_GINT)
list(APPEND SOURCES
src/gint/init.cpp)
endif()
# gint rendering
if(AZUR_GRAPHICS_GINT_CG)
list(APPEND SOURCES

98
azur/src/gint/init.cpp Normal file
View File

@ -0,0 +1,98 @@
#include <azur/azur.h>
#include <azur/log.h>
#include <gint/timer.h>
#include <gint/cpu.h>
int azur_init(char const *title, int window_width, int window_height)
{
(void)title;
(void)window_width;
(void)window_height;
return 0;
}
__attribute__((destructor))
void azur_quit(void)
{
}
//---
// Main loop setup
//---
/* Time spent in the main loop (seconds)
TODO: Handle ml_time (also in the SDL backend) */
static double ml_time = 0.0;
/* Timers for render and updates */
static int ml_timer_render = -1;
static int ml_timer_update = -1;
static int set_flag(volatile int *flag)
{
*flag = 1;
return TIMER_CONTINUE;
}
int azur_main_loop(
void (*render)(void), int render_fps,
int (*update)(void), int update_ups,
int flags)
{
volatile int render_tick = 1;
volatile int update_tick = 0;
bool started = false;
ml_timer_render = timer_configure(TIMER_ANY, 1000000 / render_fps,
GINT_CALL(set_flag, &render_tick));
if(ml_timer_render < 0) {
azlog(ERROR, "failed to create render timer\n");
return 1;
}
else {
timer_start(ml_timer_render);
}
if(!(flags & AZUR_MAIN_LOOP_TIED)) {
ml_timer_update = timer_configure(TIMER_ANY, 1000000 / update_ups,
GINT_CALL(set_flag, &update_tick));
if(ml_timer_update < 0) {
timer_stop(ml_timer_render);
azlog(ERROR, "failed to create render timer\n");
return 1;
}
else {
timer_start(ml_timer_update);
}
}
while(1) {
if(update_tick && !(flags & AZUR_MAIN_LOOP_TIED)) {
update_tick = 0;
if(update && update()) break;
}
if(render_tick) {
render_tick = 0;
/* Tied renders and updates */
if(started && (flags & AZUR_MAIN_LOOP_TIED)) {
if(update && update()) break;
}
if(render) render();
started = true;
}
sleep();
}
if(ml_timer_render >= 0) {
timer_stop(ml_timer_render);
ml_timer_render = 0;
}
if(ml_timer_update >= 0) {
timer_stop(ml_timer_update);
ml_timer_update = 0;
}
return 0;
}

View File

@ -134,7 +134,8 @@ SDL_Window *azur_sdl_window(void)
// Main loop setup
//---
/* Time spent in the main loop (seconds) */
/* Time spent in the main loop (seconds)
TODO: Handle ml_time (also in the gint backend) */
static double ml_time = 0.0;
/* In emscripten, callbacks are void/void, vsync is always ON, and the

View File

@ -8,6 +8,7 @@
include(CTest)
add_library(num STATIC
src/num.cpp
src/str.cpp)
target_include_directories(num PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")

View File

@ -117,9 +117,15 @@ struct num8
v %= other.v;
return *this;
}
inline constexpr num8 ifloor() {
return 0;
}
inline constexpr num8 floor() {
return num8(0);
}
inline constexpr num8 iceil() {
return v != 0;
}
/* Warning: num8::ceil() always overflows! */
inline constexpr num8 ceil() {
return num8(0);
@ -132,19 +138,19 @@ struct num8
/* Comparisons with int */
inline constexpr bool operator==(int const &i) {
inline constexpr bool operator==(int const &i) const {
return (v | i) == 0;
}
inline constexpr bool operator<(int const &i) {
inline constexpr bool operator<(int const &i) const {
return i >= 1;
}
inline constexpr bool operator>=(int const &i) {
inline constexpr bool operator>=(int const &i) const {
return i <= 0;
}
inline constexpr bool operator<=(int const &i) {
inline constexpr bool operator<=(int const &i) const {
return i + !v > 0;
}
inline constexpr bool operator>(int const &i) {
inline constexpr bool operator>(int const &i) const {
return i + !v <= 0;
}
@ -195,6 +201,9 @@ struct num16
/* num16 x num16 -> num32 multiplication
This is efficiently implemented with a muls.w instruction. */
static constexpr num32 dmul(num16 const &x, num16 const &y);
/* num16 / num16 -> num16 division for positive numbers
This bypasses some sign tests, which saves a bit of time. */
static constexpr num16 div_positive(num16 const &x, num16 const &y);
/* Basic arithmetic */
@ -218,11 +227,17 @@ struct num16
v %= other.v;
return *this;
}
inline constexpr int ifloor() {
return v >> 8;
}
inline constexpr num16 floor() {
num16 x;
x.v = v & 0xff00;
return x;
}
inline constexpr int iceil() {
return (v + 0xff) >> 8;
}
inline constexpr num16 ceil() {
num16 x;
x.v = ((v - 1) | 0xff) + 1;
@ -236,22 +251,22 @@ struct num16
/* Comparisons with int */
inline constexpr bool operator==(int const &i) {
inline constexpr bool operator==(int const &i) const {
return (int16_t)i == i && (i << 8) == v;
}
inline constexpr bool operator<(int const &i) {
inline constexpr bool operator<(int const &i) const {
return (v >> 8) < i;
}
inline constexpr bool operator>=(int const &i) {
inline constexpr bool operator>=(int const &i) const {
return (v >> 8) >= i;
}
/* Unfortunately the branchless version for this test is expressed in terms
of `v`, not `i`, so it does not simplify well when `i` is known. In that
case, writing eg. `x > num16(0)` is faster than `x > 0`. */
inline constexpr bool operator<=(int const &i) {
inline constexpr bool operator<=(int const &i) const {
return (v >> 8) + ((v & 0xff) != 0) <= i;
}
inline constexpr bool operator>(int const &i) {
inline constexpr bool operator>(int const &i) const {
return (v >> 8) + ((v & 0xff) != 0) > i;
}
@ -330,11 +345,17 @@ struct num32
v %= other.v;
return *this;
}
inline constexpr int ifloor() {
return v >> 16;
}
inline constexpr num32 floor() {
num32 x;
x.v = v & 0xffff0000;
return x;
}
inline constexpr int iceil() {
return (v + 0xffff) >> 16;
}
inline constexpr num32 ceil() {
num32 x;
x.v = ((v - 1) | 0xffff) + 1;
@ -345,22 +366,23 @@ struct num32
x.v = v & 0xffff;
return x;
}
num32 sqrt() const;
/* Comparisons with int */
inline constexpr bool operator==(int const &i) {
inline constexpr bool operator==(int const &i) const {
return (int16_t)i == i && (i << 16) == v;
}
inline constexpr bool operator<(int const &i) {
inline constexpr bool operator<(int const &i) const {
return (v >> 16) < i;
}
inline constexpr bool operator>=(int const &i) {
inline constexpr bool operator>=(int const &i) const {
return (v >> 16) >= i;
}
inline constexpr bool operator<=(int const &i) {
inline constexpr bool operator<=(int const &i) const {
return (v >> 16) + ((v & 0xffff) != 0) <= i;
}
inline constexpr bool operator>(int const &i) {
inline constexpr bool operator>(int const &i) const {
return (v >> 16) + ((v & 0xffff) != 0) > i;
}
@ -447,11 +469,17 @@ struct num64
v %= other.v;
return *this;
}
inline constexpr int ifloor() {
return v >> 32;
}
inline constexpr num64 floor() {
num64 x;
x.v = v & 0xffffffff00000000ull;
return x;
}
inline constexpr int iceil() {
return (v >> 32) + ((uint32_t)v != 0);
}
inline constexpr num64 ceil() {
num64 x;
x.v = ((v - 1) | 0xffffffffull) + 1;
@ -569,6 +597,26 @@ inline constexpr T operator-(T const &op) {
return T(0) - op;
}
/* Internal minima, maxima and clamp */
template<typename T> requires(is_num<T>)
inline constexpr T min(T const &left, T const &right)
{
return (left < right) ? left : right;
}
template<typename T> requires(is_num<T>)
inline constexpr T max(T const &left, T const &right)
{
return (left > right) ? left : right;
}
template<typename T> requires(is_num<T>)
inline constexpr T clamp(T const &val, T const &lower, T const &upper)
{
return max(lower, min(val, upper));
}
/* Other specific operations */
inline constexpr num32 num16::dmul(num16 const &x, num16 const &y)
@ -578,6 +626,13 @@ inline constexpr num32 num16::dmul(num16 const &x, num16 const &y)
return n;
}
inline constexpr num16 num16::div_positive(num16 const &x, num16 const &y)
{
num16 r;
r.v = ((uint32_t)(uint16_t)x.v << 8) / (uint16_t)y.v;
return r;
}
inline constexpr num64 num32::dmul(num32 const &x, num32 const &y)
{
num64 n;
@ -585,4 +640,12 @@ inline constexpr num64 num32::dmul(num32 const &x, num32 const &y)
return n;
}
/* Floor modulo. We provide an optimized version for constants, which optimizes
away the main condition. */
template<typename T> requires(is_num<T>)
inline constexpr T modf(T const &x, T const &y) {
T r = x % y;
return (r.v && (r.v ^ y.v) < 0) ? r + y : r;
}
} /* namespace libnum */

View File

@ -189,6 +189,10 @@ inline constexpr vec<T,N> operator*(T const &lhs, vec<T,N> rhs) {
rhs[i] *= lhs;
return rhs;
}
template<typename T, int N>
inline constexpr vec<T,N> operator/(vec<T,N> lhs, T const &rhs) {
return lhs /= rhs;
}
/* Comparisons */

21
libnum/src/num.cpp Normal file
View File

@ -0,0 +1,21 @@
#include <num/num.h>
using namespace libnum;
/* Integer square root (rather slow) */
static int64_t sqrtll(int64_t n)
{
if(n < 4)
return (n > 0);
int64_t low_bound = sqrtll(n / 4) * 2;
int64_t high_bound = low_bound + 1;
return (high_bound * high_bound <= n) ? high_bound : low_bound;
}
num32 num32::sqrt() const
{
num32 r;
r.v = sqrtll((int64_t)v << 16);
return r;
}

View File

@ -306,7 +306,7 @@ class ExprParser:
return decorate
def binaryOpsRight(ctor, ops):
return binaryOpsRight(ctor, ops, rassoc=True)
return binaryOps(ctor, ops, rassoc=True)
def unaryOps(ctor, ops, assoc=True):
def decorate(f):