int main (int argc, char** argv) { int i; LIMdlBuilder* builder; LIMdlModel* model; if (!argc || !strcmp (argv[1], "--help") || !strcmp (argv[1], "-h")) { printf ("Usage: %s [lmdl...]\n", argv[0]); return 0; } for (i = 1 ; i < argc ; i++) { /* Load the model. */ model = limdl_model_new_from_file (argv[i], 1); if (model == NULL) { lisys_error_report (); continue; } /* Check for existing LOD. */ if (!model->lod.array[0].indices.count) { printf (" Unneeded %s\n", argv[i]); continue; } if (model->lod.count > 1) { printf ("%3d%%: Existing %s\n", 100 - 100 * model->lod.array[model->lod.count - 1].indices.count / model->lod.array[0].indices.count, argv[i]); limdl_model_free (model); continue; } /* Build the detail levels. */ builder = limdl_builder_new (model); if (builder == NULL) { lisys_error_report (); limdl_model_free (model); continue; } limdl_builder_calculate_lod (builder, 5, 0.05f); limdl_builder_finish (builder); limdl_builder_free (builder); /* Save the modified model. */ printf ("%3d%%: Built %s\n", 100 - 100 * model->lod.array[model->lod.count - 1].indices.count / model->lod.array[0].indices.count, argv[i]); limdl_model_write_file (model, argv[i]); limdl_model_free (model); } return 0; }
static void Heightmap_new (LIScrArgs* args) { int i; int size; float spacing; float scaling; LIExtHeightmap* heightmap; LIExtHeightmapModule* module; LIImgImage* image; LIMatVector position; LIScrData* data; /* Get arguments. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_HEIGHTMAP); if (!liscr_args_geti_vector (args, 0, &position)) position = limat_vector_init (0.0f, 0.0f, 0.0f); if (!liscr_args_geti_int (args, 1, &size)) size = 33; else if (size < 0) size = 0; if (!liscr_args_geti_float (args, 2, &spacing)) spacing = 1.0f; else if (spacing <= 0.0f) spacing = 1.0f; if (!liscr_args_geti_float (args, 3, &scaling)) scaling = 1.0f; else if (scaling <= 0.0f) scaling = 1.0f; if (liscr_args_geti_data (args, 4, LIEXT_SCRIPT_IMAGE, &data)) image = liscr_data_get_data (data); else image = NULL; /* Ensure that the size is valid. */ for (i = 32 ; i < 65536 ; i *= 2) { if (size == i + 1) break; } if (size != i + 1) { lisys_error_set (EINVAL, "invalid heightmap size"); lisys_error_report (); return; } /* Allocate the heightmap. */ heightmap = liext_heightmap_new (module, image, &position, size, spacing, scaling); if (heightmap == NULL) return; /* Allocate the userdata. */ data = liscr_data_new (args->script, args->lua, heightmap, LIEXT_SCRIPT_HEIGHTMAP, liext_heightmap_free); if (data == NULL) { liext_heightmap_free (heightmap); return; } liscr_args_seti_stack (args); }
static void Heightmap_add_texture_layer (LIScrArgs* args) { float size; const char* name; const char* diffuse; const char* specular; const char* normal; const char* height; const char* blend; /* Get arguments. */ if (!liscr_args_geti_float (args, 0, &size)) size = 1.0f; if (!liscr_args_geti_string (args, 1, &name) || !liscr_args_geti_string (args, 2, &diffuse) || !liscr_args_geti_string (args, 3, &specular) || !liscr_args_geti_string (args, 4, &normal) || !liscr_args_geti_string (args, 5, &height)) return; if (!liscr_args_geti_string (args, 6, &blend)) blend = NULL; /* Create the layer. */ if (!liext_heightmap_add_texture_layer (args->self, size, name, diffuse, specular, normal, height, blend)) lisys_error_report (); }
static void private_thread_main ( LISysThread* thread, void* data) { LIExtThread* self = data; if (self->code != NULL) { if (!limai_program_execute_string (self->program, self->code)) lisys_error_report (); } else { if (!limai_program_execute_script (self->program, self->file)) lisys_error_report (); } }
static void private_worker_thread ( LISysAsyncCall* call, void* data) { LISndSample* self = data; if (lisys_path_check_ext (self->file, "flac")) { if (!private_load_flac (self, self->file)) lisys_error_report (); } else if (lisys_path_check_ext (self->file, "ogg")) { if (!private_load_vorbis (self, self->file)) lisys_error_report (); } self->loaded = 1; }
/** * \brief Initializes the global video card information. * \return Nonzero on success. */ int livid_video_init () { int ver[3]; GLenum error; const GLubyte* tmp; /* Initialize GLEW. */ error = glewInit (); if (error != GLEW_OK) { lisys_error_set (LISYS_ERROR_UNKNOWN, "%s", glewGetErrorString (error)); return 0; } /* Check for OpenGL 3.2 capabilities. */ /* GLEW versions up to 1.5.3 had a bug that completely broke OpenGL 3.2 support. We try to detect it and warn the user of the problem. */ if (GLEW_VERSION_3_2) return 1; tmp = glewGetString (GLEW_VERSION); if (sscanf ((const char*) tmp, "%d.%d.%d", ver, ver + 1, ver + 2) == 3 && (ver[0] < 1 || ver[1] < 5 || ver[2] <= 3)) { lisys_error_set (EINVAL, "OpenGL 3.2 isn't supported because it requires GLEW 1.5.4 or newer while you have %s", tmp); lisys_error_report (); } else { lisys_error_set (EINVAL, "OpenGL 3.2 isn't supported by your graphics card or drivers"); lisys_error_report (); } /* Check for OpenGL 2.1 capabilities. */ if (GLEW_VERSION_2_1) return 1; lisys_error_set (EINVAL, "OpenGL 2.1 isn't supported by your graphics card or drivers"); return 0; }
static void Model_merge (LIScrArgs* args) { LIScrData* data; LIEngModel* model1; LIEngModel* model2; if (liscr_args_geti_data (args, 0, LISCR_SCRIPT_MODEL, &data) || liscr_args_gets_data (args, "model", LISCR_SCRIPT_MODEL, &data)) { model1 = args->self; model2 = liscr_data_get_data (data); if (!limdl_model_merge (model1->model, model2->model)) lisys_error_report (); } }
static void Lobby_upload_server_info (LIScrArgs* args) { #ifdef HAVE_CURL int port = 0; int players = 0; char* url; char* decoded; const char* desc = NULL; const char* master = NULL; const char* name = NULL; char error_buffer[CURL_ERROR_SIZE]; CURL* curl; /* Get arguments. */ if (!liscr_args_gets_string (args, "desc", &desc) || !liscr_args_gets_string (args, "master", &master) || !liscr_args_gets_string (args, "name", &name) || !liscr_args_gets_int (args, "players", &players) || !liscr_args_gets_int (args, "port", &port)) return; players = LIMAT_CLAMP (players, 0, 256); port = LIMAT_CLAMP (port, 1, 65535); /* Format the script URL. */ url = lisys_string_concat (master, "/lossrvapi.php"); if (url == NULL) return; /* POST to the master server. */ curl = curl_easy_init(); if (curl != NULL) { decoded = lisys_string_format ("u=%d|%d|%s|%s", port, players, name, desc); curl_easy_setopt (curl, CURLOPT_URL, url); curl_easy_setopt (curl, CURLOPT_POSTFIELDS, decoded); curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, error_buffer); if (curl_easy_perform (curl)) { lisys_error_set (EINVAL, "lobby: %s", error_buffer); lisys_error_report (); } curl_easy_cleanup (curl); lisys_free (decoded); } lisys_free (url); #endif }
static void Animation_load (LIScrArgs* args) { char* file; const char* path; const char* name; LIMdlAnimation* self; LIExtAnimationModule* module; LIScrData* data; /* Get arguments. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_ANIMATION); if (!liscr_args_geti_string (args, 0, &name)) return; /* Create the path. */ file = lisys_string_concat (name, ".lani"); if (file == NULL) return; path = lipth_paths_find_file (module->program->paths, file); lisys_free (file); if (path == NULL) return; /* Allocate the animation. */ self = limdl_animation_new_from_file (path); if (self == NULL) { lisys_error_report (); return; } /* Allocate the userdata. */ data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_ANIMATION, limdl_animation_free); if (data == NULL) { limdl_animation_free (self); return; } liscr_args_seti_stack (args); }
/** * \brief Creates a rendering framebuffer. * \param render Renderer. * \param width Framebuffer width. * \param height Framebuffer height. * \param samples Number of multisamples. * \param hdr Nonzero to use floating point framebuffer to enable HDR. * \return New deferred framebuffer or NULL. */ LIRenFramebuffer32* liren_framebuffer32_new ( LIRenRender32* render, int width, int height, int samples, int hdr) { LIRenFramebuffer32* self; /* Allocate self. */ self = lisys_calloc (1, sizeof (LIRenFramebuffer32)); if (self == NULL) return NULL; self->render = render; self->width = width; self->height = height; /* Create frame buffer object. */ for ( ; samples > 0 ; samples--) { if (!liren_framebuffer32_resize (self, width, height, samples, hdr)) lisys_error_report (); else break; } if (samples == 0) { liren_framebuffer32_free (self); return NULL; } /* Add to dictionary. */ if (!lialg_ptrdic_insert (render->framebuffers, self, self)) { liren_framebuffer32_free (self); return NULL; } return self; }
static void Widgets_add_font_style (LIScrArgs* args) { int size = 16; const char* file; const char* name; LIExtModule* module; /* Arguments. */ if (!liscr_args_geti_string (args, 0, &name) && !liscr_args_gets_string (args, "name", &name)) return; if (!liscr_args_geti_string (args, 1, &file) && !liscr_args_gets_string (args, "file", &file)) return; if (!liscr_args_geti_int (args, 2, &size)) liscr_args_gets_int (args, "size", &size); /* Load the font. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_WIDGETS); if (!liwdg_styles_load_font (module->widgets->styles, name, file, size)) lisys_error_report (); }
/** * \brief Prints the traceback to the terminal. * * This function is intended to be used for debugging. It helps with locating * crashes and other problems that involve Lua calling the C functions. * * \param lua Lua state. */ void liscr_traceback ( lua_State* lua) { /* Get debug table. */ lua_getfield (lua, LUA_GLOBALSINDEX, "debug"); if (lua_type (lua, -1) != LUA_TTABLE) { lisys_error_set (EINVAL, "invalid debug table"); lua_pop (lua, 1); return; } /* Get traceback function. */ lua_getfield (lua, -1, "traceback"); lua_remove (lua, -2); if (lua_type (lua, -1) != LUA_TFUNCTION) { lisys_error_set (EINVAL, "invalid traceback function"); lua_pop (lua, 1); return; } /* Call traceback excluding itself from the trace. */ lua_pushstring (lua, ""); lua_pushinteger (lua, 1); if (lua_pcall (lua, 2, 1, 0) != 0) { lisys_error_set (EINVAL, lua_tostring (lua, -1)); lisys_error_report (); lua_pop (lua, 1); return; } /* Print the traceback to the terminal. */ printf ("\nLua traceback:\n%s\n\n", lua_tostring (lua, -1)); lua_pop (lua, 1); }
int main (int argc, char** argv) { char* path; char* launch_name; char* launch_args; LIMaiProgram* program; /* Resolve game directory. */ path = lipth_paths_get_root (); if (path == NULL) { lisys_error_report (); return 1; } /* Parse command line arguments. */ launch_name = "default"; launch_args = NULL; if (!private_parse_arguments (argc, argv, &launch_name, &launch_args)) { lisys_error_report (); lisys_free (path); return 1; } /* Start the program. */ program = limai_program_new (path, launch_name, launch_args); lisys_free (launch_args); if (program == NULL) { lisys_error_report (); lisys_free (path); return 1; } /* Execute mods until one exits without starting a new one. */ while (program != NULL) { /* Execute the module until the script exits. */ if (!limai_program_execute_script (program, "main.lua")) { lisys_error_report (); break; } /* Check if the module started another one. */ launch_name = program->launch_name; launch_args = program->launch_args; if (launch_name == NULL) break; program->launch_name = NULL; program->launch_args = NULL; limai_program_free (program); /* Unload the old module and load a new one. */ program = limai_program_new (path, launch_name, launch_args); lisys_free (launch_name); lisys_free (launch_args); if (program == NULL) { lisys_error_report (); break; } } /* Free all resources. */ limai_program_free (program); lisys_free (path); SDL_Quit (); return 0; }
static void Lobby_download_server_list (LIScrArgs* args) { #ifdef HAVE_CURL int ret; int port = 0; int players = 0; char* url; char* desc; char* ip; char* name; const char* master; char error_buffer[CURL_ERROR_SIZE]; LIArcReader* reader; LIArcWriter* writer; CURL* curl; /* Get arguments. */ if (!liscr_args_gets_string (args, "master", &master)) return; liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); /* Format the script URL. */ url = lisys_string_concat (master, "/lossrvapi.php"); if (url == NULL) return; /* GET from the master server. */ curl = curl_easy_init(); if (curl != NULL) { writer = liarc_writer_new (); curl_easy_setopt (curl, CURLOPT_URL, url); curl_easy_setopt (curl, CURLOPT_WRITEDATA, writer); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, private_write); curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, error_buffer); if (curl_easy_perform (curl)) { lisys_error_set (EINVAL, "lobby: %s", error_buffer); lisys_error_report (); curl_easy_cleanup (curl); liarc_writer_free (writer); lisys_free (url); return; } curl_easy_cleanup (curl); liarc_writer_append_nul (writer); reader = liarc_reader_new ( liarc_writer_get_buffer (writer), liarc_writer_get_length (writer)); while (!liarc_reader_check_end (reader)) { ip = NULL; name = NULL; desc = NULL; ret = liarc_reader_get_text (reader, "\t", &ip) && liarc_reader_get_text_int (reader, &port) && liarc_reader_skip_bytes (reader, 1) && liarc_reader_get_text_int (reader, &players) && liarc_reader_skip_bytes (reader, 1) && liarc_reader_get_text (reader, "\t", &name) && liarc_reader_get_text (reader, "\n", &desc); if (ret) { lua_newtable (args->lua); lua_pushstring (args->lua, ip); lua_setfield (args->lua, -2, "ip"); lua_pushnumber (args->lua, port); lua_setfield (args->lua, -2, "port"); lua_pushnumber (args->lua, players); lua_setfield (args->lua, -2, "players"); lua_pushstring (args->lua, name); lua_setfield (args->lua, -2, "name"); lua_pushstring (args->lua, desc); lua_setfield (args->lua, -2, "desc"); liscr_args_seti_stack (args); } lisys_free (ip); lisys_free (name); lisys_free (desc); if (!ret) break; } liarc_reader_free (reader); liarc_writer_free (writer); } lisys_free (url); #endif }
static void Database_new (LIScrArgs* args) { int ok; char* path; char* path1; const char* ptr; const char* name; sqlite3* sql; LIExtModule* module; LIScrData* data; module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_DATABASE); /* Get and validate the filename. */ if (!liscr_args_geti_string (args, 0, &name) && !liscr_args_gets_string (args, "name", &name)) return; for (ptr = name ; *ptr != '\0' ; ptr++) { if (*ptr >= 'a' && *ptr <= 'z') ok = 1; else if (*ptr >= 'A' && *ptr <= 'Z') ok = 1; else if (*ptr >= '0' && *ptr <= '9') ok = 1; else if (*ptr == '-') ok = 1; else if (*ptr == '_') ok = 1; else if (*ptr == '.') ok = 1; else ok = 0; if (!ok) { lisys_error_set (EINVAL, "invalid database name `%s'", name); lisys_error_report (); return; } } /* Format the path. */ ptr = lipth_paths_create_file (module->program->paths, name, 0); if (ptr == NULL) { lisys_error_report (); return; } path = lisys_string_dup (ptr); if (path == NULL) return; /* Convert the path to UTF-8. */ /* Unlike other file functions we use, SQLite requires the filename to be in UTF-8 instead of the system locale. */ path1 = lisys_string_convert_sys_to_utf8 (path); if (path1 != NULL) { lisys_free (path); path = path1; } /* Open database. */ if (sqlite3_open_v2 (path, &sql, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) != SQLITE_OK) { lisys_error_set (EINVAL, "sqlite: %s", sqlite3_errmsg (sql)); lisys_error_report (); lisys_free (path); lisys_free (sql); return; } lisys_free (path); /* Allocate userdata. */ data = liscr_data_new (args->script, args->lua, sql, LIEXT_SCRIPT_DATABASE, private_free_database); if (data == NULL) { sqlite3_close (sql); return; } liscr_args_seti_stack (args); }
static void Database_query (LIScrArgs* args) { int i; int col; int row; int ret; int size; const char* query; const char* str; sqlite3* self; LIArcPacket* packet; LIScrData* data; sqlite3_stmt* statement; self = args->self; if (!liscr_args_geti_string (args, 0, &query) && !liscr_args_gets_string (args, "query", &query)) return; /* Create a statement. */ if (sqlite3_prepare_v2 (self, query, -1, &statement, NULL) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL prepare: %s", sqlite3_errmsg (self)); lisys_error_report (); return; } /* Bind variables. */ if (liscr_args_geti_table (args, 1) || liscr_args_gets_table (args, "bind")) { for (i = 1 ; i < sqlite3_bind_parameter_count (statement) + 1 ; i++) { /* We got a table that has the bound variables in fields matching the indices of the bound variables. We can simply loop through the table and use the binding index as the key. */ lua_pushnumber (args->lua, i); lua_gettable (args->lua, -2); switch (lua_type (args->lua, -1)) { /* Bind numbers as doubles. */ case LUA_TNUMBER: if (sqlite3_bind_double (statement, i, lua_tonumber (args->lua, -1)) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } break; /* Bind strings as text. */ case LUA_TSTRING: if (sqlite3_bind_text (statement, i, lua_tostring (args->lua, -1), -1, SQLITE_TRANSIENT) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } break; /* Bind packets as blobs. */ case LUA_TUSERDATA: data = liscr_isdata (args->lua, -1, LISCR_SCRIPT_PACKET); if (data == NULL) break; packet = liscr_data_get_data (data); if (packet->writer != NULL) { if (sqlite3_bind_blob (statement, i, packet->writer->memory.buffer, packet->writer->memory.length, SQLITE_TRANSIENT) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } } else { if (sqlite3_bind_blob (statement, i, packet->reader->buffer, packet->reader->length, SQLITE_TRANSIENT) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } } break; /* Bind any other values as NULL. */ default: if (sqlite3_bind_null (statement, i) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } break; } lua_pop (args->lua, 1); } lua_pop (args->lua, 1); } /* Execute the statement and process results. */ for (row = 0, ret = sqlite3_step (statement) ; ret != SQLITE_DONE ; ret = sqlite3_step (statement), row++) { /* Check for errors. */ if (ret != SQLITE_ROW) { lisys_error_set (EINVAL, "SQL step: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } if (!row) liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); /* Create a row table. */ lua_newtable (args->lua); /* Push the columns to the table. */ for (col = 0 ; col < sqlite3_column_count (statement) ; col++) { switch (sqlite3_column_type (statement, col)) { case SQLITE_INTEGER: lua_pushnumber (args->lua, col + 1); lua_pushnumber (args->lua, sqlite3_column_int (statement, col)); lua_settable (args->lua, -3); break; case SQLITE_FLOAT: lua_pushnumber (args->lua, col + 1); lua_pushnumber (args->lua, sqlite3_column_double (statement, col)); lua_settable (args->lua, -3); break; case SQLITE_TEXT: str = (const char*) sqlite3_column_text (statement, col); size = sqlite3_column_bytes (statement, col); lua_pushnumber (args->lua, col + 1); if (size > 0 && str != NULL) lua_pushstring (args->lua, str); else lua_pushstring (args->lua, str); lua_settable (args->lua, -3); break; case SQLITE_BLOB: str = sqlite3_column_blob (statement, col); size = sqlite3_column_bytes (statement, col); packet = liarc_packet_new_readable (str, size); if (packet != NULL) { lua_pushnumber (args->lua, col + 1); data = liscr_data_new (args->script, args->lua, packet, LISCR_SCRIPT_PACKET, liarc_packet_free); if (data != NULL) lua_settable (args->lua, -3); else { lua_pop (args->lua, 1); liarc_packet_free (packet); } } break; case SQLITE_NULL: break; default: lisys_assert (0 && "invalid column type"); break; } } /* Add the row to the return values. */ liscr_args_seti_stack (args); } if (!row) liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); sqlite3_finalize (statement); }