static void Animation_new (LIScrArgs* args) { const char* name; LIMdlAnimation* self; LIScrData* data; /* Get arguments. */ if (!liscr_args_geti_string (args, 0, &name)) return; /* Allocate the animation. */ self = limdl_animation_new (); if (self == NULL) return; self->name = lisys_string_dup (name); if (self->name == NULL) { lisys_free (self); 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); }
static void Terrain_new (LIScrArgs* args) { int chunk_size; float grid_size; LIExtTerrain* self; LIExtTerrainModule* module; LIScrData* data; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &chunk_size) || chunk_size < 1) return; if (!liscr_args_geti_float (args, 1, &grid_size) || grid_size <= 0.0f) return; module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_TERRAIN); /* Allocate the object. */ self = liext_terrain_new (module, chunk_size, grid_size); if (self == NULL) return; /* Allocate the userdata. */ data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_TERRAIN, liext_terrain_free); if (data == NULL) { liext_terrain_free (self); return; } liscr_args_seti_stack (args); }
static void Animation_copy (LIScrArgs* args) { LIMdlAnimation* self; LIMdlAnimation* copy; LIScrData* data; /* Get arguments. */ if (!liscr_args_geti_data (args, 0, LIEXT_SCRIPT_ANIMATION, &data)) return; copy = liscr_data_get_data (data); /* Allocate the animation. */ self = limdl_animation_new_copy (copy); if (self == NULL) 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); }
static void Camera_new (LIScrArgs* args) { LIExtCamera* self; LIExtCameraModule* module; LIScrData* data; LIRenRender* render; LIRenVideomode mode; /* Allocate self. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_CAMERA); self = liext_camera_new (module); if (self == NULL) return; liext_camera_set_driver (self, LIALG_CAMERA_THIRDPERSON); /* Initialize the viewport. */ render = limai_program_find_component (module->program, "render"); if (render) { liren_render_get_videomode (render, &mode); liext_camera_set_viewport (self, 0, 0, mode.width, mode.height); } /* Allocate userdata. */ data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_CAMERA, liext_camera_free); if (data == NULL) { liext_camera_free (self); return; } liscr_args_seti_stack (args); }
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 Model_copy (LIScrArgs* args) { int shape_keys = 1; LIMaiProgram* program; LIMdlModel* self; LIScrData* data; /* Get arguments. */ program = liscr_script_get_userdata (args->script, LISCR_SCRIPT_PROGRAM); liscr_args_geti_bool (args, 0, &shape_keys); /* Allocate the model. */ self = limdl_model_new_copy (args->self, shape_keys); if (self == NULL) return; /* Allocate the unique ID. */ if (!limdl_manager_add_model (program->models, self)) { limdl_model_free (self); return; } /* Allocate userdata. */ data = liscr_data_new (args->script, args->lua, self, LISCR_SCRIPT_MODEL, limdl_manager_free_model); if (data == NULL) { limdl_model_free (self); return; } liscr_args_seti_stack (args); }
static void FirFilter_new (LIScrArgs* args) { int i; int length; float* coeffs; LIExtFirFilter* fir; LIScrData* data; /* Get the number of coefficients. */ if (!liscr_args_geti_int (args, 0, &length)) return; if (length <= 0) return; /* Allocate the coefficients. */ coeffs = lisys_calloc (length, sizeof (float)); if (!coeffs) return; /* Read the coefficients. */ if (liscr_args_geti_table (args, 1)) { for (i = 0 ; i < length ; i++) { lua_pushnumber (args->lua, i + 1); lua_gettable (args->lua, -2); if (lua_type (args->lua, -1) == LUA_TNUMBER) coeffs[i] = lua_tonumber (args->lua, -1); lua_pop (args->lua, 1); } lua_pop (args->lua, 1); } /* Create the filter. */ fir = liext_fir_filter_new (length, coeffs); lisys_free (coeffs); if (fir == NULL) return; /* Allocate userdata. */ data = liscr_data_new (args->script, args->lua, fir, LIEXT_SCRIPT_FIR_FILTER, liext_fir_filter_free); if (data == NULL) { liext_fir_filter_free (fir); return; } liscr_args_seti_stack (args); }
static void Terrain_get_column (LIScrArgs* args) { int i; int vtx_x; int vtx_z; int grid_x; int grid_z; LIExtTerrainColumn* column; LIExtTerrainStick* stick; /* Get the arguments. */ if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) return; /* Get the column. */ column = liext_terrain_get_column (args->self, grid_x, grid_z); if (column == NULL) return; /* Pack the sticks into a table. */ liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); for (stick = column->sticks ; stick != NULL ; stick = stick->next) { i = 0; lua_newtable (args->lua); #define PUSHNUM(v) lua_pushnumber (args->lua, ++i);\ lua_pushnumber (args->lua, v);\ lua_settable (args->lua, -3); PUSHNUM (stick->material); PUSHNUM (stick->height); for (vtx_z = 0 ; vtx_z < 2 ; vtx_z++) { for (vtx_x = 0 ; vtx_x < 2 ; vtx_x++) { PUSHNUM (stick->vertices[vtx_x][vtx_z].offset); PUSHNUM (stick->vertices[vtx_x][vtx_z].splatting); PUSHNUM (stick->vertices[vtx_x][vtx_z].normal.x); PUSHNUM (stick->vertices[vtx_x][vtx_z].normal.y); PUSHNUM (stick->vertices[vtx_x][vtx_z].normal.z); } } #undef PUSHNUM liscr_args_seti_stack (args); } }
static void Terrain_build_chunk_model (LIScrArgs* args) { int grid_x; int grid_z; LIExtTerrain* self; LIExtTerrainModule* module; LIMatVector offset; LIMdlModel* model; LIScrData* data; /* Get the arguments. */ self = args->self; module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_TERRAIN); if (!liscr_args_geti_int (args, 0, &grid_x) || grid_x < 0) return; if (!liscr_args_geti_int (args, 1, &grid_z) || grid_z < 0) return; if (!liscr_args_geti_vector (args, 2, &offset)) offset = limat_vector_init (grid_x * self->grid_size, 0.0f, grid_z * self->grid_size); /* Build the model. */ model = liext_terrain_build_chunk_model (self, grid_x, grid_z, &offset); if (model == NULL) return; /* Copy the model. */ model = limdl_model_new_copy (model, 0); if (model == NULL) return; /* Allocate the unique ID. */ if (!limdl_manager_add_model (module->program->models, model)) { limdl_model_free (model); return; } /* Allocate the userdata. */ data = liscr_data_new (args->script, args->lua, model, LISCR_SCRIPT_MODEL, limdl_manager_free_model); if (data == NULL) { limdl_model_free (model); return; } liscr_args_seti_stack (args); }
static void ImageMerger_new (LIScrArgs* args) { LIImgAsyncMerger* self; LIScrData* data; /* Allocate the merger. */ self = liimg_async_merger_new (); if (self == NULL) return; /* Allocate the userdata. */ data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_IMAGE_MERGER, liimg_async_merger_free); if (data == NULL) { liimg_async_merger_free (self); return; } liscr_args_seti_stack (args); }
static void Thread_new (LIScrArgs* args) { const char* args_ = ""; const char* file = "main.lua"; const char* code = NULL; LIExtModule* module; /* Read arguments. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_THREAD); if (!liscr_args_geti_string (args, 0, &file)) liscr_args_gets_string (args, "file", &file); if (!liscr_args_geti_string (args, 1, &args_)) liscr_args_gets_string (args, "args", &args_); if (!liscr_args_geti_string (args, 2, &code)) liscr_args_gets_string (args, "code", &code); /* Create the thread to the stack. */ if (liext_thread_inst_new (module->program, args->lua, file, code, args_) != NULL) liscr_args_seti_stack (args); }
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); }
static void Widget_new (LIScrArgs* args) { LIExtModule* module; LIScrData* data; LIWdgWidget* self; /* Allocate userdata. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_WIDGET); self = liwdg_widget_new (module->widgets); if (self == NULL) return; /* Allocate userdata. */ data = liscr_data_new (args->script, args->lua, self, LIEXT_SCRIPT_WIDGET, liwdg_widget_free); if (data == NULL) { liwdg_widget_free (self); return; } liwdg_widget_set_script (self, data); liscr_args_seti_stack (args); }
static void ImageMerger_pop_image (LIScrArgs* args) { LIImgAsyncMerger* self; LIImgImage* image; LIScrData* data; /* Get arguments. */ self = args->self; /* Get the image. */ image = liimg_async_merger_pop_image (self); if (image == NULL) return; /* Create the script image. */ data = liscr_data_new (args->script, args->lua, image, LIEXT_SCRIPT_IMAGE, liimg_image_free); if (data == NULL) { liimg_image_free (image); 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); }
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 Voxel_copy_region (LIScrArgs* args) { int i; int length; int sector; int offset[3]; LIArcPacket* packet; LIScrData* data; LIExtModule* module; LIMatVector point; LIMatVector size; LIVoxVoxel* result; /* Get region offset and size. */ module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_VOXEL); if (liscr_args_gets_int (args, "sector", §or)) { lialg_sectors_index_to_offset (module->program->sectors, sector, offset + 0, offset + 1, offset + 2); point = limat_vector_init (offset[0], offset[1], offset[2]); point = limat_vector_multiply (point, module->voxels->tiles_per_line); size.x = size.y = size.z = module->voxels->tiles_per_line; length = module->voxels->tiles_per_sector; } else if (liscr_args_gets_vector (args, "point", &point) && liscr_args_gets_vector (args, "size", &size)) { if (point.x < 0.0f || point.y < 0.0f || point.z < 0.0f || size.x < 1.0f || size.y < 1.0f || size.z < 1.0f) return; length = (int) size.x * (int) size.y * (int) size.z; } else return; /* Read voxel data. */ result = lisys_calloc (length, sizeof (LIVoxVoxel)); if (result == NULL) return; livox_manager_copy_voxels (module->voxels, (int) point.x, (int) point.y, (int) point.z, (int) size.x, (int) size.y, (int) size.z, result); /* Create a packet writer. */ packet = liarc_packet_new_writable (0); if (packet == NULL) { lisys_free (result); return; } /* Write the dimensions. */ if (!liarc_writer_append_uint32 (packet->writer, (int) size.x) || !liarc_writer_append_uint32 (packet->writer, (int) size.y) || !liarc_writer_append_uint32 (packet->writer, (int) size.z)) { lisys_free (result); return; } /* Write voxel data. */ for (i = 0 ; i < length ; i++) { if (!livox_voxel_write (result + i, packet->writer)) { lisys_free (result); return; } } lisys_free (result); /* Return data. */ data = liscr_data_new (args->script, args->lua, packet, LISCR_SCRIPT_PACKET, liarc_packet_free); if (data == NULL) { liarc_packet_free (packet); return; } liscr_args_seti_stack (args); }
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); }