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

1
.gitignore vendored
View File

@ -12,3 +12,4 @@ sysroot/
*.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)
{ {
@ -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 // testing file io
File_Handle f = os_file_open(lit_str("text.txt"), FileAccess_Read | FileAccess_Write, FileCreate_OpenExisting); String fp = lit_str("text.txt");
File_Info i = os_file_get_info(f, scratch.a); File_Handle f = os_file_open(fp, FileAccess_Write, FileCreate_OpenAlways);
assert(f.value != 0);
Data d0 = os_file_read_all(f, scratch.a);
assert(d0.size > 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

@ -14,6 +14,8 @@ os_file_open(String path, File_Access_Flags flags_access, File_Create_Flags fla
{ {
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)))
{ {
@ -34,12 +36,24 @@ os_file_open(String path, File_Access_Flags flags_access, File_Create_Flags fla
} }
} }
// 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;
} }
@ -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)
{ {

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,18 +1,102 @@
#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)
{ {
// 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; 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
os_interlocked_increment(volatile u32* value) os_interlocked_increment(volatile u32* value)
@ -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);
// returns the new value of the provided variable
u32 os_interlocked_increment(volatile u32* value); u32 os_interlocked_increment(volatile u32* value);
u32 os_interlocked_cmp_exchg(volatile u32* dest, u32 new_value, u32 old_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,8 +54,9 @@ 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);

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,6 +53,7 @@ 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)
@ -273,15 +276,15 @@ int main (int arg_count, char** args)
} }
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");

View File

@ -11,6 +11,8 @@ os_file_open(String path, File_Access_Flags flags_access, File_Create_Flags fla
{ {
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)))
{ {
@ -32,16 +34,28 @@ os_file_open(String path, File_Access_Flags flags_access, File_Create_Flags fla
} }
} }
// 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)
{ {

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,11 +29,23 @@ os_socket_create(s32 domain, s32 type, s32 protocol)
} }
bool bool
os_socket_bind() os_socket_bind(Socket_Handle socket, u32 port)
{ {
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 false;
} }
return true;
}
bool bool
os_socket_connect() os_socket_connect()
{ {
@ -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

@ -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)
{ {
@ -780,7 +798,33 @@ 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,
Color_Ramp color_ramp)
{
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, r32 period, r32 offset, r32 radius,
v3 color) v3 color)
{ {
@ -826,9 +870,9 @@ pattern_data_flow(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Inc
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);
} }
@ -906,74 +950,13 @@ pattern_sun_passive(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, I
} }
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;
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];
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_Intro);
}
void
pattern_bar_chart(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++) for (u32 row_i = 0; row_i < scene.data_len; row_i++)
{ {
Incenter_Data_Row row = scene.data[row_i]; Incenter_Data_Row row = scene.data[row_i];
if (row.year != year || row.month != month) continue;
Assembly_Strip strip = strips.strips[row.id]; Assembly_Strip strip = strips.strips[row.id];
for (u32 led_i = 0; led_i < strip.pixels_len; led_i++) for (u32 led_i = 0; led_i < strip.pixels_len; led_i++)
{ {
@ -983,13 +966,76 @@ pattern_bar_chart(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Inc
r32 pct = 1 - ((r32)led_i / (r32)strip.pixels_len); r32 pct = 1 - ((r32)led_i / (r32)strip.pixels_len);
if (pct < row.prop) { if (pct < row.prop) {
r32 cpct = pct / row.prop; r32 cpct = pct / row.prop;
Assembly_Pixel p = color_ramp_eval_pixel(xray_ramp, cpct); Assembly_Pixel p = color_ramp_eval_pixel(color_ramp, cpct);
pixels.pixels[led_index] = p; pixels.pixels[led_index] = p;
} }
} }
} }
} }
void
pattern_bar_chart(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);
pattern_add_bar_chart(pixels, strips, ins, scene, scene.data[0].year, scene.data[0].month, xray_ramp);
}
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)
{
last_scene_at = ins->scene_at;
// Determine what the end of the data set is
for (u32 row_i = 0; row_i < scene.data_len; row_i++)
{
Incenter_Data_Row row = scene.data[row_i];
if (row.year >= year_max) {
year_max = row.year;
month_max = max(row.month, month_max);
}
}
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);
}
//////////////////////////////////////// ////////////////////////////////////////
// Felt Isolated // Felt Isolated
@ -1072,3 +1118,270 @@ pattern_rainbow(Assembly_Pixel_Buffer pixels, Assembly_Strip_Array strips, Incen
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

@ -7,31 +7,32 @@ 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,8 +47,8 @@ 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){
@ -55,8 +56,8 @@ incenter_scene_descs_init()
.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){
@ -64,32 +65,32 @@ incenter_scene_descs_init()
.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){
@ -97,32 +98,34 @@ incenter_scene_descs_init()
.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){
@ -130,52 +133,45 @@ incenter_scene_descs_init()
.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){
@ -183,32 +179,10 @@ incenter_scene_descs_init()
.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){
@ -216,10 +190,10 @@ incenter_scene_descs_init()
.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){
@ -227,43 +201,21 @@ incenter_scene_descs_init()
.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){
@ -271,32 +223,21 @@ incenter_scene_descs_init()
.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){
@ -304,11 +245,88 @@ incenter_scene_descs_init()
.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,8 +57,13 @@ 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;
} }
} }
} }
@ -90,6 +73,7 @@ incenter_scene_render(App_State* state, Incenter_State* ins)
{ {
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];
@ -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
@ -181,9 +168,13 @@ incenter_init(App_State* state)
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
@ -222,6 +213,8 @@ incenter_frame(App_State* state)
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);
@ -231,5 +224,8 @@ incenter_frame(App_State* state)
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 {
@ -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