2121#include <args.h>
2222#include <sdl.h>
2323
24- struct usr_data {
24+ struct cb_context {
2525 struct cr_renderer * r ;
26- struct v_mutex * win_mutex ;
2726 struct sdl_window * w ;
28- struct sdl_prefs p ;
29- bool should_save ;
27+ bool skip_save ;
28+
29+ const struct cr_bitmap * * temp_rbuf ;
3030};
3131
3232/*
@@ -39,67 +39,61 @@ struct usr_data {
3939 when it has allocated a render buffer and is ready to render. We then pass a a ref
4040 to that buffer and some context to this async win_init_task().
4141*/
42- struct win_init_data {
43- struct usr_data * driver ;
44- struct cr_renderer_cb_info * cb_info ;
45- };
46-
4742static void * win_init_task (void * arg ) {
48- struct win_init_data * w = arg ;
49- if (!w ) return NULL ;
50- struct usr_data * d = w -> driver ;
51- struct cr_renderer_cb_info * cb_info = w -> cb_info ;
52- struct sdl_window * win = win_try_init (& d -> p , (* cb_info -> fb )-> width , (* cb_info -> fb )-> height );
53- v_mutex_lock (d -> win_mutex );
54- if (d -> p .enabled && * cb_info -> fb ) d -> w = win ;
55- v_mutex_release (d -> win_mutex );
56- #if !defined(__APPLE__ )
57- free (w );
58- #endif
43+ struct cb_context * d = arg ;
44+ d -> w = win_try_init (d -> temp_rbuf );
45+ d -> temp_rbuf = NULL ;
5946 return NULL ;
6047}
6148
6249static void on_start (struct cr_renderer_cb_info * cb_info , void * user_data ) {
63- struct usr_data * d = user_data ;
50+ struct cb_context * d = user_data ;
51+ d -> temp_rbuf = cb_info -> fb ;
6452#if defined(__APPLE__ )
6553 // The SDL2 Cocoa backend on macOS will crash the program if it's invoked from a background thread.
6654 // Solution is to init SDL2 synchronously on macOS.
67- win_init_task (( void * ) & ( struct win_init_data ){ . cb_info = cb_info , . driver = d }) ;
55+ win_init_task (d ); ;
6856#else
69- struct win_init_data * data = malloc (sizeof (* data ));
70- * data = (struct win_init_data ){
71- .cb_info = cb_info ,
72- .driver = d ,
73- };
7457 v_thread_ctx ctx = {
7558 .thread_fn = win_init_task ,
76- .ctx = data ,
59+ .ctx = d ,
7760 };
7861 v_thread * ret = v_thread_create (ctx , v_thread_type_detached );
79- if (!ret ) { // Try synchronously, then.
80- win_init_task (data );
81- }
62+ if (!ret ) // Fall back to running synchronously.
63+ win_init_task (d );
8264#endif
8365}
8466
8567static void on_stop (struct cr_renderer_cb_info * info , void * user_data ) {
8668 (void )info ;
87- struct usr_data * d = user_data ;
88- if (d -> w ) win_destroy (d -> w );
69+ struct cb_context * d = user_data ;
70+ if (d -> w )
71+ win_destroy (d -> w );
8972 if (info -> aborted )
90- d -> should_save = false ;
73+ d -> skip_save = true ;
9174}
9275
9376static void status (struct cr_renderer_cb_info * state , void * user_data ) {
9477 static int pauser = 0 ;
95- struct usr_data * d = user_data ;
96- if (!d ) return ;
97- v_mutex_lock (d -> win_mutex );
98- struct input_state in = win_update (d -> w , state -> tiles , state -> tiles_count , * ((struct texture * * )state -> fb ));
99- v_mutex_release (d -> win_mutex );
100- d -> should_save = in .should_save ;
101- if (in .stop_render ) cr_renderer_stop (d -> r );
102- if (in .pause_render ) cr_renderer_toggle_pause (d -> r );
78+ struct cb_context * d = user_data ;
79+ if (!d )
80+ return ;
81+ if (d -> w ) {
82+ enum input_event e = win_update (d -> w , state -> tiles , state -> tiles_count );
83+ switch (e ) {
84+ case ev_stop_nosave :
85+ d -> skip_save = true;
86+ cr_renderer_stop (d -> r );
87+ break ;
88+ case ev_stop :
89+ cr_renderer_stop (d -> r );
90+ break ;
91+ case ev_pause :
92+ cr_renderer_toggle_pause (d -> r );
93+ default :
94+ break ;
95+ }
96+ }
10397
10498 //Run the status printing about 4x/s
10599 if (++ pauser >= 16 ) {
@@ -239,14 +233,14 @@ int main(int argc, char *argv[]) {
239233 }
240234 }
241235
242- struct usr_data usrdata = (struct usr_data ){
243- .p = sdl_parse (cJSON_GetObjectItem (input_json , "display" )),
236+ struct cb_context usrdata = {
244237 .r = renderer ,
245- .should_save = true,
246- .win_mutex = v_mutex_create (),
247238 };
248- if (!args_is_set (opts , "no_sdl" ))
239+
240+ const cJSON * display = cJSON_GetObjectItem (input_json , "display" );
241+ if (!args_is_set (opts , "no_sdl" ) && display && !cJSON_IsFalse (cJSON_GetObjectItem (display , "enabled" )))
249242 cr_renderer_set_callback (renderer , cr_cb_on_start , on_start , & usrdata );
243+
250244 cr_renderer_set_callback (renderer , cr_cb_on_stop , on_stop , & usrdata );
251245 cr_renderer_set_callback (renderer , cr_cb_status_update , status , & usrdata );
252246
@@ -298,7 +292,9 @@ int main(int argc, char *argv[]) {
298292 logr (plain , "\n" );
299293 logr (info , "Finished render in %s\n" , ms_to_readable (ms , buf ));
300294
301- if (usrdata .should_save ) {
295+ if (usrdata .skip_save ) {
296+ logr (info , "Abort pressed, image won't be saved.\n" );
297+ } else {
302298 struct imageFile file = (struct imageFile ){
303299 .filePath = output_path ,
304300 .fileName = output_name ,
@@ -316,8 +312,6 @@ int main(int argc, char *argv[]) {
316312 };
317313 writeImage (& file );
318314 logr (info , "Render finished, exiting.\n" );
319- } else {
320- logr (info , "Abort pressed, image won't be saved.\n" );
321315 }
322316
323317 if (output_path ) free (output_path );
0 commit comments