network sacn outputting correctly on mac
This commit is contained in:
parent
8c904d5c1c
commit
0651c96f99
Binary file not shown.
|
@ -275,10 +275,10 @@ InitStreamHeader (u8* Buffer, s32 BufferSize,
|
||||||
Cursor = PackB1(Cursor, ADDRESS_AND_DATA_FORMAT);
|
Cursor = PackB1(Cursor, ADDRESS_AND_DATA_FORMAT);
|
||||||
|
|
||||||
// DMP first property address
|
// DMP first property address
|
||||||
Cursor = PackB2(Cursor, 0);
|
Cursor = PackB1(Cursor, 0);
|
||||||
|
|
||||||
// DMP Address Increment
|
// DMP Address Increment
|
||||||
Cursor = PackB2(Cursor, ADDRESS_INC);
|
Cursor = PackB1(Cursor, ADDRESS_INC);
|
||||||
|
|
||||||
// Property Value Count -- Includes one byte for start code
|
// Property Value Count -- Includes one byte for start code
|
||||||
Cursor = PackB2(Cursor, SlotCount + 1);
|
Cursor = PackB2(Cursor, SlotCount + 1);
|
||||||
|
|
|
@ -199,7 +199,7 @@ dw_get_u8(Data_Writer* w)
|
||||||
u8 result = 0;
|
u8 result = 0;
|
||||||
if (w->at < w->data.size)
|
if (w->at < w->data.size)
|
||||||
{
|
{
|
||||||
result = w->data.base[w->at++];
|
result = w->data.base[w->at];
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,91 @@
|
||||||
|
|
||||||
typedef struct { u64 value; } Socket_Handle;
|
typedef struct { u64 value; } Socket_Handle;
|
||||||
|
|
||||||
// TODO
|
u16 endian_swap_u16(u16 v);
|
||||||
|
u32 endian_swap_u32(u32 v);
|
||||||
|
u64 endian_swap_u64(u64 v);
|
||||||
|
|
||||||
|
#define hton_u16(v) endian_swap_u16(v)
|
||||||
|
#define hton_u32(v) endian_swap_u32(v)
|
||||||
|
#define hton_u64(v) endian_swap_u64(v)
|
||||||
|
#define ntoh_s16(v) endian_swap_u16(v)
|
||||||
|
#define ntoh_s32(v) endian_swap_u32(v)
|
||||||
|
#define ntoh_s64(v) endian_swap_u64(v)
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////
|
||||||
|
// Implementation
|
||||||
|
|
||||||
|
u16
|
||||||
|
endian_swap_u16(u16 v)
|
||||||
|
{
|
||||||
|
u8* p = (u8*)&v;
|
||||||
|
u16 result = (u16)(
|
||||||
|
(p[0] << 8) |
|
||||||
|
(p[1] << 0)
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32
|
||||||
|
endian_swap_u32(u32 v)
|
||||||
|
{
|
||||||
|
u8* p = (u8*)&v;
|
||||||
|
u32 result = (u32)(
|
||||||
|
(p[0] << 24) |
|
||||||
|
(p[1] << 16) |
|
||||||
|
(p[2] << 8) |
|
||||||
|
(p[3] << 0)
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64
|
||||||
|
endian_swap_u64(u64 v)
|
||||||
|
{
|
||||||
|
u8* p = (u8*)&v;
|
||||||
|
u64 result = (u64)(
|
||||||
|
((u64)p[0] << 56) |
|
||||||
|
((u64)p[1] << 48) |
|
||||||
|
((u64)p[2] << 40) |
|
||||||
|
((u64)p[3] << 32) |
|
||||||
|
((u64)p[4] << 24) |
|
||||||
|
((u64)p[5] << 16) |
|
||||||
|
((u64)p[6] << 8) |
|
||||||
|
((u64)p[7] << 0)
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(DEBUG)
|
||||||
|
|
||||||
|
void
|
||||||
|
core_socket_tests()
|
||||||
|
{
|
||||||
|
// u16 endian swap
|
||||||
|
u16 a_0 = 0xABCD;
|
||||||
|
u16 a_1 = endian_swap_u16(a_0);
|
||||||
|
u16 a_2 = endian_swap_u16(a_1);
|
||||||
|
assert(a_1 == 0xCDAB);
|
||||||
|
assert(a_2 == a_0);
|
||||||
|
|
||||||
|
// u32 endian swap
|
||||||
|
u32 b_0 = 0x89ABCDEF;
|
||||||
|
u32 b_1 = endian_swap_u32(b_0);
|
||||||
|
u32 b_2 = endian_swap_u32(b_1);
|
||||||
|
assert(b_1 == 0xEFCDAB89);
|
||||||
|
assert(b_2 == b_0);
|
||||||
|
|
||||||
|
// u64 endian swap
|
||||||
|
u64 c_0 = 0x7654321089ABCDEF;
|
||||||
|
u64 c_1 = endian_swap_u64(c_0);
|
||||||
|
u64 c_2 = endian_swap_u64(c_1);
|
||||||
|
assert(c_1 == 0xEFCDAB8910325476);
|
||||||
|
assert(c_2 == c_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
# define core_socket_tests()
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // LUMENARIUM_CORE_SOCKET_H
|
#endif // LUMENARIUM_CORE_SOCKET_H
|
|
@ -1,6 +1,8 @@
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
// String
|
// String
|
||||||
|
|
||||||
|
internal u64 c_str_len(char* s);
|
||||||
|
|
||||||
// NOTE(PS): even though this has a len and cap, it should always be
|
// NOTE(PS): even though this has a len and cap, it should always be
|
||||||
// null terminated
|
// null terminated
|
||||||
typedef struct String String;
|
typedef struct String String;
|
||||||
|
@ -296,4 +298,22 @@ dw_put_str(Data_Writer* w, String str)
|
||||||
{
|
{
|
||||||
dw_put_u8(w, str.str[i]);
|
dw_put_u8(w, str.str[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
dw_put_str_min_len(Data_Writer* w, String str, u64 min_len)
|
||||||
|
{
|
||||||
|
u64 start = w->at;
|
||||||
|
dw_put_str(w, str);
|
||||||
|
if (str.len < min_len)
|
||||||
|
{
|
||||||
|
w->at = start + min_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
dw_put_str_min_len_nullterm(Data_Writer* w, String str, u64 min_len)
|
||||||
|
{
|
||||||
|
dw_put_str_min_len(w, str, min_len);
|
||||||
|
w->data.base[w->at - 1] = '\0';
|
||||||
}
|
}
|
|
@ -7,9 +7,9 @@ en_init(App_State* state, App_Init_Desc desc)
|
||||||
state->assemblies = assembly_array_create(permanent, desc.assembly_cap);
|
state->assemblies = assembly_array_create(permanent, desc.assembly_cap);
|
||||||
|
|
||||||
Output* o = &state->output;
|
Output* o = &state->output;
|
||||||
register_output_method(o, OutputData_Invalid, 0, 0);
|
register_output_method(o, OutputData_Invalid, 0, 0, 0);
|
||||||
register_output_method(o, OutputData_NetworkSACN, output_network_sacn_build, output_network_sacn_init());
|
register_output_method(o, OutputData_NetworkSACN, output_network_sacn_update, output_network_sacn_build, output_network_sacn_init());
|
||||||
register_output_method(o, OutputData_ComUART, output_network_sacn_build, output_com_uart_init());
|
register_output_method(o, OutputData_ComUART, 0, output_network_sacn_build, output_com_uart_init());
|
||||||
|
|
||||||
lumenarium_env_validate();
|
lumenarium_env_validate();
|
||||||
}
|
}
|
||||||
|
@ -50,28 +50,38 @@ en_frame(App_State* state)
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Output Data
|
// Output Data
|
||||||
|
Output_Methods methods = state->output.methods;
|
||||||
|
|
||||||
|
// update each method that has an update method
|
||||||
|
for (u32 i = 0; i < OutputData_Count; i++)
|
||||||
|
{
|
||||||
|
if (methods.update_procs[i] == 0) continue;
|
||||||
|
methods.update_procs[i](methods.method_data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
Output_Data_Queue output_queue = {};
|
Output_Data_Queue output_queue = {};
|
||||||
output_queue.a = scratch.a;
|
output_queue.a = scratch.a;
|
||||||
|
|
||||||
// build output data buffers
|
// build output data buffers
|
||||||
Output_Methods methods = state->output.methods;
|
|
||||||
for (u32 i = 0; i < assemblies.len; i++)
|
for (u32 i = 0; i < assemblies.len; i++)
|
||||||
{
|
{
|
||||||
Assembly_Strip_Array strips = assemblies.strip_arrays[i];
|
Assembly_Strip_Array strips = assemblies.strip_arrays[i];
|
||||||
|
Assembly_Pixel_Buffer* pixels = assemblies.pixel_buffers + i;
|
||||||
for (u32 j = 0; j < strips.len; j++)
|
for (u32 j = 0; j < strips.len; j++)
|
||||||
{
|
{
|
||||||
Assembly_Strip* strip = strips.strips + j;
|
Assembly_Strip* strip = strips.strips + j;
|
||||||
Build_Output_Data_Buffer* method_proc = methods.procs[strip->output_kind];
|
Build_Output_Data_Buffer* method_proc = methods.procs[strip->output_kind];
|
||||||
u8* method_data = methods.method_data[strip->output_kind];
|
u8* method_data = methods.method_data[strip->output_kind];
|
||||||
if (method_proc == 0) continue;
|
if (method_proc == 0) continue;
|
||||||
method_proc(state, i, strip, method_data, &output_queue);
|
method_proc(state, i, pixels, strip, method_data, &output_queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// output the buffers
|
// output the buffers
|
||||||
// TODO(PS): we could sort these first if switchig between output
|
// TODO(PS): we could sort these first if switchig between output
|
||||||
// types is time consuming
|
// types is time consuming
|
||||||
|
|
||||||
|
Sacn* sacn = (Sacn*)state->output.methods.method_data[OutputData_NetworkSACN];
|
||||||
for (Output_Data* at = output_queue.first; at != 0; at = at->next)
|
for (Output_Data* at = output_queue.first; at != 0; at = at->next)
|
||||||
{
|
{
|
||||||
// NOTE(PS): we can overload each switch case as more methods come in
|
// NOTE(PS): we can overload each switch case as more methods come in
|
||||||
|
@ -82,7 +92,13 @@ en_frame(App_State* state)
|
||||||
{
|
{
|
||||||
case OutputData_NetworkSACN:
|
case OutputData_NetworkSACN:
|
||||||
{
|
{
|
||||||
// TODO(PS): platform network io
|
os_socket_send_to(
|
||||||
|
sacn->socket,
|
||||||
|
at->network.v4_addr,
|
||||||
|
at->network.port,
|
||||||
|
at->data,
|
||||||
|
0
|
||||||
|
);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case OutputData_ComUART:
|
case OutputData_ComUART:
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
register_output_method(Output* output, Output_Data_Kind kind, Build_Output_Data_Buffer* proc, u8* method_data)
|
register_output_method(Output* output, Output_Data_Kind kind, Output_Method_Update* update, Build_Output_Data_Buffer* proc, u8* method_data)
|
||||||
{
|
{
|
||||||
|
output->methods.update_procs[kind] = update;
|
||||||
output->methods.procs[kind] = proc;
|
output->methods.procs[kind] = proc;
|
||||||
output->methods.method_data[kind] = method_data;
|
output->methods.method_data[kind] = method_data;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +14,7 @@ output_data_queue_push(Output_Data_Queue* q, u32 size, Output_Data_Kind kind)
|
||||||
d->kind = kind;
|
d->kind = kind;
|
||||||
d->data.size = size;
|
d->data.size = size;
|
||||||
d->data.base = allocator_alloc(q->a, size);
|
d->data.base = allocator_alloc(q->a, size);
|
||||||
|
sll_push(q->first, q->last, d);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,11 +49,13 @@ struct Output_Data_Queue
|
||||||
Allocator* a;
|
Allocator* a;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void Build_Output_Data_Buffer(App_State* state, u32 assembly_id, Assembly_Strip* strip, u8* method_data, Output_Data_Queue* queue);
|
typedef void Output_Method_Update(u8* method_data);
|
||||||
|
typedef void Build_Output_Data_Buffer(App_State* state, u32 assembly_id, Assembly_Pixel_Buffer* pixels, Assembly_Strip* strip, u8* method_data, Output_Data_Queue* queue);
|
||||||
|
|
||||||
typedef struct Output_Methods Output_Methods;
|
typedef struct Output_Methods Output_Methods;
|
||||||
struct Output_Methods
|
struct Output_Methods
|
||||||
{
|
{
|
||||||
|
Output_Method_Update* update_procs[OutputData_Count];
|
||||||
Build_Output_Data_Buffer* procs[OutputData_Count];
|
Build_Output_Data_Buffer* procs[OutputData_Count];
|
||||||
u8* method_data[OutputData_Count];
|
u8* method_data[OutputData_Count];
|
||||||
};
|
};
|
||||||
|
@ -64,7 +66,7 @@ struct Output
|
||||||
Output_Methods methods;
|
Output_Methods methods;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void register_output_method(Output* output, Output_Data_Kind kind, Build_Output_Data_Buffer* proc, u8* method_data);
|
internal void register_output_method(Output* output, Output_Data_Kind kind, Output_Method_Update* update, Build_Output_Data_Buffer* proc, u8* method_data);
|
||||||
|
|
||||||
internal Output_Data* output_data_queue_push(Output_Data_Queue* q, u32 size, Output_Data_Kind kind);
|
internal Output_Data* output_data_queue_push(Output_Data_Queue* q, u32 size, Output_Data_Kind kind);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#define SACN_DEFAULT_PORT 5568
|
#define SACN_DEFAULT_PORT 5568
|
||||||
|
|
||||||
|
#define SACN_STARTCODE_DMX 0
|
||||||
|
|
||||||
// a description of the address space being used
|
// a description of the address space being used
|
||||||
#define SACN_PREAMBLE_SIZE_ADDR 0
|
#define SACN_PREAMBLE_SIZE_ADDR 0
|
||||||
|
@ -59,13 +60,12 @@ internal void
|
||||||
sacn_vhd_pack_flags(Data_Writer* w, b8 inherit_vec, b8 inherit_head, b8 inherit_data)
|
sacn_vhd_pack_flags(Data_Writer* w, b8 inherit_vec, b8 inherit_head, b8 inherit_data)
|
||||||
{
|
{
|
||||||
u8 last_byte = dw_get_u8(w) & 0x8F;
|
u8 last_byte = dw_get_u8(w) & 0x8F;
|
||||||
w->at -= 1;
|
|
||||||
|
|
||||||
if (!inherit_vec) { last_byte |= SACN_VHD_V_FLAG; }
|
if (!inherit_vec) { last_byte |= SACN_VHD_V_FLAG; }
|
||||||
if (!inherit_head) { last_byte |= SACN_VHD_H_FLAG; }
|
if (!inherit_head) { last_byte |= SACN_VHD_H_FLAG; }
|
||||||
if (!inherit_data) { last_byte |= SACN_VHD_D_FLAG; }
|
if (!inherit_data) { last_byte |= SACN_VHD_D_FLAG; }
|
||||||
|
|
||||||
dw_put_u8(w, last_byte);
|
w->data.base[w->at] = last_byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -86,7 +86,6 @@ sacn_vhd_pack_len(Data_Writer* w, u32 len, b8 include_len)
|
||||||
|
|
||||||
// Mask out the length bits to keep flags intact
|
// Mask out the length bits to keep flags intact
|
||||||
u8 last_byte = dw_get_u8(w) & 0x70;
|
u8 last_byte = dw_get_u8(w) & 0x70;
|
||||||
w->at -= 1;
|
|
||||||
|
|
||||||
if (len_adjusted > SACN_VHD_MAXMINLENGTH) last_byte |= SACN_VHD_L_FLAG;
|
if (len_adjusted > SACN_VHD_MAXMINLENGTH) last_byte |= SACN_VHD_L_FLAG;
|
||||||
|
|
||||||
|
@ -105,14 +104,230 @@ sacn_vhd_pack_len(Data_Writer* w, u32 len, b8 include_len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CopyMemoryTo(from, to, size) CopyMemory_((u8*)(from), (u8*)(to), (size))
|
||||||
|
internal void
|
||||||
|
CopyMemory_(u8* From, u8* To, u64 Size)
|
||||||
|
{
|
||||||
|
for (u64 i = 0; i < Size; i++)
|
||||||
|
{
|
||||||
|
To[i] = From[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packs a u8 to a known big endian buffer
|
||||||
|
u8*
|
||||||
|
PackB1(u8* ptr, u8 val)
|
||||||
|
{
|
||||||
|
*ptr = val;
|
||||||
|
return ptr + sizeof(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Unpacks a u8 from a known big endian buffer
|
||||||
|
u8
|
||||||
|
UpackB1(const u8* ptr)
|
||||||
|
{
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Packs a u8 to a known little endian buffer
|
||||||
|
u8*
|
||||||
|
PackL1(u8* ptr, u8 val)
|
||||||
|
{
|
||||||
|
*ptr = val;
|
||||||
|
return ptr + sizeof(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Unpacks a u8 from a known little endian buffer
|
||||||
|
u8
|
||||||
|
UpackL1(const u8* ptr)
|
||||||
|
{
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8*
|
||||||
|
PackB2(u8* ptr, u16 val)
|
||||||
|
{
|
||||||
|
ptr[1] = (u8)(val & 0xff);
|
||||||
|
ptr[0] = (u8)((val & 0xff00) >> 8);
|
||||||
|
return ptr + sizeof(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Unpacks a u16 from a known big endian buffer
|
||||||
|
u16
|
||||||
|
UpackB2(const u8* ptr)
|
||||||
|
{
|
||||||
|
return (u16)(ptr[1] | ptr[0] << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Packs a u32 to a known big endian buffer
|
||||||
|
u8*
|
||||||
|
PackB4(u8* ptr, u32 val)
|
||||||
|
{
|
||||||
|
ptr[3] = (u8) (val & 0xff);
|
||||||
|
ptr[2] = (u8)((val & 0xff00) >> 8);
|
||||||
|
ptr[1] = (u8)((val & 0xff0000) >> 16);
|
||||||
|
ptr[0] = (u8)((val & 0xff000000) >> 24);
|
||||||
|
return ptr + sizeof(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
VHD_PackFlags_(u8* Buffer, b32 InheritVec, b32 InheritHead, b32 InheritData)
|
||||||
|
{
|
||||||
|
u8* Cursor = Buffer;
|
||||||
|
u8 NewByte = UpackB1(Cursor) & 0x8f;
|
||||||
|
|
||||||
|
if (!InheritVec) { NewByte |= SACN_VHD_V_FLAG; }
|
||||||
|
if (!InheritHead) { NewByte |= SACN_VHD_H_FLAG; }
|
||||||
|
if (!InheritData) { NewByte |= SACN_VHD_D_FLAG; }
|
||||||
|
|
||||||
|
PackB1(Cursor, NewByte);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal u8*
|
||||||
|
VHD_PackLength_(u8* Buffer, u32 Length, b32 IncludeLength)
|
||||||
|
{
|
||||||
|
u8* Cursor = Buffer;
|
||||||
|
u32 AdjustedLength = Length;
|
||||||
|
if (IncludeLength)
|
||||||
|
{
|
||||||
|
if (Length + 1 > SACN_VHD_MAXMINLENGTH)
|
||||||
|
{
|
||||||
|
AdjustedLength += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AdjustedLength += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mask out the length bits to keep flags intact
|
||||||
|
u8 NewByte = UpackB1(Cursor) & 0x70;
|
||||||
|
if (AdjustedLength > SACN_VHD_MAXMINLENGTH)
|
||||||
|
{
|
||||||
|
NewByte |= SACN_VHD_L_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 PackBuffer[4];
|
||||||
|
PackB4(PackBuffer, AdjustedLength);
|
||||||
|
if (AdjustedLength <= SACN_VHD_MAXMINLENGTH)
|
||||||
|
{
|
||||||
|
NewByte |= (PackBuffer[2] & 0x0f);
|
||||||
|
Cursor = PackB1(Cursor, NewByte);
|
||||||
|
Cursor = PackB1(Cursor, PackBuffer[3]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NewByte |= (PackBuffer[1] & 0x0f);
|
||||||
|
Cursor = PackB1(Cursor, PackBuffer[2]);
|
||||||
|
Cursor = PackB1(Cursor, PackBuffer[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
InitStreamHeader (u8* Buffer, s32 BufferSize,
|
||||||
|
u16 SlotCount,
|
||||||
|
u8 StartCode,
|
||||||
|
u16 Universe,
|
||||||
|
u8 Priority,
|
||||||
|
u16 Reserved,
|
||||||
|
u8 Options,
|
||||||
|
const char* SourceName,
|
||||||
|
Sacn_Cid CID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// TODO(pjs): Replace packing with gs_memory_cursor
|
||||||
|
|
||||||
|
u8* Cursor = Buffer;
|
||||||
|
|
||||||
|
// Preamble Size
|
||||||
|
Cursor = PackB2(Cursor, SACN_RLP_PREAMBLE_SIZE);
|
||||||
|
Cursor = PackB2(Cursor, SACN_RLP_POSTAMBLE_SIZE);
|
||||||
|
|
||||||
|
CopyMemoryTo(SACN_ACN_IDENTIFIER.str, Cursor, SACN_ACN_IDENTIFIER_SIZE);
|
||||||
|
Cursor += SACN_ACN_IDENTIFIER_SIZE;
|
||||||
|
|
||||||
|
// TODO(Peter): If you never use this anywhere else, go back and remove the parameters
|
||||||
|
VHD_PackFlags_(Cursor, false, false, false);
|
||||||
|
Cursor = VHD_PackLength_(Cursor,
|
||||||
|
SACN_BUFFER_HEADER_SIZE - SACN_RLP_PREAMBLE_SIZE + SlotCount,
|
||||||
|
false);
|
||||||
|
|
||||||
|
// root vector
|
||||||
|
Cursor = PackB4(Cursor, SACN_ROOT_VECTOR); // 22
|
||||||
|
|
||||||
|
// CID Pack
|
||||||
|
for (s32 i = 0; i < SACN_CID_BYTES; i++)
|
||||||
|
{
|
||||||
|
*Cursor++ = CID.bytes[i];
|
||||||
|
}// 38
|
||||||
|
|
||||||
|
VHD_PackFlags_(Cursor, false, false, false);
|
||||||
|
Cursor = VHD_PackLength_(Cursor,
|
||||||
|
SACN_BUFFER_HEADER_SIZE - SACN_FRAMING_FLAGS_AND_LEN_ADDR + SlotCount,
|
||||||
|
false);
|
||||||
|
// 40
|
||||||
|
// framing vector
|
||||||
|
Cursor = PackB4(Cursor, SACN_FRAMING_VECTOR);
|
||||||
|
|
||||||
|
// framing source name
|
||||||
|
// :Check
|
||||||
|
|
||||||
|
CopyMemoryTo(SourceName, (char*)Cursor, c_str_len((char*)SourceName));
|
||||||
|
Cursor[SACN_SOURCE_NAME_SIZE - 1] = '\0';
|
||||||
|
Cursor += SACN_SOURCE_NAME_SIZE; // 108
|
||||||
|
|
||||||
|
// priority
|
||||||
|
Cursor = PackB1(Cursor, Priority);
|
||||||
|
|
||||||
|
// reserved
|
||||||
|
Cursor = PackB2(Cursor, Reserved); // 111
|
||||||
|
|
||||||
|
// Sequence # is always set to 0/NONE at the beginning, but it is incremented when sending data
|
||||||
|
Cursor = PackB1(Cursor, 0);
|
||||||
|
|
||||||
|
// Options
|
||||||
|
Cursor = PackB1(Cursor, Options);
|
||||||
|
|
||||||
|
// Universe
|
||||||
|
Cursor = PackB2(Cursor, Universe); // 115
|
||||||
|
|
||||||
|
VHD_PackFlags_(Cursor, false, false, false);
|
||||||
|
Cursor = VHD_PackLength_(Cursor,
|
||||||
|
SACN_BUFFER_HEADER_SIZE - SACN_DMP_FLAGS_AND_LEN_ADDR + SlotCount,
|
||||||
|
false); // 117
|
||||||
|
|
||||||
|
// DMP Vector
|
||||||
|
Cursor = PackB1(Cursor, SACN_DMP_VECTOR);
|
||||||
|
|
||||||
|
// DMP Address and data type
|
||||||
|
Cursor = PackB1(Cursor, SACN_ADDRESS_AND_DATA_FORMAT);
|
||||||
|
|
||||||
|
// DMP first property address
|
||||||
|
Cursor = PackB1(Cursor, 0);
|
||||||
|
|
||||||
|
// DMP Address Increment
|
||||||
|
Cursor = PackB1(Cursor, SACN_ADDR_INC);
|
||||||
|
|
||||||
|
// Property Value Count -- Includes one byte for start code
|
||||||
|
Cursor = PackB2(Cursor, SlotCount + 1);
|
||||||
|
|
||||||
|
Cursor = PackB1(Cursor, StartCode);
|
||||||
|
|
||||||
|
assert(Cursor - Buffer == SACN_BUFFER_HEADER_SIZE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
sacn_fill_buffer_header(Output_Data* d, u16 universe, Sacn* sacn)
|
sacn_fill_buffer_header(Output_Data* d, u16 universe, Sacn* sacn)
|
||||||
{
|
{
|
||||||
assert(d && d->data.size > 0);
|
assert(d && d->data.size > 0);
|
||||||
|
|
||||||
// TODO(PS): these should be passed in?
|
// TODO(PS): these should be passed in?
|
||||||
u16 slot_count = 0;
|
u16 slot_count = SACN_BUFFER_BODY_SIZE;
|
||||||
u8 start_code = 0;
|
u8 start_code = SACN_STARTCODE_DMX;
|
||||||
|
// universe
|
||||||
u8 priority = 0;
|
u8 priority = 0;
|
||||||
u16 reserved = 0;
|
u16 reserved = 0;
|
||||||
u8 options = 0;
|
u8 options = 0;
|
||||||
|
@ -122,7 +337,7 @@ sacn_fill_buffer_header(Output_Data* d, u16 universe, Sacn* sacn)
|
||||||
|
|
||||||
dw_put_u16_b(&w, SACN_RLP_PREAMBLE_SIZE);
|
dw_put_u16_b(&w, SACN_RLP_PREAMBLE_SIZE);
|
||||||
dw_put_u16_b(&w, SACN_RLP_POSTAMBLE_SIZE);
|
dw_put_u16_b(&w, SACN_RLP_POSTAMBLE_SIZE);
|
||||||
dw_put_str(&w, SACN_ACN_IDENTIFIER);
|
dw_put_str_min_len(&w, SACN_ACN_IDENTIFIER, SACN_ACN_IDENTIFIER_SIZE);
|
||||||
|
|
||||||
sacn_vhd_pack_flags(&w, false, false, false);
|
sacn_vhd_pack_flags(&w, false, false, false);
|
||||||
sacn_vhd_pack_len(&w, SACN_BUFFER_HEADER_SIZE - SACN_RLP_PREAMBLE_SIZE + slot_count, false);
|
sacn_vhd_pack_len(&w, SACN_BUFFER_HEADER_SIZE - SACN_RLP_PREAMBLE_SIZE + slot_count, false);
|
||||||
|
@ -130,16 +345,17 @@ sacn_fill_buffer_header(Output_Data* d, u16 universe, Sacn* sacn)
|
||||||
dw_put_u32_b(&w, SACN_ROOT_VECTOR);
|
dw_put_u32_b(&w, SACN_ROOT_VECTOR);
|
||||||
|
|
||||||
for (u32 i = 0; i < SACN_CID_BYTES; i++) dw_put_u8(&w, sacn->cid.bytes[i]);
|
for (u32 i = 0; i < SACN_CID_BYTES; i++) dw_put_u8(&w, sacn->cid.bytes[i]);
|
||||||
|
|
||||||
sacn_vhd_pack_flags(&w, false, false, false);
|
sacn_vhd_pack_flags(&w, false, false, false);
|
||||||
sacn_vhd_pack_len(&w, SACN_BUFFER_HEADER_SIZE - SACN_FRAMING_FLAGS_AND_LEN_ADDR + slot_count, false);
|
sacn_vhd_pack_len(&w, SACN_BUFFER_HEADER_SIZE - SACN_FRAMING_FLAGS_AND_LEN_ADDR + slot_count, false);
|
||||||
|
|
||||||
dw_put_u32_b(&w, SACN_FRAMING_VECTOR);
|
dw_put_u32_b(&w, SACN_FRAMING_VECTOR);
|
||||||
dw_put_str(&w, sacn->source_name);
|
|
||||||
|
dw_put_str_min_len_nullterm(&w, sacn->source_name, SACN_SOURCE_NAME_SIZE);
|
||||||
|
|
||||||
dw_put_u8(&w, priority);
|
dw_put_u8(&w, priority);
|
||||||
dw_put_u16_b(&w, reserved);
|
dw_put_u16_b(&w, reserved); // synchronization
|
||||||
dw_put_u8(&w, 0); // Sequence Number starts at 0, gets updated
|
dw_put_u8(&w, sacn->sequence_iter);
|
||||||
dw_put_u8(&w, options);
|
dw_put_u8(&w, options);
|
||||||
dw_put_u16_b(&w, universe);
|
dw_put_u16_b(&w, universe);
|
||||||
|
|
||||||
|
@ -148,8 +364,8 @@ sacn_fill_buffer_header(Output_Data* d, u16 universe, Sacn* sacn)
|
||||||
|
|
||||||
dw_put_u8(&w, SACN_DMP_VECTOR);
|
dw_put_u8(&w, SACN_DMP_VECTOR);
|
||||||
dw_put_u8(&w, SACN_ADDRESS_AND_DATA_FORMAT);
|
dw_put_u8(&w, SACN_ADDRESS_AND_DATA_FORMAT);
|
||||||
dw_put_u8(&w, 0); // dmp first priority addr
|
dw_put_u16_b(&w, 0); // dmp first priority addr
|
||||||
dw_put_u8(&w, SACN_ADDR_INC); // dmp address increment
|
dw_put_u16_b(&w, SACN_ADDR_INC); // dmp address increment
|
||||||
dw_put_u16_b(&w, slot_count + 1);
|
dw_put_u16_b(&w, slot_count + 1);
|
||||||
dw_put_u8(&w, start_code);
|
dw_put_u8(&w, start_code);
|
||||||
|
|
||||||
|
@ -157,9 +373,20 @@ sacn_fill_buffer_header(Output_Data* d, u16 universe, Sacn* sacn)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
sacn_fill_buffer_body(Output_Data* d, u32* leds_placed)
|
sacn_fill_buffer_body(Output_Data* d, Assembly_Pixel_Buffer* pixels, Assembly_Strip* strip, u32* leds_placed)
|
||||||
{
|
{
|
||||||
|
u32 first = *leds_placed;
|
||||||
|
u32 to_add = min(strip->pixels_len - first, SACN_BUFFER_BODY_SIZE / 3);
|
||||||
|
u32 one_past_last = first + to_add;
|
||||||
|
for (u32 i = *leds_placed; i < one_past_last; i++)
|
||||||
|
{
|
||||||
|
u32 led_index = strip->pixels[i];
|
||||||
|
Assembly_Pixel color = pixels->pixels[led_index];
|
||||||
|
d->data.base[SACN_BUFFER_HEADER_SIZE + (i * 3) + 0] = color.r;
|
||||||
|
d->data.base[SACN_BUFFER_HEADER_SIZE + (i * 3) + 1] = color.g;
|
||||||
|
d->data.base[SACN_BUFFER_HEADER_SIZE + (i * 3) + 2] = color.b;
|
||||||
|
}
|
||||||
|
*leds_placed += to_add;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Sacn_Cid
|
internal Sacn_Cid
|
||||||
|
@ -178,16 +405,34 @@ internal u8*
|
||||||
output_network_sacn_init()
|
output_network_sacn_init()
|
||||||
{
|
{
|
||||||
Sacn* result = allocator_alloc_struct(permanent, Sacn);
|
Sacn* result = allocator_alloc_struct(permanent, Sacn);
|
||||||
// TODO(PS): get platform send socket
|
zero_struct(*result);
|
||||||
|
|
||||||
|
result->source_name = string_f(permanent, "lumenarium::incenter");
|
||||||
|
|
||||||
String cid_str = lit_str("{67F9D986-544E-4abb-8986-D5F79382586C}");
|
String cid_str = lit_str("{67F9D986-544E-4abb-8986-D5F79382586C}");
|
||||||
result->cid = sacn_string_to_cid(cid_str);
|
result->cid = sacn_string_to_cid(cid_str);
|
||||||
|
|
||||||
|
s32 ttl = 20;
|
||||||
|
result->socket = os_socket_create(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
os_socket_set_opt(
|
||||||
|
result->socket,
|
||||||
|
IPPROTO_IP,
|
||||||
|
IP_MULTICAST_TTL,
|
||||||
|
(u8*)&ttl, sizeof(ttl)
|
||||||
|
);
|
||||||
|
|
||||||
return (u8*)result;
|
return (u8*)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
output_network_sacn_build(App_State* state, u32 assembly_id, Assembly_Strip* strip, u8* method_data, Output_Data_Queue* queue)
|
output_network_sacn_update(u8* method_data)
|
||||||
|
{
|
||||||
|
Sacn* sacn = (Sacn*)method_data;
|
||||||
|
sacn->sequence_iter += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
output_network_sacn_build(App_State* state, u32 assembly_id, Assembly_Pixel_Buffer* pixels, Assembly_Strip* strip, u8* method_data, Output_Data_Queue* queue)
|
||||||
{
|
{
|
||||||
Sacn* sacn = (Sacn*)method_data;
|
Sacn* sacn = (Sacn*)method_data;
|
||||||
|
|
||||||
|
@ -200,8 +445,9 @@ output_network_sacn_build(App_State* state, u32 assembly_id, Assembly_Strip* str
|
||||||
Output_Data* d = output_data_queue_push(queue, SACN_BUFFER_SIZE, OutputData_NetworkSACN);
|
Output_Data* d = output_data_queue_push(queue, SACN_BUFFER_SIZE, OutputData_NetworkSACN);
|
||||||
output_data_set_network_addr(d, v4_send_addr, send_port);
|
output_data_set_network_addr(d, v4_send_addr, send_port);
|
||||||
|
|
||||||
|
//InitStreamHeader(d->data.base, d->data.size, SACN_BUFFER_BODY_SIZE, SACN_STARTCODE_DMX, universe, 0, 0, 0, "lumenarium::sacn", sacn->cid);
|
||||||
sacn_fill_buffer_header(d, universe, sacn);
|
sacn_fill_buffer_header(d, universe, sacn);
|
||||||
sacn_fill_buffer_body(d, &leds_placed);
|
sacn_fill_buffer_body(d, pixels, strip, &leds_placed);
|
||||||
universe += 1;
|
universe += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,11 @@ struct Sacn
|
||||||
Sacn_Cid cid;
|
Sacn_Cid cid;
|
||||||
s32 sequence_iter;
|
s32 sequence_iter;
|
||||||
String source_name;
|
String source_name;
|
||||||
|
Socket_Handle socket;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal u8* output_network_sacn_init();
|
internal u8* output_network_sacn_init();
|
||||||
internal void output_network_sacn_build(App_State* state, u32 assembly_id, Assembly_Strip* strip, u8* method_data, Output_Data_Queue* queue);
|
internal void output_network_sacn_update(u8* method_data);
|
||||||
|
internal void output_network_sacn_build(App_State* state, u32 assembly_id, Assembly_Pixel_Buffer* pixels, Assembly_Strip* strip, u8* method_data, Output_Data_Queue* queue);
|
||||||
|
|
||||||
#endif //LUMENARIUM_OUTPUT_SACN_H
|
#endif //LUMENARIUM_OUTPUT_SACN_H
|
||||||
|
|
|
@ -9,7 +9,8 @@ lumenarium_init(Editor_Desc* ed_desc)
|
||||||
permanent = bump_allocator_create_reserve(GB(2));
|
permanent = bump_allocator_create_reserve(GB(2));
|
||||||
global_scratch_ = bump_allocator_create_reserve(GB(4));
|
global_scratch_ = bump_allocator_create_reserve(GB(4));
|
||||||
|
|
||||||
//run_tests();
|
run_tests();
|
||||||
|
|
||||||
scratch_get(scratch);
|
scratch_get(scratch);
|
||||||
App_Init_Desc desc = incenter_get_init_desc();
|
App_Init_Desc desc = incenter_get_init_desc();
|
||||||
// TODO(PS): make sure the values make sense in desc
|
// TODO(PS): make sure the values make sense in desc
|
||||||
|
@ -20,6 +21,7 @@ lumenarium_init(Editor_Desc* ed_desc)
|
||||||
add_flag(state->flags, AppState_RunUserSpace);
|
add_flag(state->flags, AppState_RunUserSpace);
|
||||||
|
|
||||||
state->file_async_job_system = os_file_jobs_init();
|
state->file_async_job_system = os_file_jobs_init();
|
||||||
|
open_sockets_init();
|
||||||
state->input_state = input_state_create(permanent);
|
state->input_state = input_state_create(permanent);
|
||||||
|
|
||||||
String exe_file_path = os_get_exe_path(scratch.a);
|
String exe_file_path = os_get_exe_path(scratch.a);
|
||||||
|
|
|
@ -17,6 +17,7 @@ global Allocator* global_scratch_; // gets reset at frame boundaries
|
||||||
|
|
||||||
// Engine
|
// Engine
|
||||||
typedef struct Assembly_Strip Assembly_Strip;
|
typedef struct Assembly_Strip Assembly_Strip;
|
||||||
|
typedef struct Assembly_Pixel_Buffer Assembly_Pixel_Buffer;
|
||||||
#include "engine/lumenarium_engine_output.h"
|
#include "engine/lumenarium_engine_output.h"
|
||||||
#include "engine/lumenarium_engine_assembly.h"
|
#include "engine/lumenarium_engine_assembly.h"
|
||||||
#include "engine/output/lumenarium_output_uart.h"
|
#include "engine/output/lumenarium_output_uart.h"
|
||||||
|
@ -48,6 +49,8 @@ lumenarium_env_validate_()
|
||||||
bump_allocator_validate(permanent);
|
bump_allocator_validate(permanent);
|
||||||
bump_allocator_validate(global_scratch_);
|
bump_allocator_validate(global_scratch_);
|
||||||
bump_allocator_validate(file_jobs_arena);
|
bump_allocator_validate(file_jobs_arena);
|
||||||
|
|
||||||
|
core_socket_tests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -155,7 +155,7 @@ dw_get_u8(Data_Writer* w)
|
||||||
u8 result = 0;
|
u8 result = 0;
|
||||||
if (w->at < w->data.size)
|
if (w->at < w->data.size)
|
||||||
{
|
{
|
||||||
result = w->data.base[w->at++];
|
result = w->data.base[w->at];
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -227,6 +227,24 @@ dw_put_str(Data_Writer* w, String str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
dw_put_str_min_len(Data_Writer* w, String str, u64 min_len)
|
||||||
|
{
|
||||||
|
u64 start = w->at;
|
||||||
|
dw_put_str(w, str);
|
||||||
|
if (str->len < min_len)
|
||||||
|
{
|
||||||
|
w->at = start + min_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
dw_put_str_min_len_nullterm(Data_Writer* w, String str, u64 min_len)
|
||||||
|
{
|
||||||
|
dw_put_str_min_len(w, str, min_len);
|
||||||
|
w->data.base[w->at - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(PS): get functions
|
// TODO(PS): get functions
|
||||||
|
|
||||||
#define Bytes(x) (x)
|
#define Bytes(x) (x)
|
||||||
|
|
|
@ -45,14 +45,17 @@ u32 os_interlocked_cmp_exchg(volatile u32* dest, u32 new_value, u32 old_value);
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// Network Access
|
// Network Access
|
||||||
|
|
||||||
Socket_Handle os_socket_create();
|
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();
|
||||||
Data os_socket_recv();
|
Data os_socket_recv();
|
||||||
s32 os_Socket_set_listening();
|
s32 os_socket_set_listening();
|
||||||
s32 os_Socket_send();
|
s32 os_socket_send();
|
||||||
s32 os_Socket_send_to();
|
s32 os_socket_send_to(Socket_Handle handle, u32 addr, u32 port, Data data, s32 flags);
|
||||||
s32 os_Socket_set_opt();
|
s32 os_socket_set_opt(Socket_Handle handle, int level, int option_name,
|
||||||
|
u8* option_value, s32 option_len);
|
||||||
|
|
||||||
|
void open_sockets_init();
|
||||||
|
|
||||||
#endif // LUMENARIUM_OS
|
#endif // LUMENARIUM_OS
|
|
@ -8,6 +8,9 @@
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
#include <OpenGL/gl.h>
|
#include <OpenGL/gl.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#include "lumenarium_osx_memory.h"
|
#include "lumenarium_osx_memory.h"
|
||||||
#include "../../core/lumenarium_core.h"
|
#include "../../core/lumenarium_core.h"
|
||||||
#include "../lumenarium_os.h"
|
#include "../lumenarium_os.h"
|
||||||
|
@ -37,34 +40,15 @@ osx_err_print_(char* proc, char* sub_proc, s32 errsv)
|
||||||
#define OS_FILE_HANDLE_TYPE s32
|
#define OS_FILE_HANDLE_TYPE s32
|
||||||
#define OS_FILE_MAX_PATH PATH_MAX
|
#define OS_FILE_MAX_PATH PATH_MAX
|
||||||
#define OS_FILE_INVALID_HANDLE -1
|
#define OS_FILE_INVALID_HANDLE -1
|
||||||
|
#define OS_SOCKET_TYPE s32
|
||||||
|
#define OS_SOCKET_INVALID_HANDLE -1
|
||||||
#include "../shared/lumenarium_shared_file_tracker.h"
|
#include "../shared/lumenarium_shared_file_tracker.h"
|
||||||
#include "../shared/lumenarium_shared_file_async_work_on_job.h"
|
#include "../shared/lumenarium_shared_file_async_work_on_job.h"
|
||||||
|
#include "../shared/lumenarium_shared_network.h"
|
||||||
#include "lumenarium_osx_file.h"
|
#include "lumenarium_osx_file.h"
|
||||||
#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"
|
||||||
void osx_tests()
|
|
||||||
{
|
|
||||||
Ticks t0 = os_get_ticks();
|
|
||||||
|
|
||||||
// File Tests
|
|
||||||
File_Handle file = os_file_open(lit_str("text.txt"), FileAccess_Read | FileAccess_Write, FileCreate_OpenAlways);
|
|
||||||
File_Info info = os_file_get_info(file, global_scratch_);
|
|
||||||
Data d = os_file_read_all(file, global_scratch_);
|
|
||||||
os_file_write_all(file, d);
|
|
||||||
os_file_close(file);
|
|
||||||
|
|
||||||
// Path tests
|
|
||||||
String path_exe = os_get_exe_path(global_scratch_);
|
|
||||||
printf("%.*s\n", str_varg(path_exe));
|
|
||||||
String path = string_chop_last_slash(path_exe);
|
|
||||||
String path0 = string_copy(path, global_scratch_);
|
|
||||||
os_pwd_set(path0);
|
|
||||||
|
|
||||||
Ticks t1 = os_get_ticks();
|
|
||||||
Ticks td = get_ticks_elapsed(t0, t1);
|
|
||||||
r64 sd = ticks_to_seconds(td, os_get_ticks_per_second());
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
glfw_error_callback(int error, const char* description)
|
glfw_error_callback(int error, const char* description)
|
||||||
|
@ -279,9 +263,7 @@ scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
int main (int arg_count, char** args)
|
int main (int arg_count, char** args)
|
||||||
{
|
{
|
||||||
// osx_tests();
|
|
||||||
|
|
||||||
if (!glfwInit())
|
if (!glfwInit())
|
||||||
{
|
{
|
||||||
printf("Error: Could not initialize glfw.\n");
|
printf("Error: Could not initialize glfw.\n");
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
Socket_Handle
|
||||||
|
os_socket_create(s32 domain, s32 type, s32 protocol)
|
||||||
|
{
|
||||||
|
Socket_Handle result = {};
|
||||||
|
OS_SOCKET_TYPE sock = socket(domain, type, protocol);
|
||||||
|
if (sock == -1) {
|
||||||
|
perror("Error: os_socket_create\n");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = open_sockets_put(sock);
|
||||||
|
if (result.value == 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: os_socket_create - not enough room in open_sockets\n");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
os_socket_bind()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
os_socket_connect()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
os_socket_close()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data
|
||||||
|
os_socket_recv()
|
||||||
|
{
|
||||||
|
return (Data){};
|
||||||
|
}
|
||||||
|
|
||||||
|
s32
|
||||||
|
os_socket_set_listening()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32
|
||||||
|
os_socket_send()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32
|
||||||
|
os_socket_send_to(Socket_Handle handle, u32 addr, u32 port, Data data, s32 flags)
|
||||||
|
{
|
||||||
|
OS_SOCKET_TYPE sock = open_sockets_get(handle);
|
||||||
|
|
||||||
|
struct sockaddr_in dst = {
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_port = hton_u16(port),
|
||||||
|
.sin_addr.s_addr = hton_u32(addr),
|
||||||
|
};
|
||||||
|
struct sockaddr* dst_ptr = (struct sockaddr*)&dst;
|
||||||
|
s32 len_sent = sendto(sock, data.base, data.size, flags, dst_ptr, sizeof(struct sockaddr_in));
|
||||||
|
if (len_sent == -1)
|
||||||
|
{
|
||||||
|
perror("Error: os_socket_send_to\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len_sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32
|
||||||
|
os_socket_set_opt(Socket_Handle handle, int level, int option_name,
|
||||||
|
u8* option_value, s32 option_len)
|
||||||
|
{
|
||||||
|
OS_SOCKET_TYPE sock = open_sockets_get(handle);
|
||||||
|
s32 err = setsockopt(sock, level, option_name, (void*)option_value, (socklen_t)option_len);
|
||||||
|
if (err) {
|
||||||
|
fprintf(stderr, "Error: setsockopt - %d\n\targs: %d %d %.*s\n", err, level, option_name, option_len, (char*)option_value);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
#if !defined(OS_SOCKET_TYPE)
|
||||||
|
# error "You must define an OS_SOCKET_TYPE"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(OS_SOCKET_INVALID_HANDLE)
|
||||||
|
# error "You must define an OS_SOCKET_INVALID_HANDLE"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define open_sockets_cap 2
|
||||||
|
global u32 open_sockets_len = 1;
|
||||||
|
global OS_SOCKET_TYPE open_sockets[open_sockets_cap];
|
||||||
|
|
||||||
|
void open_sockets_init();
|
||||||
|
s32 open_sockets_next_free();
|
||||||
|
bool open_sockets_has_room();
|
||||||
|
OS_SOCKET_TYPE open_sockets_get(Socket_Handle handle);
|
||||||
|
Socket_Handle open_sockets_put(OS_SOCKET_TYPE socket);
|
||||||
|
void open_sockets_rem(Socket_Handle handle);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////
|
||||||
|
// IMPLEMENTATION
|
||||||
|
|
||||||
|
void
|
||||||
|
open_sockets_init()
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < open_sockets_cap; i++)
|
||||||
|
{
|
||||||
|
open_sockets[i] = OS_SOCKET_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s32
|
||||||
|
open_sockets_next_free()
|
||||||
|
{
|
||||||
|
if (open_sockets_len < open_sockets_cap) return open_sockets_len++;
|
||||||
|
for (u32 i = 1; i < open_sockets_len; i++)
|
||||||
|
{
|
||||||
|
if (open_sockets[i] == OS_SOCKET_INVALID_HANDLE) return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_SOCKET_TYPE
|
||||||
|
open_sockets_get(Socket_Handle handle)
|
||||||
|
{
|
||||||
|
assert(handle.value < open_sockets_len);
|
||||||
|
return open_sockets[handle.value];
|
||||||
|
}
|
||||||
|
|
||||||
|
Socket_Handle
|
||||||
|
open_sockets_put(OS_SOCKET_TYPE socket)
|
||||||
|
{
|
||||||
|
Socket_Handle result = { .value = open_sockets_next_free() };
|
||||||
|
assert(result.value != 0);
|
||||||
|
open_sockets[result.value] = socket;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
open_sockets_rem(Socket_Handle handle)
|
||||||
|
{
|
||||||
|
assert(handle.value < open_sockets_len);
|
||||||
|
open_sockets[handle.value] = OS_SOCKET_INVALID_HANDLE;
|
||||||
|
if (handle.value + 1 == open_sockets_len) {
|
||||||
|
open_sockets_len -= 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,6 +40,8 @@ incenter_init(App_State* state)
|
||||||
for (u32 i = 0; i < 40; i++)
|
for (u32 i = 0; i < 40; i++)
|
||||||
{
|
{
|
||||||
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->sacn_universe = i;
|
||||||
|
|
||||||
r32 theta = random_series_next_unilateral(&rand) * r32_tau;
|
r32 theta = random_series_next_unilateral(&rand) * r32_tau;
|
||||||
r32 phi = random_series_next_unilateral(&rand) * r32_tau;
|
r32 phi = random_series_next_unilateral(&rand) * r32_tau;
|
||||||
|
|
Loading…
Reference in New Issue