error screen is a bit silly but works
[vg.git] / src / vg / vg_loader.h
1 /*
2 * Copyright 2021-2022 (C) Mount0 Software, Harry Godden - All Rights Reserved
3 * -----------------------------------------------------------------------------
4 *
5 * Splash / load screen
6 *
7 * -----------------------------------------------------------------------------
8 */
9
10 #ifndef VG_LOADER_H
11 #define VG_LOADER_H
12
13 #include "common.h"
14
15 static struct vg_loader
16 {
17 /* Shutdown steps */
18 struct loader_free_step
19 {
20 void (*fn_free)(void *);
21 void *data;
22 }
23 *step_buffer;
24 u32 step_count, step_cap, step_action;
25 }
26 vg_loader;
27
28 static int vg_loader_init(void)
29 {
30 return 1;
31 }
32
33 static void vg_loader_free(void)
34 {
35 vg_info( "vg_loader_free\n" );
36
37 for( int i=0; i<vg_loader.step_count; i++ )
38 {
39 struct loader_free_step *step =
40 &vg_loader.step_buffer[vg_loader.step_count -1 -i];
41
42 vg_info( " -> %p\n", step->fn_free );
43 step->fn_free( step->data );
44 }
45
46 vg_free( vg_loader.step_buffer );
47 vg_info( "done\n" );
48 }
49
50 static float hue_to_rgb( float p, float q, float t )
51 {
52 if(t < 0.0f) t += 1.0f;
53 if(t > 1.0f) t -= 1.0f;
54 if(t < 1.0f/6.0f) return p + (q - p) * 6.0f * t;
55 if(t < 1.0f/2.0f) return q;
56 if(t < 2.0f/3.0f) return p + (q - p) * (2.0f/3.0f - t) * 6.0f;
57 return p;
58 }
59
60 static void vg_render_log(void)
61 {
62 ui_begin( &ui_global_ctx, vg_window_x, vg_window_y );
63
64
65 int const fh = 14;
66 int lines_screen_max = ((vg_window_y/fh)-2),
67 lines_max_draw = VG_MIN( lines_screen_max, vg_list_size(vg_log.buffer) ),
68 lines_to_draw = VG_MIN( lines_max_draw, vg_log.buffer_line_count );
69
70 int ptr = vg_log.buffer_line_current;
71
72 ui_global_ctx.cursor[0] = 0;
73 ui_global_ctx.cursor[1] = lines_to_draw*fh;
74 ui_global_ctx.cursor[3] = fh;
75 ui_fill_x( &ui_global_ctx );
76
77 for( int i=0; i<lines_to_draw; i ++ )
78 {
79 ptr --;
80
81 if( ptr < 0 )
82 ptr = vg_list_size( vg_log.buffer )-1;
83
84 ui_text( &ui_global_ctx, ui_global_ctx.cursor,
85 vg_log.buffer[ptr], vg_console.scale, 0 );
86
87 ui_global_ctx.cursor[1] -= fh*vg_console.scale;
88 }
89
90 ui_resolve( &ui_global_ctx );
91 ui_draw( &ui_global_ctx, NULL );
92 }
93
94 static void vg_loader_render(void)
95 {
96 float h = vg_randf(),
97 s = 0.7f,
98 l = 0.1f, //* (0.5f+vg_fractf(vg_time*40.0)*0.5f),
99 q = l < 0.5f ? l * (1.0f + s) : l + s - l * s,
100 p = 2.0f * l - q,
101 r = hue_to_rgb( p, q, h + 1.0f/3.0f ),
102 g = hue_to_rgb( p, q, h ),
103 b = hue_to_rgb( p, q, h - 1.0f/3.0f );
104
105 glClearColor( r, g, b, 1.0f );
106 glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
107
108 vg_render_log();
109 }
110
111
112 static void vg_load_full(void);
113
114 static void vg_loader_thread(void * nothing)
115 {
116 vg_thread_info.gl_context_level = 0;
117 vg_thread_info.purpose = k_thread_purpose_loader;
118 vg_set_thread_name( "[vg] Loader" );
119
120 /* Run client loader */
121 vg_load_full();
122 vg_semaphore_post( &vg.sem_loader );
123 }
124
125 static void vg_loader_start(void)
126 {
127 vg_semaphore_wait( &vg.sem_loader );
128 vg_thread_run( vg_loader_thread, NULL );
129 }
130
131 static void vg_free_libc_malloced( void *data )
132 {
133 vg_free( data );
134 }
135
136 static void vg_loader_push_free_step( struct loader_free_step step )
137 {
138 vg_loader.step_buffer =
139 buffer_reserve( vg_loader.step_buffer, vg_loader.step_count,
140 &vg_loader.step_cap, 1,
141 sizeof( struct loader_free_step ) );
142
143 vg_loader.step_buffer[ vg_loader.step_count ++ ] = step;
144 }
145
146 /*
147 * Schedule something to be ran now, freed later
148 */
149 static void vg_loader_highwater( void( *fn_load )(void),
150 void( *fn_free )(void *), void *data )
151 {
152 if( fn_load )
153 fn_load();
154
155 if( fn_free )
156 {
157 struct loader_free_step step;
158 step.data = data;
159 step.fn_free = fn_free;
160
161 vg_loader_push_free_step( step );
162 }
163 else
164 {
165 if( data )
166 {
167 struct loader_free_step step;
168 step.data = data;
169 step.fn_free = vg_free_libc_malloced;
170
171 vg_loader_push_free_step( step );
172 }
173 }
174
175 vg_ensure_engine_running();
176 }
177
178 #endif /* VG_LOADER_H */