@@ -977,6 +977,50 @@ lversion(lua_State *L) {
977977 return 2 ;
978978}
979979
980+ static void
981+ desc_get_boolean (lua_State * L , bool * r , int index , const char * key ) {
982+ if (lua_getfield (L , index , key ) == LUA_TBOOLEAN ) {
983+ * r = lua_toboolean (L , -1 );
984+ } else {
985+ luaL_checktype (L , -1 , LUA_TNIL );
986+ }
987+ lua_pop (L , 1 );
988+ }
989+
990+ static void
991+ desc_get_int (lua_State * L , int * r , int index , const char * key ) {
992+ if (lua_getfield (L , index , key ) == LUA_TNUMBER ) {
993+ * r = lua_tointeger (L , -1 );
994+ } else {
995+ luaL_checktype (L , -1 , LUA_TNIL );
996+ }
997+ lua_pop (L , 1 );
998+ }
999+
1000+ static void
1001+ desc_get_string (lua_State * L , const char * * r , int index , const char * key ) {
1002+ if (lua_getfield (L , index , key ) == LUA_TSTRING ) {
1003+ * r = lua_tostring (L , -1 );
1004+ } else {
1005+ luaL_checktype (L , -1 , LUA_TNIL );
1006+ }
1007+ lua_pop (L , 1 );
1008+ }
1009+
1010+ static int
1011+ linit_desc (lua_State * L ) {
1012+ luaL_checktype (L , 1 , LUA_TLIGHTUSERDATA );
1013+ luaL_checktype (L , 2 , LUA_TTABLE );
1014+ sapp_desc * d = lua_touserdata (L , 1 );
1015+ desc_get_boolean (L , & d -> high_dpi , 2 , "high_dpi" );
1016+ desc_get_boolean (L , & d -> fullscreen , 2 , "fullscreen" );
1017+ desc_get_int (L , & d -> width , 2 , "width" );
1018+ desc_get_int (L , & d -> height , 2 , "height" );
1019+ desc_get_string (L , & d -> window_title , 2 , "window_title" );
1020+
1021+ return 0 ;
1022+ }
1023+
9801024int
9811025luaopen_soluna_app (lua_State * L ) {
9821026 luaL_checkversion (L );
@@ -994,6 +1038,7 @@ luaopen_soluna_app(lua_State *L) {
9941038 { "close_window" , lclose_window },
9951039 { "platform" , NULL },
9961040 { "version" , lversion },
1041+ { "init_desc" , linit_desc },
9971042 { NULL , NULL },
9981043 };
9991044 luaL_newlib (L , l );
@@ -1033,22 +1078,6 @@ void soluna_openlibs(lua_State *L);
10331078
10341079static const char * code = "local embed = require 'soluna.embedsource' ; local f = load(embed.runtime.main()) ; return f(...)" ;
10351080
1036- static void
1037- set_app_info (lua_State * L , int index ) {
1038- lua_newtable (L );
1039- const float dpi_scale = sapp_dpi_scale ();
1040- const float safe_scale = dpi_scale > 0.0f ? dpi_scale : 1.0f ;
1041- const int fb_width = sapp_width ();
1042- const int fb_height = sapp_height ();
1043- const int logical_width = (int )((float )fb_width / safe_scale + 0.5f );
1044- const int logical_height = (int )((float )fb_height / safe_scale + 0.5f );
1045- lua_pushinteger (L , logical_width );
1046- lua_setfield (L , -2 , "width" );
1047- lua_pushinteger (L , logical_height );
1048- lua_setfield (L , -2 , "height" );
1049- lua_setfield (L , index , "app" );
1050- }
1051-
10521081static int
10531082pmain (lua_State * L ) {
10541083 soluna_openlibs (L );
@@ -1067,8 +1096,6 @@ pmain(lua_State *L) {
10671096 lua_setfield (L , arg_table , k );
10681097 }
10691098 }
1070- set_app_info (L , arg_table );
1071-
10721099 int arg_n = lua_gettop (L ) - arg_table + 1 ;
10731100 if (luaL_loadstring (L , code ) != LUA_OK ) {
10741101 return lua_error (L );
@@ -1125,13 +1152,40 @@ msghandler(lua_State *L) {
11251152 return 1 ;
11261153}
11271154
1155+ static void
1156+ get_app_info (lua_State * L ) {
1157+ lua_newtable (L );
1158+ const float dpi_scale = sapp_dpi_scale ();
1159+ const float safe_scale = dpi_scale > 0.0f ? dpi_scale : 1.0f ;
1160+ const int fb_width = sapp_width ();
1161+ const int fb_height = sapp_height ();
1162+ const int logical_width = (int )((float )fb_width / safe_scale + 0.5f );
1163+ const int logical_height = (int )((float )fb_height / safe_scale + 0.5f );
1164+ lua_pushinteger (L , logical_width );
1165+ lua_setfield (L , -2 , "width" );
1166+ lua_pushinteger (L , logical_height );
1167+ lua_setfield (L , -2 , "height" );
1168+ }
1169+
11281170static int
11291171start_app (lua_State * L ) {
1130- lua_settop (L , 0 );
1131- lua_pushcfunction (L , msghandler );
1132- lua_pushcfunction (L , pmain );
1133- if (lua_pcall (L , 0 , 1 , 1 ) != LUA_OK ) {
1134- fprintf (stderr , "Start fatal : %s" , lua_tostring (L , -1 ));
1172+ if (L == NULL ) {
1173+ fprintf (stderr , "Can't open lua state\n" );
1174+ return 1 ;
1175+ }
1176+
1177+ if (lua_gettop (L ) != 2 ) {
1178+ fprintf (stderr , "Invalid lua stack (top = %d)\n" , lua_gettop (L ));
1179+ return 1 ;
1180+ }
1181+ if (lua_getfield (L , -1 , "start" ) != LUA_TFUNCTION ) {
1182+ fprintf (stderr , "No start function\n" );
1183+ return 1 ;
1184+ }
1185+ lua_replace (L , -2 );
1186+ get_app_info (L );
1187+ if (lua_pcall (L , 1 , 1 , 1 ) != LUA_OK ) {
1188+ fprintf (stderr , "Start fatal : %s\n" , lua_tostring (L , -1 ));
11351189 return 1 ;
11361190 } else {
11371191 return init_callback (L , CTX );
@@ -1140,19 +1194,6 @@ start_app(lua_State *L) {
11401194
11411195static void
11421196app_init () {
1143- static struct app_context app ;
1144- lua_State * L = luaL_newstate ();
1145- if (L == NULL )
1146- return ;
1147-
1148- app .L = L ;
1149- app .quitL = NULL ;
1150- app .send_log = NULL ;
1151- app .send_log_ud = NULL ;
1152- app .mqueue = NULL ;
1153-
1154- CTX = & app ;
1155-
11561197#if defined(__APPLE__ )
11571198 soluna_macos_install_ime ();
11581199#endif
@@ -1164,10 +1205,14 @@ app_init() {
11641205 .environment = sglue_environment (),
11651206 .logger .func = log_func ,
11661207 });
1208+
1209+ lua_State * L = CTX -> L ;
11671210 if (start_app (L )) {
11681211 sargs_shutdown ();
1169- lua_close (L );
1170- app .L = NULL ;
1212+ if (L ) {
1213+ lua_close (L );
1214+ }
1215+ CTX -> L = NULL ;
11711216 sapp_quit ();
11721217 } else {
11731218 sargs_shutdown ();
@@ -1241,29 +1286,79 @@ app_event(const sapp_event* ev) {
12411286 }
12421287}
12431288
1289+ static int
1290+ init_settings (lua_State * L , sapp_desc * desc ) {
1291+ if (L == NULL ) {
1292+ fprintf (stderr , "Can't open lua state\n" );
1293+ return 1 ;
1294+ }
1295+ if (lua_gettop (L ) != 2 ) {
1296+ fprintf (stderr , "Invalid lua stack (top = %d)\n" , lua_gettop (L ));
1297+ return 1 ;
1298+ }
1299+ if (lua_getfield (L , -1 , "init" ) != LUA_TFUNCTION ) {
1300+ fprintf (stderr , "No start function\n" );
1301+ return 1 ;
1302+ }
1303+ lua_pushlightuserdata (L , (void * )desc );
1304+ if (lua_pcall (L , 1 , 0 , 1 ) != LUA_OK ) {
1305+ fprintf (stderr , "Start fatal : %s\n" , lua_tostring (L , -1 ));
1306+ return 1 ;
1307+ } else {
1308+ return 0 ;
1309+ }
1310+ }
1311+
12441312sapp_desc
12451313sokol_main (int argc , char * argv []) {
1314+ // init sargs
12461315 sargs_desc arg_desc ;
12471316 memset (& arg_desc , 0 , sizeof (arg_desc ));
12481317 arg_desc .argc = argc ;
12491318 arg_desc .argv = argv ;
12501319 sargs_setup (& arg_desc );
12511320
1321+ // init L
1322+ static struct app_context app ;
1323+ lua_State * L = luaL_newstate ();
1324+
1325+ lua_settop (L , 0 );
1326+ lua_pushcfunction (L , msghandler );
1327+ lua_pushcfunction (L , pmain );
1328+
1329+ if (lua_pcall (L , 0 , 1 , 1 ) != LUA_OK ) {
1330+ fprintf (stderr , "Init fatal : %s\n" , lua_tostring (L , -1 ));
1331+ lua_close (L );
1332+ L = NULL ;
1333+ }
1334+
1335+ // default sapp_desc
1336+
12521337 sapp_desc d ;
12531338 memset (& d , 0 , sizeof (d ));
12541339
1255- d .high_dpi = true;
1256- d .width = 1024 ;
1257- d .height = 768 ;
12581340 d .init_cb = app_init ;
12591341 d .frame_cb = app_frame ;
12601342 d .cleanup_cb = app_cleanup ;
12611343 d .event_cb = app_event ;
12621344 d .logger .func = log_func ;
12631345 d .win32_console_utf8 = 1 ;
12641346 d .win32_console_attach = 1 ;
1265- d .window_title = "soluna" ;
12661347 d .alpha = 0 ;
1348+
1349+ if (init_settings (L , & d )) {
1350+ fprintf (stderr , "Init setting fatal : %s\n" , lua_tostring (L , -1 ));
1351+ lua_close (L );
1352+ L = NULL ;
1353+ }
1354+
1355+ app .L = L ;
1356+ app .quitL = NULL ;
1357+ app .send_log = NULL ;
1358+ app .send_log_ud = NULL ;
1359+ app .mqueue = NULL ;
1360+
1361+ CTX = & app ;
12671362
12681363 return d ;
12691364}
0 commit comments