mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-06 04:05:11 +08:00
Compare commits
224 Commits
continuous
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56ba2325c1 | ||
|
|
b77a4ed3a1 | ||
|
|
9b86c3127a | ||
|
|
0da7ffe45f | ||
|
|
30b78d9559 | ||
|
|
c16abc0b85 | ||
|
|
708c691cdb | ||
|
|
31c20ac4d8 | ||
|
|
1458014a29 | ||
|
|
1c84a5c8ad | ||
|
|
6728b843f7 | ||
|
|
1b55104d51 | ||
|
|
76978bfd47 | ||
|
|
6ff3231dab | ||
|
|
64716e6b42 | ||
|
|
a1191eb4ab | ||
|
|
166bed732e | ||
|
|
02cb12e4b4 | ||
|
|
159467ad44 | ||
|
|
2a006086c5 | ||
|
|
e0dc1eec93 | ||
|
|
ab130ee92c | ||
|
|
dabbe09918 | ||
|
|
296a7ac11d | ||
|
|
6bbf08893e | ||
|
|
f8b958738a | ||
|
|
1b4427f13f | ||
|
|
e55577fd26 | ||
|
|
c42960ec2a | ||
|
|
c033d4b65c | ||
|
|
dc6f03b4e4 | ||
|
|
b6967a432a | ||
|
|
7d0467863c | ||
|
|
a0b72d3995 | ||
|
|
5fe4b867f3 | ||
|
|
40af058406 | ||
|
|
b4376a6a8c | ||
|
|
457422c679 | ||
|
|
080eba948f | ||
|
|
eff86defd9 | ||
|
|
fcb463d400 | ||
|
|
efee8149e2 | ||
|
|
bc32f37fce | ||
|
|
58bfa247a4 | ||
|
|
59b9b31604 | ||
|
|
844af709c0 | ||
|
|
bb6e2d6885 | ||
|
|
6243dc7913 | ||
|
|
45c4362ae6 | ||
|
|
a0230b7e00 | ||
|
|
768755c31a | ||
|
|
3088c7f198 | ||
|
|
c8469071bf | ||
|
|
115fc301b5 | ||
|
|
bc449b8e95 | ||
|
|
74bbc0fe7e | ||
|
|
c73fa3d7a6 | ||
|
|
5694610478 | ||
|
|
ec107dfba5 | ||
|
|
64aa476330 | ||
|
|
42f6719e8d | ||
|
|
244b9dc02b | ||
|
|
fe3644a417 | ||
|
|
e18b61e041 | ||
|
|
d054782693 | ||
|
|
d56e53a347 | ||
|
|
3503c721ac | ||
|
|
0fab5f07d0 | ||
|
|
b0d12f8bf9 | ||
|
|
9fe58aaabc | ||
|
|
03c8ea14cc | ||
|
|
260edc2a08 | ||
|
|
b41591a527 | ||
|
|
4e9481451b | ||
|
|
95b48da37d | ||
|
|
1b36785177 | ||
|
|
8bc76e3d58 | ||
|
|
1a5e2b907d | ||
|
|
3717e5c2e0 | ||
|
|
33a1416199 | ||
|
|
ff4221fbe7 | ||
|
|
486bca82e8 | ||
|
|
611d07fc16 | ||
|
|
f7e12586cf | ||
|
|
f62aa051c8 | ||
|
|
2b6b898102 | ||
|
|
1dd0444531 | ||
|
|
ba9eb01c1f | ||
|
|
73a8144e75 | ||
|
|
6aef422de6 | ||
|
|
5f4b8b60cb | ||
|
|
3256236ba2 | ||
|
|
b102727320 | ||
|
|
3434005e66 | ||
|
|
b3026a7991 | ||
|
|
0a051832a8 | ||
|
|
2dbafbda02 | ||
|
|
240b6fb6f2 | ||
|
|
4163d3655a | ||
|
|
2c7bf49fc9 | ||
|
|
739592e50d | ||
|
|
393e31e509 | ||
|
|
a1dceacc8f | ||
|
|
cf26c87872 | ||
|
|
21195b3491 | ||
|
|
3f66f6a6a5 | ||
|
|
daae4f2f80 | ||
|
|
4e2708c1ac | ||
|
|
d57d8e0d5d | ||
|
|
9577a6af21 | ||
|
|
107a6aed01 | ||
|
|
2c2045d413 | ||
|
|
30fe471d2b | ||
|
|
5ab6979633 | ||
|
|
ec5e9cb6e3 | ||
|
|
f4b4546197 | ||
|
|
f047749e61 | ||
|
|
87840ce91d | ||
|
|
bf31e9f634 | ||
|
|
f86d84daed | ||
|
|
41ed920d35 | ||
|
|
df23ddb545 | ||
|
|
767556ccad | ||
|
|
f9dab2ad19 | ||
|
|
66cb3a6120 | ||
|
|
7672a370da | ||
|
|
870e47ed03 | ||
|
|
32d4bdb80f | ||
|
|
929dfd2c71 | ||
|
|
f437af6451 | ||
|
|
413a0fb2e5 | ||
|
|
793adadb06 | ||
|
|
999b43b89f | ||
|
|
bd60c88c7d | ||
|
|
23b9a2eddf | ||
|
|
0b57d97c8c | ||
|
|
6255293dd4 | ||
|
|
04136d95a3 | ||
|
|
40aa29e42a | ||
|
|
a709f30da9 | ||
|
|
0796c14e79 | ||
|
|
a9c0a4be23 | ||
|
|
3e1209d3a4 | ||
|
|
caf14c1b7c | ||
|
|
27f7d2c8d2 | ||
|
|
8ee430eda2 | ||
|
|
484e4cb225 | ||
|
|
b080ad9954 | ||
|
|
f6625d9188 | ||
|
|
1eb2816bc4 | ||
|
|
077be5aaf3 | ||
|
|
d59875f114 | ||
|
|
e89191ed39 | ||
|
|
ea21438637 | ||
|
|
0d2e8333e8 | ||
|
|
338399e622 | ||
|
|
27cab8aad5 | ||
|
|
1545a49b4c | ||
|
|
3ca15250e8 | ||
|
|
6cbac51731 | ||
|
|
e310c666b1 | ||
|
|
677b0170aa | ||
|
|
9150b770e4 | ||
|
|
2ad6511c31 | ||
|
|
0848f28d83 | ||
|
|
5d9bc950ce | ||
|
|
714da79395 | ||
|
|
823fe9ebbd | ||
|
|
4bf72b5383 | ||
|
|
51945f002b | ||
|
|
bcca9387de | ||
|
|
b8417fa46d | ||
|
|
85b0699288 | ||
|
|
6c03fb0226 | ||
|
|
a084dea07c | ||
|
|
2e0fc3e4c1 | ||
|
|
24f4d410ce | ||
|
|
052e0445ab | ||
|
|
758c908d5a | ||
|
|
3917c2589d | ||
|
|
f4a77308ec | ||
|
|
103b9724f9 | ||
|
|
75a315ecf0 | ||
|
|
63b3b9ef6d | ||
|
|
a6c2cfe89b | ||
|
|
5120657386 | ||
|
|
e754de46d1 | ||
|
|
5d718aa0d6 | ||
|
|
55fcbc8880 | ||
|
|
e19aa001b2 | ||
|
|
b447ea9c18 | ||
|
|
13274655d4 | ||
|
|
3723ac60ef | ||
|
|
da578f47f1 | ||
|
|
433e7de686 | ||
|
|
e18e9ae2ea | ||
|
|
27d5123a61 | ||
|
|
89b9f9ffe2 | ||
|
|
a17b8aaa13 | ||
|
|
e210969612 | ||
|
|
1208356b92 | ||
|
|
d7cd74fe2f | ||
|
|
31b63e9939 | ||
|
|
b99c2c2df1 | ||
|
|
94d3eff9ce | ||
|
|
b78e9961c6 | ||
|
|
b0704ca5d6 | ||
|
|
31c0934108 | ||
|
|
37083c8aef | ||
|
|
af23b0c67b | ||
|
|
a9e83fb9cf | ||
|
|
51126e1691 | ||
|
|
dd410a2de5 | ||
|
|
7ccb0b5c02 | ||
|
|
7f3e62e456 | ||
|
|
fcfc29d7ea | ||
|
|
2f3429a144 | ||
|
|
20782693f4 | ||
|
|
0cfb354374 | ||
|
|
9be5b7c6c9 | ||
|
|
e7653d2ea6 | ||
|
|
1494887e29 | ||
|
|
42dab2b1a5 | ||
|
|
36a0c1fb17 |
12
.cirrus.yml
12
.cirrus.yml
@@ -1,15 +1,3 @@
|
||||
task:
|
||||
name: freebsd-13-amd64
|
||||
freebsd_instance:
|
||||
image_family: freebsd-13-2
|
||||
setup_script:
|
||||
- pkg update
|
||||
- pkg install -y pkgconf git sdl2 python fontconfig opus
|
||||
- git submodule update --init --recursive
|
||||
test_script:
|
||||
- ./scripts/cirrus/build_freebsd.sh dedicated
|
||||
- ./scripts/cirrus/build_freebsd.sh full
|
||||
|
||||
task:
|
||||
name: freebsd-14-amd64
|
||||
freebsd_instance:
|
||||
|
||||
360
.editorconfig
360
.editorconfig
@@ -1,9 +1,365 @@
|
||||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
# this file is just a suggestion, you might follow it, you might not
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = latin1
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = tab
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
ij_formatter_off_tag = @formatter:off
|
||||
ij_formatter_on_tag = @formatter:on
|
||||
|
||||
[*.{c++,cc,cpp,cppm,cxx,h,h++,hh,hpp,hxx,inl,ipp,ixx,tlh,tli}]
|
||||
|
||||
# Visual C++ Formatting settings
|
||||
cpp_indent_braces = false
|
||||
cpp_indent_multi_line_relative_to = innermost_parenthesis
|
||||
cpp_indent_within_parentheses = indent
|
||||
cpp_indent_preserve_within_parentheses = true
|
||||
cpp_indent_case_contents = true
|
||||
cpp_indent_case_labels = false
|
||||
cpp_indent_case_contents_when_block = false
|
||||
cpp_indent_lambda_braces_when_parameter = true
|
||||
cpp_indent_goto_labels = one_left
|
||||
cpp_indent_preprocessor = leftmost_column
|
||||
cpp_indent_access_specifiers = false
|
||||
cpp_indent_namespace_contents = true
|
||||
cpp_indent_preserve_comments = false
|
||||
cpp_new_line_before_open_brace_namespace = new_line
|
||||
cpp_new_line_before_open_brace_type = new_line
|
||||
cpp_new_line_before_open_brace_function = new_line
|
||||
cpp_new_line_before_open_brace_block = new_line
|
||||
cpp_new_line_before_open_brace_lambda = new_line
|
||||
cpp_new_line_scope_braces_on_separate_lines = true
|
||||
cpp_new_line_close_brace_same_line_empty_type = false
|
||||
cpp_new_line_close_brace_same_line_empty_function = false
|
||||
cpp_new_line_before_catch = true
|
||||
cpp_new_line_before_else = true
|
||||
cpp_new_line_before_while_in_do_while = false
|
||||
cpp_space_before_function_open_parenthesis = remove
|
||||
cpp_space_within_parameter_list_parentheses = true
|
||||
cpp_space_between_empty_parameter_list_parentheses = true
|
||||
cpp_space_after_keywords_in_control_flow_statements = false
|
||||
cpp_space_within_control_flow_statement_parentheses = true
|
||||
cpp_space_before_lambda_open_parenthesis = false
|
||||
cpp_space_within_cast_parentheses = false
|
||||
cpp_space_after_cast_close_parenthesis = false
|
||||
cpp_space_within_expression_parentheses = true
|
||||
cpp_space_before_block_open_brace = true
|
||||
cpp_space_between_empty_braces = true
|
||||
cpp_space_before_initializer_list_open_brace = false
|
||||
cpp_space_within_initializer_list_braces = true
|
||||
cpp_space_preserve_in_initializer_list = true
|
||||
cpp_space_before_open_square_bracket = false
|
||||
cpp_space_within_square_brackets = false
|
||||
cpp_space_before_empty_square_brackets = false
|
||||
cpp_space_between_empty_square_brackets = false
|
||||
cpp_space_group_square_brackets = true
|
||||
cpp_space_within_lambda_brackets = false
|
||||
cpp_space_between_empty_lambda_brackets = false
|
||||
cpp_space_before_comma = false
|
||||
cpp_space_after_comma = true
|
||||
cpp_space_remove_around_member_operators = true
|
||||
cpp_space_before_inheritance_colon = true
|
||||
cpp_space_before_constructor_colon = true
|
||||
cpp_space_remove_before_semicolon = true
|
||||
cpp_space_after_semicolon = true
|
||||
cpp_space_remove_around_unary_operator = true
|
||||
cpp_space_around_binary_operator = insert
|
||||
cpp_space_around_assignment_operator = insert
|
||||
cpp_space_pointer_reference_alignment = right
|
||||
cpp_space_around_ternary_operator = insert
|
||||
cpp_use_unreal_engine_macro_formatting = true
|
||||
cpp_wrap_preserve_blocks = one_liners
|
||||
|
||||
# IDEA settings
|
||||
ij_c_add_brief_tag = false
|
||||
ij_c_add_getter_prefix = true
|
||||
ij_c_add_setter_prefix = true
|
||||
ij_c_align_dictionary_pair_values = false
|
||||
ij_c_align_group_field_declarations = false
|
||||
ij_c_align_init_list_in_columns = true
|
||||
ij_c_align_multiline_array_initializer_expression = false
|
||||
ij_c_align_multiline_assignment = false
|
||||
ij_c_align_multiline_binary_operation = false
|
||||
ij_c_align_multiline_chained_methods = false
|
||||
ij_c_align_multiline_for = true
|
||||
ij_c_align_multiline_ternary_operation = false
|
||||
ij_c_array_initializer_comma_on_next_line = false
|
||||
ij_c_array_initializer_new_line_after_left_brace = false
|
||||
ij_c_array_initializer_right_brace_on_new_line = false
|
||||
ij_c_array_initializer_wrap = off
|
||||
ij_c_assignment_wrap = off
|
||||
ij_c_binary_operation_sign_on_next_line = false
|
||||
ij_c_binary_operation_wrap = off
|
||||
ij_c_blank_lines_after_class_header = 0
|
||||
ij_c_blank_lines_after_imports = 1
|
||||
ij_c_blank_lines_around_class = 1
|
||||
ij_c_blank_lines_around_field = 0
|
||||
ij_c_blank_lines_around_field_in_interface = 0
|
||||
ij_c_blank_lines_around_method = 1
|
||||
ij_c_blank_lines_around_method_in_interface = 1
|
||||
ij_c_blank_lines_around_namespace = 0
|
||||
ij_c_blank_lines_around_properties_in_declaration = 0
|
||||
ij_c_blank_lines_around_properties_in_interface = 0
|
||||
ij_c_blank_lines_before_imports = 1
|
||||
ij_c_blank_lines_before_method_body = 0
|
||||
ij_c_block_brace_placement = next_line
|
||||
ij_c_block_brace_style = next_line
|
||||
ij_c_block_comment_at_first_column = true
|
||||
ij_c_catch_on_new_line = false
|
||||
ij_c_class_brace_style = next_line
|
||||
ij_c_class_constructor_init_list_align_multiline = true
|
||||
ij_c_class_constructor_init_list_comma_on_next_line = false
|
||||
ij_c_class_constructor_init_list_new_line_after_colon = never
|
||||
ij_c_class_constructor_init_list_new_line_before_colon = if_long
|
||||
ij_c_class_constructor_init_list_wrap = normal
|
||||
ij_c_copy_is_deep = false
|
||||
ij_c_create_interface_for_categories = true
|
||||
ij_c_declare_generated_methods = true
|
||||
ij_c_description_include_member_names = true
|
||||
ij_c_discharged_short_ternary_operator = false
|
||||
ij_c_do_not_add_breaks = false
|
||||
ij_c_do_while_brace_force = never
|
||||
ij_c_else_on_new_line = false
|
||||
ij_c_enum_constants_comma_on_next_line = false
|
||||
ij_c_enum_constants_wrap = off
|
||||
ij_c_for_brace_force = never
|
||||
ij_c_for_statement_new_line_after_left_paren = false
|
||||
ij_c_for_statement_right_paren_on_new_line = false
|
||||
ij_c_for_statement_wrap = off
|
||||
ij_c_function_brace_placement = next_line
|
||||
ij_c_function_call_arguments_align_multiline = true
|
||||
ij_c_function_call_arguments_align_multiline_pars = false
|
||||
ij_c_function_call_arguments_comma_on_next_line = false
|
||||
ij_c_function_call_arguments_new_line_after_lpar = false
|
||||
ij_c_function_call_arguments_new_line_before_rpar = false
|
||||
ij_c_function_call_arguments_wrap = normal
|
||||
ij_c_function_non_top_after_return_type_wrap = normal
|
||||
ij_c_function_parameters_align_multiline = true
|
||||
ij_c_function_parameters_align_multiline_pars = false
|
||||
ij_c_function_parameters_comma_on_next_line = false
|
||||
ij_c_function_parameters_new_line_after_lpar = false
|
||||
ij_c_function_parameters_new_line_before_rpar = false
|
||||
ij_c_function_parameters_wrap = normal
|
||||
ij_c_function_top_after_return_type_wrap = normal
|
||||
ij_c_generate_additional_eq_operators = true
|
||||
ij_c_generate_additional_rel_operators = true
|
||||
ij_c_generate_class_constructor = true
|
||||
ij_c_generate_comparison_operators_use_std_tie = false
|
||||
ij_c_generate_instance_variables_for_properties = ask
|
||||
ij_c_generate_operators_as_members = true
|
||||
ij_c_header_guard_style_pattern = ${PROJECT_NAME}_${FILE_NAME}_${EXT}
|
||||
ij_c_if_brace_force = never
|
||||
ij_c_in_line_short_ternary_operator = true
|
||||
ij_c_indent_block_comment = true
|
||||
ij_c_indent_c_struct_members = 4
|
||||
ij_c_indent_case_from_switch = true
|
||||
ij_c_indent_class_members = 4
|
||||
ij_c_indent_directive_as_code = false
|
||||
ij_c_indent_implementation_members = 0
|
||||
ij_c_indent_inside_code_block = 4
|
||||
ij_c_indent_interface_members = 0
|
||||
ij_c_indent_interface_members_except_ivars_block = false
|
||||
ij_c_indent_namespace_members = 4
|
||||
ij_c_indent_preprocessor_directive = 0
|
||||
ij_c_indent_visibility_keywords = 0
|
||||
ij_c_insert_override = true
|
||||
ij_c_insert_virtual_with_override = false
|
||||
ij_c_introduce_auto_consts = false
|
||||
ij_c_introduce_auto_vars = false
|
||||
ij_c_introduce_const_params = false
|
||||
ij_c_introduce_const_vars = false
|
||||
ij_c_introduce_constexpr_consts = false
|
||||
ij_c_introduce_generate_property = false
|
||||
ij_c_introduce_generate_synthesize = true
|
||||
ij_c_introduce_globals_to_header = true
|
||||
ij_c_introduce_prop_to_private_category = false
|
||||
ij_c_introduce_static_consts = true
|
||||
ij_c_introduce_use_ns_types = false
|
||||
ij_c_ivars_prefix = _
|
||||
ij_c_ivars_suffix =
|
||||
ij_c_keep_blank_lines_before_end = 2
|
||||
ij_c_keep_blank_lines_before_right_brace = 2
|
||||
ij_c_keep_blank_lines_in_code = 2
|
||||
ij_c_keep_blank_lines_in_declarations = 2
|
||||
ij_c_keep_case_expressions_in_one_line = false
|
||||
ij_c_keep_control_statement_in_one_line = false
|
||||
ij_c_keep_directive_at_first_column = true
|
||||
ij_c_keep_first_column_comment = false
|
||||
ij_c_keep_line_breaks = true
|
||||
ij_c_keep_nested_namespaces_in_one_line = false
|
||||
ij_c_keep_simple_blocks_in_one_line = false
|
||||
ij_c_keep_simple_methods_in_one_line = false
|
||||
ij_c_keep_structures_in_one_line = false
|
||||
ij_c_lambda_capture_list_align_multiline = false
|
||||
ij_c_lambda_capture_list_align_multiline_bracket = false
|
||||
ij_c_lambda_capture_list_comma_on_next_line = false
|
||||
ij_c_lambda_capture_list_new_line_after_lbracket = false
|
||||
ij_c_lambda_capture_list_new_line_before_rbracket = false
|
||||
ij_c_lambda_capture_list_wrap = off
|
||||
ij_c_line_comment_add_space = false
|
||||
ij_c_line_comment_at_first_column = true
|
||||
ij_c_method_brace_placement = end_of_line
|
||||
ij_c_method_call_arguments_align_by_colons = true
|
||||
ij_c_method_call_arguments_align_multiline = false
|
||||
ij_c_method_call_arguments_special_dictionary_pairs_treatment = true
|
||||
ij_c_method_call_arguments_wrap = off
|
||||
ij_c_method_call_chain_wrap = off
|
||||
ij_c_method_parameters_align_by_colons = true
|
||||
ij_c_method_parameters_align_multiline = false
|
||||
ij_c_method_parameters_wrap = off
|
||||
ij_c_namespace_brace_placement = next_line
|
||||
ij_c_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_c_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_c_place_assignment_sign_on_next_line = false
|
||||
ij_c_property_nonatomic = true
|
||||
ij_c_put_ivars_to_implementation = true
|
||||
ij_c_refactor_compatibility_aliases_and_classes = true
|
||||
ij_c_refactor_properties_and_ivars = true
|
||||
ij_c_release_style = ivar
|
||||
ij_c_retain_object_parameters_in_constructor = true
|
||||
ij_c_semicolon_after_method_signature = false
|
||||
ij_c_shift_operation_align_multiline = true
|
||||
ij_c_shift_operation_wrap = normal
|
||||
ij_c_show_non_virtual_functions = false
|
||||
ij_c_space_after_colon = true
|
||||
ij_c_space_after_colon_in_foreach = true
|
||||
ij_c_space_after_colon_in_selector = false
|
||||
ij_c_space_after_comma = true
|
||||
ij_c_space_after_cup_in_blocks = false
|
||||
ij_c_space_after_dictionary_literal_colon = true
|
||||
ij_c_space_after_for_semicolon = true
|
||||
ij_c_space_after_init_list_colon = true
|
||||
ij_c_space_after_method_parameter_type_parentheses = false
|
||||
ij_c_space_after_method_return_type_parentheses = false
|
||||
ij_c_space_after_pointer_in_declaration = false
|
||||
ij_c_space_after_quest = true
|
||||
ij_c_space_after_reference_in_declaration = false
|
||||
ij_c_space_after_reference_in_rvalue = false
|
||||
ij_c_space_after_structures_rbrace = true
|
||||
ij_c_space_after_superclass_colon = true
|
||||
ij_c_space_after_type_cast = false
|
||||
ij_c_space_after_visibility_sign_in_method_declaration = true
|
||||
ij_c_space_before_autorelease_pool_lbrace = true
|
||||
ij_c_space_before_catch_keyword = true
|
||||
ij_c_space_before_catch_left_brace = true
|
||||
ij_c_space_before_catch_parentheses = false
|
||||
ij_c_space_before_category_parentheses = true
|
||||
ij_c_space_before_chained_send_message = true
|
||||
ij_c_space_before_class_left_brace = true
|
||||
ij_c_space_before_colon = true
|
||||
ij_c_space_before_colon_in_foreach = true
|
||||
ij_c_space_before_comma = false
|
||||
ij_c_space_before_dictionary_literal_colon = true
|
||||
ij_c_space_before_do_left_brace = true
|
||||
ij_c_space_before_else_keyword = true
|
||||
ij_c_space_before_else_left_brace = true
|
||||
ij_c_space_before_export_lbrace = true
|
||||
ij_c_space_before_for_left_brace = true
|
||||
ij_c_space_before_for_parentheses = false
|
||||
ij_c_space_before_for_semicolon = false
|
||||
ij_c_space_before_if_left_brace = true
|
||||
ij_c_space_before_if_parentheses = false
|
||||
ij_c_space_before_init_list = false
|
||||
ij_c_space_before_init_list_colon = true
|
||||
ij_c_space_before_method_call_parentheses = false
|
||||
ij_c_space_before_method_left_brace = true
|
||||
ij_c_space_before_method_parentheses = false
|
||||
ij_c_space_before_namespace_lbrace = true
|
||||
ij_c_space_before_pointer_in_declaration = true
|
||||
ij_c_space_before_property_attributes_parentheses = false
|
||||
ij_c_space_before_protocols_brackets = true
|
||||
ij_c_space_before_quest = true
|
||||
ij_c_space_before_reference_in_declaration = true
|
||||
ij_c_space_before_superclass_colon = true
|
||||
ij_c_space_before_switch_left_brace = true
|
||||
ij_c_space_before_switch_parentheses = false
|
||||
ij_c_space_before_template_call_lt = false
|
||||
ij_c_space_before_template_declaration_lt = true
|
||||
ij_c_space_before_try_left_brace = true
|
||||
ij_c_space_before_while_keyword = true
|
||||
ij_c_space_before_while_left_brace = true
|
||||
ij_c_space_before_while_parentheses = false
|
||||
ij_c_space_between_adjacent_brackets = false
|
||||
ij_c_space_between_operator_and_punctuator = false
|
||||
ij_c_space_within_empty_array_initializer_braces = true
|
||||
ij_c_spaces_around_additive_operators = true
|
||||
ij_c_spaces_around_assignment_operators = true
|
||||
ij_c_spaces_around_bitwise_operators = true
|
||||
ij_c_spaces_around_equality_operators = true
|
||||
ij_c_spaces_around_lambda_arrow = true
|
||||
ij_c_spaces_around_logical_operators = true
|
||||
ij_c_spaces_around_multiplicative_operators = true
|
||||
ij_c_spaces_around_pm_operators = false
|
||||
ij_c_spaces_around_relational_operators = true
|
||||
ij_c_spaces_around_shift_operators = true
|
||||
ij_c_spaces_around_unary_operator = false
|
||||
ij_c_spaces_within_array_initializer_braces = true
|
||||
ij_c_spaces_within_braces = false
|
||||
ij_c_spaces_within_brackets = false
|
||||
ij_c_spaces_within_cast_parentheses = false
|
||||
ij_c_spaces_within_catch_parentheses = true
|
||||
ij_c_spaces_within_category_parentheses = false
|
||||
ij_c_spaces_within_empty_braces = false
|
||||
ij_c_spaces_within_empty_function_call_parentheses = true
|
||||
ij_c_spaces_within_empty_function_declaration_parentheses = true
|
||||
ij_c_spaces_within_empty_lambda_capture_list_bracket = false
|
||||
ij_c_spaces_within_empty_template_call_ltgt = false
|
||||
ij_c_spaces_within_empty_template_declaration_ltgt = false
|
||||
ij_c_spaces_within_for_parentheses = true
|
||||
ij_c_spaces_within_function_call_parentheses = true
|
||||
ij_c_spaces_within_function_declaration_parentheses = true
|
||||
ij_c_spaces_within_if_parentheses = true
|
||||
ij_c_spaces_within_lambda_capture_list_bracket = false
|
||||
ij_c_spaces_within_method_parameter_type_parentheses = false
|
||||
ij_c_spaces_within_method_return_type_parentheses = false
|
||||
ij_c_spaces_within_parentheses = true
|
||||
ij_c_spaces_within_property_attributes_parentheses = false
|
||||
ij_c_spaces_within_protocols_brackets = false
|
||||
ij_c_spaces_within_send_message_brackets = false
|
||||
ij_c_spaces_within_structured_binding_list_bracket = false
|
||||
ij_c_spaces_within_switch_parentheses = true
|
||||
ij_c_spaces_within_template_call_ltgt = false
|
||||
ij_c_spaces_within_template_declaration_ltgt = false
|
||||
ij_c_spaces_within_template_double_gt = false
|
||||
ij_c_spaces_within_while_parentheses = true
|
||||
ij_c_special_else_if_treatment = true
|
||||
ij_c_structured_binding_list_align_multiline = false
|
||||
ij_c_structured_binding_list_align_multiline_bracket = false
|
||||
ij_c_structured_binding_list_comma_on_next_line = false
|
||||
ij_c_structured_binding_list_new_line_after_lbracket = false
|
||||
ij_c_structured_binding_list_new_line_before_rbracket = false
|
||||
ij_c_structured_binding_list_wrap = off
|
||||
ij_c_superclass_list_after_colon = never
|
||||
ij_c_superclass_list_align_multiline = true
|
||||
ij_c_superclass_list_before_colon = if_long
|
||||
ij_c_superclass_list_comma_on_next_line = false
|
||||
ij_c_superclass_list_wrap = on_every_item
|
||||
ij_c_tag_prefix_of_block_comment = at
|
||||
ij_c_tag_prefix_of_line_comment = back_slash
|
||||
ij_c_template_call_arguments_align_multiline = false
|
||||
ij_c_template_call_arguments_align_multiline_pars = false
|
||||
ij_c_template_call_arguments_comma_on_next_line = false
|
||||
ij_c_template_call_arguments_new_line_after_lt = false
|
||||
ij_c_template_call_arguments_new_line_before_gt = false
|
||||
ij_c_template_call_arguments_wrap = off
|
||||
ij_c_template_declaration_function_body_indent = false
|
||||
ij_c_template_declaration_function_wrap = split_into_lines
|
||||
ij_c_template_declaration_struct_body_indent = false
|
||||
ij_c_template_declaration_struct_wrap = split_into_lines
|
||||
ij_c_template_parameters_align_multiline = false
|
||||
ij_c_template_parameters_align_multiline_pars = false
|
||||
ij_c_template_parameters_comma_on_next_line = false
|
||||
ij_c_template_parameters_new_line_after_lt = false
|
||||
ij_c_template_parameters_new_line_before_gt = false
|
||||
ij_c_template_parameters_wrap = off
|
||||
ij_c_ternary_operation_signs_on_next_line = false
|
||||
ij_c_ternary_operation_wrap = off
|
||||
ij_c_type_qualifiers_placement = before
|
||||
ij_c_use_modern_casts = true
|
||||
ij_c_use_setters_in_constructor = true
|
||||
ij_c_while_brace_force = never
|
||||
ij_c_while_on_new_line = false
|
||||
ij_c_wrap_property_declaration = off
|
||||
|
||||
2
.github/workflows/c-cpp.yml
vendored
2
.github/workflows/c-cpp.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
||||
targetos: win32
|
||||
targetarch: i386
|
||||
env:
|
||||
SDL_VERSION: 2.28.5
|
||||
SDL_VERSION: 2.30.3
|
||||
GH_CPU_ARCH: ${{ matrix.targetarch }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
2
3rdparty/mainui
vendored
2
3rdparty/mainui
vendored
Submodule 3rdparty/mainui updated: f5497ceb04...f0c11b141f
2
3rdparty/vgui_support
vendored
2
3rdparty/vgui_support
vendored
Submodule 3rdparty/vgui_support updated: a2a7b9073f...7276993f3f
@@ -13,3 +13,4 @@ When `-bugcomp` is specified with argument, it interpreted as flags separated wi
|
||||
| Flag | Description | Games that require this flag |
|
||||
| ------- | ----------- | ---------------------------- |
|
||||
| `peoei` | Reverts `pfnPEntityOfEntIndex` behavior to GoldSrc, where it returns NULL for last player due to incorrect player index comparison | * Counter-Strike: Condition Zero - Deleted Scenes |
|
||||
| `gsmrf` | Rewrites message at the moment when Game DLL attempts to write an internal engine message, usually specific to GoldSrc protocol. Right now only supports `svc_spawnstaticsound`, more messages added by request. | * MetaMod/AMXModX based mods |
|
||||
|
||||
40
Documentation/hd-textures.md
Normal file
40
Documentation/hd-textures.md
Normal file
@@ -0,0 +1,40 @@
|
||||
### HD (external) textures support
|
||||
|
||||
Xash3D supports loading texture replacements in TGA format for almost all types of models in the game, except alias models at this time.
|
||||
|
||||
Textures are expected to be located at:
|
||||
* `modfolder/materials/<mapname>` - for a specific map
|
||||
* `modfolder/materials/common` - common for all maps
|
||||
* `modfolder/materials/decals` - for decals
|
||||
* `modfolder/materials/models/<model>` - for models (texture name must match the internal texture name in the model)
|
||||
|
||||
Support for high-resolution textures is enabled setting `host_allow_materials` cvar to `1` or in the menu, in "Video options" section.
|
||||
|
||||
#### Xash3D FWGS additions
|
||||
|
||||
In addition to paths above, Xash3D FWGS checks following paths:
|
||||
|
||||
* `modfolder/materials/sprites/<sprite>` - for sprites, except HUD sprites
|
||||
|
||||
Also, to check which texture replacements are loaded successfully, failed or weren't found, a mod developer can set `host_allow_materials` cvar value to `2`. The engine will spew log at any developer level in the following format:
|
||||
|
||||
```
|
||||
Looking for <replacement> replacement... <status code> (<path relative to mod directory>)
|
||||
```
|
||||
|
||||
Status codes:
|
||||
* `OK` - texture replacement file was found and loaded into GPU memory successfully
|
||||
* `FAIL` - texture file was found but hasn't been parsed or loaded successfully. Refer to engine log for more details.
|
||||
* `MISS` - texture file wasn't found
|
||||
|
||||
Example:
|
||||
```
|
||||
Looking for maps/bounce.bsp:!waterblue tex replacement...OK (materials/common/!waterblue.tga)
|
||||
Looking for maps/bounce.bsp:!waterblue_luma tex replacement...MISS (not found)
|
||||
Looking for {shot2 decal replacement...MISS (materials/decals/{shot2.tga)
|
||||
Looking for {shot4 decal replacement...MISS (materials/decals/{shot4.tga)
|
||||
Looking for {shot3 decal replacement...MISS (materials/decals/{shot3.tga)
|
||||
Looking for models/gman tex replacement...FAIL (materials/models/gman/GMan_Case1.tga)
|
||||
Looking for models/gman tex replacement...FAIL (materials/models/gman/inside_1.tga)
|
||||
```
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
boneinfo.h - structure that send delta-compressed bones across network
|
||||
Copyright (C) 2018 Uncle Mike
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef BONEINFO_H
|
||||
#define BONEINFO_H
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t angles;
|
||||
vec3_t origin;
|
||||
} boneinfo_t;
|
||||
|
||||
#endif//BONEINFO_H
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
features.h - engine features that can be enabled by mod-maker request
|
||||
enginefeatures.h - engine features that can be enabled by mod-maker request
|
||||
Copyright (C) 2012 Uncle Mike
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -27,6 +27,7 @@ GNU General Public License for more details.
|
||||
#define ENGINE_COMPUTE_STUDIO_LERP (1<<7) // enable MOVETYPE_STEP lerping back in engine
|
||||
#define ENGINE_LINEAR_GAMMA_SPACE (1<<8) // disable influence of gamma/brightness cvars to textures/lightmaps, for mods with custom renderer
|
||||
|
||||
#define ENGINE_DISABLE_HDTEXTURES (1U<<30) // disable support of HD-textures in case custom renderer have separate way to load them
|
||||
#define ENGINE_STEP_POSHISTORY_LERP (1U<<31) // enable MOVETYPE_STEP interpolation based on position history. Incompatible with ENGINE_COMPUTE_STUDIO_LERP!
|
||||
|
||||
// adjust the mask when features will be added or removed
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
// Set this flag for things like broadcast requests, etc. where the engine should not
|
||||
// kill the request hook after receiving the first response
|
||||
#define FNETAPI_MULTIPLE_RESPONSE ( 1<<0 )
|
||||
#define FNETAPI_LEGACY_PROTOCOL ( 1<<1 ) // xash3d-fwgs extension
|
||||
|
||||
struct net_response_s;
|
||||
typedef void (*net_api_response_func_t) ( struct net_response_s *response );
|
||||
@@ -35,6 +36,7 @@ typedef void (*net_api_response_func_t) ( struct net_response_s *response );
|
||||
#define NET_ERROR_TIMEOUT ( 1<<0 )
|
||||
#define NET_ERROR_PROTO_UNSUPPORTED ( 1<<1 )
|
||||
#define NET_ERROR_UNDEFINED ( 1<<2 )
|
||||
#define NET_ERROR_FORBIDDEN ( 1<<3 ) // xash3d-fwgs extension
|
||||
|
||||
typedef struct net_adrlist_s
|
||||
{
|
||||
|
||||
@@ -70,48 +70,50 @@ typedef uint64_t longtime_t;
|
||||
#define IsColorString( p ) ( p && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' )
|
||||
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#ifdef __i386__
|
||||
#define EXPORT __attribute__ ((visibility ("default"),force_align_arg_pointer))
|
||||
#define GAME_EXPORT __attribute((force_align_arg_pointer))
|
||||
#if defined( __GNUC__ )
|
||||
#if defined( __i386__ )
|
||||
#define EXPORT __attribute__(( visibility( "default" ), force_align_arg_pointer ))
|
||||
#define GAME_EXPORT __attribute(( force_align_arg_pointer ))
|
||||
#else
|
||||
#define EXPORT __attribute__ ((visibility ("default")))
|
||||
#define EXPORT __attribute__(( visibility ( "default" )))
|
||||
#define GAME_EXPORT
|
||||
#endif
|
||||
#define _format(x) __attribute__((format(printf, x, x+1)))
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
#define NONNULL __attribute__((nonnull))
|
||||
#define ALLOC_CHECK(x) __attribute__((alloc_size(x)))
|
||||
#elif defined(_MSC_VER)
|
||||
#define EXPORT __declspec( dllexport )
|
||||
#define GAME_EXPORT
|
||||
#define _format(x)
|
||||
#define NORETURN
|
||||
#define NONNULL
|
||||
#define ALLOC_CHECK(x)
|
||||
|
||||
#define NORETURN __attribute__(( noreturn ))
|
||||
#define NONNULL __attribute__(( nonnull ))
|
||||
#define _format( x ) __attribute__(( format( printf, x, x + 1 )))
|
||||
#define ALLOC_CHECK( x ) __attribute__(( alloc_size( x )))
|
||||
#define NO_ASAN __attribute__(( no_sanitize( "address" )))
|
||||
#define RENAME_SYMBOL( x ) asm( x )
|
||||
#else
|
||||
#define EXPORT
|
||||
#if defined( _MSC_VER )
|
||||
#define EXPORT __declspec( dllexport )
|
||||
#define NO_ASAN __declspec( no_sanitize_address )
|
||||
#else
|
||||
#define EXPORT
|
||||
#define NO_ASAN
|
||||
#endif
|
||||
#define GAME_EXPORT
|
||||
#define _format(x)
|
||||
#define NORETURN
|
||||
#define NONNULL
|
||||
#define ALLOC_CHECK(x)
|
||||
#define _format( x )
|
||||
#define ALLOC_CHECK( x )
|
||||
#define RENAME_SYMBOL( x )
|
||||
#endif
|
||||
|
||||
#if ( __GNUC__ >= 3 )
|
||||
#define unlikely(x) __builtin_expect(x, 0)
|
||||
#define likely(x) __builtin_expect(x, 1)
|
||||
#if __GNUC__ >= 3
|
||||
#define unlikely( x ) __builtin_expect( x, 0 )
|
||||
#define likely( x ) __builtin_expect( x, 1 )
|
||||
#elif defined( __has_builtin )
|
||||
#if __has_builtin( __builtin_expect )
|
||||
#define unlikely(x) __builtin_expect(x, 0)
|
||||
#define likely(x) __builtin_expect(x, 1)
|
||||
#else
|
||||
#define unlikely(x) (x)
|
||||
#define likely(x) (x)
|
||||
#if __has_builtin( __builtin_expect ) // this must be after defined() check
|
||||
#define unlikely( x ) __builtin_expect( x, 0 )
|
||||
#define likely( x ) __builtin_expect( x, 1 )
|
||||
#endif
|
||||
#else
|
||||
#define unlikely(x) (x)
|
||||
#define likely(x) (x)
|
||||
#endif
|
||||
|
||||
#if !defined( unlikely ) || !defined( likely )
|
||||
#define unlikely( x ) ( x )
|
||||
#define likely( x ) ( x )
|
||||
#endif
|
||||
|
||||
#if __STDC_VERSION__ >= 202311L || __cplusplus >= 201103L // C23 or C++ static_assert is a keyword
|
||||
@@ -128,6 +130,14 @@ typedef uint64_t longtime_t;
|
||||
#define STATIC_ASSERT( x, y ) STATIC_ASSERT_2( __LINE__, x, y )
|
||||
#endif
|
||||
|
||||
#if !defined( __cplusplus ) && __STDC_VERSION__ >= 199101L // not C++ and C99 or newer
|
||||
#define XASH_RESTRICT restrict
|
||||
#elif _MSC_VER || __GNUC__ || __clang__ // compiler-specific extensions
|
||||
#define XASH_RESTRICT __restrict
|
||||
#else
|
||||
#define XASH_RESTRICT // nothing
|
||||
#endif
|
||||
|
||||
#ifdef XASH_BIG_ENDIAN
|
||||
#define LittleLong(x) (((int)(((x)&255)<<24)) + ((int)((((x)>>8)&255)<<16)) + ((int)(((x)>>16)&255)<<8) + (((x) >> 24)&255))
|
||||
#define LittleLongSW(x) (x = LittleLong(x) )
|
||||
@@ -158,8 +168,9 @@ _inline float LittleFloat( float f )
|
||||
#endif
|
||||
|
||||
|
||||
typedef unsigned int dword;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned int dword;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
typedef char string[MAX_STRING];
|
||||
typedef struct file_s file_t; // normal file
|
||||
typedef struct stream_s stream_t; // sound stream for background music playing
|
||||
|
||||
@@ -349,7 +349,7 @@ void CL_SetSky_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
ref.dllFuncs.R_SetupSky( Cmd_Argv( 1 ));
|
||||
R_SetupSky( Cmd_Argv( 1 ));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -70,16 +70,17 @@ qboolean CL_CheckFile( sizebuf_t *msg, resource_t *pResource )
|
||||
return true;
|
||||
}
|
||||
|
||||
if( cl.downloadUrl[0] )
|
||||
host.downloadcount++;
|
||||
|
||||
if( cl.http_download )
|
||||
{
|
||||
HTTP_AddDownload( filepath, pResource->nDownloadSize, true );
|
||||
host.downloadcount++;
|
||||
return false;
|
||||
}
|
||||
|
||||
MSG_BeginClientCmd( msg, clc_stringcmd );
|
||||
MSG_WriteStringf( msg, "dlfile %s", filepath );
|
||||
host.downloadcount++;
|
||||
else
|
||||
{
|
||||
MSG_BeginClientCmd( msg, clc_stringcmd );
|
||||
MSG_WriteStringf( msg, "dlfile %s", filepath );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -104,7 +105,7 @@ void CL_AddToResourceList( resource_t *pResource, resource_t *pList )
|
||||
void CL_RemoveFromResourceList( resource_t *pResource )
|
||||
{
|
||||
if( pResource->pPrev == NULL || pResource->pNext == NULL )
|
||||
Host_Error( "mislinked resource in CL_RemoveFromResourceList\n" );
|
||||
Host_Error( "mislinked resource in %s\n", __func__ );
|
||||
|
||||
if( pResource->pNext == pResource || pResource->pPrev == pResource )
|
||||
Host_Error( "attempt to free last entry in list.\n" );
|
||||
@@ -119,7 +120,7 @@ void CL_MoveToOnHandList( resource_t *pResource )
|
||||
{
|
||||
if( !pResource )
|
||||
{
|
||||
Con_Reportf( "Null resource passed to CL_MoveToOnHandList\n" );
|
||||
Con_Reportf( "Null resource passed to %s\n", __func__ );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,9 +52,23 @@ const char *CL_MsgInfo( int cmd )
|
||||
// get engine message name
|
||||
const char *svc_string = NULL;
|
||||
|
||||
if( cls.legacymode )
|
||||
switch( cls.legacymode )
|
||||
{
|
||||
case PROTO_CURRENT:
|
||||
svc_string = svc_strings[cmd];
|
||||
break;
|
||||
case PROTO_LEGACY:
|
||||
svc_string = svc_legacy_strings[cmd];
|
||||
break;
|
||||
case PROTO_QUAKE:
|
||||
svc_string = svc_quake_strings[cmd];
|
||||
break;
|
||||
case PROTO_GOLDSRC:
|
||||
svc_string = svc_goldsrc_strings[cmd];
|
||||
break;
|
||||
}
|
||||
|
||||
// fall back to current protocol strings
|
||||
if( !svc_string )
|
||||
svc_string = svc_strings[cmd];
|
||||
|
||||
|
||||
@@ -109,6 +109,40 @@ struct
|
||||
|
||||
static qboolean CL_NextDemo( void );
|
||||
|
||||
static int CL_GetDemoNetProtocol( connprotocol_t proto )
|
||||
{
|
||||
switch( proto )
|
||||
{
|
||||
case PROTO_CURRENT:
|
||||
return PROTOCOL_VERSION;
|
||||
case PROTO_LEGACY:
|
||||
return PROTOCOL_LEGACY_VERSION;
|
||||
case PROTO_QUAKE:
|
||||
return PROTOCOL_VERSION_QUAKE;
|
||||
case PROTO_GOLDSRC:
|
||||
return PROTOCOL_GOLDSRC_VERSION;
|
||||
}
|
||||
|
||||
return PROTOCOL_VERSION;
|
||||
}
|
||||
|
||||
static connprotocol_t CL_GetProtocolFromDemo( int net_protocol )
|
||||
{
|
||||
switch( net_protocol )
|
||||
{
|
||||
case PROTOCOL_VERSION:
|
||||
return PROTO_CURRENT;
|
||||
case PROTOCOL_LEGACY_VERSION:
|
||||
return PROTO_LEGACY;
|
||||
case PROTOCOL_VERSION_QUAKE:
|
||||
return PROTO_QUAKE;
|
||||
case PROTOCOL_GOLDSRC_VERSION:
|
||||
return PROTO_GOLDSRC;
|
||||
}
|
||||
|
||||
return PROTO_CURRENT;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_StartupDemoHeader
|
||||
@@ -119,12 +153,8 @@ we record a demo on this level
|
||||
*/
|
||||
void CL_StartupDemoHeader( void )
|
||||
{
|
||||
if( cls.demoheader )
|
||||
{
|
||||
FS_Close( cls.demoheader );
|
||||
}
|
||||
CL_CloseDemoHeader();
|
||||
|
||||
// Note: this is replacing tmpfile()
|
||||
cls.demoheader = FS_Open( "demoheader.tmp", "w+b", true );
|
||||
|
||||
if( !cls.demoheader )
|
||||
@@ -373,7 +403,7 @@ static void CL_WriteDemoHeader( const char *name )
|
||||
|
||||
demo.header.id = IDEMOHEADER;
|
||||
demo.header.dem_protocol = DEMO_PROTOCOL;
|
||||
demo.header.net_protocol = cls.legacymode ? PROTOCOL_LEGACY_VERSION : PROTOCOL_VERSION;
|
||||
demo.header.net_protocol = CL_GetDemoNetProtocol( cls.legacymode );
|
||||
demo.header.host_fps = host_maxfps.value ? bound( MIN_FPS, host_maxfps.value, MAX_FPS ) : MAX_FPS;
|
||||
Q_strncpy( demo.header.mapname, clgame.mapname, sizeof( demo.header.mapname ));
|
||||
Q_strncpy( demo.header.comment, clgame.maptitle, sizeof( demo.header.comment ));
|
||||
@@ -393,6 +423,7 @@ static void CL_WriteDemoHeader( const char *name )
|
||||
|
||||
// finish off the startup info.
|
||||
CL_WriteDemoCmdHeader( dem_stop, cls.demoheader );
|
||||
FS_Flush( cls.demoheader );
|
||||
|
||||
// now copy the stuff we cached from the server.
|
||||
copysize = savepos = FS_Tell( cls.demoheader );
|
||||
@@ -1489,6 +1520,7 @@ void CL_PlayDemo_f( void )
|
||||
}
|
||||
|
||||
if( neg ) cls.forcetrack = -cls.forcetrack;
|
||||
cls.legacymode = PROTO_QUAKE;
|
||||
CL_DemoStartPlayback( DEMO_QUAKE1 );
|
||||
return; // quake demo is started
|
||||
}
|
||||
@@ -1544,9 +1576,11 @@ void CL_PlayDemo_f( void )
|
||||
|
||||
CL_DemoStartPlayback( DEMO_XASH3D );
|
||||
|
||||
// must be after DemoStartPlayback, as CL_Disconnect_f resets the protocol
|
||||
cls.legacymode = CL_GetProtocolFromDemo( demo.header.net_protocol );
|
||||
|
||||
// g-cont. is this need?
|
||||
Q_strncpy( cls.servername, demoname, sizeof( cls.servername ));
|
||||
cls.legacymode = demo.header.net_protocol == PROTOCOL_LEGACY_VERSION;
|
||||
|
||||
// begin a playback demo
|
||||
}
|
||||
@@ -1588,7 +1622,7 @@ void CL_StartDemos_f( void )
|
||||
c = Cmd_Argc() - 1;
|
||||
if( c > MAX_DEMOS )
|
||||
{
|
||||
Con_DPrintf( S_WARN "Host_StartDemos: max %i demos in demoloop\n", MAX_DEMOS );
|
||||
Con_DPrintf( S_WARN "%s: max %i demos in demoloop\n", __func__, MAX_DEMOS );
|
||||
c = MAX_DEMOS;
|
||||
}
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ void CL_RegisterEvent( int lastnum, const char *szEvName, pfnEventHook func )
|
||||
ev = clgame.events[lastnum];
|
||||
|
||||
// NOTE: ev->index will be set later
|
||||
Q_strncpy( ev->name, szEvName, MAX_QPATH );
|
||||
Q_strncpy( ev->name, szEvName, sizeof( ev->name ));
|
||||
ev->func = func;
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ static qboolean CL_FireEvent( event_info_t *ei, int slot )
|
||||
if( !ev )
|
||||
{
|
||||
idx = bound( 1, ei->index, ( MAX_EVENTS - 1 ));
|
||||
Con_Reportf( S_ERROR "CL_FireEvent: %s not precached\n", cl.event_precache[idx] );
|
||||
Con_Reportf( S_ERROR "%s: %s not precached\n", __func__, cl.event_precache[idx] );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -244,7 +244,7 @@ static qboolean CL_FireEvent( event_info_t *ei, int slot )
|
||||
return true;
|
||||
}
|
||||
|
||||
Con_Reportf( S_ERROR "CL_FireEvent: %s not hooked\n", name );
|
||||
Con_Reportf( S_ERROR "%s: %s not hooked\n", __func__, name );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -497,14 +497,14 @@ void GAME_EXPORT CL_PlaybackEvent( int flags, const edict_t *pInvoker, word even
|
||||
// first check event for out of bounds
|
||||
if( eventindex < 1 || eventindex >= MAX_EVENTS )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "CL_PlaybackEvent: invalid eventindex %i\n", eventindex );
|
||||
Con_DPrintf( S_ERROR "%s: invalid eventindex %i\n", __func__, eventindex );
|
||||
return;
|
||||
}
|
||||
|
||||
// check event for precached
|
||||
if( !CL_EventIndex( cl.event_precache[eventindex] ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "CL_PlaybackEvent: event %i was not precached\n", eventindex );
|
||||
Con_DPrintf( S_ERROR "%s: event %i was not precached\n", __func__, eventindex );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -712,7 +712,7 @@ static void CL_FlushEntityPacket( sizebuf_t *msg )
|
||||
break; // done
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
Host_Error( "CL_FlushEntityPacket: overflow\n" );
|
||||
Host_Error( "%s: overflow\n", __func__ );
|
||||
|
||||
MSG_ReadDeltaEntity( msg, &from, &to, newnum, CL_IsPlayerIndex( newnum ) ? DELTA_PLAYER : DELTA_ENTITY, cl.mtime[0] );
|
||||
}
|
||||
@@ -740,7 +740,7 @@ static void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_s
|
||||
|
||||
if(( newnum < 0 ) || ( newnum >= clgame.maxEntities ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "CL_DeltaEntity: invalid newnum: %d\n", newnum );
|
||||
Con_DPrintf( S_ERROR "%s: invalid newnum: %d\n", __func__, newnum );
|
||||
if( has_update )
|
||||
MSG_ReadDeltaEntity( msg, old, state, newnum, delta_type, cl.mtime[0] );
|
||||
return;
|
||||
@@ -885,7 +885,7 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta )
|
||||
break; // done
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
Host_Error( "CL_ParsePacketEntities: overflow\n" );
|
||||
Host_Error( "%s: overflow\n", __func__ );
|
||||
|
||||
player = CL_IsPlayerIndex( newnum );
|
||||
|
||||
@@ -955,7 +955,7 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta )
|
||||
}
|
||||
|
||||
if( newframe->num_entities != count && newframe->num_entities != 0 )
|
||||
Con_Reportf( S_WARN "CL_Parse%sPacketEntities: (%i should be %i)\n", delta ? "Delta" : "", newframe->num_entities, count );
|
||||
Con_Reportf( S_WARN "%s%s: (%i should be %i)\n", __func__, delta ? "Delta" : "", newframe->num_entities, count );
|
||||
|
||||
if( !newframe->valid )
|
||||
return playerbytes; // frame is not valid but message was parsed
|
||||
@@ -1187,7 +1187,7 @@ static void CL_LinkPacketEntities( frame_t *frame )
|
||||
|
||||
if( !ent )
|
||||
{
|
||||
Con_Reportf( S_ERROR "CL_LinkPacketEntity: bad entity %i\n", state->number );
|
||||
Con_Reportf( S_ERROR "%s: bad entity %i\n", __func__, state->number );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@ static void CL_InitCDAudio( const char *filename )
|
||||
|
||||
if( ++c > MAX_CDTRACKS - 1 )
|
||||
{
|
||||
Con_Reportf( S_WARN "CD_Init: too many tracks %i in %s\n", MAX_CDTRACKS, filename );
|
||||
Con_Reportf( S_WARN "%s: too many tracks %i in %s\n", __func__, MAX_CDTRACKS, filename );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -777,14 +777,14 @@ static const char *CL_SoundFromIndex( int index )
|
||||
|
||||
if( !hSound )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "CL_SoundFromIndex: invalid sound index %i\n", index );
|
||||
Con_DPrintf( S_ERROR "%s: invalid sound index %i\n", __func__, index );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sfx = S_GetSfxByHandle( hSound );
|
||||
if( !sfx )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "CL_SoundFromIndex: bad sfx for index %i\n", index );
|
||||
Con_DPrintf( S_ERROR "%s: bad sfx for index %i\n", __func__, index );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1041,10 +1041,10 @@ void CL_LinkUserMessage( char *pszName, const int svc_num, int iSize )
|
||||
int i;
|
||||
|
||||
if( !pszName || !*pszName )
|
||||
Host_Error( "CL_LinkUserMessage: bad message name\n" );
|
||||
Host_Error( "%s: bad message name\n", __func__ );
|
||||
|
||||
if( svc_num <= svc_lastmsg )
|
||||
Host_Error( "CL_LinkUserMessage: tried to hook a system message \"%s\"\n", svc_strings[svc_num] );
|
||||
Host_Error( "%s: tried to hook a system message \"%s\"\n", __func__, svc_strings[svc_num] );
|
||||
|
||||
// see if already hooked
|
||||
for( i = 0; i < MAX_USER_MESSAGES && clgame.msg[i].name[0]; i++ )
|
||||
@@ -1061,7 +1061,7 @@ void CL_LinkUserMessage( char *pszName, const int svc_num, int iSize )
|
||||
|
||||
if( i == MAX_USER_MESSAGES )
|
||||
{
|
||||
Host_Error( "CL_LinkUserMessage: MAX_USER_MESSAGES hit!\n" );
|
||||
Host_Error( "%s: MAX_USER_MESSAGES hit!\n", __func__ );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1242,7 +1242,7 @@ static model_t *CL_LoadSpriteModel( const char *filename, uint type, uint texFla
|
||||
|
||||
if( !COM_CheckString( filename ))
|
||||
{
|
||||
Con_Reportf( S_ERROR "CL_LoadSpriteModel: bad name!\n" );
|
||||
Con_Reportf( S_ERROR "%s: bad name!\n", __func__ );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1503,12 +1503,12 @@ static void GAME_EXPORT pfnSPR_DrawAdditive( int frame, int x, int y, const wrec
|
||||
|
||||
/*
|
||||
=========
|
||||
pfnSPR_GetList
|
||||
SPR_GetList
|
||||
|
||||
for parsing half-life scripts - hud.txt etc
|
||||
=========
|
||||
*/
|
||||
static client_sprite_t *pfnSPR_GetList( char *psz, int *piCount )
|
||||
static client_sprite_t *SPR_GetList( char *psz, int *piCount )
|
||||
{
|
||||
cached_spritelist_t *pEntry = &clgame.sprlist[0];
|
||||
int slot, index, numSprites = 0;
|
||||
@@ -1534,7 +1534,7 @@ static client_sprite_t *pfnSPR_GetList( char *psz, int *piCount )
|
||||
|
||||
if( slot == MAX_CLIENT_SPRITES )
|
||||
{
|
||||
Con_Printf( S_ERROR "SPR_GetList: overflow cache!\n" );
|
||||
Con_Printf( S_ERROR "%s: overflow cache!\n", __func__ );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1743,7 +1743,7 @@ static int GAME_EXPORT pfnHookUserMsg( const char *pszName, pfnUserMsgHook pfn )
|
||||
|
||||
if( i == MAX_USER_MESSAGES )
|
||||
{
|
||||
Host_Error( "HookUserMsg: MAX_USER_MESSAGES hit!\n" );
|
||||
Host_Error( "%s: MAX_USER_MESSAGES hit!\n", __func__ );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2293,7 +2293,7 @@ static void GAME_EXPORT pfnHookEvent( const char *filename, pfnEventHook pfn )
|
||||
|
||||
if( !Q_stricmp( name, ev->name ) && ev->func != NULL )
|
||||
{
|
||||
Con_Reportf( S_WARN "CL_HookEvent: %s already hooked!\n", name );
|
||||
Con_Reportf( S_WARN "%s: %s already hooked!\n", __func__, name );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2376,7 +2376,7 @@ static int GAME_EXPORT CL_FindModelIndex( const char *m )
|
||||
if( lasttimewarn < host.realtime )
|
||||
{
|
||||
// tell user about problem (but don't spam console)
|
||||
Con_Printf( S_ERROR "Could not find index for model %s: not precached\n", filepath );
|
||||
Con_DPrintf( S_ERROR "Could not find index for model %s: not precached\n", filepath );
|
||||
lasttimewarn = host.realtime + 1.0f;
|
||||
}
|
||||
|
||||
@@ -2788,10 +2788,10 @@ static void GAME_EXPORT PlayerInfo_SetValueForKey( const char *key, const char *
|
||||
{
|
||||
Cvar_DirectSet( var, value );
|
||||
}
|
||||
else if( Info_SetValueForStarKey( cls.userinfo, key, value, MAX_INFO_STRING ))
|
||||
else if( Info_SetValueForStarKey( cls.userinfo, key, value, sizeof( cls.userinfo )))
|
||||
{
|
||||
// time to update server copy of userinfo
|
||||
CL_ServerCommand( true, "setinfo \"%s\" \"%s\"\n", key, value );
|
||||
CL_UpdateInfo( key, value );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3420,11 +3420,11 @@ static void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags,
|
||||
|
||||
if( !response )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Net_SendRequest: no callbcak specified for request with context %i!\n", context );
|
||||
Con_DPrintf( S_ERROR "%s: no callbcak specified for request with context %i!\n", __func__, context );
|
||||
return;
|
||||
}
|
||||
|
||||
if( remote_address->type != NA_IPX && remote_address->type != NA_BROADCAST_IPX )
|
||||
if( remote_address->type == NA_IPX || remote_address->type == NA_BROADCAST_IPX )
|
||||
return; // IPX no longer support
|
||||
|
||||
if( request == NETAPI_REQUEST_SERVERLIST )
|
||||
@@ -3467,7 +3467,7 @@ static void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags,
|
||||
nr->flags = flags;
|
||||
|
||||
// local servers request
|
||||
Q_snprintf( req, sizeof( req ), "netinfo %i %i %i", PROTOCOL_VERSION, context, request );
|
||||
Q_snprintf( req, sizeof( req ), "netinfo %i %i %i", FBitSet( flags, FNETAPI_LEGACY_PROTOCOL ) ? PROTOCOL_LEGACY_VERSION : PROTOCOL_VERSION, context, request );
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, nr->resp.remote_address, "%s", req );
|
||||
}
|
||||
|
||||
@@ -3772,7 +3772,7 @@ static demo_api_t gDemoApi =
|
||||
Demo_WriteBuffer,
|
||||
};
|
||||
|
||||
static net_api_t gNetApi =
|
||||
net_api_t gNetApi =
|
||||
{
|
||||
NetAPI_InitNetworking,
|
||||
NetAPI_Status,
|
||||
@@ -3808,7 +3808,7 @@ static cl_enginefunc_t gEngfuncs =
|
||||
pfnSPR_DrawAdditive,
|
||||
SPR_EnableScissor,
|
||||
SPR_DisableScissor,
|
||||
pfnSPR_GetList,
|
||||
SPR_GetList,
|
||||
CL_FillRGBA,
|
||||
CL_GetScreenInfo,
|
||||
pfnSetCrosshair,
|
||||
@@ -4030,14 +4030,14 @@ qboolean CL_LoadProgs( const char *name )
|
||||
// trying to get single export
|
||||
if(( GetClientAPI = (void *)COM_GetProcAddress( clgame.hInstance, "GetClientAPI" )) != NULL )
|
||||
{
|
||||
Con_Reportf( "CL_LoadProgs: found single callback export\n" );
|
||||
Con_Reportf( "%s: found single callback export\n", __func__ );
|
||||
|
||||
// trying to fill interface now
|
||||
GetClientAPI( &clgame.dllFuncs );
|
||||
}
|
||||
else if(( GetClientAPI = (void *)COM_GetProcAddress( clgame.hInstance, "F" )) != NULL )
|
||||
{
|
||||
Con_Reportf( "CL_LoadProgs: found single callback export (secured client dlls)\n" );
|
||||
Con_Reportf( "%s: found single callback export (secured client dlls)\n", __func__ );
|
||||
|
||||
// trying to fill interface now
|
||||
CL_GetSecuredClientAPI( GetClientAPI );
|
||||
@@ -4065,7 +4065,7 @@ qboolean CL_LoadProgs( const char *name )
|
||||
// functions are cleared before all the extensions are evaluated
|
||||
if(( *func->func = (void *)COM_GetProcAddress( clgame.hInstance, func->name )) == NULL )
|
||||
{
|
||||
Con_Reportf( "CL_LoadProgs: failed to get address of %s proc\n", func->name );
|
||||
Con_Reportf( "%s: failed to get address of %s proc\n", __func__, func->name );
|
||||
|
||||
if( critical_exports )
|
||||
{
|
||||
@@ -4092,13 +4092,13 @@ qboolean CL_LoadProgs( const char *name )
|
||||
// functions are cleared before all the extensions are evaluated
|
||||
// NOTE: new exports can be missed without stop the engine
|
||||
if(( *func->func = (void *)COM_GetProcAddress( clgame.hInstance, func->name )) == NULL )
|
||||
Con_Reportf( "CL_LoadProgs: failed to get address of %s proc\n", func->name );
|
||||
Con_Reportf( "%s: failed to get address of %s proc\n", __func__, func->name );
|
||||
}
|
||||
|
||||
if( !clgame.dllFuncs.pfnInitialize( &gEngfuncs, CLDLL_INTERFACE_VERSION ))
|
||||
{
|
||||
COM_FreeLibrary( clgame.hInstance );
|
||||
Con_Reportf( "CL_LoadProgs: can't init client API\n" );
|
||||
Con_Reportf( "%s: can't init client API\n", __func__ );
|
||||
clgame.hInstance = NULL;
|
||||
return false;
|
||||
}
|
||||
@@ -4115,10 +4115,10 @@ qboolean CL_LoadProgs( const char *name )
|
||||
CL_InitTempEnts ();
|
||||
|
||||
if( !R_InitRenderAPI()) // Xash3D extension
|
||||
Con_Reportf( S_WARN "CL_LoadProgs: couldn't get render API\n" );
|
||||
Con_Reportf( S_WARN "%s: couldn't get render API\n", __func__ );
|
||||
|
||||
if( !Mobile_Init() ) // Xash3D FWGS extension: mobile interface
|
||||
Con_Reportf( S_WARN "CL_LoadProgs: couldn't get mobility API\n" );
|
||||
Con_Reportf( S_WARN "%s: couldn't get mobility API\n", __func__ );
|
||||
|
||||
CL_InitEdicts( cl.maxclients ); // initailize local player and world
|
||||
CL_InitClientMove(); // initialize pm_shared
|
||||
|
||||
@@ -216,12 +216,14 @@ UI_ShowConnectionWarning
|
||||
show message box
|
||||
=================
|
||||
*/
|
||||
void UI_ShowMessageBox( const char *text )
|
||||
qboolean UI_ShowMessageBox( const char *text )
|
||||
{
|
||||
if( gameui.dllFuncs2.pfnShowMessageBox )
|
||||
{
|
||||
gameui.dllFuncs2.pfnShowMessageBox( text );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void UI_ConnectionProgress_Disconnect( void )
|
||||
@@ -492,7 +494,7 @@ static HIMAGE GAME_EXPORT pfnPIC_Load( const char *szPicName, const byte *image_
|
||||
|
||||
if( !COM_CheckString( szPicName ))
|
||||
{
|
||||
Con_Reportf( S_ERROR "CL_LoadImage: refusing to load image with empty name\n" );
|
||||
Con_Reportf( S_ERROR "%s: refusing to load image with empty name\n", __func__ );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1011,7 +1013,7 @@ pfnChangeInstance
|
||||
*/
|
||||
static void GAME_EXPORT pfnChangeInstance( const char *newInstance, const char *szFinalMessage )
|
||||
{
|
||||
Con_Reportf( S_ERROR "ChangeInstance menu call is deprecated!\n" );
|
||||
Con_Reportf( S_ERROR "%s menu call is deprecated!\n", __func__ );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1097,6 +1099,20 @@ static void GAME_EXPORT pfnCon_DefaultColor( int r, int g, int b )
|
||||
Con_DefaultColor( r, g, b, true );
|
||||
}
|
||||
|
||||
static void GAME_EXPORT pfnSetCursor( void *hCursor )
|
||||
{
|
||||
uintptr_t cursor;
|
||||
|
||||
if( !gameui.use_extended_api )
|
||||
return; // ignore original Xash menus
|
||||
|
||||
cursor = (uintptr_t)hCursor;
|
||||
if( cursor < dc_user || cursor > dc_last )
|
||||
return;
|
||||
|
||||
Platform_SetCursorType( cursor );
|
||||
}
|
||||
|
||||
// engine callbacks
|
||||
static ui_enginefuncs_t gEngfuncs =
|
||||
{
|
||||
@@ -1176,7 +1192,7 @@ static ui_enginefuncs_t gEngfuncs =
|
||||
pfnHostEndGame,
|
||||
COM_RandomFloat,
|
||||
COM_RandomLong,
|
||||
IN_SetCursor,
|
||||
pfnSetCursor,
|
||||
pfnIsMapValid,
|
||||
GL_ProcessTexture,
|
||||
COM_CompareFileTime,
|
||||
@@ -1221,6 +1237,7 @@ static ui_extendedfuncs_t gExtendedfuncs =
|
||||
NET_AdrToString,
|
||||
NET_CompareAdrSort,
|
||||
Sys_GetNativeObject,
|
||||
&gNetApi,
|
||||
};
|
||||
|
||||
void UI_UnloadProgs( void )
|
||||
@@ -1280,13 +1297,13 @@ qboolean UI_LoadProgs( void )
|
||||
if(( GetMenuAPI = (MENUAPI)COM_GetProcAddress( gameui.hInstance, "GetMenuAPI" )) == NULL )
|
||||
{
|
||||
COM_FreeLibrary( gameui.hInstance );
|
||||
Con_Reportf( "UI_LoadProgs: can't init menu API\n" );
|
||||
Con_Reportf( "%s: can't init menu API\n", __func__ );
|
||||
gameui.hInstance = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
gameui.use_text_api = false;
|
||||
gameui.use_extended_api = false;
|
||||
|
||||
// make local copy of engfuncs to prevent overwrite it with user dll
|
||||
memcpy( &gpEngfuncs, &gEngfuncs, sizeof( gpEngfuncs ));
|
||||
@@ -1296,7 +1313,7 @@ qboolean UI_LoadProgs( void )
|
||||
if( !GetMenuAPI( &gameui.dllFuncs, &gpEngfuncs, gameui.globals ))
|
||||
{
|
||||
COM_FreeLibrary( gameui.hInstance );
|
||||
Con_Reportf( "UI_LoadProgs: can't init menu API\n" );
|
||||
Con_Reportf( "%s: can't init menu API\n", __func__ );
|
||||
Mem_FreePool( &gameui.mempool );
|
||||
gameui.hInstance = NULL;
|
||||
return false;
|
||||
@@ -1309,30 +1326,30 @@ qboolean UI_LoadProgs( void )
|
||||
// try to initialize new extended API
|
||||
if( ( GetExtAPI = (UIEXTENEDEDAPI)COM_GetProcAddress( gameui.hInstance, "GetExtAPI" ) ) )
|
||||
{
|
||||
Con_Reportf( "UI_LoadProgs: extended Menu API found\n" );
|
||||
Con_Reportf( "%s: extended Menu API found\n", __func__ );
|
||||
if( GetExtAPI( MENU_EXTENDED_API_VERSION, &gameui.dllFuncs2, &gpExtendedfuncs ) )
|
||||
{
|
||||
Con_Reportf( "UI_LoadProgs: extended Menu API initialized\n" );
|
||||
gameui.use_text_api = true;
|
||||
Con_Reportf( "%s: extended Menu API initialized\n", __func__ );
|
||||
gameui.use_extended_api = true;
|
||||
}
|
||||
}
|
||||
else // otherwise, fallback to old and deprecated extensions
|
||||
{
|
||||
if( ( GiveTextApi = (UITEXTAPI)COM_GetProcAddress( gameui.hInstance, "GiveTextAPI" ) ) )
|
||||
{
|
||||
Con_Reportf( "UI_LoadProgs: extended text API found\n" );
|
||||
Con_Reportf( "%s: extended text API found\n", __func__ );
|
||||
Con_Reportf( S_WARN "Text API is deprecated! If you are mod developer, consider moving to Extended Menu API!\n" );
|
||||
if( GiveTextApi( &gpExtendedfuncs ) ) // they are binary compatible, so we can just pass extended funcs API to menu
|
||||
{
|
||||
Con_Reportf( "UI_LoadProgs: extended text API initialized\n" );
|
||||
gameui.use_text_api = true;
|
||||
Con_Reportf( "%s: extended text API initialized\n", __func__ );
|
||||
gameui.use_extended_api = true;
|
||||
}
|
||||
}
|
||||
|
||||
gameui.dllFuncs2.pfnAddTouchButtonToList = (ADDTOUCHBUTTONTOLIST)COM_GetProcAddress( gameui.hInstance, "AddTouchButtonToList" );
|
||||
if( gameui.dllFuncs2.pfnAddTouchButtonToList )
|
||||
{
|
||||
Con_Reportf( "UI_LoadProgs: AddTouchButtonToList call found\n" );
|
||||
Con_Reportf( "%s: AddTouchButtonToList call found\n", __func__ );
|
||||
Con_Reportf( S_WARN "AddTouchButtonToList is deprecated! If you are mod developer, consider moving to Extended Menu API!\n" );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,15 +31,16 @@ GNU General Public License for more details.
|
||||
#define CL_TEST_RETRIES 5
|
||||
|
||||
CVAR_DEFINE_AUTO( mp_decals, "300", FCVAR_ARCHIVE, "decals limit in multiplayer" );
|
||||
CVAR_DEFINE_AUTO( dev_overview, "0", 0, "draw level in overview-mode" );
|
||||
CVAR_DEFINE_AUTO( cl_resend, "6.0", 0, "time to resend connect" );
|
||||
static CVAR_DEFINE_AUTO( dev_overview, "0", 0, "draw level in overview-mode" );
|
||||
static CVAR_DEFINE_AUTO( cl_resend, "6.0", 0, "time to resend connect" );
|
||||
CVAR_DEFINE( cl_allow_download, "cl_allowdownload", "1", FCVAR_ARCHIVE, "allow to downloading resources from the server" );
|
||||
CVAR_DEFINE_AUTO( cl_allow_upload, "1", FCVAR_ARCHIVE, "allow to uploading resources to the server" );
|
||||
static CVAR_DEFINE( cl_allow_upload, "cl_allowupload", "1", FCVAR_ARCHIVE, "allow to uploading resources to the server" );
|
||||
CVAR_DEFINE_AUTO( cl_download_ingame, "1", FCVAR_ARCHIVE, "allow to downloading resources while client is active" );
|
||||
CVAR_DEFINE_AUTO( cl_logofile, "lambda", FCVAR_ARCHIVE, "player logo name" );
|
||||
CVAR_DEFINE_AUTO( cl_logocolor, "orange", FCVAR_ARCHIVE, "player logo color" );
|
||||
CVAR_DEFINE_AUTO( cl_logoext, "bmp", FCVAR_ARCHIVE, "temporary cvar to tell engine which logo must be packed" );
|
||||
CVAR_DEFINE_AUTO( cl_test_bandwidth, "1", FCVAR_ARCHIVE, "test network bandwith before connection" );
|
||||
static CVAR_DEFINE_AUTO( cl_logofile, "lambda", FCVAR_ARCHIVE, "player logo name" );
|
||||
static CVAR_DEFINE_AUTO( cl_logocolor, "orange", FCVAR_ARCHIVE, "player logo color" );
|
||||
static CVAR_DEFINE_AUTO( cl_logoext, "bmp", FCVAR_ARCHIVE, "temporary cvar to tell engine which logo must be packed" );
|
||||
CVAR_DEFINE_AUTO( cl_logomaxdim, "96", FCVAR_ARCHIVE, "maximum decal dimension" );
|
||||
static CVAR_DEFINE_AUTO( cl_test_bandwidth, "1", FCVAR_ARCHIVE, "test network bandwith before connection" );
|
||||
|
||||
CVAR_DEFINE( cl_draw_particles, "r_drawparticles", "1", FCVAR_CHEAT, "render particles" );
|
||||
CVAR_DEFINE( cl_draw_tracers, "r_drawtracers", "1", FCVAR_CHEAT, "render tracers" );
|
||||
@@ -48,17 +49,17 @@ CVAR_DEFINE( cl_draw_beams, "r_drawbeams", "1", FCVAR_CHEAT, "render beams" );
|
||||
static CVAR_DEFINE_AUTO( rcon_address, "", FCVAR_PRIVILEGED, "remote control address" );
|
||||
CVAR_DEFINE_AUTO( cl_timeout, "60", 0, "connect timeout (in-seconds)" );
|
||||
CVAR_DEFINE_AUTO( cl_nopred, "0", FCVAR_ARCHIVE|FCVAR_USERINFO, "disable client movement prediction" );
|
||||
CVAR_DEFINE_AUTO( cl_nodelta, "0", 0, "disable delta-compression for server messages" );
|
||||
static CVAR_DEFINE_AUTO( cl_nodelta, "0", 0, "disable delta-compression for server messages" );
|
||||
CVAR_DEFINE( cl_crosshair, "crosshair", "1", FCVAR_ARCHIVE, "show weapon chrosshair" );
|
||||
static CVAR_DEFINE_AUTO( cl_cmdbackup, "10", FCVAR_ARCHIVE, "how many additional history commands are sent" );
|
||||
CVAR_DEFINE_AUTO( cl_showerror, "0", FCVAR_ARCHIVE, "show prediction error" );
|
||||
CVAR_DEFINE_AUTO( cl_bmodelinterp, "1", FCVAR_ARCHIVE, "enable bmodel interpolation" );
|
||||
CVAR_DEFINE_AUTO( cl_lightstyle_lerping, "0", FCVAR_ARCHIVE, "enables animated light lerping (perfomance option)" );
|
||||
static CVAR_DEFINE_AUTO( cl_lightstyle_lerping, "0", FCVAR_ARCHIVE, "enables animated light lerping (perfomance option)" );
|
||||
CVAR_DEFINE_AUTO( cl_idealpitchscale, "0.8", 0, "how much to look up/down slopes and stairs when not using freelook" );
|
||||
CVAR_DEFINE_AUTO( cl_nosmooth, "0", FCVAR_ARCHIVE, "disable smooth up stair climbing" );
|
||||
CVAR_DEFINE_AUTO( cl_smoothtime, "0.1", FCVAR_ARCHIVE, "time to smooth up" );
|
||||
CVAR_DEFINE_AUTO( cl_clockreset, "0.1", FCVAR_ARCHIVE, "frametime delta maximum value before reset" );
|
||||
CVAR_DEFINE_AUTO( cl_fixtimerate, "7.5", FCVAR_ARCHIVE, "time in msec to client clock adjusting" );
|
||||
static CVAR_DEFINE_AUTO( cl_fixtimerate, "7.5", FCVAR_ARCHIVE, "time in msec to client clock adjusting" );
|
||||
CVAR_DEFINE_AUTO( hud_fontscale, "1.0", FCVAR_ARCHIVE|FCVAR_LATCH, "scale hud font texture" );
|
||||
CVAR_DEFINE_AUTO( hud_fontrender, "0", FCVAR_ARCHIVE, "hud font render mode (0: additive, 1: holes, 2: trans)" );
|
||||
CVAR_DEFINE_AUTO( hud_scale, "0", FCVAR_ARCHIVE|FCVAR_LATCH, "scale hud at current resolution" );
|
||||
@@ -68,7 +69,7 @@ CVAR_DEFINE_AUTO( cl_updaterate, "20", FCVAR_USERINFO|FCVAR_ARCHIVE, "refresh ra
|
||||
CVAR_DEFINE_AUTO( cl_showevents, "0", FCVAR_ARCHIVE, "show events playback" );
|
||||
CVAR_DEFINE_AUTO( cl_cmdrate, "60", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" );
|
||||
CVAR_DEFINE( cl_interp, "ex_interp", "0.1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "Interpolate object positions starting this many seconds in past" );
|
||||
CVAR_DEFINE_AUTO( cl_nointerp, "0", FCVAR_CLIENTDLL, "disable interpolation of entities and players" );
|
||||
CVAR_DEFINE_AUTO( cl_nointerp, "0", 0, "disable interpolation of entities and players" );
|
||||
static CVAR_DEFINE_AUTO( cl_dlmax, "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "max allowed outcoming fragment size" );
|
||||
static CVAR_DEFINE_AUTO( cl_upmax, "1200", FCVAR_ARCHIVE, "max allowed incoming fragment size" );
|
||||
|
||||
@@ -115,17 +116,12 @@ qboolean CL_IsInGame( void )
|
||||
if( host.type == HOST_DEDICATED )
|
||||
return true; // always active for dedicated servers
|
||||
|
||||
if( cl.background || CL_GetMaxClients() > 1 )
|
||||
if( cl.background || cl.maxclients > 1 )
|
||||
return true; // always active for multiplayer or background map
|
||||
|
||||
return ( cls.key_dest == key_game ); // active if not menu or console
|
||||
}
|
||||
|
||||
qboolean CL_IsInMenu( void )
|
||||
{
|
||||
return ( cls.key_dest == key_menu );
|
||||
}
|
||||
|
||||
qboolean CL_IsInConsole( void )
|
||||
{
|
||||
return ( cls.key_dest == key_console );
|
||||
@@ -222,7 +218,7 @@ An svc_signonnum has been received, perform a client side setup
|
||||
void CL_SignonReply( void )
|
||||
{
|
||||
// g-cont. my favorite message :-)
|
||||
Con_Reportf( "CL_SignonReply: %i\n", cls.signon );
|
||||
Con_Reportf( "%s: %i\n", __func__, cls.signon );
|
||||
|
||||
switch( cls.signon )
|
||||
{
|
||||
@@ -587,21 +583,38 @@ CL_CreateCmd
|
||||
*/
|
||||
static void CL_CreateCmd( void )
|
||||
{
|
||||
usercmd_t nullcmd, *cmd;
|
||||
runcmd_t *pcmd;
|
||||
vec3_t angles;
|
||||
qboolean active;
|
||||
int input_override;
|
||||
int i, ms;
|
||||
usercmd_t nullcmd, *cmd;
|
||||
runcmd_t *pcmd;
|
||||
qboolean active;
|
||||
double accurate_ms;
|
||||
vec3_t angles;
|
||||
int input_override;
|
||||
int i, ms;
|
||||
|
||||
if( cls.state < ca_connected || cls.state == ca_cinematic )
|
||||
return;
|
||||
|
||||
// store viewangles in case it's will be freeze
|
||||
VectorCopy( cl.viewangles, angles );
|
||||
ms = bound( 1, host.frametime * 1000, 255 );
|
||||
input_override = 0;
|
||||
|
||||
// fix rounding error and framerate depending player move
|
||||
accurate_ms = host.frametime * 1000;
|
||||
ms = (int)accurate_ms;
|
||||
cl.frametime_remainder += accurate_ms - ms; // accumulate rounding error each frame
|
||||
|
||||
// add a ms if error accumulates enough
|
||||
if( cl.frametime_remainder >= 1.0 )
|
||||
{
|
||||
int ms2 = (int)cl.frametime_remainder;
|
||||
|
||||
ms += ms2;
|
||||
cl.frametime_remainder -= ms2;
|
||||
}
|
||||
|
||||
// ms can't be negative, rely on error accumulation only if FPS > 1000
|
||||
ms = Q_min( ms, 255 );
|
||||
|
||||
CL_SetSolidEntities();
|
||||
CL_PushPMStates();
|
||||
CL_SetSolidPlayers( cl.playernum );
|
||||
@@ -809,7 +822,7 @@ static void CL_WritePacket( void )
|
||||
from = to;
|
||||
|
||||
if( MSG_CheckOverflow( &buf ))
|
||||
Host_Error( "CL_WritePacket: overflowed command buffer (%i bytes)\n", MAX_CMD_BUFFER );
|
||||
Host_Error( "%s: overflowed command buffer (%i bytes)\n", __func__, MAX_CMD_BUFFER );
|
||||
}
|
||||
|
||||
// calculate a checksum over the move commands
|
||||
@@ -834,7 +847,7 @@ static void CL_WritePacket( void )
|
||||
}
|
||||
|
||||
if( MSG_CheckOverflow( &buf ))
|
||||
Host_Error( "CL_WritePacket: overflowed command buffer (%i bytes)\n", MAX_CMD_BUFFER );
|
||||
Host_Error( "%s: overflowed command buffer (%i bytes)\n", __func__, MAX_CMD_BUFFER );
|
||||
|
||||
// remember outgoing command that we are sending
|
||||
cls.lastoutgoingcommand = cls.netchan.outgoing_sequence;
|
||||
@@ -920,16 +933,16 @@ static void CL_BeginUpload_f( void )
|
||||
memset( &custResource, 0, sizeof( custResource ));
|
||||
COM_HexConvert( name + 4, 32, md5 );
|
||||
|
||||
if( HPAK_ResourceForHash( CUSTOM_RES_PATH, md5, &custResource ))
|
||||
if( HPAK_ResourceForHash( hpk_custom_file.string, md5, &custResource ))
|
||||
{
|
||||
if( memcmp( md5, custResource.rgucMD5_hash, 16 ))
|
||||
{
|
||||
Con_Reportf( "Bogus data retrieved from %s, attempting to delete entry\n", CUSTOM_RES_PATH );
|
||||
HPAK_RemoveLump( CUSTOM_RES_PATH, &custResource );
|
||||
Con_Reportf( "Bogus data retrieved from %s, attempting to delete entry\n", hpk_custom_file.string );
|
||||
HPAK_RemoveLump( hpk_custom_file.string, &custResource );
|
||||
return;
|
||||
}
|
||||
|
||||
if( HPAK_GetDataPointer( CUSTOM_RES_PATH, &custResource, &buf, &size ))
|
||||
if( HPAK_GetDataPointer( hpk_custom_file.string, &custResource, &buf, &size ))
|
||||
{
|
||||
byte md5[16];
|
||||
MD5Context_t ctx;
|
||||
@@ -945,7 +958,7 @@ static void CL_BeginUpload_f( void )
|
||||
Con_Reportf( "Purported: %s\n", MD5_Print( custResource.rgucMD5_hash ) );
|
||||
Con_Reportf( "Actual : %s\n", MD5_Print( md5 ) );
|
||||
Con_Reportf( "Removing conflicting lump\n" );
|
||||
HPAK_RemoveLump( CUSTOM_RES_PATH, &custResource );
|
||||
HPAK_RemoveLump( hpk_custom_file.string, &custResource );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1001,7 +1014,7 @@ static void CL_SendConnectPacket( void )
|
||||
|
||||
if( !NET_StringToAdr( cls.servername, &adr ))
|
||||
{
|
||||
Con_Printf( "CL_SendConnectPacket: bad server address\n");
|
||||
Con_Printf( "%s: bad server address\n", __func__ );
|
||||
cls.connect_time = 0;
|
||||
return;
|
||||
}
|
||||
@@ -1149,7 +1162,7 @@ static void CL_CheckForResend( void )
|
||||
// only retry so many times before failure.
|
||||
if( cls.connect_retry >= CL_CONNECTION_RETRIES )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "CL_CheckForResend: couldn't connected\n" );
|
||||
Con_DPrintf( S_ERROR "%s: couldn't connect\n", __func__ );
|
||||
CL_Disconnect();
|
||||
return;
|
||||
}
|
||||
@@ -1236,7 +1249,7 @@ static void CL_CreateResourceList( void )
|
||||
{
|
||||
SetBits( pNewResource->ucFlags, RES_CUSTOM );
|
||||
memcpy( pNewResource->rgucMD5_hash, rgucMD5_hash, 16 );
|
||||
HPAK_AddLump( false, CUSTOM_RES_PATH, pNewResource, NULL, fp );
|
||||
HPAK_AddLump( false, hpk_custom_file.string, pNewResource, NULL, fp );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1252,16 +1265,28 @@ CL_Connect_f
|
||||
static void CL_Connect_f( void )
|
||||
{
|
||||
string server;
|
||||
qboolean legacyconnect = false;
|
||||
connprotocol_t proto = PROTO_CURRENT;
|
||||
|
||||
// hidden hint to connect by using legacy protocol
|
||||
// hint to connect by using legacy protocol
|
||||
if( Cmd_Argc() == 3 )
|
||||
{
|
||||
legacyconnect = !Q_strcmp( Cmd_Argv( 2 ), "legacy" );
|
||||
const char *s = Cmd_Argv( 2 );
|
||||
|
||||
if( !Q_strcmp( s, "current" ) || !Q_strcmp( s, "49" ))
|
||||
proto = PROTO_CURRENT;
|
||||
else if( !Q_strcmp( s, "legacy" ) || !Q_strcmp( s, "48" ))
|
||||
proto = PROTO_LEGACY;
|
||||
else
|
||||
{
|
||||
// quake protocol only used for demos
|
||||
// goldsrc protocol is not supported yet
|
||||
Con_Printf( "Unknown protocol. Supported are: current, legacy\n" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Con_Printf( S_USAGE "connect <server>\n" );
|
||||
Con_Printf( S_USAGE "connect <server> [protocol]\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1279,7 +1304,7 @@ static void CL_Connect_f( void )
|
||||
Key_SetKeyDest( key_console );
|
||||
|
||||
cls.state = ca_connecting;
|
||||
cls.legacymode = legacyconnect;
|
||||
cls.legacymode = proto;
|
||||
Q_strncpy( cls.servername, server, sizeof( cls.servername ));
|
||||
cls.connect_time = MAX_HEARTBEAT; // CL_CheckForResend() will fire immediately
|
||||
cls.max_fragment_size = FRAGMENT_MAX_SIZE; // guess a we can establish connection with maximum fragment size
|
||||
@@ -1425,20 +1450,18 @@ static void CL_SendDisconnectMessage( void )
|
||||
|
||||
int CL_GetSplitSize( void )
|
||||
{
|
||||
int splitsize;
|
||||
int splitsize = (int)cl_dlmax.value;
|
||||
|
||||
if( Host_IsDedicated() )
|
||||
return 0;
|
||||
|
||||
if( !(cls.extensions & NET_EXT_SPLITSIZE) )
|
||||
if( !FBitSet( cls.extensions, NET_EXT_SPLITSIZE ))
|
||||
return 1400;
|
||||
|
||||
splitsize = cl_dlmax.value;
|
||||
|
||||
if( splitsize < FRAGMENT_MIN_SIZE || splitsize > FRAGMENT_MAX_SIZE )
|
||||
if(( splitsize < FRAGMENT_MIN_SIZE ) || ( splitsize > FRAGMENT_MAX_SIZE ))
|
||||
{
|
||||
Cvar_SetValue( "cl_dlmax", FRAGMENT_DEFAULT_SIZE );
|
||||
return FRAGMENT_DEFAULT_SIZE;
|
||||
}
|
||||
|
||||
return cl_dlmax.value;
|
||||
return (int)cl_dlmax.value;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1509,7 +1532,7 @@ This is also called on Host_Error, so it shouldn't cause any errors
|
||||
*/
|
||||
void CL_Disconnect( void )
|
||||
{
|
||||
cls.legacymode = false;
|
||||
cls.legacymode = PROTO_CURRENT;
|
||||
|
||||
if( cls.state == ca_disconnected )
|
||||
return;
|
||||
@@ -1539,7 +1562,7 @@ void CL_Disconnect( void )
|
||||
cls.signon = 0;
|
||||
|
||||
// back to menu in non-developer mode
|
||||
if( host_developer.value || CL_IsInMenu( ))
|
||||
if( host_developer.value || cls.key_dest == key_menu )
|
||||
return;
|
||||
|
||||
UI_SetActiveMenu( true );
|
||||
@@ -1618,9 +1641,17 @@ static size_t NONNULL CL_BuildMasterServerScanRequest( char *buf, size_t size, u
|
||||
#ifndef XASH_ALL_SERVERS
|
||||
Info_SetValueForKey( info, "gamedir", GI->gamefolder, remaining );
|
||||
#endif
|
||||
Info_SetValueForKey( info, "clver", XASH_VERSION, remaining ); // let master know about client version
|
||||
// let master know about client version
|
||||
Info_SetValueForKey( info, "clver", XASH_VERSION, remaining );
|
||||
Info_SetValueForKey( info, "nat", nat ? "1" : "0", remaining );
|
||||
Info_SetValueForKey( info, "commit", Q_buildcommit(), remaining );
|
||||
Info_SetValueForKey( info, "branch", Q_buildbranch(), remaining );
|
||||
Info_SetValueForKey( info, "os", Q_buildos(), remaining );
|
||||
Info_SetValueForKey( info, "arch", Q_buildarch(), remaining );
|
||||
|
||||
Q_snprintf( temp, sizeof( temp ), "%d", Q_buildnum() );
|
||||
Info_SetValueForKey( info, "buildnum", temp, remaining );
|
||||
|
||||
Q_snprintf( temp, sizeof( temp ), "%x", *key );
|
||||
Info_SetValueForKey( info, "key", temp, remaining );
|
||||
|
||||
@@ -1688,7 +1719,7 @@ static void CL_Reconnect_f( void )
|
||||
|
||||
if( COM_CheckString( cls.servername ))
|
||||
{
|
||||
qboolean legacy = cls.legacymode;
|
||||
connprotocol_t proto = cls.legacymode;
|
||||
|
||||
if( cls.state >= ca_connected )
|
||||
CL_Disconnect();
|
||||
@@ -1697,7 +1728,7 @@ static void CL_Reconnect_f( void )
|
||||
cls.demonum = cls.movienum = -1; // not in the demo loop now
|
||||
cls.state = ca_connecting;
|
||||
cls.signon = 0;
|
||||
cls.legacymode = legacy; // don't change protocol
|
||||
cls.legacymode = proto; // don't change protocol
|
||||
|
||||
Con_Printf( "reconnecting...\n" );
|
||||
}
|
||||
@@ -1710,7 +1741,7 @@ CL_FixupColorStringsForInfoString
|
||||
all the keys and values must be ends with ^7
|
||||
=================
|
||||
*/
|
||||
static void CL_FixupColorStringsForInfoString( const char *in, char *out )
|
||||
static void CL_FixupColorStringsForInfoString( const char *in, char *out, size_t len )
|
||||
{
|
||||
qboolean hasPrefix = false;
|
||||
qboolean endOfKeyVal = false;
|
||||
@@ -1723,7 +1754,7 @@ static void CL_FixupColorStringsForInfoString( const char *in, char *out )
|
||||
count++;
|
||||
}
|
||||
|
||||
while( *in && count < MAX_INFO_STRING )
|
||||
while( *in && count < len )
|
||||
{
|
||||
if( IsColorString( in ))
|
||||
color = ColorIndex( *(in+1));
|
||||
@@ -1794,7 +1825,7 @@ static void CL_ParseStatusMessage( netadr_t from, sizebuf_t *msg )
|
||||
return;
|
||||
}
|
||||
|
||||
CL_FixupColorStringsForInfoString( s, infostring );
|
||||
CL_FixupColorStringsForInfoString( s, infostring, sizeof( infostring ));
|
||||
|
||||
if( !COM_CheckString( Info_ValueForKey( infostring, "gamedir" )))
|
||||
{
|
||||
@@ -1823,52 +1854,87 @@ CL_ParseNETInfoMessage
|
||||
Handle a reply from a netinfo
|
||||
=================
|
||||
*/
|
||||
static void CL_ParseNETInfoMessage( netadr_t from, sizebuf_t *msg, const char *s )
|
||||
static void CL_ParseNETInfoMessage( netadr_t from, const char *s )
|
||||
{
|
||||
net_request_t *nr;
|
||||
static char infostring[MAX_INFO_STRING+8];
|
||||
net_request_t *nr = NULL;
|
||||
static char infostring[MAX_PRINT_MSG];
|
||||
int i, context, type;
|
||||
int errorBits = 0;
|
||||
const char *val;
|
||||
size_t slen;
|
||||
|
||||
context = Q_atoi( Cmd_Argv( 1 ));
|
||||
type = Q_atoi( Cmd_Argv( 2 ));
|
||||
while( *s != '\\' ) s++; // fetching infostring
|
||||
|
||||
// check for errors
|
||||
val = Info_ValueForKey( s, "neterror" );
|
||||
|
||||
if( !Q_stricmp( val, "protocol" ))
|
||||
SetBits( errorBits, NET_ERROR_PROTO_UNSUPPORTED );
|
||||
else if( !Q_stricmp( val, "undefined" ))
|
||||
SetBits( errorBits, NET_ERROR_UNDEFINED );
|
||||
|
||||
CL_FixupColorStringsForInfoString( s, infostring );
|
||||
|
||||
// find a request with specified context
|
||||
// find request with specified context and type
|
||||
for( i = 0; i < MAX_REQUESTS; i++ )
|
||||
{
|
||||
nr = &clgame.net_requests[i];
|
||||
|
||||
if( nr->resp.context == context && nr->resp.type == type )
|
||||
if( clgame.net_requests[i].resp.context == context && clgame.net_requests[i].resp.type == type )
|
||||
{
|
||||
// setup the answer
|
||||
nr->resp.response = infostring;
|
||||
nr->resp.remote_address = from;
|
||||
nr->resp.error = NET_SUCCESS;
|
||||
nr->resp.ping = host.realtime - nr->timesend;
|
||||
|
||||
if( nr->timeout <= host.realtime )
|
||||
SetBits( nr->resp.error, NET_ERROR_TIMEOUT );
|
||||
SetBits( nr->resp.error, errorBits ); // misc error bits
|
||||
|
||||
nr->pfnFunc( &nr->resp );
|
||||
|
||||
if( !FBitSet( nr->flags, FNETAPI_MULTIPLE_RESPONSE ))
|
||||
memset( nr, 0, sizeof( *nr )); // done
|
||||
return;
|
||||
nr = &clgame.net_requests[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// not found, ignore
|
||||
if( nr == NULL )
|
||||
return;
|
||||
|
||||
// find the payload
|
||||
s = Q_strchr( s, ' ' ); // skip netinfo
|
||||
if( !s )
|
||||
return;
|
||||
|
||||
s = Q_strchr( s + 1, ' ' ); // skip challenge
|
||||
if( !s )
|
||||
return;
|
||||
|
||||
s = Q_strchr( s + 1, ' ' ); // skip type
|
||||
if( s )
|
||||
s++; // skip final whitespace
|
||||
else if( type != NETAPI_REQUEST_PING ) // ping have no payload, and that's ok
|
||||
return;
|
||||
|
||||
if( s )
|
||||
{
|
||||
if( s[0] == '\\' )
|
||||
{
|
||||
// check for errors
|
||||
val = Info_ValueForKey( s, "neterror" );
|
||||
|
||||
if( !Q_stricmp( val, "protocol" ))
|
||||
SetBits( errorBits, NET_ERROR_PROTO_UNSUPPORTED );
|
||||
else if( !Q_stricmp( val, "undefined" ))
|
||||
SetBits( errorBits, NET_ERROR_UNDEFINED );
|
||||
else if( !Q_stricmp( val, "forbidden" ))
|
||||
SetBits( errorBits, NET_ERROR_FORBIDDEN );
|
||||
|
||||
CL_FixupColorStringsForInfoString( s, infostring, sizeof( infostring ));
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_strncpy( infostring, s, sizeof( infostring ));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
infostring[0] = 0;
|
||||
}
|
||||
|
||||
// setup the answer
|
||||
nr->resp.response = infostring;
|
||||
nr->resp.remote_address = from;
|
||||
nr->resp.error = NET_SUCCESS;
|
||||
nr->resp.ping = host.realtime - nr->timesend;
|
||||
|
||||
if( nr->timeout <= host.realtime )
|
||||
SetBits( nr->resp.error, NET_ERROR_TIMEOUT );
|
||||
SetBits( nr->resp.error, errorBits ); // misc error bits
|
||||
|
||||
nr->pfnFunc( &nr->resp );
|
||||
|
||||
if( !FBitSet( nr->flags, FNETAPI_MULTIPLE_RESPONSE ))
|
||||
memset( nr, 0, sizeof( *nr )); // done
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1966,7 +2032,6 @@ static void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
const char *c;
|
||||
char buf[MAX_SYSPATH];
|
||||
int len = sizeof( buf );
|
||||
int dataoffset = 0;
|
||||
netadr_t servadr;
|
||||
|
||||
MSG_Clear( msg );
|
||||
@@ -1977,7 +2042,7 @@ static void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
Cmd_TokenizeString( args );
|
||||
c = Cmd_Argv( 0 );
|
||||
|
||||
Con_Reportf( "CL_ConnectionlessPacket: %s : %s\n", NET_AdrToString( from ), c );
|
||||
Con_Reportf( "%s: %s : %s\n", __func__, NET_AdrToString( from ), c );
|
||||
|
||||
// server connection
|
||||
if( !Q_strcmp( c, "client_connect" ))
|
||||
@@ -2002,7 +2067,7 @@ static void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
else if( !Q_strcmp( c, "netinfo" ))
|
||||
{
|
||||
// server responding to a status broadcast
|
||||
CL_ParseNETInfoMessage( from, msg, args );
|
||||
CL_ParseNETInfoMessage( from, args );
|
||||
}
|
||||
else if( !Q_strcmp( c, "cmd" ))
|
||||
{
|
||||
@@ -2023,7 +2088,11 @@ static void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
else if( !Q_strcmp( c, "print" ))
|
||||
{
|
||||
// print command from somewhere
|
||||
Con_Printf( "%s", MSG_ReadString( msg ));
|
||||
char *s = MSG_ReadString( msg );
|
||||
|
||||
Con_Printf( S_CYAN "r:" S_DEFAULT " %s", s );
|
||||
if( !COM_CheckStringEmpty( s ) || s[Q_strlen( s ) - 1] != '\n' )
|
||||
Con_Printf( "\n" );
|
||||
}
|
||||
else if( !Q_strcmp( c, "testpacket" ))
|
||||
{
|
||||
@@ -2134,30 +2203,21 @@ static void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
// a disconnect message from the server, which will happen if the server
|
||||
// dropped the connection but it is still getting packets from us
|
||||
CL_Disconnect_f();
|
||||
|
||||
if( NET_CompareAdr( from, cls.legacyserver ))
|
||||
{
|
||||
Cbuf_AddTextf( "connect %s legacy\n", NET_AdrToString( from ));
|
||||
memset( &cls.legacyserver, 0, sizeof( cls.legacyserver ));
|
||||
}
|
||||
}
|
||||
else if( !Q_strcmp( c, "errormsg" ))
|
||||
{
|
||||
char formatted_msg[MAX_VA_STRING];
|
||||
|
||||
if( !CL_IsFromConnectingServer( from ))
|
||||
return;
|
||||
|
||||
args = MSG_ReadString( msg );
|
||||
|
||||
if( !Q_strcmp( args, "Server uses protocol version 48.\n" ))
|
||||
{
|
||||
cls.legacyserver = from;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( UI_IsVisible() )
|
||||
UI_ShowMessageBox( va("^3Server message^7\n%s", args ) );
|
||||
Msg( "%s", args );
|
||||
}
|
||||
Q_snprintf( formatted_msg, sizeof( formatted_msg ), "^3Server message^7\n%s", args );
|
||||
|
||||
// in case we're in console or it's classic mainui which doesn't support messageboxes
|
||||
if( !UI_IsVisible() || !UI_ShowMessageBox( formatted_msg ))
|
||||
Msg( "%s\n", formatted_msg );
|
||||
}
|
||||
else if( !Q_strcmp( c, "updatemsg" ))
|
||||
{
|
||||
@@ -2271,6 +2331,32 @@ static int CL_GetMessage( byte *data, size_t *length )
|
||||
return false;
|
||||
}
|
||||
|
||||
static void CL_ParseNetMessage( sizebuf_t *msg, void (*parsefn)( sizebuf_t * ))
|
||||
{
|
||||
cls.starting_count = MSG_GetNumBytesRead( msg ); // updates each frame
|
||||
CL_Parse_Debug( true ); // begin parsing
|
||||
|
||||
parsefn( msg );
|
||||
|
||||
cl.frames[cl.parsecountmod].graphdata.msgbytes += MSG_GetNumBytesRead( msg ) - cls.starting_count;
|
||||
CL_Parse_Debug( false ); // done
|
||||
|
||||
// we don't know if it is ok to save a demo message until
|
||||
// after we have parsed the frame
|
||||
if( !cls.demoplayback )
|
||||
{
|
||||
if( cls.demorecording && !cls.demowaiting )
|
||||
{
|
||||
CL_WriteDemoMessage( false, cls.starting_count, msg );
|
||||
}
|
||||
else if( cls.state != ca_active )
|
||||
{
|
||||
CL_WriteDemoMessage( true, cls.starting_count, msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_ReadNetMessage
|
||||
@@ -2279,11 +2365,29 @@ CL_ReadNetMessage
|
||||
static void CL_ReadNetMessage( void )
|
||||
{
|
||||
size_t curSize;
|
||||
void (*parsefn)( sizebuf_t *msg );
|
||||
|
||||
switch( cls.legacymode )
|
||||
{
|
||||
case PROTO_CURRENT:
|
||||
parsefn = CL_ParseServerMessage;
|
||||
break;
|
||||
case PROTO_LEGACY:
|
||||
parsefn = CL_ParseLegacyServerMessage;
|
||||
break;
|
||||
case PROTO_QUAKE:
|
||||
parsefn = CL_ParseQuakeMessage;
|
||||
break;
|
||||
case PROTO_GOLDSRC:
|
||||
default:
|
||||
ASSERT( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
while( CL_GetMessage( net_message_buffer, &curSize ))
|
||||
{
|
||||
const int split_header = LittleLong( 0xFFFFFFFE );
|
||||
if( cls.legacymode && !memcmp( &split_header, net_message_buffer, sizeof( split_header )))
|
||||
if( cls.legacymode == PROTO_LEGACY && !memcmp( &split_header, net_message_buffer, sizeof( split_header )))
|
||||
{
|
||||
// Will rewrite existing packet by merged
|
||||
if( !NetSplit_GetLong( &cls.netchan.netsplit, &net_from, net_message_buffer, &curSize ) )
|
||||
@@ -2302,27 +2406,36 @@ static void CL_ReadNetMessage( void )
|
||||
// can't be a valid sequenced packet
|
||||
if( cls.state < ca_connected ) continue;
|
||||
|
||||
if( !cls.demoplayback && MSG_GetMaxBytes( &net_message ) < 8 )
|
||||
if( !cls.demoplayback )
|
||||
{
|
||||
Con_Printf( S_WARN "CL_ReadPackets: %s:runt packet\n", NET_AdrToString( net_from ));
|
||||
continue;
|
||||
if( MSG_GetMaxBytes( &net_message ) < 8 )
|
||||
{
|
||||
Con_Printf( S_WARN "%s: %s:runt packet\n", __func__, NET_AdrToString( net_from ));
|
||||
continue;
|
||||
}
|
||||
|
||||
// packet from server
|
||||
if( !NET_CompareAdr( net_from, cls.netchan.remote_address ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: %s:sequenced packet without connection\n", __func__, NET_AdrToString( net_from ));
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !Netchan_Process( &cls.netchan, &net_message ))
|
||||
continue; // wasn't accepted for some reason
|
||||
}
|
||||
|
||||
// packet from server
|
||||
if( !cls.demoplayback && !NET_CompareAdr( net_from, cls.netchan.remote_address ))
|
||||
if( cls.state == ca_active )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "CL_ReadPackets: %s:sequenced packet without connection\n", NET_AdrToString( net_from ));
|
||||
continue;
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].valid = false;
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
CL_ResetFrame( &cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK] );
|
||||
}
|
||||
|
||||
if( !cls.demoplayback && !Netchan_Process( &cls.netchan, &net_message ))
|
||||
continue; // wasn't accepted for some reason
|
||||
|
||||
// run special handler for quake demos
|
||||
if( cls.demoplayback == DEMO_QUAKE1 )
|
||||
CL_ParseQuakeMessage( &net_message, true );
|
||||
else if( cls.legacymode ) CL_ParseLegacyServerMessage( &net_message, true );
|
||||
else CL_ParseServerMessage( &net_message, true );
|
||||
CL_ParseNetMessage( &net_message, parsefn );
|
||||
cl.send_reply = true;
|
||||
}
|
||||
|
||||
@@ -2336,7 +2449,7 @@ static void CL_ReadNetMessage( void )
|
||||
if( Netchan_CopyNormalFragments( &cls.netchan, &net_message, &curSize ))
|
||||
{
|
||||
MSG_Init( &net_message, "ServerData", net_message_buffer, curSize );
|
||||
CL_ParseServerMessage( &net_message, false );
|
||||
CL_ParseNetMessage( &net_message, parsefn );
|
||||
}
|
||||
|
||||
if( Netchan_CopyFileFragments( &cls.netchan, &net_message ))
|
||||
@@ -2510,11 +2623,6 @@ void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
||||
return;
|
||||
}
|
||||
|
||||
pfilename = filename;
|
||||
|
||||
if( !Q_strnicmp( filename, DEFAULT_SOUNDPATH, sound_len ))
|
||||
pfilename += sound_len;
|
||||
|
||||
for( p = cl.resourcesneeded.pNext; p != &cl.resourcesneeded; p = p->pNext )
|
||||
{
|
||||
if( !Q_strnicmp( filename, "!MD5", 4 ))
|
||||
@@ -2524,18 +2632,20 @@ void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
||||
if( !memcmp( p->rgucMD5_hash, rgucMD5_hash, 16 ))
|
||||
break;
|
||||
}
|
||||
else if( p->type == t_sound )
|
||||
{
|
||||
const char *pfilename = filename;
|
||||
|
||||
if( !Q_strnicmp( filename, DEFAULT_SOUNDPATH, sound_len ))
|
||||
pfilename += sound_len;
|
||||
|
||||
if( !Q_stricmp( p->szFileName, pfilename ))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( p->type == t_generic )
|
||||
{
|
||||
if( !Q_stricmp( p->szFileName, filename ))
|
||||
if( !Q_stricmp( p->szFileName, filename ))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !Q_stricmp( p->szFileName, pfilename ))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2552,7 +2662,7 @@ void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
||||
{
|
||||
if( p->ucFlags & RES_CUSTOM )
|
||||
{
|
||||
HPAK_AddLump( true, CUSTOM_RES_PATH, p, cls.netchan.tempbuffer, NULL );
|
||||
HPAK_AddLump( true, hpk_custom_file.string, p, cls.netchan.tempbuffer, NULL );
|
||||
CL_RegisterCustomization( p );
|
||||
}
|
||||
}
|
||||
@@ -2600,7 +2710,7 @@ void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
||||
|
||||
if( cls.netchan.tempbuffer )
|
||||
{
|
||||
Con_Printf( "Received a decal %s, but didn't find it in resources needed list!\n", pfilename );
|
||||
Con_Printf( "Received a decal %s, but didn't find it in resources needed list!\n", filename );
|
||||
Mem_Free( cls.netchan.tempbuffer );
|
||||
}
|
||||
|
||||
@@ -2640,6 +2750,29 @@ void CL_ServerCommand( qboolean reliable, const char *fmt, ... )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_UpdateInfo
|
||||
|
||||
tell server about changed userinfo
|
||||
===============
|
||||
*/
|
||||
void CL_UpdateInfo( const char *key, const char *value )
|
||||
{
|
||||
if( !cls.legacymode )
|
||||
{
|
||||
CL_ServerCommand( true, "setinfo \"%s\" \"%s\"\n", key, value );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( cls.state != ca_active )
|
||||
return;
|
||||
|
||||
MSG_BeginClientCmd( &cls.netchan.message, clc_legacy_userinfo );
|
||||
MSG_WriteString( &cls.netchan.message, cls.userinfo );
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*
|
||||
==============
|
||||
@@ -2654,7 +2787,7 @@ static void CL_SetInfo_f( void )
|
||||
{
|
||||
Con_Printf( "User info settings:\n" );
|
||||
Info_Print( cls.userinfo );
|
||||
Con_Printf( "Total %i symbols\n", Q_strlen( cls.userinfo ));
|
||||
Con_Printf( "Total %zu symbols\n", Q_strlen( cls.userinfo ));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2674,7 +2807,7 @@ static void CL_SetInfo_f( void )
|
||||
{
|
||||
Cvar_DirectSet( var, Cmd_Argv( 2 ));
|
||||
}
|
||||
else if( Info_SetValueForKey( cls.userinfo, Cmd_Argv( 1 ), Cmd_Argv( 2 ), MAX_INFO_STRING ))
|
||||
else if( Info_SetValueForKey( cls.userinfo, Cmd_Argv( 1 ), Cmd_Argv( 2 ), sizeof( cls.userinfo )))
|
||||
{
|
||||
// send update only on successfully changed userinfo
|
||||
Cmd_ForwardToServer ();
|
||||
@@ -2690,13 +2823,35 @@ static void CL_Physinfo_f( void )
|
||||
{
|
||||
Con_Printf( "Phys info settings:\n" );
|
||||
Info_Print( cls.physinfo );
|
||||
Con_Printf( "Total %i symbols\n", Q_strlen( cls.physinfo ));
|
||||
Con_Printf( "Total %zu symbols\n", Q_strlen( cls.physinfo ));
|
||||
}
|
||||
|
||||
static qboolean CL_ShouldRescanFilesystem( void )
|
||||
{
|
||||
resource_t *res;
|
||||
|
||||
for( res = cl.resourcesonhand.pNext; res && res != &cl.resourcesonhand; res = res->pNext )
|
||||
{
|
||||
if( res->type == t_generic )
|
||||
{
|
||||
const char *ext = COM_FileExtension( res->szFileName );
|
||||
// TODO: query supported archives format from fs_stdio
|
||||
// TODO: query if was already opened
|
||||
if( !Q_stricmp( ext, "wad" ) || !Q_stricmp( ext, "pk3" ) || !Q_stricmp( ext, "pak" ))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean CL_PrecacheResources( void )
|
||||
{
|
||||
resource_t *pRes;
|
||||
|
||||
// if we downloaded new WAD files or any other archives they must be added to searchpath
|
||||
if( CL_ShouldRescanFilesystem( ))
|
||||
g_fsapi.Rescan();
|
||||
|
||||
// NOTE: world need to be loaded as first model
|
||||
for( pRes = cl.resourcesonhand.pNext; pRes && pRes != &cl.resourcesonhand; pRes = pRes->pNext )
|
||||
{
|
||||
@@ -2895,6 +3050,7 @@ static void CL_InitLocal( void )
|
||||
Cvar_RegisterVariable( &cl_logofile );
|
||||
Cvar_RegisterVariable( &cl_logocolor );
|
||||
Cvar_RegisterVariable( &cl_logoext );
|
||||
Cvar_RegisterVariable( &cl_logomaxdim );
|
||||
Cvar_RegisterVariable( &cl_test_bandwidth );
|
||||
|
||||
Voice_RegisterCvars();
|
||||
@@ -3190,7 +3346,7 @@ CL_Shutdown
|
||||
*/
|
||||
void CL_Shutdown( void )
|
||||
{
|
||||
Con_Printf( "CL_Shutdown()\n" );
|
||||
Con_Printf( "%s()\n", __func__ );
|
||||
|
||||
if( !host.crashed && cls.initialized )
|
||||
{
|
||||
|
||||
@@ -188,7 +188,7 @@ void CL_ParseServerTime( sizebuf_t *msg )
|
||||
cl.mtime[1] = cl.mtime[0];
|
||||
cl.mtime[0] = MSG_ReadFloat( msg );
|
||||
|
||||
if( cls.demoplayback == DEMO_QUAKE1 )
|
||||
if( cls.legacymode == PROTO_QUAKE )
|
||||
return; // don't mess the time
|
||||
|
||||
if( cl.maxclients == 1 )
|
||||
@@ -249,7 +249,7 @@ void CL_ParseMovevars( sizebuf_t *msg )
|
||||
|
||||
// update sky if changed
|
||||
if( Q_strcmp( clgame.oldmovevars.skyName, clgame.movevars.skyName ) && cl.video_prepped )
|
||||
ref.dllFuncs.R_SetupSky( clgame.movevars.skyName );
|
||||
R_SetupSky( clgame.movevars.skyName );
|
||||
|
||||
memcpy( &clgame.oldmovevars, &clgame.movevars, sizeof( movevars_t ));
|
||||
clgame.entities->curstate.scale = clgame.movevars.waveHeight;
|
||||
@@ -458,6 +458,7 @@ void CL_BatchResourceRequest( qboolean initialize )
|
||||
byte data[MAX_INIT_MSG];
|
||||
resource_t *p, *n;
|
||||
sizebuf_t msg;
|
||||
qboolean done_downloading = true;
|
||||
|
||||
MSG_Init( &msg, "Resource Batch", data, sizeof( data ));
|
||||
|
||||
@@ -487,20 +488,24 @@ void CL_BatchResourceRequest( qboolean initialize )
|
||||
case t_model:
|
||||
case t_eventscript:
|
||||
if( !CL_CheckFile( &msg, p ))
|
||||
{
|
||||
done_downloading = false;
|
||||
break;
|
||||
}
|
||||
CL_MoveToOnHandList( p );
|
||||
break;
|
||||
case t_skin:
|
||||
CL_MoveToOnHandList( p );
|
||||
break;
|
||||
case t_decal:
|
||||
if( !HPAK_GetDataPointer( CUSTOM_RES_PATH, p, NULL, NULL ))
|
||||
if( !HPAK_GetDataPointer( hpk_custom_file.string, p, NULL, NULL ))
|
||||
{
|
||||
if( !FBitSet( p->ucFlags, RES_REQUESTED ))
|
||||
{
|
||||
MSG_BeginClientCmd( &msg, clc_stringcmd );
|
||||
MSG_WriteStringf( &msg, "dlfile !MD5%s", MD5_Print( p->rgucMD5_hash ));;
|
||||
SetBits( p->ucFlags, RES_REQUESTED );
|
||||
done_downloading = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -525,11 +530,7 @@ void CL_BatchResourceRequest( qboolean initialize )
|
||||
|
||||
if( cls.state != ca_disconnected )
|
||||
{
|
||||
if( !cl.downloadUrl[0] && !MSG_GetNumBytesWritten( &msg ) && CL_PrecacheResources( ))
|
||||
{
|
||||
CL_RegisterResources( &msg );
|
||||
}
|
||||
if( cl.downloadUrl[0] && host.downloadcount == 0 && CL_PrecacheResources( ) )
|
||||
if( done_downloading && CL_PrecacheResources( ))
|
||||
{
|
||||
CL_RegisterResources( &msg );
|
||||
}
|
||||
@@ -721,7 +722,7 @@ void CL_ParseCustomization( sizebuf_t *msg )
|
||||
}
|
||||
}
|
||||
|
||||
if( HPAK_GetDataPointer( CUSTOM_RES_PATH, pRes, NULL, NULL ))
|
||||
if( HPAK_GetDataPointer( hpk_custom_file.string, pRes, NULL, NULL ))
|
||||
{
|
||||
qboolean bError = false;
|
||||
|
||||
@@ -853,7 +854,7 @@ void CL_ParseServerData( sizebuf_t *msg, qboolean legacy )
|
||||
int i;
|
||||
uint32_t mapCRC;
|
||||
|
||||
HPAK_CheckSize( CUSTOM_RES_PATH );
|
||||
HPAK_CheckSize( hpk_custom_file.string );
|
||||
|
||||
Con_Reportf( "%s packet received.\n", legacy ? "Legacy serverdata" : "Serverdata" );
|
||||
|
||||
@@ -1203,7 +1204,7 @@ void CL_ParseBaseline( sizebuf_t *msg, qboolean legacy )
|
||||
player = CL_IsPlayerIndex( newnum );
|
||||
|
||||
if( newnum >= clgame.maxEntities )
|
||||
Host_Error( "CL_AllocEdict: no free edicts\n" );
|
||||
Host_Error( "%s: no free edicts\n", __func__ );
|
||||
|
||||
ent = CL_EDICT_NUM( newnum );
|
||||
memset( &ent->prevstate, 0, sizeof( ent->prevstate ));
|
||||
@@ -1380,7 +1381,7 @@ void CL_UpdateUserinfo( sizebuf_t *msg, qboolean legacy )
|
||||
slot = MSG_ReadUBitLong( msg, MAX_CLIENT_BITS );
|
||||
|
||||
if( slot >= MAX_CLIENTS )
|
||||
Host_Error( "CL_ParseServerMessage: svc_updateuserinfo >= MAX_CLIENTS\n" );
|
||||
Host_Error( "%s: svc_updateuserinfo >= MAX_CLIENTS\n", __func__ );
|
||||
|
||||
player = &cl.players[slot];
|
||||
|
||||
@@ -1493,7 +1494,7 @@ void CL_UpdateUserPings( sizebuf_t *msg )
|
||||
slot = MSG_ReadUBitLong( msg, MAX_CLIENT_BITS );
|
||||
|
||||
if( slot >= MAX_CLIENTS )
|
||||
Host_Error( "CL_ParseServerMessage: svc_pings > MAX_CLIENTS\n" );
|
||||
Host_Error( "%s: svc_pings > MAX_CLIENTS\n", __func__ );
|
||||
|
||||
player = &cl.players[slot];
|
||||
player->ping = MSG_ReadUBitLong( msg, 12 );
|
||||
@@ -1645,6 +1646,9 @@ void CL_RegisterResources( sizebuf_t *msg )
|
||||
|
||||
CL_ClearWorld ();
|
||||
|
||||
// load skybox
|
||||
R_SetupSky( clgame.movevars.skyName );
|
||||
|
||||
// tell rendering system we have a new set of models.
|
||||
ref.dllFuncs.R_NewMap ();
|
||||
|
||||
@@ -1718,7 +1722,7 @@ static void CL_ParseConsistencyInfo( sizebuf_t *msg )
|
||||
}
|
||||
|
||||
if( cl.num_consistency >= MAX_MODELS )
|
||||
Host_Error( "CL_CheckConsistency: MAX_MODELS limit exceeded (%d)\n", MAX_MODELS );
|
||||
Host_Error( "%s: MAX_MODELS limit exceeded (%d)\n", __func__, MAX_MODELS );
|
||||
|
||||
pc = &cl.consistency_list[cl.num_consistency];
|
||||
cl.num_consistency++;
|
||||
@@ -1840,13 +1844,10 @@ void CL_ParseResLocation( sizebuf_t *msg )
|
||||
return;
|
||||
}
|
||||
|
||||
while( ( data = COM_ParseFile( data, token, sizeof( token ) ) ) )
|
||||
while(( data = COM_ParseFile( data, token, sizeof( token ))))
|
||||
{
|
||||
Con_Reportf( "Adding %s as download location\n", token );
|
||||
|
||||
if( !cl.downloadUrl[0] )
|
||||
Q_strncpy( cl.downloadUrl, token, sizeof( token ) );
|
||||
|
||||
cl.http_download = true;
|
||||
HTTP_AddCustomServer( token );
|
||||
}
|
||||
}
|
||||
@@ -1877,8 +1878,12 @@ void CL_ParseHLTV( sizebuf_t *msg )
|
||||
break;
|
||||
case HLTV_LISTEN:
|
||||
cls.signon = SIGNONS;
|
||||
#if 1
|
||||
MSG_ReadString( msg );
|
||||
#else
|
||||
NET_StringToAdr( MSG_ReadString( msg ), &cls.hltv_listen_address );
|
||||
// NET_JoinGroup( cls.netchan.sock, cls.hltv_listen_address );
|
||||
NET_JoinGroup( cls.netchan.sock, cls.hltv_listen_address );
|
||||
#endif
|
||||
SCR_EndLoadingPlaque();
|
||||
break;
|
||||
default:
|
||||
@@ -1988,7 +1993,7 @@ Find the client cvar value
|
||||
and sent it back to the server
|
||||
==============
|
||||
*/
|
||||
void CL_ParseCvarValue( sizebuf_t *msg, const qboolean ext )
|
||||
void CL_ParseCvarValue( sizebuf_t *msg, const qboolean ext, const connprotocol_t proto )
|
||||
{
|
||||
const char *cvarName, *response;
|
||||
convar_t *cvar;
|
||||
@@ -2011,7 +2016,14 @@ void CL_ParseCvarValue( sizebuf_t *msg, const qboolean ext )
|
||||
else
|
||||
response = cvar->string;
|
||||
}
|
||||
else response = "Bad CVAR request";
|
||||
else if( proto == PROTO_LEGACY )
|
||||
{
|
||||
response = "Not Found";
|
||||
}
|
||||
else
|
||||
{
|
||||
response = "Bad CVAR request";
|
||||
}
|
||||
|
||||
if( ext )
|
||||
{
|
||||
@@ -2128,7 +2140,7 @@ void CL_ParseUserMessage( sizebuf_t *msg, int svc_num )
|
||||
if( svc_num <= svc_lastmsg || svc_num > ( MAX_USER_MESSAGES + svc_lastmsg ))
|
||||
{
|
||||
// out or range
|
||||
Host_Error( "CL_ParseUserMessage: illegible server message %d\n", svc_num );
|
||||
Host_Error( "%s: illegible server message %d\n", __func__, svc_num );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2140,7 +2152,7 @@ void CL_ParseUserMessage( sizebuf_t *msg, int svc_num )
|
||||
}
|
||||
|
||||
if( i == MAX_USER_MESSAGES ) // probably unregistered
|
||||
Host_Error( "CL_ParseUserMessage: illegible server message %d\n", svc_num );
|
||||
Host_Error( "%s: illegible server message %d\n", __func__, svc_num );
|
||||
|
||||
// NOTE: some user messages handled into engine
|
||||
if( !Q_strcmp( clgame.msg[i].name, "ScreenShake" ))
|
||||
@@ -2166,7 +2178,7 @@ void CL_ParseUserMessage( sizebuf_t *msg, int svc_num )
|
||||
|
||||
if( iSize >= MAX_USERMSG_LENGTH )
|
||||
{
|
||||
Msg("WTF??? %d %d\n", i, svc_num );
|
||||
Con_Reportf( "%s: user message %s size limit hit (%d > %d)!\n", __func__, clgame.msg[i].name, iSize, MAX_USERMSG_LENGTH );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2195,7 +2207,7 @@ void CL_ParseUserMessage( sizebuf_t *msg, int svc_num )
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_DPrintf( S_ERROR "UserMsg: No pfn %s %d\n", clgame.msg[i].name, clgame.msg[i].number );
|
||||
Con_DPrintf( S_ERROR "%s: No pfn %s %d\n", __func__, clgame.msg[i].name, clgame.msg[i].number );
|
||||
clgame.msg[i].func = CL_UserMsgStub; // throw warning only once
|
||||
}
|
||||
}
|
||||
@@ -2214,36 +2226,19 @@ CL_ParseServerMessage
|
||||
dispatch messages
|
||||
=====================
|
||||
*/
|
||||
void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
void CL_ParseServerMessage( sizebuf_t *msg )
|
||||
{
|
||||
size_t bufStart, playerbytes;
|
||||
int cmd, param1, param2;
|
||||
int old_background;
|
||||
const char *s;
|
||||
|
||||
cls.starting_count = MSG_GetNumBytesRead( msg ); // updates each frame
|
||||
CL_Parse_Debug( true ); // begin parsing
|
||||
|
||||
if( normal_message )
|
||||
{
|
||||
// assume no entity/player update this packet
|
||||
if( cls.state == ca_active )
|
||||
{
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].valid = false;
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
CL_ResetFrame( &cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK] );
|
||||
}
|
||||
}
|
||||
|
||||
// parse the message
|
||||
while( 1 )
|
||||
{
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
{
|
||||
Host_Error( "CL_ParseServerMessage: overflow!\n" );
|
||||
Host_Error( "%s: overflow!\n", __func__ );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2488,10 +2483,10 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
CL_ParseResLocation( msg );
|
||||
break;
|
||||
case svc_querycvarvalue:
|
||||
CL_ParseCvarValue( msg, false );
|
||||
CL_ParseCvarValue( msg, false, PROTO_CURRENT );
|
||||
break;
|
||||
case svc_querycvarvalue2:
|
||||
CL_ParseCvarValue( msg, true );
|
||||
CL_ParseCvarValue( msg, true, PROTO_CURRENT );
|
||||
break;
|
||||
case svc_exec:
|
||||
CL_ParseExec( msg );
|
||||
@@ -2502,21 +2497,4 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cl.frames[cl.parsecountmod].graphdata.msgbytes += MSG_GetNumBytesRead( msg ) - cls.starting_count;
|
||||
CL_Parse_Debug( false ); // done
|
||||
|
||||
// we don't know if it is ok to save a demo message until
|
||||
// after we have parsed the frame
|
||||
if( !cls.demoplayback )
|
||||
{
|
||||
if( cls.demorecording && !cls.demowaiting )
|
||||
{
|
||||
CL_WriteDemoMessage( false, cls.starting_count, msg );
|
||||
}
|
||||
else if( cls.state != ca_active )
|
||||
{
|
||||
CL_WriteDemoMessage( true, cls.starting_count, msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ static void CL_LegacyPrecacheSound( sizebuf_t *msg )
|
||||
soundIndex = MSG_ReadUBitLong( msg, MAX_SOUND_BITS );
|
||||
|
||||
if( soundIndex < 0 || soundIndex >= MAX_SOUNDS )
|
||||
Host_Error( "CL_PrecacheSound: bad soundindex %i\n", soundIndex );
|
||||
Host_Error( "%s: bad soundindex %i\n", __func__, soundIndex );
|
||||
|
||||
Q_strncpy( cl.sound_precache[soundIndex], MSG_ReadString( msg ), sizeof( cl.sound_precache[0] ));
|
||||
|
||||
@@ -192,9 +192,9 @@ static void CL_LegacyPrecacheModel( sizebuf_t *msg )
|
||||
modelIndex = MSG_ReadUBitLong( msg, MAX_LEGACY_MODEL_BITS );
|
||||
|
||||
if( modelIndex < 0 || modelIndex >= MAX_MODELS )
|
||||
Host_Error( "CL_PrecacheModel: bad modelindex %i\n", modelIndex );
|
||||
Host_Error( "%s: bad modelindex %i\n", __func__, modelIndex );
|
||||
|
||||
Q_strncpy( model, MSG_ReadString( msg ), MAX_STRING );
|
||||
Q_strncpy( model, MSG_ReadString( msg ), sizeof( model ));
|
||||
//Q_strncpy( cl.model_precache[modelIndex], BF_ReadString( msg ), sizeof( cl.model_precache[0] ));
|
||||
|
||||
// when we loading map all resources is precached sequentially
|
||||
@@ -221,7 +221,7 @@ static void CL_LegacyPrecacheEvent( sizebuf_t *msg )
|
||||
eventIndex = MSG_ReadUBitLong( msg, MAX_EVENT_BITS );
|
||||
|
||||
if( eventIndex < 0 || eventIndex >= MAX_EVENTS )
|
||||
Host_Error( "CL_PrecacheEvent: bad eventindex %i\n", eventIndex );
|
||||
Host_Error( "%s: bad eventindex %i\n", __func__, eventIndex );
|
||||
|
||||
Q_strncpy( cl.event_precache[eventIndex], MSG_ReadString( msg ), sizeof( cl.event_precache[0] ));
|
||||
|
||||
@@ -256,15 +256,15 @@ static void CL_LegacyParseResourceList( sizebuf_t *msg )
|
||||
reslist.rescount = MSG_ReadWord( msg ) - 1;
|
||||
|
||||
if( reslist.rescount > MAX_LEGACY_RESOURCES )
|
||||
Host_Error("MAX_RESOURCES reached\n");
|
||||
Host_Error( "MAX_RESOURCES reached\n" );
|
||||
|
||||
for( i = 0; i < reslist.rescount; i++ )
|
||||
{
|
||||
reslist.restype[i] = MSG_ReadWord( msg );
|
||||
Q_strncpy( reslist.resnames[i], MSG_ReadString( msg ), MAX_QPATH );
|
||||
Q_strncpy( reslist.resnames[i], MSG_ReadString( msg ), sizeof( reslist.resnames[i] ));
|
||||
}
|
||||
|
||||
if( CL_IsPlaybackDemo() )
|
||||
if( cls.demoplayback )
|
||||
return;
|
||||
|
||||
if( !cl_allow_download.value )
|
||||
@@ -317,36 +317,19 @@ CL_ParseLegacyServerMessage
|
||||
dispatch messages
|
||||
=====================
|
||||
*/
|
||||
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
{
|
||||
size_t bufStart, playerbytes;
|
||||
int cmd, param1, param2;
|
||||
int old_background;
|
||||
const char *s;
|
||||
|
||||
cls.starting_count = MSG_GetNumBytesRead( msg ); // updates each frame
|
||||
CL_Parse_Debug( true ); // begin parsing
|
||||
|
||||
if( normal_message )
|
||||
{
|
||||
// assume no entity/player update this packet
|
||||
if( cls.state == ca_active )
|
||||
{
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].valid = false;
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
CL_ResetFrame( &cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK] );
|
||||
}
|
||||
}
|
||||
|
||||
// parse the message
|
||||
while( 1 )
|
||||
{
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
{
|
||||
Host_Error( "CL_ParseServerMessage: overflow!\n" );
|
||||
Host_Error( "%s: overflow!\n", __func__ );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -385,7 +368,9 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
{
|
||||
int maxclients = cl.maxclients;
|
||||
|
||||
cls.changelevel = true;
|
||||
// we can only changelevel in singleplayer
|
||||
// and singleplayer always runs in current protocol
|
||||
// cls.changelevel = true;
|
||||
S_StopAllSounds( true );
|
||||
|
||||
Con_Printf( "Server changing, reconnecting\n" );
|
||||
@@ -612,10 +597,10 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
CL_ParseResLocation( msg );
|
||||
break;
|
||||
case svc_querycvarvalue:
|
||||
CL_ParseCvarValue( msg, false );
|
||||
CL_ParseCvarValue( msg, false, PROTO_LEGACY );
|
||||
break;
|
||||
case svc_querycvarvalue2:
|
||||
CL_ParseCvarValue( msg, true );
|
||||
CL_ParseCvarValue( msg, true, PROTO_LEGACY );
|
||||
break;
|
||||
default:
|
||||
CL_ParseUserMessage( msg, cmd );
|
||||
@@ -623,23 +608,6 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cl.frames[cl.parsecountmod].graphdata.msgbytes += MSG_GetNumBytesRead( msg ) - cls.starting_count;
|
||||
CL_Parse_Debug( false ); // done
|
||||
|
||||
// we don't know if it is ok to save a demo message until
|
||||
// after we have parsed the frame
|
||||
if( !cls.demoplayback )
|
||||
{
|
||||
if( cls.demorecording && !cls.demowaiting )
|
||||
{
|
||||
CL_WriteDemoMessage( false, cls.starting_count, msg );
|
||||
}
|
||||
else if( cls.state != ca_active )
|
||||
{
|
||||
CL_WriteDemoMessage( true, cls.starting_count, msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CL_LegacyPrecache_f( void )
|
||||
@@ -664,6 +632,9 @@ void CL_LegacyPrecache_f( void )
|
||||
if( clgame.entities )
|
||||
clgame.entities->model = cl.worldmodel;
|
||||
|
||||
// load skybox
|
||||
R_SetupSky( clgame.movevars.skyName );
|
||||
|
||||
// tell rendering system we have a new set of models.
|
||||
ref.dllFuncs.R_NewMap ();
|
||||
|
||||
@@ -688,19 +659,7 @@ void CL_LegacyPrecache_f( void )
|
||||
cls.signon = SIGNONS;
|
||||
}
|
||||
|
||||
void CL_LegacyUpdateInfo( void )
|
||||
{
|
||||
if( !cls.legacymode )
|
||||
return;
|
||||
|
||||
if( cls.state != ca_active )
|
||||
return;
|
||||
|
||||
MSG_BeginClientCmd( &cls.netchan.message, clc_legacy_userinfo );
|
||||
MSG_WriteString( &cls.netchan.message, cls.userinfo );
|
||||
}
|
||||
|
||||
qboolean CL_LegacyMode( void )
|
||||
{
|
||||
return cls.legacymode;
|
||||
return cls.legacymode == PROTO_LEGACY;
|
||||
}
|
||||
|
||||
@@ -853,7 +853,7 @@ static void CL_SetupPMove( playermove_t *pmove, const local_state_t *from, const
|
||||
VectorCopy( cd->vuser4, pmove->vuser4 );
|
||||
pmove->cmd = *ucmd; // copy current cmds
|
||||
|
||||
Q_strncpy( pmove->physinfo, cls.physinfo, MAX_INFO_STRING );
|
||||
Q_strncpy( pmove->physinfo, cls.physinfo, sizeof( pmove->physinfo ));
|
||||
}
|
||||
|
||||
static const void CL_FinishPMove( const playermove_t *pmove, local_state_t *to )
|
||||
|
||||
@@ -211,7 +211,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
||||
clgame.maxEntities = GI->max_edicts;
|
||||
clgame.maxEntities = bound( 600, clgame.maxEntities, MAX_EDICTS );
|
||||
clgame.maxModels = MAX_MODELS;
|
||||
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), MAX_STRING );
|
||||
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), sizeof( clgame.maptitle ));
|
||||
|
||||
// Re-init hud video, especially if we changed game directories
|
||||
clgame.dllFuncs.pfnVidInit();
|
||||
@@ -620,11 +620,11 @@ static void CL_ParseQuakeDamage( sizebuf_t *msg )
|
||||
|
||||
/*
|
||||
===================
|
||||
CL_ParseQuakeStaticEntity
|
||||
CL_ParseStaticEntity
|
||||
|
||||
===================
|
||||
*/
|
||||
static void CL_ParseQuakeStaticEntity( sizebuf_t *msg )
|
||||
static void CL_ParseStaticEntity( sizebuf_t *msg )
|
||||
{
|
||||
entity_state_t state;
|
||||
cl_entity_t *ent;
|
||||
@@ -646,7 +646,7 @@ static void CL_ParseQuakeStaticEntity( sizebuf_t *msg )
|
||||
i = clgame.numStatics;
|
||||
if( i >= MAX_STATIC_ENTITIES )
|
||||
{
|
||||
Con_Printf( S_ERROR "CL_ParseStaticEntity: static entities limit exceeded!\n" );
|
||||
Con_Printf( S_ERROR "%s: static entities limit exceeded!\n", __func__ );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -697,7 +697,7 @@ static void CL_ParseQuakeBaseline( sizebuf_t *msg )
|
||||
newnum = MSG_ReadWord( msg ); // entnum
|
||||
|
||||
if( newnum >= clgame.maxEntities )
|
||||
Host_Error( "CL_AllocEdict: no free edicts\n" );
|
||||
Host_Error( "%s: no free edicts\n", __func__ );
|
||||
|
||||
// parse baseline
|
||||
memset( &state, 0, sizeof( state ));
|
||||
@@ -778,7 +778,7 @@ static void CL_ParseQuakeSignon( sizebuf_t *msg )
|
||||
int i = MSG_ReadByte( msg );
|
||||
|
||||
if( i == 3 ) cls.signon = SIGNONS - 1;
|
||||
Con_Reportf( "CL_Signon: %d\n", i );
|
||||
Con_Reportf( "%s: %d\n", __func__, i );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -844,7 +844,7 @@ static void CL_QuakeExecStuff( void )
|
||||
while( 1 )
|
||||
{
|
||||
// skip whitespace up to a /n
|
||||
while( *text && ((byte)*text) <= ' ' && *text != '\r' && *text != '\n' )
|
||||
while( *text && ((byte)*text ) <= ' ' && *text != '\r' && *text != '\n' )
|
||||
text++;
|
||||
|
||||
if( *text == '\n' || *text == '\r' )
|
||||
@@ -886,38 +886,21 @@ CL_ParseQuakeMessage
|
||||
|
||||
==================
|
||||
*/
|
||||
void CL_ParseQuakeMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
void CL_ParseQuakeMessage( sizebuf_t *msg )
|
||||
{
|
||||
int cmd, param1, param2;
|
||||
size_t bufStart;
|
||||
const char *str;
|
||||
|
||||
cls.starting_count = MSG_GetNumBytesRead( msg ); // updates each frame
|
||||
CL_Parse_Debug( true ); // begin parsing
|
||||
|
||||
// init excise buffer
|
||||
MSG_Init( &msg_demo, "UserMsg", msg_buf, sizeof( msg_buf ));
|
||||
|
||||
if( normal_message )
|
||||
{
|
||||
// assume no entity/player update this packet
|
||||
if( cls.state == ca_active )
|
||||
{
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].valid = false;
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
CL_ResetFrame( &cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK] );
|
||||
}
|
||||
}
|
||||
|
||||
// parse the message
|
||||
while( 1 )
|
||||
{
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
{
|
||||
Host_Error( "CL_ParseServerMessage: overflow!\n" );
|
||||
Host_Error( "%s: overflow!\n", __func__ );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1022,7 +1005,7 @@ void CL_ParseQuakeMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
CL_ParseQuakeDamage( msg );
|
||||
break;
|
||||
case svc_spawnstatic:
|
||||
CL_ParseQuakeStaticEntity( msg );
|
||||
CL_ParseStaticEntity( msg );
|
||||
break;
|
||||
case svc_spawnbinary:
|
||||
// never used in Quake
|
||||
@@ -1108,14 +1091,11 @@ void CL_ParseQuakeMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Host_Error( "CL_ParseServerMessage: Illegible server message\n" );
|
||||
Host_Error( "%s: Illegible server message\n", __func__ );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cl.frames[cl.parsecountmod].graphdata.msgbytes += MSG_GetNumBytesRead( msg ) - cls.starting_count;
|
||||
CL_Parse_Debug( false ); // done
|
||||
|
||||
// now process packet.
|
||||
CL_ProcessPacket( &cl.frames[cl.parsecountmod] );
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ GNU General Public License for more details.
|
||||
|
||||
int R_FatPVS( const vec3_t org, float radius, byte *visbuffer, qboolean merge, qboolean fullvis )
|
||||
{
|
||||
return Mod_FatPVS( org, radius, visbuffer, world.visbytes, merge, fullvis );
|
||||
return Mod_FatPVS( org, radius, visbuffer, world.visbytes, merge, fullvis, false );
|
||||
}
|
||||
|
||||
lightstyle_t *CL_GetLightStyle( int number )
|
||||
@@ -170,6 +170,12 @@ intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRe
|
||||
return refState.width;
|
||||
case PARM_SCREEN_HEIGHT:
|
||||
return refState.height;
|
||||
case PARM_SKY_SPHERE:
|
||||
return FBitSet( world.flags, FWORLD_SKYSPHERE ) && !FBitSet( world.flags, FWORLD_CUSTOM_SKYBOX );
|
||||
case PARM_SURF_SAMPLESIZE:
|
||||
if( arg >= 0 && arg < cl.worldmodel->numsurfaces )
|
||||
return Mod_SampleSizeForFace( &cl.worldmodel->surfaces[arg] );
|
||||
return LM_SAMPLE_SIZE;
|
||||
default:
|
||||
// indicates call from client.dll
|
||||
if( checkRef )
|
||||
@@ -341,7 +347,7 @@ qboolean R_InitRenderAPI( void )
|
||||
{
|
||||
if( clgame.dllFuncs.pfnGetRenderInterface( CL_RENDER_INTERFACE_VERSION, &gRenderAPI, &clgame.drawFuncs ))
|
||||
{
|
||||
Con_Reportf( "CL_LoadProgs: ^2initailized extended RenderAPI ^7ver. %i\n", CL_RENDER_INTERFACE_VERSION );
|
||||
Con_Reportf( "%s: ^2initailized extended RenderAPI ^7ver. %i\n", __func__, CL_RENDER_INTERFACE_VERSION );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ CVAR_DEFINE_AUTO( scr_centertime, "2.5", 0, "centerprint hold time" );
|
||||
CVAR_DEFINE_AUTO( scr_loading, "0", 0, "loading bar progress" );
|
||||
CVAR_DEFINE_AUTO( scr_download, "-1", 0, "downloading bar progress" );
|
||||
CVAR_DEFINE( scr_viewsize, "viewsize", "120", FCVAR_ARCHIVE, "screen size (quake only)" );
|
||||
CVAR_DEFINE_AUTO( cl_testlights, "0", 0, "test dynamic lights" );
|
||||
CVAR_DEFINE_AUTO( cl_testlights, "0", FCVAR_CHEAT, "test dynamic lights" );
|
||||
CVAR_DEFINE( cl_allow_levelshots, "allow_levelshots", "0", FCVAR_ARCHIVE, "allow engine to use indivdual levelshots instead of 'loading' image" );
|
||||
CVAR_DEFINE_AUTO( cl_levelshot_name, "*black", 0, "contains path to current levelshot" );
|
||||
static CVAR_DEFINE_AUTO( cl_envshot_size, "256", FCVAR_ARCHIVE, "envshot size of cube side" );
|
||||
@@ -32,6 +32,7 @@ CVAR_DEFINE_AUTO( v_dark, "0", 0, "starts level from dark screen" );
|
||||
static CVAR_DEFINE_AUTO( net_speeds, "0", FCVAR_ARCHIVE, "show network packets" );
|
||||
static CVAR_DEFINE_AUTO( cl_showfps, "0", FCVAR_ARCHIVE, "show client fps" );
|
||||
static CVAR_DEFINE_AUTO( cl_showpos, "0", FCVAR_ARCHIVE, "show local player position and velocity" );
|
||||
static CVAR_DEFINE_AUTO( cl_showents, "0", FCVAR_ARCHIVE | FCVAR_CHEAT, "show entities information (largely undone)" );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -122,7 +123,7 @@ void SCR_DrawPos( void )
|
||||
if( cls.state != ca_active || !cl_showpos.value || cl.background )
|
||||
return;
|
||||
|
||||
ent = CL_GetLocalPlayer();
|
||||
ent = CL_EDICT_NUM( cl.playernum + 1 );
|
||||
speed = VectorLength( cl.simvel );
|
||||
|
||||
Q_snprintf( msg, MAX_SYSPATH,
|
||||
@@ -140,6 +141,68 @@ void SCR_DrawPos( void )
|
||||
Con_DrawString( refState.width / 2, 4, msg, color );
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SCR_DrawEnts
|
||||
==============
|
||||
*/
|
||||
void SCR_DrawEnts( void )
|
||||
{
|
||||
rgba_t color = { 255, 255, 255, 255 };
|
||||
int i;
|
||||
|
||||
if( cls.state != ca_active || !cl_showents.value || ( cl.maxclients > 1 && !cls.demoplayback ))
|
||||
return;
|
||||
|
||||
// this probably better hook CL_AddVisibleEntities
|
||||
// as entities might get added by client.dll
|
||||
for( i = 0; i < clgame.maxEntities; i++ )
|
||||
{
|
||||
const cl_entity_t *ent = &clgame.entities[i];
|
||||
string msg;
|
||||
vec3_t screen, pos;
|
||||
|
||||
if( ent->curstate.messagenum != cl.parsecount )
|
||||
continue;
|
||||
|
||||
VectorCopy( ent->origin, pos );
|
||||
|
||||
if( ent->model != NULL )
|
||||
{
|
||||
vec3_t v;
|
||||
|
||||
// simple model type filter
|
||||
if( cl_showents.value > 1 )
|
||||
{
|
||||
if( ent->model->type != (modtype_t)( cl_showents.value - 2 ))
|
||||
continue;
|
||||
}
|
||||
|
||||
VectorAverage( ent->model->mins, ent->model->maxs, v );
|
||||
VectorAdd( pos, v, pos );
|
||||
}
|
||||
|
||||
if( !ref.dllFuncs.WorldToScreen( pos, screen ))
|
||||
{
|
||||
Q_snprintf( msg, sizeof( msg ),
|
||||
"entity %d\n"
|
||||
"model %s\n"
|
||||
"movetype %d\n",
|
||||
ent->index,
|
||||
ent->model ? ent->model->name : "(null)",
|
||||
ent->curstate.movetype );
|
||||
|
||||
screen[0] = 0.5f * screen[0] * refState.width;
|
||||
screen[1] = -0.5f * screen[1] * refState.height;
|
||||
screen[0] += 0.5f * refState.width;
|
||||
screen[1] += 0.5f * refState.height;
|
||||
|
||||
|
||||
Con_DrawString( screen[0], screen[1], msg, color );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SCR_NetSpeeds
|
||||
@@ -345,7 +408,7 @@ void SCR_MakeScreenShot( void )
|
||||
SCR_DrawPlaque
|
||||
================
|
||||
*/
|
||||
static void SCR_DrawPlaque( void )
|
||||
static qboolean SCR_DrawPlaque( void )
|
||||
{
|
||||
if(( cl_allow_levelshots.value && !cls.changelevel ) || cl.background )
|
||||
{
|
||||
@@ -353,7 +416,11 @@ static void SCR_DrawPlaque( void )
|
||||
ref.dllFuncs.GL_SetRenderMode( kRenderNormal );
|
||||
ref.dllFuncs.R_DrawStretchPic( 0, 0, refState.width, refState.height, 0, 0, 1, 1, levelshot );
|
||||
if( !cl.background ) CL_DrawHUD( CL_LOADING );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -363,15 +430,10 @@ SCR_BeginLoadingPlaque
|
||||
*/
|
||||
void SCR_BeginLoadingPlaque( qboolean is_background )
|
||||
{
|
||||
float oldclear = 0;;
|
||||
S_StopAllSounds( true );
|
||||
cl.audio_prepped = false; // don't play ambients
|
||||
cl.video_prepped = false;
|
||||
|
||||
if( !Host_IsDedicated() )
|
||||
oldclear = gl_clear.value;
|
||||
|
||||
if( CL_IsInMenu( ) && !cls.changedemo && !is_background )
|
||||
if( cls.key_dest == key_menu && !cls.changedemo && !is_background )
|
||||
{
|
||||
UI_SetActiveMenu( false );
|
||||
if( cls.state == ca_disconnected && !(GameState->curstate == STATE_RUNFRAME && GameState->nextstate != STATE_RUNFRAME) )
|
||||
@@ -384,18 +446,15 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
|
||||
if( cls.key_dest == key_console )
|
||||
return;
|
||||
|
||||
if( !Host_IsDedicated() )
|
||||
gl_clear.value = 0.0f;
|
||||
|
||||
if( is_background ) IN_MouseSavePos( );
|
||||
cls.draw_changelevel = !is_background;
|
||||
SCR_UpdateScreen();
|
||||
|
||||
// set video_prepped after update screen, so engine can draw last remaining frame
|
||||
cl.video_prepped = false;
|
||||
cls.disable_screen = host.realtime;
|
||||
cl.background = is_background; // set right state before svc_serverdata is came
|
||||
|
||||
if( !Host_IsDedicated() )
|
||||
gl_clear.value = oldclear;
|
||||
|
||||
// SNDDMA_LockSound();
|
||||
}
|
||||
|
||||
@@ -445,7 +504,7 @@ void SCR_TileClear( void )
|
||||
int i, top, bottom, left, right;
|
||||
dirty_t clear;
|
||||
|
||||
if( scr_viewsize.value >= 120 )
|
||||
if( likely( scr_viewsize.value >= 120 ))
|
||||
return; // full screen rendering
|
||||
|
||||
// erase rect will be the union of the past three frames
|
||||
@@ -523,6 +582,8 @@ text to the screen.
|
||||
*/
|
||||
void SCR_UpdateScreen( void )
|
||||
{
|
||||
qboolean screen_redraw = true; // assume screen has been redrawn
|
||||
|
||||
if( !V_PreRender( )) return;
|
||||
|
||||
switch( cls.state )
|
||||
@@ -533,7 +594,7 @@ void SCR_UpdateScreen( void )
|
||||
case ca_connecting:
|
||||
case ca_connected:
|
||||
case ca_validate:
|
||||
SCR_DrawPlaque();
|
||||
screen_redraw = SCR_DrawPlaque();
|
||||
break;
|
||||
case ca_active:
|
||||
Con_RunConsole ();
|
||||
@@ -543,11 +604,15 @@ void SCR_UpdateScreen( void )
|
||||
SCR_DrawCinematic();
|
||||
break;
|
||||
default:
|
||||
Host_Error( "SCR_UpdateScreen: bad cls.state\n" );
|
||||
Host_Error( "%s: bad cls.state\n", __func__ );
|
||||
break;
|
||||
}
|
||||
|
||||
V_PostRender();
|
||||
// during changelevel we might have a few frames when we have nothing to draw
|
||||
// (assuming levelshots are off) and drawing 2d on top of nothing or cleared screen
|
||||
// is ugly, specifically with Adreno and ImgTec GPUs
|
||||
if( screen_redraw || !cls.changelevel || !cls.changedemo )
|
||||
V_PostRender();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -753,6 +818,9 @@ void SCR_Init( void )
|
||||
Cvar_RegisterVariable( &net_speeds );
|
||||
Cvar_RegisterVariable( &cl_showfps );
|
||||
Cvar_RegisterVariable( &cl_showpos );
|
||||
#ifdef _DEBUG
|
||||
Cvar_RegisterVariable( &cl_showents );
|
||||
#endif // NDEBUG
|
||||
|
||||
// register our commands
|
||||
Cmd_AddCommand( "skyname", CL_SetSky_f, "set new skybox by basename" );
|
||||
|
||||
@@ -1904,7 +1904,7 @@ void CL_ParseTempEntity( sizebuf_t *msg )
|
||||
|
||||
// this will probably be fatal anyway
|
||||
if( iSize > sizeof( pbuf ))
|
||||
Con_Printf( S_ERROR "%s: Temp buffer overflow!\n", __FUNCTION__ );
|
||||
Con_Printf( S_ERROR "%s: Temp buffer overflow!\n", __func__ );
|
||||
|
||||
// parse user message into buffer
|
||||
MSG_ReadBytes( msg, pbuf, iSize );
|
||||
@@ -2384,13 +2384,13 @@ void CL_ParseTempEntity( sizebuf_t *msg )
|
||||
R_UserTracerParticle( pos, pos2, life, color, scale, 0, NULL );
|
||||
break;
|
||||
default:
|
||||
Con_DPrintf( S_ERROR "ParseTempEntity: illegible TE message %i\n", type );
|
||||
Con_DPrintf( S_ERROR "%s: illegible TE message %i\n", __func__, type );
|
||||
break;
|
||||
}
|
||||
|
||||
// throw warning
|
||||
if( MSG_CheckOverflow( &buf ))
|
||||
Con_DPrintf( S_WARN "ParseTempEntity: overflow TE message %i\n", type );
|
||||
Con_DPrintf( S_WARN "%s: overflow TE message %i\n", __func__, type );
|
||||
}
|
||||
|
||||
|
||||
@@ -2927,16 +2927,26 @@ static void CL_PlayerDecal( int playernum, int customIndex, int entityIndex, flo
|
||||
{
|
||||
if( !pCust->nUserData1 )
|
||||
{
|
||||
int sprayTextureIndex;
|
||||
char decalname[MAX_VA_STRING];
|
||||
int width, height;
|
||||
|
||||
Q_snprintf( decalname, sizeof( decalname ), "player%dlogo%d", playernum, customIndex );
|
||||
sprayTextureIndex = ref.dllFuncs.GL_FindTexture( decalname );
|
||||
if( sprayTextureIndex != 0 )
|
||||
{
|
||||
ref.dllFuncs.GL_FreeTexture( sprayTextureIndex );
|
||||
}
|
||||
textureIndex = ref.dllFuncs.GL_FindTexture( decalname );
|
||||
if( textureIndex != 0 )
|
||||
ref.dllFuncs.GL_FreeTexture( textureIndex );
|
||||
|
||||
pCust->nUserData1 = GL_LoadTextureInternal( decalname, pCust->pInfo, TF_DECAL );
|
||||
|
||||
width = REF_GET_PARM( PARM_TEX_WIDTH, pCust->nUserData1 );
|
||||
height = REF_GET_PARM( PARM_TEX_HEIGHT, pCust->nUserData1 );
|
||||
|
||||
if( width > cl_logomaxdim.value || height > cl_logomaxdim.value )
|
||||
{
|
||||
double scale = cl_logomaxdim.value / Q_max( width, height );
|
||||
width = round( width * scale );
|
||||
height = round( height * scale );
|
||||
ref.dllFuncs.R_OverrideTextureSourceSize( pCust->nUserData1, width, height ); // default custom decal from HL1
|
||||
}
|
||||
}
|
||||
textureIndex = pCust->nUserData1;
|
||||
}
|
||||
@@ -2981,8 +2991,47 @@ int GAME_EXPORT CL_DecalIndex( int id )
|
||||
|
||||
if( cl.decal_index[id] == 0 )
|
||||
{
|
||||
int gl_texturenum = 0;
|
||||
|
||||
Image_SetForceFlags( IL_LOAD_DECAL );
|
||||
cl.decal_index[id] = ref.dllFuncs.GL_LoadTexture( host.draw_decals[id], NULL, 0, TF_DECAL );
|
||||
|
||||
if( Mod_AllowMaterials( ))
|
||||
{
|
||||
string decalname;
|
||||
|
||||
if( Q_snprintf( decalname, sizeof( decalname ), "materials/decals/%s.tga", host.draw_decals[id] ) > 0 )
|
||||
{
|
||||
if( g_fsapi.FileExists( decalname, false ))
|
||||
{
|
||||
gl_texturenum = ref.dllFuncs.GL_LoadTexture( decalname, NULL, 0, TF_DECAL );
|
||||
if( host_allow_materials.value == 2.0f )
|
||||
Con_Printf( "Looking for %s decal replacement...%s (%s)\n", host.draw_decals[id], gl_texturenum != 0 ? S_GREEN "OK" : S_RED "FAIL", decalname );
|
||||
}
|
||||
else if( host_allow_materials.value == 2.0f )
|
||||
Con_Printf( "Looking for %s decal replacement..." S_YELLOW "MISS (%s)\n", host.draw_decals[id], decalname );
|
||||
}
|
||||
else if( host_allow_materials.value == 2.0f )
|
||||
Con_Printf( "Looking for %s decal replacement..." S_YELLOW "MISS (overflow)\n", host.draw_decals[id] );
|
||||
|
||||
if( gl_texturenum )
|
||||
{
|
||||
byte *fin;
|
||||
|
||||
Q_snprintf( decalname, sizeof( decalname ), "decals.wad/%s", host.draw_decals[id] );
|
||||
|
||||
if(( fin = g_fsapi.LoadFile( decalname, NULL, false )) != NULL )
|
||||
{
|
||||
mip_t *mip = (mip_t *)fin;
|
||||
ref.dllFuncs.R_OverrideTextureSourceSize( gl_texturenum, mip->width, mip->height );
|
||||
Mem_Free( fin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !gl_texturenum )
|
||||
gl_texturenum = ref.dllFuncs.GL_LoadTexture( host.draw_decals[id], NULL, 0, TF_DECAL );
|
||||
|
||||
cl.decal_index[id] = gl_texturenum;
|
||||
Image_ClearForceFlags();
|
||||
}
|
||||
|
||||
|
||||
@@ -341,7 +341,7 @@ qboolean V_PreRender( void )
|
||||
{
|
||||
if(( host.realtime - cls.disable_screen ) > cl_timeout.value )
|
||||
{
|
||||
Con_Reportf( "V_PreRender: loading plaque timed out\n" );
|
||||
Con_Reportf( "%s: loading plaque timed out\n", __func__ );
|
||||
cls.disable_screen = 0.0f;
|
||||
}
|
||||
return false;
|
||||
@@ -506,7 +506,6 @@ V_PostRender
|
||||
*/
|
||||
void V_PostRender( void )
|
||||
{
|
||||
static double oldtime;
|
||||
qboolean draw_2d = false;
|
||||
|
||||
ref.dllFuncs.R_AllowFog( false );
|
||||
@@ -533,6 +532,7 @@ void V_PostRender( void )
|
||||
SCR_RSpeeds();
|
||||
SCR_NetSpeeds();
|
||||
SCR_DrawPos();
|
||||
SCR_DrawEnts();
|
||||
SCR_DrawNetGraph();
|
||||
SV_DrawOrthoTriangles();
|
||||
CL_DrawDemoRecording();
|
||||
|
||||
@@ -229,7 +229,7 @@ typedef struct
|
||||
char serverinfo[MAX_SERVERINFO_STRING];
|
||||
player_info_t players[MAX_CLIENTS]; // collected info about all other players include himself
|
||||
double lastresourcecheck;
|
||||
string downloadUrl;
|
||||
qboolean http_download;
|
||||
event_state_t events;
|
||||
|
||||
// predicting stuff but not only...
|
||||
@@ -276,6 +276,8 @@ typedef struct
|
||||
model_t *worldmodel; // pointer to world
|
||||
|
||||
int lostpackets; // count lost packets and show dialog in menu
|
||||
|
||||
double frametime_remainder;
|
||||
} client_t;
|
||||
|
||||
/*
|
||||
@@ -307,6 +309,14 @@ typedef enum
|
||||
CL_CHANGELEVEL, // draw 'loading' during changelevel
|
||||
} scrstate_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PROTO_CURRENT = 0, // Xash3D 49
|
||||
PROTO_LEGACY = 1, // Xash3D 48
|
||||
PROTO_QUAKE = 2, // Quake 15
|
||||
PROTO_GOLDSRC = 3, // GoldSrc 48
|
||||
} connprotocol_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[32];
|
||||
@@ -518,7 +528,7 @@ typedef struct
|
||||
int logo_yres;
|
||||
float logo_length;
|
||||
|
||||
qboolean use_text_api;
|
||||
qboolean use_extended_api;
|
||||
} gameui_static_t;
|
||||
|
||||
typedef struct
|
||||
@@ -539,12 +549,8 @@ typedef struct
|
||||
|
||||
poolhandle_t mempool; // client premamnent pool: edicts etc
|
||||
|
||||
netadr_t hltv_listen_address;
|
||||
|
||||
int signon; // 0 to SIGNONS, for the signon sequence.
|
||||
int quakePort; // a 16 bit value that allows quake servers
|
||||
// to work around address translating routers
|
||||
// g-cont. this port allow many copies of engine in multiplayer game
|
||||
|
||||
// connection information
|
||||
char servername[MAX_QPATH]; // name of server from original connect
|
||||
double connect_time; // for connection retransmits
|
||||
@@ -628,12 +634,14 @@ typedef struct
|
||||
char internetservers_query[512]; // cached query
|
||||
uint32_t internetservers_query_len;
|
||||
|
||||
// legacy mode support
|
||||
qboolean legacymode; // one-way 48 protocol compatibility
|
||||
netadr_t legacyserver;
|
||||
// multiprotocol support
|
||||
connprotocol_t legacymode;
|
||||
int extensions;
|
||||
|
||||
netadr_t serveradr;
|
||||
|
||||
// do we accept utf8 as input
|
||||
qboolean accept_utf8;
|
||||
} client_static_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -653,14 +661,11 @@ extern gameui_static_t gameui;
|
||||
// cvars
|
||||
//
|
||||
extern convar_t mp_decals;
|
||||
extern convar_t cl_logofile;
|
||||
extern convar_t cl_logocolor;
|
||||
extern convar_t cl_logomaxdim;
|
||||
extern convar_t cl_allow_download;
|
||||
extern convar_t cl_allow_upload;
|
||||
extern convar_t cl_download_ingame;
|
||||
extern convar_t cl_nopred;
|
||||
extern convar_t cl_timeout;
|
||||
extern convar_t cl_nodelta;
|
||||
extern convar_t cl_interp;
|
||||
extern convar_t cl_nointerp;
|
||||
extern convar_t cl_showerror;
|
||||
@@ -673,13 +678,11 @@ extern convar_t cl_updaterate;
|
||||
extern convar_t cl_solid_players;
|
||||
extern convar_t cl_idealpitchscale;
|
||||
extern convar_t cl_allow_levelshots;
|
||||
extern convar_t cl_lightstyle_lerping;
|
||||
extern convar_t cl_draw_particles;
|
||||
extern convar_t cl_draw_tracers;
|
||||
extern convar_t cl_levelshot_name;
|
||||
extern convar_t cl_draw_beams;
|
||||
extern convar_t cl_clockreset;
|
||||
extern convar_t cl_fixtimerate;
|
||||
extern convar_t hud_fontscale;
|
||||
extern convar_t hud_fontrender;
|
||||
extern convar_t hud_scale;
|
||||
@@ -849,14 +852,14 @@ _inline cl_entity_t *CL_EDICT_NUM( int n )
|
||||
{
|
||||
if( !clgame.entities )
|
||||
{
|
||||
Host_Error( "CL_EDICT_NUM: clgame.entities is NULL\n");
|
||||
Host_Error( "%s: clgame.entities is NULL\n", __func__ );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(( n >= 0 ) && ( n < clgame.maxEntities ))
|
||||
return clgame.entities + n;
|
||||
|
||||
Host_Error( "CL_EDICT_NUM: bad number %i\n", n );
|
||||
Host_Error( "%s: bad number %i\n", __func__, n );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -887,8 +890,8 @@ void CL_ParseFileTransferFailed( sizebuf_t *msg );
|
||||
void CL_ParseHLTV( sizebuf_t *msg );
|
||||
void CL_ParseDirector( sizebuf_t *msg );
|
||||
void CL_ParseResLocation( sizebuf_t *msg );
|
||||
void CL_ParseCvarValue( sizebuf_t *msg, const qboolean ext );
|
||||
void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message );
|
||||
void CL_ParseCvarValue( sizebuf_t *msg, const qboolean ext, const connprotocol_t proto );
|
||||
void CL_ParseServerMessage( sizebuf_t *msg );
|
||||
void CL_ParseTempEntity( sizebuf_t *msg );
|
||||
qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf );
|
||||
qboolean CL_RequestMissingResources( void );
|
||||
@@ -904,7 +907,7 @@ int CL_EstimateNeededResources( void );
|
||||
//
|
||||
// cl_parse_48.c
|
||||
//
|
||||
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message );
|
||||
void CL_ParseLegacyServerMessage( sizebuf_t *msg );
|
||||
void CL_LegacyPrecache_f( void );
|
||||
|
||||
//
|
||||
@@ -922,6 +925,7 @@ void SCR_NetSpeeds( void );
|
||||
void SCR_RSpeeds( void );
|
||||
void SCR_DrawFPS( int height );
|
||||
void SCR_DrawPos( void );
|
||||
void SCR_DrawEnts( void );
|
||||
|
||||
//
|
||||
// cl_netgraph.c
|
||||
@@ -963,7 +967,7 @@ void CL_SetIdealPitch( void );
|
||||
//
|
||||
// cl_qparse.c
|
||||
//
|
||||
void CL_ParseQuakeMessage( sizebuf_t *msg, qboolean normal_message );
|
||||
void CL_ParseQuakeMessage( sizebuf_t *msg );
|
||||
|
||||
//
|
||||
// cl_frame.c
|
||||
@@ -1056,7 +1060,6 @@ int Con_UtfMoveRight( char *str, int pos, int length );
|
||||
void Con_DefaultColor( int r, int g, int b, qboolean gameui );
|
||||
cl_font_t *Con_GetCurFont( void );
|
||||
cl_font_t *Con_GetFont( int num );
|
||||
void Con_DrawCharacterLen( int number, int *width, int *height );
|
||||
int Con_DrawString( int x, int y, const char *string, rgba_t setColor ); // legacy, use cl_font.c
|
||||
void GAME_EXPORT Con_DrawStringLen( const char *pText, int *length, int *height ); // legacy, use cl_font.c
|
||||
void Con_CharEvent( int key );
|
||||
@@ -1107,7 +1110,7 @@ qboolean UI_MouseInRect( void );
|
||||
qboolean UI_IsVisible( void );
|
||||
void UI_ResetPing( void );
|
||||
void UI_ShowUpdateDialog( qboolean preferStore );
|
||||
void UI_ShowMessageBox( const char *text );
|
||||
qboolean UI_ShowMessageBox( const char *text );
|
||||
void UI_AddTouchButtonToList( const char *name, const char *texture, const char *command, unsigned char *color, int flags );
|
||||
void UI_ConnectionProgress_Disconnect( void );
|
||||
void UI_ConnectionProgress_Download( const char *pszFileName, const char *pszServerName, const char *pszServerPath, int iCurrent, int iTotal, const char *comment );
|
||||
@@ -1161,5 +1164,7 @@ int Key_ToUpper( int key );
|
||||
void OSK_Draw( void );
|
||||
|
||||
extern rgba_t g_color_table[8];
|
||||
extern triangleapi_t gTriApi;
|
||||
extern net_api_t gNetApi;
|
||||
|
||||
#endif//CLIENT_H
|
||||
|
||||
@@ -21,6 +21,7 @@ GNU General Public License for more details.
|
||||
#include "qfont.h"
|
||||
#include "wadfile.h"
|
||||
#include "input.h"
|
||||
#include "utflib.h"
|
||||
|
||||
static CVAR_DEFINE_AUTO( scr_conspeed, "600", FCVAR_ARCHIVE, "console moving speed" );
|
||||
static CVAR_DEFINE_AUTO( con_notifytime, "3", FCVAR_ARCHIVE, "notify time to live" );
|
||||
@@ -34,7 +35,6 @@ static CVAR_DEFINE_AUTO( scr_drawversion, "1", FCVAR_ARCHIVE, "draw version in m
|
||||
static CVAR_DEFINE_AUTO( con_oldfont, "0", 0, "use legacy font from gfx.wad, might be missing or broken" );
|
||||
|
||||
static int g_codepage = 0;
|
||||
static qboolean g_utf8 = false;
|
||||
|
||||
static qboolean g_messagemode_privileged = true;
|
||||
|
||||
@@ -610,19 +610,6 @@ static void Con_LoadConchars( void )
|
||||
con.curFont = &con.chars[fontSize];
|
||||
}
|
||||
|
||||
// CP1251 table
|
||||
|
||||
int table_cp1251[64] = {
|
||||
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
|
||||
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x007F, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
|
||||
0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
|
||||
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
|
||||
0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457
|
||||
};
|
||||
|
||||
/*
|
||||
============================
|
||||
Con_UtfProcessChar
|
||||
@@ -632,84 +619,28 @@ Convert utf char to current font's single-byte encoding
|
||||
*/
|
||||
int Con_UtfProcessCharForce( int in )
|
||||
{
|
||||
static int m = -1, k = 0; //multibyte state
|
||||
static int uc = 0; //unicode char
|
||||
// TODO: get rid of global state where possible
|
||||
static utfstate_t state = { 0 };
|
||||
|
||||
if( !in )
|
||||
{
|
||||
m = -1;
|
||||
k = 0;
|
||||
uc = 0;
|
||||
return 0;
|
||||
}
|
||||
int ch = Q_DecodeUTF8( &state, in );
|
||||
|
||||
// Get character length
|
||||
if(m == -1)
|
||||
{
|
||||
uc = 0;
|
||||
if( in >= 0xF8 )
|
||||
return 0;
|
||||
else if( in >= 0xF0 )
|
||||
uc = in & 0x07, m = 3;
|
||||
else if( in >= 0xE0 )
|
||||
uc = in & 0x0F, m = 2;
|
||||
else if( in >= 0xC0 )
|
||||
uc = in & 0x1F, m = 1;
|
||||
else if( in <= 0x7F)
|
||||
return in; //ascii
|
||||
// return 0 if we need more chars to decode one
|
||||
k=0;
|
||||
return 0;
|
||||
}
|
||||
// get more chars
|
||||
else if( k <= m )
|
||||
{
|
||||
uc <<= 6;
|
||||
uc += in & 0x3F;
|
||||
k++;
|
||||
}
|
||||
if( in > 0xBF || m < 0 )
|
||||
{
|
||||
m = -1;
|
||||
return 0;
|
||||
}
|
||||
if( k == m )
|
||||
{
|
||||
k = m = -1;
|
||||
if( g_codepage == 1251 )
|
||||
{
|
||||
// cp1251 now
|
||||
if( uc >= 0x0410 && uc <= 0x042F )
|
||||
return uc - 0x410 + 0xC0;
|
||||
if( uc >= 0x0430 && uc <= 0x044F )
|
||||
return uc - 0x430 + 0xE0;
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < 64; i++ )
|
||||
if( table_cp1251[i] == uc )
|
||||
return i + 0x80;
|
||||
}
|
||||
}
|
||||
else if( g_codepage == 1252 )
|
||||
{
|
||||
if( uc < 255 )
|
||||
return uc;
|
||||
}
|
||||
if( g_codepage == 1251 )
|
||||
return Q_UnicodeToCP1251( ch );
|
||||
if( g_codepage == 1252 )
|
||||
return Q_UnicodeToCP1252( ch );
|
||||
|
||||
// not implemented yet
|
||||
return '?';
|
||||
}
|
||||
return 0;
|
||||
return '?'; // not implemented yet
|
||||
}
|
||||
|
||||
int GAME_EXPORT Con_UtfProcessChar( int in )
|
||||
{
|
||||
if( !g_utf8 )
|
||||
if( !cls.accept_utf8 ) // incoming character is not a UTF-8 sequence
|
||||
return in;
|
||||
else
|
||||
return Con_UtfProcessCharForce( in );
|
||||
|
||||
// otherwise, decode it and convert to selected codepage
|
||||
return Con_UtfProcessCharForce( in );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Con_UtfMoveLeft
|
||||
@@ -719,16 +650,22 @@ get position of previous printful char
|
||||
*/
|
||||
int Con_UtfMoveLeft( char *str, int pos )
|
||||
{
|
||||
int i, k = 0;
|
||||
// int j;
|
||||
if( !g_utf8 )
|
||||
utfstate_t state = { 0 };
|
||||
int k = 0;
|
||||
int i;
|
||||
|
||||
if( !cls.accept_utf8 ) // incoming character is not a UTF-8 sequence
|
||||
return pos - 1;
|
||||
Con_UtfProcessChar( 0 );
|
||||
if(pos == 1) return 0;
|
||||
for( i = 0; i < pos-1; i++ )
|
||||
if( Con_UtfProcessChar( (unsigned char)str[i] ) )
|
||||
k = i+1;
|
||||
Con_UtfProcessChar( 0 );
|
||||
|
||||
if( pos == 1 )
|
||||
return 0;
|
||||
|
||||
for( i = 0; i < pos - 1; i++ )
|
||||
{
|
||||
if( Q_DecodeUTF8( &state, (byte)str[i] ))
|
||||
k = i + 1;
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
@@ -741,17 +678,19 @@ get next of previous printful char
|
||||
*/
|
||||
int Con_UtfMoveRight( char *str, int pos, int length )
|
||||
{
|
||||
utfstate_t state = { 0 };
|
||||
int i;
|
||||
if( !g_utf8 )
|
||||
|
||||
if( !cls.accept_utf8 ) // incoming character is not a UTF-8 sequence
|
||||
return pos + 1;
|
||||
Con_UtfProcessChar( 0 );
|
||||
|
||||
for( i = pos; i <= length; i++ )
|
||||
{
|
||||
if( Con_UtfProcessChar( (unsigned char)str[i] ) )
|
||||
return i+1;
|
||||
if( Q_DecodeUTF8( &state, (byte)str[i] ))
|
||||
return i + 1;
|
||||
}
|
||||
Con_UtfProcessChar( 0 );
|
||||
return pos+1;
|
||||
|
||||
return pos + 1;
|
||||
}
|
||||
|
||||
static void Con_DrawCharToConback( int num, const byte *conchars, byte *dest )
|
||||
@@ -908,7 +847,6 @@ void Con_Print( const char *txt )
|
||||
static char buf[MAX_PRINT_MSG];
|
||||
qboolean norefresh = false;
|
||||
static int lastlength = 0;
|
||||
static qboolean inupdate;
|
||||
static int bufpos = 0;
|
||||
int c, mask = 0;
|
||||
|
||||
@@ -999,6 +937,27 @@ void Con_Print( const char *txt )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Con_NXPrintfv
|
||||
|
||||
Draw a single debug line with specified height, color and time to live
|
||||
================
|
||||
*/
|
||||
static void Con_NXPrintfv( keydest_t key_dest, const con_nprint_t *info, const char *fmt, va_list va )
|
||||
{
|
||||
if( info->index < 0 || info->index >= ARRAYSIZE( con.notify ))
|
||||
return;
|
||||
|
||||
Q_vsnprintf( con.notify[info->index].szNotify, sizeof( con.notify[info->index].szNotify ), fmt, va );
|
||||
|
||||
// setup values
|
||||
con.notify[info->index].key_dest = key_dest;
|
||||
con.notify[info->index].expire = host.realtime + info->time_to_live;
|
||||
MakeRGBA( con.notify[info->index].color, (byte)(info->color[0] * 255), (byte)(info->color[1] * 255), (byte)(info->color[2] * 255), 255 );
|
||||
con.draw_notify = true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Con_NPrint
|
||||
@@ -1009,21 +968,16 @@ Draw a single debug line with specified height
|
||||
void GAME_EXPORT Con_NPrintf( int idx, const char *fmt, ... )
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if( idx < 0 || idx >= MAX_DBG_NOTIFY )
|
||||
return;
|
||||
|
||||
memset( con.notify[idx].szNotify, 0, MAX_STRING );
|
||||
con_nprint_t info =
|
||||
{
|
||||
.index = idx,
|
||||
.time_to_live = 4.0f,
|
||||
.color = { 1.0f, 1.0f, 1.0f },
|
||||
};
|
||||
|
||||
va_start( args, fmt );
|
||||
Q_vsnprintf( con.notify[idx].szNotify, MAX_STRING, fmt, args );
|
||||
Con_NXPrintfv( key_game, &info, fmt, args );
|
||||
va_end( args );
|
||||
|
||||
// reset values
|
||||
con.notify[idx].key_dest = key_game;
|
||||
con.notify[idx].expire = host.realtime + 4.0f;
|
||||
MakeRGBA( con.notify[idx].color, 255, 255, 255, 255 );
|
||||
con.draw_notify = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1039,20 +993,9 @@ void GAME_EXPORT Con_NXPrintf( con_nprint_t *info, const char *fmt, ... )
|
||||
|
||||
if( !info ) return;
|
||||
|
||||
if( info->index < 0 || info->index >= MAX_DBG_NOTIFY )
|
||||
return;
|
||||
|
||||
memset( con.notify[info->index].szNotify, 0, MAX_STRING );
|
||||
|
||||
va_start( args, fmt );
|
||||
Q_vsnprintf( con.notify[info->index].szNotify, MAX_STRING, fmt, args );
|
||||
Con_NXPrintfv( key_game, info, fmt, args );
|
||||
va_end( args );
|
||||
|
||||
// setup values
|
||||
con.notify[info->index].key_dest = key_game;
|
||||
con.notify[info->index].expire = host.realtime + info->time_to_live;
|
||||
MakeRGBA( con.notify[info->index].color, (byte)(info->color[0] * 255), (byte)(info->color[1] * 255), (byte)(info->color[2] * 255), 255 );
|
||||
con.draw_notify = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1065,21 +1008,16 @@ Draw a single debug line with specified height (menu version)
|
||||
void GAME_EXPORT UI_NPrintf( int idx, const char *fmt, ... )
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if( idx < 0 || idx >= MAX_DBG_NOTIFY )
|
||||
return;
|
||||
|
||||
memset( con.notify[idx].szNotify, 0, MAX_STRING );
|
||||
con_nprint_t info =
|
||||
{
|
||||
.index = idx,
|
||||
.time_to_live = 4.0f,
|
||||
.color = { 1.0f, 1.0f, 1.0f },
|
||||
};
|
||||
|
||||
va_start( args, fmt );
|
||||
Q_vsnprintf( con.notify[idx].szNotify, MAX_STRING, fmt, args );
|
||||
Con_NXPrintfv( key_menu, &info, fmt, args );
|
||||
va_end( args );
|
||||
|
||||
// reset values
|
||||
con.notify[idx].key_dest = key_menu;
|
||||
con.notify[idx].expire = host.realtime + 4.0f;
|
||||
MakeRGBA( con.notify[idx].color, 255, 255, 255, 255 );
|
||||
con.draw_notify = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1095,20 +1033,9 @@ void GAME_EXPORT UI_NXPrintf( con_nprint_t *info, const char *fmt, ... )
|
||||
|
||||
if( !info ) return;
|
||||
|
||||
if( info->index < 0 || info->index >= MAX_DBG_NOTIFY )
|
||||
return;
|
||||
|
||||
memset( con.notify[info->index].szNotify, 0, MAX_STRING );
|
||||
|
||||
va_start( args, fmt );
|
||||
Q_vsnprintf( con.notify[info->index].szNotify, MAX_STRING, fmt, args );
|
||||
Con_NXPrintfv( key_menu, info, fmt, args );
|
||||
va_end( args );
|
||||
|
||||
// setup values
|
||||
con.notify[info->index].key_dest = key_menu;
|
||||
con.notify[info->index].expire = host.realtime + info->time_to_live;
|
||||
MakeRGBA( con.notify[info->index].color, (byte)(info->color[0] * 255), (byte)(info->color[1] * 255), (byte)(info->color[2] * 255), 255 );
|
||||
con.draw_notify = true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1138,7 +1065,7 @@ Field_Set
|
||||
static void Field_Set( field_t *f, const char *string )
|
||||
{
|
||||
f->scroll = 0;
|
||||
f->cursor = Q_strncpy( f->buffer, string, MAX_STRING );
|
||||
f->cursor = Q_strncpy( f->buffer, string, sizeof( f->buffer ));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1507,7 +1434,15 @@ static void Con_SaveHistory( con_history_t *self )
|
||||
f = FS_Open( "console_history.txt", "wb", true );
|
||||
|
||||
for( i = historyStart; i < self->next; i++ )
|
||||
FS_Printf( f, "%s\n", self->lines[i % CON_HISTORY].buffer );
|
||||
{
|
||||
const char *s = self->lines[i % CON_HISTORY].buffer;
|
||||
|
||||
// HACKHACK: don't save lines that have something that looks like a password
|
||||
if( Q_stristr( s, "password" ) || Q_stristr( s, "_pw" ))
|
||||
continue;
|
||||
|
||||
FS_Printf( f, "%s\n", s );
|
||||
}
|
||||
|
||||
FS_Close( f );
|
||||
}
|
||||
@@ -1549,6 +1484,9 @@ void Key_Console( int key )
|
||||
Con_Printf( ">%s\n", con.input.buffer );
|
||||
|
||||
// copy line to history buffer
|
||||
// just in case, remove all CR and LF characters pushing it to the history
|
||||
// not sure how they get even added in the first place
|
||||
COM_RemoveLineFeed( con.input.buffer, sizeof( con.input.buffer ));
|
||||
Con_HistoryAppend( &con.history, &con.input );
|
||||
|
||||
Con_ClearField( &con.input );
|
||||
@@ -2157,7 +2095,7 @@ void Con_RunConsole( void )
|
||||
g_codepage = 1252;
|
||||
}
|
||||
|
||||
g_utf8 = !Q_stricmp( cl_charset.string, "utf-8" );
|
||||
cls.accept_utf8 = !Q_stricmp( cl_charset.string, "utf-8" );
|
||||
Con_InvalidateFonts();
|
||||
Con_LoadConchars();
|
||||
ClearBits( con_charset.flags, FCVAR_CHANGED );
|
||||
@@ -2195,6 +2133,34 @@ void Con_CharEvent( int key )
|
||||
}
|
||||
}
|
||||
|
||||
static int Con_LoadSimpleConback( const char *name, int flags )
|
||||
{
|
||||
const char *paths[] = {
|
||||
"gfx/shell/%s.dds",
|
||||
"gfx/shell/%s.bmp",
|
||||
"gfx/shell/%s.tga",
|
||||
"cached/%s640",
|
||||
"cached/%s",
|
||||
};
|
||||
size_t i;
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( paths ); i++ )
|
||||
{
|
||||
string path;
|
||||
|
||||
Q_snprintf( path, sizeof( path ), paths[i], name );
|
||||
if( g_fsapi.FileExists( path, false ))
|
||||
{
|
||||
int gl_texturenum = ref.dllFuncs.GL_LoadTexture( path, NULL, 0, flags );
|
||||
|
||||
if( gl_texturenum )
|
||||
return gl_texturenum;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=========
|
||||
Con_VidInit
|
||||
@@ -2217,38 +2183,12 @@ void Con_VidInit( void )
|
||||
|
||||
Con_LoadConchars();
|
||||
Con_CheckResize();
|
||||
|
||||
#if XASH_LOW_MEMORY
|
||||
con.background = R_GetBuiltinTexture( REF_BLACK_TEXTURE );
|
||||
con.background = R_GetBuiltinTexture( REF_GRAY_TEXTURE );
|
||||
#else
|
||||
// loading console image
|
||||
if( host.allow_console )
|
||||
{
|
||||
// trying to load truecolor image first
|
||||
if( FS_FileExists( "gfx/shell/conback.bmp", false ) || FS_FileExists( "gfx/shell/conback.tga", false ))
|
||||
con.background = ref.dllFuncs.GL_LoadTexture( "gfx/shell/conback", NULL, 0, flags );
|
||||
|
||||
if( !con.background )
|
||||
{
|
||||
if( FS_FileExists( "cached/conback640", false ))
|
||||
con.background = ref.dllFuncs.GL_LoadTexture( "cached/conback640", NULL, 0, flags );
|
||||
else if( FS_FileExists( "cached/conback", false ))
|
||||
con.background = ref.dllFuncs.GL_LoadTexture( "cached/conback", NULL, 0, flags );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// trying to load truecolor image first
|
||||
if( FS_FileExists( "gfx/shell/loading.bmp", false ) || FS_FileExists( "gfx/shell/loading.tga", false ))
|
||||
con.background = ref.dllFuncs.GL_LoadTexture( "gfx/shell/loading", NULL, 0, flags );
|
||||
|
||||
if( !con.background )
|
||||
{
|
||||
if( FS_FileExists( "cached/loading640", false ))
|
||||
con.background = ref.dllFuncs.GL_LoadTexture( "cached/loading640", NULL, 0, flags );
|
||||
else if( FS_FileExists( "cached/loading", false ))
|
||||
con.background = ref.dllFuncs.GL_LoadTexture( "cached/loading", NULL, 0, flags );
|
||||
}
|
||||
}
|
||||
con.background = Con_LoadSimpleConback( host.allow_console ? "conback" : "loading", flags );
|
||||
|
||||
if( !con.background ) // last chance - quake conback image
|
||||
{
|
||||
|
||||
@@ -134,7 +134,7 @@ static void Joy_ProcessTrigger( const engineAxis_t engineAxis, short value )
|
||||
trigThreshold = joy_lt_threshold.value;
|
||||
break;
|
||||
default:
|
||||
Con_Reportf( S_ERROR "Joy_ProcessTrigger: invalid axis = %i", engineAxis );
|
||||
Con_Reportf( S_ERROR "%s: invalid axis = %i\n", __func__, engineAxis );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ static void Joy_ProcessStick( const engineAxis_t engineAxis, short value )
|
||||
case JOY_AXIS_PITCH: deadzone = joy_pitch_deadzone.value; break;
|
||||
case JOY_AXIS_YAW: deadzone = joy_yaw_deadzone.value; break;
|
||||
default:
|
||||
Con_Reportf( S_ERROR "Joy_ProcessStick: invalid axis = %i", engineAxis );
|
||||
Con_Reportf( S_ERROR "%s: invalid axis = %i\n", __func__, engineAxis );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ static void Joy_ProcessStick( const engineAxis_t engineAxis, short value )
|
||||
|
||||
// fwd/side axis simulate hat movement
|
||||
if( ( engineAxis == JOY_AXIS_SIDE || engineAxis == JOY_AXIS_FWD ) &&
|
||||
( CL_IsInMenu() || CL_IsInConsole() ) )
|
||||
( cls.key_dest == key_menu || cls.key_dest == key_console ))
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
|
||||
@@ -333,7 +333,7 @@ void Touch_WriteConfig( void )
|
||||
if( Sys_CheckParm( "-nowriteconfig" ) || !touch.configchanged || !touch.config_loaded )
|
||||
return;
|
||||
|
||||
Con_DPrintf( "Touch_WriteConfig(): %s\n", touch_config_file.string );
|
||||
Con_DPrintf( "%s: %s\n", __func__, touch_config_file.string );
|
||||
|
||||
Q_snprintf( newconfigfile, sizeof( newconfigfile ), "%s.new", touch_config_file.string );
|
||||
Q_snprintf( oldconfigfile, sizeof( oldconfigfile ), "%s.bak", touch_config_file.string );
|
||||
@@ -1064,7 +1064,7 @@ void Touch_Init( void )
|
||||
return;
|
||||
touch.mempool = Mem_AllocPool( "Touch" );
|
||||
//touch.first = touch.last = NULL;
|
||||
Con_Printf( "IN_TouchInit()\n");
|
||||
Con_Printf( "%s()\n", __func__ );
|
||||
touch.move_finger = touch.resize_finger = touch.look_finger = touch.wheel_finger = -1;
|
||||
touch.state = state_none;
|
||||
touch.showeditbuttons = true;
|
||||
@@ -1217,10 +1217,10 @@ static qboolean Touch_IsVisible( touch_button_t *button )
|
||||
if( FBitSet( button->flags, TOUCH_FL_HIDE ))
|
||||
return false; // skip hidden
|
||||
|
||||
if( FBitSet( button->flags, TOUCH_FL_SP ) && CL_GetMaxClients() != 1 )
|
||||
if( FBitSet( button->flags, TOUCH_FL_SP ) && cl.maxclients != 1 )
|
||||
return false; // skip singleplayer(load, save) buttons in multiplayer
|
||||
|
||||
if( FBitSet( button->flags, TOUCH_FL_MP ) && CL_GetMaxClients() == 1 )
|
||||
if( FBitSet( button->flags, TOUCH_FL_MP ) && cl.maxclients == 1 )
|
||||
return false; // skip multiplayer buttons in singleplayer
|
||||
|
||||
return true;
|
||||
@@ -2163,8 +2163,7 @@ void Touch_KeyEvent( int key, int down )
|
||||
x = xi / SCR_W;
|
||||
y = yi / SCR_H;
|
||||
|
||||
Con_DPrintf( "event %d %.2f %.2f %.2f %.2f\n",
|
||||
event, x, y, x - lx, y - ly );
|
||||
// Con_DPrintf( "event %d %.2f %.2f %.2f %.2f\n", event, x, y, x - lx, y - ly );
|
||||
|
||||
IN_TouchEvent( event, finger, x, y, x - lx, y - ly );
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ GNU General Public License for more details.
|
||||
#include "input.h"
|
||||
#include "client.h"
|
||||
#include "vgui_draw.h"
|
||||
#include "cursor_type.h"
|
||||
|
||||
#if XASH_SDL
|
||||
#include <SDL.h>
|
||||
@@ -123,11 +124,6 @@ static void IN_StartupMouse( void )
|
||||
in_mouseinitialized = true;
|
||||
}
|
||||
|
||||
void GAME_EXPORT IN_SetCursor( void *hCursor )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_MouseSavePos
|
||||
|
||||
@@ -40,7 +40,6 @@ void IN_DeactivateMouse( void );
|
||||
void IN_MouseSavePos( void );
|
||||
void IN_MouseRestorePos( void );
|
||||
void IN_ToggleClientMouse( int newstate, int oldstate );
|
||||
void IN_SetCursor( void *hCursor );
|
||||
|
||||
uint IN_CollectInputDevices( void );
|
||||
void IN_LockInputDevices( qboolean lock );
|
||||
|
||||
@@ -553,7 +553,7 @@ static void Key_AddKeyCommands( int key, const char *kb, qboolean down )
|
||||
}
|
||||
|
||||
buttonPtr = button;
|
||||
while(( kb[i] <= ' ' || kb[i] == ';' ) && kb[i] != 0 )
|
||||
while((((byte)kb[i]) <= ' ' || kb[i] == ';' ) && kb[i] != 0 )
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -749,10 +749,10 @@ void GAME_EXPORT Key_Event( int key, int down )
|
||||
if( cls.key_dest == key_menu )
|
||||
{
|
||||
// only non printable keys passed
|
||||
if( !gameui.use_text_api )
|
||||
if( !gameui.use_extended_api )
|
||||
Key_EnableTextInput( true, false );
|
||||
//pass printable chars for old menus
|
||||
if( !gameui.use_text_api && !host.textmode && down && ( key >= 32 ) && ( key <= 'z' ) )
|
||||
if( !gameui.use_extended_api && !host.textmode && down && ( key >= 32 ) && ( key <= 'z' ) )
|
||||
{
|
||||
if( Key_IsDown( K_SHIFT ) )
|
||||
{
|
||||
@@ -840,7 +840,7 @@ void GAME_EXPORT Key_SetKeyDest( int key_dest )
|
||||
cls.key_dest = key_message;
|
||||
break;
|
||||
default:
|
||||
Host_Error( "Key_SetKeyDest: wrong destination (%i)\n", key_dest );
|
||||
Host_Error( "%s: wrong destination (%i)\n", __func__, key_dest );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1055,18 +1055,16 @@ static qboolean OSK_KeyEvent( int key, int down )
|
||||
break;
|
||||
}
|
||||
|
||||
if( !Q_stricmp( cl_charset.string, "utf-8" ) )
|
||||
ch = (unsigned char)osk.curbutton.val;
|
||||
else
|
||||
ch = Con_UtfProcessCharForce( (unsigned char)osk.curbutton.val );
|
||||
ch = (byte)osk.curbutton.val;
|
||||
|
||||
// do not pass UTF-8 sequence into the engine, convert it here
|
||||
if( !cls.accept_utf8 )
|
||||
ch = Con_UtfProcessCharForce( ch );
|
||||
|
||||
if( !ch )
|
||||
break;
|
||||
|
||||
Con_CharEvent( ch );
|
||||
if( cls.key_dest == key_menu )
|
||||
UI_CharEvent ( ch );
|
||||
|
||||
CL_CharEvent( ch );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1121,7 +1119,6 @@ static void OSK_EnableTextInput( qboolean enable, qboolean force )
|
||||
{
|
||||
osk.curlayout = 0;
|
||||
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ static void free_winding( winding_t *w )
|
||||
{
|
||||
// simple sentinel by Carmack
|
||||
if( *(unsigned *)w == 0xDEADC0DE )
|
||||
Host_Error( "free_winding: freed a freed winding\n" );
|
||||
Host_Error( "%s: freed a freed winding\n", __func__ );
|
||||
*(unsigned *)w = 0xDEADC0DE;
|
||||
free( w );
|
||||
}
|
||||
@@ -154,7 +154,7 @@ static winding_t *winding_for_plane( const mplane_t *p )
|
||||
vup[0] = 1;
|
||||
break;
|
||||
default:
|
||||
Host_Error( "BaseWindingForPlane: no axis found\n" );
|
||||
Host_Error( "%s: no axis found\n", __func__ );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -685,6 +685,9 @@ void Mod_CreatePolygonsForHull( int hullnum )
|
||||
if( hullnum < 1 || hullnum > 3 )
|
||||
return;
|
||||
|
||||
if( !world.num_hull_models )
|
||||
Mod_InitDebugHulls( mod ); // FIXME: build hulls for separate bmodels (shells, medkits etc)
|
||||
|
||||
Con_Printf( "generating polygons for hull %u...\n", hullnum );
|
||||
start = Sys_DoubleTime();
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
struct ref_state_s ref;
|
||||
ref_globals_t refState;
|
||||
|
||||
static const char* r_skyBoxSuffix[SKYBOX_MAX_SIDES] = { "rt", "bk", "lf", "ft", "up", "dn" };
|
||||
|
||||
CVAR_DEFINE_AUTO( gl_vsync, "0", FCVAR_ARCHIVE, "enable vertical syncronization" );
|
||||
CVAR_DEFINE_AUTO( r_showtextures, "0", FCVAR_CHEAT, "show all uploaded textures" );
|
||||
CVAR_DEFINE_AUTO( r_adjust_fov, "1", FCVAR_ARCHIVE, "making FOV adjustment for wide-screens" );
|
||||
@@ -49,13 +51,102 @@ void R_GetTextureParms( int *w, int *h, int texnum )
|
||||
if( h ) *h = REF_GET_PARM( PARM_TEX_HEIGHT, texnum );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
GL_FreeImage
|
||||
static qboolean CheckSkybox( const char *name, char out[SKYBOX_MAX_SIDES][MAX_STRING] )
|
||||
{
|
||||
static const char *skybox_ext[3] = { "dds", "tga", "bmp" };
|
||||
static const char *skybox_delim[2] = { "", "_" }; // no space for HL style, underscore for Q1 style
|
||||
int i;
|
||||
|
||||
// search for skybox images
|
||||
for( i = 0; i < ARRAYSIZE( skybox_ext ); i++ )
|
||||
{
|
||||
int j;
|
||||
|
||||
for( j = 0; j < ARRAYSIZE( skybox_delim ); j++ )
|
||||
{
|
||||
int k, num_checked_sides = 0;
|
||||
|
||||
for( k = 0; k < SKYBOX_MAX_SIDES; k++ )
|
||||
{
|
||||
char sidename[MAX_VA_STRING];
|
||||
|
||||
Q_snprintf( sidename, sizeof( sidename ), "%s%s%s.%s", name, skybox_delim[j], r_skyBoxSuffix[k], skybox_ext[i] );
|
||||
if( g_fsapi.FileExists( sidename, false ))
|
||||
{
|
||||
Q_strncpy( out[k], sidename, sizeof( out[k] ));
|
||||
num_checked_sides++;
|
||||
}
|
||||
}
|
||||
|
||||
if( num_checked_sides == SKYBOX_MAX_SIDES )
|
||||
return true; // image exists
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void R_SetupSky( const char *name )
|
||||
{
|
||||
string loadname;
|
||||
char sidenames[SKYBOX_MAX_SIDES][MAX_STRING];
|
||||
int skyboxTextures[SKYBOX_MAX_SIDES] = { 0 };
|
||||
int i, len;
|
||||
qboolean result;
|
||||
|
||||
if( !COM_CheckString( name ))
|
||||
{
|
||||
ref.dllFuncs.R_SetupSky( NULL ); // unload skybox
|
||||
return;
|
||||
}
|
||||
|
||||
Q_snprintf( loadname, sizeof( loadname ), "gfx/env/%s", name );
|
||||
COM_StripExtension( loadname );
|
||||
|
||||
// kill the underline suffix to find them manually later
|
||||
len = Q_strlen( loadname );
|
||||
|
||||
if( loadname[len - 1] == '_' )
|
||||
loadname[len - 1] = '\0';
|
||||
result = CheckSkybox( loadname, sidenames );
|
||||
|
||||
// to prevent infinite recursion if default skybox was missed
|
||||
if( !result && Q_stricmp( name, DEFAULT_SKYBOX_NAME ))
|
||||
{
|
||||
Con_Reportf( S_WARN "missed or incomplete skybox '%s'\n", name );
|
||||
R_SetupSky( DEFAULT_SKYBOX_NAME ); // force to default
|
||||
return;
|
||||
}
|
||||
|
||||
ref.dllFuncs.R_SetupSky( NULL ); // unload skybox
|
||||
Con_DPrintf( "SKY: " );
|
||||
|
||||
for( i = 0; i < SKYBOX_MAX_SIDES; i++ )
|
||||
{
|
||||
skyboxTextures[i] = ref.dllFuncs.GL_LoadTexture( sidenames[i], NULL, 0, TF_CLAMP|TF_SKY );
|
||||
|
||||
if( !skyboxTextures[i] )
|
||||
break;
|
||||
|
||||
Con_DPrintf( "%s%s%s", name, r_skyBoxSuffix[i], i != 5 ? ", " : ". " );
|
||||
}
|
||||
|
||||
if( i == SKYBOX_MAX_SIDES )
|
||||
{
|
||||
SetBits( world.flags, FWORLD_CUSTOM_SKYBOX );
|
||||
Con_DPrintf( "done\n" );
|
||||
ref.dllFuncs.R_SetupSky( skyboxTextures );
|
||||
return; // loaded
|
||||
}
|
||||
|
||||
Con_DPrintf( "^2failed\n" );
|
||||
for( i = 0; i < SKYBOX_MAX_SIDES; i++ )
|
||||
{
|
||||
if( skyboxTextures[i] )
|
||||
ref.dllFuncs.GL_FreeTexture( skyboxTextures[i] );
|
||||
}
|
||||
}
|
||||
|
||||
Frees image by name
|
||||
================
|
||||
*/
|
||||
void GAME_EXPORT GL_FreeImage( const char *name )
|
||||
{
|
||||
int texnum;
|
||||
@@ -91,7 +182,7 @@ static model_t *pfnGetDefaultSprite( enum ref_defaultsprite_e spr )
|
||||
{
|
||||
case REF_DOT_SPRITE: return cl_sprite_dot;
|
||||
case REF_CHROME_SPRITE: return cl_sprite_shell;
|
||||
default: Host_Error( "GetDefaultSprite: unknown sprite %d\n", spr );
|
||||
default: Host_Error( "%s: unknown sprite %d\n", __func__, spr );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -104,7 +195,7 @@ static void *pfnMod_Extradata( int type, model_t *m )
|
||||
case mod_studio: return Mod_StudioExtradata( m );
|
||||
case mod_sprite: // fallthrough
|
||||
case mod_brush: return NULL;
|
||||
default: Host_Error( "Mod_Extradata: unknown type %d\n", type );
|
||||
default: Host_Error( "%s: unknown type %d\n", __func__, type );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -376,7 +467,6 @@ static void CL_FillTriAPIFromRef( triangleapi_t *dst, const ref_interface_t *src
|
||||
|
||||
static qboolean R_LoadProgs( const char *name )
|
||||
{
|
||||
extern triangleapi_t gTriApi;
|
||||
static ref_api_t gpEngfuncs;
|
||||
REFAPI GetRefAPI; // single export
|
||||
|
||||
@@ -386,7 +476,7 @@ static qboolean R_LoadProgs( const char *name )
|
||||
if( !(ref.hInstance = COM_LoadLibrary( name, false, true ) ))
|
||||
{
|
||||
FS_AllowDirectPaths( false );
|
||||
Con_Reportf( "R_LoadProgs: can't load renderer library %s: %s\n", name, COM_GetLibraryError() );
|
||||
Con_Reportf( "%s: can't load renderer library %s: %s\n", __func__, name, COM_GetLibraryError() );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -395,7 +485,7 @@ static qboolean R_LoadProgs( const char *name )
|
||||
if( !( GetRefAPI = (REFAPI)COM_GetProcAddress( ref.hInstance, GET_REF_API )) )
|
||||
{
|
||||
COM_FreeLibrary( ref.hInstance );
|
||||
Con_Reportf( "R_LoadProgs: can't find GetRefAPI entry point in %s\n", name );
|
||||
Con_Reportf( "%s: can't find GetRefAPI entry point in %s\n", __func__, name );
|
||||
ref.hInstance = NULL;
|
||||
return false;
|
||||
}
|
||||
@@ -406,7 +496,7 @@ static qboolean R_LoadProgs( const char *name )
|
||||
if( GetRefAPI( REF_API_VERSION, &ref.dllFuncs, &gpEngfuncs, &refState ) != REF_API_VERSION )
|
||||
{
|
||||
COM_FreeLibrary( ref.hInstance );
|
||||
Con_Reportf( "R_LoadProgs: can't init renderer API: wrong version\n" );
|
||||
Con_Reportf( "%s: can't init renderer API: wrong version\n", __func__ );
|
||||
ref.hInstance = NULL;
|
||||
return false;
|
||||
}
|
||||
@@ -416,7 +506,7 @@ static qboolean R_LoadProgs( const char *name )
|
||||
if( !ref.dllFuncs.R_Init( ) )
|
||||
{
|
||||
COM_FreeLibrary( ref.hInstance );
|
||||
Con_Reportf( "R_LoadProgs: can't init renderer!\n" ); //, ref.dllFuncs.R_GetInitError() );
|
||||
Con_Reportf( "%s: can't init renderer!\n", __func__ ); //, ref.dllFuncs.R_GetInitError() );
|
||||
ref.hInstance = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -18,19 +18,18 @@ GNU General Public License for more details.
|
||||
|
||||
#include "ref_api.h"
|
||||
|
||||
#define RP_LOCALCLIENT( e ) ((e) != NULL && (e)->index == ( cl.playernum + 1 ) && e->player )
|
||||
#define RP_LOCALCLIENT( e ) ((e) != NULL && (e)->index == ( cl.playernum + 1 ) && e->player )
|
||||
|
||||
struct ref_state_s
|
||||
{
|
||||
qboolean initialized;
|
||||
|
||||
HINSTANCE hInstance;
|
||||
HINSTANCE hInstance;
|
||||
qboolean initialized;
|
||||
int numRenderers;
|
||||
ref_interface_t dllFuncs;
|
||||
|
||||
// depends on build configuration
|
||||
int numRenderers;
|
||||
const char **shortNames;
|
||||
const char **readableNames;
|
||||
const char **shortNames;
|
||||
const char **readableNames;
|
||||
};
|
||||
|
||||
extern struct ref_state_s ref;
|
||||
@@ -45,14 +44,14 @@ void R_GetTextureParms( int *w, int *h, int texnum );
|
||||
|
||||
void GL_RenderFrame( const struct ref_viewpass_s *rvp );
|
||||
|
||||
void R_SetupSky( const char *name );
|
||||
|
||||
// common engine and renderer cvars
|
||||
extern convar_t r_decals;
|
||||
extern convar_t r_adjust_fov;
|
||||
extern convar_t r_decals;
|
||||
extern convar_t r_adjust_fov;
|
||||
extern convar_t gl_clear;
|
||||
|
||||
qboolean R_Init( void );
|
||||
void R_Shutdown( void );
|
||||
|
||||
extern triangleapi_t gTriApi;
|
||||
|
||||
#endif // REF_COMMON_H
|
||||
|
||||
@@ -154,7 +154,8 @@ static const sx_preset_t rgsxpre_hlalpha052[] =
|
||||
static const sx_preset_t *ptable = rgsxpre;
|
||||
|
||||
// cvars
|
||||
static CVAR_DEFINE_AUTO( dsp_off, "0", FCVAR_ARCHIVE, "disable DSP processing" );
|
||||
static CVAR_DEFINE_AUTO( dsp_off, "0", FCVAR_ARCHIVE, "disable DSP processing (deprecated)" );
|
||||
static CVAR_DEFINE_AUTO( room_off, "0", FCVAR_ARCHIVE, "disable DSP processing (GoldSrc compatible cvar)" );
|
||||
static CVAR_DEFINE_AUTO( dsp_coeff_table, "0", FCVAR_ARCHIVE, "select DSP coefficient table: 0 for release or 1 for alpha 0.52" );
|
||||
static CVAR_DEFINE_AUTO( room_type, "0", 0, "current room type preset" );
|
||||
|
||||
@@ -232,6 +233,7 @@ void SX_Init( void )
|
||||
sxmod2cur = sxmod2 = 450 * ( idsp_dma_speed / SOUND_11k );
|
||||
|
||||
Cvar_RegisterVariable( &dsp_off );
|
||||
Cvar_RegisterVariable( &room_off );
|
||||
Cvar_RegisterVariable( &dsp_coeff_table );
|
||||
|
||||
Cvar_RegisterVariable( &roomwater_type );
|
||||
@@ -809,7 +811,7 @@ DSP_Process
|
||||
*/
|
||||
void DSP_Process( portable_samplepair_t *pbfront, int sampleCount )
|
||||
{
|
||||
if( dsp_off.value || !sampleCount )
|
||||
if( dsp_off.value || room_off.value || !sampleCount )
|
||||
return;
|
||||
|
||||
// preset is already installed by CheckNewDspPresets
|
||||
@@ -843,7 +845,7 @@ CheckNewDspPresets
|
||||
*/
|
||||
void CheckNewDspPresets( void )
|
||||
{
|
||||
if( dsp_off.value != 0.0f )
|
||||
if( dsp_off.value || room_off.value )
|
||||
return;
|
||||
|
||||
if( FBitSet( dsp_coeff_table.flags, FCVAR_CHANGED ))
|
||||
|
||||
@@ -52,8 +52,11 @@ void S_SoundList_f( void )
|
||||
{
|
||||
totalSize += sc->size;
|
||||
|
||||
if( sc->loopStart >= 0 ) Con_Printf( "L" );
|
||||
else Con_Printf( " " );
|
||||
if( FBitSet( sc->flags, SOUND_LOOPED ))
|
||||
Con_Printf( "L" );
|
||||
else
|
||||
Con_Printf( " " );
|
||||
|
||||
if( sfx->name[0] == '*' || !Q_strncmp( sfx->name, DEFAULT_SOUNDPATH, sizeof( DEFAULT_SOUNDPATH ) - 1 ))
|
||||
Con_Printf( " (%2db) %s : %s\n", sc->width * 8, Q_memprint( sc->size ), sfx->name );
|
||||
else Con_Printf( " (%2db) %s : " DEFAULT_SOUNDPATH "%s\n", sc->width * 8, Q_memprint( sc->size ), sfx->name );
|
||||
@@ -110,7 +113,7 @@ static wavdata_t *S_CreateDefaultSound( void )
|
||||
|
||||
sc->width = 2;
|
||||
sc->channels = 1;
|
||||
sc->loopStart = -1;
|
||||
sc->loopStart = 0;
|
||||
sc->rate = SOUND_DMA_SPEED;
|
||||
sc->samples = SOUND_DMA_SPEED;
|
||||
sc->size = sc->samples * sc->width * sc->channels;
|
||||
@@ -141,8 +144,8 @@ wavdata_t *S_LoadSound( sfx_t *sfx )
|
||||
if( Q_stricmp( sfx->name, "*default" ))
|
||||
{
|
||||
// load it from disk
|
||||
if( s_warn_late_precache.value > 0 && CL_Active() )
|
||||
Con_Printf( S_WARN "S_LoadSound: late precache of %s\n", sfx->name );
|
||||
if( s_warn_late_precache.value > 0 && cls.state == ca_active )
|
||||
Con_Printf( S_WARN "%s: late precache of %s\n", __func__, sfx->name );
|
||||
|
||||
if( sfx->name[0] == '*' )
|
||||
sc = FS_LoadSound( sfx->name + 1, NULL, 0 );
|
||||
@@ -155,7 +158,7 @@ wavdata_t *S_LoadSound( sfx_t *sfx )
|
||||
Sound_Process( &sc, SOUND_11k, sc->width, SOUND_RESAMPLE );
|
||||
else if( sc->rate > SOUND_11k && sc->rate < SOUND_22k ) // some bad sounds
|
||||
Sound_Process( &sc, SOUND_22k, sc->width, SOUND_RESAMPLE );
|
||||
else if( sc->rate > SOUND_22k && sc->rate <= SOUND_32k ) // some bad sounds
|
||||
else if( sc->rate > SOUND_22k && sc->rate < SOUND_44k ) // some bad sounds
|
||||
Sound_Process( &sc, SOUND_44k, sc->width, SOUND_RESAMPLE );
|
||||
|
||||
sfx->cache = sc;
|
||||
@@ -218,7 +221,7 @@ sfx_t *S_FindName( const char *pname, int *pfInCache )
|
||||
sfx = &s_knownSfx[i];
|
||||
memset( sfx, 0, sizeof( *sfx ));
|
||||
if( pfInCache ) *pfInCache = false;
|
||||
Q_strncpy( sfx->name, name, MAX_STRING );
|
||||
Q_strncpy( sfx->name, name, sizeof( sfx->name ));
|
||||
sfx->servercount = cl.servercount;
|
||||
sfx->hashValue = COM_HashKey( sfx->name, MAX_SFX_HASH );
|
||||
|
||||
@@ -377,7 +380,7 @@ S_InitSounds
|
||||
void S_InitSounds( void )
|
||||
{
|
||||
// create unused 0-entry
|
||||
Q_strncpy( s_knownSfx->name, "*default", MAX_QPATH );
|
||||
Q_strncpy( s_knownSfx->name, "*default", sizeof( s_knownSfx->name ));
|
||||
s_knownSfx->hashValue = COM_HashKey( s_knownSfx->name, MAX_SFX_HASH );
|
||||
s_knownSfx->hashNext = s_sfxHashList[s_knownSfx->hashValue];
|
||||
s_sfxHashList[s_knownSfx->hashValue] = s_knownSfx;
|
||||
|
||||
@@ -43,7 +43,7 @@ CVAR_DEFINE_AUTO( s_lerping, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "apply interpo
|
||||
static CVAR_DEFINE( s_ambient_level, "ambient_level", "0.3", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "volume of environment noises (water and wind)" );
|
||||
static CVAR_DEFINE( s_ambient_fade, "ambient_fade", "1000", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "rate of volume fading when client is moving" );
|
||||
static CVAR_DEFINE_AUTO( s_combine_sounds, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "combine channels with same sounds" );
|
||||
static CVAR_DEFINE_AUTO( snd_mute_losefocus, "1", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "silence the audio when game window loses focus" );
|
||||
CVAR_DEFINE_AUTO( snd_mute_losefocus, "1", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "silence the audio when game window loses focus" );
|
||||
CVAR_DEFINE_AUTO( s_test, "0", 0, "engine developer cvar for quick testing new features" );
|
||||
CVAR_DEFINE_AUTO( s_samplecount, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "sample count (0 for default value)" );
|
||||
CVAR_DEFINE_AUTO( s_warn_late_precache, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "warn about late precached sounds on client-side" );
|
||||
@@ -328,7 +328,7 @@ channel_t *SND_PickDynamicChannel( int entnum, int channel, sfx_t *sfx, qboolean
|
||||
// don't restart looping sounds for the same entity
|
||||
wavdata_t *sc = channels[first_to_die].sfx->cache;
|
||||
|
||||
if( sc && sc->loopStart != -1 )
|
||||
if( sc && FBitSet( sc->flags, SOUND_LOOPED ))
|
||||
{
|
||||
channel_t *ch = &channels[first_to_die];
|
||||
|
||||
@@ -382,7 +382,7 @@ channel_t *SND_PickStaticChannel( const vec3_t pos, sfx_t *sfx )
|
||||
// no empty slots, alloc a new static sound channel
|
||||
if( total_channels == MAX_CHANNELS )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "S_PickStaticChannel: no free channels\n" );
|
||||
Con_DPrintf( S_ERROR "%s: no free channels\n", __func__ );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -503,7 +503,7 @@ static void SND_Spatialize( channel_t *ch )
|
||||
|
||||
pSource = ch->sfx->cache;
|
||||
|
||||
if( ch->use_loop && pSource && pSource->loopStart != -1 )
|
||||
if( ch->use_loop && pSource && FBitSet( pSource->flags, SOUND_LOOPED ))
|
||||
looping = true;
|
||||
|
||||
if( !ch->staticsound )
|
||||
@@ -641,7 +641,7 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
|
||||
if( !target_chan->leftvol && !target_chan->rightvol )
|
||||
{
|
||||
// looping sounds don't use this optimization because they should stick around until they're killed.
|
||||
if( !sfx->cache || sfx->cache->loopStart == -1 )
|
||||
if( !sfx->cache || !FBitSet( sfx->cache->flags, SOUND_LOOPED ))
|
||||
{
|
||||
// if this is a streaming sound, play the whole thing.
|
||||
if( chan != CHAN_STREAM )
|
||||
@@ -893,7 +893,7 @@ int S_GetCurrentStaticSounds( soundlist_t *pout, int size )
|
||||
VectorCopy( channels[i].origin, pout->origin );
|
||||
pout->volume = (float)channels[i].master_vol / 255.0f;
|
||||
pout->attenuation = channels[i].dist_mult * SND_CLIP_DISTANCE;
|
||||
pout->looping = ( channels[i].use_loop && channels[i].sfx->cache->loopStart != -1 );
|
||||
pout->looping = ( channels[i].use_loop && FBitSet( channels[i].sfx->cache->flags, SOUND_LOOPED ));
|
||||
pout->pitch = channels[i].basePitch;
|
||||
pout->channel = channels[i].entchannel;
|
||||
pout->wordIndex = channels[i].wordIndex;
|
||||
@@ -928,7 +928,7 @@ int S_GetCurrentDynamicSounds( soundlist_t *pout, int size )
|
||||
if( !channels[i].sfx || !channels[i].sfx->name[0] || !Q_stricmp( channels[i].sfx->name, "*default" ))
|
||||
continue; // don't serialize default sounds
|
||||
|
||||
looped = ( channels[i].use_loop && channels[i].sfx->cache->loopStart != -1 );
|
||||
looped = ( channels[i].use_loop && FBitSet( channels[i].sfx->cache->flags, SOUND_LOOPED ));
|
||||
|
||||
if( channels[i].entchannel == CHAN_STATIC && looped && !Host_IsQuakeCompatible())
|
||||
continue; // never serialize static looped sounds. It will be restoring in game code
|
||||
@@ -1599,11 +1599,10 @@ void SND_UpdateSound( void )
|
||||
// release raw-channels that no longer used more than 10 secs
|
||||
S_FreeIdleRawChannels();
|
||||
|
||||
VectorCopy( cl.simvel, s_listener.velocity );
|
||||
s_listener.frametime = (cl.time - cl.oldtime);
|
||||
s_listener.waterlevel = cl.local.waterlevel;
|
||||
s_listener.active = CL_IsInGame();
|
||||
s_listener.inmenu = CL_IsInMenu();
|
||||
s_listener.inmenu = cls.key_dest == key_menu;
|
||||
s_listener.paused = cl.paused;
|
||||
|
||||
// update general area ambient sound sources
|
||||
|
||||
@@ -17,30 +17,56 @@ GNU General Public License for more details.
|
||||
#include "sound.h"
|
||||
#include "client.h"
|
||||
|
||||
#define IPAINTBUFFER 0
|
||||
#define IROOMBUFFER 1
|
||||
#define ISTREAMBUFFER 2
|
||||
enum
|
||||
{
|
||||
IPAINTBUFFER = 0,
|
||||
IROOMBUFFER,
|
||||
ISTREAMBUFFER,
|
||||
CPAINTBUFFERS,
|
||||
};
|
||||
|
||||
#define FILTERTYPE_NONE 0
|
||||
#define FILTERTYPE_LINEAR 1
|
||||
#define FILTERTYPE_CUBIC 2
|
||||
enum
|
||||
{
|
||||
FILTERTYPE_NONE = 0,
|
||||
FILTERTYPE_LINEAR,
|
||||
FILTERTYPE_CUBIC,
|
||||
};
|
||||
|
||||
#define CCHANVOLUMES 2
|
||||
|
||||
#define SND_SCALE_BITS 7
|
||||
#define SND_SCALE_SHIFT (8 - SND_SCALE_BITS)
|
||||
#define SND_SCALE_LEVELS (1 << SND_SCALE_BITS)
|
||||
#define SND_SCALE_BITS 7
|
||||
#define SND_SCALE_SHIFT ( 8 - SND_SCALE_BITS )
|
||||
#define SND_SCALE_LEVELS ( 1 << SND_SCALE_BITS )
|
||||
|
||||
portable_samplepair_t *g_curpaintbuffer;
|
||||
portable_samplepair_t streambuffer[(PAINTBUFFER_SIZE+1)];
|
||||
portable_samplepair_t paintbuffer[(PAINTBUFFER_SIZE+1)];
|
||||
portable_samplepair_t roombuffer[(PAINTBUFFER_SIZE+1)];
|
||||
portable_samplepair_t facingbuffer[(PAINTBUFFER_SIZE+1)];
|
||||
portable_samplepair_t temppaintbuffer[(PAINTBUFFER_SIZE+1)];
|
||||
paintbuffer_t paintbuffers[CPAINTBUFFERS];
|
||||
// sound mixing buffer
|
||||
#define CPAINTFILTERMEM 3
|
||||
#define CPAINTFILTERS 4 // maximum number of consecutive upsample passes per paintbuffer
|
||||
|
||||
int snd_scaletable[SND_SCALE_LEVELS][256];
|
||||
// fixed point stuff for real-time resampling
|
||||
#define FIX_BITS 28
|
||||
#define FIX_SCALE ( 1 << FIX_BITS )
|
||||
#define FIX_MASK (( 1 << FIX_BITS ) - 1 )
|
||||
#define FIX_FLOAT( a ) ((int)(( a ) * FIX_SCALE ))
|
||||
#define FIX( a ) (((int)( a )) << FIX_BITS )
|
||||
#define FIX_INTPART( a ) (((int)( a )) >> FIX_BITS )
|
||||
#define FIX_FRACPART( a ) (( a ) & FIX_MASK )
|
||||
|
||||
typedef struct
|
||||
{
|
||||
qboolean factive; // if true, mix to this paintbuffer using flags
|
||||
portable_samplepair_t *pbuf; // front stereo mix buffer, for 2 or 4 channel mixing
|
||||
int ifilter; // current filter memory buffer to use for upsampling pass
|
||||
portable_samplepair_t fltmem[CPAINTFILTERS][CPAINTFILTERMEM];
|
||||
} paintbuffer_t;
|
||||
|
||||
static portable_samplepair_t *g_curpaintbuffer;
|
||||
static portable_samplepair_t streambuffer[(PAINTBUFFER_SIZE+1)];
|
||||
static portable_samplepair_t paintbuffer[(PAINTBUFFER_SIZE+1)];
|
||||
static portable_samplepair_t roombuffer[(PAINTBUFFER_SIZE+1)];
|
||||
static portable_samplepair_t temppaintbuffer[(PAINTBUFFER_SIZE+1)];
|
||||
static paintbuffer_t paintbuffers[CPAINTBUFFERS];
|
||||
|
||||
static int snd_scaletable[SND_SCALE_LEVELS][256];
|
||||
void S_InitScaletable( void )
|
||||
{
|
||||
int i, j;
|
||||
@@ -67,7 +93,7 @@ static void S_TransferPaintBuffer( int endtime )
|
||||
dword *pbuf;
|
||||
|
||||
pbuf = (dword *)dma.buffer;
|
||||
snd_p = (int *)PAINTBUFFER;
|
||||
snd_p = (int *)g_curpaintbuffer;
|
||||
lpaintedtime = paintedtime;
|
||||
sampleMask = ((dma.samples >> 1) - 1);
|
||||
|
||||
@@ -111,20 +137,20 @@ static void S_TransferPaintBuffer( int endtime )
|
||||
//===============================================================================
|
||||
// Activate a paintbuffer. All active paintbuffers are mixed in parallel within
|
||||
// MIX_MixChannelsToPaintbuffer, according to flags
|
||||
_inline void MIX_ActivatePaintbuffer( int ipaintbuffer )
|
||||
static void MIX_ActivatePaintbuffer( int ipaintbuffer )
|
||||
{
|
||||
Assert( ipaintbuffer < CPAINTBUFFERS );
|
||||
paintbuffers[ipaintbuffer].factive = true;
|
||||
}
|
||||
|
||||
_inline void MIX_SetCurrentPaintbuffer( int ipaintbuffer )
|
||||
static void MIX_SetCurrentPaintbuffer( int ipaintbuffer )
|
||||
{
|
||||
Assert( ipaintbuffer < CPAINTBUFFERS );
|
||||
g_curpaintbuffer = paintbuffers[ipaintbuffer].pbuf;
|
||||
Assert( g_curpaintbuffer != NULL );
|
||||
}
|
||||
|
||||
_inline int MIX_GetCurrentPaintbufferIndex( void )
|
||||
static int MIX_GetCurrentPaintbufferIndex( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -136,7 +162,7 @@ _inline int MIX_GetCurrentPaintbufferIndex( void )
|
||||
return 0;
|
||||
}
|
||||
|
||||
_inline paintbuffer_t *MIX_GetCurrentPaintbufferPtr( void )
|
||||
static paintbuffer_t *MIX_GetCurrentPaintbufferPtr( void )
|
||||
{
|
||||
int ipaint = MIX_GetCurrentPaintbufferIndex();
|
||||
|
||||
@@ -145,7 +171,7 @@ _inline paintbuffer_t *MIX_GetCurrentPaintbufferPtr( void )
|
||||
}
|
||||
|
||||
// Don't mix into any paintbuffers
|
||||
_inline void MIX_DeactivateAllPaintbuffers( void )
|
||||
static void MIX_DeactivateAllPaintbuffers( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -154,7 +180,7 @@ _inline void MIX_DeactivateAllPaintbuffers( void )
|
||||
}
|
||||
|
||||
// set upsampling filter indexes back to 0
|
||||
_inline void MIX_ResetPaintbufferFilterCounters( void )
|
||||
static void MIX_ResetPaintbufferFilterCounters( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -163,13 +189,13 @@ _inline void MIX_ResetPaintbufferFilterCounters( void )
|
||||
}
|
||||
|
||||
// return pointer to front paintbuffer pbuf, given index
|
||||
_inline portable_samplepair_t *MIX_GetPFrontFromIPaint( int ipaintbuffer )
|
||||
static portable_samplepair_t *MIX_GetPFrontFromIPaint( int ipaintbuffer )
|
||||
{
|
||||
Assert( ipaintbuffer < CPAINTBUFFERS );
|
||||
return paintbuffers[ipaintbuffer].pbuf;
|
||||
}
|
||||
|
||||
_inline paintbuffer_t *MIX_GetPPaintFromIPaint( int ipaint )
|
||||
static paintbuffer_t *MIX_GetPPaintFromIPaint( int ipaint )
|
||||
{
|
||||
Assert( ipaint < CPAINTBUFFERS );
|
||||
return &paintbuffers[ipaint];
|
||||
@@ -523,6 +549,7 @@ static void MIX_MixChannelsToPaintbuffer( int endtime, int rate, int outputRate
|
||||
wavdata_t *pSource;
|
||||
int i, sampleCount;
|
||||
qboolean bZeroVolume;
|
||||
qboolean local = Host_IsLocalGame();
|
||||
|
||||
// mix each channel into paintbuffer
|
||||
ch = channels;
|
||||
@@ -549,7 +576,7 @@ static void MIX_MixChannelsToPaintbuffer( int endtime, int rate, int outputRate
|
||||
{
|
||||
// play, playvol
|
||||
}
|
||||
else if(( s_listener.inmenu || s_listener.paused ) && !ch->localsound )
|
||||
else if(( s_listener.inmenu || s_listener.paused ) && !ch->localsound && local )
|
||||
{
|
||||
// play only local sounds, keep pause for other
|
||||
continue;
|
||||
@@ -567,6 +594,7 @@ static void MIX_MixChannelsToPaintbuffer( int endtime, int rate, int outputRate
|
||||
|
||||
// Don't mix sound data for sounds with zero volume. If it's a non-looping sound,
|
||||
// just remove the sound when its volume goes to zero.
|
||||
|
||||
bZeroVolume = !ch->leftvol && !ch->rightvol;
|
||||
|
||||
if( !bZeroVolume )
|
||||
@@ -576,7 +604,7 @@ static void MIX_MixChannelsToPaintbuffer( int endtime, int rate, int outputRate
|
||||
bZeroVolume = true;
|
||||
}
|
||||
|
||||
if( !pSource || ( bZeroVolume && pSource->loopStart == -1 ))
|
||||
if( !pSource || ( bZeroVolume && !FBitSet( pSource->flags, SOUND_LOOPED )))
|
||||
{
|
||||
if( !pSource )
|
||||
{
|
||||
@@ -629,7 +657,7 @@ static void MIX_MixChannelsToPaintbuffer( int endtime, int rate, int outputRate
|
||||
}
|
||||
|
||||
// pass in index -1...count+2, return pointer to source sample in either paintbuffer or delay buffer
|
||||
_inline portable_samplepair_t *S_GetNextpFilter( int i, portable_samplepair_t *pbuffer, portable_samplepair_t *pfiltermem )
|
||||
static portable_samplepair_t *S_GetNextpFilter( int i, portable_samplepair_t *pbuffer, portable_samplepair_t *pfiltermem )
|
||||
{
|
||||
// The delay buffer is assumed to precede the paintbuffer by 6 duplicated samples
|
||||
if( i == -1 ) return (&(pfiltermem[0]));
|
||||
@@ -838,6 +866,14 @@ static void MIX_MixPaintbuffers( int ibuf1, int ibuf2, int ibuf3, int count, flo
|
||||
pbuf2 = paintbuffers[ibuf2].pbuf;
|
||||
pbuf3 = paintbuffers[ibuf3].pbuf;
|
||||
|
||||
if( !gain )
|
||||
{
|
||||
// do not mix buf2 into buf3, just copy
|
||||
if( pbuf1 != pbuf3 )
|
||||
memcpy( pbuf3, pbuf1, sizeof( *pbuf1 ) * count );
|
||||
return;
|
||||
}
|
||||
|
||||
// destination buffer stereo - average n chans down to stereo
|
||||
|
||||
// destination 2ch:
|
||||
|
||||
@@ -57,6 +57,12 @@ float S_GetMusicVolume( void )
|
||||
{
|
||||
float scale = 1.0f;
|
||||
|
||||
if( host.status == HOST_NOFOCUS && snd_mute_losefocus.value != 0.0f )
|
||||
{
|
||||
// we return zero volume to keep sounds running
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if( !s_listener.inmenu && musicfade.percent != 0 )
|
||||
{
|
||||
scale = bound( 0.0f, musicfade.percent / 100.0f, 1.0f );
|
||||
@@ -142,7 +148,7 @@ S_StreamGetCurrentState
|
||||
save\restore code
|
||||
=================
|
||||
*/
|
||||
qboolean S_StreamGetCurrentState( char *currentTrack, char *loopTrack, int *position )
|
||||
qboolean S_StreamGetCurrentState( char *currentTrack, size_t currentTrackSize, char *loopTrack, size_t loopTrackSize, int *position )
|
||||
{
|
||||
if( !s_bgTrack.stream )
|
||||
return false; // not active
|
||||
@@ -150,15 +156,15 @@ qboolean S_StreamGetCurrentState( char *currentTrack, char *loopTrack, int *posi
|
||||
if( currentTrack )
|
||||
{
|
||||
if( s_bgTrack.current[0] )
|
||||
Q_strncpy( currentTrack, s_bgTrack.current, MAX_STRING );
|
||||
else Q_strncpy( currentTrack, "*", MAX_STRING ); // no track
|
||||
Q_strncpy( currentTrack, s_bgTrack.current, currentTrackSize );
|
||||
else Q_strncpy( currentTrack, "*", currentTrackSize ); // no track
|
||||
}
|
||||
|
||||
if( loopTrack )
|
||||
{
|
||||
if( s_bgTrack.loopName[0] )
|
||||
Q_strncpy( loopTrack, s_bgTrack.loopName, MAX_STRING );
|
||||
else Q_strncpy( loopTrack, "*", MAX_STRING ); // no track
|
||||
Q_strncpy( loopTrack, s_bgTrack.loopName, loopTrackSize );
|
||||
else Q_strncpy( loopTrack, "*", loopTrackSize ); // no track
|
||||
}
|
||||
|
||||
if( position )
|
||||
|
||||
@@ -27,7 +27,7 @@ int S_ConvertLoopedPosition( wavdata_t *pSource, int samplePosition, qboolean us
|
||||
// convert to a position within the loop
|
||||
// At the end of the loop, we return a short buffer, and subsequent call
|
||||
// will loop back and get the rest of the buffer
|
||||
if( pSource->loopStart >= 0 && samplePosition >= pSource->samples && use_loop )
|
||||
if( FBitSet( pSource->flags, SOUND_LOOPED ) && samplePosition >= pSource->samples && use_loop )
|
||||
{
|
||||
// size of loop
|
||||
int loopSize = pSource->samples - pSource->loopStart;
|
||||
|
||||
@@ -261,7 +261,7 @@ static const char *VOX_GetDirectory( char *szpath, const char *psz, int nsize )
|
||||
|
||||
if( len > nsize )
|
||||
{
|
||||
Con_Printf( "VOX_GetDirectory: invalid directory in: %s\n", psz );
|
||||
Con_Printf( "%s: invalid directory in: %s\n", __func__, psz );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -467,7 +467,7 @@ void VOX_LoadSound( channel_t *ch, const char *pszin )
|
||||
|
||||
if( !psz )
|
||||
{
|
||||
Con_Printf( "VOX_LoadSound: no sentence named %s\n", pszin );
|
||||
Con_Printf( "%s: no sentence named %s\n", __func__, pszin );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -475,13 +475,13 @@ void VOX_LoadSound( channel_t *ch, const char *pszin )
|
||||
|
||||
if( !psz )
|
||||
{
|
||||
Con_Printf( "VOX_LoadSound: failed getting directory for %s\n", pszin );
|
||||
Con_Printf( "%s: failed getting directory for %s\n", __func__, pszin );
|
||||
return;
|
||||
}
|
||||
|
||||
if( Q_strlen( psz ) >= sizeof( buffer ) )
|
||||
{
|
||||
Con_Printf( "VOX_LoadSound: sentence is too long %s", psz );
|
||||
Con_Printf( "%s: sentence is too long %s", __func__, psz );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,208 +20,181 @@ extern poolhandle_t sndpool;
|
||||
|
||||
#include "xash3d_mathlib.h"
|
||||
|
||||
// sound engine rate defines
|
||||
#define SOUND_DMA_SPEED 44100 // hardware playback rate
|
||||
#define SOUND_11k 11025 // 11khz sample rate
|
||||
#define SOUND_16k 16000 // 16khz sample rate
|
||||
#define SOUND_22k 22050 // 22khz sample rate
|
||||
#define SOUND_32k 32000 // 32khz sample rate
|
||||
#define SOUND_44k 44100 // 44khz sample rate
|
||||
#define DMA_MSEC_PER_SAMPLE ((float)(1000.0 / SOUND_DMA_SPEED))
|
||||
#define XASH_AUDIO_CD_QUALITY 1 // some platforms might need this
|
||||
|
||||
// fixed point stuff for real-time resampling
|
||||
#define FIX_BITS 28
|
||||
#define FIX_SCALE (1 << FIX_BITS)
|
||||
#define FIX_MASK ((1 << FIX_BITS)-1)
|
||||
#define FIX_FLOAT(a) ((int)((a) * FIX_SCALE))
|
||||
#define FIX(a) (((int)(a)) << FIX_BITS)
|
||||
#define FIX_INTPART(a) (((int)(a)) >> FIX_BITS)
|
||||
#define FIX_FRACTION(a,b) (FIX(a)/(b))
|
||||
#define FIX_FRACPART(a) ((a) & FIX_MASK)
|
||||
// sound engine rate defines
|
||||
#if XASH_AUDIO_CD_QUALITY
|
||||
#define SOUND_11k 11025 // 11khz sample rate
|
||||
#define SOUND_22k 22050 // 22khz sample rate
|
||||
#define SOUND_44k 44100 // 44khz sample rate
|
||||
#else // XASH_AUDIO_CD_QUALITY
|
||||
#define SOUND_11k 12000 // 11khz sample rate
|
||||
#define SOUND_22k 24000 // 22khz sample rate
|
||||
#define SOUND_44k 48000 // 44khz sample rate
|
||||
#endif // XASH_AUDIO_CD_QUALITY
|
||||
|
||||
#define SOUND_DMA_SPEED SOUND_44k // hardware playback rate
|
||||
|
||||
// NOTE: clipped sound at 32760 to avoid overload
|
||||
#define CLIP( x ) (( x ) > 32760 ? 32760 : (( x ) < -32760 ? -32760 : ( x )))
|
||||
#define CLIP( x ) (( x ) > 32760 ? 32760 : (( x ) < -32760 ? -32760 : ( x )))
|
||||
|
||||
#define PAINTBUFFER_SIZE 1024 // 44k: was 512
|
||||
#define PAINTBUFFER (g_curpaintbuffer)
|
||||
#define CPAINTBUFFERS 3
|
||||
#define PAINTBUFFER_SIZE 1024 // 44k: was 512
|
||||
|
||||
// sound mixing buffer
|
||||
#define CPAINTFILTERMEM 3
|
||||
#define CPAINTFILTERS 4 // maximum number of consecutive upsample passes per paintbuffer
|
||||
|
||||
#define S_RAW_SOUND_IDLE_SEC 10 // time interval for idling raw sound before it's freed
|
||||
#define S_RAW_SOUND_BACKGROUNDTRACK -2
|
||||
#define S_RAW_SOUND_SOUNDTRACK -1
|
||||
#define S_RAW_SAMPLES_PRECISION_BITS 14
|
||||
|
||||
#define CIN_FRAMETIME (1.0f / 30.0f)
|
||||
#define S_RAW_SOUND_IDLE_SEC 10 // time interval for idling raw sound before it's freed
|
||||
#define S_RAW_SOUND_BACKGROUNDTRACK -2
|
||||
#define S_RAW_SOUND_SOUNDTRACK -1
|
||||
#define S_RAW_SAMPLES_PRECISION_BITS 14
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int left;
|
||||
int right;
|
||||
int left;
|
||||
int right;
|
||||
} portable_samplepair_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
qboolean factive; // if true, mix to this paintbuffer using flags
|
||||
portable_samplepair_t *pbuf; // front stereo mix buffer, for 2 or 4 channel mixing
|
||||
int ifilter; // current filter memory buffer to use for upsampling pass
|
||||
portable_samplepair_t fltmem[CPAINTFILTERS][CPAINTFILTERMEM];
|
||||
} paintbuffer_t;
|
||||
|
||||
typedef struct sfx_s
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
wavdata_t *cache;
|
||||
char name[MAX_QPATH];
|
||||
wavdata_t *cache;
|
||||
|
||||
int servercount;
|
||||
uint hashValue;
|
||||
struct sfx_s *hashNext;
|
||||
int servercount;
|
||||
uint hashValue;
|
||||
struct sfx_s *hashNext;
|
||||
} sfx_t;
|
||||
|
||||
extern portable_samplepair_t paintbuffer[];
|
||||
extern portable_samplepair_t roombuffer[];
|
||||
extern portable_samplepair_t temppaintbuffer[];
|
||||
extern portable_samplepair_t *g_curpaintbuffer;
|
||||
extern paintbuffer_t paintbuffers[];
|
||||
|
||||
// structure used for fading in and out client sound volume.
|
||||
typedef struct
|
||||
{
|
||||
float initial_percent;
|
||||
float percent; // how far to adjust client's volume down by.
|
||||
float starttime; // GetHostTime() when we started adjusting volume
|
||||
float fadeouttime; // # of seconds to get to faded out state
|
||||
float holdtime; // # of seconds to hold
|
||||
float fadeintime; // # of seconds to restore
|
||||
float initial_percent;
|
||||
float percent; // how far to adjust client's volume down by.
|
||||
float starttime; // GetHostTime() when we started adjusting volume
|
||||
float fadeouttime; // # of seconds to get to faded out state
|
||||
float holdtime; // # of seconds to hold
|
||||
float fadeintime; // # of seconds to restore
|
||||
} soundfade_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float percent;
|
||||
float percent;
|
||||
} musicfade_t;
|
||||
|
||||
typedef struct snd_format_s
|
||||
{
|
||||
unsigned int speed;
|
||||
unsigned int width;
|
||||
unsigned int channels;
|
||||
uint speed;
|
||||
byte width;
|
||||
byte channels;
|
||||
} snd_format_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
snd_format_t format;
|
||||
int samples; // mono samples in buffer
|
||||
int samplepos; // in mono samples
|
||||
byte *buffer;
|
||||
qboolean initialized; // sound engine is active
|
||||
const char *backendName;
|
||||
snd_format_t format;
|
||||
int samples; // mono samples in buffer
|
||||
int samplepos; // in mono samples
|
||||
qboolean initialized; // sound engine is active
|
||||
byte *buffer;
|
||||
const char *backendName;
|
||||
} dma_t;
|
||||
|
||||
#include "vox.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double sample;
|
||||
|
||||
wavdata_t *pData;
|
||||
double forcedEndSample;
|
||||
qboolean finished;
|
||||
double sample;
|
||||
wavdata_t *pData;
|
||||
double forcedEndSample;
|
||||
qboolean finished;
|
||||
} mixer_t;
|
||||
|
||||
typedef struct rawchan_s
|
||||
{
|
||||
int entnum;
|
||||
int master_vol;
|
||||
int leftvol; // 0-255 left volume
|
||||
int rightvol; // 0-255 right volume
|
||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
volatile uint s_rawend;
|
||||
wavdata_t sound_info; // advance play position
|
||||
float oldtime; // catch time jumps
|
||||
size_t max_samples; // buffer length
|
||||
portable_samplepair_t rawsamples[1]; // variable sized
|
||||
int entnum;
|
||||
int master_vol;
|
||||
int leftvol; // 0-255 left volume
|
||||
int rightvol; // 0-255 right volume
|
||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
volatile uint s_rawend;
|
||||
float oldtime; // catch time jumps
|
||||
wavdata_t sound_info; // advance play position
|
||||
size_t max_samples; // buffer length
|
||||
portable_samplepair_t rawsamples[1]; // variable sized
|
||||
} rawchan_t;
|
||||
|
||||
typedef struct channel_s
|
||||
{
|
||||
char name[16]; // keept sentence name
|
||||
sfx_t *sfx; // sfx number
|
||||
char name[16]; // keep sentence name
|
||||
sfx_t *sfx; // sfx number
|
||||
|
||||
int leftvol; // 0-255 left volume
|
||||
int rightvol; // 0-255 right volume
|
||||
int leftvol; // 0-255 left volume
|
||||
int rightvol; // 0-255 right volume
|
||||
|
||||
int entnum; // entity soundsource
|
||||
int entchannel; // sound channel (CHAN_STREAM, CHAN_VOICE, etc.)
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||
int master_vol; // 0-255 master volume
|
||||
qboolean isSentence; // bit who indicated sentence
|
||||
int basePitch; // base pitch percent (100% is normal pitch playback)
|
||||
float pitch; // real-time pitch after any modulation or shift by dynamic data
|
||||
qboolean use_loop; // don't loop default and local sounds
|
||||
qboolean staticsound; // use origin instead of fetching entnum's origin
|
||||
qboolean localsound; // it's a local menu sound (not looped, not paused)
|
||||
mixer_t pMixer;
|
||||
int entnum; // entity soundsource
|
||||
int entchannel; // sound channel (CHAN_STREAM, CHAN_VOICE, etc.)
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||
int master_vol; // 0-255 master volume
|
||||
int basePitch; // base pitch percent (100% is normal pitch playback)
|
||||
float pitch; // real-time pitch after any modulation or shift by dynamic data
|
||||
qboolean use_loop; // don't loop default and local sounds
|
||||
qboolean staticsound; // use origin instead of fetching entnum's origin
|
||||
qboolean localsound; // it's a local menu sound (not looped, not paused)
|
||||
mixer_t pMixer;
|
||||
|
||||
// sentence mixer
|
||||
int wordIndex;
|
||||
mixer_t *currentWord; // NULL if sentence is finished
|
||||
voxword_t words[CVOXWORDMAX];
|
||||
qboolean isSentence; // bit indicating sentence
|
||||
int wordIndex;
|
||||
mixer_t *currentWord; // NULL if sentence is finished
|
||||
voxword_t words[CVOXWORDMAX];
|
||||
} channel_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t origin; // simorg + view_ofs
|
||||
vec3_t velocity;
|
||||
vec3_t forward;
|
||||
vec3_t right;
|
||||
vec3_t up;
|
||||
vec3_t origin; // simorg + view_ofs
|
||||
vec3_t forward;
|
||||
vec3_t right;
|
||||
vec3_t up;
|
||||
|
||||
int entnum;
|
||||
int waterlevel;
|
||||
float frametime; // used for sound fade
|
||||
qboolean active;
|
||||
qboolean inmenu; // listener in-menu ?
|
||||
qboolean paused;
|
||||
qboolean streaming; // playing AVI-file
|
||||
qboolean stream_paused; // pause only background track
|
||||
int entnum;
|
||||
int waterlevel;
|
||||
float frametime; // used for sound fade
|
||||
qboolean active;
|
||||
qboolean inmenu; // listener in-menu ?
|
||||
qboolean paused;
|
||||
qboolean streaming; // playing AVI-file
|
||||
qboolean stream_paused; // pause only background track
|
||||
} listener_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
string current; // a currently playing track
|
||||
string loopName; // may be empty
|
||||
stream_t *stream;
|
||||
int source; // may be game, menu, etc
|
||||
string current; // a currently playing track
|
||||
string loopName; // may be empty
|
||||
stream_t *stream;
|
||||
int source; // may be game, menu, etc
|
||||
} bg_track_t;
|
||||
|
||||
//====================================================================
|
||||
|
||||
#define MAX_DYNAMIC_CHANNELS (60 + NUM_AMBIENTS)
|
||||
#define MAX_CHANNELS (256 + MAX_DYNAMIC_CHANNELS) // Scourge Of Armagon has too many static sounds on hip2m4.bsp
|
||||
#define MAX_RAW_CHANNELS 48
|
||||
#define MAX_RAW_SAMPLES 8192
|
||||
#define MAX_DYNAMIC_CHANNELS (60 + NUM_AMBIENTS)
|
||||
#define MAX_CHANNELS (256 + MAX_DYNAMIC_CHANNELS) // Scourge Of Armagon has too many static sounds on hip2m4.bsp
|
||||
#define MAX_RAW_CHANNELS 48
|
||||
#define MAX_RAW_SAMPLES 8192
|
||||
|
||||
extern sound_t ambient_sfx[NUM_AMBIENTS];
|
||||
extern qboolean snd_ambient;
|
||||
extern channel_t channels[MAX_CHANNELS];
|
||||
extern rawchan_t *raw_channels[MAX_RAW_CHANNELS];
|
||||
extern int total_channels;
|
||||
extern int paintedtime;
|
||||
extern int soundtime;
|
||||
extern listener_t s_listener;
|
||||
extern int idsp_room;
|
||||
extern dma_t dma;
|
||||
extern sound_t ambient_sfx[NUM_AMBIENTS];
|
||||
extern qboolean snd_ambient;
|
||||
extern channel_t channels[MAX_CHANNELS];
|
||||
extern rawchan_t *raw_channels[MAX_RAW_CHANNELS];
|
||||
extern int total_channels;
|
||||
extern int paintedtime;
|
||||
extern int soundtime;
|
||||
extern listener_t s_listener;
|
||||
extern int idsp_room;
|
||||
extern dma_t dma;
|
||||
|
||||
extern convar_t s_musicvolume;
|
||||
extern convar_t s_lerping;
|
||||
extern convar_t s_test; // cvar to testify new effects
|
||||
extern convar_t s_musicvolume;
|
||||
extern convar_t s_lerping;
|
||||
extern convar_t s_test; // cvar to test new effects
|
||||
extern convar_t s_samplecount;
|
||||
extern convar_t s_warn_late_precache;
|
||||
extern convar_t snd_mute_losefocus;
|
||||
|
||||
void S_InitScaletable( void );
|
||||
wavdata_t *S_LoadSound( sfx_t *sfx );
|
||||
@@ -292,7 +265,6 @@ void SND_ForceCloseMouth( int entnum );
|
||||
//
|
||||
void S_StreamSoundTrack( void );
|
||||
void S_StreamBackgroundTrack( void );
|
||||
qboolean S_StreamGetCurrentState( char *currentTrack, char *loopTrack, int *position );
|
||||
void S_PrintBackgroundTrackState( void );
|
||||
void S_FadeMusicVolume( float fadePercent );
|
||||
|
||||
|
||||
@@ -250,7 +250,7 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
|
||||
|
||||
if( IsEndOfText( trim ))
|
||||
{
|
||||
Con_Reportf( "TextMessage: unexpected '}' found, line %d\n", lineNumber );
|
||||
Con_Reportf( "%s: unexpected '}' found, line %d\n", __func__, lineNumber );
|
||||
return;
|
||||
}
|
||||
Q_strncpy( currentName, trim, sizeof( currentName ));
|
||||
@@ -263,7 +263,7 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
|
||||
// save name on name heap
|
||||
if( lastNamePos + length > 32768 )
|
||||
{
|
||||
Con_Reportf( "TextMessage: error while parsing!\n" );
|
||||
Con_Reportf( "%s: error while parsing!\n", __func__ );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
|
||||
}
|
||||
if( IsStartOfText( trim ))
|
||||
{
|
||||
Con_Reportf( "TextMessage: unexpected '{' found, line %d\n", lineNumber );
|
||||
Con_Reportf( "%s: unexpected '{' found, line %d\n", __func__, lineNumber );
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@@ -302,7 +302,7 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
|
||||
}
|
||||
}
|
||||
|
||||
Con_Reportf( "TextMessage: parsed %d text messages\n", messageCount );
|
||||
Con_Reportf( "%s: parsed %d text messages\n", __func__, messageCount );
|
||||
nameHeapSize = lastNamePos;
|
||||
textHeapSize = 0;
|
||||
|
||||
@@ -347,7 +347,7 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
|
||||
}
|
||||
|
||||
if(( pCurrentText - (char *)clgame.titles ) != ( textHeapSize + nameHeapSize + messageSize ))
|
||||
Con_DPrintf( S_ERROR "TextMessage: overflow text message buffer!\n" );
|
||||
Con_DPrintf( S_ERROR "%s: overflow text message buffer!\n", __func__ );
|
||||
|
||||
clgame.numTitles = messageCount;
|
||||
}
|
||||
|
||||
@@ -23,55 +23,180 @@ GNU General Public License for more details.
|
||||
#include "input.h"
|
||||
#include "platform/platform.h"
|
||||
|
||||
CVAR_DEFINE_AUTO( vgui_utf8, "0", FCVAR_ARCHIVE, "enable utf-8 support for vgui text" );
|
||||
#define VGUI_MAX_TEXTURES 1024
|
||||
|
||||
static void GAME_EXPORT *VGUI_EngineMalloc( size_t size );
|
||||
static void GAME_EXPORT VGUI_GetMousePos( int *, int * );
|
||||
static void GAME_EXPORT VGUI_CursorSelect( VGUI_DefaultCursor );
|
||||
static byte GAME_EXPORT VGUI_GetColor( int, int );
|
||||
static int GAME_EXPORT VGUI_UtfProcessChar( int in );
|
||||
static qboolean GAME_EXPORT VGUI_IsInGame( void );
|
||||
|
||||
static struct
|
||||
typedef struct vgui_static_s
|
||||
{
|
||||
qboolean initialized;
|
||||
vguiapi_t dllFuncs;
|
||||
VGUI_DefaultCursor cursor;
|
||||
vguiapi_t dllFuncs;
|
||||
|
||||
int textures[VGUI_MAX_TEXTURES];
|
||||
int texture_id;
|
||||
int bound_texture;
|
||||
byte color[4];
|
||||
qboolean enable_texture;
|
||||
|
||||
HINSTANCE hInstance;
|
||||
|
||||
enum VGUI_KeyCode virtualKeyTrans[256];
|
||||
} vgui =
|
||||
{
|
||||
false,
|
||||
{
|
||||
false, // Not initialized yet
|
||||
NULL, // VGUI_DrawInit,
|
||||
NULL, // VGUI_DrawShutdown,
|
||||
NULL, // VGUI_SetupDrawingText,
|
||||
NULL, // VGUI_SetupDrawingRect,
|
||||
NULL, // VGUI_SetupDrawingImage,
|
||||
NULL, // VGUI_BindTexture,
|
||||
NULL, // VGUI_EnableTexture,
|
||||
NULL, // VGUI_CreateTexture,
|
||||
NULL, // VGUI_UploadTexture,
|
||||
NULL, // VGUI_UploadTextureBlock,
|
||||
NULL, // VGUI_DrawQuad,
|
||||
NULL, // VGUI_GetTextureSizes,
|
||||
NULL, // VGUI_GenerateTexture,
|
||||
VGUI_EngineMalloc,
|
||||
VGUI_CursorSelect,
|
||||
VGUI_GetColor,
|
||||
VGUI_IsInGame,
|
||||
Key_EnableTextInput,
|
||||
VGUI_GetMousePos,
|
||||
VGUI_UtfProcessChar,
|
||||
Platform_GetClipboardText,
|
||||
Platform_SetClipboardText,
|
||||
Platform_GetKeyModifiers,
|
||||
},
|
||||
-1
|
||||
} vgui_static_t;
|
||||
|
||||
static vgui_static_t vgui = {
|
||||
false, -1
|
||||
};
|
||||
static CVAR_DEFINE_AUTO( vgui_utf8, "0", FCVAR_ARCHIVE, "enable utf-8 support for vgui text" );
|
||||
|
||||
static void GAME_EXPORT VGUI_DrawInit( void )
|
||||
{
|
||||
memset( vgui.textures, 0, sizeof( vgui.textures ));
|
||||
vgui.texture_id = vgui.bound_texture = 0;
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_DrawShutdown( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 1; i < vgui.texture_id; i++ )
|
||||
ref.dllFuncs.GL_FreeTexture( vgui.textures[i] );
|
||||
}
|
||||
|
||||
static int GAME_EXPORT VGUI_GenerateTexture( void )
|
||||
{
|
||||
if( ++vgui.texture_id >= VGUI_MAX_TEXTURES )
|
||||
Host_Error( "%s: VGUI_MAX_TEXTURES limit exceeded\n", __func__ );
|
||||
|
||||
return vgui.texture_id;
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_UploadTexture( int id, const char *buffer, int width, int height )
|
||||
{
|
||||
rgbdata_t r_image = { 0 };
|
||||
char texName[32];
|
||||
|
||||
if( id <= 0 || id >= VGUI_MAX_TEXTURES )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: bad texture %i. Ignored\n", __func__, id );
|
||||
return;
|
||||
}
|
||||
|
||||
Q_snprintf( texName, sizeof( texName ), "*vgui%i", id );
|
||||
|
||||
r_image.width = width;
|
||||
r_image.height = height;
|
||||
r_image.type = PF_RGBA_32;
|
||||
r_image.size = width * height * 4;
|
||||
r_image.flags = IMAGE_HAS_COLOR|IMAGE_HAS_ALPHA;
|
||||
r_image.buffer = (byte*)buffer;
|
||||
|
||||
vgui.textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE );
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_CreateTexture( int id, int width, int height )
|
||||
{
|
||||
rgbdata_t r_image = { 0 };
|
||||
char texName[32];
|
||||
|
||||
if( id <= 0 || id >= VGUI_MAX_TEXTURES )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: bad texture %i. Ignored\n", __func__, id );
|
||||
return;
|
||||
}
|
||||
|
||||
Q_snprintf( texName, sizeof( texName ), "*vgui%i", id );
|
||||
|
||||
r_image.width = width;
|
||||
r_image.height = height;
|
||||
r_image.type = PF_RGBA_32;
|
||||
r_image.size = width * height * 4;
|
||||
r_image.flags = IMAGE_HAS_COLOR|IMAGE_HAS_ALPHA;
|
||||
r_image.buffer = NULL;
|
||||
|
||||
vgui.textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE );
|
||||
vgui.bound_texture = id;
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_UploadTextureBlock( int id, int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight )
|
||||
{
|
||||
if( id <= 0 || id >= VGUI_MAX_TEXTURES || vgui.textures[id] == 0 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: bad texture %i. Ignored\n", __func__, id );
|
||||
return;
|
||||
}
|
||||
|
||||
ref.dllFuncs.VGUI_UploadTextureBlock( drawX, drawY, rgba, blockWidth, blockHeight );
|
||||
vgui.bound_texture = id;
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_BindTexture( int id )
|
||||
{
|
||||
if( id <= 0 || id >= VGUI_MAX_TEXTURES || !vgui.textures[id] )
|
||||
id = 1; // NOTE: same as bogus index 2700 in GoldSrc
|
||||
|
||||
ref.dllFuncs.GL_Bind( XASH_TEXTURE0, vgui.textures[id] );
|
||||
vgui.bound_texture = id;
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_GetTextureSizes( int *w, int *h )
|
||||
{
|
||||
int texnum;
|
||||
|
||||
if( vgui.bound_texture )
|
||||
texnum = vgui.textures[vgui.bound_texture];
|
||||
else
|
||||
texnum = R_GetBuiltinTexture( REF_DEFAULT_TEXTURE );
|
||||
|
||||
R_GetTextureParms( w, h, texnum );
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_SetupDrawingRect( int *pColor )
|
||||
{
|
||||
ref.dllFuncs.VGUI_SetupDrawing( true );
|
||||
Vector4Set( vgui.color, pColor[0], pColor[1], pColor[2], 255 - pColor[3] );
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_SetupDrawingText( int *pColor )
|
||||
{
|
||||
ref.dllFuncs.VGUI_SetupDrawing( false );
|
||||
Vector4Set( vgui.color, pColor[0], pColor[1], pColor[2], 255 - pColor[3] );
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_DrawQuad( const vpoint_t *ul, const vpoint_t *lr )
|
||||
{
|
||||
float x, y, w, h;
|
||||
|
||||
if( !ul || !lr )
|
||||
return;
|
||||
|
||||
x = ul->point[0];
|
||||
y = ul->point[1];
|
||||
w = lr->point[0] - x;
|
||||
h = lr->point[1] - y;
|
||||
|
||||
SPR_AdjustSize( &x, &y, &w, &h );
|
||||
|
||||
if( vgui.enable_texture )
|
||||
{
|
||||
float s1, s2, t1, t2;
|
||||
|
||||
s1 = ul->coord[0];
|
||||
t1 = ul->coord[1];
|
||||
s2 = lr->coord[0];
|
||||
t2 = lr->coord[1];
|
||||
|
||||
ref.dllFuncs.Color4ub( vgui.color[0], vgui.color[1], vgui.color[2], vgui.color[3] );
|
||||
ref.dllFuncs.R_DrawStretchPic( x, y, w, h, s1, t1, s2, t2, vgui.textures[vgui.bound_texture] );
|
||||
}
|
||||
else
|
||||
{
|
||||
ref.dllFuncs.FillRGBABlend( x, y, w, h, vgui.color[0], vgui.color[1], vgui.color[2], vgui.color[3] );
|
||||
}
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_EnableTexture( qboolean enable )
|
||||
{
|
||||
vgui.enable_texture = enable;
|
||||
}
|
||||
|
||||
static void GAME_EXPORT *VGUI_EngineMalloc( size_t size )
|
||||
{
|
||||
@@ -117,33 +242,46 @@ qboolean VGui_IsActive( void )
|
||||
return vgui.initialized;
|
||||
}
|
||||
|
||||
static void VGui_FillAPIFromRef( vguiapi_t *to, const ref_interface_t *from )
|
||||
{
|
||||
to->DrawInit = from->VGUI_DrawInit;
|
||||
to->DrawShutdown = from->VGUI_DrawShutdown;
|
||||
to->SetupDrawingText = from->VGUI_SetupDrawingText;
|
||||
to->SetupDrawingRect = from->VGUI_SetupDrawingRect;
|
||||
to->SetupDrawingImage = from->VGUI_SetupDrawingImage;
|
||||
to->BindTexture = from->VGUI_BindTexture;
|
||||
to->EnableTexture = from->VGUI_EnableTexture;
|
||||
to->CreateTexture = from->VGUI_CreateTexture;
|
||||
to->UploadTexture = from->VGUI_UploadTexture;
|
||||
to->UploadTextureBlock = from->VGUI_UploadTextureBlock;
|
||||
to->DrawQuad = from->VGUI_DrawQuad;
|
||||
to->GetTextureSizes = from->VGUI_GetTextureSizes;
|
||||
to->GenerateTexture = from->VGUI_GenerateTexture;
|
||||
}
|
||||
|
||||
void VGui_RegisterCvars( void )
|
||||
{
|
||||
Cvar_RegisterVariable( &vgui_utf8 );
|
||||
}
|
||||
|
||||
static const vguiapi_t gEngfuncs =
|
||||
{
|
||||
false, // Not initialized yet
|
||||
VGUI_DrawInit, // VGUI_DrawInit,
|
||||
VGUI_DrawShutdown, // VGUI_DrawShutdown,
|
||||
VGUI_SetupDrawingText, // VGUI_SetupDrawingText,
|
||||
VGUI_SetupDrawingRect, // VGUI_SetupDrawingRect,
|
||||
VGUI_SetupDrawingText, // VGUI_SetupDrawingImage, (same as text)
|
||||
VGUI_BindTexture, // VGUI_BindTexture,
|
||||
VGUI_EnableTexture, // VGUI_EnableTexture,
|
||||
VGUI_CreateTexture, // VGUI_CreateTexture,
|
||||
VGUI_UploadTexture, // VGUI_UploadTexture,
|
||||
VGUI_UploadTextureBlock, // VGUI_UploadTextureBlock,
|
||||
VGUI_DrawQuad, // VGUI_DrawQuad,
|
||||
VGUI_GetTextureSizes, // VGUI_GetTextureSizes,
|
||||
VGUI_GenerateTexture, // VGUI_GenerateTexture,
|
||||
VGUI_EngineMalloc,
|
||||
VGUI_CursorSelect,
|
||||
VGUI_GetColor,
|
||||
VGUI_IsInGame,
|
||||
Key_EnableTextInput,
|
||||
VGUI_GetMousePos,
|
||||
VGUI_UtfProcessChar,
|
||||
Platform_GetClipboardText,
|
||||
Platform_SetClipboardText,
|
||||
Platform_GetKeyModifiers,
|
||||
};
|
||||
|
||||
qboolean VGui_LoadProgs( HINSTANCE hInstance )
|
||||
{
|
||||
void (*F)( vguiapi_t* );
|
||||
qboolean client = hInstance != NULL;
|
||||
|
||||
memcpy( &vgui.dllFuncs, &gEngfuncs, sizeof( vgui.dllFuncs ));
|
||||
|
||||
// not loading interface from client.dll, load vgui_support.dll instead
|
||||
if( !client )
|
||||
{
|
||||
@@ -167,7 +305,7 @@ qboolean VGui_LoadProgs( HINSTANCE hInstance )
|
||||
{
|
||||
if( FS_FileExists( vguiloader, false ))
|
||||
Con_Reportf( S_ERROR "Failed to load vgui_support library: %s\n", COM_GetLibraryError() );
|
||||
else Con_Reportf( "vgui_support: not found\n" );
|
||||
else Con_Reportf( "%s: not found\n", __func__ );
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -178,16 +316,15 @@ qboolean VGui_LoadProgs( HINSTANCE hInstance )
|
||||
|
||||
if( F )
|
||||
{
|
||||
VGui_FillAPIFromRef( &vgui.dllFuncs, &ref.dllFuncs );
|
||||
F( &vgui.dllFuncs );
|
||||
|
||||
vgui.initialized = vgui.dllFuncs.initialized = true;
|
||||
Con_Reportf( "vgui_support: initialized legacy API in %s module\n", client ? "client" : "support" );
|
||||
Con_Reportf( "%s: initialized legacy API in %s module\n", __func__, client ? "client" : "support" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Con_Reportf( S_ERROR "Failed to find VGUI support API entry point in %s module\n", client ? "client" : "support" );
|
||||
Con_Reportf( S_ERROR "%s: Failed to find VGUI support API entry point in %s module\n", __func__, client ? "client" : "support" );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -233,8 +370,9 @@ void VGui_Shutdown( void )
|
||||
if( vgui.hInstance )
|
||||
COM_FreeLibrary( vgui.hInstance );
|
||||
|
||||
// drop pointers to now unloaded vgui_support
|
||||
memcpy( &vgui.dllFuncs, &gEngfuncs, sizeof( vgui.dllFuncs ));
|
||||
vgui.hInstance = NULL;
|
||||
vgui.initialized = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ static void VID_Mode_f( void )
|
||||
vidmode = R_GetVideoMode( Q_atoi( Cmd_Argv( 1 )) );
|
||||
if( !vidmode )
|
||||
{
|
||||
Con_Print( S_ERROR "unable to set mode, backend returned null" );
|
||||
Con_Printf( S_ERROR "unable to set mode, backend returned null" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ typedef struct OpusCustomMode OpusCustomMode;
|
||||
#define VOICE_PCM_CHANNELS 1 // always mono
|
||||
|
||||
// never change these parameters when using opuscustom
|
||||
#define VOICE_OPUS_CUSTOM_SAMPLERATE SOUND_44k
|
||||
#define VOICE_OPUS_CUSTOM_SAMPLERATE 44100
|
||||
// must follow opus custom requirements
|
||||
// also be divisible with MAX_RAW_SAMPLES
|
||||
#define VOICE_OPUS_CUSTOM_FRAME_SIZE 1024
|
||||
|
||||
@@ -16,21 +16,20 @@ GNU General Public License for more details.
|
||||
#ifndef VOX_H
|
||||
#define VOX_H
|
||||
|
||||
#define CVOXWORDMAX 64
|
||||
|
||||
#define SENTENCE_INDEX -99999 // unique sentence index
|
||||
#define CVOXWORDMAX 64
|
||||
#define SENTENCE_INDEX -99999 // unique sentence index
|
||||
|
||||
typedef struct voxword_s
|
||||
{
|
||||
int volume; // increase percent, ie: 125 = 125% increase
|
||||
int pitch; // pitch shift up percent
|
||||
int start; // offset start of wave percent
|
||||
int end; // offset end of wave percent
|
||||
int cbtrim; // end of wave after being trimmed to 'end'
|
||||
int fKeepCached; // 1 if this word was already in cache before sentence referenced it
|
||||
int samplefrac; // if pitch shifting, this is position into wav * 256
|
||||
int timecompress; // % of wave to skip during playback (causes no pitch shift)
|
||||
sfx_t *sfx; // name and cache pointer
|
||||
int volume; // increase percent, ie: 125 = 125% increase
|
||||
int pitch; // pitch shift up percent
|
||||
int start; // offset start of wave percent
|
||||
int end; // offset end of wave percent
|
||||
int cbtrim; // end of wave after being trimmed to 'end'
|
||||
int fKeepCached; // 1 if this word was already in cache before sentence referenced it
|
||||
int samplefrac; // if pitch shifting, this is position into wav * 256
|
||||
int timecompress; // % of wave to skip during playback (causes no pitch shift)
|
||||
sfx_t *sfx; // name and cache pointer
|
||||
} voxword_t;
|
||||
|
||||
struct channel_s;
|
||||
|
||||
@@ -19,13 +19,15 @@ GNU General Public License for more details.
|
||||
|
||||
#define HASH_SIZE 128 // 128 * 4 * 4 == 2048 bytes
|
||||
|
||||
typedef struct base_command_hashmap_s
|
||||
typedef struct base_command_hashmap_s base_command_hashmap_t;
|
||||
|
||||
struct base_command_hashmap_s
|
||||
{
|
||||
base_command_t *basecmd; // base command: cvar, alias or command
|
||||
const char *name; // key for searching
|
||||
base_command_type_e type; // type for faster searching
|
||||
struct base_command_hashmap_s *next;
|
||||
} base_command_hashmap_t;
|
||||
base_command_t *basecmd; // base command: cvar, alias or command
|
||||
base_command_hashmap_t *next;
|
||||
base_command_type_e type; // type for faster searching
|
||||
char name[1]; // key for searching
|
||||
};
|
||||
|
||||
static base_command_hashmap_t *hashed_cmds[HASH_SIZE];
|
||||
|
||||
@@ -124,11 +126,12 @@ void BaseCmd_Insert( base_command_type_e type, base_command_t *basecmd, const ch
|
||||
{
|
||||
base_command_hashmap_t *elem, *cur, *find;
|
||||
uint hash = BaseCmd_HashKey( name );
|
||||
size_t len = Q_strlen( name );
|
||||
|
||||
elem = Z_Malloc( sizeof( base_command_hashmap_t ) );
|
||||
elem = Z_Malloc( sizeof( base_command_hashmap_t ) + len );
|
||||
elem->basecmd = basecmd;
|
||||
elem->type = type;
|
||||
elem->name = name;
|
||||
Q_strncpy( elem->name, name, len + 1 );
|
||||
|
||||
// link the variable in alphanumerical order
|
||||
for( cur = NULL, find = hashed_cmds[hash];
|
||||
@@ -159,7 +162,7 @@ void BaseCmd_Remove( base_command_type_e type, const char *name )
|
||||
|
||||
if( !i )
|
||||
{
|
||||
Con_Reportf( S_ERROR "Couldn't find %s in buckets\n", name );
|
||||
Con_Reportf( S_ERROR "%s: Couldn't find %s in buckets\n", __func__, name );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,6 @@ typedef enum base_command_type
|
||||
|
||||
typedef void base_command_t;
|
||||
|
||||
|
||||
|
||||
void BaseCmd_Init( void );
|
||||
base_command_t *BaseCmd_Find( base_command_type_e type, const char *name );
|
||||
void BaseCmd_FindAll( const char *name,
|
||||
|
||||
@@ -86,7 +86,7 @@ static void *Cbuf_GetSpace( cmdbuf_t *buf, int length )
|
||||
if(( buf->cursize + length ) > buf->maxsize )
|
||||
{
|
||||
buf->cursize = 0;
|
||||
Host_Error( "Cbuf_GetSpace: overflow\n" );
|
||||
Host_Error( "%s: overflow\n", __func__ );
|
||||
}
|
||||
|
||||
data = buf->data + buf->cursize;
|
||||
@@ -156,7 +156,7 @@ static void Cbuf_InsertTextToBuffer( cmdbuf_t *buf, const char *text )
|
||||
|
||||
if(( buf->cursize + l ) >= buf->maxsize )
|
||||
{
|
||||
Con_Reportf( S_WARN "Cbuf_InsertText: overflow\n" );
|
||||
Con_Reportf( S_WARN "%s: overflow\n", __func__ );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -224,7 +224,7 @@ static void Cbuf_ExecuteCommandsFromBuffer( cmdbuf_t *buf, qboolean isPrivileged
|
||||
|
||||
if( i >= ( MAX_CMD_LINE - 1 ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Cbuf_Execute: command string owerflow\n" );
|
||||
Con_DPrintf( S_ERROR "%s: command string owerflow\n", __func__ );
|
||||
line[0] = 0;
|
||||
}
|
||||
else
|
||||
@@ -640,7 +640,7 @@ void Cmd_TokenizeString( const char *text )
|
||||
while( 1 )
|
||||
{
|
||||
// skip whitespace up to a /n
|
||||
while( *text && *text <= ' ' && *text != '\r' && *text != '\n' )
|
||||
while( *text && ((byte)*text ) <= ' ' && *text != '\r' && *text != '\n' )
|
||||
text++;
|
||||
|
||||
if( *text == '\n' || *text == '\r' )
|
||||
@@ -682,7 +682,7 @@ static int Cmd_AddCommandEx( const char *funcname, const char *cmd_name, xcomman
|
||||
|
||||
if( !COM_CheckString( cmd_name ))
|
||||
{
|
||||
Con_Reportf( S_ERROR "%s: NULL name\n", funcname );
|
||||
Con_Reportf( S_ERROR "%s: NULL name\n", funcname );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -728,7 +728,7 @@ Cmd_AddCommand
|
||||
*/
|
||||
void Cmd_AddCommand( const char *cmd_name, xcommand_t function, const char *cmd_desc )
|
||||
{
|
||||
Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, cmd_desc, 0 );
|
||||
Cmd_AddCommandEx( __func__, cmd_name, function, cmd_desc, 0 );
|
||||
}
|
||||
|
||||
|
||||
@@ -739,7 +739,7 @@ Cmd_AddRestrictedCommand
|
||||
*/
|
||||
void Cmd_AddRestrictedCommand( const char *cmd_name, xcommand_t function, const char *cmd_desc )
|
||||
{
|
||||
Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, cmd_desc, CMD_PRIVILEGED );
|
||||
Cmd_AddCommandEx( __func__, cmd_name, function, cmd_desc, CMD_PRIVILEGED );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -749,7 +749,7 @@ Cmd_AddServerCommand
|
||||
*/
|
||||
void GAME_EXPORT Cmd_AddServerCommand( const char *cmd_name, xcommand_t function )
|
||||
{
|
||||
Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, "server command", CMD_SERVERDLL );
|
||||
Cmd_AddCommandEx( __func__, cmd_name, function, "server command", CMD_SERVERDLL );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -767,7 +767,7 @@ int GAME_EXPORT Cmd_AddClientCommand( const char *cmd_name, xcommand_t function
|
||||
flags |= CMD_PRIVILEGED;
|
||||
}
|
||||
|
||||
return Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, "client command", flags );
|
||||
return Cmd_AddCommandEx( __func__, cmd_name, function, "client command", flags );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -777,7 +777,7 @@ Cmd_AddGameUICommand
|
||||
*/
|
||||
int GAME_EXPORT Cmd_AddGameUICommand( const char *cmd_name, xcommand_t function )
|
||||
{
|
||||
return Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, "gameui command", CMD_GAMEUIDLL );
|
||||
return Cmd_AddCommandEx( __func__, cmd_name, function, "gameui command", CMD_GAMEUIDLL );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -787,7 +787,7 @@ Cmd_AddRefCommand
|
||||
*/
|
||||
int Cmd_AddRefCommand( const char *cmd_name, xcommand_t function, const char *description )
|
||||
{
|
||||
return Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, description, CMD_REFDLL );
|
||||
return Cmd_AddCommandEx( __func__, cmd_name, function, description, CMD_REFDLL );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -949,7 +949,7 @@ static void Cmd_Else_f( void )
|
||||
|
||||
static qboolean Cmd_ShouldAllowCommand( cmd_t *cmd, qboolean isPrivileged )
|
||||
{
|
||||
const char *prefixes[] = { "cl_", "gl_", "r_", "m_", "hud_", "joy_" };
|
||||
const char *prefixes[] = { "cl_", "gl_", "r_", "m_", "hud_", "joy_", "con_", "scr_" };
|
||||
int i;
|
||||
|
||||
// always allow local commands
|
||||
@@ -1015,7 +1015,7 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
|
||||
*ptoken++ = *text++;
|
||||
*ptoken = 0;
|
||||
|
||||
len += Q_strncpy( pcmd, Cvar_VariableString( token ), MAX_CMD_LINE - len );
|
||||
len += Q_strncpy( pcmd, Cvar_VariableString( token ), sizeof( token ) - len );
|
||||
pcmd = command + len;
|
||||
|
||||
if( !*text ) break;
|
||||
|
||||
@@ -39,9 +39,6 @@ GNU General Public License for more details.
|
||||
// end game final default message
|
||||
#define DEFAULT_ENDGAME_MESSAGE "The End"
|
||||
|
||||
// path to the hash-pak that contain custom player decals
|
||||
#define CUSTOM_RES_PATH "custom.hpk"
|
||||
|
||||
// path to default playermodel in GoldSrc
|
||||
#define DEFAULT_PLAYER_PATH_HALFLIFE "models/player.mdl"
|
||||
|
||||
@@ -62,7 +59,7 @@ GNU General Public License for more details.
|
||||
#define DEFAULT_SAVE_DIRECTORY "save/"
|
||||
|
||||
// fallback to this skybox
|
||||
#define DEFAULT_SKYBOX_PATH "gfx/env/desert"
|
||||
#define DEFAULT_SKYBOX_NAME "desert"
|
||||
|
||||
// playlist for startup videos
|
||||
#define DEFAULT_VIDEOLIST_PATH "media/StartupVids.txt"
|
||||
|
||||
@@ -25,16 +25,19 @@ GNU General Public License for more details.
|
||||
|
||||
static const char *file_exts[] =
|
||||
{
|
||||
"cfg",
|
||||
"lst",
|
||||
"exe",
|
||||
"vbs",
|
||||
"com",
|
||||
"bat",
|
||||
"dll",
|
||||
"ini",
|
||||
"log",
|
||||
"sys",
|
||||
// ban text files that don't make sense as resource
|
||||
"cfg", "lst", "ini", "log",
|
||||
|
||||
// ban Windows code
|
||||
"exe", "vbs", "com", "bat",
|
||||
"dll", "sys", "ps1",
|
||||
|
||||
// ban common unix code
|
||||
// NOTE: in unix anything can be executed as long it has access flag
|
||||
"so", "sh", "dylib",
|
||||
|
||||
// ban mobile archives
|
||||
"apk", "ipa",
|
||||
};
|
||||
|
||||
#ifdef _DEBUG
|
||||
@@ -900,7 +903,10 @@ qboolean COM_IsSafeFileToDownload( const char *filename )
|
||||
if( !COM_CheckString( filename ))
|
||||
return false;
|
||||
|
||||
if( !Q_strncmp( filename, "!MD5", 4 ))
|
||||
ext = COM_FileExtension( lwrfilename );
|
||||
|
||||
// only allow extensionless files that start with !MD5
|
||||
if( !Q_strncmp( filename, "!MD5", 4 ) && ext[0] == 0 )
|
||||
return true;
|
||||
|
||||
Q_strnlwr( filename, lwrfilename, sizeof( lwrfilename ));
|
||||
@@ -923,8 +929,6 @@ qboolean COM_IsSafeFileToDownload( const char *filename )
|
||||
if( Q_strlen( first ) != 4 )
|
||||
return false;
|
||||
|
||||
ext = COM_FileExtension( lwrfilename );
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( file_exts ); i++ )
|
||||
{
|
||||
if( !Q_stricmp( ext, file_exts[i] ))
|
||||
@@ -967,7 +971,7 @@ used by CS:CZ
|
||||
*/
|
||||
void *GAME_EXPORT pfnSequenceGet( const char *fileName, const char *entryName )
|
||||
{
|
||||
Msg( "Sequence_Get: file %s, entry %s\n", fileName, entryName );
|
||||
Msg( "%s: file %s, entry %s\n", __func__, fileName, entryName );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -981,7 +985,7 @@ used by CS:CZ
|
||||
*/
|
||||
void *GAME_EXPORT pfnSequencePickSentence( const char *groupName, int pickMethod, int *picked )
|
||||
{
|
||||
Msg( "Sequence_PickSentence: group %s, pickMethod %i\n", groupName, pickMethod );
|
||||
Msg( "%s: group %s, pickMethod %i\n", __func__, groupName, pickMethod );
|
||||
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -157,13 +157,16 @@ extern convar_t gl_vsync;
|
||||
extern convar_t scr_loading;
|
||||
extern convar_t scr_download;
|
||||
extern convar_t cmd_scripting;
|
||||
extern convar_t cl_allow_levelshots;
|
||||
extern convar_t host_allow_materials;
|
||||
extern convar_t host_developer;
|
||||
extern convar_t host_limitlocal;
|
||||
extern convar_t host_maxfps;
|
||||
extern convar_t sys_timescale;
|
||||
extern convar_t cl_filterstuffcmd;
|
||||
extern convar_t rcon_password;
|
||||
extern convar_t hpk_custom_file;
|
||||
|
||||
#define Mod_AllowMaterials() ( host_allow_materials.value != 0.0f && !FBitSet( host.features, ENGINE_DISABLE_HDTEXTURES ))
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
@@ -180,15 +183,6 @@ GAMEINFO stuff
|
||||
internal shared gameinfo structure (readonly for engine parts)
|
||||
========================================================================
|
||||
*/
|
||||
typedef struct sysinfo_s
|
||||
{
|
||||
string exeName; // exe.filename
|
||||
string rcName; // .rc script name
|
||||
string basedirName; // name of base directory
|
||||
string gamedll;
|
||||
string clientlib;
|
||||
} sysinfo_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HOST_INIT = 0, // initalize operations
|
||||
@@ -275,94 +269,81 @@ typedef enum bugcomp_e
|
||||
{
|
||||
// reverts fix for pfnPEntityOfEntIndex for bug compatibility with GoldSrc
|
||||
BUGCOMP_PENTITYOFENTINDEX_FLAG = BIT( 0 ),
|
||||
|
||||
// rewrites mod's attempts to write GoldSrc-specific messages into Xash protocol
|
||||
// (new wrappers are added by request)
|
||||
BUGCOMP_MESSAGE_REWRITE_FACILITY_FLAG = BIT( 1 ),
|
||||
} bugcomp_t;
|
||||
|
||||
typedef struct host_parm_s
|
||||
{
|
||||
HINSTANCE hInst;
|
||||
HANDLE hMutex;
|
||||
// ==== shared through RefAPI's ref_host_t
|
||||
double realtime; // host.curtime
|
||||
double frametime; // time between engine frames
|
||||
uint features; // custom features that enables by mod-maker request
|
||||
// ==== shared through RefAPI's ref_host_t
|
||||
|
||||
host_status_t status; // global host state
|
||||
game_status_t game; // game manager
|
||||
uint type; // running at
|
||||
jmp_buf abortframe; // abort current frame
|
||||
dword errorframe; // to prevent multiple host error
|
||||
poolhandle_t mempool; // static mempool for misc allocations
|
||||
string finalmsg; // server shutdown final message
|
||||
string downloadfile; // filename to be downloading
|
||||
int downloadcount; // how many files remain to downloading
|
||||
char deferred_cmd[128]; // deferred commands
|
||||
host_redirect_t rd; // remote console
|
||||
host_status_t status; // global host state
|
||||
game_status_t game; // game manager
|
||||
uint type; // running at
|
||||
poolhandle_t mempool; // static mempool for misc allocations
|
||||
poolhandle_t imagepool; // imagelib mempool
|
||||
poolhandle_t soundpool; // soundlib mempool
|
||||
string finalmsg; // server shutdown final message
|
||||
string downloadfile; // filename to be downloading
|
||||
int downloadcount; // how many files remain to downloading
|
||||
char deferred_cmd[128];// deferred commands
|
||||
|
||||
host_redirect_t rd; // remote console
|
||||
|
||||
void *hWnd; // main window
|
||||
|
||||
// command line parms
|
||||
int argc;
|
||||
char **argv;
|
||||
char **argv;
|
||||
int argc;
|
||||
|
||||
// ==== shared through RefAPI's ref_host_t
|
||||
double realtime; // host.curtime
|
||||
double frametime; // time between engine frames
|
||||
uint features; // custom features that enables by mod-maker request
|
||||
// ==== shared through RefAPI's ref_host_t
|
||||
uint framecount; // global framecount
|
||||
uint errorframe; // to prevent multiple host error
|
||||
uint32_t bugcomp; // bug compatibility level, for very "special" games
|
||||
double realframetime; // for some system events, e.g. console animations
|
||||
double starttime; // measure time to first frame
|
||||
double pureframetime; // count of sleeps can be inserted between frames
|
||||
double force_draw_version_time;
|
||||
|
||||
double realframetime; // for some system events, e.g. console animations
|
||||
char draw_decals[MAX_DECALS][MAX_QPATH]; // list of unique decal indexes
|
||||
vec3_t player_mins[MAX_MAP_HULLS]; // 4 hulls allowed
|
||||
vec3_t player_maxs[MAX_MAP_HULLS]; // 4 hulls allowed
|
||||
|
||||
uint framecount; // global framecount
|
||||
|
||||
// list of unique decal indexes
|
||||
char draw_decals[MAX_DECALS][MAX_QPATH];
|
||||
|
||||
vec3_t player_mins[MAX_MAP_HULLS]; // 4 hulls allowed
|
||||
vec3_t player_maxs[MAX_MAP_HULLS]; // 4 hulls allowed
|
||||
|
||||
void* hWnd; // main window
|
||||
qboolean allow_console; // allow console in dev-mode or multiplayer game
|
||||
qboolean allow_console_init; // initial value to allow the console
|
||||
qboolean key_overstrike; // key overstrike mode
|
||||
qboolean stuffcmds_pending; // should execute stuff commands
|
||||
qboolean allow_cheats; // this host will allow cheating
|
||||
qboolean con_showalways; // show console always (developer and dedicated)
|
||||
qboolean change_game; // initialize when game is changed
|
||||
qboolean mouse_visible; // vgui override cursor control (never change outside Platform_SetCursorType!)
|
||||
qboolean shutdown_issued; // engine is shutting down
|
||||
double force_draw_version_time;
|
||||
qboolean apply_game_config; // when true apply only to game cvars and ignore all other commands
|
||||
qboolean apply_opengl_config;// when true apply only to opengl cvars and ignore all other commands
|
||||
qboolean config_executed; // a bit who indicated was config.cfg already executed e.g. from valve.rc
|
||||
qboolean crashed; // set to true if crashed
|
||||
qboolean daemonized;
|
||||
qboolean enabledll;
|
||||
qboolean textmode;
|
||||
qboolean allow_console; // allow console in dev-mode or multiplayer game
|
||||
qboolean allow_console_init; // initial value to allow the console
|
||||
qboolean key_overstrike; // key overstrike mode
|
||||
qboolean stuffcmds_pending; // should execute stuff commands
|
||||
qboolean allow_cheats; // this host will allow cheating
|
||||
qboolean change_game; // initialize when game is changed
|
||||
qboolean mouse_visible; // vgui override cursor control (never change outside Platform_SetCursorType!)
|
||||
qboolean shutdown_issued; // engine is shutting down
|
||||
qboolean apply_game_config; // when true apply only to game cvars and ignore all other commands
|
||||
qboolean apply_opengl_config; // when true apply only to opengl cvars and ignore all other commands
|
||||
qboolean config_executed; // a bit who indicated was config.cfg already executed e.g. from valve.rc
|
||||
qboolean crashed; // set to true if crashed
|
||||
#if XASH_DLL_LOADER
|
||||
qboolean enabledll;
|
||||
#endif
|
||||
qboolean textmode;
|
||||
|
||||
// some settings were changed and needs to global update
|
||||
qboolean userinfo_changed;
|
||||
qboolean movevars_changed;
|
||||
qboolean renderinfo_changed;
|
||||
|
||||
char rootdir[MAX_OSPATH]; // member root directory
|
||||
char rodir[MAX_OSPATH]; // readonly root
|
||||
char gamefolder[MAX_QPATH]; // it's a default gamefolder
|
||||
poolhandle_t imagepool; // imagelib mempool
|
||||
poolhandle_t soundpool; // soundlib mempool
|
||||
qboolean userinfo_changed;
|
||||
qboolean movevars_changed;
|
||||
qboolean renderinfo_changed;
|
||||
|
||||
// for IN_MouseMove() easy access
|
||||
int window_center_x;
|
||||
int window_center_y;
|
||||
|
||||
struct decallist_s *decalList; // used for keep decals, when renderer is restarted or changed
|
||||
int numdecals;
|
||||
|
||||
// bug compatibility level, for very "special" games
|
||||
uint32_t bugcomp;
|
||||
|
||||
// measure time to first frame
|
||||
double starttime;
|
||||
|
||||
// count of sleeps can be inserted between frames
|
||||
double pureframetime;
|
||||
int window_center_x;
|
||||
int window_center_y;
|
||||
string gamedll;
|
||||
string clientlib;
|
||||
} host_parm_t;
|
||||
|
||||
extern host_parm_t host;
|
||||
extern sysinfo_t SI;
|
||||
|
||||
#define CMD_SERVERDLL BIT( 0 ) // added by server.dll
|
||||
#define CMD_CLIENTDLL BIT( 1 ) // added by client.dll
|
||||
@@ -376,8 +357,7 @@ typedef void (*xcommand_t)( void );
|
||||
//
|
||||
// filesystem_engine.c
|
||||
//
|
||||
qboolean FS_LoadProgs( void );
|
||||
void FS_Init( void );
|
||||
void FS_Init( const char *basedir );
|
||||
void FS_Shutdown( void );
|
||||
void *FS_GetNativeObject( const char *obj );
|
||||
|
||||
@@ -475,14 +455,6 @@ typedef enum
|
||||
WF_TOTALCOUNT, // must be last
|
||||
} sndformat_t;
|
||||
|
||||
// soundlib global settings
|
||||
typedef enum
|
||||
{
|
||||
SL_USE_LERPING = BIT(0), // lerping sounds during resample
|
||||
SL_KEEP_8BIT = BIT(1), // don't expand 8bit sounds automatically up to 16 bit
|
||||
SL_ALLOW_OVERWRITE = BIT(2), // allow to overwrite stored sounds
|
||||
} slFlags_t;
|
||||
|
||||
// wavdata output flags
|
||||
typedef enum
|
||||
{
|
||||
@@ -491,21 +463,20 @@ typedef enum
|
||||
SOUND_STREAM = BIT( 1 ), // this is a streaminfo, not a real sound
|
||||
|
||||
// Sound_Process manipulation flags
|
||||
SOUND_RESAMPLE = BIT(12), // resample sound to specified rate
|
||||
SOUND_CONVERT16BIT = BIT(13), // change sound resolution from 8 bit to 16
|
||||
SOUND_RESAMPLE = BIT( 12 ), // resample sound to specified rate
|
||||
} sndFlags_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
word rate; // num samples per second (e.g. 11025 - 11 khz)
|
||||
byte width; // resolution - bum bits divided by 8 (8 bit is 1, 16 bit is 2)
|
||||
byte channels; // num channels (1 - mono, 2 - stereo)
|
||||
int loopStart; // offset at this point sound will be looping while playing more than only once
|
||||
int samples; // total samplecount in wav
|
||||
uint type; // compression type
|
||||
uint flags; // misc sound flags
|
||||
byte *buffer; // sound buffer
|
||||
size_t size; // for bounds checking
|
||||
word rate; // num samples per second (e.g. 11025 - 11 khz)
|
||||
byte width; // resolution - bum bits divided by 8 (8 bit is 1, 16 bit is 2)
|
||||
byte channels; // num channels (1 - mono, 2 - stereo)
|
||||
uint loopStart; // offset at this point sound will be looping while playing more than only once
|
||||
uint samples; // total samplecount in wav
|
||||
uint type; // compression type
|
||||
uint flags; // misc sound flags
|
||||
byte *buffer; // sound buffer
|
||||
size_t size; // for bounds checking
|
||||
} wavdata_t;
|
||||
|
||||
//
|
||||
@@ -540,12 +511,10 @@ void Host_WriteServerConfig( const char *name );
|
||||
void Host_WriteOpenGLConfig( void );
|
||||
void Host_WriteVideoConfig( void );
|
||||
void Host_WriteConfig( void );
|
||||
qboolean Host_IsLocalGame( void );
|
||||
qboolean Host_IsLocalClient( void );
|
||||
void Host_ShutdownServer( void );
|
||||
void Host_Error( const char *error, ... ) _format( 1 );
|
||||
void Host_ValidateEngineFeatures( uint32_t features );
|
||||
void Host_Frame( float time );
|
||||
void Host_Frame( double time );
|
||||
void Host_Credits( void );
|
||||
|
||||
//
|
||||
@@ -556,7 +525,7 @@ void COM_NewGame( char const *pMapName );
|
||||
void COM_LoadLevel( char const *pMapName, qboolean background );
|
||||
void COM_LoadGame( char const *pSaveFileName );
|
||||
void COM_ChangeLevel( char const *pNewLevel, char const *pLandmarkName, qboolean background );
|
||||
void COM_Frame( float time );
|
||||
void COM_Frame( double time );
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
@@ -682,7 +651,6 @@ struct physent_s;
|
||||
struct sv_client_s;
|
||||
typedef struct sizebuf_s sizebuf_t;
|
||||
qboolean CL_IsInGame( void );
|
||||
qboolean CL_IsInMenu( void );
|
||||
qboolean CL_IsInConsole( void );
|
||||
qboolean CL_IsThirdPerson( void );
|
||||
qboolean CL_IsIntermission( void );
|
||||
@@ -700,8 +668,9 @@ void Log_Printf( const char *fmt, ... ) _format( 1 );
|
||||
void SV_BroadcastCommand( const char *fmt, ... ) _format( 1 );
|
||||
void SV_BroadcastPrintf( struct sv_client_s *ignore, const char *fmt, ... ) _format( 2 );
|
||||
void CL_ClearStaticEntities( void );
|
||||
qboolean S_StreamGetCurrentState( char *currentTrack, char *loopTrack, int *position );
|
||||
qboolean S_StreamGetCurrentState( char *currentTrack, size_t currentTrackSize, char *loopTrack, size_t loopTrackSize, int *position );
|
||||
void CL_ServerCommand( qboolean reliable, const char *fmt, ... ) _format( 2 );
|
||||
void CL_UpdateInfo( const char *key, const char *value );
|
||||
void CL_HudMessage( const char *pMessage );
|
||||
const char *CL_MsgInfo( int cmd );
|
||||
void SV_DrawDebugTriangles( void );
|
||||
@@ -775,6 +744,18 @@ int COM_CompareFileTime( const char *filename1, const char *filename2, int *iCom
|
||||
char *va( const char *format, ... ) _format( 1 );
|
||||
qboolean CRC32_MapFile( dword *crcvalue, const char *filename, qboolean multiplayer );
|
||||
|
||||
static inline qboolean Host_IsLocalGame( void )
|
||||
{
|
||||
if( SV_Active( ))
|
||||
return SV_GetMaxClients() == 1 ? true : false;
|
||||
return CL_GetMaxClients() == 1 ? true : false;
|
||||
}
|
||||
|
||||
static inline qboolean Host_IsLocalClient( void )
|
||||
{
|
||||
return CL_Initialized( ) && SV_Initialized( ) ? true : false;
|
||||
}
|
||||
|
||||
// soundlib shared exports
|
||||
qboolean S_Init( void );
|
||||
void S_Shutdown( void );
|
||||
|
||||
@@ -465,7 +465,7 @@ static qboolean Cmd_GetSoundList( const char *s, char *completedname, int length
|
||||
t = FS_Search( va( "%s%s*.*", DEFAULT_SOUNDPATH, s ), true, false );
|
||||
if( !t ) return false;
|
||||
|
||||
Q_strncpy( matchbuf, t->filenames[0] + sizeof( DEFAULT_SOUNDPATH ) - 1, MAX_STRING );
|
||||
Q_strncpy( matchbuf, t->filenames[0] + sizeof( DEFAULT_SOUNDPATH ) - 1, sizeof( matchbuf ));
|
||||
COM_StripExtension( matchbuf );
|
||||
if( completedname && length )
|
||||
Q_strncpy( completedname, matchbuf, length );
|
||||
@@ -478,7 +478,7 @@ static qboolean Cmd_GetSoundList( const char *s, char *completedname, int length
|
||||
if( Q_stricmp( ext, "wav" ) && Q_stricmp( ext, "mp3" ))
|
||||
continue;
|
||||
|
||||
Q_strncpy( matchbuf, t->filenames[i] + sizeof( DEFAULT_SOUNDPATH ) - 1, MAX_STRING );
|
||||
Q_strncpy( matchbuf, t->filenames[i] + sizeof( DEFAULT_SOUNDPATH ) - 1, sizeof( matchbuf ));
|
||||
COM_StripExtension( matchbuf );
|
||||
Con_Printf( "%16s\n", matchbuf );
|
||||
numsounds++;
|
||||
@@ -585,7 +585,7 @@ static qboolean Cmd_GetKeysList( const char *s, char *completedname, int length
|
||||
Con_Printf( "%16s\n", matchbuf );
|
||||
}
|
||||
|
||||
Con_Printf( "\n^3 %lu keys found.\n", numkeys );
|
||||
Con_Printf( "\n^3 %zu keys found.\n", numkeys );
|
||||
|
||||
if( completedname && length )
|
||||
{
|
||||
@@ -764,14 +764,14 @@ static qboolean Cmd_GetGamesList( const char *s, char *completedname, int length
|
||||
}
|
||||
|
||||
if( !numgamedirs ) return false;
|
||||
Q_strncpy( matchbuf, gamedirs[0], MAX_STRING );
|
||||
Q_strncpy( matchbuf, gamedirs[0], sizeof( matchbuf ));
|
||||
if( completedname && length )
|
||||
Q_strncpy( completedname, matchbuf, length );
|
||||
if( numgamedirs == 1 ) return true;
|
||||
|
||||
for( i = 0; i < numgamedirs; i++ )
|
||||
{
|
||||
Q_strncpy( matchbuf, gamedirs[i], MAX_STRING );
|
||||
Q_strncpy( matchbuf, gamedirs[i], sizeof( matchbuf ));
|
||||
Con_Printf( "%16s\n", matchbuf );
|
||||
}
|
||||
|
||||
@@ -825,14 +825,14 @@ static qboolean Cmd_GetCDList( const char *s, char *completedname, int length )
|
||||
}
|
||||
|
||||
if( !numcdcommands ) return false;
|
||||
Q_strncpy( matchbuf, cdcommands[0], MAX_STRING );
|
||||
Q_strncpy( matchbuf, cdcommands[0], sizeof( matchbuf ));
|
||||
if( completedname && length )
|
||||
Q_strncpy( completedname, matchbuf, length );
|
||||
if( numcdcommands == 1 ) return true;
|
||||
|
||||
for( i = 0; i < numcdcommands; i++ )
|
||||
{
|
||||
Q_strncpy( matchbuf, cdcommands[i], MAX_STRING );
|
||||
Q_strncpy( matchbuf, cdcommands[i], sizeof( matchbuf ));
|
||||
Con_Printf( "%16s\n", matchbuf );
|
||||
}
|
||||
|
||||
@@ -901,12 +901,10 @@ static qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
|
||||
if( f )
|
||||
{
|
||||
qboolean have_spawnpoints = false;
|
||||
dheader_t *header;
|
||||
dlump_t entities;
|
||||
|
||||
memset( buf, 0, MAX_SYSPATH );
|
||||
FS_Read( f, buf, MAX_SYSPATH );
|
||||
header = (dheader_t *)buf;
|
||||
|
||||
// check all the lumps and some other errors
|
||||
if( !Mod_TestBmodelLumps( f, t->filenames[i], buf, true, &entities ))
|
||||
@@ -937,7 +935,7 @@ static qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
|
||||
char token[MAX_TOKEN];
|
||||
qboolean worldspawn = true;
|
||||
|
||||
Q_strncpy( message, "No Title", MAX_STRING );
|
||||
Q_strncpy( message, "No Title", sizeof( message ));
|
||||
pfile = ents;
|
||||
|
||||
while(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) != NULL )
|
||||
@@ -1397,7 +1395,7 @@ void Host_WriteConfig( void )
|
||||
f = FS_Open( "config.cfg.new", "w", false );
|
||||
if( f )
|
||||
{
|
||||
Con_Reportf( "Host_WriteConfig()\n" );
|
||||
Con_Reportf( "%s()\n", __func__ );
|
||||
FS_Printf( f, "//=======================================================================\n");
|
||||
FS_Printf( f, "//\t\t\tCopyright XashXT Group & Flying With Gauss %s (C)\n", Q_timestamp( TIME_YEAR_ONLY ));
|
||||
FS_Printf( f, "//\t\t\tconfig.cfg - archive of cvars\n" );
|
||||
@@ -1480,7 +1478,7 @@ void Host_WriteOpenGLConfig( void )
|
||||
f = FS_Open( va( "%s.new", name ), "w", false );
|
||||
if( f )
|
||||
{
|
||||
Con_Reportf( "Host_WriteGLConfig()\n" );
|
||||
Con_Reportf( "%s()\n", __func__ );
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
FS_Printf( f, "//\t\t\tCopyright XashXT Group & Flying With Gauss %s (C)\n", Q_timestamp( TIME_YEAR_ONLY ));
|
||||
FS_Printf( f, "//\t\t %s - archive of renderer implementation cvars\n", name );
|
||||
@@ -1510,7 +1508,7 @@ void Host_WriteVideoConfig( void )
|
||||
f = FS_Open( "video.cfg.new", "w", false );
|
||||
if( f )
|
||||
{
|
||||
Con_Reportf( "Host_WriteVideoConfig()\n" );
|
||||
Con_Reportf( "%s()\n", __func__ );
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
FS_Printf( f, "//\t\t\tCopyright XashXT Group & Flying With Gauss %s (C)\n", Q_timestamp( TIME_YEAR_ONLY ));
|
||||
FS_Printf( f, "//\t\tvideo.cfg - archive of renderer variables\n");
|
||||
|
||||
@@ -80,7 +80,7 @@ static int Sys_ModuleName( HANDLE process, char *name, void *address, int len )
|
||||
|
||||
static void Sys_StackTrace( PEXCEPTION_POINTERS pInfo )
|
||||
{
|
||||
char message[1024];
|
||||
char message[8192]; // match *nix Sys_Crash
|
||||
int len = 0;
|
||||
size_t i;
|
||||
HANDLE process = GetCurrentProcess();
|
||||
@@ -129,9 +129,29 @@ static void Sys_StackTrace( PEXCEPTION_POINTERS pInfo )
|
||||
stackframe.AddrBStore.Mode = AddrModeFlat;
|
||||
stackframe.AddrStack.Offset = context.IntSp;
|
||||
stackframe.AddrStack.Mode = AddrModeFlat;
|
||||
#elif _M_ARM
|
||||
image = IMAGE_FILE_MACHINE_ARMNT;
|
||||
stackframe.AddrPC.Offset = context.Pc;
|
||||
stackframe.AddrPC.Mode = AddrModeFlat;
|
||||
stackframe.AddrFrame.Offset = context.R11;
|
||||
stackframe.AddrFrame.Mode = AddrModeFlat;
|
||||
stackframe.AddrStack.Offset = context.Sp;
|
||||
stackframe.AddrStack.Mode = AddrModeFlat;
|
||||
#elif _M_ARM64
|
||||
image = IMAGE_FILE_MACHINE_ARM64;
|
||||
stackframe.AddrPC.Offset = context.Pc;
|
||||
stackframe.AddrPC.Mode = AddrModeFlat;
|
||||
stackframe.AddrFrame.Offset = context.Fp;
|
||||
stackframe.AddrFrame.Mode = AddrModeFlat;
|
||||
stackframe.AddrStack.Offset = context.Sp;
|
||||
stackframe.AddrStack.Mode = AddrModeFlat;
|
||||
#elif
|
||||
#error
|
||||
#endif
|
||||
|
||||
len = Q_snprintf( message, sizeof( message ), "Ver: " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s, %s-%s)\n",
|
||||
Q_buildnum(), Q_buildcommit(), Q_buildos(), Q_buildarch() );
|
||||
|
||||
len += Q_snprintf( message + len, 1024 - len, "Sys_Crash: address %p, code %p\n",
|
||||
pInfo->ExceptionRecord->ExceptionAddress, (void*)pInfo->ExceptionRecord->ExceptionCode );
|
||||
if( SymGetLineFromAddr64( process, (DWORD64)pInfo->ExceptionRecord->ExceptionAddress, &dline, &line ) )
|
||||
@@ -259,6 +279,10 @@ static long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
|
||||
// check to avoid recursive call
|
||||
host.crashed = true;
|
||||
|
||||
#ifdef XASH_SDL
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
|
||||
#endif // XASH_SDL
|
||||
|
||||
#if DBGHELP
|
||||
Sys_StackTrace( pInfo );
|
||||
#else
|
||||
@@ -309,7 +333,6 @@ void Sys_SetupCrashHandler( void )
|
||||
{
|
||||
SetErrorMode( SEM_FAILCRITICALERRORS ); // no abort/retry/fail errors
|
||||
oldFilter = SetUnhandledExceptionFilter( Sys_Crash );
|
||||
host.hInst = GetModuleHandle( NULL );
|
||||
}
|
||||
|
||||
void Sys_RestoreCrashHandler( void )
|
||||
|
||||
@@ -16,6 +16,7 @@ GNU General Public License for more details.
|
||||
#include "common.h"
|
||||
#include "custom.h"
|
||||
#include "ref_common.h"
|
||||
#include "hpak.h" // be aware of HPK limits
|
||||
|
||||
static rgbdata_t *CustomDecal_LoadImage( const char *path, void *raw, int size )
|
||||
{
|
||||
@@ -93,7 +94,7 @@ qboolean COM_CreateCustomization( customization_t *pListHead, resource_t *pResou
|
||||
|
||||
if( FBitSet( flags, FCUST_FROMHPAK ))
|
||||
{
|
||||
if( !HPAK_GetDataPointer( CUSTOM_RES_PATH, pResource, (byte **)&pCust->pBuffer, NULL ))
|
||||
if( !HPAK_GetDataPointer( hpk_custom_file.string, pResource, (byte **)&pCust->pBuffer, NULL ))
|
||||
bError = true;
|
||||
}
|
||||
else
|
||||
@@ -115,11 +116,11 @@ qboolean COM_CreateCustomization( customization_t *pListHead, resource_t *pResou
|
||||
{
|
||||
if( !FBitSet( flags, FCUST_IGNOREINIT ))
|
||||
{
|
||||
if( pResource->nDownloadSize >= (1 * 1024) && pResource->nDownloadSize <= ( 128 * 1024 ))
|
||||
if( pResource->nDownloadSize >= HPAK_ENTRY_MIN_SIZE && pResource->nDownloadSize <= HPAK_ENTRY_MAX_SIZE )
|
||||
{
|
||||
pCust->bTranslated = true;
|
||||
pCust->nUserData1 = 0;
|
||||
pCust->nUserData2 = 1;
|
||||
pCust->nUserData2 = 7;
|
||||
|
||||
if( !FBitSet( flags, FCUST_WIPEDATA ))
|
||||
pCust->pInfo = CustomDecal_LoadImage( pResource->szFileName, pCust->pBuffer, pCust->resource.nDownloadSize );
|
||||
|
||||
@@ -164,8 +164,7 @@ static qboolean Cvar_UpdateInfo( convar_t *var, const char *value, qboolean noti
|
||||
return false; // failed to change value
|
||||
|
||||
// time to update server copy of userinfo
|
||||
CL_ServerCommand( true, "setinfo \"%s\" \"%s\"\n", var->name, value );
|
||||
CL_LegacyUpdateInfo();
|
||||
CL_UpdateInfo( var->name, value );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -794,7 +793,7 @@ void GAME_EXPORT Cvar_Set( const char *var_name, const char *value )
|
||||
if( !var_name )
|
||||
{
|
||||
// there is an error in C code if this happens
|
||||
Con_Printf( "Cvar_Set: passed NULL variable name\n" );
|
||||
Con_Printf( "%s: passed NULL variable name\n", __func__ );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -803,7 +802,7 @@ void GAME_EXPORT Cvar_Set( const char *var_name, const char *value )
|
||||
if( !var )
|
||||
{
|
||||
// there is an error in C code if this happens
|
||||
Con_Printf( "Cvar_Set: variable '%s' not found\n", var_name );
|
||||
Con_Printf( "%s: variable '%s' not found\n", __func__, var_name );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -848,7 +847,7 @@ float GAME_EXPORT Cvar_VariableValue( const char *var_name )
|
||||
if( !var_name )
|
||||
{
|
||||
// there is an error in C code if this happens
|
||||
Con_Printf( "Cvar_VariableValue: passed NULL variable name\n" );
|
||||
Con_Printf( "%s: passed NULL variable name\n", __func__ );
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
@@ -885,7 +884,7 @@ const char *Cvar_VariableString( const char *var_name )
|
||||
if( !var_name )
|
||||
{
|
||||
// there is an error in C code if this happens
|
||||
Con_Printf( "Cvar_VariableString: passed NULL variable name\n" );
|
||||
Con_Printf( "%s: passed NULL variable name\n", __func__ );
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -955,7 +954,7 @@ static void Cvar_SetGL( const char *name, const char *value )
|
||||
|
||||
static qboolean Cvar_ShouldSetCvar( convar_t *v, qboolean isPrivileged )
|
||||
{
|
||||
const char *prefixes[] = { "cl_", "gl_", "m_", "r_", "hud_", "joy_" };
|
||||
const char *prefixes[] = { "cl_", "gl_", "m_", "r_", "hud_", "joy_", "con_", "scr_" };
|
||||
int i;
|
||||
|
||||
if( isPrivileged )
|
||||
|
||||
@@ -39,11 +39,6 @@ qboolean CL_IsInGame( void )
|
||||
return true; // always active for dedicated servers
|
||||
}
|
||||
|
||||
qboolean CL_IsInMenu( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean CL_IsInConsole( void )
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -16,6 +16,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
#include "library.h"
|
||||
#include "platform/platform.h"
|
||||
@@ -26,6 +27,15 @@ fs_globals_t *FI;
|
||||
static pfnCreateInterface_t fs_pfnCreateInterface;
|
||||
static HINSTANCE fs_hInstance;
|
||||
|
||||
static void COM_StripDirectorySlash( char *pname )
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = Q_strlen( pname );
|
||||
if( len > 0 && pname[len - 1] == '/' )
|
||||
pname[len - 1] = 0;
|
||||
}
|
||||
|
||||
void *FS_GetNativeObject( const char *obj )
|
||||
{
|
||||
if( fs_pfnCreateInterface )
|
||||
@@ -80,7 +90,7 @@ static void FS_UnloadProgs( void )
|
||||
#define FILESYSTEM_STDIO_DLL "filesystem_stdio." OS_LIB_EXT
|
||||
#endif
|
||||
|
||||
qboolean FS_LoadProgs( void )
|
||||
static qboolean FS_LoadProgs( void )
|
||||
{
|
||||
const char *name = FILESYSTEM_STDIO_DLL;
|
||||
FSAPI GetFSAPI;
|
||||
@@ -89,63 +99,154 @@ qboolean FS_LoadProgs( void )
|
||||
|
||||
if( !fs_hInstance )
|
||||
{
|
||||
Host_Error( "%s: can't load filesystem library %s: %s\n", __func__, name, COM_GetLibraryError() );
|
||||
Sys_Error( "%s: can't load filesystem library %s: %s\n", __func__, name, COM_GetLibraryError() );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !( GetFSAPI = (FSAPI)COM_GetProcAddress( fs_hInstance, GET_FS_API )))
|
||||
{
|
||||
FS_UnloadProgs();
|
||||
Host_Error( "%s: can't find GetFSAPI entry point in %s\n", __func__, name );
|
||||
Sys_Error( "%s: can't find GetFSAPI entry point in %s\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( GetFSAPI( FS_API_VERSION, &g_fsapi, &FI, &fs_memfuncs ) != FS_API_VERSION )
|
||||
{
|
||||
FS_UnloadProgs();
|
||||
Host_Error( "%s: can't initialize filesystem API: wrong version\n", __func__ );
|
||||
Sys_Error( "%s: can't initialize filesystem API: wrong version\n", __func__ );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !( fs_pfnCreateInterface = (pfnCreateInterface_t)COM_GetProcAddress( fs_hInstance, "CreateInterface" )))
|
||||
{
|
||||
FS_UnloadProgs();
|
||||
Host_Error( "%s: can't find CreateInterface entry point in %s\n", __func__, name );
|
||||
Sys_Error( "%s: can't find CreateInterface entry point in %s\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
Con_DPrintf( "%s: filesystem_stdio successfully loaded\n", __func__ );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static qboolean FS_DetermineRootDirectory( char *out, size_t size )
|
||||
{
|
||||
const char *path = getenv( "XASH3D_BASEDIR" );
|
||||
|
||||
if( COM_CheckString( path ))
|
||||
{
|
||||
Q_strncpy( out, path, size );
|
||||
return true;
|
||||
}
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
Q_strncpy( out, IOS_GetDocsDir(), size );
|
||||
return true;
|
||||
#elif XASH_ANDROID && XASH_SDL
|
||||
path = SDL_AndroidGetExternalStoragePath();
|
||||
if( path != NULL )
|
||||
{
|
||||
Q_strncpy( out, path, size );
|
||||
return true;
|
||||
}
|
||||
Sys_Error( "couldn't determine Android external storage path: %s", SDL_GetError( ));
|
||||
return false;
|
||||
#elif XASH_PSVITA
|
||||
if( PSVita_GetBasePath( out, size ))
|
||||
return true;
|
||||
Sys_Error( "couldn't find Xash3D data directory" );
|
||||
return false;
|
||||
#elif ( XASH_SDL == 2 ) && !XASH_NSWITCH // GetBasePath not impl'd in switch-sdl2
|
||||
path = SDL_GetBasePath();
|
||||
if( path != NULL )
|
||||
{
|
||||
Q_strncpy( out, path, size );
|
||||
SDL_free(( void *)path );
|
||||
return true;
|
||||
}
|
||||
|
||||
#if XASH_POSIX || XASH_WIN32
|
||||
if( getcwd( out, size ))
|
||||
return true;
|
||||
Sys_Error( "couldn't determine current directory: %s, getcwd: %s", SDL_GetError(), strerror( errno ));
|
||||
#else // !( XASH_POSIX || XASH_WIN32 )
|
||||
Sys_Error( "couldn't determine current directory: %s", SDL_GetError( ));
|
||||
#endif // !( XASH_POSIX || XASH_WIN32 )
|
||||
return false;
|
||||
#else // generic case
|
||||
if( getcwd( out, size ))
|
||||
return true;
|
||||
|
||||
Sys_Error( "couldn't determine current directory: %s", strerror( errno ));
|
||||
return false;
|
||||
#endif // generic case
|
||||
}
|
||||
|
||||
static qboolean FS_DetermineReadOnlyRootDirectory( char *out, size_t size )
|
||||
{
|
||||
const char *env_rodir = getenv( "XASH3D_RODIR" );
|
||||
|
||||
if( _Sys_GetParmFromCmdLine( "-rodir", out, size ))
|
||||
return true;
|
||||
|
||||
if( COM_CheckString( env_rodir ))
|
||||
{
|
||||
Q_strncpy( out, env_rodir, size );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
FS_Init
|
||||
================
|
||||
*/
|
||||
void FS_Init( void )
|
||||
void FS_Init( const char *basedir )
|
||||
{
|
||||
string gamedir;
|
||||
char rodir[MAX_OSPATH], rootdir[MAX_OSPATH];
|
||||
rodir[0] = rootdir[0] = 0;
|
||||
|
||||
if( !FS_DetermineRootDirectory( rootdir, sizeof( rootdir )) || !COM_CheckStringEmpty( rootdir ))
|
||||
{
|
||||
Sys_Error( "couldn't determine current directory (empty string)" );
|
||||
return;
|
||||
}
|
||||
COM_FixSlashes( rootdir );
|
||||
COM_StripDirectorySlash( rootdir );
|
||||
|
||||
FS_DetermineReadOnlyRootDirectory( rodir, sizeof( rodir ));
|
||||
COM_FixSlashes( rodir );
|
||||
COM_StripDirectorySlash( rodir );
|
||||
|
||||
if( !Sys_GetParmFromCmdLine( "-game", gamedir ))
|
||||
Q_strncpy( gamedir, basedir, sizeof( gamedir )); // gamedir == basedir
|
||||
|
||||
FS_LoadProgs();
|
||||
|
||||
// TODO: this function will cause engine to stop in case of fail
|
||||
// when it will have an option to return string error, restore Sys_Error
|
||||
// FIXME: why do we call this function before InitStdio?
|
||||
// because InitStdio immediately scans all available game directories
|
||||
// and this better be reworked at some point
|
||||
g_fsapi.SetCurrentDirectory( rootdir );
|
||||
|
||||
if( !g_fsapi.InitStdio( true, rootdir, basedir, gamedir, rodir ))
|
||||
{
|
||||
Sys_Error( "Can't init filesystem_stdio!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Cmd_AddRestrictedCommand( "fs_rescan", FS_Rescan_f, "rescan filesystem search pathes" );
|
||||
Cmd_AddRestrictedCommand( "fs_path", FS_Path_f_, "show filesystem search pathes" );
|
||||
Cmd_AddRestrictedCommand( "fs_clearpaths", FS_ClearPaths_f, "clear filesystem search pathes" );
|
||||
|
||||
if( !Sys_GetParmFromCmdLine( "-game", gamedir ))
|
||||
Q_strncpy( gamedir, SI.basedirName, sizeof( gamedir )); // gamedir == basedir
|
||||
if( !Sys_GetParmFromCmdLine( "-dll", host.gamedll ))
|
||||
host.gamedll[0] = 0;
|
||||
|
||||
if( !FS_InitStdio( true, host.rootdir, SI.basedirName, gamedir, host.rodir ))
|
||||
{
|
||||
Host_Error( "Can't init filesystem_stdio!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !Sys_GetParmFromCmdLine( "-dll", SI.gamedll ))
|
||||
SI.gamedll[0] = 0;
|
||||
|
||||
if( !Sys_GetParmFromCmdLine( "-clientlib", SI.clientlib ))
|
||||
SI.clientlib[0] = 0;
|
||||
if( !Sys_GetParmFromCmdLine( "-clientlib", host.clientlib ))
|
||||
host.clientlib[0] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -158,11 +259,5 @@ void FS_Shutdown( void )
|
||||
if( g_fsapi.ShutdownStdio )
|
||||
g_fsapi.ShutdownStdio();
|
||||
|
||||
memset( &SI, 0, sizeof( sysinfo_t ));
|
||||
|
||||
FS_UnloadProgs();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@ GNU General Public License for more details.
|
||||
#include <SDL.h>
|
||||
#endif // XASH_SDL
|
||||
#include <stdarg.h> // va_args
|
||||
#include <errno.h> // errno
|
||||
#include <string.h> // strerror
|
||||
#if !XASH_WIN32
|
||||
#include <unistd.h> // fork
|
||||
#include <sys/types.h>
|
||||
@@ -29,7 +27,6 @@ GNU General Public License for more details.
|
||||
#if XASH_EMSCRIPTEN
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
#include "base_cmd.h"
|
||||
#include "client.h"
|
||||
@@ -45,7 +42,6 @@ GNU General Public License for more details.
|
||||
|
||||
pfnChangeGame pChangeGame = NULL;
|
||||
host_parm_t host; // host parms
|
||||
sysinfo_t SI;
|
||||
|
||||
#ifdef XASH_ENGINE_TESTS
|
||||
struct tests_stats_s tests_stats;
|
||||
@@ -53,7 +49,7 @@ struct tests_stats_s tests_stats;
|
||||
|
||||
CVAR_DEFINE( host_developer, "developer", "0", FCVAR_FILTERABLE, "engine is in development-mode" );
|
||||
CVAR_DEFINE_AUTO( sys_timescale, "1.0", FCVAR_FILTERABLE, "scale frame time" );
|
||||
CVAR_DEFINE_AUTO( sys_ticrate, "100", 0, "framerate in dedicated mode" );
|
||||
CVAR_DEFINE_AUTO( sys_ticrate, "100", FCVAR_SERVER, "framerate in dedicated mode" );
|
||||
|
||||
static CVAR_DEFINE_AUTO( host_serverstate, "0", FCVAR_READ_ONLY, "displays current server state" );
|
||||
static CVAR_DEFINE_AUTO( host_gameloaded, "0", FCVAR_READ_ONLY, "inidcates a loaded game.dll" );
|
||||
@@ -63,6 +59,7 @@ CVAR_DEFINE( host_maxfps, "fps_max", "72", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "host
|
||||
static CVAR_DEFINE_AUTO( host_framerate, "0", FCVAR_FILTERABLE, "locks frame timing to this value in seconds" );
|
||||
static CVAR_DEFINE( host_sleeptime, "sleeptime", "1", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "milliseconds to sleep for each frame. higher values reduce fps accuracy" );
|
||||
static CVAR_DEFINE_AUTO( host_sleeptime_debug, "0", 0, "print sleeps between frames" );
|
||||
CVAR_DEFINE_AUTO( host_allow_materials, "0", FCVAR_LATCH|FCVAR_ARCHIVE, "allow texture replacements from materials/ folder" );
|
||||
CVAR_DEFINE( con_gamemaps, "con_mapfilter", "1", FCVAR_ARCHIVE, "when true show only maps in game folder" );
|
||||
|
||||
typedef struct feature_message_s
|
||||
@@ -75,6 +72,7 @@ typedef struct feature_message_s
|
||||
static feature_message_t bugcomp_features[] =
|
||||
{
|
||||
{ BUGCOMP_PENTITYOFENTINDEX_FLAG, "pfnPEntityOfEntIndex bugfix revert", "peoei" },
|
||||
{ BUGCOMP_MESSAGE_REWRITE_FACILITY_FLAG, "GoldSrc Message Rewrite Facility", "gsmrf" },
|
||||
};
|
||||
|
||||
static feature_message_t engine_features[] =
|
||||
@@ -91,7 +89,7 @@ static feature_message_t engine_features[] =
|
||||
{ ENGINE_STEP_POSHISTORY_LERP, "MOVETYPE_STEP Position History Based Lerping" },
|
||||
};
|
||||
|
||||
static void Sys_PrintUsage( void )
|
||||
static void Sys_PrintUsage( const char *exename )
|
||||
{
|
||||
string version_str;
|
||||
const char *usage_str;
|
||||
@@ -99,10 +97,14 @@ static void Sys_PrintUsage( void )
|
||||
Q_snprintf( version_str, sizeof( version_str ),
|
||||
XASH_ENGINE_NAME " %i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
|
||||
|
||||
#if XASH_WIN32
|
||||
#define XASH_EXE "(xash).exe"
|
||||
#if XASH_MESSAGEBOX != MSGBOX_STDERR
|
||||
#if XASH_WIN32
|
||||
#define XASH_EXE "(xash).exe"
|
||||
#else
|
||||
#define XASH_EXE "(xash)"
|
||||
#endif
|
||||
#else
|
||||
#define XASH_EXE "(xash)"
|
||||
#define XASH_EXE "%s"
|
||||
#endif
|
||||
|
||||
#define O( x, y ) " "x" "y"\n"
|
||||
@@ -190,7 +192,8 @@ static void Sys_PrintUsage( void )
|
||||
#if XASH_MESSAGEBOX != MSGBOX_STDERR
|
||||
Platform_MessageBox( version_str, usage_str, false );
|
||||
#else
|
||||
fprintf( stderr, "%s\n%s", version_str, usage_str );
|
||||
fprintf( stderr, "%s\n", version_str );
|
||||
fprintf( stderr, usage_str, exename );
|
||||
#endif
|
||||
|
||||
Sys_Quit();
|
||||
@@ -241,7 +244,7 @@ void Host_ValidateEngineFeatures( uint32_t features )
|
||||
{
|
||||
uint32_t mask = ENGINE_FEATURES_MASK;
|
||||
|
||||
#if !HOST_DEDICATED
|
||||
#if !XASH_DEDICATED
|
||||
if( !Host_IsDedicated( ) && cls.legacymode )
|
||||
mask = ENGINE_LEGACY_FEATURES_MASK;
|
||||
#endif
|
||||
@@ -315,18 +318,6 @@ void Host_EndGame( qboolean abort, const char *message, ... )
|
||||
if( abort ) Host_AbortCurrentFrame ();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Host_AbortCurrentFrame
|
||||
|
||||
aborts the current host frame and goes on with the next one
|
||||
================
|
||||
*/
|
||||
void Host_AbortCurrentFrame( void )
|
||||
{
|
||||
longjmp( host.abortframe, 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Host_CalcSleep
|
||||
@@ -334,14 +325,7 @@ Host_CalcSleep
|
||||
*/
|
||||
static int Host_CalcSleep( void )
|
||||
{
|
||||
#ifndef XASH_DEDICATED
|
||||
// never sleep in timedemo for benchmarking purposes
|
||||
// also don't sleep with vsync for less lag
|
||||
if( CL_IsTimeDemo( ) || gl_vsync.value )
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if( Host_IsDedicated() )
|
||||
if( Host_IsDedicated( ))
|
||||
{
|
||||
// let the dedicated server some sleep
|
||||
return host_sleeptime.value;
|
||||
@@ -423,7 +407,6 @@ static void Host_Exec_f( void )
|
||||
byte *f;
|
||||
char *txt;
|
||||
fs_offset_t len;
|
||||
const char *arg;
|
||||
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
@@ -431,7 +414,8 @@ static void Host_Exec_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
arg = Cmd_Argv( 1 );
|
||||
Q_strncpy( cfgpath, Cmd_Argv( 1 ), sizeof( cfgpath ));
|
||||
COM_DefaultExtension( cfgpath, ".cfg", sizeof( cfgpath )); // append as default
|
||||
|
||||
#ifndef XASH_DEDICATED
|
||||
if( !Cmd_CurrentCommandIsPrivileged() )
|
||||
@@ -451,7 +435,7 @@ static void Host_Exec_f( void )
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( unprivilegedWhitelist ); i++ )
|
||||
{
|
||||
if( !Q_strcmp( arg, unprivilegedWhitelist[i] ))
|
||||
if( !Q_strcmp( cfgpath, unprivilegedWhitelist[i] ))
|
||||
{
|
||||
allow = true;
|
||||
break;
|
||||
@@ -460,21 +444,15 @@ static void Host_Exec_f( void )
|
||||
|
||||
if( !allow )
|
||||
{
|
||||
Con_Printf( "exec %s: not privileged or in whitelist\n", arg );
|
||||
Con_Printf( "exec %s: not privileged or in whitelist\n", cfgpath );
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif // XASH_DEDICATED
|
||||
|
||||
if( !Q_stricmp( "game.cfg", arg ))
|
||||
{
|
||||
// don't execute game.cfg in singleplayer
|
||||
if( SV_GetMaxClients() == 1 )
|
||||
return;
|
||||
}
|
||||
|
||||
Q_strncpy( cfgpath, arg, sizeof( cfgpath ));
|
||||
COM_DefaultExtension( cfgpath, ".cfg", sizeof( cfgpath )); // append as default
|
||||
// don't execute game.cfg in singleplayer
|
||||
if( SV_GetMaxClients() == 1 && !Q_stricmp( "game.cfg", cfgpath ))
|
||||
return;
|
||||
|
||||
f = FS_LoadFile( cfgpath, &len, false );
|
||||
if( !f )
|
||||
@@ -483,17 +461,18 @@ static void Host_Exec_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
if( !Q_stricmp( "config.cfg", arg ))
|
||||
if( !Q_stricmp( "config.cfg", cfgpath ))
|
||||
host.config_executed = true;
|
||||
|
||||
// adds \n\0 at end of the file
|
||||
txt = Z_Calloc( len + 2 );
|
||||
memcpy( txt, f, len );
|
||||
Q_strncat( txt, "\n", len + 2 );
|
||||
txt[len] = '\n';
|
||||
txt[len + 1] = '\0';
|
||||
Mem_Free( f );
|
||||
|
||||
if( !host.apply_game_config )
|
||||
Con_Printf( "execing %s\n", arg );
|
||||
Con_Printf( "execing %s\n", Cmd_Argv( 1 ));
|
||||
Cbuf_InsertText( txt );
|
||||
Mem_Free( txt );
|
||||
}
|
||||
@@ -528,33 +507,6 @@ static void Host_Minimize_f( void )
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Host_IsLocalGame
|
||||
|
||||
singleplayer game detect
|
||||
=================
|
||||
*/
|
||||
qboolean Host_IsLocalGame( void )
|
||||
{
|
||||
if( SV_Active( ))
|
||||
{
|
||||
return ( SV_GetMaxClients() == 1 ) ? true : false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ( CL_GetMaxClients() == 1 ) ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
qboolean Host_IsLocalClient( void )
|
||||
{
|
||||
// only the local client have the active server
|
||||
if( CL_Initialized( ) && SV_Initialized( ))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Host_RegisterDecal
|
||||
@@ -599,10 +551,6 @@ static void Host_InitDecals( void )
|
||||
int i, num_decals = 0;
|
||||
search_t *t;
|
||||
|
||||
// NOTE: only once resource without which engine can't continue work
|
||||
if( !FS_FileExists( "gfx/conchars", false ))
|
||||
Sys_Error( "W_LoadWadFile: couldn't load gfx.wad\n" );
|
||||
|
||||
memset( host.draw_decals, 0, sizeof( host.draw_decals ));
|
||||
|
||||
// lookup all the decals in decals.wad (basedir, gamedir, falldir)
|
||||
@@ -615,7 +563,7 @@ static void Host_InitDecals( void )
|
||||
}
|
||||
|
||||
if( t ) Mem_Free( t );
|
||||
Con_Reportf( "InitDecals: %i decals\n", num_decals );
|
||||
Con_Reportf( "%s: %i decals\n", __func__, num_decals );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -647,7 +595,7 @@ static double Host_CalcFPS( void )
|
||||
{
|
||||
double fps = 0.0;
|
||||
|
||||
if( Host_IsDedicated() )
|
||||
if( Host_IsDedicated( ))
|
||||
{
|
||||
fps = sys_ticrate.value;
|
||||
}
|
||||
@@ -760,7 +708,7 @@ Host_FilterTime
|
||||
Returns false if the time is too short to run a frame
|
||||
===================
|
||||
*/
|
||||
static qboolean Host_FilterTime( float time )
|
||||
static qboolean Host_FilterTime( double time )
|
||||
{
|
||||
static double oldtime;
|
||||
double dt;
|
||||
@@ -790,9 +738,9 @@ static qboolean Host_FilterTime( float time )
|
||||
Host_Frame
|
||||
=================
|
||||
*/
|
||||
void Host_Frame( float time )
|
||||
void Host_Frame( double time )
|
||||
{
|
||||
double t1, t2;
|
||||
double t1;
|
||||
|
||||
// decide the simulation time
|
||||
if( !Host_FilterTime( time ))
|
||||
@@ -810,11 +758,8 @@ void Host_Frame( float time )
|
||||
Host_ClientFrame (); // client frame
|
||||
HTTP_Run(); // both server and client
|
||||
|
||||
t2 = Sys_DoubleTime();
|
||||
|
||||
host.pureframetime = t2 - t1;
|
||||
|
||||
host.framecount++;
|
||||
host.pureframetime = Sys_DoubleTime() - t1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -837,11 +782,11 @@ void GAME_EXPORT Host_Error( const char *error, ... )
|
||||
|
||||
if( host.framecount < 3 )
|
||||
{
|
||||
Sys_Error( "Host_InitError: %s", hosterror1 );
|
||||
Sys_Error( "%sInit: %s", __func__, hosterror1 );
|
||||
}
|
||||
else if( host.framecount == host.errorframe )
|
||||
{
|
||||
Sys_Error( "Host_MultiError: %s", hosterror2 );
|
||||
Sys_Error( "%sMulti: %s", __func__, hosterror2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -849,7 +794,7 @@ void GAME_EXPORT Host_Error( const char *error, ... )
|
||||
{
|
||||
UI_SetActiveMenu( false );
|
||||
Key_SetKeyDest( key_console );
|
||||
Con_Printf( "Host_Error: %s", hosterror1 );
|
||||
Con_Printf( "%s: %s", __func__, hosterror1 );
|
||||
}
|
||||
else Platform_MessageBox( "Host Error", hosterror1, true );
|
||||
}
|
||||
@@ -859,12 +804,12 @@ void GAME_EXPORT Host_Error( const char *error, ... )
|
||||
|
||||
if( recursive )
|
||||
{
|
||||
Con_Printf( "Host_RecursiveError: %s", hosterror2 );
|
||||
Con_Printf( "%sRecursive: %s", __func__, hosterror2 );
|
||||
Sys_Error( "%s", hosterror1 );
|
||||
}
|
||||
|
||||
recursive = true;
|
||||
Q_strncpy( hosterror2, hosterror1, MAX_SYSPATH );
|
||||
Q_strncpy( hosterror2, hosterror1, sizeof( hosterror2 ));
|
||||
host.errorframe = host.framecount; // to avoid multply calls per frame
|
||||
Q_snprintf( host.finalmsg, sizeof( host.finalmsg ), "Server crashed: %s", hosterror1 );
|
||||
|
||||
@@ -958,15 +903,15 @@ static void Host_RunTests( int stage )
|
||||
|
||||
static uint32_t Host_CheckBugcomp( void )
|
||||
{
|
||||
const char *prev, *next;
|
||||
uint32_t flags = 0;
|
||||
string args, arg;
|
||||
char *prev, *next;
|
||||
size_t i;
|
||||
|
||||
if( !Sys_CheckParm( "-bugcomp" ))
|
||||
return 0;
|
||||
|
||||
if( Sys_GetParmFromCmdLine( "-bugcomp", args ) && args[0] != '-' )
|
||||
if( Sys_GetParmFromCmdLine( "-bugcomp", args ) && isalpha( args[0] ))
|
||||
{
|
||||
for( prev = args, next = Q_strchrnul( prev, '+' ); ; prev = next + 1, next = Q_strchrnul( prev, '+' ))
|
||||
{
|
||||
@@ -1003,40 +948,59 @@ static uint32_t Host_CheckBugcomp( void )
|
||||
return flags;
|
||||
}
|
||||
|
||||
static void Host_DetermineExecutableName( char *out, size_t size )
|
||||
{
|
||||
#if XASH_WIN32
|
||||
char temp[MAX_SYSPATH];
|
||||
|
||||
if( GetModuleFileName( NULL, temp, sizeof( temp )))
|
||||
COM_FileBase( temp, out, size );
|
||||
#else
|
||||
if( host.argc > 0 )
|
||||
COM_FileBase( host.argv[0], out, size );
|
||||
else
|
||||
Q_strncpy( out, "xash", size );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Host_InitCommon
|
||||
=================
|
||||
*/
|
||||
static void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bChangeGame )
|
||||
static void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bChangeGame, char *exename, size_t exename_size )
|
||||
{
|
||||
char dev_level[4];
|
||||
int developer = DEFAULT_DEV;
|
||||
const char *baseDir;
|
||||
char ticrate[16];
|
||||
int len, i;
|
||||
const char *basedir = progname[0] == '#' ? progname + 1 : progname;
|
||||
char dev_level[4], ticrate[16];
|
||||
int developer = DEFAULT_DEV;
|
||||
|
||||
// some commands may turn engine into infinite loop,
|
||||
// e.g. xash.exe +game xash -game xash
|
||||
// so we clear all cmd_args, but leave dbg states as well
|
||||
Sys_ParseCommandLine( argc, argv );
|
||||
Host_DetermineExecutableName( exename, exename_size );
|
||||
|
||||
if( !Sys_CheckParm( "-disablehelp" ) )
|
||||
if( !Sys_CheckParm( "-disablehelp" ))
|
||||
{
|
||||
if( Sys_CheckParm( "-help" ) || Sys_CheckParm( "-h" ) || Sys_CheckParm( "--help" ) )
|
||||
{
|
||||
Sys_PrintUsage();
|
||||
}
|
||||
if( Sys_CheckParm( "-help" ) || Sys_CheckParm( "-h" ) || Sys_CheckParm( "--help" ))
|
||||
Sys_PrintUsage( exename );
|
||||
}
|
||||
|
||||
if( !Sys_CheckParm( "-noch" ) )
|
||||
if( !Sys_CheckParm( "-noch" ))
|
||||
Sys_SetupCrashHandler();
|
||||
|
||||
#if XASH_DLL_LOADER
|
||||
host.enabledll = !Sys_CheckParm( "-nodll" );
|
||||
#endif
|
||||
|
||||
host.change_game = bChangeGame || Sys_CheckParm( "-changegame" );
|
||||
host.config_executed = false;
|
||||
host.status = HOST_INIT; // initialzation started
|
||||
host.type = HOST_DEDICATED; // predict state
|
||||
#ifndef XASH_DEDICATED
|
||||
if( !Sys_CheckParm( "-dedicated" ))
|
||||
host.type = HOST_NORMAL;
|
||||
#endif
|
||||
|
||||
Memory_Init(); // init memory subsystem
|
||||
|
||||
@@ -1044,11 +1008,6 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
|
||||
|
||||
host.allow_console = DEFAULT_ALLOWCONSOLE;
|
||||
|
||||
// HACKHACK: Quake console is always allowed
|
||||
// TODO: determine if we are running QWrap more reliable
|
||||
if( !host.allow_console && ( Sys_CheckParm( "-console" ) || !Q_stricmp( SI.exeName, "quake" )))
|
||||
host.allow_console = true;
|
||||
|
||||
if( Sys_CheckParm( "-dev" ))
|
||||
{
|
||||
host.allow_console = true;
|
||||
@@ -1069,40 +1028,9 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
|
||||
}
|
||||
#endif
|
||||
|
||||
host.con_showalways = true;
|
||||
|
||||
#if XASH_DEDICATED
|
||||
host.type = HOST_DEDICATED; // predict state
|
||||
#else
|
||||
if( Sys_CheckParm("-dedicated") || progname[0] == '#' )
|
||||
{
|
||||
host.type = HOST_DEDICATED;
|
||||
}
|
||||
else
|
||||
{
|
||||
host.type = HOST_NORMAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// set default gamedir
|
||||
if( progname[0] == '#' )
|
||||
progname++;
|
||||
|
||||
Q_strncpy( SI.exeName, progname, sizeof( SI.exeName ));
|
||||
Q_strncpy( SI.basedirName, progname, sizeof( SI.basedirName ));
|
||||
|
||||
if( Host_IsDedicated() )
|
||||
{
|
||||
Sys_MergeCommandLine( );
|
||||
|
||||
// always enable console for Quake
|
||||
if( !host.allow_console && ( Sys_CheckParm( "-console" ) || !Q_strnicmp( exename, "quake", 5 )))
|
||||
host.allow_console = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't show console as default
|
||||
if( developer <= DEV_NORMAL )
|
||||
host.con_showalways = false;
|
||||
}
|
||||
|
||||
// member console allowing
|
||||
host.allow_console_init = host.allow_console;
|
||||
@@ -1143,93 +1071,8 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
|
||||
Host_RunTests( 0 );
|
||||
#endif
|
||||
|
||||
Platform_Init();
|
||||
|
||||
baseDir = getenv( "XASH3D_BASEDIR" );
|
||||
|
||||
if( COM_CheckString( baseDir ) )
|
||||
{
|
||||
Q_strncpy( host.rootdir, baseDir, sizeof( host.rootdir ));
|
||||
}
|
||||
else
|
||||
{
|
||||
#if TARGET_OS_IOS
|
||||
Q_strncpy( host.rootdir, IOS_GetDocsDir(), sizeof( host.rootdir ));
|
||||
#elif XASH_ANDROID && XASH_SDL
|
||||
Q_strncpy( host.rootdir, SDL_AndroidGetExternalStoragePath(), sizeof( host.rootdir ));
|
||||
#elif XASH_PSVITA
|
||||
if ( !PSVita_GetBasePath( host.rootdir, sizeof( host.rootdir )))
|
||||
{
|
||||
Sys_Error( "couldn't find xash3d data directory" );
|
||||
host.rootdir[0] = 0;
|
||||
}
|
||||
#elif (XASH_SDL == 2) && !XASH_NSWITCH // GetBasePath not impl'd in switch-sdl2
|
||||
char *szBasePath = SDL_GetBasePath();
|
||||
if( szBasePath )
|
||||
{
|
||||
Q_strncpy( host.rootdir, szBasePath, sizeof( host.rootdir ));
|
||||
SDL_free( szBasePath );
|
||||
}
|
||||
else
|
||||
{
|
||||
#if XASH_POSIX || XASH_WIN32
|
||||
if( !getcwd( host.rootdir, sizeof( host.rootdir )))
|
||||
Sys_Error( "couldn't determine current directory: %s, getcwd: %s", SDL_GetError(), strerror( errno ));
|
||||
#else
|
||||
Sys_Error( "couldn't determine current directory: %s", SDL_GetError() );
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
if( !getcwd( host.rootdir, sizeof( host.rootdir )))
|
||||
{
|
||||
Sys_Error( "couldn't determine current directory: %s", strerror( errno ) );
|
||||
host.rootdir[0] = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if XASH_WIN32
|
||||
COM_FixSlashes( host.rootdir );
|
||||
#endif
|
||||
|
||||
len = Q_strlen( host.rootdir );
|
||||
|
||||
if( len && host.rootdir[len - 1] == '/' )
|
||||
host.rootdir[len - 1] = 0;
|
||||
|
||||
// get readonly root. The order is: check for arg, then env.
|
||||
// if still not got it, rodir is disabled.
|
||||
host.rodir[0] = '\0';
|
||||
if( !Sys_GetParmFromCmdLine( "-rodir", host.rodir ))
|
||||
{
|
||||
char *roDir = getenv( "XASH3D_RODIR" );
|
||||
|
||||
if( COM_CheckString( roDir ))
|
||||
Q_strncpy( host.rodir, roDir, sizeof( host.rodir ));
|
||||
}
|
||||
|
||||
#if XASH_WIN32
|
||||
COM_FixSlashes( host.rootdir );
|
||||
#endif
|
||||
|
||||
len = Q_strlen( host.rodir );
|
||||
|
||||
if( len && host.rodir[len - 1] == '/' )
|
||||
host.rodir[len - 1] = 0;
|
||||
|
||||
if( !COM_CheckStringEmpty( host.rootdir ))
|
||||
{
|
||||
Sys_Error( "Changing working directory failed (empty working directory)\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
FS_LoadProgs();
|
||||
|
||||
// TODO: this function will cause engine to stop in case of fail
|
||||
// when it will have an option to return string error, restore Sys_Error
|
||||
FS_SetCurrentDirectory( host.rootdir );
|
||||
|
||||
FS_Init();
|
||||
Platform_Init( Host_IsDedicated( ) || developer >= DEV_EXTENDED );
|
||||
FS_Init( basedir );
|
||||
|
||||
Sys_InitLog();
|
||||
|
||||
@@ -1254,39 +1097,14 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
|
||||
FS_LoadGameInfo( NULL );
|
||||
Cvar_PostFSInit();
|
||||
|
||||
Q_strncpy( host.gamefolder, GI->gamefolder, sizeof( host.gamefolder ));
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
const char *rcName;
|
||||
switch( i )
|
||||
{
|
||||
case 0: rcName = SI.basedirName; break; // e.g. valve.rc
|
||||
case 1: rcName = SI.exeName; break; // e.g. quake.rc
|
||||
case 2: rcName = host.gamefolder; break; // e.g. game.rc (ran from default launcher)
|
||||
}
|
||||
|
||||
if( FS_FileExists( va( "%s.rc", rcName ), false ))
|
||||
{
|
||||
Q_strncpy( SI.rcName, rcName, sizeof( SI.rcName ));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Image_CheckPaletteQ1 ();
|
||||
|
||||
// NOTE: only once resource without which engine can't continue work
|
||||
if( !FS_FileExists( "gfx/conchars", false ))
|
||||
Sys_Error( "%s: couldn't load gfx.wad\n", __func__ );
|
||||
|
||||
Host_InitDecals (); // reload decals
|
||||
|
||||
// DEPRECATED: by FWGS fork
|
||||
#if 0
|
||||
if( GI->secure )
|
||||
{
|
||||
// clear all developer levels when game is protected
|
||||
Cvar_DirectSet( &host_developer, "0" );
|
||||
host.allow_console_init = false;
|
||||
host.con_showalways = false;
|
||||
host.allow_console = false;
|
||||
}
|
||||
#endif
|
||||
HPAK_Init();
|
||||
|
||||
IN_Init();
|
||||
@@ -1310,13 +1128,13 @@ Host_Main
|
||||
int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGame, pfnChangeGame func )
|
||||
{
|
||||
static double oldtime, newtime;
|
||||
string demoname;
|
||||
string demoname, exename;
|
||||
|
||||
host.starttime = Sys_DoubleTime();
|
||||
|
||||
pChangeGame = func; // may be NULL
|
||||
|
||||
Host_InitCommon( argc, argv, progname, bChangeGame );
|
||||
Host_InitCommon( argc, argv, progname, bChangeGame, exename, sizeof( exename ));
|
||||
|
||||
// init commands and vars
|
||||
if( host_developer.value >= DEV_EXTENDED )
|
||||
@@ -1326,6 +1144,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
Cmd_AddRestrictedCommand ( "crash", Host_Crash_f, "a way to force a bus error for development reasons");
|
||||
}
|
||||
|
||||
Cvar_RegisterVariable( &host_allow_materials );
|
||||
Cvar_RegisterVariable( &host_serverstate );
|
||||
Cvar_RegisterVariable( &host_maxfps );
|
||||
Cvar_RegisterVariable( &host_framerate );
|
||||
@@ -1365,21 +1184,25 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
ID_Init();
|
||||
SoundList_Init();
|
||||
|
||||
if( Host_IsDedicated() )
|
||||
if( Host_IsDedicated( ))
|
||||
{
|
||||
#ifdef _WIN32
|
||||
Wcon_InitConsoleCommands ();
|
||||
#endif
|
||||
|
||||
// disable texture replacements for dedicated
|
||||
Cvar_FullSet( "host_allow_materials", "0", FCVAR_READ_ONLY );
|
||||
|
||||
Cmd_AddRestrictedCommand( "quit", Sys_Quit, "quit the game" );
|
||||
Cmd_AddRestrictedCommand( "exit", Sys_Quit, "quit the game" );
|
||||
}
|
||||
else Cmd_AddRestrictedCommand( "minimize", Host_Minimize_f, "minimize main window to tray" );
|
||||
|
||||
HPAK_CheckIntegrity( CUSTOM_RES_PATH );
|
||||
|
||||
host.errorframe = 0;
|
||||
|
||||
if( progname[0] == '#' )
|
||||
progname++;
|
||||
|
||||
// post initializations
|
||||
switch( host.type )
|
||||
{
|
||||
@@ -1388,8 +1211,14 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
Wcon_ShowConsole( false ); // hide console
|
||||
#endif
|
||||
// execute startup config and cmdline
|
||||
Cbuf_AddTextf( "exec %s.rc\n", SI.rcName );
|
||||
if( FS_FileExists( va( "%s.rc", progname ), false )) // e.g. valve.rc
|
||||
Cbuf_AddTextf( "exec %s.rc", progname );
|
||||
else if( FS_FileExists( va( "%s.rc", exename ), false )) // e.g. quake.rc
|
||||
Cbuf_AddTextf( "exec %s.rc", exename );
|
||||
else if( FS_FileExists( va( "%s.rc", GI->gamefolder ), false )) // e.g. game.rc (ran from default launcher)
|
||||
Cbuf_AddTextf( "exec %s.rc", GI->gamefolder );
|
||||
Cbuf_Execute();
|
||||
|
||||
if( !host.config_executed )
|
||||
{
|
||||
Cbuf_AddText( "exec config.cfg\n" );
|
||||
@@ -1433,6 +1262,9 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
Cbuf_Execute();
|
||||
}
|
||||
|
||||
// check after all configs were executed
|
||||
HPAK_CheckIntegrity( hpk_custom_file.string );
|
||||
|
||||
// main window message loop
|
||||
while( !host.crashed )
|
||||
{
|
||||
|
||||
@@ -16,6 +16,8 @@ GNU General Public License for more details.
|
||||
#include "common.h"
|
||||
#include "platform/platform.h"
|
||||
|
||||
static jmp_buf g_abortframe;
|
||||
|
||||
void COM_InitHostState( void )
|
||||
{
|
||||
memset( GameState, 0, sizeof( game_status_t ));
|
||||
@@ -58,6 +60,9 @@ void COM_NewGame( char const *pMapName )
|
||||
GameState->loadGame = false;
|
||||
GameState->newGame = true;
|
||||
|
||||
if( !SV_Active( ))
|
||||
CL_Disconnect( ); // disconnect from current online game
|
||||
|
||||
SV_ShutdownGame(); // exit from current game
|
||||
}
|
||||
|
||||
@@ -77,6 +82,9 @@ void COM_LoadLevel( char const *pMapName, qboolean background )
|
||||
GameState->loadGame = false;
|
||||
GameState->newGame = false;
|
||||
|
||||
if( !SV_Active( ))
|
||||
CL_Disconnect( ); // disconnect from current online game
|
||||
|
||||
SV_ShutdownGame(); // exit from current game
|
||||
}
|
||||
|
||||
@@ -93,6 +101,9 @@ void COM_LoadGame( char const *pMapName )
|
||||
GameState->backgroundMap = false;
|
||||
GameState->newGame = false;
|
||||
GameState->loadGame = true;
|
||||
|
||||
if( !SV_Active( ))
|
||||
CL_Disconnect( ); // disconnect from current online game
|
||||
}
|
||||
|
||||
void COM_ChangeLevel( char const *pNewLevel, char const *pLandmarkName, qboolean background )
|
||||
@@ -137,7 +148,7 @@ static void Host_ShutdownGame( void )
|
||||
}
|
||||
}
|
||||
|
||||
static void Host_RunFrame( float time )
|
||||
static void Host_RunFrame( double time )
|
||||
{
|
||||
// at this time, we don't need to get events from OS on dedicated
|
||||
#if !XASH_DEDICATED
|
||||
@@ -168,11 +179,23 @@ static void Host_RunFrame( float time )
|
||||
}
|
||||
}
|
||||
|
||||
void COM_Frame( float time )
|
||||
/*
|
||||
================
|
||||
Host_AbortCurrentFrame
|
||||
|
||||
aborts the current host frame and goes on with the next one
|
||||
================
|
||||
*/
|
||||
void Host_AbortCurrentFrame( void )
|
||||
{
|
||||
longjmp( g_abortframe, 1 );
|
||||
}
|
||||
|
||||
void COM_Frame( double time )
|
||||
{
|
||||
int loopCount = 0;
|
||||
|
||||
if( setjmp( host.abortframe ))
|
||||
if( setjmp( g_abortframe ))
|
||||
return;
|
||||
|
||||
while( 1 )
|
||||
|
||||
@@ -17,8 +17,6 @@ GNU General Public License for more details.
|
||||
#include "hpak.h"
|
||||
|
||||
#define HPAK_MAX_ENTRIES 0x8000
|
||||
#define HPAK_ENTRY_MIN_SIZE (512)
|
||||
#define HPAK_ENTRY_MAX_SIZE (128 * 1024)
|
||||
|
||||
typedef struct hash_pack_queue_s
|
||||
{
|
||||
@@ -29,11 +27,17 @@ typedef struct hash_pack_queue_s
|
||||
struct hash_pack_queue_s *next;
|
||||
} hash_pack_queue_t;
|
||||
|
||||
static CVAR_DEFINE_AUTO( hpk_maxsize, "4", FCVAR_ARCHIVE, "set limit by size for all HPK-files ( 0 - unlimited )" );
|
||||
static CVAR_DEFINE( hpk_maxsize, "hpk_max_size", "64", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "set limit by size for all HPK-files in megabytes ( 0 - unlimited )" );
|
||||
CVAR_DEFINE_AUTO( hpk_custom_file, "custom.hpk", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "set custom path for players customizations cache file" );
|
||||
static hash_pack_queue_t *gp_hpak_queue = NULL;
|
||||
static hpak_header_t hash_pack_header;
|
||||
static hpak_info_t hash_pack_info;
|
||||
|
||||
static void HPAK_MaxSize_f( void )
|
||||
{
|
||||
Con_Printf( S_ERROR "hpk_maxsize is deprecated, use hpk_max_size\n" );
|
||||
}
|
||||
|
||||
static const char *HPAK_TypeFromIndex( int type )
|
||||
{
|
||||
switch( type )
|
||||
@@ -73,7 +77,7 @@ static void HPAK_AddToQueue( const char *name, resource_t *pResource, void *data
|
||||
|
||||
if( data != NULL ) memcpy( p->data, data, p->size );
|
||||
else if( f != NULL ) FS_Read( f, p->data, p->size );
|
||||
else Host_Error( "HPAK_AddToQueue: data == NULL.\n" );
|
||||
else Host_Error( "%s: data == NULL.\n", __func__ );
|
||||
|
||||
p->next = gp_hpak_queue;
|
||||
gp_hpak_queue = p;
|
||||
@@ -116,7 +120,7 @@ static void HPAK_CreatePak( const char *filename, resource_t *pResource, byte *p
|
||||
fout = FS_Open( pakname, "wb", true );
|
||||
if( !fout )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "HPAK_CreatePak: can't write %s.\n", pakname );
|
||||
Con_DPrintf( S_ERROR "%s: can't write %s.\n", __func__, pakname );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -145,7 +149,7 @@ static void HPAK_CreatePak( const char *filename, resource_t *pResource, byte *p
|
||||
|
||||
if( memcmp( md5, pResource->rgucMD5_hash, 16 ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "HPAK_CreatePak: bad checksum for %s. Ignored\n", pakname );
|
||||
Con_DPrintf( S_ERROR "%s: bad checksum for %s. Ignored\n", __func__, pakname );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -246,7 +250,7 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
|
||||
|
||||
if( memcmp( md5, pResource->rgucMD5_hash, 16 ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "HPAK_AddLump: bad checksum for %s. Ignored\n", pResource->szFileName );
|
||||
Con_DPrintf( S_ERROR "%s: bad checksum for %s. Ignored\n", __func__, pResource->szFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -275,7 +279,7 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
|
||||
|
||||
if( !file_dst )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "HPAK_AddLump: couldn't open %s.\n", srcname );
|
||||
Con_DPrintf( S_ERROR "%s: couldn't open %s.\n", __func__, srcname );
|
||||
FS_Close( file_src );
|
||||
return;
|
||||
}
|
||||
@@ -286,7 +290,7 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
|
||||
if( hash_pack_header.version != IDHPAK_VERSION )
|
||||
{
|
||||
// we don't check the HPAK bit for some reason.
|
||||
Con_DPrintf( S_ERROR "HPAK_AddLump: %s does not have a valid header.\n", srcname );
|
||||
Con_DPrintf( S_ERROR "%s: %s does not have a valid header.\n", __func__, srcname );
|
||||
FS_Close( file_src );
|
||||
FS_Close( file_dst );
|
||||
return;
|
||||
@@ -301,7 +305,7 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
|
||||
|
||||
if( srcpak.count < 1 || srcpak.count > HPAK_MAX_ENTRIES )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "HPAK_AddLump: %s contain too many lumps.\n", srcname );
|
||||
Con_DPrintf( S_ERROR "%s: %s contain too many lumps.\n", __func__, srcname );
|
||||
FS_Close( file_src );
|
||||
FS_Close( file_dst );
|
||||
return;
|
||||
@@ -410,7 +414,7 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
FS_Read( f, &hdr, sizeof( hdr ));
|
||||
if( hdr.ident != IDHPAKHEADER || hdr.version != IDHPAK_VERSION )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "HPAK_ValidatePak: %s does not have a valid HPAK header.\n", pakname );
|
||||
Con_DPrintf( S_ERROR "%s: %s does not have a valid HPAK header.\n", __func__, pakname );
|
||||
FS_Close( f );
|
||||
if( delete ) FS_Delete( pakname );
|
||||
return false;
|
||||
@@ -421,7 +425,7 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
|
||||
if( num_lumps < 1 || num_lumps > HPAK_MAX_ENTRIES )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "HPAK_ValidatePak: %s has too many lumps %u.\n", pakname, num_lumps );
|
||||
Con_DPrintf( S_ERROR "%s: %s has too many lumps %u.\n", __func__, pakname, num_lumps );
|
||||
FS_Close( f );
|
||||
if( delete ) FS_Delete( pakname );
|
||||
return false;
|
||||
@@ -439,7 +443,7 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
if( dataDir[i].disksize < HPAK_ENTRY_MIN_SIZE || dataDir[i].disksize > HPAK_ENTRY_MAX_SIZE )
|
||||
{
|
||||
// odd max size
|
||||
Con_DPrintf( S_ERROR "HPAK_ValidatePak: lump %i has invalid size %s\n", i, Q_pretifymem( dataDir[i].disksize, 2 ));
|
||||
Con_DPrintf( S_ERROR "%s: lump %i has invalid size %s\n", __func__, i, Q_pretifymem( dataDir[i].disksize, 2 ));
|
||||
Mem_Free( dataDir );
|
||||
FS_Close( f );
|
||||
if( delete ) FS_Delete( pakname );
|
||||
@@ -467,7 +471,7 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
{
|
||||
if( quiet )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "HPAK_ValidatePak: %s has invalid checksum.\n", pakname );
|
||||
Con_DPrintf( S_ERROR "%s: %s has invalid checksum.\n", __func__, pakname );
|
||||
Mem_Free( dataPak );
|
||||
Mem_Free( dataDir );
|
||||
FS_Close( f );
|
||||
@@ -517,7 +521,7 @@ void HPAK_CheckSize( const char *filename )
|
||||
Q_strncpy( pakname, filename, sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk", sizeof( pakname ));
|
||||
|
||||
if( FS_FileSize( pakname, false ) > ( maxsize * 1048576 ))
|
||||
if( FS_FileSize( pakname, false ) > ( maxsize * 1024 * 1024 ))
|
||||
{
|
||||
Con_Printf( "Server: Size of %s > %f MB, deleting.\n", filename, hpk_maxsize.value );
|
||||
Log_Printf( "Server: Size of %s > %f MB, deleting.\n", filename, hpk_maxsize.value );
|
||||
@@ -708,7 +712,7 @@ qboolean HPAK_GetDataPointer( const char *filename, resource_t *pResource, byte
|
||||
|
||||
if( directory.count < 1 || directory.count > HPAK_MAX_ENTRIES )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "HPAK_GetDataPointer: %s has too many lumps %u.\n", filename, directory.count );
|
||||
Con_DPrintf( S_ERROR "%s: %s has too many lumps %u.\n", __func__, filename, directory.count );
|
||||
FS_Close( f );
|
||||
return false;
|
||||
}
|
||||
@@ -1101,7 +1105,9 @@ void HPAK_Init( void )
|
||||
Cmd_AddRestrictedCommand( "hpkremove", HPAK_Remove_f, "remove specified file from HPK-file" );
|
||||
Cmd_AddRestrictedCommand( "hpkval", HPAK_Validate_f, "validate specified HPK-file" );
|
||||
Cmd_AddRestrictedCommand( "hpkextract", HPAK_Extract_f, "extract all lumps from specified HPK-file" );
|
||||
Cmd_AddRestrictedCommand( "hpk_maxsize", HPAK_MaxSize_f, "deprecation notice for hpk_maxsize" );
|
||||
Cvar_RegisterVariable( &hpk_maxsize );
|
||||
Cvar_RegisterVariable( &hpk_custom_file );
|
||||
|
||||
gp_hpak_queue = NULL;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@ GNU General Public License for more details.
|
||||
|
||||
#include "custom.h"
|
||||
|
||||
#define HPAK_ENTRY_MIN_SIZE (512)
|
||||
#define HPAK_ENTRY_MAX_SIZE (256 * 1024)
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
.HPK archive format (Hash PAK - HPK)
|
||||
|
||||
@@ -13,6 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "common.h"
|
||||
#include <fcntl.h>
|
||||
#if !XASH_WIN32
|
||||
@@ -104,7 +105,7 @@ static void ID_BloomFilter_f( void )
|
||||
for( i = 1; i < Cmd_Argc(); i++ )
|
||||
value |= BloomFilter_ProcessStr( Cmd_Argv( i ) );
|
||||
|
||||
Msg( "%d %016llX\n", BloomFilter_Weight( value ), value );
|
||||
Msg( "%d %016"PRIX64"\n", BloomFilter_Weight( value ), value );
|
||||
|
||||
// test
|
||||
// for( i = 1; i < Cmd_Argc(); i++ )
|
||||
@@ -283,7 +284,7 @@ static void ID_TestCPUInfo_f( void )
|
||||
bloomfilter_t value = 0;
|
||||
|
||||
if( ID_ProcessCPUInfo( &value ) )
|
||||
Msg( "Got %016llX\n", value );
|
||||
Msg( "Got %016"PRIX64"\n", value );
|
||||
else
|
||||
Msg( "Could not get serial\n" );
|
||||
}
|
||||
@@ -555,7 +556,7 @@ static uint ID_CheckRawId( bloomfilter_t filter )
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
Msg( "ID_CheckRawId: %d\n", count );
|
||||
Msg( "%s: %d\n", __func__, count );
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
@@ -575,7 +576,7 @@ static void ID_Check( void )
|
||||
{
|
||||
id = 0;
|
||||
#if 0
|
||||
Msg( "ID_Check(): fail %d\n", weight );
|
||||
Msg( "%s: fail %d\n", __func__, weight );
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -583,7 +584,7 @@ static void ID_Check( void )
|
||||
if( ID_CheckRawId( id ) < mincount )
|
||||
id = 0;
|
||||
#if 0
|
||||
Msg( "ID_Check(): success %d\n", weight );
|
||||
Msg( "%s: success %d\n", __func__, weight );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -621,7 +622,7 @@ void ID_Init( void )
|
||||
#endif
|
||||
|
||||
#if XASH_ANDROID && !XASH_DEDICATED
|
||||
sscanf( Android_LoadID(), "%016llX", &id );
|
||||
sscanf( Android_LoadID(), "%016"PRIX64, &id );
|
||||
if( id )
|
||||
{
|
||||
id ^= SYSTEM_XOR_MASK;
|
||||
@@ -633,7 +634,7 @@ void ID_Init( void )
|
||||
CHAR szBuf[MAX_PATH];
|
||||
ID_GetKeyData( HKEY_CURRENT_USER, "Software\\Xash3D\\", "xash_id", szBuf, MAX_PATH );
|
||||
|
||||
sscanf(szBuf, "%016llX", &id);
|
||||
sscanf(szBuf, "%016"PRIX64, &id);
|
||||
id ^= SYSTEM_XOR_MASK;
|
||||
ID_Check();
|
||||
}
|
||||
@@ -649,7 +650,7 @@ void ID_Init( void )
|
||||
cfg = fopen( va( "%s/.xash_id", home ), "r" );
|
||||
if( cfg )
|
||||
{
|
||||
if( fscanf( cfg, "%016llX", &id ) > 0 )
|
||||
if( fscanf( cfg, "%016"PRIX64, &id ) > 0 )
|
||||
{
|
||||
id ^= SYSTEM_XOR_MASK;
|
||||
ID_Check();
|
||||
@@ -664,7 +665,7 @@ void ID_Init( void )
|
||||
const char *buf = (const char*) FS_LoadFile( ".xash_id", NULL, false );
|
||||
if( buf )
|
||||
{
|
||||
sscanf( buf, "%016llX", &id );
|
||||
sscanf( buf, "%016"PRIX64, &id );
|
||||
id ^= GAME_XOR_MASK;
|
||||
ID_Check();
|
||||
}
|
||||
@@ -680,11 +681,11 @@ void ID_Init( void )
|
||||
Q_snprintf( &id_md5[i*2], sizeof( id_md5 ) - i * 2, "%02hhx", md5[i] );
|
||||
|
||||
#if XASH_ANDROID && !XASH_DEDICATED
|
||||
Android_SaveID( va("%016llX", id^SYSTEM_XOR_MASK ) );
|
||||
Android_SaveID( va("%016"PRIX64, id^SYSTEM_XOR_MASK ) );
|
||||
#elif XASH_WIN32
|
||||
{
|
||||
CHAR Buf[MAX_PATH];
|
||||
sprintf( Buf, "%016llX", id^SYSTEM_XOR_MASK );
|
||||
sprintf( Buf, "%016"PRIX64, id^SYSTEM_XOR_MASK );
|
||||
ID_SetKeyData( HKEY_CURRENT_USER, "Software\\Xash3D\\", REG_SZ, "xash_id", Buf, Q_strlen(Buf) );
|
||||
}
|
||||
#else
|
||||
@@ -699,14 +700,14 @@ void ID_Init( void )
|
||||
cfg = fopen( va( "%s/.xash_id", home ), "w" );
|
||||
if( cfg )
|
||||
{
|
||||
fprintf( cfg, "%016llX", id^SYSTEM_XOR_MASK );
|
||||
fprintf( cfg, "%016"PRIX64, id^SYSTEM_XOR_MASK );
|
||||
fclose( cfg );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
FS_WriteFile( ".xash_id", va("%016llX", id^GAME_XOR_MASK), 16 );
|
||||
FS_WriteFile( ".xash_id", va("%016"PRIX64, id^GAME_XOR_MASK), 16 );
|
||||
#if 0
|
||||
Msg("MD5 id: %s\nRAW id:%016llX\n", id_md5, id );
|
||||
Msg("MD5 id: %s\nRAW id:%016"PRIX64"\n", id_md5, id );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -103,8 +103,8 @@ typedef struct imglib_s
|
||||
#define IMAGE_MAXHEIGHT 8192
|
||||
#define LUMP_MAXWIDTH 1024 // WorldCraft limits
|
||||
#define LUMP_MAXHEIGHT 1024
|
||||
#define PLDECAL_MAXWIDTH 512
|
||||
#define PLDECAL_MAXHEIGHT 512
|
||||
#define PLDECAL_MAXWIDTH 768 // total of ~2mb uncompressed rgba data
|
||||
#define PLDECAL_MAXHEIGHT 768
|
||||
|
||||
enum
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
if( filesize < sizeof( bhdr ))
|
||||
{
|
||||
Con_Reportf( S_ERROR "Image_LoadBMP: %s have incorrect file size %li should be greater than %li (header)\n", name, filesize, sizeof( bhdr ) );
|
||||
Con_Reportf( S_ERROR "%s: %s have incorrect file size %li should be greater than %zu (header)\n", __func__, name, (long)filesize, sizeof( bhdr ));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -49,13 +49,13 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
if( memcmp( bhdr.id, "BM", 2 ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadBMP: only Windows-style BMP files supported (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: only Windows-style BMP files supported (%s)\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!( bhdr.bitmapHeaderSize == 40 || bhdr.bitmapHeaderSize == 108 || bhdr.bitmapHeaderSize == 124 ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadBMP: %s have non-standard header size %i\n", name, bhdr.bitmapHeaderSize );
|
||||
Con_DPrintf( S_ERROR "%s: %s have non-standard header size %i\n", __func__, name, bhdr.bitmapHeaderSize );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
if( bhdr.fileSize != filesize )
|
||||
{
|
||||
// Sweet Half-Life issues. splash.bmp have bogus filesize
|
||||
Con_Reportf( S_WARN "Image_LoadBMP: %s have incorrect file size %li should be %i\n", name, filesize, bhdr.fileSize );
|
||||
Con_Reportf( S_WARN "%s: %s have incorrect file size %li should be %i\n", __func__, name, (long)filesize, bhdr.fileSize );
|
||||
}
|
||||
|
||||
// bogus compression? Only non-compressed supported.
|
||||
@@ -71,7 +71,7 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
{
|
||||
if( bhdr.bitsPerPixel != 32 || bhdr.compression != BI_BITFIELDS )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadBMP: only uncompressed BMP files supported (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: only uncompressed BMP files supported (%s)\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -108,7 +108,7 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
estimatedSize = ( buf_p - buffer ) + cbPalBytes;
|
||||
if( filesize < estimatedSize )
|
||||
{
|
||||
Con_Reportf( S_ERROR "Image_LoadBMP: %s have incorrect file size %li should be greater than %li (palette)\n", name, filesize, estimatedSize );
|
||||
Con_Reportf( S_ERROR "%s: %s have incorrect file size %li should be greater than %li (palette)\n", __func__, name, (long)filesize, (long)estimatedSize );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
image.palette = NULL;
|
||||
}
|
||||
|
||||
Con_Reportf( S_ERROR "Image_LoadBMP: %s have incorrect file size %li should be greater than %li (pixels)\n", name, filesize, estimatedSize );
|
||||
Con_Reportf( S_ERROR "%s: %s have incorrect file size %li should be greater than %li (pixels)\n", __func__, name, (long)filesize, (long)estimatedSize );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ static uint Image_DXTCalcSize( const char *name, dds_t *hdr, size_t filesize )
|
||||
|
||||
if( filesize != buffsize ) // main check
|
||||
{
|
||||
Con_DPrintf( S_WARN "Image_LoadDDS: (%s) probably corrupted (%zu should be %lu)\n", name, buffsize, filesize );
|
||||
Con_DPrintf( S_WARN "%s: (%s) probably corrupted (%zu should be %zu)\n", __func__, name, buffsize, filesize );
|
||||
if( buffsize > filesize )
|
||||
return false;
|
||||
}
|
||||
@@ -300,13 +300,13 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
if( header.dwSize != sizeof( header ) - sizeof( uint )) // size of the structure (minus MagicNum)
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadDDS: (%s) have corrupted header\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: (%s) have corrupted header\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( header.dsPixelFormat.dwSize != sizeof( dds_pixf_t )) // size of the structure
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadDDS: (%s) have corrupt pixelformat header\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: (%s) have corrupt pixelformat header\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
if( image.type == PF_UNKNOWN )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadDDS: (%s) has unrecognized type\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: (%s) has unrecognized type\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -78,49 +78,49 @@ static qboolean Image_KTX2Parse( const ktx2_header_t *header, const byte *buffer
|
||||
|
||||
if( image.type == PF_UNKNOWN )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: unsupported KTX2 format %d\n", __FUNCTION__, header->vkFormat );
|
||||
Con_DPrintf( S_ERROR "%s: unsupported KTX2 format %d\n", __func__, header->vkFormat );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !Image_CheckFlag( IL_DDS_HARDWARE ) && ImageCompressed( image.type ))
|
||||
{
|
||||
Con_DPrintf( S_WARN "%s: has compressed format, but support is not advertized\n", __FUNCTION__ );
|
||||
Con_DPrintf( S_WARN "%s: has compressed format, but support is not advertized\n", __func__ );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( header->levelCount == 0 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: file has no mip levels\n", __FUNCTION__ );
|
||||
Con_DPrintf( S_ERROR "%s: file has no mip levels\n", __func__ );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( header->pixelDepth > 1 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: unsupported KTX2 pixelDepth %d\n", __FUNCTION__, header->pixelDepth );
|
||||
Con_DPrintf( S_ERROR "%s: unsupported KTX2 pixelDepth %d\n", __func__, header->pixelDepth );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( header->faceCount > 1 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: unsupported KTX2 faceCount %d\n", __FUNCTION__, header->faceCount );
|
||||
Con_DPrintf( S_ERROR "%s: unsupported KTX2 faceCount %d\n", __func__, header->faceCount );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( header->layerCount > 1 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: unsupported KTX2 layerCount %d\n", __FUNCTION__, header->layerCount );
|
||||
Con_DPrintf( S_ERROR "%s: unsupported KTX2 layerCount %d\n", __func__, header->layerCount );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( header->supercompressionScheme != 0 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: unsupported KTX2 supercompressionScheme %d\n", __FUNCTION__, header->supercompressionScheme );
|
||||
Con_DPrintf( S_ERROR "%s: unsupported KTX2 supercompressionScheme %d\n", __func__, header->supercompressionScheme );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( header->levelCount * sizeof( ktx2_level_t ) + KTX2_LEVELS_OFFSET > filesize )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: file abruptly ends\n", __FUNCTION__ );
|
||||
Con_DPrintf( S_ERROR "%s: file abruptly ends\n", __func__ );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ static qboolean Image_KTX2Parse( const ktx2_header_t *header, const byte *buffer
|
||||
if( mip_size != level.byteLength )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: mip=%d size mismatch read=%d, but computed=%d\n",
|
||||
__FUNCTION__, mip, (int)level.byteLength, mip_size );
|
||||
__func__, mip, (int)level.byteLength, mip_size );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ qboolean Image_LoadKTX2( const char *name, const byte *buffer, fs_offset_t files
|
||||
|
||||
if( memcmp( buffer, KTX2_IDENTIFIER, KTX2_IDENTIFIER_SIZE ) != 0 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: (%s) has invalid identifier\n", __FUNCTION__, name );
|
||||
Con_DPrintf( S_ERROR "%s: (%s) has invalid identifier\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ qboolean Image_LoadKTX2( const char *name, const byte *buffer, fs_offset_t files
|
||||
// If KTX2 to imagelib conversion failed, try passing the file as raw data.
|
||||
// This is useful for ref_vk which can directly support hundreds of formats which we don't convert to pixformat_t here
|
||||
|
||||
Con_DPrintf( S_WARN "%s: (%s) could not be converted to supported imagelib format, passing as raw KTX2 data\n", __FUNCTION__, name );
|
||||
Con_DPrintf( S_WARN "%s: (%s) could not be converted to supported imagelib format, passing as raw KTX2 data\n", __func__, name );
|
||||
// This is a catch-all for ref_vk, which can do this format directly and natively
|
||||
image.type = PF_KTX2_RAW;
|
||||
|
||||
|
||||
@@ -360,7 +360,7 @@ load_internal:
|
||||
}
|
||||
|
||||
if( loadname[0] != '#' )
|
||||
Con_Reportf( S_WARN "FS_LoadImage: couldn't load \"%s\"\n", loadname );
|
||||
Con_Reportf( S_WARN "%s: couldn't load \"%s\"\n", __func__, loadname );
|
||||
|
||||
// clear any force flags
|
||||
image.force_flags = 0;
|
||||
|
||||
@@ -63,7 +63,7 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
// check png signature
|
||||
if( memcmp( png_hdr.sign, png_sign, sizeof( png_sign ) ) )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: Invalid PNG signature (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: Invalid PNG signature (%s)\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -73,14 +73,14 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
// check IHDR chunk length (valid value - 13)
|
||||
if( png_hdr.ihdr_len != sizeof( png_ihdr_t ) )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: Invalid IHDR chunk size %u (%s)\n", png_hdr.ihdr_len, name );
|
||||
Con_DPrintf( S_ERROR "%s: Invalid IHDR chunk size %u (%s)\n", __func__, png_hdr.ihdr_len, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
// check IHDR chunk signature
|
||||
if( memcmp( png_hdr.ihdr_sign, ihdr_sign, sizeof( ihdr_sign ) ) )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: IHDR chunk corrupted (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: IHDR chunk corrupted (%s)\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
if( png_hdr.ihdr_chunk.height == 0 || png_hdr.ihdr_chunk.width == 0 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: Invalid image size %ux%u (%s)\n", png_hdr.ihdr_chunk.width, png_hdr.ihdr_chunk.height, name );
|
||||
Con_DPrintf( S_ERROR "%s: Invalid image size %ux%u (%s)\n", __func__, png_hdr.ihdr_chunk.width, png_hdr.ihdr_chunk.height, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
if( png_hdr.ihdr_chunk.bitdepth != 8 )
|
||||
{
|
||||
Con_DPrintf( S_WARN "Image_LoadPNG: Only 8-bit images is supported (%s)\n", name );
|
||||
Con_DPrintf( S_WARN "%s: Only 8-bit images is supported (%s)\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -109,31 +109,31 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|| png_hdr.ihdr_chunk.colortype == PNG_CT_ALPHA
|
||||
|| png_hdr.ihdr_chunk.colortype == PNG_CT_PALLETE ) )
|
||||
{
|
||||
Con_DPrintf( S_WARN "Image_LoadPNG: Unknown color type %u (%s)\n", png_hdr.ihdr_chunk.colortype, name );
|
||||
Con_DPrintf( S_WARN "%s: Unknown color type %u (%s)\n", __func__, png_hdr.ihdr_chunk.colortype, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( png_hdr.ihdr_chunk.compression > 0 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: Unknown compression method %u (%s)\n", png_hdr.ihdr_chunk.compression, name );
|
||||
Con_DPrintf( S_ERROR "%s: Unknown compression method %u (%s)\n", __func__, png_hdr.ihdr_chunk.compression, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( png_hdr.ihdr_chunk.filter > 0 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: Unknown filter type %u (%s)\n", png_hdr.ihdr_chunk.filter, name );
|
||||
Con_DPrintf( S_ERROR "%s: Unknown filter type %u (%s)\n", __func__, png_hdr.ihdr_chunk.filter, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( png_hdr.ihdr_chunk.interlace == 1 )
|
||||
{
|
||||
Con_DPrintf( S_WARN "Image_LoadPNG: Adam7 Interlacing not supported (%s)\n", name );
|
||||
Con_DPrintf( S_WARN "%s: Adam7 Interlacing not supported (%s)\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( png_hdr.ihdr_chunk.interlace > 0 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: Unknown interlacing type %u (%s)\n", png_hdr.ihdr_chunk.interlace, name );
|
||||
Con_DPrintf( S_ERROR "%s: Unknown interlacing type %u (%s)\n", __func__, png_hdr.ihdr_chunk.interlace, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
// check IHDR chunk CRC
|
||||
if( ntohl( png_hdr.ihdr_crc32 ) != crc32_check )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: IHDR chunk has wrong CRC32 sum (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: IHDR chunk has wrong CRC32 sum (%s)\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -163,14 +163,14 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
if( chunk_len > INT_MAX )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: Found chunk with wrong size (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: Found chunk with wrong size (%s)\n", __func__, name );
|
||||
if( idat_buf ) Mem_Free( idat_buf );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( chunk_len > filesize - ( buf_p - buffer ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: Found chunk with size past file size (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: Found chunk with size past file size (%s)\n", __func__, name );
|
||||
if( idat_buf ) Mem_Free( idat_buf );
|
||||
return false;
|
||||
}
|
||||
@@ -216,7 +216,7 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
// check chunk CRC
|
||||
if( ntohl( crc32 ) != crc32_check )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: Found chunk with wrong CRC32 sum (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: Found chunk with wrong CRC32 sum (%s)\n", __func__, name );
|
||||
if( idat_buf ) Mem_Free( idat_buf );
|
||||
return false;
|
||||
}
|
||||
@@ -227,27 +227,27 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
if( oldsize == 0 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: Couldn't find IDAT chunks (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: Couldn't find IDAT chunks (%s)\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( png_hdr.ihdr_chunk.colortype == PNG_CT_PALLETE && !pallete )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: PLTE chunk not found (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: PLTE chunk not found (%s)\n", __func__, name );
|
||||
Mem_Free( idat_buf );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !has_iend_chunk )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: IEND chunk not found (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: IEND chunk not found (%s)\n", __func__, name );
|
||||
Mem_Free( idat_buf );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( chunk_len != 0 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: IEND chunk has wrong size %u (%s)\n", chunk_len, name );
|
||||
Con_DPrintf( S_ERROR "%s: IEND chunk has wrong size %u (%s)\n", __func__, chunk_len, name );
|
||||
Mem_Free( idat_buf );
|
||||
return false;
|
||||
}
|
||||
@@ -298,7 +298,7 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
// uncompress image
|
||||
if( inflateInit2( &stream, MAX_WBITS ) != Z_OK )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: IDAT chunk decompression failed (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: IDAT chunk decompression failed (%s)\n", __func__, name );
|
||||
Mem_Free( uncompressed_buffer );
|
||||
Mem_Free( idat_buf );
|
||||
return false;
|
||||
@@ -311,7 +311,7 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
if( ret != Z_OK && ret != Z_STREAM_END )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: IDAT chunk decompression failed (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: IDAT chunk decompression failed (%s)\n", __func__, name );
|
||||
Mem_Free( uncompressed_buffer );
|
||||
return false;
|
||||
}
|
||||
@@ -351,7 +351,7 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
pixbuf[i] = raw[i] + ( pixbuf[i - pixel_size] >> 1 );
|
||||
break;
|
||||
default:
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: Found unknown filter type (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: Found unknown filter type (%s)\n", __func__, name );
|
||||
Mem_Free( uncompressed_buffer );
|
||||
Mem_Free( image.rgba );
|
||||
return false;
|
||||
@@ -415,7 +415,7 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Con_DPrintf( S_ERROR "Image_LoadPNG: Found unknown filter type (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: Found unknown filter type (%s)\n", __func__, name );
|
||||
Mem_Free( uncompressed_buffer );
|
||||
Mem_Free( image.rgba );
|
||||
return false;
|
||||
@@ -650,7 +650,7 @@ qboolean Image_SavePNG( const char *name, rgbdata_t *pix )
|
||||
// compress image
|
||||
if( deflateInit( &stream, Z_BEST_COMPRESSION ) != Z_OK )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_SavePNG: deflateInit failed (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: deflateInit failed (%s)\n", __func__, name );
|
||||
Mem_Free( filtered_buffer );
|
||||
Mem_Free( buffer );
|
||||
return false;
|
||||
@@ -663,7 +663,7 @@ qboolean Image_SavePNG( const char *name, rgbdata_t *pix )
|
||||
|
||||
if( ret != Z_OK && ret != Z_STREAM_END )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_SavePNG: IDAT chunk compression failed (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: IDAT chunk compression failed (%s)\n", __func__, name );
|
||||
Mem_Free( buffer );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -62,17 +62,17 @@ qboolean Image_LoadTGA( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
// uncompressed colormapped image
|
||||
if( targa_header.pixel_size != 8 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadTGA: (%s) Only 8 bit images supported for type 1 and 9\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: (%s) Only 8 bit images supported for type 1 and 9\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
if( targa_header.colormap_length != 256 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadTGA: (%s) Only 8 bit colormaps are supported for type 1 and 9\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: (%s) Only 8 bit colormaps are supported for type 1 and 9\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
if( targa_header.colormap_index )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadTGA: (%s) colormap_index is not supported for type 1 and 9\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: (%s) colormap_index is not supported for type 1 and 9\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
if( targa_header.colormap_size == 24 )
|
||||
@@ -97,7 +97,7 @@ qboolean Image_LoadTGA( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadTGA: (%s) only 24 and 32 bit colormaps are supported for type 1 and 9\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: (%s) only 24 and 32 bit colormaps are supported for type 1 and 9\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -106,7 +106,7 @@ qboolean Image_LoadTGA( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
// uncompressed or RLE compressed RGB
|
||||
if( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadTGA: (%s) Only 32 or 24 bit images supported for type 2 and 10\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: (%s) Only 32 or 24 bit images supported for type 2 and 10\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,7 @@ qboolean Image_LoadTGA( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
// uncompressed greyscale
|
||||
if( targa_header.pixel_size != 8 && targa_header.pixel_size != 16 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadTGA: (%s) Only 8 bit images supported for type 3 and 11\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: (%s) Only 8 bit images supported for type 3 and 11\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1179,7 +1179,7 @@ byte *Image_FlipInternal( const byte *in, word *srcwidth, word *srcheight, int t
|
||||
return image.tempbuffer;
|
||||
}
|
||||
|
||||
static byte *Image_CreateLumaInternal( byte *fin, int width, int height, int type, int flags )
|
||||
static byte *Image_MakeLuma( byte *fin, int width, int height, int type, int flags )
|
||||
{
|
||||
byte *out;
|
||||
int i;
|
||||
@@ -1197,7 +1197,7 @@ static byte *Image_CreateLumaInternal( byte *fin, int width, int height, int typ
|
||||
break;
|
||||
default:
|
||||
// another formats does ugly result :(
|
||||
Con_Printf( S_ERROR "Image_MakeLuma: unsupported format %s\n", PFDesc[type].name );
|
||||
Con_Printf( S_ERROR "%s: unsupported format %s\n", __func__, PFDesc[type].name );
|
||||
return (byte *)fin;
|
||||
}
|
||||
|
||||
@@ -1396,7 +1396,7 @@ qboolean Image_Process(rgbdata_t **pix, int width, int height, uint flags, float
|
||||
|
||||
if( FBitSet( flags, IMAGE_MAKE_LUMA ))
|
||||
{
|
||||
out = Image_CreateLumaInternal( pic->buffer, pic->width, pic->height, pic->type, pic->flags );
|
||||
out = Image_MakeLuma( pic->buffer, pic->width, pic->height, pic->type, pic->flags );
|
||||
if( pic->buffer != out ) memcpy( pic->buffer, image.tempbuffer, pic->size );
|
||||
ClearBits( pic->flags, IMAGE_HAS_LUMA );
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ qboolean Image_LoadPAL( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
if( filesize != 768 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadPAL: (%s) have invalid size (%ld should be %d)\n", name, filesize, 768 );
|
||||
Con_DPrintf( S_ERROR "%s: (%s) have invalid size (%li should be %d)\n", __func__, name, (long)filesize, 768 );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,8 +81,8 @@ void *COM_FunctionFromName_SR( void *hInstance, const char *pName )
|
||||
const char *COM_OffsetNameForFunction( void *function )
|
||||
{
|
||||
static string sname;
|
||||
Q_snprintf( sname, MAX_STRING, "ofs:%lu", (size_t)((byte*)function - (byte*)svgame.dllFuncs.pfnGameInit) );
|
||||
Con_Reportf( "COM_OffsetNameForFunction %s\n", sname );
|
||||
Q_snprintf( sname, MAX_STRING, "ofs:%zu", ((byte*)function - (byte*)svgame.dllFuncs.pfnGameInit) );
|
||||
Con_Reportf( "%s: %s\n", __func__, sname );
|
||||
return sname;
|
||||
}
|
||||
|
||||
@@ -231,9 +231,9 @@ void COM_GetCommonLibraryPath( ECommonLibraryType eLibType, char *out, size_t si
|
||||
COM_GenerateClientLibraryPath( "menu", out, size );
|
||||
break;
|
||||
case LIBRARY_CLIENT:
|
||||
if( SI.clientlib[0] )
|
||||
if( COM_CheckStringEmpty( host.clientlib ))
|
||||
{
|
||||
Q_strncpy( out, SI.clientlib, size );
|
||||
Q_strncpy( out, host.clientlib, size );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -241,9 +241,9 @@ void COM_GetCommonLibraryPath( ECommonLibraryType eLibType, char *out, size_t si
|
||||
}
|
||||
break;
|
||||
case LIBRARY_SERVER:
|
||||
if( SI.gamedll[0] )
|
||||
if( COM_CheckStringEmpty( host.gamedll ))
|
||||
{
|
||||
Q_strncpy( out, SI.gamedll, size );
|
||||
Q_strncpy( out, host.gamedll, size );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -359,7 +359,7 @@ static char *COM_GetItaniumName( const char * const in_name )
|
||||
|
||||
if( i == MAX_NESTED_NAMESPACES )
|
||||
{
|
||||
Con_DPrintf( "%s: too much nested namespaces: %s\n", __FUNCTION__, in_name );
|
||||
Con_DPrintf( "%s: too much nested namespaces: %s\n", __func__, in_name );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -373,7 +373,7 @@ static char *COM_GetItaniumName( const char * const in_name )
|
||||
return out_name;
|
||||
|
||||
invalid_format:
|
||||
Con_DPrintf( "%s: invalid format: %s\n", __FUNCTION__, in_name );
|
||||
Con_DPrintf( "%s: invalid format: %s\n", __func__, in_name );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -421,7 +421,7 @@ char **COM_ConvertToLocalPlatform( EFunctionMangleType to, const char *from, siz
|
||||
|
||||
if( i == MAX_NESTED_NAMESPACES )
|
||||
{
|
||||
Con_DPrintf( "%s: too much nested namespaces: %s\n", __FUNCTION__, from );
|
||||
Con_DPrintf( "%s: too much nested namespaces: %s\n", __func__, from );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -262,7 +262,7 @@ static void NET_AddMaster( const char *addr, qboolean save )
|
||||
}
|
||||
|
||||
master = Mem_Malloc( host.mempool, sizeof( master_t ) );
|
||||
Q_strncpy( master->address, addr, MAX_STRING );
|
||||
Q_strncpy( master->address, addr, sizeof( master->address ));
|
||||
master->sent = false;
|
||||
master->save = save;
|
||||
master->next = NULL;
|
||||
@@ -389,7 +389,7 @@ void NET_SaveMasters( void )
|
||||
|
||||
if( !f )
|
||||
{
|
||||
Con_Reportf( S_ERROR "Couldn't write xashcomm.lst\n" );
|
||||
Con_Reportf( S_ERROR "Couldn't write xashcomm.lst\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -419,6 +419,8 @@ void NET_InitMasters( void )
|
||||
|
||||
// keep main master always there
|
||||
NET_AddMaster( MASTERSERVER_ADR, false );
|
||||
NET_AddMaster( MASTERSERVER_ADR_TEST, false );
|
||||
NET_AddMaster( "aaaa.mentality.rip:27010", false ); // IPv6-only
|
||||
NET_AddMaster( "mentality.rip:27011", false );
|
||||
|
||||
NET_LoadMasters( );
|
||||
}
|
||||
|
||||
@@ -24,6 +24,9 @@ GNU General Public License for more details.
|
||||
#include "client.h"
|
||||
#include "server.h" // LUMP_ error codes
|
||||
#include "ref_common.h"
|
||||
#if defined( HAVE_OPENMP )
|
||||
#include <omp.h>
|
||||
#endif // HAVE_OPENMP
|
||||
|
||||
#define MIPTEX_CUSTOM_PALETTE_SIZE_BYTES ( sizeof( int16_t ) + 768 )
|
||||
|
||||
@@ -310,7 +313,7 @@ static qboolean Mod_NameImpliesTextureIsAnimated( texture_t *tex )
|
||||
if( !( tex->name[1] >= '0' && tex->name[1] <= '9' ) &&
|
||||
!( tex->name[1] >= 'a' && tex->name[1] <= 'j' ))
|
||||
{
|
||||
Con_Printf( S_ERROR "Mod_NameImpliesTextureIsAnimated: animating texture \"%s\" has invalid name\n", tex->name );
|
||||
Con_Printf( S_ERROR "%s: animating texture \"%s\" has invalid name\n", __func__, tex->name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -578,6 +581,42 @@ void Mod_PrintWorldStats_f( void )
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
/*
|
||||
===================
|
||||
Mod_DecompressPVS
|
||||
|
||||
TODO: replace all Mod_DecompressPVS calls by this
|
||||
===================
|
||||
*/
|
||||
static void Mod_DecompressPVSTo( byte *const out, const byte *in, size_t visbytes )
|
||||
{
|
||||
byte *dst = out;
|
||||
|
||||
if( !in ) // no visinfo, make all visible
|
||||
{
|
||||
memset( out, 0xFF, visbytes );
|
||||
return;
|
||||
}
|
||||
|
||||
while( dst < out + visbytes )
|
||||
{
|
||||
if( *in ) // uncompressed
|
||||
{
|
||||
*dst++ = *in++;
|
||||
}
|
||||
else // zero repeated `c` times
|
||||
{
|
||||
size_t c = in[1];
|
||||
if( c > out + visbytes - dst )
|
||||
c = out + visbytes - dst;
|
||||
|
||||
memset( dst, 0, c );
|
||||
in += 2;
|
||||
dst += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
Mod_DecompressPVS
|
||||
@@ -585,41 +624,36 @@ Mod_DecompressPVS
|
||||
*/
|
||||
static byte *Mod_DecompressPVS( const byte *in, int visbytes )
|
||||
{
|
||||
byte *out;
|
||||
int c;
|
||||
Mod_DecompressPVSTo( g_visdata, in, visbytes );
|
||||
return g_visdata;
|
||||
}
|
||||
|
||||
out = g_visdata;
|
||||
static size_t Mod_CompressPVS( byte *const out, const byte *in, size_t inbytes )
|
||||
{
|
||||
size_t i;
|
||||
byte *dst = out;
|
||||
|
||||
if( !in )
|
||||
for( i = 0; i < inbytes; i++ )
|
||||
{
|
||||
// no vis info, so make all visible
|
||||
while( visbytes )
|
||||
size_t j = i + 1, rep = 1;
|
||||
|
||||
*dst++ = in[i];
|
||||
|
||||
// only compress zeros
|
||||
if( in[i] )
|
||||
continue;
|
||||
|
||||
for( ; j < inbytes && rep != 255; j++, rep++ )
|
||||
{
|
||||
*out++ = 0xff;
|
||||
visbytes--;
|
||||
if( in[j] )
|
||||
break;
|
||||
}
|
||||
return g_visdata;
|
||||
|
||||
*dst++ = rep;
|
||||
i = j - 1;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if( *in )
|
||||
{
|
||||
*out++ = *in++;
|
||||
continue;
|
||||
}
|
||||
|
||||
c = in[1];
|
||||
in += 2;
|
||||
|
||||
while( c )
|
||||
{
|
||||
*out++ = 0;
|
||||
c--;
|
||||
}
|
||||
} while( out - g_visdata < visbytes );
|
||||
|
||||
return g_visdata;
|
||||
return dst - out;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -653,22 +687,11 @@ NOTE: can return NULL
|
||||
*/
|
||||
byte *Mod_GetPVSForPoint( const vec3_t p )
|
||||
{
|
||||
mnode_t *node;
|
||||
mleaf_t *leaf = NULL;
|
||||
mleaf_t *leaf;
|
||||
|
||||
ASSERT( worldmodel != NULL );
|
||||
|
||||
node = worldmodel->nodes;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if( node->contents < 0 )
|
||||
{
|
||||
leaf = (mleaf_t *)node;
|
||||
break; // we found a leaf
|
||||
}
|
||||
node = node->children[PlaneDiff( p, node->plane ) <= 0];
|
||||
}
|
||||
leaf = Mod_PointInLeaf( p, worldmodel->nodes );
|
||||
|
||||
if( leaf && leaf->cluster >= 0 )
|
||||
return Mod_DecompressPVS( leaf->compressed_vis, world.visbytes );
|
||||
@@ -681,7 +704,7 @@ Mod_FatPVS_RecursiveBSPNode
|
||||
|
||||
==================
|
||||
*/
|
||||
static void Mod_FatPVS_RecursiveBSPNode( const vec3_t org, float radius, byte *visbuffer, int visbytes, mnode_t *node )
|
||||
static void Mod_FatPVS_RecursiveBSPNode( const vec3_t org, float radius, byte *visbuffer, int visbytes, mnode_t *node, qboolean phs )
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -696,7 +719,7 @@ static void Mod_FatPVS_RecursiveBSPNode( const vec3_t org, float radius, byte *v
|
||||
else
|
||||
{
|
||||
// go down both sides
|
||||
Mod_FatPVS_RecursiveBSPNode( org, radius, visbuffer, visbytes, node->children[0] );
|
||||
Mod_FatPVS_RecursiveBSPNode( org, radius, visbuffer, visbytes, node->children[0], phs );
|
||||
node = node->children[1];
|
||||
}
|
||||
}
|
||||
@@ -704,10 +727,19 @@ static void Mod_FatPVS_RecursiveBSPNode( const vec3_t org, float radius, byte *v
|
||||
// if this leaf is in a cluster, accumulate the vis bits
|
||||
if(((mleaf_t *)node)->cluster >= 0 )
|
||||
{
|
||||
byte *vis = Mod_DecompressPVS( ((mleaf_t *)node)->compressed_vis, world.visbytes );
|
||||
byte *vis;
|
||||
|
||||
for( i = 0; i < visbytes; i++ )
|
||||
visbuffer[i] |= vis[i];
|
||||
if( phs )
|
||||
{
|
||||
int i = ((mleaf_t *)node)->cluster + 1;
|
||||
vis = Mod_DecompressPVS( &world.compressed_phs[world.phsofs[i]], world.visbytes );
|
||||
}
|
||||
else
|
||||
{
|
||||
vis = Mod_DecompressPVS( ((mleaf_t *)node)->compressed_vis, world.visbytes );
|
||||
}
|
||||
|
||||
Q_memor( visbuffer, vis, visbytes );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -719,7 +751,7 @@ Calculates a PVS that is the inclusive or of all leafs
|
||||
within radius pixels of the given point.
|
||||
==================
|
||||
*/
|
||||
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis )
|
||||
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis, qboolean phs )
|
||||
{
|
||||
int bytes = world.visbytes;
|
||||
mleaf_t *leaf = NULL;
|
||||
@@ -736,9 +768,17 @@ int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, q
|
||||
return bytes;
|
||||
}
|
||||
|
||||
// requested PHS but we don't have PHS for some reason
|
||||
// enable full visibility
|
||||
if( phs && !( world.compressed_phs && world.phsofs ))
|
||||
{
|
||||
memset( visbuffer, 0xFF, bytes );
|
||||
return bytes;
|
||||
}
|
||||
|
||||
if( !merge ) memset( visbuffer, 0x00, bytes );
|
||||
|
||||
Mod_FatPVS_RecursiveBSPNode( org, radius, visbuffer, bytes, worldmodel->nodes );
|
||||
Mod_FatPVS_RecursiveBSPNode( org, radius, visbuffer, bytes, worldmodel->nodes, phs );
|
||||
|
||||
return bytes;
|
||||
}
|
||||
@@ -902,7 +942,7 @@ static void Mod_FindModelOrigin( const char *entities, const char *modelname, ve
|
||||
while(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) != NULL )
|
||||
{
|
||||
if( token[0] != '{' )
|
||||
Host_Error( "Mod_FindModelOrigin: found %s when expecting {\n", token );
|
||||
Host_Error( "%s: found %s when expecting {\n", __func__, token );
|
||||
|
||||
model_found = origin_found = false;
|
||||
VectorClear( origin );
|
||||
@@ -911,17 +951,17 @@ static void Mod_FindModelOrigin( const char *entities, const char *modelname, ve
|
||||
{
|
||||
// parse key
|
||||
if(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) == NULL )
|
||||
Host_Error( "Mod_FindModelOrigin: EOF without closing brace\n" );
|
||||
Host_Error( "%s: EOF without closing brace\n", __func__ );
|
||||
if( token[0] == '}' ) break; // end of desc
|
||||
|
||||
Q_strncpy( keyname, token, sizeof( keyname ));
|
||||
|
||||
// parse value
|
||||
if(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) == NULL )
|
||||
Host_Error( "Mod_FindModelOrigin: EOF without closing brace\n" );
|
||||
Host_Error( "%s: EOF without closing brace\n", __func__ );
|
||||
|
||||
if( token[0] == '}' )
|
||||
Host_Error( "Mod_FindModelOrigin: closing brace without data\n" );
|
||||
Host_Error( "%s: closing brace without data\n", __func__ );
|
||||
|
||||
if( !Q_stricmp( keyname, "model" ) && !Q_stricmp( modelname, token ))
|
||||
model_found = true;
|
||||
@@ -1158,7 +1198,7 @@ static void Mod_CalcSurfaceExtents( model_t *mod, msurface_t *surf )
|
||||
e = mod->surfedges[surf->firstedge + i];
|
||||
|
||||
if( e >= mod->numedges || e <= -mod->numedges )
|
||||
Host_Error( "Mod_CalcSurfaceExtents: bad edge\n" );
|
||||
Host_Error( "%s: bad edge\n", __func__ );
|
||||
|
||||
if( e >= 0 ) v = &mod->vertexes[mod->edges[e].v[0]];
|
||||
else v = &mod->vertexes[mod->edges[-e].v[1]];
|
||||
@@ -1227,7 +1267,7 @@ static void Mod_CalcSurfaceBounds( model_t *mod, msurface_t *surf )
|
||||
e = mod->surfedges[surf->firstedge + i];
|
||||
|
||||
if( e >= mod->numedges || e <= -mod->numedges )
|
||||
Host_Error( "Mod_CalcSurfaceBounds: bad edge\n" );
|
||||
Host_Error( "%s: bad edge\n", __func__ );
|
||||
|
||||
if( e >= 0 ) v = &mod->vertexes[mod->edges[e].v[0]];
|
||||
else v = &mod->vertexes[mod->edges[-e].v[1]];
|
||||
@@ -1451,7 +1491,7 @@ static void Mod_SetupHull( dbspmodel_t *bmod, model_t *mod, poolhandle_t mempool
|
||||
VectorCopy( host.player_maxs[1], hull->clip_maxs );
|
||||
break;
|
||||
default:
|
||||
Host_Error( "Mod_SetupHull: bad hull number %i\n", hullnum );
|
||||
Host_Error( "%s: bad hull number %i\n", __func__, hullnum );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1508,7 +1548,7 @@ static qboolean Mod_LoadColoredLighting( model_t *mod, dbspmodel_t *bmod )
|
||||
|
||||
if( litdatasize != ( bmod->lightdatasize * 3 ))
|
||||
{
|
||||
Con_Printf( S_ERROR "%s has mismatched size (%llu should be %zu)\n", path, litdatasize, bmod->lightdatasize * 3 );
|
||||
Con_Printf( S_ERROR "%s has mismatched size (%li should be %zu)\n", path, (long)litdatasize, bmod->lightdatasize * 3 );
|
||||
Mem_Free( in );
|
||||
return false;
|
||||
}
|
||||
@@ -1563,7 +1603,7 @@ static void Mod_LoadDeluxemap( model_t *mod, dbspmodel_t *bmod )
|
||||
|
||||
if( deluxdatasize != bmod->lightdatasize )
|
||||
{
|
||||
Con_Reportf( S_ERROR "%s has mismatched size (%llu should be %zu)\n", path, deluxdatasize, bmod->lightdatasize );
|
||||
Con_Reportf( S_ERROR "%s has mismatched size (%li should be %zu)\n", path, (long)deluxdatasize, bmod->lightdatasize );
|
||||
Mem_Free( in );
|
||||
return;
|
||||
}
|
||||
@@ -1801,30 +1841,30 @@ static void Mod_LoadEntities( model_t *mod, dbspmodel_t *bmod )
|
||||
while(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) != NULL )
|
||||
{
|
||||
if( token[0] != '{' )
|
||||
Host_Error( "Mod_LoadEntities: found %s when expecting {\n", token );
|
||||
Host_Error( "%s: found %s when expecting {\n", __func__, token );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
// parse key
|
||||
if(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) == NULL )
|
||||
Host_Error( "Mod_LoadEntities: EOF without closing brace\n" );
|
||||
Host_Error( "%s: EOF without closing brace\n", __func__ );
|
||||
if( token[0] == '}' ) break; // end of desc
|
||||
|
||||
Q_strncpy( keyname, token, sizeof( keyname ));
|
||||
|
||||
// parse value
|
||||
if(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) == NULL )
|
||||
Host_Error( "Mod_LoadEntities: EOF without closing brace\n" );
|
||||
Host_Error( "%s: EOF without closing brace\n", __func__ );
|
||||
|
||||
if( token[0] == '}' )
|
||||
Host_Error( "Mod_LoadEntities: closing brace without data\n" );
|
||||
Host_Error( "%s: closing brace without data\n", __func__ );
|
||||
|
||||
if( !Q_stricmp( keyname, "wad" ))
|
||||
{
|
||||
char *pszWadFile;
|
||||
|
||||
Q_strncpy( wadstring, token, MAX_TOKEN - 2 );
|
||||
wadstring[MAX_TOKEN - 2] = 0;
|
||||
Q_strncpy( wadstring, token, sizeof( wadstring ) - 2 );
|
||||
wadstring[sizeof( wadstring ) - 2] = 0;
|
||||
|
||||
if( !Q_strchr( wadstring, ';' ))
|
||||
Q_strncat( wadstring, ";", sizeof( wadstring ));
|
||||
@@ -1835,7 +1875,7 @@ static void Mod_LoadEntities( model_t *mod, dbspmodel_t *bmod )
|
||||
COM_FixSlashes( pszWadFile );
|
||||
COM_FileBase( pszWadFile, token, sizeof( token ));
|
||||
|
||||
// make sure what wad is really exist
|
||||
// make sure that wad is really exist
|
||||
if( FS_FileExists( va( "%s.wad", token ), false ))
|
||||
{
|
||||
int num = bmod->wadlist.count++;
|
||||
@@ -1995,7 +2035,7 @@ static void Mod_LoadMarkSurfaces( model_t *mod, dbspmodel_t *bmod )
|
||||
for( i = 0; i < bmod->nummarkfaces; i++, in++ )
|
||||
{
|
||||
if( *in < 0 || *in >= mod->numsurfaces )
|
||||
Host_Error( "Mod_LoadMarkFaces: bad surface number in '%s'\n", mod->name );
|
||||
Host_Error( "%s: bad surface number in '%s'\n", __func__, mod->name );
|
||||
out[i] = mod->surfaces + *in;
|
||||
}
|
||||
}
|
||||
@@ -2006,7 +2046,7 @@ static void Mod_LoadMarkSurfaces( model_t *mod, dbspmodel_t *bmod )
|
||||
for( i = 0; i < bmod->nummarkfaces; i++, in++ )
|
||||
{
|
||||
if( *in < 0 || *in >= mod->numsurfaces )
|
||||
Host_Error( "Mod_LoadMarkFaces: bad surface number in '%s'\n", mod->name );
|
||||
Host_Error( "%s: bad surface number in '%s'\n", __func__, mod->name );
|
||||
out[i] = mod->surfaces + *in;
|
||||
}
|
||||
}
|
||||
@@ -2026,22 +2066,218 @@ static qboolean Mod_LooksLikeWaterTexture( const char *name )
|
||||
return false;
|
||||
}
|
||||
|
||||
static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureIndex )
|
||||
static void Mod_TextureReplacementReport( const char *modelname, const char *texname, const char *type, int gl_texturenum, const char *foundpath )
|
||||
{
|
||||
if( host_allow_materials.value != 2.0f )
|
||||
return;
|
||||
|
||||
if( gl_texturenum > 0 ) // found and loaded successfully
|
||||
Con_Printf( "Looking for %s:%s%s tex replacement..." S_GREEN "OK (%s)\n", modelname, texname, type, foundpath );
|
||||
else if( gl_texturenum < 0 ) // not found
|
||||
Con_Printf( "Looking for %s:%s%s tex replacement..." S_YELLOW "MISS (%s)\n", modelname, texname, type, foundpath );
|
||||
else // found but not loaded
|
||||
Con_Printf( "Looking for %s:%s%s tex replacement..." S_RED "FAIL (%s)\n", modelname, texname, type, foundpath );
|
||||
}
|
||||
|
||||
static qboolean Mod_SearchForTextureReplacement( char *out, size_t size, const char *modelname, const char *texname, const char *type )
|
||||
{
|
||||
const char *subdirs[] = { modelname, "common" };
|
||||
int i;
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( subdirs ); i++ )
|
||||
{
|
||||
if( Q_snprintf( out, size, "materials/%s/%s%s.tga", subdirs[i], texname, type ) < 0 )
|
||||
continue; // truncated name
|
||||
|
||||
if( g_fsapi.FileExists( out, false ))
|
||||
return true; // found, load it
|
||||
}
|
||||
|
||||
Mod_TextureReplacementReport( modelname, texname, type, -1, "not found" );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void Mod_InitSkyClouds( model_t *mod, mip_t *mt, texture_t *tx, qboolean custom_palette )
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
rgbdata_t r_temp, *r_sky;
|
||||
uint *trans, *rgba;
|
||||
uint transpix;
|
||||
int r, g, b;
|
||||
int i, j, p;
|
||||
string texname;
|
||||
int solidskyTexture = 0, alphaskyTexture = 0;
|
||||
|
||||
if( !ref.initialized )
|
||||
return;
|
||||
|
||||
if( Mod_AllowMaterials( ))
|
||||
{
|
||||
rgbdata_t *pic;
|
||||
|
||||
if( Mod_SearchForTextureReplacement( texname, sizeof( texname ), mod->name, mt->name, "_solid" ))
|
||||
{
|
||||
pic = FS_LoadImage( texname, NULL, 0 );
|
||||
if( pic )
|
||||
{
|
||||
// need to do rename texture to properly cleanup these textures on reload
|
||||
solidskyTexture = GL_LoadTextureInternal( "solid_sky", pic, TF_NOMIPMAP );
|
||||
Mod_TextureReplacementReport( mod->name, mt->name, "_solid", solidskyTexture, texname );
|
||||
FS_FreeImage( pic );
|
||||
}
|
||||
}
|
||||
|
||||
if( Mod_SearchForTextureReplacement( texname, sizeof( texname ), mod->name, mt->name, "_alpha" ))
|
||||
{
|
||||
pic = FS_LoadImage( texname, NULL, 0 );
|
||||
if( pic )
|
||||
{
|
||||
alphaskyTexture = GL_LoadTextureInternal( "alpha_sky", pic, TF_NOMIPMAP );
|
||||
Mod_TextureReplacementReport( mod->name, mt->name, "_alpha", alphaskyTexture, texname );
|
||||
FS_FreeImage( pic );
|
||||
}
|
||||
}
|
||||
|
||||
if( !solidskyTexture || !alphaskyTexture )
|
||||
{
|
||||
ref.dllFuncs.GL_FreeTexture( solidskyTexture );
|
||||
ref.dllFuncs.GL_FreeTexture( alphaskyTexture );
|
||||
}
|
||||
else goto done; // replacements found, notify the renderer and exit
|
||||
}
|
||||
|
||||
Q_snprintf( texname, sizeof( texname ), "%s%s.mip", ( mt->offsets[0] > 0 ) ? "#" : "", tx->name );
|
||||
|
||||
if( mt->offsets[0] > 0 )
|
||||
{
|
||||
size_t size = sizeof( mip_t ) + (( mt->width * mt->height * 85 ) >> 6 );
|
||||
|
||||
if( custom_palette )
|
||||
size += sizeof( short ) + 768;
|
||||
|
||||
r_sky = FS_LoadImage( texname, (byte *)mt, size );
|
||||
}
|
||||
else
|
||||
{
|
||||
// okay loading it from wad
|
||||
r_sky = FS_LoadImage( texname, NULL, 0 );
|
||||
}
|
||||
|
||||
if( !r_sky || !r_sky->palette || r_sky->type != PF_INDEXED_32 || r_sky->height == 0 )
|
||||
{
|
||||
Con_Printf( S_ERROR "%s: unable to load sky texture %s\n", __func__, tx->name );
|
||||
|
||||
if( r_sky )
|
||||
FS_FreeImage( r_sky );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// make an average value for the back to avoid
|
||||
// a fringe on the top level
|
||||
trans = Mem_Malloc( host.mempool, r_sky->height * r_sky->height * sizeof( *trans ));
|
||||
r = g = b = 0;
|
||||
|
||||
for( i = 0; i < r_sky->width >> 1; i++ )
|
||||
{
|
||||
for( j = 0; j < r_sky->height; j++ )
|
||||
{
|
||||
p = r_sky->buffer[i * r_sky->width + j + r_sky->height];
|
||||
rgba = (uint *)r_sky->palette + p;
|
||||
trans[(i * r_sky->height) + j] = *rgba;
|
||||
r += ((byte *)rgba)[0];
|
||||
g += ((byte *)rgba)[1];
|
||||
b += ((byte *)rgba)[2];
|
||||
}
|
||||
}
|
||||
|
||||
((byte *)&transpix)[0] = r / ( r_sky->height * r_sky->height );
|
||||
((byte *)&transpix)[1] = g / ( r_sky->height * r_sky->height );
|
||||
((byte *)&transpix)[2] = b / ( r_sky->height * r_sky->height );
|
||||
((byte *)&transpix)[3] = 0;
|
||||
|
||||
// build a temporary image
|
||||
r_temp = *r_sky;
|
||||
r_temp.width = r_sky->width >> 1;
|
||||
r_temp.height = r_sky->height;
|
||||
r_temp.type = PF_RGBA_32;
|
||||
r_temp.flags = IMAGE_HAS_COLOR;
|
||||
r_temp.size = r_temp.width * r_temp.height * 4;
|
||||
r_temp.buffer = (byte *)trans;
|
||||
r_temp.palette = NULL;
|
||||
|
||||
// load it in
|
||||
solidskyTexture = GL_LoadTextureInternal( "solid_sky", &r_temp, TF_NOMIPMAP );
|
||||
|
||||
for( i = 0; i < r_sky->width >> 1; i++ )
|
||||
{
|
||||
for( j = 0; j < r_sky->height; j++ )
|
||||
{
|
||||
p = r_sky->buffer[i * r_sky->width + j];
|
||||
|
||||
if( p == 0 )
|
||||
{
|
||||
trans[(i * r_sky->height) + j] = transpix;
|
||||
}
|
||||
else
|
||||
{
|
||||
rgba = (uint *)r_sky->palette + p;
|
||||
trans[(i * r_sky->height) + j] = *rgba;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r_temp.flags = IMAGE_HAS_COLOR|IMAGE_HAS_ALPHA;
|
||||
|
||||
// load it in
|
||||
alphaskyTexture = GL_LoadTextureInternal( "alpha_sky", &r_temp, TF_NOMIPMAP );
|
||||
|
||||
// clean up
|
||||
FS_FreeImage( r_sky );
|
||||
Mem_Free( trans );
|
||||
|
||||
if( !solidskyTexture || !alphaskyTexture )
|
||||
{
|
||||
ref.dllFuncs.GL_FreeTexture( solidskyTexture );
|
||||
ref.dllFuncs.GL_FreeTexture( alphaskyTexture );
|
||||
return;
|
||||
}
|
||||
|
||||
done:
|
||||
// notify the renderer
|
||||
ref.dllFuncs.R_SetSkyCloudsTextures( solidskyTexture, alphaskyTexture );
|
||||
|
||||
if( solidskyTexture && alphaskyTexture )
|
||||
SetBits( world.flags, FWORLD_SKYSPHERE );
|
||||
#endif // !XASH_DEDICATED
|
||||
}
|
||||
|
||||
static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureIndex )
|
||||
{
|
||||
texture_t *texture = NULL;
|
||||
mip_t *mipTex = NULL;
|
||||
qboolean usesCustomPalette = false;
|
||||
uint32_t txFlags = 0;
|
||||
char texpath[MAX_VA_STRING];
|
||||
char safemtname[16]; // only for external textures
|
||||
qboolean load_external = false;
|
||||
|
||||
// Don't load texture data on dedicated server, as there is no renderer.
|
||||
// don't load texture data on dedicated server, as there is no renderer.
|
||||
// but count the wadusage for automatic precache
|
||||
//
|
||||
// FIXME: for ENGINE_IMPROVED_LINETRACE we need to load textures on server too
|
||||
// but there is no facility for this yet
|
||||
if( Host_IsDedicated( ))
|
||||
return;
|
||||
|
||||
texture = mod->textures[textureIndex];
|
||||
mipTex = Mod_GetMipTexForTexture( bmod, textureIndex );
|
||||
usesCustomPalette = Mod_CalcMipTexUsesCustomPalette( mod, bmod, textureIndex );
|
||||
|
||||
// check for multi-layered sky texture (quake1 specific)
|
||||
if( bmod->isworld && Q_strncmp( mipTex->name, "sky", 3 ) == 0 && ( mipTex->width / mipTex->height ) == 2 )
|
||||
{
|
||||
Mod_InitSkyClouds( mod, mipTex, texture, usesCustomPalette ); // load quake sky
|
||||
return;
|
||||
}
|
||||
|
||||
if( FBitSet( host.features, ENGINE_IMPROVED_LINETRACE ) && mipTex->name[0] == '{' )
|
||||
SetBits( txFlags, TF_KEEP_SOURCE ); // Paranoia2 texture alpha-tracing
|
||||
@@ -2050,37 +2286,47 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
|
||||
if( Mod_LooksLikeWaterTexture( mipTex->name ))
|
||||
SetBits( txFlags, TF_KEEP_SOURCE | TF_EXPAND_SOURCE );
|
||||
|
||||
usesCustomPalette = Mod_CalcMipTexUsesCustomPalette( mod, bmod, textureIndex );
|
||||
// Texture loading order:
|
||||
// 1. HQ from disk
|
||||
// 2. From WAD
|
||||
// 3. Internal from map
|
||||
|
||||
// check for multi-layered sky texture (quake1 specific)
|
||||
if( bmod->isworld && Q_strncmp( mipTex->name, "sky", 3 ) == 0 && ( mipTex->width / mipTex->height ) == 2 )
|
||||
texture->gl_texturenum = 0;
|
||||
Q_strncpy( safemtname, mipTex->name, sizeof( safemtname ));
|
||||
if( safemtname[0] == '*' )
|
||||
safemtname[0] = '!'; // replace unexpected symbol
|
||||
|
||||
if( Mod_AllowMaterials( ))
|
||||
{
|
||||
ref.dllFuncs.R_InitSkyClouds( mipTex, texture, usesCustomPalette ); // load quake sky
|
||||
|
||||
if( R_GetBuiltinTexture( REF_SOLIDSKY_TEXTURE ) && R_GetBuiltinTexture( REF_ALPHASKY_TEXTURE ))
|
||||
SetBits( world.flags, FWORLD_SKYSPHERE );
|
||||
|
||||
// No texture to load in this case, so just exit.
|
||||
return;
|
||||
#if !XASH_DEDICATED
|
||||
if( Mod_SearchForTextureReplacement( texpath, sizeof( texpath ), mod->name, safemtname, "" ))
|
||||
{
|
||||
texture->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texpath, NULL, 0, txFlags );
|
||||
load_external = texture->gl_texturenum != 0;
|
||||
Mod_TextureReplacementReport( mod->name, safemtname, "", texture->gl_texturenum, texpath );
|
||||
}
|
||||
#endif // !XASH_DEDICATED
|
||||
}
|
||||
|
||||
// Texture loading order:
|
||||
// 1. From WAD
|
||||
// 2. Internal from map
|
||||
|
||||
// Try WAD texture (force while r_wadtextures is 1)
|
||||
if(( r_wadtextures.value && bmod->wadlist.count > 0 ) || mipTex->offsets[0] <= 0 )
|
||||
if( !texture->gl_texturenum && (( r_wadtextures.value && bmod->wadlist.count > 0 ) || mipTex->offsets[0] <= 0 ))
|
||||
{
|
||||
char texpath[MAX_VA_STRING];
|
||||
int wadIndex = Mod_FindTextureInWadList( &bmod->wadlist, mipTex->name, texpath, sizeof( texpath ));
|
||||
|
||||
if( wadIndex >= 0 )
|
||||
{
|
||||
texture->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texpath, NULL, 0, txFlags );
|
||||
#if !XASH_DEDICATED
|
||||
if( !Host_IsDedicated( ))
|
||||
texture->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texpath, NULL, 0, txFlags );
|
||||
#endif // !XASH_DEDICATED
|
||||
bmod->wadlist.wadusage[wadIndex]++;
|
||||
}
|
||||
}
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
if( Host_IsDedicated( ))
|
||||
return;
|
||||
|
||||
// WAD failed, so use internal texture (if present)
|
||||
if( mipTex->offsets[0] > 0 && texture->gl_texturenum == 0 )
|
||||
{
|
||||
@@ -2099,9 +2345,20 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
|
||||
}
|
||||
|
||||
// Check for luma texture
|
||||
if( FBitSet( REF_GET_PARM( PARM_TEX_FLAGS, texture->gl_texturenum ), TF_HAS_LUMA ))
|
||||
texture->fb_texturenum = 0;
|
||||
if( load_external ) // external textures will not have TF_HAS_LUMA flag because it set only from WAD images loader
|
||||
{
|
||||
if( Mod_SearchForTextureReplacement( texpath, sizeof( texpath ), mod->name, safemtname, "_luma" ))
|
||||
{
|
||||
texture->fb_texturenum = ref.dllFuncs.GL_LoadTexture( texpath, NULL, 0, TF_MAKELUMA );
|
||||
Mod_TextureReplacementReport( mod->name, safemtname, "_luma", texture->fb_texturenum, texpath );
|
||||
}
|
||||
}
|
||||
|
||||
if( FBitSet( REF_GET_PARM( PARM_TEX_FLAGS, texture->gl_texturenum ), TF_HAS_LUMA ) && !texture->fb_texturenum )
|
||||
{
|
||||
char texName[64];
|
||||
|
||||
Q_snprintf( texName, sizeof( texName ), "#%s:%s_luma.mip", loadstat.name, mipTex->name );
|
||||
|
||||
if( mipTex->offsets[0] > 0 )
|
||||
@@ -2263,7 +2520,8 @@ static void Mod_SequenceAnimatedTexture( model_t *mod, int baseTextureIndex )
|
||||
|
||||
if( !tex )
|
||||
{
|
||||
Con_Printf( S_ERROR "Mod_SequenceAnimatedTexture: missing frame %i of animated texture \"%s\"\n",
|
||||
Con_Printf( S_ERROR "%s: missing frame %i of animated texture \"%s\"\n",
|
||||
__func__,
|
||||
candidateIndex,
|
||||
baseTexture->name );
|
||||
|
||||
@@ -2287,7 +2545,8 @@ static void Mod_SequenceAnimatedTexture( model_t *mod, int baseTextureIndex )
|
||||
|
||||
if( !tex )
|
||||
{
|
||||
Con_Printf( S_ERROR "Mod_SequenceAnimatedTexture: missing alternate frame %i of animated texture \"%s\"\n",
|
||||
Con_Printf( S_ERROR "%s: missing alternate frame %i of animated texture \"%s\"\n",
|
||||
__func__,
|
||||
candidateIndex,
|
||||
baseTexture->name );
|
||||
|
||||
@@ -2326,8 +2585,8 @@ static void Mod_LoadTextures( model_t *mod, dbspmodel_t *bmod )
|
||||
// release old sky layers first
|
||||
if( !Host_IsDedicated() && bmod->isworld )
|
||||
{
|
||||
ref.dllFuncs.GL_FreeTexture( R_GetBuiltinTexture( REF_ALPHASKY_TEXTURE ));
|
||||
ref.dllFuncs.GL_FreeTexture( R_GetBuiltinTexture( REF_SOLIDSKY_TEXTURE ));
|
||||
ref.dllFuncs.GL_FreeTexture( R_GetBuiltinTexture( "alpha_sky" ));
|
||||
ref.dllFuncs.GL_FreeTexture( R_GetBuiltinTexture( "solid_sky" ));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2702,13 +2961,160 @@ static void Mod_LoadLeafs( model_t *mod, dbspmodel_t *bmod )
|
||||
}
|
||||
|
||||
if( bmod->isworld && mod->leafs[0].contents != CONTENTS_SOLID )
|
||||
Host_Error( "Mod_LoadLeafs: Map %s has leaf 0 is not CONTENTS_SOLID\n", mod->name );
|
||||
Host_Error( "%s: Map %s has leaf 0 is not CONTENTS_SOLID\n", __func__, mod->name );
|
||||
|
||||
// do some final things for world
|
||||
if( bmod->isworld && Mod_CheckWaterAlphaSupport( mod, bmod ))
|
||||
SetBits( world.flags, FWORLD_WATERALPHA );
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
Mod_CalcPHS
|
||||
|
||||
To be called while loading world for multiplayer game server
|
||||
===========
|
||||
*/
|
||||
static void Mod_CalcPHS( model_t *mod )
|
||||
{
|
||||
const qboolean vis_stats = host_developer.value >= DEV_EXTENDED;
|
||||
const size_t rowbytes = ALIGN( world.visbytes, 4 ); // force align rows by 32-bit boundary
|
||||
const size_t count = mod->numleafs + 1; // same as mod->submodels[0].visleafs + 1
|
||||
double t1;
|
||||
double t2;
|
||||
size_t total_compressed_size = 0;
|
||||
size_t hcount = 0;
|
||||
size_t vcount = 0;
|
||||
int i;
|
||||
byte *uncompressed_pvs;
|
||||
byte *uncompressed_phs;
|
||||
|
||||
if( !mod->visdata )
|
||||
return;
|
||||
|
||||
#if defined( HAVE_OPENMP )
|
||||
Con_Reportf( "Building PHS in %d threads...\n", omp_get_max_threads( ));
|
||||
#else
|
||||
Con_Reportf( "Building PHS...\n" );
|
||||
#endif
|
||||
|
||||
uncompressed_pvs = Mem_Calloc( mod->mempool, rowbytes * count * 2 );
|
||||
uncompressed_phs = &uncompressed_pvs[rowbytes * count];
|
||||
|
||||
world.phsofs = Mem_Calloc( mod->mempool, sizeof( size_t ) * count );
|
||||
world.compressed_phs = NULL;
|
||||
|
||||
t1 = Platform_DoubleTime();
|
||||
|
||||
#pragma omp parallel
|
||||
{
|
||||
// uncompress pvs first
|
||||
#pragma omp for schedule( static, 256 ) // there might be thousands of leafs, split by 256
|
||||
for( i = 0; i < count; i++ )
|
||||
Mod_DecompressPVSTo( &uncompressed_pvs[rowbytes * i], mod->leafs[i].compressed_vis, world.visbytes );
|
||||
|
||||
// now create phs
|
||||
#pragma omp for schedule( static, 256 ) reduction( + : vcount, hcount )
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
const byte *scan = &uncompressed_pvs[rowbytes * i];
|
||||
byte *dst = &uncompressed_phs[rowbytes * i]; // rowbytes, not rowwords!
|
||||
size_t j;
|
||||
|
||||
memcpy( dst, scan, rowbytes );
|
||||
|
||||
for( j = 0; j < rowbytes; j++ )
|
||||
{
|
||||
size_t k;
|
||||
uint bitbyte = scan[j];
|
||||
|
||||
if( bitbyte == 0 )
|
||||
continue;
|
||||
|
||||
for( k = 0; k < 8; k++ )
|
||||
{
|
||||
size_t index;
|
||||
|
||||
if( !FBitSet( bitbyte, BIT( k )))
|
||||
continue;
|
||||
|
||||
// OR this pvs row into the phs
|
||||
// +1 because pvs is 1 based
|
||||
index = (( j * 8 ) + k + 1 );
|
||||
if( index >= count )
|
||||
continue;
|
||||
|
||||
Q_memor( dst, &uncompressed_pvs[rowbytes * index], rowbytes );
|
||||
}
|
||||
}
|
||||
|
||||
if( vis_stats && i != 0 )
|
||||
{
|
||||
size_t j;
|
||||
|
||||
for( j = 0; j < count; j++ )
|
||||
{
|
||||
if( CHECKVISBIT( scan, j ))
|
||||
vcount++;
|
||||
|
||||
if( CHECKVISBIT( dst, j ))
|
||||
hcount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// since I can't predict at which spot compressed array
|
||||
// should be put, this loop is single threaded
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
const byte *src = &uncompressed_phs[rowbytes * i];
|
||||
byte temp_compressed_row[(MAX_MAP_LEAFS+1)/4]; // compression for this row might be ineffective
|
||||
size_t compressed_size;
|
||||
|
||||
compressed_size = Mod_CompressPVS( temp_compressed_row, src, rowbytes );
|
||||
|
||||
world.compressed_phs = Mem_Realloc( mod->mempool, world.compressed_phs, total_compressed_size + compressed_size );
|
||||
memcpy( &world.compressed_phs[total_compressed_size], temp_compressed_row, compressed_size );
|
||||
world.phsofs[i] = total_compressed_size;
|
||||
|
||||
total_compressed_size += compressed_size;
|
||||
}
|
||||
|
||||
t2 = Platform_DoubleTime();
|
||||
|
||||
if( vis_stats )
|
||||
Con_Reportf( "Average leaves visible / audible / total: %zu / %zu / %zu\n", vcount / count, hcount / count, count );
|
||||
Con_Reportf( "Uncompressed PHS size: %s\n", Q_memprint( rowbytes * count ));
|
||||
Con_Reportf( "Compressed PHS size: %s\n", Q_memprint( total_compressed_size + sizeof( *world.phsofs ) * count ));
|
||||
Con_Reportf( "PHS building time: %.2f ms\n", ( t2 - t1 ) * 1000.0f );
|
||||
|
||||
// TODO: rewrite this into a unit test
|
||||
// NOTE: how to get GoldSrc fat PHS and PVS data
|
||||
// start a multiplayer server with some op4_bootcamp (for example)
|
||||
// attach to process with GDB:
|
||||
// (gdb) p gPAS[0]
|
||||
// $0 = (byte *) ...
|
||||
// (gdb) p gPAS[gPVSRowBytes * (cl.worldmodel->numleafs + 1)]
|
||||
// $1 = (byte *) ...
|
||||
// (gdb) dump binary memory op4_bootcamp_gs.phs $0 $1
|
||||
// (gdb) p gPVS[0]
|
||||
// $2 = (byte *) ...
|
||||
// (gdb) p gPVS[gPVSRowBytes * (cl.worldmodel->numleafs + 1)]
|
||||
// $3 = (byte *) ...
|
||||
// (gdb) dump binary memory op4_bootcamp_gs.pvs $0 $1
|
||||
//
|
||||
// NOTE: as of writing, uncompressed PVS and PHS data do match! hooray!
|
||||
//
|
||||
// FS_WriteFile( "op4_bootcamp.pvs", uncompressed_pvs, rowbytes * count );
|
||||
// FS_WriteFile( "op4_bootcamp.phs", uncompressed_phs, rowbytes * count );
|
||||
|
||||
// release uncompressed data
|
||||
Mem_Free( uncompressed_pvs );
|
||||
|
||||
// TODO: cache the PHS somewhere, it might take a long time on giant maps
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_LoadClipnodes
|
||||
@@ -2776,7 +3182,7 @@ static void Mod_LoadLightVecs( model_t *mod, dbspmodel_t *bmod )
|
||||
if( bmod->deluxdatasize != bmod->lightdatasize )
|
||||
{
|
||||
if( bmod->deluxdatasize > 0 )
|
||||
Con_Printf( S_ERROR "Mod_LoadLightVecs: has mismatched size (%zu should be %zu)\n", bmod->deluxdatasize, bmod->lightdatasize );
|
||||
Con_Printf( S_ERROR "%s: has mismatched size (%zu should be %zu)\n", __func__, bmod->deluxdatasize, bmod->lightdatasize );
|
||||
else Mod_LoadDeluxemap( mod, bmod ); // old method
|
||||
return;
|
||||
}
|
||||
@@ -2795,7 +3201,7 @@ static void Mod_LoadShadowmap( model_t *mod, dbspmodel_t *bmod )
|
||||
if( bmod->shadowdatasize != ( bmod->lightdatasize / 3 ))
|
||||
{
|
||||
if( bmod->shadowdatasize > 0 )
|
||||
Con_Printf( S_ERROR "Mod_LoadShadowmap: has mismatched size (%zu should be %zu)\n", bmod->shadowdatasize, bmod->lightdatasize / 3 );
|
||||
Con_Printf( S_ERROR "%s: has mismatched size (%zu should be %zu)\n", __func__, bmod->shadowdatasize, bmod->lightdatasize / 3 );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2837,7 +3243,7 @@ static void Mod_LoadLighting( model_t *mod, dbspmodel_t *bmod )
|
||||
SetBits( mod->flags, MODEL_COLORED_LIGHTING );
|
||||
break;
|
||||
default:
|
||||
Host_Error( "Mod_LoadLighting: bad lightmap sample count %i\n", bmod->lightmap_samples );
|
||||
Host_Error( "%s: bad lightmap sample count %i\n", __func__, bmod->lightmap_samples );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2906,6 +3312,7 @@ static qboolean Mod_LoadBmodelLumps( model_t *mod, const byte *mod_base, qboolea
|
||||
char wadvalue[2048];
|
||||
size_t len = 0;
|
||||
int i, ret, flags = 0;
|
||||
qboolean wadlist_warn = false;
|
||||
|
||||
// always reset the intermediate struct
|
||||
memset( bmod, 0, sizeof( dbspmodel_t ));
|
||||
@@ -3000,23 +3407,37 @@ static qboolean Mod_LoadBmodelLumps( model_t *mod, const byte *mod_base, qboolea
|
||||
{
|
||||
world.version = bmod->version;
|
||||
#if !XASH_DEDICATED
|
||||
Mod_InitDebugHulls( mod ); // FIXME: build hulls for separate bmodels (shells, medkits etc)
|
||||
world.deluxedata = bmod->deluxedata_out; // deluxemap data pointer
|
||||
world.shadowdata = bmod->shadowdata_out; // occlusion data pointer
|
||||
#endif // XASH_DEDICATED
|
||||
|
||||
if( SV_Active() && svs.maxclients > 1 )
|
||||
Mod_CalcPHS( mod );
|
||||
}
|
||||
|
||||
for( i = 0; i < bmod->wadlist.count; i++ )
|
||||
{
|
||||
string wadname;
|
||||
|
||||
if( !bmod->wadlist.wadusage[i] )
|
||||
continue;
|
||||
ret = Q_snprintf( &wadvalue[len], sizeof( wadvalue ), "%s.wad; ", bmod->wadlist.wadnames[i] );
|
||||
if( ret == -1 )
|
||||
|
||||
Q_snprintf( wadname, sizeof( wadname ), "%s.wad", bmod->wadlist.wadnames[i] );
|
||||
|
||||
// a1ba: automatically precache used wad files so client will download it
|
||||
if( SV_Active( ))
|
||||
SV_GenericIndex( wadname );
|
||||
|
||||
if( !wadlist_warn )
|
||||
{
|
||||
Con_DPrintf( S_WARN "Too many wad files for output!\n" );
|
||||
break;
|
||||
ret = Q_snprintf( &wadvalue[len], sizeof( wadvalue ), "%s; ", wadname );
|
||||
if( ret == -1 )
|
||||
{
|
||||
Con_DPrintf( S_WARN "Too many wad files for output!\n" );
|
||||
wadlist_warn = true;
|
||||
}
|
||||
len += ret;
|
||||
}
|
||||
len += ret;
|
||||
}
|
||||
|
||||
if( COM_CheckString( wadvalue ))
|
||||
@@ -3141,13 +3562,13 @@ qboolean Mod_TestBmodelLumps( file_t *f, const char *name, const byte *mod_base,
|
||||
if( loadstat.numerrors )
|
||||
{
|
||||
if( !FBitSet( flags, LUMP_SILENT ))
|
||||
Con_Printf( "Mod_LoadWorld: %i error(s), %i warning(s)\n", loadstat.numerrors, loadstat.numwarnings );
|
||||
Con_Printf( "%s: %i error(s), %i warning(s)\n", __func__, loadstat.numerrors, loadstat.numwarnings );
|
||||
return false; // there were errors, we can't load this map
|
||||
}
|
||||
else if( loadstat.numwarnings )
|
||||
{
|
||||
if( !FBitSet( flags, LUMP_SILENT ))
|
||||
Con_Printf( "Mod_LoadWorld: %i warning(s)\n", loadstat.numwarnings );
|
||||
Con_Printf( "%s: %i warning(s)\n", __func__, loadstat.numwarnings );
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -33,7 +33,7 @@ GNU General Public License for more details.
|
||||
|
||||
#define REFPVS_RADIUS 2.0f // radius for rendering
|
||||
#define FATPVS_RADIUS 8.0f // FatPVS use radius smaller than the FatPHS
|
||||
#define FATPHS_RADIUS 16.0f
|
||||
#define FATPHS_RADIUS 8.0f // see SV_AddToFatPAS in GoldSrc
|
||||
|
||||
#define WORLD_INDEX (1) // world index is always 1
|
||||
|
||||
@@ -115,6 +115,10 @@ typedef struct world_static_s
|
||||
int max_recursion;
|
||||
|
||||
uint32_t version; // BSP version
|
||||
|
||||
// Potentially Hearable Set
|
||||
byte *compressed_phs;
|
||||
size_t *phsofs;
|
||||
} world_static_t;
|
||||
|
||||
#ifndef REF_DLL
|
||||
@@ -151,7 +155,7 @@ void Mod_FreeUnused( void );
|
||||
void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *loaded );
|
||||
qboolean Mod_TestBmodelLumps( file_t *f, const char *name, const byte *mod_base, qboolean silent, dlump_t *entities );
|
||||
qboolean Mod_HeadnodeVisible( mnode_t *node, const byte *visbits, int *lastleaf );
|
||||
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis );
|
||||
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis, qboolean false );
|
||||
qboolean Mod_BoxVisible( const vec3_t mins, const vec3_t maxs, const byte *visbits );
|
||||
int Mod_CheckLump( const char *filename, const int lump, int *lumpsize );
|
||||
int Mod_ReadLump( const char *filename, const int lump, void **lumpdata, int *lumpsize );
|
||||
|
||||
@@ -436,8 +436,8 @@ void *R_StudioGetAnim( studiohdr_t *m_pStudioHeader, model_t *m_pSubModel, mstud
|
||||
Q_snprintf( filepath, sizeof( filepath ), "%s/%s%i%i.mdl", modelpath, modelname, pseqdesc->seqgroup / 10, pseqdesc->seqgroup % 10 );
|
||||
|
||||
buf = FS_LoadFile( filepath, &filesize, false );
|
||||
if( !buf || !filesize ) Host_Error( "StudioGetAnim: can't load %s\n", filepath );
|
||||
if( IDSEQGRPHEADER != *(uint *)buf ) Host_Error( "StudioGetAnim: %s is corrupted\n", filepath );
|
||||
if( !buf || !filesize ) Host_Error( "%s: can't load %s\n", __func__, filepath );
|
||||
if( IDSEQGRPHEADER != *(uint *)buf ) Host_Error( "%s: %s is corrupted\n", __func__, filepath );
|
||||
|
||||
Con_Printf( "loading: %s\n", filepath );
|
||||
|
||||
@@ -482,7 +482,7 @@ static void SV_StudioSetupBones( model_t *pModel, float frame, int sequence, con
|
||||
{
|
||||
// only show warn if sequence that out of range was specified intentionally
|
||||
if( sequence > mod_studiohdr->numseq )
|
||||
Con_Reportf( S_WARN "SV_StudioSetupBones: sequence %i/%i out of range for model %s\n", sequence, mod_studiohdr->numseq, pModel->name );
|
||||
Con_Reportf( S_WARN "%s: sequence %i/%i out of range for model %s\n", __func__, sequence, mod_studiohdr->numseq, pModel->name );
|
||||
sequence = 0;
|
||||
}
|
||||
|
||||
@@ -780,7 +780,7 @@ extract texture filename from modelname
|
||||
*/
|
||||
const char *Mod_StudioTexName( const char *modname )
|
||||
{
|
||||
static char texname[MAX_QPATH];
|
||||
static char texname[MAX_QPATH+1];
|
||||
|
||||
Q_strncpy( texname, modname, sizeof( texname ));
|
||||
COM_StripExtension( texname );
|
||||
@@ -841,6 +841,22 @@ static studiohdr_t *R_StudioLoadHeader( model_t *mod, const void *buffer )
|
||||
return (studiohdr_t *)buffer;
|
||||
}
|
||||
|
||||
static studiohdr_t *Mod_MaybeTruncateStudioTextureData( model_t *mod )
|
||||
{
|
||||
#if XASH_LOW_MEMORY
|
||||
studiohdr_t *phdr = (studiohdr_t *)mod->cache.data;
|
||||
|
||||
mod->cache.data = Mem_Realloc( mod->mempool, mod->cache.data, phdr->texturedataindex );
|
||||
phdr = (studiohdr_t *)mod->cache.data; // get the new pointer on studiohdr
|
||||
phdr->length = phdr->texturedataindex; // update model size
|
||||
|
||||
return phdr;
|
||||
#else
|
||||
// NOTE: some mods potentially might require full studio model data
|
||||
return (studiohdr_t *)mod->cache.data;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_LoadStudioModel
|
||||
@@ -850,6 +866,7 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
|
||||
{
|
||||
char poolname[MAX_VA_STRING];
|
||||
studiohdr_t *phdr;
|
||||
qboolean textures_loaded = false;
|
||||
|
||||
Q_snprintf( poolname, sizeof( poolname ), "^2%s^7", mod->name );
|
||||
|
||||
@@ -858,75 +875,67 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
|
||||
mod->type = mod_studio;
|
||||
|
||||
phdr = R_StudioLoadHeader( mod, buffer );
|
||||
if( !phdr ) return; // bad model
|
||||
if( !phdr )
|
||||
return; // bad model
|
||||
|
||||
if( !Host_IsDedicated() )
|
||||
#if !XASH_DEDICATED
|
||||
if( !Host_IsDedicated( ) && phdr->numtextures == 0 )
|
||||
{
|
||||
if( phdr->numtextures == 0 )
|
||||
studiohdr_t *thdr;
|
||||
void *buffer2;
|
||||
|
||||
buffer2 = FS_LoadFile( Mod_StudioTexName( mod->name ), NULL, false );
|
||||
thdr = R_StudioLoadHeader( mod, buffer2 );
|
||||
|
||||
if( thdr != NULL )
|
||||
{
|
||||
studiohdr_t *thdr;
|
||||
byte *in, *out;
|
||||
void *buffer2 = NULL;
|
||||
size_t size1, size2;
|
||||
byte *in, *out;
|
||||
size_t size1, size2;
|
||||
|
||||
buffer2 = FS_LoadFile( Mod_StudioTexName( mod->name ), NULL, false );
|
||||
thdr = R_StudioLoadHeader( mod, buffer2 );
|
||||
// TODO: Mod_StudioLoadTextures will crash if passed a merged studio model!
|
||||
ref.dllFuncs.Mod_StudioLoadTextures( mod, thdr );
|
||||
textures_loaded = true;
|
||||
|
||||
if( !thdr )
|
||||
{
|
||||
Con_Printf( S_WARN "Mod_LoadStudioModel: %s missing textures file\n", mod->name );
|
||||
if( buffer2 ) Mem_Free( buffer2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
ref.dllFuncs.Mod_StudioLoadTextures( mod, thdr );
|
||||
#endif
|
||||
|
||||
// give space for textures and skinrefs
|
||||
size1 = thdr->numtextures * sizeof( mstudiotexture_t );
|
||||
size2 = thdr->numskinfamilies * thdr->numskinref * sizeof( short );
|
||||
mod->cache.data = Mem_Calloc( mod->mempool, phdr->length + size1 + size2 );
|
||||
memcpy( mod->cache.data, buffer, phdr->length ); // copy main mdl buffer
|
||||
phdr = (studiohdr_t *)mod->cache.data; // get the new pointer on studiohdr
|
||||
phdr->numskinfamilies = thdr->numskinfamilies;
|
||||
phdr->numtextures = thdr->numtextures;
|
||||
phdr->numskinref = thdr->numskinref;
|
||||
phdr->textureindex = phdr->length;
|
||||
phdr->skinindex = phdr->textureindex + size1;
|
||||
|
||||
in = (byte *)thdr + thdr->textureindex;
|
||||
out = (byte *)phdr + phdr->textureindex;
|
||||
memcpy( out, in, size1 + size2 ); // copy textures + skinrefs
|
||||
phdr->length += size1 + size2;
|
||||
Mem_Free( buffer2 ); // release T.mdl
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: don't modify source buffer because it's used for CRC computing
|
||||
mod->cache.data = Mem_Calloc( mod->mempool, phdr->length );
|
||||
memcpy( mod->cache.data, buffer, phdr->length );
|
||||
// give space for textures and skinrefs
|
||||
size1 = thdr->numtextures * sizeof( mstudiotexture_t );
|
||||
size2 = thdr->numskinfamilies * thdr->numskinref * sizeof( short );
|
||||
mod->cache.data = Mem_Calloc( mod->mempool, phdr->length + size1 + size2 );
|
||||
memcpy( mod->cache.data, buffer, phdr->length ); // copy main mdl buffer
|
||||
phdr = (studiohdr_t *)mod->cache.data; // get the new pointer on studiohdr
|
||||
#if !XASH_DEDICATED
|
||||
ref.dllFuncs.Mod_StudioLoadTextures( mod, phdr );
|
||||
#endif
|
||||
phdr->numskinfamilies = thdr->numskinfamilies;
|
||||
phdr->numtextures = thdr->numtextures;
|
||||
phdr->numskinref = thdr->numskinref;
|
||||
phdr->textureindex = phdr->length;
|
||||
phdr->skinindex = phdr->textureindex + size1;
|
||||
|
||||
// NOTE: we wan't keep raw textures in memory. just cutoff model pointer above texture base
|
||||
mod->cache.data = Mem_Realloc( mod->mempool, mod->cache.data, phdr->texturedataindex );
|
||||
phdr = (studiohdr_t *)mod->cache.data; // get the new pointer on studiohdr
|
||||
phdr->length = phdr->texturedataindex; // update model size
|
||||
in = (byte *)thdr + thdr->textureindex;
|
||||
out = (byte *)phdr + phdr->textureindex;
|
||||
memcpy( out, in, size1 + size2 ); // copy textures + skinrefs
|
||||
phdr->length += size1 + size2;
|
||||
}
|
||||
else Con_Printf( S_WARN "%s: %s missing textures file\n", __func__, mod->name );
|
||||
|
||||
if( buffer2 )
|
||||
Mem_Free( buffer2 ); // release T.mdl
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if( !textures_loaded )
|
||||
{
|
||||
// just copy model into memory
|
||||
// NOTE: don't modify source buffer because it's used for CRC computing
|
||||
mod->cache.data = Mem_Calloc( mod->mempool, phdr->length );
|
||||
memcpy( mod->cache.data, buffer, phdr->length );
|
||||
|
||||
phdr = mod->cache.data;
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
if( !Host_IsDedicated( ))
|
||||
ref.dllFuncs.Mod_StudioLoadTextures( mod, phdr );
|
||||
#endif
|
||||
}
|
||||
|
||||
// NOTE: we may not want to keep raw textures in memory. just cutoff model pointer above texture base
|
||||
phdr = Mod_MaybeTruncateStudioTextureData( mod );
|
||||
|
||||
// setup bounding box
|
||||
if( !VectorCompare( vec3_origin, phdr->bbmin ))
|
||||
{
|
||||
@@ -985,7 +994,7 @@ void Mod_InitStudioAPI( void )
|
||||
pBlendIface = (STUDIOAPI)COM_GetProcAddress( svgame.hInstance, "Server_GetBlendingInterface" );
|
||||
if( pBlendIface && pBlendIface( SV_BLENDING_INTERFACE_VERSION, &pBlendAPI, &gStudioAPI, &studio_transform, &studio_bones ))
|
||||
{
|
||||
Con_Reportf( "SV_LoadProgs: ^2initailized Server Blending interface ^7ver. %i\n", SV_BLENDING_INTERFACE_VERSION );
|
||||
Con_Reportf( "%s: ^2initailized Server Blending interface ^7ver. %i\n", __func__, SV_BLENDING_INTERFACE_VERSION );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +114,11 @@ void Mod_FreeModel( model_t *mod )
|
||||
world.version = 0;
|
||||
world.shadowdata = NULL;
|
||||
world.deluxedata = NULL;
|
||||
|
||||
// data already freed by Mem_FreePool above
|
||||
world.hull_models = NULL;
|
||||
world.compressed_phs = NULL;
|
||||
world.phsofs = NULL;
|
||||
}
|
||||
|
||||
memset( mod, 0, sizeof( *mod ));
|
||||
|
||||
@@ -119,6 +119,27 @@ const char *svc_goldsrc_strings[svc_lastmsg+1] =
|
||||
[svc_goldsrc_sendcvarvalue2] = "svc_goldsrc_sendcvarvalue2",
|
||||
};
|
||||
|
||||
const char *svc_quake_strings[svc_lastmsg+1] =
|
||||
{
|
||||
[svc_updatestat] = "svc_quake_updatestat",
|
||||
[svc_version] = "svc_quake_version",
|
||||
[svc_updatename] = "svc_quake_updatename",
|
||||
[svc_updatefrags] = "svc_quake_updatefrags",
|
||||
[svc_stopsound] = "svc_quake_stopsound",
|
||||
[svc_updatecolors] = "svc_quake_updatecolors",
|
||||
[svc_damage] = "svc_quake_damage",
|
||||
[svc_spawnbinary] = "svc_quake_spawnbinary",
|
||||
[svc_killedmonster] = "svc_quake_killedmonster",
|
||||
[svc_foundsecret] = "svc_quake_foundsecret",
|
||||
[svc_spawnstaticsound] = "svc_quake_spawnstaticsound",
|
||||
[svc_sellscreen] = "svc_quake_sellscreen",
|
||||
[svc_showlmp] = "svc_quake_showlmp",
|
||||
[svc_hidelmp] = "svc_quake_hidelmp",
|
||||
[svc_skybox] = "svc_quake_skybox",
|
||||
[svc_skyboxsize] = "svc_quake_skyboxsize",
|
||||
[svc_fog] = "svc_quake_fog",
|
||||
};
|
||||
|
||||
void MSG_InitMasks( void )
|
||||
{
|
||||
uint startbit, endbit;
|
||||
|
||||
@@ -174,7 +174,7 @@ void MSG_ExciseBits( sizebuf_t *sb, int startbit, int bitstoremove );
|
||||
|
||||
// Bit-write functions
|
||||
void MSG_WriteOneBit( sizebuf_t *sb, int nValue );
|
||||
void MSG_WriteUBitLong( sizebuf_t *sb, uint curData, int numbits );
|
||||
NO_ASAN void MSG_WriteUBitLong( sizebuf_t *sb, uint curData, int numbits );
|
||||
void MSG_WriteSBitLong( sizebuf_t *sb, int data, int numbits );
|
||||
void MSG_WriteBitLong( sizebuf_t *sb, uint data, int numbits, qboolean bSigned );
|
||||
qboolean MSG_WriteBits( sizebuf_t *sb, const void *pData, int nBits );
|
||||
|
||||
@@ -85,9 +85,9 @@ then a packet only needs to be delivered if there is something in the
|
||||
unacknowledged reliable
|
||||
*/
|
||||
CVAR_DEFINE_AUTO( net_showpackets, "0", 0, "show network packets" );
|
||||
CVAR_DEFINE_AUTO( net_chokeloop, "0", 0, "apply bandwidth choke to loopback packets" );
|
||||
CVAR_DEFINE_AUTO( net_showdrop, "0", 0, "show packets that are dropped" );
|
||||
CVAR_DEFINE_AUTO( net_qport, "0", FCVAR_READ_ONLY, "current quake netport" );
|
||||
static CVAR_DEFINE_AUTO( net_chokeloop, "0", 0, "apply bandwidth choke to loopback packets" );
|
||||
static CVAR_DEFINE_AUTO( net_showdrop, "0", 0, "show packets that are dropped" );
|
||||
static CVAR_DEFINE_AUTO( net_qport, "0", FCVAR_READ_ONLY, "current quake netport" );
|
||||
|
||||
int net_drop;
|
||||
netadr_t net_from;
|
||||
@@ -131,7 +131,7 @@ qboolean NetSplit_GetLong( netsplit_t *ns, netadr_t *from, byte *data, size_t *l
|
||||
LittleLongSW(packet->part);
|
||||
|
||||
p = &ns->packets[packet->id & NETSPLIT_BACKUP_MASK];
|
||||
// Con_Reportf( S_NOTE "NetSplit_GetLong: packet from %s, id %d, index %d length %d\n", NET_AdrToString( *from ), (int)packet->id, (int)packet->index, (int)*length );
|
||||
// Con_Reportf( S_NOTE "%s: packet from %s, id %d, index %d length %d\n", __func__, NET_AdrToString( *from ), (int)packet->id, (int)packet->index, (int)*length );
|
||||
|
||||
// no packets with this id received
|
||||
if( packet->id != p->id )
|
||||
@@ -140,7 +140,7 @@ qboolean NetSplit_GetLong( netsplit_t *ns, netadr_t *from, byte *data, size_t *l
|
||||
if( p->received < p->count )
|
||||
{
|
||||
UI_ShowConnectionWarning();
|
||||
Con_Reportf( S_WARN "NetSplit_GetLong: lost packet %d\n", p->id );
|
||||
Con_Reportf( S_WARN "%s: lost packet %d\n", __func__, p->id );
|
||||
}
|
||||
|
||||
p->id = packet->id;
|
||||
@@ -152,7 +152,7 @@ qboolean NetSplit_GetLong( netsplit_t *ns, netadr_t *from, byte *data, size_t *l
|
||||
// use bool vector to detect dup packets
|
||||
if( p->recieved_v[packet->index >> 5 ] & ( 1 << ( packet->index & 31 ) ) )
|
||||
{
|
||||
Con_Reportf( S_WARN "NetSplit_GetLong: dup packet from %s\n", NET_AdrToString( *from ) );
|
||||
Con_Reportf( S_WARN "%s: dup packet from %s\n", __func__, NET_AdrToString( *from ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -164,13 +164,13 @@ qboolean NetSplit_GetLong( netsplit_t *ns, netadr_t *from, byte *data, size_t *l
|
||||
// prevent overflow
|
||||
if( packet->part * packet->index > NET_MAX_PAYLOAD )
|
||||
{
|
||||
Con_Reportf( S_WARN "NetSplit_GetLong: packet out fo bounds from %s (part %d index %d)\n", NET_AdrToString( *from ), packet->part, packet->index );
|
||||
Con_Reportf( S_WARN "%s: packet out fo bounds from %s (part %d index %d)\n", __func__, NET_AdrToString( *from ), packet->part, packet->index );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( packet->length > NET_MAX_PAYLOAD )
|
||||
{
|
||||
Con_Reportf( S_WARN "NetSplit_GetLong: packet out fo bounds from %s (length %d)\n", NET_AdrToString( *from ), packet->length );
|
||||
Con_Reportf( S_WARN "%s: packet out fo bounds from %s (length %d)\n", __func__, NET_AdrToString( *from ), packet->length );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ qboolean NetSplit_GetLong( netsplit_t *ns, netadr_t *from, byte *data, size_t *l
|
||||
ns->total_received_uncompressed += len;
|
||||
*length = len;
|
||||
|
||||
// Con_Reportf( S_NOTE "NetSplit_GetLong: packet from %s, id %d received %d length %d\n", NET_AdrToString( *from ), (int)packet->id, (int)p->received, (int)packet->length );
|
||||
// Con_Reportf( S_NOTE "%s: packet from %s, id %d received %d length %d\n", __func__, NET_AdrToString( *from ), (int)packet->id, (int)p->received, (int)packet->length );
|
||||
memcpy( data, p->data, len );
|
||||
return true;
|
||||
}
|
||||
@@ -919,13 +919,20 @@ int Netchan_CreateFileFragments( netchan_t *chan, const char *filename )
|
||||
int remaining;
|
||||
int bufferid = 1;
|
||||
fs_offset_t filesize = 0;
|
||||
char compressedfilename[MAX_OSPATH];
|
||||
int compressedFileTime;
|
||||
int fileTime;
|
||||
qboolean firstfragment = true;
|
||||
qboolean bCompressed = false;
|
||||
fragbufwaiting_t *wait, *p;
|
||||
fragbuf_t *buf;
|
||||
char compressedfilename[sizeof( buf->filename ) + 5];
|
||||
|
||||
// shouldn't be critical, but just in case
|
||||
if( Q_strlen( filename ) > sizeof( buf->filename ) - 1 )
|
||||
{
|
||||
Con_Printf( S_WARN "Unable to transfer %s due to path length overflow\n", filename );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(( filesize = FS_FileSize( filename, false )) <= 0 )
|
||||
{
|
||||
@@ -937,8 +944,7 @@ int Netchan_CreateFileFragments( netchan_t *chan, const char *filename )
|
||||
chunksize = chan->pfnBlockSize( chan->client, FRAGSIZE_FRAG );
|
||||
else chunksize = FRAGMENT_MAX_SIZE; // fallback
|
||||
|
||||
Q_strncpy( compressedfilename, filename, sizeof( compressedfilename ));
|
||||
COM_ReplaceExtension( compressedfilename, ".ztmp", sizeof( compressedfilename ));
|
||||
Q_snprintf( compressedfilename, sizeof( compressedfilename ), "%s.ztmp", filename );
|
||||
compressedFileTime = FS_FileTime( compressedfilename, false );
|
||||
fileTime = FS_FileTime( filename, false );
|
||||
|
||||
@@ -1521,10 +1527,9 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
||||
|
||||
if( pbuf->iscompressed )
|
||||
{
|
||||
char compressedfilename[MAX_OSPATH];
|
||||
char compressedfilename[sizeof( pbuf->filename ) + 5];
|
||||
|
||||
Q_strncpy( compressedfilename, pbuf->filename, sizeof( compressedfilename ));
|
||||
COM_ReplaceExtension( compressedfilename, ".ztmp", sizeof( compressedfilename ));
|
||||
Q_snprintf( compressedfilename, sizeof( compressedfilename ), "%s.ztmp", pbuf->filename );
|
||||
file = FS_Open( compressedfilename, "rb", false );
|
||||
}
|
||||
else file = FS_Open( pbuf->filename, "rb", false );
|
||||
@@ -1583,7 +1588,7 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
||||
// send the qport if we are a client
|
||||
if( chan->sock == NS_CLIENT )
|
||||
{
|
||||
MSG_WriteWord( &send, Cvar_VariableInteger( "net_qport" ));
|
||||
MSG_WriteWord( &send, (int)net_qport.value );
|
||||
}
|
||||
|
||||
if( send_reliable && send_reliable_fragment )
|
||||
@@ -1619,7 +1624,7 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
||||
|
||||
if( (( MSG_GetNumBytesWritten( &send ) + length ) >> 3) <= maxsize )
|
||||
MSG_WriteBits( &send, data, length );
|
||||
else Con_Printf( S_WARN "Netchan_Transmit: unreliable message overflow: %d\n", MSG_GetNumBytesWritten( &send ) );
|
||||
else Con_Printf( S_WARN "%s: unreliable message overflow: %d\n", __func__, MSG_GetNumBytesWritten( &send ) );
|
||||
}
|
||||
|
||||
// deal with packets that are too small for some networks
|
||||
@@ -1695,9 +1700,6 @@ qboolean Netchan_Process( netchan_t *chan, sizebuf_t *msg )
|
||||
qboolean message_contains_fragments;
|
||||
int i, qport, statId;
|
||||
|
||||
if( !CL_IsPlaybackDemo() && !NET_CompareAdr( net_from, chan->remote_address ))
|
||||
return false;
|
||||
|
||||
// get sequence numbers
|
||||
MSG_Clear( msg );
|
||||
sequence = MSG_ReadLong( msg );
|
||||
|
||||
@@ -510,13 +510,13 @@ static qboolean Delta_AddField( delta_info_t *dt, const char *pName, int flags,
|
||||
pFieldInfo = Delta_FindFieldInfo( dt->pInfo, pName );
|
||||
if( !pFieldInfo )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Delta_Add: couldn't find description for %s->%s\n", dt->pName, pName );
|
||||
Con_DPrintf( S_ERROR "%s: couldn't find description for %s->%s\n", __func__, dt->pName, pName );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( dt->numFields + 1 > dt->maxFields )
|
||||
{
|
||||
Con_DPrintf( S_WARN "Delta_Add: can't add %s->%s encoder list is full\n", dt->pName, pName );
|
||||
Con_DPrintf( S_WARN "%s: can't add %s->%s encoder list is full\n", __func__, dt->pName, pName );
|
||||
return false; // too many fields specified (duplicated ?)
|
||||
}
|
||||
|
||||
@@ -587,7 +587,7 @@ void Delta_ParseTableField( sizebuf_t *msg )
|
||||
tableIndex = MSG_ReadUBitLong( msg, 4 );
|
||||
dt = Delta_FindStructByIndex( tableIndex );
|
||||
if( !dt )
|
||||
Host_Error( "Delta_ParseTableField: not initialized" );
|
||||
Host_Error( "%s: not initialized", __func__ );
|
||||
|
||||
nameIndex = MSG_ReadUBitLong( msg, 8 ); // read field name index
|
||||
if( ( nameIndex >= 0 && nameIndex < dt->maxFields ) )
|
||||
@@ -597,7 +597,7 @@ void Delta_ParseTableField( sizebuf_t *msg )
|
||||
else
|
||||
{
|
||||
ignore = true;
|
||||
Con_Reportf( "Delta_ParseTableField: wrong nameIndex %d for table %s, ignoring\n", nameIndex, dt->pName );
|
||||
Con_Reportf( "%s: wrong nameIndex %d for table %s, ignoring\n", __func__, nameIndex, dt->pName );
|
||||
}
|
||||
|
||||
flags = MSG_ReadUBitLong( msg, 10 );
|
||||
@@ -630,28 +630,28 @@ static qboolean Delta_ParseField( char **delta_script, const delta_field_t *pInf
|
||||
*delta_script = COM_ParseFile( *delta_script, token, sizeof( token ));
|
||||
if( Q_strcmp( token, "(" ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Delta_ParseField: expected '(', found '%s' instead\n", token );
|
||||
Con_DPrintf( S_ERROR "%s: expected '(', found '%s' instead\n", __func__, token );
|
||||
return false;
|
||||
}
|
||||
|
||||
// read the variable name
|
||||
if(( *delta_script = COM_ParseFile( *delta_script, token, sizeof( token ))) == NULL )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Delta_ParseField: missing field name\n" );
|
||||
Con_DPrintf( S_ERROR "%s: missing field name\n", __func__ );
|
||||
return false;
|
||||
}
|
||||
|
||||
pFieldInfo = Delta_FindFieldInfo( pInfo, token );
|
||||
if( !pFieldInfo )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Delta_ParseField: unable to find field %s\n", token );
|
||||
Con_DPrintf( S_ERROR "%s: unable to find field %s\n", __func__, token );
|
||||
return false;
|
||||
}
|
||||
|
||||
*delta_script = COM_ParseFile( *delta_script, token, sizeof( token ));
|
||||
if( Q_strcmp( token, "," ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Delta_ParseField: expected ',', found '%s' instead\n", token );
|
||||
Con_DPrintf( S_ERROR "%s: expected ',', found '%s' instead\n", __func__, token );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -692,14 +692,14 @@ static qboolean Delta_ParseField( char **delta_script, const delta_field_t *pInf
|
||||
|
||||
if( Q_strcmp( token, "," ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Delta_ParseField: expected ',', found '%s' instead\n", token );
|
||||
Con_DPrintf( S_ERROR "%s: expected ',', found '%s' instead\n", __func__, token );
|
||||
return false;
|
||||
}
|
||||
|
||||
// read delta-bits
|
||||
if(( *delta_script = COM_ParseFile( *delta_script, token, sizeof( token ))) == NULL )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Delta_ParseField: %s field bits argument is missing\n", pField->name );
|
||||
Con_DPrintf( S_ERROR "%s: %s field bits argument is missing\n", __func__, pField->name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -708,14 +708,14 @@ static qboolean Delta_ParseField( char **delta_script, const delta_field_t *pInf
|
||||
*delta_script = COM_ParseFile( *delta_script, token, sizeof( token ));
|
||||
if( Q_strcmp( token, "," ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Delta_ParseField: expected ',', found '%s' instead\n", token );
|
||||
Con_DPrintf( S_ERROR "%s: expected ',', found '%s' instead\n", __func__, token );
|
||||
return false;
|
||||
}
|
||||
|
||||
// read delta-multiplier
|
||||
if(( *delta_script = COM_ParseFile( *delta_script, token, sizeof( token ))) == NULL )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Delta_ParseField: %s missing 'multiplier' argument\n", pField->name );
|
||||
Con_DPrintf( S_ERROR "%s: %s missing 'multiplier' argument\n", __func__, pField->name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -726,14 +726,14 @@ static qboolean Delta_ParseField( char **delta_script, const delta_field_t *pInf
|
||||
*delta_script = COM_ParseFile( *delta_script, token, sizeof( token ));
|
||||
if( Q_strcmp( token, "," ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Delta_ParseField: expected ',', found '%s' instead\n", token );
|
||||
Con_DPrintf( S_ERROR "%s: expected ',', found '%s' instead\n", __func__, token );
|
||||
return false;
|
||||
}
|
||||
|
||||
// read delta-postmultiplier
|
||||
if(( *delta_script = COM_ParseFile( *delta_script, token, sizeof( token ))) == NULL )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Delta_ParseField: %s missing 'post_multiply' argument\n", pField->name );
|
||||
Con_DPrintf( S_ERROR "%s: %s missing 'post_multiply' argument\n", __func__, pField->name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -749,7 +749,7 @@ static qboolean Delta_ParseField( char **delta_script, const delta_field_t *pInf
|
||||
*delta_script = COM_ParseFile( *delta_script, token, sizeof( token ));
|
||||
if( Q_strcmp( token, ")" ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Delta_ParseField: expected ')', found '%s' instead\n", token );
|
||||
Con_DPrintf( S_ERROR "%s: expected ')', found '%s' instead\n", __func__, token );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -823,7 +823,7 @@ static void Delta_InitFields( void )
|
||||
delta_info_t *dt;
|
||||
|
||||
afile = FS_LoadFile( DELTA_PATH, NULL, false );
|
||||
if( !afile ) Sys_Error( "DELTA_Load: couldn't load file %s\n", DELTA_PATH );
|
||||
if( !afile ) Sys_Error( "%s: couldn't load file %s\n", __func__, DELTA_PATH );
|
||||
|
||||
pfile = (char *)afile;
|
||||
|
||||
@@ -1801,7 +1801,7 @@ void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, sizebuf_t *
|
||||
startBit = msg->iCurBit;
|
||||
|
||||
if( to->number < 0 || to->number >= GI->max_edicts )
|
||||
Host_Error( "MSG_WriteDeltaEntity: Bad entity number: %i\n", to->number );
|
||||
Host_Error( "%s: Bad entity number: %i\n", __func__, to->number );
|
||||
|
||||
MSG_WriteUBitLong( msg, to->number, MAX_ENTITY_BITS );
|
||||
MSG_WriteUBitLong( msg, 0, 2 ); // alive
|
||||
@@ -1882,7 +1882,7 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state
|
||||
int baseline_offset = 0;
|
||||
|
||||
if( number < 0 || number >= clgame.maxEntities )
|
||||
Host_Error( "MSG_ReadDeltaEntity: bad delta entity number: %i\n", number );
|
||||
Host_Error( "%s: bad delta entity number: %i\n", __func__, number );
|
||||
|
||||
fRemoveType = MSG_ReadUBitLong( msg, 2 );
|
||||
|
||||
@@ -1904,7 +1904,7 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state
|
||||
return false;
|
||||
}
|
||||
|
||||
Host_Error( "MSG_ReadDeltaEntity: unknown update type %i\n", fRemoveType );
|
||||
Host_Error( "%s: unknown update type %i\n", __func__, fRemoveType );
|
||||
}
|
||||
|
||||
if( !cls.legacymode )
|
||||
@@ -2003,13 +2003,13 @@ void GAME_EXPORT Delta_AddEncoder( char *name, pfnDeltaEncode encodeFunc )
|
||||
|
||||
if( !dt || !dt->bInitialized )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Delta_AddEncoder: couldn't find delta with specified custom encode %s\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: couldn't find delta with specified custom encode %s\n", __func__, name );
|
||||
return;
|
||||
}
|
||||
|
||||
if( dt->customEncode == CUSTOM_NONE )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Delta_AddEncoder: %s not supposed for custom encoding\n", dt->pName );
|
||||
Con_DPrintf( S_ERROR "%s: %s not supposed for custom encoding\n", __func__, dt->pName );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -544,7 +544,7 @@ static net_gai_state_t NET_StringToSockaddr( const char *s, struct sockaddr_stor
|
||||
}
|
||||
else // failed to create thread
|
||||
{
|
||||
Con_Reportf( S_ERROR "NET_StringToSockaddr: failed to create thread!\n");
|
||||
Con_Reportf( S_ERROR "%s: failed to create thread!\n", __func__ );
|
||||
nsthread.busy = false;
|
||||
}
|
||||
}
|
||||
@@ -937,7 +937,7 @@ qboolean NET_CompareAdr( const netadr_t a, const netadr_t b )
|
||||
return true;
|
||||
}
|
||||
|
||||
Con_DPrintf( S_ERROR "NET_CompareAdr: bad address type\n" );
|
||||
Con_DPrintf( S_ERROR "%s: bad address type\n", __func__ );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1397,7 +1397,7 @@ static qboolean NET_GetLong( byte *pData, int size, size_t *outSize, int splitsi
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_DPrintf( "NET_GetLong: Ignoring duplicated split packet %i of %i ( %i bytes )\n", packet_number + 1, packet_count, size );
|
||||
Con_DPrintf( "%s: Ignoring duplicated split packet %i of %i ( %i bytes )\n", __func__, packet_number + 1, packet_count, size );
|
||||
}
|
||||
|
||||
offset = (packet_number * body_size);
|
||||
@@ -1478,7 +1478,7 @@ static qboolean NET_QueuePacket( netsrc_t sock, netadr_t *from, byte *data, size
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Reportf( "NET_QueuePacket: oversize packet from %s\n", NET_AdrToString( *from ));
|
||||
Con_Reportf( "%s: oversize packet from %s\n", __func__, NET_AdrToString( *from ));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1494,7 +1494,7 @@ static qboolean NET_QueuePacket( netsrc_t sock, netadr_t *from, byte *data, size
|
||||
case WSAETIMEDOUT:
|
||||
break;
|
||||
default: // let's continue even after errors
|
||||
Con_DPrintf( S_ERROR "NET_QueuePacket: %s from %s\n", NET_ErrorString(), NET_AdrToString( *from ));
|
||||
Con_DPrintf( S_ERROR "%s: %s from %s\n", __func__, NET_ErrorString(), NET_AdrToString( *from ));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1624,7 +1624,7 @@ void NET_SendPacketEx( netsrc_t sock, size_t length, const void *data, netadr_t
|
||||
}
|
||||
else
|
||||
{
|
||||
Host_Error( "NET_SendPacket: bad address type %i (%i)\n", to.type, to.type6 );
|
||||
Host_Error( "%s: bad address type %i (%i)\n", __func__, to.type, to.type6 );
|
||||
}
|
||||
|
||||
NET_NetadrToSockadr( &to, &addr );
|
||||
@@ -1645,15 +1645,15 @@ void NET_SendPacketEx( netsrc_t sock, size_t length, const void *data, netadr_t
|
||||
|
||||
if( Host_IsDedicated( ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "NET_SendPacket: %s to %s\n", NET_ErrorString(), NET_AdrToString( to ));
|
||||
Con_DPrintf( S_ERROR "%s: %s to %s\n", __func__, NET_ErrorString(), NET_AdrToString( to ));
|
||||
}
|
||||
else if( err == WSAEADDRNOTAVAIL || err == WSAENOBUFS )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "NET_SendPacket: %s to %s\n", NET_ErrorString(), NET_AdrToString( to ));
|
||||
Con_DPrintf( S_ERROR "%s: %s to %s\n", __func__, NET_ErrorString(), NET_AdrToString( to ));
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf( S_ERROR "NET_SendPacket: %s to %s\n", NET_ErrorString(), NET_AdrToString( to ));
|
||||
Con_Printf( S_ERROR "%s: %s to %s\n", __func__, NET_ErrorString(), NET_AdrToString( to ));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1689,7 +1689,7 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
||||
{
|
||||
err = WSAGetLastError();
|
||||
if( err != WSAEAFNOSUPPORT )
|
||||
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d socket: %s\n", port, NET_ErrorString( ));
|
||||
Con_DPrintf( S_WARN "%s: port: %d socket: %s\n", __func__, port, NET_ErrorString( ));
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
@@ -1697,7 +1697,7 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
||||
{
|
||||
struct timeval timeout;
|
||||
|
||||
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d ioctl FIONBIO: %s\n", port, NET_ErrorString( ));
|
||||
Con_DPrintf( S_WARN "%s: port: %d ioctl FIONBIO: %s\n", __func__, port, NET_ErrorString( ));
|
||||
// try timeout instead of NBIO
|
||||
timeout.tv_sec = timeout.tv_usec = 0;
|
||||
setsockopt( net_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
|
||||
@@ -1706,12 +1706,12 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
||||
// make it broadcast capable
|
||||
if( NET_IsSocketError( setsockopt( net_socket, SOL_SOCKET, SO_BROADCAST, (char *)&_true, sizeof( _true ))))
|
||||
{
|
||||
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d setsockopt SO_BROADCAST: %s\n", port, NET_ErrorString( ));
|
||||
Con_DPrintf( S_WARN "%s: port: %d setsockopt SO_BROADCAST: %s\n", __func__, port, NET_ErrorString( ));
|
||||
}
|
||||
|
||||
if( NET_IsSocketError( setsockopt( net_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&optval, sizeof( optval ))))
|
||||
{
|
||||
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d setsockopt SO_REUSEADDR: %s\n", port, NET_ErrorString( ));
|
||||
Con_DPrintf( S_WARN "%s: port: %d setsockopt SO_REUSEADDR: %s\n", __func__, port, NET_ErrorString( ));
|
||||
closesocket( net_socket );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
@@ -1722,7 +1722,7 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
||||
{
|
||||
if( NET_IsSocketError( setsockopt( net_socket, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&_true, sizeof( _true ))))
|
||||
{
|
||||
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d setsockopt IPV6_V6ONLY: %s\n", port, NET_ErrorString( ));
|
||||
Con_DPrintf( S_WARN "%s: port: %d setsockopt IPV6_V6ONLY: %s\n", __func__, port, NET_ErrorString( ));
|
||||
closesocket( net_socket );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
@@ -1730,7 +1730,7 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
||||
if( Sys_CheckParm( "-loopback" ))
|
||||
{
|
||||
if( NET_IsSocketError( setsockopt( net_socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *)&_true, sizeof( _true ))))
|
||||
Con_DPrintf( S_WARN "NET_UDPSocket: port %d setsockopt IPV6_MULTICAST_LOOP: %s\n", port, NET_ErrorString( ));
|
||||
Con_DPrintf( S_WARN "%s: port %d setsockopt IPV6_MULTICAST_LOOP: %s\n", __func__, port, NET_ErrorString( ));
|
||||
}
|
||||
|
||||
if( COM_CheckStringEmpty( net_iface ) && Q_stricmp( net_iface, "localhost" ))
|
||||
@@ -1742,7 +1742,7 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
||||
|
||||
if( NET_IsSocketError( bind( net_socket, (struct sockaddr *)&addr, sizeof( struct sockaddr_in6 ))))
|
||||
{
|
||||
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d bind6: %s\n", port, NET_ErrorString( ));
|
||||
Con_DPrintf( S_WARN "%s: port: %d bind6: %s\n", __func__, port, NET_ErrorString( ));
|
||||
closesocket( net_socket );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
@@ -1758,7 +1758,7 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
||||
{
|
||||
err = WSAGetLastError();
|
||||
if( err != WSAENOPROTOOPT )
|
||||
Con_Printf( S_WARN "NET_UDPSocket: port: %d setsockopt IP_TOS: %s\n", port, NET_ErrorString( ));
|
||||
Con_Printf( S_WARN "%s: port: %d setsockopt IP_TOS: %s\n", __func__, port, NET_ErrorString( ));
|
||||
closesocket( net_socket );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
@@ -1767,7 +1767,7 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
||||
if( Sys_CheckParm( "-loopback" ))
|
||||
{
|
||||
if( NET_IsSocketError( setsockopt( net_socket, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&_true, sizeof( _true ))))
|
||||
Con_DPrintf( S_WARN "NET_UDPSocket: port %d setsockopt IP_MULTICAST_LOOP: %s\n", port, NET_ErrorString( ));
|
||||
Con_DPrintf( S_WARN "%s: port %d setsockopt IP_MULTICAST_LOOP: %s\n", __func__, port, NET_ErrorString( ));
|
||||
}
|
||||
|
||||
if( COM_CheckStringEmpty( net_iface ) && Q_stricmp( net_iface, "localhost" ))
|
||||
@@ -1779,7 +1779,7 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
||||
|
||||
if( NET_IsSocketError( bind( net_socket, (struct sockaddr *)&addr, sizeof( struct sockaddr_in ))))
|
||||
{
|
||||
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d bind: %s\n", port, NET_ErrorString( ));
|
||||
Con_DPrintf( S_WARN "%s: port: %d bind: %s\n", __func__, port, NET_ErrorString( ));
|
||||
closesocket( net_socket );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
@@ -1796,8 +1796,8 @@ NET_OpenIP
|
||||
static void NET_OpenIP( qboolean change_port, int *sockets, const char *net_iface, int hostport, int clientport, int family )
|
||||
{
|
||||
int port;
|
||||
qboolean sv_nat = Cvar_VariableInteger("sv_nat");
|
||||
qboolean cl_nat = Cvar_VariableInteger("cl_nat");
|
||||
qboolean sv_nat = Cvar_VariableInteger( "sv_nat" );
|
||||
qboolean cl_nat = Cvar_VariableInteger( "cl_nat" );
|
||||
|
||||
if( change_port && ( FBitSet( net_hostport.flags, FCVAR_CHANGED ) || sv_nat ))
|
||||
{
|
||||
@@ -2375,7 +2375,7 @@ static qboolean HTTP_ProcessStream( httpfile_t *curfile )
|
||||
|
||||
if( curfile->header_size >= sizeof( buf ))
|
||||
{
|
||||
Con_Reportf( S_ERROR "Header too big, the size is %s\n", curfile->header_size );
|
||||
Con_Reportf( S_ERROR "Header too big, the size is %d\n", curfile->header_size );
|
||||
HTTP_FreeFile( curfile, true );
|
||||
return false;
|
||||
}
|
||||
@@ -2395,8 +2395,6 @@ static qboolean HTTP_ProcessStream( httpfile_t *curfile )
|
||||
int cutheadersize = begin - curfile->buf + 4; // after that begin of data
|
||||
char *content_length_line;
|
||||
|
||||
Con_Reportf( "HTTP: Got response!\n" );
|
||||
|
||||
if( !Q_strstr( curfile->buf, "200 OK" ))
|
||||
{
|
||||
*begin = 0; // cut string to print out response
|
||||
@@ -2420,10 +2418,10 @@ static qboolean HTTP_ProcessStream( httpfile_t *curfile )
|
||||
content_length_line += sizeof( "Content-Length: " ) - 1;
|
||||
size = Q_atoi( content_length_line );
|
||||
|
||||
Con_Reportf( "HTTP: File size is %d\n", size );
|
||||
Con_Reportf( "HTTP: Got 200 OK! File size is %d\n", size );
|
||||
|
||||
if( ( curfile->size != -1 ) && ( curfile->size != size )) // check size if specified, not used
|
||||
Con_Reportf( S_WARN "Server reports wrong file size!\n" );
|
||||
Con_Reportf( S_WARN "Server reports wrong file size for %s!\n", curfile->path );
|
||||
|
||||
curfile->size = size;
|
||||
curfile->header_size = 0;
|
||||
@@ -2535,7 +2533,7 @@ void HTTP_Run( void )
|
||||
|
||||
if( !curfile->file )
|
||||
{
|
||||
Con_Printf( S_ERROR "cannot open %s!\n", name );
|
||||
Con_Printf( S_ERROR "HTTP: cannot open %s!\n", name );
|
||||
HTTP_FreeFile( curfile, true );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,6 @@ GNU General Public License for more details.
|
||||
#define NET_MAX_MESSAGE PAD_NUMBER(( NET_MAX_PAYLOAD + HEADER_BYTES ), 16 )
|
||||
|
||||
#define MASTERSERVER_ADR "mentality.rip:27010"
|
||||
#define MASTERSERVER_ADR_TEST "mentality.rip:27011"
|
||||
#define MS_SCAN_REQUEST "1\xFF" "0.0.0.0:0\0"
|
||||
|
||||
#define PORT_MASTER 27010
|
||||
|
||||
@@ -246,7 +246,7 @@ loc0:
|
||||
}
|
||||
|
||||
if( num < hull->firstclipnode || num > hull->lastclipnode )
|
||||
Host_Error( "PM_RecursiveHullCheck: bad node number %i\n", num );
|
||||
Host_Error( "%s: bad node number %i\n", __func__, num );
|
||||
|
||||
// find the point distances
|
||||
node = hull->clipnodes + num;
|
||||
|
||||
@@ -279,6 +279,7 @@ GNU General Public License for more details.
|
||||
|
||||
extern const char *svc_strings[svc_lastmsg+1];
|
||||
extern const char *svc_legacy_strings[svc_lastmsg+1];
|
||||
extern const char *svc_quake_strings[svc_lastmsg+1];
|
||||
extern const char *svc_goldsrc_strings[svc_lastmsg+1];
|
||||
extern const char *clc_strings[clc_lastmsg+1];
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ int open_mpeg_stream( void *mpg, void *file, pfread f_read, pfseek f_seek, wavin
|
||||
|
||||
if( !mh || !sc ) return 0;
|
||||
|
||||
ret = mpg123_replace_reader_handle( mh, (void *)f_read, (void *)f_seek, NULL );
|
||||
ret = mpg123_replace_reader_handle( mh, f_read, f_seek, NULL );
|
||||
if( ret != MPG123_OK )
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -34,9 +34,15 @@ typedef struct
|
||||
int playtime; // stream size in milliseconds
|
||||
} wavinfo_t;
|
||||
|
||||
#ifdef _MSC_VER // a1ba: MSVC6 don't have ssize_t
|
||||
typedef long mpg_ssize_t;
|
||||
#else
|
||||
typedef ssize_t mpg_ssize_t;
|
||||
#endif
|
||||
|
||||
// custom stdio
|
||||
typedef long (*pfread)( void *handle, void *buf, size_t count );
|
||||
typedef long (*pfseek)( void *handle, long offset, int whence );
|
||||
typedef mpg_ssize_t (*pfread)( void *handle, void *buf, size_t count );
|
||||
typedef fs_offset_t (*pfseek)( void *handle, fs_offset_t offset, int whence );
|
||||
|
||||
extern void *create_decoder( int *error );
|
||||
extern int feed_mpeg_header( void *mpg, const byte *data, long bufsize, long streamsize, wavinfo_t *sc );
|
||||
|
||||
@@ -32,6 +32,7 @@ typedef struct mpg123_handle_s mpg123_handle_t;
|
||||
#include <stdlib.h>
|
||||
#include "fmt123.h"
|
||||
#include STDINT_H
|
||||
#include "xash3d_types.h"
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
@@ -50,7 +51,7 @@ typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned long ulong;
|
||||
typedef unsigned int uint;
|
||||
typedef long mpg_off_t;
|
||||
typedef fs_offset_t mpg_off_t;
|
||||
|
||||
#ifdef _MSC_VER // a1ba: MSVC6 don't have ssize_t
|
||||
typedef long mpg_ssize_t;
|
||||
|
||||
@@ -853,11 +853,21 @@ int open_feed( mpg123_handle_t *fr )
|
||||
return 0;
|
||||
}
|
||||
|
||||
static mpg_ssize_t read_mpgtypes( int fd, void *buf, size_t count )
|
||||
{
|
||||
return read( fd, buf, count );
|
||||
}
|
||||
|
||||
static mpg_off_t lseek_mpgtypes( int fd, mpg_off_t offset, int whence )
|
||||
{
|
||||
return lseek( fd, offset, whence );
|
||||
}
|
||||
|
||||
static int default_init( mpg123_handle_t *fr )
|
||||
{
|
||||
fr->rdat.fdread = plain_read;
|
||||
fr->rdat.read = fr->rdat.r_read != NULL ? fr->rdat.r_read : read;
|
||||
fr->rdat.lseek = fr->rdat.r_lseek != NULL ? fr->rdat.r_lseek : lseek;
|
||||
fr->rdat.read = fr->rdat.r_read != NULL ? fr->rdat.r_read : read_mpgtypes;
|
||||
fr->rdat.lseek = fr->rdat.r_lseek != NULL ? fr->rdat.r_lseek : lseek_mpgtypes;
|
||||
fr->rdat.filelen = get_fileinfo( fr );
|
||||
fr->rdat.filepos = 0;
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ load_internal:
|
||||
}
|
||||
|
||||
if( filename[0] != '#' )
|
||||
Con_DPrintf( S_WARN "FS_LoadSound: couldn't load \"%s\"\n", loadname );
|
||||
Con_DPrintf( S_WARN "%s: couldn't load \"%s\"\n", __func__, loadname );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -216,7 +216,7 @@ wavdata_t *FS_StreamInfo( stream_t *stream )
|
||||
if( !stream ) return NULL;
|
||||
|
||||
// fill structure
|
||||
info.loopStart = -1;
|
||||
info.loopStart = 0;
|
||||
info.rate = stream->rate;
|
||||
info.width = stream->width;
|
||||
info.channels = stream->channels;
|
||||
|
||||
@@ -74,7 +74,10 @@ static uint32_t Sound_ParseSynchInteger( uint32_t v )
|
||||
static void Sound_HandleCustomID3Comment( const char *key, const char *value )
|
||||
{
|
||||
if( !Q_strcmp( key, "LOOP_START" ) || !Q_strcmp( key, "LOOPSTART" ))
|
||||
{
|
||||
sound.loopstart = Q_atoi( value );
|
||||
SetBits( sound.flags, SOUND_LOOPED );
|
||||
}
|
||||
// unknown comment is not an error
|
||||
}
|
||||
|
||||
@@ -91,7 +94,7 @@ static qboolean Sound_ParseID3Frame( const did3v2_frame_t *frame, const byte *bu
|
||||
value_len = frame_length - (1 + key_len + 1);
|
||||
if( value_len <= 0 || value_len >= sizeof( value ))
|
||||
{
|
||||
Con_Printf( S_ERROR "Sound_ParseID3Frame: invalid TXXX description, possibly broken file.\n" );
|
||||
Con_Printf( S_ERROR "%s: invalid TXXX description, possibly broken file.\n", __func__ );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -103,9 +106,9 @@ static qboolean Sound_ParseID3Frame( const did3v2_frame_t *frame, const byte *bu
|
||||
else
|
||||
{
|
||||
if( buffer[0] == 0x01 || buffer[0] == 0x02 ) // UTF-16 with BOM
|
||||
Con_Printf( S_ERROR "Sound_ParseID3Frame: UTF-16 encoding is unsupported. Use UTF-8 or ISO-8859!\n" );
|
||||
Con_Printf( S_ERROR "%s: UTF-16 encoding is unsupported. Use UTF-8 or ISO-8859!\n", __func__ );
|
||||
else
|
||||
Con_Printf( S_ERROR "Sound_ParseID3Frame: unknown TXXX tag encoding %d, possibly broken file.\n", buffer[0] );
|
||||
Con_Printf( S_ERROR "%s: unknown TXXX tag encoding %d, possibly broken file.\n", __func__, buffer[0] );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -129,7 +132,7 @@ static qboolean Sound_ParseID3Tag( const byte *buffer, fs_offset_t filesize )
|
||||
{
|
||||
// old id3v1 header found
|
||||
if( CHECK_IDENT( header->ident, 'T', 'A', 'G' ))
|
||||
Con_Printf( S_ERROR "Sound_ParseID3Tag: ID3v1 is not supported! Convert to ID3v2.4!\n" );
|
||||
Con_Printf( S_ERROR "%s: ID3v1 is not supported! Convert to ID3v2.4!\n", __func__ );
|
||||
|
||||
return true; // missing tag header is not an error
|
||||
}
|
||||
@@ -137,14 +140,14 @@ static qboolean Sound_ParseID3Tag( const byte *buffer, fs_offset_t filesize )
|
||||
// support only latest id3 v2.4
|
||||
if( header->major_ver != 4 || header->minor_ver == 0xff )
|
||||
{
|
||||
Con_Printf( S_ERROR "Sound_ParseID3Tag: invalid ID3v2 tag version 2.%d.%d. Convert to ID3v2.4!\n", header->major_ver, header->minor_ver );
|
||||
Con_Printf( S_ERROR "%s: invalid ID3v2 tag version 2.%d.%d. Convert to ID3v2.4!\n", __func__, header->major_ver, header->minor_ver );
|
||||
return false;
|
||||
}
|
||||
|
||||
tag_length = Sound_ParseSynchInteger( header->length );
|
||||
if( tag_length > filesize - sizeof( *header ))
|
||||
{
|
||||
Con_Printf( S_ERROR "Sound_ParseID3Tag: invalid tag length %u, possibly broken file.\n", tag_length );
|
||||
Con_Printf( S_ERROR "%s: invalid tag length %u, possibly broken file.\n", __func__, tag_length );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -156,7 +159,7 @@ static qboolean Sound_ParseID3Tag( const byte *buffer, fs_offset_t filesize )
|
||||
|
||||
if( ext_length > tag_length )
|
||||
{
|
||||
Con_Printf( S_ERROR "Sound_ParseID3Tag: invalid extended header length %u, possibly broken file.\n", ext_length );
|
||||
Con_Printf( S_ERROR "%s: invalid extended header length %u, possibly broken file.\n", __func__, ext_length );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -170,7 +173,7 @@ static qboolean Sound_ParseID3Tag( const byte *buffer, fs_offset_t filesize )
|
||||
|
||||
if( frame_length > tag_length )
|
||||
{
|
||||
Con_Printf( S_ERROR "Sound_ParseID3Tag: invalid frame length %u, possibly broken file.\n", frame_length );
|
||||
Con_Printf( S_ERROR "%s: invalid frame length %u, possibly broken file.\n", __func__, frame_length );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -225,7 +228,7 @@ qboolean Sound_LoadMPG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
// trying to read header
|
||||
if( !feed_mpeg_header( mpeg, buffer, FRAME_SIZE, filesize, &sc ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Sound_LoadMPG: failed to load (%s): %s\n", name, get_error( mpeg ));
|
||||
Con_DPrintf( S_ERROR "%s: failed to load (%s): %s\n", __func__, name, get_error( mpeg ));
|
||||
close_decoder( mpeg );
|
||||
return false;
|
||||
}
|
||||
@@ -233,21 +236,19 @@ qboolean Sound_LoadMPG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
sound.channels = sc.channels;
|
||||
sound.rate = sc.rate;
|
||||
sound.width = 2; // always 16-bit PCM
|
||||
sound.loopstart = -1;
|
||||
sound.size = ( sound.channels * sound.rate * sound.width ) * ( sc.playtime / 1000 ); // in bytes
|
||||
padsize = sound.size % FRAME_SIZE;
|
||||
pos += FRAME_SIZE; // evaluate pos
|
||||
|
||||
if( !Sound_ParseID3Tag( buffer, filesize ))
|
||||
{
|
||||
Con_DPrintf( S_WARN "Sound_LoadMPG: (%s) failed to extract LOOP_START tag\n", name );
|
||||
sound.loopstart = -1;
|
||||
Con_DPrintf( S_WARN "%s: (%s) failed to extract LOOP_START tag\n", __func__, name );
|
||||
}
|
||||
|
||||
if( !sound.size )
|
||||
{
|
||||
// bad mpeg file ?
|
||||
Con_DPrintf( S_ERROR "Sound_LoadMPG: (%s) is probably corrupted\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: (%s) is probably corrupted\n", __func__, name );
|
||||
close_decoder( mpeg );
|
||||
return false;
|
||||
}
|
||||
@@ -290,14 +291,14 @@ qboolean Sound_LoadMPG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
FS_SeekEx
|
||||
=================
|
||||
*/
|
||||
static fs_offset_t FS_SeekEx( file_t *file, fs_offset_t offset, int whence )
|
||||
static fs_offset_t FS_SeekMpg( void *file, fs_offset_t offset, int whence )
|
||||
{
|
||||
return FS_Seek( file, offset, whence ) == -1 ? -1 : FS_Tell( file );
|
||||
return g_fsapi.Seek((file_t *)file, offset, whence ) == -1 ? -1 : g_fsapi.Tell((file_t *)file );
|
||||
}
|
||||
|
||||
static mpg_ssize_t FS_ReadMpg( void *file, void *buf, size_t count )
|
||||
{
|
||||
return g_fsapi.Read((file_t *)file, buf, count );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -324,7 +325,7 @@ stream_t *Stream_OpenMPG( const char *filename )
|
||||
// couldn't create decoder
|
||||
if(( mpeg = create_decoder( &ret )) == NULL )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Stream_OpenMPG: couldn't create decoder: %s\n", get_error( mpeg ) );
|
||||
Con_DPrintf( S_ERROR "%s: couldn't create decoder: %s\n", __func__, get_error( mpeg ) );
|
||||
Mem_Free( stream );
|
||||
FS_Close( file );
|
||||
return NULL;
|
||||
@@ -333,9 +334,9 @@ stream_t *Stream_OpenMPG( const char *filename )
|
||||
if( ret ) Con_DPrintf( S_ERROR "%s\n", get_error( mpeg ));
|
||||
|
||||
// trying to open stream and read header
|
||||
if( !open_mpeg_stream( mpeg, file, (void*)FS_Read, (void*)FS_SeekEx, &sc ))
|
||||
if( !open_mpeg_stream( mpeg, file, FS_ReadMpg, FS_SeekMpg, &sc ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Stream_OpenMPG: failed to load (%s): %s\n", filename, get_error( mpeg ));
|
||||
Con_DPrintf( S_ERROR "%s: failed to load (%s): %s\n", __func__, filename, get_error( mpeg ));
|
||||
close_decoder( mpeg );
|
||||
Mem_Free( stream );
|
||||
FS_Close( file );
|
||||
|
||||
@@ -14,6 +14,9 @@ GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "soundlib.h"
|
||||
#if XASH_SDL
|
||||
#include <SDL_audio.h>
|
||||
#endif // XASH_SDL
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
@@ -130,7 +133,309 @@ uint GAME_EXPORT Sound_GetApproxWavePlayLen( const char *filepath )
|
||||
return msecs;
|
||||
}
|
||||
|
||||
#define drint( v ) (int)( v + 0.5 )
|
||||
static qboolean Sound_ConvertNoResample( wavdata_t *sc, int inwidth, int outwidth, int outcount )
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if( inwidth == 1 && outwidth == 2 ) // S8 to S16
|
||||
{
|
||||
for( i = 0; i < outcount * sc->channels; i++ )
|
||||
((int16_t*)sound.tempbuffer)[i] = ((int8_t *)sc->buffer)[i] * 256;
|
||||
return true;
|
||||
}
|
||||
|
||||
if( inwidth == 2 && outwidth == 1 ) // S16 to S8
|
||||
{
|
||||
for( i = 0; i < outcount * sc->channels; i++ )
|
||||
((int8_t*)sound.tempbuffer)[i] = ((int16_t *)sc->buffer)[i] / 256;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static qboolean Sound_ConvertDownsample( wavdata_t *sc, int inwidth, int outwidth, int outcount, double stepscale )
|
||||
{
|
||||
size_t i;
|
||||
double j;
|
||||
|
||||
if( inwidth == 1 && outwidth == 1 )
|
||||
{
|
||||
int8_t *data = (int8_t *)sc->buffer;
|
||||
|
||||
if( outwidth == 1 )
|
||||
{
|
||||
int8_t *outdata = (int8_t *)sound.tempbuffer;
|
||||
|
||||
if( sc->channels == 2 )
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i*2+0] = data[((int)j)*2+0];
|
||||
outdata[i*2+1] = data[((int)j)*2+1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i] = data[(int)j];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if( outwidth == 2 )
|
||||
{
|
||||
int16_t *outdata = (int16_t *)sound.tempbuffer;
|
||||
|
||||
if( sc->channels == 2 )
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i*2+0] = data[((int)j)*2+0] * 256;
|
||||
outdata[i*2+1] = data[((int)j)*2+1] * 256;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i] = data[(int)j] * 256;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if( inwidth == 2 )
|
||||
{
|
||||
int16_t *data = (int16_t *)sc->buffer;
|
||||
|
||||
if( outwidth == 1 )
|
||||
{
|
||||
int8_t *outdata = (int8_t *)sound.tempbuffer;
|
||||
|
||||
if( sc->channels == 2 )
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i*2+0] = data[((int)j)*2+0] / 256;
|
||||
outdata[i*2+1] = data[((int)j)*2+1] / 256;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i] = data[(int)j] / 256;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if( outwidth == 2 )
|
||||
{
|
||||
int16_t *outdata = (int16_t *)sound.tempbuffer;
|
||||
|
||||
if( sc->channels == 2 )
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i*2+0] = data[((int)j)*2+0];
|
||||
outdata[i*2+1] = data[((int)j)*2+1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i] = data[(int)j];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static qboolean Sound_ConvertUpsample( wavdata_t *sc, int inwidth, int outwidth, int outcount, int incount, double stepscale )
|
||||
{
|
||||
size_t i;
|
||||
double j;
|
||||
double frac;
|
||||
|
||||
incount--; // to not go past last sample while interpolating
|
||||
|
||||
if( inwidth == 1 )
|
||||
{
|
||||
int8_t *data = (int8_t *)sc->buffer;
|
||||
|
||||
if( outwidth == 1 )
|
||||
{
|
||||
int8_t *outdata = (int8_t *)sound.tempbuffer;
|
||||
|
||||
if( sc->channels == 2 )
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i*2+0] = data[((int)j)*2+0];
|
||||
outdata[i*2+1] = data[((int)j)*2+1];
|
||||
if( j != (int)j && j < incount )
|
||||
{
|
||||
frac = j - (int)j;
|
||||
outdata[i*2+0] += (data[((int)j+1)*2+0] - data[((int)j)*2+0]) * frac;
|
||||
outdata[i*2+1] += (data[((int)j+1)*2+1] - data[((int)j)*2+1]) * frac;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i] = data[(int)j];
|
||||
if( j != (int)j && j < incount )
|
||||
{
|
||||
frac = j - (int)j;
|
||||
outdata[i] += (data[(int)j+1] - data[(int)j]) * frac;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if( outwidth == 2 )
|
||||
{
|
||||
int16_t *outdata = (int16_t *)sound.tempbuffer;
|
||||
|
||||
if( sc->channels == 2 )
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i*2+0] = data[((int)j)*2+0] * 256;
|
||||
outdata[i*2+1] = data[((int)j)*2+1] * 256;
|
||||
if( j != (int)j && j < incount )
|
||||
{
|
||||
frac = ( j - (int)j ) * 256;
|
||||
outdata[i*2+0] += (data[((int)j+1)*2+0] - data[((int)j)*2+0]) * frac;
|
||||
outdata[i*2+1] += (data[((int)j+1)*2+1] - data[((int)j)*2+1]) * frac;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i] = data[(int)j] * 256;
|
||||
if( j != (int)j && j < incount )
|
||||
{
|
||||
frac = ( j - (int)j ) * 256;
|
||||
outdata[i] += (data[(int)j+1] - data[(int)j]) * frac;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if( inwidth == 2 )
|
||||
{
|
||||
int16_t *data = (int16_t *)sc->buffer;
|
||||
|
||||
if( outwidth == 1 )
|
||||
{
|
||||
int8_t *outdata = (int8_t *)sound.tempbuffer;
|
||||
|
||||
if( sc->channels == 2 )
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i*2+0] = data[((int)j)*2+0] / 256;
|
||||
outdata[i*2+1] = data[((int)j)*2+1] / 256;
|
||||
if( j != (int)j && j < incount )
|
||||
{
|
||||
frac = ( j - (int)j ) / 256;
|
||||
outdata[i*2+0] += (data[((int)j+1)*2+0] - data[((int)j)*2+0]) * frac;
|
||||
outdata[i*2+1] += (data[((int)j+1)*2+1] - data[((int)j)*2+1]) * frac;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i] = data[(int)j] / 256;
|
||||
if( j != (int)j && j < incount )
|
||||
{
|
||||
frac = ( j - (int)j ) / 256;
|
||||
outdata[i] += (data[(int)j+1] - data[(int)j]) * frac;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if( outwidth == 2 )
|
||||
{
|
||||
int16_t *outdata = (int16_t *)sound.tempbuffer;
|
||||
|
||||
if( sc->channels == 2 )
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i*2+0] = data[((int)j)*2+0];
|
||||
outdata[i*2+1] = data[((int)j)*2+1];
|
||||
if( j != (int)j && j < incount )
|
||||
{
|
||||
frac = j - (int)j;
|
||||
outdata[i*2+0] += (data[((int)j+1)*2+0] - data[((int)j)*2+0]) * frac;
|
||||
outdata[i*2+1] += (data[((int)j+1)*2+1] - data[((int)j)*2+1]) * frac;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
j = stepscale * i;
|
||||
outdata[i] = data[(int)j];
|
||||
if( j != (int)j && j < incount )
|
||||
{
|
||||
frac = j - (int)j;
|
||||
outdata[i] += (data[(int)j+1] - data[(int)j]) * frac;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
@@ -141,125 +446,70 @@ We need convert sound to signed even if nothing to resample
|
||||
*/
|
||||
static qboolean Sound_ResampleInternal( wavdata_t *sc, int inrate, int inwidth, int outrate, int outwidth )
|
||||
{
|
||||
double stepscale, j;
|
||||
int outcount;
|
||||
int i;
|
||||
const size_t oldsize = sc->size;
|
||||
qboolean handled = false;
|
||||
double stepscale;
|
||||
double t1, t2;
|
||||
int outcount, incount = sc->samples;
|
||||
|
||||
if( inrate == outrate && inwidth == outwidth )
|
||||
return false;
|
||||
|
||||
t1 = Sys_DoubleTime();
|
||||
|
||||
stepscale = (double)inrate / outrate; // this is usually 0.5, 1, or 2
|
||||
outcount = sc->samples / stepscale;
|
||||
sc->size = outcount * outwidth * sc->channels;
|
||||
|
||||
sound.tempbuffer = (byte *)Mem_Realloc( host.soundpool, sound.tempbuffer, sc->size );
|
||||
|
||||
sc->samples = outcount;
|
||||
if( sc->loopStart != -1 )
|
||||
if( FBitSet( sc->flags, SOUND_LOOPED ))
|
||||
sc->loopStart = sc->loopStart / stepscale;
|
||||
|
||||
if( inrate == outrate )
|
||||
#if 0 && XASH_SDL // slow but somewhat accurate
|
||||
{
|
||||
if( inwidth == 1 && outwidth == 2 ) // S8 to S16
|
||||
{
|
||||
for( i = 0; i < outcount * sc->channels; i++ )
|
||||
((int16_t*)sound.tempbuffer)[i] = ((int8_t *)sc->buffer)[i] * 256;
|
||||
handled = true;
|
||||
}
|
||||
else if( inwidth == 2 && outwidth == 1 ) // S16 to S8
|
||||
{
|
||||
for( i = 0; i < outcount * sc->channels; i++ )
|
||||
((int8_t*)sound.tempbuffer)[i] = ((int16_t *)sc->buffer)[i] / 256;
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
else // resample case
|
||||
{
|
||||
if( inwidth == 1 )
|
||||
{
|
||||
int8_t *data = (int8_t *)sc->buffer;
|
||||
const SDL_AudioFormat infmt = inwidth == 1 ? AUDIO_S8 : AUDIO_S16;
|
||||
const SDL_AudioFormat outfmt = outwidth == 1 ? AUDIO_S8 : AUDIO_S16;
|
||||
SDL_AudioCVT cvt;
|
||||
|
||||
if( outwidth == 1 )
|
||||
{
|
||||
if( sc->channels == 2 )
|
||||
{
|
||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
||||
{
|
||||
((int8_t*)sound.tempbuffer)[i*2+0] = data[((int)j)*2+0];
|
||||
((int8_t*)sound.tempbuffer)[i*2+1] = data[((int)j)*2+1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
||||
((int8_t*)sound.tempbuffer)[i] = data[(int)j];
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
else if( outwidth == 2 )
|
||||
{
|
||||
if( sc->channels == 2 )
|
||||
{
|
||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
||||
{
|
||||
((int16_t*)sound.tempbuffer)[i*2+0] = data[((int)j)*2+0] * 256;
|
||||
((int16_t*)sound.tempbuffer)[i*2+1] = data[((int)j)*2+1] * 256;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
||||
((int16_t*)sound.tempbuffer)[i] = data[(int)j] * 256;
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
else if( inwidth == 2 )
|
||||
// SDL_AudioCVT does conversion in place, original buffer is used for it
|
||||
if( SDL_BuildAudioCVT( &cvt, infmt, sc->channels, inrate, outfmt, sc->channels, outrate ) > 0 && cvt.needed )
|
||||
{
|
||||
int16_t *data = (int16_t *)sc->buffer;
|
||||
sc->buffer = (byte *)Mem_Realloc( host.soundpool, sc->buffer, oldsize * cvt.len_mult );
|
||||
cvt.len = oldsize;
|
||||
cvt.buf = sc->buffer;
|
||||
|
||||
if( outwidth == 1 )
|
||||
if( !SDL_ConvertAudio( &cvt ))
|
||||
{
|
||||
if( sc->channels == 2 )
|
||||
{
|
||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
||||
{
|
||||
((int8_t*)sound.tempbuffer)[i*2+0] = data[((int)j)*2+0] / 256;
|
||||
((int8_t*)sound.tempbuffer)[i*2+1] = data[((int)j)*2+1] / 256;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
||||
((int8_t*)sound.tempbuffer)[i] = data[(int)j] / 256;
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
else if( outwidth == 2 )
|
||||
{
|
||||
if( sc->channels == 2 )
|
||||
{
|
||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
||||
{
|
||||
((int16_t*)sound.tempbuffer)[i*2+0] = data[((int)j)*2+0];
|
||||
((int16_t*)sound.tempbuffer)[i*2+1] = data[((int)j)*2+1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
||||
((int16_t*)sound.tempbuffer)[i] = data[(int)j];
|
||||
}
|
||||
handled = true;
|
||||
t2 = Sys_DoubleTime();
|
||||
Con_Reportf( "Sound_Resample: from [%d bit %d Hz] to [%d bit %d Hz] (took %.3fs through SDL)\n", inwidth * 8, inrate, outwidth * 8, outrate, t2 - t1 );
|
||||
sc->rate = outrate;
|
||||
sc->width = outwidth;
|
||||
return false; // HACKHACK: return false so Sound_Process won't reallocate buffer
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
sound.tempbuffer = (byte *)Mem_Realloc( host.soundpool, sound.tempbuffer, sc->size );
|
||||
|
||||
if( inrate == outrate ) // no resampling, just copy data
|
||||
handled = Sound_ConvertNoResample( sc, inwidth, outwidth, outcount );
|
||||
else if( inrate > outrate ) // fast case, usually downsample but is also ok for upsampling
|
||||
handled = Sound_ConvertDownsample( sc, inwidth, outwidth, outcount, stepscale );
|
||||
else // upsample case, w/ interpolation
|
||||
handled = Sound_ConvertUpsample( sc, inwidth, outwidth, outcount, incount, stepscale );
|
||||
|
||||
t2 = Sys_DoubleTime();
|
||||
|
||||
if( handled )
|
||||
Con_Reportf( "Sound_Resample: from [%d bit %d Hz] to [%d bit %d Hz]\n", inwidth * 8, inrate, outwidth * 8, outrate );
|
||||
{
|
||||
if( t2 - t1 > 0.01f ) // critical, report to mod developer
|
||||
Con_Printf( S_WARN "%s: from [%d bit %d Hz] to [%d bit %d Hz] (took %.3fs)\n", __func__, inwidth * 8, inrate, outwidth * 8, outrate, t2 - t1 );
|
||||
else
|
||||
Con_Reportf( "%s: from [%d bit %d Hz] to [%d bit %d Hz] (took %.3fs)\n", __func__, inwidth * 8, inrate, outwidth * 8, outrate, t2 - t1 );
|
||||
}
|
||||
else
|
||||
Con_Reportf( S_ERROR "Sound_Resample: unsupported from [%d bit %d Hz] to [%d bit %d Hz]\n", inwidth * 8, inrate, outwidth * 8, outrate );
|
||||
Con_Printf( S_ERROR "%s: unsupported from [%d bit %d Hz] to [%d bit %d Hz]\n", __func__, inwidth * 8, inrate, outwidth * 8, outrate );
|
||||
|
||||
sc->rate = outrate;
|
||||
sc->width = outwidth;
|
||||
@@ -276,23 +526,20 @@ qboolean Sound_Process( wavdata_t **wav, int rate, int width, uint flags )
|
||||
if( !snd || !snd->buffer )
|
||||
return false;
|
||||
|
||||
if(( flags & SOUND_RESAMPLE ) && ( width > 0 || rate > 0 ))
|
||||
if( FBitSet( flags, SOUND_RESAMPLE ) && ( width > 0 || rate > 0 ))
|
||||
{
|
||||
if( Sound_ResampleInternal( snd, snd->rate, snd->width, rate, width ))
|
||||
result = Sound_ResampleInternal( snd, snd->rate, snd->width, rate, width );
|
||||
|
||||
if( result )
|
||||
{
|
||||
Mem_Free( snd->buffer ); // free original image buffer
|
||||
snd->buffer = Sound_Copy( snd->size ); // unzone buffer (don't touch image.tempbuffer)
|
||||
}
|
||||
else
|
||||
{
|
||||
// not resampled
|
||||
result = false;
|
||||
snd->buffer = Sound_Copy( snd->size ); // unzone buffer (don't touch sound.tempbuffer)
|
||||
}
|
||||
}
|
||||
|
||||
*wav = snd;
|
||||
|
||||
return false;
|
||||
return result;
|
||||
}
|
||||
|
||||
qboolean Sound_SupportedFileFormat( const char *fileext )
|
||||
|
||||
@@ -23,6 +23,11 @@ static const byte *iff_end;
|
||||
static const byte *iff_lastChunk;
|
||||
static int iff_chunkLen;
|
||||
|
||||
static int IsFourCC( const byte *ptr, const byte *fourcc )
|
||||
{
|
||||
return 0 == memcmp( ptr, fourcc, 4 );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
GetLittleShort
|
||||
@@ -86,7 +91,21 @@ static void FindNextChunk( const char *filename, const char *name )
|
||||
|
||||
if( iff_chunkLen > remaining )
|
||||
{
|
||||
Con_DPrintf( "%s: '%s' truncated by %i bytes\n", __func__, filename, iff_chunkLen - remaining );
|
||||
// only print this warning if selected chunk is truncated
|
||||
//
|
||||
// otherwise this warning becomes misleading because some
|
||||
// idiot programs like CoolEdit (i.e. Adobe Audition) don't always
|
||||
// respect pad byte. The file isn't actually truncated, it just
|
||||
// can't be reliably parsed as a whole
|
||||
|
||||
if( IsFourCC( iff_lastChunk, "RIFF" )
|
||||
|| IsFourCC( iff_lastChunk, "fmt " )
|
||||
|| IsFourCC( iff_lastChunk, "cue " )
|
||||
|| IsFourCC( iff_lastChunk, "LIST" )
|
||||
|| IsFourCC( iff_lastChunk, "data" ))
|
||||
{
|
||||
Con_DPrintf( "%s: '%s' truncated by %zi bytes\n", __func__, filename, iff_chunkLen - remaining );
|
||||
}
|
||||
iff_chunkLen = remaining;
|
||||
}
|
||||
|
||||
@@ -94,9 +113,9 @@ static void FindNextChunk( const char *filename, const char *name )
|
||||
iff_dataPtr -= 8;
|
||||
|
||||
iff_lastChunk = iff_dataPtr + 8 + iff_chunkLen;
|
||||
if ((iff_chunkLen&1) && remaining)
|
||||
if(( iff_chunkLen & 1 ) && remaining )
|
||||
iff_lastChunk++;
|
||||
if (!Q_strncmp(iff_dataPtr, name, 4))
|
||||
if( IsFourCC( iff_dataPtr, name ))
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -130,15 +149,18 @@ static qboolean StreamFindNextChunk( file_t *file, const char *name, int *last_c
|
||||
return false; // didn't find the chunk
|
||||
|
||||
FS_Seek( file, 4, SEEK_CUR );
|
||||
FS_Read( file, &iff_chunk_len, sizeof( iff_chunk_len ));
|
||||
if( FS_Read( file, &iff_chunk_len, sizeof( iff_chunk_len )) != sizeof( iff_chunk_len ))
|
||||
return false;
|
||||
|
||||
if( iff_chunk_len < 0 )
|
||||
return false; // didn't find the chunk
|
||||
|
||||
FS_Seek( file, -8, SEEK_CUR );
|
||||
*last_chunk = FS_Tell( file ) + 8 + (( iff_chunk_len + 1 ) & ~1 );
|
||||
FS_Read( file, chunkName, 4 );
|
||||
if( FS_Read( file, chunkName, sizeof( chunkName )) != sizeof( chunkName ))
|
||||
return false;
|
||||
|
||||
if( !Q_strncmp( chunkName, name, 4 ))
|
||||
if( IsFourCC( chunkName, name ))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -164,9 +186,9 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
// find "RIFF" chunk
|
||||
FindChunk( name, "RIFF" );
|
||||
|
||||
if( !( iff_dataPtr && !Q_strncmp( (const char *)iff_dataPtr + 8, "WAVE", 4 )))
|
||||
if( !iff_dataPtr || !IsFourCC( iff_dataPtr + 8, "WAVE" ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Sound_LoadWAV: %s missing 'RIFF/WAVE' chunks\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: %s missing 'RIFF/WAVE' chunks\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -176,7 +198,7 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
if( !iff_dataPtr )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Sound_LoadWAV: %s missing 'fmt ' chunk\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: %s missing 'fmt ' chunk\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -187,7 +209,7 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
{
|
||||
if( fmt != 85 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Sound_LoadWAV: %s not a microsoft PCM format\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: %s not a microsoft PCM format\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@@ -200,7 +222,7 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
sound.channels = GetLittleShort();
|
||||
if( sound.channels != 1 && sound.channels != 2 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Sound_LoadWAV: only mono and stereo WAV files supported (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: only mono and stereo WAV files supported (%s)\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -212,7 +234,7 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
if( sound.width != 1 && sound.width != 2 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Sound_LoadWAV: only 8 and 16 bit WAV files supported (%s)\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: only 8 and 16 bit WAV files supported (%s)\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -223,11 +245,12 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
{
|
||||
iff_dataPtr += 32;
|
||||
sound.loopstart = GetLittleLong();
|
||||
SetBits( sound.flags, SOUND_LOOPED );
|
||||
FindNextChunk( name, "LIST" ); // if the next chunk is a LIST chunk, look for a cue length marker
|
||||
|
||||
if( iff_dataPtr )
|
||||
{
|
||||
if( !Q_strncmp( (const char *)iff_dataPtr + 28, "mark", 4 ))
|
||||
if( IsFourCC( iff_dataPtr + 28, "mark" ))
|
||||
{
|
||||
// this is not a proper parse, but it works with CoolEdit...
|
||||
iff_dataPtr += 24;
|
||||
@@ -237,7 +260,7 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
}
|
||||
else
|
||||
{
|
||||
sound.loopstart = -1;
|
||||
sound.loopstart = 0;
|
||||
sound.samples = 0;
|
||||
}
|
||||
|
||||
@@ -246,7 +269,7 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
if( !iff_dataPtr )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Sound_LoadWAV: %s missing 'data' chunk\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: %s missing 'data' chunk\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -257,7 +280,7 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
{
|
||||
if( samples < sound.samples )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Sound_LoadWAV: %s has a bad loop length\n", name );
|
||||
Con_DPrintf( S_ERROR "%s: %s has a bad loop length\n", __func__, name );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -265,7 +288,7 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
if( sound.samples <= 0 )
|
||||
{
|
||||
Con_Reportf( S_ERROR "Sound_LoadWAV: file with %i samples (%s)\n", sound.samples, name );
|
||||
Con_Reportf( S_ERROR "%s: file with %i samples (%s)\n", __func__, sound.samples, name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -337,25 +360,33 @@ stream_t *Stream_OpenWAV( const char *filename )
|
||||
// find "RIFF" chunk
|
||||
if( !StreamFindNextChunk( file, "RIFF", &last_chunk ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Stream_OpenWAV: %s missing RIFF chunk\n", filename );
|
||||
Con_DPrintf( S_ERROR "%s: %s missing RIFF chunk\n", __func__, filename );
|
||||
FS_Close( file );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FS_Read( file, chunkName, 4 );
|
||||
if( !Q_strncmp( chunkName, "WAVE", 4 ))
|
||||
FS_Seek( file, 4, SEEK_CUR );
|
||||
|
||||
if( FS_Read( file, chunkName, 4 ) != 4 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Stream_OpenWAV: %s missing WAVE chunk\n", filename );
|
||||
Con_DPrintf( S_ERROR "%s: %s missing WAVE chunk, truncated\n", __func__, filename );
|
||||
FS_Close( file );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !IsFourCC( chunkName, "WAVE" ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: %s missing WAVE chunk\n", __func__, filename );
|
||||
FS_Close( file );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// get "fmt " chunk
|
||||
iff_data = FS_Tell( file ) + 4;
|
||||
iff_data = FS_Tell( file );
|
||||
last_chunk = iff_data;
|
||||
if( !StreamFindNextChunk( file, "fmt ", &last_chunk ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Stream_OpenWAV: %s missing 'fmt ' chunk\n", filename );
|
||||
Con_DPrintf( S_ERROR "%s: %s missing 'fmt ' chunk\n", __func__, filename );
|
||||
FS_Close( file );
|
||||
return NULL;
|
||||
}
|
||||
@@ -365,7 +396,7 @@ stream_t *Stream_OpenWAV( const char *filename )
|
||||
FS_Read( file, &t, sizeof( t ));
|
||||
if( t != 1 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Stream_OpenWAV: %s not a microsoft PCM format\n", filename );
|
||||
Con_DPrintf( S_ERROR "%s: %s not a microsoft PCM format\n", __func__, filename );
|
||||
FS_Close( file );
|
||||
return NULL;
|
||||
}
|
||||
@@ -386,7 +417,7 @@ stream_t *Stream_OpenWAV( const char *filename )
|
||||
last_chunk = iff_data;
|
||||
if( !StreamFindNextChunk( file, "data", &last_chunk ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Stream_OpenWAV: %s missing 'data' chunk\n", filename );
|
||||
Con_DPrintf( S_ERROR "%s: %s missing 'data' chunk\n", __func__, filename );
|
||||
FS_Close( file );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ typedef struct sndlib_s
|
||||
int rate; // num samples per second (e.g. 11025 - 11 khz)
|
||||
int width; // resolution - bum bits divided by 8 (8 bit is 1, 16 bit is 2)
|
||||
int channels; // num channels (1 - mono, 2 - stereo)
|
||||
int loopstart; // start looping from
|
||||
uint loopstart; // start looping from
|
||||
uint samples; // total samplecount in sound
|
||||
uint flags; // additional sound flags
|
||||
size_t size; // sound unpacked size (for bounds checking)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user