diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 5726c9cc7e..66e94ea92d 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -80,7 +80,7 @@ jobs: } env: CC: ${{matrix.config.cc}} - CMAKE_OPTS: "-DEXTERNAL_ASSETS=Off -DSANITIZE=On -DFAST=${{matrix.config.fast}} -DLTO=${{matrix.config.lto}}" + CMAKE_OPTS: "-DSANITIZE=On -DFAST=${{matrix.config.fast}} -DLTO=${{matrix.config.lto}}" steps: - name: checkout uses: actions/checkout@v4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 75ab8e3721..04741e2b6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,11 +11,10 @@ endif() project(Volo VERSION 0.1.0 LANGUAGES C) # Custom options. -set(FAST "Off" CACHE BOOL "Fast mode, disables various runtime validations") -set(TRACE "On" CACHE BOOL "Trace mode, enables runtime performance tracing") -set(LTO "Off" CACHE BOOL "Link time optimization") -set(SANITIZE "Off" CACHE BOOL "Should santiser instrumentation be enabled") -set(EXTERNAL_ASSETS "On" CACHE BOOL "Should external assets be downloaded") +set(FAST "Off" CACHE BOOL "Fast mode, disables various runtime validations") +set(TRACE "On" CACHE BOOL "Trace mode, enables runtime performance tracing") +set(LTO "Off" CACHE BOOL "Link time optimization") +set(SANITIZE "Off" CACHE BOOL "Should santiser instrumentation be enabled") # Diagnostic information. message(STATUS "Configuring Volo") @@ -30,12 +29,10 @@ message(STATUS "* Fast: ${FAST}") message(STATUS "* Trace: ${TRACE}") message(STATUS "* Lto: ${LTO}") message(STATUS "* Sanitize: ${SANITIZE}") -message(STATUS "* External assets: ${EXTERNAL_ASSETS}") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules") include(cmake/compiler.cmake) include(cmake/debug.cmake) -include(cmake/download.cmake) include(cmake/findpkg.cmake) include(cmake/platform.cmake) include(cmake/test.cmake) @@ -58,9 +55,6 @@ add_subdirectory(libs) message(STATUS "Configuring applications") add_subdirectory(apps) -message(STATUS "Configuring assets") -add_subdirectory(assets) - message(STATUS "Configuring utility targets") configure_test_target() configure_dbgsetup_target() diff --git a/apps/game/CMakeLists.txt b/apps/game/CMakeLists.txt index 2d766bde31..093f9b549e 100644 --- a/apps/game/CMakeLists.txt +++ b/apps/game/CMakeLists.txt @@ -26,8 +26,7 @@ target_link_libraries(app_game PRIVATE lib_ui lib_vfx ) -add_dependencies(app_game volo_assets) configure_debuggable(app_game) add_custom_target(run.game COMMAND app_game - "-w" "--assets" "$" VERBATIM USES_TERMINAL) + "-w" "--assets" "${CMAKE_SOURCE_DIR}/assets" VERBATIM USES_TERMINAL) diff --git a/apps/utilities/CMakeLists.txt b/apps/utilities/CMakeLists.txt index 200ecb21fa..78078d4a64 100644 --- a/apps/utilities/CMakeLists.txt +++ b/apps/utilities/CMakeLists.txt @@ -9,26 +9,35 @@ target_link_libraries(app_schemasetup PRIVATE lib_app_cli lib_asset lib_log) configure_debuggable(app_schemasetup) add_custom_target(run.schemasetup COMMAND app_schemasetup "--out" - "$/schemas/arraytex.schema.json" - "$/schemas/atlas.schema.json" - "$/schemas/decal.schema.json" - "$/schemas/fonttex.schema.json" - "$/schemas/graphic.schema.json" - "$/schemas/icon.schema.json" - "$/schemas/inputs.schema.json" - "$/schemas/level.schema.json" - "$/schemas/prefabs.schema.json" - "$/schemas/procmesh.schema.json" - "$/schemas/proctex.schema.json" - "$/schemas/products.schema.json" - "$/schemas/script_import_mesh_binder.json" - "$/schemas/script_import_texture_binder.json" - "$/schemas/script_scene_binder.json" - "$/schemas/terrain.schema.json" - "$/schemas/vfx.schema.json" - "$/schemas/weapons.schema.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/arraytex.schema.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/atlas.schema.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/decal.schema.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/fonttex.schema.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/graphic.schema.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/icon.schema.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/inputs.schema.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/level.schema.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/prefabs.schema.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/procmesh.schema.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/proctex.schema.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/products.schema.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/script_import_mesh_binder.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/script_import_texture_binder.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/script_scene_binder.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/terrain.schema.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/vfx.schema.json" + "${CMAKE_SOURCE_DIR}/assets/schemas/weapons.schema.json" VERBATIM USES_TERMINAL) +message(STATUS "> application: fetch") + +add_executable(app_fetch fetch.c) +target_link_libraries(app_fetch PRIVATE lib_app_cli lib_net lib_log lib_data) +configure_debuggable(app_fetch) + +add_custom_target(run.fetch COMMAND app_fetch + "${CMAKE_SOURCE_DIR}/assets/fetch.json" VERBATIM USES_TERMINAL) + message(STATUS "> application: dbgsetup") add_executable(app_dbgsetup dbgsetup.c) diff --git a/apps/utilities/fetch.c b/apps/utilities/fetch.c new file mode 100644 index 0000000000..58010e054e --- /dev/null +++ b/apps/utilities/fetch.c @@ -0,0 +1,279 @@ +#include "app_cli.h" +#include "cli_app.h" +#include "cli_help.h" +#include "cli_parse.h" +#include "cli_read.h" +#include "cli_validate.h" +#include "core_alloc.h" +#include "core_array.h" +#include "core_dynstring.h" +#include "core_file.h" +#include "core_math.h" +#include "core_path.h" +#include "core_thread.h" +#include "core_time.h" +#include "data_read.h" +#include "data_utils.h" +#include "log_logger.h" +#include "log_sink_json.h" +#include "log_sink_pretty.h" +#include "net_http.h" +#include "net_init.h" +#include "net_rest.h" +#include "net_result.h" + +/** + * Fetch - Utility to download external assets. + */ + +#define fetch_worker_count 2 + +typedef struct { + String host; + String license; + String rootUri; + String authUser, authPass; + HeapArray_t(String) assets; +} FetchOrigin; + +typedef struct { + String targetPath; + HeapArray_t(FetchOrigin) origins; +} FetchConfig; + +static DataMeta g_fetchConfigMeta; + +static void fetch_data_init(void) { + // clang-format off + data_reg_struct_t(g_dataReg, FetchOrigin); + data_reg_field_t(g_dataReg, FetchOrigin, host, data_prim_t(String), .flags = DataFlags_NotEmpty); + data_reg_field_t(g_dataReg, FetchOrigin, license, data_prim_t(String), .flags = DataFlags_Opt); + data_reg_field_t(g_dataReg, FetchOrigin, rootUri, data_prim_t(String)); + data_reg_field_t(g_dataReg, FetchOrigin, authUser, data_prim_t(String), .flags = DataFlags_Opt | DataFlags_NotEmpty); + data_reg_field_t(g_dataReg, FetchOrigin, authPass, data_prim_t(String), .flags = DataFlags_Opt | DataFlags_NotEmpty); + data_reg_field_t(g_dataReg, FetchOrigin, assets, data_prim_t(String), .container = DataContainer_HeapArray, .flags = DataFlags_NotEmpty); + + data_reg_struct_t(g_dataReg, FetchConfig); + data_reg_field_t(g_dataReg, FetchConfig, targetPath, data_prim_t(String)); + data_reg_field_t(g_dataReg, FetchConfig, origins, t_FetchOrigin, .container = DataContainer_HeapArray); + // clang-format on + + g_fetchConfigMeta = data_meta_t(t_FetchConfig); +} + +static bool fetch_config_load(const String path, FetchConfig* out) { + // Open the file handle. + bool success = false; + File* file = null; + FileResult fileRes; + if ((fileRes = file_create(g_allocScratch, path, FileMode_Open, FileAccess_Read, &file))) { + log_e("Failed to open config file", log_param("err", fmt_text(file_result_str(fileRes)))); + goto Ret; + } + + // Map the file data. + String fileData; + if (UNLIKELY(fileRes = file_map(file, &fileData, FileHints_Prefetch))) { + log_e("Failed to map config file", log_param("err", fmt_text(file_result_str(fileRes)))); + goto Ret; + } + + // Parse the json. + DataReadResult result; + const Mem outMem = mem_create(out, sizeof(FetchConfig)); + data_read_json(g_dataReg, fileData, g_allocHeap, g_fetchConfigMeta, outMem, &result); + if (UNLIKELY(result.error)) { + log_e("Failed to parse config file", log_param("err", fmt_text(result.errorMsg))); + goto Ret; + } + success = true; + +Ret: + if (file) { + file_destroy(file); + } + return success; +} + +static void fetch_config_destroy(FetchConfig* cfg) { + data_destroy(g_dataReg, g_allocHeap, g_fetchConfigMeta, mem_create(cfg, sizeof(FetchConfig))); +} + +static u32 fetch_config_max_origin_assets(FetchConfig* cfg) { + u32 res = 0; + heap_array_for_t(cfg->origins, FetchOrigin, origin) { + res = math_max(res, (u32)origin->assets.count); + } + return res; +} + +static String fetch_config_uri_scratch(const FetchOrigin* origin, const String asset) { + DynString result = dynstring_create(g_allocScratch, 256); + if (!string_starts_with(origin->rootUri, string_lit("/"))) { + dynstring_append_char(&result, '/'); + } + dynstring_append(&result, origin->rootUri); + if (!string_ends_with(dynstring_view(&result), string_lit("/"))) { + dynstring_append_char(&result, '/'); + } + if (string_starts_with(asset, string_lit("/"))) { + dynstring_append(&result, string_consume(asset, 1)); + } else { + dynstring_append(&result, asset); + } + return dynstring_view(&result); +} + +static NetHttpFlags fetch_http_flags(void) { + /** + * Enable Tls transport but do not enable certificate validation. + * This means traffic is encrypted and people cannot eavesdrop, however its trivial for someone + * to man-in-the-middle as we do not verify the server's authenticity. + * Please do not use this for security sensitive applications! + */ + return NetHttpFlags_TlsNoVerify; +} + +static i32 fetch_run_origin(NetRest* rest, const String targetPath, const FetchOrigin* origin) { + i32 retCode = 0; + + NetHttpAuth auth = {0}; + if (!string_is_empty(origin->authUser)) { + auth = (NetHttpAuth){ + .type = NetHttpAuthType_Basic, + .user = origin->authUser, + .pw = origin->authPass, + }; + } + + NetRestId* requests = alloc_array_t(g_allocHeap, NetRestId, origin->assets.count); + + // Start a GET request for all assets. + for (u32 i = 0; i != origin->assets.count; ++i) { + const String uri = fetch_config_uri_scratch(origin, origin->assets.values[i]); + requests[i] = net_rest_get(rest, origin->host, uri, &auth, null); + } + + // Save the results. + for (u32 i = 0; i != origin->assets.count; ++i) { + const NetRestId request = requests[i]; + const String asset = origin->assets.values[i]; + + // Wait for the request to be done. + while (!net_rest_done(rest, request)) { + thread_sleep(time_milliseconds(100)); + } + + // Save the asset to disk. + const NetResult result = net_rest_result(rest, request); + if (result == NetResult_Success) { + const String path = path_build_scratch(targetPath, asset); + const String data = net_rest_data(rest, request); + + FileResult saveRes = file_create_dir_sync(path_parent(path)); + if (saveRes == FileResult_Success) { + saveRes = file_write_to_path_atomic(path, data); + } + if (saveRes != FileResult_Success) { + log_e( + "Asset save failed: '{}'", + log_param("asset", fmt_text(asset)), + log_param("path", fmt_path(path)), + log_param("error", fmt_text(file_result_str(saveRes)))); + retCode = 2; + } else { + log_i( + "Asset fetched: '{}'", + log_param("asset", fmt_text(asset)), + log_param("size", fmt_size(data.size))); + } + } else { + log_e( + "Asset fetch failed: '{}'", + log_param("asset", fmt_text(asset)), + log_param("error", fmt_text(net_result_str(result)))); + retCode = 1; + } + net_rest_release(rest, request); + } + + alloc_free_array_t(g_allocHeap, requests, origin->assets.count); + return retCode; +} + +static i32 fetch_run(const String configPath) { + const TimeSteady timeStart = time_steady_clock(); + + i32 retCode = 0; + NetRest* rest = null; + FetchConfig cfg; + if (!fetch_config_load(configPath, &cfg)) { + return 1; + } + + DynString targetPath = dynstring_create(g_allocHeap, 128); + path_build(&targetPath, path_parent(configPath), cfg.targetPath); + + const u32 maxOriginAssetCount = fetch_config_max_origin_assets(&cfg); + if (!maxOriginAssetCount) { + goto Done; + } + rest = net_rest_create(g_allocHeap, fetch_worker_count, maxOriginAssetCount, fetch_http_flags()); + + heap_array_for_t(cfg.origins, FetchOrigin, origin) { + const i32 originRet = fetch_run_origin(rest, dynstring_view(&targetPath), origin); + retCode = math_max(retCode, originRet); + } + +Done:; + const TimeDuration duration = time_steady_duration(timeStart, time_steady_clock()); + if (!retCode) { + log_i("Fetch finished", log_param("duration", fmt_duration(duration))); + } else { + log_e("Fetch failed", log_param("duration", fmt_duration(duration))); + } + if (rest) { + net_rest_destroy(rest); + } + fetch_config_destroy(&cfg); + dynstring_destroy(&targetPath); + return retCode; +} + +static CliId g_optConfigPath, g_optVerbose, g_optHelp; + +void app_cli_configure(CliApp* app) { + cli_app_register_desc(app, string_lit("Fetch utility.")); + + g_optConfigPath = cli_register_arg(app, string_lit("config"), CliOptionFlags_Required); + cli_register_desc(app, g_optConfigPath, string_lit("Path to a fetch config file.")); + cli_register_validator(app, g_optConfigPath, cli_validate_file_regular); + + g_optVerbose = cli_register_flag(app, 'v', string_lit("verbose"), CliOptionFlags_None); + + g_optHelp = cli_register_flag(app, 'h', string_lit("help"), CliOptionFlags_None); + cli_register_desc(app, g_optHelp, string_lit("Display this help page.")); + cli_register_exclusions(app, g_optHelp, g_optConfigPath); + cli_register_exclusions(app, g_optHelp, g_optVerbose); +} + +i32 app_cli_run(const CliApp* app, const CliInvocation* invoc) { + i32 retCode = 0; + if (cli_parse_provided(invoc, g_optHelp)) { + cli_help_write_file(app, g_fileStdOut); + return retCode; + } + + const LogMask logMask = cli_parse_provided(invoc, g_optVerbose) ? LogMask_All : ~LogMask_Debug; + log_add_sink(g_logger, log_sink_pretty_default(g_allocHeap, logMask)); + log_add_sink(g_logger, log_sink_json_default(g_allocHeap, LogMask_All)); + + fetch_data_init(); + net_init(); + + const String configPath = cli_read_string(invoc, g_optConfigPath, string_empty); + retCode = fetch_run(configPath); + + net_teardown(); + return retCode; +} diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt deleted file mode 100644 index 455baaae57..0000000000 --- a/assets/CMakeLists.txt +++ /dev/null @@ -1,251 +0,0 @@ -# -------------------------------------------------------------------------------------------------- -# Assets cmake file. -# -------------------------------------------------------------------------------------------------- - -message(STATUS "> assets") - -if(${EXTERNAL_ASSETS}) - message(STATUS ">> Retrieving external assets, licensed seperatly: https://www.bastian.tech/assets/license.txt") - download_external_files( - PATH ${CMAKE_CURRENT_SOURCE_DIR}/external - REMOTE_URL "https://www.bastian.tech/assets" - FILES - alarm/alarm_color_rough.tga - alarm/alarm_normal_emissive.tga - alarm/alarm.bin - alarm/alarm.gltf - barracks/barracks_2_color_rough.tga - barracks/barracks_2_normal.tga - barracks/barracks_2.bin - barracks/barracks_2.gltf - barrel_explosive/barrel_explosive_color_rough.tga - barrel_explosive/barrel_explosive_normal.tga - barrel_explosive/barrel_explosive.bin - barrel_explosive/barrel_explosive.gltf - barrel/barrel_2_color_rough.tga - barrel/barrel_2_normal.tga - barrel/barrel.bin - barrel/barrel.gltf - car_wreck/car_wreck_2_normal.tga - car_wreck/car_wreck_3_color_rough.tga - car_wreck/car_wreck.bin - car_wreck/car_wreck.gltf - container/container_2_normal.tga - container/container_4_color_rough.tga - container/container.bin - container/container.gltf - crate/crate_2_color_rough.tga - crate/crate_2_normal.tga - crate/crate.bin - crate/crate.gltf - cursors/click.tga - cursors/normal.tga - cursors/resize.tga - cursors/select-add.tga - cursors/select-subtract.tga - cursors/select.tga - cursors/target.tga - cursors/text.tga - decal/blood_splatter_2_normal.tga - decal/blood_splatter_2.tga - decal/dirt.tga - decal/explosion_normal.tga - decal/explosion.tga - decal/foot_shoe_left_4_normal.tga - decal/foot_shoe_right_4_normal.tga - decal/oil_splatter_normal.tga - decal/oil_splatter.tga - decal/radioactive.tga - decal/rust.tga - decal/sand_normal.tga - decal/sand.tga - decal/scorch.tga - decal/square_alpha_trail.tga - decal/square_alpha.tga - decal/tank_track_normal.tga - decal/tarp_normal.tga - decal/tarp.tga - decal/text_volo.tga - factory/factory_2_color_rough.tga - factory/factory_2_normal.tga - factory/factory.bin - factory/factory.gltf - fence/fence_1.bin - fence/fence_1.gltf - fence/fence_2_color_rough.tga - fence/fence_2_normal.tga - fire_2/fire_0.tga - fire_2/fire_1.tga - fire_2/fire_10.tga - fire_2/fire_11.tga - fire_2/fire_12.tga - fire_2/fire_13.tga - fire_2/fire_14.tga - fire_2/fire_15.tga - fire_2/fire_2.tga - fire_2/fire_3.tga - fire_2/fire_4.tga - fire_2/fire_5.tga - fire_2/fire_6.tga - fire_2/fire_7.tga - fire_2/fire_8.tga - fire_2/fire_9.tga - floor_light/floor_light_color_rough.tga - floor_light/floor_light_mask.tga - floor_light/floor_light_normal_emissive.tga - floor_light/floor_light.bin - floor_light/floor_light.gltf - gas_tank/gas_tank_2_color_rough.tga - gas_tank/gas_tank_2_normal.tga - gas_tank/gas_tank.bin - gas_tank/gas_tank.gltf - gate/gate_1.bin - gate/gate_1.gltf - gate/gate_color_rough.tga - gate/gate_normal.tga - icon/icon_infantry_flame.tga - icon/icon_infantry_rifle.tga - icon/icon_infantry_rocket.tga - icon/icon_structure_barracks.tga - icon/icon_structure_factory.tga - icon/icon_structure_hospital.tga - icon/icon_structure_turret_gun.tga - icon/icon_structure_turret_missile.tga - icon/icon_vehicle_tank.tga - icon/icon_volo_dark_tool.tga - icon/icon_volo_dark.tga - maynard/maynard_3_color_rough.tga - maynard/maynard_3_nrm.tga - maynard/maynard_3.bin - maynard/maynard_3.gltf - plant_fern/plant_fern_alpha.tga - plant_fern/plant_fern_color_rough.tga - plant_fern/plant_fern_normal.tga - plant_fern/plant_fern.bin - plant_fern/plant_fern.gltf - pressure_plate/pressure_plate_3_color_rough.tga - pressure_plate/pressure_plate.bin - pressure_plate/pressure_plate.gltf - rock/rock_2_color_rough.tga - rock/rock_2_normal.tga - rock/rock.bin - rock/rock.gltf - skybox/teide_small_back.tga - skybox/teide_small_down.tga - skybox/teide_small_forward.tga - skybox/teide_small_left.tga - skybox/teide_small_right.tga - skybox/teide_small_up.tga - sound/alarm-01.wav - sound/ambiance-01.wav - sound/announcer-building-01.wav - sound/announcer-cancelled-01.wav - sound/announcer-location-invalid-01.wav - sound/announcer-rallypos-updated-01.wav - sound/announcer-structure-deployed-01.wav - sound/announcer-structure-ready-01.wav - sound/announcer-training-01.wav - sound/announcer-unit-ready-02.wav - sound/burning-01.wav - sound/burning-02.wav - sound/burning-03.wav - sound/click-02.wav - sound/click-03.wav - sound/confirm-01.wav - sound/confirm-02.wav - sound/confirm-03.wav - sound/confirm-04.wav - sound/death-02.wav - sound/death-03.wav - sound/death-04.wav - sound/electric-motor-01.wav - sound/explosion-01.wav - sound/explosion-02.wav - sound/explosion-03.wav - sound/gun-04.wav - sound/gun-05.wav - sound/impact-01.wav - sound/impact-02.wav - sound/indicator-01.wav - sound/indicator-02.wav - sound/launch-01.wav - sound/launch-02.wav - sound/projectile-loop-01.wav - sound/rank-up-01.wav - sound/swoosh-01.wav - sound/tank-idle-01.wav - sound/tank-move-01.wav - sound/tank-shot-01.wav - sound/tank-turret-01.wav - swat/swat_3_color_rough.tga - swat/swat_3_nrm.tga - swat/swat_4.bin - swat/swat_4.gltf - swat/swat_flame_1.bin - swat/swat_flame_1.gltf - swat/swat_flame_2_color_rough.tga - swat/swat_flame_2_nrm.tga - swat/swat_rocket_1.bin - swat/swat_rocket_1.gltf - swat/swat_rocket_2_color_rough.tga - swat/swat_rocket_2_nrm.tga - tank/tank_04.bin - tank/tank_04.gltf - tank/tank_3_color_rough.tga - tent/tent_2_color_rough.tga - tent/tent_2_normal.tga - tent/tent_medical_2_color_rough.tga - tent/tent.bin - tent/tent.gltf - terrain/terrain_3_height.r16 - terrain/terrain_3_splat.tga - tiling/clouds_2.tga - tiling/dirt_2_color_rough.tga - tiling/dirt_2_normal.tga - tiling/metal_panel_color_rough.tga - tiling/metal_panel_normal.tga - tiling/sand_2_color_rough.tga - tiling/sand_4_normal.tga - tires/tires_color_rough.tga - tires/tires_normal.tga - tires/tires.bin - tires/tires.gltf - traffic_signs/traffic_blockade.bin - traffic_signs/traffic_blockade.gltf - traffic_signs/traffic_cone.bin - traffic_signs/traffic_cone.gltf - traffic_signs/traffic_sign_stop.bin - traffic_signs/traffic_sign_stop.gltf - traffic_signs/traffic_signs_2_color_rough.tga - traffic_signs/traffic_signs_2_normal.tga - tree_acacia/tree_acacia_2_alpha.tga - tree_acacia/tree_acacia_2_normal.tga - tree_acacia/tree_acacia_3_color_rough.tga - tree_acacia/tree_acacia.bin - tree_acacia/tree_acacia.gltf - turret/turret_3_nrm.tga - turret/turret_5_color_rough.tga - turret/turret_big.gltf - turret/turret_missile_2.bin - turret/turret_missile_2.gltf - turret/turret.bin - vfx/arrow.tga - vfx/blood_splash_normal.tga - vfx/blood_splash.tga - vfx/flash_2.tga - vfx/flash_star_2.tga - vfx/grid.tga - vfx/heat_distortion_2_nrm.tga - vfx/ring_distortion_nrm.tga - vfx/rock.tga - vfx/smoke.tga - vfx/star.tga - vfx/trail_2.tga - water_tower/water_tower_2_color_rough.tga - water_tower/water_tower_2_normal.tga - water_tower/water_tower.obj - ) -endif() - -add_custom_target(volo_assets) -set_target_properties(volo_assets PROPERTIES path ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/assets/fetch.json b/assets/fetch.json new file mode 100644 index 0000000000..85c9ef7be1 --- /dev/null +++ b/assets/fetch.json @@ -0,0 +1,246 @@ +{ + "targetPath": "external", + "origins": [ + { + "host": "bastian.tech", + "license": "/assets/license.txt", + "rootUri": "/assets/", + "assets": [ + "alarm/alarm_color_rough.tga", + "alarm/alarm_normal_emissive.tga", + "alarm/alarm.bin", + "alarm/alarm.gltf", + "barracks/barracks_2_color_rough.tga", + "barracks/barracks_2_normal.tga", + "barracks/barracks_2.bin", + "barracks/barracks_2.gltf", + "barrel_explosive/barrel_explosive_color_rough.tga", + "barrel_explosive/barrel_explosive_normal.tga", + "barrel_explosive/barrel_explosive.bin", + "barrel_explosive/barrel_explosive.gltf", + "barrel/barrel_2_color_rough.tga", + "barrel/barrel_2_normal.tga", + "barrel/barrel.bin", + "barrel/barrel.gltf", + "car_wreck/car_wreck_2_normal.tga", + "car_wreck/car_wreck_3_color_rough.tga", + "car_wreck/car_wreck.bin", + "car_wreck/car_wreck.gltf", + "container/container_2_normal.tga", + "container/container_4_color_rough.tga", + "container/container.bin", + "container/container.gltf", + "crate/crate_2_color_rough.tga", + "crate/crate_2_normal.tga", + "crate/crate.bin", + "crate/crate.gltf", + "cursors/click.tga", + "cursors/normal.tga", + "cursors/resize.tga", + "cursors/select-add.tga", + "cursors/select-subtract.tga", + "cursors/select.tga", + "cursors/target.tga", + "cursors/text.tga", + "decal/blood_splatter_2_normal.tga", + "decal/blood_splatter_2.tga", + "decal/dirt.tga", + "decal/explosion_normal.tga", + "decal/explosion.tga", + "decal/foot_shoe_left_4_normal.tga", + "decal/foot_shoe_right_4_normal.tga", + "decal/oil_splatter_normal.tga", + "decal/oil_splatter.tga", + "decal/radioactive.tga", + "decal/rust.tga", + "decal/sand_normal.tga", + "decal/sand.tga", + "decal/scorch.tga", + "decal/square_alpha_trail.tga", + "decal/square_alpha.tga", + "decal/tank_track_normal.tga", + "decal/tarp_normal.tga", + "decal/tarp.tga", + "decal/text_volo.tga", + "factory/factory_2_color_rough.tga", + "factory/factory_2_normal.tga", + "factory/factory.bin", + "factory/factory.gltf", + "fence/fence_1.bin", + "fence/fence_1.gltf", + "fence/fence_2_color_rough.tga", + "fence/fence_2_normal.tga", + "fire_2/fire_0.tga", + "fire_2/fire_1.tga", + "fire_2/fire_10.tga", + "fire_2/fire_11.tga", + "fire_2/fire_12.tga", + "fire_2/fire_13.tga", + "fire_2/fire_14.tga", + "fire_2/fire_15.tga", + "fire_2/fire_2.tga", + "fire_2/fire_3.tga", + "fire_2/fire_4.tga", + "fire_2/fire_5.tga", + "fire_2/fire_6.tga", + "fire_2/fire_7.tga", + "fire_2/fire_8.tga", + "fire_2/fire_9.tga", + "floor_light/floor_light_color_rough.tga", + "floor_light/floor_light_mask.tga", + "floor_light/floor_light_normal_emissive.tga", + "floor_light/floor_light.bin", + "floor_light/floor_light.gltf", + "gas_tank/gas_tank_2_color_rough.tga", + "gas_tank/gas_tank_2_normal.tga", + "gas_tank/gas_tank.bin", + "gas_tank/gas_tank.gltf", + "gate/gate_1.bin", + "gate/gate_1.gltf", + "gate/gate_color_rough.tga", + "gate/gate_normal.tga", + "icon/icon_infantry_flame.tga", + "icon/icon_infantry_rifle.tga", + "icon/icon_infantry_rocket.tga", + "icon/icon_structure_barracks.tga", + "icon/icon_structure_factory.tga", + "icon/icon_structure_hospital.tga", + "icon/icon_structure_turret_gun.tga", + "icon/icon_structure_turret_missile.tga", + "icon/icon_vehicle_tank.tga", + "icon/icon_volo_dark_tool.tga", + "icon/icon_volo_dark.tga", + "maynard/maynard_3_color_rough.tga", + "maynard/maynard_3_nrm.tga", + "maynard/maynard_3.bin", + "maynard/maynard_3.gltf", + "plant_fern/plant_fern_alpha.tga", + "plant_fern/plant_fern_color_rough.tga", + "plant_fern/plant_fern_normal.tga", + "plant_fern/plant_fern.bin", + "plant_fern/plant_fern.gltf", + "pressure_plate/pressure_plate_3_color_rough.tga", + "pressure_plate/pressure_plate.bin", + "pressure_plate/pressure_plate.gltf", + "rock/rock_2_color_rough.tga", + "rock/rock_2_normal.tga", + "rock/rock.bin", + "rock/rock.gltf", + "skybox/teide_small_back.tga", + "skybox/teide_small_down.tga", + "skybox/teide_small_forward.tga", + "skybox/teide_small_left.tga", + "skybox/teide_small_right.tga", + "skybox/teide_small_up.tga", + "sound/alarm-01.wav", + "sound/ambiance-01.wav", + "sound/announcer-building-01.wav", + "sound/announcer-cancelled-01.wav", + "sound/announcer-location-invalid-01.wav", + "sound/announcer-rallypos-updated-01.wav", + "sound/announcer-structure-deployed-01.wav", + "sound/announcer-structure-ready-01.wav", + "sound/announcer-training-01.wav", + "sound/announcer-unit-ready-02.wav", + "sound/burning-01.wav", + "sound/burning-02.wav", + "sound/burning-03.wav", + "sound/click-02.wav", + "sound/click-03.wav", + "sound/confirm-01.wav", + "sound/confirm-02.wav", + "sound/confirm-03.wav", + "sound/confirm-04.wav", + "sound/death-02.wav", + "sound/death-03.wav", + "sound/death-04.wav", + "sound/electric-motor-01.wav", + "sound/explosion-01.wav", + "sound/explosion-02.wav", + "sound/explosion-03.wav", + "sound/gun-04.wav", + "sound/gun-05.wav", + "sound/impact-01.wav", + "sound/impact-02.wav", + "sound/indicator-01.wav", + "sound/indicator-02.wav", + "sound/launch-01.wav", + "sound/launch-02.wav", + "sound/projectile-loop-01.wav", + "sound/rank-up-01.wav", + "sound/swoosh-01.wav", + "sound/tank-idle-01.wav", + "sound/tank-move-01.wav", + "sound/tank-shot-01.wav", + "sound/tank-turret-01.wav", + "swat/swat_3_color_rough.tga", + "swat/swat_3_nrm.tga", + "swat/swat_4.bin", + "swat/swat_4.gltf", + "swat/swat_flame_1.bin", + "swat/swat_flame_1.gltf", + "swat/swat_flame_2_color_rough.tga", + "swat/swat_flame_2_nrm.tga", + "swat/swat_rocket_1.bin", + "swat/swat_rocket_1.gltf", + "swat/swat_rocket_2_color_rough.tga", + "swat/swat_rocket_2_nrm.tga", + "tank/tank_04.bin", + "tank/tank_04.gltf", + "tank/tank_3_color_rough.tga", + "tent/tent_2_color_rough.tga", + "tent/tent_2_normal.tga", + "tent/tent_medical_2_color_rough.tga", + "tent/tent.bin", + "tent/tent.gltf", + "terrain/terrain_3_height.r16", + "terrain/terrain_3_splat.tga", + "tiling/clouds_2.tga", + "tiling/dirt_2_color_rough.tga", + "tiling/dirt_2_normal.tga", + "tiling/metal_panel_color_rough.tga", + "tiling/metal_panel_normal.tga", + "tiling/sand_2_color_rough.tga", + "tiling/sand_4_normal.tga", + "tires/tires_color_rough.tga", + "tires/tires_normal.tga", + "tires/tires.bin", + "tires/tires.gltf", + "traffic_signs/traffic_blockade.bin", + "traffic_signs/traffic_blockade.gltf", + "traffic_signs/traffic_cone.bin", + "traffic_signs/traffic_cone.gltf", + "traffic_signs/traffic_sign_stop.bin", + "traffic_signs/traffic_sign_stop.gltf", + "traffic_signs/traffic_signs_2_color_rough.tga", + "traffic_signs/traffic_signs_2_normal.tga", + "tree_acacia/tree_acacia_2_alpha.tga", + "tree_acacia/tree_acacia_2_normal.tga", + "tree_acacia/tree_acacia_3_color_rough.tga", + "tree_acacia/tree_acacia.bin", + "tree_acacia/tree_acacia.gltf", + "turret/turret_3_nrm.tga", + "turret/turret_5_color_rough.tga", + "turret/turret_big.gltf", + "turret/turret_missile_2.bin", + "turret/turret_missile_2.gltf", + "turret/turret.bin", + "vfx/arrow.tga", + "vfx/blood_splash_normal.tga", + "vfx/blood_splash.tga", + "vfx/flash_2.tga", + "vfx/flash_star_2.tga", + "vfx/grid.tga", + "vfx/heat_distortion_2_nrm.tga", + "vfx/ring_distortion_nrm.tga", + "vfx/rock.tga", + "vfx/smoke.tga", + "vfx/star.tga", + "vfx/trail_2.tga", + "water_tower/water_tower_2_color_rough.tga", + "water_tower/water_tower_2_normal.tga", + "water_tower/water_tower.obj" + ] + } + ] +} diff --git a/cmake/download.cmake b/cmake/download.cmake deleted file mode 100644 index 6665165335..0000000000 --- a/cmake/download.cmake +++ /dev/null @@ -1,18 +0,0 @@ -# -------------------------------------------------------------------------------------------------- -# CMake download utilities. -# -------------------------------------------------------------------------------------------------- - -# -# Download a set of external files if they do not exist locally yet. -# NOTE: Does not do any change detection; files are only downloaded once. -# -function(download_external_files) - cmake_parse_arguments(PARSE_ARGV 0 ARG "" "PATH;REMOTE_URL" "FILES") - - foreach(file ${ARG_FILES}) - if(NOT EXISTS ${ARG_PATH}/${file}) - message(STATUS ">> Downloading: ${ARG_REMOTE_URL}/${file}") - file(DOWNLOAD "${ARG_REMOTE_URL}/${file}" ${ARG_PATH}/${file}) - endif() - endforeach() -endfunction(download_external_files) diff --git a/libs/net/src/rest.c b/libs/net/src/rest.c index 1e77bb8f01..bc0fd2ad93 100644 --- a/libs/net/src/rest.c +++ b/libs/net/src/rest.c @@ -293,7 +293,7 @@ void net_rest_destroy(NetRest* rest) { // Cleanup worker data. thread_mutex_destroy(rest->workerMutex); - thread_mutex_destroy(rest->workerWakeCondition); + thread_cond_destroy(rest->workerWakeCondition); alloc_free_array_t(rest->alloc, rest->workerThreads, rest->workerCount); // Cleanup requests.