diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 195ffa6e1..7e24f3659 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -15,6 +15,10 @@ include_directories (depends/tinyxml) include_directories (depends/tthread) include_directories (private) +execute_process(COMMAND perl xml/list.pl xml include/dfhack/df ";" + WORKING_DIRECTORY ${dfapi_SOURCE_DIR} + OUTPUT_VARIABLE GENERATED_HDRS) + SET(PROJECT_HDRS_INTERNAL private/ContextShared.h private/Internal.h @@ -123,6 +127,24 @@ SET_SOURCE_FILES_PROPERTIES( ${PROJECT_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE ) LIST(APPEND PROJECT_SRCS ${PROJECT_HDRS}) +# Generation + +SET_SOURCE_FILES_PROPERTIES(${GENERATED_HDRS} PROPERTIES HEADER_FILE_ONLY TRUE GENERATED TRUE) + +FILE(GLOB GENERATE_INPUT_XMLS ${dfapi_SOURCE_DIR}/xml/*.xml) + +ADD_CUSTOM_COMMAND( + OUTPUT ${dfapi_SOURCE_DIR}/include/dfhack/df/static.inc + COMMAND perl xml/codegen.pl xml include/dfhack/df + WORKING_DIRECTORY ${dfapi_SOURCE_DIR} + MAIN_DEPENDENCY ${dfapi_SOURCE_DIR}/xml/codegen.pl + DEPENDS ${GENERATE_INPUT_XMLS} +) + +ADD_CUSTOM_TARGET(generate_headers DEPENDS ${dfapi_SOURCE_DIR}/include/dfhack/df/static.inc) + +# Compilation + ADD_DEFINITIONS(-DBUILD_DFHACK_LIB) IF(UNIX) @@ -142,6 +164,7 @@ ELSE(WIN32) ENDIF() ADD_LIBRARY(dfhack SHARED ${PROJECT_SRCS}) +ADD_DEPENDENCIES(dfhack generate_headers) IF(WIN32) SET_TARGET_PROPERTIES(dfhack PROPERTIES OUTPUT_NAME "SDL" ) diff --git a/library/xml/codegen.pl b/library/xml/codegen.pl new file mode 100755 index 000000000..33210f616 --- /dev/null +++ b/library/xml/codegen.pl @@ -0,0 +1,905 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use XML::LibXML; + +my $input_dir = $ARGV[0] || '.'; +my $output_dir = $ARGV[1] || 'codegen'; +my $main_namespace = $ARGV[2] || 'df'; +my $export_prefix = 'DFHACK_EXPORT '; + +my %types; +my %type_files; + +# Misc XML analysis + +our $typename; +our $filename; + +sub parse_address($;$) { + my ($str,$in_bits) = @_; + return undef unless defined $str; + + # Parse the format used by offset attributes in xml + $str =~ /^0x([0-9a-f]+)(?:\.([0-7]))?$/ + or die "Invalid address syntax: $str\n"; + my ($full, $bv) = ($1, $2); + die "Bits not allowed: $str\n" unless $in_bits; + return $in_bits ? (hex($full)*8 + ($bv||0)) : hex($full); +} + +sub check_bad_attrs($;$$) { + my ($tag, $allow_size, $allow_align) = @_; + + die "Cannot use size, alignment or offset for ".$tag->nodeName."\n" + if ((!$allow_size && defined $tag->getAttribute('size')) || + defined $tag->getAttribute('offset') || + (!$allow_align && defined $tag->getAttribute('alignment'))); +} + +sub check_name($) { + my ($name) = @_; + $name =~ /^[_a-zA-Z][_a-zA-Z0-9]*$/ + or die "Invalid identifier: $name\n"; + return $name; +} + +sub is_attr_true($$) { + my ($tag, $name) = @_; + return ($tag->getAttribute($name)||'') eq 'true'; +} + +sub type_header_def($) { + my ($name) = @_; + return uc($main_namespace).'_'.uc($name).'_H'; +} + +# Text generation with indentation + +our @lines; +our $indentation = 0; + +sub with_emit(&;$) { + # Executes the code block, and returns emitted lines + my ($blk, $start_indent) = @_; + local @lines; + local $indentation = ($start_indent||0); + $blk->(); + return @lines; +} + +sub emit(@) { + # Emit an indented line to be returned from with_emit + my $line = join('',map { defined($_) ? $_ : '' } @_); + $line = (' 'x$indentation).$line unless length($line) == 0; + push @lines, $line; +} + +sub indent(&) { + # Indent lines emitted from the block by one step + my ($blk) = @_; + local $indentation = $indentation+2; + $blk->(); +} + +sub outdent(&) { + # Unindent lines emitted from the block by one step + my ($blk) = @_; + local $indentation = ($indentation >= 2 ? $indentation-2 : 0); + $blk->(); +} + +sub emit_block(&;$$) { + # Emit a full {...} block with indentation + my ($blk, $prefix, $suffix) = @_; + $prefix ||= ''; + $suffix ||= ''; + emit $prefix,'{'; + &indent($blk); + emit '}',$suffix; +} + +# Static file output + +my @static_lines; +my %static_includes; + +sub with_emit_static(&) { + my ($blk) = @_; + $static_includes{$typename}++; + push @static_lines, &with_emit($blk,2); +} + +# Anonymous variable names + +our $anon_id = 0; +our $anon_prefix; + +sub ensure_name($) { + # If the name is empty, assign an auto-generated one + my ($name) = @_; + unless ($name) { + $name = $anon_prefix.(($anon_id == 0) ? '' : '_'.$anon_id); + $anon_id++; + } + return check_name($name); +} + +sub with_anon(&;$) { + # Establish a new anonymous namespace + my ($blk,$stem) = @_; + local $anon_id = $stem ? 0 : 1; + local $anon_prefix = ($stem||'anon'); + $blk->(); +} + +# Primitive types + +my @primitive_type_list = + qw(int8_t uint8_t int16_t uint16_t + int32_t uint32_t int64_t uint64_t + s-float + bool ptr-string stl-string flag-bit + pointer); + +my %primitive_aliases = ( + 'stl-string' => 'std::string', + 'ptr-string' => 'char*', + 'flag-bit' => 'void', + 'pointer' => 'void*', + 's-float' => 'float', +); + +my %primitive_types; +$primitive_types{$_}++ for @primitive_type_list; + +sub primitive_type_name($) { + my ($tag_name) = @_; + $primitive_types{$tag_name} + or die "Not primitive: $tag_name\n"; + return $primitive_aliases{$tag_name} || $tag_name; +} + +# Type references + +our %weak_refs; +our %strong_refs; + +sub register_ref($;$) { + # Register a reference to another type. + # Strong ones require the type to be included. + my ($ref, $is_strong) = @_; + + if ($ref) { + my $type = $types{$ref} + or die "Unknown type $ref referenced.\n"; + + if ($is_strong) { + $strong_refs{$ref}++; + } else { + $weak_refs{$ref}++; + } + } +} + +# Determines if referenced other types should be included or forward-declared +our $is_strong_ref = 1; + +sub with_struct_block(&$;$%) { + my ($blk, $tag, $name, %flags) = @_; + + my $kwd = (is_attr_true($tag,'is-union') ? "union" : "struct"); + my $exp = $flags{-export} ? $export_prefix : ''; + my $prefix = $kwd.' '.$exp.($name ? $name.' ' : ''); + + emit_block { + local $_; + local $is_strong_ref = 1; # reset the state + if ($flags{-no_anon}) { + $blk->(); + } else { + &with_anon($blk); + } + } $prefix, ";"; +} + +sub decode_type_name_ref($;%) { + # Interpret the type-name field of a tag + my ($tag,%flags) = @_; + my $force_type = $flags{-force_type}; + my $force_strong = $flags{-force_strong}; + my $tname = $tag->getAttribute($flags{-attr_name} || 'type-name') + or return undef; + + if ($primitive_types{$tname}) { + die "Cannot use type $tname as type-name of ".$tag->nodeName."\n" + if ($force_type && $force_type ne 'primitive'); + return primitive_type_name($tname); + } else { + register_ref $tname, ($force_strong||$is_strong_ref); + die "Cannot use type $tname as type-name of ".$tag->nodeName."\n" + if ($force_type && $force_type ne $types{$tname}->nodeName); + return $main_namespace.'::'.$tname; + } +} + +# CONDITIONALS + +sub is_conditional($) { + my ($tag) = @_; + return $tag->nodeName =~ /^(cond-if|cond-elseif)$/; +} + +sub translate_if_cond($) { + my ($tag) = @_; + + my @rules; + if (my $defvar = $tag->getAttribute('defined')) { + push @rules, "defined($defvar)"; + } + if (my $cmpvar = $tag->getAttribute('var')) { + if (my $cmpval = $tag->getAttribute('lt')) { + push @rules, "($cmpvar < $cmpval)"; + } + if (my $cmpval = $tag->getAttribute('le')) { + push @rules, "($cmpvar <= $cmpval)"; + } + if (my $cmpval = $tag->getAttribute('eq')) { + push @rules, "($cmpvar == $cmpval)"; + } + if (my $cmpval = $tag->getAttribute('ge')) { + push @rules, "($cmpvar >= $cmpval)"; + } + if (my $cmpval = $tag->getAttribute('gt')) { + push @rules, "($cmpvar > $cmpval)"; + } + if (my $cmpval = $tag->getAttribute('ne')) { + push @rules, "($cmpvar != $cmpval)"; + } + } + return '('.(join(' && ',@rules) || '1').')'; +} + +our $in_cond = 0; + +sub render_cond_if($$$;@) { + my ($tag, $in_elseif, $render_cb, @tail) = @_; + + local $in_cond = 1; + + { + local $indentation = 0; + my $op = ($in_elseif && $in_elseif >= 2) ? '#elif' : '#if'; + emit $op, ' ', translate_if_cond($tag); + } + + for my $child ($tag->findnodes('child::*')) { + &render_cond($child, $render_cb, @tail); + } + + unless ($in_elseif) { + local $indentation = 0; + emit "#endif"; + } +} + +sub render_cond($$;@) { + my ($tag, $render_cb, @tail) = @_; + + my $tag_name = $tag->nodeName; + if ($tag_name eq 'cond-if') { + render_cond_if($tag, 0, $render_cb, @tail); + } elsif ($tag_name eq 'cond-elseif') { + my $idx = 1; + for my $child ($tag->findnodes('child::*')) { + ($child->nodeName eq 'cond-if') + or die "Only cond-if tags may be inside a cond-switch: ".$child->nodeName."\n"; + render_cond_if($child, $idx++, $render_cb, @tail); + } + { + local $indentation = 0; + emit "#endif"; + } + } else { + local $_ = $tag; + $render_cb->($tag, @tail); + } +} + +# ENUM + +sub render_enum_core($$) { + my ($name,$tag) = @_; + + my $base = 0; + + emit_block { + my @items = $tag->findnodes('child::*'); + my $idx = 0; + + for my $item (@items) { + render_cond $item, sub { + my $tag = $_->nodeName; + return if $tag eq 'enum-attr'; + ($tag eq 'enum-item') + or die "Invalid enum member: ".$item->nodeName."\n"; + + my $name = ensure_name $_->getAttribute('name'); + my $value = $_->getAttribute('value'); + + $base = ($idx == 0 && !$in_cond) ? $value : undef if defined $value; + $idx++; + + emit $name, (defined($value) ? ' = '.$value : ''), ','; + }; + } + + emit "_last_item_of_$name"; + } "enum $name ", ";"; + + return $base; +} + +sub render_enum_tables($$$) { + my ($name,$tag,$base) = @_; + + # Enumerate enum attributes + + my %aidx = ('key' => 0); + my @anames = ('key'); + my @avals = ('NULL'); + my @atypes = ('const char*'); + my @atnames = (undef); + + for my $attr ($tag->findnodes('child::enum-attr')) { + my $name = $attr->getAttribute('name') or die "Unnamed enum-attr.\n"; + my $type = $attr->getAttribute('type-name'); + my $def = $attr->getAttribute('default-value'); + + die "Duplicate attribute $name.\n" if exists $aidx{$name}; + + check_name $name; + $aidx{$name} = scalar @anames; + push @anames, $name; + push @atnames, $type; + + if ($type) { + push @atypes, $type; + push @avals, (defined $def ? $def : "($type)0"); + } else { + push @atypes, 'const char*'; + push @avals, (defined $def ? "\"$def\"" : 'NULL'); + } + } + + # Emit accessor function prototypes + + emit "const $name _first_item_of_$name = ($name)$base;"; + + emit_block { + emit "return (value >= _first_item_of_$name && value < _last_item_of_$name);"; + } "inline bool is_valid($name value) "; + + for (my $i = 0; $i < @anames; $i++) { + emit "${export_prefix}$atypes[$i] get_$anames[$i]($name value);"; + } + + # Emit implementation + + with_emit_static { + emit_block { + emit_block { + # Emit the entry type + emit_block { + for (my $i = 0; $i < @anames; $i++) { + emit "$atypes[$i] $anames[$i];"; + } + } "struct _info_entry ", ";"; + + # Emit the info table + emit_block { + for my $item ($tag->findnodes('child::*')) { + render_cond $item, sub { + my $tag = $_->nodeName; + return if $tag eq 'enum-attr'; + + # Assemble item-specific attr values + my @evals = @avals; + my $name = $_->getAttribute('name'); + $evals[0] = "\"$name\"" if $name; + + for my $attr ($_->findnodes('child::item-attr')) { + my $name = $attr->getAttribute('name') or die "Unnamed item-attr.\n"; + my $value = $attr->getAttribute('value') or die "No-value item-attr.\n"; + my $idx = $aidx{$name} or die "Unknown item-attr: $name\n"; + + if ($atnames[$idx]) { + $evals[$idx] = $value; + } else { + $evals[$idx] = "\"$value\""; + } + } + + emit "{ ",join(', ',@evals)," },"; + }; + } + + emit "{ ",join(', ',@avals)," }"; + } "static const _info_entry _info[] = ", ";"; + + for (my $i = 0; $i < @anames; $i++) { + emit_block { + emit "return is_valid(value) ? _info[value - $base].$anames[$i] : $avals[$i];"; + } "$atypes[$i] get_$anames[$i]($name value) "; + } + } "namespace $name "; + } "namespace enums "; + }; +} + +sub render_enum_type { + my ($tag) = @_; + + emit_block { + emit_block { + my $base = render_enum_core($typename,$tag); + + if (defined $base) { + render_enum_tables($typename,$tag,$base); + } else { + print STDERR "Warning: complex enum: $typename\n"; + } + } "namespace $typename "; + } "namespace enums "; + + emit "using enums::",$typename,"::",$typename,";"; +} + +# BITFIELD + +sub get_primitive_base($;$) { + my ($tag, $default) = @_; + + my $base = $tag->getAttribute('base-type') || $default || 'uint32_t'; + $primitive_types{$base} or die "Must be primitive: $base\n"; + + return $base; +} + +sub render_bitfield_core { + my ($name, $tag) = @_; + + emit_block { + emit get_primitive_base($tag), ' whole;'; + + emit_block { + for my $item ($tag->findnodes('child::*')) { + render_cond $item, sub { + my ($item) = @_; + ($item->nodeName eq 'flag-bit') + or die "Invalid bitfield member:".$item->nodeName."\n"; + + check_bad_attrs($item); + my $name = ensure_name $item->getAttribute('name'); + my $size = $item->getAttribute('count') || 1; + emit "unsigned ", $name, " : ", $size, ";"; + }; + } + } "struct ", " bits;"; + } "union $name ", ";"; +} + +sub render_bitfield_type { + my ($tag) = @_; + render_bitfield_core($typename,$tag); +} + +# STRUCT + +my %struct_field_handlers; + +sub get_struct_fields($) { + # Retrieve subtags that are actual struct fields + my ($struct_tag) = @_; + local $_; + return grep { + my $tag = $_->nodeName; + die "Unknown field tag: $tag\n" + unless exists $struct_field_handlers{$tag}; + $struct_field_handlers{$tag}; + } $struct_tag->findnodes('child::*'); +} + +sub get_struct_field_type($) { + # Dispatch on the tag name, and retrieve the type prefix & suffix + my ($tag) = @_; + my $handler = $struct_field_handlers{$tag->nodeName} + or die "Unexpected tag: ".$tag->nodeName; + return $handler->($tag); +} + +sub do_render_struct_field($) { + my ($tag) = @_; + my $tag_name = $tag->nodeName; + my $field_name = $tag->getAttribute('name'); + + # Special case: anonymous compounds. + if ($tag_name eq 'compound' && !defined $field_name && + !defined $tag->getAttribute('type-name')) + { + check_bad_attrs($tag); + with_struct_block { + render_struct_field($_) for get_struct_fields($tag); + } $tag, undef, -no_anon => 1; + return; + } + + # Otherwise, create the name if necessary, and render + my $name = ensure_name $field_name; + with_anon { + my ($prefix, $postfix) = get_struct_field_type($tag); + emit $prefix, ' ', $name, $postfix, ';'; + } "T_$name"; +} + +sub render_struct_field($) { + my ($tag) = @_; + render_cond $tag, \&do_render_struct_field; +} + +sub emit_typedef($$) { + # Convert a prefix/postfix pair into a single name + my ($pre, $post) = @_; + my $name = ensure_name undef; + emit 'typedef ', $pre, ' ', $name, $post, ';'; + return $name; +} + +sub get_container_item_type($$;$) { + # Interpret the type-name and nested fields for a generic container type + my ($tag,$strong_ref,$allow_void) = @_; + + check_bad_attrs($tag); + + my $prefix; + my $postfix = ''; + local $is_strong_ref = $strong_ref; + + unless ($prefix = decode_type_name_ref($tag)) { + my @fields = get_struct_fields($tag); + + if (scalar(@fields) == 1 && !is_conditional($fields[0])) { + ($prefix, $postfix) = get_struct_field_type($fields[0]); + } elsif (scalar(@fields) == 0) { + $allow_void or die "Empty container: ".$tag->nodeName."\n"; + $prefix = $allow_void; + } else { + $prefix = ensure_name undef; + with_struct_block { + render_struct_field($_) for @fields; + } $tag, $prefix; + } + } + + return ($prefix,$postfix) if wantarray; + return emit_typedef($prefix, $postfix) if $postfix; + return $prefix; +} + +sub get_primitive_field_type { + # Primitive type handler + my ($tag,$fname) = @_; + check_bad_attrs($tag); + my $name = $tag->nodeName; + return (primitive_type_name($name), ""); +} + +sub get_static_string_type { + # Static string handler + my ($tag, $fname) = @_; + check_bad_attrs($tag, 1); + my $count = $tag->getAttribute('size') || 0; + return ('char', "[$count]"); +} + +sub get_padding_type { + # Padding handler. Supports limited alignment. + my ($tag, $fname) = @_; + + check_bad_attrs($tag, 1, 1); + my $count = $tag->getAttribute('size') || 0; + my $align = $tag->getAttribute('alignment') || 1; + + if ($align == 1) { + return ('char', "[$count]"); + } elsif ($align == 2) { + ($count % 2 == 0) or die "Size not aligned in padding: $count at $align\n"; + return ('short', "[".($count/2)."]"); + } elsif ($align == 4) { + ($count % 4 == 0) or die "Size not aligned in padding: $count at $align\n"; + return ('int', "[".($count/4)."]"); + } else { + die "Bad padding alignment $align in $typename in $filename\n"; + } +} + +sub get_static_array_type { + # static-array handler + my ($tag, $fname) = @_; + my ($pre, $post) = get_container_item_type($tag, 1); + my $count = $tag->getAttribute('count') + or die "Count is mandatory for static-array in $typename in $filename\n"; + return ($pre, "[$count]".$post); +} + +sub get_pointer_type($) { + # pointer handler + my ($tag) = @_; + my $item = get_container_item_type($tag, 0, 'void'); + return ($item.'*', ''); +} + +sub get_compound_type($) { + # compound (nested struct) handler + my ($tag) = @_; + check_bad_attrs($tag); + + my $tname = decode_type_name_ref($tag); + unless ($tname) { + $tname = ensure_name undef; + with_struct_block { + render_struct_field($_) for get_struct_fields($tag); + } $tag, $tname; + } + return ($tname,''); +} + +sub get_bitfield_type($) { + # nested bitfield handler + my ($tag) = @_; + check_bad_attrs($tag); + + my $tname = decode_type_name_ref($tag, -force_type => 'bitfield-type'); + unless ($tname) { + $tname = ensure_name undef; + with_anon { + render_bitfield_core($tname, $tag); + }; + } + return ($tname,''); +} + +sub get_enum_type($) { + # nested enum handler + my ($tag) = @_; + check_bad_attrs($tag); + + my $tname = decode_type_name_ref($tag, -force_type => 'enum-type', -force_strong => 1); + my $base = get_primitive_base($tag, 'int32_t'); + unless ($tname) { + $tname = ensure_name undef; + with_anon { + render_enum_core($tname,$tag); + }; + } + return ("enum_field<$tname,$base>", ''); +} + +sub get_stl_vector_type($) { + # STL vector + my ($tag) = @_; + my $item = get_container_item_type($tag,1,'void*'); + $item = 'char' if $item eq 'bool'; + return ("std::vector<$item>", ''); +} + +sub get_stl_bit_vector_type($) { + # STL bit vector + my ($tag) = @_; + check_bad_attrs($tag); + return ("std::vector", ''); +} + +sub get_df_flagarray_type($) { + # DF flag array + my ($tag) = @_; + check_bad_attrs($tag); + my $type = decode_type_name_ref($tag, -attr_name => 'index-enum', -force_type => 'enum-type', -force_strong => 1) || 'int'; + return ("BitArray<$type>", ''); +} + +# Struct dispatch table and core + +%struct_field_handlers = ( + 'comment' => undef, # skip + 'code-helper' => undef, # skip + 'cond-if' => sub { die "cond handling error"; }, + 'cond-elseif' => sub { die "cond handling error"; }, + 'static-string' => \&get_static_string_type, + 'padding' => \&get_padding_type, + 'static-array' => \&get_static_array_type, + 'pointer' => \&get_pointer_type, + 'compound' => \&get_compound_type, + 'bitfield' => \&get_bitfield_type, + 'enum' => \&get_enum_type, + 'stl-vector' => \&get_stl_vector_type, + 'stl-bit-vector' => \&get_stl_bit_vector_type, + 'df-flagarray' => \&get_df_flagarray_type, +); +$struct_field_handlers{$_} ||= \&get_primitive_field_type for @primitive_type_list; + +sub render_struct_type { + my ($tag) = @_; + + my $tag_name = $tag->nodeName; + my $is_class = ($tag_name eq 'class-type'); + my $has_methods = $is_class || is_attr_true($tag, 'has-methods'); + my $inherits = $tag->getAttribute('inherits-from'); + my $original_name = $tag->getAttribute('original-name'); + my $ispec = ''; + + if ($inherits) { + register_ref $inherits, 1; + $ispec = ' : '.$inherits; + } elsif ($is_class) { + $ispec = ' : virtual_class'; + } + + with_struct_block { + render_struct_field($_) for get_struct_fields($tag); + + if ($has_methods) { + if ($is_class) { + emit "static class_virtual_identity<$typename> _identity;"; + with_emit_static { + emit "class_virtual_identity<$typename> ${typename}::_identity(", + "\"$typename\",", + ($original_name ? "\"$original_name\"" : 'NULL'), ',', + ($inherits ? "&${inherits}::_identity" : 'NULL'), + ");"; + } + } + + outdent { + emit "protected:"; + }; + + if ($is_class) { + emit "virtual ~",$typename,"() {}"; + } else { + emit "~",$typename,"() {}"; + } + } + } $tag, "$typename$ispec", -export => 1; +} + +# MAIN BODY + +# Collect all type definitions from XML files + +sub add_type_to_hash($) { + my ($type) = @_; + + my $name = $type->getAttribute('type-name') + or die "Type without a name in $filename\n"; + + die "Duplicate definition of $name in $filename\n" if $types{$name}; + + local $typename = $name; + check_bad_attrs $type; + $types{$name} = $type; + $type_files{$name} = $filename; +} + +for my $fn (glob "$input_dir/*.xml") { + local $filename = $fn; + my $parser = XML::LibXML->new(); + my $doc = $parser->parse_file($filename); + + add_type_to_hash $_ foreach $doc->findnodes('/data-definition/enum-type'); + add_type_to_hash $_ foreach $doc->findnodes('/data-definition/bitfield-type'); + add_type_to_hash $_ foreach $doc->findnodes('/data-definition/struct-type'); + add_type_to_hash $_ foreach $doc->findnodes('/data-definition/class-type'); +} + +# Generate text representations + +my %type_handlers = ( + 'enum-type' => \&render_enum_type, + 'bitfield-type' => \&render_bitfield_type, + 'class-type' => \&render_struct_type, + 'struct-type' => \&render_struct_type, +); + +my %type_data; + +for my $name (sort { $a cmp $b } keys %types) { + local $typename = $name; + local $filename = $type_files{$typename}; + local %weak_refs; + local %strong_refs; + + eval { + my $type = $types{$typename}; + + # Emit the actual type definition + my @code = with_emit { + with_anon { + $type_handlers{$type->nodeName}->($type); + }; + } 2; + + delete $weak_refs{$name}; + delete $strong_refs{$name}; + + # Add wrapping + my @all = with_emit { + my $def = type_header_def($typename); + emit "#ifndef $def"; + emit "#define $def"; + + for my $strong (sort { $a cmp $b } keys %strong_refs) { + my $sdef = type_header_def($strong); + emit "#ifndef $sdef"; + emit "#include \"$strong.h\""; + emit "#endif"; + } + + emit_block { + for my $weak (sort { $a cmp $b } keys %weak_refs) { + next if $strong_refs{$weak}; + my $ttype = $types{$weak}; + my $tstr = 'struct'; + $tstr = 'enum' if $ttype->nodeName eq 'enum-type'; + $tstr = 'union' if $ttype->nodeName eq 'bitfield-type'; + $tstr = 'union' if ($ttype->nodeName eq 'struct-type' && is_attr_true($ttype,'is-union')); + emit $tstr, ' ', $weak, ';'; + } + + push @lines, @code; + } "namespace $main_namespace "; + + emit "#endif"; + }; + + $type_data{$typename} = \@all; + }; + if ($@) { + print 'Error: '.$@."Type $typename in $filename ignored\n"; + } +} + +# Write output files + +mkdir $output_dir; + +{ + # Delete the old files + for my $name (glob "$output_dir/*.h") { + unlink $name; + } + + # Write out the headers + local $, = "\n"; + local $\ = "\n"; + + for my $name (keys %type_data) { + open FH, ">$output_dir/$name.h"; + print FH "/* THIS FILE WAS GENERATED. DO NOT EDIT. */"; + print FH @{$type_data{$name}}; + close FH; + } + + # Write out the static file + open FH, ">$output_dir/static.inc"; + print FH "/* THIS FILE WAS GENERATED. DO NOT EDIT. */"; + for my $name (sort { $a cmp $b } keys %static_includes) { + print FH "#include \"$name.h\""; + } + print FH "namespace $main_namespace {"; + print FH @static_lines; + print FH '}'; + close FH; +} diff --git a/library/xml/df.building-raws.xml b/library/xml/df.building-raws.xml new file mode 100644 index 000000000..bf522ae31 --- /dev/null +++ b/library/xml/df.building-raws.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.buildings.xml b/library/xml/df.buildings.xml new file mode 100644 index 000000000..f54c76eb8 --- /dev/null +++ b/library/xml/df.buildings.xml @@ -0,0 +1,403 @@ + + + + + + + + + + + (find-by-id $global.world.buildings.all $id $) + + + + + + + + + + + + + + + + + 0 - not room; 1 in stockpile; 2 wall; 3 inner; 4 distance boundary. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- stockpile -- + + + + + + + + + + + + + + + + + + + + + + + + + -- zone -- + + + + + + -- actual -- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- workshops -- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- misc -- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.creature-raws.xml b/library/xml/df.creature-raws.xml new file mode 100644 index 000000000..61aa7ed7c --- /dev/null +++ b/library/xml/df.creature-raws.xml @@ -0,0 +1,592 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // 0 around of, 1 around by + + + + + + + + + + + + + + + + + + + $global.world.raws.creatures.all[$$].caste[$] + + + + + + + + + // temporary + + + + fingers[2], nose, ear, head, eyes, mouth, hair, knuckles, lips, cheek, nails, f eet, arms, hands, tongue, leg + + + + + + + + + + + + + + + + + + + + + + + + + + // NOT 32-bit! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $global.world.raws.creatures.all[$] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.d_init.xml b/library/xml/df.d_init.xml new file mode 100644 index 000000000..345fa812a --- /dev/null +++ b/library/xml/df.d_init.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 85266c0 + + + + diff --git a/library/xml/df.history.xml b/library/xml/df.history.xml new file mode 100644 index 000000000..78dd33a3b --- /dev/null +++ b/library/xml/df.history.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + (find-by-id $global.world.history.figures $id $) + + + (describe-obj $.name) + (awhen (find-creature $.race) + (fmt "~:(~A ~A~)" $it.caste[$.caste].caste_id $it.creature_id)) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + dtor 8532fa0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.init.xml b/library/xml/df.init.xml new file mode 100644 index 000000000..6680b788a --- /dev/null +++ b/library/xml/df.init.xml @@ -0,0 +1,138 @@ + + -- init.h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- texture_handler.h + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.item-raws.xml b/library/xml/df.item-raws.xml new file mode 100644 index 000000000..81d9c7671 --- /dev/null +++ b/library/xml/df.item-raws.xml @@ -0,0 +1,303 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.items.xml b/library/xml/df.items.xml new file mode 100644 index 000000000..a49c35ff5 --- /dev/null +++ b/library/xml/df.items.xml @@ -0,0 +1,578 @@ + + -- MISC TYPES + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- CORE ITEM + + + (find-by-id $global.world.items.all $id $) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- ACTUAL ITEM + + + -- Important + + + + + + -- Misc + + + + + + + + + + + + + + + + + + + + + + + + + + -- Wielders + + + + + + + + + + + + (if (> $.stack_size 1) (fmt "stack: ~A" $.stack_size)) + (if (> $.wear 0) (fmt "wear: ~A" $.wear)) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- CRAFTED ITEM + + + + + + + $.quality + (describe-obj (material-by-id $.matType $.matIndex)) + + + + + + + + + + -- CONSTRUCTED ITEM + + + + + + + + -- BODY COMPONENT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- CRITTER + + + + + + + + + -- LIQUID/POWER + + + + + + + + + + + + + + + + + + -- MISC + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- CONSTRUCTED + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.job-enums.xml b/library/xml/df.job-enums.xml new file mode 100644 index 000000000..6a84ec8f5 --- /dev/null +++ b/library/xml/df.job-enums.xml @@ -0,0 +1,1785 @@ + + ----- PROFESSION ----- + + + + + + + -- 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 40 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 50 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 60 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 70 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 80 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 90 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 100 + + + + + + + + + + + + + + + + + + + + + + ----- LABOR ----- + + + + + -- 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 40 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 50 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 60 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 70 + + + + + + + + + + + + + ----- SKILL ----- + + + + + -- 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 40 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 50 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 60 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 70 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 80 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 90 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 100 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 110 + + + + + + + + + + + + + + + + + + + + + + ----- JOB TYPE ----- + + + -- Declare attributes: + + + + -- 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 20 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 30 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 40 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 50 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 60 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 70 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 80 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 90 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 100 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 110 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 120 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 130 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 140 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 150 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 160 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 170 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 180 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 190 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 200 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 210 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 220 + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.jobs.xml b/library/xml/df.jobs.xml new file mode 100644 index 000000000..48163fc48 --- /dev/null +++ b/library/xml/df.jobs.xml @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (find-by-id $global.world.activities.all $id $) + + + + + + + + + + + + + + -- Guess: + + + + + + + + + + + -- Either empty, or same as above: + + + + + + + + -- These are equal to the ones above: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.language.xml b/library/xml/df.language.xml new file mode 100644 index 000000000..347946602 --- /dev/null +++ b/library/xml/df.language.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + $global.world.raws.language_words[$] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $global.world.raws.translations[$] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (when $.has_name + (let* ((nick $.nickname) + (language $global.world.raws.translations[$.language]) + (fname $.first_name) + (lwords $language.words)) + (fmt "~:(~@[~A ~]~@['~A' ~]~{~A~^ ~}~)" + (if (> (length fname) 0) fname) + (if (> (length nick) 0) nick) + (loop for i from 0 below 7 for word = $.words[i] + when (>= word 0) collect $lwords[word].value)))) + + + + + diff --git a/library/xml/df.legends.xml b/library/xml/df.legends.xml new file mode 100644 index 000000000..0b8b8c926 --- /dev/null +++ b/library/xml/df.legends.xml @@ -0,0 +1,317 @@ + + + + + + + + + + + + (find-by-id $global.world.entities.all $id $) + + + (describe-obj $.name) + (describe-obj (find-creature $.race)) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (find-by-id $global.world.entity_populations $id $) + + (describe-obj $.name) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (find-by-id $global.world.nemesis.all $id $) + + + + + + + + + + + (describe-obj $.figure) + + + + + + + + + + + + + + + (find-by-id $global.world.artifacts.all $id $) + + + (describe-obj $.name) + + + + + + + + + + + + + + + (find-by-id $global.world.history.events $id $) + + + + diff --git a/library/xml/df.machines.xml b/library/xml/df.machines.xml new file mode 100644 index 000000000..10b41c5a2 --- /dev/null +++ b/library/xml/df.machines.xml @@ -0,0 +1,97 @@ + + -- MACHINE + + + + + + + + + (find-by-id $global.world.machines.all $id $) + + + + + + + + + + + + + + + + + + + + + -- MACHINE COMPONENT BUILDINGS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.map.xml b/library/xml/df.map.xml new file mode 100644 index 000000000..eac8bbeb9 --- /dev/null +++ b/library/xml/df.map.xml @@ -0,0 +1,247 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.materials.xml b/library/xml/df.materials.xml new file mode 100644 index 000000000..f3f5033d5 --- /dev/null +++ b/library/xml/df.materials.xml @@ -0,0 +1,341 @@ + + + + + + + + (describe-material $) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // color token index + + + + + + + + + + + + + (material-by-id $ $$) + (describe-material $) + + + + + + + + + + + + + + + (describe-material $) + + + + + + + + + $global.world.raws.plants.all[$] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $global.world.raws.inorganics.all[$] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.military.xml b/library/xml/df.military.xml new file mode 100644 index 000000000..016b01241 --- /dev/null +++ b/library/xml/df.military.xml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- May be invalid: + + + + + + + + + + + + + + + (find-by-id $global.world.squads.all $id $) + + + + + + (describe-obj $.name) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (describe-obj $.name) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.projectile.xml b/library/xml/df.projectile.xml new file mode 100644 index 000000000..5fc9b3e4a --- /dev/null +++ b/library/xml/df.projectile.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.raws.xml b/library/xml/df.raws.xml new file mode 100644 index 000000000..ed2745fb5 --- /dev/null +++ b/library/xml/df.raws.xml @@ -0,0 +1,237 @@ + + + -- Materials + + + + + + -- Inorganic + + + + + + + + + -- Plants + + + dtor 852cc20 + + + + + + + + + + + + + + + + + + + + + + + + + -- Creature RAWs + + + + dtor 89bab50 + + + dtor 8527e40 + + + + + + + + + + + + + dtor 89ba980 + + + -- Creatures + + + dtor 81448c0 + + + + + + + + + + + + + + + + -- Item RAWs + + + dtor 852e080 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- Sapient species + + + + + + -- Language RAWs + + dtor 852bc90 + + + + + + + + + + + + + + + + + + + + + + -- Words + + + + + + + + + + + + + + + + + + + + + + + + + + + -- Reaction RAWs + + + + + + -- Workshops + + + + + + + + + + + + + + + + -- Material index + + + + + + diff --git a/library/xml/df.refs.xml b/library/xml/df.refs.xml new file mode 100644 index 000000000..04671dc55 --- /dev/null +++ b/library/xml/df.refs.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.stockpile.xml b/library/xml/df.stockpile.xml new file mode 100644 index 000000000..cfd48e38d --- /dev/null +++ b/library/xml/df.stockpile.xml @@ -0,0 +1,254 @@ + + + + + + + + + + + also 26 + also 31 + also 32 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 16 + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + 5 + 5 + + + + + 659 + + + + + + + + 17 + + + + + + + + + + + + + + + + + + + + + + + + 11 + + + + + + + + + + + + + + + 11 + + + + + + + + + + + + + diff --git a/library/xml/df.ui.xml b/library/xml/df.ui.xml new file mode 100644 index 000000000..ca08c3d87 --- /dev/null +++ b/library/xml/df.ui.xml @@ -0,0 +1,604 @@ + + + + + + + + + + + + + + (find-by-id $global.ui.burrows.list $id $) + + (describe-obj $.name) + + + + + + + + + + + + + + + + + + -- 2 + + + + + + + + + + + + + + + -- 14 + + + + + + -- 17 + + + + + + + + -- 22 + + + + + + -- 25 + + + + + + + + + + + -- 33 + + + + + -- 35 + + + + -- 36 + + + + + + + -- 40 + + + + + + + -- 44 + + + + + + + + + + + + + + + + + + + + + + + + + + ctor 86e33c0 x + dtor 8534190 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + dtor: 0x85272c0 + + + + diff --git a/library/xml/df.units.xml b/library/xml/df.units.xml new file mode 100644 index 000000000..9889c630f --- /dev/null +++ b/library/xml/df.units.xml @@ -0,0 +1,703 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Scuttle creature: causes creature to be killed, leaving a behind + corpse and generating negative thoughts like a real kill. + + + + + + + + + + + (find-by-id $global.world.units.all $id $) + + + (describe-obj $.name) + (awhen (find-creature $.race) + (fmt "~:(~A ~A~)" $it.caste[$.caste].caste_id $it.creature_id)) + + + + + + + + + + + + + + + + E.g. for a dead miner, holds the place where he + was likely hanging around when he got the command + to mine in an aquifer. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- If shot by a ranged weapon: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // fight related + // fight related + + + // increments every tick + + + + + + + + + // 87*0 ? + + + + + // 238*0 + // 238*0 + // 238*0 + // 238*0 + // 238*0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // 490 + + + + + + + + + + + + + + + + + + + + + + + + // 53c decrements every job_counter reroll, set when changing jobs + // 540 current_job unit/walk done when reach -1, decremented every tick + // if set, decrements every job_counter reroll + + + // 54c decrements every tick, unstun at 0 + + + + + // coords ? (-30.000x3) + + + // coords again + + + + + + + + + + + + + + + + + + + + + + + + // counter, decrement to 0 + // same as 58c + + // fluctuate + + + + + + + + + + + + + + + + + + + + + + + + // 0x3e8 (1000) + // 0x3e8 (1000) + + + + + + + + + + + + + + + + // item ids? + + // 6f0: dined in a legendary dinning room, etc + + + + // 710 + + + + + // 738 + + + + // coords (-30000*3) + + + + + + + + + + + // 794 + // 796 + // 798 + // 79a + + + + + + + + + + + + + + + + + + + + + + // combat log? + + + + + + + + + + + + + // item related + + + + + + // age ? incremented every tick + + + + + + + + + + // items ids? + + // same size as 8e8, soldier related? + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (fmt "value=~A" $.value) + + + + + + + + + + + + + + + (describe-obj $.name) + (awhen (find-creature $.race) + (fmt "~:(~A ~A~)" $it.caste[$.caste].caste_id $it.creature_id)) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.viewscreen.xml b/library/xml/df.viewscreen.xml new file mode 100644 index 000000000..3874c445a --- /dev/null +++ b/library/xml/df.viewscreen.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.world-data.xml b/library/xml/df.world-data.xml new file mode 100644 index 000000000..2f0faa3a2 --- /dev/null +++ b/library/xml/df.world-data.xml @@ -0,0 +1,374 @@ + + + + + + + + + + + + + + + + + + + + (describe-obj $.name) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/df.world.xml b/library/xml/df.world.xml new file mode 100644 index 000000000..3058b0a64 --- /dev/null +++ b/library/xml/df.world.xml @@ -0,0 +1,503 @@ + + + dtor 89fff80 + + + dtor 8532540 + + + + + + + + + + + + + + + + + -- + + + + + + + + + + -- Entities + + + + + + + + + + + + -- Unknown + + + + -- Units + + + + + + + + + + + + + + + + + + -- Unknown + + + + + + + + + -- Nemesis + + + + + + + + + + + + + + -- Items + + + dtor 852f4b0 + + + + + + + + + + + + + + + + + + + -- Artifacts + + + + + + + + + + + + -- Jobs and projectiles + + + + + + -- Buildings + + + dtor 85316f0 + + + + + + + + + + + + + + + + + + + + -- Machines (connected groups of gears and so on) + + + + + + + + + + + -- Unknown + + + + + + + + + + + + + + + + + + + + + + + + -- Plants + + + + + + + + + -- Unknown + + + + -- Unknown + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- Drills + + + + + + + + + + + -- Reports and announcements + + + dtor 85356e0 + + + + + + + + + + Written to by code at 0x80fd7b0 + + + + + + + + + + + + + + + + + + + + + + 52cdc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 547f8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- RAWs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ctor 87ae880 + + + + + + + + + + + dtor 83bed90 + + + + + + + + + + + + -- hist figures + + + + + + + + + + + + + + + + Looks like a temporary buffer for pathfinding or something. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 192be0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/library/xml/list.pl b/library/xml/list.pl new file mode 100755 index 000000000..206565843 --- /dev/null +++ b/library/xml/list.pl @@ -0,0 +1,33 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use XML::LibXML; + +my $input_dir = $ARGV[0] || '.'; +my $output_dir = $ARGV[1] || 'codegen'; +my $separator = $ARGV[2] || "\n"; + +print "$output_dir/static.inc"; + +for my $filename (glob "$input_dir/*.xml") { + my $parser = XML::LibXML->new(); + my $doc = $parser->parse_file($filename); + + my @nodes = ( + $doc->findnodes('/data-definition/enum-type'), + $doc->findnodes('/data-definition/bitfield-type'), + $doc->findnodes('/data-definition/struct-type'), + $doc->findnodes('/data-definition/class-type') + ); + + for my $node (@nodes) { + my $name = $node->getAttribute('type-name') + or die "Unnamed type in $filename\n"; + print "$separator$output_dir/$name.h"; + } +} + +print $separator if $separator eq "\n"; +