Merge branch 'v2_incenter' of github.com:peter-slattery/Lumenarium into v2_incenter

This commit is contained in:
Cameron Tacklind 2022-08-23 15:07:08 -07:00
commit 597127c7f3
37 changed files with 8494 additions and 455 deletions

3
.gitignore vendored
View File

@ -11,4 +11,5 @@ sysroot/
*.DS_Store *.DS_Store
*.vscode *.vscode
*.vscode/* *.vscode/*
*.dSYM *.dSYM
run_tree/data/live_data

View File

@ -1,7 +1,7 @@
set -e set -e
SCRIPT_REL_DIR=$(dirname "${BASH_SOURCE[0]}") SCRIPT_REL_DIR=$(dirname "${BASH_SOURCE[0]}")
$SCRIPT_REL_DIR/build_.sh prod raspi arm64 $SCRIPT_REL_DIR/build_.sh debug osx arm64
# $SCRIPT_REL_DIR/build_.sh debug wasm intel # $SCRIPT_REL_DIR/build_.sh debug wasm intel
# pushd "run_tree/raspi/arm64/debug" # pushd "run_tree/raspi/arm64/debug"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
static Incenter_Data_Row question_5_data[] = {
[0] = { city_bucharest, 2022, MONTH_jan, 0.601593625498008, },
[1] = { city_brisbane, 2022, MONTH_jan, 0.6060606060606061, },
[2] = { city_chengdu, 2022, MONTH_jan, 0.5254237288135594, },
[3] = { city_new_delhi, 2022, MONTH_jan, 0.6507936507936508, },
[4] = { city_paris, 2022, MONTH_jan, 0.569806492883416, },
[5] = { city_san_francisco, 2022, MONTH_jan, 0.6120930232558139, },
[6] = { city_denver, 2022, MONTH_jan, 0.6120930232558139, },
[7] = { city_ankara, 2022, MONTH_jan, 0.7948003714020427, },
[8] = { city_harare, 2022, MONTH_jan, 0.5714285714285714, },
[9] = { city_hanoi, 2022, MONTH_jan, 0.6158536585365854, },
[10] = { city_washington, 2022, MONTH_jan, 0.6120930232558139, },
[11] = { city_bangkok, 2022, MONTH_jan, 0.5555555555555556, },
[12] = { city_tunis, 2022, MONTH_jan, 0.5142857142857142, },
[13] = { city_seoul, 2022, MONTH_jan, 0.6158536585365854, },
[14] = { city_belgrade, 2022, MONTH_jan, 0.6169354838709677, },
[15] = { city_moscow, 2022, MONTH_jan, 0.5819672131147541, },
[16] = { city_lima, 2022, MONTH_jan, 0.425, },
[17] = { city_islamabad, 2022, MONTH_jan, 0.6363636363636364, },
[18] = { city_abuja, 2022, MONTH_jan, 0.8333333333333334, },
[19] = { city_managua, 2022, MONTH_jan, 0.6774193548387096, },
[20] = { city_amsterdam, 2022, MONTH_jan, 0.464638783269962, },
[21] = { city_rabat, 2022, MONTH_jan, 0.6190476190476191, },
[22] = { city_ulaanbaatar, 2022, MONTH_jan, 0.5254237288135594, },
[23] = { city_mexico_city, 2022, MONTH_jan, 0.5176882661996497, },
[24] = { city_nairobi, 2022, MONTH_jan, 0.5714285714285714, },
[25] = { city_tokyo, 2022, MONTH_jan, 0.5993009868421053, },
[26] = { city_baghdad, 2022, MONTH_jan, 0.5, },
[27] = { city_tehran, 2022, MONTH_jan, 0.5, },
[28] = { city_jakarta, 2022, MONTH_jan, 0.6011644832605532, },
[29] = { city_guatemala_city, 2022, MONTH_jan, 0.6774193548387096, },
[30] = { city_berlin, 2022, MONTH_jan, 0.6111111111111112, },
[31] = { city_addis_ababa, 2022, MONTH_jan, 0.5714285714285714, },
[32] = { city_cairo, 2022, MONTH_jan, 0.5142857142857142, },
[33] = { city_quito, 2022, MONTH_jan, 0.4827586206896552, },
[34] = { city_bogota, 2022, MONTH_jan, 0.45, },
[35] = { city_beijing, 2022, MONTH_jan, 0.5254237288135594, },
[36] = { city_accra, 2022, MONTH_jan, 0.5714285714285714, },
[37] = { city_ottawa, 2022, MONTH_jan, 0.6352941176470588, },
[38] = { city_brasilia, 2022, MONTH_jan, 0.7062314540059347, },
[39] = { city_la_paz, 2022, MONTH_jan, 0.7062314540059347, },
[40] = { city_dhaka, 2022, MONTH_jan, 0.7107438016528925, },
[41] = { city_yerevan, 2022, MONTH_jan, 0.7948003714020427, },
[42] = { city_chicago, 2022, MONTH_jan, 0.6120930232558139, },
[43] = { city_kyiv, 2022, MONTH_jan, 0.59375, },
[44] = { city_dubai, 2022, MONTH_jan, 0.5, },
[45] = { city_mumbai, 2022, MONTH_jan, 0.6507936507936508, },
[46] = { city_madrid, 2022, MONTH_jan, 0.4838709677419355, },
};
global u32 question_5_len = sizeof(question_5_data) / sizeof(question_5_data[0]);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,48 @@
city_data,year,month,prop
city_bucharest,2022,MONTH_jan,0.601593625498008
city_brisbane,2022,MONTH_jan,0.6060606060606061
city_chengdu,2022,MONTH_jan,0.5254237288135594
city_new_delhi,2022,MONTH_jan,0.6507936507936508
city_paris,2022,MONTH_jan,0.569806492883416
city_san_francisco,2022,MONTH_jan,0.6120930232558139
city_denver,2022,MONTH_jan,0.6120930232558139
city_ankara,2022,MONTH_jan,0.7948003714020427
city_harare,2022,MONTH_jan,0.5714285714285714
city_hanoi,2022,MONTH_jan,0.6158536585365854
city_washington,2022,MONTH_jan,0.6120930232558139
city_bangkok,2022,MONTH_jan,0.5555555555555556
city_tunis,2022,MONTH_jan,0.5142857142857142
city_seoul,2022,MONTH_jan,0.6158536585365854
city_belgrade,2022,MONTH_jan,0.6169354838709677
city_moscow,2022,MONTH_jan,0.5819672131147541
city_lima,2022,MONTH_jan,0.425
city_islamabad,2022,MONTH_jan,0.6363636363636364
city_abuja,2022,MONTH_jan,0.8333333333333334
city_managua,2022,MONTH_jan,0.6774193548387096
city_amsterdam,2022,MONTH_jan,0.464638783269962
city_rabat,2022,MONTH_jan,0.6190476190476191
city_ulaanbaatar,2022,MONTH_jan,0.5254237288135594
city_mexico_city,2022,MONTH_jan,0.5176882661996497
city_nairobi,2022,MONTH_jan,0.5714285714285714
city_tokyo,2022,MONTH_jan,0.5993009868421053
city_baghdad,2022,MONTH_jan,0.5
city_tehran,2022,MONTH_jan,0.5
city_jakarta,2022,MONTH_jan,0.6011644832605532
city_guatemala_city,2022,MONTH_jan,0.6774193548387096
city_berlin,2022,MONTH_jan,0.6111111111111112
city_addis_ababa,2022,MONTH_jan,0.5714285714285714
city_cairo,2022,MONTH_jan,0.5142857142857142
city_quito,2022,MONTH_jan,0.4827586206896552
city_bogota,2022,MONTH_jan,0.45
city_beijing,2022,MONTH_jan,0.5254237288135594
city_accra,2022,MONTH_jan,0.5714285714285714
city_ottawa,2022,MONTH_jan,0.6352941176470588
city_brasilia,2022,MONTH_jan,0.7062314540059347
city_la_paz,2022,MONTH_jan,0.7062314540059347
city_dhaka,2022,MONTH_jan,0.7107438016528925
city_yerevan,2022,MONTH_jan,0.7948003714020427
city_chicago,2022,MONTH_jan,0.6120930232558139
city_kyiv,2022,MONTH_jan,0.59375
city_dubai,2022,MONTH_jan,0.5
city_mumbai,2022,MONTH_jan,0.6507936507936508
city_madrid,2022,MONTH_jan,0.4838709677419355
1 city_data year month prop
2 city_bucharest 2022 MONTH_jan 0.601593625498008
3 city_brisbane 2022 MONTH_jan 0.6060606060606061
4 city_chengdu 2022 MONTH_jan 0.5254237288135594
5 city_new_delhi 2022 MONTH_jan 0.6507936507936508
6 city_paris 2022 MONTH_jan 0.569806492883416
7 city_san_francisco 2022 MONTH_jan 0.6120930232558139
8 city_denver 2022 MONTH_jan 0.6120930232558139
9 city_ankara 2022 MONTH_jan 0.7948003714020427
10 city_harare 2022 MONTH_jan 0.5714285714285714
11 city_hanoi 2022 MONTH_jan 0.6158536585365854
12 city_washington 2022 MONTH_jan 0.6120930232558139
13 city_bangkok 2022 MONTH_jan 0.5555555555555556
14 city_tunis 2022 MONTH_jan 0.5142857142857142
15 city_seoul 2022 MONTH_jan 0.6158536585365854
16 city_belgrade 2022 MONTH_jan 0.6169354838709677
17 city_moscow 2022 MONTH_jan 0.5819672131147541
18 city_lima 2022 MONTH_jan 0.425
19 city_islamabad 2022 MONTH_jan 0.6363636363636364
20 city_abuja 2022 MONTH_jan 0.8333333333333334
21 city_managua 2022 MONTH_jan 0.6774193548387096
22 city_amsterdam 2022 MONTH_jan 0.464638783269962
23 city_rabat 2022 MONTH_jan 0.6190476190476191
24 city_ulaanbaatar 2022 MONTH_jan 0.5254237288135594
25 city_mexico_city 2022 MONTH_jan 0.5176882661996497
26 city_nairobi 2022 MONTH_jan 0.5714285714285714
27 city_tokyo 2022 MONTH_jan 0.5993009868421053
28 city_baghdad 2022 MONTH_jan 0.5
29 city_tehran 2022 MONTH_jan 0.5
30 city_jakarta 2022 MONTH_jan 0.6011644832605532
31 city_guatemala_city 2022 MONTH_jan 0.6774193548387096
32 city_berlin 2022 MONTH_jan 0.6111111111111112
33 city_addis_ababa 2022 MONTH_jan 0.5714285714285714
34 city_cairo 2022 MONTH_jan 0.5142857142857142
35 city_quito 2022 MONTH_jan 0.4827586206896552
36 city_bogota 2022 MONTH_jan 0.45
37 city_beijing 2022 MONTH_jan 0.5254237288135594
38 city_accra 2022 MONTH_jan 0.5714285714285714
39 city_ottawa 2022 MONTH_jan 0.6352941176470588
40 city_brasilia 2022 MONTH_jan 0.7062314540059347
41 city_la_paz 2022 MONTH_jan 0.7062314540059347
42 city_dhaka 2022 MONTH_jan 0.7107438016528925
43 city_yerevan 2022 MONTH_jan 0.7948003714020427
44 city_chicago 2022 MONTH_jan 0.6120930232558139
45 city_kyiv 2022 MONTH_jan 0.59375
46 city_dubai 2022 MONTH_jan 0.5
47 city_mumbai 2022 MONTH_jan 0.6507936507936508
48 city_madrid 2022 MONTH_jan 0.4838709677419355

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -416,6 +416,14 @@ bump_allocator_destroy(Allocator* allocator)
allocator_destroy_(allocator, sizeof(Allocator_Bump)); allocator_destroy_(allocator, sizeof(Allocator_Bump));
} }
internal u64
bump_allocator_at(Allocator* allocator)
{
Allocator_Bump* bump = (Allocator_Bump*)allocator->allocator_data;
bump_allocator_validate(allocator);
return bump->at;
}
internal void internal void
bump_allocator_rewind(Allocator* allocator, u64 to_point) bump_allocator_rewind(Allocator* allocator, u64 to_point)
{ {

View File

@ -1,7 +1,22 @@
#if !defined(LUMENARIUM_CORE_SOCKET_H) #if !defined(LUMENARIUM_CORE_SOCKET_H)
#define LUMENARIUM_CORE_SOCKET_H #define LUMENARIUM_CORE_SOCKET_H
typedef struct { u64 value; } Socket_Handle; typedef struct Socket_Handle Socket_Handle;
struct Socket_Handle { u64 value; };
typedef s32 Socket_Error;
enum {
SocketError_NOERROR,
SocketError_EAGAIN,
SocketError_EBADF,
SocketError_ECONNREFUSED,
SocketError_EFAULT,
SocketError_EINTR,
SocketError_EINVAL,
SocketError_ENOMEM,
SocketError_ENOTCONN,
SocketError_ENOTSOCK,
};
u16 endian_swap_u16(u16 v); u16 endian_swap_u16(u16 v);
u32 endian_swap_u32(u32 v); u32 endian_swap_u32(u32 v);

View File

@ -107,7 +107,7 @@ string_substring(String s, u64 min, u64 max)
internal String internal String
string_skip(String s, u64 min) string_skip(String s, u64 min)
{ {
return string_substring(s, min, s.len); return string_substring(s, min, s.len - min);
} }
internal String internal String

View File

@ -7,8 +7,12 @@ struct Thread_Handle { u64 value; };
typedef struct Thread_Result Thread_Result; typedef struct Thread_Result Thread_Result;
struct Thread_Result { u32 code; }; struct Thread_Result { u32 code; };
// TODO(PS): In the interest of time while getting Incenter
// up and running, you made Thread_Proc take a u8* rather than
// the whole Thread_Data structure, whcih currently isnt' being
// used at all
typedef struct Thread_Data Thread_Data; typedef struct Thread_Data Thread_Data;
typedef Thread_Result Thread_Proc(Thread_Data* data); typedef Thread_Result Thread_Proc(u8* data);
struct Thread_Data struct Thread_Data
{ {
Thread_Handle thread_handle; Thread_Handle thread_handle;
@ -18,4 +22,6 @@ struct Thread_Data
u8* user_data; u8* user_data;
}; };
#endif // LUMENARIUM_CORE_THREADS_H #endif // LUMENARIUM_CORE_THREADS_H

View File

@ -1,3 +1,6 @@
#include <fcntl.h>
#include <unistd.h>
Thread_Result Thread_Result
thread_proc(Thread_Data* td) thread_proc(Thread_Data* td)
{ {
@ -134,7 +137,7 @@ run_tests()
assert(has_flag(b, Test4)); assert(has_flag(b, Test4));
assert(has_flag(b, Test1 | Test4)); assert(has_flag(b, Test1 | Test4));
assert(!has_flag(b, Test3)); assert(!has_flag(b, Test3));
// memory tests // memory tests
uint8_t* r0 = os_mem_reserve(1024); uint8_t* r0 = os_mem_reserve(1024);
uint8_t* r1 = os_mem_commit(r0, 512); uint8_t* r1 = os_mem_commit(r0, 512);
@ -142,12 +145,12 @@ run_tests()
os_mem_decommit(r1, 512); os_mem_decommit(r1, 512);
os_mem_release(r0, 1024); os_mem_release(r0, 1024);
// r0[256] = 100; // this should break if you uncomment // r0[256] = 100; // this should break if you uncomment
uint8_t* a0 = allocator_alloc_array(scratch.a, uint8_t, 32); uint8_t* a0 = allocator_alloc_array(scratch.a, uint8_t, 32);
uint8_t* a1 = allocator_alloc_array(scratch.a, uint8_t, 32); uint8_t* a1 = allocator_alloc_array(scratch.a, uint8_t, 32);
assert(a0 != a1); assert(a0 != a1);
assert((a0 + 32) <= a1); assert((a0 + 32) <= a1);
a1[0] = 25; a1[0] = 25;
for (uint32_t i = 0; i < 32; i++) for (uint32_t i = 0; i < 32; i++)
@ -163,14 +166,14 @@ run_tests()
assert(a1[i] == (100 + i)); assert(a1[i] == (100 + i));
} }
assert(round_up_to_pow2_u32(1) == 1); assert(round_up_to_pow2_u32(1) == 1);
assert(round_up_to_pow2_u32(3) == 4); assert(round_up_to_pow2_u32(3) == 4);
assert(round_up_to_pow2_u32(29) == 32); assert(round_up_to_pow2_u32(29) == 32);
assert(round_up_to_pow2_u32(32) == 32); assert(round_up_to_pow2_u32(32) == 32);
assert(round_up_to_pow2_u32(120) == 128); assert(round_up_to_pow2_u32(120) == 128);
memory_tests(); memory_tests();
bsp_tests(); bsp_tests();
@ -180,6 +183,21 @@ run_tests()
return; return;
#endif #endif
// OS Atomics
{
u32 v = 232;
u32 v0 = os_interlocked_increment(&v);
assert(v0 == 233);
assert(v == 233);
bool ice0 = os_interlocked_cmp_exchg(&v, 232, 235); // fails, old value != v
assert(!ice0);
assert(v == 233);
bool ice1 = os_interlocked_cmp_exchg(&v, 233, 235);
assert(ice1);
assert(v == 235);
}
// testing strings and exe path // testing strings and exe path
String exe_file_path = os_get_exe_path(scratch.a); String exe_file_path = os_get_exe_path(scratch.a);
@ -192,19 +210,34 @@ run_tests()
assert(run_tree_path_nullterm.len > 0); assert(run_tree_path_nullterm.len > 0);
assert(os_pwd_set(run_tree_path_nullterm)); assert(os_pwd_set(run_tree_path_nullterm));
String td = lit_str("Testing data");
// testing file io
File_Handle f = os_file_open(lit_str("text.txt"), FileAccess_Read | FileAccess_Write, FileCreate_OpenExisting);
File_Info i = os_file_get_info(f, scratch.a);
Data d0 = os_file_read_all(f, scratch.a); // testing file io
assert(d0.size > 0); String fp = lit_str("text.txt");
File_Handle f = os_file_open(fp, FileAccess_Write, FileCreate_OpenAlways);
assert(f.value != 0);
String s = lit_str("foooooooooobbbbbbaaaarrrrrr"); String s = lit_str("foooooooooobbbbbbaaaarrrrrr");
Data d1 = { s.str, s.len }; Data d1 = { s.str, s.len };
bool r = os_file_write_all(f, d1); bool r = os_file_write_all(f, d1);
assert(r); assert(r);
os_file_close(f);
f = os_file_open(fp, FileAccess_Read, FileCreate_OpenExisting);
assert(f.value != 0);
File_Info i = os_file_get_info(f, scratch.a);
Data d0 = os_file_read_all(f, scratch.a);
assert(d0.size > 0);
os_file_close(f);
if (!os_file_delete(fp)) {
invalid_code_path;
}
#if 0 #if 0
// TODO(PS): these were causing startup problems but you weren't focusing on // TODO(PS): these were causing startup problems but you weren't focusing on
// threads/ When you build something multithreaded come back here and // threads/ When you build something multithreaded come back here and

View File

@ -306,6 +306,23 @@ typedef struct {
u32 anchors_count; u32 anchors_count;
} Color_Ramp; } Color_Ramp;
Color_Ramp
color_ramp_reverse(Color_Ramp ramp)
{
Color_Ramp result = { .anchors_count = ramp.anchors_count };
for (u32 i = 0; i < ramp.anchors_count; i++)
{
u32 new_i = (ramp.anchors_count - 1) - i;
assert(new_i < ramp.anchors_count);
r32 rev_pct = 1.f - ramp.anchors[i].pct;
result.anchors[new_i] = (Color_Ramp_Anchor){
.color = ramp.anchors[i].color,
.pct = rev_pct,
};
}
return result;
}
v3 v3
color_ramp_eval(Color_Ramp ramp, r32 pct) color_ramp_eval(Color_Ramp ramp, r32 pct)
{ {
@ -331,6 +348,7 @@ color_ramp_eval(Color_Ramp ramp, r32 pct)
// interpolate between them // interpolate between them
r32 anchor_range = nearest_above.pct - nearest_below.pct; r32 anchor_range = nearest_above.pct - nearest_below.pct;
if (anchor_range == 0) anchor_range = 1;
r32 pct_remapped = (pct - nearest_below.pct) / anchor_range; r32 pct_remapped = (pct - nearest_below.pct) / anchor_range;
v3 result = pm_lerp_v3(nearest_below.color, pct_remapped, nearest_above.color); v3 result = pm_lerp_v3(nearest_below.color, pct_remapped, nearest_above.color);
return result; return result;

View File

@ -13,7 +13,9 @@ File_Handle
os_file_open(String path, File_Access_Flags flags_access, File_Create_Flags flags_create) os_file_open(String path, File_Access_Flags flags_access, File_Create_Flags flags_create)
{ {
File_Handle result = {}; File_Handle result = {};
mode_t mode = 0;
s32 flags = 0; s32 flags = 0;
if(has_flag_exact(flags_access, (FileAccess_Read | FileAccess_Write))) if(has_flag_exact(flags_access, (FileAccess_Read | FileAccess_Write)))
{ {
@ -33,16 +35,28 @@ os_file_open(String path, File_Access_Flags flags_access, File_Create_Flags fla
return result; return result;
} }
} }
// This additional argument is required if we're creating a file
// if we want this process to be able to open it again later.
mode_t create_flags = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
switch (flags_create) switch (flags_create)
{ {
case FileCreate_New: { add_flag(flags, O_CREAT | O_EXCL ); } break; case FileCreate_New:
case FileCreate_CreateAlways: { add_flag(flags, O_CREAT); } break; {
add_flag(flags, O_CREAT | O_EXCL );
mode = create_flags;
} break;
case FileCreate_OpenExisting: { /* add_flag(flags, O_); */ } break; case FileCreate_OpenExisting: { /* add_flag(flags, O_); */ } break;
case FileCreate_OpenAlways: { /* add_flag(flags, O_); */ } break; case FileCreate_CreateAlways:
case FileCreate_OpenAlways:
{
add_flag(flags, O_CREAT);
mode = create_flags;
} break;
invalid_default_case; invalid_default_case;
} }
s32 file_handle = open((char*)path.str, flags); s32 file_handle = open((char*)path.str, flags);
if (file_handle >= 0) if (file_handle >= 0)
{ {
@ -73,6 +87,16 @@ os_file_close(File_Handle file_handle)
} }
} }
bool
os_file_delete(String file_path)
{
if (remove((char*)file_path.str) != 0) {
perror("Error deleting file\n");
return false;
}
return true;
}
File_Info File_Info
os_file_get_info(File_Handle file_handle, Allocator* allocator) os_file_get_info(File_Handle file_handle, Allocator* allocator)
{ {
@ -81,7 +105,7 @@ os_file_get_info(File_Handle file_handle, Allocator* allocator)
if (os_handle != -1) if (os_handle != -1)
{ {
String path = open_files_get_path(file_handle); String path = open_files_get_path(file_handle);
struct stat os_info = {}; struct stat os_info = {};
if (fstat(os_handle, &os_info) != -1) if (fstat(os_handle, &os_info) != -1)
{ {
@ -121,7 +145,7 @@ os_file_read_all(File_Handle file_handle, Allocator* allocator)
Data result = {}; Data result = {};
s32 os_handle = open_files_get_handle(file_handle); s32 os_handle = open_files_get_handle(file_handle);
if (os_handle == -1) return result; if (os_handle == -1) return result;
// get file size // get file size
s32 offset = lseek(os_handle, 0, SEEK_END); s32 offset = lseek(os_handle, 0, SEEK_END);
if (offset == -1) if (offset == -1)
@ -131,10 +155,10 @@ os_file_read_all(File_Handle file_handle, Allocator* allocator)
return result; return result;
} }
lseek(os_handle, 0, SEEK_SET); lseek(os_handle, 0, SEEK_SET);
result.base = allocator_alloc(allocator, offset + 1); result.base = allocator_alloc(allocator, offset + 1);
result.size = offset + 1; result.size = offset + 1;
s32 bytes_read = read(os_handle, result.base, result.size); s32 bytes_read = read(os_handle, result.base, result.size);
if (bytes_read == (result.size - 1)) if (bytes_read == (result.size - 1))
{ {
@ -167,7 +191,7 @@ os_file_write_(s32 os_handle, Data file_data)
linux_err_print("write"); linux_err_print("write");
return false; return false;
} }
return true; return true;
} }
@ -176,7 +200,7 @@ os_file_write_all(File_Handle file_handle, Data file_data)
{ {
s32 os_handle = open_files_get_handle(file_handle); s32 os_handle = open_files_get_handle(file_handle);
if (os_handle == -1) return false; if (os_handle == -1) return false;
lseek(os_handle, 0, SEEK_SET); lseek(os_handle, 0, SEEK_SET);
return os_file_write_(os_handle, file_data); return os_file_write_(os_handle, file_data);
} }
@ -186,7 +210,7 @@ os_file_write(File_Handle file_handle, Data file_data)
{ {
s32 os_handle = open_files_get_handle(file_handle); s32 os_handle = open_files_get_handle(file_handle);
if (os_handle == -1) return false; if (os_handle == -1) return false;
return os_file_write_(os_handle, file_data); return os_file_write_(os_handle, file_data);
} }
@ -231,7 +255,7 @@ os_dir_enum(String path, Platform_Enum_Dir_Flags flags, Allocator* allocator)
void void
os_file_async_work_on_job(File_Async_Job* job) os_file_async_work_on_job(File_Async_Job* job)
{ {
} }
#endif // LUMENARIUM_LINUX_FILE_H #endif // LUMENARIUM_LINUX_FILE_H

View File

@ -34,10 +34,11 @@ os_socket_connect()
} }
bool bool
os_socket_close() os_socket_close(Socket_Handle handle)
{ {
invalid_code_path; OS_SOCKET_TYPE sock = open_sockets_get(handle);
return false; close(sock);
return true;
} }
Data Data

View File

@ -1,17 +1,101 @@
#ifndef LUMENARIUM_RASPI_THREADS_H #ifndef LUMENARIUM_RASPI_THREADS_H
#define LUMENARIUM_RASPI_THREADS_H 1 #define LUMENARIUM_RASPI_THREADS_H 1
typedef struct Os_Linux_Thread Os_Linux_Thread;
struct Os_Linux_Thread
{
pthread_t thread;
Thread_Proc* proc;
u8* user_data;
Thread_Result result;
};
#define LINUX_THREAD_CAP 8
global Os_Linux_Thread linux_threads_[LINUX_THREAD_CAP];
global u32 linux_threads_len_;
Thread_Handle Thread_Handle
os_thread_begin(Thread_Proc* proc, u8* user_data) os_thread_begin(Thread_Proc* proc, u8* user_data)
{ {
invalid_code_path; // Call the actual thread function
return Thread_Handle{0}; // This is essentially a blocking call for the rest of this function
Os_Linux_Thread* thread_data = (Os_Linux_Thread*)arg;
thread_data->result = thread_data->proc(thread_data->user_data);
// Clean up this threads thread slot so other threads
// can use it
thread_data->proc = 0;
thread_data->user_data = 0;
pthread_exit(&thread_data->result);
} }
void void
os_thread_end(Thread_Handle thread_handle) os_thread_end(Thread_Handle thread_handle)
{ {
invalid_code_path; // Find an unused thread slot
Thread_Handle result = { .value = 0 };
if (linux_threads_len_ < OSX_THREAD_CAP)
{
result = (Thread_Handle){ .value = linux_threads_len_++ };
}
else
{
bool found = false;
for (u32 i = 0; i < OSX_THREAD_CAP; i++)
{
if (linux_threads_[i].proc == 0)
{
result.value = i;
found = true;
}
}
if (!found) {
printf("ERROR: Unable to create thread.\n");
invalid_code_path;
}
}
// Initialize Thread Slot
Os_Linux_Thread* t = linux_threads_ + result.value;
*t = (Os_Linux_Thread){
.proc = proc,
.user_data = user_data
};
// Create PThread
s32 create_error = pthread_create(&t->thread,
NULL, // use default attrs
(void * _Nullable (* _Nonnull)(void * _Nullable))proc,
user_data
);
if (create_error)
{
switch (create_error) {
case EAGAIN: {
} break;
case EINVAL: {
} break;
// case ELEMULTITHREADFORK: {
// } break;
case ENOMEM: {
} break;
}
}
return result;
}
void
os_thread_end(Thread_Handle thread_handle)
{
Os_Linux_Thread* t = linux_threads_ + thread_handle.value;
pthread_kill(t->thread, 0);
} }
u32 u32
@ -21,8 +105,8 @@ os_interlocked_increment(volatile u32* value)
return 0; return 0;
} }
u32 bool
os_interlocked_cmp_exchg(volatile u32* dest, u32 new_value, u32 old_value) os_interlocked_cmp_exchg(volatile u32* dest, u32 old_value, u32 new_value)
{ {
invalid_code_path; invalid_code_path;
return 0; return 0;

View File

@ -15,6 +15,7 @@ bool os_mem_release(u8* base, u64 size);
File_Async_Job_System os_file_jobs_init(); File_Async_Job_System os_file_jobs_init();
File_Handle os_file_open(String path, File_Access_Flags flags_access, File_Create_Flags flags_create); File_Handle os_file_open(String path, File_Access_Flags flags_access, File_Create_Flags flags_create);
void os_file_close(File_Handle file_handle); void os_file_close(File_Handle file_handle);
bool os_file_delete(String path);
File_Info os_file_get_info(File_Handle file_handle, Allocator* allocator); File_Info os_file_get_info(File_Handle file_handle, Allocator* allocator);
Data os_file_read_all(File_Handle file_handle, Allocator* allocator); Data os_file_read_all(File_Handle file_handle, Allocator* allocator);
bool os_file_write_all(File_Handle file_handle, Data file_data); bool os_file_write_all(File_Handle file_handle, Data file_data);
@ -40,8 +41,12 @@ r64 os_get_ticks_per_second();
Thread_Handle os_thread_begin(Thread_Proc* proc, u8* user_data); Thread_Handle os_thread_begin(Thread_Proc* proc, u8* user_data);
void os_thread_end(Thread_Handle thread_handle); void os_thread_end(Thread_Handle thread_handle);
u32 os_interlocked_increment(volatile u32* value); // returns the new value of the provided variable
u32 os_interlocked_cmp_exchg(volatile u32* dest, u32 new_value, u32 old_value); u32 os_interlocked_increment(volatile u32* value);
// returns true if dest was equal to old_value, and the exchange was successful,
// returns false otherwise
bool os_interlocked_cmp_exchg(volatile u32* dest, u32 old_value, u32 new_value);
/////////////////////////////////////// ///////////////////////////////////////
// Network Access // Network Access
@ -49,13 +54,14 @@ u32 os_interlocked_cmp_exchg(volatile u32* dest, u32 new_value, u32 old_value);
Socket_Handle os_socket_create(s32 domain, s32 type, s32 protocol); Socket_Handle os_socket_create(s32 domain, s32 type, s32 protocol);
bool os_socket_bind(); bool os_socket_bind();
bool os_socket_connect(); bool os_socket_connect();
bool os_socket_close(); bool os_socket_close(Socket_Handle handle);
Data os_socket_recv(); Data os_socket_recv();
Data os_socket_recvfrom(Socket_Handle handle, u8* buffer, u32 buffer_size, Socket_Error* err_out);
s32 os_socket_set_listening(); s32 os_socket_set_listening();
s32 os_socket_send(); s32 os_socket_send();
s32 os_socket_send_to(Socket_Handle handle, u32 addr, u32 port, Data data, s32 flags); s32 os_socket_send_to(Socket_Handle handle, u32 addr, u32 port, Data data, s32 flags);
s32 os_socket_set_opt(Socket_Handle handle, int level, int option_name, s32 os_socket_set_opt(Socket_Handle handle, int level, int option_name,
u8* option_value, s32 option_len); u8* option_value, s32 option_len);
void open_sockets_init(); void open_sockets_init();

View File

@ -29,6 +29,8 @@
#include <string.h> #include <string.h>
#include <mach-o/dyld.h> #include <mach-o/dyld.h>
#include <mach/mach_time.h> #include <mach/mach_time.h>
#include <libkern/OSAtomic.h>
#include <pthread.h>
#include "../../libs/glfw_osx/include/GLFW/glfw3.h" #include "../../libs/glfw_osx/include/GLFW/glfw3.h"
@ -51,11 +53,12 @@ osx_err_print_(char* proc, char* sub_proc, s32 errsv)
#include "lumenarium_osx_time.h" #include "lumenarium_osx_time.h"
#include "lumenarium_osx_graphics.h" #include "lumenarium_osx_graphics.h"
#include "lumenarium_osx_network.h" #include "lumenarium_osx_network.h"
#include "lumenarium_osx_thread.h"
void void
glfw_error_callback(int error, const char* description) glfw_error_callback(int error, const char* description)
{ {
fprintf(stderr, "Error: %s\n", description); fprintf(stderr, "Error: %s\n", description);
} }
global u8* app_state_data = 0; global u8* app_state_data = 0;
@ -211,11 +214,11 @@ button_event(Key_Code key, int action, int mods)
.kind = WindowEvent_ButtonDown, .kind = WindowEvent_ButtonDown,
.key_code = key, .key_code = key,
}; };
if (has_flag(mods, GLFW_MOD_SHIFT)) add_flag(evt.key_flags, KeyFlag_Mod_Shift); if (has_flag(mods, GLFW_MOD_SHIFT)) add_flag(evt.key_flags, KeyFlag_Mod_Shift);
if (has_flag(mods, GLFW_MOD_CONTROL)) add_flag(evt.key_flags, KeyFlag_Mod_Shift); if (has_flag(mods, GLFW_MOD_CONTROL)) add_flag(evt.key_flags, KeyFlag_Mod_Shift);
if (has_flag(mods, GLFW_MOD_ALT)) add_flag(evt.key_flags, KeyFlag_Mod_Shift); if (has_flag(mods, GLFW_MOD_ALT)) add_flag(evt.key_flags, KeyFlag_Mod_Shift);
switch (action) switch (action)
{ {
case GLFW_PRESS: { evt.key_flags = KeyFlag_State_IsDown; } break; case GLFW_PRESS: { evt.key_flags = KeyFlag_State_IsDown; } break;
@ -272,16 +275,16 @@ int main (int arg_count, char** args)
return 1; return 1;
} }
glfwSetErrorCallback(glfw_error_callback); glfwSetErrorCallback(glfw_error_callback);
s32 init_window_width = 1400; s32 init_window_width = 1400 / 2;
s32 init_window_height = 700; s32 init_window_height = 700 / 2;
glfwWindowHint(GLFW_DOUBLEBUFFER, true); glfwWindowHint(GLFW_DOUBLEBUFFER, true);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, 1); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, 1);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
GLFWwindow* window = glfwCreateWindow(init_window_width, init_window_width, "Lumenarium", NULL, NULL); GLFWwindow* window = glfwCreateWindow(init_window_width, init_window_height, "Lumenarium", NULL, NULL);
if (!window) if (!window)
{ {
printf("Error: Unable to create a glfw window\n"); printf("Error: Unable to create a glfw window\n");
@ -290,29 +293,29 @@ int main (int arg_count, char** args)
glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);
glfwSwapInterval(1); glfwSwapInterval(1);
gl = osx_load_opengl_ext(); gl = osx_load_opengl_ext();
// Input Callbacks // Input Callbacks
glfwSetKeyCallback(window, key_callback); glfwSetKeyCallback(window, key_callback);
glfwSetMouseButtonCallback(window, mouse_button_callback); glfwSetMouseButtonCallback(window, mouse_button_callback);
glfwSetCursorPosCallback(window, cursor_position_callback); glfwSetCursorPosCallback(window, cursor_position_callback);
glfwSetScrollCallback(window, scroll_callback); glfwSetScrollCallback(window, scroll_callback);
Editor_Desc ed_desc = {}; Editor_Desc ed_desc = {};
float xscale, yscale; float xscale, yscale;
glfwGetWindowContentScale(window, &xscale, &yscale); glfwGetWindowContentScale(window, &xscale, &yscale);
ed_desc.content_scale = (v2){ xscale, yscale }; ed_desc.content_scale = (v2){ xscale, yscale };
ed_desc.init_window_dim = (v2){init_window_width, init_window_height}; ed_desc.init_window_dim = (v2){init_window_width, init_window_height};
App_State* state = lumenarium_init(&ed_desc); App_State* state = lumenarium_init(&ed_desc);
app_state_data = (u8*)state; app_state_data = (u8*)state;
bool running = true; bool running = true;
r64 target_seconds_per_frame = state->target_seconds_per_frame; r64 target_seconds_per_frame = state->target_seconds_per_frame;
Ticks ticks_start = os_get_ticks(); Ticks ticks_start = os_get_ticks();
while(!glfwWindowShouldClose(window) && running && has_flag(state->flags, AppState_IsRunning)) { while(!glfwWindowShouldClose(window) && running && has_flag(state->flags, AppState_IsRunning)) {
lumenarium_frame_prepare(state); lumenarium_frame_prepare(state);
glfwPollEvents(); glfwPollEvents();
if (has_flag(state->flags, AppState_RunEditor)) if (has_flag(state->flags, AppState_RunEditor))
{ {
s32 w, h; s32 w, h;
@ -322,7 +325,7 @@ int main (int arg_count, char** args)
lumenarium_frame(state); lumenarium_frame(state);
lumenarium_env_validate(); lumenarium_env_validate();
glfwSwapBuffers(window); glfwSwapBuffers(window);
Ticks ticks_end = os_get_ticks(); Ticks ticks_end = os_get_ticks();
@ -337,7 +340,7 @@ int main (int arg_count, char** args)
} }
ticks_start = ticks_end; ticks_start = ticks_end;
} }
lumenarium_cleanup(state); lumenarium_cleanup(state);
glfwDestroyWindow(window); glfwDestroyWindow(window);
glfwTerminate(); glfwTerminate();

View File

@ -10,7 +10,9 @@ File_Handle
os_file_open(String path, File_Access_Flags flags_access, File_Create_Flags flags_create) os_file_open(String path, File_Access_Flags flags_access, File_Create_Flags flags_create)
{ {
File_Handle result = {}; File_Handle result = {};
mode_t mode = 0;
s32 flags = 0; s32 flags = 0;
if (has_flag_exact(flags_access, (FileAccess_Read | FileAccess_Write))) if (has_flag_exact(flags_access, (FileAccess_Read | FileAccess_Write)))
{ {
@ -31,17 +33,29 @@ os_file_open(String path, File_Access_Flags flags_access, File_Create_Flags fla
return result; return result;
} }
} }
// This additional argument is required if we're creating a file
// if we want this process to be able to open it again later.
mode_t create_flags = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
switch (flags_create) switch (flags_create)
{ {
case FileCreate_New: { add_flag(flags, O_CREAT | O_EXCL ); } break; case FileCreate_New:
case FileCreate_CreateAlways: { add_flag(flags, O_CREAT); } break; {
add_flag(flags, O_CREAT | O_EXCL );
mode = create_flags;
} break;
case FileCreate_OpenExisting: { /* add_flag(flags, O_); */ } break; case FileCreate_OpenExisting: { /* add_flag(flags, O_); */ } break;
case FileCreate_OpenAlways: { /* add_flag(flags, O_); */ } break; case FileCreate_CreateAlways:
case FileCreate_OpenAlways:
{
add_flag(flags, O_CREAT);
mode = create_flags;
} break;
invalid_default_case; invalid_default_case;
} }
s32 file_handle = open((char*)path.str, flags); s32 file_handle = open((char*)path.str, flags, mode);
if (file_handle >= 0) if (file_handle >= 0)
{ {
result = open_files_put_handle(file_handle, path); result = open_files_put_handle(file_handle, path);
@ -49,7 +63,20 @@ os_file_open(String path, File_Access_Flags flags_access, File_Create_Flags fla
else else
{ {
s32 errsv = errno; s32 errsv = errno;
printf("Error: os_file_open - %d\n", errsv); printf("Error: os_file_open - %d - ", errsv);
switch (errsv) {
case EACCES: printf("EACCESS\n"); break;
case EBADF: printf("EBADF\n"); break;
case EBUSY: printf("EBUSY\n"); break;
case EDQUOT: printf("EDQUOT\n"); break;
case EEXIST: printf("EEXIST\n"); break;
case EFAULT: printf("EFAULT\n"); break;
case EFBIG: printf("EFBIG\n"); break;
case ENOMEM: printf("ENOMEM\n"); break;
case ENFILE: printf("ENFILE\n"); break;
case EINVAL: printf("EINVAL\n"); break;
default: printf("Unregistered error\n"); break;
}
printf("\tAttempting to open: %.*s\n", str_varg(path)); printf("\tAttempting to open: %.*s\n", str_varg(path));
printf("\tFlags: %u %u\n", flags_access, flags_create); printf("\tFlags: %u %u\n", flags_access, flags_create);
} }
@ -71,6 +98,16 @@ os_file_close(File_Handle file_handle)
} }
} }
bool
os_file_delete(String file_path)
{
if (remove((char*)file_path.str) != 0) {
perror("Error deleting file\n");
return false;
}
return true;
}
File_Info File_Info
os_file_get_info(File_Handle file_handle, Allocator* allocator) os_file_get_info(File_Handle file_handle, Allocator* allocator)
{ {
@ -79,7 +116,7 @@ os_file_get_info(File_Handle file_handle, Allocator* allocator)
if (os_handle != -1) if (os_handle != -1)
{ {
String path = open_files_get_path(file_handle); String path = open_files_get_path(file_handle);
struct stat os_info = {}; struct stat os_info = {};
if (fstat(os_handle, &os_info) != -1) if (fstat(os_handle, &os_info) != -1)
{ {
@ -119,7 +156,7 @@ os_file_read_all(File_Handle file_handle, Allocator* allocator)
Data result = {}; Data result = {};
s32 os_handle = open_files_get_handle(file_handle); s32 os_handle = open_files_get_handle(file_handle);
if (os_handle == -1) return result; if (os_handle == -1) return result;
// get file size // get file size
s32 offset = lseek(os_handle, 0, SEEK_END); s32 offset = lseek(os_handle, 0, SEEK_END);
if (offset == -1) if (offset == -1)
@ -129,10 +166,10 @@ os_file_read_all(File_Handle file_handle, Allocator* allocator)
return result; return result;
} }
lseek(os_handle, 0, SEEK_SET); lseek(os_handle, 0, SEEK_SET);
result.base = allocator_alloc(allocator, offset + 1); result.base = allocator_alloc(allocator, offset + 1);
result.size = offset + 1; result.size = offset + 1;
s32 bytes_read = read(os_handle, result.base, result.size); s32 bytes_read = read(os_handle, result.base, result.size);
if (bytes_read == (result.size - 1)) if (bytes_read == (result.size - 1))
{ {
@ -165,7 +202,7 @@ os_file_write_(s32 os_handle, Data file_data)
osx_err_print("write"); osx_err_print("write");
return false; return false;
} }
return true; return true;
} }
@ -174,7 +211,7 @@ os_file_write_all(File_Handle file_handle, Data file_data)
{ {
s32 os_handle = open_files_get_handle(file_handle); s32 os_handle = open_files_get_handle(file_handle);
if (os_handle == -1) return false; if (os_handle == -1) return false;
lseek(os_handle, 0, SEEK_SET); lseek(os_handle, 0, SEEK_SET);
return os_file_write_(os_handle, file_data); return os_file_write_(os_handle, file_data);
} }
@ -184,7 +221,7 @@ os_file_write(File_Handle file_handle, Data file_data)
{ {
s32 os_handle = open_files_get_handle(file_handle); s32 os_handle = open_files_get_handle(file_handle);
if (os_handle == -1) return false; if (os_handle == -1) return false;
return os_file_write_(os_handle, file_data); return os_file_write_(os_handle, file_data);
} }
@ -193,7 +230,7 @@ os_get_exe_path(Allocator* allocator)
{ {
u32 needed = 0; u32 needed = 0;
_NSGetExecutablePath(0, &needed); _NSGetExecutablePath(0, &needed);
String result = allocator_alloc_string(allocator, needed + 1); String result = allocator_alloc_string(allocator, needed + 1);
u32 cap = (u64)result.cap; u32 cap = (u64)result.cap;
@ -203,7 +240,7 @@ os_get_exe_path(Allocator* allocator)
result.len = cap; result.len = cap;
result.str[result.len] = 0; result.str[result.len] = 0;
} }
return result; return result;
} }
@ -223,6 +260,6 @@ os_pwd_set(String path)
File_Info_List File_Info_List
os_dir_enum(String path, Platform_Enum_Dir_Flags flags, Allocator* allocator) os_dir_enum(String path, Platform_Enum_Dir_Flags flags, Allocator* allocator)
{ {
} }
#endif #endif

View File

@ -1,3 +1,15 @@
static Socket_Error os_osx_socket_error_translation_table[] = {
[EAGAIN] = SocketError_EAGAIN,
[EBADF] = SocketError_EBADF,
[ECONNREFUSED] = SocketError_ECONNREFUSED,
[EFAULT] = SocketError_EFAULT,
[EINTR] = SocketError_EINTR,
[EINVAL] = SocketError_EINVAL,
[ENOMEM] = SocketError_ENOMEM,
[ENOTCONN] = SocketError_ENOTCONN,
[ENOTSOCK] = SocketError_ENOTSOCK,
};
Socket_Handle Socket_Handle
os_socket_create(s32 domain, s32 type, s32 protocol) os_socket_create(s32 domain, s32 type, s32 protocol)
{ {
@ -17,9 +29,21 @@ os_socket_create(s32 domain, s32 type, s32 protocol)
} }
bool bool
os_socket_bind() os_socket_bind(Socket_Handle socket, u32 port)
{ {
return false; OS_SOCKET_TYPE sock = open_sockets_get(socket);
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_addr.s_addr = INADDR_ANY,
.sin_port = htons(port),
};
s32 bind_res = bind(sock, (struct sockaddr*)&addr, sizeof(addr));
if (bind_res < 0) {
printf("ERROR: os_socket_bind - %d\n", bind_res);
return false;
}
return true;
} }
bool bool
@ -29,9 +53,11 @@ os_socket_connect()
} }
bool bool
os_socket_close() os_socket_close(Socket_Handle handle)
{ {
return false; OS_SOCKET_TYPE sock = open_sockets_get(handle);
close(sock);
return true;
} }
Data Data
@ -40,6 +66,57 @@ os_socket_recv()
return (Data){}; return (Data){};
} }
Data
os_socket_recvfrom(Socket_Handle handle, u8* buffer, u32 buffer_size, Socket_Error* err_out)
{
OS_SOCKET_TYPE sock = open_sockets_get(handle);
Data result = {
.base = buffer,
.size = buffer_size,
};
struct sockaddr from = {};
s32 from_len = sizeof(from);
// TODO: Look into MSG_PEEK - there might be a way to determine
// the size of the packet without losing it, even on UDP/SOCK_DGRAM
// connections
s32 flags = 0;
s32 r = recvfrom(
sock,
result.base,
result.size,
flags,
&from,
(socklen_t*)&from_len
);
if (r < 0) {
if (err_out) {
*err_out = os_osx_socket_error_translation_table[errno];
} else {
printf("UNHANDLED ERROR: os_socket_recvfrom\n\t");
switch (errno)
{
case EAGAIN: printf("EAGAIN\n"); break;
case EBADF: printf("EBADF\n"); break;
case ECONNREFUSED: printf("ECONNREFUSED\n"); break;
case EFAULT: printf("EFAULT\n"); break;
case EINTR: printf("EINTR\n"); break;
case EINVAL: printf("EINVAL\n"); break;
case ENOMEM: printf("ENOMEM\n"); break;
case ENOTCONN: printf("ENOTCONN\n"); break;
case ENOTSOCK: printf("ENOTSOCK\n"); break;
default: { printf("%d\n", errno); } break;
}
}
}
result.size = r;
return result;
}
s32 s32
os_socket_set_listening() os_socket_set_listening()
{ {

View File

@ -0,0 +1,120 @@
/* date = August 13th 2022 1:57 pm */
#ifndef LUMENARIUM_OSX_THREAD_H
#define LUMENARIUM_OSX_THREAD_H
typedef struct Os_Osx_Thread Os_Osx_Thread;
struct Os_Osx_Thread
{
pthread_t thread;
Thread_Proc* proc;
u8* user_data;
Thread_Result result;
};
#define OSX_THREAD_CAP 8
global Os_Osx_Thread osx_threads_[OSX_THREAD_CAP];
global u32 osx_threads_len_;
void*
os_thread_proc_wrapper(void* arg)
{
// Call the actual thread function
// This is essentially a blocking call for the rest of this function
Os_Osx_Thread* thread_data = (Os_Osx_Thread*)arg;
thread_data->result = thread_data->proc(thread_data->user_data);
// Clean up this threads thread slot so other threads
// can use it
thread_data->proc = 0;
thread_data->user_data = 0;
pthread_exit(&thread_data->result);
}
Thread_Handle
os_thread_begin(Thread_Proc* proc, u8* user_data)
{
// Find an unused thread slot
Thread_Handle result = { .value = 0 };
if (osx_threads_len_ < OSX_THREAD_CAP)
{
result = (Thread_Handle){ .value = osx_threads_len_++ };
}
else
{
bool found = false;
for (u32 i = 0; i < OSX_THREAD_CAP; i++)
{
if (osx_threads_[i].proc == 0)
{
result.value = i;
found = true;
}
}
if (!found) {
printf("ERROR: Unable to create thread.\n");
invalid_code_path;
}
}
// Initialize Thread Slot
Os_Osx_Thread* t = osx_threads_ + result.value;
*t = (Os_Osx_Thread){
.proc = proc,
.user_data = user_data
};
// Create PThread
s32 create_error = pthread_create(
&t->thread,
NULL, // use default attrs
(void * _Nullable (* _Nonnull)(void * _Nullable))proc,
user_data
);
if (create_error)
{
switch (create_error) {
case EAGAIN: {
} break;
case EINVAL: {
} break;
// case ELEMULTITHREADFORK: {
// } break;
case ENOMEM: {
} break;
}
}
return result;
}
void
os_thread_end(Thread_Handle thread_handle)
{
Os_Osx_Thread* t = osx_threads_ + thread_handle.value;
pthread_kill(t->thread, 0);
}
u32
os_interlocked_increment(volatile u32* value)
{
assert(*value <= s32_max);
u32 result = OSAtomicIncrement32((volatile s32*)value);
return result;
}
bool
os_interlocked_cmp_exchg(volatile u32* dest, u32 old_value, u32 new_value)
{
assert(*dest <= s32_max);
bool result = OSAtomicCompareAndSwapInt((s32)old_value, (s32)new_value, (volatile s32*)dest);
return result;
}
#endif //LUMENARIUM_OSX_THREAD_H

View File

@ -6,7 +6,7 @@
# error "You must define an OS_SOCKET_INVALID_HANDLE" # error "You must define an OS_SOCKET_INVALID_HANDLE"
#endif #endif
#define open_sockets_cap 2 #define open_sockets_cap 3
global u32 open_sockets_len = 1; global u32 open_sockets_len = 1;
global OS_SOCKET_TYPE open_sockets[open_sockets_cap]; global OS_SOCKET_TYPE open_sockets[open_sockets_cap];

View File

@ -129,8 +129,8 @@ int main (int arg_c, char** args)
cvtcsv_convert("question_1"); cvtcsv_convert("question_1");
cvtcsv_convert("question_2"); cvtcsv_convert("question_2");
cvtcsv_convert("question_3"); cvtcsv_convert("question_3");
//cvtcsv_convert("question_4"); cvtcsv_convert("question_4");
//cvtcsv_convert("question_5"); cvtcsv_convert("question_5");
cvtcsv_convert("question_6"); cvtcsv_convert("question_6");
cvtcsv_convert("question_7"); cvtcsv_convert("question_7");
cvtcsv_convert("question_8"); cvtcsv_convert("question_8");
@ -146,6 +146,7 @@ int main (int arg_c, char** args)
cvtcsv_convert("question_18"); cvtcsv_convert("question_18");
cvtcsv_convert("question_19"); cvtcsv_convert("question_19");
cvtcsv_convert("question_20"); cvtcsv_convert("question_20");
cvtcsv_convert("question_21");

View File

@ -0,0 +1,224 @@
internal void incenter_handle_interface_msg(Incenter_State* ins, Data msg);
void
incenter_interface_connection_cleanup(Incenter_State* ins)
{
if (ins->interface_socket.value == 0) return;
if (!os_socket_close(ins->interface_socket)) {
printf("Error closing interface connection socket\n");
}
ins->interface_socket = (Socket_Handle){0};
printf("Incenter Interface Socket Connection Closed.\n");
}
Thread_Result
incenter_interface_connection_thread_proc(u8* user_data)
{
Incenter_State* ins = (Incenter_State*)user_data;
// Open Socket Connection To Server
ins->interface_socket = os_socket_create(
AF_INET, // IPv4
SOCK_DGRAM,
0
);
// Bind the socket to the correct address
if (!os_socket_bind(ins->interface_socket, 1337)) {
printf("ERROR: Unable to bind incenter interface socket\n");
return (Thread_Result){ 0 };
}
// Message Recv Loop
while (ins->running)
{
u32 next_msg_i = ins->interface_messages_write_next;
Data* next_msg = ins->interface_messages + next_msg_i;
next_msg->size = INTERFACE_MESSAGE_SIZE; // reset buffer of known size
Socket_Error err = SocketError_NOERROR;
*next_msg = os_socket_recvfrom(ins->interface_socket, next_msg->base, next_msg->size, &err);
if (err == SocketError_EBADF && ins->running) {
if (!os_socket_close(ins->interface_socket)) {
printf("Trying to close interface socket before reopening. Socket was already closed.\n");
}
ins->interface_socket = os_socket_create(AF_INET, SOCK_DGRAM, 0);
}
if (err == SocketError_NOERROR) {
next_msg->base[next_msg->size] = 0;
// write_next isn't incremented until here because the message
// is not ready to be read until this point
ins->interface_messages_write_next = (ins->interface_messages_write_next + 1) % INTERFACE_MESSAGES_CAP;
}
}
// Close Down once Incenter indicates it's time to stop running
incenter_interface_connection_cleanup(ins);
return (Thread_Result){ 0 };
}
internal void
incenter_interface_connection_init(App_State* state, Incenter_State* ins)
{
// Start Thread to handle blocking socket calls
ins->interface_thread = os_thread_begin(incenter_interface_connection_thread_proc, (u8*)ins);
for (u32 msg_i = 0; msg_i < INTERFACE_MESSAGES_CAP; msg_i++)
{
ins->interface_messages[msg_i] = (Data){
.base = allocator_alloc(permanent, INTERFACE_MESSAGE_SIZE),
.size = INTERFACE_MESSAGE_SIZE,
};
}
}
internal void
incenter_interface_connection_frame(App_State* state, Incenter_State* ins)
{
while (ins->interface_messages_write_next != ins->interface_messages_read_next)
{
u32 read_next = ins->interface_messages_read_next;
ins->interface_messages_read_next = (read_next + 1) % INTERFACE_MESSAGES_CAP;
Data msg_read = ins->interface_messages[read_next];
printf("Handling message on the main thread\n");
printf(" %s\n", (char*)msg_read.base);
incenter_handle_interface_msg(ins, msg_read);
}
}
#define INCENTER_CMP3(base, str) ((base[0] == str[0]) && (base[1] == str[1]) && (base[2] == str[2]))
internal void
incenter_handle_sliding_scale_msg(Incenter_State* ins, Incenter_Scene scene, char msg)
{
assert(scene.kind == Incenter_SceneKind_SlidingScale);
if (msg != 'M' && msg != 'L' && msg != 'C') {
printf("Invalid input sent to sliding scale scene: %c\n", msg);
printf(" Scene: %s\n", scene.name);
return;
}
switch (msg) {
case 'M': {
ins->input_pct += 0.1f;
} break;
case 'L': {
ins->input_pct -= 0.1f;
} break;
case 'C': {
live_answers_input_r32(ins, scene, ins->input_pct);
ins->scene_mode = Incenter_SceneMode_Passive;
} break;
}
ins->input_pct = clamp(0, ins->input_pct, 1);
}
internal void
incenter_handle_yes_no_msg(Incenter_State* ins, Incenter_Scene scene, char msg)
{
assert(scene.kind == Incenter_SceneKind_YesOrNo);
if (msg != 'Y' && msg != 'N') {
printf("Invalid input sent to yes no scene: %c\n", msg);
printf(" Scene: %s\n", scene.name);
return;
}
switch (msg) {
case 'Y': {
ins->input_option = 1;
} break;
case 'N': {
ins->input_option = 0;
} break;
}
live_answers_input_u32(ins, scene, ins->input_option);
ins->scene_mode = Incenter_SceneMode_Passive;
}
internal void
incenter_handle_three_option_msg(Incenter_State* ins, Incenter_Scene scene, char msg)
{
assert(scene.kind == Incenter_SceneKind_ThreeOption);
if (msg != '1' && msg != '2' && msg != '3') {
printf("Invalid input sent to 3 option scene: %c\n", msg);
printf(" Scene: %s\n", scene.name);
return;
}
ins->input_option = (msg - '0') - 1;
live_answers_input_u32(ins, scene, ins->input_option);
ins->scene_mode = Incenter_SceneMode_Passive;
}
internal void
incenter_handle_interface_msg(Incenter_State* ins, Data msg)
{
u32 msg_kind = Incenter_InterfaceMessage_Invalid;
u32 scene_id = 0;
if (INCENTER_CMP3(msg.base, "UIN")) {
msg_kind = Incenter_InterfaceMessage_UserInput;
} else if (INCENTER_CMP3(msg.base, "GTS")){
msg_kind = Incenter_InterfaceMessage_GoToScene;
char* scene_id_start = (char*)(msg.base + 3);
scene_id = scene_id_start[0] - '0';
if (scene_id_start[1] != 0) {
scene_id *= 10;
scene_id += scene_id_start[1] - '0';
}
}
switch (msg_kind)
{
case Incenter_InterfaceMessage_GoToScene:
{
if (scene_id > Incenter_Scene_Invalid &&
scene_id < Incenter_Scene_Count)
{
if (scene_id != ins->scene_at) {
incenter_scene_go_to(ins, scene_id);
}
}
else
{
printf("Unknown Scene ID Requested: %d\n", scene_id);
}
} break;
case Incenter_InterfaceMessage_UserInput:
{
Incenter_Scene scene = ins->scenes[ins->scene_at];
char input_kind = msg.base[3];
switch (scene.kind) {
case Incenter_SceneKind_SlidingScale: {
incenter_handle_sliding_scale_msg(ins, scene, input_kind);
} break;
case Incenter_SceneKind_YesOrNo: {
incenter_handle_yes_no_msg(ins, scene, input_kind);
} break;
case Incenter_SceneKind_ThreeOption: {
incenter_handle_three_option_msg(ins, scene, input_kind);
} break;
}
} break;
default:
{
printf("Unknown message kind: %d\n", msg_kind);
// TODO: Print the actual message received
} break;
}
}

View File

@ -0,0 +1,13 @@
/* date = August 11th 2022 5:38 pm */
#ifndef INCENTER_INTERFACE_CONNECTION_H
#define INCENTER_INTERFACE_CONNECTION_H
enum {
Incenter_InterfaceMessage_Invalid = 0,
Incenter_InterfaceMessage_GoToScene = 1,
Incenter_InterfaceMessage_UserInput = 2,
};
#endif //INCENTER_INTERFACE_CONNECTION_H

View File

@ -0,0 +1,216 @@
internal void
live_answers_set_magic(char dst[4], char value[4])
{
dst[0] = value[0];
dst[1] = value[1];
dst[2] = value[2];
dst[3] = value[3];
}
internal bool
live_answers_valid_magic(char dst[4], char value[4])
{
return ((dst[0] == value[0]) &&
(dst[1] == value[1]) &&
(dst[2] == value[2]) &&
(dst[3] == value[3]));
}
internal void
live_answers_init_bucket_u32(Live_Answers_File_Bucket* bucket, u32 answer, u32 count)
{
live_answers_set_magic((char*)bucket->magic, LIVE_DATA_BUCKET_MAGIC_NUMBER);
bucket->answer_u32 = answer;
bucket->count = count;
}
internal void
live_answers_init_bucket_r32(Live_Answers_File_Bucket* bucket, r32 answer, u32 count)
{
live_answers_set_magic((char*)bucket->magic, LIVE_DATA_BUCKET_MAGIC_NUMBER);
bucket->answer_r32 = answer;
bucket->count = count;
}
internal bool
live_answers_validate(Live_Answers_File file)
{
bool valid = true;
if (!live_answers_valid_magic((char*)file.header->magic, LIVE_DATA_HEADER_MAGIC_NUMBER)) {
printf("Error: Live Answers File has corrupted header.\n");
valid = false;
}
// if there was an error in the header, we can't assume that the count
// its keeping of the number of buckets is correct
if (valid)
{
for (u32 i = 0; i < file.header->buckets_count; i++)
{
Live_Answers_File_Bucket* b = file.buckets + i;
if (!live_answers_valid_magic((char*)b->magic, LIVE_DATA_BUCKET_MAGIC_NUMBER))
{
printf("Error: Live Answers Bucket has corrupted header.\n");
valid = false;
}
}
}
if (!valid)
{
printf(" Invalid Live Answers File: %.*s\n", str_varg(file.path));
}
return valid;
}
internal Live_Answers_File
live_answers_load(Incenter_Scene scene, Allocator* allocator)
{
Live_Answers_File result = {0};
// Read the File
result.path = string_f(allocator, "data/live_data/%s.incenterdata", scene.name);
File_Handle file = os_file_open(result.path, FileAccess_Read, FileCreate_OpenExisting);
Data file_data = {0};
if (file.value != 0)
{
file_data = os_file_read_all(file, allocator);
os_file_close(file);
}
// Obtain structure of file data
if (file_data.size > 1) {
result.header = (Live_Answers_File_Header*)file_data.base;
result.buckets = (Live_Answers_File_Bucket*)(result.header + 1);
} else {
// create the file's initial contents
file_data.size = sizeof(Live_Answers_File_Header);
file_data.base = allocator_alloc(allocator, file_data.size);
// obtain structure
result.header = (Live_Answers_File_Header*)file_data.base;
result.buckets = (Live_Answers_File_Bucket*)(result.header + 1);
// initialize
live_answers_set_magic((char*)result.header->magic, LIVE_DATA_HEADER_MAGIC_NUMBER);
result.header->buckets_count = 0;
result.header->answers_total_count = 0;
}
if (!live_answers_validate(result)) {
return (Live_Answers_File){0};
}
return result;
}
internal void
live_answers_save(Live_Answers_File file, Live_Answers_File_Bucket* new_bucket)
{
if (!live_answers_validate(file)) {
printf(" Not saving invalid live answers data\n");
return;
}
File_Handle fh = os_file_open(file.path, FileAccess_Write, FileCreate_OpenAlways);
if (fh.value == 0) {
printf("Error: Unable to open live data file for writing\n");
printf(" Live Data File: %.*s\n", str_varg(file.path));
// TODO(PS): maybe print out what the values should be so we can
// recover if necessary?
return;
}
Data existing_data = {
.base = (u8*)file.header,
.size = sizeof(Live_Answers_File_Header) + (sizeof(Live_Answers_File_Bucket) * file.header->buckets_count)
};
if (!os_file_write(fh, existing_data)) {
printf("Error: Could not write existing data to Live Data File\n");
printf(" Live Data File: %.*s\n", str_varg(file.path));
}
if (new_bucket) {
Data new_data = {
.base = (u8*)new_bucket,
.size = sizeof(Live_Answers_File_Bucket)
};
if (!os_file_write(fh, new_data)) {
printf("Error: Could not write new bucket data to Live Data File\n");
printf(" Live Data File: %.*s\n", str_varg(file.path));
}
}
os_file_close(fh);
}
internal void
live_answers_input_u32(Incenter_State* ins, Incenter_Scene scene, u32 value)
{
scratch_get(scratch);
Live_Answers_File file = live_answers_load(scene, scratch.a);
if (file.header == 0) {
printf("Unable to save live data file\n");
return;
}
bool found = false;
for (u32 i = 0; i < file.header->buckets_count; i++)
{
Live_Answers_File_Bucket* b = file.buckets + i;
if (b->answer_u32 == value) {
b->count += 1;
found = true;
break;
}
}
Live_Answers_File_Bucket* new_bucket = 0;
if (!found) {
new_bucket = allocator_alloc_struct(scratch.a, Live_Answers_File_Bucket);
live_answers_init_bucket_u32(new_bucket, value, 1);
file.header->buckets_count += 1;
}
file.header->answers_total_count += 1;
live_answers_save(file, new_bucket);
scratch_release(scratch);
}
internal void
live_answers_input_r32(Incenter_State* ins, Incenter_Scene scene, r32 value)
{
scratch_get(scratch);
Live_Answers_File file = live_answers_load(scene, scratch.a);
if (file.header == 0) {
printf("Unable to save live data file\n");
return;
}
bool found = false;
for (u32 i = 0; i < file.header->buckets_count; i++)
{
Live_Answers_File_Bucket* b = file.buckets + i;
if (b->answer_r32 == value) {
b->count += 1;
found = true;
break;
}
}
Live_Answers_File_Bucket* new_bucket = 0;
if (!found) {
new_bucket = allocator_alloc_struct(scratch.a, Live_Answers_File_Bucket);
live_answers_init_bucket_r32(new_bucket, value, 1);
}
live_answers_save(file, new_bucket);
scratch_release(scratch);
}

View File

@ -27,7 +27,7 @@ pattern_debug(Assembly_Pixel_Buffer pixels)
{ {
r32 scale = 6; r32 scale = 6;
r32 offset = 0; r32 offset = 0;
for (u32 j = 0; j < pixels.len; j++) for (u32 j = 0; j < pixels.len; j++)
{ {
v4 p = pixels.positions[j]; v4 p = pixels.positions[j];
@ -145,13 +145,13 @@ sun_center_for_pos(v4 p, v4 center, r32 radius, r32 falloff)
r32 d0 = HMM_LengthVec4(HMM_SubtractVec4(p_unit, center)); r32 d0 = HMM_LengthVec4(HMM_SubtractVec4(p_unit, center));
r32 d1 = falloff - fabsf(d0 - (radius + (0.02f * sinf(tt)))); r32 d1 = falloff - fabsf(d0 - (radius + (0.02f * sinf(tt))));
r32 b = d1 / falloff; r32 b = d1 / falloff;
v3 result = {}; v3 result = {};
if (b > 0) if (b > 0)
{ {
v3 p0 = p.xyz; v3 p0 = p.xyz;
v3 p1 = HMM_AddVec3(p0, (v3){ tt, -tt, 0 }); v3 p1 = HMM_AddVec3(p0, (v3){ tt, -tt, 0 });
v3 color = { v3 color = {
.x = remap_r32(pm_fmb_3d(p0, tt), 0, 1, 0.5, 1), .x = remap_r32(pm_fmb_3d(p0, tt), 0, 1, 0.5, 1),
.y = remap_r32(pm_noise_v3_to_r32(p1), 0, 1, 0, 0.3f), .y = remap_r32(pm_noise_v3_to_r32(p1), 0, 1, 0, 0.3f),
@ -170,17 +170,17 @@ sun_center(Assembly_Pixel_Buffer pixels, v4 center, r32 radius, r32 falloff)
v3 color = sun_center_for_pos(pixels.positions[j], center, radius, falloff); v3 color = sun_center_for_pos(pixels.positions[j], center, radius, falloff);
Assembly_Pixel ac = color_v3_to_assembly_pixel(color); Assembly_Pixel ac = color_v3_to_assembly_pixel(color);
pixels.pixels[j] = assembly_pixel_add(ac, pixels.pixels[j]); pixels.pixels[j] = assembly_pixel_add(ac, pixels.pixels[j]);
#if 0 #if 0
r32 d0 = HMM_LengthVec4(HMM_SubtractVec4(p, center)); r32 d0 = HMM_LengthVec4(HMM_SubtractVec4(p, center));
r32 d1 = falloff - fabsf(d0 - (radius + (0.02f * sinf(tt)))); r32 d1 = falloff - fabsf(d0 - (radius + (0.02f * sinf(tt))));
r32 b = d1 / falloff; r32 b = d1 / falloff;
if (b > 0) if (b > 0)
{ {
v3 p0 = pixels.positions[j].xyz; v3 p0 = pixels.positions[j].xyz;
v3 p1 = HMM_AddVec3(p0, (v3){ tt, -tt, 0 }); v3 p1 = HMM_AddVec3(p0, (v3){ tt, -tt, 0 });
v3 color = { v3 color = {
.x = remap_r32(pm_fmb_3d(p0, tt), 0, 1, 0.5, 1), .x = remap_r32(pm_fmb_3d(p0, tt), 0, 1, 0.5, 1),
.y = remap_r32(pm_noise_v3_to_r32(p1), 0, 1, 0, 0.3f), .y = remap_r32(pm_noise_v3_to_r32(p1), 0, 1, 0, 0.3f),
@ -192,7 +192,7 @@ sun_center(Assembly_Pixel_Buffer pixels, v4 center, r32 radius, r32 falloff)
Assembly_Pixel color_1 = assembly_pixel_add(color_0, pixels.pixels[j]); Assembly_Pixel color_1 = assembly_pixel_add(color_0, pixels.pixels[j]);
pixels.pixels[j] = color_1; pixels.pixels[j] = color_1;
} }
#endif #endif
} }
} }
@ -207,7 +207,7 @@ grow_pattern_sphere_function(Assembly_Pixel_Buffer pixels, v4 center, r32 radius
r32 d2 = falloff - d1; r32 d2 = falloff - d1;
r32 b = d2 / falloff; r32 b = d2 / falloff;
r32 inner_b = d0 < (radius - falloff) ? 1 : 0; r32 inner_b = d0 < (radius - falloff) ? 1 : 0;
v3 color = { v3 color = {
.x = 0.5f + 0.5f * sinf(p.x * r32_tau * 4.313f + tt * 1.3f), .x = 0.5f + 0.5f * sinf(p.x * r32_tau * 4.313f + tt * 1.3f),
.y = 0.5f + 0.5f * cosf(0.2314f + p.y * r32_tau * 3.915f + tt), .y = 0.5f + 0.5f * cosf(0.2314f + p.y * r32_tau * 3.915f + tt),
@ -243,7 +243,7 @@ grow_pattern(Assembly_Pixel_Buffer pixels, r32 time, Assembly_Pixel inner_color)
radius = 0.05f + curve_ease_in_out(t) * 0.6f; radius = 0.05f + curve_ease_in_out(t) * 0.6f;
falloff = 0.1f - (curve_ease_in_out(t) * 0.05f); falloff = 0.1f - (curve_ease_in_out(t) * 0.05f);
} }
grow_pattern_sphere_function(pixels, center, radius, falloff, inner_color); grow_pattern_sphere_function(pixels, center, radius, falloff, inner_color);
} }
@ -300,7 +300,7 @@ test_data_find_nearest_row(Incenter_City_Id city, u32 year, Incenter_Month_Id mo
{ {
Incenter_Test_Data_Row row = test_data[i]; Incenter_Test_Data_Row row = test_data[i];
if (row.city != city) continue; if (row.city != city) continue;
s32 row_months = (row.year * 12) + row.month; s32 row_months = (row.year * 12) + row.month;
s32 months_offset = months - row_months; s32 months_offset = months - row_months;
if (months_offset < nearest && months_offset >= 0) { if (months_offset < nearest && months_offset >= 0) {
@ -322,10 +322,10 @@ void
pattern_test_data_scene_hombre(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Assembly_Pixel color_before_a, Assembly_Pixel color_before_b, Assembly_Pixel color_at, Assembly_Pixel color_after) pattern_test_data_scene_hombre(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Assembly_Pixel color_before_a, Assembly_Pixel color_before_b, Assembly_Pixel color_at, Assembly_Pixel color_after)
{ {
Incenter_Test_Data_Row* rows = test_data; Incenter_Test_Data_Row* rows = test_data;
r32 rand_min = 1000; r32 rand_min = 1000;
r32 rand_max = -1000; r32 rand_max = -1000;
r32 month_delta = 1.0f / 24.0f; r32 month_delta = 1.0f / 24.0f;
if (month >= 11) { if (month >= 11) {
s32 x = 5; s32 x = 5;
@ -336,7 +336,7 @@ pattern_test_data_scene_hombre(Assembly_Pixel_Buffer pixels, Assembly_Strip_Arra
s32 data_row = test_data_find_nearest_row(city, year, month); s32 data_row = test_data_find_nearest_row(city, year, month);
if (data_row < 0) continue; if (data_row < 0) continue;
s32 data_row_next = data_row + 1; s32 data_row_next = data_row + 1;
Incenter_Test_Data_Row row_curr = test_data[data_row]; Incenter_Test_Data_Row row_curr = test_data[data_row];
r32 target_p = test_data[data_row].value_0; r32 target_p = test_data[data_row].value_0;
if (data_row_next < test_data_len) { if (data_row_next < test_data_len) {
@ -346,15 +346,15 @@ pattern_test_data_scene_hombre(Assembly_Pixel_Buffer pixels, Assembly_Strip_Arra
r32 row_curr_months = (r32)((row_curr.year * 12) + row_curr.month); r32 row_curr_months = (r32)((row_curr.year * 12) + row_curr.month);
r32 row_next_months = (r32)((row_next.year * 12) + row_next.month); r32 row_next_months = (r32)((row_next.year * 12) + row_next.month);
r32 curr_months = (r32)(year * 12) + month; r32 curr_months = (r32)(year * 12) + month;
r32 row_month_delta = row_next_months - row_curr_months; r32 row_month_delta = row_next_months - row_curr_months;
r32 delta_from_row_curr = curr_months - row_curr_months; r32 delta_from_row_curr = curr_months - row_curr_months;
r32 theta = delta_from_row_curr / row_month_delta; r32 theta = delta_from_row_curr / row_month_delta;
target_p = lerp(row_curr.value_0 * 0.8f, theta, row_next.value_0 * 0.8f); target_p = lerp(row_curr.value_0 * 0.8f, theta, row_next.value_0 * 0.8f);
} }
} }
r32 last_value = city_last_values[city]; r32 last_value = city_last_values[city];
r32 dist_to_target = (target_p - last_value); r32 dist_to_target = (target_p - last_value);
r32 towards_target = dist_to_target > 0 ? 1 : -1; r32 towards_target = dist_to_target > 0 ? 1 : -1;
@ -365,15 +365,15 @@ pattern_test_data_scene_hombre(Assembly_Pixel_Buffer pixels, Assembly_Strip_Arra
r32 max_vel = 0.01f; r32 max_vel = 0.01f;
r32 force_damping = -max(1 - dist_to_target, 0) * (city_last_vel[city]); r32 force_damping = -max(1 - dist_to_target, 0) * (city_last_vel[city]);
city_last_vel[city] = clamp(-1 * max_vel, city_last_vel[city] + force_damping, max_vel); city_last_vel[city] = clamp(-1 * max_vel, city_last_vel[city] + force_damping, max_vel);
city_last_values[city] += city_last_vel[city]; city_last_values[city] += city_last_vel[city];
for (u32 led = 0; led < strip.pixels_len; led++) for (u32 led = 0; led < strip.pixels_len; led++)
{ {
r32 pct = (r32)(strip.pixels_len - led) / (r32)strip.pixels_len; r32 pct = (r32)(strip.pixels_len - led) / (r32)strip.pixels_len;
u32 led_index = strip.pixels[led]; u32 led_index = strip.pixels[led];
v4 led_pos = incenter_pos_to_unit(pixels.positions[led_index]); v4 led_pos = incenter_pos_to_unit(pixels.positions[led_index]);
// max(-|pct -pct_r|, 0) ^ 10 // max(-|pct -pct_r|, 0) ^ 10
r32 d0 = (-1 * fabsf(city_last_values[city] - pct)) + 1; r32 d0 = (-1 * fabsf(city_last_values[city] - pct)) + 1;
r32 d1 = max(0, d0); r32 d1 = max(0, d0);
@ -383,24 +383,24 @@ pattern_test_data_scene_hombre(Assembly_Pixel_Buffer pixels, Assembly_Strip_Arra
r32 at_noise = pm_fmb_3d(noise_pos0, 1); r32 at_noise = pm_fmb_3d(noise_pos0, 1);
at_noise = pm_smoothstep_r32(at_noise); at_noise = pm_smoothstep_r32(at_noise);
r32 d3 = d2; r32 d3 = d2;
v3 noise_pos1 = HMM_MultiplyVec3f(HMM_AddVec3(led_pos.xyz, (v3){237, 111 + (tt * 0.3f), 923}), 16); v3 noise_pos1 = HMM_MultiplyVec3f(HMM_AddVec3(led_pos.xyz, (v3){237, 111 + (tt * 0.3f), 923}), 16);
r32 inner_noise = pm_smoothstep_r32(pm_fmb_3d(noise_pos1, 1)); r32 inner_noise = pm_smoothstep_r32(pm_fmb_3d(noise_pos1, 1));
r32 before = pct < city_last_values[city] ? d2_inverse : 0; r32 before = pct < city_last_values[city] ? d2_inverse : 0;
r32 after = pct > city_last_values[city] ? d2_inverse : 0; r32 after = pct > city_last_values[city] ? d2_inverse : 0;
Assembly_Pixel color_before_ = assembly_pixel_scale( Assembly_Pixel color_before_ = assembly_pixel_scale(
assembly_pixel_blend(color_before_a, color_before_b, at_noise * at_noise * at_noise), assembly_pixel_blend(color_before_a, color_before_b, at_noise * at_noise * at_noise),
before before
); );
Assembly_Pixel color_after_ = assembly_pixel_scale(color_after, after - (0.8f * inner_noise)); Assembly_Pixel color_after_ = assembly_pixel_scale(color_after, after - (0.8f * inner_noise));
Assembly_Pixel color_at_ = assembly_pixel_scale(color_at, d3); Assembly_Pixel color_at_ = assembly_pixel_scale(color_at, d3);
pixels.pixels[led_index] = assembly_pixel_add_multi(3, color_before_, color_after_, color_at_); pixels.pixels[led_index] = assembly_pixel_add_multi(3, color_before_, color_after_, color_at_);
} }
} }
month += month_delta; month += month_delta;
if (month > (r32)MONTH_Dec + 1) { if (month > (r32)MONTH_Dec + 1) {
month = (r32)MONTH_Jan; month = (r32)MONTH_Jan;
@ -415,7 +415,7 @@ void
pattern_test_data_scene(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips) pattern_test_data_scene(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips)
{ {
Incenter_Test_Data_Row* rows = test_data; Incenter_Test_Data_Row* rows = test_data;
r32 month_delta = 1.0f / 24.0f; r32 month_delta = 1.0f / 24.0f;
if (month >= 11) { if (month >= 11) {
s32 x = 5; s32 x = 5;
@ -426,7 +426,7 @@ pattern_test_data_scene(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strip
s32 data_row = test_data_find_nearest_row(city, year, month); s32 data_row = test_data_find_nearest_row(city, year, month);
if (data_row < 0) continue; if (data_row < 0) continue;
s32 data_row_next = data_row + 1; s32 data_row_next = data_row + 1;
Incenter_Test_Data_Row row_curr = test_data[data_row]; Incenter_Test_Data_Row row_curr = test_data[data_row];
r32 percent_r = test_data[data_row].value_0; r32 percent_r = test_data[data_row].value_0;
r32 percent_g = test_data[data_row].value_1; r32 percent_g = test_data[data_row].value_1;
@ -438,35 +438,35 @@ pattern_test_data_scene(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strip
r32 row_curr_months = (r32)((row_curr.year * 12) + row_curr.month); r32 row_curr_months = (r32)((row_curr.year * 12) + row_curr.month);
r32 row_next_months = (r32)((row_next.year * 12) + row_next.month); r32 row_next_months = (r32)((row_next.year * 12) + row_next.month);
r32 curr_months = (r32)(year * 12) + month; r32 curr_months = (r32)(year * 12) + month;
r32 row_month_delta = row_next_months - row_curr_months; r32 row_month_delta = row_next_months - row_curr_months;
r32 delta_from_row_curr = curr_months - row_curr_months; r32 delta_from_row_curr = curr_months - row_curr_months;
r32 theta = delta_from_row_curr / row_month_delta; r32 theta = delta_from_row_curr / row_month_delta;
percent_r = lerp(row_curr.value_0, theta, row_next.value_0); percent_r = lerp(row_curr.value_0, theta, row_next.value_0);
percent_g = lerp(row_curr.value_1, theta, row_next.value_1); percent_g = lerp(row_curr.value_1, theta, row_next.value_1);
percent_b = lerp(row_curr.value_2, theta, row_next.value_2); percent_b = lerp(row_curr.value_2, theta, row_next.value_2);
} }
} }
// printf("%d %f - %f\n", year, month, percent_r); // printf("%d %f - %f\n", year, month, percent_r);
for (u32 led = 0; led < strip.pixels_len; led++) for (u32 led = 0; led < strip.pixels_len; led++)
{ {
r32 pct = (r32)(strip.pixels_len - led) / (r32)strip.pixels_len; r32 pct = (r32)(strip.pixels_len - led) / (r32)strip.pixels_len;
u32 led_index = strip.pixels[led]; u32 led_index = strip.pixels[led];
#if 0 #if 0
pixels.pixels[led_index] = (Assembly_Pixel){ pixels.pixels[led_index] = (Assembly_Pixel){
.r = 32, .r = 32,
.g = 32, .g = 32,
.b = 32, .b = 32,
}; };
if (pct <= percent_r) pixels.pixels[led_index].r = 255; if (pct <= percent_r) pixels.pixels[led_index].r = 255;
if (pct <= percent_g) pixels.pixels[led_index].g = 255; if (pct <= percent_g) pixels.pixels[led_index].g = 255;
if (pct <= percent_b) pixels.pixels[led_index].b = 255; if (pct <= percent_b) pixels.pixels[led_index].b = 255;
#else #else
if (pct > percent_r) { if (pct > percent_r) {
pixels.pixels[led_index] = (Assembly_Pixel){ pixels.pixels[led_index] = (Assembly_Pixel){
.r = 32, .r = 32,
@ -477,17 +477,17 @@ pattern_test_data_scene(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strip
r32 pct_dist = percent_r - pct; r32 pct_dist = percent_r - pct;
r32 ramp = (percent_r - pct_dist) / percent_r; r32 ramp = (percent_r - pct_dist) / percent_r;
ramp = ramp * ramp; ramp = ramp * ramp;
pixels.pixels[led_index] = (Assembly_Pixel){ pixels.pixels[led_index] = (Assembly_Pixel){
.r = 32 + (128 * ramp), .r = 32 + (128 * ramp),
.g = 128 + (128 * ramp), .g = 128 + (128 * ramp),
.b = 255, .b = 255,
}; };
} }
#endif #endif
} }
} }
month += month_delta; month += month_delta;
if (month > (r32)MONTH_Dec + 1) { if (month > (r32)MONTH_Dec + 1) {
month = (r32)MONTH_Jan; month = (r32)MONTH_Jan;
@ -505,7 +505,7 @@ pattern_demo(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter
{ {
// clear previous frame // clear previous frame
pattern_color(pixels, strips, 0, 0, 0); pattern_color(pixels, strips, 0, 0, 0);
r32 sun_limit = 5; r32 sun_limit = 5;
if (tt < sun_limit) if (tt < sun_limit)
{ {
@ -518,18 +518,18 @@ pattern_demo(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter
sun_center(pixels, (v4){0.5f, 0.5f, 0.5f, 1}, r, r); sun_center(pixels, (v4){0.5f, 0.5f, 0.5f, 1}, r, r);
} }
pattern_blink(pixels); pattern_blink(pixels);
Assembly_Pixel data_less_than_color_a = { .r = 32, .g = 128, .b = 255 }; Assembly_Pixel data_less_than_color_a = { .r = 32, .g = 128, .b = 255 };
Assembly_Pixel data_less_than_color_b = { .r = 32, .g = 255, .b = 128 }; Assembly_Pixel data_less_than_color_b = { .r = 32, .g = 255, .b = 128 };
Assembly_Pixel data_border_color = { .r = 255, .g = 255, .b = 255 }; Assembly_Pixel data_border_color = { .r = 255, .g = 255, .b = 255 };
Assembly_Pixel data_greater_than_color = { .r = 64, .g = 0, .b = 0 }; Assembly_Pixel data_greater_than_color = { .r = 64, .g = 0, .b = 0 };
r32 grow_delay = 2; r32 grow_delay = 2;
if (tt > grow_delay && tt < grow_delay + 10) if (tt > grow_delay && tt < grow_delay + 10)
{ {
grow_pattern(pixels, tt - grow_delay, data_greater_than_color); grow_pattern(pixels, tt - grow_delay, data_greater_than_color);
} }
if (tt >= grow_delay + 9) { if (tt >= grow_delay + 9) {
//pattern_test_data_scene_hombre(pixels, strips, data_less_than_color_a, data_less_than_color_b, data_border_color, data_greater_than_color); //pattern_test_data_scene_hombre(pixels, strips, data_less_than_color_a, data_less_than_color_b, data_border_color, data_greater_than_color);
} }
@ -592,6 +592,24 @@ global Color_Ramp xray_ramp = {
.anchors_count = 3 .anchors_count = 3
}; };
global Color_Ramp xray_ramp_rev = {
.anchors = {
[2] = { .pct = 1.0f, .color = { 32.f / 255.f, 2.f / 255.f, 186.f / 255.f } },
[1] = { .pct = 0.5f, .color = { 230.f / 255.f, 37.f / 255.f, 7.f / 255.f } },
[0] = { .pct = 0.0f, .color = { 255.f / 255.f, 162.f / 255.f, 0 } },
},
.anchors_count = 3
};
global Color_Ramp nature_ramp = {
.anchors = {
[0] = {.pct = 0.0f, .color = { 85.f / 255.f, 192.f / 255.f, 255.f / 255.f } },
[1] = {.pct = 0.5f, .color = { 0, 1, 0.5f } },
[2] = {.pct = 1.0f, .color = { 85.f / 255.f, 192.f / 255.f, 255.f / 255.f } },
},
.anchors_count = 3,
};
void void
pattern_aurora_led(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, v4 pos, u32 index, r32 scene_time) pattern_aurora_led(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, v4 pos, u32 index, r32 scene_time)
{ {
@ -625,7 +643,7 @@ pattern_demo_2(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incent
{ {
r32 pct = (r32)(strip.pixels_len - led) / (r32)strip.pixels_len; r32 pct = (r32)(strip.pixels_len - led) / (r32)strip.pixels_len;
u32 led_index = strip.pixels[led]; u32 led_index = strip.pixels[led];
v3 color = color_ramp_eval(cities_ramp, 1 - pct); v3 color = color_ramp_eval(cities_ramp, 1 - pct);
pixels.pixels[led_index] = color_v3_to_assembly_pixel(color); pixels.pixels[led_index] = color_v3_to_assembly_pixel(color);
} }
@ -645,7 +663,7 @@ pattern_demo_3(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incent
{ {
r32 pct = (r32)(strip.pixels_len - led) / (r32)strip.pixels_len; r32 pct = (r32)(strip.pixels_len - led) / (r32)strip.pixels_len;
u32 led_index = strip.pixels[led]; u32 led_index = strip.pixels[led];
v3 cities_color = color_ramp_eval(cities_ramp, 1 - pct); v3 cities_color = color_ramp_eval(cities_ramp, 1 - pct);
v4 p = pixels.positions[led_index]; v4 p = pixels.positions[led_index];
v4 p_unit = incenter_pos_to_bimodal(p); v4 p_unit = incenter_pos_to_bimodal(p);
@ -653,11 +671,11 @@ pattern_demo_3(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incent
r32 dc = clamp(0, d, 1); r32 dc = clamp(0, d, 1);
r32 ds = clamp(0, -1 * d, 1); r32 ds = clamp(0, -1 * d, 1);
cities_color = HMM_MultiplyVec3f(cities_color, dc); cities_color = HMM_MultiplyVec3f(cities_color, dc);
v3 sky_color = { 49.f / 255.f, 156.f / 255.f, 255.f / 255.f }; v3 sky_color = { 49.f / 255.f, 156.f / 255.f, 255.f / 255.f };
sky_color = HMM_MultiplyVec3f(sky_color, ds); sky_color = HMM_MultiplyVec3f(sky_color, ds);
v3 day_color = HMM_AddVec3(sky_color, cities_color); v3 day_color = HMM_AddVec3(sky_color, cities_color);
//v3 sun_color = sun_center_for_pos(pixels.positions[led_index], (v4){0.5f, 0.5f, 0.5f, 1}, .1f, .1f); //v3 sun_color = sun_center_for_pos(pixels.positions[led_index], (v4){0.5f, 0.5f, 0.5f, 1}, .1f, .1f);
v3 color = day_color; //HMM_AddVec3(day_color, sun_color); v3 color = day_color; //HMM_AddVec3(day_color, sun_color);
pixels.pixels[led_index] = color_v3_to_assembly_pixel(color); pixels.pixels[led_index] = color_v3_to_assembly_pixel(color);
@ -683,9 +701,9 @@ void
pattern_random_fill(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins) pattern_random_fill(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins)
{ {
pattern_color(pixels, strips, 1, 38, 45); // dull green pattern_color(pixels, strips, 1, 38, 45); // dull green
Assembly_Pixel color = color_v3_to_assembly_pixel((v3){1, .9f, 0}); Assembly_Pixel color = color_v3_to_assembly_pixel((v3){1, .9f, 0});
r32 scene_time = ins->scene_time; r32 scene_time = ins->scene_time;
r32 dots_per_second = 5; r32 dots_per_second = 5;
u32 iter_cap = scene_time * dots_per_second; u32 iter_cap = scene_time * dots_per_second;
@ -729,7 +747,7 @@ noise_v3_to_r32(v3 p, r32 scale)
v3 p_fl_5 = HMM_AddVec3(p_fl, (v3){1, 0, 1}); v3 p_fl_5 = HMM_AddVec3(p_fl, (v3){1, 0, 1});
v3 p_fl_6 = HMM_AddVec3(p_fl, (v3){0, 1, 1}); v3 p_fl_6 = HMM_AddVec3(p_fl, (v3){0, 1, 1});
v3 p_fl_7 = HMM_AddVec3(p_fl, (v3){1, 1, 1}); v3 p_fl_7 = HMM_AddVec3(p_fl, (v3){1, 1, 1});
r32 h0 = hash_v3_to_r32(p_fl_0); r32 h0 = hash_v3_to_r32(p_fl_0);
r32 h1 = hash_v3_to_r32(p_fl_1); r32 h1 = hash_v3_to_r32(p_fl_1);
r32 h2 = hash_v3_to_r32(p_fl_2); r32 h2 = hash_v3_to_r32(p_fl_2);
@ -738,7 +756,7 @@ noise_v3_to_r32(v3 p, r32 scale)
r32 h5 = hash_v3_to_r32(p_fl_5); r32 h5 = hash_v3_to_r32(p_fl_5);
r32 h6 = hash_v3_to_r32(p_fl_6); r32 h6 = hash_v3_to_r32(p_fl_6);
r32 h7 = hash_v3_to_r32(p_fl_7); r32 h7 = hash_v3_to_r32(p_fl_7);
r32 h0_1 = lerp(h0, f.x, h1); r32 h0_1 = lerp(h0, f.x, h1);
r32 h2_3 = lerp(h2, f.x, h3); r32 h2_3 = lerp(h2, f.x, h3);
r32 h4_5 = lerp(h4, f.x, h5); r32 h4_5 = lerp(h4, f.x, h5);
@ -780,12 +798,38 @@ fbm_3d(v3 x, r32 scale)
// Data Flow Pattern // Data Flow Pattern
void void
pattern_add_data_flow(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, pattern_add_data_flow_ramp(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips,
r32 period, r32 offset, r32 radius, r32 period, r32 offset, r32 radius,
v3 color) Color_Ramp color_ramp)
{ {
Random_Series rs = random_series_create(133753); Random_Series rs = random_series_create(133753);
for (u32 city = 0; city < city_count; city++)
{
Assembly_Strip strip = strips.strips[city + 1];
r32 city_offset = random_series_next_unilateral(&rs) * period;
for (u32 led = 0; led < strip.pixels_len; led++)
{
u32 led_index = strip.pixels[led];
r32 led_pct = (r32)led_index / (r32)strip.pixels_len;
r32 dist = (-1 * fmodf(led_pct + offset + city_offset, period)) + radius;
dist = max(dist, 0) / radius;
v3 color = color_ramp_eval(color_ramp, led_pct);
pixels.pixels[led_index] = assembly_pixel_add(
pixels.pixels[led_index],
color_v3_to_assembly_pixel_faded(color, dist)
);
}
}
}
void
pattern_add_data_flow_color(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips,
r32 period, r32 offset, r32 radius,
v3 color)
{
Random_Series rs = random_series_create(133753);
for (u32 city = 0; city < city_count; city++) for (u32 city = 0; city < city_count; city++)
{ {
Assembly_Strip strip = strips.strips[city + 1]; Assembly_Strip strip = strips.strips[city + 1];
@ -797,7 +841,7 @@ pattern_add_data_flow(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips,
r32 dist = (-1 * fmodf(led_pct + offset + city_offset, period)) + radius; r32 dist = (-1 * fmodf(led_pct + offset + city_offset, period)) + radius;
dist = max(dist, 0) / radius; dist = max(dist, 0) / radius;
pixels.pixels[led_index] = assembly_pixel_add( pixels.pixels[led_index] = assembly_pixel_add(
pixels.pixels[led_index], pixels.pixels[led_index],
color_v3_to_assembly_pixel_faded(color, dist) color_v3_to_assembly_pixel_faded(color, dist)
); );
} }
@ -824,11 +868,11 @@ void
pattern_data_flow(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins) pattern_data_flow(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins)
{ {
pattern_color(pixels, strips, 1, 38, 45); // dull green pattern_color(pixels, strips, 1, 38, 45); // dull green
r32 tt_base = ins->scene_time; r32 tt_base = ins->scene_time;
pattern_add_data_flow(pixels, strips, .6f, tt_base, .02f, (v3){1, 0, .8f}); pattern_add_data_flow_color(pixels, strips, .6f, tt_base, .02f, (v3){1, 0, .8f});
pattern_add_data_flow(pixels, strips, .8f, tt_base * .5f, .035f, (v3){0, 1, 0}); pattern_add_data_flow_color(pixels, strips, .8f, tt_base * .5f, .035f, (v3){0, 1, 0});
pattern_add_data_flow(pixels, strips, 1.2f, tt_base * .35f, .06f, (v3){0, 1, 1}); pattern_add_data_flow_color(pixels, strips, 1.2f, tt_base * .35f, .06f, (v3){0, 1, 1});
pattern_mask_noise(pixels, strips, 5, tt); pattern_mask_noise(pixels, strips, 5, tt);
} }
@ -901,93 +945,95 @@ pattern_sun_passive(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, I
r32 r2 = HMM_LengthSquaredVec3(pos.xyz); r32 r2 = HMM_LengthSquaredVec3(pos.xyz);
pixels.pixels[j] = sun(pos.xyz, r2, (Assembly_Pixel){0, 0, 0}, st); pixels.pixels[j] = sun(pos.xyz, r2, (Assembly_Pixel){0, 0, 0}, st);
} }
secondary_pattern_twinkle(pixels, strips, ins); secondary_pattern_twinkle(pixels, strips, ins);
} }
void void
pattern_sun_transition(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins, r32 radius_start, r32 radius_end, u32 back_scene_mode) pattern_add_bar_chart(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins, Incenter_Scene scene, u32 year, Incenter_Month_Id month, Color_Ramp color_ramp)
{ {
r32 st = (r32)ins->transition_time; for (u32 row_i = 0; row_i < scene.data_len; row_i++)
r32 shrink_duration = INCENTER_TRANSITION_SUN_REVEAL_DURATION;
r32 shrink_progress_pct = (st / shrink_duration);
shrink_progress_pct = clamp(0, shrink_progress_pct, 1);
r32 radius = lerp(radius_start, shrink_progress_pct, radius_end);
r32 radius2 = radius * radius;
//Assembly_Pixel color_shell = { 255, 255, 255 };
Assembly_Pixel color_void = { 0, 0, 0 };
r32 falloff = INCENTER_FEET(1);
r32 falloff2 = falloff * falloff;
Incenter_Scene back_scene = ins->scenes[ins->scene_at];
Incenter_Pattern* back_pattern = back_scene.patterns[back_scene_mode];
back_pattern(pixels, strips, ins);
for (u32 j = 0; j < pixels.len; j++)
{ {
v4 pos = pixels.positions[j]; Incenter_Data_Row row = scene.data[row_i];
v4 p = incenter_pos_to_unit(pos); if (row.year != year || row.month != month) continue;
r32 r2 = HMM_LengthSquaredVec3(pos.xyz);
r32 b = sdf_sphere_hull2_d(radius2, 3, r2); Assembly_Strip strip = strips.strips[row.id];
Assembly_Pixel back_color = pixels.pixels[j]; for (u32 led_i = 0; led_i < strip.pixels_len; led_i++)
if (r2 > radius2) { {
back_color = sun(pos.xyz, r2, color_void, st); u32 led_index = strip.pixels[led_i];
// Bar Chart
r32 pct = 1 - ((r32)led_i / (r32)strip.pixels_len);
if (pct < row.prop) {
r32 cpct = pct / row.prop;
Assembly_Pixel p = color_ramp_eval_pixel(color_ramp, cpct);
pixels.pixels[led_index] = p;
}
} }
v3 color_shell_v3 = {
.x = 0.5f + 0.5f * sinf(p.x * r32_tau * 4.313f + tt * 1.3f),
.y = 0.5f + 0.5f * cosf(0.2314f + p.y * r32_tau * 3.915f + tt),
.z = 0.2f + 0.8f * p.z,
};
Assembly_Pixel color_shell = color_v3_to_assembly_pixel(color_shell_v3);
pixels.pixels[j] = assembly_pixel_blend(back_color, color_shell, b);
} }
} }
void
pattern_sun_transition_shrink(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins)
{
r32 radius_start = INCENTER_FEET(15);
r32 radius_end = INCENTER_FEET(0);
pattern_sun_transition(pixels, strips, ins, radius_start, radius_end, Incenter_SceneMode_Passive);
}
void
pattern_sun_transition_grow(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins)
{
r32 radius_start = INCENTER_FEET(0);
r32 radius_end = INCENTER_FEET(15);
pattern_sun_transition(pixels, strips, ins, radius_start, radius_end, Incenter_SceneMode_Intro);
}
void void
pattern_bar_chart(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins) pattern_bar_chart(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins)
{ {
Incenter_Scene scene = ins->scenes[ins->scene_at]; Incenter_Scene scene = ins->scenes[ins->scene_at];
if (!scene.data) return; if (!scene.data) return;
pattern_color(pixels, strips, 0, 0, 0); pattern_color(pixels, strips, 0, 0, 0);
r32 scene_time = ins->scene_time; pattern_add_bar_chart(pixels, strips, ins, scene, scene.data[0].year, scene.data[0].month, xray_ramp);
}
for (u32 row_i = 0; row_i < scene.data_len; row_i++)
void
pattern_bar_chart_over_time(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins)
{
Incenter_Scene scene = ins->scenes[ins->scene_at];
if (!scene.data) return;
local_persist s32 last_scene_at = -1;
local_persist u32 year_max = 0;
local_persist Incenter_Month_Id month_max = 0;
local_persist u32 year_at = 0;
local_persist Incenter_Month_Id month_at = 0;
local_persist r32 month_start_time = 0;
if (last_scene_at != ins->scene_at)
{ {
Incenter_Data_Row row = scene.data[row_i]; last_scene_at = ins->scene_at;
Assembly_Strip strip = strips.strips[row.id];
for (u32 led_i = 0; led_i < strip.pixels_len; led_i++) // Determine what the end of the data set is
for (u32 row_i = 0; row_i < scene.data_len; row_i++)
{ {
u32 led_index = strip.pixels[led_i]; Incenter_Data_Row row = scene.data[row_i];
if (row.year >= year_max) {
// Bar Chart year_max = row.year;
r32 pct = 1 - ((r32)led_i / (r32)strip.pixels_len); month_max = max(row.month, month_max);
if (pct < row.prop) {
r32 cpct = pct / row.prop;
Assembly_Pixel p = color_ramp_eval_pixel(xray_ramp, cpct);
pixels.pixels[led_index] = p;
} }
} }
year_at = scene.data[0].year;
month_at = scene.data[0].month;
month_start_time = ins->scene_time;
} }
r32 month_duration = 2;
r32 time_at_month = ins->scene_time - month_start_time;
if (time_at_month > month_duration)
{
if (year_at < year_max) {
month_at += 1;
if (month > MONTH_dec) {
month_at = MONTH_jan;
year_at += 1;
}
} else {
if (month < month_max) month += 1;
}
month_start_time = ins->scene_time;
}
pattern_color(pixels, strips, 0, 0, 0);
pattern_add_bar_chart(pixels, strips, ins, scene, year_at, month_at, xray_ramp);
} }
//////////////////////////////////////// ////////////////////////////////////////
@ -1016,7 +1062,7 @@ pattern_felt_isolated_intro(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array s
r32 row_offset = (.1439f * row_i); r32 row_offset = (.1439f * row_i);
r32 b = pm_sinf_01(ins->scene_time + row_offset); r32 b = pm_sinf_01(ins->scene_time + row_offset);
pixels.pixels[pixel_index] = pattern_felt_isolated_color( pixels.pixels[pixel_index] = pattern_felt_isolated_color(
pixel_start, pixel_start,
strip.pixels_len, strip.pixels_len,
b b
); );
@ -1028,7 +1074,7 @@ pattern_felt_isolated_passive(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array
{ {
Incenter_Scene scene = ins->scenes[ins->scene_at]; Incenter_Scene scene = ins->scenes[ins->scene_at];
r32 scene_time = ins->scene_time; r32 scene_time = ins->scene_time;
pattern_color(pixels, strips, 0, 0, 0); pattern_color(pixels, strips, 0, 0, 0);
for (u32 row_i = 0; row_i < scene.data_len; row_i++) for (u32 row_i = 0; row_i < scene.data_len; row_i++)
{ {
@ -1037,11 +1083,11 @@ pattern_felt_isolated_passive(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array
u32 pixel_start = row.prop * strip.pixels_len; u32 pixel_start = row.prop * strip.pixels_len;
r32 row_offset = (.1439f * row_i); r32 row_offset = (.1439f * row_i);
r32 b = pm_sinf_01(ins->scene_time + row_offset); r32 b = pm_sinf_01(ins->scene_time + row_offset);
r32 grow_duration = 4.0f; r32 grow_duration = 4.0f;
r32 grow_delay = row_offset * 5; r32 grow_delay = row_offset * 5;
r32 grow_time = (scene_time - 2.0f) - grow_delay; r32 grow_time = (scene_time - 2.0f) - grow_delay;
r32 grow_pct = clamp(0, grow_time, grow_duration) / grow_duration; r32 grow_pct = clamp(0, grow_time, grow_duration) / grow_duration;
r32 grow_pct_smoothed = pm_easeinout_cubic_r32(grow_pct); r32 grow_pct_smoothed = pm_easeinout_cubic_r32(grow_pct);
u32 pixels_on = (strip.pixels_len - pixel_start) * grow_pct_smoothed; u32 pixels_on = (strip.pixels_len - pixel_start) * grow_pct_smoothed;
@ -1050,12 +1096,12 @@ pattern_felt_isolated_passive(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array
{ {
u32 pixel_index = strip.pixels[pixel_i]; u32 pixel_index = strip.pixels[pixel_i];
pixels.pixels[pixel_index] = pattern_felt_isolated_color( pixels.pixels[pixel_index] = pattern_felt_isolated_color(
pixel_i, pixel_i,
strip.pixels_len, strip.pixels_len,
b b
); );
} }
} }
} }
@ -1063,12 +1109,279 @@ void
pattern_rainbow(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins) pattern_rainbow(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins)
{ {
Assembly_Pixel p = color_v3_to_assembly_pixel((v3){ Assembly_Pixel p = color_v3_to_assembly_pixel((v3){
.x = pm_sinf_01(ins->scene_time), .x = pm_sinf_01(ins->scene_time),
.y = pm_cosf_01(ins->scene_time), .y = pm_cosf_01(ins->scene_time),
.z = 0.5f, .z = 0.5f,
}); });
for (u32 j = 0; j < pixels.len; j++) for (u32 j = 0; j < pixels.len; j++)
{ {
pixels.pixels[j] = p; pixels.pixels[j] = p;
} }
} }
///////////////////////////////////
// Begun to Heal
void
pattern_bar_chart_bubbly_intro(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins)
{
Incenter_Scene scene = ins->scenes[ins->scene_at];
if (!scene.data) return;
pattern_color(pixels, strips, 0, 0, 0);
r32 scene_time = ins->scene_time;
for (u32 row_i = 0; row_i < scene.data_len; row_i++)
{
Incenter_Data_Row row = scene.data[row_i];
Assembly_Strip strip = strips.strips[row.id];
u32 led_index = strip.pixels[strip.pixels_len - 1];
Assembly_Pixel p = color_v3_to_assembly_pixel(nature_ramp.anchors[0].color);
pixels.pixels[led_index] = p;
}
}
void
pattern_bar_chart_bubbly_passive(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins)
{
Incenter_Scene scene = ins->scenes[ins->scene_at];
if (!scene.data) return;
pattern_color(pixels, strips, 0, 0, 0);
r32 scene_time = ins->scene_time;
r32 grow_time = 5;
r32 pct_grow_time = clamp(0, ((scene_time - INCENTER_TRANSITION_DURATION) / grow_time), 1);
// create a ramp that is 0 at pct_grow_time = 0 and pct_grow_time = 1,
// but smoothly grows to 1 at pct_grow_time = 0.5
r32 offset_influence = sinf((1 - pct_grow_time) * r32_pi);
for (u32 row_i = 0; row_i < scene.data_len; row_i++)
{
Incenter_Data_Row row = scene.data[row_i];
Assembly_Strip strip = strips.strips[row.id];
u32 first_led = strip.pixels[strip.pixels_len - 1];
v3 first_led_pos = pixels.positions[first_led].xyz;
v3 root = HMM_AddVec3(first_led_pos, (v3){ ins->scene_time, 0, 0 });
r32 strip_pct = row.prop * pct_grow_time;
if (pct_grow_time < 1) {
r32 strip_offset = (pm_noise_v3_to_r32(root) * 0.4f) - 0.2f;
strip_pct += strip_offset * offset_influence;
strip_pct = clamp(0, strip_pct, row.prop);
}
for (u32 led_i = 0; led_i < strip.pixels_len; led_i++)
{
u32 led_index = strip.pixels[led_i];
// Bar Chart
r32 pct = 1 - ((r32)led_i / (r32)strip.pixels_len);
if (pct < strip_pct) {
r32 cpct = fractf(((1 - pct) / row.prop) + (ins->scene_time * 0.3f));
Assembly_Pixel p = color_ramp_eval_pixel(nature_ramp, cpct);
pixels.pixels[led_index] = p;
}
}
}
}
///////////////////////////////////////////////////
// Relationship Community Support
void
pattern_bar_chart_with_connections(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins)
{
Incenter_Scene scene = ins->scenes[ins->scene_at];
if (!scene.data) return;
pattern_color(pixels, strips, 0, 0, 0);
r32 scene_time = ins->scene_time;
pattern_add_bar_chart(pixels, strips, ins, scene, scene.data[0].year, scene.data[0].month, xray_ramp);
pattern_add_data_flow_color(pixels, strips, .3f, ins->scene_time, .01f, (v3){1,1,1});
pattern_add_data_flow_color(pixels, strips, .15f, ins->scene_time, .005f, (v3){1,1,1});
}
/////
// Believe Science Renewable Tech
void
pattern_bar_chart_random_fill(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins)
{
Incenter_Scene scene = ins->scenes[ins->scene_at];
if (!scene.data) return;
pattern_color(pixels, strips, 1, 38, 45); // dull green
Assembly_Pixel color = color_v3_to_assembly_pixel((v3){1, .9f, 0});
assert(color.r != 1);
r32 scene_time = ins->scene_time;
r32 dots_per_second = 5;
u32 iter_cap = scene_time * dots_per_second;
for (u32 row_i = 0; row_i < scene.data_len; row_i++)
{
Incenter_Data_Row row = scene.data[row_i];
Assembly_Strip strip = strips.strips[row.id];
u32 led_max = strip.pixels_len;
u32 led_min = strip.pixels_len * (1 - row.prop);
u32 led_range = led_max - led_min;
Random_Series rs = random_series_create(city_hashes[row.id]);
u32 city_iter = min(iter_cap, led_range);
for (u32 i = 0; i < city_iter; i++)
{
u32 led_first = (random_series_next(&rs) % led_range) + led_min;
u32 led = led_first;
u32 led_index = 0;
do {
led = ((led + 1) % led_range) + led_min;
if (led == led_first) break;
led_index = strip.pixels[led];
} while (pixels.pixels[led_index].r == 1);
pixels.pixels[led_index] = color;
}
}
#if 0
for (u32 city = 0; city < city_count; city++)
{
Random_Series rs = random_series_create(city_hashes[city]);
u32 city_iter = min(city_iters[city], iter_cap);
Assembly_Strip strip = strips.strips[city + 1];
for (u32 i = 0; i < city_iter; i++)
{
u32 led = random_series_next(&rs) % strip.pixels_cap;
u32 led_index = strip.pixels[led];
pixels.pixels[led_index] = color;
}
}
#endif
}
void
pattern_scene_input(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins)
{
Incenter_Scene scene = ins->scenes[ins->scene_at];
Assembly_Strip brc_strip = strips.strips[city_black_rock];
pattern_color(pixels, strips, 0, 0, 0);
secondary_pattern_twinkle(pixels, strips, ins);
// black out whole strip
for (u32 led_i = 0; led_i < brc_strip.pixels_len; led_i++)
{
u32 led = brc_strip.pixels[led_i];
pixels.pixels[led] = (Assembly_Pixel){0,0,0};
}
u32 on_range_start = 0;
u32 on_range_stop = 0;
switch (scene.kind)
{
case Incenter_SceneKind_Information:
{
} break;
case Incenter_SceneKind_YesOrNo:
{
u32 middle = brc_strip.pixels_len / 2;
on_range_start = ins->input_option == 0 ? 0 : middle;
on_range_stop = ins->input_option == 0 ? middle : brc_strip.pixels_len;
} break;
case Incenter_SceneKind_ThreeOption:
{
u32 one_third = brc_strip.pixels_len / 3;
u32 two_thirds = one_third * 2;
u32 top = brc_strip.pixels_len;
switch (ins->input_option) {
case 0: { on_range_start = 0; on_range_stop = one_third; } break;
case 1: { on_range_start = one_third; on_range_stop = two_thirds; } break;
case 2: { on_range_start = two_thirds; on_range_stop = top; } break;
}
} break;
case Incenter_SceneKind_SlidingScale:
{
on_range_start = 0;
on_range_stop = (r32)brc_strip.pixels_len * ins->input_pct;
} break;
invalid_default_case;
}
for (u32 led_i = on_range_start; led_i < on_range_stop; led_i++)
{
u32 led = brc_strip.pixels[led_i];
pixels.pixels[led] = (Assembly_Pixel){255,255,255};
}
}
/////////////////////////////////////////////
// Transition Patterns
void
pattern_sun_transition(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins, r32 radius_start, r32 radius_end, u32 back_scene_mode)
{
r32 st = (r32)ins->transition_time;
r32 shrink_duration = INCENTER_TRANSITION_SUN_REVEAL_DURATION;
r32 shrink_progress_pct = (st / shrink_duration);
shrink_progress_pct = clamp(0, shrink_progress_pct, 1);
r32 radius = lerp(radius_start, shrink_progress_pct, radius_end);
r32 radius2 = radius * radius;
//Assembly_Pixel color_shell = { 255, 255, 255 };
Assembly_Pixel color_void = { 0, 0, 0 };
r32 falloff = INCENTER_FEET(1);
r32 falloff2 = falloff * falloff;
Incenter_Scene back_scene = ins->scenes[ins->scene_at];
Incenter_Pattern* back_pattern = 0;
if (back_scene_mode < Incenter_SceneMode_Count) {
back_pattern = back_scene.patterns[back_scene_mode];
} else if (back_scene_mode == Incenter_SceneMode_Input) {
back_pattern = pattern_scene_input;
}
assert(back_pattern != 0);
back_pattern(pixels, strips, ins);
for (u32 j = 0; j < pixels.len; j++)
{
v4 pos = pixels.positions[j];
v4 p = incenter_pos_to_unit(pos);
r32 r2 = HMM_LengthSquaredVec3(pos.xyz);
r32 b = sdf_sphere_hull2_d(radius2, 3, r2);
Assembly_Pixel back_color = pixels.pixels[j];
if (r2 > radius2) {
back_color = sun(pos.xyz, r2, color_void, st);
}
v3 color_shell_v3 = {
.x = 0.5f + 0.5f * sinf(p.x * r32_tau * 4.313f + tt * 1.3f),
.y = 0.5f + 0.5f * cosf(0.2314f + p.y * r32_tau * 3.915f + tt),
.z = 0.2f + 0.8f * p.z,
};
Assembly_Pixel color_shell = color_v3_to_assembly_pixel(color_shell_v3);
pixels.pixels[j] = assembly_pixel_blend(back_color, color_shell, b);
}
}
void
pattern_sun_transition_shrink(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins)
{
r32 radius_start = INCENTER_FEET(15);
r32 radius_end = INCENTER_FEET(0);
pattern_sun_transition(pixels, strips, ins, radius_start, radius_end, Incenter_SceneMode_Passive);
}
void
pattern_sun_transition_grow(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incenter_State* ins)
{
r32 radius_start = INCENTER_FEET(0);
r32 radius_end = INCENTER_FEET(15);
pattern_sun_transition(pixels, strips, ins, radius_start, radius_end, Incenter_SceneMode_Input);
}

View File

@ -6,33 +6,34 @@
typedef u8 Incenter_Scene_ID; typedef u8 Incenter_Scene_ID;
enum { enum {
Incenter_Scene_Invalid = 0, Incenter_Scene_Invalid = 0,
Incenter_Scene_AnyoneHome, Incenter_Scene_AnyoneHome = 1,
Incenter_Scene_WelcomeHome, Incenter_Scene_WelcomeHome = 2,
Incenter_Scene_Question_FeltIsolated, Incenter_Scene_Question_FeltIsolated = 3,
Incenter_Scene_Question_FeltFearAnxiety, Incenter_Scene_Question_FeltFearAnxiety = 4,
Incenter_Scene_Question_FeltPowerless, Incenter_Scene_Question_FeltPowerless = 5,
Incenter_Scene_Question_LostAccessToResources, Incenter_Scene_Question_LostAccessToResources = 6,
Incenter_Scene_Question_LostLovedOne, Incenter_Scene_Question_LostLovedOne = 7,
Incenter_Scene_Question_BegunToHeal, Incenter_Scene_Question_BegunToHeal = 8,
Incenter_Scene_OnPlayaResources, Incenter_Scene_OnPlayaResources = 9,
Incenter_Scene_Question_HowYouFaceChallenges, Incenter_Scene_Question_RelationshipCommunitySupport = 10,
Incenter_Scene_Question_RelationshipCommunitySupport, Incenter_Scene_Question_ConnectionFriendsFamily = 11,
Incenter_Scene_Question_ConnectionFriendsFamily, Incenter_Scene_Question_ValueConnections = 12,
Incenter_Scene_Question_ValueConnections, Incenter_Scene_Question_FindHappiness = 13,
Incenter_Scene_Question_FindHappiness, Incenter_Scene_Question_FeltExcludedIdentity = 14,
Incenter_Scene_Question_InspiredToHelpOthers, Incenter_Scene_Question_RepresentedByLeadership = 15,
Incenter_Scene_Question_LearningOpenMinded, Incenter_Scene_Question_LearningOpenMinded = 16,
Incenter_Scene_Question_FeltExcludedIdentity, Incenter_Scene_Question_ProtectOurEarth = 17,
Incenter_Scene_Question_RepresentedByLeadership, Incenter_Scene_Question_BelieveScienceRenewableTech = 18,
Incenter_Scene_Question_CommunityFeelBelong, Incenter_Scene_Question_StriveMoreEcoFriendly = 19,
Incenter_Scene_Question_PracticeRadicalInclusion, Incenter_Scene_Question_ActionToHelpPlanet = 20,
Incenter_Scene_Question_PracticeChangeHopeFor, Incenter_Scene_Question_HowYouFaceChallenges = 21,
Incenter_Scene_Question_ProtectOurEarth, Incenter_Scene_Question_InspiredToHelpOthers = 22,
Incenter_Scene_Question_BelieveScienceRenewableTech, Incenter_Scene_Question_PracticeChangeHopeFor = 23,
Incenter_Scene_Question_ActionToHelpPlanet, Incenter_Scene_Question_PracticeRadicalInclusion = 24,
Incenter_Scene_Question_StriveMoreEcoFriendly, Incenter_Scene_Question_CommunityFeelBelong = 25,
Incenter_Scene_Credits = 26,
Incenter_Scene_Count, Incenter_Scene_Count,
}; };
@ -46,269 +47,286 @@ incenter_scene_descs_init()
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_sun_passive, [Incenter_SceneMode_Intro] = pattern_sun_passive,
[Incenter_SceneMode_Passive] = pattern_sun_passive, [Incenter_SceneMode_Passive] = pattern_sun_passive,
[Incenter_SceneMode_Input] = pattern_sun_passive,
}, },
.kind = Incenter_SceneKind_Information,
}; };
incenter_scene_descs[Incenter_Scene_WelcomeHome] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_WelcomeHome] = (Incenter_Scene){
.name = "WelcomeHome", .name = "WelcomeHome",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_rainbow, [Incenter_SceneMode_Intro] = pattern_rainbow,
[Incenter_SceneMode_Passive] = pattern_rainbow, [Incenter_SceneMode_Passive] = pattern_rainbow,
[Incenter_SceneMode_Input] = pattern_sun_passive,
}, },
.kind = Incenter_SceneKind_Information,
}; };
incenter_scene_descs[Incenter_Scene_Question_FeltIsolated] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_FeltIsolated] = (Incenter_Scene){
.name = "FeltIsolated", .name = "FeltIsolated",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_felt_isolated_intro, [Incenter_SceneMode_Intro] = pattern_felt_isolated_intro,
[Incenter_SceneMode_Passive] = pattern_felt_isolated_passive, [Incenter_SceneMode_Passive] = pattern_felt_isolated_passive,
[Incenter_SceneMode_Input] = pattern_felt_isolated_passive,
}, },
.data = question_1_data, .data = question_1_data,
.data_len = question_1_len, .data_len = question_1_len,
.kind = Incenter_SceneKind_YesOrNo,
}; };
incenter_scene_descs[Incenter_Scene_Question_FeltFearAnxiety] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_FeltFearAnxiety] = (Incenter_Scene){
.name = "FeltFearAnxiety", .name = "FeltFearAnxiety",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_felt_isolated_intro,
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_felt_isolated_passive,
[Incenter_SceneMode_Input] = pattern_bar_chart,
}, },
.data = question_2_data, .data = question_2_data,
.data_len = question_2_len, .data_len = question_2_len,
.kind = Incenter_SceneKind_ThreeOption,
}; };
incenter_scene_descs[Incenter_Scene_Question_FeltPowerless] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_FeltPowerless] = (Incenter_Scene){
.name = "FeltPowerless", .name = "FeltPowerless",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_felt_isolated_intro,
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_felt_isolated_passive,
[Incenter_SceneMode_Input] = pattern_bar_chart,
}, },
.data = question_3_data, .data = question_5_data,
.data_len = question_3_len, .data_len = question_5_len,
.kind = Incenter_SceneKind_YesOrNo,
}; };
incenter_scene_descs[Incenter_Scene_Question_LostAccessToResources] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_LostAccessToResources] = (Incenter_Scene){
.name = "LostAccessToResources", .name = "LostAccessToResources",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_bar_chart,
[Incenter_SceneMode_Input] = pattern_bar_chart,
}, },
// .data = question_4_data, .data = question_3_data,
// .data_len = question_4_len, .data_len = question_3_len,
.kind = Incenter_SceneKind_YesOrNo,
}; };
incenter_scene_descs[Incenter_Scene_Question_LostLovedOne] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_LostLovedOne] = (Incenter_Scene){
.name = "LostLovedOne", .name = "LostLovedOne",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_bar_chart_over_time,
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_bar_chart_over_time,
[Incenter_SceneMode_Input] = pattern_bar_chart,
}, },
// .data = question_5_data, .data = question_4_data,
// .data_len = question_5_len, .data_len = question_4_len,
.kind = Incenter_SceneKind_YesOrNo,
}; };
// TODO: We need an animation that communicates healing / connection
// grow out from the person's answer into the entire planet
incenter_scene_descs[Incenter_Scene_Question_BegunToHeal] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_BegunToHeal] = (Incenter_Scene){
.name = "BegunToHeal", .name = "BegunToHeal",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_bar_chart_bubbly_intro,
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_bar_chart_bubbly_passive,
[Incenter_SceneMode_Input] = pattern_bar_chart,
}, },
.data = question_6_data, // no data .data = question_6_data,
.data_len = question_6_len, // no data .data_len = question_6_len,
.kind = Incenter_SceneKind_SlidingScale,
}; };
incenter_scene_descs[Incenter_Scene_OnPlayaResources] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_OnPlayaResources] = (Incenter_Scene){
.name = "OnPlayaResources", .name = "OnPlayaResources",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_bar_chart,
[Incenter_SceneMode_Input] = pattern_bar_chart,
}, },
.kind = Incenter_SceneKind_Information,
}; };
incenter_scene_descs[Incenter_Scene_Question_HowYouFaceChallenges] = (Incenter_Scene){
.name = "HowYouFaceChallenges",
.patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart,
[Incenter_SceneMode_Input] = pattern_bar_chart,
},
.data = question_7_data,
.data_len = question_7_len,
};
incenter_scene_descs[Incenter_Scene_Question_RelationshipCommunitySupport] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_RelationshipCommunitySupport] = (Incenter_Scene){
.name = "RelationshipCommunitySupport", .name = "RelationshipCommunitySupport",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_bar_chart_with_connections,
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_bar_chart_with_connections,
[Incenter_SceneMode_Input] = pattern_bar_chart,
}, },
.data = question_8_data, .data = question_7_data,
.data_len = question_8_len, .data_len = question_7_len,
.kind = Incenter_SceneKind_SlidingScale,
}; };
incenter_scene_descs[Incenter_Scene_Question_ConnectionFriendsFamily] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_ConnectionFriendsFamily] = (Incenter_Scene){
.name = "ConnectionFriendsFamily", .name = "ConnectionFriendsFamily",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_bar_chart_with_connections,
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_bar_chart_with_connections,
[Incenter_SceneMode_Input] = pattern_bar_chart,
}, },
.data = question_9_data, .data = question_8_data,
.data_len = question_9_len, .data_len = question_8_len,
.kind = Incenter_SceneKind_SlidingScale,
}; };
incenter_scene_descs[Incenter_Scene_Question_ValueConnections] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_ValueConnections] = (Incenter_Scene){
.name = "ValueConnections", .name = "ValueConnections",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, #if 0
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_bar_chart_with_connections,
[Incenter_SceneMode_Input] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_bar_chart_with_connections,
#endif
[Incenter_SceneMode_Intro] = pattern_bar_chart_random_fill,
[Incenter_SceneMode_Passive] = pattern_bar_chart_random_fill,
}, },
.data = question_10_data, .data = question_9_data,
.data_len = question_10_len, .data_len = question_9_len,
.kind = Incenter_SceneKind_SlidingScale,
}; };
incenter_scene_descs[Incenter_Scene_Question_FindHappiness] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_FindHappiness] = (Incenter_Scene){
.name = "FindHappiness", .name = "FindHappiness",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_bar_chart,
[Incenter_SceneMode_Input] = pattern_bar_chart,
}, },
.data = question_11_data, .data = question_10_data,
.data_len = question_11_len, .data_len = question_10_len,
.kind = Incenter_SceneKind_YesOrNo,
}; };
incenter_scene_descs[Incenter_Scene_Question_InspiredToHelpOthers] = (Incenter_Scene){
.name = "InspiredToHelpOthers",
.patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart,
[Incenter_SceneMode_Input] = pattern_bar_chart,
},
.data = question_12_data,
.data_len = question_12_len,
};
incenter_scene_descs[Incenter_Scene_Question_LearningOpenMinded] = (Incenter_Scene){
.name = "LearningOpenMinded",
.patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart,
[Incenter_SceneMode_Input] = pattern_bar_chart,
},
.data = question_13_data,
.data_len = question_13_len,
};
incenter_scene_descs[Incenter_Scene_Question_FeltExcludedIdentity] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_FeltExcludedIdentity] = (Incenter_Scene){
.name = "FeltExcludedIdentity", .name = "FeltExcludedIdentity",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_bar_chart,
[Incenter_SceneMode_Input] = pattern_bar_chart,
}, },
.data = question_14_data, .data = question_13_data,
.data_len = question_14_len, .data_len = question_13_len,
.kind = Incenter_SceneKind_YesOrNo,
}; };
incenter_scene_descs[Incenter_Scene_Question_RepresentedByLeadership] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_RepresentedByLeadership] = (Incenter_Scene){
.name = "RepresentedByLeadership", .name = "RepresentedByLeadership",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_bar_chart,
[Incenter_SceneMode_Input] = pattern_bar_chart,
}, },
.data = question_15_data, .data = question_14_data,
.data_len = question_15_len, .data_len = question_14_len,
.kind = Incenter_SceneKind_SlidingScale,
}; };
incenter_scene_descs[Incenter_Scene_Question_CommunityFeelBelong] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_LearningOpenMinded] = (Incenter_Scene){
.name = "CommunityFeelBelong", .name = "LearningOpenMinded",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_bar_chart,
[Incenter_SceneMode_Input] = pattern_bar_chart,
}, },
.data = question_16_data, .data = question_12_data,
.data_len = question_16_len, .data_len = question_12_len,
.kind = Incenter_SceneKind_SlidingScale,
}; };
incenter_scene_descs[Incenter_Scene_Question_PracticeRadicalInclusion] = (Incenter_Scene){
.name = "PracticeRadicalInclusion",
.patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart,
[Incenter_SceneMode_Input] = pattern_bar_chart,
},
.data = question_17_data,
.data_len = question_17_len,
};
incenter_scene_descs[Incenter_Scene_Question_PracticeChangeHopeFor] = (Incenter_Scene){
.name = "PracticeChangeHopeFor",
.patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart,
[Incenter_SceneMode_Input] = pattern_bar_chart,
},
.data = question_18_data,
.data_len = question_18_len,
};
incenter_scene_descs[Incenter_Scene_Question_ProtectOurEarth] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_ProtectOurEarth] = (Incenter_Scene){
.name = "ProtectOurEarth", .name = "ProtectOurEarth",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_bar_chart,
[Incenter_SceneMode_Input] = pattern_bar_chart,
}, },
.data = question_19_data, .data = question_18_data,
.data_len = question_19_len, .data_len = question_18_len,
.kind = Incenter_SceneKind_YesOrNo,
}; };
incenter_scene_descs[Incenter_Scene_Question_BelieveScienceRenewableTech] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_BelieveScienceRenewableTech] = (Incenter_Scene){
.name = "BelieveScienceRenewableTech", .name = "BelieveScienceRenewableTech",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_bar_chart_random_fill,
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_bar_chart_random_fill,
[Incenter_SceneMode_Input] = pattern_bar_chart,
}, },
.data = question_20_data, .data = question_19_data,
.data_len = question_20_len, .data_len = question_19_len,
.kind = Incenter_SceneKind_YesOrNo,
}; };
incenter_scene_descs[Incenter_Scene_Question_ActionToHelpPlanet] = (Incenter_Scene){
.name = "ActionToHelpPlanet",
.patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart,
[Incenter_SceneMode_Input] = pattern_bar_chart,
},
// .data = question_21_data,
// .data_len = question_21_len,
};
incenter_scene_descs[Incenter_Scene_Question_StriveMoreEcoFriendly] = (Incenter_Scene){ incenter_scene_descs[Incenter_Scene_Question_StriveMoreEcoFriendly] = (Incenter_Scene){
.name = "StriveMoreEcoFriendly", .name = "StriveMoreEcoFriendly",
.patterns = { .patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart, [Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart, [Incenter_SceneMode_Passive] = pattern_bar_chart,
[Incenter_SceneMode_Input] = pattern_bar_chart,
}, },
// .data = question_22_data, // .data = question_22_data,
// .data_len = question_22_len, // .data_len = question_22_len,
.kind = Incenter_SceneKind_YesOrNo,
}; };
incenter_scene_descs[Incenter_Scene_Question_ActionToHelpPlanet] = (Incenter_Scene){
.name = "ActionToHelpPlanet",
.patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart,
},
.data = question_20_data,
.data_len = question_20_len,
.kind = Incenter_SceneKind_YesOrNo,
};
incenter_scene_descs[Incenter_Scene_Question_HowYouFaceChallenges] = (Incenter_Scene){
.name = "HowYouFaceChallenges",
.patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart,
},
.data = question_6_data,
.data_len = question_6_len,
.kind = Incenter_SceneKind_YesOrNo,
};
incenter_scene_descs[Incenter_Scene_Question_InspiredToHelpOthers] = (Incenter_Scene){
.name = "InspiredToHelpOthers",
.patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart,
},
.data = question_11_data,
.data_len = question_11_len,
.kind = Incenter_SceneKind_YesOrNo,
};
incenter_scene_descs[Incenter_Scene_Question_PracticeChangeHopeFor] = (Incenter_Scene){
.name = "PracticeChangeHopeFor",
.patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart,
},
.data = question_17_data,
.data_len = question_17_len,
.kind = Incenter_SceneKind_YesOrNo,
};
incenter_scene_descs[Incenter_Scene_Question_PracticeRadicalInclusion] = (Incenter_Scene){
.name = "PracticeRadicalInclusion",
.patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart,
},
.data = question_16_data,
.data_len = question_16_len,
.kind = Incenter_SceneKind_YesOrNo,
};
incenter_scene_descs[Incenter_Scene_Question_CommunityFeelBelong] = (Incenter_Scene){
.name = "CommunityFeelBelong",
.patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart,
},
.data = question_15_data,
.data_len = question_15_len,
.kind = Incenter_SceneKind_YesOrNo,
};
incenter_scene_descs[Incenter_Scene_Credits] = (Incenter_Scene){
.name = "Credits",
.patterns = {
[Incenter_SceneMode_Intro] = pattern_bar_chart,
[Incenter_SceneMode_Passive] = pattern_bar_chart,
},
.kind = Incenter_SceneKind_Information,
};
} }
#endif //INCENTER_SCENES_H #endif //INCENTER_SCENES_H

View File

@ -1,30 +1,8 @@
#define INCENTER_METER 1.0f
#define INCENTER_FOOT 0.3048f
#define INCENTER_METERS(count) (count) * INCENTER_METER
#define INCENTER_FEET(count) (count) * INCENTER_FOOT
#define INCENTER_PER_METER(count) INCENTER_METER / (r32)(count)
internal v4
incenter_latlng_to_cartesian(r32 lat, r32 lng, r32 radius)
{
r32 theta = (lat / 180.0f) * r32_pi;
r32 phi = (lng / 180.0f) * r32_pi;
// spherical to cartesian conversion
v4 result = {
radius * sinf(phi) * cosf(theta),
radius * sinf(phi) * sinf(theta),
radius * cosf(phi),
1
};
return result;
}
#include "../user_space/incenter_patterns.c" #include "../user_space/incenter_patterns.c"
#include "../user_space/incenter_secondary_patterns.c" #include "../user_space/incenter_secondary_patterns.c"
#include "incenter_scenes.h" #include "incenter_scenes.h"
#include "incenter_live_answers.c"
//////////////////////////////////////////////// ////////////////////////////////////////////////
// INCENTER SCENES // INCENTER SCENES
@ -35,7 +13,7 @@ incenter_scenes_init(Incenter_State* ins, u32 cap, Allocator* a)
incenter_scene_descs_init(); incenter_scene_descs_init();
ins->scenes = incenter_scene_descs; ins->scenes = incenter_scene_descs;
ins->scenes_cap = Incenter_Scene_Count; ins->scenes_cap = Incenter_Scene_Count;
ins->scene_at = Incenter_Scene_WelcomeHome; ins->scene_at = Incenter_Scene_Question_LostAccessToResources;
} }
internal void internal void
@ -44,7 +22,7 @@ incenter_scene_go_to(Incenter_State* ins, u32 index)
ins->transition_time = 0; ins->transition_time = 0;
ins->scene_next = index % ins->scenes_cap; ins->scene_next = index % ins->scenes_cap;
ins->scene_mode = Incenter_SceneMode_TransitioningOut; ins->scene_mode = Incenter_SceneMode_TransitioningOut;
printf("Switching To: %s\n", ins->scenes[ins->scene_next].name); printf("Switching To: %d:%s\n", ins->scene_next, ins->scenes[ins->scene_next].name);
} }
internal void internal void
@ -79,23 +57,29 @@ incenter_scene_render(App_State* state, Incenter_State* ins)
ins->scene_mode = Incenter_SceneMode_TransitioningIn; ins->scene_mode = Incenter_SceneMode_TransitioningIn;
ins->scene_at = ins->scene_next; ins->scene_at = ins->scene_next;
ins->scene_time = 0; ins->scene_time = 0;
// reset inputs
ins->input_pct = 0.5f;
ins->input_option = 0;
ins->input_advance = false;
} else { } else {
ins->scene_mode = Incenter_SceneMode_Passive; ins->scene_mode = Incenter_SceneMode_Input;
} }
} }
} }
// DRaw the transition // DRaw the transition
switch (ins->scene_mode) switch (ins->scene_mode)
{ {
case Incenter_SceneMode_TransitioningOut: pattern = pattern_sun_transition_shrink; break; case Incenter_SceneMode_TransitioningOut: pattern = pattern_sun_transition_shrink; break;
case Incenter_SceneMode_TransitioningIn: pattern = pattern_sun_transition_grow; break; case Incenter_SceneMode_TransitioningIn: pattern = pattern_sun_transition_grow; break;
case Incenter_SceneMode_Input: pattern = pattern_scene_input; break;
default: { default: {
Incenter_Scene scene = ins->scenes[ins->scene_at]; Incenter_Scene scene = ins->scenes[ins->scene_at];
pattern = scene.patterns[ins->scene_mode]; pattern = scene.patterns[ins->scene_mode];
} break; } break;
} }
Assembly_Array assemblies = state->assemblies; Assembly_Array assemblies = state->assemblies;
if (pattern) if (pattern)
{ {
@ -107,6 +91,9 @@ incenter_scene_render(App_State* state, Incenter_State* ins)
} }
} }
#include "incenter_interface_connection.h"
#include "incenter_interface_connection.c"
//////////////////////////////////////////////// ////////////////////////////////////////////////
// INCENTER LIFECYCLE // INCENTER LIFECYCLE
@ -126,7 +113,7 @@ incenter_init(App_State* state)
state->user_space_data = (u8*)ins; state->user_space_data = (u8*)ins;
incenter_scenes_init(ins, 8, permanent); incenter_scenes_init(ins, 8, permanent);
// create the sculpture // create the sculpture
u32 lights_per_primary_city = 123; u32 lights_per_primary_city = 123;
u32 primary_city_lights = (city_count + 1) * lights_per_primary_city; u32 primary_city_lights = (city_count + 1) * lights_per_primary_city;
@ -142,7 +129,7 @@ incenter_init(App_State* state)
Assembly_Strip* vertical_strip = assembly_add_strip(&state->assemblies, ah, 123); Assembly_Strip* vertical_strip = assembly_add_strip(&state->assemblies, ah, 123);
assembly_strip_create_leds( assembly_strip_create_leds(
&state->assemblies, &state->assemblies,
ah, ah,
vertical_strip, vertical_strip,
start_p, start_p,
@ -156,7 +143,7 @@ incenter_init(App_State* state)
{ {
Incenter_City_Desc city = city_descs[i]; Incenter_City_Desc city = city_descs[i];
v3 end_p = incenter_latlng_to_cartesian(city.lat, city.lon, radius).xyz; v3 end_p = incenter_latlng_to_cartesian(city.lat, city.lon, radius).xyz;
Assembly_Strip* strip = assembly_add_strip(&state->assemblies, ah, 123); Assembly_Strip* strip = assembly_add_strip(&state->assemblies, ah, 123);
strip->output_kind = OutputData_NetworkSACN; strip->output_kind = OutputData_NetworkSACN;
strip->sacn_universe = city.sacn_universe; strip->sacn_universe = city.sacn_universe;
@ -178,12 +165,16 @@ incenter_init(App_State* state)
// PATTERN INIT // PATTERN INIT
pattern_random_fill_prep(); pattern_random_fill_prep();
r32 rad = 0.05f; r32 rad = 0.05f;
sculpture_updated(state, 5, rad); sculpture_updated(state, 5, rad);
scratch_release(scratch);
ins->running = true;
incenter_interface_connection_init(state, ins);
printf("Incenter Initialized\n"); printf("Incenter Initialized\n");
scratch_release(scratch);
} }
internal void internal void
@ -201,11 +192,11 @@ incenter_sculpture_visualizer_ui(App_State* state, Editor* ed)
layout.bounds_min = (v2){0, 0}, layout.bounds_min = (v2){0, 0},
layout.bounds_max.x = 250; layout.bounds_max.x = 250;
ui_layout_push(&ed->ui, &layout); ui_layout_push(&ed->ui, &layout);
Incenter_State* ins = (Incenter_State*)state->user_space_data; Incenter_State* ins = (Incenter_State*)state->user_space_data;
ui_text_f(&ed->ui, WHITE_V4, "Scene Time: %fs", ins->scene_time); ui_text_f(&ed->ui, WHITE_V4, "Scene Time: %fs", ins->scene_time);
ui_text_f(&ed->ui, WHITE_V4, "Scene: %s", ins->scenes[ins->scene_at].name); ui_text_f(&ed->ui, WHITE_V4, "Scene: %s", ins->scenes[ins->scene_at].name);
ui_layout_pop(&ed->ui); ui_layout_pop(&ed->ui);
} }
#endif #endif
@ -215,21 +206,26 @@ incenter_frame(App_State* state)
{ {
Incenter_State* ins = (Incenter_State*)state->user_space_data; Incenter_State* ins = (Incenter_State*)state->user_space_data;
Assembly_Array assemblies = state->assemblies; Assembly_Array assemblies = state->assemblies;
{ // INPUT HANDLING { // INPUT HANDLING
Input_State* is = state->input_state; Input_State* is = state->input_state;
if (input_key_went_down(is, KeyCode_LeftArrow)) incenter_scene_go_to_prev(ins); if (input_key_went_down(is, KeyCode_LeftArrow)) incenter_scene_go_to_prev(ins);
if (input_key_went_down(is, KeyCode_RightArrow)) incenter_scene_go_to_next(ins); if (input_key_went_down(is, KeyCode_RightArrow)) incenter_scene_go_to_next(ins);
} }
incenter_interface_connection_frame(state, ins);
ins->scene_time += state->target_seconds_per_frame; ins->scene_time += state->target_seconds_per_frame;
ins->transition_time += state->target_seconds_per_frame; ins->transition_time += state->target_seconds_per_frame;
incenter_scene_render(state, ins); incenter_scene_render(state, ins);
} }
internal void internal void
incenter_cleanup(App_State* state) incenter_cleanup(App_State* state)
{ {
Incenter_State* ins = (Incenter_State*)state->user_space_data;
ins->running = false;
os_thread_end(ins->interface_thread);
incenter_interface_connection_cleanup(ins);
} }

View File

@ -1,4 +1,10 @@
#define INCENTER_METER 1.0f
#define INCENTER_FOOT 0.3048f
#define INCENTER_METERS(count) (count) * INCENTER_METER
#define INCENTER_FEET(count) (count) * INCENTER_FOOT
#define INCENTER_PER_METER(count) INCENTER_METER / (r32)(count)
typedef u32 Incenter_City_Id; typedef u32 Incenter_City_Id;
enum { enum {
@ -21,12 +27,12 @@ typedef struct Incenter_City_Desc Incenter_City_Desc;
struct Incenter_City_Desc struct Incenter_City_Desc
{ {
Incenter_City_Id id; Incenter_City_Id id;
r32 lat; r32 lat;
r32 lon; r32 lon;
u32 sacn_universe; u32 sacn_universe;
// TODO: Some way to access this cities strip of leds // TODO: Some way to access this cities strip of leds
}; };
@ -47,8 +53,8 @@ struct Incenter_Data_Row
#include "../../run_tree/data/incenter_data/c/question_1.h" #include "../../run_tree/data/incenter_data/c/question_1.h"
#include "../../run_tree/data/incenter_data/c/question_2.h" #include "../../run_tree/data/incenter_data/c/question_2.h"
#include "../../run_tree/data/incenter_data/c/question_3.h" #include "../../run_tree/data/incenter_data/c/question_3.h"
//#include "../../run_tree/data/incenter_data/c/question_4.h" #include "../../run_tree/data/incenter_data/c/question_4.h"
//#include "../../run_tree/data/incenter_data/c/question_5.h" #include "../../run_tree/data/incenter_data/c/question_5.h"
#include "../../run_tree/data/incenter_data/c/question_6.h" #include "../../run_tree/data/incenter_data/c/question_6.h"
#include "../../run_tree/data/incenter_data/c/question_7.h" #include "../../run_tree/data/incenter_data/c/question_7.h"
#include "../../run_tree/data/incenter_data/c/question_8.h" #include "../../run_tree/data/incenter_data/c/question_8.h"
@ -64,6 +70,7 @@ struct Incenter_Data_Row
#include "../../run_tree/data/incenter_data/c/question_18.h" #include "../../run_tree/data/incenter_data/c/question_18.h"
#include "../../run_tree/data/incenter_data/c/question_19.h" #include "../../run_tree/data/incenter_data/c/question_19.h"
#include "../../run_tree/data/incenter_data/c/question_20.h" #include "../../run_tree/data/incenter_data/c/question_20.h"
#include "../../run_tree/data/incenter_data/c/question_21.h"
typedef struct Incenter_State Incenter_State; typedef struct Incenter_State Incenter_State;
@ -72,16 +79,25 @@ typedef void Incenter_Pattern(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array
typedef u32 Incenter_Scene_Mode; typedef u32 Incenter_Scene_Mode;
enum { enum {
Incenter_SceneMode_Intro, Incenter_SceneMode_Intro,
Incenter_SceneMode_Input,
Incenter_SceneMode_Passive, Incenter_SceneMode_Passive,
Incenter_SceneMode_Count, Incenter_SceneMode_Count,
Incenter_SceneMode_Input,
Incenter_SceneMode_TransitioningOut, Incenter_SceneMode_TransitioningOut,
Incenter_SceneMode_TransitioningIn, Incenter_SceneMode_TransitioningIn,
}; };
#define INCENTER_TRANSITION_DURATION 5 #define INCENTER_TRANSITION_DURATION 3
#define INCENTER_TRANSITION_SUN_REVEAL_DURATION 3 #define INCENTER_TRANSITION_SUN_REVEAL_DURATION 2
typedef u8 Incenter_Scene_Kind;
enum {
Incenter_SceneKind_Information,
Incenter_SceneKind_YesOrNo,
Incenter_SceneKind_ThreeOption,
Incenter_SceneKind_SlidingScale,
Incenter_SceneKind_Count,
};
typedef struct Incenter_Scene Incenter_Scene; typedef struct Incenter_Scene Incenter_Scene;
struct Incenter_Scene struct Incenter_Scene
@ -90,6 +106,43 @@ struct Incenter_Scene
Incenter_Pattern* patterns[Incenter_SceneMode_Count]; Incenter_Pattern* patterns[Incenter_SceneMode_Count];
Incenter_Data_Row* data; Incenter_Data_Row* data;
u32 data_len; u32 data_len;
Incenter_Scene_Kind kind;
};
// INLH is abbrev for INcenter Live data Header
#define LIVE_DATA_HEADER_MAGIC_NUMBER "INLH"
// INLB is abbrev for INcenter Live data Bucket
#define LIVE_DATA_BUCKET_MAGIC_NUMBER "INLB"
typedef struct Live_Answers_File_Header Live_Answers_File_Header;
struct Live_Answers_File_Header
{
u8 magic[4];
u32 buckets_count;
u32 answers_total_count;
};
typedef struct Live_Answers_File_Bucket Live_Answers_File_Bucket;
struct Live_Answers_File_Bucket
{
u8 magic[4];
// the value this bucket represents.
union {
u32 answer_u32;
r32 answer_r32;
};
// The number of responses that fit within this bucket
u32 count;
};
typedef struct Live_Answers_File Live_Answers_File;
struct Live_Answers_File
{
String path;
Live_Answers_File_Header* header;
Live_Answers_File_Bucket* buckets;
}; };
struct Incenter_State struct Incenter_State
@ -101,4 +154,37 @@ struct Incenter_State
Incenter_Scene_Mode scene_mode; Incenter_Scene_Mode scene_mode;
r64 scene_time; r64 scene_time;
r64 transition_time; r64 transition_time;
};
bool running;
Thread_Handle interface_thread;
Socket_Handle interface_socket;
// Ring buffer of interface messages. All
#define INTERFACE_MESSAGES_CAP 8
#define INTERFACE_MESSAGE_SIZE 512
Data interface_messages[INTERFACE_MESSAGES_CAP];
u32 interface_messages_write_next;
u32 interface_messages_read_next;
// User Input
r32 input_pct;
u32 input_option;
b8 input_advance;
};
internal v4
incenter_latlng_to_cartesian(r32 lat, r32 lng, r32 radius)
{
r32 theta = (lat / 180.0f) * r32_pi;
r32 phi = (lng / 180.0f) * r32_pi;
// spherical to cartesian conversion
v4 result = {
radius * sinf(phi) * cosf(theta),
radius * sinf(phi) * sinf(theta),
radius * cosf(phi),
1
};
return result;
}

View File

@ -1,21 +1,32 @@
SCENES:
1. Internal representation of current scene, next and prev
2. Sequence
- Loading Scene
- Scene Intro
- Scene Question
- Scene Passive
TODO: TODO:
- sync with Cameron to do a system test
- sync with Tyler on data
- Plasma Ray - light from primary city out to secondary splash - Plasma Ray - light from primary city out to secondary splash
- Connection Pattern - fill part up with light, have the empty space do the data flow pattern x Connection Pattern - fill part up with light, have the empty space do the data flow pattern
- Spatially Vertical Rain (not spherical) - Spatially Vertical Rain (not spherical)
- Something like rain for data viz - Something like rain for data viz
- Rendering gifs to the secondary cities - Rendering gifs to the secondary cities
- Give Tyler a deadline for data scenes to test
Anyone Home
- some light, but low power mode
- blues, match screen - guide person towards display
Welcome Home
- keep the secondary cities off
Felt Isolated - blues, cooler tones, water?
Nature - gold, pink/purple - drinking champagne - carousel colors
- bluring the ends of bars is ok, just keep it consistent
For data sets that have really high values everywhere, grow them in one at a time
- for connection based ones: grow first, ripple out secondary cities to the next nearest primary city, grow that one
QUESTION: Are we showing a statement about the data during the passive mode of each scene?
- Yes
QUESTION: Can we change the scene ids? Does it matter if two screens have the same sceneId?
TODO: Put together an ending scene