Merge branch 'master' into jgrpp
# Conflicts: # CMakeLists.txt # src/3rdparty/md5/md5.h # src/3rdparty/squirrel/squirrel/squtils.h # src/animated_tile.cpp # src/console_func.h # src/core/CMakeLists.txt # src/core/container_func.hpp # src/core/smallstack_type.hpp # src/crashlog.cpp # src/crashlog.h # src/debug.h # src/economy.cpp # src/gamelog.cpp # src/industry_gui.cpp # src/lang/catalan.txt # src/misc_gui.cpp # src/network/network_content.h # src/newgrf.cpp # src/newgrf.h # src/newgrf_config.cpp # src/newgrf_config.h # src/newgrf_gui.cpp # src/os/unix/font_unix.cpp # src/os/windows/crashlog_win.cpp # src/rail_cmd.cpp # src/saveload/animated_tile_sl.cpp # src/script/api/script_tilelist.cpp # src/settings.cpp # src/settingsgen/settingsgen.cpp # src/sl/oldloader_sl.cpp # src/station.cpp # src/station_cmd.cpp # src/stdafx.h # src/strgen/strgen.cpp # src/strgen/strgen_base.cpp # src/table/settings/gui_settings.ini # src/train_gui.cpp # src/vehicle.cpp # src/vehicle_base.h # src/vehicle_cmd.cpp # src/vehicle_gui_base.h # src/viewport_sprite_sorter.h
This commit is contained in:
232
.editorconfig
232
.editorconfig
@@ -147,15 +147,15 @@ cpp_wrap_preserve_blocks = never
|
|||||||
#cpp_keep_blank_lines_in_code
|
#cpp_keep_blank_lines_in_code
|
||||||
# No override for "Number of blank lines around class/struct/enum definition" (Unspecified; Not consistent across source code)
|
# No override for "Number of blank lines around class/struct/enum definition" (Unspecified; Not consistent across source code)
|
||||||
#cpp_blank_lines_around_class_definition
|
#cpp_blank_lines_around_class_definition
|
||||||
# No override for "Number of blank lines around function declarations" (Unspecified; Not consistent across source code)
|
# No override for "Number of blank lines around function declarations" (Unspecified; Not consistent across source code)
|
||||||
#cpp_blank_lines_around_function_declaration
|
#cpp_blank_lines_around_function_declaration
|
||||||
# No override for "Number of blank lines around function definitions" (Unspecified; Not consistent across source code)
|
# No override for "Number of blank lines around function definitions" (Unspecified; Not consistent across source code)
|
||||||
#cpp_blank_lines_around_function_definition
|
#cpp_blank_lines_around_function_definition
|
||||||
# No override for "Number of blank lines around single line function definitions" (Unspecified; Not consistent across source code)
|
# No override for "Number of blank lines around single line function definitions" (Unspecified; Not consistent across source code)
|
||||||
#cpp_blank_lines_around_single_line_function_definition
|
#cpp_blank_lines_around_single_line_function_definition
|
||||||
# No override for "Number of blank lines around namespaces" (Unspecified; Not consistent across source code)
|
# No override for "Number of blank lines around namespaces" (Unspecified; Not consistent across source code)
|
||||||
#cpp_blank_lines_around_namespace
|
#cpp_blank_lines_around_namespace
|
||||||
# No override for "Number of blank lines around other definitions and declarations" (Unspecified; Not consistent across source code)
|
# No override for "Number of blank lines around other definitions and declarations" (Unspecified; Not consistent across source code)
|
||||||
#cpp_blank_lines_around_other_declaration
|
#cpp_blank_lines_around_other_declaration
|
||||||
|
|
||||||
# Braces Layout #
|
# Braces Layout #
|
||||||
@@ -201,69 +201,69 @@ cpp_alignment_tab_fill_style = use_spaces
|
|||||||
cpp_allow_far_alignment = true
|
cpp_allow_far_alignment = true
|
||||||
|
|
||||||
# Indentation and Alignment #
|
# Indentation and Alignment #
|
||||||
# No override for "Continuous line indent" (Varies throughout source code)
|
# No override for "Continuous line indent" (Varies throughout source code)
|
||||||
#cpp_continuous_line_indent
|
#cpp_continuous_line_indent
|
||||||
# Do not use continuous line indent in function declaration and invocation parentheses
|
# Do not use continuous line indent in function declaration and invocation parentheses
|
||||||
cpp_use_continuous_line_indent_in_method_pars = false
|
cpp_use_continuous_line_indent_in_method_pars = false
|
||||||
# Do not use continuous line indent in initializer lists
|
# Do not use continuous line indent in initializer lists
|
||||||
cpp_use_continuous_line_indent_in_expression_braces = false
|
cpp_use_continuous_line_indent_in_expression_braces = false
|
||||||
# Indent namespace members (including nested ones)
|
# Indent namespace members (including nested ones)
|
||||||
cpp_namespace_indentation = all
|
cpp_namespace_indentation = all
|
||||||
# No override for "Indent linkage specification block members" (Unspecified)
|
# No override for "Indent linkage specification block members" (Unspecified)
|
||||||
#cpp_linkage_specification_indentation
|
#cpp_linkage_specification_indentation
|
||||||
# Do not indent access specifier from class
|
# Do not indent access specifier from class
|
||||||
cpp_indent_access_specifiers_from_class = false
|
cpp_indent_access_specifiers_from_class = false
|
||||||
# Indent class member from access specifier
|
# Indent class member from access specifier
|
||||||
cpp_indent_class_members_from_access_specifiers = true
|
cpp_indent_class_members_from_access_specifiers = true
|
||||||
# Do not indent if a function definition or declaration is wrapped after the type
|
# Do not indent if a function definition or declaration is wrapped after the type
|
||||||
cpp_indent_wrapped_function_names = false
|
cpp_indent_wrapped_function_names = false
|
||||||
# Indent 'case' labels from 'switch'
|
# Indent 'case' labels from 'switch'
|
||||||
cpp_indent_switch_labels = true
|
cpp_indent_switch_labels = true
|
||||||
# No override for "Indent function declarations' parentheses" (Varies throughout source code)
|
# No override for "Indent function declarations' parentheses" (Varies throughout source code)
|
||||||
#cpp_indent_method_decl_pars
|
#cpp_indent_method_decl_pars
|
||||||
# No override for "Indent method calls' parentheses" (Varies throughout source code)
|
# No override for "Indent method calls' parentheses" (Varies throughout source code)
|
||||||
#cpp_indent_invocation_pars
|
#cpp_indent_invocation_pars
|
||||||
# No override for "Indent statement (if, while, for, etc) parentheses" (Varies throughout source code)
|
# No override for "Indent statement (if, while, for, etc) parentheses" (Varies throughout source code)
|
||||||
#cpp_indent_statement_pars
|
#cpp_indent_statement_pars
|
||||||
# Do not change preprocessor directives indenting
|
# Do not change preprocessor directives indenting
|
||||||
cpp_indent_preprocessor_directives = do_not_change
|
cpp_indent_preprocessor_directives = do_not_change
|
||||||
# No override for "Indent C++/CLI generic constraints" (C++/CLI is not used)
|
# No override for "Indent C++/CLI generic constraints" (C++/CLI is not used)
|
||||||
#cpp_indent_type_constraints
|
#cpp_indent_type_constraints
|
||||||
# Align/indent comments started at the first column
|
# Align/indent comments started at the first column
|
||||||
cpp_indent_comment = true
|
cpp_indent_comment = true
|
||||||
# Comments that comment out code will use the indentation level of the commented code.
|
# Comments that comment out code will use the indentation level of the commented code.
|
||||||
cpp_place_comments_at_first_column = false
|
cpp_place_comments_at_first_column = false
|
||||||
# Align multiline declarators in declaration
|
# Align multiline declarators in declaration
|
||||||
cpp_align_multiple_declaration = true
|
cpp_align_multiple_declaration = true
|
||||||
# Align multiline function parameters
|
# Align multiline function parameters
|
||||||
cpp_align_multiline_parameter = true
|
cpp_align_multiline_parameter = true
|
||||||
# Align multiline call arguments
|
# Align multiline call arguments
|
||||||
cpp_align_multiline_argument = true
|
cpp_align_multiline_argument = true
|
||||||
# Do not align first of multiline call arguments with the opening parentheses
|
# Do not align first of multiline call arguments with the opening parentheses
|
||||||
cpp_align_first_arg_by_paren = false
|
cpp_align_first_arg_by_paren = false
|
||||||
# Align multiline initializer list arguments
|
# Align multiline initializer list arguments
|
||||||
cpp_align_multiline_expression_brace = true
|
cpp_align_multiline_expression_brace = true
|
||||||
# No override for "Align multiline template parameters in template declaration" (Unspecified)
|
# No override for "Align multiline template parameters in template declaration" (Unspecified)
|
||||||
#cpp_align_multiline_type_parameter
|
#cpp_align_multiline_type_parameter
|
||||||
# No override for "Align multiline template arguments" (Unspecified)
|
# No override for "Align multiline template arguments" (Unspecified)
|
||||||
#cpp_align_multiline_type_argument
|
#cpp_align_multiline_type_argument
|
||||||
# Align multiline base classes in class base clause
|
# Align multiline base classes in class base clause
|
||||||
cpp_align_multiline_extends_list = true
|
cpp_align_multiline_extends_list = true
|
||||||
# Align multiline member initializers in member initializer lists
|
# Align multiline member initializers in member initializer lists
|
||||||
cpp_align_multiline_ctor_init = true
|
cpp_align_multiline_ctor_init = true
|
||||||
# Outdent commas placed on new line
|
# Outdent commas placed on new line
|
||||||
cpp_outdent_commas = true
|
cpp_outdent_commas = true
|
||||||
# Do not align multiline ?: operator with first line (since alignment is incorrect)
|
# Do not align multiline ?: operator with first line (since alignment is incorrect)
|
||||||
cpp_align_ternary = none
|
cpp_align_ternary = none
|
||||||
# Do not indent aligned ?: operator (since indentation varies)
|
# Do not indent aligned ?: operator (since indentation varies)
|
||||||
cpp_indent_aligned_ternary = false
|
cpp_indent_aligned_ternary = false
|
||||||
# No override for "Align multiline chained method calls" (Unspecified)
|
# No override for "Align multiline chained method calls" (Unspecified)
|
||||||
#cpp_align_multiline_calls_chain
|
#cpp_align_multiline_calls_chain
|
||||||
# No override for "Outdent '.' and '->' in chained method calls on new lines" (Unspecified)
|
# No override for "Outdent '.' and '->' in chained method calls on new lines" (Unspecified)
|
||||||
#cpp_outdent_dots
|
#cpp_outdent_dots
|
||||||
# Do not align multiline chained binary expressions
|
# Do not align multiline chained binary expressions
|
||||||
cpp_align_multiline_binary_expressions_chain = false
|
cpp_align_multiline_binary_expressions_chain = false
|
||||||
# Fix column alignment in adjacent lines
|
# Fix column alignment in adjacent lines
|
||||||
cpp_int_align_fix_in_adjacent = true
|
cpp_int_align_fix_in_adjacent = true
|
||||||
# Align assignments with adjacent assignments
|
# Align assignments with adjacent assignments
|
||||||
cpp_int_align_eq = true
|
cpp_int_align_eq = true
|
||||||
@@ -277,121 +277,121 @@ cpp_int_align_comments = true
|
|||||||
cpp_space_before_comma = false
|
cpp_space_before_comma = false
|
||||||
# Put space after ALL commas
|
# Put space after ALL commas
|
||||||
cpp_space_after_comma = true
|
cpp_space_after_comma = true
|
||||||
# Put space before ptr in declaration of variable
|
# Put space before ptr in declaration of variable
|
||||||
cpp_space_before_ptr_in_data_member = true
|
cpp_space_before_ptr_in_data_member = true
|
||||||
# Do not put space after ptr in declaration of variable
|
# Do not put space after ptr in declaration of variable
|
||||||
cpp_space_after_ptr_in_data_member = false
|
cpp_space_after_ptr_in_data_member = false
|
||||||
# Put space before ptr in declaration of multiple variables
|
# Put space before ptr in declaration of multiple variables
|
||||||
cpp_space_before_ptr_in_data_members = true
|
cpp_space_before_ptr_in_data_members = true
|
||||||
# Do not put space after ptr in declaration of multiple variables
|
# Do not put space after ptr in declaration of multiple variables
|
||||||
cpp_space_after_ptr_in_data_members = false
|
cpp_space_after_ptr_in_data_members = false
|
||||||
# Put space before ptr in return type of function
|
# Put space before ptr in return type of function
|
||||||
cpp_space_before_ptr_in_method = true
|
cpp_space_before_ptr_in_method = true
|
||||||
# Do not put space after ptr in return type of function
|
# Do not put space after ptr in return type of function
|
||||||
cpp_space_after_ptr_in_method = false
|
cpp_space_after_ptr_in_method = false
|
||||||
# Do not put space before ptr in abstract declaration
|
# Do not put space before ptr in abstract declaration
|
||||||
cpp_space_before_ptr_in_abstract_decl = false
|
cpp_space_before_ptr_in_abstract_decl = false
|
||||||
# Put space before ref in declaration of variable
|
# Put space before ref in declaration of variable
|
||||||
cpp_space_before_ref_in_data_member = true
|
cpp_space_before_ref_in_data_member = true
|
||||||
# Do not put space after ref in declaration of variable
|
# Do not put space after ref in declaration of variable
|
||||||
cpp_space_after_ref_in_data_member = false
|
cpp_space_after_ref_in_data_member = false
|
||||||
# Put space before ref in declaration of multiple variables
|
# Put space before ref in declaration of multiple variables
|
||||||
cpp_space_before_ref_in_data_members = true
|
cpp_space_before_ref_in_data_members = true
|
||||||
# Do not put space after ref in declaration of multiple variables
|
# Do not put space after ref in declaration of multiple variables
|
||||||
cpp_space_after_ref_in_data_members = false
|
cpp_space_after_ref_in_data_members = false
|
||||||
# Do not put space before ref in return type of function
|
# Do not put space before ref in return type of function
|
||||||
cpp_space_before_ref_in_method = false
|
cpp_space_before_ref_in_method = false
|
||||||
# Put space after ref in return type of function
|
# Put space after ref in return type of function
|
||||||
cpp_space_after_ref_in_method = true
|
cpp_space_after_ref_in_method = true
|
||||||
# Do not put space before ref in abstract declaration
|
# Do not put space before ref in abstract declaration
|
||||||
cpp_space_before_ref_in_abstract_decl = false
|
cpp_space_before_ref_in_abstract_decl = false
|
||||||
# Do not put space before parentheses in function parameters
|
# Do not put space before parentheses in function parameters
|
||||||
cpp_space_between_method_declaration_name_and_open_parenthesis = false
|
cpp_space_between_method_declaration_name_and_open_parenthesis = false
|
||||||
# Do not put space before parentheses in lambda parameters
|
# Do not put space before parentheses in lambda parameters
|
||||||
cpp_space_before_lambda_parentheses = false
|
cpp_space_before_lambda_parentheses = false
|
||||||
# Do not put space within parentheses in function parameters
|
# Do not put space within parentheses in function parameters
|
||||||
cpp_space_between_method_declaration_parameter_list_parentheses = false
|
cpp_space_between_method_declaration_parameter_list_parentheses = false
|
||||||
# Do not put space within empty parentheses in function parameters
|
# Do not put space within empty parentheses in function parameters
|
||||||
cpp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
cpp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||||
# Do not put space before angle brackets in template parameters
|
# Do not put space before angle brackets in template parameters
|
||||||
cpp_space_before_template_params = false
|
cpp_space_before_template_params = false
|
||||||
# Do not put space within angle brackets in template parameters
|
# Do not put space within angle brackets in template parameters
|
||||||
cpp_space_within_template_params = false
|
cpp_space_within_template_params = false
|
||||||
# Do not put space within empty angle brackets in template parameters
|
# Do not put space within empty angle brackets in template parameters
|
||||||
cpp_space_within_empty_template_params = false
|
cpp_space_within_empty_template_params = false
|
||||||
# Do not put space before angle brackets in template arguments
|
# Do not put space before angle brackets in template arguments
|
||||||
cpp_space_before_template_args = false
|
cpp_space_before_template_args = false
|
||||||
# Do not put space within angle brackets in template arguments
|
# Do not put space within angle brackets in template arguments
|
||||||
cpp_space_within_template_args = false
|
cpp_space_within_template_args = false
|
||||||
# Do not put space between closing angle brackets in template arguments
|
# Do not put space between closing angle brackets in template arguments
|
||||||
cpp_space_between_closing_angle_brackets_in_template_args = false
|
cpp_space_between_closing_angle_brackets_in_template_args = false
|
||||||
# Put space around '=' in alias declaration and namespace alias
|
# Put space around '=' in alias declaration and namespace alias
|
||||||
cpp_space_around_alias_eq = true
|
cpp_space_around_alias_eq = true
|
||||||
# Do not put space around '->' in trailing return types
|
# Do not put space around '->' in trailing return types
|
||||||
cpp_space_around_deref_in_trailing_return_type = false
|
cpp_space_around_deref_in_trailing_return_type = false
|
||||||
# Put space before base types list colon
|
# Put space before base types list colon
|
||||||
cpp_space_before_colon_in_inheritance_clause = true
|
cpp_space_before_colon_in_inheritance_clause = true
|
||||||
# Put space after base types list colon
|
# Put space after base types list colon
|
||||||
cpp_space_after_colon_in_inheritance_clause = true
|
cpp_space_after_colon_in_inheritance_clause = true
|
||||||
# No override for "Before C++/CLI generic constraint colon" (Unspecified)
|
# No override for "Before C++/CLI generic constraint colon" (Unspecified)
|
||||||
#cpp_space_before_type_parameter_constraint_colon
|
#cpp_space_before_type_parameter_constraint_colon
|
||||||
# No override for "After C++/CLI generic constraint colon" (Unspecified)
|
# No override for "After C++/CLI generic constraint colon" (Unspecified)
|
||||||
#cpp_space_after_type_parameter_constraint_colon
|
#cpp_space_after_type_parameter_constraint_colon
|
||||||
# Put space before parentheses of control statements
|
# Put space before parentheses of control statements
|
||||||
cpp_space_after_keywords_in_control_flow_statements = true
|
cpp_space_after_keywords_in_control_flow_statements = true
|
||||||
# Do not put space within parentheses of control statements
|
# Do not put space within parentheses of control statements
|
||||||
cpp_space_between_parentheses_of_control_flow_statements = false
|
cpp_space_between_parentheses_of_control_flow_statements = false
|
||||||
# Do not put space before semicolon in 'for' statements
|
# Do not put space before semicolon in 'for' statements
|
||||||
cpp_space_before_semicolon_in_for_statement = false
|
cpp_space_before_semicolon_in_for_statement = false
|
||||||
# Put space after semicolon in 'for' statements
|
# Put space after semicolon in 'for' statements
|
||||||
cpp_space_after_semicolon_in_for_statement = true
|
cpp_space_after_semicolon_in_for_statement = true
|
||||||
# Put space before ':' in range-based for loop
|
# Put space before ':' in range-based for loop
|
||||||
cpp_space_before_for_colon = true
|
cpp_space_before_for_colon = true
|
||||||
# Put space after ':' in range-based for loop
|
# Put space after ':' in range-based for loop
|
||||||
cpp_space_after_for_colon = true
|
cpp_space_after_for_colon = true
|
||||||
# Do not put space before colon in switch case or label statement
|
# Do not put space before colon in switch case or label statement
|
||||||
cpp_space_before_colon_in_case = false
|
cpp_space_before_colon_in_case = false
|
||||||
# Put space after colon in switch case or label statement
|
# Put space after colon in switch case or label statement
|
||||||
cpp_space_after_colon_in_case = true
|
cpp_space_after_colon_in_case = true
|
||||||
# Put space around binary operator
|
# Put space around binary operator
|
||||||
cpp_space_around_binary_operator = true
|
cpp_space_around_binary_operator = true
|
||||||
# Put space around assignment operator
|
# Put space around assignment operator
|
||||||
cpp_space_around_assignment_operator = true
|
cpp_space_around_assignment_operator = true
|
||||||
# Do not put space around dot, '->', '.*' and '->.'
|
# Do not put space around dot, '->', '.*' and '->.'
|
||||||
cpp_space_around_member_access_operator = false
|
cpp_space_around_member_access_operator = false
|
||||||
# Do not put space within any parentheses
|
# Do not put space within any parentheses
|
||||||
cpp_space_within_parentheses = false
|
cpp_space_within_parentheses = false
|
||||||
# Do not put space before array subscript brackets
|
# Do not put space before array subscript brackets
|
||||||
cpp_space_before_open_square_brackets = false
|
cpp_space_before_open_square_brackets = false
|
||||||
# Do not put space within array subscript brackets
|
# Do not put space within array subscript brackets
|
||||||
cpp_space_between_square_brackets = false
|
cpp_space_between_square_brackets = false
|
||||||
# Do not put space before empty parentheses in function call and initialization
|
# Do not put space before empty parentheses in function call and initialization
|
||||||
cpp_space_between_method_call_name_and_opening_parenthesis = false
|
cpp_space_between_method_call_name_and_opening_parenthesis = false
|
||||||
# Do not put space within parentheses in cast expressions
|
# Do not put space within parentheses in cast expressions
|
||||||
cpp_space_between_typecast_parentheses = false
|
cpp_space_between_typecast_parentheses = false
|
||||||
# Do not put space after parentheses in cast expressions
|
# Do not put space after parentheses in cast expressions
|
||||||
cpp_space_after_cast = false
|
cpp_space_after_cast = false
|
||||||
# Do not put space within parentheses in function call and initialization
|
# Do not put space within parentheses in function call and initialization
|
||||||
cpp_space_between_method_call_parameter_list_parentheses = false
|
cpp_space_between_method_call_parameter_list_parentheses = false
|
||||||
# Do not put space within empty parentheses in function call and initialization
|
# Do not put space within empty parentheses in function call and initialization
|
||||||
cpp_space_between_method_call_empty_parameter_list_parentheses = false
|
cpp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||||
# Put space in ternary operator '? :' before '?'
|
# Put space in ternary operator '? :' before '?'
|
||||||
cpp_space_before_ternary_quest = true
|
cpp_space_before_ternary_quest = true
|
||||||
# Put space in ternary operator '? :' after '?'
|
# Put space in ternary operator '? :' after '?'
|
||||||
cpp_space_after_ternary_quest = true
|
cpp_space_after_ternary_quest = true
|
||||||
# Put space in ternary operator '? :' before ':'
|
# Put space in ternary operator '? :' before ':'
|
||||||
cpp_space_before_ternary_colon = true
|
cpp_space_before_ternary_colon = true
|
||||||
# Put space in ternary operator '? :' after ':'
|
# Put space in ternary operator '? :' after ':'
|
||||||
cpp_space_after_ternary_colon = true
|
cpp_space_after_ternary_colon = true
|
||||||
# Do not put space before uniform initialization braces
|
# Do not put space before uniform initialization braces
|
||||||
cpp_space_before_initializer_braces = false
|
cpp_space_before_initializer_braces = false
|
||||||
# Do not put space within uniform initialization braces
|
# Do not put space within uniform initialization braces
|
||||||
cpp_space_within_initializer_braces = false
|
cpp_space_within_initializer_braces = false
|
||||||
# Do not put space within empty uniform initialization braces
|
# Do not put space within empty uniform initialization braces
|
||||||
cpp_space_within_empty_initializer_braces = false
|
cpp_space_within_empty_initializer_braces = false
|
||||||
# Put space before end of line comment
|
# Put space before end of line comment
|
||||||
cpp_space_before_trailing_comment = true
|
cpp_space_before_trailing_comment = true
|
||||||
# Preserve spaces before end of line comment
|
# Preserve spaces before end of line comment
|
||||||
cpp_disable_space_changes_before_trailing_comment = true
|
cpp_disable_space_changes_before_trailing_comment = true
|
||||||
|
|
||||||
# Line breaks and Wrapping #
|
# Line breaks and Wrapping #
|
||||||
@@ -403,75 +403,75 @@ cpp_disable_space_changes_before_trailing_comment = true
|
|||||||
cpp_new_line_before_while = false
|
cpp_new_line_before_while = false
|
||||||
# Redundant override (Already overriden earlier in Visual Studio section)
|
# Redundant override (Already overriden earlier in Visual Studio section)
|
||||||
#cpp_new_line_before_catch
|
#cpp_new_line_before_catch
|
||||||
# Do not change the line breaks of single embedded statements
|
# Do not change the line breaks of single embedded statements
|
||||||
cpp_simple_embedded_statement_style = do_not_change
|
cpp_simple_embedded_statement_style = do_not_change
|
||||||
# Do not change the line breaks of simple 'case' statement
|
# Do not change the line breaks of simple 'case' statement
|
||||||
cpp_simple_case_statement_style = do_not_change
|
cpp_simple_case_statement_style = do_not_change
|
||||||
# Put member function definition return type on same line
|
# Put member function definition return type on same line
|
||||||
cpp_function_definition_return_type_style = on_single_line
|
cpp_function_definition_return_type_style = on_single_line
|
||||||
# Put top-level function definition return type on same line
|
# Put top-level function definition return type on same line
|
||||||
cpp_toplevel_function_definition_return_type_style = on_single_line
|
cpp_toplevel_function_definition_return_type_style = on_single_line
|
||||||
# Put member function declaration return type on same line
|
# Put member function declaration return type on same line
|
||||||
cpp_function_declaration_return_type_style = on_single_line
|
cpp_function_declaration_return_type_style = on_single_line
|
||||||
# Put top-level function declaration return type on same line
|
# Put top-level function declaration return type on same line
|
||||||
cpp_toplevel_function_declaration_return_type_style = on_single_line
|
cpp_toplevel_function_declaration_return_type_style = on_single_line
|
||||||
# Force template<...> of a template declaration on new line
|
# Force template<...> of a template declaration on new line
|
||||||
cpp_break_template_declaration = line_break
|
cpp_break_template_declaration = line_break
|
||||||
# No override for "Break line before the requires-clause" (requires-clause is a C++20 feature)
|
# No override for "Break line before the requires-clause" (requires-clause is a C++20 feature)
|
||||||
#cpp_line_break_before_requires_clause
|
#cpp_line_break_before_requires_clause
|
||||||
# Do not change the line break before the colon in member initializer lists
|
# Do not change the line break before the colon in member initializer lists
|
||||||
cpp_member_initializer_list_style = do_not_change
|
cpp_member_initializer_list_style = do_not_change
|
||||||
# Do not change the line break after the colon in member initializer lists
|
# Do not change the line break after the colon in member initializer lists
|
||||||
cpp_line_break_after_colon_in_member_initializer_lists = do_not_change
|
cpp_line_break_after_colon_in_member_initializer_lists = do_not_change
|
||||||
# No override for "Break line before comma in member initializer lists" (Varies throughout source code)
|
# No override for "Break line before comma in member initializer lists" (Varies throughout source code)
|
||||||
#cpp_line_break_before_comma_in_member_initializer_lists
|
#cpp_line_break_before_comma_in_member_initializer_lists
|
||||||
# No override for "Break line after comma in member initializer lists" (Varies throughout source code)
|
# No override for "Break line after comma in member initializer lists" (Varies throughout source code)
|
||||||
#cpp_line_break_after_comma_in_member_initializer_lists
|
#cpp_line_break_after_comma_in_member_initializer_lists
|
||||||
# No override for "Allow C++/CLI generic constraints on the same line" (C++/CLI is not used)
|
# No override for "Allow C++/CLI generic constraints on the same line" (C++/CLI is not used)
|
||||||
#cpp_place_type_constraints_on_same_line
|
#cpp_place_type_constraints_on_same_line
|
||||||
# No override for "Keep existing line breaks" (Varies throughout source code; depends on developer preference)
|
# No override for "Keep existing line breaks" (Varies throughout source code; depends on developer preference)
|
||||||
#cpp_keep_user_linebreaks
|
#cpp_keep_user_linebreaks
|
||||||
# No override for "Hard wrap at _ characters" (Unspecified)
|
# No override for "Hard wrap at _ characters" (Unspecified)
|
||||||
#cpp_max_line_length
|
#cpp_max_line_length
|
||||||
# Do not prefer wrap before ','
|
# Do not prefer wrap before ','
|
||||||
cpp_wrap_before_comma = false
|
cpp_wrap_before_comma = false
|
||||||
# Do not prefer wrap before ',' in base clause
|
# Do not prefer wrap before ',' in base clause
|
||||||
cpp_wrap_before_comma_in_base_clause = false
|
cpp_wrap_before_comma_in_base_clause = false
|
||||||
# No override for "Wrap ternary expression" (Varies throughout source code)
|
# No override for "Wrap ternary expression" (Varies throughout source code)
|
||||||
#cpp_wrap_ternary_expr_style
|
#cpp_wrap_ternary_expr_style
|
||||||
# No override for "Prefer wrap before '?' and ':' in ternary expressions" (Varies throughout source code)
|
# No override for "Prefer wrap before '?' and ':' in ternary expressions" (Varies throughout source code)
|
||||||
#cpp_wrap_before_ternary_opsigns
|
#cpp_wrap_before_ternary_opsigns
|
||||||
# No override for "Prefer wrap before ':'" (Varies throughout source code)
|
# No override for "Prefer wrap before ':'" (Varies throughout source code)
|
||||||
#cpp_wrap_before_colon
|
#cpp_wrap_before_colon
|
||||||
# No override for "Prefer wrap before first C++/CLI generic constraint" (C++/CLI is not used)
|
# No override for "Prefer wrap before first C++/CLI generic constraint" (C++/CLI is not used)
|
||||||
#cpp_wrap_before_first_type_parameter_constraint
|
#cpp_wrap_before_first_type_parameter_constraint
|
||||||
# No override for "Wrap multiple C++/CLI generic constraints" (C++/CLI is not used)
|
# No override for "Wrap multiple C++/CLI generic constraints" (C++/CLI is not used)
|
||||||
#cpp_wrap_multiple_type_parameter_constraints_style
|
#cpp_wrap_multiple_type_parameter_constraints_style
|
||||||
# No override for "Wrap enum definition" (Varies throughout source code)
|
# No override for "Wrap enum definition" (Varies throughout source code)
|
||||||
#cpp_wrap_enumeration_style
|
#cpp_wrap_enumeration_style
|
||||||
# No override for "Wrap braced initializer list" (Varies throughout source code)
|
# No override for "Wrap braced initializer list" (Varies throughout source code)
|
||||||
#cpp_wrap_braced_init_list_style
|
#cpp_wrap_braced_init_list_style
|
||||||
# No override for "Wrap base classes list" (Varies throughout source code)
|
# No override for "Wrap base classes list" (Varies throughout source code)
|
||||||
#cpp_wrap_base_clause_style
|
#cpp_wrap_base_clause_style
|
||||||
# No override for "Wrap constructor initializer" (Varies throughout source code)
|
# No override for "Wrap constructor initializer" (Varies throughout source code)
|
||||||
#cpp_wrap_ctor_initializer_style
|
#cpp_wrap_ctor_initializer_style
|
||||||
# No override for "Wrap formal parameters" (Varies throughout source code)
|
# No override for "Wrap formal parameters" (Varies throughout source code)
|
||||||
#cpp_wrap_parameters_style
|
#cpp_wrap_parameters_style
|
||||||
# Do not prefer wrap before '(' in declaration
|
# Do not prefer wrap before '(' in declaration
|
||||||
cpp_wrap_before_declaration_lpar = false
|
cpp_wrap_before_declaration_lpar = false
|
||||||
# Prefer wrap after '(' in declaration
|
# Prefer wrap after '(' in declaration
|
||||||
cpp_wrap_after_declaration_lpar = true
|
cpp_wrap_after_declaration_lpar = true
|
||||||
# Do not prefer wrap before ')' in declaration
|
# Do not prefer wrap before ')' in declaration
|
||||||
cpp_wrap_before_declaration_rpar = false
|
cpp_wrap_before_declaration_rpar = false
|
||||||
# No override for "Wrap invocation arguments" (Varies throughout source code)
|
# No override for "Wrap invocation arguments" (Varies throughout source code)
|
||||||
#cpp_wrap_arguments_style
|
#cpp_wrap_arguments_style
|
||||||
# Do not prefer wrap before '(' in invocation
|
# Do not prefer wrap before '(' in invocation
|
||||||
cpp_wrap_before_invocation_lpar = false
|
cpp_wrap_before_invocation_lpar = false
|
||||||
# Prefer wrap after '(' in invocation
|
# Prefer wrap after '(' in invocation
|
||||||
cpp_wrap_after_invocation_lpar = true
|
cpp_wrap_after_invocation_lpar = true
|
||||||
# Do not prefer wrap before ')' in invocation
|
# Do not prefer wrap before ')' in invocation
|
||||||
cpp_wrap_before_invocation_rpar = false
|
cpp_wrap_before_invocation_rpar = false
|
||||||
# Prefer wrap after '{' in initializer lists
|
# Prefer wrap after '{' in initializer lists
|
||||||
cpp_wrap_after_expression_lbrace = true
|
cpp_wrap_after_expression_lbrace = true
|
||||||
# Do not prefer wrap before '}' in initializer lists
|
# Do not prefer wrap before '}' in initializer lists
|
||||||
cpp_wrap_before_expression_rbrace = false
|
cpp_wrap_before_expression_rbrace = false
|
||||||
|
4
src/3rdparty/fmt/CMakeLists.txt
vendored
4
src/3rdparty/fmt/CMakeLists.txt
vendored
@@ -1,5 +1,9 @@
|
|||||||
add_files(
|
add_files(
|
||||||
|
chrono.h
|
||||||
core.h
|
core.h
|
||||||
format.h
|
format.h
|
||||||
format-inl.h
|
format-inl.h
|
||||||
|
ostream.h
|
||||||
|
ranges.h
|
||||||
|
std.h
|
||||||
)
|
)
|
||||||
|
2
src/3rdparty/fmt/LICENSE.rst
vendored
2
src/3rdparty/fmt/LICENSE.rst
vendored
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2012 - present, Victor Zverovich
|
Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
2267
src/3rdparty/fmt/chrono.h
vendored
Normal file
2267
src/3rdparty/fmt/chrono.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3379
src/3rdparty/fmt/core.h
vendored
3379
src/3rdparty/fmt/core.h
vendored
File diff suppressed because it is too large
Load Diff
2986
src/3rdparty/fmt/format-inl.h
vendored
2986
src/3rdparty/fmt/format-inl.h
vendored
File diff suppressed because it is too large
Load Diff
6557
src/3rdparty/fmt/format.h
vendored
6557
src/3rdparty/fmt/format.h
vendored
File diff suppressed because it is too large
Load Diff
209
src/3rdparty/fmt/ostream.h
vendored
Normal file
209
src/3rdparty/fmt/ostream.h
vendored
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
// Formatting library for C++ - std::ostream support
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012 - present, Victor Zverovich
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// For the license information refer to format.h.
|
||||||
|
|
||||||
|
#ifndef FMT_OSTREAM_H_
|
||||||
|
#define FMT_OSTREAM_H_
|
||||||
|
|
||||||
|
#include <fstream> // std::filebuf
|
||||||
|
|
||||||
|
#if defined(_WIN32) && defined(__GLIBCXX__)
|
||||||
|
# include <ext/stdio_filebuf.h>
|
||||||
|
# include <ext/stdio_sync_filebuf.h>
|
||||||
|
#elif defined(_WIN32) && defined(_LIBCPP_VERSION)
|
||||||
|
# include <__std_stream>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "format.h"
|
||||||
|
|
||||||
|
FMT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
// Generate a unique explicit instantion in every translation unit using a tag
|
||||||
|
// type in an anonymous namespace.
|
||||||
|
namespace {
|
||||||
|
struct file_access_tag {};
|
||||||
|
} // namespace
|
||||||
|
template <typename Tag, typename BufType, FILE* BufType::*FileMemberPtr>
|
||||||
|
class file_access {
|
||||||
|
friend auto get_file(BufType& obj) -> FILE* { return obj.*FileMemberPtr; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#if FMT_MSC_VERSION
|
||||||
|
template class file_access<file_access_tag, std::filebuf,
|
||||||
|
&std::filebuf::_Myfile>;
|
||||||
|
auto get_file(std::filebuf&) -> FILE*;
|
||||||
|
#elif defined(_WIN32) && defined(_LIBCPP_VERSION)
|
||||||
|
template class file_access<file_access_tag, std::__stdoutbuf<char>,
|
||||||
|
&std::__stdoutbuf<char>::__file_>;
|
||||||
|
auto get_file(std::__stdoutbuf<char>&) -> FILE*;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline bool write_ostream_unicode(std::ostream& os, fmt::string_view data) {
|
||||||
|
#if FMT_MSC_VERSION
|
||||||
|
if (auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))
|
||||||
|
if (FILE* f = get_file(*buf)) return write_console(f, data);
|
||||||
|
#elif defined(_WIN32) && defined(__GLIBCXX__)
|
||||||
|
auto* rdbuf = os.rdbuf();
|
||||||
|
FILE* c_file;
|
||||||
|
if (auto* sfbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf<char>*>(rdbuf))
|
||||||
|
c_file = sfbuf->file();
|
||||||
|
else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf<char>*>(rdbuf))
|
||||||
|
c_file = fbuf->file();
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
if (c_file) return write_console(c_file, data);
|
||||||
|
#elif defined(_WIN32) && defined(_LIBCPP_VERSION)
|
||||||
|
if (auto* buf = dynamic_cast<std::__stdoutbuf<char>*>(os.rdbuf()))
|
||||||
|
if (FILE* f = get_file(*buf)) return write_console(f, data);
|
||||||
|
#else
|
||||||
|
ignore_unused(os, data);
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline bool write_ostream_unicode(std::wostream&,
|
||||||
|
fmt::basic_string_view<wchar_t>) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the content of buf to os.
|
||||||
|
// It is a separate function rather than a part of vprint to simplify testing.
|
||||||
|
template <typename Char>
|
||||||
|
void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
|
||||||
|
const Char* buf_data = buf.data();
|
||||||
|
using unsigned_streamsize = std::make_unsigned<std::streamsize>::type;
|
||||||
|
unsigned_streamsize size = buf.size();
|
||||||
|
unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
|
||||||
|
do {
|
||||||
|
unsigned_streamsize n = size <= max_size ? size : max_size;
|
||||||
|
os.write(buf_data, static_cast<std::streamsize>(n));
|
||||||
|
buf_data += n;
|
||||||
|
size -= n;
|
||||||
|
} while (size != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Char, typename T>
|
||||||
|
void format_value(buffer<Char>& buf, const T& value,
|
||||||
|
locale_ref loc = locale_ref()) {
|
||||||
|
auto&& format_buf = formatbuf<std::basic_streambuf<Char>>(buf);
|
||||||
|
auto&& output = std::basic_ostream<Char>(&format_buf);
|
||||||
|
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
|
||||||
|
if (loc) output.imbue(loc.get<std::locale>());
|
||||||
|
#endif
|
||||||
|
output << value;
|
||||||
|
output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> struct streamed_view { const T& value; };
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
// Formats an object of type T that has an overloaded ostream operator<<.
|
||||||
|
template <typename Char>
|
||||||
|
struct basic_ostream_formatter : formatter<basic_string_view<Char>, Char> {
|
||||||
|
void set_debug_format() = delete;
|
||||||
|
|
||||||
|
template <typename T, typename OutputIt>
|
||||||
|
auto format(const T& value, basic_format_context<OutputIt, Char>& ctx) const
|
||||||
|
-> OutputIt {
|
||||||
|
auto buffer = basic_memory_buffer<Char>();
|
||||||
|
detail::format_value(buffer, value, ctx.locale());
|
||||||
|
return formatter<basic_string_view<Char>, Char>::format(
|
||||||
|
{buffer.data(), buffer.size()}, ctx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using ostream_formatter = basic_ostream_formatter<char>;
|
||||||
|
|
||||||
|
template <typename T, typename Char>
|
||||||
|
struct formatter<detail::streamed_view<T>, Char>
|
||||||
|
: basic_ostream_formatter<Char> {
|
||||||
|
template <typename OutputIt>
|
||||||
|
auto format(detail::streamed_view<T> view,
|
||||||
|
basic_format_context<OutputIt, Char>& ctx) const -> OutputIt {
|
||||||
|
return basic_ostream_formatter<Char>::format(view.value, ctx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
\rst
|
||||||
|
Returns a view that formats `value` via an ostream ``operator<<``.
|
||||||
|
|
||||||
|
**Example**::
|
||||||
|
|
||||||
|
fmt::print("Current thread id: {}\n",
|
||||||
|
fmt::streamed(std::this_thread::get_id()));
|
||||||
|
\endrst
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
auto streamed(const T& value) -> detail::streamed_view<T> {
|
||||||
|
return {value};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
inline void vprint_directly(std::ostream& os, string_view format_str,
|
||||||
|
format_args args) {
|
||||||
|
auto buffer = memory_buffer();
|
||||||
|
detail::vformat_to(buffer, format_str, args);
|
||||||
|
detail::write_buffer(os, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
FMT_MODULE_EXPORT template <typename Char>
|
||||||
|
void vprint(std::basic_ostream<Char>& os,
|
||||||
|
basic_string_view<type_identity_t<Char>> format_str,
|
||||||
|
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
||||||
|
auto buffer = basic_memory_buffer<Char>();
|
||||||
|
detail::vformat_to(buffer, format_str, args);
|
||||||
|
if (detail::write_ostream_unicode(os, {buffer.data(), buffer.size()})) return;
|
||||||
|
detail::write_buffer(os, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\rst
|
||||||
|
Prints formatted data to the stream *os*.
|
||||||
|
|
||||||
|
**Example**::
|
||||||
|
|
||||||
|
fmt::print(cerr, "Don't {}!", "panic");
|
||||||
|
\endrst
|
||||||
|
*/
|
||||||
|
FMT_MODULE_EXPORT template <typename... T>
|
||||||
|
void print(std::ostream& os, format_string<T...> fmt, T&&... args) {
|
||||||
|
const auto& vargs = fmt::make_format_args(args...);
|
||||||
|
if (detail::is_utf8())
|
||||||
|
vprint(os, fmt, vargs);
|
||||||
|
else
|
||||||
|
detail::vprint_directly(os, fmt, vargs);
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_MODULE_EXPORT
|
||||||
|
template <typename... Args>
|
||||||
|
void print(std::wostream& os,
|
||||||
|
basic_format_string<wchar_t, type_identity_t<Args>...> fmt,
|
||||||
|
Args&&... args) {
|
||||||
|
vprint(os, fmt, fmt::make_format_args<buffer_context<wchar_t>>(args...));
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_MODULE_EXPORT template <typename... T>
|
||||||
|
void println(std::ostream& os, format_string<T...> fmt, T&&... args) {
|
||||||
|
fmt::print(os, "{}\n", fmt::format(fmt, std::forward<T>(args)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_MODULE_EXPORT
|
||||||
|
template <typename... Args>
|
||||||
|
void println(std::wostream& os,
|
||||||
|
basic_format_string<wchar_t, type_identity_t<Args>...> fmt,
|
||||||
|
Args&&... args) {
|
||||||
|
print(os, L"{}\n", fmt::format(fmt, std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // FMT_OSTREAM_H_
|
732
src/3rdparty/fmt/ranges.h
vendored
Normal file
732
src/3rdparty/fmt/ranges.h
vendored
Normal file
@@ -0,0 +1,732 @@
|
|||||||
|
// Formatting library for C++ - experimental range support
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012 - present, Victor Zverovich
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// For the license information refer to format.h.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018 - present, Remotion (Igor Schulz)
|
||||||
|
// All Rights Reserved
|
||||||
|
// {fmt} support for ranges, containers and types tuple interface.
|
||||||
|
|
||||||
|
#ifndef FMT_RANGES_H_
|
||||||
|
#define FMT_RANGES_H_
|
||||||
|
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include "format.h"
|
||||||
|
|
||||||
|
FMT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename Range, typename OutputIt>
|
||||||
|
auto copy(const Range& range, OutputIt out) -> OutputIt {
|
||||||
|
for (auto it = range.begin(), end = range.end(); it != end; ++it)
|
||||||
|
*out++ = *it;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OutputIt>
|
||||||
|
auto copy(const char* str, OutputIt out) -> OutputIt {
|
||||||
|
while (*str) *out++ = *str++;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OutputIt> auto copy(char ch, OutputIt out) -> OutputIt {
|
||||||
|
*out++ = ch;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OutputIt> auto copy(wchar_t ch, OutputIt out) -> OutputIt {
|
||||||
|
*out++ = ch;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if T has a std::string-like interface, like std::string_view.
|
||||||
|
template <typename T> class is_std_string_like {
|
||||||
|
template <typename U>
|
||||||
|
static auto check(U* p)
|
||||||
|
-> decltype((void)p->find('a'), p->length(), (void)p->data(), int());
|
||||||
|
template <typename> static void check(...);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr const bool value =
|
||||||
|
is_string<T>::value ||
|
||||||
|
std::is_convertible<T, std_string_view<char>>::value ||
|
||||||
|
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
struct is_std_string_like<fmt::basic_string_view<Char>> : std::true_type {};
|
||||||
|
|
||||||
|
template <typename T> class is_map {
|
||||||
|
template <typename U> static auto check(U*) -> typename U::mapped_type;
|
||||||
|
template <typename> static void check(...);
|
||||||
|
|
||||||
|
public:
|
||||||
|
#ifdef FMT_FORMAT_MAP_AS_LIST // DEPRECATED!
|
||||||
|
static constexpr const bool value = false;
|
||||||
|
#else
|
||||||
|
static constexpr const bool value =
|
||||||
|
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T> class is_set {
|
||||||
|
template <typename U> static auto check(U*) -> typename U::key_type;
|
||||||
|
template <typename> static void check(...);
|
||||||
|
|
||||||
|
public:
|
||||||
|
#ifdef FMT_FORMAT_SET_AS_LIST // DEPRECATED!
|
||||||
|
static constexpr const bool value = false;
|
||||||
|
#else
|
||||||
|
static constexpr const bool value =
|
||||||
|
!std::is_void<decltype(check<T>(nullptr))>::value && !is_map<T>::value;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename... Ts> struct conditional_helper {};
|
||||||
|
|
||||||
|
template <typename T, typename _ = void> struct is_range_ : std::false_type {};
|
||||||
|
|
||||||
|
#if !FMT_MSC_VERSION || FMT_MSC_VERSION > 1800
|
||||||
|
|
||||||
|
# define FMT_DECLTYPE_RETURN(val) \
|
||||||
|
->decltype(val) { return val; } \
|
||||||
|
static_assert( \
|
||||||
|
true, "") // This makes it so that a semicolon is required after the
|
||||||
|
// macro, which helps clang-format handle the formatting.
|
||||||
|
|
||||||
|
// C array overload
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
auto range_begin(const T (&arr)[N]) -> const T* {
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
template <typename T, std::size_t N>
|
||||||
|
auto range_end(const T (&arr)[N]) -> const T* {
|
||||||
|
return arr + N;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename Enable = void>
|
||||||
|
struct has_member_fn_begin_end_t : std::false_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct has_member_fn_begin_end_t<T, void_t<decltype(std::declval<T>().begin()),
|
||||||
|
decltype(std::declval<T>().end())>>
|
||||||
|
: std::true_type {};
|
||||||
|
|
||||||
|
// Member function overload
|
||||||
|
template <typename T>
|
||||||
|
auto range_begin(T&& rng) FMT_DECLTYPE_RETURN(static_cast<T&&>(rng).begin());
|
||||||
|
template <typename T>
|
||||||
|
auto range_end(T&& rng) FMT_DECLTYPE_RETURN(static_cast<T&&>(rng).end());
|
||||||
|
|
||||||
|
// ADL overload. Only participates in overload resolution if member functions
|
||||||
|
// are not found.
|
||||||
|
template <typename T>
|
||||||
|
auto range_begin(T&& rng)
|
||||||
|
-> enable_if_t<!has_member_fn_begin_end_t<T&&>::value,
|
||||||
|
decltype(begin(static_cast<T&&>(rng)))> {
|
||||||
|
return begin(static_cast<T&&>(rng));
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
auto range_end(T&& rng) -> enable_if_t<!has_member_fn_begin_end_t<T&&>::value,
|
||||||
|
decltype(end(static_cast<T&&>(rng)))> {
|
||||||
|
return end(static_cast<T&&>(rng));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename Enable = void>
|
||||||
|
struct has_const_begin_end : std::false_type {};
|
||||||
|
template <typename T, typename Enable = void>
|
||||||
|
struct has_mutable_begin_end : std::false_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct has_const_begin_end<
|
||||||
|
T,
|
||||||
|
void_t<
|
||||||
|
decltype(detail::range_begin(std::declval<const remove_cvref_t<T>&>())),
|
||||||
|
decltype(detail::range_end(std::declval<const remove_cvref_t<T>&>()))>>
|
||||||
|
: std::true_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct has_mutable_begin_end<
|
||||||
|
T, void_t<decltype(detail::range_begin(std::declval<T>())),
|
||||||
|
decltype(detail::range_end(std::declval<T>())),
|
||||||
|
// the extra int here is because older versions of MSVC don't
|
||||||
|
// SFINAE properly unless there are distinct types
|
||||||
|
int>> : std::true_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_range_<T, void>
|
||||||
|
: std::integral_constant<bool, (has_const_begin_end<T>::value ||
|
||||||
|
has_mutable_begin_end<T>::value)> {};
|
||||||
|
# undef FMT_DECLTYPE_RETURN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// tuple_size and tuple_element check.
|
||||||
|
template <typename T> class is_tuple_like_ {
|
||||||
|
template <typename U>
|
||||||
|
static auto check(U* p) -> decltype(std::tuple_size<U>::value, int());
|
||||||
|
template <typename> static void check(...);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr const bool value =
|
||||||
|
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check for integer_sequence
|
||||||
|
#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VERSION >= 1900
|
||||||
|
template <typename T, T... N>
|
||||||
|
using integer_sequence = std::integer_sequence<T, N...>;
|
||||||
|
template <size_t... N> using index_sequence = std::index_sequence<N...>;
|
||||||
|
template <size_t N> using make_index_sequence = std::make_index_sequence<N>;
|
||||||
|
#else
|
||||||
|
template <typename T, T... N> struct integer_sequence {
|
||||||
|
using value_type = T;
|
||||||
|
|
||||||
|
static FMT_CONSTEXPR size_t size() { return sizeof...(N); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <size_t... N> using index_sequence = integer_sequence<size_t, N...>;
|
||||||
|
|
||||||
|
template <typename T, size_t N, T... Ns>
|
||||||
|
struct make_integer_sequence : make_integer_sequence<T, N - 1, N - 1, Ns...> {};
|
||||||
|
template <typename T, T... Ns>
|
||||||
|
struct make_integer_sequence<T, 0, Ns...> : integer_sequence<T, Ns...> {};
|
||||||
|
|
||||||
|
template <size_t N>
|
||||||
|
using make_index_sequence = make_integer_sequence<size_t, N>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using tuple_index_sequence = make_index_sequence<std::tuple_size<T>::value>;
|
||||||
|
|
||||||
|
template <typename T, typename C, bool = is_tuple_like_<T>::value>
|
||||||
|
class is_tuple_formattable_ {
|
||||||
|
public:
|
||||||
|
static constexpr const bool value = false;
|
||||||
|
};
|
||||||
|
template <typename T, typename C> class is_tuple_formattable_<T, C, true> {
|
||||||
|
template <std::size_t... Is>
|
||||||
|
static std::true_type check2(index_sequence<Is...>,
|
||||||
|
integer_sequence<bool, (Is == Is)...>);
|
||||||
|
static std::false_type check2(...);
|
||||||
|
template <std::size_t... Is>
|
||||||
|
static decltype(check2(
|
||||||
|
index_sequence<Is...>{},
|
||||||
|
integer_sequence<
|
||||||
|
bool, (is_formattable<typename std::tuple_element<Is, T>::type,
|
||||||
|
C>::value)...>{})) check(index_sequence<Is...>);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr const bool value =
|
||||||
|
decltype(check(tuple_index_sequence<T>{}))::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Tuple, typename F, size_t... Is>
|
||||||
|
FMT_CONSTEXPR void for_each(index_sequence<Is...>, Tuple&& t, F&& f) {
|
||||||
|
using std::get;
|
||||||
|
// Using a free function get<Is>(Tuple) now.
|
||||||
|
const int unused[] = {0, ((void)f(get<Is>(t)), 0)...};
|
||||||
|
ignore_unused(unused);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Tuple, typename F>
|
||||||
|
FMT_CONSTEXPR void for_each(Tuple&& t, F&& f) {
|
||||||
|
for_each(tuple_index_sequence<remove_cvref_t<Tuple>>(),
|
||||||
|
std::forward<Tuple>(t), std::forward<F>(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Tuple1, typename Tuple2, typename F, size_t... Is>
|
||||||
|
void for_each2(index_sequence<Is...>, Tuple1&& t1, Tuple2&& t2, F&& f) {
|
||||||
|
using std::get;
|
||||||
|
const int unused[] = {0, ((void)f(get<Is>(t1), get<Is>(t2)), 0)...};
|
||||||
|
ignore_unused(unused);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Tuple1, typename Tuple2, typename F>
|
||||||
|
void for_each2(Tuple1&& t1, Tuple2&& t2, F&& f) {
|
||||||
|
for_each2(tuple_index_sequence<remove_cvref_t<Tuple1>>(),
|
||||||
|
std::forward<Tuple1>(t1), std::forward<Tuple2>(t2),
|
||||||
|
std::forward<F>(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace tuple {
|
||||||
|
// Workaround a bug in MSVC 2019 (v140).
|
||||||
|
template <typename Char, typename... T>
|
||||||
|
using result_t = std::tuple<formatter<remove_cvref_t<T>, Char>...>;
|
||||||
|
|
||||||
|
using std::get;
|
||||||
|
template <typename Tuple, typename Char, std::size_t... Is>
|
||||||
|
auto get_formatters(index_sequence<Is...>)
|
||||||
|
-> result_t<Char, decltype(get<Is>(std::declval<Tuple>()))...>;
|
||||||
|
} // namespace tuple
|
||||||
|
|
||||||
|
#if FMT_MSC_VERSION && FMT_MSC_VERSION < 1920
|
||||||
|
// Older MSVC doesn't get the reference type correctly for arrays.
|
||||||
|
template <typename R> struct range_reference_type_impl {
|
||||||
|
using type = decltype(*detail::range_begin(std::declval<R&>()));
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, std::size_t N> struct range_reference_type_impl<T[N]> {
|
||||||
|
using type = T&;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using range_reference_type = typename range_reference_type_impl<T>::type;
|
||||||
|
#else
|
||||||
|
template <typename Range>
|
||||||
|
using range_reference_type =
|
||||||
|
decltype(*detail::range_begin(std::declval<Range&>()));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// We don't use the Range's value_type for anything, but we do need the Range's
|
||||||
|
// reference type, with cv-ref stripped.
|
||||||
|
template <typename Range>
|
||||||
|
using uncvref_type = remove_cvref_t<range_reference_type<Range>>;
|
||||||
|
|
||||||
|
template <typename Formatter>
|
||||||
|
FMT_CONSTEXPR auto maybe_set_debug_format(Formatter& f, bool set)
|
||||||
|
-> decltype(f.set_debug_format(set)) {
|
||||||
|
f.set_debug_format(set);
|
||||||
|
}
|
||||||
|
template <typename Formatter>
|
||||||
|
FMT_CONSTEXPR void maybe_set_debug_format(Formatter&, ...) {}
|
||||||
|
|
||||||
|
// These are not generic lambdas for compatibility with C++11.
|
||||||
|
template <typename ParseContext> struct parse_empty_specs {
|
||||||
|
template <typename Formatter> FMT_CONSTEXPR void operator()(Formatter& f) {
|
||||||
|
f.parse(ctx);
|
||||||
|
detail::maybe_set_debug_format(f, true);
|
||||||
|
}
|
||||||
|
ParseContext& ctx;
|
||||||
|
};
|
||||||
|
template <typename FormatContext> struct format_tuple_element {
|
||||||
|
using char_type = typename FormatContext::char_type;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void operator()(const formatter<T, char_type>& f, const T& v) {
|
||||||
|
if (i > 0)
|
||||||
|
ctx.advance_to(detail::copy_str<char_type>(separator, ctx.out()));
|
||||||
|
ctx.advance_to(f.format(v, ctx));
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i;
|
||||||
|
FormatContext& ctx;
|
||||||
|
basic_string_view<char_type> separator;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename T> struct is_tuple_like {
|
||||||
|
static constexpr const bool value =
|
||||||
|
detail::is_tuple_like_<T>::value && !detail::is_range_<T>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename C> struct is_tuple_formattable {
|
||||||
|
static constexpr const bool value =
|
||||||
|
detail::is_tuple_formattable_<T, C>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Tuple, typename Char>
|
||||||
|
struct formatter<Tuple, Char,
|
||||||
|
enable_if_t<fmt::is_tuple_like<Tuple>::value &&
|
||||||
|
fmt::is_tuple_formattable<Tuple, Char>::value>> {
|
||||||
|
private:
|
||||||
|
decltype(detail::tuple::get_formatters<Tuple, Char>(
|
||||||
|
detail::tuple_index_sequence<Tuple>())) formatters_;
|
||||||
|
|
||||||
|
basic_string_view<Char> separator_ = detail::string_literal<Char, ',', ' '>{};
|
||||||
|
basic_string_view<Char> opening_bracket_ =
|
||||||
|
detail::string_literal<Char, '('>{};
|
||||||
|
basic_string_view<Char> closing_bracket_ =
|
||||||
|
detail::string_literal<Char, ')'>{};
|
||||||
|
|
||||||
|
public:
|
||||||
|
FMT_CONSTEXPR formatter() {}
|
||||||
|
|
||||||
|
FMT_CONSTEXPR void set_separator(basic_string_view<Char> sep) {
|
||||||
|
separator_ = sep;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_CONSTEXPR void set_brackets(basic_string_view<Char> open,
|
||||||
|
basic_string_view<Char> close) {
|
||||||
|
opening_bracket_ = open;
|
||||||
|
closing_bracket_ = close;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ParseContext>
|
||||||
|
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||||
|
auto it = ctx.begin();
|
||||||
|
if (it != ctx.end() && *it != '}')
|
||||||
|
FMT_THROW(format_error("invalid format specifier"));
|
||||||
|
detail::for_each(formatters_, detail::parse_empty_specs<ParseContext>{ctx});
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FormatContext>
|
||||||
|
auto format(const Tuple& value, FormatContext& ctx) const
|
||||||
|
-> decltype(ctx.out()) {
|
||||||
|
ctx.advance_to(detail::copy_str<Char>(opening_bracket_, ctx.out()));
|
||||||
|
detail::for_each2(
|
||||||
|
formatters_, value,
|
||||||
|
detail::format_tuple_element<FormatContext>{0, ctx, separator_});
|
||||||
|
return detail::copy_str<Char>(closing_bracket_, ctx.out());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename Char> struct is_range {
|
||||||
|
static constexpr const bool value =
|
||||||
|
detail::is_range_<T>::value && !detail::is_std_string_like<T>::value &&
|
||||||
|
!std::is_convertible<T, std::basic_string<Char>>::value &&
|
||||||
|
!std::is_convertible<T, detail::std_string_view<Char>>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template <typename Context> struct range_mapper {
|
||||||
|
using mapper = arg_mapper<Context>;
|
||||||
|
|
||||||
|
template <typename T,
|
||||||
|
FMT_ENABLE_IF(has_formatter<remove_cvref_t<T>, Context>::value)>
|
||||||
|
static auto map(T&& value) -> T&& {
|
||||||
|
return static_cast<T&&>(value);
|
||||||
|
}
|
||||||
|
template <typename T,
|
||||||
|
FMT_ENABLE_IF(!has_formatter<remove_cvref_t<T>, Context>::value)>
|
||||||
|
static auto map(T&& value)
|
||||||
|
-> decltype(mapper().map(static_cast<T&&>(value))) {
|
||||||
|
return mapper().map(static_cast<T&&>(value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Char, typename Element>
|
||||||
|
using range_formatter_type =
|
||||||
|
formatter<remove_cvref_t<decltype(range_mapper<buffer_context<Char>>{}.map(
|
||||||
|
std::declval<Element>()))>,
|
||||||
|
Char>;
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
using maybe_const_range =
|
||||||
|
conditional_t<has_const_begin_end<R>::value, const R, R>;
|
||||||
|
|
||||||
|
// Workaround a bug in MSVC 2015 and earlier.
|
||||||
|
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
|
||||||
|
template <typename R, typename Char>
|
||||||
|
struct is_formattable_delayed
|
||||||
|
: is_formattable<uncvref_type<maybe_const_range<R>>, Char> {};
|
||||||
|
#endif
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename T, typename Char, typename Enable = void>
|
||||||
|
struct range_formatter;
|
||||||
|
|
||||||
|
template <typename T, typename Char>
|
||||||
|
struct range_formatter<
|
||||||
|
T, Char,
|
||||||
|
enable_if_t<conjunction<std::is_same<T, remove_cvref_t<T>>,
|
||||||
|
is_formattable<T, Char>>::value>> {
|
||||||
|
private:
|
||||||
|
detail::range_formatter_type<Char, T> underlying_;
|
||||||
|
basic_string_view<Char> separator_ = detail::string_literal<Char, ',', ' '>{};
|
||||||
|
basic_string_view<Char> opening_bracket_ =
|
||||||
|
detail::string_literal<Char, '['>{};
|
||||||
|
basic_string_view<Char> closing_bracket_ =
|
||||||
|
detail::string_literal<Char, ']'>{};
|
||||||
|
|
||||||
|
public:
|
||||||
|
FMT_CONSTEXPR range_formatter() {}
|
||||||
|
|
||||||
|
FMT_CONSTEXPR auto underlying() -> detail::range_formatter_type<Char, T>& {
|
||||||
|
return underlying_;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_CONSTEXPR void set_separator(basic_string_view<Char> sep) {
|
||||||
|
separator_ = sep;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_CONSTEXPR void set_brackets(basic_string_view<Char> open,
|
||||||
|
basic_string_view<Char> close) {
|
||||||
|
opening_bracket_ = open;
|
||||||
|
closing_bracket_ = close;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ParseContext>
|
||||||
|
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||||
|
auto it = ctx.begin();
|
||||||
|
auto end = ctx.end();
|
||||||
|
|
||||||
|
if (it != end && *it == 'n') {
|
||||||
|
set_brackets({}, {});
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it != end && *it != '}') {
|
||||||
|
if (*it != ':') FMT_THROW(format_error("invalid format specifier"));
|
||||||
|
++it;
|
||||||
|
} else {
|
||||||
|
detail::maybe_set_debug_format(underlying_, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.advance_to(it);
|
||||||
|
return underlying_.parse(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename R, typename FormatContext>
|
||||||
|
auto format(R&& range, FormatContext& ctx) const -> decltype(ctx.out()) {
|
||||||
|
detail::range_mapper<buffer_context<Char>> mapper;
|
||||||
|
auto out = ctx.out();
|
||||||
|
out = detail::copy_str<Char>(opening_bracket_, out);
|
||||||
|
int i = 0;
|
||||||
|
auto it = detail::range_begin(range);
|
||||||
|
auto end = detail::range_end(range);
|
||||||
|
for (; it != end; ++it) {
|
||||||
|
if (i > 0) out = detail::copy_str<Char>(separator_, out);
|
||||||
|
ctx.advance_to(out);
|
||||||
|
out = underlying_.format(mapper.map(*it), ctx);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
out = detail::copy_str<Char>(closing_bracket_, out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class range_format { disabled, map, set, sequence, string, debug_string };
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template <typename T>
|
||||||
|
struct range_format_kind_
|
||||||
|
: std::integral_constant<range_format,
|
||||||
|
std::is_same<uncvref_type<T>, T>::value
|
||||||
|
? range_format::disabled
|
||||||
|
: is_map<T>::value ? range_format::map
|
||||||
|
: is_set<T>::value ? range_format::set
|
||||||
|
: range_format::sequence> {};
|
||||||
|
|
||||||
|
template <range_format K, typename R, typename Char, typename Enable = void>
|
||||||
|
struct range_default_formatter;
|
||||||
|
|
||||||
|
template <range_format K>
|
||||||
|
using range_format_constant = std::integral_constant<range_format, K>;
|
||||||
|
|
||||||
|
template <range_format K, typename R, typename Char>
|
||||||
|
struct range_default_formatter<
|
||||||
|
K, R, Char,
|
||||||
|
enable_if_t<(K == range_format::sequence || K == range_format::map ||
|
||||||
|
K == range_format::set)>> {
|
||||||
|
using range_type = detail::maybe_const_range<R>;
|
||||||
|
range_formatter<detail::uncvref_type<range_type>, Char> underlying_;
|
||||||
|
|
||||||
|
FMT_CONSTEXPR range_default_formatter() { init(range_format_constant<K>()); }
|
||||||
|
|
||||||
|
FMT_CONSTEXPR void init(range_format_constant<range_format::set>) {
|
||||||
|
underlying_.set_brackets(detail::string_literal<Char, '{'>{},
|
||||||
|
detail::string_literal<Char, '}'>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_CONSTEXPR void init(range_format_constant<range_format::map>) {
|
||||||
|
underlying_.set_brackets(detail::string_literal<Char, '{'>{},
|
||||||
|
detail::string_literal<Char, '}'>{});
|
||||||
|
underlying_.underlying().set_brackets({}, {});
|
||||||
|
underlying_.underlying().set_separator(
|
||||||
|
detail::string_literal<Char, ':', ' '>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_CONSTEXPR void init(range_format_constant<range_format::sequence>) {}
|
||||||
|
|
||||||
|
template <typename ParseContext>
|
||||||
|
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||||
|
return underlying_.parse(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FormatContext>
|
||||||
|
auto format(range_type& range, FormatContext& ctx) const
|
||||||
|
-> decltype(ctx.out()) {
|
||||||
|
return underlying_.format(range, ctx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename T, typename Char, typename Enable = void>
|
||||||
|
struct range_format_kind
|
||||||
|
: conditional_t<
|
||||||
|
is_range<T, Char>::value, detail::range_format_kind_<T>,
|
||||||
|
std::integral_constant<range_format, range_format::disabled>> {};
|
||||||
|
|
||||||
|
template <typename R, typename Char>
|
||||||
|
struct formatter<
|
||||||
|
R, Char,
|
||||||
|
enable_if_t<conjunction<bool_constant<range_format_kind<R, Char>::value !=
|
||||||
|
range_format::disabled>
|
||||||
|
// Workaround a bug in MSVC 2015 and earlier.
|
||||||
|
#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910
|
||||||
|
,
|
||||||
|
detail::is_formattable_delayed<R, Char>
|
||||||
|
#endif
|
||||||
|
>::value>>
|
||||||
|
: detail::range_default_formatter<range_format_kind<R, Char>::value, R,
|
||||||
|
Char> {
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Char, typename... T> struct tuple_join_view : detail::view {
|
||||||
|
const std::tuple<T...>& tuple;
|
||||||
|
basic_string_view<Char> sep;
|
||||||
|
|
||||||
|
tuple_join_view(const std::tuple<T...>& t, basic_string_view<Char> s)
|
||||||
|
: tuple(t), sep{s} {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define FMT_TUPLE_JOIN_SPECIFIERS to enable experimental format specifiers
|
||||||
|
// support in tuple_join. It is disabled by default because of issues with
|
||||||
|
// the dynamic width and precision.
|
||||||
|
#ifndef FMT_TUPLE_JOIN_SPECIFIERS
|
||||||
|
# define FMT_TUPLE_JOIN_SPECIFIERS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename Char, typename... T>
|
||||||
|
struct formatter<tuple_join_view<Char, T...>, Char> {
|
||||||
|
template <typename ParseContext>
|
||||||
|
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||||
|
return do_parse(ctx, std::integral_constant<size_t, sizeof...(T)>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FormatContext>
|
||||||
|
auto format(const tuple_join_view<Char, T...>& value,
|
||||||
|
FormatContext& ctx) const -> typename FormatContext::iterator {
|
||||||
|
return do_format(value, ctx,
|
||||||
|
std::integral_constant<size_t, sizeof...(T)>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::tuple<formatter<typename std::decay<T>::type, Char>...> formatters_;
|
||||||
|
|
||||||
|
template <typename ParseContext>
|
||||||
|
FMT_CONSTEXPR auto do_parse(ParseContext& ctx,
|
||||||
|
std::integral_constant<size_t, 0>)
|
||||||
|
-> decltype(ctx.begin()) {
|
||||||
|
return ctx.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ParseContext, size_t N>
|
||||||
|
FMT_CONSTEXPR auto do_parse(ParseContext& ctx,
|
||||||
|
std::integral_constant<size_t, N>)
|
||||||
|
-> decltype(ctx.begin()) {
|
||||||
|
auto end = ctx.begin();
|
||||||
|
#if FMT_TUPLE_JOIN_SPECIFIERS
|
||||||
|
end = std::get<sizeof...(T) - N>(formatters_).parse(ctx);
|
||||||
|
if (N > 1) {
|
||||||
|
auto end1 = do_parse(ctx, std::integral_constant<size_t, N - 1>());
|
||||||
|
if (end != end1)
|
||||||
|
FMT_THROW(format_error("incompatible format specs for tuple elements"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FormatContext>
|
||||||
|
auto do_format(const tuple_join_view<Char, T...>&, FormatContext& ctx,
|
||||||
|
std::integral_constant<size_t, 0>) const ->
|
||||||
|
typename FormatContext::iterator {
|
||||||
|
return ctx.out();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FormatContext, size_t N>
|
||||||
|
auto do_format(const tuple_join_view<Char, T...>& value, FormatContext& ctx,
|
||||||
|
std::integral_constant<size_t, N>) const ->
|
||||||
|
typename FormatContext::iterator {
|
||||||
|
auto out = std::get<sizeof...(T) - N>(formatters_)
|
||||||
|
.format(std::get<sizeof...(T) - N>(value.tuple), ctx);
|
||||||
|
if (N > 1) {
|
||||||
|
out = std::copy(value.sep.begin(), value.sep.end(), out);
|
||||||
|
ctx.advance_to(out);
|
||||||
|
return do_format(value, ctx, std::integral_constant<size_t, N - 1>());
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
// Check if T has an interface like a container adaptor (e.g. std::stack,
|
||||||
|
// std::queue, std::priority_queue).
|
||||||
|
template <typename T> class is_container_adaptor_like {
|
||||||
|
template <typename U> static auto check(U* p) -> typename U::container_type;
|
||||||
|
template <typename> static void check(...);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr const bool value =
|
||||||
|
!std::is_void<decltype(check<T>(nullptr))>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Container> struct all {
|
||||||
|
const Container& c;
|
||||||
|
auto begin() const -> typename Container::const_iterator { return c.begin(); }
|
||||||
|
auto end() const -> typename Container::const_iterator { return c.end(); }
|
||||||
|
};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename T, typename Char>
|
||||||
|
struct formatter<T, Char,
|
||||||
|
enable_if_t<detail::is_container_adaptor_like<T>::value>>
|
||||||
|
: formatter<detail::all<typename T::container_type>, Char> {
|
||||||
|
using all = detail::all<typename T::container_type>;
|
||||||
|
template <typename FormatContext>
|
||||||
|
auto format(const T& t, FormatContext& ctx) const -> decltype(ctx.out()) {
|
||||||
|
struct getter : T {
|
||||||
|
static auto get(const T& t) -> all {
|
||||||
|
return {t.*(&getter::c)}; // Access c through the derived class.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return formatter<all>::format(getter::get(t), ctx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
FMT_BEGIN_EXPORT
|
||||||
|
|
||||||
|
/**
|
||||||
|
\rst
|
||||||
|
Returns an object that formats `tuple` with elements separated by `sep`.
|
||||||
|
|
||||||
|
**Example**::
|
||||||
|
|
||||||
|
std::tuple<int, char> t = {1, 'a'};
|
||||||
|
fmt::print("{}", fmt::join(t, ", "));
|
||||||
|
// Output: "1, a"
|
||||||
|
\endrst
|
||||||
|
*/
|
||||||
|
template <typename... T>
|
||||||
|
FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple, string_view sep)
|
||||||
|
-> tuple_join_view<char, T...> {
|
||||||
|
return {tuple, sep};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... T>
|
||||||
|
FMT_CONSTEXPR auto join(const std::tuple<T...>& tuple,
|
||||||
|
basic_string_view<wchar_t> sep)
|
||||||
|
-> tuple_join_view<wchar_t, T...> {
|
||||||
|
return {tuple, sep};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\rst
|
||||||
|
Returns an object that formats `initializer_list` with elements separated by
|
||||||
|
`sep`.
|
||||||
|
|
||||||
|
**Example**::
|
||||||
|
|
||||||
|
fmt::print("{}", fmt::join({1, 2, 3}, ", "));
|
||||||
|
// Output: "1, 2, 3"
|
||||||
|
\endrst
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
auto join(std::initializer_list<T> list, string_view sep)
|
||||||
|
-> join_view<const T*, const T*> {
|
||||||
|
return join(std::begin(list), std::end(list), sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
FMT_END_EXPORT
|
||||||
|
FMT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // FMT_RANGES_H_
|
349
src/3rdparty/fmt/std.h
vendored
Normal file
349
src/3rdparty/fmt/std.h
vendored
Normal file
@@ -0,0 +1,349 @@
|
|||||||
|
// Formatting library for C++ - formatters for standard library types
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012 - present, Victor Zverovich
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// For the license information refer to format.h.
|
||||||
|
|
||||||
|
#ifndef FMT_STD_H_
|
||||||
|
#define FMT_STD_H_
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <exception>
|
||||||
|
#include <memory>
|
||||||
|
#include <thread>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "ostream.h"
|
||||||
|
|
||||||
|
#if FMT_HAS_INCLUDE(<version>)
|
||||||
|
# include <version>
|
||||||
|
#endif
|
||||||
|
// Checking FMT_CPLUSPLUS for warning suppression in MSVC.
|
||||||
|
#if FMT_CPLUSPLUS >= 201703L
|
||||||
|
# if FMT_HAS_INCLUDE(<filesystem>)
|
||||||
|
# include <filesystem>
|
||||||
|
# endif
|
||||||
|
# if FMT_HAS_INCLUDE(<variant>)
|
||||||
|
# include <variant>
|
||||||
|
# endif
|
||||||
|
# if FMT_HAS_INCLUDE(<optional>)
|
||||||
|
# include <optional>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// GCC 4 does not support FMT_HAS_INCLUDE.
|
||||||
|
#if FMT_HAS_INCLUDE(<cxxabi.h>) || defined(__GLIBCXX__)
|
||||||
|
# include <cxxabi.h>
|
||||||
|
// Android NDK with gabi++ library on some architectures does not implement
|
||||||
|
// abi::__cxa_demangle().
|
||||||
|
# ifndef __GABIXX_CXXABI_H__
|
||||||
|
# define FMT_HAS_ABI_CXA_DEMANGLE
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cpp_lib_filesystem
|
||||||
|
FMT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
void write_escaped_path(basic_memory_buffer<Char>& quoted,
|
||||||
|
const std::filesystem::path& p) {
|
||||||
|
write_escaped_string<Char>(std::back_inserter(quoted), p.string<Char>());
|
||||||
|
}
|
||||||
|
# ifdef _WIN32
|
||||||
|
template <>
|
||||||
|
inline void write_escaped_path<char>(memory_buffer& quoted,
|
||||||
|
const std::filesystem::path& p) {
|
||||||
|
auto buf = basic_memory_buffer<wchar_t>();
|
||||||
|
write_escaped_string<wchar_t>(std::back_inserter(buf), p.native());
|
||||||
|
// Convert UTF-16 to UTF-8.
|
||||||
|
if (!unicode_to_utf8<wchar_t>::convert(quoted, {buf.data(), buf.size()}))
|
||||||
|
FMT_THROW(std::runtime_error("invalid utf16"));
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
template <>
|
||||||
|
inline void write_escaped_path<std::filesystem::path::value_type>(
|
||||||
|
basic_memory_buffer<std::filesystem::path::value_type>& quoted,
|
||||||
|
const std::filesystem::path& p) {
|
||||||
|
write_escaped_string<std::filesystem::path::value_type>(
|
||||||
|
std::back_inserter(quoted), p.native());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
FMT_MODULE_EXPORT
|
||||||
|
template <typename Char>
|
||||||
|
struct formatter<std::filesystem::path, Char>
|
||||||
|
: formatter<basic_string_view<Char>> {
|
||||||
|
template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
|
||||||
|
auto out = formatter<basic_string_view<Char>>::parse(ctx);
|
||||||
|
this->set_debug_format(false);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
template <typename FormatContext>
|
||||||
|
auto format(const std::filesystem::path& p, FormatContext& ctx) const ->
|
||||||
|
typename FormatContext::iterator {
|
||||||
|
auto quoted = basic_memory_buffer<Char>();
|
||||||
|
detail::write_escaped_path(quoted, p);
|
||||||
|
return formatter<basic_string_view<Char>>::format(
|
||||||
|
basic_string_view<Char>(quoted.data(), quoted.size()), ctx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
FMT_END_NAMESPACE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FMT_BEGIN_NAMESPACE
|
||||||
|
FMT_MODULE_EXPORT
|
||||||
|
template <typename Char>
|
||||||
|
struct formatter<std::thread::id, Char> : basic_ostream_formatter<Char> {};
|
||||||
|
FMT_END_NAMESPACE
|
||||||
|
|
||||||
|
#ifdef __cpp_lib_optional
|
||||||
|
FMT_BEGIN_NAMESPACE
|
||||||
|
FMT_MODULE_EXPORT
|
||||||
|
template <typename T, typename Char>
|
||||||
|
struct formatter<std::optional<T>, Char,
|
||||||
|
std::enable_if_t<is_formattable<T, Char>::value>> {
|
||||||
|
private:
|
||||||
|
formatter<T, Char> underlying_;
|
||||||
|
static constexpr basic_string_view<Char> optional =
|
||||||
|
detail::string_literal<Char, 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l',
|
||||||
|
'('>{};
|
||||||
|
static constexpr basic_string_view<Char> none =
|
||||||
|
detail::string_literal<Char, 'n', 'o', 'n', 'e'>{};
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
FMT_CONSTEXPR static auto maybe_set_debug_format(U& u, bool set)
|
||||||
|
-> decltype(u.set_debug_format(set)) {
|
||||||
|
u.set_debug_format(set);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
FMT_CONSTEXPR static void maybe_set_debug_format(U&, ...) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) {
|
||||||
|
maybe_set_debug_format(underlying_, true);
|
||||||
|
return underlying_.parse(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FormatContext>
|
||||||
|
auto format(std::optional<T> const& opt, FormatContext& ctx) const
|
||||||
|
-> decltype(ctx.out()) {
|
||||||
|
if (!opt) return detail::write<Char>(ctx.out(), none);
|
||||||
|
|
||||||
|
auto out = ctx.out();
|
||||||
|
out = detail::write<Char>(out, optional);
|
||||||
|
ctx.advance_to(out);
|
||||||
|
out = underlying_.format(*opt, ctx);
|
||||||
|
return detail::write(out, ')');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
FMT_END_NAMESPACE
|
||||||
|
#endif // __cpp_lib_optional
|
||||||
|
|
||||||
|
#ifdef __cpp_lib_variant
|
||||||
|
FMT_BEGIN_NAMESPACE
|
||||||
|
FMT_MODULE_EXPORT
|
||||||
|
template <typename Char> struct formatter<std::monostate, Char> {
|
||||||
|
template <typename ParseContext>
|
||||||
|
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||||
|
return ctx.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FormatContext>
|
||||||
|
auto format(const std::monostate&, FormatContext& ctx) const
|
||||||
|
-> decltype(ctx.out()) {
|
||||||
|
auto out = ctx.out();
|
||||||
|
out = detail::write<Char>(out, "monostate");
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using variant_index_sequence =
|
||||||
|
std::make_index_sequence<std::variant_size<T>::value>;
|
||||||
|
|
||||||
|
template <typename> struct is_variant_like_ : std::false_type {};
|
||||||
|
template <typename... Types>
|
||||||
|
struct is_variant_like_<std::variant<Types...>> : std::true_type {};
|
||||||
|
|
||||||
|
// formattable element check.
|
||||||
|
template <typename T, typename C> class is_variant_formattable_ {
|
||||||
|
template <std::size_t... Is>
|
||||||
|
static std::conjunction<
|
||||||
|
is_formattable<std::variant_alternative_t<Is, T>, C>...>
|
||||||
|
check(std::index_sequence<Is...>);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr const bool value =
|
||||||
|
decltype(check(variant_index_sequence<T>{}))::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Char, typename OutputIt, typename T>
|
||||||
|
auto write_variant_alternative(OutputIt out, const T& v) -> OutputIt {
|
||||||
|
if constexpr (is_string<T>::value)
|
||||||
|
return write_escaped_string<Char>(out, detail::to_string_view(v));
|
||||||
|
else if constexpr (std::is_same_v<T, Char>)
|
||||||
|
return write_escaped_char(out, v);
|
||||||
|
else
|
||||||
|
return write<Char>(out, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
template <typename T> struct is_variant_like {
|
||||||
|
static constexpr const bool value = detail::is_variant_like_<T>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename C> struct is_variant_formattable {
|
||||||
|
static constexpr const bool value =
|
||||||
|
detail::is_variant_formattable_<T, C>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
FMT_MODULE_EXPORT
|
||||||
|
template <typename Variant, typename Char>
|
||||||
|
struct formatter<
|
||||||
|
Variant, Char,
|
||||||
|
std::enable_if_t<std::conjunction_v<
|
||||||
|
is_variant_like<Variant>, is_variant_formattable<Variant, Char>>>> {
|
||||||
|
template <typename ParseContext>
|
||||||
|
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||||
|
return ctx.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FormatContext>
|
||||||
|
auto format(const Variant& value, FormatContext& ctx) const
|
||||||
|
-> decltype(ctx.out()) {
|
||||||
|
auto out = ctx.out();
|
||||||
|
|
||||||
|
out = detail::write<Char>(out, "variant(");
|
||||||
|
try {
|
||||||
|
std::visit(
|
||||||
|
[&](const auto& v) {
|
||||||
|
out = detail::write_variant_alternative<Char>(out, v);
|
||||||
|
},
|
||||||
|
value);
|
||||||
|
} catch (const std::bad_variant_access&) {
|
||||||
|
detail::write<Char>(out, "valueless by exception");
|
||||||
|
}
|
||||||
|
*out++ = ')';
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
FMT_END_NAMESPACE
|
||||||
|
#endif // __cpp_lib_variant
|
||||||
|
|
||||||
|
FMT_BEGIN_NAMESPACE
|
||||||
|
FMT_MODULE_EXPORT
|
||||||
|
template <typename Char> struct formatter<std::error_code, Char> {
|
||||||
|
template <typename ParseContext>
|
||||||
|
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||||
|
return ctx.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FormatContext>
|
||||||
|
FMT_CONSTEXPR auto format(const std::error_code& ec, FormatContext& ctx) const
|
||||||
|
-> decltype(ctx.out()) {
|
||||||
|
auto out = ctx.out();
|
||||||
|
out = detail::write_bytes(out, ec.category().name(), format_specs<Char>());
|
||||||
|
out = detail::write<Char>(out, Char(':'));
|
||||||
|
out = detail::write<Char>(out, ec.value());
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
FMT_MODULE_EXPORT
|
||||||
|
template <typename T, typename Char>
|
||||||
|
struct formatter<
|
||||||
|
T, Char,
|
||||||
|
typename std::enable_if<std::is_base_of<std::exception, T>::value>::type> {
|
||||||
|
private:
|
||||||
|
bool with_typename_ = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
|
||||||
|
-> decltype(ctx.begin()) {
|
||||||
|
auto it = ctx.begin();
|
||||||
|
auto end = ctx.end();
|
||||||
|
if (it == end || *it == '}') return it;
|
||||||
|
if (*it == 't') {
|
||||||
|
++it;
|
||||||
|
with_typename_ = true;
|
||||||
|
}
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OutputIt>
|
||||||
|
auto format(const std::exception& ex,
|
||||||
|
basic_format_context<OutputIt, Char>& ctx) const -> OutputIt {
|
||||||
|
format_specs<Char> spec;
|
||||||
|
auto out = ctx.out();
|
||||||
|
if (!with_typename_)
|
||||||
|
return detail::write_bytes(out, string_view(ex.what()), spec);
|
||||||
|
|
||||||
|
const std::type_info& ti = typeid(ex);
|
||||||
|
#ifdef FMT_HAS_ABI_CXA_DEMANGLE
|
||||||
|
int status = 0;
|
||||||
|
std::size_t size = 0;
|
||||||
|
std::unique_ptr<char, decltype(&std::free)> demangled_name_ptr(
|
||||||
|
abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &std::free);
|
||||||
|
|
||||||
|
string_view demangled_name_view;
|
||||||
|
if (demangled_name_ptr) {
|
||||||
|
demangled_name_view = demangled_name_ptr.get();
|
||||||
|
|
||||||
|
// Normalization of stdlib inline namespace names.
|
||||||
|
// libc++ inline namespaces.
|
||||||
|
// std::__1::* -> std::*
|
||||||
|
// std::__1::__fs::* -> std::*
|
||||||
|
// libstdc++ inline namespaces.
|
||||||
|
// std::__cxx11::* -> std::*
|
||||||
|
// std::filesystem::__cxx11::* -> std::filesystem::*
|
||||||
|
if (demangled_name_view.starts_with("std::")) {
|
||||||
|
char* begin = demangled_name_ptr.get();
|
||||||
|
char* to = begin + 5; // std::
|
||||||
|
for (char *from = to, *end = begin + demangled_name_view.size();
|
||||||
|
from < end;) {
|
||||||
|
// This is safe, because demangled_name is NUL-terminated.
|
||||||
|
if (from[0] == '_' && from[1] == '_') {
|
||||||
|
char* next = from + 1;
|
||||||
|
while (next < end && *next != ':') next++;
|
||||||
|
if (next[0] == ':' && next[1] == ':') {
|
||||||
|
from = next + 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*to++ = *from++;
|
||||||
|
}
|
||||||
|
demangled_name_view = {begin, detail::to_unsigned(to - begin)};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
demangled_name_view = string_view(ti.name());
|
||||||
|
}
|
||||||
|
out = detail::write_bytes(out, demangled_name_view, spec);
|
||||||
|
#elif FMT_MSC_VERSION
|
||||||
|
string_view demangled_name_view(ti.name());
|
||||||
|
if (demangled_name_view.starts_with("class "))
|
||||||
|
demangled_name_view.remove_prefix(6);
|
||||||
|
else if (demangled_name_view.starts_with("struct "))
|
||||||
|
demangled_name_view.remove_prefix(7);
|
||||||
|
out = detail::write_bytes(out, demangled_name_view, spec);
|
||||||
|
#else
|
||||||
|
out = detail::write_bytes(out, string_view(ti.name()), spec);
|
||||||
|
#endif
|
||||||
|
out = detail::write<Char>(out, Char(':'));
|
||||||
|
out = detail::write<Char>(out, Char(' '));
|
||||||
|
out = detail::write_bytes(out, string_view(ex.what()), spec);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
FMT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // FMT_STD_H_
|
2
src/3rdparty/md5/md5.cpp
vendored
2
src/3rdparty/md5/md5.cpp
vendored
@@ -297,7 +297,7 @@ void Md5::Append(const void *data, const size_t nbytes)
|
|||||||
if (left) memcpy(this->buf, p, left);
|
if (left) memcpy(this->buf, p, left);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Md5::Finish(uint8 digest[16])
|
void Md5::Finish(MD5Hash &digest)
|
||||||
{
|
{
|
||||||
static const uint8 pad[64] = {
|
static const uint8 pad[64] = {
|
||||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
25
src/3rdparty/md5/md5.h
vendored
25
src/3rdparty/md5/md5.h
vendored
@@ -53,6 +53,29 @@
|
|||||||
#ifndef MD5_INCLUDED
|
#ifndef MD5_INCLUDED
|
||||||
#define MD5_INCLUDED
|
#define MD5_INCLUDED
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
/** The number of bytes in a MD5 hash. */
|
||||||
|
static const size_t MD5_HASH_BYTES = 16;
|
||||||
|
|
||||||
|
/** Container for storing a MD5 hash/checksum/digest. */
|
||||||
|
struct MD5Hash : std::array<byte, MD5_HASH_BYTES> {
|
||||||
|
MD5Hash() : std::array<byte, MD5_HASH_BYTES>{} {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exclusively-or the given hash into this hash.
|
||||||
|
* @param other The other hash.
|
||||||
|
* @return Reference to this hash.
|
||||||
|
*/
|
||||||
|
MD5Hash &operator^=(const MD5Hash &other)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < size(); i++) this->operator[](i) ^= other[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
char *md5sumToString(char *buf, const char *last, const MD5Hash &md5sum);
|
||||||
|
|
||||||
struct Md5 {
|
struct Md5 {
|
||||||
private:
|
private:
|
||||||
uint32 count[2]; ///< message length in bits, lsw first
|
uint32 count[2]; ///< message length in bits, lsw first
|
||||||
@@ -64,7 +87,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
Md5();
|
Md5();
|
||||||
void Append(const void *data, const size_t nbytes);
|
void Append(const void *data, const size_t nbytes);
|
||||||
void Finish(uint8 digest[16]);
|
void Finish(MD5Hash &digest);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MD5_INCLUDED */
|
#endif /* MD5_INCLUDED */
|
||||||
|
6
src/3rdparty/squirrel/squirrel/squtils.h
vendored
6
src/3rdparty/squirrel/squirrel/squtils.h
vendored
@@ -2,6 +2,8 @@
|
|||||||
#ifndef _SQUTILS_H_
|
#ifndef _SQUTILS_H_
|
||||||
#define _SQUTILS_H_
|
#define _SQUTILS_H_
|
||||||
|
|
||||||
|
#include "../../fmt/format.h"
|
||||||
|
#include "../../../script/script_fatalerror.hpp"
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
void *sq_vm_malloc(SQUnsignedInteger size);
|
void *sq_vm_malloc(SQUnsignedInteger size);
|
||||||
@@ -105,6 +107,10 @@ private:
|
|||||||
void _realloc(SQUnsignedInteger newsize)
|
void _realloc(SQUnsignedInteger newsize)
|
||||||
{
|
{
|
||||||
newsize = (newsize > 0)?newsize:4;
|
newsize = (newsize > 0)?newsize:4;
|
||||||
|
if (newsize > SIZE_MAX / sizeof(T)) {
|
||||||
|
std::string msg = fmt::format("cannot resize to {}", newsize);
|
||||||
|
throw Script_FatalError(msg);
|
||||||
|
}
|
||||||
_vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
|
_vals = (T*)SQ_REALLOC(_vals, _allocated * sizeof(T), newsize * sizeof(T));
|
||||||
_allocated = (size_t)newsize;
|
_allocated = (size_t)newsize;
|
||||||
}
|
}
|
||||||
|
@@ -441,6 +441,7 @@ add_files(
|
|||||||
strgen/strgen.h
|
strgen/strgen.h
|
||||||
string.cpp
|
string.cpp
|
||||||
string_base.h
|
string_base.h
|
||||||
|
string_extra.cpp
|
||||||
string_func.h
|
string_func.h
|
||||||
string_func_extra.h
|
string_func_extra.h
|
||||||
string_type.h
|
string_type.h
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "animated_tile.h"
|
#include "animated_tile.h"
|
||||||
#include "core/alloc_func.hpp"
|
#include "core/alloc_func.hpp"
|
||||||
#include "core/smallvec_type.hpp"
|
#include "core/container_func.hpp"
|
||||||
#include "tile_cmd.h"
|
#include "tile_cmd.h"
|
||||||
#include "viewport_func.h"
|
#include "viewport_func.h"
|
||||||
#include "framerate_type.h"
|
#include "framerate_type.h"
|
||||||
|
@@ -178,7 +178,7 @@ static inline CargoTypes GetAvailableVehicleCargoTypes(EngineID engine, bool inc
|
|||||||
*/
|
*/
|
||||||
CargoArray GetCapacityOfArticulatedParts(EngineID engine)
|
CargoArray GetCapacityOfArticulatedParts(EngineID engine)
|
||||||
{
|
{
|
||||||
CargoArray capacity;
|
CargoArray capacity{};
|
||||||
const Engine *e = Engine::Get(engine);
|
const Engine *e = Engine::Get(engine);
|
||||||
|
|
||||||
CargoID cargo_type;
|
CargoID cargo_type;
|
||||||
@@ -336,7 +336,7 @@ void CheckConsistencyOfArticulatedVehicle(const Vehicle *v)
|
|||||||
|
|
||||||
CargoTypes real_refit_union = 0;
|
CargoTypes real_refit_union = 0;
|
||||||
CargoTypes real_refit_intersection = ALL_CARGOTYPES;
|
CargoTypes real_refit_intersection = ALL_CARGOTYPES;
|
||||||
CargoArray real_default_capacity;
|
CargoArray real_default_capacity{};
|
||||||
|
|
||||||
do {
|
do {
|
||||||
CargoTypes refit_mask = GetAvailableVehicleCargoTypes(v->engine_type, true);
|
CargoTypes refit_mask = GetAvailableVehicleCargoTypes(v->engine_type, true);
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#include "gfx_type.h"
|
#include "gfx_type.h"
|
||||||
#include "textfile_type.h"
|
#include "textfile_type.h"
|
||||||
#include "textfile_gui.h"
|
#include "textfile_gui.h"
|
||||||
|
#include "3rdparty/md5/md5.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
/* Forward declare these; can't do 'struct X' in functions as older GCCs barf on that */
|
/* Forward declare these; can't do 'struct X' in functions as older GCCs barf on that */
|
||||||
@@ -31,7 +32,7 @@ struct MD5File {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::string filename; ///< filename
|
std::string filename; ///< filename
|
||||||
uint8 hash[16]; ///< md5 sum of the file
|
MD5Hash hash; ///< md5 sum of the file
|
||||||
std::string missing_warning; ///< warning when this file is missing
|
std::string missing_warning; ///< warning when this file is missing
|
||||||
ChecksumResult check_result; ///< cached result of md5 check
|
ChecksumResult check_result; ///< cached result of md5 check
|
||||||
|
|
||||||
|
@@ -98,7 +98,7 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const char *c = item->value->c_str();
|
const char *c = item->value->c_str();
|
||||||
for (uint i = 0; i < sizeof(file->hash) * 2; i++, c++) {
|
for (size_t i = 0; i < file->hash.size() * 2; i++, c++) {
|
||||||
uint j;
|
uint j;
|
||||||
if ('0' <= *c && *c <= '9') {
|
if ('0' <= *c && *c <= '9') {
|
||||||
j = *c - '0';
|
j = *c - '0';
|
||||||
@@ -284,14 +284,11 @@ template <class Tbase_set> const char *TryGetBaseSetFile(const ContentInfo *ci,
|
|||||||
if (s->shortname != ci->unique_id) continue;
|
if (s->shortname != ci->unique_id) continue;
|
||||||
if (!md5sum) return s->files[0].filename.c_str();
|
if (!md5sum) return s->files[0].filename.c_str();
|
||||||
|
|
||||||
byte md5[16];
|
MD5Hash md5;
|
||||||
memset(md5, 0, sizeof(md5));
|
|
||||||
for (uint i = 0; i < Tbase_set::NUM_FILES; i++) {
|
for (uint i = 0; i < Tbase_set::NUM_FILES; i++) {
|
||||||
for (uint j = 0; j < sizeof(md5); j++) {
|
md5 ^= s->files[i].hash;
|
||||||
md5[j] ^= s->files[i].hash[j];
|
|
||||||
}
|
}
|
||||||
}
|
if (md5 == ci->md5sum) return s->files[0].filename.c_str();
|
||||||
if (memcmp(md5, ci->md5sum, sizeof(md5)) == 0) return s->files[0].filename.c_str();
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@@ -70,48 +70,22 @@ enum CargoType {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Test whether cargo type is not CT_INVALID */
|
/** Test whether cargo type is not CT_INVALID */
|
||||||
inline bool IsCargoTypeValid(CargoType t) { return t != CT_INVALID; }
|
inline bool IsValidCargoType(CargoType t) { return t != CT_INVALID; }
|
||||||
/** Test whether cargo type is not CT_INVALID */
|
/** Test whether cargo type is not CT_INVALID */
|
||||||
inline bool IsCargoIDValid(CargoID t) { return t != CT_INVALID; }
|
inline bool IsValidCargoID(CargoID t) { return t != CT_INVALID; }
|
||||||
|
|
||||||
typedef uint64 CargoTypes;
|
typedef uint64 CargoTypes;
|
||||||
|
|
||||||
static const CargoTypes ALL_CARGOTYPES = (CargoTypes)UINT64_MAX;
|
static const CargoTypes ALL_CARGOTYPES = (CargoTypes)UINT64_MAX;
|
||||||
|
|
||||||
/** Class for storing amounts of cargo */
|
/** Class for storing amounts of cargo */
|
||||||
struct CargoArray {
|
struct CargoArray : std::array<uint, NUM_CARGO> {
|
||||||
private:
|
|
||||||
uint amount[NUM_CARGO]; ///< Amount of each type of cargo.
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** Default constructor. */
|
|
||||||
inline CargoArray()
|
|
||||||
{
|
|
||||||
this->Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Reset all entries. */
|
/** Reset all entries. */
|
||||||
inline void Clear()
|
inline void Clear()
|
||||||
{
|
{
|
||||||
memset(this->amount, 0, sizeof(this->amount));
|
for (uint &it : *this) {
|
||||||
|
it = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Read/write access to an amount of a specific cargo type.
|
|
||||||
* @param cargo Cargo type to access.
|
|
||||||
*/
|
|
||||||
inline uint &operator[](CargoID cargo)
|
|
||||||
{
|
|
||||||
return this->amount[cargo];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read-only access to an amount of a specific cargo type.
|
|
||||||
* @param cargo Cargo type to access.
|
|
||||||
*/
|
|
||||||
inline const uint &operator[](CargoID cargo) const
|
|
||||||
{
|
|
||||||
return this->amount[cargo];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -121,24 +95,20 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline const T GetSum() const
|
inline const T GetSum() const
|
||||||
{
|
{
|
||||||
T ret = 0;
|
T result = 0;
|
||||||
for (size_t i = 0; i < lengthof(this->amount); i++) {
|
for (const uint &it : *this) {
|
||||||
ret += this->amount[i];
|
result += it;
|
||||||
}
|
}
|
||||||
return ret;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the amount of cargos that have an amount.
|
* Get the amount of cargos that have an amount.
|
||||||
* @return The amount.
|
* @return The amount.
|
||||||
*/
|
*/
|
||||||
inline byte GetCount() const
|
inline uint GetCount() const
|
||||||
{
|
{
|
||||||
byte count = 0;
|
return std::count_if(this->begin(), this->end(), [](uint amount) { return amount != 0; });
|
||||||
for (size_t i = 0; i < lengthof(this->amount); i++) {
|
|
||||||
if (this->amount[i] != 0) count++;
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
struct CompanyEconomyEntry {
|
struct CompanyEconomyEntry {
|
||||||
Money income; ///< The amount of income.
|
Money income; ///< The amount of income.
|
||||||
Money expenses; ///< The amount of expenses.
|
Money expenses; ///< The amount of expenses.
|
||||||
CargoArray delivered_cargo; ///< The amount of delivered cargo.
|
CargoArray delivered_cargo{}; ///< The amount of delivered cargo.
|
||||||
int32 performance_history; ///< Company score (scale 0-1000)
|
int32 performance_history; ///< Company score (scale 0-1000)
|
||||||
Money company_value; ///< The value of the company.
|
Money company_value; ///< The value of the company.
|
||||||
};
|
};
|
||||||
|
@@ -12,6 +12,7 @@ add_files(
|
|||||||
endian_type.hpp
|
endian_type.hpp
|
||||||
enum_type.hpp
|
enum_type.hpp
|
||||||
hash_func.hpp
|
hash_func.hpp
|
||||||
|
format.hpp
|
||||||
geometry_func.cpp
|
geometry_func.cpp
|
||||||
geometry_func.hpp
|
geometry_func.hpp
|
||||||
geometry_type.hpp
|
geometry_type.hpp
|
||||||
@@ -30,7 +31,6 @@ add_files(
|
|||||||
serialisation.cpp
|
serialisation.cpp
|
||||||
serialisation.hpp
|
serialisation.hpp
|
||||||
smallstack_type.hpp
|
smallstack_type.hpp
|
||||||
smallvec_type.hpp
|
|
||||||
tinystring_type.hpp
|
tinystring_type.hpp
|
||||||
y_combinator.hpp
|
y_combinator.hpp
|
||||||
)
|
)
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file container_func.hpp Functions related to use of containers. */
|
/** @file container_func.hpp Some simple functions to help with accessing containers. */
|
||||||
|
|
||||||
#ifndef CONTAINER_FUNC_HPP
|
#ifndef CONTAINER_FUNC_HPP
|
||||||
#define CONTAINER_FUNC_HPP
|
#define CONTAINER_FUNC_HPP
|
||||||
@@ -13,6 +13,42 @@
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to append an item to a container if it is not already contained.
|
||||||
|
* The container must have a \c emplace_back function.
|
||||||
|
* Consider using std::set, std::unordered_set or std::flat_set in new code.
|
||||||
|
*
|
||||||
|
* @param container A reference to the container to be extended
|
||||||
|
* @param item Reference to the item to be copy-constructed if not found
|
||||||
|
*
|
||||||
|
* @return Whether the item was already present
|
||||||
|
*/
|
||||||
|
template <typename Container>
|
||||||
|
inline bool include(Container &container, typename Container::const_reference &item)
|
||||||
|
{
|
||||||
|
const bool is_member = std::find(container.begin(), container.end(), item) != container.end();
|
||||||
|
if (!is_member) container.emplace_back(item);
|
||||||
|
return is_member;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to get the index of an item
|
||||||
|
* Consider using std::set, std::unordered_set or std::flat_set in new code.
|
||||||
|
*
|
||||||
|
* @param container A reference to the container to be searched.
|
||||||
|
* @param item Reference to the item to be search for
|
||||||
|
*
|
||||||
|
* @return Index of element if found, otherwise -1
|
||||||
|
*/
|
||||||
|
template <typename Container>
|
||||||
|
int find_index(Container const &container, typename Container::const_reference item)
|
||||||
|
{
|
||||||
|
auto const it = std::find(container.begin(), container.end(), item);
|
||||||
|
if (it != container.end()) return std::distance(container.begin(), it);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename C, typename UP> unsigned int container_unordered_remove_if (C &container, UP predicate) {
|
template <typename C, typename UP> unsigned int container_unordered_remove_if (C &container, UP predicate) {
|
||||||
unsigned int removecount = 0;
|
unsigned int removecount = 0;
|
||||||
for (auto it = container.begin(); it != container.end();) {
|
for (auto it = container.begin(); it != container.end();) {
|
||||||
|
44
src/core/format.hpp
Normal file
44
src/core/format.hpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* OpenTTD 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, version 2.
|
||||||
|
* OpenTTD 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. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file format.hpp String formatting functions and helpers. */
|
||||||
|
|
||||||
|
#ifndef FORMAT_HPP
|
||||||
|
#define FORMAT_HPP
|
||||||
|
|
||||||
|
#include "../3rdparty/fmt/format.h"
|
||||||
|
//#include "strong_typedef_type.hpp"
|
||||||
|
|
||||||
|
template <typename E, typename Char>
|
||||||
|
struct fmt::formatter<E, Char, std::enable_if_t<std::is_enum<E>::value>> : fmt::formatter<typename std::underlying_type<E>::type> {
|
||||||
|
using underlying_type = typename std::underlying_type<E>::type;
|
||||||
|
using parent = typename fmt::formatter<underlying_type>;
|
||||||
|
|
||||||
|
constexpr fmt::format_parse_context::iterator parse(fmt::format_parse_context &ctx) {
|
||||||
|
return parent::parse(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt::format_context::iterator format(const E &e, format_context &ctx) const {
|
||||||
|
return parent::format(underlying_type(e), ctx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//template <typename T, typename Char>
|
||||||
|
//struct fmt::formatter<T, Char, std::enable_if_t<std::is_base_of<StrongTypedefBase, T>::value>> : fmt::formatter<typename T::Type> {
|
||||||
|
// using underlying_type = typename T::Type;
|
||||||
|
// using parent = typename fmt::formatter<underlying_type>;
|
||||||
|
//
|
||||||
|
// constexpr fmt::format_parse_context::iterator parse(fmt::format_parse_context &ctx) {
|
||||||
|
// return parent::parse(ctx);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fmt::format_context::iterator format(const T &t, format_context &ctx) const {
|
||||||
|
// return parent::format(underlying_type(t), ctx);
|
||||||
|
// }
|
||||||
|
//};
|
||||||
|
|
||||||
|
#endif /* FORMAT_HPP */
|
@@ -10,7 +10,6 @@
|
|||||||
#ifndef POOL_TYPE_HPP
|
#ifndef POOL_TYPE_HPP
|
||||||
#define POOL_TYPE_HPP
|
#define POOL_TYPE_HPP
|
||||||
|
|
||||||
#include "smallvec_type.hpp"
|
|
||||||
#include "enum_type.hpp"
|
#include "enum_type.hpp"
|
||||||
|
|
||||||
/** Various types of a pool. */
|
/** Various types of a pool. */
|
||||||
|
@@ -10,8 +10,6 @@
|
|||||||
#ifndef SMALLSTACK_TYPE_HPP
|
#ifndef SMALLSTACK_TYPE_HPP
|
||||||
#define SMALLSTACK_TYPE_HPP
|
#define SMALLSTACK_TYPE_HPP
|
||||||
|
|
||||||
#include "smallvec_type.hpp"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simplified pool which stores values instead of pointers and doesn't
|
* A simplified pool which stores values instead of pointers and doesn't
|
||||||
* redefine operator new/delete. It also never zeroes memory and always reuses
|
* redefine operator new/delete. It also never zeroes memory and always reuses
|
||||||
|
@@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD 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, version 2.
|
|
||||||
* OpenTTD 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. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file smallvec_type.hpp Simple vector class that allows allocating an item without the need to copy this->data needlessly. */
|
|
||||||
|
|
||||||
#ifndef SMALLVEC_TYPE_HPP
|
|
||||||
#define SMALLVEC_TYPE_HPP
|
|
||||||
|
|
||||||
#include "alloc_func.hpp"
|
|
||||||
#include "mem_func.hpp"
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function to append an item to a vector if it is not already contained
|
|
||||||
* Consider using std::set, std::unordered_set or std::flat_set in new code
|
|
||||||
*
|
|
||||||
* @param vec A reference to the vector to be extended
|
|
||||||
* @param item Reference to the item to be copy-constructed if not found
|
|
||||||
*
|
|
||||||
* @return Whether the item was already present
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
inline bool include(std::vector<T>& vec, const T &item)
|
|
||||||
{
|
|
||||||
const bool is_member = std::find(vec.begin(), vec.end(), item) != vec.end();
|
|
||||||
if (!is_member) vec.emplace_back(item);
|
|
||||||
return is_member;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function to get the index of an item
|
|
||||||
* Consider using std::set, std::unordered_set or std::flat_set in new code
|
|
||||||
*
|
|
||||||
* @param vec A reference to the vector to be extended
|
|
||||||
* @param item Reference to the item to be search for
|
|
||||||
*
|
|
||||||
* @return Index of element if found, otherwise -1
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
int find_index(std::vector<T> const& vec, T const& item)
|
|
||||||
{
|
|
||||||
auto const it = std::find(vec.begin(), vec.end(), item);
|
|
||||||
if (it != vec.end()) return it - vec.begin();
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SMALLVEC_TYPE_HPP */
|
|
@@ -928,6 +928,13 @@ static bool CopyAutosave(const std::string &old_name, const std::string &new_nam
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void CrashLog::SendSurvey() const
|
||||||
|
{
|
||||||
|
if (_game_mode == GM_NORMAL) {
|
||||||
|
_survey.Transmit(NetworkSurveyHandler::Reason::CRASH, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the crash log, writes it to a file and then subsequently tries
|
* Makes the crash log, writes it to a file and then subsequently tries
|
||||||
* to make a crash dump and crash savegame. It uses DEBUG to write
|
* to make a crash dump and crash savegame. It uses DEBUG to write
|
||||||
@@ -1174,9 +1181,7 @@ bool CrashLog::MakeCrashSavegameAndScreenshot() const
|
|||||||
printf("Writing crash screenshot failed.\n\n");
|
printf("Writing crash screenshot failed.\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_game_mode == GM_NORMAL) {
|
this->SendSurvey();
|
||||||
_survey.Transmit(NetworkSurveyHandler::Reason::CRASH, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -194,6 +194,8 @@ public:
|
|||||||
bool MakeVersionInfoLog() const;
|
bool MakeVersionInfoLog() const;
|
||||||
bool MakeCrashSavegameAndScreenshot() const;
|
bool MakeCrashSavegameAndScreenshot() const;
|
||||||
|
|
||||||
|
void SendSurvey() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialiser for crash logs; do the appropriate things so crashes are
|
* Initialiser for crash logs; do the appropriate things so crashes are
|
||||||
* handled by our crash handler instead of returning straight to the OS.
|
* handled by our crash handler instead of returning straight to the OS.
|
||||||
|
@@ -27,7 +27,6 @@
|
|||||||
#include "vehicle_gui.h"
|
#include "vehicle_gui.h"
|
||||||
#include "order_base.h"
|
#include "order_base.h"
|
||||||
#include "settings_type.h"
|
#include "settings_type.h"
|
||||||
#include "core/smallvec_type.hpp"
|
|
||||||
#include "date_type.h"
|
#include "date_type.h"
|
||||||
#include "company_type.h"
|
#include "company_type.h"
|
||||||
#include "cargo_type.h"
|
#include "cargo_type.h"
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
#define DEPARTURES_FUNC_H
|
#define DEPARTURES_FUNC_H
|
||||||
|
|
||||||
#include "station_base.h"
|
#include "station_base.h"
|
||||||
#include "core/smallvec_type.hpp"
|
|
||||||
#include "departures_type.h"
|
#include "departures_type.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@@ -28,7 +28,6 @@
|
|||||||
#include "vehicle_gui.h"
|
#include "vehicle_gui.h"
|
||||||
#include "order_base.h"
|
#include "order_base.h"
|
||||||
#include "settings_type.h"
|
#include "settings_type.h"
|
||||||
#include "core/smallvec_type.hpp"
|
|
||||||
#include "date_type.h"
|
#include "date_type.h"
|
||||||
#include "company_type.h"
|
#include "company_type.h"
|
||||||
#include "departures_func.h"
|
#include "departures_func.h"
|
||||||
|
@@ -855,7 +855,7 @@ struct DepotWindow : Window {
|
|||||||
|
|
||||||
if (v == nullptr || mode != MODE_DRAG_VEHICLE) return false;
|
if (v == nullptr || mode != MODE_DRAG_VEHICLE) return false;
|
||||||
|
|
||||||
CargoArray capacity, loaded;
|
CargoArray capacity{}, loaded{};
|
||||||
|
|
||||||
/* Display info for single (articulated) vehicle, or for whole chain starting with selected vehicle */
|
/* Display info for single (articulated) vehicle, or for whole chain starting with selected vehicle */
|
||||||
bool whole_chain = (this->type == VEH_TRAIN && _ctrl_pressed);
|
bool whole_chain = (this->type == VEH_TRAIN && _ctrl_pressed);
|
||||||
|
@@ -42,6 +42,7 @@
|
|||||||
#include "economy_base.h"
|
#include "economy_base.h"
|
||||||
#include "core/pool_func.hpp"
|
#include "core/pool_func.hpp"
|
||||||
#include "core/backup_type.hpp"
|
#include "core/backup_type.hpp"
|
||||||
|
#include "core/container_func.hpp"
|
||||||
#include "infrastructure_func.h"
|
#include "infrastructure_func.h"
|
||||||
#include "cargo_type.h"
|
#include "cargo_type.h"
|
||||||
#include "water.h"
|
#include "water.h"
|
||||||
@@ -1113,12 +1114,9 @@ void ForAcceptingIndustries(const Station *st, CargoID cargo_type, IndustryID so
|
|||||||
Industry *ind = i.industry;
|
Industry *ind = i.industry;
|
||||||
if (ind->index == source) continue;
|
if (ind->index == source) continue;
|
||||||
|
|
||||||
uint cargo_index;
|
int cargo_index = ind->GetCargoAcceptedIndex(cargo_type);
|
||||||
for (cargo_index = 0; cargo_index < lengthof(ind->accepts_cargo); cargo_index++) {
|
|
||||||
if (cargo_type == ind->accepts_cargo[cargo_index]) break;
|
|
||||||
}
|
|
||||||
/* Check if matching cargo has been found */
|
/* Check if matching cargo has been found */
|
||||||
if (cargo_index >= lengthof(ind->accepts_cargo)) continue;
|
if (cargo_index < 0) continue;
|
||||||
|
|
||||||
/* Check if industry temporarily refuses acceptance */
|
/* Check if industry temporarily refuses acceptance */
|
||||||
if (IndustryTemporarilyRefusesCargo(ind, cargo_type)) continue;
|
if (IndustryTemporarilyRefusesCargo(ind, cargo_type)) continue;
|
||||||
@@ -1932,7 +1930,7 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||||||
CargoStationIDStackSet next_station = front->GetNextStoppingStation();
|
CargoStationIDStackSet next_station = front->GetNextStoppingStation();
|
||||||
|
|
||||||
bool use_autorefit = front->current_order.IsRefit() && front->current_order.GetRefitCargo() == CT_AUTO_REFIT;
|
bool use_autorefit = front->current_order.IsRefit() && front->current_order.GetRefitCargo() == CT_AUTO_REFIT;
|
||||||
CargoArray consist_capleft;
|
CargoArray consist_capleft{};
|
||||||
bool should_reserve_consist = false;
|
bool should_reserve_consist = false;
|
||||||
bool reserve_consist_cargo_type_loading = false;
|
bool reserve_consist_cargo_type_loading = false;
|
||||||
if (_settings_game.order.improved_load && use_autorefit) {
|
if (_settings_game.order.improved_load && use_autorefit) {
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
/** @file error_gui.cpp GUI related to errors. */
|
/** @file error_gui.cpp GUI related to errors. */
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "core/mem_func.hpp"
|
||||||
#include "landscape.h"
|
#include "landscape.h"
|
||||||
#include "newgrf_text.h"
|
#include "newgrf_text.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include "string_func_extra.h"
|
#include "string_func_extra.h"
|
||||||
#include "strings_func.h"
|
#include "strings_func.h"
|
||||||
#include "tar_type.h"
|
#include "tar_type.h"
|
||||||
|
#include "core/container_func.hpp"
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
@@ -631,13 +632,12 @@ const char *FiosGetScreenshotDir()
|
|||||||
/** Basic data to distinguish a scenario. Used in the server list window */
|
/** Basic data to distinguish a scenario. Used in the server list window */
|
||||||
struct ScenarioIdentifier {
|
struct ScenarioIdentifier {
|
||||||
uint32 scenid; ///< ID for the scenario (generated by content).
|
uint32 scenid; ///< ID for the scenario (generated by content).
|
||||||
uint8 md5sum[16]; ///< MD5 checksum of file.
|
MD5Hash md5sum; ///< MD5 checksum of file.
|
||||||
std::string filename; ///< filename of the file.
|
std::string filename; ///< filename of the file.
|
||||||
|
|
||||||
bool operator == (const ScenarioIdentifier &other) const
|
bool operator == (const ScenarioIdentifier &other) const
|
||||||
{
|
{
|
||||||
return this->scenid == other.scenid &&
|
return this->scenid == other.scenid && this->md5sum == other.md5sum;
|
||||||
memcmp(this->md5sum, other.md5sum, sizeof(this->md5sum)) == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator != (const ScenarioIdentifier &other) const
|
bool operator != (const ScenarioIdentifier &other) const
|
||||||
@@ -716,7 +716,7 @@ const char *FindScenario(const ContentInfo *ci, bool md5sum)
|
|||||||
_scanner.Scan(false);
|
_scanner.Scan(false);
|
||||||
|
|
||||||
for (ScenarioIdentifier &id : _scanner) {
|
for (ScenarioIdentifier &id : _scanner) {
|
||||||
if (md5sum ? (memcmp(id.md5sum, ci->md5sum, sizeof(id.md5sum)) == 0)
|
if (md5sum ? (id.md5sum == ci->md5sum)
|
||||||
: (id.scenid == ci->unique_id)) {
|
: (id.scenid == ci->unique_id)) {
|
||||||
return id.filename.c_str();
|
return id.filename.c_str();
|
||||||
}
|
}
|
||||||
|
@@ -289,7 +289,7 @@ private:
|
|||||||
|
|
||||||
StringFilter string_filter; ///< Filter for available games.
|
StringFilter string_filter; ///< Filter for available games.
|
||||||
QueryString filter_editbox; ///< Filter editbox;
|
QueryString filter_editbox; ///< Filter editbox;
|
||||||
std::vector<bool> fios_items_shown; ///< Map of the filtered out fios items
|
std::vector<FiosItem *> display_list; ///< Filtered display list
|
||||||
|
|
||||||
static void SaveGameConfirmationCallback(Window *w, bool confirmed)
|
static void SaveGameConfirmationCallback(Window *w, bool confirmed)
|
||||||
{
|
{
|
||||||
@@ -451,14 +451,8 @@ public:
|
|||||||
|
|
||||||
Rect tr = r.Shrink(WidgetDimensions::scaled.inset).WithHeight(this->resize.step_height);
|
Rect tr = r.Shrink(WidgetDimensions::scaled.inset).WithHeight(this->resize.step_height);
|
||||||
uint scroll_pos = this->vscroll->GetPosition();
|
uint scroll_pos = this->vscroll->GetPosition();
|
||||||
for (uint row = 0; row < this->fios_items.size() && tr.top < br.bottom; row++) {
|
for (auto it = this->display_list.begin() + scroll_pos; it != this->display_list.end() && tr.top < br.bottom; ++it) {
|
||||||
if (!this->fios_items_shown[row]) {
|
const FiosItem *item = *it;
|
||||||
/* The current item is filtered out : we do not show it */
|
|
||||||
scroll_pos++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (row < scroll_pos) continue;
|
|
||||||
const FiosItem *item = &this->fios_items[row];
|
|
||||||
|
|
||||||
if (item == this->selected) {
|
if (item == this->selected) {
|
||||||
GfxFillRect(br.left, tr.top, br.right, tr.bottom, PC_DARK_BLUE);
|
GfxFillRect(br.left, tr.top, br.right, tr.bottom, PC_DARK_BLUE);
|
||||||
@@ -673,16 +667,11 @@ public:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WID_SL_DRIVES_DIRECTORIES_LIST: { // Click the listbox
|
case WID_SL_DRIVES_DIRECTORIES_LIST: { // Click the listbox
|
||||||
int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WidgetDimensions::scaled.inset.top);
|
auto it = this->vscroll->GetScrolledItemFromWidget(this->display_list, pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WidgetDimensions::scaled.inset.top);
|
||||||
if (y == INT_MAX) return;
|
if (it == this->display_list.end()) return;
|
||||||
|
|
||||||
/* Get the corresponding non-filtered out item from the list */
|
/* Get the corresponding non-filtered out item from the list */
|
||||||
int i = 0;
|
const FiosItem *file = *it;
|
||||||
while (i <= y) {
|
|
||||||
if (!this->fios_items_shown[i]) y++;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
const FiosItem *file = &this->fios_items[y];
|
|
||||||
|
|
||||||
if (FiosBrowseTo(file)) {
|
if (FiosBrowseTo(file)) {
|
||||||
/* Changed directory, need refresh. */
|
/* Changed directory, need refresh. */
|
||||||
@@ -750,16 +739,11 @@ public:
|
|||||||
void OnMouseOver(Point pt, int widget) override
|
void OnMouseOver(Point pt, int widget) override
|
||||||
{
|
{
|
||||||
if (widget == WID_SL_DRIVES_DIRECTORIES_LIST) {
|
if (widget == WID_SL_DRIVES_DIRECTORIES_LIST) {
|
||||||
int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WidgetDimensions::scaled.inset.top);
|
auto it = this->vscroll->GetScrolledItemFromWidget(this->display_list, pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WidgetDimensions::scaled.inset.top);
|
||||||
if (y == INT_MAX) return;
|
if (it == this->display_list.end()) return;
|
||||||
|
|
||||||
/* Get the corresponding non-filtered out item from the list */
|
/* Get the corresponding non-filtered out item from the list */
|
||||||
int i = 0;
|
const FiosItem *file = *it;
|
||||||
while (i <= y) {
|
|
||||||
if (!this->fios_items_shown[i]) y++;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
const FiosItem *file = &this->fios_items[y];
|
|
||||||
|
|
||||||
if (file != this->highlighted) {
|
if (file != this->highlighted) {
|
||||||
this->highlighted = file;
|
this->highlighted = file;
|
||||||
@@ -842,6 +826,35 @@ public:
|
|||||||
this->vscroll->SetCapacityFromWidget(this, WID_SL_DRIVES_DIRECTORIES_LIST);
|
this->vscroll->SetCapacityFromWidget(this, WID_SL_DRIVES_DIRECTORIES_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BuildDisplayList()
|
||||||
|
{
|
||||||
|
/* Filter changes */
|
||||||
|
this->display_list.clear();
|
||||||
|
this->display_list.reserve(this->fios_items.size());
|
||||||
|
|
||||||
|
if (this->string_filter.IsEmpty()) {
|
||||||
|
/* We don't filter anything out if the filter editbox is empty */
|
||||||
|
for (auto &it : this->fios_items) {
|
||||||
|
this->display_list.push_back(&it);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (auto &it : this->fios_items) {
|
||||||
|
this->string_filter.ResetState();
|
||||||
|
this->string_filter.AddLine(it.title);
|
||||||
|
/* We set the vector to show this fios element as filtered depending on the result of the filter */
|
||||||
|
if (this->string_filter.GetState()) {
|
||||||
|
this->display_list.push_back(&it);
|
||||||
|
} else if (&it == this->selected) {
|
||||||
|
/* The selected element has been filtered out */
|
||||||
|
this->selected = nullptr;
|
||||||
|
this->OnInvalidateData(SLIWD_SELECTION_CHANGES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->vscroll->SetCount(this->display_list.size());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some data on this window has become invalid.
|
* Some data on this window has become invalid.
|
||||||
* @param data Information about the changed data.
|
* @param data Information about the changed data.
|
||||||
@@ -858,7 +871,6 @@ public:
|
|||||||
|
|
||||||
_fios_path_changed = true;
|
_fios_path_changed = true;
|
||||||
this->fios_items.BuildFileList(this->abstract_filetype, this->fop);
|
this->fios_items.BuildFileList(this->abstract_filetype, this->fop);
|
||||||
this->vscroll->SetCount(this->fios_items.size());
|
|
||||||
this->selected = nullptr;
|
this->selected = nullptr;
|
||||||
_load_check_data.Clear();
|
_load_check_data.Clear();
|
||||||
|
|
||||||
@@ -897,30 +909,7 @@ public:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SLIWD_FILTER_CHANGES:
|
case SLIWD_FILTER_CHANGES:
|
||||||
/* Filter changes */
|
this->BuildDisplayList();
|
||||||
this->fios_items_shown.resize(this->fios_items.size());
|
|
||||||
uint items_shown_count = 0; ///< The number of items shown in the list
|
|
||||||
/* We pass through every fios item */
|
|
||||||
for (uint i = 0; i < this->fios_items.size(); i++) {
|
|
||||||
if (this->string_filter.IsEmpty()) {
|
|
||||||
/* We don't filter anything out if the filter editbox is empty */
|
|
||||||
this->fios_items_shown[i] = true;
|
|
||||||
items_shown_count++;
|
|
||||||
} else {
|
|
||||||
this->string_filter.ResetState();
|
|
||||||
this->string_filter.AddLine(this->fios_items[i].title.c_str());
|
|
||||||
/* We set the vector to show this fios element as filtered depending on the result of the filter */
|
|
||||||
this->fios_items_shown[i] = this->string_filter.GetState();
|
|
||||||
if (this->fios_items_shown[i]) items_shown_count++;
|
|
||||||
|
|
||||||
if (&(this->fios_items[i]) == this->selected && !this->fios_items_shown[i]) {
|
|
||||||
/* The selected element has been filtered out */
|
|
||||||
this->selected = nullptr;
|
|
||||||
this->OnInvalidateData(SLIWD_SELECTION_CHANGES);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this->vscroll->SetCount(items_shown_count);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,8 +10,6 @@
|
|||||||
#ifndef GAME_TEXT_HPP
|
#ifndef GAME_TEXT_HPP
|
||||||
#define GAME_TEXT_HPP
|
#define GAME_TEXT_HPP
|
||||||
|
|
||||||
#include "../core/smallvec_type.hpp"
|
|
||||||
|
|
||||||
struct StringParam {
|
struct StringParam {
|
||||||
enum ParamType {
|
enum ParamType {
|
||||||
RAW_STRING,
|
RAW_STRING,
|
||||||
|
@@ -109,12 +109,12 @@ void GamelogReset()
|
|||||||
* @param gc GrfConfig, if known
|
* @param gc GrfConfig, if known
|
||||||
* @return The buffer location.
|
* @return The buffer location.
|
||||||
*/
|
*/
|
||||||
static char *PrintGrfInfo(char *buf, const char *last, uint grfid, const uint8 *md5sum, const GRFConfig *gc)
|
static char *PrintGrfInfo(char *buf, const char *last, uint grfid, const MD5Hash *md5sum, const GRFConfig *gc)
|
||||||
{
|
{
|
||||||
char txt[40];
|
char txt[40];
|
||||||
|
|
||||||
if (md5sum != nullptr) {
|
if (md5sum != nullptr) {
|
||||||
md5sumToString(txt, lastof(txt), md5sum);
|
md5sumToString(txt, lastof(txt), *md5sum);
|
||||||
buf += seprintf(buf, last, "GRF ID %08X, checksum %s", BSWAP32(grfid), txt);
|
buf += seprintf(buf, last, "GRF ID %08X, checksum %s", BSWAP32(grfid), txt);
|
||||||
} else {
|
} else {
|
||||||
buf += seprintf(buf, last, "GRF ID %08X", BSWAP32(grfid));
|
buf += seprintf(buf, last, "GRF ID %08X", BSWAP32(grfid));
|
||||||
@@ -247,9 +247,9 @@ void GamelogPrint(GamelogPrintProc *proc)
|
|||||||
|
|
||||||
case GLCT_GRFADD: {
|
case GLCT_GRFADD: {
|
||||||
/* A NewGRF got added to the game, either at the start of the game (never an issue), or later on when it could be an issue. */
|
/* A NewGRF got added to the game, either at the start of the game (never an issue), or later on when it could be an issue. */
|
||||||
const GRFConfig *gc = FindGRFConfig(lc->grfadd.grfid, FGCM_EXACT, lc->grfadd.md5sum);
|
const GRFConfig *gc = FindGRFConfig(lc->grfadd.grfid, FGCM_EXACT, &lc->grfadd.md5sum);
|
||||||
buf += seprintf(buf, lastof(buffer), "Added NewGRF: ");
|
buf += seprintf(buf, lastof(buffer), "Added NewGRF: ");
|
||||||
buf = PrintGrfInfo(buf, lastof(buffer), lc->grfadd.grfid, lc->grfadd.md5sum, gc);
|
buf = PrintGrfInfo(buf, lastof(buffer), lc->grfadd.grfid, &lc->grfadd.md5sum, gc);
|
||||||
auto gm = grf_names.find(lc->grfrem.grfid);
|
auto gm = grf_names.find(lc->grfrem.grfid);
|
||||||
if (gm != grf_names.end() && !gm->second.was_missing) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was already added!");
|
if (gm != grf_names.end() && !gm->second.was_missing) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was already added!");
|
||||||
grf_names[lc->grfadd.grfid] = gc;
|
grf_names[lc->grfadd.grfid] = gc;
|
||||||
@@ -276,9 +276,9 @@ void GamelogPrint(GamelogPrintProc *proc)
|
|||||||
|
|
||||||
case GLCT_GRFCOMPAT: {
|
case GLCT_GRFCOMPAT: {
|
||||||
/* Another version of the same NewGRF got loaded. */
|
/* Another version of the same NewGRF got loaded. */
|
||||||
const GRFConfig *gc = FindGRFConfig(lc->grfadd.grfid, FGCM_EXACT, lc->grfadd.md5sum);
|
const GRFConfig *gc = FindGRFConfig(lc->grfadd.grfid, FGCM_EXACT, &lc->grfadd.md5sum);
|
||||||
buf += seprintf(buf, lastof(buffer), "Compatible NewGRF loaded: ");
|
buf += seprintf(buf, lastof(buffer), "Compatible NewGRF loaded: ");
|
||||||
buf = PrintGrfInfo(buf, lastof(buffer), lc->grfcompat.grfid, lc->grfcompat.md5sum, gc);
|
buf = PrintGrfInfo(buf, lastof(buffer), lc->grfcompat.grfid, &lc->grfcompat.md5sum, gc);
|
||||||
if (grf_names.find(lc->grfcompat.grfid) == grf_names.end()) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!");
|
if (grf_names.find(lc->grfcompat.grfid) == grf_names.end()) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!");
|
||||||
grf_names[lc->grfcompat.grfid] = gc;
|
grf_names[lc->grfcompat.grfid] = gc;
|
||||||
break;
|
break;
|
||||||
@@ -760,12 +760,12 @@ void GamelogGRFUpdate(const GRFConfig *oldc, const GRFConfig *newc)
|
|||||||
GamelogGRFMove(nl->grf[n++]->ident.grfid, -(int)oi);
|
GamelogGRFMove(nl->grf[n++]->ident.grfid, -(int)oi);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (memcmp(og->ident.md5sum, ng->ident.md5sum, sizeof(og->ident.md5sum)) != 0) {
|
if (og->ident.md5sum != ng->ident.md5sum) {
|
||||||
/* md5sum changed, probably loading 'compatible' GRF */
|
/* md5sum changed, probably loading 'compatible' GRF */
|
||||||
GamelogGRFCompatible(&nl->grf[n]->ident);
|
GamelogGRFCompatible(&nl->grf[n]->ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (og->num_params != ng->num_params || memcmp(og->param, ng->param, og->num_params * sizeof(og->param[0])) != 0) {
|
if (og->num_params != ng->num_params || og->param == ng->param) {
|
||||||
GamelogGRFParameters(ol->grf[o]->ident.grfid);
|
GamelogGRFParameters(ol->grf[o]->ident.grfid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#include "framerate_type.h"
|
#include "framerate_type.h"
|
||||||
#include "transparency.h"
|
#include "transparency.h"
|
||||||
#include "core/backup_type.hpp"
|
#include "core/backup_type.hpp"
|
||||||
|
#include "core/container_func.hpp"
|
||||||
#include "viewport_func.h"
|
#include "viewport_func.h"
|
||||||
|
|
||||||
#include "table/palettes.h"
|
#include "table/palettes.h"
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
/** @file gfx_layout.cpp Handling of laying out text. */
|
/** @file gfx_layout.cpp Handling of laying out text. */
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "core/math_func.hpp"
|
||||||
#include "gfx_layout.h"
|
#include "gfx_layout.h"
|
||||||
#include "string_func.h"
|
#include "string_func.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
@@ -602,7 +602,7 @@ MD5File::ChecksumResult MD5File::CheckMD5(Subdirectory subdir, size_t max_size)
|
|||||||
|
|
||||||
Md5 checksum;
|
Md5 checksum;
|
||||||
uint8 buffer[1024];
|
uint8 buffer[1024];
|
||||||
uint8 digest[16];
|
MD5Hash digest;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
while ((len = fread(buffer, 1, (size > sizeof(buffer)) ? sizeof(buffer) : size, f)) != 0 && size != 0) {
|
while ((len = fread(buffer, 1, (size > sizeof(buffer)) ? sizeof(buffer) : size, f)) != 0 && size != 0) {
|
||||||
@@ -613,7 +613,7 @@ MD5File::ChecksumResult MD5File::CheckMD5(Subdirectory subdir, size_t max_size)
|
|||||||
FioFCloseFile(f);
|
FioFCloseFile(f);
|
||||||
|
|
||||||
checksum.Finish(digest);
|
checksum.Finish(digest);
|
||||||
return memcmp(this->hash, digest, sizeof(this->hash)) == 0 ? CR_MATCH : CR_MISMATCH;
|
return this->hash == digest ? CR_MATCH : CR_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Names corresponding to the GraphicsFileType */
|
/** Names corresponding to the GraphicsFileType */
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
#include "tilehighlight_func.h"
|
#include "tilehighlight_func.h"
|
||||||
#include "vehicle_gui_base.h"
|
#include "vehicle_gui_base.h"
|
||||||
#include "core/geometry_func.hpp"
|
#include "core/geometry_func.hpp"
|
||||||
|
#include "core/container_func.hpp"
|
||||||
#include "company_base.h"
|
#include "company_base.h"
|
||||||
#include "company_gui.h"
|
#include "company_gui.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
@@ -30,7 +31,6 @@
|
|||||||
#include "newgrf_debug.h"
|
#include "newgrf_debug.h"
|
||||||
|
|
||||||
#include "widgets/group_widget.h"
|
#include "widgets/group_widget.h"
|
||||||
#include "core/smallvec_type.hpp"
|
|
||||||
|
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
|
|
||||||
|
@@ -216,9 +216,9 @@ static std::string KeycodeToString(uint16 keycode)
|
|||||||
std::string SaveKeycodes(const Hotkey *hotkey)
|
std::string SaveKeycodes(const Hotkey *hotkey)
|
||||||
{
|
{
|
||||||
std::string str;
|
std::string str;
|
||||||
for (uint i = 0; i < hotkey->keycodes.size(); i++) {
|
for (auto keycode : hotkey->keycodes) {
|
||||||
if (i > 0) str += ",";
|
if (!str.empty()) str += ",";
|
||||||
str += KeycodeToString(hotkey->keycodes[i]);
|
str += KeycodeToString(keycode);
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
@@ -260,7 +260,7 @@ Hotkey::Hotkey(const uint16 *default_keycodes, const char *name, int num) :
|
|||||||
*/
|
*/
|
||||||
void Hotkey::AddKeycode(uint16 keycode)
|
void Hotkey::AddKeycode(uint16 keycode)
|
||||||
{
|
{
|
||||||
include(this->keycodes, keycode);
|
this->keycodes.insert(keycode);
|
||||||
}
|
}
|
||||||
|
|
||||||
HotkeyList::HotkeyList(const char *ini_group, Hotkey *items, GlobalHotkeyHandlerFunc global_hotkey_handler) :
|
HotkeyList::HotkeyList(const char *ini_group, Hotkey *items, GlobalHotkeyHandlerFunc global_hotkey_handler) :
|
||||||
|
@@ -10,10 +10,10 @@
|
|||||||
#ifndef HOTKEYS_H
|
#ifndef HOTKEYS_H
|
||||||
#define HOTKEYS_H
|
#define HOTKEYS_H
|
||||||
|
|
||||||
#include "core/smallvec_type.hpp"
|
|
||||||
#include "gfx_type.h"
|
#include "gfx_type.h"
|
||||||
#include "window_type.h"
|
#include "window_type.h"
|
||||||
#include "string_type.h"
|
#include "string_type.h"
|
||||||
|
#include "3rdparty/cpp-btree/btree_set.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All data for a single hotkey. The name (for saving/loading a configfile),
|
* All data for a single hotkey. The name (for saving/loading a configfile),
|
||||||
@@ -27,7 +27,7 @@ struct Hotkey {
|
|||||||
|
|
||||||
const char *name;
|
const char *name;
|
||||||
int num;
|
int num;
|
||||||
std::vector<uint16> keycodes;
|
btree::btree_set<uint16> keycodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define HOTKEY_LIST_END Hotkey((uint16)0, nullptr, -1)
|
#define HOTKEY_LIST_END Hotkey((uint16)0, nullptr, -1)
|
||||||
|
@@ -130,6 +130,28 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> {
|
|||||||
return pos - this->accepts_cargo;
|
return pos - this->accepts_cargo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Test if this industry accepts any cargo.
|
||||||
|
* @return true iff the industry accepts any cargo.
|
||||||
|
*/
|
||||||
|
bool IsCargoAccepted() const { return std::any_of(std::begin(this->accepts_cargo), std::end(this->accepts_cargo), [](const auto &cargo) { return IsValidCargoID(cargo); }); }
|
||||||
|
|
||||||
|
/** Test if this industry produces any cargo.
|
||||||
|
* @return true iff the industry produces any cargo.
|
||||||
|
*/
|
||||||
|
bool IsCargoProduced() const { return std::any_of(std::begin(this->produced_cargo), std::end(this->produced_cargo), [](const auto &cargo) { return IsValidCargoID(cargo); }); }
|
||||||
|
|
||||||
|
/** Test if this industry accepts a specific cargo.
|
||||||
|
* @param cargo Cargo type to test.
|
||||||
|
* @return true iff the industry accepts the given cargo type.
|
||||||
|
*/
|
||||||
|
bool IsCargoAccepted(CargoID cargo) const { return std::any_of(std::begin(this->accepts_cargo), std::end(this->accepts_cargo), [&cargo](const auto &cid) { return cid == cargo; }); }
|
||||||
|
|
||||||
|
/** Test if this industry produces a specific cargo.
|
||||||
|
* @param cargo Cargo type to test.
|
||||||
|
* @return true iff the industry produces the given cargo types.
|
||||||
|
*/
|
||||||
|
bool IsCargoProduced(CargoID cargo) const { return std::any_of(std::begin(this->produced_cargo), std::end(this->produced_cargo), [&cargo](const auto &cid) { return cid == cargo; }); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the industry of the given tile
|
* Get the industry of the given tile
|
||||||
* @param tile the tile to get the industry from
|
* @param tile the tile to get the industry from
|
||||||
|
@@ -460,16 +460,8 @@ static void AddAcceptedCargo_Industry(TileIndex tile, CargoArray &acceptance, Ca
|
|||||||
/* Maybe set 'always accepted' bit (if it's not set already) */
|
/* Maybe set 'always accepted' bit (if it's not set already) */
|
||||||
if (HasBit(*always_accepted, a)) continue;
|
if (HasBit(*always_accepted, a)) continue;
|
||||||
|
|
||||||
bool accepts = false;
|
|
||||||
for (uint cargo_index = 0; cargo_index < lengthof(ind->accepts_cargo); cargo_index++) {
|
|
||||||
/* Test whether the industry itself accepts the cargo type */
|
/* Test whether the industry itself accepts the cargo type */
|
||||||
if (ind->accepts_cargo[cargo_index] == a) {
|
if (ind->IsCargoAccepted(a)) continue;
|
||||||
accepts = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accepts) continue;
|
|
||||||
|
|
||||||
/* If the industry itself doesn't accept this cargo, set 'always accepted' bit */
|
/* If the industry itself doesn't accept this cargo, set 'always accepted' bit */
|
||||||
SetBit(*always_accepted, a);
|
SetBit(*always_accepted, a);
|
||||||
@@ -2706,20 +2698,10 @@ static void CanCargoServiceIndustry(CargoID cargo, Industry *ind, bool *c_accept
|
|||||||
if (cargo == CT_INVALID) return;
|
if (cargo == CT_INVALID) return;
|
||||||
|
|
||||||
/* Check for acceptance of cargo */
|
/* Check for acceptance of cargo */
|
||||||
for (byte j = 0; j < lengthof(ind->accepts_cargo); j++) {
|
if (ind->IsCargoAccepted(cargo) && !IndustryTemporarilyRefusesCargo(ind, cargo)) *c_accepts = true;
|
||||||
if (cargo == ind->accepts_cargo[j] && !IndustryTemporarilyRefusesCargo(ind, cargo)) {
|
|
||||||
*c_accepts = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for produced cargo */
|
/* Check for produced cargo */
|
||||||
for (byte j = 0; j < lengthof(ind->produced_cargo); j++) {
|
if (ind->IsCargoProduced(cargo)) *c_produces = true;
|
||||||
if (cargo == ind->produced_cargo[j]) {
|
|
||||||
*c_produces = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1277,14 +1277,11 @@ static bool CargoFilter(const Industry * const *industry, const std::pair<CargoI
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CF_NONE:
|
case CF_NONE:
|
||||||
accepted_cargo_matches = std::all_of(std::begin((*industry)->accepts_cargo), std::end((*industry)->accepts_cargo), [](CargoID cargo) {
|
accepted_cargo_matches = !(*industry)->IsCargoAccepted();
|
||||||
return cargo == CT_INVALID;
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
const auto &ac = (*industry)->accepts_cargo;
|
accepted_cargo_matches = (*industry)->IsCargoAccepted(accepted_cargo);
|
||||||
accepted_cargo_matches = std::find(std::begin(ac), std::end(ac), accepted_cargo) != std::end(ac);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1296,14 +1293,11 @@ static bool CargoFilter(const Industry * const *industry, const std::pair<CargoI
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CF_NONE:
|
case CF_NONE:
|
||||||
produced_cargo_matches = std::all_of(std::begin((*industry)->produced_cargo), std::end((*industry)->produced_cargo), [](CargoID cargo) {
|
produced_cargo_matches = !(*industry)->IsCargoProduced();
|
||||||
return cargo == CT_INVALID;
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
const auto &pc = (*industry)->produced_cargo;
|
produced_cargo_matches = (*industry)->IsCargoProduced(produced_cargo);
|
||||||
produced_cargo_matches = std::find(std::begin(pc), std::end(pc), produced_cargo) != std::end(pc);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2566,8 +2560,8 @@ struct IndustryCargoesWindow : public Window {
|
|||||||
const IndustrySpec *indsp = GetIndustrySpec(it);
|
const IndustrySpec *indsp = GetIndustrySpec(it);
|
||||||
if (!indsp->enabled) continue;
|
if (!indsp->enabled) continue;
|
||||||
this->ind_textsize = maxdim(this->ind_textsize, GetStringBoundingBox(indsp->name));
|
this->ind_textsize = maxdim(this->ind_textsize, GetStringBoundingBox(indsp->name));
|
||||||
CargoesField::max_cargoes = std::max<uint>(CargoesField::max_cargoes, std::count_if(indsp->accepts_cargo, endof(indsp->accepts_cargo), IsCargoIDValid));
|
CargoesField::max_cargoes = std::max<uint>(CargoesField::max_cargoes, std::count_if(indsp->accepts_cargo, endof(indsp->accepts_cargo), IsValidCargoID));
|
||||||
CargoesField::max_cargoes = std::max<uint>(CargoesField::max_cargoes, std::count_if(indsp->produced_cargo, endof(indsp->produced_cargo), IsCargoIDValid));
|
CargoesField::max_cargoes = std::max<uint>(CargoesField::max_cargoes, std::count_if(indsp->produced_cargo, endof(indsp->produced_cargo), IsValidCargoID));
|
||||||
}
|
}
|
||||||
d.width = std::max(d.width, this->ind_textsize.width);
|
d.width = std::max(d.width, this->ind_textsize.width);
|
||||||
d.height = this->ind_textsize.height;
|
d.height = this->ind_textsize.height;
|
||||||
|
@@ -10,7 +10,6 @@
|
|||||||
#ifndef LANGUAGE_H
|
#ifndef LANGUAGE_H
|
||||||
#define LANGUAGE_H
|
#define LANGUAGE_H
|
||||||
|
|
||||||
#include "core/smallvec_type.hpp"
|
|
||||||
#ifdef WITH_ICU_I18N
|
#ifdef WITH_ICU_I18N
|
||||||
#include <unicode/coll.h>
|
#include <unicode/coll.h>
|
||||||
#endif /* WITH_ICU_I18N */
|
#endif /* WITH_ICU_I18N */
|
||||||
|
@@ -187,7 +187,7 @@ public:
|
|||||||
|
|
||||||
td.grf = nullptr;
|
td.grf = nullptr;
|
||||||
|
|
||||||
CargoArray acceptance;
|
CargoArray acceptance{};
|
||||||
AddAcceptedCargo(tile, acceptance, nullptr);
|
AddAcceptedCargo(tile, acceptance, nullptr);
|
||||||
GetTileDesc(tile, &td);
|
GetTileDesc(tile, &td);
|
||||||
|
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
#include "../fileio_type.h"
|
#include "../fileio_type.h"
|
||||||
#include "../string_func.h"
|
#include "../string_func.h"
|
||||||
#include "../core/endian_func.hpp"
|
#include "../core/endian_func.hpp"
|
||||||
|
#include "../core/mem_func.hpp"
|
||||||
#include "../base_media_base.h"
|
#include "../base_media_base.h"
|
||||||
#include "midi.h"
|
#include "midi.h"
|
||||||
|
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
#define MUSIC_MIDIFILE_HPP
|
#define MUSIC_MIDIFILE_HPP
|
||||||
|
|
||||||
#include "../stdafx.h"
|
#include "../stdafx.h"
|
||||||
#include "../core/smallvec_type.hpp"
|
|
||||||
#include "midi.h"
|
#include "midi.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include "midifile.hpp"
|
#include "midifile.hpp"
|
||||||
#include "midi.h"
|
#include "midi.h"
|
||||||
#include "../base_media_base.h"
|
#include "../base_media_base.h"
|
||||||
|
#include "../core/mem_func.hpp"
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#if defined(__MINGW32__)
|
#if defined(__MINGW32__)
|
||||||
#include "../3rdparty/mingw-std-threads/mingw.mutex.h"
|
#include "../3rdparty/mingw-std-threads/mingw.mutex.h"
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include "gfx_func.h"
|
#include "gfx_func.h"
|
||||||
#include "zoom_func.h"
|
#include "zoom_func.h"
|
||||||
#include "core/random_func.hpp"
|
#include "core/random_func.hpp"
|
||||||
|
#include "core/mem_func.hpp"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "core/geometry_func.hpp"
|
#include "core/geometry_func.hpp"
|
||||||
#include "string_func.h"
|
#include "string_func.h"
|
||||||
|
@@ -172,7 +172,7 @@ const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo()
|
|||||||
static void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config, std::string name)
|
static void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config, std::string name)
|
||||||
{
|
{
|
||||||
/* Find the matching GRF file */
|
/* Find the matching GRF file */
|
||||||
const GRFConfig *f = FindGRFConfig(config->ident.grfid, FGCM_EXACT, config->ident.md5sum);
|
const GRFConfig *f = FindGRFConfig(config->ident.grfid, FGCM_EXACT, &config->ident.md5sum);
|
||||||
if (f == nullptr) {
|
if (f == nullptr) {
|
||||||
AddGRFTextToList(config->name, name.empty() ? GetString(STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN) : name);
|
AddGRFTextToList(config->name, name.empty() ? GetString(STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN) : name);
|
||||||
config->status = GCS_NOT_FOUND;
|
config->status = GCS_NOT_FOUND;
|
||||||
@@ -528,9 +528,8 @@ void DeserializeNetworkGameInfoExtended(Packet *p, NetworkGameInfo *info)
|
|||||||
*/
|
*/
|
||||||
void SerializeGRFIdentifier(Packet *p, const GRFIdentifier *grf)
|
void SerializeGRFIdentifier(Packet *p, const GRFIdentifier *grf)
|
||||||
{
|
{
|
||||||
uint j;
|
|
||||||
p->Send_uint32(grf->grfid);
|
p->Send_uint32(grf->grfid);
|
||||||
for (j = 0; j < sizeof(grf->md5sum); j++) {
|
for (size_t j = 0; j < grf->md5sum.size(); j++) {
|
||||||
p->Send_uint8(grf->md5sum[j]);
|
p->Send_uint8(grf->md5sum[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -542,9 +541,8 @@ void SerializeGRFIdentifier(Packet *p, const GRFIdentifier *grf)
|
|||||||
*/
|
*/
|
||||||
void DeserializeGRFIdentifier(Packet *p, GRFIdentifier *grf)
|
void DeserializeGRFIdentifier(Packet *p, GRFIdentifier *grf)
|
||||||
{
|
{
|
||||||
uint j;
|
|
||||||
grf->grfid = p->Recv_uint32();
|
grf->grfid = p->Recv_uint32();
|
||||||
for (j = 0; j < sizeof(grf->md5sum); j++) {
|
for (size_t j = 0; j < grf->md5sum.size(); j++) {
|
||||||
grf->md5sum[j] = p->Recv_uint8();
|
grf->md5sum[j] = p->Recv_uint8();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -70,7 +70,7 @@ const char *ContentInfo::GetTextfile(TextfileType type) const
|
|||||||
tmp = Game::GetScannerLibrary()->FindMainScript(this, true);
|
tmp = Game::GetScannerLibrary()->FindMainScript(this, true);
|
||||||
break;
|
break;
|
||||||
case CONTENT_TYPE_NEWGRF: {
|
case CONTENT_TYPE_NEWGRF: {
|
||||||
const GRFConfig *gc = FindGRFConfig(BSWAP32(this->unique_id), FGCM_EXACT, this->md5sum);
|
const GRFConfig *gc = FindGRFConfig(BSWAP32(this->unique_id), FGCM_EXACT, &this->md5sum);
|
||||||
tmp = gc != nullptr ? gc->filename.c_str() : nullptr;
|
tmp = gc != nullptr ? gc->filename.c_str() : nullptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -12,6 +12,8 @@
|
|||||||
#ifndef NETWORK_CORE_TCP_CONTENT_TYPE_H
|
#ifndef NETWORK_CORE_TCP_CONTENT_TYPE_H
|
||||||
#define NETWORK_CORE_TCP_CONTENT_TYPE_H
|
#define NETWORK_CORE_TCP_CONTENT_TYPE_H
|
||||||
|
|
||||||
|
#include "../../3rdparty/md5/md5.h"
|
||||||
|
|
||||||
/** The values in the enum are important; they are used as database 'keys' */
|
/** The values in the enum are important; they are used as database 'keys' */
|
||||||
enum ContentType {
|
enum ContentType {
|
||||||
CONTENT_TYPE_BEGIN = 1, ///< Helper to mark the begin of the types
|
CONTENT_TYPE_BEGIN = 1, ///< Helper to mark the begin of the types
|
||||||
@@ -67,7 +69,7 @@ struct ContentInfo {
|
|||||||
std::string url; ///< URL related to the content
|
std::string url; ///< URL related to the content
|
||||||
std::string description; ///< Description of the content
|
std::string description; ///< Description of the content
|
||||||
uint32 unique_id = 0; ///< Unique ID; either GRF ID or shortname
|
uint32 unique_id = 0; ///< Unique ID; either GRF ID or shortname
|
||||||
byte md5sum[16] = {0}; ///< The MD5 checksum
|
MD5Hash md5sum; ///< The MD5 checksum
|
||||||
std::vector<ContentID> dependencies; ///< The dependencies (unique server side ids)
|
std::vector<ContentID> dependencies; ///< The dependencies (unique server side ids)
|
||||||
StringList tags; ///< Tags associated with the content
|
StringList tags; ///< Tags associated with the content
|
||||||
State state = State::UNSELECTED; ///< Whether the content info is selected (for download)
|
State state = State::UNSELECTED; ///< Whether the content info is selected (for download)
|
||||||
|
@@ -211,18 +211,14 @@ std::string GenerateCompanyPasswordHash(const std::string &password, const std::
|
|||||||
}
|
}
|
||||||
|
|
||||||
Md5 checksum;
|
Md5 checksum;
|
||||||
uint8 digest[16];
|
MD5Hash digest;
|
||||||
|
|
||||||
/* Generate the MD5 hash */
|
/* Generate the MD5 hash */
|
||||||
std::string salted_password_string = salted_password.str();
|
std::string salted_password_string = salted_password.str();
|
||||||
checksum.Append(salted_password_string.data(), salted_password_string.size());
|
checksum.Append(salted_password_string.data(), salted_password_string.size());
|
||||||
checksum.Finish(digest);
|
checksum.Finish(digest);
|
||||||
|
|
||||||
std::ostringstream hashed_password;
|
return BytesToHexString(digest.data(), digest.size());
|
||||||
hashed_password << std::hex << std::setfill('0');
|
|
||||||
for (int di = 0; di < 16; di++) hashed_password << std::setw(2) << (int)digest[di]; // Cast needed, otherwise interpreted as character to add
|
|
||||||
|
|
||||||
return hashed_password.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -408,7 +408,7 @@ std::string _network_server_name;
|
|||||||
NetworkJoinInfo _network_join;
|
NetworkJoinInfo _network_join;
|
||||||
|
|
||||||
/** Make sure the server ID length is the same as a md5 hash. */
|
/** Make sure the server ID length is the same as a md5 hash. */
|
||||||
static_assert(NETWORK_SERVER_ID_LENGTH == 16 * 2 + 1);
|
static_assert(NETWORK_SERVER_ID_LENGTH == MD5_HASH_BYTES * 2 + 1);
|
||||||
|
|
||||||
NetworkRecvStatus ClientNetworkGameSocketHandler::SendKeyPasswordPacket(PacketType packet_type, NetworkSharedSecrets &ss, const std::string &password, const std::string *payload)
|
NetworkRecvStatus ClientNetworkGameSocketHandler::SendKeyPasswordPacket(PacketType packet_type, NetworkSharedSecrets &ss, const std::string &password, const std::string *payload)
|
||||||
{
|
{
|
||||||
@@ -867,7 +867,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHECK_NEWGRFS(P
|
|||||||
DeserializeGRFIdentifier(p, &c);
|
DeserializeGRFIdentifier(p, &c);
|
||||||
|
|
||||||
/* Check whether we know this GRF */
|
/* Check whether we know this GRF */
|
||||||
const GRFConfig *f = FindGRFConfig(c.grfid, FGCM_EXACT, c.md5sum);
|
const GRFConfig *f = FindGRFConfig(c.grfid, FGCM_EXACT, &c.md5sum);
|
||||||
if (f == nullptr) {
|
if (f == nullptr) {
|
||||||
/* We do not know this GRF, bail out of initialization */
|
/* We do not know this GRF, bail out of initialization */
|
||||||
char buf[sizeof(c.md5sum) * 2 + 1];
|
char buf[sizeof(c.md5sum) * 2 + 1];
|
||||||
|
@@ -37,7 +37,7 @@ ClientNetworkContentSocketHandler _network_content_client;
|
|||||||
/** Wrapper function for the HasProc */
|
/** Wrapper function for the HasProc */
|
||||||
static bool HasGRFConfig(const ContentInfo *ci, bool md5sum)
|
static bool HasGRFConfig(const ContentInfo *ci, bool md5sum)
|
||||||
{
|
{
|
||||||
return FindGRFConfig(BSWAP32(ci->unique_id), md5sum ? FGCM_EXACT : FGCM_ANY, md5sum ? ci->md5sum : nullptr) != nullptr;
|
return FindGRFConfig(BSWAP32(ci->unique_id), md5sum ? FGCM_EXACT : FGCM_ANY, md5sum ? &ci->md5sum : nullptr) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,7 +62,7 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_INFO(Packet *p)
|
|||||||
ci->description = p->Recv_string(NETWORK_CONTENT_DESC_LENGTH, SVS_REPLACE_WITH_QUESTION_MARK | SVS_ALLOW_NEWLINE);
|
ci->description = p->Recv_string(NETWORK_CONTENT_DESC_LENGTH, SVS_REPLACE_WITH_QUESTION_MARK | SVS_ALLOW_NEWLINE);
|
||||||
|
|
||||||
ci->unique_id = p->Recv_uint32();
|
ci->unique_id = p->Recv_uint32();
|
||||||
for (uint j = 0; j < sizeof(ci->md5sum); j++) {
|
for (size_t j = 0; j < ci->md5sum.size(); j++) {
|
||||||
ci->md5sum[j] = p->Recv_uint8();
|
ci->md5sum[j] = p->Recv_uint8();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,8 +144,7 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_INFO(Packet *p)
|
|||||||
|
|
||||||
/* Do we already have a stub for this? */
|
/* Do we already have a stub for this? */
|
||||||
for (ContentInfo *ici : this->infos) {
|
for (ContentInfo *ici : this->infos) {
|
||||||
if (ici->type == ci->type && ici->unique_id == ci->unique_id &&
|
if (ici->type == ci->type && ici->unique_id == ci->unique_id && ci->md5sum == ici->md5sum) {
|
||||||
memcmp(ci->md5sum, ici->md5sum, sizeof(ci->md5sum)) == 0) {
|
|
||||||
/* Preserve the name if possible */
|
/* Preserve the name if possible */
|
||||||
if (ci->name.empty()) ci->name = ici->name;
|
if (ci->name.empty()) ci->name = ici->name;
|
||||||
if (ici->IsSelected()) ci->state = ici->state;
|
if (ici->IsSelected()) ci->state = ici->state;
|
||||||
@@ -265,7 +264,7 @@ void ClientNetworkContentSocketHandler::RequestContentList(ContentVector *cv, bo
|
|||||||
this->Connect();
|
this->Connect();
|
||||||
|
|
||||||
const uint max_per_packet = std::min<uint>(255, (TCP_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint8)) /
|
const uint max_per_packet = std::min<uint>(255, (TCP_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint8)) /
|
||||||
(sizeof(uint8) + sizeof(uint32) + (send_md5sum ? /*sizeof(ContentInfo::md5sum)*/16 : 0))) - 1;
|
(sizeof(uint8) + sizeof(uint32) + (send_md5sum ? MD5_HASH_BYTES : 0))) - 1;
|
||||||
|
|
||||||
uint offset = 0;
|
uint offset = 0;
|
||||||
|
|
||||||
@@ -280,7 +279,7 @@ void ClientNetworkContentSocketHandler::RequestContentList(ContentVector *cv, bo
|
|||||||
p->Send_uint32(ci->unique_id);
|
p->Send_uint32(ci->unique_id);
|
||||||
if (!send_md5sum) continue;
|
if (!send_md5sum) continue;
|
||||||
|
|
||||||
for (uint j = 0; j < sizeof(ci->md5sum); j++) {
|
for (uint j = 0; j < ci->md5sum.size(); j++) {
|
||||||
p->Send_uint8(ci->md5sum[j]);
|
p->Send_uint8(ci->md5sum[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,7 +293,7 @@ void ClientNetworkContentSocketHandler::RequestContentList(ContentVector *cv, bo
|
|||||||
bool found = false;
|
bool found = false;
|
||||||
for (ContentInfo *ci2 : this->infos) {
|
for (ContentInfo *ci2 : this->infos) {
|
||||||
if (ci->type == ci2->type && ci->unique_id == ci2->unique_id &&
|
if (ci->type == ci2->type && ci->unique_id == ci2->unique_id &&
|
||||||
(!send_md5sum || memcmp(ci->md5sum, ci2->md5sum, sizeof(ci->md5sum)) == 0)) {
|
(!send_md5sum || ci->md5sum == ci2->md5sum)) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "core/tcp_content.h"
|
#include "core/tcp_content.h"
|
||||||
#include "core/http.h"
|
#include "core/http.h"
|
||||||
|
#include "../core/container_func.hpp"
|
||||||
#include "../3rdparty/cpp-btree/btree_map.h"
|
#include "../3rdparty/cpp-btree/btree_map.h"
|
||||||
|
|
||||||
/** Vector with content info */
|
/** Vector with content info */
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include "../sortlist_type.h"
|
#include "../sortlist_type.h"
|
||||||
#include "../stringfilter_type.h"
|
#include "../stringfilter_type.h"
|
||||||
#include "../querystring_gui.h"
|
#include "../querystring_gui.h"
|
||||||
|
#include "../core/container_func.hpp"
|
||||||
#include "../core/geometry_func.hpp"
|
#include "../core/geometry_func.hpp"
|
||||||
#include "../textfile_gui.h"
|
#include "../textfile_gui.h"
|
||||||
#include "../fios.h"
|
#include "../fios.h"
|
||||||
|
@@ -124,7 +124,7 @@ void NetworkAfterNewGRFScan()
|
|||||||
for (GRFConfig *c = item->info.grfconfig; c != nullptr; c = c->next) {
|
for (GRFConfig *c = item->info.grfconfig; c != nullptr; c = c->next) {
|
||||||
assert(HasBit(c->flags, GCF_COPY));
|
assert(HasBit(c->flags, GCF_COPY));
|
||||||
|
|
||||||
const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, c->ident.md5sum);
|
const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, &c->ident.md5sum);
|
||||||
if (f == nullptr) {
|
if (f == nullptr) {
|
||||||
/* Don't know the GRF (anymore), so mark game incompatible. */
|
/* Don't know the GRF (anymore), so mark game incompatible. */
|
||||||
c->status = GCS_NOT_FOUND;
|
c->status = GCS_NOT_FOUND;
|
||||||
|
@@ -237,7 +237,7 @@ static void SurveyGrfs(nlohmann::json &survey)
|
|||||||
auto grfid = fmt::format("{:08x}", BSWAP32(c->ident.grfid));
|
auto grfid = fmt::format("{:08x}", BSWAP32(c->ident.grfid));
|
||||||
auto &grf = survey[grfid];
|
auto &grf = survey[grfid];
|
||||||
|
|
||||||
grf["md5sum"] = BytesToHexString(c->ident.md5sum, 16);
|
grf["md5sum"] = BytesToHexString(c->ident.md5sum.data(), c->ident.md5sum.size());
|
||||||
grf["status"] = c->status;
|
grf["status"] = c->status;
|
||||||
|
|
||||||
if ((c->palette & GRFP_GRF_MASK) == GRFP_GRF_UNSET) grf["palette"] = "unset";
|
if ((c->palette & GRFP_GRF_MASK) == GRFP_GRF_UNSET) grf["palette"] = "unset";
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "newgrf_internal.h"
|
#include "newgrf_internal.h"
|
||||||
|
#include "core/container_func.hpp"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "fileio_func.h"
|
#include "fileio_func.h"
|
||||||
#include "engine_func.h"
|
#include "engine_func.h"
|
||||||
@@ -8092,7 +8093,7 @@ static void GRFLoadError(ByteReader *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Only two parameter numbers can be used in the string. */
|
/* Only two parameter numbers can be used in the string. */
|
||||||
for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
|
for (uint i = 0; i < error->param_value.size() && buf->HasData(); i++) {
|
||||||
uint param_number = buf->ReadByte();
|
uint param_number = buf->ReadByte();
|
||||||
error->param_value[i] = _cur.grffile->GetParam(param_number);
|
error->param_value[i] = _cur.grffile->GetParam(param_number);
|
||||||
}
|
}
|
||||||
@@ -8992,7 +8993,7 @@ static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
|
|||||||
grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
|
grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
|
||||||
buf->Skip(len);
|
buf->Skip(len);
|
||||||
} else {
|
} else {
|
||||||
_cur.grfconfig->num_valid_params = std::min<byte>(buf->ReadByte(), lengthof(_cur.grfconfig->param));
|
_cur.grfconfig->num_valid_params = std::min(buf->ReadByte(), ClampTo<uint8_t>(_cur.grfconfig->param.size()));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -9141,7 +9142,7 @@ static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
|
|||||||
buf->Skip(len);
|
buf->Skip(len);
|
||||||
} else {
|
} else {
|
||||||
byte param_nr = buf->ReadByte();
|
byte param_nr = buf->ReadByte();
|
||||||
if (param_nr >= lengthof(_cur.grfconfig->param)) {
|
if (param_nr >= _cur.grfconfig->param.size()) {
|
||||||
grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
|
grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
|
||||||
buf->Skip(len - 1);
|
buf->Skip(len - 1);
|
||||||
} else {
|
} else {
|
||||||
@@ -9338,10 +9339,10 @@ static bool HandleParameterInfo(ByteReader *buf)
|
|||||||
if (id >= _cur.grfconfig->param_info.size()) {
|
if (id >= _cur.grfconfig->param_info.size()) {
|
||||||
_cur.grfconfig->param_info.resize(id + 1);
|
_cur.grfconfig->param_info.resize(id + 1);
|
||||||
}
|
}
|
||||||
if (_cur.grfconfig->param_info[id] == nullptr) {
|
if (!_cur.grfconfig->param_info[id].has_value()) {
|
||||||
_cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
|
_cur.grfconfig->param_info[id] = GRFParameterInfo(id);
|
||||||
}
|
}
|
||||||
_cur_parameter = _cur.grfconfig->param_info[id];
|
_cur_parameter = &_cur.grfconfig->param_info[id].value();
|
||||||
/* Read all parameter-data and process each node. */
|
/* Read all parameter-data and process each node. */
|
||||||
if (!HandleNodes(buf, _tags_parameters)) return false;
|
if (!HandleNodes(buf, _tags_parameters)) return false;
|
||||||
type = buf->ReadByte();
|
type = buf->ReadByte();
|
||||||
@@ -10570,13 +10571,8 @@ GRFFile::GRFFile(const GRFConfig *config)
|
|||||||
|
|
||||||
/* Copy the initial parameter list
|
/* Copy the initial parameter list
|
||||||
* 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
|
* 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
|
||||||
static_assert(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
|
this->param = config->param;
|
||||||
|
|
||||||
assert(config->num_params <= lengthof(config->param));
|
|
||||||
this->param_end = config->num_params;
|
this->param_end = config->num_params;
|
||||||
if (this->param_end > 0) {
|
|
||||||
MemCpyT(this->param, config->param, this->param_end);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GRFFile::~GRFFile()
|
GRFFile::~GRFFile()
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "core/bitmath_func.hpp"
|
#include "core/bitmath_func.hpp"
|
||||||
#include "core/alloc_type.hpp"
|
#include "core/alloc_type.hpp"
|
||||||
#include "core/smallvec_type.hpp"
|
#include "core/mem_func.hpp"
|
||||||
#include "3rdparty/cpp-btree/btree_map.h"
|
#include "3rdparty/cpp-btree/btree_map.h"
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
@@ -346,7 +346,7 @@ struct GRFFile : ZeroedMemoryAllocator {
|
|||||||
std::vector<GRFVariableMapEntry> grf_variable_remaps;
|
std::vector<GRFVariableMapEntry> grf_variable_remaps;
|
||||||
std::vector<std::unique_ptr<const char, FreeDeleter>> remap_unknown_property_names;
|
std::vector<std::unique_ptr<const char, FreeDeleter>> remap_unknown_property_names;
|
||||||
|
|
||||||
uint32 param[0x80];
|
std::array<uint32_t, 0x80> param;
|
||||||
uint param_end; ///< one more than the highest set parameter
|
uint param_end; ///< one more than the highest set parameter
|
||||||
|
|
||||||
std::vector<GRFLabel> labels; ///< List of labels
|
std::vector<GRFLabel> labels; ///< List of labels
|
||||||
@@ -398,9 +398,9 @@ struct GRFFile : ZeroedMemoryAllocator {
|
|||||||
/** Get GRF Parameter with range checking */
|
/** Get GRF Parameter with range checking */
|
||||||
uint32 GetParam(uint number) const
|
uint32 GetParam(uint number) const
|
||||||
{
|
{
|
||||||
/* Note: We implicitly test for number < lengthof(this->param) and return 0 for invalid parameters.
|
/* Note: We implicitly test for number < this->param.size() and return 0 for invalid parameters.
|
||||||
* In fact this is the more important test, as param is zeroed anyway. */
|
* In fact this is the more important test, as param is zeroed anyway. */
|
||||||
assert(this->param_end <= lengthof(this->param));
|
assert(this->param_end <= this->param.size());
|
||||||
return (number < this->param_end) ? this->param[number] : 0;
|
return (number < this->param_end) ? this->param[number] : 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "core/alloc_type.hpp"
|
#include "core/alloc_type.hpp"
|
||||||
#include "core/smallvec_type.hpp"
|
|
||||||
#include "command_type.h"
|
#include "command_type.h"
|
||||||
#include "direction_type.h"
|
#include "direction_type.h"
|
||||||
#include "company_type.h"
|
#include "company_type.h"
|
||||||
|
@@ -43,7 +43,7 @@
|
|||||||
* @param filename Set the filename of this GRFConfig to filename.
|
* @param filename Set the filename of this GRFConfig to filename.
|
||||||
*/
|
*/
|
||||||
GRFConfig::GRFConfig(const std::string &filename) :
|
GRFConfig::GRFConfig(const std::string &filename) :
|
||||||
filename(filename), num_valid_params(lengthof(param))
|
filename(filename), num_valid_params(ClampTo<uint8_t>(GRFConfig::param.size()))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +54,7 @@ GRFConfig::GRFConfig(const std::string &filename) :
|
|||||||
GRFConfig::GRFConfig(const GRFConfig &config) :
|
GRFConfig::GRFConfig(const GRFConfig &config) :
|
||||||
ZeroedMemoryAllocator(),
|
ZeroedMemoryAllocator(),
|
||||||
ident(config.ident),
|
ident(config.ident),
|
||||||
|
original_md5sum(config.original_md5sum),
|
||||||
filename(config.filename),
|
filename(config.filename),
|
||||||
name(config.name),
|
name(config.name),
|
||||||
info(config.info),
|
info(config.info),
|
||||||
@@ -63,27 +64,14 @@ GRFConfig::GRFConfig(const GRFConfig &config) :
|
|||||||
flags(config.flags & ~(1 << GCF_COPY)),
|
flags(config.flags & ~(1 << GCF_COPY)),
|
||||||
status(config.status),
|
status(config.status),
|
||||||
grf_bugs(config.grf_bugs),
|
grf_bugs(config.grf_bugs),
|
||||||
|
param(config.param),
|
||||||
num_params(config.num_params),
|
num_params(config.num_params),
|
||||||
num_valid_params(config.num_valid_params),
|
num_valid_params(config.num_valid_params),
|
||||||
palette(config.palette),
|
palette(config.palette),
|
||||||
|
param_info(config.param_info),
|
||||||
has_param_defaults(config.has_param_defaults)
|
has_param_defaults(config.has_param_defaults)
|
||||||
{
|
{
|
||||||
MemCpyT<uint8>(this->original_md5sum, config.original_md5sum, lengthof(this->original_md5sum));
|
|
||||||
MemCpyT<uint32>(this->param, config.param, lengthof(this->param));
|
|
||||||
if (config.error != nullptr) this->error = std::make_unique<GRFError>(*config.error);
|
if (config.error != nullptr) this->error = std::make_unique<GRFError>(*config.error);
|
||||||
for (uint i = 0; i < config.param_info.size(); i++) {
|
|
||||||
if (config.param_info[i] == nullptr) {
|
|
||||||
this->param_info.push_back(nullptr);
|
|
||||||
} else {
|
|
||||||
this->param_info.push_back(new GRFParameterInfo(*config.param_info[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Cleanup a GRFConfig object. */
|
|
||||||
GRFConfig::~GRFConfig()
|
|
||||||
{
|
|
||||||
for (uint i = 0; i < this->param_info.size(); i++) delete this->param_info[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -94,7 +82,7 @@ void GRFConfig::CopyParams(const GRFConfig &src)
|
|||||||
{
|
{
|
||||||
this->num_params = src.num_params;
|
this->num_params = src.num_params;
|
||||||
this->num_valid_params = src.num_valid_params;
|
this->num_valid_params = src.num_valid_params;
|
||||||
MemCpyT<uint32>(this->param, src.param, lengthof(this->param));
|
this->param = src.param;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -130,12 +118,12 @@ const char *GRFConfig::GetURL() const
|
|||||||
void GRFConfig::SetParameterDefaults()
|
void GRFConfig::SetParameterDefaults()
|
||||||
{
|
{
|
||||||
this->num_params = 0;
|
this->num_params = 0;
|
||||||
MemSetT<uint32>(this->param, 0, lengthof(this->param));
|
this->param = {};
|
||||||
|
|
||||||
if (!this->has_param_defaults) return;
|
if (!this->has_param_defaults) return;
|
||||||
|
|
||||||
for (uint i = 0; i < this->param_info.size(); i++) {
|
for (uint i = 0; i < this->param_info.size(); i++) {
|
||||||
if (this->param_info[i] == nullptr) continue;
|
if (!this->param_info[i]) continue;
|
||||||
this->param_info[i]->SetValue(this, this->param_info[i]->def_value);
|
this->param_info[i]->SetValue(this, this->param_info[i]->def_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,8 +149,8 @@ void GRFConfig::SetSuitablePalette()
|
|||||||
*/
|
*/
|
||||||
void GRFConfig::FinalizeParameterInfo()
|
void GRFConfig::FinalizeParameterInfo()
|
||||||
{
|
{
|
||||||
for (GRFParameterInfo *info : this->param_info) {
|
for (auto &info : this->param_info) {
|
||||||
if (info == nullptr) continue;
|
if (!info.has_value()) continue;
|
||||||
info->Finalize();
|
info->Finalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,26 +168,10 @@ bool _grf_bug_too_many_strings = false;
|
|||||||
* @param severity The severity of this error.
|
* @param severity The severity of this error.
|
||||||
* @param message The actual error-string.
|
* @param message The actual error-string.
|
||||||
*/
|
*/
|
||||||
GRFError::GRFError(StringID severity, StringID message) :
|
GRFError::GRFError(StringID severity, StringID message) : message(message), severity(severity)
|
||||||
message(message),
|
|
||||||
severity(severity),
|
|
||||||
param_value()
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new GRFError that is a deep copy of an existing error message.
|
|
||||||
* @param error The GRFError object to make a copy of.
|
|
||||||
*/
|
|
||||||
GRFError::GRFError(const GRFError &error) :
|
|
||||||
custom_message(error.custom_message),
|
|
||||||
data(error.data),
|
|
||||||
message(error.message),
|
|
||||||
severity(error.severity)
|
|
||||||
{
|
|
||||||
memcpy(this->param_value, error.param_value, sizeof(this->param_value));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new empty GRFParameterInfo object.
|
* Create a new empty GRFParameterInfo object.
|
||||||
* @param nr The newgrf parameter that is changed.
|
* @param nr The newgrf parameter that is changed.
|
||||||
@@ -218,26 +190,6 @@ GRFParameterInfo::GRFParameterInfo(uint nr) :
|
|||||||
complete_labels(false)
|
complete_labels(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new GRFParameterInfo object that is a deep copy of an existing
|
|
||||||
* parameter info object.
|
|
||||||
* @param info The GRFParameterInfo object to make a copy of.
|
|
||||||
*/
|
|
||||||
GRFParameterInfo::GRFParameterInfo(GRFParameterInfo &info) :
|
|
||||||
name(info.name),
|
|
||||||
desc(info.desc),
|
|
||||||
type(info.type),
|
|
||||||
min_value(info.min_value),
|
|
||||||
max_value(info.max_value),
|
|
||||||
def_value(info.def_value),
|
|
||||||
param_nr(info.param_nr),
|
|
||||||
first_bit(info.first_bit),
|
|
||||||
num_bit(info.num_bit),
|
|
||||||
value_names(info.value_names),
|
|
||||||
complete_labels(info.complete_labels)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of this user-changeable parameter from the given config.
|
* Get the value of this user-changeable parameter from the given config.
|
||||||
* @param config The GRFConfig to get the value from.
|
* @param config The GRFConfig to get the value from.
|
||||||
@@ -597,7 +549,7 @@ GRFListCompatibility IsGoodGRFConfigList(GRFConfig *grfconfig)
|
|||||||
GRFListCompatibility res = GLC_ALL_GOOD;
|
GRFListCompatibility res = GLC_ALL_GOOD;
|
||||||
|
|
||||||
for (GRFConfig *c = grfconfig; c != nullptr; c = c->next) {
|
for (GRFConfig *c = grfconfig; c != nullptr; c = c->next) {
|
||||||
const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, c->ident.md5sum);
|
const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, &c->ident.md5sum);
|
||||||
if (f == nullptr || HasBit(f->flags, GCF_INVALID)) {
|
if (f == nullptr || HasBit(f->flags, GCF_INVALID)) {
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
|
||||||
@@ -610,7 +562,7 @@ GRFListCompatibility IsGoodGRFConfigList(GRFConfig *grfconfig)
|
|||||||
if (!HasBit(c->flags, GCF_COMPATIBLE)) {
|
if (!HasBit(c->flags, GCF_COMPATIBLE)) {
|
||||||
/* Preserve original_md5sum after it has been assigned */
|
/* Preserve original_md5sum after it has been assigned */
|
||||||
SetBit(c->flags, GCF_COMPATIBLE);
|
SetBit(c->flags, GCF_COMPATIBLE);
|
||||||
memcpy(c->original_md5sum, c->ident.md5sum, sizeof(c->original_md5sum));
|
c->original_md5sum = c->ident.md5sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Non-found has precedence over compatibility load */
|
/* Non-found has precedence over compatibility load */
|
||||||
@@ -634,21 +586,15 @@ compatible_grf:
|
|||||||
* already a local one, so there is no need to replace it. */
|
* already a local one, so there is no need to replace it. */
|
||||||
if (!HasBit(c->flags, GCF_COPY)) {
|
if (!HasBit(c->flags, GCF_COPY)) {
|
||||||
c->filename = f->filename;
|
c->filename = f->filename;
|
||||||
memcpy(c->ident.md5sum, f->ident.md5sum, sizeof(c->ident.md5sum));
|
c->ident.md5sum = f->ident.md5sum;
|
||||||
c->name = f->name;
|
c->name = f->name;
|
||||||
c->info = f->name;
|
c->info = f->name;
|
||||||
c->error = nullptr;
|
c->error = nullptr;
|
||||||
c->version = f->version;
|
c->version = f->version;
|
||||||
c->min_loadable_version = f->min_loadable_version;
|
c->min_loadable_version = f->min_loadable_version;
|
||||||
c->num_valid_params = f->num_valid_params;
|
c->num_valid_params = f->num_valid_params;
|
||||||
|
c->param_info = f->param_info;
|
||||||
c->has_param_defaults = f->has_param_defaults;
|
c->has_param_defaults = f->has_param_defaults;
|
||||||
for (uint i = 0; i < f->param_info.size(); i++) {
|
|
||||||
if (f->param_info[i] == nullptr) {
|
|
||||||
c->param_info.push_back(nullptr);
|
|
||||||
} else {
|
|
||||||
c->param_info.push_back(new GRFParameterInfo(*f->param_info[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -698,7 +644,7 @@ public:
|
|||||||
GRFConfig **pd, *d;
|
GRFConfig **pd, *d;
|
||||||
bool stop = false;
|
bool stop = false;
|
||||||
for (pd = &_all_grfs; (d = *pd) != nullptr; pd = &d->next) {
|
for (pd = &_all_grfs; (d = *pd) != nullptr; pd = &d->next) {
|
||||||
if (c->ident.grfid == d->ident.grfid && memcmp(c->ident.md5sum, d->ident.md5sum, sizeof(c->ident.md5sum)) == 0) added = false;
|
if (c->ident.grfid == d->ident.grfid && c->ident.md5sum == d->ident.md5sum) added = false;
|
||||||
/* Because there can be multiple grfs with the same name, make sure we checked all grfs with the same name,
|
/* Because there can be multiple grfs with the same name, make sure we checked all grfs with the same name,
|
||||||
* before inserting the entry. So insert a new grf at the end of all grfs with the same name, instead of
|
* before inserting the entry. So insert a new grf at the end of all grfs with the same name, instead of
|
||||||
* just after the first with the same name. Avoids doubles in the list. */
|
* just after the first with the same name. Avoids doubles in the list. */
|
||||||
@@ -834,7 +780,7 @@ void ScanNewGRFFiles(NewGRFScanCallback *callback)
|
|||||||
* @param desired_version Requested version
|
* @param desired_version Requested version
|
||||||
* @return The matching grf, if it exists in #_all_grfs, else \c nullptr.
|
* @return The matching grf, if it exists in #_all_grfs, else \c nullptr.
|
||||||
*/
|
*/
|
||||||
const GRFConfig *FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8 *md5sum, uint32 desired_version)
|
const GRFConfig *FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const MD5Hash *md5sum, uint32 desired_version)
|
||||||
{
|
{
|
||||||
assert((mode == FGCM_EXACT) != (md5sum == nullptr));
|
assert((mode == FGCM_EXACT) != (md5sum == nullptr));
|
||||||
const GRFConfig *best = nullptr;
|
const GRFConfig *best = nullptr;
|
||||||
@@ -873,18 +819,14 @@ GRFConfig *GetGRFConfig(uint32 grfid, uint32 mask)
|
|||||||
|
|
||||||
|
|
||||||
/** Build a string containing space separated parameter values, and terminate */
|
/** Build a string containing space separated parameter values, and terminate */
|
||||||
char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last)
|
std::string GRFBuildParamList(const GRFConfig *c)
|
||||||
{
|
{
|
||||||
uint i;
|
std::string result;
|
||||||
|
for (uint i = 0; i < c->num_params; i++) {
|
||||||
/* Return an empty string if there are no parameters */
|
if (!result.empty()) result += ' ';
|
||||||
if (c->num_params == 0) return strecpy(dst, "", last);
|
result += std::to_string(c->param[i]);
|
||||||
|
|
||||||
for (i = 0; i < c->num_params; i++) {
|
|
||||||
if (i > 0) dst = strecpy(dst, " ", last);
|
|
||||||
dst += seprintf(dst, last, "%d", c->param[i]);
|
|
||||||
}
|
}
|
||||||
return dst;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
#include "fileio_type.h"
|
#include "fileio_type.h"
|
||||||
#include "textfile_type.h"
|
#include "textfile_type.h"
|
||||||
#include "newgrf_text.h"
|
#include "newgrf_text.h"
|
||||||
|
#include "3rdparty/md5/md5.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
static const uint MAX_NON_STATIC_GRF_COUNT = 256;
|
static const uint MAX_NON_STATIC_GRF_COUNT = 256;
|
||||||
@@ -84,15 +85,12 @@ enum GRFPalette {
|
|||||||
/** Basic data to distinguish a GRF. Used in the server list window */
|
/** Basic data to distinguish a GRF. Used in the server list window */
|
||||||
struct GRFIdentifier {
|
struct GRFIdentifier {
|
||||||
uint32 grfid; ///< GRF ID (defined by Action 0x08)
|
uint32 grfid; ///< GRF ID (defined by Action 0x08)
|
||||||
uint8 md5sum[16]; ///< MD5 checksum of file to distinguish files with the same GRF ID (eg. newer version of GRF)
|
MD5Hash md5sum; ///< MD5 checksum of file to distinguish files with the same GRF ID (eg. newer version of GRF)
|
||||||
|
|
||||||
GRFIdentifier() = default;
|
GRFIdentifier() = default;
|
||||||
GRFIdentifier(const GRFIdentifier &other) = default;
|
GRFIdentifier(const GRFIdentifier &other) = default;
|
||||||
GRFIdentifier(GRFIdentifier &&other) = default;
|
GRFIdentifier(GRFIdentifier &&other) = default;
|
||||||
GRFIdentifier(uint32 grfid, const uint8 *md5sum) : grfid(grfid)
|
GRFIdentifier(uint32 grfid, const MD5Hash &md5sum) : grfid(grfid), md5sum(md5sum) {}
|
||||||
{
|
|
||||||
MemCpyT(this->md5sum, md5sum, lengthof(this->md5sum));
|
|
||||||
}
|
|
||||||
|
|
||||||
GRFIdentifier& operator =(const GRFIdentifier &other) = default;
|
GRFIdentifier& operator =(const GRFIdentifier &other) = default;
|
||||||
|
|
||||||
@@ -102,27 +100,23 @@ struct GRFIdentifier {
|
|||||||
* @param md5sum Expected md5sum, may be \c nullptr (in which case, do not check it).
|
* @param md5sum Expected md5sum, may be \c nullptr (in which case, do not check it).
|
||||||
* @return the object has the provided grfid and md5sum.
|
* @return the object has the provided grfid and md5sum.
|
||||||
*/
|
*/
|
||||||
inline bool HasGrfIdentifier(uint32 grfid, const uint8 *md5sum) const
|
inline bool HasGrfIdentifier(uint32 grfid, const MD5Hash *md5sum) const
|
||||||
{
|
{
|
||||||
if (this->grfid != grfid) return false;
|
if (this->grfid != grfid) return false;
|
||||||
if (md5sum == nullptr) return true;
|
if (md5sum == nullptr) return true;
|
||||||
return memcmp(md5sum, this->md5sum, sizeof(this->md5sum)) == 0;
|
return *md5sum == this->md5sum;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Information about why GRF had problems during initialisation */
|
/** Information about why GRF had problems during initialisation */
|
||||||
struct GRFError {
|
struct GRFError {
|
||||||
GRFError(StringID severity, StringID message = 0);
|
GRFError(StringID severity, StringID message = 0);
|
||||||
GRFError(const GRFError &error);
|
|
||||||
|
|
||||||
/* Remove the copy assignment, as the default implementation will not do the right thing. */
|
|
||||||
GRFError &operator=(GRFError &rhs) = delete;
|
|
||||||
|
|
||||||
std::string custom_message; ///< Custom message (if present)
|
std::string custom_message; ///< Custom message (if present)
|
||||||
std::string data; ///< Additional data for message and custom_message
|
std::string data; ///< Additional data for message and custom_message
|
||||||
StringID message; ///< Default message
|
StringID message; ///< Default message
|
||||||
StringID severity; ///< Info / Warning / Error / Fatal
|
StringID severity; ///< Info / Warning / Error / Fatal
|
||||||
uint64 param_value[4]; ///< Values of GRF parameters to show for message and custom_message
|
std::array<uint32_t, 4> param_value; ///< Values of GRF parameters to show for message and custom_message
|
||||||
};
|
};
|
||||||
|
|
||||||
/** The possible types of a newgrf parameter. */
|
/** The possible types of a newgrf parameter. */
|
||||||
@@ -135,7 +129,6 @@ enum GRFParameterType {
|
|||||||
/** Information about one grf parameter. */
|
/** Information about one grf parameter. */
|
||||||
struct GRFParameterInfo {
|
struct GRFParameterInfo {
|
||||||
GRFParameterInfo(uint nr);
|
GRFParameterInfo(uint nr);
|
||||||
GRFParameterInfo(GRFParameterInfo &info);
|
|
||||||
GRFTextList name; ///< The name of this parameter
|
GRFTextList name; ///< The name of this parameter
|
||||||
GRFTextList desc; ///< The description of this parameter
|
GRFTextList desc; ///< The description of this parameter
|
||||||
GRFParameterType type; ///< The type of this parameter
|
GRFParameterType type; ///< The type of this parameter
|
||||||
@@ -157,13 +150,12 @@ struct GRFParameterInfo {
|
|||||||
struct GRFConfig : ZeroedMemoryAllocator {
|
struct GRFConfig : ZeroedMemoryAllocator {
|
||||||
GRFConfig(const std::string &filename = std::string{});
|
GRFConfig(const std::string &filename = std::string{});
|
||||||
GRFConfig(const GRFConfig &config);
|
GRFConfig(const GRFConfig &config);
|
||||||
~GRFConfig();
|
|
||||||
|
|
||||||
/* Remove the copy assignment, as the default implementation will not do the right thing. */
|
/* Remove the copy assignment, as the default implementation will not do the right thing. */
|
||||||
GRFConfig &operator=(GRFConfig &rhs) = delete;
|
GRFConfig &operator=(GRFConfig &rhs) = delete;
|
||||||
|
|
||||||
GRFIdentifier ident; ///< grfid and md5sum to uniquely identify newgrfs
|
GRFIdentifier ident; ///< grfid and md5sum to uniquely identify newgrfs
|
||||||
uint8 original_md5sum[16]; ///< MD5 checksum of original file if only a 'compatible' file was loaded
|
MD5Hash original_md5sum; ///< MD5 checksum of original file if only a 'compatible' file was loaded
|
||||||
std::string filename; ///< Filename - either with or without full path
|
std::string filename; ///< Filename - either with or without full path
|
||||||
std::string full_filename; ///< NOSAVE: Full filename
|
std::string full_filename; ///< NOSAVE: Full filename
|
||||||
GRFTextWrapper name; ///< NOSAVE: GRF name (Action 0x08)
|
GRFTextWrapper name; ///< NOSAVE: GRF name (Action 0x08)
|
||||||
@@ -176,11 +168,11 @@ struct GRFConfig : ZeroedMemoryAllocator {
|
|||||||
uint8 flags; ///< NOSAVE: GCF_Flags, bitset
|
uint8 flags; ///< NOSAVE: GCF_Flags, bitset
|
||||||
GRFStatus status; ///< NOSAVE: GRFStatus, enum
|
GRFStatus status; ///< NOSAVE: GRFStatus, enum
|
||||||
uint32 grf_bugs; ///< NOSAVE: bugs in this GRF in this run, @see enum GRFBugs
|
uint32 grf_bugs; ///< NOSAVE: bugs in this GRF in this run, @see enum GRFBugs
|
||||||
uint32 param[0x80]; ///< GRF parameters
|
std::array<uint32_t, 0x80> param; ///< GRF parameters
|
||||||
uint8 num_params; ///< Number of used parameters
|
uint8 num_params; ///< Number of used parameters
|
||||||
uint8 num_valid_params; ///< NOSAVE: Number of valid parameters (action 0x14)
|
uint8 num_valid_params; ///< NOSAVE: Number of valid parameters (action 0x14)
|
||||||
uint8 palette; ///< GRFPalette, bitset
|
uint8 palette; ///< GRFPalette, bitset
|
||||||
std::vector<GRFParameterInfo *> param_info; ///< NOSAVE: extra information about the parameters
|
std::vector<std::optional<GRFParameterInfo>> param_info; ///< NOSAVE: extra information about the parameters
|
||||||
bool has_param_defaults; ///< NOSAVE: did this newgrf specify any defaults for it's parameters
|
bool has_param_defaults; ///< NOSAVE: did this newgrf specify any defaults for it's parameters
|
||||||
|
|
||||||
struct GRFConfig *next; ///< NOSAVE: Next item in the linked list
|
struct GRFConfig *next; ///< NOSAVE: Next item in the linked list
|
||||||
@@ -230,7 +222,7 @@ struct NewGRFScanCallback {
|
|||||||
size_t GRFGetSizeOfDataSection(FILE *f);
|
size_t GRFGetSizeOfDataSection(FILE *f);
|
||||||
|
|
||||||
void ScanNewGRFFiles(NewGRFScanCallback *callback);
|
void ScanNewGRFFiles(NewGRFScanCallback *callback);
|
||||||
const GRFConfig *FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8 *md5sum = nullptr, uint32 desired_version = 0);
|
const GRFConfig *FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const MD5Hash *md5sum = nullptr, uint32 desired_version = 0);
|
||||||
GRFConfig *GetGRFConfig(uint32 grfid, uint32 mask = 0xFFFFFFFF);
|
GRFConfig *GetGRFConfig(uint32 grfid, uint32 mask = 0xFFFFFFFF);
|
||||||
GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src, bool init_only);
|
GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src, bool init_only);
|
||||||
void AppendStaticGRFConfigs(GRFConfig **dst);
|
void AppendStaticGRFConfigs(GRFConfig **dst);
|
||||||
@@ -239,7 +231,7 @@ void ClearGRFConfigList(GRFConfig **config);
|
|||||||
void ResetGRFConfig(bool defaults);
|
void ResetGRFConfig(bool defaults);
|
||||||
GRFListCompatibility IsGoodGRFConfigList(GRFConfig *grfconfig);
|
GRFListCompatibility IsGoodGRFConfigList(GRFConfig *grfconfig);
|
||||||
bool FillGRFDetails(GRFConfig *config, bool is_static, Subdirectory subdir = NEWGRF_DIR);
|
bool FillGRFDetails(GRFConfig *config, bool is_static, Subdirectory subdir = NEWGRF_DIR);
|
||||||
char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last);
|
std::string GRFBuildParamList(const GRFConfig *c);
|
||||||
|
|
||||||
/* In newgrf_gui.cpp */
|
/* In newgrf_gui.cpp */
|
||||||
void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config);
|
void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config);
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
#define NEWGRF_DEBUG_H
|
#define NEWGRF_DEBUG_H
|
||||||
|
|
||||||
#include "newgrf.h"
|
#include "newgrf.h"
|
||||||
#include "core/smallvec_type.hpp"
|
|
||||||
#include "tile_type.h"
|
#include "tile_type.h"
|
||||||
#include "vehicle_type.h"
|
#include "vehicle_type.h"
|
||||||
|
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include "date_func.h"
|
#include "date_func.h"
|
||||||
#include "vehicle_func.h"
|
#include "vehicle_func.h"
|
||||||
#include "core/random_func.hpp"
|
#include "core/random_func.hpp"
|
||||||
|
#include "core/container_func.hpp"
|
||||||
#include "aircraft.h"
|
#include "aircraft.h"
|
||||||
#include "station_base.h"
|
#include "station_base.h"
|
||||||
#include "company_base.h"
|
#include "company_base.h"
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
#include "sortlist_type.h"
|
#include "sortlist_type.h"
|
||||||
#include "stringfilter_type.h"
|
#include "stringfilter_type.h"
|
||||||
#include "querystring_gui.h"
|
#include "querystring_gui.h"
|
||||||
|
#include "core/container_func.hpp"
|
||||||
#include "core/geometry_func.hpp"
|
#include "core/geometry_func.hpp"
|
||||||
#include "newgrf_text.h"
|
#include "newgrf_text.h"
|
||||||
#include "textfile_gui.h"
|
#include "textfile_gui.h"
|
||||||
@@ -55,7 +56,7 @@ void ShowNewGRFError()
|
|||||||
SetDParamStr(2, c->error->custom_message);
|
SetDParamStr(2, c->error->custom_message);
|
||||||
SetDParamStr(3, c->filename);
|
SetDParamStr(3, c->filename);
|
||||||
SetDParamStr(4, c->error->data);
|
SetDParamStr(4, c->error->data);
|
||||||
for (uint i = 0; i < lengthof(c->error->param_value); i++) {
|
for (uint i = 0; i < c->error->param_value.size(); i++) {
|
||||||
SetDParam(5 + i, c->error->param_value[i]);
|
SetDParam(5 + i, c->error->param_value[i]);
|
||||||
}
|
}
|
||||||
if (c->error->severity == STR_NEWGRF_ERROR_MSG_FATAL) {
|
if (c->error->severity == STR_NEWGRF_ERROR_MSG_FATAL) {
|
||||||
@@ -75,7 +76,7 @@ static void ShowNewGRFInfo(const GRFConfig *c, const Rect &r, bool show_params)
|
|||||||
SetDParamStr(0, c->error->custom_message); // is skipped by built-in messages
|
SetDParamStr(0, c->error->custom_message); // is skipped by built-in messages
|
||||||
SetDParamStr(1, c->filename);
|
SetDParamStr(1, c->filename);
|
||||||
SetDParamStr(2, c->error->data);
|
SetDParamStr(2, c->error->data);
|
||||||
for (uint i = 0; i < lengthof(c->error->param_value); i++) {
|
for (uint i = 0; i < c->error->param_value.size(); i++) {
|
||||||
SetDParam(3 + i, c->error->param_value[i]);
|
SetDParam(3 + i, c->error->param_value[i]);
|
||||||
}
|
}
|
||||||
GetString(message, c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING, lastof(message));
|
GetString(message, c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING, lastof(message));
|
||||||
@@ -113,9 +114,9 @@ static void ShowNewGRFInfo(const GRFConfig *c, const Rect &r, bool show_params)
|
|||||||
/* Show GRF parameter list */
|
/* Show GRF parameter list */
|
||||||
if (show_params) {
|
if (show_params) {
|
||||||
if (c->num_params > 0) {
|
if (c->num_params > 0) {
|
||||||
GRFBuildParamList(buff, c, lastof(buff));
|
std::string params = GRFBuildParamList(c);
|
||||||
SetDParam(0, STR_JUST_RAW_STRING);
|
SetDParam(0, STR_JUST_RAW_STRING);
|
||||||
SetDParamStr(1, buff);
|
SetDParamStr(1, params);
|
||||||
} else {
|
} else {
|
||||||
SetDParam(0, STR_NEWGRF_SETTINGS_PARAMETER_NONE);
|
SetDParam(0, STR_NEWGRF_SETTINGS_PARAMETER_NONE);
|
||||||
}
|
}
|
||||||
@@ -170,7 +171,7 @@ struct NewGRFParametersWindow : public Window {
|
|||||||
clicked_row(UINT_MAX),
|
clicked_row(UINT_MAX),
|
||||||
editable(editable)
|
editable(editable)
|
||||||
{
|
{
|
||||||
this->action14present = (c->num_valid_params != lengthof(c->param) || c->param_info.size() != 0);
|
this->action14present = (c->num_valid_params != c->param.size() || c->param_info.size() != 0);
|
||||||
|
|
||||||
this->CreateNestedTree();
|
this->CreateNestedTree();
|
||||||
this->vscroll = this->GetScrollbar(WID_NP_SCROLLBAR);
|
this->vscroll = this->GetScrollbar(WID_NP_SCROLLBAR);
|
||||||
@@ -193,10 +194,31 @@ struct NewGRFParametersWindow : public Window {
|
|||||||
* @param nr The param number that should be changed.
|
* @param nr The param number that should be changed.
|
||||||
* @return GRFParameterInfo with dummy information about the given parameter.
|
* @return GRFParameterInfo with dummy information about the given parameter.
|
||||||
*/
|
*/
|
||||||
static GRFParameterInfo *GetDummyParameterInfo(uint nr)
|
static GRFParameterInfo &GetDummyParameterInfo(uint nr)
|
||||||
{
|
{
|
||||||
dummy_parameter_info.param_nr = nr;
|
dummy_parameter_info.param_nr = nr;
|
||||||
return &dummy_parameter_info;
|
return dummy_parameter_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if GRF Parameter Info exists for a given parameter index.
|
||||||
|
* @param nr The param number that should be tested.
|
||||||
|
* @return True iff the parameter info exists.
|
||||||
|
*/
|
||||||
|
bool HasParameterInfo(uint nr) const
|
||||||
|
{
|
||||||
|
return nr < this->grf_config->param_info.size() && this->grf_config->param_info[nr].has_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get GRF Parameter Info exists for a given parameter index.
|
||||||
|
* If the parameter info does not exist, a dummy parameter-info is returned instead.
|
||||||
|
* @param nr The param number that should be got.
|
||||||
|
* @return Reference to the GRFParameterInfo.
|
||||||
|
*/
|
||||||
|
GRFParameterInfo &GetParameterInfo(uint nr) const
|
||||||
|
{
|
||||||
|
return this->HasParameterInfo(nr) ? this->grf_config->param_info[nr].value() : GetDummyParameterInfo(nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||||
@@ -210,7 +232,7 @@ struct NewGRFParametersWindow : public Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case WID_NP_NUMPAR: {
|
case WID_NP_NUMPAR: {
|
||||||
SetDParamMaxValue(0, lengthof(this->grf_config->param));
|
SetDParamMaxValue(0, this->grf_config->param.size());
|
||||||
Dimension d = GetStringBoundingBox(this->GetWidget<NWidgetCore>(widget)->widget_data);
|
Dimension d = GetStringBoundingBox(this->GetWidget<NWidgetCore>(widget)->widget_data);
|
||||||
d.width += padding.width;
|
d.width += padding.width;
|
||||||
d.height += padding.height;
|
d.height += padding.height;
|
||||||
@@ -229,9 +251,8 @@ struct NewGRFParametersWindow : public Window {
|
|||||||
case WID_NP_DESCRIPTION:
|
case WID_NP_DESCRIPTION:
|
||||||
/* Minimum size of 4 lines. The 500 is the default size of the window. */
|
/* Minimum size of 4 lines. The 500 is the default size of the window. */
|
||||||
Dimension suggestion = {500U - WidgetDimensions::scaled.frametext.Horizontal(), (uint)FONT_HEIGHT_NORMAL * 4 + WidgetDimensions::scaled.frametext.Vertical()};
|
Dimension suggestion = {500U - WidgetDimensions::scaled.frametext.Horizontal(), (uint)FONT_HEIGHT_NORMAL * 4 + WidgetDimensions::scaled.frametext.Vertical()};
|
||||||
for (uint i = 0; i < this->grf_config->param_info.size(); i++) {
|
for (const auto &par_info : this->grf_config->param_info) {
|
||||||
const GRFParameterInfo *par_info = this->grf_config->param_info[i];
|
if (!par_info.has_value()) continue;
|
||||||
if (par_info == nullptr) continue;
|
|
||||||
const char *desc = GetGRFStringFromGRFText(par_info->desc);
|
const char *desc = GetGRFStringFromGRFText(par_info->desc);
|
||||||
if (desc == nullptr) continue;
|
if (desc == nullptr) continue;
|
||||||
Dimension d = GetStringMultiLineBoundingBox(desc, suggestion);
|
Dimension d = GetStringMultiLineBoundingBox(desc, suggestion);
|
||||||
@@ -255,9 +276,9 @@ struct NewGRFParametersWindow : public Window {
|
|||||||
void DrawWidget(const Rect &r, int widget) const override
|
void DrawWidget(const Rect &r, int widget) const override
|
||||||
{
|
{
|
||||||
if (widget == WID_NP_DESCRIPTION) {
|
if (widget == WID_NP_DESCRIPTION) {
|
||||||
const GRFParameterInfo *par_info = (this->clicked_row < this->grf_config->param_info.size()) ? this->grf_config->param_info[this->clicked_row] : nullptr;
|
if (!this->HasParameterInfo(this->clicked_row)) return;
|
||||||
if (par_info == nullptr) return;
|
const GRFParameterInfo &par_info = this->GetParameterInfo(this->clicked_row);
|
||||||
const char *desc = GetGRFStringFromGRFText(par_info->desc);
|
const char *desc = GetGRFStringFromGRFText(par_info.desc);
|
||||||
if (desc == nullptr) return;
|
if (desc == nullptr) return;
|
||||||
DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect), desc, TC_BLACK);
|
DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect), desc, TC_BLACK);
|
||||||
return;
|
return;
|
||||||
@@ -273,24 +294,23 @@ struct NewGRFParametersWindow : public Window {
|
|||||||
int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
|
int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
|
||||||
int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2;
|
int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2;
|
||||||
for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) {
|
for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) {
|
||||||
GRFParameterInfo *par_info = (i < this->grf_config->param_info.size()) ? this->grf_config->param_info[i] : nullptr;
|
GRFParameterInfo &par_info = this->GetParameterInfo(i);
|
||||||
if (par_info == nullptr) par_info = GetDummyParameterInfo(i);
|
uint32 current_value = par_info.GetValue(this->grf_config);
|
||||||
uint32 current_value = par_info->GetValue(this->grf_config);
|
|
||||||
bool selected = (i == this->clicked_row);
|
bool selected = (i == this->clicked_row);
|
||||||
|
|
||||||
if (par_info->type == PTYPE_BOOL) {
|
if (par_info.type == PTYPE_BOOL) {
|
||||||
DrawBoolButton(buttons_left, ir.top + button_y_offset, current_value != 0, this->editable);
|
DrawBoolButton(buttons_left, ir.top + button_y_offset, current_value != 0, this->editable);
|
||||||
SetDParam(2, par_info->GetValue(this->grf_config) == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON);
|
SetDParam(2, par_info.GetValue(this->grf_config) == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON);
|
||||||
} else if (par_info->type == PTYPE_UINT_ENUM) {
|
} else if (par_info.type == PTYPE_UINT_ENUM) {
|
||||||
if (par_info->complete_labels) {
|
if (par_info.complete_labels) {
|
||||||
DrawDropDownButton(buttons_left, ir.top + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && this->clicked_dropdown, this->editable);
|
DrawDropDownButton(buttons_left, ir.top + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && this->clicked_dropdown, this->editable);
|
||||||
} else {
|
} else {
|
||||||
DrawArrowButtons(buttons_left, ir.top + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, this->editable && current_value > par_info->min_value, this->editable && current_value < par_info->max_value);
|
DrawArrowButtons(buttons_left, ir.top + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, this->editable && current_value > par_info.min_value, this->editable && current_value < par_info.max_value);
|
||||||
}
|
}
|
||||||
SetDParam(2, STR_JUST_INT);
|
SetDParam(2, STR_JUST_INT);
|
||||||
SetDParam(3, current_value);
|
SetDParam(3, current_value);
|
||||||
auto it = par_info->value_names.find(current_value);
|
auto it = par_info.value_names.find(current_value);
|
||||||
if (it != par_info->value_names.end()) {
|
if (it != par_info.value_names.end()) {
|
||||||
const char *label = GetGRFStringFromGRFText(it->second);
|
const char *label = GetGRFStringFromGRFText(it->second);
|
||||||
if (label != nullptr) {
|
if (label != nullptr) {
|
||||||
SetDParam(2, STR_JUST_RAW_STRING);
|
SetDParam(2, STR_JUST_RAW_STRING);
|
||||||
@@ -299,7 +319,7 @@ struct NewGRFParametersWindow : public Window {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *name = GetGRFStringFromGRFText(par_info->name);
|
const char *name = GetGRFStringFromGRFText(par_info.name);
|
||||||
if (name != nullptr) {
|
if (name != nullptr) {
|
||||||
SetDParam(0, STR_JUST_RAW_STRING);
|
SetDParam(0, STR_JUST_RAW_STRING);
|
||||||
SetDParamStr(1, name);
|
SetDParamStr(1, name);
|
||||||
@@ -360,12 +380,11 @@ struct NewGRFParametersWindow : public Window {
|
|||||||
int x = pt.x - r.left;
|
int x = pt.x - r.left;
|
||||||
if (_current_text_dir == TD_RTL) x = r.Width() - 1 - x;
|
if (_current_text_dir == TD_RTL) x = r.Width() - 1 - x;
|
||||||
|
|
||||||
GRFParameterInfo *par_info = *it;
|
GRFParameterInfo &par_info = it->has_value() ? it->value() : GetDummyParameterInfo(num);
|
||||||
if (par_info == nullptr) par_info = GetDummyParameterInfo(num);
|
|
||||||
|
|
||||||
/* One of the arrows is clicked */
|
/* One of the arrows is clicked */
|
||||||
uint32 old_val = par_info->GetValue(this->grf_config);
|
uint32 old_val = par_info.GetValue(this->grf_config);
|
||||||
if (par_info->type != PTYPE_BOOL && IsInsideMM(x, 0, SETTING_BUTTON_WIDTH) && par_info->complete_labels) {
|
if (par_info.type != PTYPE_BOOL && IsInsideMM(x, 0, SETTING_BUTTON_WIDTH) && par_info.complete_labels) {
|
||||||
if (this->clicked_dropdown) {
|
if (this->clicked_dropdown) {
|
||||||
/* unclick the dropdown */
|
/* unclick the dropdown */
|
||||||
HideDropDownMenu(this);
|
HideDropDownMenu(this);
|
||||||
@@ -386,8 +405,8 @@ struct NewGRFParametersWindow : public Window {
|
|||||||
this->closing_dropdown = false;
|
this->closing_dropdown = false;
|
||||||
|
|
||||||
DropDownList list;
|
DropDownList list;
|
||||||
for (uint32 i = par_info->min_value; i <= par_info->max_value; i++) {
|
for (uint32 i = par_info.min_value; i <= par_info.max_value; i++) {
|
||||||
list.emplace_back(new DropDownListCharStringItem(GetGRFStringFromGRFText(par_info->value_names.find(i)->second), i, false));
|
list.emplace_back(new DropDownListCharStringItem(GetGRFStringFromGRFText(par_info.value_names.find(i)->second), i, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE);
|
ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE);
|
||||||
@@ -395,26 +414,26 @@ struct NewGRFParametersWindow : public Window {
|
|||||||
}
|
}
|
||||||
} else if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) {
|
} else if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) {
|
||||||
uint32 val = old_val;
|
uint32 val = old_val;
|
||||||
if (par_info->type == PTYPE_BOOL) {
|
if (par_info.type == PTYPE_BOOL) {
|
||||||
val = !val;
|
val = !val;
|
||||||
} else {
|
} else {
|
||||||
if (x >= SETTING_BUTTON_WIDTH / 2) {
|
if (x >= SETTING_BUTTON_WIDTH / 2) {
|
||||||
/* Increase button clicked */
|
/* Increase button clicked */
|
||||||
if (val < par_info->max_value) val++;
|
if (val < par_info.max_value) val++;
|
||||||
this->clicked_increase = true;
|
this->clicked_increase = true;
|
||||||
} else {
|
} else {
|
||||||
/* Decrease button clicked */
|
/* Decrease button clicked */
|
||||||
if (val > par_info->min_value) val--;
|
if (val > par_info.min_value) val--;
|
||||||
this->clicked_increase = false;
|
this->clicked_increase = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (val != old_val) {
|
if (val != old_val) {
|
||||||
par_info->SetValue(this->grf_config, val);
|
par_info.SetValue(this->grf_config, val);
|
||||||
|
|
||||||
this->clicked_button = num;
|
this->clicked_button = num;
|
||||||
this->timeout.SetInterval(150);
|
this->timeout.SetInterval(150);
|
||||||
}
|
}
|
||||||
} else if (par_info->type == PTYPE_UINT_ENUM && !par_info->complete_labels && click_count >= 2) {
|
} else if (par_info.type == PTYPE_UINT_ENUM && !par_info.complete_labels && click_count >= 2) {
|
||||||
/* Display a query box so users can enter a custom value. */
|
/* Display a query box so users can enter a custom value. */
|
||||||
SetDParam(0, old_val);
|
SetDParam(0, old_val);
|
||||||
ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, 10, this, CS_NUMERAL, QSF_NONE);
|
ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, 10, this, CS_NUMERAL, QSF_NONE);
|
||||||
@@ -440,19 +459,17 @@ struct NewGRFParametersWindow : public Window {
|
|||||||
{
|
{
|
||||||
if (StrEmpty(str)) return;
|
if (StrEmpty(str)) return;
|
||||||
int32 value = atoi(str);
|
int32 value = atoi(str);
|
||||||
GRFParameterInfo *par_info = ((uint)this->clicked_row < this->grf_config->param_info.size()) ? this->grf_config->param_info[this->clicked_row] : nullptr;
|
GRFParameterInfo &par_info = this->GetParameterInfo(this->clicked_row);
|
||||||
if (par_info == nullptr) par_info = GetDummyParameterInfo(this->clicked_row);
|
uint32 val = Clamp<uint32>(value, par_info.min_value, par_info.max_value);
|
||||||
uint32 val = Clamp<uint32>(value, par_info->min_value, par_info->max_value);
|
par_info.SetValue(this->grf_config, val);
|
||||||
par_info->SetValue(this->grf_config, val);
|
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnDropdownSelect(int widget, int index) override
|
void OnDropdownSelect(int widget, int index) override
|
||||||
{
|
{
|
||||||
assert(this->clicked_dropdown);
|
assert(this->clicked_dropdown);
|
||||||
GRFParameterInfo *par_info = ((uint)this->clicked_row < this->grf_config->param_info.size()) ? this->grf_config->param_info[this->clicked_row] : nullptr;
|
GRFParameterInfo &par_info = this->GetParameterInfo(this->clicked_row);
|
||||||
if (par_info == nullptr) par_info = GetDummyParameterInfo(this->clicked_row);
|
par_info.SetValue(this->grf_config, index);
|
||||||
par_info->SetValue(this->grf_config, index);
|
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1241,7 +1258,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
|||||||
bool compatible = HasBit(c->flags, GCF_COMPATIBLE);
|
bool compatible = HasBit(c->flags, GCF_COMPATIBLE);
|
||||||
if (c->status != GCS_NOT_FOUND && !compatible) continue;
|
if (c->status != GCS_NOT_FOUND && !compatible) continue;
|
||||||
|
|
||||||
const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, compatible ? c->original_md5sum : c->ident.md5sum);
|
const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, compatible ? &c->original_md5sum : &c->ident.md5sum);
|
||||||
if (f == nullptr || HasBit(f->flags, GCF_INVALID)) continue;
|
if (f == nullptr || HasBit(f->flags, GCF_INVALID)) continue;
|
||||||
|
|
||||||
*l = new GRFConfig(*f);
|
*l = new GRFConfig(*f);
|
||||||
@@ -1448,7 +1465,7 @@ private:
|
|||||||
i = a->version - b->version;
|
i = a->version - b->version;
|
||||||
if (i != 0) return i < 0;
|
if (i != 0) return i < 0;
|
||||||
|
|
||||||
return memcmp(a->ident.md5sum, b->ident.md5sum, lengthof(b->ident.md5sum)) < 0;
|
return a->ident.md5sum < b->ident.md5sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Filter grfs by tags/name */
|
/** Filter grfs by tags/name */
|
||||||
@@ -1469,7 +1486,7 @@ private:
|
|||||||
|
|
||||||
for (const GRFConfig *c = _all_grfs; c != nullptr; c = c->next) {
|
for (const GRFConfig *c = _all_grfs; c != nullptr; c = c->next) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (const GRFConfig *grf = this->actives; grf != nullptr && !found; grf = grf->next) found = grf->ident.HasGrfIdentifier(c->ident.grfid, c->ident.md5sum);
|
for (const GRFConfig *grf = this->actives; grf != nullptr && !found; grf = grf->next) found = grf->ident.HasGrfIdentifier(c->ident.grfid, &c->ident.md5sum);
|
||||||
if (found) continue;
|
if (found) continue;
|
||||||
|
|
||||||
if (_settings_client.gui.newgrf_show_old_versions) {
|
if (_settings_client.gui.newgrf_show_old_versions) {
|
||||||
@@ -1486,7 +1503,7 @@ private:
|
|||||||
* If we are the best version, then we definitely want to
|
* If we are the best version, then we definitely want to
|
||||||
* show that NewGRF!.
|
* show that NewGRF!.
|
||||||
*/
|
*/
|
||||||
if (best->version == 0 || best->ident.HasGrfIdentifier(c->ident.grfid, c->ident.md5sum)) {
|
if (best->version == 0 || best->ident.HasGrfIdentifier(c->ident.grfid, &c->ident.md5sum)) {
|
||||||
this->avails.push_back(c);
|
this->avails.push_back(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1571,7 +1588,7 @@ void ShowMissingContentWindow(const GRFConfig *list)
|
|||||||
ci->state = ContentInfo::DOES_NOT_EXIST;
|
ci->state = ContentInfo::DOES_NOT_EXIST;
|
||||||
ci->name = c->GetName();
|
ci->name = c->GetName();
|
||||||
ci->unique_id = BSWAP32(c->ident.grfid);
|
ci->unique_id = BSWAP32(c->ident.grfid);
|
||||||
memcpy(ci->md5sum, HasBit(c->flags, GCF_COMPATIBLE) ? c->original_md5sum : c->ident.md5sum, sizeof(ci->md5sum));
|
ci->md5sum = HasBit(c->flags, GCF_COMPATIBLE) ? c->original_md5sum : c->ident.md5sum;
|
||||||
cv.push_back(ci);
|
cv.push_back(ci);
|
||||||
}
|
}
|
||||||
ShowNetworkContentListWindow(cv.size() == 0 ? nullptr : &cv, CONTENT_TYPE_NEWGRF);
|
ShowNetworkContentListWindow(cv.size() == 0 ? nullptr : &cv, CONTENT_TYPE_NEWGRF);
|
||||||
|
@@ -709,7 +709,7 @@ void IndustryProductionCallback(Industry *ind, int reason)
|
|||||||
*/
|
*/
|
||||||
bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type)
|
bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type)
|
||||||
{
|
{
|
||||||
assert(std::find(ind->accepts_cargo, endof(ind->accepts_cargo), cargo_type) != endof(ind->accepts_cargo));
|
assert(ind->IsCargoAccepted(cargo_type));
|
||||||
|
|
||||||
const IndustrySpec *indspec = GetIndustrySpec(ind->type);
|
const IndustrySpec *indspec = GetIndustrySpec(ind->type);
|
||||||
if (HasBit(indspec->callback_mask, CBM_IND_REFUSE_CARGO)) {
|
if (HasBit(indspec->callback_mask, CBM_IND_REFUSE_CARGO)) {
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
/** @file newgrf_railtype.cpp NewGRF handling of rail types. */
|
/** @file newgrf_railtype.cpp NewGRF handling of rail types. */
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "core/container_func.hpp"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "newgrf_railtype.h"
|
#include "newgrf_railtype.h"
|
||||||
#include "newgrf_newsignals.h"
|
#include "newgrf_newsignals.h"
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
/** @file newgrf_roadtype.cpp NewGRF handling of road types. */
|
/** @file newgrf_roadtype.cpp NewGRF handling of road types. */
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "core/container_func.hpp"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "newgrf_roadtype.h"
|
#include "newgrf_roadtype.h"
|
||||||
#include "date_func.h"
|
#include "date_func.h"
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#ifndef NEWGRF_STORAGE_H
|
#ifndef NEWGRF_STORAGE_H
|
||||||
#define NEWGRF_STORAGE_H
|
#define NEWGRF_STORAGE_H
|
||||||
|
|
||||||
|
#include "core/alloc_func.hpp"
|
||||||
#include "core/pool_type.hpp"
|
#include "core/pool_type.hpp"
|
||||||
#include "tile_type.h"
|
#include "tile_type.h"
|
||||||
|
|
||||||
|
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#include "string_type.h"
|
#include "string_type.h"
|
||||||
#include "strings_type.h"
|
#include "strings_type.h"
|
||||||
#include "core/smallvec_type.hpp"
|
|
||||||
#include "table/control_codes.h"
|
#include "table/control_codes.h"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@@ -1111,37 +1111,13 @@ void ShowLastNewsMessage()
|
|||||||
*/
|
*/
|
||||||
static void DrawNewsString(uint left, uint right, int y, TextColour colour, const NewsItem *ni)
|
static void DrawNewsString(uint left, uint right, int y, TextColour colour, const NewsItem *ni)
|
||||||
{
|
{
|
||||||
char buffer[512], buffer2[512];
|
|
||||||
StringID str;
|
|
||||||
|
|
||||||
CopyInDParam(0, ni->params, lengthof(ni->params));
|
CopyInDParam(0, ni->params, lengthof(ni->params));
|
||||||
str = ni->string_id;
|
|
||||||
|
|
||||||
GetString(buffer, str, lastof(buffer));
|
/* Get the string, replaces newlines with spaces and remove control codes from the string. */
|
||||||
/* Copy the just gotten string to another buffer to remove any formatting
|
std::string message = StrMakeValid(GetString(ni->string_id), SVS_REPLACE_TAB_CR_NL_WITH_SPACE);
|
||||||
* from it such as big fonts, etc. */
|
|
||||||
const char *ptr = buffer;
|
|
||||||
char *dest = buffer2;
|
|
||||||
WChar c_last = '\0';
|
|
||||||
for (;;) {
|
|
||||||
WChar c = Utf8Consume(&ptr);
|
|
||||||
if (c == 0) break;
|
|
||||||
/* Make a space from a newline, but ignore multiple newlines */
|
|
||||||
if (c == '\n' && c_last != '\n') {
|
|
||||||
dest[0] = ' ';
|
|
||||||
dest++;
|
|
||||||
} else if (c == '\r') {
|
|
||||||
dest[0] = dest[1] = dest[2] = dest[3] = ' ';
|
|
||||||
dest += 4;
|
|
||||||
} else if (IsPrintable(c)) {
|
|
||||||
dest += Utf8Encode(dest, c);
|
|
||||||
}
|
|
||||||
c_last = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
*dest = '\0';
|
|
||||||
/* Truncate and show string; postfixed by '...' if necessary */
|
/* Truncate and show string; postfixed by '...' if necessary */
|
||||||
DrawString(left, right, y, buffer2, colour);
|
DrawString(left, right, y, message, colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MessageHistoryWindow : Window {
|
struct MessageHistoryWindow : Window {
|
||||||
|
@@ -509,7 +509,7 @@ public:
|
|||||||
{
|
{
|
||||||
switch (GB(widget, 0, 16)) {
|
switch (GB(widget, 0, 16)) {
|
||||||
case WID_BO_CLASS_LIST: {
|
case WID_BO_CLASS_LIST: {
|
||||||
auto it = this->vscroll->GetScrolledItemFromWidget(this->object_classes, widget, this, pt.y);
|
auto it = this->vscroll->GetScrolledItemFromWidget(this->object_classes, pt.y, this, widget);
|
||||||
if (it == this->object_classes.end()) break;
|
if (it == this->object_classes.end()) break;
|
||||||
|
|
||||||
this->SelectOtherClass(*it);
|
this->SelectOtherClass(*it);
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
#include "vehicle_func.h"
|
#include "vehicle_func.h"
|
||||||
#include "depot_base.h"
|
#include "depot_base.h"
|
||||||
#include "core/bitmath_func.hpp"
|
#include "core/bitmath_func.hpp"
|
||||||
|
#include "core/container_func.hpp"
|
||||||
#include "core/pool_func.hpp"
|
#include "core/pool_func.hpp"
|
||||||
#include "core/random_func.hpp"
|
#include "core/random_func.hpp"
|
||||||
#include "aircraft.h"
|
#include "aircraft.h"
|
||||||
|
@@ -449,6 +449,8 @@ public:
|
|||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->SendSurvey();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -833,6 +833,7 @@ static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep)
|
|||||||
log->WriteCrashDump(log->crashdump_filename, lastof(log->crashdump_filename));
|
log->WriteCrashDump(log->crashdump_filename, lastof(log->crashdump_filename));
|
||||||
SetScreenshotAuxiliaryText("Crash Log", log->crashlog);
|
SetScreenshotAuxiliaryText("Crash Log", log->crashlog);
|
||||||
log->WriteScreenshot(log->screenshot_filename, lastof(log->screenshot_filename), log->name_buffer);
|
log->WriteScreenshot(log->screenshot_filename, lastof(log->screenshot_filename), log->name_buffer);
|
||||||
|
log->SendSurvey();
|
||||||
|
|
||||||
/* Close any possible log files */
|
/* Close any possible log files */
|
||||||
CloseConsoleLogIfActive();
|
CloseConsoleLogIfActive();
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
#define PLANS_TYPE_H
|
#define PLANS_TYPE_H
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "core/smallvec_type.hpp"
|
|
||||||
#include "tile_type.h"
|
#include "tile_type.h"
|
||||||
|
|
||||||
typedef uint16 PlanID;
|
typedef uint16 PlanID;
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
#define PROGRAMMABLE_SIGNALS_H
|
#define PROGRAMMABLE_SIGNALS_H
|
||||||
#include "rail_map.h"
|
#include "rail_map.h"
|
||||||
#include "tracerestrict.h"
|
#include "tracerestrict.h"
|
||||||
#include "core/smallvec_type.hpp"
|
#include "core/container_func.hpp"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
/** @defgroup progsigs Programmable Pre-Signals */
|
/** @defgroup progsigs Programmable Pre-Signals */
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
#include "company_base.h"
|
#include "company_base.h"
|
||||||
#include "core/backup_type.hpp"
|
#include "core/backup_type.hpp"
|
||||||
#include "date_func.h"
|
#include "date_func.h"
|
||||||
|
#include "core/container_func.hpp"
|
||||||
#include "strings_func.h"
|
#include "strings_func.h"
|
||||||
#include "company_gui.h"
|
#include "company_gui.h"
|
||||||
#include "object_map.h"
|
#include "object_map.h"
|
||||||
|
@@ -2429,9 +2429,9 @@ struct BuildRailWaypointWindow : PickerWindowBase {
|
|||||||
const StationClass *waypoints;
|
const StationClass *waypoints;
|
||||||
WaypointList list;
|
WaypointList list;
|
||||||
StringFilter string_filter; ///< Filter for waypoint name
|
StringFilter string_filter; ///< Filter for waypoint name
|
||||||
QueryString editbox; ///< Filter editbox
|
static QueryString editbox; ///< Filter editbox
|
||||||
|
|
||||||
BuildRailWaypointWindow(WindowDesc *desc, Window *parent) : PickerWindowBase(desc, parent), editbox(FILTER_LENGTH * MAX_CHAR_LENGTH, FILTER_LENGTH)
|
BuildRailWaypointWindow(WindowDesc *desc, Window *parent) : PickerWindowBase(desc, parent)
|
||||||
{
|
{
|
||||||
this->waypoints = StationClass::Get(STAT_CLASS_WAYP);
|
this->waypoints = StationClass::Get(STAT_CLASS_WAYP);
|
||||||
|
|
||||||
@@ -2444,6 +2444,7 @@ struct BuildRailWaypointWindow : PickerWindowBase {
|
|||||||
|
|
||||||
this->querystrings[WID_BRW_FILTER] = &this->editbox;
|
this->querystrings[WID_BRW_FILTER] = &this->editbox;
|
||||||
this->editbox.cancel_button = QueryString::ACTION_CLEAR;
|
this->editbox.cancel_button = QueryString::ACTION_CLEAR;
|
||||||
|
this->string_filter.SetFilterTerm(this->editbox.text.buf);
|
||||||
|
|
||||||
this->list.ForceRebuild();
|
this->list.ForceRebuild();
|
||||||
this->BuildPickerList();
|
this->BuildPickerList();
|
||||||
@@ -2618,6 +2619,8 @@ struct BuildRailWaypointWindow : PickerWindowBase {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* static */ QueryString BuildRailWaypointWindow::editbox(BuildRailWaypointWindow::FILTER_LENGTH * MAX_CHAR_LENGTH, BuildRailWaypointWindow::FILTER_LENGTH);
|
||||||
|
|
||||||
/** Nested widget definition for the build NewGRF rail waypoint window */
|
/** Nested widget definition for the build NewGRF rail waypoint window */
|
||||||
static const NWidgetPart _nested_build_waypoint_widgets[] = {
|
static const NWidgetPart _nested_build_waypoint_widgets[] = {
|
||||||
NWidget(NWID_HORIZONTAL),
|
NWidget(NWID_HORIZONTAL),
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
#include "town.h"
|
#include "town.h"
|
||||||
#include "company_base.h"
|
#include "company_base.h"
|
||||||
#include "core/random_func.hpp"
|
#include "core/random_func.hpp"
|
||||||
|
#include "core/container_func.hpp"
|
||||||
#include "newgrf_debug.h"
|
#include "newgrf_debug.h"
|
||||||
#include "newgrf_railtype.h"
|
#include "newgrf_railtype.h"
|
||||||
#include "newgrf_roadtype.h"
|
#include "newgrf_roadtype.h"
|
||||||
|
@@ -39,9 +39,8 @@ void DrawRoadVehDetails(const Vehicle *v, const Rect &r)
|
|||||||
y += FONT_HEIGHT_NORMAL;
|
y += FONT_HEIGHT_NORMAL;
|
||||||
|
|
||||||
if (v->HasArticulatedPart()) {
|
if (v->HasArticulatedPart()) {
|
||||||
CargoArray max_cargo;
|
CargoArray max_cargo{};
|
||||||
StringID subtype_text[NUM_CARGO];
|
StringID subtype_text[NUM_CARGO];
|
||||||
char capacity[512];
|
|
||||||
|
|
||||||
memset(subtype_text, 0, sizeof(subtype_text));
|
memset(subtype_text, 0, sizeof(subtype_text));
|
||||||
|
|
||||||
@@ -53,23 +52,19 @@ void DrawRoadVehDetails(const Vehicle *v, const Rect &r)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GetString(capacity, STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY, lastof(capacity));
|
std::string capacity = GetString(STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY);
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||||
if (max_cargo[i] > 0) {
|
if (max_cargo[i] > 0) {
|
||||||
char buffer[128];
|
if (!first) capacity += ", ";
|
||||||
|
|
||||||
SetDParam(0, i);
|
SetDParam(0, i);
|
||||||
SetDParam(1, max_cargo[i]);
|
SetDParam(1, max_cargo[i]);
|
||||||
GetString(buffer, STR_JUST_CARGO, lastof(buffer));
|
capacity += GetString(STR_JUST_CARGO);
|
||||||
|
|
||||||
if (!first) strecat(capacity, ", ", lastof(capacity));
|
|
||||||
strecat(capacity, buffer, lastof(capacity));
|
|
||||||
|
|
||||||
if (subtype_text[i] != 0) {
|
if (subtype_text[i] != 0) {
|
||||||
GetString(buffer, subtype_text[i], lastof(buffer));
|
capacity += GetString(subtype_text[i]);
|
||||||
strecat(capacity, buffer, lastof(capacity));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
first = false;
|
first = false;
|
||||||
|
@@ -15,7 +15,6 @@
|
|||||||
#include "../tile_type.h"
|
#include "../tile_type.h"
|
||||||
#include "../animated_tile.h"
|
#include "../animated_tile.h"
|
||||||
#include "../core/alloc_func.hpp"
|
#include "../core/alloc_func.hpp"
|
||||||
#include "../core/smallvec_type.hpp"
|
|
||||||
|
|
||||||
#include "../safeguards.h"
|
#include "../safeguards.h"
|
||||||
|
|
||||||
|
@@ -329,7 +329,7 @@ public:
|
|||||||
la->change = ReallocT(la->change, la->changes + 1);
|
la->change = ReallocT(la->change, la->changes + 1);
|
||||||
|
|
||||||
LoggedChange *lc = &la->change[la->changes++];
|
LoggedChange *lc = &la->change[la->changes++];
|
||||||
memset(lc, 0, sizeof(*lc));
|
*lc = LoggedChange{};
|
||||||
lc->ct = ct;
|
lc->ct = ct;
|
||||||
|
|
||||||
SlObject(lc, this->GetLoadDescription());
|
SlObject(lc, this->GetLoadDescription());
|
||||||
@@ -343,7 +343,7 @@ public:
|
|||||||
|
|
||||||
for (size_t i = 0; i < length; i++) {
|
for (size_t i = 0; i < length; i++) {
|
||||||
LoggedChange *lc = &la->change[i];
|
LoggedChange *lc = &la->change[i];
|
||||||
memset(lc, 0, sizeof(*lc));
|
*lc = LoggedChange{};
|
||||||
|
|
||||||
lc->ct = (GamelogChangeType)SlReadByte();
|
lc->ct = (GamelogChangeType)SlReadByte();
|
||||||
SlObject(lc, this->GetLoadDescription());
|
SlObject(lc, this->GetLoadDescription());
|
||||||
@@ -377,7 +377,7 @@ struct GLOGChunkHandler : ChunkHandler {
|
|||||||
|
|
||||||
gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1);
|
gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1);
|
||||||
LoggedAction *la = &gamelog_action[gamelog_actions++];
|
LoggedAction *la = &gamelog_action[gamelog_actions++];
|
||||||
memset(la, 0, sizeof(*la));
|
*la = LoggedAction{};
|
||||||
|
|
||||||
la->at = (GamelogActionType)type;
|
la->at = (GamelogActionType)type;
|
||||||
SlObject(la, slt);
|
SlObject(la, slt);
|
||||||
@@ -388,7 +388,7 @@ struct GLOGChunkHandler : ChunkHandler {
|
|||||||
while (SlIterateArray() != -1) {
|
while (SlIterateArray() != -1) {
|
||||||
gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1);
|
gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1);
|
||||||
LoggedAction *la = &gamelog_action[gamelog_actions++];
|
LoggedAction *la = &gamelog_action[gamelog_actions++];
|
||||||
memset(la, 0, sizeof(*la));
|
*la = LoggedAction{};
|
||||||
|
|
||||||
SlObject(la, slt);
|
SlObject(la, slt);
|
||||||
}
|
}
|
||||||
|
@@ -65,14 +65,10 @@
|
|||||||
|
|
||||||
Industry *i = ::Industry::Get(industry_id);
|
Industry *i = ::Industry::Get(industry_id);
|
||||||
|
|
||||||
for (byte j = 0; j < lengthof(i->accepts_cargo); j++) {
|
if (!i->IsCargoAccepted(cargo_id)) return CAS_NOT_ACCEPTED;
|
||||||
if (i->accepts_cargo[j] == cargo_id) {
|
|
||||||
if (IndustryTemporarilyRefusesCargo(i, cargo_id)) return CAS_TEMP_REFUSED;
|
if (IndustryTemporarilyRefusesCargo(i, cargo_id)) return CAS_TEMP_REFUSED;
|
||||||
return CAS_ACCEPTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CAS_NOT_ACCEPTED;
|
return CAS_ACCEPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ SQInteger ScriptIndustry::GetStockpiledCargo(IndustryID industry_id, CargoID cargo_id)
|
/* static */ SQInteger ScriptIndustry::GetStockpiledCargo(IndustryID industry_id, CargoID cargo_id)
|
||||||
@@ -80,15 +76,12 @@
|
|||||||
if (!IsValidIndustry(industry_id)) return -1;
|
if (!IsValidIndustry(industry_id)) return -1;
|
||||||
if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
|
if (!ScriptCargo::IsValidCargo(cargo_id)) return -1;
|
||||||
|
|
||||||
Industry *ind = ::Industry::Get(industry_id);
|
Industry *i = ::Industry::Get(industry_id);
|
||||||
for (uint i = 0; i < lengthof(ind->accepts_cargo); i++) {
|
|
||||||
CargoID cid = ind->accepts_cargo[i];
|
|
||||||
if (cid == cargo_id) {
|
|
||||||
return ind->incoming_cargo_waiting[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
int j = i->GetCargoAcceptedIndex(cargo_id);
|
||||||
|
if (j < 0) return -1;
|
||||||
|
|
||||||
|
return i->incoming_cargo_waiting[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ SQInteger ScriptIndustry::GetLastMonthProduction(IndustryID industry_id, CargoID cargo_id)
|
/* static */ SQInteger ScriptIndustry::GetLastMonthProduction(IndustryID industry_id, CargoID cargo_id)
|
||||||
@@ -98,11 +91,10 @@
|
|||||||
|
|
||||||
const Industry *i = ::Industry::Get(industry_id);
|
const Industry *i = ::Industry::Get(industry_id);
|
||||||
|
|
||||||
for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
|
int j = i->GetCargoProducedIndex(cargo_id);
|
||||||
if (i->produced_cargo[j] == cargo_id) return i->last_month_production[j];
|
if (j < 0) return -1;
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
return i->last_month_production[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ SQInteger ScriptIndustry::GetLastMonthTransported(IndustryID industry_id, CargoID cargo_id)
|
/* static */ SQInteger ScriptIndustry::GetLastMonthTransported(IndustryID industry_id, CargoID cargo_id)
|
||||||
@@ -112,11 +104,10 @@
|
|||||||
|
|
||||||
const Industry *i = ::Industry::Get(industry_id);
|
const Industry *i = ::Industry::Get(industry_id);
|
||||||
|
|
||||||
for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
|
int j = i->GetCargoProducedIndex(cargo_id);
|
||||||
if (i->produced_cargo[j] == cargo_id) return i->last_month_transported[j];
|
if (j < 0) return -1;
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
return i->last_month_transported[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ SQInteger ScriptIndustry::GetLastMonthTransportedPercentage(IndustryID industry_id, CargoID cargo_id)
|
/* static */ SQInteger ScriptIndustry::GetLastMonthTransportedPercentage(IndustryID industry_id, CargoID cargo_id)
|
||||||
@@ -126,11 +117,10 @@
|
|||||||
|
|
||||||
const Industry *i = ::Industry::Get(industry_id);
|
const Industry *i = ::Industry::Get(industry_id);
|
||||||
|
|
||||||
for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
|
int j = i->GetCargoProducedIndex(cargo_id);
|
||||||
if (i->produced_cargo[j] == cargo_id) return ::ToPercent8(i->last_month_pct_transported[j]);
|
if (j < 0) return -1;
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
return ::ToPercent8(i->last_month_pct_transported[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ TileIndex ScriptIndustry::GetLocation(IndustryID industry_id)
|
/* static */ TileIndex ScriptIndustry::GetLocation(IndustryID industry_id)
|
||||||
|
@@ -23,17 +23,13 @@ ScriptIndustryList::ScriptIndustryList()
|
|||||||
ScriptIndustryList_CargoAccepting::ScriptIndustryList_CargoAccepting(CargoID cargo_id)
|
ScriptIndustryList_CargoAccepting::ScriptIndustryList_CargoAccepting(CargoID cargo_id)
|
||||||
{
|
{
|
||||||
for (const Industry *i : Industry::Iterate()) {
|
for (const Industry *i : Industry::Iterate()) {
|
||||||
for (byte j = 0; j < lengthof(i->accepts_cargo); j++) {
|
if (i->IsCargoAccepted(cargo_id)) this->AddItem(i->index);
|
||||||
if (i->accepts_cargo[j] == cargo_id) this->AddItem(i->index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptIndustryList_CargoProducing::ScriptIndustryList_CargoProducing(CargoID cargo_id)
|
ScriptIndustryList_CargoProducing::ScriptIndustryList_CargoProducing(CargoID cargo_id)
|
||||||
{
|
{
|
||||||
for (const Industry *i : Industry::Iterate()) {
|
for (const Industry *i : Industry::Iterate()) {
|
||||||
for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
|
if (i->IsCargoProduced(cargo_id)) this->AddItem(i->index);
|
||||||
if (i->produced_cargo[j] == cargo_id) this->AddItem(i->index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -83,13 +83,7 @@ ScriptTileList_IndustryAccepting::ScriptTileList_IndustryAccepting(IndustryID in
|
|||||||
if (i->neutral_station != nullptr && !_settings_game.station.serve_neutral_industries) return;
|
if (i->neutral_station != nullptr && !_settings_game.station.serve_neutral_industries) return;
|
||||||
|
|
||||||
/* Check if this industry accepts anything */
|
/* Check if this industry accepts anything */
|
||||||
{
|
if (!i->IsCargoAccepted()) return;
|
||||||
bool cargo_accepts = false;
|
|
||||||
for (byte j = 0; j < lengthof(i->accepts_cargo); j++) {
|
|
||||||
if (i->accepts_cargo[j] != CT_INVALID) cargo_accepts = true;
|
|
||||||
}
|
|
||||||
if (!cargo_accepts) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_settings_game.station.modified_catchment) radius = CA_UNMODIFIED + _settings_game.station.catchment_increase;
|
if (!_settings_game.station.modified_catchment) radius = CA_UNMODIFIED + _settings_game.station.catchment_increase;
|
||||||
|
|
||||||
@@ -123,11 +117,7 @@ ScriptTileList_IndustryProducing::ScriptTileList_IndustryProducing(IndustryID in
|
|||||||
if (i->neutral_station != nullptr && !_settings_game.station.serve_neutral_industries) return;
|
if (i->neutral_station != nullptr && !_settings_game.station.serve_neutral_industries) return;
|
||||||
|
|
||||||
/* Check if this industry produces anything */
|
/* Check if this industry produces anything */
|
||||||
bool cargo_produces = false;
|
if (!i->IsCargoProduced()) return;
|
||||||
for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
|
|
||||||
if (i->produced_cargo[j] != CT_INVALID) cargo_produces = true;
|
|
||||||
}
|
|
||||||
if (!cargo_produces) return;
|
|
||||||
|
|
||||||
if (!_settings_game.station.modified_catchment) radius = CA_UNMODIFIED + _settings_game.station.catchment_increase;
|
if (!_settings_game.station.modified_catchment) radius = CA_UNMODIFIED + _settings_game.station.catchment_increase;
|
||||||
|
|
||||||
|
@@ -155,18 +155,14 @@ std::string ScriptScanner::GetConsoleList(bool newest_only) const
|
|||||||
|
|
||||||
/** Helper for creating a MD5sum of all files within of a script. */
|
/** Helper for creating a MD5sum of all files within of a script. */
|
||||||
struct ScriptFileChecksumCreator : FileScanner {
|
struct ScriptFileChecksumCreator : FileScanner {
|
||||||
byte md5sum[16]; ///< The final md5sum.
|
MD5Hash md5sum; ///< The final md5sum.
|
||||||
Subdirectory dir; ///< The directory to look in.
|
Subdirectory dir; ///< The directory to look in.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise the md5sum to be all zeroes,
|
* Initialise the md5sum to be all zeroes,
|
||||||
* so we can easily xor the data.
|
* so we can easily xor the data.
|
||||||
*/
|
*/
|
||||||
ScriptFileChecksumCreator(Subdirectory dir)
|
ScriptFileChecksumCreator(Subdirectory dir) : dir(dir) {}
|
||||||
{
|
|
||||||
this->dir = dir;
|
|
||||||
memset(this->md5sum, 0, sizeof(this->md5sum));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the file and calculate the md5 sum. */
|
/* Add the file and calculate the md5 sum. */
|
||||||
virtual bool AddFile(const std::string &filename, size_t basepath_length, const std::string &tar_filename)
|
virtual bool AddFile(const std::string &filename, size_t basepath_length, const std::string &tar_filename)
|
||||||
@@ -174,7 +170,6 @@ struct ScriptFileChecksumCreator : FileScanner {
|
|||||||
Md5 checksum;
|
Md5 checksum;
|
||||||
uint8 buffer[1024];
|
uint8 buffer[1024];
|
||||||
size_t len, size;
|
size_t len, size;
|
||||||
byte tmp_md5sum[16];
|
|
||||||
|
|
||||||
/* Open the file ... */
|
/* Open the file ... */
|
||||||
FILE *f = FioFOpenFile(filename.c_str(), "rb", this->dir, &size);
|
FILE *f = FioFOpenFile(filename.c_str(), "rb", this->dir, &size);
|
||||||
@@ -185,12 +180,14 @@ struct ScriptFileChecksumCreator : FileScanner {
|
|||||||
size -= len;
|
size -= len;
|
||||||
checksum.Append(buffer, len);
|
checksum.Append(buffer, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MD5Hash tmp_md5sum;
|
||||||
checksum.Finish(tmp_md5sum);
|
checksum.Finish(tmp_md5sum);
|
||||||
|
|
||||||
FioFCloseFile(f);
|
FioFCloseFile(f);
|
||||||
|
|
||||||
/* ... and xor it to the overall md5sum. */
|
/* ... and xor it to the overall md5sum. */
|
||||||
for (uint i = 0; i < sizeof(md5sum); i++) this->md5sum[i] ^= tmp_md5sum[i];
|
this->md5sum ^= tmp_md5sum;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -238,7 +235,7 @@ static bool IsSameScript(const ContentInfo *ci, bool md5sum, ScriptInfo *info, S
|
|||||||
checksum.Scan(".nut", path);
|
checksum.Scan(".nut", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return memcmp(ci->md5sum, checksum.md5sum, sizeof(ci->md5sum)) == 0;
|
return ci->md5sum == checksum.md5sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScriptScanner::HasScript(const ContentInfo *ci, bool md5sum)
|
bool ScriptScanner::HasScript(const ContentInfo *ci, bool md5sum)
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
#define SQUIRREL_HELPER_HPP
|
#define SQUIRREL_HELPER_HPP
|
||||||
|
|
||||||
#include "squirrel.hpp"
|
#include "squirrel.hpp"
|
||||||
#include "../core/smallvec_type.hpp"
|
|
||||||
#include "../economy_type.h"
|
#include "../economy_type.h"
|
||||||
#include "../string_func.h"
|
#include "../string_func.h"
|
||||||
#include "../tile_type.h"
|
#include "../tile_type.h"
|
||||||
|
@@ -271,9 +271,9 @@ static size_t LookupManyOfMany(const std::vector<std::string> &many, const char
|
|||||||
* @return returns the number of items found, or -1 on an error
|
* @return returns the number of items found, or -1 on an error
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static int ParseIntList(const char *p, T *items, int maxitems)
|
static int ParseIntList(const char *p, T *items, size_t maxitems)
|
||||||
{
|
{
|
||||||
int n = 0; // number of items read so far
|
size_t n = 0; // number of items read so far
|
||||||
bool comma = false; // do we accept comma?
|
bool comma = false; // do we accept comma?
|
||||||
|
|
||||||
while (*p != '\0') {
|
while (*p != '\0') {
|
||||||
@@ -306,7 +306,7 @@ static int ParseIntList(const char *p, T *items, int maxitems)
|
|||||||
* We have read comma when (n != 0) and comma is not allowed */
|
* We have read comma when (n != 0) and comma is not allowed */
|
||||||
if (n != 0 && !comma) return -1;
|
if (n != 0 && !comma) return -1;
|
||||||
|
|
||||||
return n;
|
return ClampTo<int>(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2087,7 +2087,8 @@ static GRFConfig *GRFLoadConfig(IniFile &ini, const char *grpname, bool is_stati
|
|||||||
for (item = group->item; item != nullptr; item = item->next) {
|
for (item = group->item; item != nullptr; item = item->next) {
|
||||||
GRFConfig *c = nullptr;
|
GRFConfig *c = nullptr;
|
||||||
|
|
||||||
uint8 grfid_buf[4], md5sum[16];
|
uint8 grfid_buf[4];
|
||||||
|
MD5Hash md5sum;
|
||||||
const char *filename = item->name.c_str();
|
const char *filename = item->name.c_str();
|
||||||
bool has_grfid = false;
|
bool has_grfid = false;
|
||||||
bool has_md5sum = false;
|
bool has_md5sum = false;
|
||||||
@@ -2096,12 +2097,12 @@ static GRFConfig *GRFLoadConfig(IniFile &ini, const char *grpname, bool is_stati
|
|||||||
has_grfid = DecodeHexText(filename, grfid_buf, lengthof(grfid_buf));
|
has_grfid = DecodeHexText(filename, grfid_buf, lengthof(grfid_buf));
|
||||||
if (has_grfid) {
|
if (has_grfid) {
|
||||||
filename += 1 + 2 * lengthof(grfid_buf);
|
filename += 1 + 2 * lengthof(grfid_buf);
|
||||||
has_md5sum = DecodeHexText(filename, md5sum, lengthof(md5sum));
|
has_md5sum = DecodeHexText(filename, md5sum.data(), md5sum.size());
|
||||||
if (has_md5sum) filename += 1 + 2 * lengthof(md5sum);
|
if (has_md5sum) filename += 1 + 2 * md5sum.size();
|
||||||
|
|
||||||
uint32 grfid = grfid_buf[0] | (grfid_buf[1] << 8) | (grfid_buf[2] << 16) | (grfid_buf[3] << 24);
|
uint32 grfid = grfid_buf[0] | (grfid_buf[1] << 8) | (grfid_buf[2] << 16) | (grfid_buf[3] << 24);
|
||||||
if (has_md5sum) {
|
if (has_md5sum) {
|
||||||
const GRFConfig *s = FindGRFConfig(grfid, FGCM_EXACT, md5sum);
|
const GRFConfig *s = FindGRFConfig(grfid, FGCM_EXACT, &md5sum);
|
||||||
if (s != nullptr) c = new GRFConfig(*s);
|
if (s != nullptr) c = new GRFConfig(*s);
|
||||||
}
|
}
|
||||||
if (c == nullptr && !FioCheckFileExists(filename, NEWGRF_DIR)) {
|
if (c == nullptr && !FioCheckFileExists(filename, NEWGRF_DIR)) {
|
||||||
@@ -2113,7 +2114,7 @@ static GRFConfig *GRFLoadConfig(IniFile &ini, const char *grpname, bool is_stati
|
|||||||
|
|
||||||
/* Parse parameters */
|
/* Parse parameters */
|
||||||
if (item->value.has_value() && !item->value->empty()) {
|
if (item->value.has_value() && !item->value->empty()) {
|
||||||
int count = ParseIntList(item->value->c_str(), c->param, lengthof(c->param));
|
int count = ParseIntList(item->value->c_str(), c->param.data(), c->param.size());
|
||||||
if (count < 0) {
|
if (count < 0) {
|
||||||
SetDParamStr(0, filename);
|
SetDParamStr(0, filename);
|
||||||
ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_ARRAY, WL_CRITICAL);
|
ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_ARRAY, WL_CRITICAL);
|
||||||
@@ -2255,13 +2256,10 @@ static void GRFSaveConfig(IniFile &ini, const char *grpname, const GRFConfig *li
|
|||||||
for (c = list; c != nullptr; c = c->next) {
|
for (c = list; c != nullptr; c = c->next) {
|
||||||
/* Hex grfid (4 bytes in nibbles), "|", hex md5sum (16 bytes in nibbles), "|", file system path. */
|
/* Hex grfid (4 bytes in nibbles), "|", hex md5sum (16 bytes in nibbles), "|", file system path. */
|
||||||
char key[4 * 2 + 1 + 16 * 2 + 1 + MAX_PATH];
|
char key[4 * 2 + 1 + 16 * 2 + 1 + MAX_PATH];
|
||||||
char params[512];
|
|
||||||
GRFBuildParamList(params, c, lastof(params));
|
|
||||||
|
|
||||||
char *pos = key + seprintf(key, lastof(key), "%08X|", BSWAP32(c->ident.grfid));
|
char *pos = key + seprintf(key, lastof(key), "%08X|", BSWAP32(c->ident.grfid));
|
||||||
pos = md5sumToString(pos, lastof(key), c->ident.md5sum);
|
pos = md5sumToString(pos, lastof(key), c->ident.md5sum);
|
||||||
seprintf(pos, lastof(key), "|%s", c->filename.c_str());
|
seprintf(pos, lastof(key), "|%s", c->filename.c_str());
|
||||||
group->GetItem(key, true)->SetValue(params);
|
group->GetItem(key, true)->SetValue(GRFBuildParamList(c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,7 +10,6 @@
|
|||||||
#ifndef SETTINGS_FUNC_H
|
#ifndef SETTINGS_FUNC_H
|
||||||
#define SETTINGS_FUNC_H
|
#define SETTINGS_FUNC_H
|
||||||
|
|
||||||
#include "core/smallvec_type.hpp"
|
|
||||||
#include "company_type.h"
|
#include "company_type.h"
|
||||||
#include "string_type.h"
|
#include "string_type.h"
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
#include "../strings_type.h"
|
#include "../strings_type.h"
|
||||||
#include "../misc/getoptdata.h"
|
#include "../misc/getoptdata.h"
|
||||||
#include "../ini_type.h"
|
#include "../ini_type.h"
|
||||||
#include "../core/smallvec_type.hpp"
|
#include "../core/mem_func.hpp"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
@@ -406,7 +406,6 @@ static bool CompareFiles(const char *n1, const char *n2)
|
|||||||
|
|
||||||
/** Options of settingsgen. */
|
/** Options of settingsgen. */
|
||||||
static const OptionData _opts[] = {
|
static const OptionData _opts[] = {
|
||||||
GETOPT_NOVAL( 'v', "--version"),
|
|
||||||
GETOPT_NOVAL( 'h', "--help"),
|
GETOPT_NOVAL( 'h', "--help"),
|
||||||
GETOPT_GENERAL('h', '?', nullptr, ODF_NO_VALUE),
|
GETOPT_GENERAL('h', '?', nullptr, ODF_NO_VALUE),
|
||||||
GETOPT_VALUE( 'o', "--output"),
|
GETOPT_VALUE( 'o', "--output"),
|
||||||
@@ -461,15 +460,10 @@ int CDECL main(int argc, char *argv[])
|
|||||||
if (i == -1) break;
|
if (i == -1) break;
|
||||||
|
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 'v':
|
|
||||||
puts("$Revision$");
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
puts("settingsgen - $Revision$\n"
|
puts("settingsgen\n"
|
||||||
"Usage: settingsgen [options] ini-file...\n"
|
"Usage: settingsgen [options] ini-file...\n"
|
||||||
"with options:\n"
|
"with options:\n"
|
||||||
" -v, --version Print version information and exit\n"
|
|
||||||
" -h, -?, --help Print this help message and exit\n"
|
" -h, -?, --help Print this help message and exit\n"
|
||||||
" -b FILE, --before FILE Copy FILE before all settings\n"
|
" -b FILE, --before FILE Copy FILE before all settings\n"
|
||||||
" -a FILE, --after FILE Copy FILE after all settings\n"
|
" -a FILE, --after FILE Copy FILE after all settings\n"
|
||||||
|
@@ -72,7 +72,7 @@ void DrawShipDetails(const Vehicle *v, const Rect &r)
|
|||||||
Money feeder_share = 0;
|
Money feeder_share = 0;
|
||||||
|
|
||||||
if (v->Next() != nullptr) {
|
if (v->Next() != nullptr) {
|
||||||
CargoArray max_cargo;
|
CargoArray max_cargo{};
|
||||||
StringID subtype_text[NUM_CARGO];
|
StringID subtype_text[NUM_CARGO];
|
||||||
char capacity[512];
|
char capacity[512];
|
||||||
|
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
#include "../animated_tile.h"
|
#include "../animated_tile.h"
|
||||||
#include "../tile_type.h"
|
#include "../tile_type.h"
|
||||||
#include "../core/alloc_func.hpp"
|
#include "../core/alloc_func.hpp"
|
||||||
#include "../core/smallvec_type.hpp"
|
|
||||||
|
|
||||||
#include "saveload.h"
|
#include "saveload.h"
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
#include "../company_base.h"
|
#include "../company_base.h"
|
||||||
#include "../disaster_vehicle.h"
|
#include "../disaster_vehicle.h"
|
||||||
#include "../animated_tile.h"
|
#include "../animated_tile.h"
|
||||||
#include "../core/smallvec_type.hpp"
|
#include "../core/container_func.hpp"
|
||||||
#include "../timer/timer.h"
|
#include "../timer/timer.h"
|
||||||
#include "../timer/timer_game_tick.h"
|
#include "../timer/timer_game_tick.h"
|
||||||
#include "saveload_internal.h"
|
#include "saveload_internal.h"
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user