static void Thread_push_message (LIScrArgs* args) { const char* name = ""; const char* string = NULL; LIScrData* data; LIEngModel* emodel; LIExtThread* self; /* Read the name. */ self = args->self; if (!liscr_args_geti_string (args, 0, &name)) liscr_args_gets_string (args, "name", &name); /* Read and push the data. */ if (liscr_args_geti_string (args, 1, &string) || liscr_args_gets_string (args, "string", &string)) { if (limai_program_push_message (self->program, LIMAI_MESSAGE_QUEUE_THREAD, LIMAI_MESSAGE_TYPE_STRING, name, string)) liscr_args_seti_bool (args, 1); } else if (liscr_args_geti_data (args, 1, LISCR_SCRIPT_MODEL, &data) || liscr_args_gets_data (args, "model", LISCR_SCRIPT_MODEL, &data)) { emodel = liscr_data_get_data (data); if (limai_program_push_message (self->program, LIMAI_MESSAGE_QUEUE_THREAD, LIMAI_MESSAGE_TYPE_MODEL, name, emodel->model)) liscr_args_seti_bool (args, 1); } else { if (limai_program_push_message (self->program, LIMAI_MESSAGE_QUEUE_THREAD, LIMAI_MESSAGE_TYPE_EMPTY, name, NULL)) liscr_args_seti_bool (args, 1); } }
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 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 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 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 (); }
static void Sound_set_music (LIScrArgs* args) { #ifndef LI_DISABLE_SOUND const char* value; LIExtModule* module; if (liscr_args_geti_string (args, 0, &value)) { module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_SOUND); liext_sound_set_music (module, value); } #endif }
static void Camera_set_mode (LIScrArgs* args) { const char* value; LIExtCamera* camera; if (liscr_args_geti_string (args, 0, &value)) { camera = args->self; if (!strcmp (value, "first-person")) liext_camera_set_driver (camera, LIALG_CAMERA_FIRSTPERSON); else if (!strcmp (value, "manual")) liext_camera_set_driver (camera, LIALG_CAMERA_MANUAL); else if (!strcmp (value, "third-person")) liext_camera_set_driver (camera, LIALG_CAMERA_THIRDPERSON); } }
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 Model_morph (LIScrArgs* args) { float value = 0.5f; const char* shape; LIEngModel* model; LIEngModel* ref = NULL; LIScrData* data; model = args->self; if (!liscr_args_geti_string (args, 0, &shape) && !liscr_args_gets_string (args, "shape", &shape)) return; if (!liscr_args_geti_float (args, 1, &value)) liscr_args_gets_float (args, "value", &value); if (!liscr_args_geti_data (args, 2, LISCR_SCRIPT_MODEL, &data)) liscr_args_gets_data (args, "ref", LISCR_SCRIPT_MODEL, &data); if (data != NULL) ref = liscr_data_get_data (data); liscr_args_seti_bool (args, limdl_model_morph (model->model, (ref != NULL)? ref->model : NULL, shape, value)); }
static void Model_load (LIScrArgs* args) { int mesh = 1; char* file; const char* name; const char* path; LIMdlModel* tmpmdl; LIMaiProgram* program; program = liscr_script_get_userdata (args->script, LISCR_SCRIPT_PROGRAM); if (!liscr_args_geti_string (args, 0, &name) && !liscr_args_gets_string (args, "file", &name)) return; if (!liscr_args_geti_bool (args, 1, &mesh)) liscr_args_gets_bool (args, "mesh", &mesh); /* Find the absolute path. */ file = lisys_string_concat (name, ".lmdl"); if (file == NULL) return; path = lipth_paths_find_file (program->paths, file); if (path == NULL) { lisys_free (file); return; } lisys_free (file); /* Load the new model data. */ tmpmdl = limdl_model_new_from_file (path, mesh); if (tmpmdl == NULL) return; /* Replace the old model data. */ if (limdl_model_replace (args->self, tmpmdl)) liscr_args_seti_bool (args, 1); limdl_model_free (tmpmdl); }
/** Script callback Los.heightmap_generate This function converts the image data to Voxels: <li>First image contains height information in color values</li> <li>Second image contains material information in color values</li> <li>Position is the lower inferior voxel of the mapped area</li> <li>Size is the volume of the mapped area. Base size must fit with image size</li> <li>Materials is an array of mat ID used to associate voxel types</li> \param LIScrArgs* args */ static void Heightmap_heightmap_generate (LIScrArgs* args) { LIExtModule* module; LIVoxManager* voxels; LIVoxVoxel* tmp; const char* map_file; const char* tiles_file; LIMatVector posv; LIMatVector sizev; int materials[MAX_TEXTURES]; void* map_data; void* tiles_data; int min[3]; int max[3]; int size[3]; int x,y,z, y2, i, value; printf("Starting heightmap generation\n"); module = liscr_script_get_userdata (args->script, LIEXT_SCRIPT_HEIGHTMAP); voxels = limai_program_find_component (module->program, "voxels"); if (voxels == NULL) return; if (!liscr_args_geti_string (args, 0, &map_file) && liscr_args_gets_string (args, "map", &map_file)) return; if (!liscr_args_geti_string (args, 1, &tiles_file)) liscr_args_gets_string (args, "tiles", &tiles_file); if (!liscr_args_geti_vector (args, 2, &posv)) liscr_args_gets_vector (args, "pos", &posv); if (!liscr_args_geti_vector (args, 3, &sizev)) liscr_args_gets_vector (args, "size", &sizev); if (!liscr_args_geti_intv (args, 4, MAX_TEXTURES, materials)) liscr_args_gets_intv (args, "materials", MAX_TEXTURES, materials); if (liext_heightmap_generate(module, map_file, &map_data) != 0) { return; } if (liext_heightmap_generate(module, tiles_file, &tiles_data) != 0) { liext_heightmap_cleanup(module, &map_data); return; } /* Calculate the size of the area. */ size[0] = sizev.x; size[1] = sizev.y; size[2] = sizev.z; min[0] = posv.x; min[1] = posv.y; min[2] = posv.z; max[0] = (int)posv.x + size[0]; max[1] = (int)posv.y + size[1]; max[2] = (int)posv.z + size[2]; printf("Coords: %d %d %d / %d %d %d / %d %d %d\n", min[0], min[1], min[2], max[0], max[1], max[2], size[0], size[1], size[2]); /* Batch copy terrain data. */ /* Reading all tiles at once is faster than operating on individual tiles since there are fewer sector lookups. */ tmp = lisys_calloc (size[0] * size[1] * size[2], sizeof (LIVoxVoxel)); if (tmp == NULL) { liext_heightmap_cleanup(module, &map_data); liext_heightmap_cleanup(module, &tiles_data); return; } livox_manager_copy_voxels (voxels, min[0], min[1], min[2], size[0], size[1], size[2], tmp); /* Apply heightmap to the copied tiles. */ i = 0; for (z = min[2] ; z < max[2] ; z++) for (y = min[1] ; y < max[1] ; y++) for (x = min[0] ; x < max[0] ; x++) { //TODO: better resolution y2 = 255 - liext_heightmap_find(module, x, z, map_data); printf("gen y: %d\n", y2); if (y2 != -1 && y <= y2) { value = liext_heightmap_find(module, x, z, tiles_data); if (value < 0 || value >= MAX_TEXTURES) { value = 0; } livox_voxel_init (tmp + i, 15 /* materials[value] */); printf("voxel: %d %d\n", i, value); } i++; } /* Batch write the copied tiles. */ livox_manager_paste_voxels (voxels, min[0], min[1], min[2], size[0], size[1], size[2], tmp); lisys_free (tmp); printf("Area has been successfully loaded from heightmap\n"); liext_heightmap_cleanup(module, &map_data); liext_heightmap_cleanup(module, &tiles_data); }
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); }