Ed_
4deee942a8
Renamed HashTable to HMapZPL, with procs having the zpl_ namespace prefix. (I want to eventually get away from using it) Started to use the grime pattern for library aliasing better.
238 lines
7.2 KiB
Odin
238 lines
7.2 KiB
Odin
package sectr
|
|
|
|
import "base:runtime"
|
|
import c "core:c/libc"
|
|
import "core:dynlib"
|
|
import "core:mem"
|
|
import "core:mem/virtual"
|
|
import "core:os"
|
|
import "core:slice"
|
|
import "core:strings"
|
|
import rl "vendor:raylib"
|
|
|
|
Path_Assets :: "../assets/"
|
|
Path_Input_Replay :: "scratch.sectr_replay"
|
|
|
|
ModuleAPI :: struct {
|
|
lib : dynlib.Library,
|
|
write_time : FileTime,
|
|
lib_version : i32,
|
|
|
|
startup : type_of( startup ),
|
|
shutdown : type_of( sectr_shutdown ),
|
|
reload : type_of( reload ),
|
|
tick : type_of( tick ),
|
|
clean_temp : type_of( clean_temp ),
|
|
}
|
|
|
|
@export
|
|
startup :: proc( live_mem : virtual.Arena, snapshot_mem : []u8, host_logger : ^ Logger )
|
|
{
|
|
logger_init( & Memory_App.logger, "Sectr", host_logger.file_path, host_logger.file )
|
|
context.logger = to_odin_logger( & Memory_App.logger )
|
|
|
|
// Setup memory for the first time
|
|
{
|
|
arena_size :: size_of( Arena)
|
|
internals_size :: 4 * Megabyte
|
|
|
|
using Memory_App;
|
|
block := live_mem.curr_block
|
|
|
|
live = live_mem
|
|
snapshot = snapshot_mem
|
|
|
|
persistent_slice := slice_ptr( block.base, Memory_Persistent_Size )
|
|
transient_slice := slice_ptr( memory_after( persistent_slice), Memory_Trans_Temp_Szie )
|
|
temp_slice := slice_ptr( memory_after( transient_slice), Memory_Trans_Temp_Szie )
|
|
|
|
when Use_TrackingAllocator {
|
|
// We assign the beginning of the block to be the host's persistent memory's arena.
|
|
// Then we offset past the arena and determine its slice to be the amount left after for the size of host's persistent.
|
|
persistent = tracked_allocator_init_vmem( persistent_slice, internals_size )
|
|
transient = tracked_allocator_init_vmem( transient_slice, internals_size )
|
|
temp = tracked_allocator_init_vmem( temp_slice , internals_size )
|
|
}
|
|
else {
|
|
persistent = arena_allocator_init_vmem( persistent_slice )
|
|
transient = arena_allocator_init_vmem( transient_slice )
|
|
temp = arena_allocator_init_vmem( temp_slice )
|
|
}
|
|
|
|
context.allocator = transient_allocator()
|
|
context.temp_allocator = temp_allocator()
|
|
}
|
|
|
|
state := new( State, persistent_allocator() )
|
|
using state
|
|
|
|
context.user_ptr = state
|
|
|
|
input = & input_data[1]
|
|
input_prev = & input_data[0]
|
|
|
|
// rl.Odin_SetMalloc( RL_MALLOC )
|
|
|
|
rl.SetConfigFlags( { rl.ConfigFlag.WINDOW_RESIZABLE /*, rl.ConfigFlag.WINDOW_TOPMOST*/ } )
|
|
|
|
// Rough setup of window with rl stuff
|
|
window_width : i32 = 1000
|
|
window_height : i32 = 600
|
|
win_title : cstring = "Sectr Prototype"
|
|
rl.InitWindow( window_width, window_height, win_title )
|
|
log( "Raylib initialized and window opened" )
|
|
|
|
window := & state.app_window
|
|
window.extent.x = f32(window_width) * 0.5
|
|
window.extent.y = f32(window_height) * 0.5
|
|
|
|
// We do not support non-uniform DPI.
|
|
window.dpi_scale = rl.GetWindowScaleDPI().x
|
|
window.ppcm = os_default_ppcm * window.dpi_scale
|
|
|
|
// Determining current monitor and setting the target frametime based on it..
|
|
monitor_id = rl.GetCurrentMonitor()
|
|
monitor_refresh_hz = rl.GetMonitorRefreshRate( monitor_id )
|
|
rl.SetTargetFPS( monitor_refresh_hz )
|
|
log( str_fmt_tmp( "Set target FPS to: %v", monitor_refresh_hz ) )
|
|
|
|
// Basic Font Setup
|
|
{
|
|
font_provider_startup()
|
|
// path_rec_mono_semicasual_reg := strings.concatenate( { Path_Assets, "RecMonoSemicasual-Regular-1.084.ttf" })
|
|
// font_rec_mono_semicasual_reg = font_load( path_rec_mono_semicasual_reg, 24.0, "RecMonoSemiCasual_Regular" )
|
|
|
|
// path_squidgy_slimes := strings.concatenate( { Path_Assets, "Squidgy Slimes.ttf" } )
|
|
// font_squidgy_slimes = font_load( path_squidgy_slimes, 24.0, "Squidgy_Slime" )
|
|
|
|
path_firacode := strings.concatenate( { Path_Assets, "FiraCode-Regular.ttf" } )
|
|
font_firacode = font_load( path_firacode, 24.0, "FiraCode" )
|
|
|
|
// font_data, read_succeded : = os.read_entire_file( path_rec_mono_semicasual_reg )
|
|
// verify( read_succeded, fmt.tprintf("Failed to read font file for: %v", path_rec_mono_semicasual_reg) )
|
|
|
|
// cstr := strings.clone_to_cstring( path_rec_mono_semicasual_reg )
|
|
// font_rec_mono_semicasual_reg = rl.LoadFontEx( cstr, cast(i32) points_to_pixels(24.0), nil, 0 )
|
|
// delete( cstr)
|
|
|
|
// rl.GuiSetFont( font_rec_mono_semicasual_reg ) // TODO(Ed) : Does this do anything?
|
|
default_font = font_firacode
|
|
log( "Default font loaded" )
|
|
}
|
|
|
|
// Demo project setup
|
|
{
|
|
using project
|
|
path = "./"
|
|
name = "First Project"
|
|
workspace.name = "First Workspace"
|
|
{
|
|
using project.workspace
|
|
cam = {
|
|
target = { 0, 0 },
|
|
offset = transmute(Vec2) window.extent,
|
|
rotation = 0,
|
|
zoom = 1.0,
|
|
}
|
|
// cam = {
|
|
// position = { 0, 0, -100 },
|
|
// target = { 0, 0, 0 },
|
|
// up = { 0, 1, 0 },
|
|
// fovy = 90,
|
|
// projection = rl.CameraProjection.ORTHOGRAPHIC,
|
|
// }
|
|
|
|
// Setup workspace UI state
|
|
ui_startup( & workspace.ui, persistent_allocator() )
|
|
}
|
|
}
|
|
}
|
|
|
|
// For some reason odin's symbols conflict with native foreign symbols...
|
|
@export
|
|
sectr_shutdown :: proc()
|
|
{
|
|
if Memory_App.persistent == nil {
|
|
return
|
|
}
|
|
state := get_state()
|
|
|
|
// Replay
|
|
{
|
|
os.close( Memory_App.replay.active_file )
|
|
}
|
|
|
|
font_provider_shutdown()
|
|
|
|
log("Module shutdown complete")
|
|
}
|
|
|
|
@export
|
|
reload :: proc( live_mem : virtual.Arena, snapshot_mem : []u8, host_logger : ^ Logger )
|
|
{
|
|
using Memory_App;
|
|
block := live_mem.curr_block
|
|
|
|
live = live_mem
|
|
snapshot = snapshot_mem
|
|
|
|
// This is no longer necessary as we have proper base address setting
|
|
when false
|
|
{
|
|
persistent_slice := slice_ptr( block.base, Memory_Persistent_Size )
|
|
transient_slice := slice_ptr( memory_after( persistent_slice), Memory_Trans_Temp_Szie )
|
|
temp_slice := slice_ptr( memory_after( transient_slice), Memory_Trans_Temp_Szie )
|
|
|
|
when Use_TrackingAllocator {
|
|
persistent = cast( ^ TrackedAllocator ) & persistent_slice[0]
|
|
transient = cast( ^ TrackedAllocator ) & transient_slice[0]
|
|
temp = cast( ^ TrackedAllocator ) & temp_slice[0]
|
|
}
|
|
else {
|
|
persistent = cast( ^ Arena ) & persistent_slice[0]
|
|
transient = cast( ^ Arena ) & transient_slice[0]
|
|
temp = cast( ^ Arena ) & temp_slice[0]
|
|
}
|
|
}
|
|
context.allocator = transient_allocator()
|
|
context.temp_allocator = temp_allocator()
|
|
|
|
// Procedure Addresses are not preserved on hot-reload. They must be restored for persistent data.
|
|
// The only way to alleviate this is to either do custom handles to allocators
|
|
// Or as done below, correct containers using allocators on reload.
|
|
// Thankfully persistent dynamic allocations are rare, and thus we know exactly which ones they are.
|
|
|
|
// font_provider_data := & get_state().font_provider_data
|
|
// font_provider_data.font_cache.allocator = arena_allocator( & font_provider_data.font_arena )
|
|
|
|
ui_reload( & get_state().project.workspace.ui, persistent_allocator() )
|
|
|
|
log("Module reloaded")
|
|
}
|
|
|
|
// TODO(Ed) : This lang really not have a fucking swap?
|
|
swap :: proc( a, b : ^ $Type ) -> ( ^ Type, ^ Type ) {
|
|
return b, a
|
|
}
|
|
|
|
@export
|
|
tick :: proc( delta_time : f64 ) -> b32
|
|
{
|
|
context.allocator = transient_allocator()
|
|
context.temp_allocator = temp_allocator()
|
|
|
|
result := update( delta_time )
|
|
render()
|
|
return result
|
|
}
|
|
|
|
@export
|
|
clean_temp :: proc() {
|
|
when Use_TrackingAllocator {
|
|
mem.tracking_allocator_clear( & Memory_App.temp.tracker )
|
|
}
|
|
else {
|
|
free_all( temp_allocator() )
|
|
}
|
|
}
|